@payloadcms/figma 0.0.1-alpha.1 → 0.0.1-alpha.10

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 (308) hide show
  1. package/dist/api/control-plane.d.ts.map +1 -1
  2. package/dist/api/control-plane.js +2 -7
  3. package/dist/api/control-plane.js.map +1 -1
  4. package/dist/api/figma-api.js +3 -3
  5. package/dist/api/figma-api.js.map +1 -1
  6. package/dist/auth/jwt-validator.js.map +1 -1
  7. package/dist/auth/oauth-flow.d.ts.map +1 -1
  8. package/dist/auth/oauth-flow.js +3 -6
  9. package/dist/auth/oauth-flow.js.map +1 -1
  10. package/dist/auth/project-token.d.ts.map +1 -1
  11. package/dist/auth/project-token.js +1 -4
  12. package/dist/auth/project-token.js.map +1 -1
  13. package/dist/auth/refresh.d.ts.map +1 -1
  14. package/dist/auth/refresh.js +19 -28
  15. package/dist/auth/refresh.js.map +1 -1
  16. package/dist/auth/types.d.ts +1 -1
  17. package/dist/auth/types.d.ts.map +1 -1
  18. package/dist/auth/types.js.map +1 -1
  19. package/dist/cli.js +1 -3
  20. package/dist/cli.js.map +1 -1
  21. package/dist/commands/deploy.d.ts.map +1 -1
  22. package/dist/commands/deploy.js +17 -10
  23. package/dist/commands/deploy.js.map +1 -1
  24. package/dist/commands/init.d.ts +4 -0
  25. package/dist/commands/init.d.ts.map +1 -1
  26. package/dist/commands/init.js +21 -85
  27. package/dist/commands/init.js.map +1 -1
  28. package/dist/commands/list-tokens.d.ts +1 -1
  29. package/dist/commands/list-tokens.d.ts.map +1 -1
  30. package/dist/commands/list-tokens.js +6 -5
  31. package/dist/commands/list-tokens.js.map +1 -1
  32. package/dist/commands/login.d.ts +2 -11
  33. package/dist/commands/login.d.ts.map +1 -1
  34. package/dist/commands/login.js +4 -7
  35. package/dist/commands/login.js.map +1 -1
  36. package/dist/commands/logout.d.ts +1 -1
  37. package/dist/commands/logout.js +1 -1
  38. package/dist/commands/logout.js.map +1 -1
  39. package/dist/exports/client.d.ts +3 -0
  40. package/dist/exports/client.d.ts.map +1 -0
  41. package/dist/exports/client.js +4 -0
  42. package/dist/exports/client.js.map +1 -0
  43. package/dist/oauth/components/LoginButton/index.d.ts +9 -0
  44. package/dist/oauth/components/LoginButton/index.d.ts.map +1 -0
  45. package/dist/oauth/components/LoginButton/index.js +52 -0
  46. package/dist/oauth/components/LoginButton/index.js.map +1 -0
  47. package/dist/oauth/components/LoginButton/index.scss +10 -0
  48. package/dist/oauth/components/LogoutButton/index.d.ts +7 -0
  49. package/dist/oauth/components/LogoutButton/index.d.ts.map +1 -0
  50. package/dist/oauth/components/LogoutButton/index.js +67 -0
  51. package/dist/oauth/components/LogoutButton/index.js.map +1 -0
  52. package/dist/oauth/components/LogoutButton/index.scss +10 -0
  53. package/dist/oauth/defaults.d.ts +10 -0
  54. package/dist/oauth/defaults.d.ts.map +1 -0
  55. package/dist/oauth/defaults.js +91 -0
  56. package/dist/oauth/defaults.js.map +1 -0
  57. package/dist/oauth/endpoints/getLoginEndpoint.d.ts +13 -0
  58. package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +1 -0
  59. package/dist/oauth/endpoints/getLoginEndpoint.js +237 -0
  60. package/dist/oauth/endpoints/getLoginEndpoint.js.map +1 -0
  61. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts +12 -0
  62. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +1 -0
  63. package/dist/oauth/endpoints/getLogoutEndpoint.js +99 -0
  64. package/dist/oauth/endpoints/getLogoutEndpoint.js.map +1 -0
  65. package/dist/oauth/endpoints/getMetaEndpoint.d.ts +13 -0
  66. package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +1 -0
  67. package/dist/oauth/endpoints/getMetaEndpoint.js +25 -0
  68. package/dist/oauth/endpoints/getMetaEndpoint.js.map +1 -0
  69. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts +13 -0
  70. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +1 -0
  71. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js +21 -0
  72. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +1 -0
  73. package/dist/oauth/exports/client.d.ts +3 -0
  74. package/dist/oauth/exports/client.d.ts.map +1 -0
  75. package/dist/oauth/exports/client.js +4 -0
  76. package/dist/oauth/exports/client.js.map +1 -0
  77. package/dist/oauth/hooks/afterLogout.d.ts +8 -0
  78. package/dist/oauth/hooks/afterLogout.d.ts.map +1 -0
  79. package/dist/oauth/hooks/afterLogout.js +27 -0
  80. package/dist/oauth/hooks/afterLogout.js.map +1 -0
  81. package/dist/oauth/hooks/me.d.ts +5 -0
  82. package/dist/oauth/hooks/me.d.ts.map +1 -0
  83. package/dist/oauth/hooks/me.js +55 -0
  84. package/dist/oauth/hooks/me.js.map +1 -0
  85. package/dist/oauth/hooks/refresh.d.ts +8 -0
  86. package/dist/oauth/hooks/refresh.d.ts.map +1 -0
  87. package/dist/oauth/hooks/refresh.js +91 -0
  88. package/dist/oauth/hooks/refresh.js.map +1 -0
  89. package/dist/oauth/index.d.ts +4 -0
  90. package/dist/oauth/index.d.ts.map +1 -0
  91. package/dist/oauth/index.js +222 -0
  92. package/dist/oauth/index.js.map +1 -0
  93. package/dist/oauth/strategy/index.d.ts +54 -0
  94. package/dist/oauth/strategy/index.d.ts.map +1 -0
  95. package/dist/oauth/strategy/index.js +280 -0
  96. package/dist/oauth/strategy/index.js.map +1 -0
  97. package/dist/oauth/types.d.ts +192 -0
  98. package/dist/oauth/types.d.ts.map +1 -0
  99. package/dist/oauth/types.js +3 -0
  100. package/dist/oauth/types.js.map +1 -0
  101. package/dist/oauth/utilities/clearCookie.d.ts +9 -0
  102. package/dist/oauth/utilities/clearCookie.d.ts.map +1 -0
  103. package/dist/oauth/utilities/clearCookie.js +21 -0
  104. package/dist/oauth/utilities/clearCookie.js.map +1 -0
  105. package/dist/oauth/utilities/createCookieOptions.d.ts +10 -0
  106. package/dist/oauth/utilities/createCookieOptions.d.ts.map +1 -0
  107. package/dist/oauth/utilities/createCookieOptions.js +42 -0
  108. package/dist/oauth/utilities/createCookieOptions.js.map +1 -0
  109. package/dist/oauth/utilities/createDebugLogger.d.ts +4 -0
  110. package/dist/oauth/utilities/createDebugLogger.d.ts.map +1 -0
  111. package/dist/oauth/utilities/createDebugLogger.js +16 -0
  112. package/dist/oauth/utilities/createDebugLogger.js.map +1 -0
  113. package/dist/oauth/utilities/extractOrigin.d.ts +2 -0
  114. package/dist/oauth/utilities/extractOrigin.d.ts.map +1 -0
  115. package/dist/oauth/utilities/extractOrigin.js +12 -0
  116. package/dist/oauth/utilities/extractOrigin.js.map +1 -0
  117. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts +3 -0
  118. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +1 -0
  119. package/dist/oauth/utilities/getAdminCollectionSlug.js +18 -0
  120. package/dist/oauth/utilities/getAdminCollectionSlug.js.map +1 -0
  121. package/dist/oauth/utilities/getAdminPath.d.ts +8 -0
  122. package/dist/oauth/utilities/getAdminPath.d.ts.map +1 -0
  123. package/dist/oauth/utilities/getAdminPath.js +9 -0
  124. package/dist/oauth/utilities/getAdminPath.js.map +1 -0
  125. package/dist/oauth/utilities/getAuthorizeURL.d.ts +17 -0
  126. package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +1 -0
  127. package/dist/oauth/utilities/getAuthorizeURL.js +45 -0
  128. package/dist/oauth/utilities/getAuthorizeURL.js.map +1 -0
  129. package/dist/oauth/utilities/getCookieExpiration.d.ts +4 -0
  130. package/dist/oauth/utilities/getCookieExpiration.d.ts.map +1 -0
  131. package/dist/oauth/utilities/getCookieExpiration.js +11 -0
  132. package/dist/oauth/utilities/getCookieExpiration.js.map +1 -0
  133. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts +2 -0
  134. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +1 -0
  135. package/dist/oauth/utilities/getSecondsFromTokenExp.js +7 -0
  136. package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +1 -0
  137. package/dist/oauth/utilities/getTokenExp.d.ts +6 -0
  138. package/dist/oauth/utilities/getTokenExp.d.ts.map +1 -0
  139. package/dist/oauth/utilities/getTokenExp.js +20 -0
  140. package/dist/oauth/utilities/getTokenExp.js.map +1 -0
  141. package/dist/oauth/utilities/getUsernameField.d.ts +9 -0
  142. package/dist/oauth/utilities/getUsernameField.d.ts.map +1 -0
  143. package/dist/oauth/utilities/getUsernameField.js +20 -0
  144. package/dist/oauth/utilities/getUsernameField.js.map +1 -0
  145. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts +8 -0
  146. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +1 -0
  147. package/dist/oauth/utilities/hasUserTokenPropsChanged.js +25 -0
  148. package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +1 -0
  149. package/dist/oauth/utilities/mergeHeaders.d.ts +2 -0
  150. package/dist/oauth/utilities/mergeHeaders.d.ts.map +1 -0
  151. package/dist/oauth/utilities/mergeHeaders.js +37 -0
  152. package/dist/oauth/utilities/mergeHeaders.js.map +1 -0
  153. package/dist/oauth/utilities/refreshTokens.d.ts +16 -0
  154. package/dist/oauth/utilities/refreshTokens.d.ts.map +1 -0
  155. package/dist/oauth/utilities/refreshTokens.js +67 -0
  156. package/dist/oauth/utilities/refreshTokens.js.map +1 -0
  157. package/dist/plugin/build-config.d.ts +7 -1
  158. package/dist/plugin/build-config.d.ts.map +1 -1
  159. package/dist/plugin/build-config.js +29 -2
  160. package/dist/plugin/build-config.js.map +1 -1
  161. package/dist/types/config.d.ts +0 -11
  162. package/dist/types/config.d.ts.map +1 -1
  163. package/dist/types/config.js +1 -1
  164. package/dist/types/config.js.map +1 -1
  165. package/dist/utils/config.d.ts +0 -22
  166. package/dist/utils/config.d.ts.map +1 -1
  167. package/dist/utils/config.js +0 -46
  168. package/dist/utils/config.js.map +1 -1
  169. package/dist/utils/messages.js +11 -11
  170. package/dist/utils/messages.js.map +1 -1
  171. package/dist/utils/payload-config-ast.d.ts +17 -1
  172. package/dist/utils/payload-config-ast.d.ts.map +1 -1
  173. package/dist/utils/payload-config-ast.js +166 -14
  174. package/dist/utils/payload-config-ast.js.map +1 -1
  175. package/dist/utils/payload-config-modifier.d.ts +2 -1
  176. package/dist/utils/payload-config-modifier.d.ts.map +1 -1
  177. package/dist/utils/payload-config-modifier.js +50 -79
  178. package/dist/utils/payload-config-modifier.js.map +1 -1
  179. package/dist/utils/payload-package-check.d.ts.map +1 -1
  180. package/dist/utils/payload-package-check.js +14 -33
  181. package/dist/utils/payload-package-check.js.map +1 -1
  182. package/dist/utils/project.d.ts +1 -1
  183. package/dist/utils/project.d.ts.map +1 -1
  184. package/dist/utils/project.js +3 -5
  185. package/dist/utils/project.js.map +1 -1
  186. package/dist/utils/s3-upload.d.ts.map +1 -1
  187. package/dist/utils/s3-upload.js +3 -8
  188. package/dist/utils/s3-upload.js.map +1 -1
  189. package/dist/utils/token-display.d.ts.map +1 -1
  190. package/dist/utils/token-display.js +3 -2
  191. package/dist/utils/token-display.js.map +1 -1
  192. package/package.json +9 -3
  193. package/dist/api/control-plane.spec.d.ts +0 -2
  194. package/dist/api/control-plane.spec.d.ts.map +0 -1
  195. package/dist/api/control-plane.spec.js +0 -296
  196. package/dist/api/control-plane.spec.js.map +0 -1
  197. package/dist/api/figma-api.spec.d.ts +0 -14
  198. package/dist/api/figma-api.spec.d.ts.map +0 -1
  199. package/dist/api/figma-api.spec.js +0 -201
  200. package/dist/api/figma-api.spec.js.map +0 -1
  201. package/dist/auth/__tests__/fixtures.d.ts +0 -26
  202. package/dist/auth/__tests__/fixtures.d.ts.map +0 -1
  203. package/dist/auth/__tests__/fixtures.js +0 -67
  204. package/dist/auth/__tests__/fixtures.js.map +0 -1
  205. package/dist/auth/__tests__/mocks.d.ts +0 -33
  206. package/dist/auth/__tests__/mocks.d.ts.map +0 -1
  207. package/dist/auth/__tests__/mocks.js +0 -63
  208. package/dist/auth/__tests__/mocks.js.map +0 -1
  209. package/dist/auth/callback-server.spec.d.ts +0 -2
  210. package/dist/auth/callback-server.spec.d.ts.map +0 -1
  211. package/dist/auth/callback-server.spec.js +0 -85
  212. package/dist/auth/callback-server.spec.js.map +0 -1
  213. package/dist/auth/crypto-utils.spec.d.ts +0 -2
  214. package/dist/auth/crypto-utils.spec.d.ts.map +0 -1
  215. package/dist/auth/crypto-utils.spec.js +0 -36
  216. package/dist/auth/crypto-utils.spec.js.map +0 -1
  217. package/dist/auth/jwt-validator.spec.d.ts +0 -10
  218. package/dist/auth/jwt-validator.spec.d.ts.map +0 -1
  219. package/dist/auth/jwt-validator.spec.js +0 -236
  220. package/dist/auth/jwt-validator.spec.js.map +0 -1
  221. package/dist/auth/oauth-flow.spec.d.ts +0 -2
  222. package/dist/auth/oauth-flow.spec.d.ts.map +0 -1
  223. package/dist/auth/oauth-flow.spec.js +0 -134
  224. package/dist/auth/oauth-flow.spec.js.map +0 -1
  225. package/dist/auth/pkce.spec.d.ts +0 -2
  226. package/dist/auth/pkce.spec.d.ts.map +0 -1
  227. package/dist/auth/pkce.spec.js +0 -32
  228. package/dist/auth/pkce.spec.js.map +0 -1
  229. package/dist/auth/project-token.spec.d.ts +0 -2
  230. package/dist/auth/project-token.spec.d.ts.map +0 -1
  231. package/dist/auth/project-token.spec.js +0 -332
  232. package/dist/auth/project-token.spec.js.map +0 -1
  233. package/dist/auth/refresh.spec.d.ts +0 -2
  234. package/dist/auth/refresh.spec.d.ts.map +0 -1
  235. package/dist/auth/refresh.spec.js +0 -105
  236. package/dist/auth/refresh.spec.js.map +0 -1
  237. package/dist/auth/token-store.spec.d.ts +0 -2
  238. package/dist/auth/token-store.spec.d.ts.map +0 -1
  239. package/dist/auth/token-store.spec.js +0 -276
  240. package/dist/auth/token-store.spec.js.map +0 -1
  241. package/dist/commands/__tests__/test-utils.d.ts +0 -28
  242. package/dist/commands/__tests__/test-utils.d.ts.map +0 -1
  243. package/dist/commands/__tests__/test-utils.js +0 -34
  244. package/dist/commands/__tests__/test-utils.js.map +0 -1
  245. package/dist/commands/deploy.spec.d.ts +0 -2
  246. package/dist/commands/deploy.spec.d.ts.map +0 -1
  247. package/dist/commands/deploy.spec.js +0 -18
  248. package/dist/commands/deploy.spec.js.map +0 -1
  249. package/dist/commands/init.spec.d.ts +0 -2
  250. package/dist/commands/init.spec.d.ts.map +0 -1
  251. package/dist/commands/init.spec.js +0 -283
  252. package/dist/commands/init.spec.js.map +0 -1
  253. package/dist/plugin/build-config.spec.d.ts +0 -2
  254. package/dist/plugin/build-config.spec.d.ts.map +0 -1
  255. package/dist/plugin/build-config.spec.js +0 -72
  256. package/dist/plugin/build-config.spec.js.map +0 -1
  257. package/dist/utils/asset-collection.spec.d.ts +0 -2
  258. package/dist/utils/asset-collection.spec.d.ts.map +0 -1
  259. package/dist/utils/asset-collection.spec.js +0 -155
  260. package/dist/utils/asset-collection.spec.js.map +0 -1
  261. package/dist/utils/build-detection.spec.d.ts +0 -2
  262. package/dist/utils/build-detection.spec.d.ts.map +0 -1
  263. package/dist/utils/build-detection.spec.js +0 -110
  264. package/dist/utils/build-detection.spec.js.map +0 -1
  265. package/dist/utils/config.spec.d.ts +0 -2
  266. package/dist/utils/config.spec.d.ts.map +0 -1
  267. package/dist/utils/config.spec.js +0 -167
  268. package/dist/utils/config.spec.js.map +0 -1
  269. package/dist/utils/download-template.spec.d.ts +0 -2
  270. package/dist/utils/download-template.spec.d.ts.map +0 -1
  271. package/dist/utils/download-template.spec.js +0 -76
  272. package/dist/utils/download-template.spec.js.map +0 -1
  273. package/dist/utils/env-management.spec.d.ts +0 -2
  274. package/dist/utils/env-management.spec.d.ts.map +0 -1
  275. package/dist/utils/env-management.spec.js +0 -123
  276. package/dist/utils/env-management.spec.js.map +0 -1
  277. package/dist/utils/git.spec.d.ts +0 -2
  278. package/dist/utils/git.spec.d.ts.map +0 -1
  279. package/dist/utils/git.spec.js +0 -99
  280. package/dist/utils/git.spec.js.map +0 -1
  281. package/dist/utils/lambda-config.spec.d.ts +0 -2
  282. package/dist/utils/lambda-config.spec.d.ts.map +0 -1
  283. package/dist/utils/lambda-config.spec.js +0 -141
  284. package/dist/utils/lambda-config.spec.js.map +0 -1
  285. package/dist/utils/payload-config-ast.spec.d.ts +0 -2
  286. package/dist/utils/payload-config-ast.spec.d.ts.map +0 -1
  287. package/dist/utils/payload-config-ast.spec.js +0 -303
  288. package/dist/utils/payload-config-ast.spec.js.map +0 -1
  289. package/dist/utils/payload-config-modifier.int.spec.d.ts +0 -2
  290. package/dist/utils/payload-config-modifier.int.spec.d.ts.map +0 -1
  291. package/dist/utils/payload-config-modifier.int.spec.js +0 -116
  292. package/dist/utils/payload-config-modifier.int.spec.js.map +0 -1
  293. package/dist/utils/payload-config-modifier.spec.d.ts +0 -2
  294. package/dist/utils/payload-config-modifier.spec.d.ts.map +0 -1
  295. package/dist/utils/payload-config-modifier.spec.js +0 -162
  296. package/dist/utils/payload-config-modifier.spec.js.map +0 -1
  297. package/dist/utils/payload-package-check.spec.d.ts +0 -2
  298. package/dist/utils/payload-package-check.spec.d.ts.map +0 -1
  299. package/dist/utils/payload-package-check.spec.js +0 -148
  300. package/dist/utils/payload-package-check.spec.js.map +0 -1
  301. package/dist/utils/project.spec.d.ts +0 -2
  302. package/dist/utils/project.spec.d.ts.map +0 -1
  303. package/dist/utils/project.spec.js +0 -222
  304. package/dist/utils/project.spec.js.map +0 -1
  305. package/dist/utils/s3-upload.spec.d.ts +0 -2
  306. package/dist/utils/s3-upload.spec.d.ts.map +0 -1
  307. package/dist/utils/s3-upload.spec.js +0 -140
  308. package/dist/utils/s3-upload.spec.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs/promises';
