@sanity/cli-core 0.1.0-alpha.13 → 0.1.0-alpha.15

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.
@@ -1,9 +1,11 @@
1
1
  import { Command } from '@oclif/core';
2
2
  import { getCliConfig } from './config/cli/getCliConfig.js';
3
3
  import { findProjectRoot } from './config/findProjectRoot.js';
4
+ import { subdebug } from './debug.js';
4
5
  import { getGlobalCliClient, getProjectCliClient } from './services/apiClient.js';
5
6
  import { getCliTelemetry } from './util/getCliTelemetry.js';
6
7
  import { isInteractive } from './util/isInteractive.js';
8
+ const debug = subdebug('sanityCommand');
7
9
  export class SanityCommand extends Command {
8
10
  args;
9
11
  flags;
@@ -48,6 +50,7 @@ export class SanityCommand extends Command {
48
50
  * @returns The CLI config.
49
51
  */ async getCliConfig() {
50
52
  const root = await this.getProjectRoot();
53
+ debug(`Using project root`, root);
51
54
  return getCliConfig(root.directory);
52
55
  }
53
56
  /**
@@ -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 {\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\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 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","getGlobalCliClient","getProjectCliClient","getCliTelemetry","isInteractive","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,SACEC,kBAAkB,EAClBC,mBAAmB,QAGd,0BAAyB;AAGhC,SAAQC,eAAe,QAAO,4BAA2B;AACzD,SAAQC,aAAa,QAAO,0BAAyB;AAQrD,OAAO,MAAeC,sBAAgDP;IAC1DQ,KAAc;IACdC,MAAgB;IAE1B;;;;;;;GAOC,GACD,AAAUC,qBAAqB,CAACF,OAAiCL,mBAAmBK,MAAK;IAEzF;;;;;;;GAOC,GACD,AAAUG,sBAAsB,CAACH,OAAkCJ,oBAAoBI,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,MAAgBhB,eAAmC;QACjD,MAAMiB,OAAO,MAAM,IAAI,CAACC,cAAc;QAEtC,OAAOlB,aAAaiB,KAAKE,SAAS;IACpC;IAEA;;;;GAIC,GACD,MAAgBC,eAA4C;QAC1D,MAAMC,SAAS,MAAM,IAAI,CAACrB,YAAY;QAEtC,OAAOqB,OAAOC,GAAG,EAAEC;IACrB;IAEA;;;;GAIC,GACD,AAAUL,iBAA6C;QACrD,OAAOjB,gBAAgBuB,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,GAAGZ;QAEjB,MAAM,KAAK,CAACsB;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,OAAO7B;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 {\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"}
@@ -0,0 +1,77 @@
1
+ import {agent} from 'get-it/middleware'
2
+ import {base} from 'get-it/middleware'
3
+ import {injectResponse} from 'get-it/middleware'
4
+ import {jsonRequest} from 'get-it/middleware'
5
+ import {jsonResponse} from 'get-it/middleware'
6
+ import {keepAlive} from 'get-it/middleware'
7
+ import {observable} from 'get-it/middleware'
8
+ import {progress} from 'get-it/middleware'
9
+ import {proxy} from 'get-it/middleware'
10
+ import {Requester} from 'get-it'
11
+ import {retry} from 'get-it/middleware'
12
+ import {urlEncoded} from 'get-it/middleware'
13
+
14
+ export {agent}
15
+
16
+ export {base}
17
+
18
+ /**
19
+ * Creates a `get-it` requester with a standard set of middleware.
20
+ *
21
+ * Default middleware (in order):
22
+ * 1. `httpErrors()` — throw on HTTP error status codes
23
+ * 2. `headers({'User-Agent': '@sanity/cli-core@<version>'})` — identify CLI requests
24
+ * 3. `debug({verbose: true, namespace: 'sanity:cli'})` — debug logging
25
+ * 4. `promise({onlyBody: true})` — return body directly (must be last)
26
+ *
27
+ * @param options - Optional configuration to disable or customize middleware
28
+ * @returns A configured `get-it` requester
29
+ * @public
30
+ */
31
+ export declare function createRequester(options?: {middleware?: MiddlewareOptions}): Requester
32
+
33
+ export {injectResponse}
34
+
35
+ export {jsonRequest}
36
+
37
+ export {jsonResponse}
38
+
39
+ export {keepAlive}
40
+
41
+ /**
42
+ * Options for configuring individual middleware in {@link createRequester}.
43
+ *
44
+ * Each key corresponds to a middleware. Omitting a key uses the default,
45
+ * `false` disables it, and an object merges with the defaults.
46
+ *
47
+ * @public
48
+ */
49
+ export declare type MiddlewareOptions = {
50
+ debug?:
51
+ | false
52
+ | {
53
+ namespace?: string
54
+ verbose?: boolean
55
+ }
56
+ headers?: false | Record<string, string>
57
+ httpErrors?: false
58
+ promise?:
59
+ | false
60
+ | {
61
+ onlyBody?: boolean
62
+ }
63
+ }
64
+
65
+ export {observable}
66
+
67
+ export {progress}
68
+
69
+ export {proxy}
70
+
71
+ export {Requester}
72
+
73
+ export {retry}
74
+
75
+ export {urlEncoded}
76
+
77
+ export {}
@@ -0,0 +1,7 @@
1
+ export { createRequester } from '../request/createRequester.js';
2
+ // Re-export non-default middleware from get-it for use alongside createRequester.
3
+ // Default middleware (httpErrors, headers, debug, promise) are applied automatically
4
+ // by createRequester and don't need to be imported separately.
5
+ export { agent, base, injectResponse, jsonRequest, jsonResponse, keepAlive, observable, progress, proxy, retry, urlEncoded } from 'get-it/middleware';
6
+
7
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/_exports/request.ts"],"sourcesContent":["export {createRequester, type MiddlewareOptions} from '../request/createRequester.js'\n\n// Re-export get-it types used by consumers of createRequester\nexport {type Requester} from 'get-it'\n\n// Re-export non-default middleware from get-it for use alongside createRequester.\n// Default middleware (httpErrors, headers, debug, promise) are applied automatically\n// by createRequester and don't need to be imported separately.\nexport {\n agent,\n base,\n injectResponse,\n jsonRequest,\n jsonResponse,\n keepAlive,\n observable,\n progress,\n proxy,\n retry,\n urlEncoded,\n} from 'get-it/middleware'\n"],"names":["createRequester","agent","base","injectResponse","jsonRequest","jsonResponse","keepAlive","observable","progress","proxy","retry","urlEncoded"],"mappings":"AAAA,SAAQA,eAAe,QAA+B,gCAA+B;AAKrF,kFAAkF;AAClF,qFAAqF;AACrF,+DAA+D;AAC/D,SACEC,KAAK,EACLC,IAAI,EACJC,cAAc,EACdC,WAAW,EACXC,YAAY,EACZC,SAAS,EACTC,UAAU,EACVC,QAAQ,EACRC,KAAK,EACLC,KAAK,EACLC,UAAU,QACL,oBAAmB"}
@@ -1,10 +1,6 @@
1
- import { pathToFileURL } from 'node:url';
2
- import { getTsconfig } from 'get-tsconfig';
3
- import { tsImport } from 'tsx/esm/api';
4
1
  import { debug } from '../../debug.js';
5
- import { tsxWorkerTask } from '../../loaders/tsx/tsxWorkerTask.js';
2
+ import { importModule } from '../../util/importModule.js';
6
3
  import { NotFoundError } from '../../util/NotFoundError.js';
7
- import { tryGetDefaultExport } from '../../util/tryGetDefaultExport.js';
8
4
  import { findPathForFiles } from '../util/findConfigsPaths.js';
9
5
  import { cliConfigSchema } from './schemas.js';
10
6
  /**
@@ -33,36 +29,25 @@ import { cliConfigSchema } from './schemas.js';
33
29
  throw new Error(`Multiple CLI config files found (${configPaths.map((path)=>path.path).join(', ')})`);
34
30
  }
35
31
  const configPath = configPaths[0].path;
32
+ debug(`Loading CLI config from: ${configPath}`);
36
33
  let cliConfig;
37
34
  try {
38
- cliConfig = await tsxWorkerTask(new URL('getCliConfig.worker.js', import.meta.url), {
39
- name: 'cliConfig',
40
- rootPath,
41
- workerData: {
42
- configPath
43
- }
44
- });
35
+ const result = await importModule(configPath);
36
+ debug('CLI config loaded: %o', result);
37
+ cliConfig = result;
45
38
  } catch (err) {
46
39
  debug('Failed to load CLI config in worker thread: %s', err);
47
- // Assuming that didn't work because of unseriazable properties, so we'll try the
48
- // main thread with tsx registered.
49
- const tsconfig = getTsconfig(rootPath);
50
- // Ensure we get the default export (sometimes we get a bit of a mixed bag)
51
- cliConfig = await tsImport(pathToFileURL(configPath).href, {
52
- parentURL: import.meta.url,
53
- tsconfig: tsconfig?.path ?? undefined
40
+ throw new Error('CLI config cannot be loaded', {
41
+ cause: err
54
42
  });
55
- cliConfig = tryGetDefaultExport(cliConfig);
56
- if (!cliConfig) {
57
- throw new Error('Invalid CLI config structure');
58
- }
59
43
  }
60
44
  const { data, error, success } = cliConfigSchema.safeParse(cliConfig);
61
45
  if (!success) {
62
- throw new Error(`Invalid CLI config: ${error.message}`);
46
+ debug(`Invalid CLI config: ${error.message}`);
47
+ throw new Error(`Invalid CLI config: ${error.message}`, {
48
+ cause: error
49
+ });
63
50
  }
64
- // There is a minor difference here because of the `vite` property and how the types
65
- // aren't as specific as our manually typed `CliConfig` type, thus the cast.
66
51
  return data;
67
52
  }
68
53
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/config/cli/getCliConfig.ts"],"sourcesContent":["import {pathToFileURL} from 'node:url'\n\nimport {getTsconfig} from 'get-tsconfig'\nimport {tsImport} from 'tsx/esm/api'\n\nimport {debug} from '../../debug.js'\nimport {tsxWorkerTask} from '../../loaders/tsx/tsxWorkerTask.js'\nimport {NotFoundError} from '../../util/NotFoundError.js'\nimport {tryGetDefaultExport} from '../../util/tryGetDefaultExport.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 let cliConfig: CliConfig | undefined\n try {\n cliConfig = await tsxWorkerTask<CliConfig | undefined>(\n new URL('getCliConfig.worker.js', import.meta.url),\n {\n name: 'cliConfig',\n rootPath,\n workerData: {configPath},\n },\n )\n } catch (err) {\n debug('Failed to load CLI config in worker thread: %s', err)\n\n // Assuming that didn't work because of unseriazable properties, so we'll try the\n // main thread with tsx registered.\n const tsconfig = getTsconfig(rootPath)\n\n // Ensure we get the default export (sometimes we get a bit of a mixed bag)\n cliConfig = await tsImport(pathToFileURL(configPath).href, {\n parentURL: import.meta.url,\n tsconfig: tsconfig?.path ?? undefined,\n })\n cliConfig = tryGetDefaultExport(cliConfig) as CliConfig | undefined\n\n if (!cliConfig) {\n throw new Error('Invalid CLI config structure')\n }\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":["pathToFileURL","getTsconfig","tsImport","debug","tsxWorkerTask","NotFoundError","tryGetDefaultExport","findPathForFiles","cliConfigSchema","getCliConfig","rootPath","paths","configPaths","filter","path","exists","length","Error","map","join","configPath","cliConfig","URL","url","name","workerData","err","tsconfig","href","parentURL","undefined","data","error","success","safeParse","message"],"mappings":"AAAA,SAAQA,aAAa,QAAO,WAAU;AAEtC,SAAQC,WAAW,QAAO,eAAc;AACxC,SAAQC,QAAQ,QAAO,cAAa;AAEpC,SAAQC,KAAK,QAAO,iBAAgB;AACpC,SAAQC,aAAa,QAAO,qCAAoC;AAChE,SAAQC,aAAa,QAAO,8BAA6B;AACzD,SAAQC,mBAAmB,QAAO,oCAAmC;AACrE,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,IAAIX,cAAc,CAAC,uBAAuB,EAAEK,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;IAEtC,IAAIO;IACJ,IAAI;QACFA,YAAY,MAAMjB,cAChB,IAAIkB,IAAI,0BAA0B,YAAYC,GAAG,GACjD;YACEC,MAAM;YACNd;YACAe,YAAY;gBAACL;YAAU;QACzB;IAEJ,EAAE,OAAOM,KAAK;QACZvB,MAAM,kDAAkDuB;QAExD,iFAAiF;QACjF,mCAAmC;QACnC,MAAMC,WAAW1B,YAAYS;QAE7B,2EAA2E;QAC3EW,YAAY,MAAMnB,SAASF,cAAcoB,YAAYQ,IAAI,EAAE;YACzDC,WAAW,YAAYN,GAAG;YAC1BI,UAAUA,UAAUb,QAAQgB;QAC9B;QACAT,YAAYf,oBAAoBe;QAEhC,IAAI,CAACA,WAAW;YACd,MAAM,IAAIJ,MAAM;QAClB;IACF;IAEA,MAAM,EAACc,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAC,GAAGzB,gBAAgB0B,SAAS,CAACb;IACzD,IAAI,CAACY,SAAS;QACZ,MAAM,IAAIhB,MAAM,CAAC,oBAAoB,EAAEe,MAAMG,OAAO,EAAE;IACxD;IAEA,oFAAoF;IACpF,4EAA4E;IAC5E,OAAOJ;AACT"}
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"}
@@ -15,10 +15,5 @@ if (resolvePlugins) {
15
15
  config = await getStudioWorkspaces(configPath);
16
16
  }
17
17
  parentPort.postMessage(safeStructuredClone(config));
18
- // Explicitly exit the process to avoid any dangling references from keeping
19
- // the process alive after resolving it's main task
20
- setImmediate(()=>{
21
- process.exit(1);
22
- });
23
18
 
24
19
  //# sourceMappingURL=readStudioConfig.worker.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/config/studio/readStudioConfig.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {z} from 'zod'\n\nimport {doImport} from '../../util/doImport.js'\nimport {safeStructuredClone} from '../../util/safeStructuredClone.js'\nimport {getStudioWorkspaces} from './getStudioWorkspaces.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst {configPath, resolvePlugins} = z\n .object({configPath: z.string(), resolvePlugins: z.boolean()})\n .parse(workerData)\n\nlet {default: config} = await doImport(configPath)\n\nif (resolvePlugins) {\n config = await getStudioWorkspaces(configPath)\n}\n\nparentPort.postMessage(safeStructuredClone(config))\n\n// Explicitly exit the process to avoid any dangling references from keeping\n// the process alive after resolving it's main task\nsetImmediate(() => {\n process.exit(1)\n})\n"],"names":["isMainThread","parentPort","workerData","z","doImport","safeStructuredClone","getStudioWorkspaces","Error","configPath","resolvePlugins","object","string","boolean","parse","default","config","postMessage","setImmediate","process","exit"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,CAAC,QAAO,MAAK;AAErB,SAAQC,QAAQ,QAAO,yBAAwB;AAC/C,SAAQC,mBAAmB,QAAO,oCAAmC;AACrE,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,IAAIN,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIM,MAAM;AAClB;AAEA,MAAM,EAACC,UAAU,EAAEC,cAAc,EAAC,GAAGN,EAClCO,MAAM,CAAC;IAACF,YAAYL,EAAEQ,MAAM;IAAIF,gBAAgBN,EAAES,OAAO;AAAE,GAC3DC,KAAK,CAACX;AAET,IAAI,EAACY,SAASC,MAAM,EAAC,GAAG,MAAMX,SAASI;AAEvC,IAAIC,gBAAgB;IAClBM,SAAS,MAAMT,oBAAoBE;AACrC;AAEAP,WAAWe,WAAW,CAACX,oBAAoBU;AAE3C,4EAA4E;AAC5E,mDAAmD;AACnDE,aAAa;IACXC,QAAQC,IAAI,CAAC;AACf"}
1
+ {"version":3,"sources":["../../../src/config/studio/readStudioConfig.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {z} from 'zod'\n\nimport {doImport} from '../../util/doImport.js'\nimport {safeStructuredClone} from '../../util/safeStructuredClone.js'\nimport {getStudioWorkspaces} from './getStudioWorkspaces.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst {configPath, resolvePlugins} = z\n .object({configPath: z.string(), resolvePlugins: z.boolean()})\n .parse(workerData)\n\nlet {default: config} = await doImport(configPath)\n\nif (resolvePlugins) {\n config = await getStudioWorkspaces(configPath)\n}\n\nparentPort.postMessage(safeStructuredClone(config))\n"],"names":["isMainThread","parentPort","workerData","z","doImport","safeStructuredClone","getStudioWorkspaces","Error","configPath","resolvePlugins","object","string","boolean","parse","default","config","postMessage"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,CAAC,QAAO,MAAK;AAErB,SAAQC,QAAQ,QAAO,yBAAwB;AAC/C,SAAQC,mBAAmB,QAAO,oCAAmC;AACrE,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,IAAIN,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIM,MAAM;AAClB;AAEA,MAAM,EAACC,UAAU,EAAEC,cAAc,EAAC,GAAGN,EAClCO,MAAM,CAAC;IAACF,YAAYL,EAAEQ,MAAM;IAAIF,gBAAgBN,EAAES,OAAO;AAAE,GAC3DC,KAAK,CAACX;AAET,IAAI,EAACY,SAASC,MAAM,EAAC,GAAG,MAAMX,SAASI;AAEvC,IAAIC,gBAAgB;IAClBM,SAAS,MAAMT,oBAAoBE;AACrC;AAEAP,WAAWe,WAAW,CAACX,oBAAoBU"}
package/dist/index.d.ts CHANGED
@@ -8,8 +8,7 @@ import debugIt from 'debug'
8
8
  import {InlineConfig} from 'vite'
9
9
  import {Interfaces} from '@oclif/core'
10
10
  import {PluginOptions} from 'babel-plugin-react-compiler'
11
- import {SanityClient} from 'sanity'
12
- import {SanityClient as SanityClient_2} from '@sanity/client'
11
+ import {SanityClient} from '@sanity/client'
13
12
  import {TelemetryEvent} from '@sanity/telemetry'
14
13
  import {TelemetryLogger} from '@sanity/telemetry'
15
14
  import {URL as URL_2} from 'node:url'
@@ -504,7 +503,7 @@ export declare function getGlobalCliClient({
504
503
  requireUser,
505
504
  token: providedToken,
506
505
  ...config
507
- }: GlobalCliClientOptions): Promise<SanityClient_2>
506
+ }: GlobalCliClientOptions): Promise<SanityClient>
508
507
 
509
508
  /**
510
509
  * Create a "project" (scoped) Sanity API client.
@@ -518,7 +517,7 @@ export declare function getProjectCliClient({
518
517
  requireUser,
519
518
  token: providedToken,
520
519
  ...config
521
- }: ProjectCliClientOptions): Promise<SanityClient_2>
520
+ }: ProjectCliClientOptions): Promise<SanityClient>
522
521
 
523
522
  /**
524
523
  * Gets an environment variable with the appropriate Sanity prefix based on whether it's an app or studio.
@@ -616,6 +615,33 @@ export declare interface GlobalCliClientOptions extends ClientConfig {
616
615
  requireUser?: boolean
617
616
  }
618
617
 
618
+ /**
619
+ * Imports a module using jiti and returns its exports.
620
+ * This is a thin wrapper around tsx to allow swapping out the underlying implementation in the future if needed.
621
+ *
622
+ * @param filePath - Path to the module to import.
623
+ * @param options - Options for the importModule function.
624
+ * @returns The exported module.
625
+ *
626
+ * @internal
627
+ */
628
+ export declare function importModule<T = unknown>(
629
+ filePath: string | URL,
630
+ options?: ImportModuleOptions,
631
+ ): Promise<T>
632
+
633
+ declare interface ImportModuleOptions {
634
+ /**
635
+ * Whether to return the default export of the module.
636
+ */
637
+ default?: true
638
+ /**
639
+ * Path to the tsconfig file to use for the import. If not provided, the tsconfig
640
+ * will be inferred from the nearest `tsconfig.json` file.
641
+ */
642
+ tsconfigPath?: string
643
+ }
644
+
619
645
  export declare const isCi: () => boolean
620
646
 
621
647
  export declare function isInteractive(): boolean
@@ -782,6 +808,19 @@ export declare interface ProjectRootResult {
782
808
  type: 'app' | 'studio'
783
809
  }
784
810
 
811
+ /**
812
+ * Wraps a Node.js Worker in a Promise that resolves with the first message
813
+ * the worker sends, and rejects on error, message deserialization failure,
814
+ * or non-zero exit code. The worker is terminated after a message or error
815
+ * is received.
816
+ *
817
+ * @param worker - The Worker instance to promisify
818
+ * @returns A promise that resolves with the first message from the worker
819
+ * @throws If the worker emits an error, a message deserialization error, or exits with a non-zero code
820
+ * @internal
821
+ */
822
+ export declare function promisifyWorker<T = unknown>(worker: Worker_2): Promise<T>
823
+
785
824
  declare const rawConfigSchema: z_2.ZodUnion<
786
825
  readonly [
787
826
  z_2.ZodArray<
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ export * from './util/getEmptyAuth.js';
26
26
  export * from './util/getSanityEnvVar.js';
27
27
  export * from './util/getSanityUrl.js';
28
28
  export * from './util/getUserConfig.js';
29
+ export * from './util/importModule.js';
29
30
  export * from './util/isCi.js';
30
31
  export * from './util/isInteractive.js';
31
32
  export * from './util/isRecord.js';
@@ -33,6 +34,7 @@ export * from './util/isStaging.js';
33
34
  export * from './util/isTrueish.js';
34
35
  export * from './util/normalizePath.js';
35
36
  export * from './util/parseStringFlag.js';
37
+ export * from './util/promisifyWorker.js';
36
38
  export * from './util/readNDJSON.js';
37
39
  export * from './util/readPackageJson.js';
38
40
  export * from './util/resolveLocalPackage.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/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/readNDJSON.js'\nexport * from './util/readPackageJson.js'\nexport * from './util/resolveLocalPackage.js'\nexport * from './util/safeStructuredClone.js'\nexport * from './util/tryGetDefaultExport.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,iBAAgB;AAC9B,cAAc,0BAAyB;AACvC,cAAc,qBAAoB;AAClC,cAAc,sBAAqB;AACnC,cAAc,sBAAqB;AACnC,cAAc,0BAAyB;AACvC,cAAc,4BAA2B;AACzC,cAAc,uBAAsB;AACpC,cAAc,4BAA2B;AACzC,cAAc,gCAA+B;AAC7C,cAAc,gCAA+B;AAC7C,cAAc,gCAA+B;AAC7C,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 './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 './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,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,uBAAsB;AACpC,cAAc,uBAAsB;AACpC,cAAc,wBAAuB;AACrC,cAAc,gBAAe"}
@@ -1,5 +1,7 @@
1
+ import { fileURLToPath } from 'node:url';
1
2
  import { Worker } from 'node:worker_threads';
2
3
  import { isRecord } from '../../util/isRecord.js';
4
+ import { promisifyWorker } from '../../util/promisifyWorker.js';
3
5
  /**
4
6
  * Executes a worker file in a Sanity Studio browser context.
5
7
  *
@@ -28,32 +30,8 @@ import { isRecord } from '../../util/isRecord.js';
28
30
  * @throws If the worker exits with a non-zero code
29
31
  * @internal
30
32
  */ export function studioWorkerTask(filePath, options) {
31
- return new Promise((resolve, reject)=>{
32
- const worker = createStudioWorker(filePath, options);
33
- worker.addListener('error', function onWorkerError(err) {
34
- reject(new Error(`Fail to load file through worker: ${err.message}`));
35
- cleanup();
36
- });
37
- worker.addListener('exit', function onWorkerExit(code) {
38
- if (code > 0) {
39
- reject(new Error(`Worker exited with code ${code}`));
40
- }
41
- });
42
- worker.addListener('messageerror', function onWorkerMessageError(err) {
43
- reject(new Error(`Fail to parse message from worker: ${err}`));
44
- cleanup();
45
- });
46
- worker.addListener('message', function onWorkerMessage(message) {
47
- resolve(message);
48
- cleanup();
49
- });
50
- function cleanup() {
51
- // Allow the worker a _bit_ of time to clean up, but ensure that we don't have
52
- // lingering processes hanging around forever if the worker doesn't exit on its
53
- // own.
54
- setImmediate(()=>worker.terminate());
55
- }
56
- });
33
+ const worker = createStudioWorker(filePath, options);
34
+ return promisifyWorker(worker);
57
35
  }
58
36
  /**
59
37
  * Creates a new worker for a studio worker task.
@@ -83,7 +61,8 @@ import { isRecord } from '../../util/isRecord.js';
83
61
  * @throws If the worker exits with a non-zero code
84
62
  * @internal
85
63
  */ export function createStudioWorker(filePath, options) {
86
- if (!/\.worker\.(js|ts)$/.test(filePath.pathname)) {
64
+ const normalizedFilePath = fileURLToPath(filePath);
65
+ if (!/\.worker\.(js|ts)$/.test(normalizedFilePath)) {
87
66
  throw new Error('Studio worker tasks must include `.worker.(js|ts)` in path');
88
67
  }
89
68
  return new Worker(new URL('studioWorkerLoader.worker.js', import.meta.url), {
@@ -91,7 +70,7 @@ import { isRecord } from '../../util/isRecord.js';
91
70
  env: {
92
71
  ...isRecord(options.env) ? options.env : process.env,
93
72
  STUDIO_WORKER_STUDIO_ROOT_PATH: options.studioRootPath,
94
- STUDIO_WORKER_TASK_FILE: filePath.pathname
73
+ STUDIO_WORKER_TASK_FILE: normalizedFilePath
95
74
  }
96
75
  });
97
76
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/loaders/studio/studioWorkerTask.ts"],"sourcesContent":["import {Worker, type WorkerOptions} from 'node:worker_threads'\n\nimport {type RequireProps} from '../../types.js'\nimport {isRecord} from '../../util/isRecord.js'\n\n/**\n * Options for the studio worker task\n *\n * @internal\n */\ninterface StudioWorkerTaskOptions extends RequireProps<WorkerOptions, 'name'> {\n studioRootPath: string\n}\n\n/**\n * Executes a worker file in a Sanity Studio browser context.\n *\n * This uses a combination of vite for \"bundling\" + jsdom for emulating a browser\n * environment under the hood, which means that the same thing that will work in vite\n * _should_ work in the worker - to a degree. If the user has defined any typescript\n * path aliases, these will have to be added as aliases to the vite config - the same\n * behavior as you would see with regular vite. Other things that are accounted for:\n *\n * - TypeScript support (+JSX, enums and other \"compilation needed\" features)\n * - CSS, font and other file imports will resolve to a file path\n * - CSS module imports will resolve to a javascript object of class names\n * - Environment variables are available both as `import.meta.env` and `process.env`,\n * and `.env` files are loaded in the same way that they would in a Sanity studio.\n * - Browser globals not available in a Node.js environment but _are_ provided by JSDOM\n * are defined directly to the Node environment as globals. While this polutes the\n * global namespace, it is done only in the worker thread.\n * - Certain browser globals that are _not_ available in JSDOM are also provided to the\n * global namespace - things like `requestIdleCallback`, `IntersectionObserver` etc.\n * These are provided with a minimal stub implementation to make them not crash.\n *\n * @param filePath - Path to the worker file (`.ts` works and is encouraged)\n * @param options - Options to pass to the worker\n * @returns A promise that resolves with the message from the worker\n * @throws If the file does not exist\n * @throws If the worker exits with a non-zero code\n * @internal\n */\nexport function studioWorkerTask<T = unknown>(\n filePath: URL,\n options: StudioWorkerTaskOptions,\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const worker = createStudioWorker(filePath, options)\n\n worker.addListener('error', function onWorkerError(err) {\n reject(new Error(`Fail to load file through worker: ${err.message}`))\n cleanup()\n })\n worker.addListener('exit', function onWorkerExit(code) {\n if (code > 0) {\n reject(new Error(`Worker exited with code ${code}`))\n }\n })\n worker.addListener('messageerror', function onWorkerMessageError(err) {\n reject(new Error(`Fail to parse message from worker: ${err}`))\n cleanup()\n })\n worker.addListener('message', function onWorkerMessage(message) {\n resolve(message)\n cleanup()\n })\n\n function cleanup() {\n // Allow the worker a _bit_ of time to clean up, but ensure that we don't have\n // lingering processes hanging around forever if the worker doesn't exit on its\n // own.\n setImmediate(() => worker.terminate())\n }\n })\n}\n\n/**\n * Creates a new worker for a studio worker task.\n *\n * This uses a combination of vite for \"bundling\" + jsdom for emulating a browser\n * environment under the hood, which means that the same thing that will work in vite\n * _should_ work in the worker - to a degree. If the user has defined any typescript\n * path aliases, these will have to be added as aliases to the vite config - the same\n * behavior as you would see with regular vite. Other things that are accounted for:\n *\n * - TypeScript support (+JSX, enums and other \"compilation needed\" features)\n * - CSS, font and other file imports will resolve to a file path\n * - CSS module imports will resolve to a javascript object of class names\n * - Environment variables are available both as `import.meta.env` and `process.env`,\n * and `.env` files are loaded in the same way that they would in a Sanity studio.\n * - Browser globals not available in a Node.js environment but _are_ provided by JSDOM\n * are defined directly to the Node environment as globals. While this polutes the\n * global namespace, it is done only in the worker thread.\n * - Certain browser globals that are _not_ available in JSDOM are also provided to the\n * global namespace - things like `requestIdleCallback`, `IntersectionObserver` etc.\n * These are provided with a minimal stub implementation to make them not crash.\n *\n * @param filePath - Path to the worker file (`.ts` works and is encouraged)\n * @param options - Options to pass to the worker\n * @returns A promise that resolves with the message from the worker\n * @throws If the file does not exist\n * @throws If the worker exits with a non-zero code\n * @internal\n */\nexport function createStudioWorker(filePath: URL, options: StudioWorkerTaskOptions) {\n if (!/\\.worker\\.(js|ts)$/.test(filePath.pathname)) {\n throw new Error('Studio worker tasks must include `.worker.(js|ts)` in path')\n }\n\n return new Worker(new URL('studioWorkerLoader.worker.js', import.meta.url), {\n ...options,\n env: {\n ...(isRecord(options.env) ? options.env : process.env),\n STUDIO_WORKER_STUDIO_ROOT_PATH: options.studioRootPath,\n STUDIO_WORKER_TASK_FILE: filePath.pathname,\n },\n })\n}\n"],"names":["Worker","isRecord","studioWorkerTask","filePath","options","Promise","resolve","reject","worker","createStudioWorker","addListener","onWorkerError","err","Error","message","cleanup","onWorkerExit","code","onWorkerMessageError","onWorkerMessage","setImmediate","terminate","test","pathname","URL","url","env","process","STUDIO_WORKER_STUDIO_ROOT_PATH","studioRootPath","STUDIO_WORKER_TASK_FILE"],"mappings":"AAAA,SAAQA,MAAM,QAA2B,sBAAqB;AAG9D,SAAQC,QAAQ,QAAO,yBAAwB;AAW/C;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,SAASC,iBACdC,QAAa,EACbC,OAAgC;IAEhC,OAAO,IAAIC,QAAW,CAACC,SAASC;QAC9B,MAAMC,SAASC,mBAAmBN,UAAUC;QAE5CI,OAAOE,WAAW,CAAC,SAAS,SAASC,cAAcC,GAAG;YACpDL,OAAO,IAAIM,MAAM,CAAC,kCAAkC,EAAED,IAAIE,OAAO,EAAE;YACnEC;QACF;QACAP,OAAOE,WAAW,CAAC,QAAQ,SAASM,aAAaC,IAAI;YACnD,IAAIA,OAAO,GAAG;gBACZV,OAAO,IAAIM,MAAM,CAAC,wBAAwB,EAAEI,MAAM;YACpD;QACF;QACAT,OAAOE,WAAW,CAAC,gBAAgB,SAASQ,qBAAqBN,GAAG;YAClEL,OAAO,IAAIM,MAAM,CAAC,mCAAmC,EAAED,KAAK;YAC5DG;QACF;QACAP,OAAOE,WAAW,CAAC,WAAW,SAASS,gBAAgBL,OAAO;YAC5DR,QAAQQ;YACRC;QACF;QAEA,SAASA;YACP,8EAA8E;YAC9E,+EAA+E;YAC/E,OAAO;YACPK,aAAa,IAAMZ,OAAOa,SAAS;QACrC;IACF;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,SAASZ,mBAAmBN,QAAa,EAAEC,OAAgC;IAChF,IAAI,CAAC,qBAAqBkB,IAAI,CAACnB,SAASoB,QAAQ,GAAG;QACjD,MAAM,IAAIV,MAAM;IAClB;IAEA,OAAO,IAAIb,OAAO,IAAIwB,IAAI,gCAAgC,YAAYC,GAAG,GAAG;QAC1E,GAAGrB,OAAO;QACVsB,KAAK;YACH,GAAIzB,SAASG,QAAQsB,GAAG,IAAItB,QAAQsB,GAAG,GAAGC,QAAQD,GAAG;YACrDE,gCAAgCxB,QAAQyB,cAAc;YACtDC,yBAAyB3B,SAASoB,QAAQ;QAC5C;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/loaders/studio/studioWorkerTask.ts"],"sourcesContent":["import {fileURLToPath} from 'node:url'\nimport {Worker, type WorkerOptions} from 'node:worker_threads'\n\nimport {type RequireProps} from '../../types.js'\nimport {isRecord} from '../../util/isRecord.js'\nimport {promisifyWorker} from '../../util/promisifyWorker.js'\n\n/**\n * Options for the studio worker task\n *\n * @internal\n */\ninterface StudioWorkerTaskOptions extends RequireProps<WorkerOptions, 'name'> {\n studioRootPath: string\n}\n\n/**\n * Executes a worker file in a Sanity Studio browser context.\n *\n * This uses a combination of vite for \"bundling\" + jsdom for emulating a browser\n * environment under the hood, which means that the same thing that will work in vite\n * _should_ work in the worker - to a degree. If the user has defined any typescript\n * path aliases, these will have to be added as aliases to the vite config - the same\n * behavior as you would see with regular vite. Other things that are accounted for:\n *\n * - TypeScript support (+JSX, enums and other \"compilation needed\" features)\n * - CSS, font and other file imports will resolve to a file path\n * - CSS module imports will resolve to a javascript object of class names\n * - Environment variables are available both as `import.meta.env` and `process.env`,\n * and `.env` files are loaded in the same way that they would in a Sanity studio.\n * - Browser globals not available in a Node.js environment but _are_ provided by JSDOM\n * are defined directly to the Node environment as globals. While this polutes the\n * global namespace, it is done only in the worker thread.\n * - Certain browser globals that are _not_ available in JSDOM are also provided to the\n * global namespace - things like `requestIdleCallback`, `IntersectionObserver` etc.\n * These are provided with a minimal stub implementation to make them not crash.\n *\n * @param filePath - Path to the worker file (`.ts` works and is encouraged)\n * @param options - Options to pass to the worker\n * @returns A promise that resolves with the message from the worker\n * @throws If the file does not exist\n * @throws If the worker exits with a non-zero code\n * @internal\n */\nexport function studioWorkerTask<T = unknown>(\n filePath: URL,\n options: StudioWorkerTaskOptions,\n): Promise<T> {\n const worker = createStudioWorker(filePath, options)\n return promisifyWorker<T>(worker)\n}\n\n/**\n * Creates a new worker for a studio worker task.\n *\n * This uses a combination of vite for \"bundling\" + jsdom for emulating a browser\n * environment under the hood, which means that the same thing that will work in vite\n * _should_ work in the worker - to a degree. If the user has defined any typescript\n * path aliases, these will have to be added as aliases to the vite config - the same\n * behavior as you would see with regular vite. Other things that are accounted for:\n *\n * - TypeScript support (+JSX, enums and other \"compilation needed\" features)\n * - CSS, font and other file imports will resolve to a file path\n * - CSS module imports will resolve to a javascript object of class names\n * - Environment variables are available both as `import.meta.env` and `process.env`,\n * and `.env` files are loaded in the same way that they would in a Sanity studio.\n * - Browser globals not available in a Node.js environment but _are_ provided by JSDOM\n * are defined directly to the Node environment as globals. While this polutes the\n * global namespace, it is done only in the worker thread.\n * - Certain browser globals that are _not_ available in JSDOM are also provided to the\n * global namespace - things like `requestIdleCallback`, `IntersectionObserver` etc.\n * These are provided with a minimal stub implementation to make them not crash.\n *\n * @param filePath - Path to the worker file (`.ts` works and is encouraged)\n * @param options - Options to pass to the worker\n * @returns A promise that resolves with the message from the worker\n * @throws If the file does not exist\n * @throws If the worker exits with a non-zero code\n * @internal\n */\nexport function createStudioWorker(filePath: URL, options: StudioWorkerTaskOptions) {\n const normalizedFilePath = fileURLToPath(filePath)\n\n if (!/\\.worker\\.(js|ts)$/.test(normalizedFilePath)) {\n throw new Error('Studio worker tasks must include `.worker.(js|ts)` in path')\n }\n\n return new Worker(new URL('studioWorkerLoader.worker.js', import.meta.url), {\n ...options,\n env: {\n ...(isRecord(options.env) ? options.env : process.env),\n STUDIO_WORKER_STUDIO_ROOT_PATH: options.studioRootPath,\n STUDIO_WORKER_TASK_FILE: normalizedFilePath,\n },\n })\n}\n"],"names":["fileURLToPath","Worker","isRecord","promisifyWorker","studioWorkerTask","filePath","options","worker","createStudioWorker","normalizedFilePath","test","Error","URL","url","env","process","STUDIO_WORKER_STUDIO_ROOT_PATH","studioRootPath","STUDIO_WORKER_TASK_FILE"],"mappings":"AAAA,SAAQA,aAAa,QAAO,WAAU;AACtC,SAAQC,MAAM,QAA2B,sBAAqB;AAG9D,SAAQC,QAAQ,QAAO,yBAAwB;AAC/C,SAAQC,eAAe,QAAO,gCAA+B;AAW7D;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,SAASC,iBACdC,QAAa,EACbC,OAAgC;IAEhC,MAAMC,SAASC,mBAAmBH,UAAUC;IAC5C,OAAOH,gBAAmBI;AAC5B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,SAASC,mBAAmBH,QAAa,EAAEC,OAAgC;IAChF,MAAMG,qBAAqBT,cAAcK;IAEzC,IAAI,CAAC,qBAAqBK,IAAI,CAACD,qBAAqB;QAClD,MAAM,IAAIE,MAAM;IAClB;IAEA,OAAO,IAAIV,OAAO,IAAIW,IAAI,gCAAgC,YAAYC,GAAG,GAAG;QAC1E,GAAGP,OAAO;QACVQ,KAAK;YACH,GAAIZ,SAASI,QAAQQ,GAAG,IAAIR,QAAQQ,GAAG,GAAGC,QAAQD,GAAG;YACrDE,gCAAgCV,QAAQW,cAAc;YACtDC,yBAAyBT;QAC3B;IACF;AACF"}
@@ -1,9 +1,8 @@
1
- import { tsImport } from 'tsx/esm/api';
1
+ import { importModule } from '../../util/importModule.js';
2
2
  const workerScript = process.env.TSX_WORKER_TASK_SCRIPT;
3
3
  if (workerScript) {
4
- await tsImport(workerScript, {
5
- parentURL: import.meta.url,
6
- tsconfig: process.env.TSX_TSCONFIG_PATH
4
+ await importModule(workerScript, {
5
+ tsconfigPath: process.env.TSX_TSCONFIG_PATH
7
6
  });
8
7
  } else {
9
8
  throw new Error('`TX_WORKER_TASK_SCRIPT` not defined');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/loaders/tsx/tsxWorkerLoader.worker.ts"],"sourcesContent":["import {tsImport} from 'tsx/esm/api'\n\nconst workerScript = process.env.TSX_WORKER_TASK_SCRIPT\n\nif (workerScript) {\n await tsImport(workerScript, {\n parentURL: import.meta.url,\n tsconfig: process.env.TSX_TSCONFIG_PATH,\n })\n} else {\n throw new Error('`TX_WORKER_TASK_SCRIPT` not defined')\n}\n"],"names":["tsImport","workerScript","process","env","TSX_WORKER_TASK_SCRIPT","parentURL","url","tsconfig","TSX_TSCONFIG_PATH","Error"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,cAAa;AAEpC,MAAMC,eAAeC,QAAQC,GAAG,CAACC,sBAAsB;AAEvD,IAAIH,cAAc;IAChB,MAAMD,SAASC,cAAc;QAC3BI,WAAW,YAAYC,GAAG;QAC1BC,UAAUL,QAAQC,GAAG,CAACK,iBAAiB;IACzC;AACF,OAAO;IACL,MAAM,IAAIC,MAAM;AAClB"}
1
+ {"version":3,"sources":["../../../src/loaders/tsx/tsxWorkerLoader.worker.ts"],"sourcesContent":["import {importModule} from '../../util/importModule.js'\n\nconst workerScript = process.env.TSX_WORKER_TASK_SCRIPT\n\nif (workerScript) {\n await importModule(workerScript, {\n tsconfigPath: process.env.TSX_TSCONFIG_PATH,\n })\n} else {\n throw new Error('`TX_WORKER_TASK_SCRIPT` not defined')\n}\n"],"names":["importModule","workerScript","process","env","TSX_WORKER_TASK_SCRIPT","tsconfigPath","TSX_TSCONFIG_PATH","Error"],"mappings":"AAAA,SAAQA,YAAY,QAAO,6BAA4B;AAEvD,MAAMC,eAAeC,QAAQC,GAAG,CAACC,sBAAsB;AAEvD,IAAIH,cAAc;IAChB,MAAMD,aAAaC,cAAc;QAC/BI,cAAcH,QAAQC,GAAG,CAACG,iBAAiB;IAC7C;AACF,OAAO;IACL,MAAM,IAAIC,MAAM;AAClB"}
@@ -1,8 +1,8 @@
1
- import { URL } from 'node:url';
1
+ import { fileURLToPath, URL } from 'node:url';
2
2
  import { Worker } from 'node:worker_threads';
3
3
  import { getTsconfig } from 'get-tsconfig';
4
- import { debug } from '../../debug.js';
5
4
  import { isRecord } from '../../util/isRecord.js';
5
+ import { promisifyWorker } from '../../util/promisifyWorker.js';
6
6
  /**
7
7
  * Executes a worker file with tsx registered. This means you can import other
8
8
  * typescript with fairly rich syntax, and still have that only apply to the worker
@@ -24,41 +24,13 @@ import { isRecord } from '../../util/isRecord.js';
24
24
  ...tsconfig?.path ? {
25
25
  TSX_TSCONFIG_PATH: tsconfig.path
26
26
  } : {},
27
- TSX_WORKER_TASK_SCRIPT: filePath.pathname
27
+ TSX_WORKER_TASK_SCRIPT: fileURLToPath(filePath)
28
28
  };
29
29
  const worker = new Worker(new URL('tsxWorkerLoader.worker.js', import.meta.url), {
30
30
  ...options,
31
31
  env
32
32
  });
33
- return new Promise((resolve, reject)=>{
34
- worker.addListener('error', function onWorkerError(err) {
35
- debug(`Failed to load file through worker for: ${filePath.pathname}`, err);
36
- reject(new Error(`Failed to load file through worker: ${err.message}`, {
37
- cause: err
38
- }));
39
- cleanup();
40
- });
41
- worker.addListener('exit', function onWorkerExit(code) {
42
- if (code > 0) {
43
- reject(new Error(`Worker exited with code ${code}`));
44
- }
45
- });
46
- worker.addListener('messageerror', function onWorkerMessageError(err) {
47
- debug(`Failed to parse message from worker for: ${filePath.pathname}`, err);
48
- reject(new Error(`Fail to parse message from worker: ${err}`));
49
- cleanup();
50
- });
51
- worker.addListener('message', function onWorkerMessage(message) {
52
- resolve(message);
53
- cleanup();
54
- });
55
- function cleanup() {
56
- // Allow the worker a _bit_ of time to clean up, but ensure that we don't have
57
- // lingering processes hanging around forever if the worker doesn't exit on its
58
- // own.
59
- setImmediate(()=>worker.terminate());
60
- }
61
- });
33
+ return promisifyWorker(worker);
62
34
  }
63
35
 
64
36
  //# sourceMappingURL=tsxWorkerTask.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/loaders/tsx/tsxWorkerTask.ts"],"sourcesContent":["import {URL} from 'node:url'\nimport {Worker, type WorkerOptions} from 'node:worker_threads'\n\nimport {getTsconfig} from 'get-tsconfig'\n\nimport {debug} from '../../debug.js'\nimport {type RequireProps} from '../../types.js'\nimport {isRecord} from '../../util/isRecord.js'\n\n/**\n * Options for the tsx worker task\n *\n * @internal\n */\ninterface TsxWorkerTaskOptions extends RequireProps<WorkerOptions, 'name'> {\n rootPath: string\n}\n\n/**\n * Executes a worker file with tsx registered. This means you can import other\n * typescript with fairly rich syntax, and still have that only apply to the worker\n * thread instead of the full parent process. The worker should emit a message when\n * complete using `parentPort`. Once it has received a single message will resolve the\n * returned promise with that message. If you are expecting multiple messages, you will\n * have to implement another method ;)\n *\n * @param filePath - Path to the worker file\n * @param options - Options to pass to the worker\n * @returns A promise that resolves with the message from the worker\n * @throws If the file does not exist\n * @throws If the worker exits with a non-zero code\n * @internal\n */\nexport function tsxWorkerTask<T = unknown>(\n filePath: URL,\n options: TsxWorkerTaskOptions,\n): Promise<T> {\n const tsconfig = getTsconfig(options.rootPath)\n\n const env = {\n ...(isRecord(options.env) ? options.env : process.env),\n ...(tsconfig?.path ? {TSX_TSCONFIG_PATH: tsconfig.path} : {}),\n TSX_WORKER_TASK_SCRIPT: filePath.pathname,\n }\n\n const worker = new Worker(new URL('tsxWorkerLoader.worker.js', import.meta.url), {\n ...options,\n env,\n })\n\n return new Promise((resolve, reject) => {\n worker.addListener('error', function onWorkerError(err) {\n debug(`Failed to load file through worker for: ${filePath.pathname}`, err)\n reject(new Error(`Failed to load file through worker: ${err.message}`, {cause: err}))\n cleanup()\n })\n worker.addListener('exit', function onWorkerExit(code) {\n if (code > 0) {\n reject(new Error(`Worker exited with code ${code}`))\n }\n })\n worker.addListener('messageerror', function onWorkerMessageError(err) {\n debug(`Failed to parse message from worker for: ${filePath.pathname}`, err)\n reject(new Error(`Fail to parse message from worker: ${err}`))\n cleanup()\n })\n worker.addListener('message', function onWorkerMessage(message) {\n resolve(message)\n cleanup()\n })\n\n function cleanup() {\n // Allow the worker a _bit_ of time to clean up, but ensure that we don't have\n // lingering processes hanging around forever if the worker doesn't exit on its\n // own.\n setImmediate(() => worker.terminate())\n }\n })\n}\n"],"names":["URL","Worker","getTsconfig","debug","isRecord","tsxWorkerTask","filePath","options","tsconfig","rootPath","env","process","path","TSX_TSCONFIG_PATH","TSX_WORKER_TASK_SCRIPT","pathname","worker","url","Promise","resolve","reject","addListener","onWorkerError","err","Error","message","cause","cleanup","onWorkerExit","code","onWorkerMessageError","onWorkerMessage","setImmediate","terminate"],"mappings":"AAAA,SAAQA,GAAG,QAAO,WAAU;AAC5B,SAAQC,MAAM,QAA2B,sBAAqB;AAE9D,SAAQC,WAAW,QAAO,eAAc;AAExC,SAAQC,KAAK,QAAO,iBAAgB;AAEpC,SAAQC,QAAQ,QAAO,yBAAwB;AAW/C;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASC,cACdC,QAAa,EACbC,OAA6B;IAE7B,MAAMC,WAAWN,YAAYK,QAAQE,QAAQ;IAE7C,MAAMC,MAAM;QACV,GAAIN,SAASG,QAAQG,GAAG,IAAIH,QAAQG,GAAG,GAAGC,QAAQD,GAAG;QACrD,GAAIF,UAAUI,OAAO;YAACC,mBAAmBL,SAASI,IAAI;QAAA,IAAI,CAAC,CAAC;QAC5DE,wBAAwBR,SAASS,QAAQ;IAC3C;IAEA,MAAMC,SAAS,IAAIf,OAAO,IAAID,IAAI,6BAA6B,YAAYiB,GAAG,GAAG;QAC/E,GAAGV,OAAO;QACVG;IACF;IAEA,OAAO,IAAIQ,QAAQ,CAACC,SAASC;QAC3BJ,OAAOK,WAAW,CAAC,SAAS,SAASC,cAAcC,GAAG;YACpDpB,MAAM,CAAC,wCAAwC,EAAEG,SAASS,QAAQ,EAAE,EAAEQ;YACtEH,OAAO,IAAII,MAAM,CAAC,oCAAoC,EAAED,IAAIE,OAAO,EAAE,EAAE;gBAACC,OAAOH;YAAG;YAClFI;QACF;QACAX,OAAOK,WAAW,CAAC,QAAQ,SAASO,aAAaC,IAAI;YACnD,IAAIA,OAAO,GAAG;gBACZT,OAAO,IAAII,MAAM,CAAC,wBAAwB,EAAEK,MAAM;YACpD;QACF;QACAb,OAAOK,WAAW,CAAC,gBAAgB,SAASS,qBAAqBP,GAAG;YAClEpB,MAAM,CAAC,yCAAyC,EAAEG,SAASS,QAAQ,EAAE,EAAEQ;YACvEH,OAAO,IAAII,MAAM,CAAC,mCAAmC,EAAED,KAAK;YAC5DI;QACF;QACAX,OAAOK,WAAW,CAAC,WAAW,SAASU,gBAAgBN,OAAO;YAC5DN,QAAQM;YACRE;QACF;QAEA,SAASA;YACP,8EAA8E;YAC9E,+EAA+E;YAC/E,OAAO;YACPK,aAAa,IAAMhB,OAAOiB,SAAS;QACrC;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/loaders/tsx/tsxWorkerTask.ts"],"sourcesContent":["import {fileURLToPath, URL} from 'node:url'\nimport {Worker, type WorkerOptions} from 'node:worker_threads'\n\nimport {getTsconfig} from 'get-tsconfig'\n\nimport {type RequireProps} from '../../types.js'\nimport {isRecord} from '../../util/isRecord.js'\nimport {promisifyWorker} from '../../util/promisifyWorker.js'\n\n/**\n * Options for the tsx worker task\n *\n * @internal\n */\ninterface TsxWorkerTaskOptions extends RequireProps<WorkerOptions, 'name'> {\n rootPath: string\n}\n\n/**\n * Executes a worker file with tsx registered. This means you can import other\n * typescript with fairly rich syntax, and still have that only apply to the worker\n * thread instead of the full parent process. The worker should emit a message when\n * complete using `parentPort`. Once it has received a single message will resolve the\n * returned promise with that message. If you are expecting multiple messages, you will\n * have to implement another method ;)\n *\n * @param filePath - Path to the worker file\n * @param options - Options to pass to the worker\n * @returns A promise that resolves with the message from the worker\n * @throws If the file does not exist\n * @throws If the worker exits with a non-zero code\n * @internal\n */\nexport function tsxWorkerTask<T = unknown>(\n filePath: URL,\n options: TsxWorkerTaskOptions,\n): Promise<T> {\n const tsconfig = getTsconfig(options.rootPath)\n\n const env = {\n ...(isRecord(options.env) ? options.env : process.env),\n ...(tsconfig?.path ? {TSX_TSCONFIG_PATH: tsconfig.path} : {}),\n TSX_WORKER_TASK_SCRIPT: fileURLToPath(filePath),\n }\n\n const worker = new Worker(new URL('tsxWorkerLoader.worker.js', import.meta.url), {\n ...options,\n env,\n })\n\n return promisifyWorker<T>(worker)\n}\n"],"names":["fileURLToPath","URL","Worker","getTsconfig","isRecord","promisifyWorker","tsxWorkerTask","filePath","options","tsconfig","rootPath","env","process","path","TSX_TSCONFIG_PATH","TSX_WORKER_TASK_SCRIPT","worker","url"],"mappings":"AAAA,SAAQA,aAAa,EAAEC,GAAG,QAAO,WAAU;AAC3C,SAAQC,MAAM,QAA2B,sBAAqB;AAE9D,SAAQC,WAAW,QAAO,eAAc;AAGxC,SAAQC,QAAQ,QAAO,yBAAwB;AAC/C,SAAQC,eAAe,QAAO,gCAA+B;AAW7D;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASC,cACdC,QAAa,EACbC,OAA6B;IAE7B,MAAMC,WAAWN,YAAYK,QAAQE,QAAQ;IAE7C,MAAMC,MAAM;QACV,GAAIP,SAASI,QAAQG,GAAG,IAAIH,QAAQG,GAAG,GAAGC,QAAQD,GAAG;QACrD,GAAIF,UAAUI,OAAO;YAACC,mBAAmBL,SAASI,IAAI;QAAA,IAAI,CAAC,CAAC;QAC5DE,wBAAwBf,cAAcO;IACxC;IAEA,MAAMS,SAAS,IAAId,OAAO,IAAID,IAAI,6BAA6B,YAAYgB,GAAG,GAAG;QAC/E,GAAGT,OAAO;QACVG;IACF;IAEA,OAAON,gBAAmBW;AAC5B"}
@@ -0,0 +1,83 @@
1
+ import { getIt } from 'get-it';
2
+ import { debug, headers, httpErrors, promise } from 'get-it/middleware';
3
+ import { readPackageUpSync } from 'read-package-up';
4
+ let cachedPkg;
5
+ /**
6
+ * Creates a `get-it` requester with a standard set of middleware.
7
+ *
8
+ * Default middleware (in order):
9
+ * 1. `httpErrors()` — throw on HTTP error status codes
10
+ * 2. `headers({'User-Agent': '@sanity/cli-core@<version>'})` — identify CLI requests
11
+ * 3. `debug({verbose: true, namespace: 'sanity:cli'})` — debug logging
12
+ * 4. `promise({onlyBody: true})` — return body directly (must be last)
13
+ *
14
+ * @param options - Optional configuration to disable or customize middleware
15
+ * @returns A configured `get-it` requester
16
+ * @public
17
+ */ export function createRequester(options) {
18
+ const opts = options?.middleware;
19
+ const middleware = [];
20
+ // 1. httpErrors
21
+ if (opts?.httpErrors !== false) {
22
+ middleware.push(httpErrors());
23
+ }
24
+ // 2. headers
25
+ if (opts?.headers !== false) {
26
+ const customHeaders = typeof opts?.headers === 'object' ? opts.headers : {};
27
+ const allHeaders = customHeaders['User-Agent'] ? {
28
+ ...customHeaders
29
+ } : {
30
+ get ['User-Agent'] () {
31
+ const pkg = getPackageInfo();
32
+ return `${pkg.name}@${pkg.version}`;
33
+ },
34
+ ...customHeaders
35
+ };
36
+ middleware.push(headers(allHeaders));
37
+ }
38
+ // 3. debug
39
+ if (opts?.debug !== false) {
40
+ const debugDefaults = {
41
+ namespace: 'sanity:cli',
42
+ verbose: true
43
+ };
44
+ const customDebug = typeof opts?.debug === 'object' ? opts.debug : {};
45
+ middleware.push(debug({
46
+ ...debugDefaults,
47
+ ...customDebug
48
+ }));
49
+ }
50
+ // 4. promise (must be last)
51
+ if (opts?.promise !== false) {
52
+ const promiseDefaults = {
53
+ onlyBody: true
54
+ };
55
+ const customPromise = typeof opts?.promise === 'object' ? opts.promise : {};
56
+ middleware.push(promise({
57
+ ...promiseDefaults,
58
+ ...customPromise
59
+ }));
60
+ }
61
+ return getIt(middleware);
62
+ }
63
+ /**
64
+ * Reads the nearest `package.json` to determine the name and version of the `@sanity/cli-core` package.
65
+ *
66
+ * @returns The name and version of the package
67
+ * @internal
68
+ */ function getPackageInfo() {
69
+ if (cachedPkg) return cachedPkg;
70
+ const result = readPackageUpSync({
71
+ cwd: import.meta.dirname
72
+ });
73
+ if (!result) {
74
+ throw new Error('Unable to resolve @sanity/cli-core package root');
75
+ }
76
+ cachedPkg = {
77
+ name: result.packageJson.name ?? '@sanity/cli-core',
78
+ version: result.packageJson.version ?? '0.0.0'
79
+ };
80
+ return cachedPkg;
81
+ }
82
+
83
+ //# sourceMappingURL=createRequester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/request/createRequester.ts"],"sourcesContent":["import {getIt, type Requester} from 'get-it'\nimport {debug, headers, httpErrors, promise} from 'get-it/middleware'\nimport {readPackageUpSync} from 'read-package-up'\n\nlet cachedPkg: {name: string; version: string} | undefined\n\n/**\n * Options for configuring individual middleware in {@link createRequester}.\n *\n * Each key corresponds to a middleware. Omitting a key uses the default,\n * `false` disables it, and an object merges with the defaults.\n *\n * @public\n */\nexport type MiddlewareOptions = {\n debug?: false | {namespace?: string; verbose?: boolean}\n headers?: false | Record<string, string>\n httpErrors?: false\n promise?: false | {onlyBody?: boolean}\n}\n\n/**\n * Creates a `get-it` requester with a standard set of middleware.\n *\n * Default middleware (in order):\n * 1. `httpErrors()` — throw on HTTP error status codes\n * 2. `headers({'User-Agent': '@sanity/cli-core@<version>'})` — identify CLI requests\n * 3. `debug({verbose: true, namespace: 'sanity:cli'})` — debug logging\n * 4. `promise({onlyBody: true})` — return body directly (must be last)\n *\n * @param options - Optional configuration to disable or customize middleware\n * @returns A configured `get-it` requester\n * @public\n */\nexport function createRequester(options?: {middleware?: MiddlewareOptions}): Requester {\n const opts = options?.middleware\n\n const middleware = []\n\n // 1. httpErrors\n if (opts?.httpErrors !== false) {\n middleware.push(httpErrors())\n }\n\n // 2. headers\n if (opts?.headers !== false) {\n const customHeaders = typeof opts?.headers === 'object' ? opts.headers : {}\n const allHeaders = customHeaders['User-Agent']\n ? {...customHeaders}\n : {\n get ['User-Agent']() {\n const pkg = getPackageInfo()\n return `${pkg.name}@${pkg.version}`\n },\n ...customHeaders,\n }\n middleware.push(headers(allHeaders))\n }\n\n // 3. debug\n if (opts?.debug !== false) {\n const debugDefaults = {namespace: 'sanity:cli', verbose: true}\n const customDebug = typeof opts?.debug === 'object' ? opts.debug : {}\n middleware.push(debug({...debugDefaults, ...customDebug}))\n }\n\n // 4. promise (must be last)\n if (opts?.promise !== false) {\n const promiseDefaults = {onlyBody: true}\n const customPromise = typeof opts?.promise === 'object' ? opts.promise : {}\n middleware.push(promise({...promiseDefaults, ...customPromise}))\n }\n\n return getIt(middleware)\n}\n\n/**\n * Reads the nearest `package.json` to determine the name and version of the `@sanity/cli-core` package.\n *\n * @returns The name and version of the package\n * @internal\n */\nfunction getPackageInfo(): {name: string; version: string} {\n if (cachedPkg) return cachedPkg\n\n const result = readPackageUpSync({cwd: import.meta.dirname})\n if (!result) {\n throw new Error('Unable to resolve @sanity/cli-core package root')\n }\n\n cachedPkg = {\n name: result.packageJson.name ?? '@sanity/cli-core',\n version: result.packageJson.version ?? '0.0.0',\n }\n return cachedPkg\n}\n"],"names":["getIt","debug","headers","httpErrors","promise","readPackageUpSync","cachedPkg","createRequester","options","opts","middleware","push","customHeaders","allHeaders","pkg","getPackageInfo","name","version","debugDefaults","namespace","verbose","customDebug","promiseDefaults","onlyBody","customPromise","result","cwd","dirname","Error","packageJson"],"mappings":"AAAA,SAAQA,KAAK,QAAuB,SAAQ;AAC5C,SAAQC,KAAK,EAAEC,OAAO,EAAEC,UAAU,EAAEC,OAAO,QAAO,oBAAmB;AACrE,SAAQC,iBAAiB,QAAO,kBAAiB;AAEjD,IAAIC;AAiBJ;;;;;;;;;;;;CAYC,GACD,OAAO,SAASC,gBAAgBC,OAA0C;IACxE,MAAMC,OAAOD,SAASE;IAEtB,MAAMA,aAAa,EAAE;IAErB,gBAAgB;IAChB,IAAID,MAAMN,eAAe,OAAO;QAC9BO,WAAWC,IAAI,CAACR;IAClB;IAEA,aAAa;IACb,IAAIM,MAAMP,YAAY,OAAO;QAC3B,MAAMU,gBAAgB,OAAOH,MAAMP,YAAY,WAAWO,KAAKP,OAAO,GAAG,CAAC;QAC1E,MAAMW,aAAaD,aAAa,CAAC,aAAa,GAC1C;YAAC,GAAGA,aAAa;QAAA,IACjB;YACE,IAAI,CAAC,aAAa,IAAG;gBACnB,MAAME,MAAMC;gBACZ,OAAO,GAAGD,IAAIE,IAAI,CAAC,CAAC,EAAEF,IAAIG,OAAO,EAAE;YACrC;YACA,GAAGL,aAAa;QAClB;QACJF,WAAWC,IAAI,CAACT,QAAQW;IAC1B;IAEA,WAAW;IACX,IAAIJ,MAAMR,UAAU,OAAO;QACzB,MAAMiB,gBAAgB;YAACC,WAAW;YAAcC,SAAS;QAAI;QAC7D,MAAMC,cAAc,OAAOZ,MAAMR,UAAU,WAAWQ,KAAKR,KAAK,GAAG,CAAC;QACpES,WAAWC,IAAI,CAACV,MAAM;YAAC,GAAGiB,aAAa;YAAE,GAAGG,WAAW;QAAA;IACzD;IAEA,4BAA4B;IAC5B,IAAIZ,MAAML,YAAY,OAAO;QAC3B,MAAMkB,kBAAkB;YAACC,UAAU;QAAI;QACvC,MAAMC,gBAAgB,OAAOf,MAAML,YAAY,WAAWK,KAAKL,OAAO,GAAG,CAAC;QAC1EM,WAAWC,IAAI,CAACP,QAAQ;YAAC,GAAGkB,eAAe;YAAE,GAAGE,aAAa;QAAA;IAC/D;IAEA,OAAOxB,MAAMU;AACf;AAEA;;;;;CAKC,GACD,SAASK;IACP,IAAIT,WAAW,OAAOA;IAEtB,MAAMmB,SAASpB,kBAAkB;QAACqB,KAAK,YAAYC,OAAO;IAAA;IAC1D,IAAI,CAACF,QAAQ;QACX,MAAM,IAAIG,MAAM;IAClB;IAEAtB,YAAY;QACVU,MAAMS,OAAOI,WAAW,CAACb,IAAI,IAAI;QACjCC,SAASQ,OAAOI,WAAW,CAACZ,OAAO,IAAI;IACzC;IACA,OAAOX;AACT"}
@@ -0,0 +1,29 @@
1
+ import { fileURLToPath, pathToFileURL } from 'node:url';
2
+ import { createJiti } from '@rexxars/jiti';
3
+ import { subdebug } from '../debug.js';
4
+ const debug = subdebug('importModule');
5
+ /**
6
+ * Imports a module using jiti and returns its exports.
7
+ * This is a thin wrapper around tsx to allow swapping out the underlying implementation in the future if needed.
8
+ *
9
+ * @param filePath - Path to the module to import.
10
+ * @param options - Options for the importModule function.
11
+ * @returns The exported module.
12
+ *
13
+ * @internal
14
+ */ export async function importModule(filePath, options = {}) {
15
+ const { default: returnDefault = true, tsconfigPath } = options;
16
+ const jiti = createJiti(import.meta.url, {
17
+ debug: debug.enabled,
18
+ tsconfigPaths: typeof tsconfigPath === 'string' ? tsconfigPath : true
19
+ });
20
+ const fileURL = typeof filePath === 'string' ? pathToFileURL(filePath) : filePath;
21
+ debug(`Loading module: ${fileURLToPath(fileURL)}`, {
22
+ tsconfigPath
23
+ });
24
+ return jiti.import(fileURLToPath(fileURL), {
25
+ default: returnDefault
26
+ });
27
+ }
28
+
29
+ //# sourceMappingURL=importModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/importModule.ts"],"sourcesContent":["import {fileURLToPath, pathToFileURL} from 'node:url'\n\nimport {createJiti} from '@rexxars/jiti'\n\nimport {subdebug} from '../debug.js'\n\ninterface ImportModuleOptions {\n /**\n * Whether to return the default export of the module.\n */\n default?: true\n\n /**\n * Path to the tsconfig file to use for the import. If not provided, the tsconfig\n * will be inferred from the nearest `tsconfig.json` file.\n */\n tsconfigPath?: string\n}\n\nconst debug = subdebug('importModule')\n\n/**\n * Imports a module using jiti and returns its exports.\n * This is a thin wrapper around tsx to allow swapping out the underlying implementation in the future if needed.\n *\n * @param filePath - Path to the module to import.\n * @param options - Options for the importModule function.\n * @returns The exported module.\n *\n * @internal\n */\nexport async function importModule<T = unknown>(\n filePath: string | URL,\n options: ImportModuleOptions = {},\n): Promise<T> {\n const {default: returnDefault = true, tsconfigPath} = options\n\n const jiti = createJiti(import.meta.url, {\n debug: debug.enabled,\n tsconfigPaths: typeof tsconfigPath === 'string' ? tsconfigPath : true,\n })\n\n const fileURL = typeof filePath === 'string' ? pathToFileURL(filePath) : filePath\n\n debug(`Loading module: ${fileURLToPath(fileURL)}`, {tsconfigPath})\n\n return jiti.import<T>(fileURLToPath(fileURL), {default: returnDefault})\n}\n"],"names":["fileURLToPath","pathToFileURL","createJiti","subdebug","debug","importModule","filePath","options","default","returnDefault","tsconfigPath","jiti","url","enabled","tsconfigPaths","fileURL","import"],"mappings":"AAAA,SAAQA,aAAa,EAAEC,aAAa,QAAO,WAAU;AAErD,SAAQC,UAAU,QAAO,gBAAe;AAExC,SAAQC,QAAQ,QAAO,cAAa;AAepC,MAAMC,QAAQD,SAAS;AAEvB;;;;;;;;;CASC,GACD,OAAO,eAAeE,aACpBC,QAAsB,EACtBC,UAA+B,CAAC,CAAC;IAEjC,MAAM,EAACC,SAASC,gBAAgB,IAAI,EAAEC,YAAY,EAAC,GAAGH;IAEtD,MAAMI,OAAOT,WAAW,YAAYU,GAAG,EAAE;QACvCR,OAAOA,MAAMS,OAAO;QACpBC,eAAe,OAAOJ,iBAAiB,WAAWA,eAAe;IACnE;IAEA,MAAMK,UAAU,OAAOT,aAAa,WAAWL,cAAcK,YAAYA;IAEzEF,MAAM,CAAC,gBAAgB,EAAEJ,cAAce,UAAU,EAAE;QAACL;IAAY;IAEhE,OAAOC,KAAKK,MAAM,CAAIhB,cAAce,UAAU;QAACP,SAASC;IAAa;AACvE"}
@@ -0,0 +1,54 @@
1
+ import { subdebug } from '../debug.js';
2
+ const debug = subdebug('worker');
3
+ /**
4
+ * Wraps a Node.js Worker in a Promise that resolves with the first message
5
+ * the worker sends, and rejects on error, message deserialization failure,
6
+ * or non-zero exit code. The worker is terminated after a message or error
7
+ * is received.
8
+ *
9
+ * @param worker - The Worker instance to promisify
10
+ * @returns A promise that resolves with the first message from the worker
11
+ * @throws If the worker emits an error, a message deserialization error, or exits with a non-zero code
12
+ * @internal
13
+ */ export function promisifyWorker(worker) {
14
+ return new Promise((resolve, reject)=>{
15
+ let settled = false;
16
+ worker.addListener('error', function onWorkerError(err) {
17
+ settled = true;
18
+ debug(`Worker error: ${err.message}`, err);
19
+ reject(new Error(`Worker error: ${err.message}`, {
20
+ cause: err
21
+ }));
22
+ cleanup();
23
+ });
24
+ // No cleanup() here — the worker is already dead after exiting,
25
+ // so there is nothing to terminate or remove listeners from.
26
+ worker.addListener('exit', function onWorkerExit(code) {
27
+ if (code > 0) {
28
+ debug(`Worker exited with code ${code}`);
29
+ reject(new Error(`Worker exited with code ${code}`));
30
+ } else if (!settled) {
31
+ debug('Worker exited with code 0 without sending a message');
32
+ reject(new Error('Worker exited without sending a message'));
33
+ }
34
+ });
35
+ worker.addListener('messageerror', function onWorkerMessageError(err) {
36
+ settled = true;
37
+ debug(`Worker message error: ${err.message}`, err);
38
+ reject(new Error(`Failed to deserialize worker message: ${err}`));
39
+ cleanup();
40
+ });
41
+ worker.addListener('message', function onWorkerMessage(message) {
42
+ settled = true;
43
+ debug(`Worker message: ${message}`);
44
+ resolve(message);
45
+ cleanup();
46
+ });
47
+ function cleanup() {
48
+ setImmediate(()=>worker.terminate());
49
+ worker.removeAllListeners();
50
+ }
51
+ });
52
+ }
53
+
54
+ //# sourceMappingURL=promisifyWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/promisifyWorker.ts"],"sourcesContent":["import {type Worker} from 'node:worker_threads'\n\nimport {subdebug} from '../debug.js'\n\nconst debug = subdebug('worker')\n\n/**\n * Wraps a Node.js Worker in a Promise that resolves with the first message\n * the worker sends, and rejects on error, message deserialization failure,\n * or non-zero exit code. The worker is terminated after a message or error\n * is received.\n *\n * @param worker - The Worker instance to promisify\n * @returns A promise that resolves with the first message from the worker\n * @throws If the worker emits an error, a message deserialization error, or exits with a non-zero code\n * @internal\n */\nexport function promisifyWorker<T = unknown>(worker: Worker): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let settled = false\n\n worker.addListener('error', function onWorkerError(err) {\n settled = true\n debug(`Worker error: ${err.message}`, err)\n reject(new Error(`Worker error: ${err.message}`, {cause: err}))\n cleanup()\n })\n // No cleanup() here — the worker is already dead after exiting,\n // so there is nothing to terminate or remove listeners from.\n worker.addListener('exit', function onWorkerExit(code) {\n if (code > 0) {\n debug(`Worker exited with code ${code}`)\n reject(new Error(`Worker exited with code ${code}`))\n } else if (!settled) {\n debug('Worker exited with code 0 without sending a message')\n reject(new Error('Worker exited without sending a message'))\n }\n })\n worker.addListener('messageerror', function onWorkerMessageError(err) {\n settled = true\n debug(`Worker message error: ${err.message}`, err)\n reject(new Error(`Failed to deserialize worker message: ${err}`))\n cleanup()\n })\n worker.addListener('message', function onWorkerMessage(message) {\n settled = true\n debug(`Worker message: ${message}`)\n resolve(message)\n cleanup()\n })\n\n function cleanup() {\n setImmediate(() => worker.terminate())\n worker.removeAllListeners()\n }\n })\n}\n"],"names":["subdebug","debug","promisifyWorker","worker","Promise","resolve","reject","settled","addListener","onWorkerError","err","message","Error","cause","cleanup","onWorkerExit","code","onWorkerMessageError","onWorkerMessage","setImmediate","terminate","removeAllListeners"],"mappings":"AAEA,SAAQA,QAAQ,QAAO,cAAa;AAEpC,MAAMC,QAAQD,SAAS;AAEvB;;;;;;;;;;CAUC,GACD,OAAO,SAASE,gBAA6BC,MAAc;IACzD,OAAO,IAAIC,QAAW,CAACC,SAASC;QAC9B,IAAIC,UAAU;QAEdJ,OAAOK,WAAW,CAAC,SAAS,SAASC,cAAcC,GAAG;YACpDH,UAAU;YACVN,MAAM,CAAC,cAAc,EAAES,IAAIC,OAAO,EAAE,EAAED;YACtCJ,OAAO,IAAIM,MAAM,CAAC,cAAc,EAAEF,IAAIC,OAAO,EAAE,EAAE;gBAACE,OAAOH;YAAG;YAC5DI;QACF;QACA,gEAAgE;QAChE,6DAA6D;QAC7DX,OAAOK,WAAW,CAAC,QAAQ,SAASO,aAAaC,IAAI;YACnD,IAAIA,OAAO,GAAG;gBACZf,MAAM,CAAC,wBAAwB,EAAEe,MAAM;gBACvCV,OAAO,IAAIM,MAAM,CAAC,wBAAwB,EAAEI,MAAM;YACpD,OAAO,IAAI,CAACT,SAAS;gBACnBN,MAAM;gBACNK,OAAO,IAAIM,MAAM;YACnB;QACF;QACAT,OAAOK,WAAW,CAAC,gBAAgB,SAASS,qBAAqBP,GAAG;YAClEH,UAAU;YACVN,MAAM,CAAC,sBAAsB,EAAES,IAAIC,OAAO,EAAE,EAAED;YAC9CJ,OAAO,IAAIM,MAAM,CAAC,sCAAsC,EAAEF,KAAK;YAC/DI;QACF;QACAX,OAAOK,WAAW,CAAC,WAAW,SAASU,gBAAgBP,OAAO;YAC5DJ,UAAU;YACVN,MAAM,CAAC,gBAAgB,EAAEU,SAAS;YAClCN,QAAQM;YACRG;QACF;QAEA,SAASA;YACPK,aAAa,IAAMhB,OAAOiB,SAAS;YACnCjB,OAAOkB,kBAAkB;QAC3B;IACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli-core",
3
- "version": "0.1.0-alpha.13",
3
+ "version": "0.1.0-alpha.15",
4
4
  "description": "Sanity CLI core package",
5
5
  "keywords": [
6
6
  "sanity",
@@ -35,6 +35,10 @@
35
35
  "source": "./src/_exports/ux.ts",
36
36
  "default": "./dist/_exports/ux.js"
37
37
  },
38
+ "./request": {
39
+ "source": "./src/_exports/request.ts",
40
+ "default": "./dist/_exports/request.js"
41
+ },
38
42
  "./package.json": "./package.json"
39
43
  },
40
44
  "main": "./dist/index.js",
@@ -45,12 +49,15 @@
45
49
  "dependencies": {
46
50
  "@inquirer/prompts": "^8.2.0",
47
51
  "@oclif/core": "^4.8.0",
48
- "@sanity/client": "^7.14.1",
49
- "@sanity/types": "^5.9.0",
52
+ "@rexxars/jiti": "^2.6.2",
53
+ "@sanity/client": "^7.15.0",
54
+ "@sanity/types": "^5.11.0",
50
55
  "babel-plugin-react-compiler": "^1.0.0",
51
56
  "boxen": "^8.0.1",
52
57
  "configstore": "^7.0.0",
53
58
  "debug": "^4.4.3",
59
+ "get-it": "^8.7.0",
60
+ "read-package-up": "^12.0.0",
54
61
  "get-tsconfig": "^4.13.6",
55
62
  "import-meta-resolve": "^4.2.0",
56
63
  "jsdom": "^27.4.0",
@@ -66,7 +73,7 @@
66
73
  },
67
74
  "devDependencies": {
68
75
  "@eslint/compat": "^2.0.2",
69
- "@sanity/codegen": "^5.9.3",
76
+ "@sanity/codegen": "^5.9.4",
70
77
  "@sanity/pkg-utils": "^10.4.4",
71
78
  "@sanity/telemetry": "^0.8.1",
72
79
  "@swc/cli": "^0.8.0",
@@ -76,12 +83,12 @@
76
83
  "@types/node": "^20.19.33",
77
84
  "eslint": "^9.39.2",
78
85
  "publint": "^0.3.17",
79
- "sanity": "^5.9.0",
86
+ "sanity": "^5.11.0",
80
87
  "typescript": "^5.9.3",
81
88
  "vitest": "^4.0.18",
82
- "@repo/package.config": "0.0.1",
83
89
  "@repo/tsconfig": "3.70.0",
84
- "@sanity/eslint-config-cli": "0.0.0-alpha.2"
90
+ "@sanity/eslint-config-cli": "0.0.0-alpha.2",
91
+ "@repo/package.config": "0.0.1"
85
92
  },
86
93
  "peerDependencies": {
87
94
  "@sanity/telemetry": ">=0.8.1 <0.9.0"
@@ -1,15 +0,0 @@
1
- import { isMainThread, parentPort, workerData } from 'node:worker_threads';
2
- import { z } from 'zod';
3
- import { doImport } from '../../util/doImport.js';
4
- if (isMainThread || !parentPort) {
5
- throw new Error('Should only be run in a worker!');
6
- }
7
- const { configPath } = z.object({
8
- configPath: z.string()
9
- }).parse(workerData);
10
- const { default: loadedConfig } = await doImport(configPath);
11
- // This might throw on unserializable properties, but that's actually wanted in this
12
- // case, since we _need_ any unserializable props (such as vite config functions)
13
- parentPort.postMessage(loadedConfig);
14
-
15
- //# sourceMappingURL=getCliConfig.worker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/config/cli/getCliConfig.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {z} from 'zod'\n\nimport {doImport} from '../../util/doImport.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst {configPath} = z.object({configPath: z.string()}).parse(workerData)\n\nconst {default: loadedConfig} = await doImport(configPath)\n\n// This might throw on unserializable properties, but that's actually wanted in this\n// case, since we _need_ any unserializable props (such as vite config functions)\nparentPort.postMessage(loadedConfig)\n"],"names":["isMainThread","parentPort","workerData","z","doImport","Error","configPath","object","string","parse","default","loadedConfig","postMessage"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,CAAC,QAAO,MAAK;AAErB,SAAQC,QAAQ,QAAO,yBAAwB;AAE/C,IAAIJ,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAII,MAAM;AAClB;AAEA,MAAM,EAACC,UAAU,EAAC,GAAGH,EAAEI,MAAM,CAAC;IAACD,YAAYH,EAAEK,MAAM;AAAE,GAAGC,KAAK,CAACP;AAE9D,MAAM,EAACQ,SAASC,YAAY,EAAC,GAAG,MAAMP,SAASE;AAE/C,oFAAoF;AACpF,iFAAiF;AACjFL,WAAWW,WAAW,CAACD"}