@payloadcms/figma 0.0.1-alpha.7 → 0.0.1-alpha.70

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 (390) hide show
  1. package/dist/api/control-plane.d.ts +56 -6
  2. package/dist/api/control-plane.js +181 -72
  3. package/dist/api/figma-api.d.ts +22 -1
  4. package/dist/api/figma-api.js +78 -25
  5. package/dist/auth/callback-server.d.ts +19 -7
  6. package/dist/auth/callback-server.js +72 -30
  7. package/dist/auth/credentials.d.ts +21 -0
  8. package/dist/auth/credentials.js +21 -0
  9. package/dist/auth/crypto-utils.d.ts +28 -0
  10. package/dist/auth/crypto-utils.js +132 -21
  11. package/dist/auth/jwt-validator.d.ts +2 -1
  12. package/dist/auth/jwt-validator.js +2 -2
  13. package/dist/auth/oauth-flow.d.ts +19 -3
  14. package/dist/auth/oauth-flow.js +77 -22
  15. package/dist/auth/project-token.d.ts +32 -16
  16. package/dist/auth/project-token.js +171 -65
  17. package/dist/auth/refresh.d.ts +2 -1
  18. package/dist/auth/refresh.js +25 -12
  19. package/dist/auth/token-store-migration.d.ts +58 -0
  20. package/dist/auth/token-store-migration.js +156 -0
  21. package/dist/auth/token-store.d.ts +63 -97
  22. package/dist/auth/token-store.js +405 -122
  23. package/dist/auth/types.d.ts +35 -4
  24. package/dist/cli.js +93 -6
  25. package/dist/commands/bootstrap.d.ts +18 -0
  26. package/dist/commands/bootstrap.js +90 -0
  27. package/dist/commands/build-lambda-zip.d.ts +5 -0
  28. package/dist/commands/build-lambda-zip.js +19 -0
  29. package/dist/commands/debug.d.ts +8 -0
  30. package/dist/commands/debug.js +180 -0
  31. package/dist/commands/deploy.d.ts +9 -0
  32. package/dist/commands/deploy.js +180 -151
  33. package/dist/commands/dump-tokens.d.ts +12 -0
  34. package/dist/commands/dump-tokens.js +69 -0
  35. package/dist/commands/env.d.ts +13 -0
  36. package/dist/commands/env.js +88 -0
  37. package/dist/commands/init.d.ts +9 -5
  38. package/dist/commands/init.js +241 -148
  39. package/dist/commands/list-tokens.d.ts +3 -3
  40. package/dist/commands/list-tokens.js +24 -9
  41. package/dist/commands/login.d.ts +8 -1
  42. package/dist/commands/login.js +34 -16
  43. package/dist/commands/logout.d.ts +5 -4
  44. package/dist/commands/logout.js +77 -15
  45. package/dist/commands/upgrade.d.ts +5 -0
  46. package/dist/commands/upgrade.js +331 -0
  47. package/dist/config/oauth.d.ts +17 -11
  48. package/dist/config/oauth.js +38 -37
  49. package/dist/constants.d.ts +63 -18
  50. package/dist/constants.js +158 -18
  51. package/dist/db-content-api/generated/content-api-types.d.ts +3978 -0
  52. package/dist/db-content-api/generated/content-api-types.js +7 -0
  53. package/dist/db-content-api/index.d.ts +37 -0
  54. package/dist/db-content-api/index.js +923 -0
  55. package/dist/db-content-api/temp-utilities/slug.d.ts +2 -0
  56. package/dist/db-content-api/temp-utilities/slug.js +3 -0
  57. package/dist/db-content-api/temp-utilities/sorting.d.ts +3 -0
  58. package/dist/db-content-api/temp-utilities/sorting.js +39 -0
  59. package/dist/db-content-api/temp-utilities/types.d.ts +22 -0
  60. package/dist/db-content-api/temp-utilities/types.js +15 -0
  61. package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +39 -0
  62. package/dist/db-content-api/temp-utilities/unwrapDocument.js +64 -0
  63. package/dist/db-content-api/utilities/auth.d.ts +30 -0
  64. package/dist/db-content-api/utilities/auth.js +84 -0
  65. package/dist/db-content-api/utilities/data/applyDefaults.d.ts +7 -0
  66. package/dist/db-content-api/utilities/data/applyDefaults.js +75 -0
  67. package/dist/db-content-api/utilities/data/castFieldValue.d.ts +11 -0
  68. package/dist/db-content-api/utilities/data/castFieldValue.js +68 -0
  69. package/dist/db-content-api/utilities/data/index.d.ts +49 -0
  70. package/dist/db-content-api/utilities/data/index.js +301 -0
  71. package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +12 -0
  72. package/dist/db-content-api/utilities/data/removeVirtualFields.js +54 -0
  73. package/dist/db-content-api/utilities/data/stripFields.d.ts +48 -0
  74. package/dist/db-content-api/utilities/data/stripFields.js +195 -0
  75. package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +23 -0
  76. package/dist/db-content-api/utilities/data/transformPublishedLocale.js +42 -0
  77. package/dist/db-content-api/utilities/data/validateRelationships.d.ts +7 -0
  78. package/dist/db-content-api/utilities/data/validateRelationships.js +102 -0
  79. package/dist/db-content-api/utilities/joins.d.ts +53 -0
  80. package/dist/db-content-api/utilities/joins.js +139 -0
  81. package/dist/db-content-api/utilities/locale/index.d.ts +10 -0
  82. package/dist/db-content-api/utilities/locale/index.js +21 -0
  83. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts +11 -0
  84. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +74 -0
  85. package/dist/db-content-api/utilities/meta/buildMeta.d.ts +42 -0
  86. package/dist/db-content-api/utilities/meta/buildMeta.js +41 -0
  87. package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +17 -0
  88. package/dist/db-content-api/utilities/meta/buildPathTypes.js +244 -0
  89. package/dist/db-content-api/utilities/meta/buildUniquePaths.d.ts +13 -0
  90. package/dist/db-content-api/utilities/meta/buildUniquePaths.js +62 -0
  91. package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.d.ts +10 -0
  92. package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.js +102 -0
  93. package/dist/db-content-api/utilities/where.d.ts +20 -0
  94. package/dist/db-content-api/utilities/where.js +108 -0
  95. package/dist/deploy/schedule-extract-plugin.d.ts +11 -0
  96. package/dist/deploy/schedule-extract-plugin.js +34 -0
  97. package/dist/endpoints/health.d.ts +3 -0
  98. package/dist/endpoints/health.js +11 -0
  99. package/dist/endpoints/schema.d.ts +3 -0
  100. package/dist/endpoints/schema.js +29 -0
  101. package/dist/exports/client.d.ts +3 -0
  102. package/dist/exports/client.js +3 -0
  103. package/dist/index.d.ts +2 -1
  104. package/dist/index.js +3 -1
  105. package/dist/lib/download-skill.d.ts +13 -0
  106. package/dist/lib/download-skill.js +79 -0
  107. package/dist/oauth/components/FigmaAvatar/index.d.ts +4 -0
  108. package/dist/oauth/components/FigmaAvatar/index.js +27 -0
  109. package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
  110. package/dist/oauth/components/FigmaAvatarCell/index.d.ts +5 -0
  111. package/dist/oauth/components/FigmaAvatarCell/index.js +25 -0
  112. package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
  113. package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +9 -0
  114. package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +37 -0
  115. package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
  116. package/dist/oauth/components/LoginButton/iframeAutoLogin.d.ts +82 -0
  117. package/dist/oauth/components/LoginButton/iframeAutoLogin.js +170 -0
  118. package/dist/oauth/components/LoginButton/index.js +144 -11
  119. package/dist/oauth/components/LoginButton/index.scss +75 -3
  120. package/dist/oauth/components/LogoutButton/index.js +19 -6
  121. package/dist/oauth/defaults.d.ts +3 -1
  122. package/dist/oauth/defaults.js +68 -10
  123. package/dist/oauth/endpoints/getLoginEndpoint.js +72 -77
  124. package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -4
  125. package/dist/oauth/endpoints/getMetaEndpoint.js +18 -3
  126. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js +11 -2
  127. package/dist/oauth/index.js +27 -5
  128. package/dist/oauth/strategy/index.d.ts +0 -2
  129. package/dist/oauth/strategy/index.js +40 -17
  130. package/dist/oauth/types.d.ts +23 -6
  131. package/dist/oauth/utilities/establishSession.d.ts +23 -0
  132. package/dist/oauth/utilities/establishSession.js +82 -0
  133. package/dist/oauth/utilities/exchangeCodeForAccessToken.d.ts +24 -0
  134. package/dist/oauth/utilities/exchangeCodeForAccessToken.js +28 -0
  135. package/dist/oauth/utilities/figmaHostnames.d.ts +3 -0
  136. package/dist/oauth/utilities/figmaHostnames.js +26 -0
  137. package/dist/oauth/utilities/getAuthorizeURL.d.ts +65 -1
  138. package/dist/oauth/utilities/getAuthorizeURL.js +57 -2
  139. package/dist/oauth/utilities/isAbsoluteURL.d.ts +2 -0
  140. package/dist/oauth/utilities/isAbsoluteURL.js +3 -0
  141. package/dist/oauth/utilities/isDuplicateKeyError.d.ts +7 -0
  142. package/dist/oauth/utilities/isDuplicateKeyError.js +14 -0
  143. package/dist/oauth/utilities/refreshTokens.js +6 -3
  144. package/dist/plugin/auth-preflight.d.ts +8 -0
  145. package/dist/plugin/auth-preflight.js +20 -0
  146. package/dist/plugin/bootstrap-preflight.d.ts +23 -0
  147. package/dist/plugin/bootstrap-preflight.js +45 -0
  148. package/dist/plugin/build-config.d.ts +27 -15
  149. package/dist/plugin/build-config.js +327 -17
  150. package/dist/plugin/dev-cookie-names.d.ts +14 -0
  151. package/dist/plugin/dev-cookie-names.js +19 -0
  152. package/dist/storage-content-api/api-types.d.ts +168 -0
  153. package/dist/storage-content-api/api-types.js +6 -0
  154. package/dist/storage-content-api/client-uploads/ClientUploadHandler.d.ts +9 -0
  155. package/dist/storage-content-api/client-uploads/ClientUploadHandler.js +43 -0
  156. package/dist/storage-content-api/client-uploads/generateSignedURL.d.ts +13 -0
  157. package/dist/storage-content-api/client-uploads/generateSignedURL.js +39 -0
  158. package/dist/storage-content-api/client.d.ts +6 -0
  159. package/dist/storage-content-api/client.js +39 -0
  160. package/dist/storage-content-api/generateURL.d.ts +7 -0
  161. package/dist/storage-content-api/generateURL.js +8 -0
  162. package/dist/storage-content-api/handleDelete.d.ts +8 -0
  163. package/dist/storage-content-api/handleDelete.js +17 -0
  164. package/dist/storage-content-api/handleUpload.d.ts +11 -0
  165. package/dist/storage-content-api/handleUpload.js +144 -0
  166. package/dist/storage-content-api/index.d.ts +5 -0
  167. package/dist/storage-content-api/index.js +31 -0
  168. package/dist/storage-content-api/staticHandler.d.ts +10 -0
  169. package/dist/storage-content-api/staticHandler.js +63 -0
  170. package/dist/storage-content-api/types.d.ts +10 -0
  171. package/dist/storage-content-api/types.js +3 -0
  172. package/dist/storage-content-api/utilities/getSafeFilename.d.ts +12 -0
  173. package/dist/storage-content-api/utilities/getSafeFilename.js +61 -0
  174. package/dist/storage-content-api/utilities/index.d.ts +3 -0
  175. package/dist/storage-content-api/utilities/index.js +4 -0
  176. package/dist/storage-content-api/utilities/parseClientUploadContext.d.ts +19 -0
  177. package/dist/storage-content-api/utilities/parseClientUploadContext.js +30 -0
  178. package/dist/templates/.env.example +5 -0
  179. package/dist/templates/README.md +19 -0
  180. package/dist/types/config.d.ts +2 -1
  181. package/dist/types/config.js +0 -2
  182. package/dist/types.d.ts +10 -1
  183. package/dist/utils/adapters/nextjs.d.ts +9 -0
  184. package/dist/utils/adapters/nextjs.js +64 -0
  185. package/dist/utils/adapters/nitro.d.ts +9 -0
  186. package/dist/utils/adapters/nitro.js +169 -0
  187. package/dist/utils/adapters/vite.d.ts +10 -0
  188. package/dist/utils/adapters/vite.js +33 -0
  189. package/dist/utils/asset-collection.d.ts +27 -6
  190. package/dist/utils/asset-collection.js +59 -30
  191. package/dist/utils/build-detection.d.ts +5 -11
  192. package/dist/utils/build-detection.js +74 -11
  193. package/dist/utils/build-lambda-zip.d.ts +16 -0
  194. package/dist/utils/build-lambda-zip.js +78 -0
  195. package/dist/utils/cache-bootstrap.d.ts +8 -0
  196. package/dist/utils/cache-bootstrap.js +18 -0
  197. package/dist/utils/config.js +1 -1
  198. package/dist/utils/deploy-adapter.d.ts +40 -0
  199. package/dist/utils/deploy-adapter.js +58 -0
  200. package/dist/utils/download-template.d.ts +9 -1
  201. package/dist/utils/download-template.js +24 -18
  202. package/dist/utils/env-management.d.ts +24 -7
  203. package/dist/utils/env-management.js +119 -64
  204. package/dist/utils/format-env-suffix.d.ts +12 -0
  205. package/dist/utils/format-env-suffix.js +13 -0
  206. package/dist/utils/formatter.js +23 -11
  207. package/dist/utils/fs-utils.d.ts +6 -0
  208. package/dist/utils/fs-utils.js +27 -0
  209. package/dist/utils/handle-upgrade.d.ts +9 -0
  210. package/dist/utils/handle-upgrade.js +41 -0
  211. package/dist/utils/lambda-config.d.ts +3 -1
  212. package/dist/utils/lambda-config.js +75 -78
  213. package/dist/utils/messages.d.ts +1 -2
  214. package/dist/utils/messages.js +39 -11
  215. package/dist/utils/package-manager.d.ts +24 -0
  216. package/dist/utils/package-manager.js +53 -0
  217. package/dist/utils/parse-template-spec.d.ts +12 -0
  218. package/dist/utils/parse-template-spec.js +62 -0
  219. package/dist/utils/payload-config-ast.d.ts +27 -6
  220. package/dist/utils/payload-config-ast.js +106 -58
  221. package/dist/utils/payload-config-finder.d.ts +2 -2
  222. package/dist/utils/payload-config-finder.js +48 -9
  223. package/dist/utils/payload-config-modifier.d.ts +1 -1
  224. package/dist/utils/payload-config-modifier.js +114 -66
  225. package/dist/utils/payload-package-check.d.ts +33 -2
  226. package/dist/utils/payload-package-check.js +129 -28
  227. package/dist/utils/project.d.ts +7 -2
  228. package/dist/utils/project.js +60 -32
  229. package/dist/utils/resolve-environment.d.ts +14 -0
  230. package/dist/utils/resolve-environment.js +31 -0
  231. package/dist/utils/s3-upload.d.ts +7 -2
  232. package/dist/utils/s3-upload.js +39 -6
  233. package/dist/utils/token-display.d.ts +5 -1
  234. package/dist/utils/token-display.js +49 -22
  235. package/dist/utils/typescript-validator.js +4 -6
  236. package/dist/utils/version-check.d.ts +3 -0
  237. package/dist/utils/version-check.js +38 -0
  238. package/package.json +44 -15
  239. package/dist/api/control-plane.d.ts.map +0 -1
  240. package/dist/api/control-plane.js.map +0 -1
  241. package/dist/api/figma-api.d.ts.map +0 -1
  242. package/dist/api/figma-api.js.map +0 -1
  243. package/dist/auth/browser.d.ts.map +0 -1
  244. package/dist/auth/browser.js.map +0 -1
  245. package/dist/auth/callback-server.d.ts.map +0 -1
  246. package/dist/auth/callback-server.js.map +0 -1
  247. package/dist/auth/crypto-utils.d.ts.map +0 -1
  248. package/dist/auth/crypto-utils.js.map +0 -1
  249. package/dist/auth/jwt-validator.d.ts.map +0 -1
  250. package/dist/auth/jwt-validator.js.map +0 -1
  251. package/dist/auth/oauth-flow.d.ts.map +0 -1
  252. package/dist/auth/oauth-flow.js.map +0 -1
  253. package/dist/auth/pkce.d.ts.map +0 -1
  254. package/dist/auth/pkce.js.map +0 -1
  255. package/dist/auth/project-token.d.ts.map +0 -1
  256. package/dist/auth/project-token.js.map +0 -1
  257. package/dist/auth/refresh.d.ts.map +0 -1
  258. package/dist/auth/refresh.js.map +0 -1
  259. package/dist/auth/token-store.d.ts.map +0 -1
  260. package/dist/auth/token-store.js.map +0 -1
  261. package/dist/auth/types.d.ts.map +0 -1
  262. package/dist/auth/types.js.map +0 -1
  263. package/dist/cli.d.ts.map +0 -1
  264. package/dist/cli.js.map +0 -1
  265. package/dist/commands/deploy.d.ts.map +0 -1
  266. package/dist/commands/deploy.js.map +0 -1
  267. package/dist/commands/init.d.ts.map +0 -1
  268. package/dist/commands/init.js.map +0 -1
  269. package/dist/commands/list-tokens.d.ts.map +0 -1
  270. package/dist/commands/list-tokens.js.map +0 -1
  271. package/dist/commands/login.d.ts.map +0 -1
  272. package/dist/commands/login.js.map +0 -1
  273. package/dist/commands/logout.d.ts.map +0 -1
  274. package/dist/commands/logout.js.map +0 -1
  275. package/dist/config/oauth.d.ts.map +0 -1
  276. package/dist/config/oauth.js.map +0 -1
  277. package/dist/constants.d.ts.map +0 -1
  278. package/dist/constants.js.map +0 -1
  279. package/dist/exports/client.d.ts.map +0 -1
  280. package/dist/exports/client.js.map +0 -1
  281. package/dist/index.d.ts.map +0 -1
  282. package/dist/index.js.map +0 -1
  283. package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
  284. package/dist/oauth/components/LoginButton/index.js.map +0 -1
  285. package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
  286. package/dist/oauth/components/LogoutButton/index.js.map +0 -1
  287. package/dist/oauth/defaults.d.ts.map +0 -1
  288. package/dist/oauth/defaults.js.map +0 -1
  289. package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
  290. package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
  291. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
  292. package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
  293. package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
  294. package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
  295. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
  296. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
  297. package/dist/oauth/exports/client.d.ts.map +0 -1
  298. package/dist/oauth/exports/client.js.map +0 -1
  299. package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
  300. package/dist/oauth/hooks/afterLogout.js.map +0 -1
  301. package/dist/oauth/hooks/me.d.ts.map +0 -1
  302. package/dist/oauth/hooks/me.js.map +0 -1
  303. package/dist/oauth/hooks/refresh.d.ts.map +0 -1
  304. package/dist/oauth/hooks/refresh.js.map +0 -1
  305. package/dist/oauth/index.d.ts.map +0 -1
  306. package/dist/oauth/index.js.map +0 -1
  307. package/dist/oauth/strategy/index.d.ts.map +0 -1
  308. package/dist/oauth/strategy/index.js.map +0 -1
  309. package/dist/oauth/types.d.ts.map +0 -1
  310. package/dist/oauth/types.js.map +0 -1
  311. package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
  312. package/dist/oauth/utilities/clearCookie.js.map +0 -1
  313. package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
  314. package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
  315. package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
  316. package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
  317. package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
  318. package/dist/oauth/utilities/extractOrigin.js.map +0 -1
  319. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
  320. package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
  321. package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
  322. package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
  323. package/dist/oauth/utilities/getAdminPath.js +0 -9
  324. package/dist/oauth/utilities/getAdminPath.js.map +0 -1
  325. package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
  326. package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
  327. package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
  328. package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
  329. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
  330. package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
  331. package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
  332. package/dist/oauth/utilities/getTokenExp.js.map +0 -1
  333. package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
  334. package/dist/oauth/utilities/getUsernameField.js.map +0 -1
  335. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
  336. package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
  337. package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
  338. package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
  339. package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
  340. package/dist/oauth/utilities/refreshTokens.js.map +0 -1
  341. package/dist/plugin/adapter.d.ts.map +0 -1
  342. package/dist/plugin/adapter.js.map +0 -1
  343. package/dist/plugin/build-config.d.ts.map +0 -1
  344. package/dist/plugin/build-config.js.map +0 -1
  345. package/dist/types/config.d.ts.map +0 -1
  346. package/dist/types/config.js.map +0 -1
  347. package/dist/types.d.ts.map +0 -1
  348. package/dist/types.js.map +0 -1
  349. package/dist/utils/asset-collection.d.ts.map +0 -1
  350. package/dist/utils/asset-collection.js.map +0 -1
  351. package/dist/utils/build-detection.d.ts.map +0 -1
  352. package/dist/utils/build-detection.js.map +0 -1
  353. package/dist/utils/config.d.ts.map +0 -1
  354. package/dist/utils/config.js.map +0 -1
  355. package/dist/utils/download-template.d.ts.map +0 -1
  356. package/dist/utils/download-template.js.map +0 -1
  357. package/dist/utils/env-management.d.ts.map +0 -1
  358. package/dist/utils/env-management.js.map +0 -1
  359. package/dist/utils/format.d.ts.map +0 -1
  360. package/dist/utils/format.js.map +0 -1
  361. package/dist/utils/formatter.d.ts.map +0 -1
  362. package/dist/utils/formatter.js.map +0 -1
  363. package/dist/utils/git.d.ts.map +0 -1
  364. package/dist/utils/git.js.map +0 -1
  365. package/dist/utils/is-debug.d.ts.map +0 -1
  366. package/dist/utils/is-debug.js.map +0 -1
  367. package/dist/utils/lambda-config.d.ts.map +0 -1
  368. package/dist/utils/lambda-config.js.map +0 -1
  369. package/dist/utils/log.d.ts.map +0 -1
  370. package/dist/utils/log.js.map +0 -1
  371. package/dist/utils/messages.d.ts.map +0 -1
  372. package/dist/utils/messages.js.map +0 -1
  373. package/dist/utils/package-manager.d.ts.map +0 -1
  374. package/dist/utils/package-manager.js.map +0 -1
  375. package/dist/utils/payload-config-ast.d.ts.map +0 -1
  376. package/dist/utils/payload-config-ast.js.map +0 -1
  377. package/dist/utils/payload-config-finder.d.ts.map +0 -1
  378. package/dist/utils/payload-config-finder.js.map +0 -1
  379. package/dist/utils/payload-config-modifier.d.ts.map +0 -1
  380. package/dist/utils/payload-config-modifier.js.map +0 -1
  381. package/dist/utils/payload-package-check.d.ts.map +0 -1
  382. package/dist/utils/payload-package-check.js.map +0 -1
  383. package/dist/utils/project.d.ts.map +0 -1
  384. package/dist/utils/project.js.map +0 -1
  385. package/dist/utils/s3-upload.d.ts.map +0 -1
  386. package/dist/utils/s3-upload.js.map +0 -1
  387. package/dist/utils/token-display.d.ts.map +0 -1
  388. package/dist/utils/token-display.js.map +0 -1
  389. package/dist/utils/typescript-validator.d.ts.map +0 -1
  390. package/dist/utils/typescript-validator.js.map +0 -1
