@sanity/cli-core 0.0.0-20260424084316 → 0.0.0-20260428150004

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.
@@ -402,6 +402,10 @@ declare type Flags<T extends typeof Command> = Interfaces.InferredFlags<
402
402
  *
403
403
  * If loading fails the cached promise is evicted so the next call retries.
404
404
  *
405
+ * Long-lived processes that need to observe edits to `sanity.cli.(ts|js)`
406
+ * (e.g. a dev-server watcher) should use {@link getCliConfigUncached}
407
+ * instead — it bypasses both this in-memory cache and Node's module cache.
408
+ *
405
409
  * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.
406
410
  * @returns The CLI config
407
411
  * @internal
@@ -420,6 +424,26 @@ export declare function getCliConfig(rootPath: string): Promise<CliConfig>;
420
424
  */
421
425
  export declare function getCliConfigSync(rootPath: string): CliConfig;
422
426
 
427
+ /**
428
+ * Read the CLI config for a project from disk, bypassing both the
429
+ * `getCliConfig` in-memory cache and Node's module cache. Each call locates
430
+ * `sanity.cli.(ts|js)`, drops any prior jiti compilation from `require.cache`,
431
+ * re-imports, and re-validates.
432
+ *
433
+ * Use this when the config file is expected to change during the process's
434
+ * lifetime — typically a dev-server watcher that needs the new values picked
435
+ * up after each save. One-shot CLI invocations should prefer
436
+ * {@link getCliConfig} so the prerun hook, SanityCommand helpers, and action
437
+ * files share a single load.
438
+ *
439
+ * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.
440
+ * @returns The freshly loaded CLI config
441
+ * @internal
442
+ */
443
+ export declare function getCliConfigUncached(
444
+ rootPath: string,
445
+ ): Promise<CliConfig>;
446
+
423
447
  /**
424
448
  * @public
425
449
  */
@@ -1,3 +1,4 @@
1
+ import { createRequire } from 'node:module';
1
2
  import { debug } from '../../debug.js';
2
3
  import { NotFoundError } from '../../errors/NotFoundError.js';
3
4
  import { importModule } from '../../util/importModule.js';
@@ -15,6 +16,10 @@ const cache = new Map();
15
16
  *
16
17
  * If loading fails the cached promise is evicted so the next call retries.
17
18
  *
19
+ * Long-lived processes that need to observe edits to `sanity.cli.(ts|js)`
20
+ * (e.g. a dev-server watcher) should use {@link getCliConfigUncached}
21
+ * instead — it bypasses both this in-memory cache and Node's module cache.
22
+ *
18
23
  * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.
19
24
  * @returns The CLI config
20
25
  * @internal
@@ -23,14 +28,29 @@ const cache = new Map();
23
28
  if (cached) {
24
29
  return cached;
25
30
  }