2
2
  import path from 'path';
3
- import { isDebug } from './is-debug.js';
3
+ import * as log from './log.js';
4
4
  /**
5
5
  * Retry configuration
6
6
  */ const MAX_RETRIES = 3;
@@ -28,9 +28,7 @@ const INITIAL_RETRY_DELAY = 1000 // 1 second
28
28
  */ export async function uploadFile(filePath, signedUrl, contentType) {
29
29
  // Skip actual upload for mock URLs
30
30
  if (isMockUrl(signedUrl)) {
31
- if (isDebug()) {
32
- console.log(`Mock upload: ${path.basename(filePath)}`);
33
- }
31
+ log.debug(`Mock upload detected for ${path.basename(filePath)}`);
34
32
  // Verify file exists
35
33
  const stats = await fs.stat(filePath);
36
34
  // Simulate upload latency based on file size
@@ -115,10 +113,7 @@ const INITIAL_RETRY_DELAY = 1000 // 1 second
115
113
  onProgress?.(results.assetsUploaded, assetPaths.length);
116
114
  } catch (error) {
117
115
  results.assetsFailed++;
118
- if (isDebug()) {
119
- const message = error instanceof Error ? error.message : 'Unknown error';
120
- console.error(`Failed to upload ${assetPath}: ${message}`);
121
- }
116
+ log.debug(`Failed to upload ${assetPath}: ${error instanceof Error ? error.message : 'Unknown error'}`);
122
117
  }
123
118
  }));