@@ -3,7 +3,9 @@
3
3
  *
4
4
  * Client for Figma REST API (Pixie) endpoints
5
5
  * Handles project token generation and other CMS-related API calls
6
- */ import * as log from '../utils/log.js';
6
+ */ import { getAuthHeaders } from '../auth/credentials.js';
7
+ import { getEnvConfig } from '../constants.js';
8
+ import * as log from '../utils/log.js';
7
9
  /**
8
10
  * Error thrown when Figma API calls fail
9
11
  */ export class FigmaApiError extends Error {
@@ -14,19 +16,6 @@
14
16
  this.name = 'FigmaApiError';
15
17
  }
16
18
  }
17
- /**
18
- * Base URLs for Figma API
19
- */ const API_BASE_URLS = {
20
- prod: 'https://api.figma.com',
21
- staging: 'https://api.staging.figma.com'
22
- };
23
- /**
24
- * Get the Figma API base URL based on environment
25
- * TODO: Use this once real API endpoints are available
26
- */ function _getApiBaseUrl() {
27
- // For now, default to staging to match OAuth config
28
- return process.env.FIGMA_API_BASE_URL || API_BASE_URLS.staging;
29
- }
30
19
  /**
31
20
  * Get a project token (JWT) for a specific tenant/CMS
32
21
  *
@@ -40,14 +29,42 @@
40
29
  * @param tenantId - The tenant/CMS ID
41
30
  * @returns ProjectToken with JWT and expiry information
42
31
  * @throws {FigmaApiError} If the API call fails
43
- */ export async function getProjectToken(accessToken, tenantId) {
44
- // Check if project token API should be mocked
45
- // Default to true until real API is available
46
- const shouldMock = process.env.FIGMA_MOCK_PROJECT_TOKEN !== 'false';
32
+ */ export async function getProjectToken(credential, tenantId) {
33
+ // Priority 1: Check for direct token value from environment
34
+ const envTokenValue = process.env.FIGMA_MOCK_PROJECT_TOKEN_VALUE;
35
+ if (envTokenValue) {
36
+ log.debug('Using direct project token from FIGMA_MOCK_PROJECT_TOKEN_VALUE');
37
+ try {
38
+ // Parse JWT payload to extract claims
39
+ const parts = envTokenValue.split('.');
40
+ if (parts.length !== 3) {
41
+ throw new Error('Invalid JWT format: must have 3 parts (header.payload.signature)');
42
+ }
43
+ const payload = parts[1];
44
+ const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
45
+ const paddedBase64 = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');
46
+ const decodedPayload = JSON.parse(Buffer.from(paddedBase64, 'base64').toString('utf-8'));
47
+ if (!decodedPayload.exp || typeof decodedPayload.exp !== 'number') {
48
+ throw new Error('JWT payload missing exp claim');
49
+ }
50
+ // Extract tenant ID from aud claim (use parameter as fallback)
51
+ const extractedTenantId = decodedPayload.aud || tenantId;
52
+ return {
53
+ expiresAt: decodedPayload.exp * 1000,
54
+ tenantId: extractedTenantId,
55
+ token: envTokenValue
56
+ };
57
+ } catch (error) {
58
+ throw new FigmaApiError(`Invalid JWT token in FIGMA_MOCK_PROJECT_TOKEN_VALUE: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error instanceof Error ? error : undefined);
59
+ }
60
+ }
61
+ // Priority 2: Check if project token API should be mocked
62
+ // Default to false (use real API)
63
+ const shouldMock = process.env.FIGMA_MOCK_PROJECT_TOKEN === 'true';
47
64
  try {
48
65
  if (shouldMock) {
49
66
  // MOCK IMPLEMENTATION: Generate a mock JWT token for testing
50
- log.debug('Using mock project token API for getProjectToken (FIGMA_MOCK_PROJECT_TOKEN != "false")');
67
+ log.debug('Using mock project token API for getProjectToken (FIGMA_MOCK_PROJECT_TOKEN = "true")');
51
68
  const mockToken = createMockJWT(tenantId, 25) // 25 minutes expiry
52
69
  ;
53
70
  // Mock response data
@@ -68,12 +85,10 @@
68
85
  };
69
86
  }
70
87
  // REAL API IMPLEMENTATION
71
- const baseUrl = _getApiBaseUrl();
88
+ const baseUrl = getEnvConfig().apiBaseUrl;
72
89
  const url = `${baseUrl}/v1/cms/${tenantId}/token/`;
73
90
  const response = await fetch(url, {
74
- headers: {
75
- Authorization: `Bearer ${accessToken}`
76
- },
91
+ headers: getAuthHeaders(credential),
77
92
  method: 'POST'
78
93
  });
79
94
  if (!response.ok) {
@@ -81,12 +96,19 @@
81
96
  let errorMessage = `Failed to get project token: ${response.status} ${response.statusText}`;
82
97
  try {
83
98
  const errorBody = await response.json();
84
- if (errorBody.error || errorBody.message) {
85
- errorMessage = errorBody.error || errorBody.message;
99
+ // Only use string error messages (API may return { error: true })
100
+ if (typeof errorBody.message === 'string') {
101
+ errorMessage = errorBody.message;
102
+ } else if (typeof errorBody.error === 'string') {
103
+ errorMessage = errorBody.error;
86
104
  }
87
105
  } catch {
88
106
  // Ignore JSON parse errors for error body
89
107
  }
108
+ // Provide actionable error for common cases
109
+ if (response.status === 404) {
110
+ errorMessage = `Content System ID "${tenantId}" not found. Ensure FIGMA_CONTENT_API_CONTENT_SYSTEM_ID is set to a valid content system ID in your .env file.`;
111
+ }
90
112
  throw new FigmaApiError(errorMessage, response.status);
91
113
  }
92
114
  const data = await response.json();
@@ -165,5 +187,36 @@
165
187
  throw new FigmaApiError(`Failed to parse JWT expiry: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error instanceof Error ? error : undefined);
166
188
  }
167
189
  }
190
+ /**
191
+ * Get user info from Figma API
192
+ *
193
+ * Endpoint: GET https://api.figma.com/v1/me
194
+ * Requires OAuth access_token (not project token)
195
+ *
196
+ * @param accessToken - OAuth access token for authentication
197
+ * @returns FigmaUserInfo with user profile data
198
+ * @throws {FigmaApiError} If the API call fails
199
+ */ export async function getUserInfo(credential) {
200
+ const baseUrl = getEnvConfig().apiBaseUrl;
201
+ const url = `${baseUrl}/v1/me`;
202
+ try {
203
+ const response = await fetch(url, {
204
+ headers: getAuthHeaders(credential)
205
+ });
206
+ if (!response.ok) {
207
+ throw new FigmaApiError(`Failed to get user info: ${response.status} ${response.statusText}`, response.status);
208
+ }
209
+ const data = await response.json();
210
+ if (!data.id || !data.email || typeof data.handle !== 'string') {
211
+ throw new FigmaApiError('Invalid user info response: missing required fields');
212
+ }
213
+ return data;
214
+ } catch (error) {
215
+ if (error instanceof FigmaApiError) {
216
+ throw error;
217
+ }
218
+ throw new FigmaApiError(`Failed to get user info: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error instanceof Error ? error : undefined);
219
+ }
220
+ }
168
221
 
169
222
  //# sourceMappingURL=figma-api.js.map
@@ -7,6 +7,14 @@ export interface CallbackResult {
7
7
  /** State parameter for CSRF verification */
8
8
  state: string;
9
9
  }
10
+ export type CallbackServerOptions = {
11
+ /** Additional callback ports to try after port. */
12
+ fallbackPorts?: number[];
13
+ /** First callback port to try. Defaults to the configured callback port range. */
14
+ port?: number;
15
+ /** Callback timeout in milliseconds. */
16
+ timeoutMs?: number;
17
+ };
10
18
  /**
11
19
  * Error from OAuth callback
12
20
  */
@@ -20,18 +28,18 @@ export declare class CallbackError extends Error {
20
28
  * Starts a temporary server on localhost to receive the OAuth authorization code.
21
29
  * The server automatically shuts down after receiving the callback or on timeout.
22
30
  *
23
- * Implements dynamic port allocation: tries preferred port first, falls back to
24
- * OS-assigned port if unavailable.
31
+ * Tries the registered localhost callback ports in order. It does not use an
32
+ * OS-assigned random port because OAuth redirect URIs must be registered.
25
33
  */
26
34
  export declare class CallbackServer {
27
35
  private actualPort?;
28
- private preferredPort;
36
+ private callbackPorts;
37
+ private readyPromise;
38
+ private rejectReady?;
39
+ private resolveReady?;
29
40
  private server;
30
41
  private timeoutMs;
31
- constructor(options?: {
32
- port?: number;
33
- timeoutMs?: number;
34
- });
42
+ constructor(options?: CallbackServerOptions);
35
43
  /**
36
44
  * Render error page shown in browser when auth fails
37
45
  */
@@ -57,5 +65,9 @@ export declare class CallbackServer {
57
65
  * @throws CallbackError if callback fails or times out
58
66
  */
59
67
  waitForCallback(expectedState: string): Promise<CallbackResult>;
68
+ /**
69
+ * Wait until the callback server is listening.
70
+ */
71
+ waitUntilReady(): Promise<number>;
60
72
  }
61
73
  //# sourceMappingURL=callback-server.d.ts.map
@@ -2,6 +2,7 @@ import { readFileSync } from 'fs';
2
2
  import { createServer } from 'http';
3
3
  import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
+ import { DEFAULT_CALLBACK_PORT, DEFAULT_CALLBACK_PORTS } from '../config/oauth.js';
5
6
  const filename = fileURLToPath(import.meta.url);
6
7
  const dirname = path.dirname(filename);
7
8
  /**
@@ -19,17 +20,19 @@ const dirname = path.dirname(filename);
19
20
  * Starts a temporary server on localhost to receive the OAuth authorization code.
20
21
  * The server automatically shuts down after receiving the callback or on timeout.
21
22
  *
22
- * Implements dynamic port allocation: tries preferred port first, falls back to
23
- * OS-assigned port if unavailable.
23
+ * Tries the registered localhost callback ports in order. It does not use an
24
+ * OS-assigned random port because OAuth redirect URIs must be registered.
24
25
  */ export class CallbackServer {
25
26
  actualPort;
26
- preferredPort;
27
+ callbackPorts;
28
+ readyPromise = null;
29
+ rejectReady;
30
+ resolveReady;
27
31
  server = null;
28
32
  timeoutMs;
29
33
  constructor(options = {}){
30
- this.preferredPort = options.port || 3000;
34
+ this.callbackPorts = resolveCallbackPorts(options);
31
35
  this.timeoutMs = options.timeoutMs || 120000; // 2 minutes default
32
- this.server = createServer();
33
36
  }
34
37
  /**
35
38
  * Render error page shown in browser when auth fails
@@ -46,7 +49,7 @@ const dirname = path.dirname(filename);
46
49
  * Get the actual port the server is listening on
47
50
  * @returns Port number (may differ from preferred if that was in use)
48
51
  */ getActualPort() {
49
- return this.actualPort || this.preferredPort;
52
+ return this.actualPort || this.callbackPorts[0];
50
53
  }
51
54
  /**
52
55
  * Stop the server if running
@@ -64,6 +67,17 @@ const dirname = path.dirname(filename);
64
67
  * @throws CallbackError if callback fails or times out
65
68
  */ async waitForCallback(expectedState) {
66
69
  return new Promise((resolve, reject)=>{
70
+ if (this.server) {
71
+ reject(new CallbackError('Callback server is already running', 'server_error'));
72
+ return;
73
+ }
74
+ this.readyPromise = new Promise((resolveReady, rejectReady)=>{
75
+ this.resolveReady = resolveReady;
76
+ this.rejectReady = rejectReady;
77
+ });
78
+ this.readyPromise.catch(()=>{
79
+ // The caller may only await waitForCallback(); avoid an unhandled rejection.
80
+ });
67
81
  const cleanup = (handle)=>{
68
82
  clearTimeout(handle);
69
83
  if (this.server) {
@@ -76,8 +90,7 @@ const dirname = path.dirname(filename);
76
90
  cleanup(timeoutHandle);
77
91
  reject(new CallbackError('OAuth authorization timed out. Please try again.', 'timeout'));
78
92
  }, this.timeoutMs);
79
- // Create HTTP server
80
- this.server = createServer((req, res)=>{
93
+ const handleRequest = (req, res)=>{
81
94
  const url = new URL(req.url || '', `http://localhost:${this.getActualPort()}`);
82
95
  // Only handle /callback path
83
96
  if (url.pathname !== '/callback') {
@@ -133,36 +146,65 @@ const dirname = path.dirname(filename);
133
146
  code,
134
147
  state
135
148
  });
136
- });
137
- // Try to start server with dynamic port allocation
138
- const tryListen = (port, isRetry = false)=>{
139
- if (!this.server) {
140
- reject(new CallbackError('Server instance is not available', 'server_error'));
141
- return;
142
- }
143
- this.server.listen(port, '127.0.0.1', ()=>{
149
+ };
150
+ // Try registered callback ports in order.
151
+ const tryListen = (portIndex)=>{
152
+ const port = this.callbackPorts[portIndex];
153
+ const server = createServer(handleRequest);
154
+ this.server = server;
155
+ server.once('error', (err)=>{
156
+ if (this.server === server) {
157
+ this.server = null;
158
+ }
159
+ if (err.code === 'EADDRINUSE' && portIndex < this.callbackPorts.length - 1) {
160
+ tryListen(portIndex + 1);
161
+ return;
162
+ }
163
+ cleanup(timeoutHandle);
164
+ const callbackError = err.code === 'EADDRINUSE' ? new CallbackError(`OAuth callback ports are all in use: ${this.callbackPorts.join(', ')}. Close the process using one of these ports and run login again.`, 'ports_in_use') : new CallbackError(`Failed to start callback server: ${err.message}`, 'server_error');
165
+ this.rejectReady?.(callbackError);
166
+ reject(callbackError);
167
+ });
168
+ server.listen(port, '127.0.0.1', ()=>{
169
+ if (this.server !== server) {
170
+ return;
171
+ }
144
172
  // Capture the actual port that was assigned
145
- const addr = this.server.address();
173
+ const addr = server.address();
146
174
  if (addr && typeof addr === 'object') {
147
175
  this.actualPort = addr.port;
148
- }
149
- });
150
- // Handle server errors (port in use, etc)
151
- this.server.once('error', (err)=>{
152
- if (err.code === 'EADDRINUSE' && !isRetry) {
153
- // Port in use, try with OS-assigned port (0 = dynamic)
154
- this.server.removeAllListeners();
155
- tryListen(0, true);
156
- } else {
157
- cleanup(timeoutHandle);
158
- reject(new CallbackError(`Failed to start callback server: ${err.message}${!isRetry ? ' (tried fallback port)' : ''}`));
176
+ this.resolveReady?.(addr.port);
159
177
  }
160
178
  });
161
179
  };
162
- // Start with preferred port
163
- tryListen(this.preferredPort);
180
+ // Start with first configured port
181
+ tryListen(0);
164
182
  });
165
183
  }
184
+ /**
185
+ * Wait until the callback server is listening.
186
+ */ waitUntilReady() {
187
+ if (!this.readyPromise) {
188
+ return Promise.reject(new CallbackError('Callback server has not started', 'server_error'));
189
+ }
190
+ return this.readyPromise;
191
+ }
192
+ }
193
+ function resolveCallbackPorts(options) {
194
+ if (!options.port && !options.fallbackPorts) {
195
+ return DEFAULT_CALLBACK_PORTS;
196
+ }
197
+ const primaryPort = options.port || DEFAULT_CALLBACK_PORT;
198
+ const ports = uniquePorts([
199
+ primaryPort,
200
+ ...options.fallbackPorts || []
201
+ ]).slice(0, DEFAULT_CALLBACK_PORTS.length);
202
+ return ports.length > 0 ? ports : DEFAULT_CALLBACK_PORTS;
203
+ }
204
+ function uniquePorts(ports) {
205
+ return [
206
+ ...new Set(ports)
207
+ ];
166
208
  }
