@payloadcms/figma 0.0.1-alpha.8 → 0.1.0-alpha.0

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 (470) 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 +7574 -0
  64. package/dist/db-content-api/generated/content-api-types.js +5 -0
  65. package/dist/db-content-api/index.d.ts +37 -0
  66. package/dist/db-content-api/index.js +938 -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/data/applyDefaults.d.ts +6 -0
  78. package/dist/db-content-api/utilities/data/applyDefaults.js +75 -0
  79. package/dist/db-content-api/utilities/data/castFieldValue.d.ts +10 -0
  80. package/dist/db-content-api/utilities/data/castFieldValue.js +66 -0
  81. package/dist/db-content-api/utilities/data/index.d.ts +48 -0
  82. package/dist/db-content-api/utilities/data/index.js +299 -0
  83. package/dist/db-content-api/utilities/data/pointShape.d.ts +3 -0
  84. package/dist/db-content-api/utilities/data/pointShape.js +43 -0
  85. package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +11 -0
  86. package/dist/db-content-api/utilities/data/removeVirtualFields.js +52 -0
  87. package/dist/db-content-api/utilities/data/richTextShape.d.ts +3 -0
  88. package/dist/db-content-api/utilities/data/richTextShape.js +56 -0
  89. package/dist/db-content-api/utilities/data/stripFields.d.ts +47 -0
  90. package/dist/db-content-api/utilities/data/stripFields.js +170 -0
  91. package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +22 -0
  92. package/dist/db-content-api/utilities/data/transformPublishedLocale.js +40 -0
  93. package/dist/db-content-api/utilities/data/validateRelationships.d.ts +6 -0
  94. package/dist/db-content-api/utilities/data/validateRelationships.js +100 -0
  95. package/dist/db-content-api/utilities/joins.d.ts +52 -0
  96. package/dist/db-content-api/utilities/joins.js +137 -0
  97. package/dist/db-content-api/utilities/locale/index.d.ts +9 -0
  98. package/dist/db-content-api/utilities/locale/index.js +19 -0
  99. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts +10 -0
  100. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +71 -0
  101. package/dist/db-content-api/utilities/meta/buildMeta.d.ts +41 -0
  102. package/dist/db-content-api/utilities/meta/buildMeta.js +39 -0
  103. package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +16 -0
  104. package/dist/db-content-api/utilities/meta/buildPathTypes.js +243 -0
  105. package/dist/db-content-api/utilities/meta/buildUniquePaths.d.ts +12 -0
  106. package/dist/db-content-api/utilities/meta/buildUniquePaths.js +60 -0
  107. package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.d.ts +9 -0
  108. package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.js +100 -0
  109. package/dist/db-content-api/utilities/resolveBlocks.d.ts +19 -0
  110. package/dist/db-content-api/utilities/resolveBlocks.js +31 -0
  111. package/dist/db-content-api/utilities/schema/buildDocumentSchema.d.ts +55 -0
  112. package/dist/db-content-api/utilities/schema/buildDocumentSchema.js +182 -0
  113. package/dist/db-content-api/utilities/where.d.ts +19 -0
  114. package/dist/db-content-api/utilities/where.js +106 -0
  115. package/dist/deploy/schedule-extract-plugin.d.ts +10 -0
  116. package/dist/deploy/schedule-extract-plugin.js +32 -0
  117. package/dist/endpoints/health.d.ts +2 -0
  118. package/dist/endpoints/health.js +9 -0
  119. package/dist/endpoints/schema.d.ts +2 -0
  120. package/dist/endpoints/schema.js +27 -0
  121. package/dist/exports/client.d.ts +2 -1
  122. package/dist/exports/client.js +2 -2
  123. package/dist/index.d.ts +2 -2
  124. package/dist/index.js +3 -3
  125. package/dist/lib/download-skill.d.ts +12 -0
  126. package/dist/lib/download-skill.js +77 -0
  127. package/dist/oauth/components/FigmaAvatar/index.d.ts +3 -0
  128. package/dist/oauth/components/FigmaAvatar/index.js +25 -0
  129. package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
  130. package/dist/oauth/components/FigmaAvatarCell/index.d.ts +4 -0
  131. package/dist/oauth/components/FigmaAvatarCell/index.js +23 -0
  132. package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
  133. package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +8 -0
  134. package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +35 -0
  135. package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
  136. package/dist/oauth/components/LoginButton/iframeAutoLogin.d.ts +81 -0
  137. package/dist/oauth/components/LoginButton/iframeAutoLogin.js +168 -0
  138. package/dist/oauth/components/LoginButton/index.d.ts +0 -1
  139. package/dist/oauth/components/LoginButton/index.js +156 -18
  140. package/dist/oauth/components/LoginButton/index.scss +75 -3
  141. package/dist/oauth/components/LogoutButton/index.d.ts +0 -1
  142. package/dist/oauth/components/LogoutButton/index.js +20 -9
  143. package/dist/oauth/defaults.d.ts +3 -2
  144. package/dist/oauth/defaults.js +79 -12
  145. package/dist/oauth/endpoints/getLoginEndpoint.d.ts +0 -1
  146. package/dist/oauth/endpoints/getLoginEndpoint.js +87 -84
  147. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts +0 -1
  148. package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -6
  149. package/dist/oauth/endpoints/getMetaEndpoint.d.ts +0 -1
  150. package/dist/oauth/endpoints/getMetaEndpoint.js +18 -5
  151. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts +0 -1
  152. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js +11 -4
  153. package/dist/oauth/exports/client.d.ts +0 -1
  154. package/dist/oauth/exports/client.js +0 -2
  155. package/dist/oauth/hooks/afterLogout.d.ts +0 -1
  156. package/dist/oauth/hooks/afterLogout.js +0 -2
  157. package/dist/oauth/hooks/me.d.ts +0 -1
  158. package/dist/oauth/hooks/me.js +0 -2
  159. package/dist/oauth/hooks/refresh.d.ts +0 -1
  160. package/dist/oauth/hooks/refresh.js +2 -3
  161. package/dist/oauth/index.d.ts +0 -1
  162. package/dist/oauth/index.js +27 -7
  163. package/dist/oauth/strategy/index.d.ts +0 -3
  164. package/dist/oauth/strategy/index.js +55 -34
  165. package/dist/oauth/types.d.ts +23 -7
  166. package/dist/oauth/types.js +0 -2
  167. package/dist/oauth/utilities/buildUnauthorizedRedirect.d.ts +14 -0
  168. package/dist/oauth/utilities/buildUnauthorizedRedirect.js +28 -0
  169. package/dist/oauth/utilities/clearCookie.d.ts +0 -1
  170. package/dist/oauth/utilities/clearCookie.js +5 -3
  171. package/dist/oauth/utilities/createCookieOptions.d.ts +0 -1
  172. package/dist/oauth/utilities/createCookieOptions.js +9 -4
  173. package/dist/oauth/utilities/createDebugLogger.d.ts +0 -1
  174. package/dist/oauth/utilities/createDebugLogger.js +0 -2
  175. package/dist/oauth/utilities/establishSession.d.ts +22 -0
  176. package/dist/oauth/utilities/establishSession.js +80 -0
  177. package/dist/oauth/utilities/exchangeCodeForAccessToken.d.ts +23 -0
  178. package/dist/oauth/utilities/exchangeCodeForAccessToken.js +26 -0
  179. package/dist/oauth/utilities/extractOrigin.d.ts +0 -1
  180. package/dist/oauth/utilities/extractOrigin.js +0 -2
  181. package/dist/oauth/utilities/figmaHostnames.d.ts +2 -0
  182. package/dist/oauth/utilities/figmaHostnames.js +24 -0
  183. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts +0 -1
  184. package/dist/oauth/utilities/getAdminCollectionSlug.js +0 -2
  185. package/dist/oauth/utilities/getAuthorizeURL.d.ts +65 -2
  186. package/dist/oauth/utilities/getAuthorizeURL.js +57 -4
  187. package/dist/oauth/utilities/getCookieExpiration.d.ts +0 -1
  188. package/dist/oauth/utilities/getCookieExpiration.js +0 -2
  189. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts +0 -1
  190. package/dist/oauth/utilities/getSecondsFromTokenExp.js +0 -2
  191. package/dist/oauth/utilities/getTokenExp.d.ts +0 -1
  192. package/dist/oauth/utilities/getTokenExp.js +0 -2
  193. package/dist/oauth/utilities/getUsernameField.d.ts +0 -1
  194. package/dist/oauth/utilities/getUsernameField.js +0 -2
  195. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts +0 -1
  196. package/dist/oauth/utilities/hasUserTokenPropsChanged.js +0 -2
  197. package/dist/oauth/utilities/isAbsoluteURL.d.ts +1 -0
  198. package/dist/oauth/utilities/isAbsoluteURL.js +1 -0
  199. package/dist/oauth/utilities/isDuplicateKeyError.d.ts +6 -0
  200. package/dist/oauth/utilities/isDuplicateKeyError.js +12 -0
  201. package/dist/oauth/utilities/mergeHeaders.d.ts +0 -1
  202. package/dist/oauth/utilities/mergeHeaders.js +0 -2
  203. package/dist/oauth/utilities/refreshTokens.d.ts +0 -1
  204. package/dist/oauth/utilities/refreshTokens.js +21 -13
  205. package/dist/oauth/utilities/withPartitionedCookie.d.ts +19 -0
  206. package/dist/oauth/utilities/withPartitionedCookie.js +26 -0
  207. package/dist/oauth/utils/getSearchParam.d.ts +17 -0
  208. package/dist/oauth/utils/getSearchParam.js +22 -0
  209. package/dist/plugin/adapter.d.ts +0 -1
  210. package/dist/plugin/adapter.js +0 -2
  211. package/dist/plugin/auth-preflight.d.ts +7 -0
  212. package/dist/plugin/auth-preflight.js +18 -0
  213. package/dist/plugin/bootstrap-preflight.d.ts +22 -0
  214. package/dist/plugin/bootstrap-preflight.js +43 -0
  215. package/dist/plugin/build-config.d.ts +27 -15
  216. package/dist/plugin/build-config.js +381 -18
  217. package/dist/plugin/dev-cookie-names.d.ts +13 -0
  218. package/dist/plugin/dev-cookie-names.js +17 -0
  219. package/dist/scss.d.js +2 -0
  220. package/dist/storage-content-api/api-types.d.ts +183 -0
  221. package/dist/storage-content-api/api-types.js +4 -0
  222. package/dist/storage-content-api/client-uploads/generate.d.ts +14 -0
  223. package/dist/storage-content-api/client-uploads/generate.js +69 -0
  224. package/dist/storage-content-api/client.d.ts +5 -0
  225. package/dist/storage-content-api/client.js +37 -0
  226. package/dist/storage-content-api/generateURL.d.ts +6 -0
  227. package/dist/storage-content-api/generateURL.js +6 -0
  228. package/dist/storage-content-api/handleDelete.d.ts +7 -0
  229. package/dist/storage-content-api/handleDelete.js +15 -0
  230. package/dist/storage-content-api/handleUpload.d.ts +10 -0
  231. package/dist/storage-content-api/handleUpload.js +162 -0
  232. package/dist/storage-content-api/index.d.ts +4 -0
  233. package/dist/storage-content-api/index.js +37 -0
  234. package/dist/storage-content-api/staticHandler.d.ts +9 -0
  235. package/dist/storage-content-api/staticHandler.js +61 -0
  236. package/dist/storage-content-api/types.d.ts +9 -0
  237. package/dist/storage-content-api/types.js +1 -0
  238. package/dist/storage-content-api/utilities/getSafeFilename.d.ts +11 -0
  239. package/dist/storage-content-api/utilities/getSafeFilename.js +59 -0
  240. package/dist/storage-content-api/utilities/index.d.ts +2 -0
  241. package/dist/storage-content-api/utilities/index.js +2 -0
  242. package/dist/storage-content-api/utilities/parseUploadReference.d.ts +17 -0
  243. package/dist/storage-content-api/utilities/parseUploadReference.js +27 -0
  244. package/dist/templates/.env.example +5 -0
  245. package/dist/templates/README.md +19 -0
  246. package/dist/types/config.d.ts +2 -2
  247. package/dist/types/config.js +0 -4
  248. package/dist/types.d.ts +10 -2
  249. package/dist/types.js +0 -2
  250. package/dist/utils/adapters/nextjs.d.ts +8 -0
  251. package/dist/utils/adapters/nextjs.js +61 -0
  252. package/dist/utils/adapters/nitro.d.ts +8 -0
  253. package/dist/utils/adapters/nitro.js +172 -0
  254. package/dist/utils/adapters/vite.d.ts +9 -0
  255. package/dist/utils/adapters/vite.js +31 -0
  256. package/dist/utils/asset-collection.d.ts +27 -7
  257. package/dist/utils/asset-collection.js +59 -32
  258. package/dist/utils/build-detection.d.ts +5 -12
  259. package/dist/utils/build-detection.js +74 -13
  260. package/dist/utils/build-lambda-zip.d.ts +25 -0
  261. package/dist/utils/build-lambda-zip.js +90 -0
  262. package/dist/utils/cache-bootstrap.d.ts +7 -0
  263. package/dist/utils/cache-bootstrap.js +16 -0
  264. package/dist/utils/config.d.ts +0 -1
  265. package/dist/utils/config.js +1 -3
  266. package/dist/utils/deploy-adapter.d.ts +45 -0
  267. package/dist/utils/deploy-adapter.js +56 -0
  268. package/dist/utils/download-template.d.ts +9 -2
  269. package/dist/utils/download-template.js +24 -20
  270. package/dist/utils/env-management.d.ts +24 -8
  271. package/dist/utils/env-management.js +119 -66
  272. package/dist/utils/format-env-suffix.d.ts +11 -0
  273. package/dist/utils/format-env-suffix.js +11 -0
  274. package/dist/utils/format.d.ts +0 -1
  275. package/dist/utils/format.js +0 -2
  276. package/dist/utils/formatter.d.ts +0 -1
  277. package/dist/utils/formatter.js +23 -13
  278. package/dist/utils/fs-utils.d.ts +12 -0
  279. package/dist/utils/fs-utils.js +55 -0
  280. package/dist/utils/git.d.ts +0 -1
  281. package/dist/utils/git.js +0 -2
  282. package/dist/utils/handle-upgrade.d.ts +8 -0
  283. package/dist/utils/handle-upgrade.js +39 -0
  284. package/dist/utils/is-debug.d.ts +0 -1
  285. package/dist/utils/is-debug.js +0 -2
  286. package/dist/utils/lambda-config.d.ts +3 -2
  287. package/dist/utils/lambda-config.js +75 -80
  288. package/dist/utils/load-payload-config.d.ts +9 -0
  289. package/dist/utils/load-payload-config.js +27 -0
  290. package/dist/utils/log.d.ts +0 -1
  291. package/dist/utils/log.js +0 -2
  292. package/dist/utils/messages.d.ts +1 -3
  293. package/dist/utils/messages.js +47 -13
  294. package/dist/utils/package-manager.d.ts +24 -1
  295. package/dist/utils/package-manager.js +53 -2
  296. package/dist/utils/parse-template-spec.d.ts +11 -0
  297. package/dist/utils/parse-template-spec.js +60 -0
  298. package/dist/utils/payload-config-ast.d.ts +27 -7
  299. package/dist/utils/payload-config-ast.js +106 -60
  300. package/dist/utils/payload-config-finder.d.ts +2 -3
  301. package/dist/utils/payload-config-finder.js +48 -11
  302. package/dist/utils/payload-config-modifier.d.ts +1 -2
  303. package/dist/utils/payload-config-modifier.js +114 -68
  304. package/dist/utils/payload-package-check.d.ts +28 -3
  305. package/dist/utils/payload-package-check.js +90 -31
  306. package/dist/utils/project.d.ts +8 -4
  307. package/dist/utils/project.js +63 -37
  308. package/dist/utils/resolve-environment.d.ts +13 -0
  309. package/dist/utils/resolve-environment.js +29 -0
  310. package/dist/utils/s3-upload.d.ts +7 -3
  311. package/dist/utils/s3-upload.js +44 -9
  312. package/dist/utils/token-display.d.ts +5 -2
  313. package/dist/utils/token-display.js +49 -24
  314. package/dist/utils/typescript-validator.d.ts +0 -1
  315. package/dist/utils/typescript-validator.js +4 -8
  316. package/dist/utils/version-check.d.ts +2 -0
  317. package/dist/utils/version-check.js +43 -0
  318. package/package.json +47 -16
  319. package/dist/api/control-plane.d.ts.map +0 -1
  320. package/dist/api/control-plane.js.map +0 -1
  321. package/dist/api/figma-api.d.ts.map +0 -1
  322. package/dist/api/figma-api.js.map +0 -1
  323. package/dist/auth/browser.d.ts.map +0 -1
  324. package/dist/auth/browser.js.map +0 -1
  325. package/dist/auth/callback-server.d.ts.map +0 -1
  326. package/dist/auth/callback-server.js.map +0 -1
  327. package/dist/auth/crypto-utils.d.ts.map +0 -1
  328. package/dist/auth/crypto-utils.js.map +0 -1
  329. package/dist/auth/jwt-validator.d.ts.map +0 -1
  330. package/dist/auth/jwt-validator.js.map +0 -1
  331. package/dist/auth/oauth-flow.d.ts.map +0 -1
  332. package/dist/auth/oauth-flow.js.map +0 -1
  333. package/dist/auth/pkce.d.ts.map +0 -1
  334. package/dist/auth/pkce.js.map +0 -1
  335. package/dist/auth/project-token.d.ts.map +0 -1
  336. package/dist/auth/project-token.js.map +0 -1
  337. package/dist/auth/refresh.d.ts.map +0 -1
  338. package/dist/auth/refresh.js.map +0 -1
  339. package/dist/auth/token-store.d.ts.map +0 -1
  340. package/dist/auth/token-store.js.map +0 -1
  341. package/dist/auth/types.d.ts.map +0 -1
  342. package/dist/auth/types.js.map +0 -1
  343. package/dist/cli.d.ts.map +0 -1
  344. package/dist/cli.js.map +0 -1
  345. package/dist/commands/deploy.d.ts.map +0 -1
  346. package/dist/commands/deploy.js.map +0 -1
  347. package/dist/commands/init.d.ts.map +0 -1
  348. package/dist/commands/init.js.map +0 -1
  349. package/dist/commands/list-tokens.d.ts.map +0 -1
  350. package/dist/commands/list-tokens.js.map +0 -1
  351. package/dist/commands/login.d.ts.map +0 -1
  352. package/dist/commands/login.js.map +0 -1
  353. package/dist/commands/logout.d.ts.map +0 -1
  354. package/dist/commands/logout.js.map +0 -1
  355. package/dist/config/oauth.d.ts.map +0 -1
  356. package/dist/config/oauth.js.map +0 -1
  357. package/dist/constants.d.ts.map +0 -1
  358. package/dist/constants.js.map +0 -1
  359. package/dist/exports/client.d.ts.map +0 -1
  360. package/dist/exports/client.js.map +0 -1
  361. package/dist/index.d.ts.map +0 -1
  362. package/dist/index.js.map +0 -1
  363. package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
  364. package/dist/oauth/components/LoginButton/index.js.map +0 -1
  365. package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
  366. package/dist/oauth/components/LogoutButton/index.js.map +0 -1
  367. package/dist/oauth/defaults.d.ts.map +0 -1
  368. package/dist/oauth/defaults.js.map +0 -1
  369. package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
  370. package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
  371. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
  372. package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
  373. package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
  374. package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
  375. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
  376. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
  377. package/dist/oauth/exports/client.d.ts.map +0 -1
  378. package/dist/oauth/exports/client.js.map +0 -1
  379. package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
  380. package/dist/oauth/hooks/afterLogout.js.map +0 -1
  381. package/dist/oauth/hooks/me.d.ts.map +0 -1
  382. package/dist/oauth/hooks/me.js.map +0 -1
  383. package/dist/oauth/hooks/refresh.d.ts.map +0 -1
  384. package/dist/oauth/hooks/refresh.js.map +0 -1
  385. package/dist/oauth/index.d.ts.map +0 -1
  386. package/dist/oauth/index.js.map +0 -1
  387. package/dist/oauth/strategy/index.d.ts.map +0 -1
  388. package/dist/oauth/strategy/index.js.map +0 -1
  389. package/dist/oauth/types.d.ts.map +0 -1
  390. package/dist/oauth/types.js.map +0 -1
  391. package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
  392. package/dist/oauth/utilities/clearCookie.js.map +0 -1
  393. package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
  394. package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
  395. package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
  396. package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
  397. package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
  398. package/dist/oauth/utilities/extractOrigin.js.map +0 -1
  399. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
  400. package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
  401. package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
  402. package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
  403. package/dist/oauth/utilities/getAdminPath.js +0 -9
  404. package/dist/oauth/utilities/getAdminPath.js.map +0 -1
  405. package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
  406. package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
  407. package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
  408. package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
  409. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
  410. package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
  411. package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
  412. package/dist/oauth/utilities/getTokenExp.js.map +0 -1
  413. package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
  414. package/dist/oauth/utilities/getUsernameField.js.map +0 -1
  415. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
  416. package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
  417. package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
  418. package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
  419. package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
  420. package/dist/oauth/utilities/refreshTokens.js.map +0 -1
  421. package/dist/plugin/adapter.d.ts.map +0 -1
  422. package/dist/plugin/adapter.js.map +0 -1
  423. package/dist/plugin/build-config.d.ts.map +0 -1
  424. package/dist/plugin/build-config.js.map +0 -1
  425. package/dist/types/config.d.ts.map +0 -1
  426. package/dist/types/config.js.map +0 -1
  427. package/dist/types.d.ts.map +0 -1
  428. package/dist/types.js.map +0 -1
  429. package/dist/utils/asset-collection.d.ts.map +0 -1
  430. package/dist/utils/asset-collection.js.map +0 -1
  431. package/dist/utils/build-detection.d.ts.map +0 -1
  432. package/dist/utils/build-detection.js.map +0 -1
  433. package/dist/utils/config.d.ts.map +0 -1
  434. package/dist/utils/config.js.map +0 -1
  435. package/dist/utils/download-template.d.ts.map +0 -1
  436. package/dist/utils/download-template.js.map +0 -1
  437. package/dist/utils/env-management.d.ts.map +0 -1
  438. package/dist/utils/env-management.js.map +0 -1
  439. package/dist/utils/format.d.ts.map +0 -1
  440. package/dist/utils/format.js.map +0 -1
  441. package/dist/utils/formatter.d.ts.map +0 -1
  442. package/dist/utils/formatter.js.map +0 -1
  443. package/dist/utils/git.d.ts.map +0 -1
  444. package/dist/utils/git.js.map +0 -1
  445. package/dist/utils/is-debug.d.ts.map +0 -1
  446. package/dist/utils/is-debug.js.map +0 -1
  447. package/dist/utils/lambda-config.d.ts.map +0 -1
  448. package/dist/utils/lambda-config.js.map +0 -1
  449. package/dist/utils/log.d.ts.map +0 -1
  450. package/dist/utils/log.js.map +0 -1
  451. package/dist/utils/messages.d.ts.map +0 -1
  452. package/dist/utils/messages.js.map +0 -1
  453. package/dist/utils/package-manager.d.ts.map +0 -1
  454. package/dist/utils/package-manager.js.map +0 -1
  455. package/dist/utils/payload-config-ast.d.ts.map +0 -1
  456. package/dist/utils/payload-config-ast.js.map +0 -1
  457. package/dist/utils/payload-config-finder.d.ts.map +0 -1
  458. package/dist/utils/payload-config-finder.js.map +0 -1
  459. package/dist/utils/payload-config-modifier.d.ts.map +0 -1
  460. package/dist/utils/payload-config-modifier.js.map +0 -1
  461. package/dist/utils/payload-package-check.d.ts.map +0 -1
  462. package/dist/utils/payload-package-check.js.map +0 -1
  463. package/dist/utils/project.d.ts.map +0 -1
  464. package/dist/utils/project.js.map +0 -1
  465. package/dist/utils/s3-upload.d.ts.map +0 -1
  466. package/dist/utils/s3-upload.js.map +0 -1
  467. package/dist/utils/token-display.d.ts.map +0 -1
  468. package/dist/utils/token-display.js.map +0 -1
  469. package/dist/utils/typescript-validator.d.ts.map +0 -1
  470. package/dist/utils/typescript-validator.js.map +0 -1