124
119
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/s3-upload.ts"],"sourcesContent":["import fs from 'fs/promises'\nimport path from 'path'\n\nimport { isDebug } from './is-debug.js'\n\n/**\n * Results from uploading assets\n */\nexport interface UploadResults {\n /** Number of static assets that failed to upload */\n assetsFailed: number\n /** Number of static assets successfully uploaded */\n assetsUploaded: number\n /** Whether Lambda code was uploaded */\n lambdaUploaded: boolean\n /** Total bytes uploaded */\n totalBytesUploaded: number\n}\n\n/**\n * Retry configuration\n */\nconst MAX_RETRIES = 3\nconst INITIAL_RETRY_DELAY = 1000 // 1 second\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Check if a signed URL is a mock URL\n */\nfunction isMockUrl(signedUrl: string): boolean {\n return signedUrl.includes('X-Amz-Signature=mock')\n}\n\n/**\n * Upload a file to S3 using a signed URL\n *\n * Retries up to 3 times with exponential backoff\n *\n * @param filePath - Absolute path to file to upload\n * @param signedUrl - Signed S3 upload URL\n * @param contentType - MIME type (optional)\n * @throws Error if upload fails after retries\n */\nexport async function uploadFile(\n filePath: string,\n signedUrl: string,\n contentType?: string,\n): Promise<void> {\n // Skip actual upload for mock URLs\n if (isMockUrl(signedUrl)) {\n if (isDebug()) {\n console.log(`Mock upload: ${path.basename(filePath)}`)\n }\n // Verify file exists\n const stats = await fs.stat(filePath)\n\n // Simulate upload latency based on file size\n // lambda.zip: ~1-2 seconds, small files: 50-150ms\n const isLargeFile = stats.size > 1024 * 1024 // > 1MB\n const latency = isLargeFile\n ? 1000 + Math.random() * 1000 // 1-2 seconds for large files\n : 50 + Math.random() * 100 // 50-150ms for small files\n await sleep(latency)\n return\n }\n\n const fileBuffer = await fs.readFile(filePath)\n\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(signedUrl, {\n body: fileBuffer,\n headers: contentType ? { 'Content-Type': contentType } : {},\n method: 'PUT',\n })\n\n if (response.ok) {\n return // Success\n }\n\n lastError = new Error(`Upload failed: ${response.status} ${response.statusText}`)\n } catch (error) {\n lastError = error instanceof Error ? error : new Error('Unknown error')\n }\n\n // Wait before retry (exponential backoff)\n if (attempt < MAX_RETRIES - 1) {\n await sleep(INITIAL_RETRY_DELAY * Math.pow(2, attempt))\n }\n }\n\n throw lastError || new Error('Upload failed after retries')\n}\n\n/**\n * Upload Lambda code zip to S3\n *\n * @param zipPath - Path to lambda.zip\n * @param signedUrl - Signed S3 upload URL\n */\nexport async function uploadLambdaZip(zipPath: string, signedUrl: string): Promise<void> {\n await uploadFile(zipPath, signedUrl, 'application/zip')\n}\n\n/**\n * Upload static assets to S3 in parallel\n *\n * Uploads up to 5 files concurrently\n *\n * @param projectPath - Path to project root\n * @param assetUrls - Map of asset paths to signed URLs\n * @param onProgress - Optional callback for progress updates (uploaded, total)\n * @returns Upload results with counts\n */\nexport async function uploadStaticAssets(\n projectPath: string,\n assetUrls: Record<string, string>,\n onProgress?: (uploaded: number, total: number) => void,\n): Promise<UploadResults> {\n const results: UploadResults = {\n assetsFailed: 0,\n assetsUploaded: 0,\n lambdaUploaded: false,\n totalBytesUploaded: 0,\n }\n\n const assetPaths = Object.keys(assetUrls)\n\n if (assetPaths.length === 0) {\n return results\n }\n\n // Upload assets with limited concurrency\n const CONCURRENCY = 5\n for (let i = 0; i < assetPaths.length; i += CONCURRENCY) {\n const batch = assetPaths.slice(i, i + CONCURRENCY)\n\n await Promise.all(\n batch.map(async (assetPath) => {\n try {\n // Convert _next back to .next for file system\n const fsPath = assetPath.replace(/^_next\\//, '.next/')\n const fullPath = path.join(projectPath, fsPath)\n const signedUrl = assetUrls[assetPath]\n\n await uploadFile(fullPath, signedUrl)\n\n results.assetsUploaded++\n\n // Track bytes uploaded\n const stats = await fs.stat(fullPath)\n results.totalBytesUploaded += stats.size\n\n // Report progress\n onProgress?.(results.assetsUploaded, assetPaths.length)\n } catch (error) {\n results.assetsFailed++\n if (isDebug()) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n console.error(`Failed to upload ${assetPath}: ${message}`)\n }\n }\n }),\n )\n }\n\n return results\n}\n"],"names":["fs","path","isDebug","MAX_RETRIES","INITIAL_RETRY_DELAY","sleep","ms","Promise","resolve","setTimeout","isMockUrl","signedUrl","includes","uploadFile","filePath","contentType","console","log","basename","stats","stat","isLargeFile","size","latency","Math","random","fileBuffer","readFile","lastError","attempt","response","fetch","body","headers","method","ok","Error","status","statusText","error","pow","uploadLambdaZip","zipPath","uploadStaticAssets","projectPath","assetUrls","onProgress","results","assetsFailed","assetsUploaded","lambdaUploaded","totalBytesUploaded","assetPaths","Object","keys","length","CONCURRENCY","i","batch","slice","all","map","assetPath","fsPath","replace","fullPath","join","message"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/s3-upload.ts"],"sourcesContent":["import fs from 'fs/promises'\nimport path from 'path'\n\nimport * as log from './log.js'\n\n/**\n * Results from uploading assets\n */\nexport interface UploadResults {\n /** Number of static assets that failed to upload */\n assetsFailed: number\n /** Number of static assets successfully uploaded */\n assetsUploaded: number\n /** Whether Lambda code was uploaded */\n lambdaUploaded: boolean\n /** Total bytes uploaded */\n totalBytesUploaded: number\n}\n\n/**\n * Retry configuration\n */\nconst MAX_RETRIES = 3\nconst INITIAL_RETRY_DELAY = 1000 // 1 second\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Check if a signed URL is a mock URL\n */\nfunction isMockUrl(signedUrl: string): boolean {\n return signedUrl.includes('X-Amz-Signature=mock')\n}\n\n/**\n * Upload a file to S3 using a signed URL\n *\n * Retries up to 3 times with exponential backoff\n *\n * @param filePath - Absolute path to file to upload\n * @param signedUrl - Signed S3 upload URL\n * @param contentType - MIME type (optional)\n * @throws Error if upload fails after retries\n */\nexport async function uploadFile(\n filePath: string,\n signedUrl: string,\n contentType?: string,\n): Promise<void> {\n // Skip actual upload for mock URLs\n if (isMockUrl(signedUrl)) {\n log.debug(`Mock upload detected for ${path.basename(filePath)}`)\n // Verify file exists\n const stats = await fs.stat(filePath)\n\n // Simulate upload latency based on file size\n // lambda.zip: ~1-2 seconds, small files: 50-150ms\n const isLargeFile = stats.size > 1024 * 1024 // > 1MB\n const latency = isLargeFile\n ? 1000 + Math.random() * 1000 // 1-2 seconds for large files\n : 50 + Math.random() * 100 // 50-150ms for small files\n await sleep(latency)\n return\n }\n\n const fileBuffer = await fs.readFile(filePath)\n\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(signedUrl, {\n body: fileBuffer,\n headers: contentType ? { 'Content-Type': contentType } : {},\n method: 'PUT',\n })\n\n if (response.ok) {\n return // Success\n }\n\n lastError = new Error(`Upload failed: ${response.status} ${response.statusText}`)\n } catch (error) {\n lastError = error instanceof Error ? error : new Error('Unknown error')\n }\n\n // Wait before retry (exponential backoff)\n if (attempt < MAX_RETRIES - 1) {\n await sleep(INITIAL_RETRY_DELAY * Math.pow(2, attempt))\n }\n }\n\n throw lastError || new Error('Upload failed after retries')\n}\n\n/**\n * Upload Lambda code zip to S3\n *\n * @param zipPath - Path to lambda.zip\n * @param signedUrl - Signed S3 upload URL\n */\nexport async function uploadLambdaZip(zipPath: string, signedUrl: string): Promise<void> {\n await uploadFile(zipPath, signedUrl, 'application/zip')\n}\n\n/**\n * Upload static assets to S3 in parallel\n *\n * Uploads up to 5 files concurrently\n *\n * @param projectPath - Path to project root\n * @param assetUrls - Map of asset paths to signed URLs\n * @param onProgress - Optional callback for progress updates (uploaded, total)\n * @returns Upload results with counts\n */\nexport async function uploadStaticAssets(\n projectPath: string,\n assetUrls: Record<string, string>,\n onProgress?: (uploaded: number, total: number) => void,\n): Promise<UploadResults> {\n const results: UploadResults = {\n assetsFailed: 0,\n assetsUploaded: 0,\n lambdaUploaded: false,\n totalBytesUploaded: 0,\n }\n\n const assetPaths = Object.keys(assetUrls)\n\n if (assetPaths.length === 0) {\n return results\n }\n\n // Upload assets with limited concurrency\n const CONCURRENCY = 5\n for (let i = 0; i < assetPaths.length; i += CONCURRENCY) {\n const batch = assetPaths.slice(i, i + CONCURRENCY)\n\n await Promise.all(\n batch.map(async (assetPath) => {\n try {\n // Convert _next back to .next for file system\n const fsPath = assetPath.replace(/^_next\\//, '.next/')\n const fullPath = path.join(projectPath, fsPath)\n const signedUrl = assetUrls[assetPath]\n\n await uploadFile(fullPath, signedUrl)\n\n results.assetsUploaded++\n\n // Track bytes uploaded\n const stats = await fs.stat(fullPath)\n results.totalBytesUploaded += stats.size\n\n // Report progress\n onProgress?.(results.assetsUploaded, assetPaths.length)\n } catch (error) {\n results.assetsFailed++\n log.debug(\n `Failed to upload ${assetPath}: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n }),\n )\n }\n\n return results\n}\n"],"names":["fs","path","log","MAX_RETRIES","INITIAL_RETRY_DELAY","sleep","ms","Promise","resolve","setTimeout","isMockUrl","signedUrl","includes","uploadFile","filePath","contentType","debug","basename","stats","stat","isLargeFile","size","latency","Math","random","fileBuffer","readFile","lastError","attempt","response","fetch","body","headers","method","ok","Error","status","statusText","error","pow","uploadLambdaZip","zipPath","uploadStaticAssets","projectPath","assetUrls","onProgress","results","assetsFailed","assetsUploaded","lambdaUploaded","totalBytesUploaded","assetPaths","Object","keys","length","CONCURRENCY","i","batch","slice","all","map","assetPath","fsPath","replace","fullPath","join","message"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"token-display.d.ts","sourceRoot":"","sources":["../../src/utils/token-display.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAExD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAsBzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAgC9D"}
1
+ {"version":3,"file":"token-display.d.ts","sourceRoot":"","sources":["../../src/utils/token-display.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAsBzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAkC9D"}
@@ -1,5 +1,6 @@
1
1
  import * as p from '@clack/prompts';
2
2
  import pc from 'picocolors';
3
+ import { isDebug } from './is-debug.js';
3
4
  /**
4
5
  * Mask token for display (show first 4 and last 4 characters)
5
6
  */ export function maskToken(token) {
@@ -37,7 +38,7 @@ import pc from 'picocolors';
37
38
  const tenantIds = tokenStore.getAllProjectTokenTenantIds();
38
39
  if (tenantIds.length === 0) {
39
40
  p.log.step(pc.dim('No project tokens stored.'));
40
- p.note(`Run ${pc.cyan('payloadcms-figma init')} to create a CMS instance`, 'Tip');
41
+ p.note(`Run ${pc.cyan('@payloadcms/figma init')} to create a CMS instance`, 'Tip');
41
42
  return;
42
43
  }
43
44
  const projectTokenLines = [];
@@ -53,7 +54,7 @@ import pc from 'picocolors';
53
54
  }
54
55
  projectTokenLines.push(`Tenant ID: ${tenantId}`);
55
56
  projectTokenLines.push(`Status: ${status}`);
56
- projectTokenLines.push(`Token: ${maskToken(projectToken.token)}`);
57
+ projectTokenLines.push(`Token: ${isDebug() ? projectToken.token : maskToken(projectToken.token)}`);
57
58
  projectTokenLines.push(`Expires: ${formatTimestamp(projectToken.expiresAt)}`);
58
59
  });