167
209
 
168
210
  //# sourceMappingURL=callback-server.js.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Auth Access Tokens types for CLI authentication
3
+ *
4
+ * Distinguishes between OAuth tokens (Authorization: Bearer) and
5
+ * Plan Access Tokens (X-Figma-Token header).
6
+ */
7
+ /**
8
+ * Represents an authenticated credential — either OAuth or PAT
9
+ */
10
+ export type AuthCredential = {
11
+ token: string;
12
+ type: 'oauth';
13
+ } | {
14
+ token: string;
15
+ type: 'plan_access_token';
16
+ };
17
+ /**
18
+ * Build the correct auth headers for a credential
19
+ */
20
+ export declare function getAuthHeaders(credential: AuthCredential): Record<string, string>;
21
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Auth Access Tokens types for CLI authentication
3
+ *
4
+ * Distinguishes between OAuth tokens (Authorization: Bearer) and
5
+ * Plan Access Tokens (X-Figma-Token header).
6
+ */ /**
7
+ * Represents an authenticated credential — either OAuth or PAT
8
+ */ /**
9
+ * Build the correct auth headers for a credential
10
+ */ export function getAuthHeaders(credential) {
11
+ if (credential.type === 'plan_access_token') {
12
+ return {
13
+ 'X-Figma-Token': credential.token
14
+ };
15
+ }
16
+ return {
17
+ Authorization: `Bearer ${credential.token}`
18
+ };
19
+ }
20
+
21
+ //# sourceMappingURL=credentials.js.map
@@ -30,4 +30,32 @@
30
30
  * @throws Error if unable to derive key due to missing machine information
