@sanity/cli-core 0.1.0-alpha.17 → 0.1.0-alpha.18

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.
@@ -2,6 +2,8 @@ import { Command } from '@oclif/core';
2
2
  import { getCliConfig } from './config/cli/getCliConfig.js';
3
3
  import { findProjectRoot } from './config/findProjectRoot.js';
4
4
  import { subdebug } from './debug.js';
5
+ import { NonInteractiveError } from './errors/NonInteractiveError.js';
6
+ import { ProjectRootNotFoundError } from './errors/ProjectRootNotFoundError.js';
5
7
  import { getGlobalCliClient, getProjectCliClient } from './services/apiClient.js';
6
8
  import { getCliTelemetry } from './util/getCliTelemetry.js';
7
9
  import { isInteractive } from './util/isInteractive.js';
@@ -54,12 +56,59 @@ export class SanityCommand extends Command {
54
56
  return getCliConfig(root.directory);
55
57
  }
56
58
  /**
57
- * Get the project ID from the CLI config.
59
+ * Get the project ID from passed flags or (if not provided) the CLI config.
58
60
  *
59
- * @returns The project ID or `undefined` if it's not set.
60
- */ async getProjectId() {
61
- const config = await this.getCliConfig();
62
- return config.api?.projectId;
61
+ * Optionally accepts a `fallback` function that is called when no project ID
62
+ * can be determined from flags or config. This allows commands to provide
63
+ * interactive project selection while keeping the prompt logic in the CLI package.
64
+ *
65
+ * If the fallback throws a `NonInteractiveError` (e.g. because the terminal is
66
+ * not interactive), it falls through to the standard error with suggestions.
67
+ *
68
+ * @returns The project ID.
69
+ */ async getProjectId(options) {
70
+ const hasProjectFlag = this.ctor.flags != null && 'project-id' in this.ctor.flags;
71
+ // Check --project-id flag first
72
+ if (hasProjectFlag) {
73
+ const flagProjectId = 'project-id' in this.flags && typeof this.flags['project-id'] === 'string' ? this.flags['project-id'] : undefined;
74
+ if (flagProjectId) return flagProjectId;
75
+ }
76
+ // Fall back to CLI config
77
+ try {
78
+ const config = await this.getCliConfig();
79
+ const configProjectId = config.api?.projectId;
80
+ if (configProjectId) return configProjectId;
81
+ } catch (err) {
82
+ if (!(err instanceof ProjectRootNotFoundError)) throw err;
83
+ // No project root — fall through to fallback/error
84
+ }
85
+ // Offer interactive selection if a fallback was provided
86
+ if (options?.fallback) {
87
+ try {
88
+ return await options.fallback();
89
+ } catch (err) {
90
+ if (!(err instanceof NonInteractiveError)) throw err;
91
+ // Non-interactive: throw with actionable suggestions
92
+ throw new ProjectRootNotFoundError('Unable to determine project ID', {
93
+ cause: err,
94
+ suggestions: [
95
+ ...hasProjectFlag ? [
96
+ 'Providing a project ID: --project-id <project-id>'
97
+ ] : [],
98
+ 'Running this command from within a Sanity project directory',
99
+ 'Running in an interactive terminal to get a project selection prompt'
100
+ ]
101
+ });
102
+ }
103
+ }
104
+ throw new ProjectRootNotFoundError('Unable to determine project ID', {
105
+ suggestions: [
106
+ ...hasProjectFlag ? [
107
+ 'Providing a project ID: --project-id <project-id>'
108
+ ] : [],
109
+ 'Running this command from within a Sanity project directory'
110
+ ]
111
+ });
63
112
  }
64
113
  /**
65
114
  * Get the project's root directory by resolving the config
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/SanityCommand.ts"],"sourcesContent":["import {Command, Interfaces} from '@oclif/core'\n\nimport {getCliConfig} from './config/cli/getCliConfig.js'\nimport {type CliConfig} from './config/cli/types/cliConfig.js'\nimport {findProjectRoot} from './config/findProjectRoot.js'\nimport {type ProjectRootResult} from './config/util/recursivelyResolveProjectRoot.js'\nimport {subdebug} from './debug.js'\nimport {\n getGlobalCliClient,\n getProjectCliClient,\n type GlobalCliClientOptions,\n type ProjectCliClientOptions,\n} from './services/apiClient.js'\nimport {type CLITelemetryStore} from './telemetry/types.js'\nimport {type Output} from './types.js'\nimport {getCliTelemetry} from './util/getCliTelemetry.js'\nimport {isInteractive} from './util/isInteractive.js'\n\ntype Flags<T extends typeof Command> = Interfaces.InferredFlags<\n (typeof SanityCommand)['baseFlags'] & T['flags']\n>\n\ntype Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>\n\nconst debug = subdebug('sanityCommand')\n\nexport abstract class SanityCommand<T extends typeof Command> extends Command {\n protected args!: Args<T>\n protected flags!: Flags<T>\n\n /**\n * Get the global API client.\n *\n * @param args - The global API client options.\n * @returns The global API client.\n *\n * @deprecated use `getGlobalCliClient` function directly instead.\n */\n protected getGlobalApiClient = (args: GlobalCliClientOptions) => getGlobalCliClient(args)\n\n /**\n * Get the project API client.\n *\n * @param args - The project API client options.\n * @returns The project API client.\n *\n * @deprecated use `getProjectCliClient` function directly instead.\n */\n protected getProjectApiClient = (args: ProjectCliClientOptions) => getProjectCliClient(args)\n\n /**\n * Helper for outputting to the console.\n *\n * @example\n * ```ts\n * this.output.log('Hello')\n * this.output.warn('Warning')\n * this.output.error('Error')\n * ```\n */\n protected output: Output = {\n error: this.error.bind(this),\n log: this.log.bind(this),\n warn: this.warn.bind(this),\n }\n\n /**\n * The telemetry store.\n *\n * @returns The telemetry store.\n */\n protected telemetry!: CLITelemetryStore\n\n /**\n * Get the CLI config.\n *\n * @returns The CLI config.\n */\n protected async getCliConfig(): Promise<CliConfig> {\n const root = await this.getProjectRoot()\n\n debug(`Using project root`, root)\n return getCliConfig(root.directory)\n }\n\n /**\n * Get the project ID from the CLI config.\n *\n * @returns The project ID or `undefined` if it's not set.\n */\n protected async getProjectId(): Promise<string | undefined> {\n const config = await this.getCliConfig()\n\n return config.api?.projectId\n }\n\n /**\n * Get the project's root directory by resolving the config\n *\n * @returns The project root result.\n */\n protected getProjectRoot(): Promise<ProjectRootResult> {\n return findProjectRoot(process.cwd())\n }\n\n public async init(): Promise<void> {\n const {args, flags} = await this.parse({\n args: this.ctor.args,\n baseFlags: (super.ctor as typeof SanityCommand).baseFlags,\n enableJsonFlag: this.ctor.enableJsonFlag,\n flags: this.ctor.flags,\n strict: this.ctor.strict,\n })\n\n this.args = args as Args<T>\n this.flags = flags as Flags<T>\n this.telemetry = getCliTelemetry()\n\n await super.init()\n }\n\n /**\n * Check if the command is running in unattended mode.\n *\n * This means the command should not ask for user input, instead using defaults where\n * possible, and if that does not make sense (eg there's missing information), then we\n * should error out (remember to exit with a non-zero code).\n *\n * Most commands should take an explicit `--yes` flag to enable unattended mode, but\n * some commands may also be run in unattended mode if `process.stdin` is not a TTY\n * (eg when running in a CI environment).\n */\n protected isUnattended(): boolean {\n return this.flags.yes || !this.resolveIsInteractive()\n }\n\n /**\n * Resolver for checking if the terminal is interactive. Override in tests to provide mock values.\n *\n * @returns Whether the terminal is interactive.\n */\n protected resolveIsInteractive(): boolean {\n return isInteractive()\n }\n}\n"],"names":["Command","getCliConfig","findProjectRoot","subdebug","getGlobalCliClient","getProjectCliClient","getCliTelemetry","isInteractive","debug","SanityCommand","args","flags","getGlobalApiClient","getProjectApiClient","output","error","bind","log","warn","telemetry","root","getProjectRoot","directory","getProjectId","config","api","projectId","process","cwd","init","parse","ctor","baseFlags","enableJsonFlag","strict","isUnattended","yes","resolveIsInteractive"],"mappings":"AAAA,SAAQA,OAAO,QAAmB,cAAa;AAE/C,SAAQC,YAAY,QAAO,+BAA8B;AAEzD,SAAQC,eAAe,QAAO,8BAA6B;AAE3D,SAAQC,QAAQ,QAAO,aAAY;AACnC,SACEC,kBAAkB,EAClBC,mBAAmB,QAGd,0BAAyB;AAGhC,SAAQC,eAAe,QAAO,4BAA2B;AACzD,SAAQC,aAAa,QAAO,0BAAyB;AAQrD,MAAMC,QAAQL,SAAS;AAEvB,OAAO,MAAeM,sBAAgDT;IAC1DU,KAAc;IACdC,MAAgB;IAE1B;;;;;;;GAOC,GACD,AAAUC,qBAAqB,CAACF,OAAiCN,mBAAmBM,MAAK;IAEzF;;;;;;;GAOC,GACD,AAAUG,sBAAsB,CAACH,OAAkCL,oBAAoBK,MAAK;IAE5F;;;;;;;;;GASC,GACD,AAAUI,SAAiB;QACzBC,OAAO,IAAI,CAACA,KAAK,CAACC,IAAI,CAAC,IAAI;QAC3BC,KAAK,IAAI,CAACA,GAAG,CAACD,IAAI,CAAC,IAAI;QACvBE,MAAM,IAAI,CAACA,IAAI,CAACF,IAAI,CAAC,IAAI;IAC3B,EAAC;IAED;;;;GAIC,GACD,AAAUG,UAA6B;IAEvC;;;;GAIC,GACD,MAAgBlB,eAAmC;QACjD,MAAMmB,OAAO,MAAM,IAAI,CAACC,cAAc;QAEtCb,MAAM,CAAC,kBAAkB,CAAC,EAAEY;QAC5B,OAAOnB,aAAamB,KAAKE,SAAS;IACpC;IAEA;;;;GAIC,GACD,MAAgBC,eAA4C;QAC1D,MAAMC,SAAS,MAAM,IAAI,CAACvB,YAAY;QAEtC,OAAOuB,OAAOC,GAAG,EAAEC;IACrB;IAEA;;;;GAIC,GACD,AAAUL,iBAA6C;QACrD,OAAOnB,gBAAgByB,QAAQC,GAAG;IACpC;IAEA,MAAaC,OAAsB;QACjC,MAAM,EAACnB,IAAI,EAAEC,KAAK,EAAC,GAAG,MAAM,IAAI,CAACmB,KAAK,CAAC;YACrCpB,MAAM,IAAI,CAACqB,IAAI,CAACrB,IAAI;YACpBsB,WAAW,AAAC,KAAK,CAACD,KAA8BC,SAAS;YACzDC,gBAAgB,IAAI,CAACF,IAAI,CAACE,cAAc;YACxCtB,OAAO,IAAI,CAACoB,IAAI,CAACpB,KAAK;YACtBuB,QAAQ,IAAI,CAACH,IAAI,CAACG,MAAM;QAC1B;QAEA,IAAI,CAACxB,IAAI,GAAGA;QACZ,IAAI,CAACC,KAAK,GAAGA;QACb,IAAI,CAACQ,SAAS,GAAGb;QAEjB,MAAM,KAAK,CAACuB;IACd;IAEA;;;;;;;;;;GAUC,GACD,AAAUM,eAAwB;QAChC,OAAO,IAAI,CAACxB,KAAK,CAACyB,GAAG,IAAI,CAAC,IAAI,CAACC,oBAAoB;IACrD;IAEA;;;;GAIC,GACD,AAAUA,uBAAgC;QACxC,OAAO9B;IACT;AACF"}
1
+ {"version":3,"sources":["../src/SanityCommand.ts"],"sourcesContent":["import {Command, Interfaces} from '@oclif/core'\n\nimport {getCliConfig} from './config/cli/getCliConfig.js'\nimport {type CliConfig} from './config/cli/types/cliConfig.js'\nimport {findProjectRoot} from './config/findProjectRoot.js'\nimport {type ProjectRootResult} from './config/util/recursivelyResolveProjectRoot.js'\nimport {subdebug} from './debug.js'\nimport {NonInteractiveError} from './errors/NonInteractiveError.js'\nimport {ProjectRootNotFoundError} from './errors/ProjectRootNotFoundError.js'\nimport {\n getGlobalCliClient,\n getProjectCliClient,\n type GlobalCliClientOptions,\n type ProjectCliClientOptions,\n} from './services/apiClient.js'\nimport {type CLITelemetryStore} from './telemetry/types.js'\nimport {type Output} from './types.js'\nimport {getCliTelemetry} from './util/getCliTelemetry.js'\nimport {isInteractive} from './util/isInteractive.js'\n\ntype Flags<T extends typeof Command> = Interfaces.InferredFlags<\n (typeof SanityCommand)['baseFlags'] & T['flags']\n>\n\ntype Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>\n\nconst debug = subdebug('sanityCommand')\n\nexport abstract class SanityCommand<T extends typeof Command> extends Command {\n protected args!: Args<T>\n protected flags!: Flags<T>\n\n /**\n * Get the global API client.\n *\n * @param args - The global API client options.\n * @returns The global API client.\n *\n * @deprecated use `getGlobalCliClient` function directly instead.\n */\n protected getGlobalApiClient = (args: GlobalCliClientOptions) => getGlobalCliClient(args)\n\n /**\n * Get the project API client.\n *\n * @param args - The project API client options.\n * @returns The project API client.\n *\n * @deprecated use `getProjectCliClient` function directly instead.\n */\n protected getProjectApiClient = (args: ProjectCliClientOptions) => getProjectCliClient(args)\n\n /**\n * Helper for outputting to the console.\n *\n * @example\n * ```ts\n * this.output.log('Hello')\n * this.output.warn('Warning')\n * this.output.error('Error')\n * ```\n */\n protected output: Output = {\n error: this.error.bind(this),\n log: this.log.bind(this),\n warn: this.warn.bind(this),\n }\n\n /**\n * The telemetry store.\n *\n * @returns The telemetry store.\n */\n protected telemetry!: CLITelemetryStore\n\n /**\n * Get the CLI config.\n *\n * @returns The CLI config.\n */\n protected async getCliConfig(): Promise<CliConfig> {\n const root = await this.getProjectRoot()\n\n debug(`Using project root`, root)\n return getCliConfig(root.directory)\n }\n\n /**\n * Get the project ID from passed flags or (if not provided) the CLI config.\n *\n * Optionally accepts a `fallback` function that is called when no project ID\n * can be determined from flags or config. This allows commands to provide\n * interactive project selection while keeping the prompt logic in the CLI package.\n *\n * If the fallback throws a `NonInteractiveError` (e.g. because the terminal is\n * not interactive), it falls through to the standard error with suggestions.\n *\n * @returns The project ID.\n */\n protected async getProjectId(options?: {fallback?: () => Promise<string>}): Promise<string> {\n const hasProjectFlag = this.ctor.flags != null && 'project-id' in this.ctor.flags\n\n // Check --project-id flag first\n if (hasProjectFlag) {\n const flagProjectId =\n 'project-id' in this.flags && typeof this.flags['project-id'] === 'string'\n ? this.flags['project-id']\n : undefined\n\n if (flagProjectId) return flagProjectId\n }\n\n // Fall back to CLI config\n try {\n const config = await this.getCliConfig()\n const configProjectId = config.api?.projectId\n if (configProjectId) return configProjectId\n } catch (err) {\n if (!(err instanceof ProjectRootNotFoundError)) throw err\n // No project root — fall through to fallback/error\n }\n\n // Offer interactive selection if a fallback was provided\n if (options?.fallback) {\n try {\n return await options.fallback()\n } catch (err) {\n if (!(err instanceof NonInteractiveError)) throw err\n // Non-interactive: throw with actionable suggestions\n throw new ProjectRootNotFoundError('Unable to determine project ID', {\n cause: err,\n suggestions: [\n ...(hasProjectFlag ? ['Providing a project ID: --project-id <project-id>'] : []),\n 'Running this command from within a Sanity project directory',\n 'Running in an interactive terminal to get a project selection prompt',\n ],\n })\n }\n }\n\n throw new ProjectRootNotFoundError('Unable to determine project ID', {\n suggestions: [\n ...(hasProjectFlag ? ['Providing a project ID: --project-id <project-id>'] : []),\n 'Running this command from within a Sanity project directory',\n ],\n })\n }\n\n /**\n * Get the project's root directory by resolving the config\n *\n * @returns The project root result.\n */\n protected getProjectRoot(): Promise<ProjectRootResult> {\n return findProjectRoot(process.cwd())\n }\n\n public async init(): Promise<void> {\n const {args, flags} = await this.parse({\n args: this.ctor.args,\n baseFlags: (super.ctor as typeof SanityCommand).baseFlags,\n enableJsonFlag: this.ctor.enableJsonFlag,\n flags: this.ctor.flags,\n strict: this.ctor.strict,\n })\n\n this.args = args as Args<T>\n this.flags = flags as Flags<T>\n this.telemetry = getCliTelemetry()\n\n await super.init()\n }\n\n /**\n * Check if the command is running in unattended mode.\n *\n * This means the command should not ask for user input, instead using defaults where\n * possible, and if that does not make sense (eg there's missing information), then we\n * should error out (remember to exit with a non-zero code).\n *\n * Most commands should take an explicit `--yes` flag to enable unattended mode, but\n * some commands may also be run in unattended mode if `process.stdin` is not a TTY\n * (eg when running in a CI environment).\n */\n protected isUnattended(): boolean {\n return this.flags.yes || !this.resolveIsInteractive()\n }\n\n /**\n * Resolver for checking if the terminal is interactive. Override in tests to provide mock values.\n *\n * @returns Whether the terminal is interactive.\n */\n protected resolveIsInteractive(): boolean {\n return isInteractive()\n }\n}\n"],"names":["Command","getCliConfig","findProjectRoot","subdebug","NonInteractiveError","ProjectRootNotFoundError","getGlobalCliClient","getProjectCliClient","getCliTelemetry","isInteractive","debug","SanityCommand","args","flags","getGlobalApiClient","getProjectApiClient","output","error","bind","log","warn","telemetry","root","getProjectRoot","directory","getProjectId","options","hasProjectFlag","ctor","flagProjectId","undefined","config","configProjectId","api","projectId","err","fallback","cause","suggestions","process","cwd","init","parse","baseFlags","enableJsonFlag","strict","isUnattended","yes","resolveIsInteractive"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import {default as boxen} from 'boxen'
2
2
  import {Options as BoxenOptions} from 'boxen'
3
3
  import {Boxes} from 'boxen'
4
+ import {CLIError} from '@oclif/core/errors'
4
5
  import {CustomBorderStyle} from 'boxen'
5
6
  import * as inquirer from '@inquirer/prompts'
6
7
  import {default as logSymbols} from 'log-symbols'
@@ -38,8 +39,10 @@ export {logSymbols}
38
39
  * Error thrown when a prompt is attempted in a non-interactive environment
39
40
  * (e.g., CI, non-TTY, piped stdin). Callers can catch this specific error
40
41
  * to provide appropriate fallback behavior.
42
+ *
43
+ * Extends `CLIError` to suppress stack traces in user-facing output.
41
44
  */
42
- export declare class NonInteractiveError extends Error {
45
+ export declare class NonInteractiveError extends CLIError {
43
46
  constructor(promptName: string)
44
47
  }
45
48
 
@@ -1,4 +1,4 @@
1
- export { NonInteractiveError } from '../util/NonInteractiveError.js';
1
+ export { NonInteractiveError } from '../errors/NonInteractiveError.js';
2
2
  export * from '../ux/boxen.js';
3
3
  export * from '../ux/logSymbols.js';
4
4
  export * from '../ux/prompts.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/_exports/ux.ts"],"sourcesContent":["export {NonInteractiveError} from '../util/NonInteractiveError.js'\nexport * from '../ux/boxen.js'\nexport * from '../ux/logSymbols.js'\nexport * from '../ux/prompts.js'\nexport * from '../ux/spinner.js'\n"],"names":["NonInteractiveError"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,iCAAgC;AAClE,cAAc,iBAAgB;AAC9B,cAAc,sBAAqB;AACnC,cAAc,mBAAkB;AAChC,cAAc,mBAAkB"}
1
+ {"version":3,"sources":["../../src/_exports/ux.ts"],"sourcesContent":["export {NonInteractiveError} from '../errors/NonInteractiveError.js'\nexport * from '../ux/boxen.js'\nexport * from '../ux/logSymbols.js'\nexport * from '../ux/prompts.js'\nexport * from '../ux/spinner.js'\n"],"names":["NonInteractiveError"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,mCAAkC;AACpE,cAAc,iBAAgB;AAC9B,cAAc,sBAAqB;AACnC,cAAc,mBAAkB;AAChC,cAAc,mBAAkB"}
@@ -1,22 +1,36 @@
1
1
  import { debug } from '../../debug.js';
2
+ import { NotFoundError } from '../../errors/NotFoundError.js';
2
3
  import { importModule } from '../../util/importModule.js';
3
- import { NotFoundError } from '../../util/NotFoundError.js';
4
4
  import { findPathForFiles } from '../util/findConfigsPaths.js';
5
5
  import { cliConfigSchema } from './schemas.js';
6
+ const cache = new Map();
6
7
  /**
7
8
  * Get the CLI config for a project, given the root path.
8
9
  *
9
- * We really want to avoid loading the CLI config in the main thread, as we'll need
10
- * TypeScript loading logic, potentially with ts path aliases, syntax extensions and all
11
- * sorts of nonsense. Thus, we _attempt_ to use a worker thread - but have to fall back
12
- * to using the main thread if not possible. This can be the case if the configuration
13
- * contains non-serializable properties, such as functions. This is unfortunately used
14
- * by the vite config, for example.
10
+ * Results are cached in-memory keyed by rootPath for the lifetime of the
11
+ * process. Since the CLI always runs from a single project root, the config
12
+ * won't change during a command's execution, so caching avoids redundant
13
+ * filesystem reads and jiti imports from the prerun hook, SanityCommand
14
+ * helpers, and action files.
15
+ *
16
+ * If loading fails the cached promise is evicted so the next call retries.
15
17
  *
16
18
  * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.
17
19
  * @returns The CLI config
18
20
  * @internal
19
- */ export async function getCliConfig(rootPath) {
21
+ */ export function getCliConfig(rootPath) {
22
+ const cached = cache.get(rootPath);
23
+ if (cached) {
24
+ return cached;
25
+ }
26
+ const promise = loadCliConfig(rootPath).catch((err)=>{
27
+ cache.delete(rootPath);
28
+ throw err;
29
+ });
30
+ cache.set(rootPath, promise);
31
+ return promise;
32
+ }
33
+ async function loadCliConfig(rootPath) {
20
34
  const paths = await findPathForFiles(rootPath, [
21
35
  'sanity.cli.ts',
22
36
  'sanity.cli.js'
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/config/cli/getCliConfig.ts"],"sourcesContent":["import {debug} from '../../debug.js'\nimport {importModule} from '../../util/importModule.js'\nimport {NotFoundError} from '../../util/NotFoundError.js'\nimport {findPathForFiles} from '../util/findConfigsPaths.js'\nimport {cliConfigSchema} from './schemas.js'\nimport {type CliConfig} from './types/cliConfig.js'\n\n/**\n * Get the CLI config for a project, given the root path.\n *\n * We really want to avoid loading the CLI config in the main thread, as we'll need\n * TypeScript loading logic, potentially with ts path aliases, syntax extensions and all\n * sorts of nonsense. Thus, we _attempt_ to use a worker thread - but have to fall back\n * to using the main thread if not possible. This can be the case if the configuration\n * contains non-serializable properties, such as functions. This is unfortunately used\n * by the vite config, for example.\n *\n * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.\n * @returns The CLI config\n * @internal\n */\nexport async function getCliConfig(rootPath: string): Promise<CliConfig> {\n const paths = await findPathForFiles(rootPath, ['sanity.cli.ts', 'sanity.cli.js'])\n const configPaths = paths.filter((path) => path.exists)\n\n if (configPaths.length === 0) {\n throw new NotFoundError(`No CLI config found at ${rootPath}/sanity.cli.(ts|js)`)\n }\n\n if (configPaths.length > 1) {\n throw new Error(\n `Multiple CLI config files found (${configPaths.map((path) => path.path).join(', ')})`,\n )\n }\n\n const configPath = configPaths[0].path\n\n debug(`Loading CLI config from: ${configPath}`)\n\n let cliConfig: CliConfig | undefined\n try {\n const result = await importModule<CliConfig>(configPath)\n\n debug('CLI config loaded: %o', result)\n\n cliConfig = result\n } catch (err) {\n debug('Failed to load CLI config in worker thread: %s', err)\n\n throw new Error('CLI config cannot be loaded', {cause: err})\n }\n\n const {data, error, success} = cliConfigSchema.safeParse(cliConfig)\n if (!success) {\n debug(`Invalid CLI config: ${error.message}`)\n throw new Error(`Invalid CLI config: ${error.message}`, {cause: error})\n }\n\n return data\n}\n"],"names":["debug","importModule","NotFoundError","findPathForFiles","cliConfigSchema","getCliConfig","rootPath","paths","configPaths","filter","path","exists","length","Error","map","join","configPath","cliConfig","result","err","cause","data","error","success","safeParse","message"],"mappings":"AAAA,SAAQA,KAAK,QAAO,iBAAgB;AACpC,SAAQC,YAAY,QAAO,6BAA4B;AACvD,SAAQC,aAAa,QAAO,8BAA6B;AACzD,SAAQC,gBAAgB,QAAO,8BAA6B;AAC5D,SAAQC,eAAe,QAAO,eAAc;AAG5C;;;;;;;;;;;;;CAaC,GACD,OAAO,eAAeC,aAAaC,QAAgB;IACjD,MAAMC,QAAQ,MAAMJ,iBAAiBG,UAAU;QAAC;QAAiB;KAAgB;IACjF,MAAME,cAAcD,MAAME,MAAM,CAAC,CAACC,OAASA,KAAKC,MAAM;IAEtD,IAAIH,YAAYI,MAAM,KAAK,GAAG;QAC5B,MAAM,IAAIV,cAAc,CAAC,uBAAuB,EAAEI,SAAS,mBAAmB,CAAC;IACjF;IAEA,IAAIE,YAAYI,MAAM,GAAG,GAAG;QAC1B,MAAM,IAAIC,MACR,CAAC,iCAAiC,EAAEL,YAAYM,GAAG,CAAC,CAACJ,OAASA,KAAKA,IAAI,EAAEK,IAAI,CAAC,MAAM,CAAC,CAAC;IAE1F;IAEA,MAAMC,aAAaR,WAAW,CAAC,EAAE,CAACE,IAAI;IAEtCV,MAAM,CAAC,yBAAyB,EAAEgB,YAAY;IAE9C,IAAIC;IACJ,IAAI;QACF,MAAMC,SAAS,MAAMjB,aAAwBe;QAE7ChB,MAAM,yBAAyBkB;QAE/BD,YAAYC;IACd,EAAE,OAAOC,KAAK;QACZnB,MAAM,kDAAkDmB;QAExD,MAAM,IAAIN,MAAM,+BAA+B;YAACO,OAAOD;QAAG;IAC5D;IAEA,MAAM,EAACE,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAC,GAAGnB,gBAAgBoB,SAAS,CAACP;IACzD,IAAI,CAACM,SAAS;QACZvB,MAAM,CAAC,oBAAoB,EAAEsB,MAAMG,OAAO,EAAE;QAC5C,MAAM,IAAIZ,MAAM,CAAC,oBAAoB,EAAES,MAAMG,OAAO,EAAE,EAAE;YAACL,OAAOE;QAAK;IACvE;IAEA,OAAOD;AACT"}
1
+ {"version":3,"sources":["../../../src/config/cli/getCliConfig.ts"],"sourcesContent":["import {debug} from '../../debug.js'\nimport {NotFoundError} from '../../errors/NotFoundError.js'\nimport {importModule} from '../../util/importModule.js'\nimport {findPathForFiles} from '../util/findConfigsPaths.js'\nimport {cliConfigSchema} from './schemas.js'\nimport {type CliConfig} from './types/cliConfig.js'\n\nconst cache = new Map<string, Promise<CliConfig>>()\n\n/**\n * Get the CLI config for a project, given the root path.\n *\n * Results are cached in-memory keyed by rootPath for the lifetime of the\n * process. Since the CLI always runs from a single project root, the config\n * won't change during a command's execution, so caching avoids redundant\n * filesystem reads and jiti imports from the prerun hook, SanityCommand\n * helpers, and action files.\n *\n * If loading fails the cached promise is evicted so the next call retries.\n *\n * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.\n * @returns The CLI config\n * @internal\n */\nexport function getCliConfig(rootPath: string): Promise<CliConfig> {\n const cached = cache.get(rootPath)\n if (cached) {\n return cached\n }\n\n const promise = loadCliConfig(rootPath).catch((err) => {\n cache.delete(rootPath)\n throw err\n })\n\n cache.set(rootPath, promise)\n return promise\n}\n\nasync function loadCliConfig(rootPath: string): Promise<CliConfig> {\n const paths = await findPathForFiles(rootPath, ['sanity.cli.ts', 'sanity.cli.js'])\n const configPaths = paths.filter((path) => path.exists)\n\n if (configPaths.length === 0) {\n throw new NotFoundError(`No CLI config found at ${rootPath}/sanity.cli.(ts|js)`)\n }\n\n if (configPaths.length > 1) {\n throw new Error(\n `Multiple CLI config files found (${configPaths.map((path) => path.path).join(', ')})`,\n )\n }\n\n const configPath = configPaths[0].path\n\n debug(`Loading CLI config from: ${configPath}`)\n\n let cliConfig: CliConfig | undefined\n try {\n const result = await importModule<CliConfig>(configPath)\n\n debug('CLI config loaded: %o', result)\n\n cliConfig = result\n } catch (err) {\n debug('Failed to load CLI config in worker thread: %s', err)\n\n throw new Error('CLI config cannot be loaded', {cause: err})\n }\n\n const {data, error, success} = cliConfigSchema.safeParse(cliConfig)\n if (!success) {\n debug(`Invalid CLI config: ${error.message}`)\n throw new Error(`Invalid CLI config: ${error.message}`, {cause: error})\n }\n\n return data\n}\n"],"names":["debug","NotFoundError","importModule","findPathForFiles","cliConfigSchema","cache","Map","getCliConfig","rootPath","cached","get","promise","loadCliConfig","catch","err","delete","set","paths","configPaths","filter","path","exists","length","Error","map","join","configPath","cliConfig","result","cause","data","error","success","safeParse","message"],"mappings":"AAAA,SAAQA,KAAK,QAAO,iBAAgB;AACpC,SAAQC,aAAa,QAAO,gCAA+B;AAC3D,SAAQC,YAAY,QAAO,6BAA4B;AACvD,SAAQC,gBAAgB,QAAO,8BAA6B;AAC5D,SAAQC,eAAe,QAAO,eAAc;AAG5C,MAAMC,QAAQ,IAAIC;AAElB;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASC,aAAaC,QAAgB;IAC3C,MAAMC,SAASJ,MAAMK,GAAG,CAACF;IACzB,IAAIC,QAAQ;QACV,OAAOA;IACT;IAEA,MAAME,UAAUC,cAAcJ,UAAUK,KAAK,CAAC,CAACC;QAC7CT,MAAMU,MAAM,CAACP;QACb,MAAMM;IACR;IAEAT,MAAMW,GAAG,CAACR,UAAUG;IACpB,OAAOA;AACT;AAEA,eAAeC,cAAcJ,QAAgB;IAC3C,MAAMS,QAAQ,MAAMd,iBAAiBK,UAAU;QAAC;QAAiB;KAAgB;IACjF,MAAMU,cAAcD,MAAME,MAAM,CAAC,CAACC,OAASA,KAAKC,MAAM;IAEtD,IAAIH,YAAYI,MAAM,KAAK,GAAG;QAC5B,MAAM,IAAIrB,cAAc,CAAC,uBAAuB,EAAEO,SAAS,mBAAmB,CAAC;IACjF;IAEA,IAAIU,YAAYI,MAAM,GAAG,GAAG;QAC1B,MAAM,IAAIC,MACR,CAAC,iCAAiC,EAAEL,YAAYM,GAAG,CAAC,CAACJ,OAASA,KAAKA,IAAI,EAAEK,IAAI,CAAC,MAAM,CAAC,CAAC;IAE1F;IAEA,MAAMC,aAAaR,WAAW,CAAC,EAAE,CAACE,IAAI;IAEtCpB,MAAM,CAAC,yBAAyB,EAAE0B,YAAY;IAE9C,IAAIC;IACJ,IAAI;QACF,MAAMC,SAAS,MAAM1B,aAAwBwB;QAE7C1B,MAAM,yBAAyB4B;QAE/BD,YAAYC;IACd,EAAE,OAAOd,KAAK;QACZd,MAAM,kDAAkDc;QAExD,MAAM,IAAIS,MAAM,+BAA+B;YAACM,OAAOf;QAAG;IAC5D;IAEA,MAAM,EAACgB,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAC,GAAG5B,gBAAgB6B,SAAS,CAACN;IACzD,IAAI,CAACK,SAAS;QACZhC,MAAM,CAAC,oBAAoB,EAAE+B,MAAMG,OAAO,EAAE;QAC5C,MAAM,IAAIX,MAAM,CAAC,oBAAoB,EAAEQ,MAAMG,OAAO,EAAE,EAAE;YAACL,OAAOE;QAAK;IACvE;IAEA,OAAOD;AACT"}
@@ -2,7 +2,7 @@ import { existsSync } from 'node:fs';
2
2
  import { createRequire } from 'node:module';
3
3
  import { join } from 'node:path';
4
4
  import { register } from 'tsx/esm/api';
5
- import { NotFoundError } from '../../util/NotFoundError.js';
5
+ import { NotFoundError } from '../../errors/NotFoundError.js';
6
6
  import { tryGetDefaultExport } from '../../util/tryGetDefaultExport.js';
7
7
  import { cliConfigSchema } from './schemas.js';
8
8
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/config/cli/getCliConfigSync.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport {createRequire} from 'node:module'\nimport {join} from 'node:path'\n\nimport {register} from 'tsx/esm/api'\n\nimport {NotFoundError} from '../../util/NotFoundError.js'\nimport {tryGetDefaultExport} from '../../util/tryGetDefaultExport.js'\nimport {cliConfigSchema} from './schemas.js'\nimport {type CliConfig} from './types/cliConfig.js'\n\n/**\n * Get the CLI config for a project synchronously, given the root path.\n *\n * This loads the CLI config in the main thread using tsx/register for TypeScript support.\n * Note: This is a synchronous operation and does not use worker threads like the async version.\n *\n * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.\n * @returns The CLI config\n * @internal\n */\nexport function getCliConfigSync(rootPath: string): CliConfig {\n const possiblePaths = ['sanity.cli.ts', 'sanity.cli.js'].map((file) => join(rootPath, file))\n const configPaths = possiblePaths.filter((path) => existsSync(path))\n\n if (configPaths.length === 0) {\n throw new NotFoundError(`No CLI config found at ${rootPath}/sanity.cli.(ts|js)`)\n }\n\n if (configPaths.length > 1) {\n throw new Error(`Multiple CLI config files found (${configPaths.join(', ')})`)\n }\n\n const configPath = configPaths[0]\n\n // Register tsx for TypeScript support\n const unregister = register()\n\n let cliConfig: CliConfig | undefined\n try {\n // Use createRequire for synchronous loading in ESM contexts\n // This works when tsx loader is active\n const require = createRequire(import.meta.url)\n const loaded = require(configPath)\n cliConfig = tryGetDefaultExport(loaded) as CliConfig | undefined\n } finally {\n unregister()\n }\n\n const {data, error, success} = cliConfigSchema.safeParse(cliConfig)\n if (!success) {\n throw new Error(`Invalid CLI config: ${error.message}`)\n }\n\n // There is a minor difference here because of the `vite` property and how the types\n // aren't as specific as our manually typed `CliConfig` type, thus the cast.\n return data as CliConfig\n}\n"],"names":["existsSync","createRequire","join","register","NotFoundError","tryGetDefaultExport","cliConfigSchema","getCliConfigSync","rootPath","possiblePaths","map","file","configPaths","filter","path","length","Error","configPath","unregister","cliConfig","require","url","loaded","data","error","success","safeParse","message"],"mappings":"AAAA,SAAQA,UAAU,QAAO,UAAS;AAClC,SAAQC,aAAa,QAAO,cAAa;AACzC,SAAQC,IAAI,QAAO,YAAW;AAE9B,SAAQC,QAAQ,QAAO,cAAa;AAEpC,SAAQC,aAAa,QAAO,8BAA6B;AACzD,SAAQC,mBAAmB,QAAO,oCAAmC;AACrE,SAAQC,eAAe,QAAO,eAAc;AAG5C;;;;;;;;;CASC,GACD,OAAO,SAASC,iBAAiBC,QAAgB;IAC/C,MAAMC,gBAAgB;QAAC;QAAiB;KAAgB,CAACC,GAAG,CAAC,CAACC,OAAST,KAAKM,UAAUG;IACtF,MAAMC,cAAcH,cAAcI,MAAM,CAAC,CAACC,OAASd,WAAWc;IAE9D,IAAIF,YAAYG,MAAM,KAAK,GAAG;QAC5B,MAAM,IAAIX,cAAc,CAAC,uBAAuB,EAAEI,SAAS,mBAAmB,CAAC;IACjF;IAEA,IAAII,YAAYG,MAAM,GAAG,GAAG;QAC1B,MAAM,IAAIC,MAAM,CAAC,iCAAiC,EAAEJ,YAAYV,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/E;IAEA,MAAMe,aAAaL,WAAW,CAAC,EAAE;IAEjC,sCAAsC;IACtC,MAAMM,aAAaf;IAEnB,IAAIgB;IACJ,IAAI;QACF,4DAA4D;QAC5D,uCAAuC;QACvC,MAAMC,UAAUnB,cAAc,YAAYoB,GAAG;QAC7C,MAAMC,SAASF,QAAQH;QACvBE,YAAYd,oBAAoBiB;IAClC,SAAU;QACRJ;IACF;IAEA,MAAM,EAACK,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAC,GAAGnB,gBAAgBoB,SAAS,CAACP;IACzD,IAAI,CAACM,SAAS;QACZ,MAAM,IAAIT,MAAM,CAAC,oBAAoB,EAAEQ,MAAMG,OAAO,EAAE;IACxD;IAEA,oFAAoF;IACpF,4EAA4E;IAC5E,OAAOJ;AACT"}
1
+ {"version":3,"sources":["../../../src/config/cli/getCliConfigSync.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport {createRequire} from 'node:module'\nimport {join} from 'node:path'\n\nimport {register} from 'tsx/esm/api'\n\nimport {NotFoundError} from '../../errors/NotFoundError.js'\nimport {tryGetDefaultExport} from '../../util/tryGetDefaultExport.js'\nimport {cliConfigSchema} from './schemas.js'\nimport {type CliConfig} from './types/cliConfig.js'\n\n/**\n * Get the CLI config for a project synchronously, given the root path.\n *\n * This loads the CLI config in the main thread using tsx/register for TypeScript support.\n * Note: This is a synchronous operation and does not use worker threads like the async version.\n *\n * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.\n * @returns The CLI config\n * @internal\n */\nexport function getCliConfigSync(rootPath: string): CliConfig {\n const possiblePaths = ['sanity.cli.ts', 'sanity.cli.js'].map((file) => join(rootPath, file))\n const configPaths = possiblePaths.filter((path) => existsSync(path))\n\n if (configPaths.length === 0) {\n throw new NotFoundError(`No CLI config found at ${rootPath}/sanity.cli.(ts|js)`)\n }\n\n if (configPaths.length > 1) {\n throw new Error(`Multiple CLI config files found (${configPaths.join(', ')})`)\n }\n\n const configPath = configPaths[0]\n\n // Register tsx for TypeScript support\n const unregister = register()\n\n let cliConfig: CliConfig | undefined\n try {\n // Use createRequire for synchronous loading in ESM contexts\n // This works when tsx loader is active\n const require = createRequire(import.meta.url)\n const loaded = require(configPath)\n cliConfig = tryGetDefaultExport(loaded) as CliConfig | undefined\n } finally {\n unregister()\n }\n\n const {data, error, success} = cliConfigSchema.safeParse(cliConfig)\n if (!success) {\n throw new Error(`Invalid CLI config: ${error.message}`)\n }\n\n // There is a minor difference here because of the `vite` property and how the types\n // aren't as specific as our manually typed `CliConfig` type, thus the cast.\n return data as CliConfig\n}\n"],"names":["existsSync","createRequire","join","register","NotFoundError","tryGetDefaultExport","cliConfigSchema","getCliConfigSync","rootPath","possiblePaths","map","file","configPaths","filter","path","length","Error","configPath","unregister","cliConfig","require","url","loaded","data","error","success","safeParse","message"],"mappings":"AAAA,SAAQA,UAAU,QAAO,UAAS;AAClC,SAAQC,aAAa,QAAO,cAAa;AACzC,SAAQC,IAAI,QAAO,YAAW;AAE9B,SAAQC,QAAQ,QAAO,cAAa;AAEpC,SAAQC,aAAa,QAAO,gCAA+B;AAC3D,SAAQC,mBAAmB,QAAO,oCAAmC;AACrE,SAAQC,eAAe,QAAO,eAAc;AAG5C;;;;;;;;;CASC,GACD,OAAO,SAASC,iBAAiBC,QAAgB;IAC/C,MAAMC,gBAAgB;QAAC;QAAiB;KAAgB,CAACC,GAAG,CAAC,CAACC,OAAST,KAAKM,UAAUG;IACtF,MAAMC,cAAcH,cAAcI,MAAM,CAAC,CAACC,OAASd,WAAWc;IAE9D,IAAIF,YAAYG,MAAM,KAAK,GAAG;QAC5B,MAAM,IAAIX,cAAc,CAAC,uBAAuB,EAAEI,SAAS,mBAAmB,CAAC;IACjF;IAEA,IAAII,YAAYG,MAAM,GAAG,GAAG;QAC1B,MAAM,IAAIC,MAAM,CAAC,iCAAiC,EAAEJ,YAAYV,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/E;IAEA,MAAMe,aAAaL,WAAW,CAAC,EAAE;IAEjC,sCAAsC;IACtC,MAAMM,aAAaf;IAEnB,IAAIgB;IACJ,IAAI;QACF,4DAA4D;QAC5D,uCAAuC;QACvC,MAAMC,UAAUnB,cAAc,YAAYoB,GAAG;QAC7C,MAAMC,SAASF,QAAQH;QACvBE,YAAYd,oBAAoBiB;IAClC,SAAU;QACRJ;IACF;IAEA,MAAM,EAACK,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAC,GAAGnB,gBAAgBoB,SAAS,CAACP;IACzD,IAAI,CAACM,SAAS;QACZ,MAAM,IAAIT,MAAM,CAAC,oBAAoB,EAAEQ,MAAMG,OAAO,EAAE;IACxD;IAEA,oFAAoF;IACpF,4EAA4E;IAC5E,OAAOJ;AACT"}
@@ -41,6 +41,7 @@ import { z } from 'zod';
41
41
  reactCompiler: z.custom().optional(),
42
42
  reactStrictMode: z.boolean().optional(),
43
43
  schemaExtraction: z.object({
44
+ enabled: z.boolean().optional(),
44
45
  enforceRequiredFields: z.boolean().optional(),
45
46
  path: z.string().optional(),
46
47
  watchPatterns: z.array(z.string()).optional(),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/config/cli/schemas.ts"],"sourcesContent":["import {type TypeGenConfig} from '@sanity/codegen'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {z} from 'zod'\n\nimport {type CliConfig} from './types/cliConfig'\nimport {type UserViteConfig} from './types/userViteConfig'\n\n/**\n * @public\n */\nexport const cliConfigSchema = z.object({\n api: z\n .object({\n dataset: z.string().optional(),\n projectId: z.string().optional(),\n })\n .optional(),\n\n app: z\n .object({\n entry: z.string().optional(),\n icon: z.string().optional(),\n id: z.string().optional(),\n organizationId: z.string().optional(),\n title: z.string().optional(),\n })\n .optional(),\n\n autoUpdates: z.boolean().optional(),\n\n deployment: z\n .object({\n appId: z.string().optional(),\n autoUpdates: z.boolean().optional(),\n })\n .optional(),\n\n graphql: z\n .array(\n z.object({\n filterSuffix: z.string().optional(),\n generation: z.enum(['gen1', 'gen2', 'gen3']).optional(),\n id: z.string().optional(),\n nonNullDocumentFields: z.boolean().optional(),\n playground: z.boolean().optional(),\n source: z.string().optional(),\n tag: z.string().optional(),\n workspace: z.string().optional(),\n }),\n )\n .optional(),\n\n mediaLibrary: z\n .object({\n aspectsPath: z.string().optional(),\n })\n .optional(),\n\n project: z\n .object({\n basePath: z.string().optional(),\n })\n .optional(),\n\n reactCompiler: z.custom<ReactCompilerConfig>().optional(),\n\n reactStrictMode: z.boolean().optional(),\n\n schemaExtraction: z\n .object({\n enforceRequiredFields: z.boolean().optional(),\n path: z.string().optional(),\n watchPatterns: z.array(z.string()).optional(),\n workspace: z.string().optional(),\n })\n .optional(),\n\n server: z\n .object({\n hostname: z.string().optional(),\n port: z.number().optional(),\n })\n .optional(),\n\n studioHost: z.string().optional(),\n\n vite: z.custom<UserViteConfig>().optional(),\n\n typegen: z.custom<TypeGenConfig>().optional(),\n}) satisfies z.ZodType<CliConfig>\n"],"names":["z","cliConfigSchema","object","api","dataset","string","optional","projectId","app","entry","icon","id","organizationId","title","autoUpdates","boolean","deployment","appId","graphql","array","filterSuffix","generation","enum","nonNullDocumentFields","playground","source","tag","workspace","mediaLibrary","aspectsPath","project","basePath","reactCompiler","custom","reactStrictMode","schemaExtraction","enforceRequiredFields","path","watchPatterns","server","hostname","port","number","studioHost","vite","typegen"],"mappings":"AAEA,SAAQA,CAAC,QAAO,MAAK;AAKrB;;CAEC,GACD,OAAO,MAAMC,kBAAkBD,EAAEE,MAAM,CAAC;IACtCC,KAAKH,EACFE,MAAM,CAAC;QACNE,SAASJ,EAAEK,MAAM,GAAGC,QAAQ;QAC5BC,WAAWP,EAAEK,MAAM,GAAGC,QAAQ;IAChC,GACCA,QAAQ;IAEXE,KAAKR,EACFE,MAAM,CAAC;QACNO,OAAOT,EAAEK,MAAM,GAAGC,QAAQ;QAC1BI,MAAMV,EAAEK,MAAM,GAAGC,QAAQ;QACzBK,IAAIX,EAAEK,MAAM,GAAGC,QAAQ;QACvBM,gBAAgBZ,EAAEK,MAAM,GAAGC,QAAQ;QACnCO,OAAOb,EAAEK,MAAM,GAAGC,QAAQ;IAC5B,GACCA,QAAQ;IAEXQ,aAAad,EAAEe,OAAO,GAAGT,QAAQ;IAEjCU,YAAYhB,EACTE,MAAM,CAAC;QACNe,OAAOjB,EAAEK,MAAM,GAAGC,QAAQ;QAC1BQ,aAAad,EAAEe,OAAO,GAAGT,QAAQ;IACnC,GACCA,QAAQ;IAEXY,SAASlB,EACNmB,KAAK,CACJnB,EAAEE,MAAM,CAAC;QACPkB,cAAcpB,EAAEK,MAAM,GAAGC,QAAQ;QACjCe,YAAYrB,EAAEsB,IAAI,CAAC;YAAC;YAAQ;YAAQ;SAAO,EAAEhB,QAAQ;QACrDK,IAAIX,EAAEK,MAAM,GAAGC,QAAQ;QACvBiB,uBAAuBvB,EAAEe,OAAO,GAAGT,QAAQ;QAC3CkB,YAAYxB,EAAEe,OAAO,GAAGT,QAAQ;QAChCmB,QAAQzB,EAAEK,MAAM,GAAGC,QAAQ;QAC3BoB,KAAK1B,EAAEK,MAAM,GAAGC,QAAQ;QACxBqB,WAAW3B,EAAEK,MAAM,GAAGC,QAAQ;IAChC,IAEDA,QAAQ;IAEXsB,cAAc5B,EACXE,MAAM,CAAC;QACN2B,aAAa7B,EAAEK,MAAM,GAAGC,QAAQ;IAClC,GACCA,QAAQ;IAEXwB,SAAS9B,EACNE,MAAM,CAAC;QACN6B,UAAU/B,EAAEK,MAAM,GAAGC,QAAQ;IAC/B,GACCA,QAAQ;IAEX0B,eAAehC,EAAEiC,MAAM,GAAwB3B,QAAQ;IAEvD4B,iBAAiBlC,EAAEe,OAAO,GAAGT,QAAQ;IAErC6B,kBAAkBnC,EACfE,MAAM,CAAC;QACNkC,uBAAuBpC,EAAEe,OAAO,GAAGT,QAAQ;QAC3C+B,MAAMrC,EAAEK,MAAM,GAAGC,QAAQ;QACzBgC,eAAetC,EAAEmB,KAAK,CAACnB,EAAEK,MAAM,IAAIC,QAAQ;QAC3CqB,WAAW3B,EAAEK,MAAM,GAAGC,QAAQ;IAChC,GACCA,QAAQ;IAEXiC,QAAQvC,EACLE,MAAM,CAAC;QACNsC,UAAUxC,EAAEK,MAAM,GAAGC,QAAQ;QAC7BmC,MAAMzC,EAAE0C,MAAM,GAAGpC,QAAQ;IAC3B,GACCA,QAAQ;IAEXqC,YAAY3C,EAAEK,MAAM,GAAGC,QAAQ;IAE/BsC,MAAM5C,EAAEiC,MAAM,GAAmB3B,QAAQ;IAEzCuC,SAAS7C,EAAEiC,MAAM,GAAkB3B,QAAQ;AAC7C,GAAiC"}
1
+ {"version":3,"sources":["../../../src/config/cli/schemas.ts"],"sourcesContent":["import {type TypeGenConfig} from '@sanity/codegen'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {z} from 'zod'\n\nimport {type CliConfig} from './types/cliConfig'\nimport {type UserViteConfig} from './types/userViteConfig'\n\n/**\n * @public\n */\nexport const cliConfigSchema = z.object({\n api: z\n .object({\n dataset: z.string().optional(),\n projectId: z.string().optional(),\n })\n .optional(),\n\n app: z\n .object({\n entry: z.string().optional(),\n icon: z.string().optional(),\n id: z.string().optional(),\n organizationId: z.string().optional(),\n title: z.string().optional(),\n })\n .optional(),\n\n autoUpdates: z.boolean().optional(),\n\n deployment: z\n .object({\n appId: z.string().optional(),\n autoUpdates: z.boolean().optional(),\n })\n .optional(),\n\n graphql: z\n .array(\n z.object({\n filterSuffix: z.string().optional(),\n generation: z.enum(['gen1', 'gen2', 'gen3']).optional(),\n id: z.string().optional(),\n nonNullDocumentFields: z.boolean().optional(),\n playground: z.boolean().optional(),\n source: z.string().optional(),\n tag: z.string().optional(),\n workspace: z.string().optional(),\n }),\n )\n .optional(),\n\n mediaLibrary: z\n .object({\n aspectsPath: z.string().optional(),\n })\n .optional(),\n\n project: z\n .object({\n basePath: z.string().optional(),\n })\n .optional(),\n\n reactCompiler: z.custom<ReactCompilerConfig>().optional(),\n\n reactStrictMode: z.boolean().optional(),\n\n schemaExtraction: z\n .object({\n enabled: z.boolean().optional(),\n enforceRequiredFields: z.boolean().optional(),\n path: z.string().optional(),\n watchPatterns: z.array(z.string()).optional(),\n workspace: z.string().optional(),\n })\n .optional(),\n\n server: z\n .object({\n hostname: z.string().optional(),\n port: z.number().optional(),\n })\n .optional(),\n\n studioHost: z.string().optional(),\n\n vite: z.custom<UserViteConfig>().optional(),\n\n typegen: z.custom<Partial<TypeGenConfig> & {enabled?: boolean}>().optional(),\n}) satisfies z.ZodType<CliConfig>\n"],"names":["z","cliConfigSchema","object","api","dataset","string","optional","projectId","app","entry","icon","id","organizationId","title","autoUpdates","boolean","deployment","appId","graphql","array","filterSuffix","generation","enum","nonNullDocumentFields","playground","source","tag","workspace","mediaLibrary","aspectsPath","project","basePath","reactCompiler","custom","reactStrictMode","schemaExtraction","enabled","enforceRequiredFields","path","watchPatterns","server","hostname","port","number","studioHost","vite","typegen"],"mappings":"AAEA,SAAQA,CAAC,QAAO,MAAK;AAKrB;;CAEC,GACD,OAAO,MAAMC,kBAAkBD,EAAEE,MAAM,CAAC;IACtCC,KAAKH,EACFE,MAAM,CAAC;QACNE,SAASJ,EAAEK,MAAM,GAAGC,QAAQ;QAC5BC,WAAWP,EAAEK,MAAM,GAAGC,QAAQ;IAChC,GACCA,QAAQ;IAEXE,KAAKR,EACFE,MAAM,CAAC;QACNO,OAAOT,EAAEK,MAAM,GAAGC,QAAQ;QAC1BI,MAAMV,EAAEK,MAAM,GAAGC,QAAQ;QACzBK,IAAIX,EAAEK,MAAM,GAAGC,QAAQ;QACvBM,gBAAgBZ,EAAEK,MAAM,GAAGC,QAAQ;QACnCO,OAAOb,EAAEK,MAAM,GAAGC,QAAQ;IAC5B,GACCA,QAAQ;IAEXQ,aAAad,EAAEe,OAAO,GAAGT,QAAQ;IAEjCU,YAAYhB,EACTE,MAAM,CAAC;QACNe,OAAOjB,EAAEK,MAAM,GAAGC,QAAQ;QAC1BQ,aAAad,EAAEe,OAAO,GAAGT,QAAQ;IACnC,GACCA,QAAQ;IAEXY,SAASlB,EACNmB,KAAK,CACJnB,EAAEE,MAAM,CAAC;QACPkB,cAAcpB,EAAEK,MAAM,GAAGC,QAAQ;QACjCe,YAAYrB,EAAEsB,IAAI,CAAC;YAAC;YAAQ;YAAQ;SAAO,EAAEhB,QAAQ;QACrDK,IAAIX,EAAEK,MAAM,GAAGC,QAAQ;QACvBiB,uBAAuBvB,EAAEe,OAAO,GAAGT,QAAQ;QAC3CkB,YAAYxB,EAAEe,OAAO,GAAGT,QAAQ;QAChCmB,QAAQzB,EAAEK,MAAM,GAAGC,QAAQ;QAC3BoB,KAAK1B,EAAEK,MAAM,GAAGC,QAAQ;QACxBqB,WAAW3B,EAAEK,MAAM,GAAGC,QAAQ;IAChC,IAEDA,QAAQ;IAEXsB,cAAc5B,EACXE,MAAM,CAAC;QACN2B,aAAa7B,EAAEK,MAAM,GAAGC,QAAQ;IAClC,GACCA,QAAQ;IAEXwB,SAAS9B,EACNE,MAAM,CAAC;QACN6B,UAAU/B,EAAEK,MAAM,GAAGC,QAAQ;IAC/B,GACCA,QAAQ;IAEX0B,eAAehC,EAAEiC,MAAM,GAAwB3B,QAAQ;IAEvD4B,iBAAiBlC,EAAEe,OAAO,GAAGT,QAAQ;IAErC6B,kBAAkBnC,EACfE,MAAM,CAAC;QACNkC,SAASpC,EAAEe,OAAO,GAAGT,QAAQ;QAC7B+B,uBAAuBrC,EAAEe,OAAO,GAAGT,QAAQ;QAC3CgC,MAAMtC,EAAEK,MAAM,GAAGC,QAAQ;QACzBiC,eAAevC,EAAEmB,KAAK,CAACnB,EAAEK,MAAM,IAAIC,QAAQ;QAC3CqB,WAAW3B,EAAEK,MAAM,GAAGC,QAAQ;IAChC,GACCA,QAAQ;IAEXkC,QAAQxC,EACLE,MAAM,CAAC;QACNuC,UAAUzC,EAAEK,MAAM,GAAGC,QAAQ;QAC7BoC,MAAM1C,EAAE2C,MAAM,GAAGrC,QAAQ;IAC3B,GACCA,QAAQ;IAEXsC,YAAY5C,EAAEK,MAAM,GAAGC,QAAQ;IAE/BuC,MAAM7C,EAAEiC,MAAM,GAAmB3B,QAAQ;IAEzCwC,SAAS9C,EAAEiC,MAAM,GAAiD3B,QAAQ;AAC5E,GAAiC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/config/cli/types/cliConfig.ts"],"sourcesContent":["import {type TypeGenConfig} from '@sanity/codegen'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\n\nimport {type UserViteConfig} from './userViteConfig'\n\n/**\n * @public\n */\nexport interface CliConfig {\n /** The project ID and dataset the Sanity CLI should use to run its commands */\n api?: {\n dataset?: string\n projectId?: string\n }\n\n /** Configuration for custom Sanity apps built with the App SDK */\n app?: {\n /** The entrypoint for your custom app. By default, `src/App.tsx` */\n entry?: string\n /** String encoding of an icon (typically an SVG) */\n icon?: string\n /** @deprecated Use deployment.appId */\n id?: string\n /** The ID for the Sanity organization that manages this application */\n organizationId?: string\n /** The title of the custom app. Used in Dashboard and in the browser tab */\n title?: string\n }\n\n /** @deprecated Use deployment.autoUpdates */\n autoUpdates?: boolean\n\n /** Options for custom app and Studio deployments */\n deployment?: {\n /**\n * The ID for your custom app or Studio. Generated when deploying your app or Studio for the first time.\n * Get your app ID by either:\n * 1. Checking the output of `sanity deploy`, or\n * 2. Checking your project’s Studio tab at https://sanity.io/manage\n *\n * @remarks This is required for all custom app deployments, and for Studios opting in to fine grained version control.\n * {@link https://www.sanity.io/docs/studio/latest-version-of-sanity#k0896ed4574b7}\n */\n appId?: string\n /**\n * Enable automatic updates for your Studio or custom app’s Sanity dependencies.\n * {@link https://www.sanity.io/docs/studio/latest-version-of-sanity}\n */\n autoUpdates?: boolean\n }\n\n /** Define the GraphQL APIs that the CLI can deploy and interact with */\n graphql?: Array<{\n filterSuffix?: string\n generation?: 'gen1' | 'gen2' | 'gen3'\n id?: string\n nonNullDocumentFields?: boolean\n playground?: boolean\n source?: string\n tag?: string\n workspace?: string\n }>\n\n /** Configuration for the Media Library */\n mediaLibrary?: {\n /** The path to the Media Library aspects directory. When using the CLI to manage aspects, this is the directory they will be read from and written to. */\n aspectsPath?: string\n }\n\n /** Contains the property `basePath` which lets you change the top-level slug for the Studio. You typically need to set this if you embed the Studio in another application where it is one of many routes. Defaults to an empty string. */\n project?: {\n basePath?: string\n }\n\n /** Configuration options for React Compiler */\n reactCompiler?: ReactCompilerConfig\n\n /** Wraps the Studio in \\<React.StrictMode\\> root to aid in flagging potential problems related to concurrent features (startTransition, useTransition, useDeferredValue, Suspense). Can also be enabled by setting SANITY_STUDIO_REACT_STRICT_MODE=\"true\"|\"false\". It only applies to sanity dev in development mode and is ignored in sanity build and in production. Defaults to false. */\n reactStrictMode?: boolean\n\n /**\n * Configuration for schema extraction (`sanity schema extract`)\n */\n schemaExtraction?: {\n /**\n * When true, schema fields marked as required will be non-optional in the output.\n * Defaults to `false`\n */\n enforceRequiredFields?: boolean\n\n /**\n * Output path for the extracted schema file.\n * Defaults to `schema.json` in the working directory.\n */\n path?: string\n\n /**\n * Additional glob patterns to watch for schema changes in watch mode.\n * These extend the default patterns:\n * - `sanity.config.{js,jsx,ts,tsx,mjs}`\n * - `schema*\\/**\\/*.{js,jsx,ts,tsx,mjs}`\n */\n watchPatterns?: string[]\n\n /**\n * The name of the workspace to generate a schema for. Required if your Sanity project has more than one\n * workspace.\n */\n workspace?: string\n }\n\n /** Defines the hostname and port that the development server should run on. hostname defaults to localhost, and port to 3333. */\n server?: {\n hostname?: string\n port?: number\n }\n\n /** @deprecated Use deployment.appId */\n studioHost?: string\n\n /**\n * Configuration for Sanity typegen\n */\n typegen?: Partial<TypeGenConfig>\n\n /** Exposes the default Vite configuration for custom apps and the Studio so it can be changed and extended. */\n vite?: UserViteConfig\n}\n"],"names":[],"mappings":"AAKA;;CAEC,GACD,WAuHC"}
1
+ {"version":3,"sources":["../../../../src/config/cli/types/cliConfig.ts"],"sourcesContent":["import {type TypeGenConfig} from '@sanity/codegen'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\n\nimport {type UserViteConfig} from './userViteConfig'\n\n/**\n * @public\n */\nexport interface CliConfig {\n /** The project ID and dataset the Sanity CLI should use to run its commands */\n api?: {\n dataset?: string\n projectId?: string\n }\n\n /** Configuration for custom Sanity apps built with the App SDK */\n app?: {\n /** The entrypoint for your custom app. By default, `src/App.tsx` */\n entry?: string\n /** String encoding of an icon (typically an SVG) */\n icon?: string\n /** @deprecated Use deployment.appId */\n id?: string\n /** The ID for the Sanity organization that manages this application */\n organizationId?: string\n /** The title of the custom app. Used in Dashboard and in the browser tab */\n title?: string\n }\n\n /** @deprecated Use deployment.autoUpdates */\n autoUpdates?: boolean\n\n /** Options for custom app and Studio deployments */\n deployment?: {\n /**\n * The ID for your custom app or Studio. Generated when deploying your app or Studio for the first time.\n * Get your app ID by either:\n * 1. Checking the output of `sanity deploy`, or\n * 2. Checking your project’s Studio tab at https://sanity.io/manage\n *\n * @remarks This is required for all custom app deployments, and for Studios opting in to fine grained version control.\n * {@link https://www.sanity.io/docs/studio/latest-version-of-sanity#k0896ed4574b7}\n */\n appId?: string\n /**\n * Enable automatic updates for your Studio or custom app’s Sanity dependencies.\n * {@link https://www.sanity.io/docs/studio/latest-version-of-sanity}\n */\n autoUpdates?: boolean\n }\n\n /** Define the GraphQL APIs that the CLI can deploy and interact with */\n graphql?: Array<{\n filterSuffix?: string\n generation?: 'gen1' | 'gen2' | 'gen3'\n id?: string\n nonNullDocumentFields?: boolean\n playground?: boolean\n source?: string\n tag?: string\n workspace?: string\n }>\n\n /** Configuration for the Media Library */\n mediaLibrary?: {\n /** The path to the Media Library aspects directory. When using the CLI to manage aspects, this is the directory they will be read from and written to. */\n aspectsPath?: string\n }\n\n /** Contains the property `basePath` which lets you change the top-level slug for the Studio. You typically need to set this if you embed the Studio in another application where it is one of many routes. Defaults to an empty string. */\n project?: {\n basePath?: string\n }\n\n /** Configuration options for React Compiler */\n reactCompiler?: ReactCompilerConfig\n\n /** Wraps the Studio in \\<React.StrictMode\\> root to aid in flagging potential problems related to concurrent features (startTransition, useTransition, useDeferredValue, Suspense). Can also be enabled by setting SANITY_STUDIO_REACT_STRICT_MODE=\"true\"|\"false\". It only applies to sanity dev in development mode and is ignored in sanity build and in production. Defaults to false. */\n reactStrictMode?: boolean\n\n /**\n * Configuration for schema extraction (`sanity schema extract`)\n */\n schemaExtraction?: {\n /**\n * Enable schema extraction as part of sanity dev and sanity build\n */\n enabled?: boolean\n\n /**\n * When true, schema fields marked as required will be non-optional in the output.\n * Defaults to `false`\n */\n enforceRequiredFields?: boolean\n\n /**\n * Output path for the extracted schema file.\n * Defaults to `schema.json` in the working directory.\n */\n path?: string\n\n /**\n * Additional glob patterns to watch for schema changes in watch mode.\n * These extend the default patterns:\n * - `sanity.config.{js,jsx,ts,tsx,mjs}`\n * - `schema*\\/**\\/*.{js,jsx,ts,tsx,mjs}`\n */\n watchPatterns?: string[]\n\n /**\n * The name of the workspace to generate a schema for. Required if your Sanity project has more than one\n * workspace.\n */\n workspace?: string\n }\n\n /** Defines the hostname and port that the development server should run on. hostname defaults to localhost, and port to 3333. */\n server?: {\n hostname?: string\n port?: number\n }\n\n /** @deprecated Use deployment.appId */\n studioHost?: string\n\n /**\n * Configuration for Sanity typegen\n */\n typegen?: Partial<TypeGenConfig> & {\n /**\n * Enable typegen as part of sanity dev and sanity build.\n * When enabled, types are generated on startup and when files change.\n * Defaults to `false`\n */\n enabled?: boolean\n }\n\n /** Exposes the default Vite configuration for custom apps and the Studio so it can be changed and extended. */\n vite?: UserViteConfig\n}\n"],"names":[],"mappings":"AAKA;;CAEC,GACD,WAmIC"}
@@ -1,3 +1,4 @@
1
+ import { ProjectRootNotFoundError } from '../errors/ProjectRootNotFoundError.js';
1
2
  import { findAppConfigPath } from './util/findAppConfigPath.js';
2
3
  import { tryFindStudioConfigPath } from './util/findStudioConfigPath.js';
3
4
  import { recursivelyResolveProjectRoot } from './util/recursivelyResolveProjectRoot.js';
@@ -24,9 +25,12 @@ import { recursivelyResolveProjectRoot } from './util/recursivelyResolveProjectR
24
25
  if (appProjectRoot) {
25
26
  return appProjectRoot;
26
27
  }
27
- // If nothing is found throw an error
28
- throw new Error('No project root found');
28
+ // If nothing is found throw a specific error
29
+ throw new ProjectRootNotFoundError('No project root found');
29
30
  } catch (err) {
31
+ if (err instanceof ProjectRootNotFoundError) {
32
+ throw err;
33
+ }
30
34
  const message = err instanceof Error ? err.message : `${err}`;
31
35
  throw new Error(`Error occurred trying to resolve project root:\n${message}`);
32
36
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/findProjectRoot.ts"],"sourcesContent":["import {findAppConfigPath} from './util/findAppConfigPath.js'\nimport {tryFindStudioConfigPath} from './util/findStudioConfigPath.js'\nimport {\n type ProjectRootResult,\n recursivelyResolveProjectRoot,\n} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Resolve project root directory and type.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @internal\n */\nexport async function findProjectRoot(cwd: string): Promise<ProjectRootResult> {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = await resolveProjectRootForStudio(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = await resolveProjectRootForApp(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw an error\n throw new Error('No project root found')\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}`)\n }\n}\n\n/**\n * Recursively searches for a project configuration file in the given directory and its parents.\n * Throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns A promise that resolves to an object if config is found, false otherwise\n * @internal\n */\nasync function resolveProjectRootForStudio(\n basePath: string,\n iterations = 0,\n): Promise<false | ProjectRootResult> {\n return recursivelyResolveProjectRoot(basePath, tryFindStudioConfigPath, 'studio', iterations)\n}\n\n/**\n * Recursively searches for a app project configuration file in the given directory and its parents.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns A promise that resolves to an object if config is found, false otherwise\n * @internal\n */\nasync function resolveProjectRootForApp(\n basePath: string,\n iterations = 0,\n): Promise<false | ProjectRootResult> {\n return recursivelyResolveProjectRoot(basePath, findAppConfigPath, 'app', iterations)\n}\n"],"names":["findAppConfigPath","tryFindStudioConfigPath","recursivelyResolveProjectRoot","findProjectRoot","cwd","studioProjectRoot","resolveProjectRootForStudio","appProjectRoot","resolveProjectRootForApp","Error","err","message","basePath","iterations"],"mappings":"AAAA,SAAQA,iBAAiB,QAAO,8BAA6B;AAC7D,SAAQC,uBAAuB,QAAO,iCAAgC;AACtE,SAEEC,6BAA6B,QACxB,0CAAyC;AAEhD;;;;;;;;;;;CAWC,GACD,OAAO,eAAeC,gBAAgBC,GAAW;IAC/C,IAAI;QACF,6EAA6E;QAC7E,MAAMC,oBAAoB,MAAMC,4BAA4BF;QAC5D,IAAIC,mBAAmB;YACrB,OAAOA;QACT;QAEA,wEAAwE;QACxE,MAAME,iBAAiB,MAAMC,yBAAyBJ;QACtD,IAAIG,gBAAgB;YAClB,OAAOA;QACT;QAEA,qCAAqC;QACrC,MAAM,IAAIE,MAAM;IAClB,EAAE,OAAOC,KAAc;QACrB,MAAMC,UAAUD,eAAeD,QAAQC,IAAIC,OAAO,GAAG,GAAGD,KAAK;QAC7D,MAAM,IAAID,MAAM,CAAC,gDAAgD,EAAEE,SAAS;IAC9E;AACF;AAEA;;;;;;;;CAQC,GACD,eAAeL,4BACbM,QAAgB,EAChBC,aAAa,CAAC;IAEd,OAAOX,8BAA8BU,UAAUX,yBAAyB,UAAUY;AACpF;AAEA;;;;;;;CAOC,GACD,eAAeL,yBACbI,QAAgB,EAChBC,aAAa,CAAC;IAEd,OAAOX,8BAA8BU,UAAUZ,mBAAmB,OAAOa;AAC3E"}
1
+ {"version":3,"sources":["../../src/config/findProjectRoot.ts"],"sourcesContent":["import {ProjectRootNotFoundError} from '../errors/ProjectRootNotFoundError.js'\nimport {findAppConfigPath} from './util/findAppConfigPath.js'\nimport {tryFindStudioConfigPath} from './util/findStudioConfigPath.js'\nimport {\n type ProjectRootResult,\n recursivelyResolveProjectRoot,\n} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Resolve project root directory and type.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @internal\n */\nexport async function findProjectRoot(cwd: string): Promise<ProjectRootResult> {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = await resolveProjectRootForStudio(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = await resolveProjectRootForApp(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw a specific error\n throw new ProjectRootNotFoundError('No project root found')\n } catch (err: unknown) {\n if (err instanceof ProjectRootNotFoundError) {\n throw err\n }\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}`)\n }\n}\n\n/**\n * Recursively searches for a project configuration file in the given directory and its parents.\n * Throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns A promise that resolves to an object if config is found, false otherwise\n * @internal\n */\nasync function resolveProjectRootForStudio(\n basePath: string,\n iterations = 0,\n): Promise<false | ProjectRootResult> {\n return recursivelyResolveProjectRoot(basePath, tryFindStudioConfigPath, 'studio', iterations)\n}\n\n/**\n * Recursively searches for a app project configuration file in the given directory and its parents.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns A promise that resolves to an object if config is found, false otherwise\n * @internal\n */\nasync function resolveProjectRootForApp(\n basePath: string,\n iterations = 0,\n): Promise<false | ProjectRootResult> {\n return recursivelyResolveProjectRoot(basePath, findAppConfigPath, 'app', iterations)\n}\n"],"names":["ProjectRootNotFoundError","findAppConfigPath","tryFindStudioConfigPath","recursivelyResolveProjectRoot","findProjectRoot","cwd","studioProjectRoot","resolveProjectRootForStudio","appProjectRoot","resolveProjectRootForApp","err","message","Error","basePath","iterations"],"mappings":"AAAA,SAAQA,wBAAwB,QAAO,wCAAuC;AAC9E,SAAQC,iBAAiB,QAAO,8BAA6B;AAC7D,SAAQC,uBAAuB,QAAO,iCAAgC;AACtE,SAEEC,6BAA6B,QACxB,0CAAyC;AAEhD;;;;;;;;;;;CAWC,GACD,OAAO,eAAeC,gBAAgBC,GAAW;IAC/C,IAAI;QACF,6EAA6E;QAC7E,MAAMC,oBAAoB,MAAMC,4BAA4BF;QAC5D,IAAIC,mBAAmB;YACrB,OAAOA;QACT;QAEA,wEAAwE;QACxE,MAAME,iBAAiB,MAAMC,yBAAyBJ;QACtD,IAAIG,gBAAgB;YAClB,OAAOA;QACT;QAEA,6CAA6C;QAC7C,MAAM,IAAIR,yBAAyB;IACrC,EAAE,OAAOU,KAAc;QACrB,IAAIA,eAAeV,0BAA0B;YAC3C,MAAMU;QACR;QACA,MAAMC,UAAUD,eAAeE,QAAQF,IAAIC,OAAO,GAAG,GAAGD,KAAK;QAC7D,MAAM,IAAIE,MAAM,CAAC,gDAAgD,EAAED,SAAS;IAC9E;AACF;AAEA;;;;;;;;CAQC,GACD,eAAeJ,4BACbM,QAAgB,EAChBC,aAAa,CAAC;IAEd,OAAOX,8BAA8BU,UAAUX,yBAAyB,UAAUY;AACpF;AAEA;;;;;;;CAOC,GACD,eAAeL,yBACbI,QAAgB,EAChBC,aAAa,CAAC;IAEd,OAAOX,8BAA8BU,UAAUZ,mBAAmB,OAAOa;AAC3E"}
@@ -1,4 +1,5 @@
1
1
  import { dirname, resolve } from 'node:path';
2
+ import { ProjectRootNotFoundError } from '../errors/ProjectRootNotFoundError.js';
2
3
  import { findAppConfigPathSync, findStudioConfigPathSync } from './util/configPathsSync.js';
3
4
  /**
4
5
  * Generic recursive search function for project configuration files (synchronous version).
@@ -50,9 +51,12 @@ import { findAppConfigPathSync, findStudioConfigPathSync } from './util/configPa
50
51
  if (appProjectRoot) {
51
52
  return appProjectRoot;
52
53
  }
53
- // If nothing is found throw an error
54
- throw new Error(`No project root found in ${cwd}`);
54
+ // If nothing is found throw a specific error
55
+ throw new ProjectRootNotFoundError(`No project root found in ${cwd}`);
55
56
  } catch (err) {
57
+ if (err instanceof ProjectRootNotFoundError) {
58
+ throw err;
59
+ }
56
60
  const message = err instanceof Error ? err.message : `${err}`;
57
61
  throw new Error(`Error occurred trying to resolve project root:\n${message}`);
58
62
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/findProjectRootSync.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path'\n\nimport {findAppConfigPathSync, findStudioConfigPathSync} from './util/configPathsSync.js'\nimport {ProjectRootResult} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Generic recursive search function for project configuration files (synchronous version).\n *\n * @param basePath - The base path to start searching from\n * @param findConfigFn - Function that looks for config files in a given directory\n * @param projectType - The type of project ('app' | 'studio')\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion\n * @returns An object if config is found, false otherwise\n * @internal\n */\nexport function recursivelyResolveProjectRootSync(\n basePath: string,\n findConfigFn: (path: string) => string | undefined,\n projectType: 'app' | 'studio',\n iterations = 0,\n): false | ProjectRootResult {\n const configPath = findConfigFn(basePath)\n\n if (configPath) {\n return {\n directory: dirname(configPath),\n path: configPath,\n type: projectType,\n }\n }\n\n const parentDir = resolve(basePath, '..')\n if (parentDir === basePath || iterations > 50) {\n // Reached root (or max depth), give up\n return false\n }\n\n return recursivelyResolveProjectRootSync(parentDir, findConfigFn, projectType, iterations + 1)\n}\n\n/**\n * Resolve project root directory and type synchronously.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @param cwd - Current working directory to start searching from\n * @returns Project root result\n * @internal\n */\nexport function findProjectRootSync(cwd: string): ProjectRootResult {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = resolveProjectRootForStudioSync(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = resolveProjectRootForAppSync(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw an error\n throw new Error(`No project root found in ${cwd}`)\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}`)\n }\n}\n\n/**\n * Recursively searches for a project configuration file in the given directory and its parents.\n * Throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction resolveProjectRootForStudioSync(\n basePath: string,\n iterations = 0,\n): false | ProjectRootResult {\n return recursivelyResolveProjectRootSync(basePath, findStudioConfigPathSync, 'studio', iterations)\n}\n\n/**\n * Recursively searches for a app project configuration file in the given directory and its parents.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction resolveProjectRootForAppSync(basePath: string, iterations = 0): false | ProjectRootResult {\n return recursivelyResolveProjectRootSync(basePath, findAppConfigPathSync, 'app', iterations)\n}\n"],"names":["dirname","resolve","findAppConfigPathSync","findStudioConfigPathSync","recursivelyResolveProjectRootSync","basePath","findConfigFn","projectType","iterations","configPath","directory","path","type","parentDir","findProjectRootSync","cwd","studioProjectRoot","resolveProjectRootForStudioSync","appProjectRoot","resolveProjectRootForAppSync","Error","err","message"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAW;AAE1C,SAAQC,qBAAqB,EAAEC,wBAAwB,QAAO,4BAA2B;AAGzF;;;;;;;;;CASC,GACD,OAAO,SAASC,kCACdC,QAAgB,EAChBC,YAAkD,EAClDC,WAA6B,EAC7BC,aAAa,CAAC;IAEd,MAAMC,aAAaH,aAAaD;IAEhC,IAAII,YAAY;QACd,OAAO;YACLC,WAAWV,QAAQS;YACnBE,MAAMF;YACNG,MAAML;QACR;IACF;IAEA,MAAMM,YAAYZ,QAAQI,UAAU;IACpC,IAAIQ,cAAcR,YAAYG,aAAa,IAAI;QAC7C,uCAAuC;QACvC,OAAO;IACT;IAEA,OAAOJ,kCAAkCS,WAAWP,cAAcC,aAAaC,aAAa;AAC9F;AAEA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASM,oBAAoBC,GAAW;IAC7C,IAAI;QACF,6EAA6E;QAC7E,MAAMC,oBAAoBC,gCAAgCF;QAC1D,IAAIC,mBAAmB;YACrB,OAAOA;QACT;QAEA,wEAAwE;QACxE,MAAME,iBAAiBC,6BAA6BJ;QACpD,IAAIG,gBAAgB;YAClB,OAAOA;QACT;QAEA,qCAAqC;QACrC,MAAM,IAAIE,MAAM,CAAC,yBAAyB,EAAEL,KAAK;IACnD,EAAE,OAAOM,KAAc;QACrB,MAAMC,UAAUD,eAAeD,QAAQC,IAAIC,OAAO,GAAG,GAAGD,KAAK;QAC7D,MAAM,IAAID,MAAM,CAAC,gDAAgD,EAAEE,SAAS;IAC9E;AACF;AAEA;;;;;;;;CAQC,GACD,SAASL,gCACPZ,QAAgB,EAChBG,aAAa,CAAC;IAEd,OAAOJ,kCAAkCC,UAAUF,0BAA0B,UAAUK;AACzF;AAEA;;;;;;;CAOC,GACD,SAASW,6BAA6Bd,QAAgB,EAAEG,aAAa,CAAC;IACpE,OAAOJ,kCAAkCC,UAAUH,uBAAuB,OAAOM;AACnF"}
1
+ {"version":3,"sources":["../../src/config/findProjectRootSync.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path'\n\nimport {ProjectRootNotFoundError} from '../errors/ProjectRootNotFoundError.js'\nimport {findAppConfigPathSync, findStudioConfigPathSync} from './util/configPathsSync.js'\nimport {ProjectRootResult} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Generic recursive search function for project configuration files (synchronous version).\n *\n * @param basePath - The base path to start searching from\n * @param findConfigFn - Function that looks for config files in a given directory\n * @param projectType - The type of project ('app' | 'studio')\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion\n * @returns An object if config is found, false otherwise\n * @internal\n */\nexport function recursivelyResolveProjectRootSync(\n basePath: string,\n findConfigFn: (path: string) => string | undefined,\n projectType: 'app' | 'studio',\n iterations = 0,\n): false | ProjectRootResult {\n const configPath = findConfigFn(basePath)\n\n if (configPath) {\n return {\n directory: dirname(configPath),\n path: configPath,\n type: projectType,\n }\n }\n\n const parentDir = resolve(basePath, '..')\n if (parentDir === basePath || iterations > 50) {\n // Reached root (or max depth), give up\n return false\n }\n\n return recursivelyResolveProjectRootSync(parentDir, findConfigFn, projectType, iterations + 1)\n}\n\n/**\n * Resolve project root directory and type synchronously.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @param cwd - Current working directory to start searching from\n * @returns Project root result\n * @internal\n */\nexport function findProjectRootSync(cwd: string): ProjectRootResult {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = resolveProjectRootForStudioSync(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = resolveProjectRootForAppSync(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw a specific error\n throw new ProjectRootNotFoundError(`No project root found in ${cwd}`)\n } catch (err: unknown) {\n if (err instanceof ProjectRootNotFoundError) {\n throw err\n }\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}`)\n }\n}\n\n/**\n * Recursively searches for a project configuration file in the given directory and its parents.\n * Throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction resolveProjectRootForStudioSync(\n basePath: string,\n iterations = 0,\n): false | ProjectRootResult {\n return recursivelyResolveProjectRootSync(basePath, findStudioConfigPathSync, 'studio', iterations)\n}\n\n/**\n * Recursively searches for a app project configuration file in the given directory and its parents.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction resolveProjectRootForAppSync(basePath: string, iterations = 0): false | ProjectRootResult {\n return recursivelyResolveProjectRootSync(basePath, findAppConfigPathSync, 'app', iterations)\n}\n"],"names":["dirname","resolve","ProjectRootNotFoundError","findAppConfigPathSync","findStudioConfigPathSync","recursivelyResolveProjectRootSync","basePath","findConfigFn","projectType","iterations","configPath","directory","path","type","parentDir","findProjectRootSync","cwd","studioProjectRoot","resolveProjectRootForStudioSync","appProjectRoot","resolveProjectRootForAppSync","err","message","Error"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAW;AAE1C,SAAQC,wBAAwB,QAAO,wCAAuC;AAC9E,SAAQC,qBAAqB,EAAEC,wBAAwB,QAAO,4BAA2B;AAGzF;;;;;;;;;CASC,GACD,OAAO,SAASC,kCACdC,QAAgB,EAChBC,YAAkD,EAClDC,WAA6B,EAC7BC,aAAa,CAAC;IAEd,MAAMC,aAAaH,aAAaD;IAEhC,IAAII,YAAY;QACd,OAAO;YACLC,WAAWX,QAAQU;YACnBE,MAAMF;YACNG,MAAML;QACR;IACF;IAEA,MAAMM,YAAYb,QAAQK,UAAU;IACpC,IAAIQ,cAAcR,YAAYG,aAAa,IAAI;QAC7C,uCAAuC;QACvC,OAAO;IACT;IAEA,OAAOJ,kCAAkCS,WAAWP,cAAcC,aAAaC,aAAa;AAC9F;AAEA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASM,oBAAoBC,GAAW;IAC7C,IAAI;QACF,6EAA6E;QAC7E,MAAMC,oBAAoBC,gCAAgCF;QAC1D,IAAIC,mBAAmB;YACrB,OAAOA;QACT;QAEA,wEAAwE;QACxE,MAAME,iBAAiBC,6BAA6BJ;QACpD,IAAIG,gBAAgB;YAClB,OAAOA;QACT;QAEA,6CAA6C;QAC7C,MAAM,IAAIjB,yBAAyB,CAAC,yBAAyB,EAAEc,KAAK;IACtE,EAAE,OAAOK,KAAc;QACrB,IAAIA,eAAenB,0BAA0B;YAC3C,MAAMmB;QACR;QACA,MAAMC,UAAUD,eAAeE,QAAQF,IAAIC,OAAO,GAAG,GAAGD,KAAK;QAC7D,MAAM,IAAIE,MAAM,CAAC,gDAAgD,EAAED,SAAS;IAC9E;AACF;AAEA;;;;;;;;CAQC,GACD,SAASJ,gCACPZ,QAAgB,EAChBG,aAAa,CAAC;IAEd,OAAOJ,kCAAkCC,UAAUF,0BAA0B,UAAUK;AACzF;AAEA;;;;;;;CAOC,GACD,SAASW,6BAA6Bd,QAAgB,EAAEG,aAAa,CAAC;IACpE,OAAOJ,kCAAkCC,UAAUH,uBAAuB,OAAOM;AACnF"}
@@ -1,10 +1,16 @@
1
+ import { CLIError } from '@oclif/core/errors';
1
2
  /**
2
3
  * Error thrown when a prompt is attempted in a non-interactive environment
3
4
  * (e.g., CI, non-TTY, piped stdin). Callers can catch this specific error
4
5
  * to provide appropriate fallback behavior.
5
- */ export class NonInteractiveError extends Error {
6
+ *
7
+ * Extends `CLIError` to suppress stack traces in user-facing output.
8
+ */ export class NonInteractiveError extends CLIError {
6
9
  constructor(promptName){
7
- super(`Cannot run "${promptName}" prompt in a non-interactive environment. ` + 'Provide the required value via flags or environment variables, or run in an interactive terminal.');
10
+ super(`Cannot run "${promptName}" prompt in a non-interactive environment. ` + 'Provide the required value via flags or environment variables, or run in an interactive terminal.', {
11
+ code: 'NON_INTERACTIVE',
12
+ exit: 1
13
+ });
8
14
  this.name = 'NonInteractiveError';
9
15
  }
10
16
  }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/errors/NonInteractiveError.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\n\n/**\n * Error thrown when a prompt is attempted in a non-interactive environment\n * (e.g., CI, non-TTY, piped stdin). Callers can catch this specific error\n * to provide appropriate fallback behavior.\n *\n * Extends `CLIError` to suppress stack traces in user-facing output.\n */\nexport class NonInteractiveError extends CLIError {\n constructor(promptName: string) {\n super(\n `Cannot run \"${promptName}\" prompt in a non-interactive environment. ` +\n 'Provide the required value via flags or environment variables, or run in an interactive terminal.',\n {code: 'NON_INTERACTIVE', exit: 1},\n )\n this.name = 'NonInteractiveError'\n }\n}\n"],"names":["CLIError","NonInteractiveError","promptName","code","exit","name"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,qBAAoB;AAE3C;;;;;;CAMC,GACD,OAAO,MAAMC,4BAA4BD;IACvC,YAAYE,UAAkB,CAAE;QAC9B,KAAK,CACH,CAAC,YAAY,EAAEA,WAAW,2CAA2C,CAAC,GACpE,qGACF;YAACC,MAAM;YAAmBC,MAAM;QAAC;QAEnC,IAAI,CAACC,IAAI,GAAG;IACd;AACF"}
@@ -1,4 +1,4 @@
1
- import { isRecord } from './isRecord.js';
1
+ import { isRecord } from '../util/isRecord.js';
2
2
  /**
3
3
  * Error thrown when a file or directory is not found
4
4
  *
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/errors/NotFoundError.ts"],"sourcesContent":["import {isRecord} from '../util/isRecord.js'\n\n/**\n * Error thrown when a file or directory is not found\n *\n * `code` is always `ENOENT` to mirror Node.js behavior when a file is not found\n *\n * @internal\n */\nexport class NotFoundError extends Error {\n code = 'ENOENT'\n path?: string\n\n constructor(message: string, path?: string) {\n super(message)\n this.path = path\n this.name = 'NotFoundError'\n }\n}\n\n/**\n * Returns whether or not the given error is a `NotFoundError`\n *\n * @param err - The error to check\n * @returns `true` if the error is a `NotFoundError`, `false` otherwise\n * @internal\n */\nexport function isNotFoundError(err: unknown): err is NotFoundError {\n return (\n isRecord(err) &&\n 'name' in err &&\n err.name === 'NotFoundError' &&\n 'code' in err &&\n err.code === 'ENOENT' &&\n 'message' in err &&\n typeof err.message === 'string'\n )\n}\n"],"names":["isRecord","NotFoundError","Error","code","path","message","name","isNotFoundError","err"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,sBAAqB;AAE5C;;;;;;CAMC,GACD,OAAO,MAAMC,sBAAsBC;IACjCC,OAAO,SAAQ;IACfC,KAAa;IAEb,YAAYC,OAAe,EAAED,IAAa,CAAE;QAC1C,KAAK,CAACC;QACN,IAAI,CAACD,IAAI,GAAGA;QACZ,IAAI,CAACE,IAAI,GAAG;IACd;AACF;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,gBAAgBC,GAAY;IAC1C,OACER,SAASQ,QACT,UAAUA,OACVA,IAAIF,IAAI,KAAK,mBACb,UAAUE,OACVA,IAAIL,IAAI,KAAK,YACb,aAAaK,OACb,OAAOA,IAAIH,OAAO,KAAK;AAE3B"}
@@ -0,0 +1,35 @@
1
+ import { CLIError } from '@oclif/core/errors';
2
+ import { isRecord } from '../util/isRecord.js';
3
+ /**
4
+ * Error thrown when a project root directory cannot be found.
5
+ *
6
+ * This occurs when the CLI is run outside a Sanity project directory
7
+ * (one containing `sanity.config.(ts|js)` or `sanity.cli.(ts|js)`).
8
+ *
9
+ * Extends `CLIError` to suppress stack traces in user-facing output.
10
+ *
11
+ * @internal
12
+ */ export class ProjectRootNotFoundError extends CLIError {
13
+ constructor(message, options){
14
+ super(message, {
15
+ code: 'PROJECT_ROOT_NOT_FOUND',
16
+ exit: 1,
17
+ suggestions: options?.suggestions
18
+ });
19
+ this.name = 'ProjectRootNotFoundError';
20
+ if (options?.cause) {
21
+ this.cause = options.cause;
22
+ }
23
+ }
24
+ }
25
+ /**
26
+ * Returns whether or not the given error is a `ProjectRootNotFoundError`
27
+ *
28
+ * @param err - The error to check
29
+ * @returns `true` if the error is a `ProjectRootNotFoundError`, `false` otherwise
30
+ * @internal
31
+ */ export function isProjectRootNotFoundError(err) {
32
+ return isRecord(err) && 'name' in err && err.name === 'ProjectRootNotFoundError' && 'code' in err && err.code === 'PROJECT_ROOT_NOT_FOUND' && 'message' in err && typeof err.message === 'string';
33
+ }
34
+
35
+ //# sourceMappingURL=ProjectRootNotFoundError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/errors/ProjectRootNotFoundError.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\n\nimport {isRecord} from '../util/isRecord.js'\n\n/**\n * Error thrown when a project root directory cannot be found.\n *\n * This occurs when the CLI is run outside a Sanity project directory\n * (one containing `sanity.config.(ts|js)` or `sanity.cli.(ts|js)`).\n *\n * Extends `CLIError` to suppress stack traces in user-facing output.\n *\n * @internal\n */\nexport class ProjectRootNotFoundError extends CLIError {\n constructor(message: string, options?: {cause?: Error; suggestions?: string[]}) {\n super(message, {code: 'PROJECT_ROOT_NOT_FOUND', exit: 1, suggestions: options?.suggestions})\n this.name = 'ProjectRootNotFoundError'\n if (options?.cause) {\n this.cause = options.cause\n }\n }\n}\n\n/**\n * Returns whether or not the given error is a `ProjectRootNotFoundError`\n *\n * @param err - The error to check\n * @returns `true` if the error is a `ProjectRootNotFoundError`, `false` otherwise\n * @internal\n */\nexport function isProjectRootNotFoundError(err: unknown): err is ProjectRootNotFoundError {\n return (\n isRecord(err) &&\n 'name' in err &&\n err.name === 'ProjectRootNotFoundError' &&\n 'code' in err &&\n err.code === 'PROJECT_ROOT_NOT_FOUND' &&\n 'message' in err &&\n typeof err.message === 'string'\n )\n}\n"],"names":["CLIError","isRecord","ProjectRootNotFoundError","message","options","code","exit","suggestions","name","cause","isProjectRootNotFoundError","err"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,qBAAoB;AAE3C,SAAQC,QAAQ,QAAO,sBAAqB;AAE5C;;;;;;;;;CASC,GACD,OAAO,MAAMC,iCAAiCF;IAC5C,YAAYG,OAAe,EAAEC,OAAiD,CAAE;QAC9E,KAAK,CAACD,SAAS;YAACE,MAAM;YAA0BC,MAAM;YAAGC,aAAaH,SAASG;QAAW;QAC1F,IAAI,CAACC,IAAI,GAAG;QACZ,IAAIJ,SAASK,OAAO;YAClB,IAAI,CAACA,KAAK,GAAGL,QAAQK,KAAK;QAC5B;IACF;AACF;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,2BAA2BC,GAAY;IACrD,OACEV,SAASU,QACT,UAAUA,OACVA,IAAIH,IAAI,KAAK,8BACb,UAAUG,OACVA,IAAIN,IAAI,KAAK,4BACb,aAAaM,OACb,OAAOA,IAAIR,OAAO,KAAK;AAE3B"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import {ClientConfig} from '@sanity/client'
2
+ import {CLIError} from '@oclif/core/errors'
2
3
  import {Command} from '@oclif/core'
3
4
  import {ConfigEnv} from 'vite'
4
5
  import ConfigStore from 'configstore'
@@ -103,6 +104,10 @@ export declare interface CliConfig {
103
104
  * Configuration for schema extraction (`sanity schema extract`)
104
105
  */
105
106
  schemaExtraction?: {
107
+ /**
108
+ * Enable schema extraction as part of sanity dev and sanity build
109
+ */
110
+ enabled?: boolean
106
111
  /**
107
112
  * When true, schema fields marked as required will be non-optional in the output.
108
113
  * Defaults to `false`
@@ -136,7 +141,14 @@ export declare interface CliConfig {
136
141
  /**
137
142
  * Configuration for Sanity typegen
138
143
  */
139
- typegen?: Partial<TypeGenConfig>
144
+ typegen?: Partial<TypeGenConfig> & {
145
+ /**
146
+ * Enable typegen as part of sanity dev and sanity build.
147
+ * When enabled, types are generated on startup and when files change.
148
+ * Defaults to `false`
149
+ */
150
+ enabled?: boolean
151
+ }
140
152
  /** Exposes the default Vite configuration for custom apps and the Studio so it can be changed and extended. */
141
153
  vite?: UserViteConfig
142
154
  }
@@ -438,12 +450,13 @@ export declare function formatObject(obj: unknown): string
438
450
  /**
439
451
  * Get the CLI config for a project, given the root path.
440
452
  *
441
- * We really want to avoid loading the CLI config in the main thread, as we'll need
442
- * TypeScript loading logic, potentially with ts path aliases, syntax extensions and all
443
- * sorts of nonsense. Thus, we _attempt_ to use a worker thread - but have to fall back
444
- * to using the main thread if not possible. This can be the case if the configuration
445
- * contains non-serializable properties, such as functions. This is unfortunately used
446
- * by the vite config, for example.
453
+ * Results are cached in-memory keyed by rootPath for the lifetime of the
454
+ * process. Since the CLI always runs from a single project root, the config
455
+ * won't change during a command's execution, so caching avoids redundant
456
+ * filesystem reads and jiti imports from the prerun hook, SanityCommand
457
+ * helpers, and action files.
458
+ *
459
+ * If loading fails the cached promise is evicted so the next call retries.
447
460
  *
448
461
  * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.
449
462
  * @returns The CLI config
@@ -646,6 +659,24 @@ export declare const isCi: () => boolean
646
659
 
647
660
  export declare function isInteractive(): boolean
648
661
 
662
+ /**
663
+ * Returns whether or not the given error is a `NotFoundError`
664
+ *
665
+ * @param err - The error to check
666
+ * @returns `true` if the error is a `NotFoundError`, `false` otherwise
667
+ * @internal
668
+ */
669
+ export declare function isNotFoundError(err: unknown): err is NotFoundError
670
+
671
+ /**
672
+ * Returns whether or not the given error is a `ProjectRootNotFoundError`
673
+ *
674
+ * @param err - The error to check
675
+ * @returns `true` if the error is a `ProjectRootNotFoundError`, `false` otherwise
676
+ * @internal
677
+ */
678
+ export declare function isProjectRootNotFoundError(err: unknown): err is ProjectRootNotFoundError
679
+
649
680
  /**
650
681
  * Checks if the given value is a record (javascript objectish)
651
682
  *
@@ -687,8 +718,10 @@ export declare function mockBrowserEnvironment(basePath: string): Promise<() =>
687
718
  * Error thrown when a prompt is attempted in a non-interactive environment
688
719
  * (e.g., CI, non-TTY, piped stdin). Callers can catch this specific error
689
720
  * to provide appropriate fallback behavior.
721
+ *
722
+ * Extends `CLIError` to suppress stack traces in user-facing output.
690
723
  */
691
- export declare class NonInteractiveError extends Error {
724
+ export declare class NonInteractiveError extends CLIError {
692
725
  constructor(promptName: string)
693
726
  }
694
727
 
@@ -702,6 +735,19 @@ export declare class NonInteractiveError extends Error {
702
735
  */
703
736
  export declare function normalizePath(path: string): string
704
737
 
738
+ /**
739
+ * Error thrown when a file or directory is not found
740
+ *
741
+ * `code` is always `ENOENT` to mirror Node.js behavior when a file is not found
742
+ *
743
+ * @internal
744
+ */
745
+ export declare class NotFoundError extends Error {
746
+ code: string
747
+ path?: string
748
+ constructor(message: string, path?: string)
749
+ }
750
+
705
751
  export declare interface Output {
706
752
  error: Command['error']
707
753
  log: Command['log']
@@ -800,6 +846,26 @@ export declare interface ProjectCliClientOptions extends ClientConfig {
800
846
  requireUser?: boolean
801
847
  }
802
848
 
849
+ /**
850
+ * Error thrown when a project root directory cannot be found.
851
+ *
852
+ * This occurs when the CLI is run outside a Sanity project directory
853
+ * (one containing `sanity.config.(ts|js)` or `sanity.cli.(ts|js)`).
854
+ *
855
+ * Extends `CLIError` to suppress stack traces in user-facing output.
856
+ *
857
+ * @internal
858
+ */
859
+ export declare class ProjectRootNotFoundError extends CLIError {
860
+ constructor(
861
+ message: string,
862
+ options?: {
863
+ cause?: Error
864
+ suggestions?: string[]
865
+ },
866
+ )
867
+ }
868
+
803
869
  /**
804
870
  * Result of finding a project configuration
805
871
  *
@@ -1114,11 +1180,18 @@ export declare abstract class SanityCommand<T extends typeof Command> extends Co
1114
1180
  */
1115
1181
  protected getCliConfig(): Promise<CliConfig>
1116
1182
  /**
1117
- * Get the project ID from the CLI config.
1183
+ * Get the project ID from passed flags or (if not provided) the CLI config.
1184
+ *
1185
+ * Optionally accepts a `fallback` function that is called when no project ID
1186
+ * can be determined from flags or config. This allows commands to provide
1187
+ * interactive project selection while keeping the prompt logic in the CLI package.
1188
+ *
1189
+ * If the fallback throws a `NonInteractiveError` (e.g. because the terminal is
1190
+ * not interactive), it falls through to the standard error with suggestions.
1118
1191
  *
1119
- * @returns The project ID or `undefined` if it's not set.
1192
+ * @returns The project ID.
1120
1193
  */
1121
- protected getProjectId(): Promise<string | undefined>
1194
+ protected getProjectId(options?: {fallback?: () => Promise<string>}): Promise<string>
1122
1195
  /**
1123
1196
  * Get the project's root directory by resolving the config
1124
1197
  *
package/dist/index.js CHANGED
@@ -7,6 +7,9 @@ export * from './config/studio/getStudioWorkspaces.js';
7
7
  export * from './config/util/findConfigsPaths.js';
8
8
  export * from './config/util/findStudioConfigPath.js';
9
9
  export * from './debug.js';
10
+ export * from './errors/NonInteractiveError.js';
11
+ export * from './errors/NotFoundError.js';
12
+ export * from './errors/ProjectRootNotFoundError.js';
10
13
  export * from './loaders/studio/studioWorkerTask.js';
11
14
  export * from './loaders/tsx/tsxWorkerTask.js';
12
15
  export * from './SanityCommand.js';
@@ -32,7 +35,6 @@ export * from './util/isInteractive.js';
32
35
  export * from './util/isRecord.js';
33
36
  export * from './util/isStaging.js';
34
37
  export * from './util/isTrueish.js';
35
- export * from './util/NonInteractiveError.js';
36
38
  export * from './util/normalizePath.js';
37
39
  export * from './util/parseStringFlag.js';
38
40
  export * from './util/promisifyWorker.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './config/cli/getCliConfig.js'\nexport * from './config/cli/getCliConfigSync.js'\nexport {type CliConfig} from './config/cli/types/cliConfig.js'\nexport {type UserViteConfig} from './config/cli/types/userViteConfig.js'\nexport * from './config/findProjectRoot.js'\nexport * from './config/findProjectRootSync.js'\nexport * from './config/studio/getStudioConfig.js'\nexport * from './config/studio/getStudioWorkspaces.js'\nexport * from './config/util/findConfigsPaths.js'\nexport * from './config/util/findStudioConfigPath.js'\nexport {type ProjectRootResult} from './config/util/recursivelyResolveProjectRoot.js'\nexport * from './debug.js'\nexport * from './loaders/studio/studioWorkerTask.js'\nexport * from './loaders/tsx/tsxWorkerTask.js'\nexport * from './SanityCommand.js'\nexport * from './services/apiClient.js'\nexport * from './services/cliUserConfig.js'\nexport * from './services/getCliToken.js'\nexport * from './telemetry/createTelemetryStore.js'\nexport * from './telemetry/flushTelemetryFiles.js'\nexport * from './telemetry/getTelemetryBaseInfo.js'\nexport * from './telemetry/telemetryStoreDebug.js'\nexport {\n type CLITelemetryStore,\n type ConsentInformation,\n type TelemetryUserProperties,\n} from './telemetry/types.js'\nexport {type Output, type SanityOrgUser} from './types.js'\nexport * from './util/createExpiringConfig.js'\nexport {doImport} from './util/doImport.js'\nexport * from './util/environment/mockBrowserEnvironment.js'\nexport * from './util/fileExists.js'\nexport {\n clearCliTelemetry,\n CLI_TELEMETRY_SYMBOL,\n getCliTelemetry,\n setCliTelemetry,\n} from './util/getCliTelemetry.js'\nexport * from './util/getEmptyAuth.js'\nexport * from './util/getSanityEnvVar.js'\nexport * from './util/getSanityUrl.js'\nexport * from './util/getUserConfig.js'\nexport * from './util/importModule.js'\nexport * from './util/isCi.js'\nexport * from './util/isInteractive.js'\nexport * from './util/isRecord.js'\nexport * from './util/isStaging.js'\nexport * from './util/isTrueish.js'\nexport * from './util/NonInteractiveError.js'\nexport * from './util/normalizePath.js'\nexport * from './util/parseStringFlag.js'\nexport * from './util/promisifyWorker.js'\nexport * from './util/readNDJSON.js'\nexport * from './util/readPackageJson.js'\nexport * from './util/resolveLocalPackage.js'\nexport * from './util/safeStructuredClone.js'\nexport * from './util/tryGetDefaultExport.js'\nexport * from './util/waitForAsync.js'\nexport * from './ux/colorizeJson.js'\nexport * from './ux/formatObject.js'\nexport * from './ux/printKeyValue.js'\nexport * from './ux/timer.js'\n"],"names":["doImport","clearCliTelemetry","CLI_TELEMETRY_SYMBOL","getCliTelemetry","setCliTelemetry"],"mappings":"AAAA,cAAc,+BAA8B;AAC5C,cAAc,mCAAkC;AAGhD,cAAc,8BAA6B;AAC3C,cAAc,kCAAiC;AAC/C,cAAc,qCAAoC;AAClD,cAAc,yCAAwC;AACtD,cAAc,oCAAmC;AACjD,cAAc,wCAAuC;AAErD,cAAc,aAAY;AAC1B,cAAc,uCAAsC;AACpD,cAAc,iCAAgC;AAC9C,cAAc,qBAAoB;AAClC,cAAc,0BAAyB;AACvC,cAAc,8BAA6B;AAC3C,cAAc,4BAA2B;AACzC,cAAc,sCAAqC;AACnD,cAAc,qCAAoC;AAClD,cAAc,sCAAqC;AACnD,cAAc,qCAAoC;AAOlD,cAAc,iCAAgC;AAC9C,SAAQA,QAAQ,QAAO,qBAAoB;AAC3C,cAAc,+CAA8C;AAC5D,cAAc,uBAAsB;AACpC,SACEC,iBAAiB,EACjBC,oBAAoB,EACpBC,eAAe,EACfC,eAAe,QACV,4BAA2B;AAClC,cAAc,yBAAwB;AACtC,cAAc,4BAA2B;AACzC,cAAc,yBAAwB;AACtC,cAAc,0BAAyB;AACvC,cAAc,yBAAwB;AACtC,cAAc,iBAAgB;AAC9B,cAAc,0BAAyB;AACvC,cAAc,qBAAoB;AAClC,cAAc,sBAAqB;AACnC,cAAc,sBAAqB;AACnC,cAAc,gCAA+B;AAC7C,cAAc,0BAAyB;AACvC,cAAc,4BAA2B;AACzC,cAAc,4BAA2B;AACzC,cAAc,uBAAsB;AACpC,cAAc,4BAA2B;AACzC,cAAc,gCAA+B;AAC7C,cAAc,gCAA+B;AAC7C,cAAc,gCAA+B;AAC7C,cAAc,yBAAwB;AACtC,cAAc,uBAAsB;AACpC,cAAc,uBAAsB;AACpC,cAAc,wBAAuB;AACrC,cAAc,gBAAe"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './config/cli/getCliConfig.js'\nexport * from './config/cli/getCliConfigSync.js'\nexport {type CliConfig} from './config/cli/types/cliConfig.js'\nexport {type UserViteConfig} from './config/cli/types/userViteConfig.js'\nexport * from './config/findProjectRoot.js'\nexport * from './config/findProjectRootSync.js'\nexport * from './config/studio/getStudioConfig.js'\nexport * from './config/studio/getStudioWorkspaces.js'\nexport * from './config/util/findConfigsPaths.js'\nexport * from './config/util/findStudioConfigPath.js'\nexport {type ProjectRootResult} from './config/util/recursivelyResolveProjectRoot.js'\nexport * from './debug.js'\nexport * from './errors/NonInteractiveError.js'\nexport * from './errors/NotFoundError.js'\nexport * from './errors/ProjectRootNotFoundError.js'\nexport * from './loaders/studio/studioWorkerTask.js'\nexport * from './loaders/tsx/tsxWorkerTask.js'\nexport * from './SanityCommand.js'\nexport * from './services/apiClient.js'\nexport * from './services/cliUserConfig.js'\nexport * from './services/getCliToken.js'\nexport * from './telemetry/createTelemetryStore.js'\nexport * from './telemetry/flushTelemetryFiles.js'\nexport * from './telemetry/getTelemetryBaseInfo.js'\nexport * from './telemetry/telemetryStoreDebug.js'\nexport {\n type CLITelemetryStore,\n type ConsentInformation,\n type TelemetryUserProperties,\n} from './telemetry/types.js'\nexport {type Output, type SanityOrgUser} from './types.js'\nexport * from './util/createExpiringConfig.js'\nexport {doImport} from './util/doImport.js'\nexport * from './util/environment/mockBrowserEnvironment.js'\nexport * from './util/fileExists.js'\nexport {\n clearCliTelemetry,\n CLI_TELEMETRY_SYMBOL,\n getCliTelemetry,\n setCliTelemetry,\n} from './util/getCliTelemetry.js'\nexport * from './util/getEmptyAuth.js'\nexport * from './util/getSanityEnvVar.js'\nexport * from './util/getSanityUrl.js'\nexport * from './util/getUserConfig.js'\nexport * from './util/importModule.js'\nexport * from './util/isCi.js'\nexport * from './util/isInteractive.js'\nexport * from './util/isRecord.js'\nexport * from './util/isStaging.js'\nexport * from './util/isTrueish.js'\nexport * from './util/normalizePath.js'\nexport * from './util/parseStringFlag.js'\nexport * from './util/promisifyWorker.js'\nexport * from './util/readNDJSON.js'\nexport * from './util/readPackageJson.js'\nexport * from './util/resolveLocalPackage.js'\nexport * from './util/safeStructuredClone.js'\nexport * from './util/tryGetDefaultExport.js'\nexport * from './util/waitForAsync.js'\nexport * from './ux/colorizeJson.js'\nexport * from './ux/formatObject.js'\nexport * from './ux/printKeyValue.js'\nexport * from './ux/timer.js'\n"],"names":["doImport","clearCliTelemetry","CLI_TELEMETRY_SYMBOL","getCliTelemetry","setCliTelemetry"],"mappings":"AAAA,cAAc,+BAA8B;AAC5C,cAAc,mCAAkC;AAGhD,cAAc,8BAA6B;AAC3C,cAAc,kCAAiC;AAC/C,cAAc,qCAAoC;AAClD,cAAc,yCAAwC;AACtD,cAAc,oCAAmC;AACjD,cAAc,wCAAuC;AAErD,cAAc,aAAY;AAC1B,cAAc,kCAAiC;AAC/C,cAAc,4BAA2B;AACzC,cAAc,uCAAsC;AACpD,cAAc,uCAAsC;AACpD,cAAc,iCAAgC;AAC9C,cAAc,qBAAoB;AAClC,cAAc,0BAAyB;AACvC,cAAc,8BAA6B;AAC3C,cAAc,4BAA2B;AACzC,cAAc,sCAAqC;AACnD,cAAc,qCAAoC;AAClD,cAAc,sCAAqC;AACnD,cAAc,qCAAoC;AAOlD,cAAc,iCAAgC;AAC9C,SAAQA,QAAQ,QAAO,qBAAoB;AAC3C,cAAc,+CAA8C;AAC5D,cAAc,uBAAsB;AACpC,SACEC,iBAAiB,EACjBC,oBAAoB,EACpBC,eAAe,EACfC,eAAe,QACV,4BAA2B;AAClC,cAAc,yBAAwB;AACtC,cAAc,4BAA2B;AACzC,cAAc,yBAAwB;AACtC,cAAc,0BAAyB;AACvC,cAAc,yBAAwB;AACtC,cAAc,iBAAgB;AAC9B,cAAc,0BAAyB;AACvC,cAAc,qBAAoB;AAClC,cAAc,sBAAqB;AACnC,cAAc,sBAAqB;AACnC,cAAc,0BAAyB;AACvC,cAAc,4BAA2B;AACzC,cAAc,4BAA2B;AACzC,cAAc,uBAAsB;AACpC,cAAc,4BAA2B;AACzC,cAAc,gCAA+B;AAC7C,cAAc,gCAA+B;AAC7C,cAAc,gCAA+B;AAC7C,cAAc,yBAAwB;AACtC,cAAc,uBAAsB;AACpC,cAAc,uBAAsB;AACpC,cAAc,wBAAuB;AACrC,cAAc,gBAAe"}
@@ -5,10 +5,10 @@ import { ViteNodeServer } from 'vite-node/server';
5
5
  import { installSourcemapsSupport } from 'vite-node/source-map';
6
6
  import { getCliConfig } from '../../config/cli/getCliConfig.js';
7
7
  import { subdebug } from '../../debug.js';
8
+ import { isNotFoundError } from '../../errors/NotFoundError.js';
8
9
  import { getStudioEnvironmentVariables } from '../../util/environment/getStudioEnvironmentVariables.js';
9
10
  import { setupBrowserStubs } from '../../util/environment/setupBrowserStubs.js';
10
11
  import { isRecord } from '../../util/isRecord.js';
11
- import { isNotFoundError } from '../../util/NotFoundError.js';
12
12
  if (isMainThread) {
13
13
  throw new Error('Should be child of thread, not the main thread');
14
14
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/loaders/studio/studioWorkerLoader.worker.ts"],"sourcesContent":["import {isMainThread} from 'node:worker_threads'\n\nimport {createServer, type InlineConfig, loadEnv, mergeConfig} from 'vite'\nimport {ViteNodeRunner} from 'vite-node/client'\nimport {ViteNodeServer} from 'vite-node/server'\nimport {installSourcemapsSupport} from 'vite-node/source-map'\n\nimport {getCliConfig} from '../../config/cli/getCliConfig.js'\nimport {type CliConfig} from '../../config/cli/types/cliConfig.js'\nimport {subdebug} from '../../debug.js'\nimport {getStudioEnvironmentVariables} from '../../util/environment/getStudioEnvironmentVariables.js'\nimport {setupBrowserStubs} from '../../util/environment/setupBrowserStubs.js'\nimport {isRecord} from '../../util/isRecord.js'\nimport {isNotFoundError} from '../../util/NotFoundError.js'\n\nif (isMainThread) {\n throw new Error('Should be child of thread, not the main thread')\n}\n\nconst rootPath = process.env.STUDIO_WORKER_STUDIO_ROOT_PATH\nif (!rootPath) {\n throw new Error('Missing `STUDIO_WORKER_STUDIO_ROOT_PATH` environment variable')\n}\n\nconst debug = subdebug('studio:worker')\n\nconst workerScriptPath = process.env.STUDIO_WORKER_TASK_FILE\nif (!workerScriptPath) {\n throw new Error('Missing `STUDIO_WORKER_TASK_FILE` environment variable')\n}\n\nawait setupBrowserStubs()\n\nconst studioEnvVars = await getStudioEnvironmentVariables(rootPath)\n\n// Allow the CLI config (`sanity.cli.(js|ts)`) to define a `vite` property which can\n// extend/modify the default vite configuration for the studio.\nlet cliConfig: CliConfig | undefined\ntry {\n cliConfig = await getCliConfig(rootPath)\n} catch (err) {\n debug('Failed to load CLI config: %o', err)\n if (!isNotFoundError(err)) {\n // eslint-disable-next-line no-console\n console.warn('[warn] Failed to load CLI config:', err)\n }\n}\n\n/**\n * Fetches and caches modules from HTTP/HTTPS URLs.\n * Vite's SSR transform treats `https://` imports as external and bypasses the plugin\n * resolve pipeline entirely, so we intercept them at the ViteNodeRunner level instead.\n */\nconst httpModuleCache = new Map<string, string>()\nasync function fetchHttpModule(url: string): Promise<{code: string}> {\n const cached = httpModuleCache.get(url)\n if (cached) return {code: cached}\n\n debug('Fetching HTTP import: %s', url)\n const response = await fetch(url, {signal: AbortSignal.timeout(30_000)})\n if (!response.ok) {\n throw new Error(`Failed to fetch module from ${url}: ${response.status} ${response.statusText}`)\n }\n\n const code = await response.text()\n httpModuleCache.set(url, code)\n return {code}\n}\n\nfunction isHttpsUrl(id: string): boolean {\n return id.startsWith('https://')\n}\n\nconst defaultViteConfig: InlineConfig = {\n build: {target: 'node'},\n configFile: false,\n // Inject environment variables as compile-time constants for Vite\n define: Object.fromEntries(\n Object.entries(studioEnvVars).map(([key, value]) => [\n `process.env.${key}`,\n JSON.stringify(value),\n ]),\n ),\n envPrefix: cliConfig && 'app' in cliConfig ? 'SANITY_APP_' : 'SANITY_STUDIO_',\n esbuild: {\n jsx: 'automatic',\n },\n logLevel: 'error',\n optimizeDeps: {\n include: undefined,\n noDiscovery: true,\n },\n root: rootPath,\n server: {\n hmr: false,\n watch: null,\n },\n ssr: {\n /**\n * We don't want to externalize any dependencies, we want everything to run thru vite.\n * Especially for CJS compatibility, etc.\n */\n noExternal: true,\n },\n}\n\n// Merge the CLI config's Vite config with the default Vite config\nlet viteConfig = defaultViteConfig\nif (typeof cliConfig?.vite === 'function') {\n viteConfig = (await cliConfig.vite(viteConfig, {\n command: 'build',\n isSsrBuild: true,\n mode: 'production',\n })) as InlineConfig\n} else if (isRecord(cliConfig?.vite)) {\n viteConfig = mergeConfig(viteConfig, cliConfig.vite)\n}\n\ndebug('Creating Vite server with config: %o', viteConfig)\n// Vite will build the files we give it - targetting Node.js instead of the browser.\n// We include the inject plugin in order to provide the stubs for the undefined global APIs.\nconst server = await createServer(viteConfig)\n\n// Bit of a hack, but seems necessary based on the `node-vite` binary implementation\nawait server.pluginContainer.buildStart({})\n\n// Load environment variables from `.env` files in the same way as Vite does.\n// Note that Sanity also provides environment variables through `process.env.*` for compat reasons,\n// and so we need to do the same here.\nconst env = loadEnv(server.config.mode, server.config.envDir, viteConfig.envPrefix ?? '')\nfor (const key in env) {\n process.env[key] ??= env[key]\n}\n\n// Now we're providing the glue that ensures node-specific loading and execution works.\nconst node = new ViteNodeServer(server)\n\n// Should make it easier to debug any crashes in the imported code…\ninstallSourcemapsSupport({\n getSourceMap: (source) => node.getSourceMap(source),\n})\n\nconst runner = new ViteNodeRunner({\n base: server.config.base,\n async fetchModule(id) {\n // Vite's SSR transform externalizes https:// imports, so Node's ESM loader\n // would reject them. We fetch the module over HTTP and run it through Vite's\n // SSR transform to rewrite ESM export/import syntax to the __vite_ssr_*\n // format that ViteNodeRunner expects.\n if (isHttpsUrl(id)) {\n const {code: rawCode} = await fetchHttpModule(id)\n const result = await server.ssrTransform(rawCode, null, id)\n return {code: result?.code || rawCode}\n }\n return node.fetchModule(id)\n },\n resolveId(id, importer) {\n // Prevent vite-node from trying to resolve HTTP URLs through Node's resolver\n if (isHttpsUrl(id)) return {id}\n // Resolve any import from an HTTP-fetched module against the remote origin\n // (e.g. esm.sh returns `export * from '/pkg@1.0/es2022/pkg.mjs'`)\n if (importer && isHttpsUrl(importer)) {\n return {id: new URL(id, importer).href}\n }\n return node.resolveId(id, importer)\n },\n root: server.config.root,\n})\n\n// Copied from `vite-node` - it appears that this applies the `define` config from\n// vite, but it also takes a surprisingly long time to execute. Not clear at this\n// point why this is, so we should investigate whether it's necessary or not.\nawait runner.executeId('/@vite/env')\n\nawait runner.executeId(workerScriptPath)\n"],"names":["isMainThread","createServer","loadEnv","mergeConfig","ViteNodeRunner","ViteNodeServer","installSourcemapsSupport","getCliConfig","subdebug","getStudioEnvironmentVariables","setupBrowserStubs","isRecord","isNotFoundError","Error","rootPath","process","env","STUDIO_WORKER_STUDIO_ROOT_PATH","debug","workerScriptPath","STUDIO_WORKER_TASK_FILE","studioEnvVars","cliConfig","err","console","warn","httpModuleCache","Map","fetchHttpModule","url","cached","get","code","response","fetch","signal","AbortSignal","timeout","ok","status","statusText","text","set","isHttpsUrl","id","startsWith","defaultViteConfig","build","target","configFile","define","Object","fromEntries","entries","map","key","value","JSON","stringify","envPrefix","esbuild","jsx","logLevel","optimizeDeps","include","undefined","noDiscovery","root","server","hmr","watch","ssr","noExternal","viteConfig","vite","command","isSsrBuild","mode","pluginContainer","buildStart","config","envDir","node","getSourceMap","source","runner","base","fetchModule","rawCode","result","ssrTransform","resolveId","importer","URL","href","executeId"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/loaders/studio/studioWorkerLoader.worker.ts"],"sourcesContent":["import {isMainThread} from 'node:worker_threads'\n\nimport {createServer, type InlineConfig, loadEnv, mergeConfig} from 'vite'\nimport {ViteNodeRunner} from 'vite-node/client'\nimport {ViteNodeServer} from 'vite-node/server'\nimport {installSourcemapsSupport} from 'vite-node/source-map'\n\nimport {getCliConfig} from '../../config/cli/getCliConfig.js'\nimport {type CliConfig} from '../../config/cli/types/cliConfig.js'\nimport {subdebug} from '../../debug.js'\nimport {isNotFoundError} from '../../errors/NotFoundError.js'\nimport {getStudioEnvironmentVariables} from '../../util/environment/getStudioEnvironmentVariables.js'\nimport {setupBrowserStubs} from '../../util/environment/setupBrowserStubs.js'\nimport {isRecord} from '../../util/isRecord.js'\n\nif (isMainThread) {\n throw new Error('Should be child of thread, not the main thread')\n}\n\nconst rootPath = process.env.STUDIO_WORKER_STUDIO_ROOT_PATH\nif (!rootPath) {\n throw new Error('Missing `STUDIO_WORKER_STUDIO_ROOT_PATH` environment variable')\n}\n\nconst debug = subdebug('studio:worker')\n\nconst workerScriptPath = process.env.STUDIO_WORKER_TASK_FILE\nif (!workerScriptPath) {\n throw new Error('Missing `STUDIO_WORKER_TASK_FILE` environment variable')\n}\n\nawait setupBrowserStubs()\n\nconst studioEnvVars = await getStudioEnvironmentVariables(rootPath)\n\n// Allow the CLI config (`sanity.cli.(js|ts)`) to define a `vite` property which can\n// extend/modify the default vite configuration for the studio.\nlet cliConfig: CliConfig | undefined\ntry {\n cliConfig = await getCliConfig(rootPath)\n} catch (err) {\n debug('Failed to load CLI config: %o', err)\n if (!isNotFoundError(err)) {\n // eslint-disable-next-line no-console\n console.warn('[warn] Failed to load CLI config:', err)\n }\n}\n\n/**\n * Fetches and caches modules from HTTP/HTTPS URLs.\n * Vite's SSR transform treats `https://` imports as external and bypasses the plugin\n * resolve pipeline entirely, so we intercept them at the ViteNodeRunner level instead.\n */\nconst httpModuleCache = new Map<string, string>()\nasync function fetchHttpModule(url: string): Promise<{code: string}> {\n const cached = httpModuleCache.get(url)\n if (cached) return {code: cached}\n\n debug('Fetching HTTP import: %s', url)\n const response = await fetch(url, {signal: AbortSignal.timeout(30_000)})\n if (!response.ok) {\n throw new Error(`Failed to fetch module from ${url}: ${response.status} ${response.statusText}`)\n }\n\n const code = await response.text()\n httpModuleCache.set(url, code)\n return {code}\n}\n\nfunction isHttpsUrl(id: string): boolean {\n return id.startsWith('https://')\n}\n\nconst defaultViteConfig: InlineConfig = {\n build: {target: 'node'},\n configFile: false,\n // Inject environment variables as compile-time constants for Vite\n define: Object.fromEntries(\n Object.entries(studioEnvVars).map(([key, value]) => [\n `process.env.${key}`,\n JSON.stringify(value),\n ]),\n ),\n envPrefix: cliConfig && 'app' in cliConfig ? 'SANITY_APP_' : 'SANITY_STUDIO_',\n esbuild: {\n jsx: 'automatic',\n },\n logLevel: 'error',\n optimizeDeps: {\n include: undefined,\n noDiscovery: true,\n },\n root: rootPath,\n server: {\n hmr: false,\n watch: null,\n },\n ssr: {\n /**\n * We don't want to externalize any dependencies, we want everything to run thru vite.\n * Especially for CJS compatibility, etc.\n */\n noExternal: true,\n },\n}\n\n// Merge the CLI config's Vite config with the default Vite config\nlet viteConfig = defaultViteConfig\nif (typeof cliConfig?.vite === 'function') {\n viteConfig = (await cliConfig.vite(viteConfig, {\n command: 'build',\n isSsrBuild: true,\n mode: 'production',\n })) as InlineConfig\n} else if (isRecord(cliConfig?.vite)) {\n viteConfig = mergeConfig(viteConfig, cliConfig.vite)\n}\n\ndebug('Creating Vite server with config: %o', viteConfig)\n// Vite will build the files we give it - targetting Node.js instead of the browser.\n// We include the inject plugin in order to provide the stubs for the undefined global APIs.\nconst server = await createServer(viteConfig)\n\n// Bit of a hack, but seems necessary based on the `node-vite` binary implementation\nawait server.pluginContainer.buildStart({})\n\n// Load environment variables from `.env` files in the same way as Vite does.\n// Note that Sanity also provides environment variables through `process.env.*` for compat reasons,\n// and so we need to do the same here.\nconst env = loadEnv(server.config.mode, server.config.envDir, viteConfig.envPrefix ?? '')\nfor (const key in env) {\n process.env[key] ??= env[key]\n}\n\n// Now we're providing the glue that ensures node-specific loading and execution works.\nconst node = new ViteNodeServer(server)\n\n// Should make it easier to debug any crashes in the imported code…\ninstallSourcemapsSupport({\n getSourceMap: (source) => node.getSourceMap(source),\n})\n\nconst runner = new ViteNodeRunner({\n base: server.config.base,\n async fetchModule(id) {\n // Vite's SSR transform externalizes https:// imports, so Node's ESM loader\n // would reject them. We fetch the module over HTTP and run it through Vite's\n // SSR transform to rewrite ESM export/import syntax to the __vite_ssr_*\n // format that ViteNodeRunner expects.\n if (isHttpsUrl(id)) {\n const {code: rawCode} = await fetchHttpModule(id)\n const result = await server.ssrTransform(rawCode, null, id)\n return {code: result?.code || rawCode}\n }\n return node.fetchModule(id)\n },\n resolveId(id, importer) {\n // Prevent vite-node from trying to resolve HTTP URLs through Node's resolver\n if (isHttpsUrl(id)) return {id}\n // Resolve any import from an HTTP-fetched module against the remote origin\n // (e.g. esm.sh returns `export * from '/pkg@1.0/es2022/pkg.mjs'`)\n if (importer && isHttpsUrl(importer)) {\n return {id: new URL(id, importer).href}\n }\n return node.resolveId(id, importer)\n },\n root: server.config.root,\n})\n\n// Copied from `vite-node` - it appears that this applies the `define` config from\n// vite, but it also takes a surprisingly long time to execute. Not clear at this\n// point why this is, so we should investigate whether it's necessary or not.\nawait runner.executeId('/@vite/env')\n\nawait runner.executeId(workerScriptPath)\n"],"names":["isMainThread","createServer","loadEnv","mergeConfig","ViteNodeRunner","ViteNodeServer","installSourcemapsSupport","getCliConfig","subdebug","isNotFoundError","getStudioEnvironmentVariables","setupBrowserStubs","isRecord","Error","rootPath","process","env","STUDIO_WORKER_STUDIO_ROOT_PATH","debug","workerScriptPath","STUDIO_WORKER_TASK_FILE","studioEnvVars","cliConfig","err","console","warn","httpModuleCache","Map","fetchHttpModule","url","cached","get","code","response","fetch","signal","AbortSignal","timeout","ok","status","statusText","text","set","isHttpsUrl","id","startsWith","defaultViteConfig","build","target","configFile","define","Object","fromEntries","entries","map","key","value","JSON","stringify","envPrefix","esbuild","jsx","logLevel","optimizeDeps","include","undefined","noDiscovery","root","server","hmr","watch","ssr","noExternal","viteConfig","vite","command","isSsrBuild","mode","pluginContainer","buildStart","config","envDir","node","getSourceMap","source","runner","base","fetchModule","rawCode","result","ssrTransform","resolveId","importer","URL","href","executeId"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import * as inquirer from '@inquirer/prompts';
2
+ import { NonInteractiveError } from '../errors/NonInteractiveError.js';
2
3
  import { isInteractive } from '../util/isInteractive.js';
3
- import { NonInteractiveError } from '../util/NonInteractiveError.js';
4
4
  export { Separator } from '@inquirer/prompts';
5
5
  function assertInteractive(promptName) {
6
6
  if (!isInteractive()) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ux/prompts.ts"],"sourcesContent":["import * as inquirer from '@inquirer/prompts'\n\nimport {isInteractive} from '../util/isInteractive.js'\nimport {NonInteractiveError} from '../util/NonInteractiveError.js'\n\nexport {Separator} from '@inquirer/prompts'\n\nfunction assertInteractive(promptName: string): void {\n if (!isInteractive()) {\n throw new NonInteractiveError(promptName)\n }\n}\n\nexport const checkbox: typeof inquirer.checkbox = (...args) => {\n assertInteractive('checkbox')\n return inquirer.checkbox(...args)\n}\n\nexport const confirm: typeof inquirer.confirm = (...args) => {\n assertInteractive('confirm')\n return inquirer.confirm(...args)\n}\n\nexport const editor: typeof inquirer.editor = (...args) => {\n assertInteractive('editor')\n return inquirer.editor(...args)\n}\n\nexport const expand: typeof inquirer.expand = (...args) => {\n assertInteractive('expand')\n return inquirer.expand(...args)\n}\n\nexport const input: typeof inquirer.input = (...args) => {\n assertInteractive('input')\n return inquirer.input(...args)\n}\n\nexport const number: typeof inquirer.number = (...args) => {\n assertInteractive('number')\n return inquirer.number(...args)\n}\n\nexport const password: typeof inquirer.password = (...args) => {\n assertInteractive('password')\n return inquirer.password(...args)\n}\n\nexport const rawlist: typeof inquirer.rawlist = (...args) => {\n assertInteractive('rawlist')\n return inquirer.rawlist(...args)\n}\n\nexport const search: typeof inquirer.search = (...args) => {\n assertInteractive('search')\n return inquirer.search(...args)\n}\n\nexport const select: typeof inquirer.select = (...args) => {\n assertInteractive('select')\n return inquirer.select(...args)\n}\n"],"names":["inquirer","isInteractive","NonInteractiveError","Separator","assertInteractive","promptName","checkbox","args","confirm","editor","expand","input","number","password","rawlist","search","select"],"mappings":"AAAA,YAAYA,cAAc,oBAAmB;AAE7C,SAAQC,aAAa,QAAO,2BAA0B;AACtD,SAAQC,mBAAmB,QAAO,iCAAgC;AAElE,SAAQC,SAAS,QAAO,oBAAmB;AAE3C,SAASC,kBAAkBC,UAAkB;IAC3C,IAAI,CAACJ,iBAAiB;QACpB,MAAM,IAAIC,oBAAoBG;IAChC;AACF;AAEA,OAAO,MAAMC,WAAqC,CAAC,GAAGC;IACpDH,kBAAkB;IAClB,OAAOJ,SAASM,QAAQ,IAAIC;AAC9B,EAAC;AAED,OAAO,MAAMC,UAAmC,CAAC,GAAGD;IAClDH,kBAAkB;IAClB,OAAOJ,SAASQ,OAAO,IAAID;AAC7B,EAAC;AAED,OAAO,MAAME,SAAiC,CAAC,GAAGF;IAChDH,kBAAkB;IAClB,OAAOJ,SAASS,MAAM,IAAIF;AAC5B,EAAC;AAED,OAAO,MAAMG,SAAiC,CAAC,GAAGH;IAChDH,kBAAkB;IAClB,OAAOJ,SAASU,MAAM,IAAIH;AAC5B,EAAC;AAED,OAAO,MAAMI,QAA+B,CAAC,GAAGJ;IAC9CH,kBAAkB;IAClB,OAAOJ,SAASW,KAAK,IAAIJ;AAC3B,EAAC;AAED,OAAO,MAAMK,SAAiC,CAAC,GAAGL;IAChDH,kBAAkB;IAClB,OAAOJ,SAASY,MAAM,IAAIL;AAC5B,EAAC;AAED,OAAO,MAAMM,WAAqC,CAAC,GAAGN;IACpDH,kBAAkB;IAClB,OAAOJ,SAASa,QAAQ,IAAIN;AAC9B,EAAC;AAED,OAAO,MAAMO,UAAmC,CAAC,GAAGP;IAClDH,kBAAkB;IAClB,OAAOJ,SAASc,OAAO,IAAIP;AAC7B,EAAC;AAED,OAAO,MAAMQ,SAAiC,CAAC,GAAGR;IAChDH,kBAAkB;IAClB,OAAOJ,SAASe,MAAM,IAAIR;AAC5B,EAAC;AAED,OAAO,MAAMS,SAAiC,CAAC,GAAGT;IAChDH,kBAAkB;IAClB,OAAOJ,SAASgB,MAAM,IAAIT;AAC5B,EAAC"}
1
+ {"version":3,"sources":["../../src/ux/prompts.ts"],"sourcesContent":["import * as inquirer from '@inquirer/prompts'\n\nimport {NonInteractiveError} from '../errors/NonInteractiveError.js'\nimport {isInteractive} from '../util/isInteractive.js'\n\nexport {Separator} from '@inquirer/prompts'\n\nfunction assertInteractive(promptName: string): void {\n if (!isInteractive()) {\n throw new NonInteractiveError(promptName)\n }\n}\n\nexport const checkbox: typeof inquirer.checkbox = (...args) => {\n assertInteractive('checkbox')\n return inquirer.checkbox(...args)\n}\n\nexport const confirm: typeof inquirer.confirm = (...args) => {\n assertInteractive('confirm')\n return inquirer.confirm(...args)\n}\n\nexport const editor: typeof inquirer.editor = (...args) => {\n assertInteractive('editor')\n return inquirer.editor(...args)\n}\n\nexport const expand: typeof inquirer.expand = (...args) => {\n assertInteractive('expand')\n return inquirer.expand(...args)\n}\n\nexport const input: typeof inquirer.input = (...args) => {\n assertInteractive('input')\n return inquirer.input(...args)\n}\n\nexport const number: typeof inquirer.number = (...args) => {\n assertInteractive('number')\n return inquirer.number(...args)\n}\n\nexport const password: typeof inquirer.password = (...args) => {\n assertInteractive('password')\n return inquirer.password(...args)\n}\n\nexport const rawlist: typeof inquirer.rawlist = (...args) => {\n assertInteractive('rawlist')\n return inquirer.rawlist(...args)\n}\n\nexport const search: typeof inquirer.search = (...args) => {\n assertInteractive('search')\n return inquirer.search(...args)\n}\n\nexport const select: typeof inquirer.select = (...args) => {\n assertInteractive('select')\n return inquirer.select(...args)\n}\n"],"names":["inquirer","NonInteractiveError","isInteractive","Separator","assertInteractive","promptName","checkbox","args","confirm","editor","expand","input","number","password","rawlist","search","select"],"mappings":"AAAA,YAAYA,cAAc,oBAAmB;AAE7C,SAAQC,mBAAmB,QAAO,mCAAkC;AACpE,SAAQC,aAAa,QAAO,2BAA0B;AAEtD,SAAQC,SAAS,QAAO,oBAAmB;AAE3C,SAASC,kBAAkBC,UAAkB;IAC3C,IAAI,CAACH,iBAAiB;QACpB,MAAM,IAAID,oBAAoBI;IAChC;AACF;AAEA,OAAO,MAAMC,WAAqC,CAAC,GAAGC;IACpDH,kBAAkB;IAClB,OAAOJ,SAASM,QAAQ,IAAIC;AAC9B,EAAC;AAED,OAAO,MAAMC,UAAmC,CAAC,GAAGD;IAClDH,kBAAkB;IAClB,OAAOJ,SAASQ,OAAO,IAAID;AAC7B,EAAC;AAED,OAAO,MAAME,SAAiC,CAAC,GAAGF;IAChDH,kBAAkB;IAClB,OAAOJ,SAASS,MAAM,IAAIF;AAC5B,EAAC;AAED,OAAO,MAAMG,SAAiC,CAAC,GAAGH;IAChDH,kBAAkB;IAClB,OAAOJ,SAASU,MAAM,IAAIH;AAC5B,EAAC;AAED,OAAO,MAAMI,QAA+B,CAAC,GAAGJ;IAC9CH,kBAAkB;IAClB,OAAOJ,SAASW,KAAK,IAAIJ;AAC3B,EAAC;AAED,OAAO,MAAMK,SAAiC,CAAC,GAAGL;IAChDH,kBAAkB;IAClB,OAAOJ,SAASY,MAAM,IAAIL;AAC5B,EAAC;AAED,OAAO,MAAMM,WAAqC,CAAC,GAAGN;IACpDH,kBAAkB;IAClB,OAAOJ,SAASa,QAAQ,IAAIN;AAC9B,EAAC;AAED,OAAO,MAAMO,UAAmC,CAAC,GAAGP;IAClDH,kBAAkB;IAClB,OAAOJ,SAASc,OAAO,IAAIP;AAC7B,EAAC;AAED,OAAO,MAAMQ,SAAiC,CAAC,GAAGR;IAChDH,kBAAkB;IAClB,OAAOJ,SAASe,MAAM,IAAIR;AAC5B,EAAC;AAED,OAAO,MAAMS,SAAiC,CAAC,GAAGT;IAChDH,kBAAkB;IAClB,OAAOJ,SAASgB,MAAM,IAAIT;AAC5B,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli-core",
3
- "version": "0.1.0-alpha.17",
3
+ "version": "0.1.0-alpha.18",
4
4
  "description": "Sanity CLI core package",
5
5
  "keywords": [
6
6
  "sanity",
@@ -47,11 +47,11 @@
47
47
  "./dist"
48
48
  ],
49
49
  "dependencies": {
50
- "@inquirer/prompts": "^8.2.0",
51
- "@oclif/core": "^4.8.1",
50
+ "@inquirer/prompts": "^8.3.0",
51
+ "@oclif/core": "^4.8.2",
52
52
  "@rexxars/jiti": "^2.6.2",
53
53
  "@sanity/client": "^7.16.0",
54
- "@sanity/types": "^5.12.0",
54
+ "@sanity/types": "^5.13.0",
55
55
  "babel-plugin-react-compiler": "^1.0.0",
56
56
  "boxen": "^8.0.1",
57
57
  "configstore": "^7.0.0",
@@ -75,21 +75,21 @@
75
75
  "devDependencies": {
76
76
  "@eslint/compat": "^2.0.2",
77
77
  "@sanity/codegen": "^5.10.1",
78
- "@sanity/pkg-utils": "^10.4.4",
78
+ "@sanity/pkg-utils": "^10.4.6",
79
79
  "@sanity/telemetry": "^0.8.1",
80
80
  "@swc/cli": "^0.8.0",
81
- "@swc/core": "^1.15.13",
81
+ "@swc/core": "^1.15.17",
82
82
  "@types/debug": "^4.1.12",
83
83
  "@types/jsdom": "^28.0.0",
84
84
  "@types/node": "^20.19.35",
85
85
  "eslint": "^9.39.3",
86
86
  "publint": "^0.3.17",
87
- "sanity": "^5.12.0",
87
+ "sanity": "^5.13.0",
88
88
  "typescript": "^5.9.3",
89
89
  "vitest": "^4.0.18",
90
90
  "@repo/tsconfig": "3.70.0",
91
- "@sanity/eslint-config-cli": "0.0.0-alpha.3",
92
- "@repo/package.config": "0.0.1"
91
+ "@repo/package.config": "0.0.1",
92
+ "@sanity/eslint-config-cli": "0.0.0-alpha.4"
93
93
  },
94
94
  "peerDependencies": {
95
95
  "@sanity/telemetry": ">=0.8.1 <0.9.0"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/util/NonInteractiveError.ts"],"sourcesContent":["/**\n * Error thrown when a prompt is attempted in a non-interactive environment\n * (e.g., CI, non-TTY, piped stdin). Callers can catch this specific error\n * to provide appropriate fallback behavior.\n */\nexport class NonInteractiveError extends Error {\n constructor(promptName: string) {\n super(\n `Cannot run \"${promptName}\" prompt in a non-interactive environment. ` +\n 'Provide the required value via flags or environment variables, or run in an interactive terminal.',\n )\n this.name = 'NonInteractiveError'\n }\n}\n"],"names":["NonInteractiveError","Error","promptName","name"],"mappings":"AAAA;;;;CAIC,GACD,OAAO,MAAMA,4BAA4BC;IACvC,YAAYC,UAAkB,CAAE;QAC9B,KAAK,CACH,CAAC,YAAY,EAAEA,WAAW,2CAA2C,CAAC,GACpE;QAEJ,IAAI,CAACC,IAAI,GAAG;IACd;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/util/NotFoundError.ts"],"sourcesContent":["import {isRecord} from './isRecord.js'\n\n/**\n * Error thrown when a file or directory is not found\n *\n * `code` is always `ENOENT` to mirror Node.js behavior when a file is not found\n *\n * @internal\n */\nexport class NotFoundError extends Error {\n code = 'ENOENT'\n path?: string\n\n constructor(message: string, path?: string) {\n super(message)\n this.path = path\n this.name = 'NotFoundError'\n }\n}\n\n/**\n * Returns whether or not the given error is a `NotFoundError`\n *\n * @param err - The error to check\n * @returns `true` if the error is a `NotFoundError`, `false` otherwise\n * @internal\n */\nexport function isNotFoundError(err: unknown): err is NotFoundError {\n return (\n isRecord(err) &&\n 'name' in err &&\n err.name === 'NotFoundError' &&\n 'code' in err &&\n err.code === 'ENOENT' &&\n 'message' in err &&\n typeof err.message === 'string'\n )\n}\n"],"names":["isRecord","NotFoundError","Error","code","path","message","name","isNotFoundError","err"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,gBAAe;AAEtC;;;;;;CAMC,GACD,OAAO,MAAMC,sBAAsBC;IACjCC,OAAO,SAAQ;IACfC,KAAa;IAEb,YAAYC,OAAe,EAAED,IAAa,CAAE;QAC1C,KAAK,CAACC;QACN,IAAI,CAACD,IAAI,GAAGA;QACZ,IAAI,CAACE,IAAI,GAAG;IACd;AACF;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,gBAAgBC,GAAY;IAC1C,OACER,SAASQ,QACT,UAAUA,OACVA,IAAIF,IAAI,KAAK,mBACb,UAAUE,OACVA,IAAIL,IAAI,KAAK,YACb,aAAaK,OACb,OAAOA,IAAIH,OAAO,KAAK;AAE3B"}