@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
@@ -5,24 +5,20 @@ import { afterEach, describe, expect, test, vi } from 'vitest';
5
5
  import { TOKENS_API_VERSION } from '../../../actions/tokens/constants.js';
6
6
  import { NO_PROJECT_ID } from '../../../util/errorMessages.js';
7
7
  import { TokensListCommand } from '../list.js';
8
- // Mock the config functions with relative paths
9
- vi.mock('../../../../../cli-core/src/config/findProjectRoot.js', ()=>({
10
- findProjectRoot: vi.fn().mockResolvedValue({
11
- directory: '/test/path',
12
- root: '/test/path',
13
- type: 'studio'
14
- })
15
- }));
16
- vi.mock('../../../../../cli-core/src/config/cli/getCliConfig.js', ()=>({
17
- getCliConfig: vi.fn().mockResolvedValue({
18
- api: {
19
- projectId: 'test-project'
20
- }
21
- })
22
- }));
23
- vi.mock('../../../../../cli-core/src/services/getCliToken.js', ()=>({
24
- getCliToken: vi.fn().mockResolvedValue('test-token')
25
- }));
8
+ const testProjectId = 'test-project';
9
+ const defaultMocks = {
10
+ cliConfig: {
11
+ api: {
12
+ projectId: testProjectId
13
+ }
14
+ },
15
+ projectRoot: {
16
+ directory: '/test/path',
17
+ path: '/test/path/sanity.config.ts',
18
+ type: 'studio'
19
+ },
20
+ token: 'test-token'
21
+ };
26
22
  const mockTokens = [
27
23
  {
28
24
  createdAt: '2023-01-01T00:00:00Z',
@@ -34,7 +30,7 @@ const mockTokens = [
34
30
  'read',
35
31
  'write'
36
32
  ],
37
- projectId: 'test-project',
33
+ projectId: testProjectId,
38
34
  projectUserId: 'user-1',
39
35
  roles: [
40
36
  {
@@ -56,7 +52,7 @@ const mockTokens = [
56
52
  permissions: [
57
53
  'read'
58
54
  ],
59
- projectId: 'test-project',
55
+ projectId: testProjectId,
60
56
  projectUserId: 'user-2',
61
57
  roles: [
62
58
  {
@@ -74,7 +70,7 @@ const mockTokens = [
74
70
  permissions: [
75
71
  'read'
76
72
  ],
77
- projectId: 'test-project',
73
+ projectId: testProjectId,
78
74
  projectUserId: 'user-3',
79
75
  roles: []
80
76
  }
@@ -118,9 +114,11 @@ describe('#tokens:list', ()=>{
118
114
  test('displays tokens in table format by default', async ()=>{
119
115
  mockApi({
120
116
  apiVersion: TOKENS_API_VERSION,
121
- uri: '/projects/test-project/tokens'
117
+ uri: `/projects/${testProjectId}/tokens`
122
118
  }).reply(200, mockTokens);
123
- const { stdout } = await testCommand(TokensListCommand);
119
+ const { stdout } = await testCommand(TokensListCommand, [], {
120
+ mocks: defaultMocks
121
+ });
124
122
  expect(stdout).toContain('Found 3 API tokens');
125
123
  expect(stdout).toContain('Label');
126
124
  expect(stdout).toContain('Token ID');
@@ -138,11 +136,13 @@ describe('#tokens:list', ()=>{
138
136
  test('displays tokens in JSON format when requested', async ()=>{
139
137
  mockApi({
140
138
  apiVersion: TOKENS_API_VERSION,
141
- uri: '/projects/test-project/tokens'
139
+ uri: `/projects/${testProjectId}/tokens`
142
140
  }).reply(200, mockTokens);
143
141
  const { stdout } = await testCommand(TokensListCommand, [
144
142
  '--json'
145
- ]);
143
+ ], {
144
+ mocks: defaultMocks
145
+ });
146
146
  const parsed = JSON.parse(stdout);
147
147
  expect(parsed).toHaveLength(3);
148
148
  expect(parsed[0]).toMatchObject({
@@ -164,73 +164,90 @@ describe('#tokens:list', ()=>{
164
164
  test('handles empty tokens list', async ()=>{
165
165
  mockApi({
166
166
  apiVersion: TOKENS_API_VERSION,
167
- uri: '/projects/test-project/tokens'
167
+ uri: `/projects/${testProjectId}/tokens`
168
168
  }).reply(200, []);
169
- const { stdout } = await testCommand(TokensListCommand);
169
+ const { stdout } = await testCommand(TokensListCommand, [], {
170
+ mocks: defaultMocks
171
+ });
170
172
  expect(stdout).toBe('No API tokens found for this project.\n');
171
173
  });
172
174
  test('displays an error if the API request fails', async ()=>{
173
175
  mockApi({
174
176
  apiVersion: TOKENS_API_VERSION,
175
- uri: '/projects/test-project/tokens'
177
+ uri: `/projects/${testProjectId}/tokens`
176
178
  }).reply(500, {
177
179
  message: 'Internal Server Error'
178
180
  });
179
- const { error } = await testCommand(TokensListCommand);
181
+ const { error } = await testCommand(TokensListCommand, [], {
182
+ mocks: defaultMocks
183
+ });
180
184
  expect(error).toBeInstanceOf(Error);
181
185
  expect(error?.message).toContain('Token list retrieval failed');
182
186
  expect(error?.message).toContain('Internal Server Error');
183
187
  });
184
188
  test('handles network errors gracefully', async ()=>{
185
189
  // Don't set up any mock to simulate network failure
186
- const { error } = await testCommand(TokensListCommand);
190
+ const { error } = await testCommand(TokensListCommand, [], {
191
+ mocks: defaultMocks
192
+ });
187
193
  expect(error).toBeInstanceOf(Error);
188
194
  expect(error?.message).toContain('Token list retrieval failed');
189
195
  expect(error?.oclif?.exit).toBe(1);
190
196
  });
191
197
  test('throws error when no project ID is found', async ()=>{
192
- const { getCliConfig } = await import('../../../../../cli-core/src/config/cli/getCliConfig.js');
193
- vi.mocked(getCliConfig).mockResolvedValueOnce({
194
- api: {
195
- projectId: undefined
198
+ const { error } = await testCommand(TokensListCommand, [], {
199
+ mocks: {
200
+ ...defaultMocks,
201
+ cliConfig: {
202
+ api: {
203
+ projectId: undefined
204
+ }
205
+ }
196
206
  }
197
207
  });
198
- const { error } = await testCommand(TokensListCommand);
199
208
  expect(error).toBeInstanceOf(Error);
200
209
  expect(error?.message).toEqual(NO_PROJECT_ID);
201
210
  expect(error?.oclif?.exit).toBe(1);
202
211
  });
203
212
  test('throws error when project ID is null', async ()=>{
204
- const { getCliConfig } = await import('../../../../../cli-core/src/config/cli/getCliConfig.js');
205
- vi.mocked(getCliConfig).mockResolvedValueOnce({
206
- api: {
207
- projectId: undefined
213
+ const { error } = await testCommand(TokensListCommand, [], {
214
+ mocks: {
215
+ ...defaultMocks,
216
+ cliConfig: {
217
+ api: {
218
+ projectId: undefined
219
+ }
220
+ }
208
221
  }
209
222
  });
210
- const { error } = await testCommand(TokensListCommand);
211
223
  expect(error).toBeInstanceOf(Error);
212
224
  expect(error?.message).toEqual(NO_PROJECT_ID);
213
225
  expect(error?.oclif?.exit).toBe(1);
214
226
  });
215
227
  test('throws error when project ID is empty string', async ()=>{
216
- const { getCliConfig } = await import('../../../../../cli-core/src/config/cli/getCliConfig.js');
217
- vi.mocked(getCliConfig).mockResolvedValueOnce({
218
- api: {
219
- projectId: ''
228
+ const { error } = await testCommand(TokensListCommand, [], {
229
+ mocks: {
230
+ ...defaultMocks,
231
+ cliConfig: {
232
+ api: {
233
+ projectId: ''
234
+ }
235
+ }
220
236
  }
221
237
  });
222
- const { error } = await testCommand(TokensListCommand);
223
238
  expect(error).toBeInstanceOf(Error);
224
239
  expect(error?.message).toEqual(NO_PROJECT_ID);
225
240
  });
226
241
  test('handles 404 error gracefully', async ()=>{
227
242
  mockApi({
228
243
  apiVersion: TOKENS_API_VERSION,
229
- uri: '/projects/test-project/tokens'
244
+ uri: `/projects/${testProjectId}/tokens`
230
245
  }).reply(404, {
231
246
  message: 'Project not found'
232
247
  });
233
- const { error } = await testCommand(TokensListCommand);
248
+ const { error } = await testCommand(TokensListCommand, [], {
249
+ mocks: defaultMocks
250
+ });
234
251
  expect(error).toBeInstanceOf(Error);
235
252
  expect(error?.message).toContain('Token list retrieval failed');
236
253
  expect(error?.message).toContain('Project not found');
@@ -239,11 +256,13 @@ describe('#tokens:list', ()=>{
239
256
  test('handles 403 forbidden error', async ()=>{
240
257
  mockApi({
241
258
  apiVersion: TOKENS_API_VERSION,
242
- uri: '/projects/test-project/tokens'
259
+ uri: `/projects/${testProjectId}/tokens`
243
260
  }).reply(403, {
244
261
  message: 'Forbidden'
245
262
  });
246
- const { error } = await testCommand(TokensListCommand);
263
+ const { error } = await testCommand(TokensListCommand, [], {
264
+ mocks: defaultMocks
265
+ });
247
266
  expect(error).toBeInstanceOf(Error);
248
267
  expect(error?.message).toContain('Token list retrieval failed');
249
268
  expect(error?.message).toContain('Forbidden');
@@ -255,9 +274,11 @@ describe('#tokens:list', ()=>{
255
274
  ];
256
275
  mockApi({
257
276
  apiVersion: TOKENS_API_VERSION,
258
- uri: '/projects/test-project/tokens'
277
+ uri: `/projects/${testProjectId}/tokens`
259
278
  }).reply(200, singleToken);
260
- const { stdout } = await testCommand(TokensListCommand);
279
+ const { stdout } = await testCommand(TokensListCommand, [], {
280
+ mocks: defaultMocks
281
+ });
261
282
  expect(stdout).toContain('Found 1 API tokens');
262
283
  expect(stdout).toContain('Production API');
263
284
  expect(stdout).toContain('token-1');
@@ -274,7 +295,7 @@ describe('#tokens:list', ()=>{
274
295
  permissions: [
275
296
  'read'
276
297
  ],
277
- projectId: 'test-project',
298
+ projectId: testProjectId,
278
299
  projectUserId: 'user-special',
279
300
  roles: [
280
301
  {
@@ -286,9 +307,11 @@ describe('#tokens:list', ()=>{
286
307
  ];
287
308
  mockApi({
288
309
  apiVersion: TOKENS_API_VERSION,
289
- uri: '/projects/test-project/tokens'
310
+ uri: `/projects/${testProjectId}/tokens`
290
311
  }).reply(200, specialTokens);
291
- const { stdout } = await testCommand(TokensListCommand);
312
+ const { stdout } = await testCommand(TokensListCommand, [], {
313
+ mocks: defaultMocks
314
+ });
292
315
  expect(stdout).toContain('API Token (Test & Dev)');
293
316
  expect(stdout).toContain('token-special');
294
317
  expect(stdout).toContain('Viewer');
@@ -304,7 +327,7 @@ describe('#tokens:list', ()=>{
304
327
  permissions: [
305
328
  'read'
306
329
  ],
307
- projectId: 'test-project',
330
+ projectId: testProjectId,
308
331
  projectUserId: 'user-long',
309
332
  roles: [
310
333
  {
@@ -316,9 +339,11 @@ describe('#tokens:list', ()=>{
316
339
  ];
317
340
  mockApi({
318
341
  apiVersion: TOKENS_API_VERSION,
319
- uri: '/projects/test-project/tokens'
342
+ uri: `/projects/${testProjectId}/tokens`
320
343
  }).reply(200, longLabelTokens);
321
- const { stdout } = await testCommand(TokensListCommand);
344
+ const { stdout } = await testCommand(TokensListCommand, [], {
345
+ mocks: defaultMocks
346
+ });
322
347
  expect(stdout).toContain('This is a very long token label that ...');
323
348
  expect(stdout).not.toContain('because it exceeds the maximum length');
324
349
  });
@@ -333,7 +358,7 @@ describe('#tokens:list', ()=>{
333
358
  permissions: [
334
359
  'read'
335
360
  ],
336
- projectId: 'test-project',
361
+ projectId: testProjectId,
337
362
  projectUserId: 'user-roles',
338
363
  roles: [
339
364
  {
@@ -357,9 +382,11 @@ describe('#tokens:list', ()=>{
357
382
  ];
358
383
  mockApi({
359
384
  apiVersion: TOKENS_API_VERSION,
360
- uri: '/projects/test-project/tokens'
385
+ uri: `/projects/${testProjectId}/tokens`
361
386
  }).reply(200, longRolesTokens);
362
- const { stdout } = await testCommand(TokensListCommand);
387
+ const { stdout } = await testCommand(TokensListCommand, [], {
388
+ mocks: defaultMocks
389
+ });
363
390
  expect(stdout).toContain('Multi Role Token');
364
391
  expect(stdout).toContain('Administrator, Editor, View...');
365
392
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/tokens/__tests__/list.test.ts"],"sourcesContent":["import {runCommand} from '@oclif/test'\nimport {mockApi, testCommand} from '@sanity/cli-test'\nimport nock from 'nock'\nimport {afterEach, describe, expect, test, vi} from 'vitest'\n\nimport {TOKENS_API_VERSION} from '../../../actions/tokens/constants.js'\nimport {NO_PROJECT_ID} from '../../../util/errorMessages.js'\nimport {TokensListCommand} from '../list.js'\n\n// Mock the config functions with relative paths\nvi.mock('../../../../../cli-core/src/config/findProjectRoot.js', () => ({\n findProjectRoot: vi.fn().mockResolvedValue({\n directory: '/test/path',\n root: '/test/path',\n type: 'studio',\n }),\n}))\n\nvi.mock('../../../../../cli-core/src/config/cli/getCliConfig.js', () => ({\n getCliConfig: vi.fn().mockResolvedValue({\n api: {\n projectId: 'test-project',\n },\n }),\n}))\n\nvi.mock('../../../../../cli-core/src/services/getCliToken.js', () => ({\n getCliToken: vi.fn().mockResolvedValue('test-token'),\n}))\n\nconst mockTokens = [\n {\n createdAt: '2023-01-01T00:00:00Z',\n createdBy: 'user@example.com',\n id: 'token-1',\n label: 'Production API',\n lastUsedAt: '2023-12-01T00:00:00Z',\n permissions: ['read', 'write'],\n projectId: 'test-project',\n projectUserId: 'user-1',\n roles: [\n {name: 'admin', title: 'Administrator'},\n {name: 'editor', title: 'Editor'},\n ],\n },\n {\n createdAt: '2023-02-01T00:00:00Z',\n createdBy: 'dev@example.com',\n id: 'token-2',\n label: 'Development API',\n lastUsedAt: null,\n permissions: ['read'],\n projectId: 'test-project',\n projectUserId: 'user-2',\n roles: [{name: 'viewer', title: 'Viewer'}],\n },\n {\n createdAt: '2023-03-01T00:00:00Z',\n createdBy: 'analytics@example.com',\n id: 'token-3',\n label: 'Analytics Token',\n lastUsedAt: '2023-11-15T00:00:00Z',\n permissions: ['read'],\n projectId: 'test-project',\n projectUserId: 'user-3',\n roles: [],\n },\n]\n\ndescribe('#tokens:list', () => {\n afterEach(() => {\n vi.clearAllMocks()\n const pending = nock.pendingMocks()\n nock.cleanAll()\n expect(pending, 'pending mocks').toEqual([])\n })\n\n test('--help works', async () => {\n const {stdout} = await runCommand(['tokens list', '--help'])\n\n expect(stdout).toMatchInlineSnapshot(`\n \"List API tokens for the current project\n\n USAGE\n $ sanity tokens list [--json]\n\n FLAGS\n --json Output tokens in JSON format\n\n DESCRIPTION\n List API tokens for the current project\n\n EXAMPLES\n List tokens for the current project\n\n $ sanity tokens list\n\n List tokens in JSON format\n\n $ sanity tokens list --json\n\n \"\n `)\n })\n\n test('displays tokens in table format by default', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(200, mockTokens)\n\n const {stdout} = await testCommand(TokensListCommand)\n\n expect(stdout).toContain('Found 3 API tokens')\n expect(stdout).toContain('Label')\n expect(stdout).toContain('Token ID')\n expect(stdout).toContain('Roles')\n expect(stdout).toContain('Production API')\n expect(stdout).toContain('token-1')\n expect(stdout).toContain('Administrator, Editor')\n expect(stdout).toContain('Development API')\n expect(stdout).toContain('token-2')\n expect(stdout).toContain('Viewer')\n expect(stdout).toContain('Analytics Token')\n expect(stdout).toContain('token-3')\n expect(stdout).toContain('No roles')\n })\n\n test('displays tokens in JSON format when requested', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(200, mockTokens)\n\n const {stdout} = await testCommand(TokensListCommand, ['--json'])\n\n const parsed = JSON.parse(stdout)\n expect(parsed).toHaveLength(3)\n expect(parsed[0]).toMatchObject({\n createdBy: 'user@example.com',\n id: 'token-1',\n label: 'Production API',\n roles: [\n {name: 'admin', title: 'Administrator'},\n {name: 'editor', title: 'Editor'},\n ],\n })\n })\n\n test('handles empty tokens list', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(200, [])\n\n const {stdout} = await testCommand(TokensListCommand)\n\n expect(stdout).toBe('No API tokens found for this project.\\n')\n })\n\n test('displays an error if the API request fails', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(500, {message: 'Internal Server Error'})\n\n const {error} = await testCommand(TokensListCommand)\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toContain('Token list retrieval failed')\n expect(error?.message).toContain('Internal Server Error')\n })\n\n test('handles network errors gracefully', async () => {\n // Don't set up any mock to simulate network failure\n const {error} = await testCommand(TokensListCommand)\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toContain('Token list retrieval failed')\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('throws error when no project ID is found', async () => {\n const {getCliConfig} = await import('../../../../../cli-core/src/config/cli/getCliConfig.js')\n vi.mocked(getCliConfig).mockResolvedValueOnce({\n api: {\n projectId: undefined,\n },\n })\n\n const {error} = await testCommand(TokensListCommand)\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toEqual(NO_PROJECT_ID)\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('throws error when project ID is null', async () => {\n const {getCliConfig} = await import('../../../../../cli-core/src/config/cli/getCliConfig.js')\n vi.mocked(getCliConfig).mockResolvedValueOnce({\n api: {\n projectId: undefined,\n },\n })\n\n const {error} = await testCommand(TokensListCommand)\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toEqual(NO_PROJECT_ID)\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('throws error when project ID is empty string', async () => {\n const {getCliConfig} = await import('../../../../../cli-core/src/config/cli/getCliConfig.js')\n vi.mocked(getCliConfig).mockResolvedValueOnce({\n api: {\n projectId: '',\n },\n })\n\n const {error} = await testCommand(TokensListCommand)\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toEqual(NO_PROJECT_ID)\n })\n\n test('handles 404 error gracefully', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(404, {message: 'Project not found'})\n\n const {error} = await testCommand(TokensListCommand)\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toContain('Token list retrieval failed')\n expect(error?.message).toContain('Project not found')\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('handles 403 forbidden error', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(403, {message: 'Forbidden'})\n\n const {error} = await testCommand(TokensListCommand)\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toContain('Token list retrieval failed')\n expect(error?.message).toContain('Forbidden')\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('displays single token correctly', async () => {\n const singleToken = [mockTokens[0]]\n\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(200, singleToken)\n\n const {stdout} = await testCommand(TokensListCommand)\n\n expect(stdout).toContain('Found 1 API tokens')\n expect(stdout).toContain('Production API')\n expect(stdout).toContain('token-1')\n expect(stdout).toContain('Administrator, Editor')\n })\n\n test('handles tokens with special characters in labels', async () => {\n const specialTokens = [\n {\n createdAt: '2023-01-01T00:00:00Z',\n createdBy: 'user@café.com',\n id: 'token-special',\n label: 'API Token (Test & Dev)',\n lastUsedAt: null,\n permissions: ['read'],\n projectId: 'test-project',\n projectUserId: 'user-special',\n roles: [{name: 'viewer', title: 'Viewer'}],\n },\n ]\n\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(200, specialTokens)\n\n const {stdout} = await testCommand(TokensListCommand)\n\n expect(stdout).toContain('API Token (Test & Dev)')\n expect(stdout).toContain('token-special')\n expect(stdout).toContain('Viewer')\n })\n\n test('truncates long labels correctly', async () => {\n const longLabelTokens = [\n {\n createdAt: '2023-01-01T00:00:00Z',\n createdBy: 'user@example.com',\n id: 'token-long',\n label:\n 'This is a very long token label that should be truncated because it exceeds the maximum length',\n lastUsedAt: null,\n permissions: ['read'],\n projectId: 'test-project',\n projectUserId: 'user-long',\n roles: [{name: 'viewer', title: 'Viewer'}],\n },\n ]\n\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(200, longLabelTokens)\n\n const {stdout} = await testCommand(TokensListCommand)\n\n expect(stdout).toContain('This is a very long token label that ...')\n expect(stdout).not.toContain('because it exceeds the maximum length')\n })\n\n test('truncates long roles correctly', async () => {\n const longRolesTokens = [\n {\n createdAt: '2023-01-01T00:00:00Z',\n createdBy: 'user@example.com',\n id: 'token-roles',\n label: 'Multi Role Token',\n lastUsedAt: null,\n permissions: ['read'],\n projectId: 'test-project',\n projectUserId: 'user-roles',\n roles: [\n {name: 'administrator', title: 'Administrator'},\n {name: 'editor', title: 'Editor'},\n {name: 'viewer', title: 'Viewer'},\n {name: 'contributor', title: 'Contributor'},\n ],\n },\n ]\n\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: '/projects/test-project/tokens',\n }).reply(200, longRolesTokens)\n\n const {stdout} = await testCommand(TokensListCommand)\n\n expect(stdout).toContain('Multi Role Token')\n expect(stdout).toContain('Administrator, Editor, View...')\n })\n})\n"],"names":["runCommand","mockApi","testCommand","nock","afterEach","describe","expect","test","vi","TOKENS_API_VERSION","NO_PROJECT_ID","TokensListCommand","mock","findProjectRoot","fn","mockResolvedValue","directory","root","type","getCliConfig","api","projectId","getCliToken","mockTokens","createdAt","createdBy","id","label","lastUsedAt","permissions","projectUserId","roles","name","title","clearAllMocks","pending","pendingMocks","cleanAll","toEqual","stdout","toMatchInlineSnapshot","apiVersion","uri","reply","toContain","parsed","JSON","parse","toHaveLength","toMatchObject","toBe","message","error","toBeInstanceOf","Error","oclif","exit","mocked","mockResolvedValueOnce","undefined","singleToken","specialTokens","longLabelTokens","not","longRolesTokens"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/commands/tokens/__tests__/list.test.ts"],"sourcesContent":["import {runCommand} from '@oclif/test'\nimport {mockApi, testCommand} from '@sanity/cli-test'\nimport nock from 'nock'\nimport {afterEach, describe, expect, test, vi} from 'vitest'\n\nimport {TOKENS_API_VERSION} from '../../../actions/tokens/constants.js'\nimport {NO_PROJECT_ID} from '../../../util/errorMessages.js'\nimport {TokensListCommand} from '../list.js'\n\nconst testProjectId = 'test-project'\n\nconst defaultMocks = {\n cliConfig: {api: {projectId: testProjectId}},\n projectRoot: {\n directory: '/test/path',\n path: '/test/path/sanity.config.ts',\n type: 'studio' as const,\n },\n token: 'test-token',\n}\n\nconst mockTokens = [\n {\n createdAt: '2023-01-01T00:00:00Z',\n createdBy: 'user@example.com',\n id: 'token-1',\n label: 'Production API',\n lastUsedAt: '2023-12-01T00:00:00Z',\n permissions: ['read', 'write'],\n projectId: testProjectId,\n projectUserId: 'user-1',\n roles: [\n {name: 'admin', title: 'Administrator'},\n {name: 'editor', title: 'Editor'},\n ],\n },\n {\n createdAt: '2023-02-01T00:00:00Z',\n createdBy: 'dev@example.com',\n id: 'token-2',\n label: 'Development API',\n lastUsedAt: null,\n permissions: ['read'],\n projectId: testProjectId,\n projectUserId: 'user-2',\n roles: [{name: 'viewer', title: 'Viewer'}],\n },\n {\n createdAt: '2023-03-01T00:00:00Z',\n createdBy: 'analytics@example.com',\n id: 'token-3',\n label: 'Analytics Token',\n lastUsedAt: '2023-11-15T00:00:00Z',\n permissions: ['read'],\n projectId: testProjectId,\n projectUserId: 'user-3',\n roles: [],\n },\n]\n\ndescribe('#tokens:list', () => {\n afterEach(() => {\n vi.clearAllMocks()\n const pending = nock.pendingMocks()\n nock.cleanAll()\n expect(pending, 'pending mocks').toEqual([])\n })\n\n test('--help works', async () => {\n const {stdout} = await runCommand(['tokens list', '--help'])\n\n expect(stdout).toMatchInlineSnapshot(`\n \"List API tokens for the current project\n\n USAGE\n $ sanity tokens list [--json]\n\n FLAGS\n --json Output tokens in JSON format\n\n DESCRIPTION\n List API tokens for the current project\n\n EXAMPLES\n List tokens for the current project\n\n $ sanity tokens list\n\n List tokens in JSON format\n\n $ sanity tokens list --json\n\n \"\n `)\n })\n\n test('displays tokens in table format by default', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(200, mockTokens)\n\n const {stdout} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(stdout).toContain('Found 3 API tokens')\n expect(stdout).toContain('Label')\n expect(stdout).toContain('Token ID')\n expect(stdout).toContain('Roles')\n expect(stdout).toContain('Production API')\n expect(stdout).toContain('token-1')\n expect(stdout).toContain('Administrator, Editor')\n expect(stdout).toContain('Development API')\n expect(stdout).toContain('token-2')\n expect(stdout).toContain('Viewer')\n expect(stdout).toContain('Analytics Token')\n expect(stdout).toContain('token-3')\n expect(stdout).toContain('No roles')\n })\n\n test('displays tokens in JSON format when requested', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(200, mockTokens)\n\n const {stdout} = await testCommand(TokensListCommand, ['--json'], {mocks: defaultMocks})\n\n const parsed = JSON.parse(stdout)\n expect(parsed).toHaveLength(3)\n expect(parsed[0]).toMatchObject({\n createdBy: 'user@example.com',\n id: 'token-1',\n label: 'Production API',\n roles: [\n {name: 'admin', title: 'Administrator'},\n {name: 'editor', title: 'Editor'},\n ],\n })\n })\n\n test('handles empty tokens list', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(200, [])\n\n const {stdout} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(stdout).toBe('No API tokens found for this project.\\n')\n })\n\n test('displays an error if the API request fails', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(500, {message: 'Internal Server Error'})\n\n const {error} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toContain('Token list retrieval failed')\n expect(error?.message).toContain('Internal Server Error')\n })\n\n test('handles network errors gracefully', async () => {\n // Don't set up any mock to simulate network failure\n const {error} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toContain('Token list retrieval failed')\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('throws error when no project ID is found', async () => {\n const {error} = await testCommand(TokensListCommand, [], {\n mocks: {\n ...defaultMocks,\n cliConfig: {api: {projectId: undefined}},\n },\n })\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toEqual(NO_PROJECT_ID)\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('throws error when project ID is null', async () => {\n const {error} = await testCommand(TokensListCommand, [], {\n mocks: {\n ...defaultMocks,\n cliConfig: {api: {projectId: undefined}},\n },\n })\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toEqual(NO_PROJECT_ID)\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('throws error when project ID is empty string', async () => {\n const {error} = await testCommand(TokensListCommand, [], {\n mocks: {\n ...defaultMocks,\n cliConfig: {api: {projectId: ''}},\n },\n })\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toEqual(NO_PROJECT_ID)\n })\n\n test('handles 404 error gracefully', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(404, {message: 'Project not found'})\n\n const {error} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toContain('Token list retrieval failed')\n expect(error?.message).toContain('Project not found')\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('handles 403 forbidden error', async () => {\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(403, {message: 'Forbidden'})\n\n const {error} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(error).toBeInstanceOf(Error)\n expect(error?.message).toContain('Token list retrieval failed')\n expect(error?.message).toContain('Forbidden')\n expect(error?.oclif?.exit).toBe(1)\n })\n\n test('displays single token correctly', async () => {\n const singleToken = [mockTokens[0]]\n\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(200, singleToken)\n\n const {stdout} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(stdout).toContain('Found 1 API tokens')\n expect(stdout).toContain('Production API')\n expect(stdout).toContain('token-1')\n expect(stdout).toContain('Administrator, Editor')\n })\n\n test('handles tokens with special characters in labels', async () => {\n const specialTokens = [\n {\n createdAt: '2023-01-01T00:00:00Z',\n createdBy: 'user@café.com',\n id: 'token-special',\n label: 'API Token (Test & Dev)',\n lastUsedAt: null,\n permissions: ['read'],\n projectId: testProjectId,\n projectUserId: 'user-special',\n roles: [{name: 'viewer', title: 'Viewer'}],\n },\n ]\n\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(200, specialTokens)\n\n const {stdout} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(stdout).toContain('API Token (Test & Dev)')\n expect(stdout).toContain('token-special')\n expect(stdout).toContain('Viewer')\n })\n\n test('truncates long labels correctly', async () => {\n const longLabelTokens = [\n {\n createdAt: '2023-01-01T00:00:00Z',\n createdBy: 'user@example.com',\n id: 'token-long',\n label:\n 'This is a very long token label that should be truncated because it exceeds the maximum length',\n lastUsedAt: null,\n permissions: ['read'],\n projectId: testProjectId,\n projectUserId: 'user-long',\n roles: [{name: 'viewer', title: 'Viewer'}],\n },\n ]\n\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(200, longLabelTokens)\n\n const {stdout} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(stdout).toContain('This is a very long token label that ...')\n expect(stdout).not.toContain('because it exceeds the maximum length')\n })\n\n test('truncates long roles correctly', async () => {\n const longRolesTokens = [\n {\n createdAt: '2023-01-01T00:00:00Z',\n createdBy: 'user@example.com',\n id: 'token-roles',\n label: 'Multi Role Token',\n lastUsedAt: null,\n permissions: ['read'],\n projectId: testProjectId,\n projectUserId: 'user-roles',\n roles: [\n {name: 'administrator', title: 'Administrator'},\n {name: 'editor', title: 'Editor'},\n {name: 'viewer', title: 'Viewer'},\n {name: 'contributor', title: 'Contributor'},\n ],\n },\n ]\n\n mockApi({\n apiVersion: TOKENS_API_VERSION,\n uri: `/projects/${testProjectId}/tokens`,\n }).reply(200, longRolesTokens)\n\n const {stdout} = await testCommand(TokensListCommand, [], {mocks: defaultMocks})\n\n expect(stdout).toContain('Multi Role Token')\n expect(stdout).toContain('Administrator, Editor, View...')\n })\n})\n"],"names":["runCommand","mockApi","testCommand","nock","afterEach","describe","expect","test","vi","TOKENS_API_VERSION","NO_PROJECT_ID","TokensListCommand","testProjectId","defaultMocks","cliConfig","api","projectId","projectRoot","directory","path","type","token","mockTokens","createdAt","createdBy","id","label","lastUsedAt","permissions","projectUserId","roles","name","title","clearAllMocks","pending","pendingMocks","cleanAll","toEqual","stdout","toMatchInlineSnapshot","apiVersion","uri","reply","mocks","toContain","parsed","JSON","parse","toHaveLength","toMatchObject","toBe","message","error","toBeInstanceOf","Error","oclif","exit","undefined","singleToken","specialTokens","longLabelTokens","not","longRolesTokens"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import { isInteractive, SanityCommand, subdebug } from '@sanity/cli-core';
2
+ import { SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { input, select } from '@sanity/cli-core/ux';
4
4
  import { validateRole } from '../../actions/tokens/validateRole.js';
5
5
  import { createToken, getTokenRoles } from '../../services/tokens.js';
@@ -88,8 +88,7 @@ export class AddTokenCommand extends SanityCommand {
88
88
  }
89
89
  }
90
90
  async promptForLabel() {
91
- const unattended = this.flags.yes;
92
- if (unattended || !isInteractive()) {
91
+ if (this.isUnattended()) {
93
92
  this.error('Token label is required in non-interactive mode. Provide a label as an argument.', {
94
93
  exit: 1
95
94
  });
@@ -106,8 +105,7 @@ export class AddTokenCommand extends SanityCommand {
106
105
  return label;
107
106
  }
108
107
  async promptForRole(projectId) {
109
- const unattended = this.flags.yes;
110
- if (unattended || !isInteractive()) {
108
+ if (this.isUnattended()) {
111
109
  return 'viewer' // Default role for unattended mode
112
110
  ;
113
111
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/tokens/add.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {isInteractive, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input, select} from '@sanity/cli-core/ux'\n\nimport {validateRole} from '../../actions/tokens/validateRole.js'\nimport {createToken, getTokenRoles} from '../../services/tokens.js'\nimport {NO_PROJECT_ID} from '../../util/errorMessages.js'\n\nconst tokensAddDebug = subdebug('tokens:add')\n\nexport class AddTokenCommand extends SanityCommand<typeof AddTokenCommand> {\n static override args = {\n label: Args.string({\n description: 'Label for the new token',\n required: false,\n }),\n }\n\n static override description = 'Create a new API token for this project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> \"My API Token\"',\n description: 'Create a token with a label',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My API Token\" --role=editor',\n description: 'Create a token with editor role',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"CI Token\" --role=editor --yes',\n description: 'Create a token in unattended mode',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"API Token\" --json',\n description: 'Output token information as JSON',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output as JSON',\n }),\n role: Flags.string({\n description: 'Role to assign to the token',\n helpValue: 'viewer',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description: 'Skip prompts and use defaults (unattended mode)',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(AddTokenCommand)\n const {label: givenLabel} = args\n const {json, role} = flags\n\n const projectId = await this.getProjectId()\n if (!projectId) {\n this.error(NO_PROJECT_ID, {exit: 1})\n }\n\n try {\n const label = givenLabel || (await this.promptForLabel())\n const roleName = await (role ? validateRole(role, projectId) : this.promptForRole(projectId))\n\n tokensAddDebug(`Creating token for project ${projectId}`, {label, roleName})\n const token = await createToken({\n label,\n projectId,\n roleName,\n })\n\n if (json) {\n this.log(JSON.stringify(token, null, 2))\n return\n }\n\n this.log('Token created successfully!')\n this.log(`Label: ${token.label}`)\n this.log(`ID: ${token.id}`)\n this.log(`Role: ${token.roles.map((r) => r.title).join(', ')}`)\n this.log(`Token: ${token.key}`)\n this.log('')\n this.log('Copy the token above – this is your only chance to do so!')\n } catch (error) {\n const err = error as Error\n\n tokensAddDebug(`Error creating token for project ${projectId}`, err)\n this.error(`Token creation failed:\\n${err.message}`, {exit: 1})\n }\n }\n\n private async promptForLabel(): Promise<string> {\n const unattended = this.flags.yes\n if (unattended || !isInteractive()) {\n this.error(\n 'Token label is required in non-interactive mode. Provide a label as an argument.',\n {\n exit: 1,\n },\n )\n }\n\n const label = await input({\n message: 'Token label:',\n validate: (value) => {\n if (!value || !value.trim()) {\n return 'Label cannot be empty'\n }\n return true\n },\n })\n\n return label\n }\n\n private async promptForRole(projectId: string): Promise<string> {\n const unattended = this.flags.yes\n if (unattended || !isInteractive()) {\n return 'viewer' // Default role for unattended mode\n }\n\n const roles = await getTokenRoles(projectId)\n const robotRoles = roles.filter((role) => role.appliesToRobots)\n\n tokensAddDebug('Robot roles', {robotRoles})\n\n if (robotRoles.length === 0) {\n this.error('No roles available for tokens', {exit: 1})\n }\n\n const selectedRoleName = await select({\n choices: robotRoles.map((role) => ({\n name: `${role.title} (${role.name})`,\n short: role.title,\n value: role.name,\n })),\n default: 'viewer',\n message: 'Select role for the token:',\n })\n\n return selectedRoleName\n }\n}\n"],"names":["Args","Flags","isInteractive","SanityCommand","subdebug","input","select","validateRole","createToken","getTokenRoles","NO_PROJECT_ID","tokensAddDebug","AddTokenCommand","args","label","string","description","required","examples","command","flags","json","boolean","default","role","helpValue","yes","char","run","parse","givenLabel","projectId","getProjectId","error","exit","promptForLabel","roleName","promptForRole","token","log","JSON","stringify","id","roles","map","r","title","join","key","err","message","unattended","validate","value","trim","robotRoles","filter","appliesToRobots","length","selectedRoleName","choices","name","short"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/tokens/add.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input, select} from '@sanity/cli-core/ux'\n\nimport {validateRole} from '../../actions/tokens/validateRole.js'\nimport {createToken, getTokenRoles} from '../../services/tokens.js'\nimport {NO_PROJECT_ID} from '../../util/errorMessages.js'\n\nconst tokensAddDebug = subdebug('tokens:add')\n\nexport class AddTokenCommand extends SanityCommand<typeof AddTokenCommand> {\n static override args = {\n label: Args.string({\n description: 'Label for the new token',\n required: false,\n }),\n }\n\n static override description = 'Create a new API token for this project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> \"My API Token\"',\n description: 'Create a token with a label',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My API Token\" --role=editor',\n description: 'Create a token with editor role',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"CI Token\" --role=editor --yes',\n description: 'Create a token in unattended mode',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"API Token\" --json',\n description: 'Output token information as JSON',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output as JSON',\n }),\n role: Flags.string({\n description: 'Role to assign to the token',\n helpValue: 'viewer',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description: 'Skip prompts and use defaults (unattended mode)',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(AddTokenCommand)\n const {label: givenLabel} = args\n const {json, role} = flags\n\n const projectId = await this.getProjectId()\n if (!projectId) {\n this.error(NO_PROJECT_ID, {exit: 1})\n }\n\n try {\n const label = givenLabel || (await this.promptForLabel())\n const roleName = await (role ? validateRole(role, projectId) : this.promptForRole(projectId))\n\n tokensAddDebug(`Creating token for project ${projectId}`, {label, roleName})\n const token = await createToken({\n label,\n projectId,\n roleName,\n })\n\n if (json) {\n this.log(JSON.stringify(token, null, 2))\n return\n }\n\n this.log('Token created successfully!')\n this.log(`Label: ${token.label}`)\n this.log(`ID: ${token.id}`)\n this.log(`Role: ${token.roles.map((r) => r.title).join(', ')}`)\n this.log(`Token: ${token.key}`)\n this.log('')\n this.log('Copy the token above – this is your only chance to do so!')\n } catch (error) {\n const err = error as Error\n\n tokensAddDebug(`Error creating token for project ${projectId}`, err)\n this.error(`Token creation failed:\\n${err.message}`, {exit: 1})\n }\n }\n\n private async promptForLabel(): Promise<string> {\n if (this.isUnattended()) {\n this.error(\n 'Token label is required in non-interactive mode. Provide a label as an argument.',\n {\n exit: 1,\n },\n )\n }\n\n const label = await input({\n message: 'Token label:',\n validate: (value) => {\n if (!value || !value.trim()) {\n return 'Label cannot be empty'\n }\n return true\n },\n })\n\n return label\n }\n\n private async promptForRole(projectId: string): Promise<string> {\n if (this.isUnattended()) {\n return 'viewer' // Default role for unattended mode\n }\n\n const roles = await getTokenRoles(projectId)\n const robotRoles = roles.filter((role) => role.appliesToRobots)\n\n tokensAddDebug('Robot roles', {robotRoles})\n\n if (robotRoles.length === 0) {\n this.error('No roles available for tokens', {exit: 1})\n }\n\n const selectedRoleName = await select({\n choices: robotRoles.map((role) => ({\n name: `${role.title} (${role.name})`,\n short: role.title,\n value: role.name,\n })),\n default: 'viewer',\n message: 'Select role for the token:',\n })\n\n return selectedRoleName\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","select","validateRole","createToken","getTokenRoles","NO_PROJECT_ID","tokensAddDebug","AddTokenCommand","args","label","string","description","required","examples","command","flags","json","boolean","default","role","helpValue","yes","char","run","parse","givenLabel","projectId","getProjectId","error","exit","promptForLabel","roleName","promptForRole","token","log","JSON","stringify","id","roles","map","r","title","join","key","err","message","isUnattended","validate","value","trim","robotRoles","filter","appliesToRobots","length","selectedRoleName","choices","name","short"],"mappings":"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"}