31
31
  */
32
32
  export declare function deriveEncryptionKey(): string;
33
+ /**
34
+ * @deprecated Exists solely to read token stores written by older versions of
35
+ * this CLI that mixed `os.hostname()` into the encryption-key derivation. macOS
36
+ * rewrites the kernel hostname across DHCP/VPN/sleep events, which made those
37
+ * stores periodically un-decryptable. Used only by the transparent-migration
38
+ * path in `token-store.ts` and should be removed in a future release once
39
+ * upgraded clients are sufficiently common.
40
+ *
41
+ * @returns 64-character hex string (32-byte key) suitable for AES-256
42
+ */
43
+ export declare function deriveLegacyEncryptionKey(): string;
44
+ /**
45
+ * Get a short hash of the encryption key for diagnostics.
46
+ * Returns first 8 chars of SHA-256 hash — enough to compare across invocations
47
+ * without exposing the actual key.
48
+ */
49
+ export declare function getEncryptionKeyHash(): string;
50
+ /**
51
+ * Write decrypted versions of all encrypted store files for debugging.
52
+ *
53
+ * For each .json file in the store directory, creates a neighboring .decrypted.json
54
+ * file containing the decrypted contents. Useful for debugging token storage issues.
55
+ *
56
+ * @param rootDir - Root directory of the token store (e.g., ~/Library/Preferences/payloadcms-figma-nodejs)
57
+ * @param encryptionKey - The encryption key used by Conf
58
+ * @returns Array of paths to decrypted files created
59
+ */
60
+ export declare function exportDecryptedStoreFiles(rootDir: string, encryptionKey: string): string[];
33
61
  //# sourceMappingURL=crypto-utils.d.ts.map