59
60
  p.note(projectTokenLines.join('\n'), `Project Tokens (${tenantIds.length})`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/token-display.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport type { TokenStore } from '../auth/token-store.js'\n\n/**\n * Mask token for display (show first 4 and last 4 characters)\n */\nexport function maskToken(token: string): string {\n if (token.length <= 8) {\n return '***'\n }\n return `${token.slice(0, 4)}${'*'.repeat(Math.min(token.length - 8, 32))}${token.slice(-4)}`\n}\n\n/**\n * Format timestamp as human-readable string with color coding\n */\nexport function formatTimestamp(timestamp: number): string {\n const now = Date.now()\n const diff = timestamp - now\n\n if (diff < 0) {\n return pc.red('Expired')\n }\n\n const minutes = Math.floor(diff / 60000)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n\n if (days > 0) {\n return pc.green(`${days}d ${hours % 24}h`)\n }\n if (hours > 0) {\n return pc.green(`${hours}h ${minutes % 60}m`)\n }\n if (minutes > 5) {\n return pc.yellow(`${minutes}m`)\n }\n return pc.red(`${minutes}m`)\n}\n\n/**\n * Show all stored project tokens\n */\nexport function showProjectTokens(tokenStore: TokenStore): void {\n // Get all tenant IDs that have project tokens\n const tenantIds = tokenStore.getAllProjectTokenTenantIds()\n\n if (tenantIds.length === 0) {\n p.log.step(pc.dim('No project tokens stored.'))\n p.note(`Run ${pc.cyan('payloadcms-figma init')} to create a CMS instance`, 'Tip')\n return\n }\n const projectTokenLines: string[] = []\n\n tenantIds.forEach((tenantId, index) => {\n const projectToken = tokenStore.getProjectToken(tenantId)\n\n if (!projectToken) {\n return\n }\n\n const isValid = tokenStore.hasValidProjectToken(tenantId)\n const status = isValid ? pc.green('✓ Valid') : pc.red('✗ Expired')\n\n if (index > 0) {\n projectTokenLines.push('') // Blank line between tokens\n }\n\n projectTokenLines.push(`Tenant ID: ${tenantId}`)\n projectTokenLines.push(`Status: ${status}`)\n projectTokenLines.push(`Token: ${maskToken(projectToken.token)}`)\n projectTokenLines.push(`Expires: ${formatTimestamp(projectToken.expiresAt)}`)\n })\n\n p.note(projectTokenLines.join('\\n'), `Project Tokens (${tenantIds.length})`)\n}\n"],"names":["p","pc","maskToken","token","length","slice","repeat","Math","min","formatTimestamp","timestamp","now","Date","diff","red","minutes","floor","hours","days","green","yellow","showProjectTokens","tokenStore","tenantIds","getAllProjectTokenTenantIds","log","step","dim","note","cyan","projectTokenLines","forEach","tenantId","index","projectToken","getProjectToken","isValid","hasValidProjectToken","status","push","expiresAt","join"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAI3B;;CAEC,GACD,OAAO,SAASC,UAAUC,KAAa;IACrC,IAAIA,MAAMC,MAAM,IAAI,GAAG;QACrB,OAAO;IACT;IACA,OAAO,GAAGD,MAAME,KAAK,CAAC,GAAG,KAAK,IAAIC,MAAM,CAACC,KAAKC,GAAG,CAACL,MAAMC,MAAM,GAAG,GAAG,OAAOD,MAAME,KAAK,CAAC,CAAC,IAAI;AAC9F;AAEA;;CAEC,GACD,OAAO,SAASI,gBAAgBC,SAAiB;IAC/C,MAAMC,MAAMC,KAAKD,GAAG;IACpB,MAAME,OAAOH,YAAYC;IAEzB,IAAIE,OAAO,GAAG;QACZ,OAAOZ,GAAGa,GAAG,CAAC;IAChB;IAEA,MAAMC,UAAUR,KAAKS,KAAK,CAACH,OAAO;IAClC,MAAMI,QAAQV,KAAKS,KAAK,CAACD,UAAU;IACnC,MAAMG,OAAOX,KAAKS,KAAK,CAACC,QAAQ;IAEhC,IAAIC,OAAO,GAAG;QACZ,OAAOjB,GAAGkB,KAAK,CAAC,GAAGD,KAAK,EAAE,EAAED,QAAQ,GAAG,CAAC,CAAC;IAC3C;IACA,IAAIA,QAAQ,GAAG;QACb,OAAOhB,GAAGkB,KAAK,CAAC,GAAGF,MAAM,EAAE,EAAEF,UAAU,GAAG,CAAC,CAAC;IAC9C;IACA,IAAIA,UAAU,GAAG;QACf,OAAOd,GAAGmB,MAAM,CAAC,GAAGL,QAAQ,CAAC,CAAC;IAChC;IACA,OAAOd,GAAGa,GAAG,CAAC,GAAGC,QAAQ,CAAC,CAAC;AAC7B;AAEA;;CAEC,GACD,OAAO,SAASM,kBAAkBC,UAAsB;IACtD,8CAA8C;IAC9C,MAAMC,YAAYD,WAAWE,2BAA2B;IAExD,IAAID,UAAUnB,MAAM,KAAK,GAAG;QAC1BJ,EAAEyB,GAAG,CAACC,IAAI,CAACzB,GAAG0B,GAAG,CAAC;QAClB3B,EAAE4B,IAAI,CAAC,CAAC,IAAI,EAAE3B,GAAG4B,IAAI,CAAC,yBAAyB,yBAAyB,CAAC,EAAE;QAC3E;IACF;IACA,MAAMC,oBAA8B,EAAE;IAEtCP,UAAUQ,OAAO,CAAC,CAACC,UAAUC;QAC3B,MAAMC,eAAeZ,WAAWa,eAAe,CAACH;QAEhD,IAAI,CAACE,cAAc;YACjB;QACF;QAEA,MAAME,UAAUd,WAAWe,oBAAoB,CAACL;QAChD,MAAMM,SAASF,UAAUnC,GAAGkB,KAAK,CAAC,aAAalB,GAAGa,GAAG,CAAC;QAEtD,IAAImB,QAAQ,GAAG;YACbH,kBAAkBS,IAAI,CAAC,KAAI,4BAA4B;QACzD;QAEAT,kBAAkBS,IAAI,CAAC,CAAC,gBAAgB,EAAEP,UAAU;QACpDF,kBAAkBS,IAAI,CAAC,CAAC,gBAAgB,EAAED,QAAQ;QAClDR,kBAAkBS,IAAI,CAAC,CAAC,gBAAgB,EAAErC,UAAUgC,aAAa/B,KAAK,GAAG;QACzE2B,kBAAkBS,IAAI,CAAC,CAAC,gBAAgB,EAAE9B,gBAAgByB,aAAaM,SAAS,GAAG;IACrF;IAEAxC,EAAE4B,IAAI,CAACE,kBAAkBW,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAElB,UAAUnB,MAAM,CAAC,CAAC,CAAC;AAC7E"}
1
+ {"version":3,"sources":["../../src/utils/token-display.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport type { TokenStore } from '../auth/token-store.js'\n\nimport { isDebug } from './is-debug.js'\n\n/**\n * Mask token for display (show first 4 and last 4 characters)\n */\nexport function maskToken(token: string): string {\n if (token.length <= 8) {\n return '***'\n }\n return `${token.slice(0, 4)}${'*'.repeat(Math.min(token.length - 8, 32))}${token.slice(-4)}`\n}\n\n/**\n * Format timestamp as human-readable string with color coding\n */\nexport function formatTimestamp(timestamp: number): string {\n const now = Date.now()\n const diff = timestamp - now\n\n if (diff < 0) {\n return pc.red('Expired')\n }\n\n const minutes = Math.floor(diff / 60000)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n\n if (days > 0) {\n return pc.green(`${days}d ${hours % 24}h`)\n }\n if (hours > 0) {\n return pc.green(`${hours}h ${minutes % 60}m`)\n }\n if (minutes > 5) {\n return pc.yellow(`${minutes}m`)\n }\n return pc.red(`${minutes}m`)\n}\n\n/**\n * Show all stored project tokens\n */\nexport function showProjectTokens(tokenStore: TokenStore): void {\n // Get all tenant IDs that have project tokens\n const tenantIds = tokenStore.getAllProjectTokenTenantIds()\n\n if (tenantIds.length === 0) {\n p.log.step(pc.dim('No project tokens stored.'))\n p.note(`Run ${pc.cyan('@payloadcms/figma init')} to create a CMS instance`, 'Tip')\n return\n }\n const projectTokenLines: string[] = []\n\n tenantIds.forEach((tenantId, index) => {\n const projectToken = tokenStore.getProjectToken(tenantId)\n\n if (!projectToken) {\n return\n }\n\n const isValid = tokenStore.hasValidProjectToken(tenantId)\n const status = isValid ? pc.green('✓ Valid') : pc.red('✗ Expired')\n\n if (index > 0) {\n projectTokenLines.push('') // Blank line between tokens\n }\n\n projectTokenLines.push(`Tenant ID: ${tenantId}`)\n projectTokenLines.push(`Status: ${status}`)\n projectTokenLines.push(\n `Token: ${isDebug() ? projectToken.token : maskToken(projectToken.token)}`,\n )\n projectTokenLines.push(`Expires: ${formatTimestamp(projectToken.expiresAt)}`)\n })\n\n p.note(projectTokenLines.join('\\n'), `Project Tokens (${tenantIds.length})`)\n}\n"],"names":["p","pc","isDebug","maskToken","token","length","slice","repeat","Math","min","formatTimestamp","timestamp","now","Date","diff","red","minutes","floor","hours","days","green","yellow","showProjectTokens","tokenStore","tenantIds","getAllProjectTokenTenantIds","log","step","dim","note","cyan","projectTokenLines","forEach","tenantId","index","projectToken","getProjectToken","isValid","hasValidProjectToken","status","push","expiresAt","join"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAI3B,SAASC,OAAO,QAAQ,gBAAe;AAEvC;;CAEC,GACD,OAAO,SAASC,UAAUC,KAAa;IACrC,IAAIA,MAAMC,MAAM,IAAI,GAAG;QACrB,OAAO;IACT;IACA,OAAO,GAAGD,MAAME,KAAK,CAAC,GAAG,KAAK,IAAIC,MAAM,CAACC,KAAKC,GAAG,CAACL,MAAMC,MAAM,GAAG,GAAG,OAAOD,MAAME,KAAK,CAAC,CAAC,IAAI;AAC9F;AAEA;;CAEC,GACD,OAAO,SAASI,gBAAgBC,SAAiB;IAC/C,MAAMC,MAAMC,KAAKD,GAAG;IACpB,MAAME,OAAOH,YAAYC;IAEzB,IAAIE,OAAO,GAAG;QACZ,OAAOb,GAAGc,GAAG,CAAC;IAChB;IAEA,MAAMC,UAAUR,KAAKS,KAAK,CAACH,OAAO;IAClC,MAAMI,QAAQV,KAAKS,KAAK,CAACD,UAAU;IACnC,MAAMG,OAAOX,KAAKS,KAAK,CAACC,QAAQ;IAEhC,IAAIC,OAAO,GAAG;QACZ,OAAOlB,GAAGmB,KAAK,CAAC,GAAGD,KAAK,EAAE,EAAED,QAAQ,GAAG,CAAC,CAAC;IAC3C;IACA,IAAIA,QAAQ,GAAG;QACb,OAAOjB,GAAGmB,KAAK,CAAC,GAAGF,MAAM,EAAE,EAAEF,UAAU,GAAG,CAAC,CAAC;IAC9C;IACA,IAAIA,UAAU,GAAG;QACf,OAAOf,GAAGoB,MAAM,CAAC,GAAGL,QAAQ,CAAC,CAAC;IAChC;IACA,OAAOf,GAAGc,GAAG,CAAC,GAAGC,QAAQ,CAAC,CAAC;AAC7B;AAEA;;CAEC,GACD,OAAO,SAASM,kBAAkBC,UAAsB;IACtD,8CAA8C;IAC9C,MAAMC,YAAYD,WAAWE,2BAA2B;IAExD,IAAID,UAAUnB,MAAM,KAAK,GAAG;QAC1BL,EAAE0B,GAAG,CAACC,IAAI,CAAC1B,GAAG2B,GAAG,CAAC;QAClB5B,EAAE6B,IAAI,CAAC,CAAC,IAAI,EAAE5B,GAAG6B,IAAI,CAAC,0BAA0B,yBAAyB,CAAC,EAAE;QAC5E;IACF;IACA,MAAMC,oBAA8B,EAAE;IAEtCP,UAAUQ,OAAO,CAAC,CAACC,UAAUC;QAC3B,MAAMC,eAAeZ,WAAWa,eAAe,CAACH;QAEhD,IAAI,CAACE,cAAc;YACjB;QACF;QAEA,MAAME,UAAUd,WAAWe,oBAAoB,CAACL;QAChD,MAAMM,SAASF,UAAUpC,GAAGmB,KAAK,CAAC,aAAanB,GAAGc,GAAG,CAAC;QAEtD,IAAImB,QAAQ,GAAG;YACbH,kBAAkBS,IAAI,CAAC,KAAI,4BAA4B;QACzD;QAEAT,kBAAkBS,IAAI,CAAC,CAAC,gBAAgB,EAAEP,UAAU;QACpDF,kBAAkBS,IAAI,CAAC,CAAC,gBAAgB,EAAED,QAAQ;QAClDR,kBAAkBS,IAAI,CACpB,CAAC,gBAAgB,EAAEtC,YAAYiC,aAAa/B,KAAK,GAAGD,UAAUgC,aAAa/B,KAAK,GAAG;QAErF2B,kBAAkBS,IAAI,CAAC,CAAC,gBAAgB,EAAE9B,gBAAgByB,aAAaM,SAAS,GAAG;IACrF;IAEAzC,EAAE6B,IAAI,CAACE,kBAAkBW,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAElB,UAAUnB,MAAM,CAAC,CAAC,CAAC;AAC7E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/figma",
3
- "version": "0.0.1-alpha.1",
3
+ "version": "0.0.1-alpha.10",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "type": "module",
6
6
  "exports": {
@@ -8,6 +8,11 @@
8
8
  "import": "./dist/index.js",
9
9
  "types": "./dist/index.d.ts",
10
10
  "default": "./dist/index.js"
11
+ },
12
+ "./client": {
13
+ "import": "./dist/exports/client.js",
14
+ "types": "./dist/exports/client.d.ts",
15
+ "default": "./dist/exports/client.js"
11
16
  }
12
17
  },
13
18
  "main": "./dist/index.js",
@@ -29,6 +34,7 @@
29
34
  "esprima-next": "^6.0.2",
30
35
  "figures": "^6.1.0",
31
36
  "jose": "6.0.12",
37
+ "jsonwebtoken": "9.0.2",
32
38
  "open": "^10.1.0",
33
39
  "picocolors": "1.1.1",
34
40
  "tar": "^7.4.3",
@@ -49,7 +55,7 @@
49
55
  "registry": "https://registry.npmjs.org/"
50
56
  },
51
57
  "scripts": {
52
- "build": "pnpm build:swc && pnpm build:types && pnpm copyfiles",
58
+ "build": "pnpm build:swc && pnpm build:types",
53
59
  "build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
54
60
  "build:types": "tsc",
55
61
  "clean": "rimraf -g \"{dist,*.tsbuildinfo,package}\"",
@@ -60,7 +66,7 @@
60
66
  "debug:refresh-token": "tsx scripts/refresh-token.ts",
61
67
  "debug:tokens": "tsx scripts/debug-tokens.ts",
62
68
  "debug:write-token": "tsx scripts/write-token.ts",
63
- "lint": "eslint src",
69
+ "lint": "eslint .",
64
70
  "lint:fix": "eslint . --fix",
65
71
  "start": "pnpm build && node ./bin/cli.js",
66
72
  "test": "TEST_UNIT=true vitest run",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=control-plane.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"control-plane.spec.d.ts","sourceRoot":"","sources":["../../src/api/control-plane.spec.ts"],"names":[],"mappings":""}
@@ -1,296 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { createDeployment, createTenant, getTenantDetails, listTenants, performDeployment } from './control-plane.js';
3
- describe('control-plane API (mocked)', ()=>{
4
- beforeEach(()=>{
5
- vi.clearAllMocks();
6
- });
7
- afterEach(()=>{
8
- vi.restoreAllMocks();
9
- });
10
- describe('listTenants', ()=>{
11
- it('should return array of tenant instances', async ()=>{
12
- const tenants = await listTenants('mock-access-token');
13
- expect(Array.isArray(tenants)).toBe(true);
14
- expect(tenants.length).toBeGreaterThan(0);
15
- });
16
- it('should return tenants with required fields', async ()=>{
17
- const tenants = await listTenants('mock-access-token');
18
- tenants.forEach((tenant)=>{
19
- expect(tenant).toHaveProperty('id');
20
- expect(tenant).toHaveProperty('domain');
21
- expect(tenant).toHaveProperty('status');
22
- expect(tenant).toHaveProperty('parentType');
23
- expect(tenant).toHaveProperty('parentId');
24
- expect(tenant).toHaveProperty('createdAt');
25
- });
26
- });
27
- it('should return tenants with valid status', async ()=>{
28
- const tenants = await listTenants('mock-access-token');
29
- tenants.forEach((tenant)=>{
30
- expect([
31
- 'active',
32
- 'provisioning',
33
- 'inactive'
34
- ]).toContain(tenant.status);
35
- });
36
- });
37
- it('should return tenants with valid parentType', async ()=>{
38
- const tenants = await listTenants('mock-access-token');
39
- tenants.forEach((tenant)=>{
40
- expect([
41
- 'team',
42
- 'org',
43
- 'workspace'
44
- ]).toContain(tenant.parentType);
45
- });
46
- });
47
- it('should handle different access tokens', async ()=>{
48
- const tenants1 = await listTenants('token-1');
49
- const tenants2 = await listTenants('token-2');
50
- // Mock should return same structure regardless of token
51
- expect(tenants1.length).toBe(tenants2.length);
52
- });
53
- });
54
- describe('createTenant', ()=>{
55
- it('should create tenant with name', async ()=>{
56
- const tenant = await createTenant('mock-access-token', {
57
- name: 'test-cms'
58
- });
59
- expect(tenant).toHaveProperty('id');
60
- expect(tenant).toHaveProperty('domain');
61
- expect(tenant.domain).toContain('test-cms');
62
- });
63
- it('should return tenant with provisioning status', async ()=>{
64
- const tenant = await createTenant('mock-access-token', {
65
- name: 'new-cms'
66
- });
67
- expect(tenant.status).toBe('provisioning');
68
- });
69
- it('should generate unique tenant IDs', async ()=>{
70
- const tenant1 = await createTenant('mock-access-token', {
71
- name: 'cms-1'
72
- });
73
- const tenant2 = await createTenant('mock-access-token', {
74
- name: 'cms-2'
75
- });
76
- expect(tenant1.id).not.toBe(tenant2.id);
77
- });
78
- it('should handle names with special characters', async ()=>{
79
- const tenant = await createTenant('mock-access-token', {
80
- name: 'My Test CMS 123!'
81
- });
82
- // Should convert to slug format
83
- expect(tenant.domain).toMatch(/^[a-z0-9-]+\.figmacms\.com$/);
84
- });
85
- it('should include optional parent fields', async ()=>{
86
- const tenant = await createTenant('mock-access-token', {
87
- name: 'test-cms',
88
- parentId: 'org_custom',
89
- parentType: 'org'
90
- });
91
- expect(tenant.parentType).toBe('org');
92
- expect(tenant.parentId).toBe('org_custom');
93
- });
94
- it('should default to team parent type', async ()=>{
95
- const tenant = await createTenant('mock-access-token', {
96
- name: 'test-cms'
97
- });
98
- expect(tenant.parentType).toBe('team');
99
- });
100
- it('should include createdAt timestamp', async ()=>{
101
- const tenant = await createTenant('mock-access-token', {
102
- name: 'test-cms'
103
- });
104
- expect(tenant.createdAt).toBeDefined();
105
- expect(new Date(tenant.createdAt).getTime()).toBeGreaterThan(0);
106
- });
107
- });
108
- describe('getTenantDetails', ()=>{
109
- it('should return tenant details for given ID', async ()=>{
110
- const tenant = await getTenantDetails('mock-access-token', 'tenant_abc123');
111
- expect(tenant).toHaveProperty('id');
112
- expect(tenant.id).toBe('tenant_abc123');
113
- });
114
- it('should return tenant with all required fields', async ()=>{
115
- const tenant = await getTenantDetails('mock-access-token', 'tenant_test');
116
- expect(tenant).toHaveProperty('id');
117
- expect(tenant).toHaveProperty('domain');
118
- expect(tenant).toHaveProperty('status');
119
- expect(tenant).toHaveProperty('parentType');
120
- expect(tenant).toHaveProperty('parentId');
121
- expect(tenant).toHaveProperty('createdAt');
122
- });
123
- it('should return active status for mock tenant', async ()=>{
124
- const tenant = await getTenantDetails('mock-access-token', 'tenant_test');
125
- expect(tenant.status).toBe('active');
126
- });
127
- it('should handle different tenant IDs', async ()=>{
128
- const tenant1 = await getTenantDetails('mock-access-token', 'tenant_1');
129
- const tenant2 = await getTenantDetails('mock-access-token', 'tenant_2');
130
- expect(tenant1.id).toBe('tenant_1');
131
- expect(tenant2.id).toBe('tenant_2');
132
- });
133
- });
134
- describe('createDeployment', ()=>{
135
- it('should return deployment ID and upload URLs', async ()=>{
136
- const result = await createDeployment('mock-token', 'tenant_123', {
137
- staticAssets: [
138
- '_next/static/abc.js',
139
- '_next/static/xyz.css'
140
- ]
141
- });
142
- expect(result).toHaveProperty('deploymentId');
143
- expect(result).toHaveProperty('codeUploadUrl');
144
- expect(result).toHaveProperty('staticAssetUploadUrls');
145
- expect(result.deploymentId).toMatch(/^deploy_/);
146
- });
147
- it('should include upload URL for each static asset', async ()=>{
148
- const result = await createDeployment('mock-token', 'tenant_456', {
149
- staticAssets: [
150
- '_next/static/abc.js',
151
- '_next/static/xyz.css'
152
- ]
153
- });
154
- expect(result.staticAssetUploadUrls).toHaveProperty('_next/static/abc.js');
155
- expect(result.staticAssetUploadUrls).toHaveProperty('_next/static/xyz.css');
156
- expect(result.staticAssetUploadUrls['_next/static/abc.js']).toContain('https://');
157
- });
158
- it('should return S3 upload URL format', async ()=>{
159
- const result = await createDeployment('mock-token', 'tenant_789', {
160
- staticAssets: [
161
- '_next/static/test.js'
162
- ]
163
- });
164
- expect(result.codeUploadUrl).toMatch(/^https:\/\/.*\.s3\..*\.amazonaws\.com\//);
165
- expect(result.staticAssetUploadUrls['_next/static/test.js']).toMatch(/^https:\/\/.*\.s3\..*\.amazonaws\.com\//);
166
- });
167
- it('should handle empty static assets array', async ()=>{
168
- const result = await createDeployment('mock-token', 'tenant_empty', {
169
- staticAssets: []
170
- });
171
- expect(result.deploymentId).toBeDefined();
172
- expect(result.codeUploadUrl).toBeDefined();
173
- expect(Object.keys(result.staticAssetUploadUrls)).toHaveLength(0);
174
- });
175
- it('should generate unique deployment IDs', async ()=>{
176
- const result1 = await createDeployment('mock-token', 'tenant_abc', {
177
- staticAssets: []
178
- });
179
- const result2 = await createDeployment('mock-token', 'tenant_abc', {
180
- staticAssets: []
181
- });
182
- expect(result1.deploymentId).not.toBe(result2.deploymentId);
183
- });
184
- });
185
- describe('performDeployment', ()=>{
186
- it('should deploy using deployment ID', async ()=>{
187
- const result = await performDeployment('mock-token', 'tenant_123', {
188
- deploymentId: 'deploy_abc123'
189
- });
190
- expect(result).toHaveProperty('deploymentId');
191
- expect(result).toHaveProperty('message');
192
- expect(result.deploymentId).toBe('deploy_abc123');
193
- });
194
- it('should return success message', async ()=>{
195
- const result = await performDeployment('mock-token', 'tenant_456', {
196
- deploymentId: 'deploy_xyz789'
197
- });
198
- expect(result.message).toBeDefined();
199
- expect(result.message).toBe('Deployment initiated successfully');
200
- expect(result.message.length).toBeGreaterThan(0);
201
- });
202
- it('should handle different tenant IDs', async ()=>{
203
- const result1 = await performDeployment('mock-token', 'tenant_aaa', {
204
- deploymentId: 'deploy_1'
205
- });
206
- const result2 = await performDeployment('mock-token', 'tenant_bbb', {
207
- deploymentId: 'deploy_2'
208
- });
209
- expect(result1.deploymentId).toBe('deploy_1');
210
- expect(result2.deploymentId).toBe('deploy_2');
211
- });
212
- });
213
- describe('error handling', ()=>{
214
- beforeEach(()=>{
215
- // Force real API mode for error testing
216
- process.env.FIGMA_MOCK_CONTROL_PLANE = 'false';
217
- });
218
- afterEach(()=>{
219
- // Restore mock mode
220
- delete process.env.FIGMA_MOCK_CONTROL_PLANE;
221
- });
222
- it('createDeployment should throw ControlPlaneError on API failure', async ()=>{
223
- // Mock fetch to return error
224
- global.fetch = vi.fn().mockResolvedValue({
225
- ok: false,
226
- status: 500,
227
- statusText: 'Internal Server Error'
228
- });
229
- await expect(createDeployment('bad-token', 'tenant_fail', {
230
- staticAssets: []
231
- })).rejects.toThrow('Failed to create deployment: 500 Internal Server Error');
232
- });
233
- it('performDeployment should throw ControlPlaneError on API failure', async ()=>{
234
- // Mock fetch to return error
235
- global.fetch = vi.fn().mockResolvedValue({
236
- ok: false,
237
- status: 404,
238
- statusText: 'Not Found'
239
- });
240
- await expect(performDeployment('bad-token', 'tenant_missing', {
241
- deploymentId: 'deploy_notfound'
242
- })).rejects.toThrow('Failed to perform deployment: 404 Not Found');
243
- });
244
- it('createDeployment should map snake_case API response to camelCase', async ()=>{
245
- // Mock fetch to return successful API response with snake_case
246
- global.fetch = vi.fn().mockResolvedValue({
247
- json: ()=>({
248
- error: false,
249
- meta: {
250
- code_upload_url: 'https://s3.amazonaws.com/code/upload',
251
- deployment_id: 'deploy_test123',
252
- static_asset_upload_urls: {
253
- '_next/static/test.js': 'https://s3.amazonaws.com/static/test.js'
254
- }
255
- },
256
- status: 200
257
- }),
258
- ok: true
259
- });
260
- const result = await createDeployment('token', 'tenant_123', {
261
- staticAssets: [
262
- '_next/static/test.js'
263
- ]
264
- });
265
- // Verify response is mapped to camelCase
266
- expect(result.deploymentId).toBe('deploy_test123');
267
- expect(result.codeUploadUrl).toBe('https://s3.amazonaws.com/code/upload');
268
- expect(result.staticAssetUploadUrls).toEqual({
269
- '_next/static/test.js': 'https://s3.amazonaws.com/static/test.js'
270
- });
271
- });
272
- it('performDeployment should map snake_case API response to camelCase', async ()=>{
273
- // Mock fetch to return successful API response with snake_case
274
- global.fetch = vi.fn().mockResolvedValue({
275
- json: ()=>({
276
- error: false,
277
- meta: {
278
- deployment_id: 'deploy_abc456',
279
- message: 'Deployment successful',
280
- status: 'deployed'
281
- },
282
- status: 200
283
- }),
284
- ok: true
285
- });
286
- const result = await performDeployment('token', 'tenant_456', {
287
- deploymentId: 'deploy_abc456'
288
- });
289
- // Verify response is mapped to camelCase
290
- expect(result.deploymentId).toBe('deploy_abc456');
291
- expect(result.message).toBe('Deployment successful');
292
- });
293
- });
294
- });
295
-
296
- //# sourceMappingURL=control-plane.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/control-plane.spec.ts"],"sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport {\n createDeployment,\n createTenant,\n getTenantDetails,\n listTenants,\n performDeployment,\n} from './control-plane.js'\n\ndescribe('control-plane API (mocked)', () => {\n beforeEach(() => {\n vi.clearAllMocks()\n })\n\n afterEach(() => {\n vi.restoreAllMocks()\n })\n\n describe('listTenants', () => {\n it('should return array of tenant instances', async () => {\n const tenants = await listTenants('mock-access-token')\n\n expect(Array.isArray(tenants)).toBe(true)\n expect(tenants.length).toBeGreaterThan(0)\n })\n\n it('should return tenants with required fields', async () => {\n const tenants = await listTenants('mock-access-token')\n\n tenants.forEach((tenant) => {\n expect(tenant).toHaveProperty('id')\n expect(tenant).toHaveProperty('domain')\n expect(tenant).toHaveProperty('status')\n expect(tenant).toHaveProperty('parentType')\n expect(tenant).toHaveProperty('parentId')\n expect(tenant).toHaveProperty('createdAt')\n })\n })\n\n it('should return tenants with valid status', async () => {\n const tenants = await listTenants('mock-access-token')\n\n tenants.forEach((tenant) => {\n expect(['active', 'provisioning', 'inactive']).toContain(tenant.status)\n })\n })\n\n it('should return tenants with valid parentType', async () => {\n const tenants = await listTenants('mock-access-token')\n\n tenants.forEach((tenant) => {\n expect(['team', 'org', 'workspace']).toContain(tenant.parentType)\n })\n })\n\n it('should handle different access tokens', async () => {\n const tenants1 = await listTenants('token-1')\n const tenants2 = await listTenants('token-2')\n\n // Mock should return same structure regardless of token\n expect(tenants1.length).toBe(tenants2.length)\n })\n })\n\n describe('createTenant', () => {\n it('should create tenant with name', async () => {\n const tenant = await createTenant('mock-access-token', {\n name: 'test-cms',\n })\n\n expect(tenant).toHaveProperty('id')\n expect(tenant).toHaveProperty('domain')\n expect(tenant.domain).toContain('test-cms')\n })\n\n it('should return tenant with provisioning status', async () => {\n const tenant = await createTenant('mock-access-token', {\n name: 'new-cms',\n })\n\n expect(tenant.status).toBe('provisioning')\n })\n\n it('should generate unique tenant IDs', async () => {\n const tenant1 = await createTenant('mock-access-token', {\n name: 'cms-1',\n })\n const tenant2 = await createTenant('mock-access-token', {\n name: 'cms-2',\n })\n\n expect(tenant1.id).not.toBe(tenant2.id)\n })\n\n it('should handle names with special characters', async () => {\n const tenant = await createTenant('mock-access-token', {\n name: 'My Test CMS 123!',\n })\n\n // Should convert to slug format\n expect(tenant.domain).toMatch(/^[a-z0-9-]+\\.figmacms\\.com$/)\n })\n\n it('should include optional parent fields', async () => {\n const tenant = await createTenant('mock-access-token', {\n name: 'test-cms',\n parentId: 'org_custom',\n parentType: 'org',\n })\n\n expect(tenant.parentType).toBe('org')\n expect(tenant.parentId).toBe('org_custom')\n })\n\n it('should default to team parent type', async () => {\n const tenant = await createTenant('mock-access-token', {\n name: 'test-cms',\n })\n\n expect(tenant.parentType).toBe('team')\n })\n\n it('should include createdAt timestamp', async () => {\n const tenant = await createTenant('mock-access-token', {\n name: 'test-cms',\n })\n\n expect(tenant.createdAt).toBeDefined()\n expect(new Date(tenant.createdAt!).getTime()).toBeGreaterThan(0)\n })\n })\n\n describe('getTenantDetails', () => {\n it('should return tenant details for given ID', async () => {\n const tenant = await getTenantDetails('mock-access-token', 'tenant_abc123')\n\n expect(tenant).toHaveProperty('id')\n expect(tenant.id).toBe('tenant_abc123')\n })\n\n it('should return tenant with all required fields', async () => {\n const tenant = await getTenantDetails('mock-access-token', 'tenant_test')\n\n expect(tenant).toHaveProperty('id')\n expect(tenant).toHaveProperty('domain')\n expect(tenant).toHaveProperty('status')\n expect(tenant).toHaveProperty('parentType')\n expect(tenant).toHaveProperty('parentId')\n expect(tenant).toHaveProperty('createdAt')\n })\n\n it('should return active status for mock tenant', async () => {\n const tenant = await getTenantDetails('mock-access-token', 'tenant_test')\n\n expect(tenant.status).toBe('active')\n })\n\n it('should handle different tenant IDs', async () => {\n const tenant1 = await getTenantDetails('mock-access-token', 'tenant_1')\n const tenant2 = await getTenantDetails('mock-access-token', 'tenant_2')\n\n expect(tenant1.id).toBe('tenant_1')\n expect(tenant2.id).toBe('tenant_2')\n })\n })\n\n describe('createDeployment', () => {\n it('should return deployment ID and upload URLs', async () => {\n const result = await createDeployment('mock-token', 'tenant_123', {\n staticAssets: ['_next/static/abc.js', '_next/static/xyz.css'],\n })\n\n expect(result).toHaveProperty('deploymentId')\n expect(result).toHaveProperty('codeUploadUrl')\n expect(result).toHaveProperty('staticAssetUploadUrls')\n expect(result.deploymentId).toMatch(/^deploy_/)\n })\n\n it('should include upload URL for each static asset', async () => {\n const result = await createDeployment('mock-token', 'tenant_456', {\n staticAssets: ['_next/static/abc.js', '_next/static/xyz.css'],\n })\n\n expect(result.staticAssetUploadUrls).toHaveProperty('_next/static/abc.js')\n expect(result.staticAssetUploadUrls).toHaveProperty('_next/static/xyz.css')\n expect(result.staticAssetUploadUrls['_next/static/abc.js']).toContain('https://')\n })\n\n it('should return S3 upload URL format', async () => {\n const result = await createDeployment('mock-token', 'tenant_789', {\n staticAssets: ['_next/static/test.js'],\n })\n\n expect(result.codeUploadUrl).toMatch(/^https:\\/\\/.*\\.s3\\..*\\.amazonaws\\.com\\//)\n expect(result.staticAssetUploadUrls['_next/static/test.js']).toMatch(\n /^https:\\/\\/.*\\.s3\\..*\\.amazonaws\\.com\\//,\n )\n })\n\n it('should handle empty static assets array', async () => {\n const result = await createDeployment('mock-token', 'tenant_empty', {\n staticAssets: [],\n })\n\n expect(result.deploymentId).toBeDefined()\n expect(result.codeUploadUrl).toBeDefined()\n expect(Object.keys(result.staticAssetUploadUrls)).toHaveLength(0)\n })\n\n it('should generate unique deployment IDs', async () => {\n const result1 = await createDeployment('mock-token', 'tenant_abc', {\n staticAssets: [],\n })\n const result2 = await createDeployment('mock-token', 'tenant_abc', {\n staticAssets: [],\n })\n\n expect(result1.deploymentId).not.toBe(result2.deploymentId)\n })\n })\n\n describe('performDeployment', () => {\n it('should deploy using deployment ID', async () => {\n const result = await performDeployment('mock-token', 'tenant_123', {\n deploymentId: 'deploy_abc123',\n })\n\n expect(result).toHaveProperty('deploymentId')\n expect(result).toHaveProperty('message')\n expect(result.deploymentId).toBe('deploy_abc123')\n })\n\n it('should return success message', async () => {\n const result = await performDeployment('mock-token', 'tenant_456', {\n deploymentId: 'deploy_xyz789',\n })\n\n expect(result.message).toBeDefined()\n expect(result.message).toBe('Deployment initiated successfully')\n expect(result.message.length).toBeGreaterThan(0)\n })\n\n it('should handle different tenant IDs', async () => {\n const result1 = await performDeployment('mock-token', 'tenant_aaa', {\n deploymentId: 'deploy_1',\n })\n const result2 = await performDeployment('mock-token', 'tenant_bbb', {\n deploymentId: 'deploy_2',\n })\n\n expect(result1.deploymentId).toBe('deploy_1')\n expect(result2.deploymentId).toBe('deploy_2')\n })\n })\n\n describe('error handling', () => {\n beforeEach(() => {\n // Force real API mode for error testing\n process.env.FIGMA_MOCK_CONTROL_PLANE = 'false'\n })\n\n afterEach(() => {\n // Restore mock mode\n delete process.env.FIGMA_MOCK_CONTROL_PLANE\n })\n\n it('createDeployment should throw ControlPlaneError on API failure', async () => {\n // Mock fetch to return error\n global.fetch = vi.fn().mockResolvedValue({\n ok: false,\n status: 500,\n statusText: 'Internal Server Error',\n })\n\n await expect(\n createDeployment('bad-token', 'tenant_fail', { staticAssets: [] }),\n ).rejects.toThrow('Failed to create deployment: 500 Internal Server Error')\n })\n\n it('performDeployment should throw ControlPlaneError on API failure', async () => {\n // Mock fetch to return error\n global.fetch = vi.fn().mockResolvedValue({\n ok: false,\n status: 404,\n statusText: 'Not Found',\n })\n\n await expect(\n performDeployment('bad-token', 'tenant_missing', {\n deploymentId: 'deploy_notfound',\n }),\n ).rejects.toThrow('Failed to perform deployment: 404 Not Found')\n })\n\n it('createDeployment should map snake_case API response to camelCase', async () => {\n // Mock fetch to return successful API response with snake_case\n global.fetch = vi.fn().mockResolvedValue({\n json: () => ({\n error: false,\n meta: {\n code_upload_url: 'https://s3.amazonaws.com/code/upload',\n deployment_id: 'deploy_test123',\n static_asset_upload_urls: {\n '_next/static/test.js': 'https://s3.amazonaws.com/static/test.js',\n },\n },\n status: 200,\n }),\n ok: true,\n })\n\n const result = await createDeployment('token', 'tenant_123', {\n staticAssets: ['_next/static/test.js'],\n })\n\n // Verify response is mapped to camelCase\n expect(result.deploymentId).toBe('deploy_test123')\n expect(result.codeUploadUrl).toBe('https://s3.amazonaws.com/code/upload')\n expect(result.staticAssetUploadUrls).toEqual({\n '_next/static/test.js': 'https://s3.amazonaws.com/static/test.js',\n })\n })\n\n it('performDeployment should map snake_case API response to camelCase', async () => {\n // Mock fetch to return successful API response with snake_case\n global.fetch = vi.fn().mockResolvedValue({\n json: () => ({\n error: false,\n meta: {\n deployment_id: 'deploy_abc456',\n message: 'Deployment successful',\n status: 'deployed',\n },\n status: 200,\n }),\n ok: true,\n })\n\n const result = await performDeployment('token', 'tenant_456', {\n deploymentId: 'deploy_abc456',\n })\n\n // Verify response is mapped to camelCase\n expect(result.deploymentId).toBe('deploy_abc456')\n expect(result.message).toBe('Deployment successful')\n })\n })\n})\n"],"names":["afterEach","beforeEach","describe","expect","it","vi","createDeployment","createTenant","getTenantDetails","listTenants","performDeployment","clearAllMocks","restoreAllMocks","tenants","Array","isArray","toBe","length","toBeGreaterThan","forEach","tenant","toHaveProperty","toContain","status","parentType","tenants1","tenants2","name","domain","tenant1","tenant2","id","not","toMatch","parentId","createdAt","toBeDefined","Date","getTime","result","staticAssets","deploymentId","staticAssetUploadUrls","codeUploadUrl","Object","keys","toHaveLength","result1","result2","message","process","env","FIGMA_MOCK_CONTROL_PLANE","global","fetch","fn","mockResolvedValue","ok","statusText","rejects","toThrow","json","error","meta","code_upload_url","deployment_id","static_asset_upload_urls","toEqual"],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- /**
2
- * Tests JWT parsing helpers and validates mock API contract.
3
- *
4
- * NOTE: The Figma API is currently mocked for development.
5
- *
6
- * These tests verify:
7
- * 1. JWT parsing helper functions (our code)
8
- * 2. JWT structure matches expected Figma API contract
9
- * 3. Mock responses are consistent for development
10
- *
11
- * TODO: Replace with integration tests when real API is available
12
- */
13
- export {};
14
- //# sourceMappingURL=figma-api.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"figma-api.spec.d.ts","sourceRoot":"","sources":["../../src/api/figma-api.spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}