@sanity/cli-core 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,27 +1,29 @@
1
1
  import { dirname } from 'node:path';
2
2
  import { z } from 'zod';
3
3
  import { studioWorkerTask } from '../../loaders/studio/studioWorkerTask.js';
4
- const schemaSchema = z.object({
4
+ const schemaSchema = z.looseObject({
5
5
  name: z.string().optional(),
6
- types: z.array(z.object({}).passthrough())
6
+ types: z.array(z.looseObject({}))
7
7
  });
8
- const sourceSchema = z.object({
8
+ const sourceSchema = z.looseObject({
9
9
  dataset: z.string(),
10
10
  projectId: z.string(),
11
- schema: z.object({
11
+ schema: z.looseObject({
12
12
  _original: schemaSchema
13
13
  })
14
14
  });
15
- const singleStudioWorkspaceSchema = z.object({
15
+ // Raw workspace schema (resolvePlugins: false) - unstable_sources not yet populated
16
+ const rawWorkspaceSchema = z.looseObject({
16
17
  ...sourceSchema.shape,
17
18
  basePath: z.string().optional(),
18
19
  name: z.string().optional(),
19
20
  plugins: z.array(z.unknown()).optional(),
20
21
  schema: schemaSchema.optional(),
21
22
  title: z.string().optional(),
22
- unstable_sources: z.array(sourceSchema)
23
- }).passthrough();
24
- const studioWorkspaceSchema = z.object({
23
+ unstable_sources: z.array(sourceSchema).optional()
24
+ });
25
+ // Resolved config schema (resolvePlugins: true) - all fields required
26
+ const resolvedWorkspaceSchema = z.looseObject({
25
27
  ...sourceSchema.shape,
26
28
  basePath: z.string(),
27
29
  name: z.string(),
@@ -30,10 +32,10 @@ const studioWorkspaceSchema = z.object({
30
32
  unstable_sources: z.array(sourceSchema)
31
33
  });
32
34
  const rawConfigSchema = z.union([
33
- z.array(studioWorkspaceSchema),
34
- singleStudioWorkspaceSchema
35
+ z.array(rawWorkspaceSchema),
36
+ rawWorkspaceSchema
35
37
  ]);
36
- const resolvedConfigSchema = z.array(studioWorkspaceSchema);
38
+ const resolvedConfigSchema = z.array(resolvedWorkspaceSchema);
37
39
  export async function readStudioConfig(configPath, options) {
38
40
  const result = await studioWorkerTask(new URL('readStudioConfig.worker.js', import.meta.url), {
39
41
  name: 'studioConfig',
@@ -43,7 +45,36 @@ export async function readStudioConfig(configPath, options) {
43
45
  resolvePlugins: options.resolvePlugins
44
46
  }
45
47
  });
46
- return options.resolvePlugins ? resolvedConfigSchema.parse(result) : rawConfigSchema.parse(result);
48
+ try {
49
+ return options.resolvePlugins ? resolvedConfigSchema.parse(result) : rawConfigSchema.parse(result);
50
+ } catch (err) {
51
+ if (err instanceof z.ZodError) {
52
+ throw new Error(`Invalid studio config at ${configPath}:\n${formatZodIssues(err.issues)}`);
53
+ }
54
+ throw err;
55
+ }
56
+ }
57
+ /**
58
+ * Recursively extracts leaf-level messages from Zod issues, including
59
+ * those nested inside union errors. Note that `prettifyError` from Zod
60
+ * only gives a high-level summary for union errors, so this function is
61
+ * needed to get the full details of all validation issues in a readable format.
62
+ *
63
+ * @internal exported for testing only
64
+ */ export function formatZodIssues(issues, indent = 2) {
65
+ const lines = [];
66
+ const prefix = ' '.repeat(indent);
67
+ for (const issue of issues){
68
+ if (issue.code === 'invalid_union' && 'errors' in issue && Array.isArray(issue.errors)) {
69
+ for (const [i, unionIssues] of issue.errors.entries()){
70
+ lines.push(`${prefix}Union option ${i + 1}:`, formatZodIssues(unionIssues, indent + 2));
71
+ }
72
+ } else {
73
+ const path = issue.path.length > 0 ? ` at "${issue.path.join('.')}"` : '';
74
+ lines.push(`${prefix}- ${issue.message}${path}`);
75
+ }
76
+ }
77
+ return lines.join('\n');
47
78
  }
48
79
 
49
80
  //# sourceMappingURL=readStudioConfig.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/config/studio/readStudioConfig.ts"],"sourcesContent":["import {dirname} from 'node:path'\n\nimport {z} from 'zod'\n\nimport {studioWorkerTask} from '../../loaders/studio/studioWorkerTask.js'\n\nconst schemaSchema = z.object({\n name: z.string().optional(),\n types: z.array(z.object({}).passthrough()),\n})\n\nconst sourceSchema = z.object({\n dataset: z.string(),\n projectId: z.string(),\n schema: z.object({_original: schemaSchema}),\n})\n\nconst singleStudioWorkspaceSchema = z\n .object({\n ...sourceSchema.shape,\n basePath: z.string().optional(),\n name: z.string().optional(),\n plugins: z.array(z.unknown()).optional(),\n schema: schemaSchema.optional(),\n title: z.string().optional(),\n unstable_sources: z.array(sourceSchema),\n })\n .passthrough()\n\nconst studioWorkspaceSchema = z.object({\n ...sourceSchema.shape,\n basePath: z.string(),\n name: z.string(),\n plugins: z.array(z.unknown()).optional(),\n title: z.string(),\n unstable_sources: z.array(sourceSchema),\n})\n\nconst rawConfigSchema = z.union([z.array(studioWorkspaceSchema), singleStudioWorkspaceSchema])\nconst resolvedConfigSchema = z.array(studioWorkspaceSchema)\n\nexport type RawStudioConfig = z.infer<typeof rawConfigSchema>\nexport type ResolvedStudioConfig = z.infer<typeof resolvedConfigSchema>\n\nexport interface ReadStudioConfigOptions {\n /**\n * Whether or not to resolve the plugins defined in the config.\n *\n * In some cases, you need this in order to have the full picture of what the studio\n * would \"see\". As an example, plugins can define schema types that are not explicitly\n * defined in the users' schema types. In order to get the full picture, you need to\n * resolve the plugins, which is an asyncronous operation.\n *\n * In other cases, it might be enough to only do a shallow pass. As an example, if you\n * only need to know about the defined workspace, or the user-defined schema types,\n * this can be set to `false` - which should resolve faster (and potentially \"safer\")\n * in terms of not triggering all kinds of browser behavior that may or may not be\n * loaded as the plugins are resolved.\n */\n resolvePlugins: boolean\n}\n\nexport async function readStudioConfig(\n configPath: string,\n options: {resolvePlugins: true},\n): Promise<ResolvedStudioConfig>\n\nexport async function readStudioConfig(\n configPath: string,\n options: {resolvePlugins: false},\n): Promise<RawStudioConfig>\n\nexport async function readStudioConfig(\n configPath: string,\n options: ReadStudioConfigOptions,\n): Promise<RawStudioConfig | ResolvedStudioConfig> {\n const result = await studioWorkerTask(new URL('readStudioConfig.worker.js', import.meta.url), {\n name: 'studioConfig',\n studioRootPath: dirname(configPath),\n workerData: {configPath, resolvePlugins: options.resolvePlugins},\n })\n\n return options.resolvePlugins ? resolvedConfigSchema.parse(result) : rawConfigSchema.parse(result)\n}\n"],"names":["dirname","z","studioWorkerTask","schemaSchema","object","name","string","optional","types","array","passthrough","sourceSchema","dataset","projectId","schema","_original","singleStudioWorkspaceSchema","shape","basePath","plugins","unknown","title","unstable_sources","studioWorkspaceSchema","rawConfigSchema","union","resolvedConfigSchema","readStudioConfig","configPath","options","result","URL","url","studioRootPath","workerData","resolvePlugins","parse"],"mappings":"AAAA,SAAQA,OAAO,QAAO,YAAW;AAEjC,SAAQC,CAAC,QAAO,MAAK;AAErB,SAAQC,gBAAgB,QAAO,2CAA0C;AAEzE,MAAMC,eAAeF,EAAEG,MAAM,CAAC;IAC5BC,MAAMJ,EAAEK,MAAM,GAAGC,QAAQ;IACzBC,OAAOP,EAAEQ,KAAK,CAACR,EAAEG,MAAM,CAAC,CAAC,GAAGM,WAAW;AACzC;AAEA,MAAMC,eAAeV,EAAEG,MAAM,CAAC;IAC5BQ,SAASX,EAAEK,MAAM;IACjBO,WAAWZ,EAAEK,MAAM;IACnBQ,QAAQb,EAAEG,MAAM,CAAC;QAACW,WAAWZ;IAAY;AAC3C;AAEA,MAAMa,8BAA8Bf,EACjCG,MAAM,CAAC;IACN,GAAGO,aAAaM,KAAK;IACrBC,UAAUjB,EAAEK,MAAM,GAAGC,QAAQ;IAC7BF,MAAMJ,EAAEK,MAAM,GAAGC,QAAQ;IACzBY,SAASlB,EAAEQ,KAAK,CAACR,EAAEmB,OAAO,IAAIb,QAAQ;IACtCO,QAAQX,aAAaI,QAAQ;IAC7Bc,OAAOpB,EAAEK,MAAM,GAAGC,QAAQ;IAC1Be,kBAAkBrB,EAAEQ,KAAK,CAACE;AAC5B,GACCD,WAAW;AAEd,MAAMa,wBAAwBtB,EAAEG,MAAM,CAAC;IACrC,GAAGO,aAAaM,KAAK;IACrBC,UAAUjB,EAAEK,MAAM;IAClBD,MAAMJ,EAAEK,MAAM;IACda,SAASlB,EAAEQ,KAAK,CAACR,EAAEmB,OAAO,IAAIb,QAAQ;IACtCc,OAAOpB,EAAEK,MAAM;IACfgB,kBAAkBrB,EAAEQ,KAAK,CAACE;AAC5B;AAEA,MAAMa,kBAAkBvB,EAAEwB,KAAK,CAAC;IAACxB,EAAEQ,KAAK,CAACc;IAAwBP;CAA4B;AAC7F,MAAMU,uBAAuBzB,EAAEQ,KAAK,CAACc;AAiCrC,OAAO,eAAeI,iBACpBC,UAAkB,EAClBC,OAAgC;IAEhC,MAAMC,SAAS,MAAM5B,iBAAiB,IAAI6B,IAAI,8BAA8B,YAAYC,GAAG,GAAG;QAC5F3B,MAAM;QACN4B,gBAAgBjC,QAAQ4B;QACxBM,YAAY;YAACN;YAAYO,gBAAgBN,QAAQM,cAAc;QAAA;IACjE;IAEA,OAAON,QAAQM,cAAc,GAAGT,qBAAqBU,KAAK,CAACN,UAAUN,gBAAgBY,KAAK,CAACN;AAC7F"}
1
+ {"version":3,"sources":["../../../src/config/studio/readStudioConfig.ts"],"sourcesContent":["import {dirname} from 'node:path'\n\nimport {z} from 'zod'\n\nimport {studioWorkerTask} from '../../loaders/studio/studioWorkerTask.js'\n\nconst schemaSchema = z.looseObject({\n name: z.string().optional(),\n types: z.array(z.looseObject({})),\n})\n\nconst sourceSchema = z.looseObject({\n dataset: z.string(),\n projectId: z.string(),\n schema: z.looseObject({_original: schemaSchema}),\n})\n\n// Raw workspace schema (resolvePlugins: false) - unstable_sources not yet populated\nconst rawWorkspaceSchema = z.looseObject({\n ...sourceSchema.shape,\n basePath: z.string().optional(),\n name: z.string().optional(),\n plugins: z.array(z.unknown()).optional(),\n schema: schemaSchema.optional(),\n title: z.string().optional(),\n unstable_sources: z.array(sourceSchema).optional(),\n})\n\n// Resolved config schema (resolvePlugins: true) - all fields required\nconst resolvedWorkspaceSchema = z.looseObject({\n ...sourceSchema.shape,\n basePath: z.string(),\n name: z.string(),\n plugins: z.array(z.unknown()).optional(),\n title: z.string(),\n unstable_sources: z.array(sourceSchema),\n})\n\nconst rawConfigSchema = z.union([z.array(rawWorkspaceSchema), rawWorkspaceSchema])\nconst resolvedConfigSchema = z.array(resolvedWorkspaceSchema)\n\nexport type RawStudioConfig = z.infer<typeof rawConfigSchema>\nexport type ResolvedStudioConfig = z.infer<typeof resolvedConfigSchema>\n\nexport interface ReadStudioConfigOptions {\n /**\n * Whether or not to resolve the plugins defined in the config.\n *\n * In some cases, you need this in order to have the full picture of what the studio\n * would \"see\". As an example, plugins can define schema types that are not explicitly\n * defined in the users' schema types. In order to get the full picture, you need to\n * resolve the plugins, which is an asyncronous operation.\n *\n * In other cases, it might be enough to only do a shallow pass. As an example, if you\n * only need to know about the defined workspace, or the user-defined schema types,\n * this can be set to `false` - which should resolve faster (and potentially \"safer\")\n * in terms of not triggering all kinds of browser behavior that may or may not be\n * loaded as the plugins are resolved.\n */\n resolvePlugins: boolean\n}\n\nexport async function readStudioConfig(\n configPath: string,\n options: {resolvePlugins: true},\n): Promise<ResolvedStudioConfig>\n\nexport async function readStudioConfig(\n configPath: string,\n options: {resolvePlugins: false},\n): Promise<RawStudioConfig>\n\nexport async function readStudioConfig(\n configPath: string,\n options: ReadStudioConfigOptions,\n): Promise<RawStudioConfig | ResolvedStudioConfig> {\n const result = await studioWorkerTask(new URL('readStudioConfig.worker.js', import.meta.url), {\n name: 'studioConfig',\n studioRootPath: dirname(configPath),\n workerData: {configPath, resolvePlugins: options.resolvePlugins},\n })\n\n try {\n return options.resolvePlugins\n ? resolvedConfigSchema.parse(result)\n : rawConfigSchema.parse(result)\n } catch (err) {\n if (err instanceof z.ZodError) {\n throw new Error(`Invalid studio config at ${configPath}:\\n${formatZodIssues(err.issues)}`)\n }\n\n throw err\n }\n}\n\n/**\n * Recursively extracts leaf-level messages from Zod issues, including\n * those nested inside union errors. Note that `prettifyError` from Zod\n * only gives a high-level summary for union errors, so this function is\n * needed to get the full details of all validation issues in a readable format.\n *\n * @internal exported for testing only\n */\nexport function formatZodIssues(issues: z.core.$ZodIssue[], indent = 2): string {\n const lines: string[] = []\n const prefix = ' '.repeat(indent)\n\n for (const issue of issues) {\n if (issue.code === 'invalid_union' && 'errors' in issue && Array.isArray(issue.errors)) {\n for (const [i, unionIssues] of issue.errors.entries()) {\n lines.push(`${prefix}Union option ${i + 1}:`, formatZodIssues(unionIssues, indent + 2))\n }\n } else {\n const path = issue.path.length > 0 ? ` at \"${issue.path.join('.')}\"` : ''\n lines.push(`${prefix}- ${issue.message}${path}`)\n }\n }\n\n return lines.join('\\n')\n}\n"],"names":["dirname","z","studioWorkerTask","schemaSchema","looseObject","name","string","optional","types","array","sourceSchema","dataset","projectId","schema","_original","rawWorkspaceSchema","shape","basePath","plugins","unknown","title","unstable_sources","resolvedWorkspaceSchema","rawConfigSchema","union","resolvedConfigSchema","readStudioConfig","configPath","options","result","URL","url","studioRootPath","workerData","resolvePlugins","parse","err","ZodError","Error","formatZodIssues","issues","indent","lines","prefix","repeat","issue","code","Array","isArray","errors","i","unionIssues","entries","push","path","length","join","message"],"mappings":"AAAA,SAAQA,OAAO,QAAO,YAAW;AAEjC,SAAQC,CAAC,QAAO,MAAK;AAErB,SAAQC,gBAAgB,QAAO,2CAA0C;AAEzE,MAAMC,eAAeF,EAAEG,WAAW,CAAC;IACjCC,MAAMJ,EAAEK,MAAM,GAAGC,QAAQ;IACzBC,OAAOP,EAAEQ,KAAK,CAACR,EAAEG,WAAW,CAAC,CAAC;AAChC;AAEA,MAAMM,eAAeT,EAAEG,WAAW,CAAC;IACjCO,SAASV,EAAEK,MAAM;IACjBM,WAAWX,EAAEK,MAAM;IACnBO,QAAQZ,EAAEG,WAAW,CAAC;QAACU,WAAWX;IAAY;AAChD;AAEA,oFAAoF;AACpF,MAAMY,qBAAqBd,EAAEG,WAAW,CAAC;IACvC,GAAGM,aAAaM,KAAK;IACrBC,UAAUhB,EAAEK,MAAM,GAAGC,QAAQ;IAC7BF,MAAMJ,EAAEK,MAAM,GAAGC,QAAQ;IACzBW,SAASjB,EAAEQ,KAAK,CAACR,EAAEkB,OAAO,IAAIZ,QAAQ;IACtCM,QAAQV,aAAaI,QAAQ;IAC7Ba,OAAOnB,EAAEK,MAAM,GAAGC,QAAQ;IAC1Bc,kBAAkBpB,EAAEQ,KAAK,CAACC,cAAcH,QAAQ;AAClD;AAEA,sEAAsE;AACtE,MAAMe,0BAA0BrB,EAAEG,WAAW,CAAC;IAC5C,GAAGM,aAAaM,KAAK;IACrBC,UAAUhB,EAAEK,MAAM;IAClBD,MAAMJ,EAAEK,MAAM;IACdY,SAASjB,EAAEQ,KAAK,CAACR,EAAEkB,OAAO,IAAIZ,QAAQ;IACtCa,OAAOnB,EAAEK,MAAM;IACfe,kBAAkBpB,EAAEQ,KAAK,CAACC;AAC5B;AAEA,MAAMa,kBAAkBtB,EAAEuB,KAAK,CAAC;IAACvB,EAAEQ,KAAK,CAACM;IAAqBA;CAAmB;AACjF,MAAMU,uBAAuBxB,EAAEQ,KAAK,CAACa;AAiCrC,OAAO,eAAeI,iBACpBC,UAAkB,EAClBC,OAAgC;IAEhC,MAAMC,SAAS,MAAM3B,iBAAiB,IAAI4B,IAAI,8BAA8B,YAAYC,GAAG,GAAG;QAC5F1B,MAAM;QACN2B,gBAAgBhC,QAAQ2B;QACxBM,YAAY;YAACN;YAAYO,gBAAgBN,QAAQM,cAAc;QAAA;IACjE;IAEA,IAAI;QACF,OAAON,QAAQM,cAAc,GACzBT,qBAAqBU,KAAK,CAACN,UAC3BN,gBAAgBY,KAAK,CAACN;IAC5B,EAAE,OAAOO,KAAK;QACZ,IAAIA,eAAenC,EAAEoC,QAAQ,EAAE;YAC7B,MAAM,IAAIC,MAAM,CAAC,yBAAyB,EAAEX,WAAW,GAAG,EAAEY,gBAAgBH,IAAII,MAAM,GAAG;QAC3F;QAEA,MAAMJ;IACR;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASG,gBAAgBC,MAA0B,EAAEC,SAAS,CAAC;IACpE,MAAMC,QAAkB,EAAE;IAC1B,MAAMC,SAAS,IAAIC,MAAM,CAACH;IAE1B,KAAK,MAAMI,SAASL,OAAQ;QAC1B,IAAIK,MAAMC,IAAI,KAAK,mBAAmB,YAAYD,SAASE,MAAMC,OAAO,CAACH,MAAMI,MAAM,GAAG;YACtF,KAAK,MAAM,CAACC,GAAGC,YAAY,IAAIN,MAAMI,MAAM,CAACG,OAAO,GAAI;gBACrDV,MAAMW,IAAI,CAAC,GAAGV,OAAO,aAAa,EAAEO,IAAI,EAAE,CAAC,CAAC,EAAEX,gBAAgBY,aAAaV,SAAS;YACtF;QACF,OAAO;YACL,MAAMa,OAAOT,MAAMS,IAAI,CAACC,MAAM,GAAG,IAAI,CAAC,KAAK,EAAEV,MAAMS,IAAI,CAACE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG;YACvEd,MAAMW,IAAI,CAAC,GAAGV,OAAO,EAAE,EAAEE,MAAMY,OAAO,GAAGH,MAAM;QACjD;IACF;IAEA,OAAOZ,MAAMc,IAAI,CAAC;AACpB"}
package/dist/index.d.ts CHANGED
@@ -786,47 +786,46 @@ declare const rawConfigSchema: z.ZodUnion<
786
786
  z.ZodArray<
787
787
  z.ZodObject<
788
788
  {
789
- basePath: z.ZodString;
790
- name: z.ZodString;
789
+ basePath: z.ZodOptional<z.ZodString>;
790
+ name: z.ZodOptional<z.ZodString>;
791
791
  plugins: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
792
- title: z.ZodString;
793
- unstable_sources: z.ZodArray<
792
+ schema: z.ZodOptional<
794
793
  z.ZodObject<
795
794
  {
796
- dataset: z.ZodString;
797
- projectId: z.ZodString;
798
- schema: z.ZodObject<
799
- {
800
- _original: z.ZodObject<
801
- {
802
- name: z.ZodOptional<z.ZodString>;
803
- types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
804
- },
805
- z.core.$strip
806
- >;
807
- },
808
- z.core.$strip
809
- >;
795
+ name: z.ZodOptional<z.ZodString>;
796
+ types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
810
797
  },
811
- z.core.$strip
798
+ z.core.$loose
812
799
  >
813
800
  >;
814
- dataset: z.ZodString;
815
- projectId: z.ZodString;
816
- schema: z.ZodObject<
817
- {
818
- _original: z.ZodObject<
801
+ title: z.ZodOptional<z.ZodString>;
802
+ unstable_sources: z.ZodOptional<
803
+ z.ZodArray<
804
+ z.ZodObject<
819
805
  {
820
- name: z.ZodOptional<z.ZodString>;
821
- types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
806
+ dataset: z.ZodString;
807
+ projectId: z.ZodString;
808
+ schema: z.ZodObject<
809
+ {
810
+ _original: z.ZodObject<
811
+ {
812
+ name: z.ZodOptional<z.ZodString>;
813
+ types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
814
+ },
815
+ z.core.$loose
816
+ >;
817
+ },
818
+ z.core.$loose
819
+ >;
822
820
  },
823
- z.core.$strip
824
- >;
825
- },
826
- z.core.$strip
821
+ z.core.$loose
822
+ >
823
+ >
827
824
  >;
825
+ dataset: z.ZodString;
826
+ projectId: z.ZodString;
828
827
  },
829
- z.core.$strip
828
+ z.core.$loose
830
829
  >
831
830
  >,
832
831
  z.ZodObject<
@@ -840,29 +839,31 @@ declare const rawConfigSchema: z.ZodUnion<
840
839
  name: z.ZodOptional<z.ZodString>;
841
840
  types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
842
841
  },
843
- z.core.$strip
842
+ z.core.$loose
844
843
  >
845
844
  >;
846
845
  title: z.ZodOptional<z.ZodString>;
847
- unstable_sources: z.ZodArray<
848
- z.ZodObject<
849
- {
850
- dataset: z.ZodString;
851
- projectId: z.ZodString;
852
- schema: z.ZodObject<
853
- {
854
- _original: z.ZodObject<
855
- {
856
- name: z.ZodOptional<z.ZodString>;
857
- types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
858
- },
859
- z.core.$strip
860
- >;
861
- },
862
- z.core.$strip
863
- >;
864
- },
865
- z.core.$strip
846
+ unstable_sources: z.ZodOptional<
847
+ z.ZodArray<
848
+ z.ZodObject<
849
+ {
850
+ dataset: z.ZodString;
851
+ projectId: z.ZodString;
852
+ schema: z.ZodObject<
853
+ {
854
+ _original: z.ZodObject<
855
+ {
856
+ name: z.ZodOptional<z.ZodString>;
857
+ types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
858
+ },
859
+ z.core.$loose
860
+ >;
861
+ },
862
+ z.core.$loose
863
+ >;
864
+ },
865
+ z.core.$loose
866
+ >
866
867
  >
867
868
  >;
868
869
  dataset: z.ZodString;
@@ -928,13 +929,13 @@ declare const resolvedConfigSchema: z.ZodArray<
928
929
  name: z.ZodOptional<z.ZodString>;
929
930
  types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
930
931
  },
931
- z.core.$strip
932
+ z.core.$loose
932
933
  >;
933
934
  },
934
- z.core.$strip
935
+ z.core.$loose
935
936
  >;
936
937
  },
937
- z.core.$strip
938
+ z.core.$loose
938
939
  >
939
940
  >;
940
941
  dataset: z.ZodString;
@@ -946,13 +947,13 @@ declare const resolvedConfigSchema: z.ZodArray<
946
947
  name: z.ZodOptional<z.ZodString>;
947
948
  types: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
948
949
  },
949
- z.core.$strip
950
+ z.core.$loose
950
951
  >;
951
952
  },
952
- z.core.$strip
953
+ z.core.$loose
953
954
  >;
954
955
  },
955
- z.core.$strip
956
+ z.core.$loose
956
957
  >
957
958
  >;
958
959
 
@@ -151,7 +151,10 @@ await server.pluginContainer.buildStart({});
151
151
  // Load environment variables from `.env` files in the same way as Vite does.
152
152
  // Note that Sanity also provides environment variables through `process.env.*` for compat reasons,
153
153
  // and so we need to do the same here.
154
- const env = loadEnv(server.config.mode, server.config.envDir, viteConfig.envPrefix ?? '');
154
+ // Load ALL env vars from .env files (not just studio-prefixed ones) so non-Sanity-prefixed
155
+ // vars (e.g. NEXT_PUBLIC_*, VITE_*) are available via process.env at runtime.
156
+ // The ??= on the next line prevents overwriting existing process.env values.
157
+ const env = loadEnv(server.config.mode, server.config.envDir, '');
155
158
  for(const key in env){
156
159
  process.env[key] ??= env[key];
157
160
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/loaders/studio/studioWorkerLoader.worker.ts"],"sourcesContent":["import {dirname, resolve as resolvePath} from 'node:path'\nimport {isMainThread} from 'node:worker_threads'\n\nimport {getTsconfig} from 'get-tsconfig'\nimport {createServer, type InlineConfig, loadEnv, mergeConfig} from 'vite'\nimport {ViteNodeRunner} from 'vite-node/client'\nimport {ViteNodeServer} from 'vite-node/server'\nimport {installSourcemapsSupport} from 'vite-node/source-map'\n\nimport {getCliConfig} from '../../config/cli/getCliConfig.js'\nimport {type CliConfig} from '../../config/cli/types/cliConfig.js'\nimport {subdebug} from '../../debug.js'\nimport {isNotFoundError} from '../../errors/NotFoundError.js'\nimport {getStudioEnvironmentVariables} from '../../util/environment/getStudioEnvironmentVariables.js'\nimport {setupBrowserStubs} from '../../util/environment/setupBrowserStubs.js'\nimport {isRecord} from '../../util/isRecord.js'\n\nif (isMainThread) {\n throw new Error('Should be child of thread, not the main thread')\n}\n\nconst rootPath = process.env.STUDIO_WORKER_STUDIO_ROOT_PATH\nif (!rootPath) {\n throw new Error('Missing `STUDIO_WORKER_STUDIO_ROOT_PATH` environment variable')\n}\n\nconst debug = subdebug('studio:worker')\n\nconst workerScriptPath = process.env.STUDIO_WORKER_TASK_FILE\nif (!workerScriptPath) {\n throw new Error('Missing `STUDIO_WORKER_TASK_FILE` environment variable')\n}\n\nawait setupBrowserStubs()\n\nconst studioEnvVars = await getStudioEnvironmentVariables(rootPath)\n\n// Allow the CLI config (`sanity.cli.(js|ts)`) to define a `vite` property which can\n// extend/modify the default vite configuration for the studio.\nlet cliConfig: CliConfig | undefined\ntry {\n cliConfig = await getCliConfig(rootPath)\n} catch (err) {\n debug('Failed to load CLI config: %o', err)\n if (!isNotFoundError(err)) {\n // eslint-disable-next-line no-console\n console.warn('[warn] Failed to load CLI config:', err)\n }\n}\n\n/**\n * Reads tsconfig.json `paths` and converts them to Vite `resolve.alias` entries.\n * This allows studio projects using path aliases (e.g. `\"@/*\": [\"./src/*\"]`) to work\n * with CLI worker commands without requiring the user to manually add `vite-tsconfig-paths`.\n */\nfunction getTsconfigPathAliases(studioRootPath: string): Record<string, string> {\n const tsconfig = getTsconfig(studioRootPath)\n if (!tsconfig) return {}\n\n const {baseUrl, paths} = tsconfig.config.compilerOptions ?? {}\n if (!paths) return {}\n\n const tsconfigDir = dirname(tsconfig.path)\n const base = baseUrl ? resolvePath(tsconfigDir, baseUrl) : tsconfigDir\n\n const aliases: Record<string, string> = {}\n for (const [pattern, targets] of Object.entries(paths)) {\n if (!targets || targets.length === 0) continue\n // Only the first target is used — multiple fallback targets are not supported\n const target = targets[0]\n\n if (pattern.endsWith('/*') && target.endsWith('/*')) {\n // Wildcard: \"@/*\" => \"./src/*\" becomes \"@\" => \"/abs/path/src\"\n aliases[pattern.slice(0, -2)] = resolvePath(base, target.slice(0, -2))\n } else {\n // Exact: \"@utils\" => \"./src/utils/index\"\n aliases[pattern] = resolvePath(base, target)\n }\n }\n // Sort by key length descending so more-specific aliases take precedence\n // (e.g. \"@lib\" is matched before \"@\" when both exist)\n return Object.fromEntries(Object.entries(aliases).toSorted(([a], [b]) => b.length - a.length))\n}\n\n/**\n * Fetches and caches modules from HTTP/HTTPS URLs.\n * Vite's SSR transform treats `https://` imports as external and bypasses the plugin\n * resolve pipeline entirely, so we intercept them at the ViteNodeRunner level instead.\n */\nconst httpModuleCache = new Map<string, string>()\nasync function fetchHttpModule(url: string): Promise<{code: string}> {\n const cached = httpModuleCache.get(url)\n if (cached) return {code: cached}\n\n debug('Fetching HTTP import: %s', url)\n const response = await fetch(url, {signal: AbortSignal.timeout(30_000)})\n if (!response.ok) {\n throw new Error(`Failed to fetch module from ${url}: ${response.status} ${response.statusText}`)\n }\n\n const code = await response.text()\n httpModuleCache.set(url, code)\n return {code}\n}\n\nfunction isHttpsUrl(id: string): boolean {\n return id.startsWith('https://')\n}\n\nlet tsconfigAliases: Record<string, string> = {}\ntry {\n tsconfigAliases = getTsconfigPathAliases(rootPath)\n} catch (err) {\n debug('Failed to read tsconfig paths: %o', err)\n}\n\nconst defaultViteConfig: InlineConfig = {\n build: {target: 'node'},\n configFile: false,\n // Inject environment variables as compile-time constants for Vite\n define: Object.fromEntries(\n Object.entries(studioEnvVars).map(([key, value]) => [\n `process.env.${key}`,\n JSON.stringify(value),\n ]),\n ),\n envPrefix: cliConfig && 'app' in cliConfig ? 'SANITY_APP_' : 'SANITY_STUDIO_',\n esbuild: {\n jsx: 'automatic',\n },\n logLevel: 'error',\n optimizeDeps: {\n include: undefined,\n noDiscovery: true,\n },\n resolve: {\n alias: tsconfigAliases,\n },\n root: rootPath,\n server: {\n hmr: false,\n watch: null,\n },\n ssr: {\n /**\n * We don't want to externalize any dependencies, we want everything to run thru vite.\n * Especially for CJS compatibility, etc.\n */\n noExternal: true,\n },\n}\n\n// Merge the CLI config's Vite config with the default Vite config\nlet viteConfig = defaultViteConfig\nif (typeof cliConfig?.vite === 'function') {\n viteConfig = (await cliConfig.vite(viteConfig, {\n command: 'build',\n isSsrBuild: true,\n mode: 'production',\n })) as InlineConfig\n} else if (isRecord(cliConfig?.vite)) {\n viteConfig = mergeConfig(viteConfig, cliConfig.vite)\n}\n\ndebug('Creating Vite server with config: %o', viteConfig)\n// Vite will build the files we give it - targetting Node.js instead of the browser.\n// We include the inject plugin in order to provide the stubs for the undefined global APIs.\nconst server = await createServer(viteConfig)\n\n// Bit of a hack, but seems necessary based on the `node-vite` binary implementation\nawait server.pluginContainer.buildStart({})\n\n// Load environment variables from `.env` files in the same way as Vite does.\n// Note that Sanity also provides environment variables through `process.env.*` for compat reasons,\n// and so we need to do the same here.\nconst env = loadEnv(server.config.mode, server.config.envDir, viteConfig.envPrefix ?? '')\nfor (const key in env) {\n process.env[key] ??= env[key]\n}\n\n// Now we're providing the glue that ensures node-specific loading and execution works.\nconst node = new ViteNodeServer(server)\n\n// Should make it easier to debug any crashes in the imported code…\ninstallSourcemapsSupport({\n getSourceMap: (source) => node.getSourceMap(source),\n})\n\nconst runner = new ViteNodeRunner({\n base: server.config.base,\n async fetchModule(id) {\n // Vite's SSR transform externalizes https:// imports, so Node's ESM loader\n // would reject them. We fetch the module over HTTP and run it through Vite's\n // SSR transform to rewrite ESM export/import syntax to the __vite_ssr_*\n // format that ViteNodeRunner expects.\n if (isHttpsUrl(id)) {\n const {code: rawCode} = await fetchHttpModule(id)\n const result = await server.ssrTransform(rawCode, null, id)\n return {code: result?.code || rawCode}\n }\n return node.fetchModule(id)\n },\n resolveId(id, importer) {\n // Prevent vite-node from trying to resolve HTTP URLs through Node's resolver\n if (isHttpsUrl(id)) return {id}\n // Resolve any import from an HTTP-fetched module against the remote origin\n // (e.g. esm.sh returns `export * from '/pkg@1.0/es2022/pkg.mjs'`)\n if (importer && isHttpsUrl(importer)) {\n return {id: new URL(id, importer).href}\n }\n return node.resolveId(id, importer)\n },\n root: server.config.root,\n})\n\n// Copied from `vite-node` - it appears that this applies the `define` config from\n// vite, but it also takes a surprisingly long time to execute. Not clear at this\n// point why this is, so we should investigate whether it's necessary or not.\nawait runner.executeId('/@vite/env')\n\nawait runner.executeId(workerScriptPath)\n"],"names":["dirname","resolve","resolvePath","isMainThread","getTsconfig","createServer","loadEnv","mergeConfig","ViteNodeRunner","ViteNodeServer","installSourcemapsSupport","getCliConfig","subdebug","isNotFoundError","getStudioEnvironmentVariables","setupBrowserStubs","isRecord","Error","rootPath","process","env","STUDIO_WORKER_STUDIO_ROOT_PATH","debug","workerScriptPath","STUDIO_WORKER_TASK_FILE","studioEnvVars","cliConfig","err","console","warn","getTsconfigPathAliases","studioRootPath","tsconfig","baseUrl","paths","config","compilerOptions","tsconfigDir","path","base","aliases","pattern","targets","Object","entries","length","target","endsWith","slice","fromEntries","toSorted","a","b","httpModuleCache","Map","fetchHttpModule","url","cached","get","code","response","fetch","signal","AbortSignal","timeout","ok","status","statusText","text","set","isHttpsUrl","id","startsWith","tsconfigAliases","defaultViteConfig","build","configFile","define","map","key","value","JSON","stringify","envPrefix","esbuild","jsx","logLevel","optimizeDeps","include","undefined","noDiscovery","alias","root","server","hmr","watch","ssr","noExternal","viteConfig","vite","command","isSsrBuild","mode","pluginContainer","buildStart","envDir","node","getSourceMap","source","runner","fetchModule","rawCode","result","ssrTransform","resolveId","importer","URL","href","executeId"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/loaders/studio/studioWorkerLoader.worker.ts"],"sourcesContent":["import {dirname, resolve as resolvePath} from 'node:path'\nimport {isMainThread} from 'node:worker_threads'\n\nimport {getTsconfig} from 'get-tsconfig'\nimport {createServer, type InlineConfig, loadEnv, mergeConfig} from 'vite'\nimport {ViteNodeRunner} from 'vite-node/client'\nimport {ViteNodeServer} from 'vite-node/server'\nimport {installSourcemapsSupport} from 'vite-node/source-map'\n\nimport {getCliConfig} from '../../config/cli/getCliConfig.js'\nimport {type CliConfig} from '../../config/cli/types/cliConfig.js'\nimport {subdebug} from '../../debug.js'\nimport {isNotFoundError} from '../../errors/NotFoundError.js'\nimport {getStudioEnvironmentVariables} from '../../util/environment/getStudioEnvironmentVariables.js'\nimport {setupBrowserStubs} from '../../util/environment/setupBrowserStubs.js'\nimport {isRecord} from '../../util/isRecord.js'\n\nif (isMainThread) {\n throw new Error('Should be child of thread, not the main thread')\n}\n\nconst rootPath = process.env.STUDIO_WORKER_STUDIO_ROOT_PATH\nif (!rootPath) {\n throw new Error('Missing `STUDIO_WORKER_STUDIO_ROOT_PATH` environment variable')\n}\n\nconst debug = subdebug('studio:worker')\n\nconst workerScriptPath = process.env.STUDIO_WORKER_TASK_FILE\nif (!workerScriptPath) {\n throw new Error('Missing `STUDIO_WORKER_TASK_FILE` environment variable')\n}\n\nawait setupBrowserStubs()\n\nconst studioEnvVars = await getStudioEnvironmentVariables(rootPath)\n\n// Allow the CLI config (`sanity.cli.(js|ts)`) to define a `vite` property which can\n// extend/modify the default vite configuration for the studio.\nlet cliConfig: CliConfig | undefined\ntry {\n cliConfig = await getCliConfig(rootPath)\n} catch (err) {\n debug('Failed to load CLI config: %o', err)\n if (!isNotFoundError(err)) {\n // eslint-disable-next-line no-console\n console.warn('[warn] Failed to load CLI config:', err)\n }\n}\n\n/**\n * Reads tsconfig.json `paths` and converts them to Vite `resolve.alias` entries.\n * This allows studio projects using path aliases (e.g. `\"@/*\": [\"./src/*\"]`) to work\n * with CLI worker commands without requiring the user to manually add `vite-tsconfig-paths`.\n */\nfunction getTsconfigPathAliases(studioRootPath: string): Record<string, string> {\n const tsconfig = getTsconfig(studioRootPath)\n if (!tsconfig) return {}\n\n const {baseUrl, paths} = tsconfig.config.compilerOptions ?? {}\n if (!paths) return {}\n\n const tsconfigDir = dirname(tsconfig.path)\n const base = baseUrl ? resolvePath(tsconfigDir, baseUrl) : tsconfigDir\n\n const aliases: Record<string, string> = {}\n for (const [pattern, targets] of Object.entries(paths)) {\n if (!targets || targets.length === 0) continue\n // Only the first target is used — multiple fallback targets are not supported\n const target = targets[0]\n\n if (pattern.endsWith('/*') && target.endsWith('/*')) {\n // Wildcard: \"@/*\" => \"./src/*\" becomes \"@\" => \"/abs/path/src\"\n aliases[pattern.slice(0, -2)] = resolvePath(base, target.slice(0, -2))\n } else {\n // Exact: \"@utils\" => \"./src/utils/index\"\n aliases[pattern] = resolvePath(base, target)\n }\n }\n // Sort by key length descending so more-specific aliases take precedence\n // (e.g. \"@lib\" is matched before \"@\" when both exist)\n return Object.fromEntries(Object.entries(aliases).toSorted(([a], [b]) => b.length - a.length))\n}\n\n/**\n * Fetches and caches modules from HTTP/HTTPS URLs.\n * Vite's SSR transform treats `https://` imports as external and bypasses the plugin\n * resolve pipeline entirely, so we intercept them at the ViteNodeRunner level instead.\n */\nconst httpModuleCache = new Map<string, string>()\nasync function fetchHttpModule(url: string): Promise<{code: string}> {\n const cached = httpModuleCache.get(url)\n if (cached) return {code: cached}\n\n debug('Fetching HTTP import: %s', url)\n const response = await fetch(url, {signal: AbortSignal.timeout(30_000)})\n if (!response.ok) {\n throw new Error(`Failed to fetch module from ${url}: ${response.status} ${response.statusText}`)\n }\n\n const code = await response.text()\n httpModuleCache.set(url, code)\n return {code}\n}\n\nfunction isHttpsUrl(id: string): boolean {\n return id.startsWith('https://')\n}\n\nlet tsconfigAliases: Record<string, string> = {}\ntry {\n tsconfigAliases = getTsconfigPathAliases(rootPath)\n} catch (err) {\n debug('Failed to read tsconfig paths: %o', err)\n}\n\nconst defaultViteConfig: InlineConfig = {\n build: {target: 'node'},\n configFile: false,\n // Inject environment variables as compile-time constants for Vite\n define: Object.fromEntries(\n Object.entries(studioEnvVars).map(([key, value]) => [\n `process.env.${key}`,\n JSON.stringify(value),\n ]),\n ),\n envPrefix: cliConfig && 'app' in cliConfig ? 'SANITY_APP_' : 'SANITY_STUDIO_',\n esbuild: {\n jsx: 'automatic',\n },\n logLevel: 'error',\n optimizeDeps: {\n include: undefined,\n noDiscovery: true,\n },\n resolve: {\n alias: tsconfigAliases,\n },\n root: rootPath,\n server: {\n hmr: false,\n watch: null,\n },\n ssr: {\n /**\n * We don't want to externalize any dependencies, we want everything to run thru vite.\n * Especially for CJS compatibility, etc.\n */\n noExternal: true,\n },\n}\n\n// Merge the CLI config's Vite config with the default Vite config\nlet viteConfig = defaultViteConfig\nif (typeof cliConfig?.vite === 'function') {\n viteConfig = (await cliConfig.vite(viteConfig, {\n command: 'build',\n isSsrBuild: true,\n mode: 'production',\n })) as InlineConfig\n} else if (isRecord(cliConfig?.vite)) {\n viteConfig = mergeConfig(viteConfig, cliConfig.vite)\n}\n\ndebug('Creating Vite server with config: %o', viteConfig)\n// Vite will build the files we give it - targetting Node.js instead of the browser.\n// We include the inject plugin in order to provide the stubs for the undefined global APIs.\nconst server = await createServer(viteConfig)\n\n// Bit of a hack, but seems necessary based on the `node-vite` binary implementation\nawait server.pluginContainer.buildStart({})\n\n// Load environment variables from `.env` files in the same way as Vite does.\n// Note that Sanity also provides environment variables through `process.env.*` for compat reasons,\n// and so we need to do the same here.\n// Load ALL env vars from .env files (not just studio-prefixed ones) so non-Sanity-prefixed\n// vars (e.g. NEXT_PUBLIC_*, VITE_*) are available via process.env at runtime.\n// The ??= on the next line prevents overwriting existing process.env values.\nconst env = loadEnv(server.config.mode, server.config.envDir, '')\nfor (const key in env) {\n process.env[key] ??= env[key]\n}\n\n// Now we're providing the glue that ensures node-specific loading and execution works.\nconst node = new ViteNodeServer(server)\n\n// Should make it easier to debug any crashes in the imported code…\ninstallSourcemapsSupport({\n getSourceMap: (source) => node.getSourceMap(source),\n})\n\nconst runner = new ViteNodeRunner({\n base: server.config.base,\n async fetchModule(id) {\n // Vite's SSR transform externalizes https:// imports, so Node's ESM loader\n // would reject them. We fetch the module over HTTP and run it through Vite's\n // SSR transform to rewrite ESM export/import syntax to the __vite_ssr_*\n // format that ViteNodeRunner expects.\n if (isHttpsUrl(id)) {\n const {code: rawCode} = await fetchHttpModule(id)\n const result = await server.ssrTransform(rawCode, null, id)\n return {code: result?.code || rawCode}\n }\n return node.fetchModule(id)\n },\n resolveId(id, importer) {\n // Prevent vite-node from trying to resolve HTTP URLs through Node's resolver\n if (isHttpsUrl(id)) return {id}\n // Resolve any import from an HTTP-fetched module against the remote origin\n // (e.g. esm.sh returns `export * from '/pkg@1.0/es2022/pkg.mjs'`)\n if (importer && isHttpsUrl(importer)) {\n return {id: new URL(id, importer).href}\n }\n return node.resolveId(id, importer)\n },\n root: server.config.root,\n})\n\n// Copied from `vite-node` - it appears that this applies the `define` config from\n// vite, but it also takes a surprisingly long time to execute. Not clear at this\n// point why this is, so we should investigate whether it's necessary or not.\nawait runner.executeId('/@vite/env')\n\nawait runner.executeId(workerScriptPath)\n"],"names":["dirname","resolve","resolvePath","isMainThread","getTsconfig","createServer","loadEnv","mergeConfig","ViteNodeRunner","ViteNodeServer","installSourcemapsSupport","getCliConfig","subdebug","isNotFoundError","getStudioEnvironmentVariables","setupBrowserStubs","isRecord","Error","rootPath","process","env","STUDIO_WORKER_STUDIO_ROOT_PATH","debug","workerScriptPath","STUDIO_WORKER_TASK_FILE","studioEnvVars","cliConfig","err","console","warn","getTsconfigPathAliases","studioRootPath","tsconfig","baseUrl","paths","config","compilerOptions","tsconfigDir","path","base","aliases","pattern","targets","Object","entries","length","target","endsWith","slice","fromEntries","toSorted","a","b","httpModuleCache","Map","fetchHttpModule","url","cached","get","code","response","fetch","signal","AbortSignal","timeout","ok","status","statusText","text","set","isHttpsUrl","id","startsWith","tsconfigAliases","defaultViteConfig","build","configFile","define","map","key","value","JSON","stringify","envPrefix","esbuild","jsx","logLevel","optimizeDeps","include","undefined","noDiscovery","alias","root","server","hmr","watch","ssr","noExternal","viteConfig","vite","command","isSsrBuild","mode","pluginContainer","buildStart","envDir","node","getSourceMap","source","runner","fetchModule","rawCode","result","ssrTransform","resolveId","importer","URL","href","executeId"],"mappings":"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"}
@@ -18,10 +18,9 @@ import { getBrowserStubs } from './stubs.js';
18
18
  const mockedGlobalThis = globalThis;
19
19
  const stubbedKeys = [];
20
20
  for (const key of Object.keys(stubs)){
21
- if (!(key in mockedGlobalThis)) {
22
- mockedGlobalThis[key] = stubs[key];
23
- stubbedKeys.push(key);
24
- }
21
+ if (key in mockedGlobalThis) continue;
22
+ mockedGlobalThis[key] = stubs[key];
23
+ stubbedKeys.push(key);
25
24
  }
26
25
  // Add marker to window to detect double-mocking
27
26
  if (globalThis.window) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/util/environment/setupBrowserStubs.ts"],"sourcesContent":["import {getBrowserStubs} from './stubs.js'\n\n/**\n * Sets up browser globals (window, document, etc.) in the global scope.\n *\n * This is used by both mockBrowserEnvironment (for child processes) and\n * studioWorkerLoader (for worker threads) to provide a browser-like environment.\n *\n * @returns A cleanup function that removes the injected globals\n * @internal\n */\nexport async function setupBrowserStubs(): Promise<() => void> {\n // Guard against double-registering\n if (globalThis.window && '__mockedBySanity' in globalThis.window) {\n return () => {\n /* intentional noop - already mocked */\n }\n }\n\n // Inject browser stubs into global scope\n const stubs = getBrowserStubs()\n const mockedGlobalThis: Record<string, unknown> = globalThis\n const stubbedKeys: string[] = []\n\n for (const key of Object.keys(stubs)) {\n if (!(key in mockedGlobalThis)) {\n mockedGlobalThis[key] = stubs[key]\n stubbedKeys.push(key)\n }\n }\n\n // Add marker to window to detect double-mocking\n if (globalThis.window) {\n ;(globalThis.window as unknown as Record<string, unknown>).__mockedBySanity = true\n }\n\n // Return cleanup function\n return () => {\n // Remove marker before deleting window\n if (globalThis.window) {\n delete (globalThis.window as unknown as Record<string, unknown>).__mockedBySanity\n }\n\n for (const key of stubbedKeys) {\n delete mockedGlobalThis[key]\n }\n }\n}\n"],"names":["getBrowserStubs","setupBrowserStubs","globalThis","window","stubs","mockedGlobalThis","stubbedKeys","key","Object","keys","push","__mockedBySanity"],"mappings":"AAAA,SAAQA,eAAe,QAAO,aAAY;AAE1C;;;;;;;;CAQC,GACD,OAAO,eAAeC;IACpB,mCAAmC;IACnC,IAAIC,WAAWC,MAAM,IAAI,sBAAsBD,WAAWC,MAAM,EAAE;QAChE,OAAO;QACL,qCAAqC,GACvC;IACF;IAEA,yCAAyC;IACzC,MAAMC,QAAQJ;IACd,MAAMK,mBAA4CH;IAClD,MAAMI,cAAwB,EAAE;IAEhC,KAAK,MAAMC,OAAOC,OAAOC,IAAI,CAACL,OAAQ;QACpC,IAAI,CAAEG,CAAAA,OAAOF,gBAAe,GAAI;YAC9BA,gBAAgB,CAACE,IAAI,GAAGH,KAAK,CAACG,IAAI;YAClCD,YAAYI,IAAI,CAACH;QACnB;IACF;IAEA,gDAAgD;IAChD,IAAIL,WAAWC,MAAM,EAAE;;QACnBD,WAAWC,MAAM,CAAwCQ,gBAAgB,GAAG;IAChF;IAEA,0BAA0B;IAC1B,OAAO;QACL,uCAAuC;QACvC,IAAIT,WAAWC,MAAM,EAAE;YACrB,OAAO,AAACD,WAAWC,MAAM,CAAwCQ,gBAAgB;QACnF;QAEA,KAAK,MAAMJ,OAAOD,YAAa;YAC7B,OAAOD,gBAAgB,CAACE,IAAI;QAC9B;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/util/environment/setupBrowserStubs.ts"],"sourcesContent":["import {getBrowserStubs} from './stubs.js'\n\n/**\n * Sets up browser globals (window, document, etc.) in the global scope.\n *\n * This is used by both mockBrowserEnvironment (for child processes) and\n * studioWorkerLoader (for worker threads) to provide a browser-like environment.\n *\n * @returns A cleanup function that removes the injected globals\n * @internal\n */\nexport async function setupBrowserStubs(): Promise<() => void> {\n // Guard against double-registering\n if (globalThis.window && '__mockedBySanity' in globalThis.window) {\n return () => {\n /* intentional noop - already mocked */\n }\n }\n\n // Inject browser stubs into global scope\n const stubs = getBrowserStubs()\n const mockedGlobalThis: Record<string, unknown> = globalThis\n const stubbedKeys: string[] = []\n\n for (const key of Object.keys(stubs)) {\n if (key in mockedGlobalThis) continue\n mockedGlobalThis[key] = stubs[key]\n stubbedKeys.push(key)\n }\n\n // Add marker to window to detect double-mocking\n if (globalThis.window) {\n ;(globalThis.window as unknown as Record<string, unknown>).__mockedBySanity = true\n }\n\n // Return cleanup function\n return () => {\n // Remove marker before deleting window\n if (globalThis.window) {\n delete (globalThis.window as unknown as Record<string, unknown>).__mockedBySanity\n }\n\n for (const key of stubbedKeys) {\n delete mockedGlobalThis[key]\n }\n }\n}\n"],"names":["getBrowserStubs","setupBrowserStubs","globalThis","window","stubs","mockedGlobalThis","stubbedKeys","key","Object","keys","push","__mockedBySanity"],"mappings":"AAAA,SAAQA,eAAe,QAAO,aAAY;AAE1C;;;;;;;;CAQC,GACD,OAAO,eAAeC;IACpB,mCAAmC;IACnC,IAAIC,WAAWC,MAAM,IAAI,sBAAsBD,WAAWC,MAAM,EAAE;QAChE,OAAO;QACL,qCAAqC,GACvC;IACF;IAEA,yCAAyC;IACzC,MAAMC,QAAQJ;IACd,MAAMK,mBAA4CH;IAClD,MAAMI,cAAwB,EAAE;IAEhC,KAAK,MAAMC,OAAOC,OAAOC,IAAI,CAACL,OAAQ;QACpC,IAAIG,OAAOF,kBAAkB;QAC7BA,gBAAgB,CAACE,IAAI,GAAGH,KAAK,CAACG,IAAI;QAClCD,YAAYI,IAAI,CAACH;IACnB;IAEA,gDAAgD;IAChD,IAAIL,WAAWC,MAAM,EAAE;;QACnBD,WAAWC,MAAM,CAAwCQ,gBAAgB,GAAG;IAChF;IAEA,0BAA0B;IAC1B,OAAO;QACL,uCAAuC;QACvC,IAAIT,WAAWC,MAAM,EAAE;YACrB,OAAO,AAACD,WAAWC,MAAM,CAAwCQ,gBAAgB;QACnF;QAEA,KAAK,MAAMJ,OAAOD,YAAa;YAC7B,OAAOD,gBAAgB,CAACE,IAAI;QAC9B;IACF;AACF"}
@@ -4,6 +4,41 @@ const html = `<!doctype html>
4
4
  <head><meta charset="utf-8"></head>
5
5
  <body></body>
6
6
  </html>`;
7
+ function isAbortSignalLike(value) {
8
+ return !!value && typeof value === 'object' && 'aborted' in value && typeof value.aborted === 'boolean' && 'addEventListener' in value && typeof value.addEventListener === 'function' && 'removeEventListener' in value && typeof value.removeEventListener === 'function';
9
+ }
10
+ /**
11
+ * Make JSDOM's `addEventListener({signal})` accept native Node.js AbortSignals.
12
+ *
13
+ * JSDOM validates `signal` using its own realm's `AbortSignal` constructor, which rejects
14
+ * Node's native signal. Instead of replacing the global Abort APIs, intercept those calls
15
+ * and emulate the abortable-listener behavior for cross-realm signals.
16
+ */ function patchEventTargetSignalSupport(dom) {
17
+ const eventTarget = dom.window.EventTarget;
18
+ const addEventListener = eventTarget.prototype.addEventListener;
19
+ eventTarget.prototype.addEventListener = function addEventListenerPatched(type, listener, options) {
20
+ if (typeof options === 'boolean' || !options?.signal) {
21
+ return addEventListener.call(this, type, listener, options);
22
+ }
23
+ const rawSignal = options.signal;
24
+ const isJSDOMSignal = rawSignal instanceof dom.window.AbortSignal;
25
+ if (!rawSignal || isJSDOMSignal || !isAbortSignalLike(rawSignal)) {
26
+ return addEventListener.call(this, type, listener, options);
27
+ }
28
+ const signal = rawSignal;
29
+ if (signal.aborted) {
30
+ return;
31
+ }
32
+ const { signal: _signal, ...optionsWithoutSignal } = options;
33
+ addEventListener.call(this, type, listener, optionsWithoutSignal);
34
+ const removeOnAbort = ()=>{
35
+ this.removeEventListener(type, listener, options);
36
+ };
37
+ signal.addEventListener('abort', removeOnAbort, {
38
+ once: true
39
+ });
40
+ };
41
+ }
7
42
  /**
8
43
  * Creates a JSDOM instance and applies polyfills for missing browser globals.
9
44
  */ function createBrowserDom() {
@@ -11,6 +46,7 @@ const html = `<!doctype html>
11
46
  pretendToBeVisual: true,
12
47
  url: 'http://localhost:3333/'
13
48
  });
49
+ patchEventTargetSignalSupport(dom);
14
50
  // Special handling of certain globals
15
51
  if (typeof dom.window.document.execCommand !== 'function') {
16
52
  // Crashes ace editor without this :/
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/util/environment/stubs.ts"],"sourcesContent":["import {JSDOM} from 'jsdom'\n\nconst html = `<!doctype html>\n<html>\n <head><meta charset=\"utf-8\"></head>\n <body></body>\n</html>`\n\n/**\n * Creates a JSDOM instance and applies polyfills for missing browser globals.\n */\nfunction createBrowserDom(): JSDOM {\n const dom = new JSDOM(html, {\n pretendToBeVisual: true,\n url: 'http://localhost:3333/',\n })\n\n // Special handling of certain globals\n if (typeof dom.window.document.execCommand !== 'function') {\n // Crashes ace editor without this :/\n dom.window.document.execCommand = function execCommand(\n // Provide the right arity for the function, even if unused\n _commandName: string,\n _showDefaultUI: boolean,\n _valueArgument: unknown,\n ) {\n // Return false to indicate \"unsupported\"\n return false\n }\n }\n\n if (dom.window.requestIdleCallback === undefined) {\n dom.window.requestIdleCallback = (cb: IdleRequestCallback) => setTimeout(cb, 10)\n }\n\n if (dom.window.cancelIdleCallback === undefined) {\n dom.window.cancelIdleCallback = (id: number) => clearTimeout(id)\n }\n\n if (dom.window.ResizeObserver === undefined) {\n dom.window.ResizeObserver = class ResizeObserver {\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(_callback: unknown) {}\n disconnect() {}\n observe(_target: unknown, _options: unknown) {}\n unobserve(_target: unknown) {}\n }\n }\n\n if (dom.window.IntersectionObserver === undefined) {\n dom.window.IntersectionObserver = class IntersectionObserver {\n options: {root?: unknown; rootMargin?: string; threshold?: number}\n constructor(\n _callback: unknown,\n options?: {root?: unknown; rootMargin?: string; threshold?: number},\n ) {\n this.options = options || {}\n }\n get root() {\n return this.options.root || null\n }\n get rootMargin() {\n return this.options.rootMargin || ''\n }\n get thresholds() {\n return Array.isArray(this.options.threshold)\n ? this.options.threshold\n : [this.options.threshold || 0]\n }\n\n disconnect() {}\n observe(_el: unknown) {}\n takeRecords() {\n return []\n }\n unobserve(_el: unknown) {}\n }\n }\n\n if (dom.window.matchMedia === undefined) {\n dom.window.matchMedia = (_qs: unknown) =>\n ({\n matches: false,\n media: '',\n onchange: null,\n }) as MediaQueryList\n }\n\n return dom\n}\n\n/**\n * Collects all browser globals from the JSDOM window that should be injected\n * into the Node.js global scope to emulate a browser environment.\n *\n * This dynamically iterates over all own properties of the JSDOM window,\n * skipping internal JSDOM properties (prefixed with `_`) and properties that\n * already exist in Node.js globals to avoid conflicts.\n *\n * This approach ensures that any new properties added by JSDOM upgrades are\n * automatically included, preventing \"missing global\" bugs (e.g. `Element`,\n * `HTMLElement`, `SVGElement` needed by libraries like styled-components).\n */\nfunction collectBrowserStubs(): Record<string, unknown> {\n const dom = createBrowserDom()\n const stubs: Record<string, unknown> = Object.create(null)\n const nodeGlobals = new Set(Object.getOwnPropertyNames(globalThis))\n\n for (const key of Object.getOwnPropertyNames(dom.window)) {\n // Skip internal JSDOM properties\n if (key.startsWith('_')) continue\n\n // Skip numeric indices (e.g. '0' for window[0])\n if (/^\\d+$/.test(key)) continue\n\n // Skip properties that Node.js already provides to avoid conflicts\n if (nodeGlobals.has(key)) continue\n\n stubs[key] = (dom.window as Record<string, unknown>)[key]\n }\n\n return stubs\n}\n\nlet browserStubs: Record<string, unknown> | undefined\n\nexport function getBrowserStubs(): Record<string, unknown> {\n if (!browserStubs) {\n browserStubs = collectBrowserStubs()\n }\n return browserStubs\n}\n"],"names":["JSDOM","html","createBrowserDom","dom","pretendToBeVisual","url","window","document","execCommand","_commandName","_showDefaultUI","_valueArgument","requestIdleCallback","undefined","cb","setTimeout","cancelIdleCallback","id","clearTimeout","ResizeObserver","_callback","disconnect","observe","_target","_options","unobserve","IntersectionObserver","options","root","rootMargin","thresholds","Array","isArray","threshold","_el","takeRecords","matchMedia","_qs","matches","media","onchange","collectBrowserStubs","stubs","Object","create","nodeGlobals","Set","getOwnPropertyNames","globalThis","key","startsWith","test","has","browserStubs","getBrowserStubs"],"mappings":"AAAA,SAAQA,KAAK,QAAO,QAAO;AAE3B,MAAMC,OAAO,CAAC;;;;OAIP,CAAC;AAER;;CAEC,GACD,SAASC;IACP,MAAMC,MAAM,IAAIH,MAAMC,MAAM;QAC1BG,mBAAmB;QACnBC,KAAK;IACP;IAEA,sCAAsC;IACtC,IAAI,OAAOF,IAAIG,MAAM,CAACC,QAAQ,CAACC,WAAW,KAAK,YAAY;QACzD,qCAAqC;QACrCL,IAAIG,MAAM,CAACC,QAAQ,CAACC,WAAW,GAAG,SAASA,YACzC,2DAA2D;QAC3DC,YAAoB,EACpBC,cAAuB,EACvBC,cAAuB;YAEvB,yCAAyC;YACzC,OAAO;QACT;IACF;IAEA,IAAIR,IAAIG,MAAM,CAACM,mBAAmB,KAAKC,WAAW;QAChDV,IAAIG,MAAM,CAACM,mBAAmB,GAAG,CAACE,KAA4BC,WAAWD,IAAI;IAC/E;IAEA,IAAIX,IAAIG,MAAM,CAACU,kBAAkB,KAAKH,WAAW;QAC/CV,IAAIG,MAAM,CAACU,kBAAkB,GAAG,CAACC,KAAeC,aAAaD;IAC/D;IAEA,IAAId,IAAIG,MAAM,CAACa,cAAc,KAAKN,WAAW;QAC3CV,IAAIG,MAAM,CAACa,cAAc,GAAG,MAAMA;YAChC,qEAAqE;YACrE,YAAYC,SAAkB,CAAE,CAAC;YACjCC,aAAa,CAAC;YACdC,QAAQC,OAAgB,EAAEC,QAAiB,EAAE,CAAC;YAC9CC,UAAUF,OAAgB,EAAE,CAAC;QAC/B;IACF;IAEA,IAAIpB,IAAIG,MAAM,CAACoB,oBAAoB,KAAKb,WAAW;QACjDV,IAAIG,MAAM,CAACoB,oBAAoB,GAAG,MAAMA;YACtCC,QAAkE;YAClE,YACEP,SAAkB,EAClBO,OAAmE,CACnE;gBACA,IAAI,CAACA,OAAO,GAAGA,WAAW,CAAC;YAC7B;YACA,IAAIC,OAAO;gBACT,OAAO,IAAI,CAACD,OAAO,CAACC,IAAI,IAAI;YAC9B;YACA,IAAIC,aAAa;gBACf,OAAO,IAAI,CAACF,OAAO,CAACE,UAAU,IAAI;YACpC;YACA,IAAIC,aAAa;gBACf,OAAOC,MAAMC,OAAO,CAAC,IAAI,CAACL,OAAO,CAACM,SAAS,IACvC,IAAI,CAACN,OAAO,CAACM,SAAS,GACtB;oBAAC,IAAI,CAACN,OAAO,CAACM,SAAS,IAAI;iBAAE;YACnC;YAEAZ,aAAa,CAAC;YACdC,QAAQY,GAAY,EAAE,CAAC;YACvBC,cAAc;gBACZ,OAAO,EAAE;YACX;YACAV,UAAUS,GAAY,EAAE,CAAC;QAC3B;IACF;IAEA,IAAI/B,IAAIG,MAAM,CAAC8B,UAAU,KAAKvB,WAAW;QACvCV,IAAIG,MAAM,CAAC8B,UAAU,GAAG,CAACC,MACtB,CAAA;gBACCC,SAAS;gBACTC,OAAO;gBACPC,UAAU;YACZ,CAAA;IACJ;IAEA,OAAOrC;AACT;AAEA;;;;;;;;;;;CAWC,GACD,SAASsC;IACP,MAAMtC,MAAMD;IACZ,MAAMwC,QAAiCC,OAAOC,MAAM,CAAC;IACrD,MAAMC,cAAc,IAAIC,IAAIH,OAAOI,mBAAmB,CAACC;IAEvD,KAAK,MAAMC,OAAON,OAAOI,mBAAmB,CAAC5C,IAAIG,MAAM,EAAG;QACxD,iCAAiC;QACjC,IAAI2C,IAAIC,UAAU,CAAC,MAAM;QAEzB,gDAAgD;QAChD,IAAI,QAAQC,IAAI,CAACF,MAAM;QAEvB,mEAAmE;QACnE,IAAIJ,YAAYO,GAAG,CAACH,MAAM;QAE1BP,KAAK,CAACO,IAAI,GAAG,AAAC9C,IAAIG,MAAM,AAA4B,CAAC2C,IAAI;IAC3D;IAEA,OAAOP;AACT;AAEA,IAAIW;AAEJ,OAAO,SAASC;IACd,IAAI,CAACD,cAAc;QACjBA,eAAeZ;IACjB;IACA,OAAOY;AACT"}
1
+ {"version":3,"sources":["../../../src/util/environment/stubs.ts"],"sourcesContent":["import {JSDOM} from 'jsdom'\n\nconst html = `<!doctype html>\n<html>\n <head><meta charset=\"utf-8\"></head>\n <body></body>\n</html>`\n\ninterface AbortSignalLike {\n aborted: boolean\n addEventListener(type: 'abort', listener: () => void, options?: {once?: boolean}): void\n removeEventListener(type: 'abort', listener: () => void): void\n}\n\ntype EventListenerOptionsWithSignal = AddEventListenerOptions & {signal?: unknown}\n\nfunction isAbortSignalLike(value: unknown): value is AbortSignalLike {\n return (\n !!value &&\n typeof value === 'object' &&\n 'aborted' in value &&\n typeof (value as AbortSignalLike).aborted === 'boolean' &&\n 'addEventListener' in value &&\n typeof (value as AbortSignalLike).addEventListener === 'function' &&\n 'removeEventListener' in value &&\n typeof (value as AbortSignalLike).removeEventListener === 'function'\n )\n}\n\n/**\n * Make JSDOM's `addEventListener({signal})` accept native Node.js AbortSignals.\n *\n * JSDOM validates `signal` using its own realm's `AbortSignal` constructor, which rejects\n * Node's native signal. Instead of replacing the global Abort APIs, intercept those calls\n * and emulate the abortable-listener behavior for cross-realm signals.\n */\nfunction patchEventTargetSignalSupport(dom: JSDOM): void {\n const eventTarget = dom.window.EventTarget\n const addEventListener = eventTarget.prototype.addEventListener\n\n eventTarget.prototype.addEventListener = function addEventListenerPatched(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: AddEventListenerOptions | boolean,\n ) {\n if (typeof options === 'boolean' || !options?.signal) {\n return addEventListener.call(this, type, listener, options)\n }\n\n const rawSignal = (options as EventListenerOptionsWithSignal).signal\n const isJSDOMSignal = rawSignal instanceof (dom.window.AbortSignal as typeof AbortSignal)\n if (!rawSignal || isJSDOMSignal || !isAbortSignalLike(rawSignal)) {\n return addEventListener.call(this, type, listener, options)\n }\n\n const signal: AbortSignalLike = rawSignal\n if (signal.aborted) {\n return\n }\n\n const {signal: _signal, ...optionsWithoutSignal} = options as EventListenerOptionsWithSignal\n addEventListener.call(this, type, listener, optionsWithoutSignal)\n\n const removeOnAbort = () => {\n this.removeEventListener(type, listener, options)\n }\n\n signal.addEventListener('abort', removeOnAbort, {once: true})\n }\n}\n\n/**\n * Creates a JSDOM instance and applies polyfills for missing browser globals.\n */\nfunction createBrowserDom(): JSDOM {\n const dom = new JSDOM(html, {\n pretendToBeVisual: true,\n url: 'http://localhost:3333/',\n })\n\n patchEventTargetSignalSupport(dom)\n\n // Special handling of certain globals\n if (typeof dom.window.document.execCommand !== 'function') {\n // Crashes ace editor without this :/\n dom.window.document.execCommand = function execCommand(\n // Provide the right arity for the function, even if unused\n _commandName: string,\n _showDefaultUI: boolean,\n _valueArgument: unknown,\n ) {\n // Return false to indicate \"unsupported\"\n return false\n }\n }\n\n if (dom.window.requestIdleCallback === undefined) {\n dom.window.requestIdleCallback = (cb: IdleRequestCallback) => setTimeout(cb, 10)\n }\n\n if (dom.window.cancelIdleCallback === undefined) {\n dom.window.cancelIdleCallback = (id: number) => clearTimeout(id)\n }\n\n if (dom.window.ResizeObserver === undefined) {\n dom.window.ResizeObserver = class ResizeObserver {\n // eslint-disable-next-line @typescript-eslint/no-useless-constructor\n constructor(_callback: unknown) {}\n disconnect() {}\n observe(_target: unknown, _options: unknown) {}\n unobserve(_target: unknown) {}\n }\n }\n\n if (dom.window.IntersectionObserver === undefined) {\n dom.window.IntersectionObserver = class IntersectionObserver {\n options: {root?: unknown; rootMargin?: string; threshold?: number}\n constructor(\n _callback: unknown,\n options?: {root?: unknown; rootMargin?: string; threshold?: number},\n ) {\n this.options = options || {}\n }\n get root() {\n return this.options.root || null\n }\n get rootMargin() {\n return this.options.rootMargin || ''\n }\n get thresholds() {\n return Array.isArray(this.options.threshold)\n ? this.options.threshold\n : [this.options.threshold || 0]\n }\n\n disconnect() {}\n observe(_el: unknown) {}\n takeRecords() {\n return []\n }\n unobserve(_el: unknown) {}\n }\n }\n\n if (dom.window.matchMedia === undefined) {\n dom.window.matchMedia = (_qs: unknown) =>\n ({\n matches: false,\n media: '',\n onchange: null,\n }) as MediaQueryList\n }\n\n return dom\n}\n\n/**\n * Collects all browser globals from the JSDOM window that should be injected\n * into the Node.js global scope to emulate a browser environment.\n *\n * This dynamically iterates over all own properties of the JSDOM window,\n * skipping internal JSDOM properties (prefixed with `_`) and properties that\n * already exist in Node.js globals to avoid conflicts.\n *\n * This approach ensures that any new properties added by JSDOM upgrades are\n * automatically included, preventing \"missing global\" bugs (e.g. `Element`,\n * `HTMLElement`, `SVGElement` needed by libraries like styled-components).\n */\nfunction collectBrowserStubs(): Record<string, unknown> {\n const dom = createBrowserDom()\n const stubs: Record<string, unknown> = Object.create(null)\n const nodeGlobals = new Set(Object.getOwnPropertyNames(globalThis))\n\n for (const key of Object.getOwnPropertyNames(dom.window)) {\n // Skip internal JSDOM properties\n if (key.startsWith('_')) continue\n\n // Skip numeric indices (e.g. '0' for window[0])\n if (/^\\d+$/.test(key)) continue\n\n // Skip properties that Node.js already provides to avoid conflicts\n if (nodeGlobals.has(key)) continue\n\n stubs[key] = (dom.window as Record<string, unknown>)[key]\n }\n\n return stubs\n}\n\nlet browserStubs: Record<string, unknown> | undefined\n\nexport function getBrowserStubs(): Record<string, unknown> {\n if (!browserStubs) {\n browserStubs = collectBrowserStubs()\n }\n return browserStubs\n}\n"],"names":["JSDOM","html","isAbortSignalLike","value","aborted","addEventListener","removeEventListener","patchEventTargetSignalSupport","dom","eventTarget","window","EventTarget","prototype","addEventListenerPatched","type","listener","options","signal","call","rawSignal","isJSDOMSignal","AbortSignal","_signal","optionsWithoutSignal","removeOnAbort","once","createBrowserDom","pretendToBeVisual","url","document","execCommand","_commandName","_showDefaultUI","_valueArgument","requestIdleCallback","undefined","cb","setTimeout","cancelIdleCallback","id","clearTimeout","ResizeObserver","_callback","disconnect","observe","_target","_options","unobserve","IntersectionObserver","root","rootMargin","thresholds","Array","isArray","threshold","_el","takeRecords","matchMedia","_qs","matches","media","onchange","collectBrowserStubs","stubs","Object","create","nodeGlobals","Set","getOwnPropertyNames","globalThis","key","startsWith","test","has","browserStubs","getBrowserStubs"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli-core",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Sanity CLI core package",
5
5
  "keywords": [
6
6
  "cli",
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@inquirer/prompts": "^8.3.0",
54
- "@oclif/core": "^4.8.4",
54
+ "@oclif/core": "^4.9.0",
55
55
  "@rexxars/jiti": "^2.6.2",
56
56
  "@sanity/client": "^7.17.0",
57
57
  "babel-plugin-react-compiler": "^1.0.0",
@@ -74,7 +74,7 @@
74
74
  },
75
75
  "devDependencies": {
76
76
  "@eslint/compat": "^2.0.3",
77
- "@sanity/pkg-utils": "^10.4.9",
77
+ "@sanity/pkg-utils": "^10.4.11",
78
78
  "@sanity/telemetry": "^0.8.1",
79
79
  "@swc/cli": "^0.8.0",
80
80
  "@swc/core": "^1.15.18",
@@ -83,12 +83,12 @@
83
83
  "@types/node": "^20.19.37",
84
84
  "eslint": "^9.39.4",
85
85
  "publint": "^0.3.18",
86
- "sanity": "^5.15.0",
86
+ "sanity": "^5.17.1",
87
87
  "typescript": "^5.9.3",
88
- "vitest": "^4.0.18",
89
- "@repo/package.config": "0.0.1",
88
+ "vitest": "^4.1.0",
90
89
  "@repo/tsconfig": "3.70.0",
91
- "@sanity/eslint-config-cli": "1.0.0"
90
+ "@repo/package.config": "0.0.1",
91
+ "@sanity/eslint-config-cli": "1.0.1"
92
92
  },
93
93
  "peerDependencies": {
94
94
  "@sanity/telemetry": ">=0.8.1 <0.9.0"