@@ -1,11 +1,9 @@
1
1
  import Conf from 'conf';
2
2
  import crypto from 'crypto';
3
+ import envPaths from 'env-paths';
4
+ import fsSync from 'node:fs';
3
5
  import os from 'os';
4
- // Configuration store for cryptographic salt
5
- const cryptoConf = new Conf({
6
- configName: 'payloadcms-figma-crypto',
7
- projectName: 'payloadcms-figma'
8
- });
6
+ import path from 'path';
9
7
  /**
10
8
  * Get or generate a random salt for key derivation
11
9
  *
@@ -13,15 +11,56 @@ const cryptoConf = new Conf({
13
11
  * for future use. This ensures the encryption key is unique per machine and not
14
12
  * reproducible even if machine identifiers are known.
15
13
  *
14
+ * Uses an atomic create-or-read pattern (O_EXCL via `flag: 'wx'`) so concurrent
15
+ * callers — e.g. parallel vitest workers on a fresh CI container — converge on
16
+ * the same salt instead of clobbering each other's writes. Once the file
17
+ * exists, no caller ever overwrites it.
18
+ *
16
19
  * @returns 32-byte hex string (64 characters)
17
20
  */ function getOrCreateSalt() {
18
- let salt = cryptoConf.get('salt');
19
- if (!salt) {
20
- // Generate cryptographically secure random salt (32 bytes = 256 bits)
21
- salt = crypto.randomBytes(32).toString('hex');
22
- cryptoConf.set('salt', salt);
21
+ // Path mirrors what `Conf({ projectName: 'payloadcms-figma', configName:
22
+ // 'payloadcms-figma-crypto' })` would produce, so files written by older
23
+ // versions remain readable.
24
+ const configDir = envPaths('payloadcms-figma', {
25
+ suffix: 'nodejs'
26
+ }).config;
27
+ const configPath = path.join(configDir, 'payloadcms-figma-crypto.json');
28
+ const readSalt = ()=>{
29
+ try {
30
+ const parsed = JSON.parse(fsSync.readFileSync(configPath, 'utf8'));
31
+ return typeof parsed.salt === 'string' && parsed.salt.length > 0 ? parsed.salt : undefined;
32
+ } catch (err) {
33
+ if (err.code === 'ENOENT') {
34
+ return undefined;
35
+ }
36
+ throw err;
37
+ }
38
+ };
39
+ const existing = readSalt();
40
+ if (existing) {
41
+ return existing;
42
+ }
43
+ fsSync.mkdirSync(configDir, {
44
+ recursive: true
45
+ });
46
+ const candidate = crypto.randomBytes(32).toString('hex');
47
+ try {
48
+ fsSync.writeFileSync(configPath, JSON.stringify({
49
+ salt: candidate
50
+ }, null, '\t'), {
51
+ flag: 'wx'
52
+ });
53
+ return candidate;
54
+ } catch (err) {
55
+ if (err.code !== 'EEXIST') {
56
+ throw err;
57
+ }
58
+ const winner = readSalt();
59
+ if (!winner) {
60
+ throw new Error('Failed to read salt after losing create-race');
61
+ }
62
+ return winner;
23
63
  }
24
- return salt;
25
64
  }
26
65
  /**
27
66
  * Gather machine-specific entropy sources
@@ -33,19 +72,12 @@ const cryptoConf = new Conf({
33
72
  * @throws Error if unable to gather sufficient entropy
34
73
  */ function gatherMachineEntropy() {
35
74
  try {
36
- const userInfo = os.userInfo();
37
- const networkInterfaces = os.networkInterfaces();
38
- // Get MAC address from first available network interface (if available)
39
- const macAddress = Object.values(networkInterfaces).flat().find((iface)=>iface && !iface.internal && iface.mac !== '00:00:00:00:00:00')?.mac;
40
75
  const entropy = [
41
- os.hostname(),
42
76
  os.homedir(),
43
- userInfo.username,
77
+ os.userInfo().username,
44
78
  os.platform(),
45
- os.arch(),
46
- macAddress
47
- ].filter(Boolean) // Remove any undefined values
48
- ;
79
+ os.arch()
80
+ ];
49
81
  if (entropy.length < 4) {
50
82
  throw new Error('Insufficient machine entropy available');
51
83
  }
@@ -92,5 +124,84 @@ const cryptoConf = new Conf({
92
124
  const key = crypto.pbkdf2Sync(machineId, salt, 100000, 32, 'sha256');
93
125
  return key.toString('hex');
94
126
  }
127
+ /**
128
+ * @deprecated Exists solely to read token stores written by older versions of
129
+ * this CLI that mixed `os.hostname()` into the encryption-key derivation. macOS
130
+ * rewrites the kernel hostname across DHCP/VPN/sleep events, which made those
131
+ * stores periodically un-decryptable. Used only by the transparent-migration
132
+ * path in `token-store.ts` and should be removed in a future release once
133
+ * upgraded clients are sufficiently common.
134
+ *
135
+ * @returns 64-character hex string (32-byte key) suitable for AES-256
136
+ */ export function deriveLegacyEncryptionKey() {
137
+ const entropy = [
138
+ os.hostname(),
139
+ os.homedir(),
140
+ os.userInfo().username,
141
+ os.platform(),
142
+ os.arch()
143
+ ];
144
+ const machineId = entropy.join('::');
145
+ const salt = getOrCreateSalt();
146
+ const key = crypto.pbkdf2Sync(machineId, salt, 100000, 32, 'sha256');
147
+ return key.toString('hex');
148
+ }
149
+ /**
150
+ * Get a short hash of the encryption key for diagnostics.
151
+ * Returns first 8 chars of SHA-256 hash — enough to compare across invocations
152
+ * without exposing the actual key.
153
+ */ export function getEncryptionKeyHash() {
154
+ const key = deriveEncryptionKey();
155
+ return crypto.createHash('sha256').update(key).digest('hex').substring(0, 8);
156
+ }
157
+ /**
158
+ * Write decrypted versions of all encrypted store files for debugging.
159
+ *
160
+ * For each .json file in the store directory, creates a neighboring .decrypted.json
161
+ * file containing the decrypted contents. Useful for debugging token storage issues.
162
+ *
163
+ * @param rootDir - Root directory of the token store (e.g., ~/Library/Preferences/payloadcms-figma-nodejs)
164
+ * @param encryptionKey - The encryption key used by Conf
165
+ * @returns Array of paths to decrypted files created
166
+ */ export function exportDecryptedStoreFiles(rootDir, encryptionKey) {
167
+ const decryptedFiles = [];
168
+ function processDirectory(dir) {
169
+ if (!fsSync.existsSync(dir)) {
170
+ return;
171
+ }
172
+ const entries = fsSync.readdirSync(dir, {
173
+ withFileTypes: true
174
+ });
175
+ for (const entry of entries){
176
+ const fullPath = path.join(dir, entry.name);
177
+ if (entry.isDirectory()) {
178
+ processDirectory(fullPath);
179
+ } else if (entry.name.endsWith('.json') && !entry.name.endsWith('.decrypted.json') && !entry.name.includes('.corrupt-')) {
180
+ try {
181
+ // Extract configName from filename (remove .json extension)
182
+ const configName = entry.name.replace(/\.json$/, '');
183
+ // Create a Conf instance to read/decrypt the file
184
+ const config = new Conf({
185
+ clearInvalidConfig: false,
186
+ configName,
187
+ cwd: dir,
188
+ encryptionKey,
189
+ projectName: 'payloadcms-figma'
190
+ });
191
+ // Read all data from the store (Conf decrypts it)
192
+ const data = config.store;
193
+ // Write decrypted content to neighboring file
194
+ const decryptedPath = fullPath.replace(/\.json$/, '.decrypted.json');
195
+ fsSync.writeFileSync(decryptedPath, JSON.stringify(data, null, 2));
196
+ decryptedFiles.push(decryptedPath);
197
+ } catch {
198
+ // Skip files that can't be decrypted (e.g., crypto config, already unencrypted)
199
+ }
200
+ }
201
+ }
202
+ }
203
+ processDirectory(rootDir);
204
+ return decryptedFiles;
205
+ }
95
206
 
96
207
  //# sourceMappingURL=crypto-utils.js.map
@@ -1,3 +1,4 @@
1
+ import type { Environment } from '../constants.js';
1
2
  import type { JWTPayload } from './types.js';
2
3
  /**
3
4
  * JWT validation error with specific error codes
@@ -27,7 +28,7 @@ export declare class JWTValidationError extends Error {
27
28
  * @returns Promise resolving to validated JWT payload
28
29
  * @throws {JWTValidationError} If validation fails
29
30
  */
30
- export declare function validateProjectToken(token: string, environment: 'production' | 'staging'): Promise<JWTPayload>;
31
+ export declare function validateProjectToken(token: string, environment: Environment): Promise<JWTPayload>;
31
32
  /**
32
33
  * Clear JWKS cache (useful for testing or forcing refresh)
33
34
  *
@@ -1,6 +1,6 @@
1
1
  import { createRemoteJWKSet, jwtVerify } from 'jose';
2
2
  import { JWKSMultipleMatchingKeys, JWKSNoMatchingKey, JWSInvalid, JWSSignatureVerificationFailed, JWTExpired } from 'jose/errors';
3
- import { getJWKSUri } from '../constants.js';
3
+ import { getEnvConfig } from '../constants.js';
4
4
  /**
5
5
  * JWT validation error with specific error codes
6
6
  */ export class JWTValidationError extends Error {
@@ -28,7 +28,7 @@ import { getJWKSUri } from '../constants.js';
28
28
  * @param environment - Figma environment ('production' or 'staging')
29
29
  * @returns JWKS resolver function
30
30
  */ function getJWKSResolver(environment) {
31
- const jwksUri = getJWKSUri(environment);
31
+ const jwksUri = getEnvConfig(environment).jwksUri;
32
32
  if (!jwksResolvers.has(jwksUri)) {
33
33
  jwksResolvers.set(jwksUri, createRemoteJWKSet(new URL(jwksUri), {
34
34
  cacheMaxAge: 24 * 60 * 60 * 1000,