26
- const promise = loadCliConfig(rootPath).catch((err)=>{
31
+ const promise = getCliConfigUncached(rootPath).catch((err)=>{
27
32
  cache.delete(rootPath);
28
33
  throw err;
29
34
  });
30
35
  cache.set(rootPath, promise);
31
36
  return promise;
32
37
  }
33
- async function loadCliConfig(rootPath) {
38
+ /**
39
+ * Read the CLI config for a project from disk, bypassing both the
40
+ * `getCliConfig` in-memory cache and Node's module cache. Each call locates
41
+ * `sanity.cli.(ts|js)`, drops any prior jiti compilation from `require.cache`,
42
+ * re-imports, and re-validates.
43
+ *
44
+ * Use this when the config file is expected to change during the process's
45
+ * lifetime — typically a dev-server watcher that needs the new values picked
46
+ * up after each save. One-shot CLI invocations should prefer
47
+ * {@link getCliConfig} so the prerun hook, SanityCommand helpers, and action
48
+ * files share a single load.
49
+ *
50
+ * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.
51
+ * @returns The freshly loaded CLI config
52
+ * @internal
53
+ */ export async function getCliConfigUncached(rootPath) {
34
54
  const paths = await findPathForFiles(rootPath, [
35
55
  'sanity.cli.ts',
36
56
  'sanity.cli.js'
@@ -44,6 +64,12 @@ async function loadCliConfig(rootPath) {
44
64
  }
45
65
  const configPath = configPaths[0].path;
46
66
  debug(`Loading CLI config from: ${configPath}`);
67
+ // Drop any cached compilation of this file from Node's CJS module cache
68
+ // (jiti compiles `sanity.cli.ts` to CJS and registers it via `require.cache`).
69
+ // Without this, repeated calls would receive the previously imported module
70
+ // even though the file on disk has changed. No-op on first load.
71
+ const cjsRequire = createRequire(import.meta.url);
72
+ delete cjsRequire.cache[configPath];
47
73
  let cliConfig;
48
74
  try {
49
75
  const result = await importModule(configPath);
@@ -1 +1 @@
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"}
1
+ {"version":3,"sources":["../../../src/config/cli/getCliConfig.ts"],"sourcesContent":["import {createRequire} from 'node:module'\n\nimport {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 * Long-lived processes that need to observe edits to `sanity.cli.(ts|js)`\n * (e.g. a dev-server watcher) should use {@link getCliConfigUncached}\n * instead — it bypasses both this in-memory cache and Node's module cache.\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 = getCliConfigUncached(rootPath).catch((err) => {\n cache.delete(rootPath)\n throw err\n })\n\n cache.set(rootPath, promise)\n return promise\n}\n\n/**\n * Read the CLI config for a project from disk, bypassing both the\n * `getCliConfig` in-memory cache and Node's module cache. Each call locates\n * `sanity.cli.(ts|js)`, drops any prior jiti compilation from `require.cache`,\n * re-imports, and re-validates.\n *\n * Use this when the config file is expected to change during the process's\n * lifetime — typically a dev-server watcher that needs the new values picked\n * up after each save. One-shot CLI invocations should prefer\n * {@link getCliConfig} so the prerun hook, SanityCommand helpers, and action\n * files share a single load.\n *\n * @param rootPath - Root path for the project, eg where `sanity.cli.(ts|js)` is located.\n * @returns The freshly loaded CLI config\n * @internal\n */\nexport async function getCliConfigUncached(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 // Drop any cached compilation of this file from Node's CJS module cache\n // (jiti compiles `sanity.cli.ts` to CJS and registers it via `require.cache`).\n // Without this, repeated calls would receive the previously imported module\n // even though the file on disk has changed. No-op on first load.\n const cjsRequire = createRequire(import.meta.url)\n delete cjsRequire.cache[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":["createRequire","debug","NotFoundError","importModule","findPathForFiles","cliConfigSchema","cache","Map","getCliConfig","rootPath","cached","get","promise","getCliConfigUncached","catch","err","delete","set","paths","configPaths","filter","path","exists","length","Error","map","join","configPath","cjsRequire","url","cliConfig","result","cause","data","error","success","safeParse","message"],"mappings":"AAAA,SAAQA,aAAa,QAAO,cAAa;AAEzC,SAAQC,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;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASC,aAAaC,QAAgB;IAC3C,MAAMC,SAASJ,MAAMK,GAAG,CAACF;IACzB,IAAIC,QAAQ;QACV,OAAOA;IACT;IAEA,MAAME,UAAUC,qBAAqBJ,UAAUK,KAAK,CAAC,CAACC;QACpDT,MAAMU,MAAM,CAACP;QACb,MAAMM;IACR;IAEAT,MAAMW,GAAG,CAACR,UAAUG;IACpB,OAAOA;AACT;AAEA;;;;;;;;;;;;;;;CAeC,GACD,OAAO,eAAeC,qBAAqBJ,QAAgB;IACzD,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,wEAAwE;IACxE,+EAA+E;IAC/E,4EAA4E;IAC5E,iEAAiE;IACjE,MAAMC,aAAa5B,cAAc,YAAY6B,GAAG;IAChD,OAAOD,WAAWtB,KAAK,CAACqB,WAAW;IAEnC,IAAIG;IACJ,IAAI;QACF,MAAMC,SAAS,MAAM5B,aAAwBwB;QAE7C1B,MAAM,yBAAyB8B;QAE/BD,YAAYC;IACd,EAAE,OAAOhB,KAAK;QACZd,MAAM,kDAAkDc;QAExD,MAAM,IAAIS,MAAM,+BAA+B;YAACQ,OAAOjB;QAAG;IAC5D;IAEA,MAAM,EAACkB,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAC,GAAG9B,gBAAgB+B,SAAS,CAACN;IACzD,IAAI,CAACK,SAAS;QACZlC,MAAM,CAAC,oBAAoB,EAAEiC,MAAMG,OAAO,EAAE;QAC5C,MAAM,IAAIb,MAAM,CAAC,oBAAoB,EAAEU,MAAMG,OAAO,EAAE,EAAE;YAACL,OAAOE;QAAK;IACvE;IAEA,OAAOD;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli-core",
3
- "version": "0.0.0-20260424084316",
3
+ "version": "0.0.0-20260428150004",
4
4
  "description": "Sanity CLI core package",
5
5
  "keywords": [
6
6
  "cli",