@payloadcms/figma 0.0.1-alpha.9 → 0.1.0-alpha.1

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 (472) hide show
  1. package/dist/api/control-plane.d.ts +56 -7
  2. package/dist/api/control-plane.js +188 -74
  3. package/dist/api/error-response.d.ts +36 -0
  4. package/dist/api/error-response.js +66 -0
  5. package/dist/api/figma-api.d.ts +24 -3
  6. package/dist/api/figma-api.js +110 -34
  7. package/dist/auth/browser.d.ts +0 -1
  8. package/dist/auth/browser.js +0 -2
  9. package/dist/auth/callback-server.d.ts +19 -8
  10. package/dist/auth/callback-server.js +72 -32
  11. package/dist/auth/credentials.d.ts +20 -0
  12. package/dist/auth/credentials.js +19 -0
  13. package/dist/auth/crypto-utils.d.ts +28 -1
  14. package/dist/auth/crypto-utils.js +132 -23
  15. package/dist/auth/jwt-validator.d.ts +23 -6
  16. package/dist/auth/jwt-validator.js +35 -9
  17. package/dist/auth/oauth-flow.d.ts +19 -4
  18. package/dist/auth/oauth-flow.js +151 -34
  19. package/dist/auth/paste-code.d.ts +33 -0
  20. package/dist/auth/paste-code.js +87 -0
  21. package/dist/auth/pkce.d.ts +0 -1
  22. package/dist/auth/pkce.js +0 -2
  23. package/dist/auth/project-token.d.ts +32 -17
  24. package/dist/auth/project-token.js +176 -68
  25. package/dist/auth/refresh.d.ts +2 -2
  26. package/dist/auth/refresh.js +25 -14
  27. package/dist/auth/token-store-migration.d.ts +57 -0
  28. package/dist/auth/token-store-migration.js +154 -0
  29. package/dist/auth/token-store.d.ts +63 -98
  30. package/dist/auth/token-store.js +405 -124
  31. package/dist/auth/types.d.ts +40 -6
  32. package/dist/auth/types.js +1 -3
  33. package/dist/cli.d.ts +0 -1
  34. package/dist/cli.js +102 -8
  35. package/dist/commands/bootstrap.d.ts +17 -0
  36. package/dist/commands/bootstrap.js +88 -0
  37. package/dist/commands/build-lambda-zip.d.ts +4 -0
  38. package/dist/commands/build-lambda-zip.js +17 -0
  39. package/dist/commands/debug.d.ts +7 -0
  40. package/dist/commands/debug.js +178 -0
  41. package/dist/commands/deploy.d.ts +11 -1
  42. package/dist/commands/deploy.js +193 -153
  43. package/dist/commands/dump-tokens.d.ts +11 -0
  44. package/dist/commands/dump-tokens.js +67 -0
  45. package/dist/commands/env.d.ts +12 -0
  46. package/dist/commands/env.js +86 -0
  47. package/dist/commands/init.d.ts +9 -6
  48. package/dist/commands/init.js +232 -152
  49. package/dist/commands/list-tokens.d.ts +3 -4
  50. package/dist/commands/list-tokens.js +24 -11
  51. package/dist/commands/login.d.ts +8 -2
  52. package/dist/commands/login.js +34 -18
  53. package/dist/commands/logout.d.ts +5 -5
  54. package/dist/commands/logout.js +77 -17
  55. package/dist/commands/upgrade.d.ts +4 -0
  56. package/dist/commands/upgrade.js +329 -0
  57. package/dist/commands/upload-schema.d.ts +8 -0
  58. package/dist/commands/upload-schema.js +91 -0
  59. package/dist/config/oauth.d.ts +17 -12
  60. package/dist/config/oauth.js +38 -39
  61. package/dist/constants.d.ts +63 -19
  62. package/dist/constants.js +158 -20
  63. package/dist/db-content-api/generated/content-api-types.d.ts +8215 -0
  64. package/dist/db-content-api/generated/content-api-types.js +5 -0
  65. package/dist/db-content-api/index.d.ts +40 -0
  66. package/dist/db-content-api/index.js +883 -0
  67. package/dist/db-content-api/temp-utilities/slug.d.ts +1 -0
  68. package/dist/db-content-api/temp-utilities/slug.js +1 -0
  69. package/dist/db-content-api/temp-utilities/sorting.d.ts +2 -0
  70. package/dist/db-content-api/temp-utilities/sorting.js +37 -0
  71. package/dist/db-content-api/temp-utilities/types.d.ts +21 -0
  72. package/dist/db-content-api/temp-utilities/types.js +13 -0
  73. package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +38 -0
  74. package/dist/db-content-api/temp-utilities/unwrapDocument.js +62 -0
  75. package/dist/db-content-api/utilities/auth.d.ts +29 -0
  76. package/dist/db-content-api/utilities/auth.js +82 -0
  77. package/dist/db-content-api/utilities/clientVersionHeaders.d.ts +7 -0
  78. package/dist/db-content-api/utilities/clientVersionHeaders.js +15 -0
  79. package/dist/db-content-api/utilities/data/applyDefaults.d.ts +6 -0
  80. package/dist/db-content-api/utilities/data/applyDefaults.js +75 -0
  81. package/dist/db-content-api/utilities/data/atomicOperations.d.ts +16 -0
  82. package/dist/db-content-api/utilities/data/atomicOperations.js +48 -0
  83. package/dist/db-content-api/utilities/data/castFieldValue.d.ts +10 -0
  84. package/dist/db-content-api/utilities/data/castFieldValue.js +66 -0
  85. package/dist/db-content-api/utilities/data/convertRelationshipIds.d.ts +25 -0
  86. package/dist/db-content-api/utilities/data/convertRelationshipIds.js +109 -0
  87. package/dist/db-content-api/utilities/data/index.d.ts +48 -0
  88. package/dist/db-content-api/utilities/data/index.js +315 -0
  89. package/dist/db-content-api/utilities/data/isLocaleMap.d.ts +10 -0
  90. package/dist/db-content-api/utilities/data/isLocaleMap.js +13 -0
  91. package/dist/db-content-api/utilities/data/pointShape.d.ts +3 -0
  92. package/dist/db-content-api/utilities/data/pointShape.js +43 -0
  93. package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +11 -0
  94. package/dist/db-content-api/utilities/data/removeVirtualFields.js +52 -0
  95. package/dist/db-content-api/utilities/data/resolveFieldLocalization.d.ts +18 -0
  96. package/dist/db-content-api/utilities/data/resolveFieldLocalization.js +21 -0
  97. package/dist/db-content-api/utilities/data/richTextShape.d.ts +3 -0
  98. package/dist/db-content-api/utilities/data/richTextShape.js +56 -0
  99. package/dist/db-content-api/utilities/data/stripFields.d.ts +47 -0
  100. package/dist/db-content-api/utilities/data/stripFields.js +170 -0
  101. package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +22 -0
  102. package/dist/db-content-api/utilities/data/transformPublishedLocale.js +40 -0
  103. package/dist/db-content-api/utilities/data/validateRelationships.d.ts +6 -0
  104. package/dist/db-content-api/utilities/data/validateRelationships.js +107 -0
  105. package/dist/db-content-api/utilities/joins.d.ts +50 -0
  106. package/dist/db-content-api/utilities/joins.js +124 -0
  107. package/dist/db-content-api/utilities/locale/index.d.ts +9 -0
  108. package/dist/db-content-api/utilities/locale/index.js +19 -0
  109. package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.d.ts +9 -0
  110. package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.js +100 -0
  111. package/dist/db-content-api/utilities/resolveBlocks.d.ts +19 -0
  112. package/dist/db-content-api/utilities/resolveBlocks.js +31 -0
  113. package/dist/db-content-api/utilities/schema/buildDocumentSchema.d.ts +72 -0
  114. package/dist/db-content-api/utilities/schema/buildDocumentSchema.js +264 -0
  115. package/dist/db-content-api/utilities/where.d.ts +9 -0
  116. package/dist/db-content-api/utilities/where.js +95 -0
  117. package/dist/deploy/schedule-extract-plugin.d.ts +10 -0
  118. package/dist/deploy/schedule-extract-plugin.js +32 -0
  119. package/dist/endpoints/health.d.ts +2 -0
  120. package/dist/endpoints/health.js +9 -0
  121. package/dist/endpoints/schema.d.ts +2 -0
  122. package/dist/endpoints/schema.js +27 -0
  123. package/dist/exports/client.d.ts +2 -1
  124. package/dist/exports/client.js +2 -2
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +3 -3
  127. package/dist/lib/download-skill.d.ts +12 -0
  128. package/dist/lib/download-skill.js +77 -0
  129. package/dist/oauth/components/FigmaAvatar/index.d.ts +3 -0
  130. package/dist/oauth/components/FigmaAvatar/index.js +25 -0
  131. package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
  132. package/dist/oauth/components/FigmaAvatarCell/index.d.ts +4 -0
  133. package/dist/oauth/components/FigmaAvatarCell/index.js +23 -0
  134. package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
  135. package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +8 -0
  136. package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +35 -0
  137. package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
  138. package/dist/oauth/components/LoginButton/iframeAutoLogin.d.ts +81 -0
  139. package/dist/oauth/components/LoginButton/iframeAutoLogin.js +168 -0
  140. package/dist/oauth/components/LoginButton/index.d.ts +0 -1
  141. package/dist/oauth/components/LoginButton/index.js +156 -18
  142. package/dist/oauth/components/LoginButton/index.scss +75 -3
  143. package/dist/oauth/components/LogoutButton/index.d.ts +0 -1
  144. package/dist/oauth/components/LogoutButton/index.js +20 -9
  145. package/dist/oauth/defaults.d.ts +3 -2
  146. package/dist/oauth/defaults.js +79 -12
  147. package/dist/oauth/endpoints/getLoginEndpoint.d.ts +0 -1
  148. package/dist/oauth/endpoints/getLoginEndpoint.js +87 -84
  149. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts +0 -1
  150. package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -6
  151. package/dist/oauth/endpoints/getMetaEndpoint.d.ts +0 -1
  152. package/dist/oauth/endpoints/getMetaEndpoint.js +18 -5
  153. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts +0 -1
  154. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js +11 -4
  155. package/dist/oauth/exports/client.d.ts +0 -1
  156. package/dist/oauth/exports/client.js +0 -2
  157. package/dist/oauth/hooks/afterLogout.d.ts +0 -1
  158. package/dist/oauth/hooks/afterLogout.js +0 -2
  159. package/dist/oauth/hooks/me.d.ts +0 -1
  160. package/dist/oauth/hooks/me.js +0 -2
  161. package/dist/oauth/hooks/refresh.d.ts +0 -1
  162. package/dist/oauth/hooks/refresh.js +2 -3
  163. package/dist/oauth/index.d.ts +0 -1
  164. package/dist/oauth/index.js +27 -7
  165. package/dist/oauth/strategy/index.d.ts +0 -3
  166. package/dist/oauth/strategy/index.js +55 -34
  167. package/dist/oauth/types.d.ts +23 -7
  168. package/dist/oauth/types.js +0 -2
  169. package/dist/oauth/utilities/buildUnauthorizedRedirect.d.ts +14 -0
  170. package/dist/oauth/utilities/buildUnauthorizedRedirect.js +28 -0
  171. package/dist/oauth/utilities/clearCookie.d.ts +0 -1
  172. package/dist/oauth/utilities/clearCookie.js +5 -3
  173. package/dist/oauth/utilities/createCookieOptions.d.ts +0 -1
  174. package/dist/oauth/utilities/createCookieOptions.js +9 -4
  175. package/dist/oauth/utilities/createDebugLogger.d.ts +0 -1
  176. package/dist/oauth/utilities/createDebugLogger.js +0 -2
  177. package/dist/oauth/utilities/establishSession.d.ts +22 -0
  178. package/dist/oauth/utilities/establishSession.js +80 -0
  179. package/dist/oauth/utilities/exchangeCodeForAccessToken.d.ts +23 -0
  180. package/dist/oauth/utilities/exchangeCodeForAccessToken.js +26 -0
  181. package/dist/oauth/utilities/extractOrigin.d.ts +0 -1
  182. package/dist/oauth/utilities/extractOrigin.js +0 -2
  183. package/dist/oauth/utilities/figmaHostnames.d.ts +2 -0
  184. package/dist/oauth/utilities/figmaHostnames.js +24 -0
  185. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts +0 -1
  186. package/dist/oauth/utilities/getAdminCollectionSlug.js +0 -2
  187. package/dist/oauth/utilities/getAuthorizeURL.d.ts +65 -2
  188. package/dist/oauth/utilities/getAuthorizeURL.js +57 -4
  189. package/dist/oauth/utilities/getCookieExpiration.d.ts +0 -1
  190. package/dist/oauth/utilities/getCookieExpiration.js +0 -2
  191. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts +0 -1
  192. package/dist/oauth/utilities/getSecondsFromTokenExp.js +0 -2
  193. package/dist/oauth/utilities/getTokenExp.d.ts +0 -1
  194. package/dist/oauth/utilities/getTokenExp.js +0 -2
  195. package/dist/oauth/utilities/getUsernameField.d.ts +0 -1
  196. package/dist/oauth/utilities/getUsernameField.js +0 -2
  197. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts +0 -1
  198. package/dist/oauth/utilities/hasUserTokenPropsChanged.js +0 -2
  199. package/dist/oauth/utilities/isAbsoluteURL.d.ts +1 -0
  200. package/dist/oauth/utilities/isAbsoluteURL.js +1 -0
  201. package/dist/oauth/utilities/isDuplicateKeyError.d.ts +6 -0
  202. package/dist/oauth/utilities/isDuplicateKeyError.js +12 -0
  203. package/dist/oauth/utilities/mergeHeaders.d.ts +0 -1
  204. package/dist/oauth/utilities/mergeHeaders.js +0 -2
  205. package/dist/oauth/utilities/refreshTokens.d.ts +0 -1
  206. package/dist/oauth/utilities/refreshTokens.js +21 -13
  207. package/dist/oauth/utilities/withPartitionedCookie.d.ts +19 -0
  208. package/dist/oauth/utilities/withPartitionedCookie.js +26 -0
  209. package/dist/oauth/utils/getSearchParam.d.ts +17 -0
  210. package/dist/oauth/utils/getSearchParam.js +22 -0
  211. package/dist/plugin/adapter.d.ts +0 -1
  212. package/dist/plugin/adapter.js +0 -2
  213. package/dist/plugin/auth-preflight.d.ts +7 -0
  214. package/dist/plugin/auth-preflight.js +18 -0
  215. package/dist/plugin/bootstrap-preflight.d.ts +22 -0
  216. package/dist/plugin/bootstrap-preflight.js +43 -0
  217. package/dist/plugin/build-config.d.ts +27 -15
  218. package/dist/plugin/build-config.js +380 -16
  219. package/dist/plugin/dev-cookie-names.d.ts +13 -0
  220. package/dist/plugin/dev-cookie-names.js +17 -0
  221. package/dist/scss.d.js +2 -0
  222. package/dist/storage-content-api/api-types.d.ts +183 -0
  223. package/dist/storage-content-api/api-types.js +4 -0
  224. package/dist/storage-content-api/client-uploads/generate.d.ts +14 -0
  225. package/dist/storage-content-api/client-uploads/generate.js +69 -0
  226. package/dist/storage-content-api/client.d.ts +5 -0
  227. package/dist/storage-content-api/client.js +37 -0
  228. package/dist/storage-content-api/generateURL.d.ts +6 -0
  229. package/dist/storage-content-api/generateURL.js +6 -0
  230. package/dist/storage-content-api/handleDelete.d.ts +7 -0
  231. package/dist/storage-content-api/handleDelete.js +15 -0
  232. package/dist/storage-content-api/handleUpload.d.ts +10 -0
  233. package/dist/storage-content-api/handleUpload.js +162 -0
  234. package/dist/storage-content-api/index.d.ts +4 -0
  235. package/dist/storage-content-api/index.js +37 -0
  236. package/dist/storage-content-api/staticHandler.d.ts +9 -0
  237. package/dist/storage-content-api/staticHandler.js +61 -0
  238. package/dist/storage-content-api/types.d.ts +9 -0
  239. package/dist/storage-content-api/types.js +1 -0
  240. package/dist/storage-content-api/utilities/getSafeFilename.d.ts +11 -0
  241. package/dist/storage-content-api/utilities/getSafeFilename.js +59 -0
  242. package/dist/storage-content-api/utilities/index.d.ts +2 -0
  243. package/dist/storage-content-api/utilities/index.js +2 -0
  244. package/dist/storage-content-api/utilities/parseUploadReference.d.ts +17 -0
  245. package/dist/storage-content-api/utilities/parseUploadReference.js +27 -0
  246. package/dist/templates/.env.example +5 -0
  247. package/dist/templates/README.md +19 -0
  248. package/dist/types/config.d.ts +2 -2
  249. package/dist/types/config.js +0 -4
  250. package/dist/types.d.ts +10 -2
  251. package/dist/types.js +0 -2
  252. package/dist/utils/adapters/nextjs.d.ts +8 -0
  253. package/dist/utils/adapters/nextjs.js +61 -0
  254. package/dist/utils/adapters/nitro.d.ts +8 -0
  255. package/dist/utils/adapters/nitro.js +172 -0
  256. package/dist/utils/adapters/vite.d.ts +9 -0
  257. package/dist/utils/adapters/vite.js +31 -0
  258. package/dist/utils/asset-collection.d.ts +27 -7
  259. package/dist/utils/asset-collection.js +59 -32
  260. package/dist/utils/build-detection.d.ts +5 -12
  261. package/dist/utils/build-detection.js +74 -13
  262. package/dist/utils/build-lambda-zip.d.ts +25 -0
  263. package/dist/utils/build-lambda-zip.js +90 -0
  264. package/dist/utils/cache-bootstrap.d.ts +7 -0
  265. package/dist/utils/cache-bootstrap.js +16 -0
  266. package/dist/utils/config.d.ts +0 -1
  267. package/dist/utils/config.js +1 -3
  268. package/dist/utils/deploy-adapter.d.ts +45 -0
  269. package/dist/utils/deploy-adapter.js +56 -0
  270. package/dist/utils/download-template.d.ts +9 -2
  271. package/dist/utils/download-template.js +24 -20
  272. package/dist/utils/env-management.d.ts +24 -8
  273. package/dist/utils/env-management.js +119 -66
  274. package/dist/utils/format-env-suffix.d.ts +11 -0
  275. package/dist/utils/format-env-suffix.js +11 -0
  276. package/dist/utils/format.d.ts +0 -1
  277. package/dist/utils/format.js +0 -2
  278. package/dist/utils/formatter.d.ts +0 -1
  279. package/dist/utils/formatter.js +23 -13
  280. package/dist/utils/fs-utils.d.ts +12 -0
  281. package/dist/utils/fs-utils.js +55 -0
  282. package/dist/utils/git.d.ts +0 -1
  283. package/dist/utils/git.js +0 -2
  284. package/dist/utils/handle-upgrade.d.ts +8 -0
  285. package/dist/utils/handle-upgrade.js +39 -0
  286. package/dist/utils/is-debug.d.ts +0 -1
  287. package/dist/utils/is-debug.js +0 -2
  288. package/dist/utils/lambda-config.d.ts +3 -2
  289. package/dist/utils/lambda-config.js +75 -80
  290. package/dist/utils/load-payload-config.d.ts +9 -0
  291. package/dist/utils/load-payload-config.js +27 -0
  292. package/dist/utils/log.d.ts +0 -1
  293. package/dist/utils/log.js +0 -2
  294. package/dist/utils/messages.d.ts +1 -3
  295. package/dist/utils/messages.js +47 -13
  296. package/dist/utils/package-manager.d.ts +24 -1
  297. package/dist/utils/package-manager.js +53 -2
  298. package/dist/utils/parse-template-spec.d.ts +11 -0
  299. package/dist/utils/parse-template-spec.js +60 -0
  300. package/dist/utils/payload-config-ast.d.ts +27 -7
  301. package/dist/utils/payload-config-ast.js +106 -60
  302. package/dist/utils/payload-config-finder.d.ts +2 -3
  303. package/dist/utils/payload-config-finder.js +48 -11
  304. package/dist/utils/payload-config-modifier.d.ts +1 -2
  305. package/dist/utils/payload-config-modifier.js +114 -68
  306. package/dist/utils/payload-package-check.d.ts +28 -3
  307. package/dist/utils/payload-package-check.js +90 -31
  308. package/dist/utils/project.d.ts +8 -4
  309. package/dist/utils/project.js +63 -37
  310. package/dist/utils/resolve-environment.d.ts +13 -0
  311. package/dist/utils/resolve-environment.js +29 -0
  312. package/dist/utils/s3-upload.d.ts +7 -3
  313. package/dist/utils/s3-upload.js +44 -9
  314. package/dist/utils/token-display.d.ts +5 -2
  315. package/dist/utils/token-display.js +49 -24
  316. package/dist/utils/typescript-validator.d.ts +0 -1
  317. package/dist/utils/typescript-validator.js +4 -8
  318. package/dist/utils/version-check.d.ts +2 -0
  319. package/dist/utils/version-check.js +43 -0
  320. package/package.json +47 -16
  321. package/dist/api/control-plane.d.ts.map +0 -1
  322. package/dist/api/control-plane.js.map +0 -1
  323. package/dist/api/figma-api.d.ts.map +0 -1
  324. package/dist/api/figma-api.js.map +0 -1
  325. package/dist/auth/browser.d.ts.map +0 -1
  326. package/dist/auth/browser.js.map +0 -1
  327. package/dist/auth/callback-server.d.ts.map +0 -1
  328. package/dist/auth/callback-server.js.map +0 -1
  329. package/dist/auth/crypto-utils.d.ts.map +0 -1
  330. package/dist/auth/crypto-utils.js.map +0 -1
  331. package/dist/auth/jwt-validator.d.ts.map +0 -1
  332. package/dist/auth/jwt-validator.js.map +0 -1
  333. package/dist/auth/oauth-flow.d.ts.map +0 -1
  334. package/dist/auth/oauth-flow.js.map +0 -1
  335. package/dist/auth/pkce.d.ts.map +0 -1
  336. package/dist/auth/pkce.js.map +0 -1
  337. package/dist/auth/project-token.d.ts.map +0 -1
  338. package/dist/auth/project-token.js.map +0 -1
  339. package/dist/auth/refresh.d.ts.map +0 -1
  340. package/dist/auth/refresh.js.map +0 -1
  341. package/dist/auth/token-store.d.ts.map +0 -1
  342. package/dist/auth/token-store.js.map +0 -1
  343. package/dist/auth/types.d.ts.map +0 -1
  344. package/dist/auth/types.js.map +0 -1
  345. package/dist/cli.d.ts.map +0 -1
  346. package/dist/cli.js.map +0 -1
  347. package/dist/commands/deploy.d.ts.map +0 -1
  348. package/dist/commands/deploy.js.map +0 -1
  349. package/dist/commands/init.d.ts.map +0 -1
  350. package/dist/commands/init.js.map +0 -1
  351. package/dist/commands/list-tokens.d.ts.map +0 -1
  352. package/dist/commands/list-tokens.js.map +0 -1
  353. package/dist/commands/login.d.ts.map +0 -1
  354. package/dist/commands/login.js.map +0 -1
  355. package/dist/commands/logout.d.ts.map +0 -1
  356. package/dist/commands/logout.js.map +0 -1
  357. package/dist/config/oauth.d.ts.map +0 -1
  358. package/dist/config/oauth.js.map +0 -1
  359. package/dist/constants.d.ts.map +0 -1
  360. package/dist/constants.js.map +0 -1
  361. package/dist/exports/client.d.ts.map +0 -1
  362. package/dist/exports/client.js.map +0 -1
  363. package/dist/index.d.ts.map +0 -1
  364. package/dist/index.js.map +0 -1
  365. package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
  366. package/dist/oauth/components/LoginButton/index.js.map +0 -1
  367. package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
  368. package/dist/oauth/components/LogoutButton/index.js.map +0 -1
  369. package/dist/oauth/defaults.d.ts.map +0 -1
  370. package/dist/oauth/defaults.js.map +0 -1
  371. package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
  372. package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
  373. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
  374. package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
  375. package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
  376. package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
  377. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
  378. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
  379. package/dist/oauth/exports/client.d.ts.map +0 -1
  380. package/dist/oauth/exports/client.js.map +0 -1
  381. package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
  382. package/dist/oauth/hooks/afterLogout.js.map +0 -1
  383. package/dist/oauth/hooks/me.d.ts.map +0 -1
  384. package/dist/oauth/hooks/me.js.map +0 -1
  385. package/dist/oauth/hooks/refresh.d.ts.map +0 -1
  386. package/dist/oauth/hooks/refresh.js.map +0 -1
  387. package/dist/oauth/index.d.ts.map +0 -1
  388. package/dist/oauth/index.js.map +0 -1
  389. package/dist/oauth/strategy/index.d.ts.map +0 -1
  390. package/dist/oauth/strategy/index.js.map +0 -1
  391. package/dist/oauth/types.d.ts.map +0 -1
  392. package/dist/oauth/types.js.map +0 -1
  393. package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
  394. package/dist/oauth/utilities/clearCookie.js.map +0 -1
  395. package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
  396. package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
  397. package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
  398. package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
  399. package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
  400. package/dist/oauth/utilities/extractOrigin.js.map +0 -1
  401. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
  402. package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
  403. package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
  404. package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
  405. package/dist/oauth/utilities/getAdminPath.js +0 -9
  406. package/dist/oauth/utilities/getAdminPath.js.map +0 -1
  407. package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
  408. package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
  409. package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
  410. package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
  411. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
  412. package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
  413. package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
  414. package/dist/oauth/utilities/getTokenExp.js.map +0 -1
  415. package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
  416. package/dist/oauth/utilities/getUsernameField.js.map +0 -1
  417. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
  418. package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
  419. package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
  420. package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
  421. package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
  422. package/dist/oauth/utilities/refreshTokens.js.map +0 -1
  423. package/dist/plugin/adapter.d.ts.map +0 -1
  424. package/dist/plugin/adapter.js.map +0 -1
  425. package/dist/plugin/build-config.d.ts.map +0 -1
  426. package/dist/plugin/build-config.js.map +0 -1
  427. package/dist/types/config.d.ts.map +0 -1
  428. package/dist/types/config.js.map +0 -1
  429. package/dist/types.d.ts.map +0 -1
  430. package/dist/types.js.map +0 -1
  431. package/dist/utils/asset-collection.d.ts.map +0 -1
  432. package/dist/utils/asset-collection.js.map +0 -1
  433. package/dist/utils/build-detection.d.ts.map +0 -1
  434. package/dist/utils/build-detection.js.map +0 -1
  435. package/dist/utils/config.d.ts.map +0 -1
  436. package/dist/utils/config.js.map +0 -1
  437. package/dist/utils/download-template.d.ts.map +0 -1
  438. package/dist/utils/download-template.js.map +0 -1
  439. package/dist/utils/env-management.d.ts.map +0 -1
  440. package/dist/utils/env-management.js.map +0 -1
  441. package/dist/utils/format.d.ts.map +0 -1
  442. package/dist/utils/format.js.map +0 -1
  443. package/dist/utils/formatter.d.ts.map +0 -1
  444. package/dist/utils/formatter.js.map +0 -1
  445. package/dist/utils/git.d.ts.map +0 -1
  446. package/dist/utils/git.js.map +0 -1
  447. package/dist/utils/is-debug.d.ts.map +0 -1
  448. package/dist/utils/is-debug.js.map +0 -1
  449. package/dist/utils/lambda-config.d.ts.map +0 -1
  450. package/dist/utils/lambda-config.js.map +0 -1
  451. package/dist/utils/log.d.ts.map +0 -1
  452. package/dist/utils/log.js.map +0 -1
  453. package/dist/utils/messages.d.ts.map +0 -1
  454. package/dist/utils/messages.js.map +0 -1
  455. package/dist/utils/package-manager.d.ts.map +0 -1
  456. package/dist/utils/package-manager.js.map +0 -1
  457. package/dist/utils/payload-config-ast.d.ts.map +0 -1
  458. package/dist/utils/payload-config-ast.js.map +0 -1
  459. package/dist/utils/payload-config-finder.d.ts.map +0 -1
  460. package/dist/utils/payload-config-finder.js.map +0 -1
  461. package/dist/utils/payload-config-modifier.d.ts.map +0 -1
  462. package/dist/utils/payload-config-modifier.js.map +0 -1
  463. package/dist/utils/payload-package-check.d.ts.map +0 -1
  464. package/dist/utils/payload-package-check.js.map +0 -1
  465. package/dist/utils/project.d.ts.map +0 -1
  466. package/dist/utils/project.js.map +0 -1
  467. package/dist/utils/s3-upload.d.ts.map +0 -1
  468. package/dist/utils/s3-upload.js.map +0 -1
  469. package/dist/utils/token-display.d.ts.map +0 -1
  470. package/dist/utils/token-display.js.map +0 -1
  471. package/dist/utils/typescript-validator.d.ts.map +0 -1
  472. package/dist/utils/typescript-validator.js.map +0 -1
