@sanity/cli 6.0.0-alpha.4 → 6.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/dist/actions/dev/startStudioDevServer.js +3 -8
  2. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  3. package/dist/actions/dev/types.d.ts +1 -3
  4. package/dist/actions/dev/types.js.map +1 -1
  5. package/dist/actions/documents/validate.d.ts +0 -2
  6. package/dist/actions/documents/validate.js +21 -1
  7. package/dist/actions/documents/validate.js.map +1 -1
  8. package/dist/actions/exec/execScript.js +1 -1
  9. package/dist/actions/exec/execScript.js.map +1 -1
  10. package/dist/actions/graphql/__tests__/getGraphQLAPIs.test.js +1 -1
  11. package/dist/actions/graphql/__tests__/getGraphQLAPIs.test.js.map +1 -1
  12. package/dist/actions/graphql/getGraphQLAPIs.js +1 -1
  13. package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
  14. package/dist/actions/manifest/extractManifest.js +1 -4
  15. package/dist/actions/manifest/extractManifest.js.map +1 -1
  16. package/dist/actions/schema/deleteSchemaAction.d.ts +13 -5
  17. package/dist/actions/schema/deleteSchemaAction.js +12 -17
  18. package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
  19. package/dist/actions/schema/deploySchemas.d.ts +15 -0
  20. package/dist/actions/schema/deploySchemas.js +98 -0
  21. package/dist/actions/schema/deploySchemas.js.map +1 -0
  22. package/dist/actions/schema/listSchemas.d.ts +12 -0
  23. package/dist/actions/schema/listSchemas.js +119 -0
  24. package/dist/actions/schema/listSchemas.js.map +1 -0
  25. package/dist/actions/schema/schemaStoreTypes.d.ts +0 -11
  26. package/dist/actions/schema/schemaStoreTypes.js.map +1 -1
  27. package/dist/actions/schema/utils/debug.d.ts +2 -0
  28. package/dist/actions/schema/utils/debug.js +5 -0
  29. package/dist/actions/schema/utils/debug.js.map +1 -0
  30. package/dist/actions/schema/utils/manifestExtractor.d.ts +3 -8
  31. package/dist/actions/schema/utils/manifestExtractor.js +12 -17
  32. package/dist/actions/schema/utils/manifestExtractor.js.map +1 -1
  33. package/dist/actions/schema/utils/manifestReader.d.ts +2 -9
  34. package/dist/actions/schema/utils/manifestReader.js +6 -12
  35. package/dist/actions/schema/utils/manifestReader.js.map +1 -1
  36. package/dist/actions/schema/utils/schemaStoreOutStrings.d.ts +0 -1
  37. package/dist/actions/schema/utils/schemaStoreOutStrings.js +1 -1
  38. package/dist/actions/schema/utils/schemaStoreOutStrings.js.map +1 -1
  39. package/dist/actions/schema/utils/schemaStoreValidation.d.ts +10 -62
  40. package/dist/actions/schema/utils/schemaStoreValidation.js +38 -125
  41. package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
  42. package/dist/actions/schema/utils/uniqByProjectIdDataset.d.ts +14 -0
  43. package/dist/actions/schema/utils/uniqByProjectIdDataset.js +9 -0
  44. package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -0
  45. package/dist/actions/users/getMembersForProject.d.ts +1 -3
  46. package/dist/actions/users/getMembersForProject.js +6 -17
  47. package/dist/actions/users/getMembersForProject.js.map +1 -1
  48. package/dist/actions/users/types.d.ts +0 -11
  49. package/dist/actions/users/types.js.map +1 -1
  50. package/dist/commands/__tests__/debug.test.js +113 -220
  51. package/dist/commands/__tests__/debug.test.js.map +1 -1
  52. package/dist/commands/__tests__/deploy.test.js +325 -293
  53. package/dist/commands/__tests__/deploy.test.js.map +1 -1
  54. package/dist/commands/__tests__/dev.test.js +62 -19
  55. package/dist/commands/__tests__/dev.test.js.map +1 -1
  56. package/dist/commands/__tests__/init/init.authentication.test.js +40 -27
  57. package/dist/commands/__tests__/init/init.authentication.test.js.map +1 -1
  58. package/dist/commands/__tests__/init/init.create-new-project.test.js +84 -85
  59. package/dist/commands/__tests__/init/init.create-new-project.test.js.map +1 -1
  60. package/dist/commands/__tests__/init/init.plan.test.js +103 -44
  61. package/dist/commands/__tests__/init/init.plan.test.js.map +1 -1
  62. package/dist/commands/__tests__/init/init.setup.test.js +85 -29
  63. package/dist/commands/__tests__/init/init.setup.test.js.map +1 -1
  64. package/dist/commands/__tests__/install.test.js +46 -22
  65. package/dist/commands/__tests__/install.test.js.map +1 -1
  66. package/dist/commands/__tests__/logout.test.js +8 -5
  67. package/dist/commands/__tests__/logout.test.js.map +1 -1
  68. package/dist/commands/__tests__/manage.test.js +29 -24
  69. package/dist/commands/__tests__/manage.test.js.map +1 -1
  70. package/dist/commands/__tests__/versions.test.js +22 -14
  71. package/dist/commands/__tests__/versions.test.js.map +1 -1
  72. package/dist/commands/backup/__tests__/disable.test.js +72 -75
  73. package/dist/commands/backup/__tests__/disable.test.js.map +1 -1
  74. package/dist/commands/backup/__tests__/download.test.js +166 -77
  75. package/dist/commands/backup/__tests__/download.test.js.map +1 -1
  76. package/dist/commands/backup/__tests__/enable.test.js +109 -140
  77. package/dist/commands/backup/__tests__/enable.test.js.map +1 -1
  78. package/dist/commands/backup/__tests__/list.test.js +84 -75
  79. package/dist/commands/backup/__tests__/list.test.js.map +1 -1
  80. package/dist/commands/backup/disable.js +5 -11
  81. package/dist/commands/backup/disable.js.map +1 -1
  82. package/dist/commands/backup/enable.js +5 -11
  83. package/dist/commands/backup/enable.js.map +1 -1
  84. package/dist/commands/backup/list.js +7 -8
  85. package/dist/commands/backup/list.js.map +1 -1
  86. package/dist/commands/cors/__tests__/add.test.js +68 -38
  87. package/dist/commands/cors/__tests__/add.test.js.map +1 -1
  88. package/dist/commands/cors/__tests__/delete.test.js +52 -37
  89. package/dist/commands/cors/__tests__/delete.test.js.map +1 -1
  90. package/dist/commands/cors/__tests__/list.test.js +80 -57
  91. package/dist/commands/cors/__tests__/list.test.js.map +1 -1
  92. package/dist/commands/cors/add.js +5 -13
  93. package/dist/commands/cors/add.js.map +1 -1
  94. package/dist/commands/cors/delete.js +7 -15
  95. package/dist/commands/cors/delete.js.map +1 -1
  96. package/dist/commands/cors/list.js +2 -10
  97. package/dist/commands/cors/list.js.map +1 -1
  98. package/dist/commands/dataset/__tests__/copy.test.js +197 -89
  99. package/dist/commands/dataset/__tests__/copy.test.js.map +1 -1
  100. package/dist/commands/dataset/__tests__/create.test.js +147 -117
  101. package/dist/commands/dataset/__tests__/create.test.js.map +1 -1
  102. package/dist/commands/dataset/__tests__/delete.test.js +75 -68
  103. package/dist/commands/dataset/__tests__/delete.test.js.map +1 -1
  104. package/dist/commands/dataset/__tests__/export.test.js +123 -83
  105. package/dist/commands/dataset/__tests__/export.test.js.map +1 -1
  106. package/dist/commands/dataset/__tests__/list.test.js +107 -65
  107. package/dist/commands/dataset/__tests__/list.test.js.map +1 -1
  108. package/dist/commands/dataset/alias/__tests__/create.test.js +114 -74
  109. package/dist/commands/dataset/alias/__tests__/create.test.js.map +1 -1
  110. package/dist/commands/dataset/alias/__tests__/delete.test.js +40 -29
  111. package/dist/commands/dataset/alias/__tests__/delete.test.js.map +1 -1
  112. package/dist/commands/dataset/alias/__tests__/link.test.js +114 -74
  113. package/dist/commands/dataset/alias/__tests__/link.test.js.map +1 -1
  114. package/dist/commands/dataset/alias/__tests__/unlink.test.js +44 -29
  115. package/dist/commands/dataset/alias/__tests__/unlink.test.js.map +1 -1
  116. package/dist/commands/dataset/export.js +4 -4
  117. package/dist/commands/dataset/export.js.map +1 -1
  118. package/dist/commands/dataset/visibility/__tests__/get.test.js +48 -67
  119. package/dist/commands/dataset/visibility/__tests__/get.test.js.map +1 -1
  120. package/dist/commands/dataset/visibility/__tests__/set.test.js +76 -123
  121. package/dist/commands/dataset/visibility/__tests__/set.test.js.map +1 -1
  122. package/dist/commands/dev.js +0 -1
  123. package/dist/commands/dev.js.map +1 -1
  124. package/dist/commands/docs/__tests__/search.test.js +8 -7
  125. package/dist/commands/docs/__tests__/search.test.js.map +1 -1
  126. package/dist/commands/documents/__tests__/create.test.js +328 -265
  127. package/dist/commands/documents/__tests__/create.test.js.map +1 -1
  128. package/dist/commands/documents/__tests__/delete.test.js +119 -87
  129. package/dist/commands/documents/__tests__/delete.test.js.map +1 -1
  130. package/dist/commands/documents/__tests__/get.test.js +68 -95
  131. package/dist/commands/documents/__tests__/get.test.js.map +1 -1
  132. package/dist/commands/documents/__tests__/query.test.js +84 -189
  133. package/dist/commands/documents/__tests__/query.test.js.map +1 -1
  134. package/dist/commands/documents/__tests__/validate.test.js +52 -29
  135. package/dist/commands/documents/__tests__/validate.test.js.map +1 -1
  136. package/dist/commands/documents/create.d.ts +1 -0
  137. package/dist/commands/documents/create.js +10 -9
  138. package/dist/commands/documents/create.js.map +1 -1
  139. package/dist/commands/documents/delete.js +2 -3
  140. package/dist/commands/documents/delete.js.map +1 -1
  141. package/dist/commands/documents/get.js +2 -3
  142. package/dist/commands/documents/get.js.map +1 -1
  143. package/dist/commands/documents/query.js +2 -3
  144. package/dist/commands/documents/query.js.map +1 -1
  145. package/dist/commands/documents/validate.js +0 -20
  146. package/dist/commands/documents/validate.js.map +1 -1
  147. package/dist/commands/graphql/__tests__/list.test.js +57 -45
  148. package/dist/commands/graphql/__tests__/list.test.js.map +1 -1
  149. package/dist/commands/graphql/__tests__/undeploy.test.js +85 -59
  150. package/dist/commands/graphql/__tests__/undeploy.test.js.map +1 -1
  151. package/dist/commands/graphql/list.js +2 -2
  152. package/dist/commands/graphql/list.js.map +1 -1
  153. package/dist/commands/graphql/undeploy.js +4 -9
  154. package/dist/commands/graphql/undeploy.js.map +1 -1
  155. package/dist/commands/hook/__tests__/attempt.test.js +48 -33
  156. package/dist/commands/hook/__tests__/attempt.test.js.map +1 -1
  157. package/dist/commands/hook/__tests__/create.test.js +49 -51
  158. package/dist/commands/hook/__tests__/create.test.js.map +1 -1
  159. package/dist/commands/hook/__tests__/delete.test.js +43 -30
  160. package/dist/commands/hook/__tests__/delete.test.js.map +1 -1
  161. package/dist/commands/hook/__tests__/list.test.js +38 -31
  162. package/dist/commands/hook/__tests__/list.test.js.map +1 -1
  163. package/dist/commands/hook/__tests__/logs.test.js +68 -40
  164. package/dist/commands/hook/__tests__/logs.test.js.map +1 -1
  165. package/dist/commands/hook/create.js +2 -6
  166. package/dist/commands/hook/create.js.map +1 -1
  167. package/dist/commands/hook/delete.js +5 -17
  168. package/dist/commands/hook/delete.js.map +1 -1
  169. package/dist/commands/hook/list.js +2 -8
  170. package/dist/commands/hook/list.js.map +1 -1
  171. package/dist/commands/manifest/__tests__/extract.test.js +22 -13
  172. package/dist/commands/manifest/__tests__/extract.test.js.map +1 -1
  173. package/dist/commands/media/__tests__/create-aspect.test.js +41 -28
  174. package/dist/commands/media/__tests__/create-aspect.test.js.map +1 -1
  175. package/dist/commands/media/__tests__/delete-aspect.test.js +44 -35
  176. package/dist/commands/media/__tests__/delete-aspect.test.js.map +1 -1
  177. package/dist/commands/media/__tests__/deploy-aspect.test.js +67 -80
  178. package/dist/commands/media/__tests__/deploy-aspect.test.js.map +1 -1
  179. package/dist/commands/media/__tests__/export.test.js +365 -66
  180. package/dist/commands/media/__tests__/export.test.js.map +1 -1
  181. package/dist/commands/media/__tests__/import.test.js +171 -105
  182. package/dist/commands/media/__tests__/import.test.js.map +1 -1
  183. package/dist/commands/media/export.js +2 -2
  184. package/dist/commands/media/export.js.map +1 -1
  185. package/dist/commands/media/import.js +2 -2
  186. package/dist/commands/media/import.js.map +1 -1
  187. package/dist/commands/projects/__tests__/list.test.js +5 -4
  188. package/dist/commands/projects/__tests__/list.test.js.map +1 -1
  189. package/dist/commands/projects/list.js +2 -6
  190. package/dist/commands/projects/list.js.map +1 -1
  191. package/dist/commands/schema/__tests__/delete.test.js +396 -151
  192. package/dist/commands/schema/__tests__/delete.test.js.map +1 -1
  193. package/dist/commands/schema/__tests__/deploy.test.js +348 -0
  194. package/dist/commands/schema/__tests__/deploy.test.js.map +1 -0
  195. package/dist/commands/schema/__tests__/extract.test.js +19 -11
  196. package/dist/commands/schema/__tests__/extract.test.js.map +1 -1
  197. package/dist/commands/schema/__tests__/list.test.js +399 -0
  198. package/dist/commands/schema/__tests__/list.test.js.map +1 -0
  199. package/dist/commands/schema/__tests__/validate.test.js +27 -10
  200. package/dist/commands/schema/__tests__/validate.test.js.map +1 -1
  201. package/dist/commands/schema/delete.d.ts +1 -1
  202. package/dist/commands/schema/delete.js +20 -23
  203. package/dist/commands/schema/delete.js.map +1 -1
  204. package/dist/commands/schema/deploy.d.ts +16 -0
  205. package/dist/commands/schema/deploy.js +98 -0
  206. package/dist/commands/schema/deploy.js.map +1 -0
  207. package/dist/commands/schema/list.d.ts +15 -0
  208. package/dist/commands/schema/list.js +104 -0
  209. package/dist/commands/schema/list.js.map +1 -0
  210. package/dist/commands/telemetry/__tests__/disable.test.js +7 -5
  211. package/dist/commands/telemetry/__tests__/disable.test.js.map +1 -1
  212. package/dist/commands/telemetry/__tests__/enable.test.js +7 -5
  213. package/dist/commands/telemetry/__tests__/enable.test.js.map +1 -1
  214. package/dist/commands/telemetry/__tests__/status.test.js +7 -5
  215. package/dist/commands/telemetry/__tests__/status.test.js.map +1 -1
  216. package/dist/commands/tokens/__tests__/add.test.js +55 -40
  217. package/dist/commands/tokens/__tests__/add.test.js.map +1 -1
  218. package/dist/commands/tokens/__tests__/delete.test.js +72 -42
  219. package/dist/commands/tokens/__tests__/delete.test.js.map +1 -1
  220. package/dist/commands/tokens/__tests__/list.test.js +87 -60
  221. package/dist/commands/tokens/__tests__/list.test.js.map +1 -1
  222. package/dist/commands/tokens/add.js +3 -5
  223. package/dist/commands/tokens/add.js.map +1 -1
  224. package/dist/commands/users/__tests__/invite.test.js +100 -79
  225. package/dist/commands/users/__tests__/invite.test.js.map +1 -1
  226. package/dist/commands/users/__tests__/list.test.js +186 -180
  227. package/dist/commands/users/__tests__/list.test.js.map +1 -1
  228. package/dist/commands/users/invite.js +6 -17
  229. package/dist/commands/users/invite.js.map +1 -1
  230. package/dist/commands/users/list.js +4 -7
  231. package/dist/commands/users/list.js.map +1 -1
  232. package/dist/config/createCliConfig.d.ts +4 -4
  233. package/dist/services/backup.d.ts +8 -0
  234. package/dist/services/backup.js +19 -0
  235. package/dist/services/backup.js.map +1 -1
  236. package/dist/services/cors.d.ts +23 -0
  237. package/dist/services/cors.js +38 -0
  238. package/dist/services/cors.js.map +1 -0
  239. package/dist/services/graphql.d.ts +7 -0
  240. package/dist/services/graphql.js +11 -0
  241. package/dist/services/graphql.js.map +1 -1
  242. package/dist/services/hooks.d.ts +2 -0
  243. package/dist/services/hooks.js +19 -0
  244. package/dist/services/hooks.js.map +1 -1
  245. package/dist/services/organizations.d.ts +1 -1
  246. package/dist/services/organizations.js +1 -1
  247. package/dist/services/organizations.js.map +1 -1
  248. package/dist/services/projects.d.ts +11 -0
  249. package/dist/services/projects.js +41 -0
  250. package/dist/services/projects.js.map +1 -1
  251. package/dist/services/schemas.d.ts +4 -0
  252. package/dist/services/schemas.js +40 -0
  253. package/dist/services/schemas.js.map +1 -0
  254. package/dist/services/user.d.ts +8 -0
  255. package/dist/services/user.js +15 -2
  256. package/dist/services/user.js.map +1 -1
  257. package/dist/util/__tests__/getCliVersion.test.js +2 -2
  258. package/dist/util/__tests__/getCliVersion.test.js.map +1 -1
  259. package/dist/util/errorMessages.d.ts +1 -0
  260. package/dist/util/errorMessages.js +1 -0
  261. package/dist/util/errorMessages.js.map +1 -1
  262. package/dist/util/getCliVersion.js +1 -1
  263. package/dist/util/getCliVersion.js.map +1 -1
  264. package/dist/util/readPackageJson.d.ts +1 -15
  265. package/dist/util/readPackageJson.js +1 -1
  266. package/dist/util/readPackageJson.js.map +1 -1
  267. package/dist/util/uniqBy.d.ts +1 -0
  268. package/dist/util/uniqBy.js +14 -0
  269. package/dist/util/uniqBy.js.map +1 -0
  270. package/oclif.manifest.json +172 -27
  271. package/package.json +27 -28
  272. package/dist/actions/cors/constants.d.ts +0 -1
  273. package/dist/actions/cors/constants.js +0 -3
  274. package/dist/actions/cors/constants.js.map +0 -1
  275. package/dist/actions/cors/types.d.ts +0 -9
  276. package/dist/actions/cors/types.js +0 -3
  277. package/dist/actions/cors/types.js.map +0 -1
  278. package/dist/actions/schema/__tests__/deleteSchemaAction.test.js +0 -294
  279. package/dist/actions/schema/__tests__/deleteSchemaAction.test.js.map +0 -1
  280. package/dist/actions/schema/schemaStoreConstants.d.ts +0 -1
  281. package/dist/actions/schema/schemaStoreConstants.js +0 -4
  282. package/dist/actions/schema/schemaStoreConstants.js.map +0 -1
  283. package/dist/actions/schema/utils/schemaActionHelpers.d.ts +0 -1
  284. package/dist/actions/schema/utils/schemaActionHelpers.js +0 -5
  285. package/dist/actions/schema/utils/schemaActionHelpers.js.map +0 -1
  286. package/dist/actions/schema/utils/schemaApiClient.d.ts +0 -6
  287. package/dist/actions/schema/utils/schemaApiClient.js +0 -17
  288. package/dist/actions/schema/utils/schemaApiClient.js.map +0 -1
  289. package/dist/actions/users/apiVersion.d.ts +0 -6
  290. package/dist/actions/users/apiVersion.js +0 -7
  291. package/dist/actions/users/apiVersion.js.map +0 -1