@@ -0,0 +1,170 @@
1
+ import { fieldShouldBeLocalized } from 'payload/shared';
2
+ import { resolveFlattenedBlock } from '../resolveBlocks.js';
3
+ /**
4
+ * Strips fields from data that are not defined in the schema or are invalid.
5
+ *
6
+ * This function was copied from the MongoDB adapter's implementation:
7
+ * @see packages/db-mongodb/src/utilities/transform.ts (stripFields function)
8
+ *
9
+ * @description
10
+ * This utility performs deep sanitization of document data by:
11
+ * 1. **Removing undefined fields**: Strips any field not present in the collection's schema
12
+ * (e.g., sensitive fields like `password`, `apiKey`, or any extra fields not in config)
13
+ * 2. **Removing invalid locales**: Deletes locale keys that don't exist in `config.localization.localeCodes`
14
+ * (e.g., if data contains `{ "es-MX": "..." }` but only `"en"` is configured)
15
+ * 3. **Removing invalid blocks**: Filters out blocks with unknown `blockType` values
16
+ * (prevents data corruption from blocks that don't exist in the schema)
17
+ * 4. **Recursive sanitization**: Processes nested structures (arrays, groups, blocks, localized fields)
18
+ * to ensure deep data integrity
19
+ *
20
+ * @remarks
21
+ * Unlike MongoDB's adapter which uses Mongoose schemas with `strict: true` (rejecting extra fields
22
+ * on write), Content API uses flexible JSONB storage that accepts any fields. Therefore, this
23
+ * function is called on **both read and write operations** to ensure data consistency.
24
+ *
25
+ * The MongoDB adapter also supports an `allowAdditionalKeys` option that allows reading/writing
26
+ * fields not in the schema. For now, Content API does not support this feature - we always
27
+ * sanitize data. If users request this functionality in the future, we can consider adding it.
28
+ *
29
+ * @todo
30
+ * 1. Consider moving this utility to `payload/shared` so both MongoDB and Content API adapters
31
+ * can use the same implementation, reducing code duplication and maintenance burden.
32
+ *
33
+ * 2. Performance optimization: This function iterates through all fields recursively.
34
+ * The `dataToContentAPI` and `dataFromContentAPI` functions in
35
+ * `packages/figma/src/db-content-api/utilities/data.ts` also iterate through fields
36
+ * to transform richText (object ↔ JSON string), custom IDs (number ↔ string), and dates.
37
+ * Consider combining both traversals into a single abstraction to avoid iterating twice.
38
+ *
39
+ * 3. Feature parity: MongoDB adapter has `allowAdditionalKeys` option. We currently always
40
+ * strip additional keys, but could add this as a configurable option if users need it.
41
+ */ export const stripFields = ({ config, data, fields, parentIsLocalized = false, reservedKeys = [] })=>{
42
+ for(const k in data){
43
+ if (!fields.some((field)=>field.name === k) && !reservedKeys.includes(k)) {
44
+ delete data[k];
45
+ }
46
+ }
47
+ for (const field of fields){
48
+ reservedKeys = [];
49
+ const fieldData = data[field.name];
50
+ if (!fieldData || typeof fieldData !== 'object') {
51
+ continue;
52
+ }
53
+ const shouldLocalizeField = fieldShouldBeLocalized({
54
+ field,
55
+ parentIsLocalized
56
+ });
57
+ if (field.type === 'blocks') {
58
+ reservedKeys.push('blockType');
59
+ }
60
+ if ('flattenedFields' in field || 'blocks' in field) {
61
+ if (shouldLocalizeField && config.localization) {
62
+ for(const localeKey in fieldData){
63
+ if (!config.localization.localeCodes.some((code)=>code === localeKey)) {
64
+ delete fieldData[localeKey];
65
+ continue;
66
+ }
67
+ const localeData = fieldData[localeKey];
68
+ if (!localeData || typeof localeData !== 'object') {
69
+ continue;
70
+ }
71
+ if (field.type === 'array' || field.type === 'blocks') {
72
+ if (!Array.isArray(localeData)) {
73
+ continue;
74
+ }
75
+ let hasNull = false;
76
+ for(let i = 0; i < localeData.length; i++){
77
+ const data = localeData[i];
78
+ let fields = null;
79
+ if (field.type === 'array') {
80
+ fields = field.flattenedFields;
81
+ } else {
82
+ const maybeBlock = resolveFlattenedBlock({
83
+ blocks: field.blocks,
84
+ blockType: data.blockType,
85
+ configBlocks: config.blocks
86
+ });
87
+ if (maybeBlock) {
88
+ fields = maybeBlock.flattenedFields;
89
+ } else {
90
+ localeData[i] = null;
91
+ hasNull = true;
92
+ }
93
+ }
94
+ if (!fields) {
95
+ continue;
96
+ }
97
+ stripFields({
98
+ config,
99
+ data,
100
+ fields,
101
+ parentIsLocalized: parentIsLocalized || field.localized,
102
+ reservedKeys
103
+ });
104
+ }
105
+ if (hasNull) {
106
+ fieldData[localeKey] = localeData.filter(Boolean);
107
+ }
108
+ continue;
109
+ } else {
110
+ stripFields({
111
+ config,
112
+ data: localeData,
113
+ fields: field.flattenedFields,
114
+ parentIsLocalized: parentIsLocalized || field.localized,
115
+ reservedKeys
116
+ });
117
+ }
118
+ }
119
+ continue;
120
+ }
121
+ if (field.type === 'array' || field.type === 'blocks') {
122
+ if (!Array.isArray(fieldData)) {
123
+ continue;
124
+ }
125
+ let hasNull = false;
126
+ for(let i = 0; i < fieldData.length; i++){
127
+ const data = fieldData[i];
128
+ let fields = null;
129
+ if (field.type === 'array') {
130
+ fields = field.flattenedFields;
131
+ } else {
132
+ const maybeBlock = resolveFlattenedBlock({
133
+ blocks: field.blocks,
134
+ blockType: data.blockType,
135
+ configBlocks: config.blocks
136
+ });
137
+ if (maybeBlock) {
138
+ fields = maybeBlock.flattenedFields;
139
+ } else {
140
+ fieldData[i] = null;
141
+ hasNull = true;
142
+ }
143
+ }
144
+ if (!fields) {
145
+ continue;
146
+ }
147
+ stripFields({
148
+ config,
149
+ data,
150
+ fields,
151
+ parentIsLocalized: parentIsLocalized || field.localized,
152
+ reservedKeys
153
+ });
154
+ }
155
+ if (hasNull) {
156
+ data[field.name] = fieldData.filter(Boolean);
157
+ }
158
+ continue;
159
+ } else {
160
+ stripFields({
161
+ config,
162
+ data: fieldData,
163
+ fields: field.flattenedFields,
164
+ parentIsLocalized: parentIsLocalized || field.localized,
165
+ reservedKeys
166
+ });
167
+ }
168
+ }
169
+ }
170
+ };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Transform publishedLocale to localizeStatus format
3
+ *
4
+ * publishedLocale is a legacy API that is going to be removed in Payload v4 in favor of localizeStatus.
5
+ * The db-adapter transforms publishedLocale here so Content API doesn't need to know about it.
6
+ */
7
+ type VersionData = Record<string, unknown>;
8
+ /**
9
+ * Transforms version data to use localizeStatus format
10
+ *
11
+ * If `publishedLocale` is provided and `_status` is a string, transforms to object format.
12
+ * If `_status` is already an object, leaves it unchanged.
13
+ *
14
+ * @example
15
+ * // Input (old format):
16
+ * { _status: 'published', text: 'Hello' }, publishedLocale: 'en'
17
+ *
18
+ * // Output (new format):
19
+ * { _status: { en: 'published' }, text: 'Hello' }
20
+ */
21
+ export declare function transformToLocalizeStatus(versionData: VersionData, publishedLocale?: string): VersionData;
22
+ export {};
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Transform publishedLocale to localizeStatus format
3
+ *
4
+ * publishedLocale is a legacy API that is going to be removed in Payload v4 in favor of localizeStatus.
5
+ * The db-adapter transforms publishedLocale here so Content API doesn't need to know about it.
6
+ */ /**
7
+ * Transforms version data to use localizeStatus format
8
+ *
9
+ * If `publishedLocale` is provided and `_status` is a string, transforms to object format.
10
+ * If `_status` is already an object, leaves it unchanged.
11
+ *
12
+ * @example
13
+ * // Input (old format):
14
+ * { _status: 'published', text: 'Hello' }, publishedLocale: 'en'
15
+ *
16
+ * // Output (new format):
17
+ * { _status: { en: 'published' }, text: 'Hello' }
18
+ */ export function transformToLocalizeStatus(versionData, publishedLocale) {
19
+ // No publishedLocale provided - no transformation needed
20
+ if (!publishedLocale) {
21
+ return versionData;
22
+ }
23
+ const status = versionData._status;
24
+ // If _status is already an object (localizeStatus format), return as-is
25
+ if (typeof status === 'object' && status !== null) {
26
+ return versionData;
27
+ }
28
+ // Transform: publishedLocale + string status → object status
29
+ if (typeof status === 'string') {
30
+ // Only the specified locale gets the status, others remain undefined
31
+ // (Content API / Payload will handle merging with existing locale statuses)
32
+ return {
33
+ ...versionData,
34
+ _status: {
35
+ [publishedLocale]: status
36
+ }
37
+ };
38
+ }
39
+ return versionData;
40
+ }
@@ -0,0 +1,6 @@
1
+ import type { Payload } from 'payload';
2
+ export declare function validateRelationshipIds({ collectionSlug, data, payload, }: {
3
+ collectionSlug: string;
4
+ data: Record<string, unknown>;
5
+ payload: Payload;
6
+ }): void;
@@ -0,0 +1,100 @@
1
+ import { traverseFields } from 'payload';
2
+ const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
3
+ function collectRelationshipValues({ data, fields }) {
4
+ const relationships = [];
5
+ const callback = ({ field, ref })=>{
6
+ if (!('name' in field) || !field.name) {
7
+ return;
8
+ }
9
+ if (field.type !== 'relationship' && field.type !== 'upload') {
10
+ return;
11
+ }
12
+ if (!ref || typeof ref !== 'object') {
13
+ return;
14
+ }
15
+ const rawValue = ref[field.name];
16
+ if (rawValue == null || rawValue === '') {
17
+ return;
18
+ }
19
+ // For localized fields, the value is a locale map (e.g. { en: "uuid", fr: "uuid" }).
20
+ // Iterate locale values instead of treating the map as an ID.
21
+ if ('localized' in field && field.localized) {
22
+ if (typeof rawValue === 'object' && !Array.isArray(rawValue)) {
23
+ for (const localeValue of Object.values(rawValue)){
24
+ if (localeValue != null && localeValue !== '') {
25
+ parseRelationshipValues(localeValue, field.relationTo, relationships);
26
+ }
27
+ }
28
+ }
29
+ return;
30
+ }
31
+ parseRelationshipValues(rawValue, field.relationTo, relationships);
32
+ };
33
+ traverseFields({
34
+ callback,
35
+ fields,
36
+ fillEmpty: false,
37
+ ref: data
38
+ });
39
+ return relationships;
40
+ }
41
+ function parseRelationshipValues(value, relationTo, relationships) {
42
+ if (Array.isArray(relationTo)) {
43
+ // Polymorphic (single or hasMany): value is { relationTo, value } or array of them
44
+ const values = Array.isArray(value) ? value : [
45
+ value
46
+ ];
47
+ for (const v of values){
48
+ if (v && typeof v === 'object' && 'relationTo' in v && 'value' in v) {
49
+ const obj = v;
50
+ if (obj.value != null && obj.value !== '') {
51
+ relationships.push({
52
+ collection: obj.relationTo,
53
+ value: obj.value
54
+ });
55
+ }
56
+ }
57
+ }
58
+ } else {
59
+ // Non-polymorphic (single or hasMany): value is a bare ID or array of IDs
60
+ const values = Array.isArray(value) ? value : [
61
+ value
62
+ ];
63
+ for (const v of values){
64
+ if (v != null && v !== '') {
65
+ relationships.push({
66
+ collection: relationTo,
67
+ value: v
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ function isValidId(value, customIDType) {
74
+ if (customIDType === 'number') {
75
+ const num = typeof value === 'number' ? value : typeof value === 'string' ? Number(value) : NaN;
76
+ return Number.isFinite(num);
77
+ }
78
+ if (customIDType === 'text') {
79
+ return typeof value === 'string' && value.length > 0;
80
+ }
81
+ return typeof value === 'string' && UUID_REGEX.test(value);
82
+ }
83
+ export function validateRelationshipIds({ collectionSlug, data, payload }) {
84
+ const isGlobal = collectionSlug.startsWith('_global-');
85
+ const actualSlug = isGlobal ? collectionSlug.substring(8) : collectionSlug;
86
+ const config = isGlobal ? payload.config.globals?.find((g)=>g.slug === actualSlug) : payload.config.collections.find((c)=>c.slug === actualSlug);
87
+ if (!config?.fields) {
88
+ return;
89
+ }
90
+ const relationships = collectRelationshipValues({
91
+ data,
92
+ fields: config.fields
93
+ });
94
+ for (const { collection, value } of relationships){
95
+ const customIDType = payload.collections?.[collection]?.customIDType;
96
+ if (!isValidId(value, customIDType)) {
97
+ throw new Error(`Invalid relationship ID "${String(value)}" for collection "${collection}". Expected ${customIDType === 'number' ? 'a number' : customIDType === 'text' ? 'a non-empty string' : 'a valid UUID'}.`);
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,52 @@
1
+ import type { JoinQuery, Payload } from 'payload';
2
+ import type { components } from '../generated/content-api-types.js';
3
+ type ContentAPIJoin = components['schemas']['JoinClause'][number];
4
+ /**
5
+ * Convert Payload's JoinQuery to Content API's join format.
6
+ *
7
+ * ## Content API Join Limitations
8
+ *
9
+ * The following Payload join features are NOT YET supported by Content API:
10
+ *
11
+ * 1. **hasMany relationships** - Content API's join uses `data#>'{path}'#>>'{}'` to extract
12
+ * a single ID. HasMany relationships store arrays `["id1", "id2"]` which can't match.
13
+ *
14
+ * 2. **Array field relationships** - `on: 'array.category'` expects iteration over array
15
+ * elements, but Content API treats the path as a single JSONB extraction.
16
+ *
17
+ * 3. **Polymorphic relationships** - Stored as `{ relationTo, value }` objects, but
18
+ * Content API expects a simple ID string.
19
+ *
20
+ * Note: "Where querying through joins" (e.g., `where: { 'relatedPosts.title': { equals: 'x' } }`)
21
+ * is a separate Payload feature that filters documents based on joined data. This is NOT
22
+ * a join feature but a where clause feature, and would need separate Content API support.
23
+ *
24
+ * Payload's JoinQuery format (at runtime):
25
+ * {
26
+ * 'group.relatedPosts': { // joinPath - where results go in the document
27
+ * sort: '-title',
28
+ * limit: 10,
29
+ * page: 2, // page-based pagination
30
+ * where: { ... }, // Payload where format
31
+ * count: true
32
+ * }
33
+ * }
34
+ *
35
+ * Content API's join format:
36
+ * [{
37
+ * collectionId: 'posts', // collection to join FROM
38
+ * on: 'group.category', // field in joined collection pointing to this doc
39
+ * path: 'group.relatedPosts', // where to put results
40
+ * count: false,
41
+ * where: { ... }, // Content API where format
42
+ * sort: '-title',
43
+ * limit: 10,
44
+ * page: 2
45
+ * }]
46
+ *
47
+ * The mapping requires the collection config to resolve:
48
+ * - Which collection each join field refers to
49
+ * - What the 'on' field is for each join
50
+ */
51
+ export declare function convertPayloadJoinsToContentAPI(payload: Payload, collectionSlug: string, joins: false | JoinQuery | undefined, locale?: string): ContentAPIJoin[] | undefined;
52
+ export {};
@@ -0,0 +1,137 @@
1
+ import { addFallbackSort } from '../temp-utilities/sorting.js';
2
+ import { convertPayloadWhereToContentAPI } from './where.js';
3
+ /**
4
+ * Convert Payload's JoinQuery to Content API's join format.
5
+ *
6
+ * ## Content API Join Limitations
7
+ *
8
+ * The following Payload join features are NOT YET supported by Content API:
9
+ *
10
+ * 1. **hasMany relationships** - Content API's join uses `data#>'{path}'#>>'{}'` to extract
11
+ * a single ID. HasMany relationships store arrays `["id1", "id2"]` which can't match.
12
+ *
13
+ * 2. **Array field relationships** - `on: 'array.category'` expects iteration over array
14
+ * elements, but Content API treats the path as a single JSONB extraction.
15
+ *
16
+ * 3. **Polymorphic relationships** - Stored as `{ relationTo, value }` objects, but
17
+ * Content API expects a simple ID string.
18
+ *
19
+ * Note: "Where querying through joins" (e.g., `where: { 'relatedPosts.title': { equals: 'x' } }`)
20
+ * is a separate Payload feature that filters documents based on joined data. This is NOT
21
+ * a join feature but a where clause feature, and would need separate Content API support.
22
+ *
23
+ * Payload's JoinQuery format (at runtime):
24
+ * {
25
+ * 'group.relatedPosts': { // joinPath - where results go in the document
26
+ * sort: '-title',
27
+ * limit: 10,
28
+ * page: 2, // page-based pagination
29
+ * where: { ... }, // Payload where format
30
+ * count: true
31
+ * }
32
+ * }
33
+ *
34
+ * Content API's join format:
35
+ * [{
36
+ * collectionId: 'posts', // collection to join FROM
37
+ * on: 'group.category', // field in joined collection pointing to this doc
38
+ * path: 'group.relatedPosts', // where to put results
39
+ * count: false,
40
+ * where: { ... }, // Content API where format
41
+ * sort: '-title',
42
+ * limit: 10,
43
+ * page: 2
44
+ * }]
45
+ *
46
+ * The mapping requires the collection config to resolve:
47
+ * - Which collection each join field refers to
48
+ * - What the 'on' field is for each join
49
+ */ export function convertPayloadJoinsToContentAPI(payload, collectionSlug, joins, locale) {
50
+ const collectionConfig = payload.config.collections.find((c)=>c.slug === collectionSlug);
51
+ if (!collectionConfig) {
52
+ return undefined;
53
+ }
54
+ // joins === false means explicitly disable all joins
55
+ // joins === undefined means use defaults (no custom query params)
56
+ if (joins === false || !joins) {
57
+ return undefined;
58
+ }
59
+ const result = [];
60
+ // Iterate through all join paths in the query
61
+ for (const [joinPath, joinQueryValue] of Object.entries(joins)){
62
+ // joinQuery === false means skip this specific join
63
+ if (joinQueryValue === false) {
64
+ continue;
65
+ }
66
+ // Normalize undefined/empty to empty object
67
+ const joinQuery = joinQueryValue ?? {};
68
+ // Find the SanitizedJoin config for this joinPath
69
+ // SanitizedJoins is indexed by the collection being joined FROM
70
+ let foundJoin;
71
+ // Search through all collections in the joins config
72
+ for (const [collectionSlug, sanitizedJoins] of Object.entries(collectionConfig.joins)){
73
+ for (const sanitizedJoin of sanitizedJoins){
74
+ if (sanitizedJoin.joinPath === joinPath) {
75
+ const on = locale && sanitizedJoin.getForeignPath ? sanitizedJoin.getForeignPath({
76
+ locale
77
+ }) : sanitizedJoin.field.on;
78
+ foundJoin = {
79
+ collectionSlug,
80
+ defaultLimit: sanitizedJoin.field.defaultLimit,
81
+ defaultSort: sanitizedJoin.field.defaultSort,
82
+ on
83
+ };
84
+ break;
85
+ }
86
+ }
87
+ if (foundJoin) {
88
+ break;
89
+ }
90
+ }
91
+ // Also check polymorphic joins
92
+ if (!foundJoin) {
93
+ for (const sanitizedJoin of collectionConfig.polymorphicJoins){
94
+ if (sanitizedJoin.joinPath === joinPath) {
95
+ const collections = sanitizedJoin.field.collection;
96
+ const on = locale && sanitizedJoin.getForeignPath ? sanitizedJoin.getForeignPath({
97
+ locale
98
+ }) : sanitizedJoin.field.on;
99
+ foundJoin = {
100
+ collectionSlug: collections,
101
+ defaultSort: sanitizedJoin.field.defaultSort,
102
+ on
103
+ };
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ if (!foundJoin) {
109
+ payload.logger.warn(`Join path '${joinPath}' not found in collection config for '${collectionConfig.slug}'`);
110
+ continue;
111
+ }
112
+ // Fall back to the default limit if not specified in the query
113
+ const effectiveLimit = joinQuery.limit ?? foundJoin.defaultLimit;
114
+ // Add fallback sort for the joined collection
115
+ const sortWithFallback = addFallbackSort(joinQuery.sort, payload, foundJoin.collectionSlug, foundJoin.defaultSort);
116
+ const contentAPIJoin = {
117
+ collectionId: foundJoin.collectionSlug,
118
+ count: joinQuery.count ?? false,
119
+ on: foundJoin.on,
120
+ path: joinPath,
121
+ ...effectiveLimit !== undefined && {
122
+ limit: effectiveLimit
123
+ },
124
+ ...joinQuery.page && {
125
+ page: joinQuery.page
126
+ },
127
+ ...sortWithFallback && {
128
+ sort: sortWithFallback
129
+ },
130
+ ...joinQuery.where && {
131
+ where: convertPayloadWhereToContentAPI(joinQuery.where)
132
+ }
133
+ };
134
+ result.push(contentAPIJoin);
135
+ }
136
+ return result.length > 0 ? result : undefined;
137
+ }
@@ -0,0 +1,9 @@
1
+ import type { Payload } from 'payload';
2
+ /**
3
+ * Determines what locale to send to Content API based on request locale value
4
+ * and config's defaultLocale.
5
+ *
6
+ * If no locale is provided, falls back to the default locale from config.
7
+ * Returns undefined for 'all' and '*' (special Payload values for returning all locales).
8
+ */
9
+ export declare function addFallbackLocale(locale: null | string | undefined, payload: Payload): string | undefined;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Determines what locale to send to Content API based on request locale value
3
+ * and config's defaultLocale.
4
+ *
5
+ * If no locale is provided, falls back to the default locale from config.
6
+ * Returns undefined for 'all' and '*' (special Payload values for returning all locales).
7
+ */ export function addFallbackLocale(locale, payload) {
8
+ const defaultLocale = payload.config.localization ? payload.config.localization.defaultLocale : undefined;
9
+ if (locale) {
10
+ // 'all' and '*' are special Payload values meaning "return all locales" - don't send to Content API
11
+ if (locale === 'all' || locale === '*') {
12
+ return undefined;
13
+ }
14
+ return locale;
15
+ } else if (defaultLocale) {
16
+ return defaultLocale;
17
+ }
18
+ return undefined;
19
+ }
@@ -0,0 +1,10 @@
1
+ import type { Payload } from 'payload';
2
+ /**
3
+ * Extracts all localized field paths from a collection's field configuration.
4
+ * Recursively traverses nested structures (groups, arrays, blocks, tabs) to find fields marked as localized.
5
+ *
6
+ * @param payload - The Payload instance containing collection configurations
7
+ * @param collectionSlug - The slug of the collection to extract localized paths from
8
+ * @returns Array of dot-notation paths to localized fields (e.g., ['title', 'metadata.description'])
9
+ */
10
+ export declare function buildLocalizedPaths(payload: Payload, collectionSlug: string): string[];
@@ -0,0 +1,71 @@
1
+ import { resolveBlocks } from '../resolveBlocks.js';
2
+ /**
3
+ * Extracts all localized field paths from a collection's field configuration.
4
+ * Recursively traverses nested structures (groups, arrays, blocks, tabs) to find fields marked as localized.
5
+ *
6
+ * @param payload - The Payload instance containing collection configurations
7
+ * @param collectionSlug - The slug of the collection to extract localized paths from
8
+ * @returns Array of dot-notation paths to localized fields (e.g., ['title', 'metadata.description'])
9
+ */ export function buildLocalizedPaths(payload, collectionSlug) {
10
+ const collectionConfig = payload.config.collections.find((c)=>c.slug === collectionSlug);
11
+ if (!collectionConfig) {
12
+ return [];
13
+ }
14
+ const localizedPaths = [];
15
+ traverseFields(collectionConfig.fields, localizedPaths, '', false, payload.config.blocks);
16
+ // Add _status to localized paths if localizeStatus is enabled for this collection
17
+ // _status is a base field added by Payload when versions.drafts is enabled,
18
+ // and it becomes localized when versions.drafts.localizeStatus is true
19
+ // localizeStatus requires both experimental flag AND collection-level config
20
+ const experimentalLocalizeStatus = 'experimental' in payload.config && payload.config.experimental && typeof payload.config.experimental === 'object' && 'localizeStatus' in payload.config.experimental && payload.config.experimental.localizeStatus === true;
21
+ const drafts = collectionConfig.versions && typeof collectionConfig.versions === 'object' ? collectionConfig.versions.drafts : false;
22
+ const collectionLocalizeStatus = drafts && typeof drafts === 'object' && 'localizeStatus' in drafts && drafts.localizeStatus === true;
23
+ const hasLocalizeStatus = payload.config.localization && experimentalLocalizeStatus && collectionLocalizeStatus;
24
+ if (hasLocalizeStatus && !localizedPaths.includes('_status')) {
25
+ localizedPaths.push('_status');
26
+ }
27
+ return localizedPaths;
28
+ }
29
+ /** Recursively traverses fields to find and collect localized paths */ function traverseFields(fields, localizedPaths, parentPath = '', parentIsLocalized = false, configBlocks) {
30
+ for (const field of fields){
31
+ // Unnamed layout fields (row, collapsible, unnamed group, unnamed tabs) don't store data
32
+ // at their own level, but their child fields may be localized. Recurse into them with
33
+ // the same parent path so localized fields bubble up correctly.
34
+ if (!('name' in field)) {
35
+ if ('fields' in field && Array.isArray(field.fields)) {
36
+ traverseFields(field.fields, localizedPaths, parentPath, parentIsLocalized, configBlocks);
37
+ }
38
+ if ('tabs' in field && Array.isArray(field.tabs)) {
39
+ for (const tab of field.tabs){
40
+ if (tab.fields) {
41
+ const tabPath = tab.name ? buildPath(parentPath, tab.name) : parentPath;
42
+ traverseFields(tab.fields, localizedPaths, tabPath, parentIsLocalized, configBlocks);
43
+ }
44
+ }
45
+ }
46
+ continue;
47
+ }
48
+ const fieldPath = buildPath(parentPath, field.name);
49
+ const isLocalized = 'localized' in field && field.localized === true;
50
+ const includeNestedPaths = isLocalized || parentIsLocalized;
51
+ // Add field to results if localized or parent is localized
52
+ if (includeNestedPaths) {
53
+ localizedPaths.push(fieldPath);
54
+ }
55
+ // Handle blocks field - has a special 'blocks' array structure and each block has its own nested fields
56
+ if (field.type === 'blocks' && 'blocks' in field) {
57
+ for (const block of resolveBlocks(field.blocks, configBlocks)){
58
+ traverseFields(block.fields, localizedPaths, fieldPath, includeNestedPaths, configBlocks);
59
+ }
60
+ continue;
61
+ }
62
+ // Handle field type that support nested fields
63
+ // Recursively handle nested structures (groups, arrays, tab, etc)
64
+ if ('fields' in field) {
65
+ traverseFields(field.fields, localizedPaths, fieldPath, includeNestedPaths, configBlocks);
66
+ }
67
+ }
68
+ }
69
+ /** Builds a dot-notation path from parent path and field name */ function buildPath(parentPath, fieldName) {
70
+ return parentPath ? `${parentPath}.${fieldName}` : fieldName;
71
+ }