@@ -5,10 +5,11 @@
5
5
  * to the Content API. Project tokens are scoped to a specific tenant/CMS
6
6
  * and have a shorter lifespan (15-30 minutes) than OAuth tokens.
7
7
  */ import { getProjectToken as fetchProjectToken } from '../api/figma-api.js';
8
- import { getEnvironment } from '../constants.js';
8
+ import { PROJECT_TOKEN_EXPIRY_BUFFER_SECONDS } from '../config/oauth.js';
9
+ import { getInfraEnvironment } from '../constants.js';
9
10
  import * as log from '../utils/log.js';
10
- import { JWTValidationError, validateProjectToken } from './jwt-validator.js';
11
- import { getValidAccessToken } from './oauth-flow.js';
11
+ import { JWTValidationError, validateContentApiToken } from './jwt-validator.js';
12
+ import { getValidCredential } from './oauth-flow.js';
12
13
  /**
13
14
  * Error during project token operations
14
15
  */ export class ProjectTokenError extends Error {
@@ -18,6 +19,21 @@ import { getValidAccessToken } from './oauth-flow.js';
18
19
  this.name = 'ProjectTokenError';
19
20
  }
20
21
  }
22
+ const projectTokenCache = new Map();
23
+ const inFlightRefreshes = new Map();
24
+ function buildCacheKey(params) {
25
+ const projectId = params.projectInfo?.projectId ?? '';
26
+ const environmentName = params.projectInfo?.environmentName ?? '';
27
+ return `${params.tenantId}::${projectId}::${environmentName}`;
28
+ }
29
+ function isCachedTokenValid(entry) {
30
+ const bufferMs = PROJECT_TOKEN_EXPIRY_BUFFER_SECONDS * 1000;
31
+ return Date.now() < entry.expiresAt - bufferMs;
32
+ }
33
+ /** Test-only: clears the in-memory token cache and any in-flight refresh promises. */ export function __resetProjectTokenCacheForTests() {
34
+ projectTokenCache.clear();
35
+ inFlightRefreshes.clear();
36
+ }
21
37
  /**
22
38
  * Parse JWT claims from token without validation
23
39
  * Used for mock tokens where signature validation is not needed
@@ -43,89 +59,181 @@ import { getValidAccessToken } from './oauth-flow.js';
43
59
  }
44
60
  }
45
61
  /**
46
- * Get a valid project token for a tenant, refreshing if necessary
62
+ * Get a valid project token for a tenant, refreshing if necessary.
47
63
  *
48
- * This function:
49
- * 1. Checks if a stored project token exists and is valid (not expired)
50
- * 2. If expired or missing, gets a valid user access token
51
- * 3. Calls the Figma API to generate a new project token
52
- * 4. Stores the new project token in encrypted storage
53
- * 5. Returns the JWT string
64
+ * Lookup order:
65
+ * 1. Module-level in-memory cache (no I/O on hits).
66
+ * 2. In-flight refresh map concurrent callers with no cached entry share a single
67
+ * refresh promise, so the project-token endpoint is only hit once per cache key.
68
+ * 3. Persisted (`conf`-backed) token store picks up tokens minted by sibling processes.
69
+ * 4. Figma API — fetch + JWT validation, then write to both the persisted store and
70
+ * the in-memory cache.
54
71
  *
55
72
  * The project token is used by local Payload instances to authenticate
56
73
  * requests to the Content API without requiring a round-trip to Sinatra.
57
74
  *
58
- * @param tokenStore - Token store for persisting tokens
59
- * @param tenantId - The tenant/CMS ID to get a token for
75
+ * @param params.tokenStore - Token store for persisting tokens
76
+ * @param params.tenantId - Optional tenant/CMS ID; resolved from stored bootstrap data when omitted
77
+ * @param params.projectInfo - Optional project scope (defaults to env vars)
60
78
  * @returns Promise resolving to JWT token string or null if failed
61
79
  * @throws {ProjectTokenError} If token generation fails
62
- */ export async function getValidProjectToken(tokenStore, tenantId) {
63
- // Check if we have a valid project token already
64
- if (tokenStore.hasValidProjectToken(tenantId)) {
65
- const projectToken = tokenStore.getProjectToken(tenantId);
66
- return projectToken?.token || null;
80
+ */ export async function getValidProjectToken({ projectInfo, tenantId, tokenStore }) {
81
+ if (process.env.FIGMA_CONTENT_API_ACCESS_KEY) {
82
+ log.debug('FIGMA_CONTENT_API_ACCESS_KEY is set; skipping project token retrieval from API');
83
+ return null;
67
84
  }
68
- // We need to refresh the project token
69
- // First, get a valid user access token (will auto-refresh if needed)
70
- let accessToken;
71
- try {
72
- accessToken = await getValidAccessToken(tokenStore);
73
- } catch (error) {
74
- throw new ProjectTokenError('Failed to get valid access token for project token refresh', error instanceof Error ? error : undefined);
85
+ const resolvedTenantId = tenantId ?? tokenStore.getTenantId({
86
+ projectInfo
87
+ });
88
+ if (!resolvedTenantId) {
89
+ throw new ProjectTokenError('tenantId was not provided and could not be resolved from bootstrap data');
75
90
  }
76
- if (!accessToken) {
77
- // No valid user tokens available - user needs to authenticate
78
- return null;
91
+ const cacheKey = buildCacheKey({
92
+ projectInfo,
93
+ tenantId: resolvedTenantId
94
+ });
95
+ const cached = projectTokenCache.get(cacheKey);
96
+ if (cached && isCachedTokenValid(cached)) {
97
+ return cached.token;
79
98
  }
80
- // Fetch a new project token from the Figma API
81
- const projectToken = await fetchProjectToken(accessToken, tenantId);
82
- // Validate the JWT signature and claims (skip for mocks)
83
- const shouldMock = process.env.FIGMA_MOCK_PROJECT_TOKEN !== 'false';
84
- let validatedClaims;
85
- if (shouldMock) {
86
- // MOCK: Skip JWT validation and parse claims directly
87
- log.debug('Skipping JWT validation for mock project token');
88
- validatedClaims = parseJWTClaims(projectToken.token);
89
- } else {
90
- // REAL: Validate JWT signature against JWKS
99
+ const inFlight = inFlightRefreshes.get(cacheKey);
100
+ if (inFlight) {
101
+ return inFlight;
102
+ }
103
+ // The IIFE references this holder so it can check whether it is still the
104
+ // active refresh before writing back to the caches. Without this guard a
105
+ // stale in-flight refresh could clobber a fresh token written by a later
106
+ // refresh (e.g. one triggered by `refreshProjectToken`).
107
+ const handle = {};
108
+ handle.promise = (async ()=>{
109
+ if (tokenStore.hasValidProjectToken({
110
+ projectInfo
111
+ })) {
112
+ const stored = tokenStore.getProjectToken({
113
+ projectInfo
114
+ });
115
+ if (stored?.token && inFlightRefreshes.get(cacheKey) === handle.promise) {
116
+ projectTokenCache.set(cacheKey, {
117
+ expiresAt: stored.expiresAt,
118
+ token: stored.token
119
+ });
120
+ return stored.token;
121
+ }
122
+ if (stored?.token) {
123
+ return stored.token;
124
+ }
125
+ // hasValidProjectToken said yes but getProjectToken returned no token —
126
+ // store was likely cleared by another process between calls. Fall through
127
+ // to fetch so the caller still gets a token.
128
+ log.warning(`Stored project token vanished between hasValidProjectToken and getProjectToken (cacheKey=${cacheKey}); re-fetching`);
129
+ }
130
+ let credential;
131
+ try {
132
+ credential = await getValidCredential(tokenStore);
133
+ } catch (error) {
134
+ throw new ProjectTokenError('Failed to get valid access token for project token refresh', error instanceof Error ? error : undefined);
135
+ }
136
+ if (!credential) {
137
+ return null;
138
+ }
139
+ let fetchedToken;
91
140
  try {
92
- validatedClaims = await validateProjectToken(projectToken.token, getEnvironment());
93
- } catch (validationError) {
94
- // Handle validation errors
95
- if (validationError instanceof JWTValidationError) {
96
- throw new ProjectTokenError(`Project token validation failed: ${validationError.message}`, validationError);
141
+ fetchedToken = await fetchProjectToken(credential, resolvedTenantId);
142
+ } catch (error) {
143
+ // Let API errors (e.g. FigmaApiError) propagate raw so callers can
144
+ // branch on status codes — but log context for debugging.
145
+ log.debug(`fetchProjectToken failed (cacheKey=${cacheKey}, tenantId=${resolvedTenantId}): ${error instanceof Error ? error.message : 'Unknown error'}`);
146
+ throw error;
147
+ }
148
+ const hasEnvToken = !!process.env.FIGMA_MOCK_PROJECT_TOKEN_VALUE;
149
+ const shouldMock = process.env.FIGMA_MOCK_PROJECT_TOKEN !== 'false';
150
+ let validatedClaims;
151
+ if (hasEnvToken || shouldMock) {
152
+ log.debug('Skipping JWT validation for mock/env project token');
153
+ validatedClaims = parseJWTClaims(fetchedToken.token);
154
+ } else {
155
+ try {
156
+ validatedClaims = await validateContentApiToken({
157
+ audience: resolvedTenantId,
158
+ environment: getInfraEnvironment(),
159
+ token: fetchedToken.token
160
+ });
161
+ } catch (validationError) {
162
+ if (validationError instanceof JWTValidationError) {
163
+ throw new ProjectTokenError(`Project token validation failed: ${validationError.message}`, validationError);
164
+ }
165
+ throw validationError;
97
166
  }
98
- throw validationError;
167
+ }
168
+ if (typeof validatedClaims.exp !== 'number' || !Number.isFinite(validatedClaims.exp)) {
169
+ throw new ProjectTokenError('Project token missing or invalid expiration (exp) claim');
170
+ }
171
+ const expiresAt = validatedClaims.exp * 1000;
172
+ if (inFlightRefreshes.get(cacheKey) !== handle.promise) {
173
+ log.debug(`Project token refresh superseded; not persisting (cacheKey=${cacheKey})`);
174
+ return fetchedToken.token;
175
+ }
176
+ try {
177
+ tokenStore.setProjectToken({
178
+ projectInfo,
179
+ token: {
180
+ claims: validatedClaims,
181
+ expiresAt,
182
+ tenantId: resolvedTenantId,
183
+ token: fetchedToken.token
184
+ }
185
+ });
186
+ } catch (error) {
187
+ // Persistence is best-effort: a failure here (disk full, permissions,
188
+ // corrupt conf entry) shouldn't lose the freshly-minted token. Log and
189
+ // populate the in-memory cache so this process can still use it.
190
+ log.error(`Failed to persist project token to store (cacheKey=${cacheKey}): ${error instanceof Error ? error.message : 'Unknown error'}`);
191
+ }
192
+ projectTokenCache.set(cacheKey, {
193
+ expiresAt,
194
+ token: fetchedToken.token
195
+ });
196
+ return fetchedToken.token;
197
+ })();
198
+ inFlightRefreshes.set(cacheKey, handle.promise);
199
+ try {
200
+ return await handle.promise;
201
+ } finally{
202
+ if (inFlightRefreshes.get(cacheKey) === handle.promise) {
203
+ inFlightRefreshes.delete(cacheKey);
99
204
  }
100
205
  }
101
- // Ensure exp claim is present
102
- if (!validatedClaims.exp) {
103
- throw new ProjectTokenError('Project token missing expiration (exp) claim');
104
- }
105
- // Store the project token with validated expiration and claims
106
- tokenStore.setProjectToken(tenantId, {
107
- claims: validatedClaims,
108
- expiresAt: validatedClaims.exp * 1000,
109
- tenantId,
110
- token: projectToken.token
111
- });
112
- return projectToken.token;
113
206
  }
114
207
  /**
115
- * Refresh a project token for a tenant
208
+ * Force-refresh a project token, bypassing all cache layers.
116
209
  *
117
- * Forces a refresh of the project token even if the current one is still valid.
118
- * Useful for testing or when you want to ensure you have the freshest token.
210
+ * Invalidates the in-memory cache entry, the in-flight refresh promise (so a
211
+ * concurrently-running refresh that may already be returning a soon-to-be-stale
212
+ * token is dropped from the dedup map), and the persisted token store. Then
213
+ * delegates to {@link getValidProjectToken} to mint a fresh token.
119
214
  *
120
- * @param tokenStore - Token store for persisting tokens
121
- * @param tenantId - The tenant/CMS ID to refresh token for
215
+ * @param params.tokenStore - Token store for persisting tokens
216
+ * @param params.tenantId - Optional tenant/CMS ID; resolved from stored bootstrap data when omitted
217
+ * @param params.projectInfo - Optional project scope (defaults to env vars)
122
218
  * @returns Promise resolving to JWT token string or null if failed
123
219
  * @throws {ProjectTokenError} If token refresh fails
124
- */ export async function refreshProjectToken(tokenStore, tenantId) {
125
- // Clear the existing project token to force a refresh
126
- tokenStore.clearProjectToken(tenantId);
127
- // Get a new token (which will fetch from API since we just cleared it)
128
- return getValidProjectToken(tokenStore, tenantId);
220
+ */ export async function refreshProjectToken(params) {
221
+ const { projectInfo, tenantId, tokenStore } = params;
222
+ const resolvedTenantId = tenantId ?? tokenStore.getTenantId({
223
+ projectInfo
224
+ });
225
+ if (resolvedTenantId) {
226
+ const cacheKey = buildCacheKey({
227
+ projectInfo,
228
+ tenantId: resolvedTenantId
229
+ });
230
+ projectTokenCache.delete(cacheKey);
231
+ // Drop any in-flight refresh so getValidProjectToken below cannot return
232
+ // a soon-to-be-stale token via the dedup map.
233
+ inFlightRefreshes.delete(cacheKey);
234
+ }
235
+ tokenStore.clearProjectToken({
236
+ projectInfo
237
+ });
238
+ return getValidProjectToken(params);
129
239
  }
130
-
131
- //# sourceMappingURL=project-token.js.map
@@ -4,7 +4,8 @@ import type { FigmaTokens } from './types.js';
4
4
  */
5
5
  export declare class TokenRefreshError extends Error {
6
6
  statusCode?: number | undefined;
7
- constructor(message: string, statusCode?: number | undefined);
7
+ errorCode?: string | undefined;
8
+ constructor(message: string, statusCode?: number | undefined, errorCode?: string | undefined);
8
9
  }
9
10
  /**
10
11
  * Refresh an expired OAuth2 access token using a refresh token
@@ -32,4 +33,3 @@ export declare function refreshAccessToken(refreshToken: string, clientId?: stri
32
33
  * @throws TokenRefreshError if exchange fails
33
34
  */
34
35
  export declare function exchangeCodeForTokens(code: string, codeVerifier: string, redirectUri?: string, clientId?: string): Promise<FigmaTokens>;
35
- //# sourceMappingURL=refresh.d.ts.map
@@ -1,11 +1,12 @@
1
- /* eslint-disable perfectionist/sort-objects */ import { OAUTH_CONFIG } from '../config/oauth.js';
1
+ /* eslint-disable perfectionist/sort-objects */ import { getOAuthConfig } from '../config/oauth.js';
2
2
  import * as log from '../utils/log.js';
3
3
  /**
4
4
  * Error thrown when token refresh fails
5
5
  */ export class TokenRefreshError extends Error {
6
6
  statusCode;
7
- constructor(message, statusCode){
8
- super(message), this.statusCode = statusCode;
7
+ errorCode;
8
+ constructor(message, statusCode, errorCode){
9
+ super(message), this.statusCode = statusCode, this.errorCode = errorCode;
9
10
  this.name = 'TokenRefreshError';
10
11
  }
11
12
  }
@@ -19,15 +20,17 @@ import * as log from '../utils/log.js';
19
20
  * @param clientId - OAuth2 client ID (defaults to config)
20
21
  * @returns Promise resolving to new tokens
21
22
  * @throws TokenRefreshError if refresh fails
22
- */ export async function refreshAccessToken(refreshToken, clientId = OAUTH_CONFIG.clientId) {
23
+ */ export async function refreshAccessToken(refreshToken, clientId) {
24
+ const oauthConfig = getOAuthConfig();
25
+ const resolvedClientId = clientId ?? oauthConfig.clientId;
23
26
  // Prepare form data for token refresh request (public client)
24
27
  const params = new URLSearchParams({
25
- client_id: clientId,
28
+ client_id: resolvedClientId,
26
29
  grant_type: 'refresh_token',
27
30
  refresh_token: refreshToken
28
31
  });
29
32
  try {
30
- const response = await fetch(OAUTH_CONFIG.refreshUrl, {
33
+ const response = await fetch(oauthConfig.refreshUrl, {
31
34
  method: 'POST',
32
35
  headers: {
33
36
  'Content-Type': 'application/x-www-form-urlencoded'
@@ -36,7 +39,14 @@ import * as log from '../utils/log.js';
36
39
  });
37
40
  if (!response.ok) {
38
41
  const errorText = await response.text();
39
- throw new TokenRefreshError(`Token refresh failed: ${response.statusText}. ${errorText}`, response.status);
42
+ let errorCode;
43
+ try {
44
+ const parsed = JSON.parse(errorText);
45
+ errorCode = parsed.error;
46
+ } catch {
47
+ // Not JSON, leave errorCode undefined
48
+ }
49
+ throw new TokenRefreshError(`Token refresh failed: ${response.statusText}. ${errorText}`, response.status, errorCode);
40
50
  }
41
51
  const data = await response.json();
42
52
  // Validate response contains required fields
@@ -71,14 +81,17 @@ import * as log from '../utils/log.js';
71
81
  * @param clientId - OAuth2 client ID (defaults to config)
72
82
  * @returns Promise resolving to tokens
73
83
  * @throws TokenRefreshError if exchange fails
74
- */ export async function exchangeCodeForTokens(code, codeVerifier, redirectUri = OAUTH_CONFIG.redirectUri, clientId = OAUTH_CONFIG.clientId) {
84
+ */ export async function exchangeCodeForTokens(code, codeVerifier, redirectUri, clientId) {
85
+ const oauthConfig = getOAuthConfig();
86
+ const resolvedRedirectUri = redirectUri ?? oauthConfig.redirectUri;
87
+ const resolvedClientId = clientId ?? oauthConfig.clientId;
75
88
  // Prepare form data for token exchange (public client with PKCE)
76
89
  const params = new URLSearchParams({
77
- client_id: clientId,
90
+ client_id: resolvedClientId,
78
91
  code,
79
92
  code_verifier: codeVerifier,
80
93
  grant_type: 'authorization_code',
81
- redirect_uri: redirectUri
94
+ redirect_uri: resolvedRedirectUri
82
95
  });
83
96
  try {
84
97
  // Public client - no client secret or Basic Auth header needed
@@ -88,11 +101,11 @@ import * as log from '../utils/log.js';
88
101
  };
89
102
  // Debug logging
90
103
  log.debug(`Token exchange request: ${JSON.stringify({
91
- url: OAUTH_CONFIG.tokenUrl,
104
+ url: oauthConfig.tokenUrl,
92
105
  headers,
93
106
  body: params.toString()
94
107
  })}`);
95
- const response = await fetch(OAUTH_CONFIG.tokenUrl, {
108
+ const response = await fetch(oauthConfig.tokenUrl, {
96
109
  method: 'POST',
97
110
  headers,
98
111
  body: params.toString()
@@ -136,5 +149,3 @@ import * as log from '../utils/log.js';
136
149
  throw new TokenRefreshError(`Failed to exchange code for tokens: ${error instanceof Error ? error.message : 'Unknown error'}`);
137
150
  }
138
151
  }
139
-
140
- //# sourceMappingURL=refresh.js.map
@@ -0,0 +1,57 @@
1
+ import type { BootstrapData, FigmaTokens, ProjectToken } from './types.js';
2
+ export type LegacyStoreSchema = {
3
+ bootstrapData?: Record<string, BootstrapData>;
4
+ projectTokens?: Record<string, ProjectToken>;
5
+ tokens?: FigmaTokens;
6
+ };
7
+ export type MigrationCheckParams = {
8
+ checkFileExists?: (filePath: string) => boolean;
9
+ legacyFilePath: string;
10
+ newOAuthFilePath: string;
11
+ };
12
+ export type MigrateOAuthParams = {
13
+ encryptionKey: string;
14
+ legacyConfigName: string;
15
+ legacyCwd?: string;
16
+ newOAuthConfigName: string;
17
+ newOAuthCwd: string;
18
+ projectName: string;
19
+ };
20
+ /**
21
+ * Check if migration is needed.
22
+ * Returns true only when legacy file exists AND new oauth file does not.
23
+ */
24
+ export declare function needsMigration(params: MigrationCheckParams): boolean;
25
+ /**
26
+ * Migrate OAuth tokens from legacy store to new oauth store.
27
+ * Reads from legacy location, writes to new location with root-level keys.
28
+ *
29
+ * `clearInvalidConfig` is deliberately OFF so a transient decrypt error does
30
+ * not wipe the legacy file — older CLI versions elsewhere on disk still read
31
+ * it. If we cannot open the file, we log and skip migration.
32
+ */
33
+ export declare function migrateOAuth(params: MigrateOAuthParams): void;
34
+ export type ResolveProjectStorePath = (scope: {
35
+ environmentName: string;
36
+ projectId: string;
37
+ }) => {
38
+ configName: string;
39
+ cwd: string;
40
+ };
41
+ export type MigrateProjectDataParams = {
42
+ encryptionKey: string;
43
+ legacyConfigName: string;
44
+ legacyCwd?: string;
45
+ projectName: string;
46
+ resolveProjectStorePath: ResolveProjectStorePath;
47
+ };
48
+ /**
49
+ * Migrate per-project bootstrap data and project tokens from the legacy
50
+ * combined store into individual per-project stores.
51
+ *
52
+ * Walks legacy `bootstrapData` (keyed by `projectId:environmentName`), writes
53
+ * each entry into its own project store file, and stashes the matching
54
+ * `projectToken` (looked up by `bootstrapData.contentSystemId`) alongside it.
55
+ * Target files that already exist are left alone.
56
+ */
57
+ export declare function migrateProjectData(params: MigrateProjectDataParams): void;
@@ -0,0 +1,154 @@
1
+ import Conf from 'conf';
2
+ import fsSync from 'node:fs';
3
+ import path from 'node:path';
4
+ import * as log from '../utils/log.js';
5
+ const OAUTH_STORE_SCHEMA_VERSION = 1;
6
+ const PROJECT_STORE_SCHEMA_VERSION = 1;
7
+ /**
8
+ * Check if migration is needed.
9
+ * Returns true only when legacy file exists AND new oauth file does not.
10
+ */ export function needsMigration(params) {
11
+ const checkExists = params.checkFileExists ?? fsSync.existsSync;
12
+ const newExists = checkExists(params.newOAuthFilePath);
13
+ if (newExists) {
14
+ return false;
15
+ }
16
+ return checkExists(params.legacyFilePath);
17
+ }
18
+ /**
19
+ * Migrate OAuth tokens from legacy store to new oauth store.
20
+ * Reads from legacy location, writes to new location with root-level keys.
21
+ *
22
+ * `clearInvalidConfig` is deliberately OFF so a transient decrypt error does
23
+ * not wipe the legacy file — older CLI versions elsewhere on disk still read
24
+ * it. If we cannot open the file, we log and skip migration.
25
+ */ export function migrateOAuth(params) {
26
+ const legacyConfig = openLegacyConfig({
27
+ encryptionKey: params.encryptionKey,
28
+ legacyConfigName: params.legacyConfigName,
29
+ legacyCwd: params.legacyCwd,
30
+ projectName: params.projectName
31
+ });
32
+ if (!legacyConfig) {
33
+ return;
34
+ }
35
+ const legacyTokens = safeGet(legacyConfig, 'tokens');
36
+ if (!legacyTokens) {
37
+ return;
38
+ }
39
+ // Ensure target directory exists
40
+ if (!fsSync.existsSync(params.newOAuthCwd)) {
41
+ fsSync.mkdirSync(params.newOAuthCwd, {
42
+ recursive: true
43
+ });
44
+ }
45
+ const newOAuthConfig = new Conf({
46
+ configName: params.newOAuthConfigName,
47
+ cwd: params.newOAuthCwd,
48
+ encryptionKey: params.encryptionKey,
49
+ projectName: params.projectName
50
+ });
51
+ // Write root-level keys
52
+ newOAuthConfig.set('_schemaVersion', OAUTH_STORE_SCHEMA_VERSION);
53
+ newOAuthConfig.set('accessToken', legacyTokens.accessToken);
54
+ newOAuthConfig.set('expiresAt', legacyTokens.expiresAt);
55
+ newOAuthConfig.set('refreshToken', legacyTokens.refreshToken);
56
+ if (legacyTokens.scopes) {
57
+ newOAuthConfig.set('scopes', legacyTokens.scopes);
58
+ }
59
+ if (legacyTokens.tokenType) {
60
+ newOAuthConfig.set('tokenType', legacyTokens.tokenType);
61
+ }
62
+ if (legacyTokens.userId) {
63
+ newOAuthConfig.set('userId', legacyTokens.userId);
64
+ }
65
+ // Leave the legacy file untouched so older CLI versions installed in other
66
+ // projects on the same machine can keep reading their last known state.
67
+ }
68
+ /**
69
+ * Migrate per-project bootstrap data and project tokens from the legacy
70
+ * combined store into individual per-project stores.
71
+ *
72
+ * Walks legacy `bootstrapData` (keyed by `projectId:environmentName`), writes
73
+ * each entry into its own project store file, and stashes the matching
74
+ * `projectToken` (looked up by `bootstrapData.contentSystemId`) alongside it.
75
+ * Target files that already exist are left alone.
76
+ */ export function migrateProjectData(params) {
77
+ const legacyConfig = openLegacyConfig({
78
+ encryptionKey: params.encryptionKey,
79
+ legacyConfigName: params.legacyConfigName,
80
+ legacyCwd: params.legacyCwd,
81
+ projectName: params.projectName
82
+ });
83
+ if (!legacyConfig) {
84
+ return;
85
+ }
86
+ const bootstrapData = safeGet(legacyConfig, 'bootstrapData') || {};
87
+ const projectTokens = safeGet(legacyConfig, 'projectTokens') || {};
88
+ if (Object.keys(bootstrapData).length === 0 && Object.keys(projectTokens).length === 0) {
89
+ return;
90
+ }
91
+ for (const [key, bootstrap] of Object.entries(bootstrapData)){
92
+ const separatorIdx = key.indexOf(':');
93
+ if (separatorIdx === -1) {
94
+ continue;
95
+ }
96
+ const projectId = key.slice(0, separatorIdx);
97
+ const environmentName = key.slice(separatorIdx + 1);
98
+ if (!projectId || !environmentName) {
99
+ continue;
100
+ }
101
+ const { configName, cwd } = params.resolveProjectStorePath({
102
+ environmentName,
103
+ projectId
104
+ });
105
+ const targetPath = path.join(cwd, `${configName}.json`);
106
+ if (fsSync.existsSync(targetPath)) {
107
+ continue;
108
+ }
109
+ if (!fsSync.existsSync(cwd)) {
110
+ fsSync.mkdirSync(cwd, {
111
+ recursive: true
112
+ });
113
+ }
114
+ const projectConfig = new Conf({
115
+ configName,
116
+ cwd,
117
+ encryptionKey: params.encryptionKey,
118
+ projectName: params.projectName
119
+ });
120
+ projectConfig.set('_schemaVersion', PROJECT_STORE_SCHEMA_VERSION);
121
+ projectConfig.set('bootstrapData', bootstrap);
122
+ const legacyProjectToken = bootstrap.contentSystemId ? projectTokens[bootstrap.contentSystemId] : undefined;
123
+ if (legacyProjectToken) {
124
+ projectConfig.set('projectToken', legacyProjectToken);
125
+ }
126
+ }
127
+ // Leave the legacy file untouched so older CLI versions installed in other
128
+ // projects on the same machine can keep reading their last known state.
129
+ }
130
+ function safeGet(config, key) {
131
+ try {
132
+ return config.get(key);
133
+ } catch (error) {
134
+ log.debug(`Migration read failed (key: ${String(key)}). ` + `File: ${config.path}. ` + `Error: ${error instanceof Error ? error.message : 'Unknown'}`);
135
+ return undefined;
136
+ }
137
+ }
138
+ /**
139
+ * Open the legacy Conf store without `clearInvalidConfig`, so a decrypt
140
+ * error does not destroy the file. Returns null when the file cannot be
141
+ * opened — callers treat that as "nothing to migrate, leave file alone".
142
+ */ function openLegacyConfig(params) {
143
+ try {
144
+ return new Conf({
145
+ configName: params.legacyConfigName,
146
+ cwd: params.legacyCwd,
147
+ encryptionKey: params.encryptionKey,
148
+ projectName: params.projectName
149
+ });
150
+ } catch (error) {
151
+ log.debug(`Legacy token store could not be opened; skipping migration and leaving file intact. ` + `Error: ${error instanceof Error ? error.message : 'Unknown'}`);
152
+ return null;
153
+ }
154
+ }