@@ -1,18 +1,18 @@
1
1
  import * as cliUX from '@sanity/cli-core/ux';
2
- import { testCommand } from '@sanity/cli-test';
2
+ import { createTestClient, mockApi, testCommand } from '@sanity/cli-test';
3
+ import nock from 'nock';
3
4
  import { afterEach, describe, expect, test, vi } from 'vitest';
5
+ import { ORGANIZATIONS_API_VERSION } from '../../../services/organizations.js';
6
+ import { CREATE_PROJECT_API_VERSION } from '../../../services/projects.js';
4
7
  import { InitCommand } from '../../init';
5
8
  const mocks = vi.hoisted(()=>({
6
- createDataset: vi.fn(),
7
- createOrganization: vi.fn(),
8
- createProject: vi.fn(),
9
+ datasetsCreate: vi.fn(),
9
10
  detectFrameworkRecord: vi.fn(),
10
11
  getOrganizationChoices: vi.fn(),
11
12
  getOrganizationsWithAttachGrantInfo: vi.fn(),
12
13
  input: vi.fn(),
13
- listOrganizations: vi.fn(),
14
14
  select: vi.fn(),
15
- spinner: vi.fn()
15
+ usersGetById: vi.fn()
16
16
  }));
17
17
  vi.mock('@vercel/fs-detectors', ()=>({
18
18
  detectFrameworkRecord: mocks.detectFrameworkRecord,
@@ -26,49 +26,62 @@ vi.mock('@sanity/cli-core/ux', async ()=>{
26
26
  select: mocks.select
27
27
  };
28
28
  });
29
- vi.mock('../../../../../cli-core/src/util/isInteractive.js', ()=>({
30
- isInteractive: vi.fn().mockReturnValue(true)
31
- }));
32
- vi.mock('../../../../../cli-core/src/services/getCliToken.js', ()=>({
33
- getCliToken: vi.fn().mockResolvedValue('test-token')
34
- }));
35
- vi.mock('../../../services/user.js', ()=>({
36
- getCliUser: vi.fn().mockResolvedValue({
37
- email: 'test@example.com',
38
- id: 'user-123',
39
- name: 'Test User',
40
- provider: 'saml-123'
29
+ vi.mock('@sanity/cli-core', async (importOriginal)=>{
30
+ const actual = await importOriginal();
31
+ const testClient = createTestClient({
32
+ apiVersion: 'v2025-05-14',
33
+ token: 'test-token'
34
+ });
35
+ return {
36
+ ...actual,
37
+ getGlobalCliClient: vi.fn().mockResolvedValue({
38
+ datasets: {
39
+ create: mocks.datasetsCreate
40
+ },
41
+ request: testClient.request,
42
+ users: {
43
+ getById: mocks.usersGetById
44
+ }
45
+ }),
46
+ getProjectCliClient: vi.fn().mockResolvedValue({
47
+ datasets: {
48
+ create: mocks.datasetsCreate
49
+ }
41
50
  })
42
- }));
51
+ };
52
+ });
43
53
  vi.mock('../../../actions/organizations/getOrganizationChoices.js', ()=>({
44
54
  getOrganizationChoices: mocks.getOrganizationChoices
45
55
  }));
46
56
  vi.mock('../../../actions/organizations/getOrganizationsWithAttachGrantInfo.js', ()=>({
47
57
  getOrganizationsWithAttachGrantInfo: mocks.getOrganizationsWithAttachGrantInfo
48
58
  }));
49
- vi.mock('../../../services/datasets.js', ()=>({
50
- createDataset: mocks.createDataset
51
- }));
52
- vi.mock('../../../services/organizations.js', ()=>({
53
- createOrganization: mocks.createOrganization,
54
- listOrganizations: mocks.listOrganizations
55
- }));
56
- vi.mock('../../../services/projects.js', ()=>({
57
- createProject: mocks.createProject
58
- }));
59
+ mocks.usersGetById.mockResolvedValue({
60
+ email: 'test@example.com',
61
+ id: 'user-123',
62
+ name: 'Test User',
63
+ provider: 'saml-123'
64
+ });
59
65
  describe('#init: create new project', ()=>{
60
66
  afterEach(()=>{
61
67
  vi.clearAllMocks();
68
+ const pending = nock.pendingMocks();
69
+ nock.cleanAll();
70
+ expect(pending, 'pending mocks').toEqual([]);
62
71
  });
63
72
  test('prompts user to create new organization if they have none', async ()=>{
64
- // Mock no framework detection
65
73
  mocks.detectFrameworkRecord.mockResolvedValueOnce(null);
66
- // Mock listOrganizations to return empty array (user has no organizations)
67
- mocks.listOrganizations.mockResolvedValueOnce([]);
68
- // Mock input prompt for organization name
74
+ mockApi({
75
+ apiVersion: ORGANIZATIONS_API_VERSION,
76
+ method: 'get',
77
+ uri: '/organizations'
78
+ }).reply(200, []);
69
79
  mocks.input.mockResolvedValueOnce('My New Organization');
70
- // Mock createOrganization to return the created organization
71
- mocks.createOrganization.mockResolvedValueOnce({
80
+ mockApi({
81
+ apiVersion: ORGANIZATIONS_API_VERSION,
82
+ method: 'post',
83
+ uri: '/organizations'
84
+ }).reply(200, {
72
85
  createdByUserId: 'user-123',
73
86
  defaultRoleName: null,
74
87
  features: [],
@@ -77,55 +90,47 @@ describe('#init: create new project', ()=>{
77
90
  name: 'My New Organization',
78
91
  slug: 'my-new-organization'
79
92
  });
80
- // Mock createProject to return the created project with correct structure
81
- mocks.createProject.mockResolvedValueOnce({
93
+ mockApi({
94
+ apiVersion: CREATE_PROJECT_API_VERSION,
95
+ method: 'post',
96
+ uri: '/projects'
97
+ }).reply(200, {
82
98
  displayName: 'Test Project',
83
99
  projectId: 'project-123'
84
100
  });
85
- // Mock createDataset
86
- mocks.createDataset.mockResolvedValueOnce(undefined);
101
+ mocks.datasetsCreate.mockResolvedValueOnce(undefined);
87
102
  const spinnerSpy = vi.spyOn(cliUX, 'spinner');
88
103
  await testCommand(InitCommand, [
89
104
  '--create-project=Test Project',
90
105
  '--dataset=production',
91
106
  '--output-path=./test-project'
92
- ]);
93
- // Verify listOrganizations was called
94
- expect(mocks.listOrganizations).toHaveBeenCalled();
95
- // Verify input prompt was called with correct parameters
107
+ ], {
108
+ mocks: {
109
+ isInteractive: true,
110
+ token: 'test-token'
111
+ }
112
+ });
96
113
  expect(mocks.input).toHaveBeenCalledWith(expect.objectContaining({
97
114
  default: 'Test User',
98
115
  message: 'Organization name:'
99
116
  }));
100
- // Verify createOrganization was called with the input value
101
- expect(mocks.createOrganization).toHaveBeenCalledWith('My New Organization');
102
- // Verify createProject was called
103
- expect(mocks.createProject).toHaveBeenCalledWith(expect.objectContaining({
104
- displayName: 'Test Project',
105
- organizationId: 'org-123'
106
- }));
107
- // Verify createDataset was called
108
- expect(mocks.createDataset).toHaveBeenCalledWith(expect.objectContaining({
109
- aclMode: undefined,
110
- datasetName: 'production',
111
- projectId: 'project-123'
112
- }));
113
- // Verify spinner was called with correct text
117
+ expect(mocks.datasetsCreate).toHaveBeenCalledWith('production');
114
118
  expect(spinnerSpy).toHaveBeenCalledWith('Creating organization');
115
119
  expect(spinnerSpy).toHaveBeenCalledWith('Creating dataset');
116
120
  });
117
121
  test('prompts user to select then create a new organization', async ()=>{
118
- // Mock no framework detection
119
122
  mocks.detectFrameworkRecord.mockResolvedValueOnce(null);
120
- // Mock listOrganizations to return existing organizations
121
- mocks.listOrganizations.mockResolvedValueOnce([
123
+ mockApi({
124
+ apiVersion: ORGANIZATIONS_API_VERSION,
125
+ method: 'get',
126
+ uri: '/organizations'
127
+ }).reply(200, [
122
128
  {
123
129
  id: 'existing-org-123',
124
130
  name: 'Existing Organization',
125
131
  slug: 'existing-organization'
126
132
  }
127
133
  ]);
128
- // Mock getOrganizationsWithAttachGrantInfo to return organizations with attach grant
129
134
  mocks.getOrganizationsWithAttachGrantInfo.mockResolvedValueOnce([
130
135
  {
131
136
  hasAttachGrant: true,
@@ -136,7 +141,6 @@ describe('#init: create new project', ()=>{
136
141
  }
137
142
  }
138
143
  ]);
139
- // Mock getOrganizationChoices to return choices including create new option
140
144
  mocks.getOrganizationChoices.mockReturnValueOnce([
141
145
  {
142
146
  name: 'Existing Organization [existing-org-123]',
@@ -147,12 +151,13 @@ describe('#init: create new project', ()=>{
147
151
  value: '-new-'
148
152
  }
149
153
  ]);
150
- // Mock select prompt - user chooses to create new organization
151
154
  mocks.select.mockResolvedValueOnce('-new-');
152
- // Mock input prompt for new organization name
153
155
  mocks.input.mockResolvedValueOnce('Brand New Organization');
154
- // Mock createOrganization to return the newly created organization
155
- mocks.createOrganization.mockResolvedValueOnce({
156
+ mockApi({
157
+ apiVersion: ORGANIZATIONS_API_VERSION,
158
+ method: 'post',
159
+ uri: '/organizations'
160
+ }).reply(200, {
156
161
  createdByUserId: 'user-123',
157
162
  defaultRoleName: null,
158
163
  features: [],
@@ -161,33 +166,27 @@ describe('#init: create new project', ()=>{
161
166
  name: 'Brand New Organization',
162
167
  slug: 'brand-new-organization'
163
168
  });
164
- // Mock createProject to return the created project
165
- mocks.createProject.mockResolvedValueOnce({
169
+ mockApi({
170
+ apiVersion: CREATE_PROJECT_API_VERSION,
171
+ method: 'post',
172
+ uri: '/projects'
173
+ }).reply(200, {
166
174
  displayName: 'Test Project',
167
175
  projectId: 'project-123'
168
176
  });
169
- // Mock createDataset
170
- mocks.createDataset.mockResolvedValueOnce(undefined);
177
+ mocks.datasetsCreate.mockResolvedValueOnce(undefined);
171
178
  const spinnerSpy = vi.spyOn(cliUX, 'spinner');
172
179
  await testCommand(InitCommand, [
173
180
  '--create-project=Test Project',
174
181
  '--dataset=production',
175
182
  '--output-path=./test-project'
176
- ]);
177
- // Verify createOrganization was called with the input value
178
- expect(mocks.createOrganization).toHaveBeenCalledWith('Brand New Organization');
179
- // Verify createProject was called
180
- expect(mocks.createProject).toHaveBeenCalledWith(expect.objectContaining({
181
- displayName: 'Test Project',
182
- organizationId: 'new-org-456'
183
- }));
184
- // Verify createDataset was called
185
- expect(mocks.createDataset).toHaveBeenCalledWith(expect.objectContaining({
186
- aclMode: undefined,
187
- datasetName: 'production',
188
- projectId: 'project-123'
189
- }));
190
- // Verify spinner was called with correct text
183
+ ], {
184
+ mocks: {
185
+ isInteractive: true,
186
+ token: 'test-token'
187
+ }
188
+ });
189
+ expect(mocks.datasetsCreate).toHaveBeenCalledWith('production');
191
190
  expect(spinnerSpy).toHaveBeenCalledWith('Creating organization');
192
191
  expect(spinnerSpy).toHaveBeenCalledWith('Creating dataset');
193
192
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/__tests__/init/init.create-new-project.test.ts"],"sourcesContent":["import * as cliUX from '@sanity/cli-core/ux'\nimport {testCommand} from '@sanity/cli-test'\nimport {afterEach, describe, expect, test, vi} from 'vitest'\n\nimport {InitCommand} from '../../init'\n\nconst mocks = vi.hoisted(() => ({\n createDataset: vi.fn(),\n createOrganization: vi.fn(),\n createProject: vi.fn(),\n detectFrameworkRecord: vi.fn(),\n getOrganizationChoices: vi.fn(),\n getOrganizationsWithAttachGrantInfo: vi.fn(),\n input: vi.fn(),\n listOrganizations: vi.fn(),\n select: vi.fn(),\n spinner: vi.fn(),\n}))\n\nvi.mock('@vercel/fs-detectors', () => ({\n detectFrameworkRecord: mocks.detectFrameworkRecord,\n LocalFileSystemDetector: vi.fn(),\n}))\n\nvi.mock('@sanity/cli-core/ux', async () => {\n const actual = await vi.importActual('@sanity/cli-core/ux')\n\n return {\n ...actual,\n input: mocks.input,\n select: mocks.select,\n // spinner: mocks.spinner,\n }\n})\n\nvi.mock('../../../../../cli-core/src/util/isInteractive.js', () => ({\n isInteractive: vi.fn().mockReturnValue(true),\n}))\n\nvi.mock('../../../../../cli-core/src/services/getCliToken.js', () => ({\n getCliToken: vi.fn().mockResolvedValue('test-token'),\n}))\n\nvi.mock('../../../services/user.js', () => ({\n getCliUser: vi.fn().mockResolvedValue({\n email: 'test@example.com',\n id: 'user-123',\n name: 'Test User',\n provider: 'saml-123',\n }),\n}))\n\nvi.mock('../../../actions/organizations/getOrganizationChoices.js', () => ({\n getOrganizationChoices: mocks.getOrganizationChoices,\n}))\n\nvi.mock('../../../actions/organizations/getOrganizationsWithAttachGrantInfo.js', () => ({\n getOrganizationsWithAttachGrantInfo: mocks.getOrganizationsWithAttachGrantInfo,\n}))\n\nvi.mock('../../../services/datasets.js', () => ({\n createDataset: mocks.createDataset,\n}))\n\nvi.mock('../../../services/organizations.js', () => ({\n createOrganization: mocks.createOrganization,\n listOrganizations: mocks.listOrganizations,\n}))\n\nvi.mock('../../../services/projects.js', () => ({\n createProject: mocks.createProject,\n}))\n\ndescribe('#init: create new project', () => {\n afterEach(() => {\n vi.clearAllMocks()\n })\n\n test('prompts user to create new organization if they have none', async () => {\n // Mock no framework detection\n mocks.detectFrameworkRecord.mockResolvedValueOnce(null)\n\n // Mock listOrganizations to return empty array (user has no organizations)\n mocks.listOrganizations.mockResolvedValueOnce([])\n\n // Mock input prompt for organization name\n mocks.input.mockResolvedValueOnce('My New Organization')\n\n // Mock createOrganization to return the created organization\n mocks.createOrganization.mockResolvedValueOnce({\n createdByUserId: 'user-123',\n defaultRoleName: null,\n features: [],\n id: 'org-123',\n members: [],\n name: 'My New Organization',\n slug: 'my-new-organization',\n })\n\n // Mock createProject to return the created project with correct structure\n mocks.createProject.mockResolvedValueOnce({\n displayName: 'Test Project',\n projectId: 'project-123',\n })\n\n // Mock createDataset\n mocks.createDataset.mockResolvedValueOnce(undefined)\n\n const spinnerSpy = vi.spyOn(cliUX, 'spinner')\n\n await testCommand(InitCommand, [\n '--create-project=Test Project',\n '--dataset=production',\n '--output-path=./test-project',\n ])\n\n // Verify listOrganizations was called\n expect(mocks.listOrganizations).toHaveBeenCalled()\n\n // Verify input prompt was called with correct parameters\n expect(mocks.input).toHaveBeenCalledWith(\n expect.objectContaining({\n default: 'Test User',\n message: 'Organization name:',\n }),\n )\n\n // Verify createOrganization was called with the input value\n expect(mocks.createOrganization).toHaveBeenCalledWith('My New Organization')\n\n // Verify createProject was called\n expect(mocks.createProject).toHaveBeenCalledWith(\n expect.objectContaining({\n displayName: 'Test Project',\n organizationId: 'org-123',\n }),\n )\n\n // Verify createDataset was called\n expect(mocks.createDataset).toHaveBeenCalledWith(\n expect.objectContaining({\n aclMode: undefined,\n datasetName: 'production',\n projectId: 'project-123',\n }),\n )\n\n // Verify spinner was called with correct text\n expect(spinnerSpy).toHaveBeenCalledWith('Creating organization')\n expect(spinnerSpy).toHaveBeenCalledWith('Creating dataset')\n })\n\n test('prompts user to select then create a new organization', async () => {\n // Mock no framework detection\n mocks.detectFrameworkRecord.mockResolvedValueOnce(null)\n\n // Mock listOrganizations to return existing organizations\n mocks.listOrganizations.mockResolvedValueOnce([\n {\n id: 'existing-org-123',\n name: 'Existing Organization',\n slug: 'existing-organization',\n },\n ])\n\n // Mock getOrganizationsWithAttachGrantInfo to return organizations with attach grant\n mocks.getOrganizationsWithAttachGrantInfo.mockResolvedValueOnce([\n {\n hasAttachGrant: true,\n organization: {\n id: 'existing-org-123',\n name: 'Existing Organization',\n slug: 'existing-organization',\n },\n },\n ])\n\n // Mock getOrganizationChoices to return choices including create new option\n mocks.getOrganizationChoices.mockReturnValueOnce([\n {name: 'Existing Organization [existing-org-123]', value: 'existing-org-123'},\n {name: 'Create new organization', value: '-new-'},\n ])\n\n // Mock select prompt - user chooses to create new organization\n mocks.select.mockResolvedValueOnce('-new-')\n\n // Mock input prompt for new organization name\n mocks.input.mockResolvedValueOnce('Brand New Organization')\n\n // Mock createOrganization to return the newly created organization\n mocks.createOrganization.mockResolvedValueOnce({\n createdByUserId: 'user-123',\n defaultRoleName: null,\n features: [],\n id: 'new-org-456',\n members: [],\n name: 'Brand New Organization',\n slug: 'brand-new-organization',\n })\n\n // Mock createProject to return the created project\n mocks.createProject.mockResolvedValueOnce({\n displayName: 'Test Project',\n projectId: 'project-123',\n })\n\n // Mock createDataset\n mocks.createDataset.mockResolvedValueOnce(undefined)\n\n const spinnerSpy = vi.spyOn(cliUX, 'spinner')\n\n await testCommand(InitCommand, [\n '--create-project=Test Project',\n '--dataset=production',\n '--output-path=./test-project',\n ])\n\n // Verify createOrganization was called with the input value\n expect(mocks.createOrganization).toHaveBeenCalledWith('Brand New Organization')\n\n // Verify createProject was called\n expect(mocks.createProject).toHaveBeenCalledWith(\n expect.objectContaining({\n displayName: 'Test Project',\n organizationId: 'new-org-456',\n }),\n )\n\n // Verify createDataset was called\n expect(mocks.createDataset).toHaveBeenCalledWith(\n expect.objectContaining({\n aclMode: undefined,\n datasetName: 'production',\n projectId: 'project-123',\n }),\n )\n\n // Verify spinner was called with correct text\n expect(spinnerSpy).toHaveBeenCalledWith('Creating organization')\n expect(spinnerSpy).toHaveBeenCalledWith('Creating dataset')\n })\n})\n"],"names":["cliUX","testCommand","afterEach","describe","expect","test","vi","InitCommand","mocks","hoisted","createDataset","fn","createOrganization","createProject","detectFrameworkRecord","getOrganizationChoices","getOrganizationsWithAttachGrantInfo","input","listOrganizations","select","spinner","mock","LocalFileSystemDetector","actual","importActual","isInteractive","mockReturnValue","getCliToken","mockResolvedValue","getCliUser","email","id","name","provider","clearAllMocks","mockResolvedValueOnce","createdByUserId","defaultRoleName","features","members","slug","displayName","projectId","undefined","spinnerSpy","spyOn","toHaveBeenCalled","toHaveBeenCalledWith","objectContaining","default","message","organizationId","aclMode","datasetName","hasAttachGrant","organization","mockReturnValueOnce","value"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/commands/__tests__/init/init.create-new-project.test.ts"],"sourcesContent":["import * as cliUX from '@sanity/cli-core/ux'\nimport {createTestClient, mockApi, testCommand} from '@sanity/cli-test'\nimport nock from 'nock'\nimport {afterEach, describe, expect, test, vi} from 'vitest'\n\nimport {ORGANIZATIONS_API_VERSION} from '../../../services/organizations.js'\nimport {CREATE_PROJECT_API_VERSION} from '../../../services/projects.js'\nimport {InitCommand} from '../../init'\n\nconst mocks = vi.hoisted(() => ({\n datasetsCreate: vi.fn(),\n detectFrameworkRecord: vi.fn(),\n getOrganizationChoices: vi.fn(),\n getOrganizationsWithAttachGrantInfo: vi.fn(),\n input: vi.fn(),\n select: vi.fn(),\n usersGetById: vi.fn(),\n}))\n\nvi.mock('@vercel/fs-detectors', () => ({\n detectFrameworkRecord: mocks.detectFrameworkRecord,\n LocalFileSystemDetector: vi.fn(),\n}))\n\nvi.mock('@sanity/cli-core/ux', async () => {\n const actual = await vi.importActual('@sanity/cli-core/ux')\n\n return {\n ...actual,\n input: mocks.input,\n select: mocks.select,\n }\n})\n\nvi.mock('@sanity/cli-core', async (importOriginal) => {\n const actual = await importOriginal<typeof import('@sanity/cli-core')>()\n const testClient = createTestClient({\n apiVersion: 'v2025-05-14',\n token: 'test-token',\n })\n\n return {\n ...actual,\n getGlobalCliClient: vi.fn().mockResolvedValue({\n datasets: {\n create: mocks.datasetsCreate,\n } as never,\n request: testClient.request,\n users: {\n getById: mocks.usersGetById,\n } as never,\n }),\n getProjectCliClient: vi.fn().mockResolvedValue({\n datasets: {\n create: mocks.datasetsCreate,\n } as never,\n }),\n }\n})\n\nvi.mock('../../../actions/organizations/getOrganizationChoices.js', () => ({\n getOrganizationChoices: mocks.getOrganizationChoices,\n}))\n\nvi.mock('../../../actions/organizations/getOrganizationsWithAttachGrantInfo.js', () => ({\n getOrganizationsWithAttachGrantInfo: mocks.getOrganizationsWithAttachGrantInfo,\n}))\n\nmocks.usersGetById.mockResolvedValue({\n email: 'test@example.com',\n id: 'user-123',\n name: 'Test User',\n provider: 'saml-123',\n})\n\ndescribe('#init: create new project', () => {\n afterEach(() => {\n vi.clearAllMocks()\n const pending = nock.pendingMocks()\n nock.cleanAll()\n expect(pending, 'pending mocks').toEqual([])\n })\n\n test('prompts user to create new organization if they have none', async () => {\n mocks.detectFrameworkRecord.mockResolvedValueOnce(null)\n\n mockApi({\n apiVersion: ORGANIZATIONS_API_VERSION,\n method: 'get',\n uri: '/organizations',\n }).reply(200, [])\n\n mocks.input.mockResolvedValueOnce('My New Organization')\n\n mockApi({\n apiVersion: ORGANIZATIONS_API_VERSION,\n method: 'post',\n uri: '/organizations',\n }).reply(200, {\n createdByUserId: 'user-123',\n defaultRoleName: null,\n features: [],\n id: 'org-123',\n members: [],\n name: 'My New Organization',\n slug: 'my-new-organization',\n })\n\n mockApi({\n apiVersion: CREATE_PROJECT_API_VERSION,\n method: 'post',\n uri: '/projects',\n }).reply(200, {\n displayName: 'Test Project',\n projectId: 'project-123',\n })\n\n mocks.datasetsCreate.mockResolvedValueOnce(undefined)\n\n const spinnerSpy = vi.spyOn(cliUX, 'spinner')\n\n await testCommand(\n InitCommand,\n ['--create-project=Test Project', '--dataset=production', '--output-path=./test-project'],\n {\n mocks: {\n isInteractive: true,\n token: 'test-token',\n },\n },\n )\n\n expect(mocks.input).toHaveBeenCalledWith(\n expect.objectContaining({\n default: 'Test User',\n message: 'Organization name:',\n }),\n )\n\n expect(mocks.datasetsCreate).toHaveBeenCalledWith('production')\n\n expect(spinnerSpy).toHaveBeenCalledWith('Creating organization')\n expect(spinnerSpy).toHaveBeenCalledWith('Creating dataset')\n })\n\n test('prompts user to select then create a new organization', async () => {\n mocks.detectFrameworkRecord.mockResolvedValueOnce(null)\n\n mockApi({\n apiVersion: ORGANIZATIONS_API_VERSION,\n method: 'get',\n uri: '/organizations',\n }).reply(200, [\n {\n id: 'existing-org-123',\n name: 'Existing Organization',\n slug: 'existing-organization',\n },\n ])\n\n mocks.getOrganizationsWithAttachGrantInfo.mockResolvedValueOnce([\n {\n hasAttachGrant: true,\n organization: {\n id: 'existing-org-123',\n name: 'Existing Organization',\n slug: 'existing-organization',\n },\n },\n ])\n\n mocks.getOrganizationChoices.mockReturnValueOnce([\n {name: 'Existing Organization [existing-org-123]', value: 'existing-org-123'},\n {name: 'Create new organization', value: '-new-'},\n ])\n\n mocks.select.mockResolvedValueOnce('-new-')\n\n mocks.input.mockResolvedValueOnce('Brand New Organization')\n\n mockApi({\n apiVersion: ORGANIZATIONS_API_VERSION,\n method: 'post',\n uri: '/organizations',\n }).reply(200, {\n createdByUserId: 'user-123',\n defaultRoleName: null,\n features: [],\n id: 'new-org-456',\n members: [],\n name: 'Brand New Organization',\n slug: 'brand-new-organization',\n })\n\n mockApi({\n apiVersion: CREATE_PROJECT_API_VERSION,\n method: 'post',\n uri: '/projects',\n }).reply(200, {\n displayName: 'Test Project',\n projectId: 'project-123',\n })\n\n mocks.datasetsCreate.mockResolvedValueOnce(undefined)\n\n const spinnerSpy = vi.spyOn(cliUX, 'spinner')\n\n await testCommand(\n InitCommand,\n ['--create-project=Test Project', '--dataset=production', '--output-path=./test-project'],\n {\n mocks: {\n isInteractive: true,\n token: 'test-token',\n },\n },\n )\n\n expect(mocks.datasetsCreate).toHaveBeenCalledWith('production')\n\n expect(spinnerSpy).toHaveBeenCalledWith('Creating organization')\n expect(spinnerSpy).toHaveBeenCalledWith('Creating dataset')\n })\n})\n"],"names":["cliUX","createTestClient","mockApi","testCommand","nock","afterEach","describe","expect","test","vi","ORGANIZATIONS_API_VERSION","CREATE_PROJECT_API_VERSION","InitCommand","mocks","hoisted","datasetsCreate","fn","detectFrameworkRecord","getOrganizationChoices","getOrganizationsWithAttachGrantInfo","input","select","usersGetById","mock","LocalFileSystemDetector","actual","importActual","importOriginal","testClient","apiVersion","token","getGlobalCliClient","mockResolvedValue","datasets","create","request","users","getById","getProjectCliClient","email","id","name","provider","clearAllMocks","pending","pendingMocks","cleanAll","toEqual","mockResolvedValueOnce","method","uri","reply","createdByUserId","defaultRoleName","features","members","slug","displayName","projectId","undefined","spinnerSpy","spyOn","isInteractive","toHaveBeenCalledWith","objectContaining","default","message","hasAttachGrant","organization","mockReturnValueOnce","value"],"mappings":"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"}
@@ -1,14 +1,13 @@
1
- import { mockApi, testCommand } from '@sanity/cli-test';
1
+ import { createTestClient, mockApi, testCommand } from '@sanity/cli-test';
2
2
  import { afterEach, describe, expect, test, vi } from 'vitest';
3
+ import { INIT_API_VERSION } from '../../../actions/init/constants.js';
3
4
  import { InitCommand } from '../../init';
4
- const mocks = vi.hoisted(()=>({
5
- confirm: vi.fn()
6
- }));
5
+ const mockConfirm = vi.hoisted(()=>vi.fn());
7
6
  vi.mock('@sanity/cli-core/ux', async ()=>{
8
7
  const actual = await vi.importActual('@sanity/cli-core/ux');
9
8
  return {
10
9
  ...actual,
11
- confirm: mocks.confirm
10
+ confirm: mockConfirm
12
11
  };
13
12
  });
14
13
  vi.mock('@vercel/fs-detectors', ()=>({
@@ -18,20 +17,27 @@ vi.mock('@vercel/fs-detectors', ()=>({
18
17
  }),
19
18
  LocalFileSystemDetector: vi.fn()
20
19
  }));
21
- vi.mock('../../../../../cli-core/src/util/isInteractive.js', ()=>({
22
- isInteractive: vi.fn().mockReturnValue(true)
23
- }));
24
- vi.mock('../../../../../cli-core/src/services/getCliToken.js', ()=>({
25
- getCliToken: vi.fn().mockResolvedValue('test-token')
26
- }));
27
- vi.mock('../../../services/user.js', ()=>({
28
- getCliUser: vi.fn().mockResolvedValue({
29
- email: 'test@example.com',
30
- id: 'user-123',
31
- name: 'Test User',
32
- provider: 'saml-123'
20
+ vi.mock('@sanity/cli-core', async ()=>{
21
+ const actual = await vi.importActual('@sanity/cli-core');
22
+ const testClient = createTestClient({
23
+ apiVersion: INIT_API_VERSION,
24
+ token: 'test-token'
25
+ });
26
+ return {
27
+ ...actual,
28
+ getGlobalCliClient: vi.fn().mockResolvedValue({
29
+ request: testClient.request,
30
+ users: {
31
+ getById: vi.fn().mockResolvedValue({
32
+ email: 'test@example.com',
33
+ id: 'user-123',
34
+ name: 'Test User',
35
+ provider: 'saml-123'
36
+ })
37
+ }
33
38
  })
34
- }));
39
+ };
40
+ });
35
41
  describe('#init: retrieving plan', ()=>{
36
42
  afterEach(()=>{
37
43
  vi.clearAllMocks();
@@ -48,7 +54,12 @@ describe('#init: retrieving plan', ()=>{
48
54
  ]);
49
55
  const { error, stdout } = await testCommand(InitCommand, [
50
56
  '--coupon=TESTCOUPON123'
51
- ]);
57
+ ], {
58
+ mocks: {
59
+ isInteractive: true,
60
+ token: 'test-token'
61
+ }
62
+ });
52
63
  expect(error).toBeUndefined();
53
64
  expect(stdout).toContain('Coupon "TESTCOUPON123" validated!');
54
65
  });
@@ -61,13 +72,18 @@ describe('#init: retrieving plan', ()=>{
61
72
  const { error } = await testCommand(InitCommand, [
62
73
  '--coupon=TESTCOUPON123',
63
74
  '--bare'
64
- ]);
75
+ ], {
76
+ mocks: {
77
+ isInteractive: true,
78
+ token: 'test-token'
79
+ }
80
+ });
65
81
  expect(error?.message).toContain('Unable to validate coupon, please try again later:');
66
82
  expect(error?.message).toContain('No plans found for coupon code "TESTCOUPON123"');
67
83
  });
68
84
  test('throws error if coupon does not have attached plan id', async ()=>{
69
85
  mockApi({
70
- apiVersion: 'v2025-06-01',
86
+ apiVersion: INIT_API_VERSION,
71
87
  method: 'get',
72
88
  uri: '/plans/coupon/TESTCOUPON123'
73
89
  }).reply(200, [
@@ -78,13 +94,18 @@ describe('#init: retrieving plan', ()=>{
78
94
  const { error } = await testCommand(InitCommand, [
79
95
  '--coupon=TESTCOUPON123',
80
96
  '--bare'
81
- ]);
97
+ ], {
98
+ mocks: {
99
+ isInteractive: true,
100
+ token: 'test-token'
101
+ }
102
+ });
82
103
  expect(error?.message).toContain('Unable to validate coupon, please try again later:');
83
104
  expect(error?.message).toContain('Unable to find a plan from coupon code');
84
105
  });
85
106
  test('uses default plan when coupon does not exist and cli in unattended mode', async ()=>{
86
107
  mockApi({
87
- apiVersion: 'v2025-06-01',
108
+ apiVersion: INIT_API_VERSION,
88
109
  method: 'get',
89
110
  uri: '/plans/coupon/INVALID123'
90
111
  }).reply(404, {
@@ -95,25 +116,34 @@ describe('#init: retrieving plan', ()=>{
95
116
  '--yes',
96
117
  '--dataset=test',
97
118
  '--project=test'
98
- ]);
119
+ ], {
120
+ mocks: {
121
+ token: 'test-token'
122
+ }
123
+ });
99
124
  expect(error).toBe(undefined);
100
125
  expect(stderr).toContain('Warning: Coupon "INVALID123" is not available - using default plan');
101
126
  expect(stdout).toContain('Using default plan.');
102
127
  });
103
128
  test('uses default plan when coupon invalid and user confirms default plan', async ()=>{
104
129
  mockApi({
105
- apiVersion: 'v2025-06-01',
130
+ apiVersion: INIT_API_VERSION,
106
131
  method: 'get',
107
132
  uri: '/plans/coupon/INVALID123'
108
133
  }).reply(404, {
109
134
  message: 'Coupon not found'
110
135
  });
111
- mocks.confirm.mockResolvedValue(true);
136
+ mockConfirm.mockResolvedValue(true);
112
137
  const { error, stdout } = await testCommand(InitCommand, [
113
138
  '--coupon=INVALID123'
114
- ]);
139
+ ], {
140
+ mocks: {
141
+ isInteractive: true,
142
+ token: 'test-token'
143
+ }
144
+ });
115
145
  expect(error).toBeUndefined();
116
- expect(mocks.confirm).toHaveBeenCalledWith({
146
+ expect(mockConfirm).toHaveBeenCalledWith({
117
147
  default: true,
118
148
  message: 'Coupon "INVALID123" is not available, use default plan instead?'
119
149
  });
@@ -121,21 +151,26 @@ describe('#init: retrieving plan', ()=>{
121
151
  });
122
152
  test('throws error when coupon invalid and user declines the default plan', async ()=>{
123
153
  mockApi({
124
- apiVersion: 'v2025-06-01',
154
+ apiVersion: INIT_API_VERSION,
125
155
  method: 'get',
126
156
  uri: '/plans/coupon/INVALID123'
127
157
  }).reply(404, {
128
158
  message: 'Coupon not found'
129
159
  });
130
- mocks.confirm.mockResolvedValue(false);
160
+ mockConfirm.mockResolvedValue(false);
131
161
  const { error } = await testCommand(InitCommand, [
132
162
  '--coupon=INVALID123'
133
- ]);
163
+ ], {
164
+ mocks: {
165
+ isInteractive: true,
166
+ token: 'test-token'
167
+ }
168
+ });
134
169
  expect(error?.message).toContain('Coupon "INVALID123" does not exist');
135
170
  });
136
171
  test('returns when client request for plan is successful', async ()=>{
137
172
  mockApi({
138
- apiVersion: 'v2025-06-01',
173
+ apiVersion: INIT_API_VERSION,
139
174
  method: 'get',
140
175
  uri: '/plans/growth'
141
176
  }).reply(200, [
@@ -145,12 +180,17 @@ describe('#init: retrieving plan', ()=>{
145
180
  ]);
146
181
  const { error } = await testCommand(InitCommand, [
147
182
  '--project-plan=growth'
148
- ]);
183
+ ], {
184
+ mocks: {
185
+ isInteractive: true,
186
+ token: 'test-token'
187
+ }
188
+ });
149
189
  expect(error).toBeUndefined();
150
190
  });
151
191
  test('throw error when no plan id is returned by request', async ()=>{
152
192
  mockApi({
153
- apiVersion: 'v2025-06-01',
193
+ apiVersion: INIT_API_VERSION,
154
194
  method: 'get',
155
195
  uri: '/plans/growth'
156
196
  }).reply(200, [
@@ -160,13 +200,18 @@ describe('#init: retrieving plan', ()=>{
160
200
  ]);
161
201
  const { error } = await testCommand(InitCommand, [
162
202
  '--project-plan=growth'
163
- ]);
203
+ ], {
204
+ mocks: {
205
+ isInteractive: true,
206
+ token: 'test-token'
207
+ }
208
+ });
164
209
  expect(error?.message).toContain('Unable to validate plan, please try again later:');
165
210
  expect(error?.message).toContain('Unable to find a plan with id growth');
166
211
  });
167
212
  test('uses default plan when plan id does not exist and cli in unattended mode', async ()=>{
168
213
  mockApi({
169
- apiVersion: 'v2025-06-01',
214
+ apiVersion: INIT_API_VERSION,
170
215
  method: 'get',
171
216
  uri: '/plans/growth'
172
217
  }).reply(404, {
@@ -177,25 +222,34 @@ describe('#init: retrieving plan', ()=>{
177
222
  '--yes',
178
223
  '--dataset=test',
179
224
  '--project==test'
180
- ]);
225
+ ], {
226
+ mocks: {
227
+ token: 'test-token'
228
+ }
229
+ });
181
230
  expect(error).toBe(undefined);
182
231
  expect(stderr).toContain('Warning: Project plan "growth" does not exist - using default plan');
183
232
  expect(stdout).toContain('Using default plan.');
184
233
  });
185
234
  test('uses default plan when plan ID not found and user confirms default plan', async ()=>{
186
235
  mockApi({
187
- apiVersion: 'v2025-06-01',
236
+ apiVersion: INIT_API_VERSION,
188
237
  method: 'get',
189
238
  uri: '/plans/growth'
190
239
  }).reply(404, {
191
240
  message: 'Plan not found'
192
241
  });
193
- mocks.confirm.mockResolvedValue(true);
242
+ mockConfirm.mockResolvedValue(true);
194
243
  const { error, stdout } = await testCommand(InitCommand, [
195
244
  '--project-plan=growth'
196
- ]);
245
+ ], {
246
+ mocks: {
247
+ isInteractive: true,
248
+ token: 'test-token'
249
+ }
250
+ });
197
251
  expect(error).toBeUndefined();
198
- expect(mocks.confirm).toHaveBeenCalledWith({
252
+ expect(mockConfirm).toHaveBeenCalledWith({
199
253
  default: true,
200
254
  message: 'Project plan "growth" does not exist, use default plan instead?'
201
255
  });
@@ -203,16 +257,21 @@ describe('#init: retrieving plan', ()=>{
203
257
  });
204
258
  test('throws error when plan ID not found and user declines default plan', async ()=>{
205
259
  mockApi({
206
- apiVersion: 'v2025-06-01',
260
+ apiVersion: INIT_API_VERSION,
207
261
  method: 'get',
208
262
  uri: '/plans/growth'
209
263
  }).reply(404, {
210
264
  message: 'Plan not found'
211
265
  });
212
- mocks.confirm.mockResolvedValue(false);
266
+ mockConfirm.mockResolvedValue(false);
213
267
  const { error } = await testCommand(InitCommand, [
214
268
  '--project-plan=growth'
215
- ]);
269
+ ], {
270
+ mocks: {
271
+ isInteractive: true,
272
+ token: 'test-token'
273
+ }
274
+ });
216
275
  expect(error?.message).toContain('Plan id "growth" does not exist');
217
276
  });
218
277
  });