@payloadcms/figma 0.0.1-alpha.5 → 0.0.1-alpha.51

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 (326) hide show
  1. package/dist/api/control-plane.d.ts +31 -1
  2. package/dist/api/control-plane.js +137 -67
  3. package/dist/api/figma-api.d.ts +20 -0
  4. package/dist/api/figma-api.js +77 -21
  5. package/dist/auth/callback-server.js +2 -1
  6. package/dist/auth/crypto-utils.js +5 -5
  7. package/dist/auth/jwt-validator.d.ts +2 -1
  8. package/dist/auth/jwt-validator.js +2 -2
  9. package/dist/auth/oauth-flow.d.ts +1 -1
  10. package/dist/auth/oauth-flow.js +15 -11
  11. package/dist/auth/project-token.js +11 -6
  12. package/dist/auth/refresh.d.ts +2 -1
  13. package/dist/auth/refresh.js +25 -12
  14. package/dist/auth/token-store.d.ts +40 -1
  15. package/dist/auth/token-store.js +65 -5
  16. package/dist/auth/types.d.ts +17 -4
  17. package/dist/cli.js +54 -6
  18. package/dist/commands/build-lambda-zip.d.ts +5 -0
  19. package/dist/commands/build-lambda-zip.js +19 -0
  20. package/dist/commands/debug.d.ts +8 -0
  21. package/dist/commands/debug.js +161 -0
  22. package/dist/commands/deploy.d.ts +6 -0
  23. package/dist/commands/deploy.js +94 -126
  24. package/dist/commands/env.d.ts +13 -0
  25. package/dist/commands/env.js +88 -0
  26. package/dist/commands/init.d.ts +3 -5
  27. package/dist/commands/init.js +118 -94
  28. package/dist/commands/list-tokens.d.ts +3 -3
  29. package/dist/commands/list-tokens.js +22 -7
  30. package/dist/commands/login.d.ts +8 -1
  31. package/dist/commands/login.js +30 -12
  32. package/dist/commands/logout.d.ts +5 -4
  33. package/dist/commands/logout.js +56 -13
  34. package/dist/config/oauth.d.ts +4 -14
  35. package/dist/config/oauth.js +18 -40
  36. package/dist/constants.d.ts +36 -19
  37. package/dist/constants.js +58 -20
  38. package/dist/db-content-api/README.md +98 -0
  39. package/dist/db-content-api/generated/content-api-types.d.ts +3746 -0
  40. package/dist/db-content-api/generated/content-api-types.js +7 -0
  41. package/dist/db-content-api/index.d.ts +20 -0
  42. package/dist/db-content-api/index.js +702 -0
  43. package/dist/db-content-api/temp-utilities/slug.d.ts +2 -0
  44. package/dist/db-content-api/temp-utilities/slug.js +3 -0
  45. package/dist/db-content-api/temp-utilities/sorting.d.ts +3 -0
  46. package/dist/db-content-api/temp-utilities/sorting.js +32 -0
  47. package/dist/db-content-api/temp-utilities/types.d.ts +22 -0
  48. package/dist/db-content-api/temp-utilities/types.js +15 -0
  49. package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +34 -0
  50. package/dist/db-content-api/temp-utilities/unwrapDocument.js +53 -0
  51. package/dist/db-content-api/utilities/auth.d.ts +30 -0
  52. package/dist/db-content-api/utilities/auth.js +81 -0
  53. package/dist/db-content-api/utilities/data/applyDefaults.d.ts +7 -0
  54. package/dist/db-content-api/utilities/data/applyDefaults.js +59 -0
  55. package/dist/db-content-api/utilities/data/castFieldValue.d.ts +11 -0
  56. package/dist/db-content-api/utilities/data/castFieldValue.js +69 -0
  57. package/dist/db-content-api/utilities/data/index.d.ts +42 -0
  58. package/dist/db-content-api/utilities/data/index.js +211 -0
  59. package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +12 -0
  60. package/dist/db-content-api/utilities/data/removeVirtualFields.js +54 -0
  61. package/dist/db-content-api/utilities/data/stripFields.d.ts +48 -0
  62. package/dist/db-content-api/utilities/data/stripFields.js +195 -0
  63. package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +23 -0
  64. package/dist/db-content-api/utilities/data/transformPublishedLocale.js +42 -0
  65. package/dist/db-content-api/utilities/joins.d.ts +55 -0
  66. package/dist/db-content-api/utilities/joins.js +136 -0
  67. package/dist/db-content-api/utilities/locale/index.d.ts +10 -0
  68. package/dist/db-content-api/utilities/locale/index.js +21 -0
  69. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts +11 -0
  70. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +66 -0
  71. package/dist/db-content-api/utilities/meta/buildMeta.d.ts +37 -0
  72. package/dist/db-content-api/utilities/meta/buildMeta.js +33 -0
  73. package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +13 -0
  74. package/dist/db-content-api/utilities/meta/buildPathTypes.js +181 -0
  75. package/dist/db-content-api/utilities/where.d.ts +20 -0
  76. package/dist/db-content-api/utilities/where.js +127 -0
  77. package/dist/endpoints/health.d.ts +3 -0
  78. package/dist/endpoints/health.js +11 -0
  79. package/dist/endpoints/schema.d.ts +3 -0
  80. package/dist/endpoints/schema.js +29 -0
  81. package/dist/exports/client.d.ts +3 -0
  82. package/dist/exports/client.js +3 -0
  83. package/dist/index.d.ts +2 -1
  84. package/dist/index.js +3 -1
  85. package/dist/oauth/components/FigmaAvatar/index.d.ts +4 -0
  86. package/dist/oauth/components/FigmaAvatar/index.js +27 -0
  87. package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
  88. package/dist/oauth/components/FigmaAvatarCell/index.d.ts +5 -0
  89. package/dist/oauth/components/FigmaAvatarCell/index.js +25 -0
  90. package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
  91. package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +9 -0
  92. package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +37 -0
  93. package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
  94. package/dist/oauth/components/LoginButton/index.js +50 -6
  95. package/dist/oauth/components/LoginButton/index.scss +50 -3
  96. package/dist/oauth/components/LogoutButton/index.js +5 -4
  97. package/dist/oauth/defaults.js +67 -10
  98. package/dist/oauth/endpoints/getLoginEndpoint.js +69 -24
  99. package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -4
  100. package/dist/oauth/index.js +40 -5
  101. package/dist/oauth/strategy/index.d.ts +0 -2
  102. package/dist/oauth/strategy/index.js +40 -17
  103. package/dist/oauth/types.d.ts +6 -6
  104. package/dist/oauth/utilities/isDuplicateKeyError.d.ts +7 -0
  105. package/dist/oauth/utilities/isDuplicateKeyError.js +14 -0
  106. package/dist/oauth/utilities/refreshTokens.js +3 -3
  107. package/dist/plugin/build-config.d.ts +21 -14
  108. package/dist/plugin/build-config.js +208 -17
  109. package/dist/storage-content-api/api-types.d.ts +168 -0
  110. package/dist/storage-content-api/api-types.js +6 -0
  111. package/dist/storage-content-api/client-uploads/ClientUploadHandler.d.ts +9 -0
  112. package/dist/storage-content-api/client-uploads/ClientUploadHandler.js +42 -0
  113. package/dist/storage-content-api/client-uploads/generateSignedURL.d.ts +13 -0
  114. package/dist/storage-content-api/client-uploads/generateSignedURL.js +39 -0
  115. package/dist/storage-content-api/client.d.ts +6 -0
  116. package/dist/storage-content-api/client.js +36 -0
  117. package/dist/storage-content-api/generateURL.d.ts +7 -0
  118. package/dist/storage-content-api/generateURL.js +8 -0
  119. package/dist/storage-content-api/handleDelete.d.ts +8 -0
  120. package/dist/storage-content-api/handleDelete.js +17 -0
  121. package/dist/storage-content-api/handleUpload.d.ts +11 -0
  122. package/dist/storage-content-api/handleUpload.js +144 -0
  123. package/dist/storage-content-api/index.d.ts +5 -0
  124. package/dist/storage-content-api/index.js +31 -0
  125. package/dist/storage-content-api/staticHandler.d.ts +10 -0
  126. package/dist/storage-content-api/staticHandler.js +56 -0
  127. package/dist/storage-content-api/types.d.ts +10 -0
  128. package/dist/storage-content-api/types.js +3 -0
  129. package/dist/storage-content-api/utilities/getSafeFilename.d.ts +12 -0
  130. package/dist/storage-content-api/utilities/getSafeFilename.js +61 -0
  131. package/dist/storage-content-api/utilities/index.d.ts +2 -0
  132. package/dist/storage-content-api/utilities/index.js +3 -0
  133. package/dist/templates/.env.example +5 -0
  134. package/dist/templates/README.md +19 -0
  135. package/dist/types/config.d.ts +2 -1
  136. package/dist/types/config.js +0 -2
  137. package/dist/types.d.ts +3 -1
  138. package/dist/utils/asset-collection.d.ts +3 -6
  139. package/dist/utils/asset-collection.js +10 -34
  140. package/dist/utils/build-lambda-zip.d.ts +14 -0
  141. package/dist/utils/build-lambda-zip.js +81 -0
  142. package/dist/utils/cache-bootstrap.d.ts +8 -0
  143. package/dist/utils/cache-bootstrap.js +18 -0
  144. package/dist/utils/config.js +1 -1
  145. package/dist/utils/env-management.d.ts +16 -7
  146. package/dist/utils/env-management.js +85 -64
  147. package/dist/utils/format-env-suffix.d.ts +12 -0
  148. package/dist/utils/format-env-suffix.js +13 -0
  149. package/dist/utils/formatter.js +3 -5
  150. package/dist/utils/lambda-config.d.ts +3 -1
  151. package/dist/utils/lambda-config.js +38 -32
  152. package/dist/utils/messages.d.ts +1 -1
  153. package/dist/utils/messages.js +22 -8
  154. package/dist/utils/package-manager.d.ts +24 -0
  155. package/dist/utils/package-manager.js +53 -0
  156. package/dist/utils/payload-config-ast.d.ts +22 -3
  157. package/dist/utils/payload-config-ast.js +96 -31
  158. package/dist/utils/payload-config-finder.d.ts +2 -2
  159. package/dist/utils/payload-config-finder.js +48 -9
  160. package/dist/utils/payload-config-modifier.d.ts +1 -1
  161. package/dist/utils/payload-config-modifier.js +61 -10
  162. package/dist/utils/payload-package-check.d.ts +12 -1
  163. package/dist/utils/payload-package-check.js +63 -5
  164. package/dist/utils/project.d.ts +3 -2
  165. package/dist/utils/project.js +29 -15
  166. package/dist/utils/resolve-environment.d.ts +14 -0
  167. package/dist/utils/resolve-environment.js +28 -0
  168. package/dist/utils/s3-upload.d.ts +0 -1
  169. package/dist/utils/s3-upload.js +10 -3
  170. package/dist/utils/token-display.js +11 -5
  171. package/dist/utils/typescript-validator.js +4 -6
  172. package/dist/utils/version-check.d.ts +3 -0
  173. package/dist/utils/version-check.js +38 -0
  174. package/package.json +29 -10
  175. package/dist/api/control-plane.d.ts.map +0 -1
  176. package/dist/api/control-plane.js.map +0 -1
  177. package/dist/api/figma-api.d.ts.map +0 -1
  178. package/dist/api/figma-api.js.map +0 -1
  179. package/dist/auth/browser.d.ts.map +0 -1
  180. package/dist/auth/browser.js.map +0 -1
  181. package/dist/auth/callback-server.d.ts.map +0 -1
  182. package/dist/auth/callback-server.js.map +0 -1
  183. package/dist/auth/crypto-utils.d.ts.map +0 -1
  184. package/dist/auth/crypto-utils.js.map +0 -1
  185. package/dist/auth/jwt-validator.d.ts.map +0 -1
  186. package/dist/auth/jwt-validator.js.map +0 -1
  187. package/dist/auth/oauth-flow.d.ts.map +0 -1
  188. package/dist/auth/oauth-flow.js.map +0 -1
  189. package/dist/auth/pkce.d.ts.map +0 -1
  190. package/dist/auth/pkce.js.map +0 -1
  191. package/dist/auth/project-token.d.ts.map +0 -1
  192. package/dist/auth/project-token.js.map +0 -1
  193. package/dist/auth/refresh.d.ts.map +0 -1
  194. package/dist/auth/refresh.js.map +0 -1
  195. package/dist/auth/token-store.d.ts.map +0 -1
  196. package/dist/auth/token-store.js.map +0 -1
  197. package/dist/auth/types.d.ts.map +0 -1
  198. package/dist/auth/types.js.map +0 -1
  199. package/dist/cli.d.ts.map +0 -1
  200. package/dist/cli.js.map +0 -1
  201. package/dist/commands/deploy.d.ts.map +0 -1
  202. package/dist/commands/deploy.js.map +0 -1
  203. package/dist/commands/init.d.ts.map +0 -1
  204. package/dist/commands/init.js.map +0 -1
  205. package/dist/commands/list-tokens.d.ts.map +0 -1
  206. package/dist/commands/list-tokens.js.map +0 -1
  207. package/dist/commands/login.d.ts.map +0 -1
  208. package/dist/commands/login.js.map +0 -1
  209. package/dist/commands/logout.d.ts.map +0 -1
  210. package/dist/commands/logout.js.map +0 -1
  211. package/dist/config/oauth.d.ts.map +0 -1
  212. package/dist/config/oauth.js.map +0 -1
  213. package/dist/constants.d.ts.map +0 -1
  214. package/dist/constants.js.map +0 -1
  215. package/dist/exports/client.d.ts.map +0 -1
  216. package/dist/exports/client.js.map +0 -1
  217. package/dist/index.d.ts.map +0 -1
  218. package/dist/index.js.map +0 -1
  219. package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
  220. package/dist/oauth/components/LoginButton/index.js.map +0 -1
  221. package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
  222. package/dist/oauth/components/LogoutButton/index.js.map +0 -1
  223. package/dist/oauth/defaults.d.ts.map +0 -1
  224. package/dist/oauth/defaults.js.map +0 -1
  225. package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
  226. package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
  227. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
  228. package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
  229. package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
  230. package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
  231. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
  232. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
  233. package/dist/oauth/exports/client.d.ts.map +0 -1
  234. package/dist/oauth/exports/client.js.map +0 -1
  235. package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
  236. package/dist/oauth/hooks/afterLogout.js.map +0 -1
  237. package/dist/oauth/hooks/me.d.ts.map +0 -1
  238. package/dist/oauth/hooks/me.js.map +0 -1
  239. package/dist/oauth/hooks/refresh.d.ts.map +0 -1
  240. package/dist/oauth/hooks/refresh.js.map +0 -1
  241. package/dist/oauth/index.d.ts.map +0 -1
  242. package/dist/oauth/index.js.map +0 -1
  243. package/dist/oauth/strategy/index.d.ts.map +0 -1
  244. package/dist/oauth/strategy/index.js.map +0 -1
  245. package/dist/oauth/types.d.ts.map +0 -1
  246. package/dist/oauth/types.js.map +0 -1
  247. package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
  248. package/dist/oauth/utilities/clearCookie.js.map +0 -1
  249. package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
  250. package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
  251. package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
  252. package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
  253. package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
  254. package/dist/oauth/utilities/extractOrigin.js.map +0 -1
  255. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
  256. package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
  257. package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
  258. package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
  259. package/dist/oauth/utilities/getAdminPath.js +0 -9
  260. package/dist/oauth/utilities/getAdminPath.js.map +0 -1
  261. package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
  262. package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
  263. package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
  264. package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
  265. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
  266. package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
  267. package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
  268. package/dist/oauth/utilities/getTokenExp.js.map +0 -1
  269. package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
  270. package/dist/oauth/utilities/getUsernameField.js.map +0 -1
  271. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
  272. package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
  273. package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
  274. package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
  275. package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
  276. package/dist/oauth/utilities/refreshTokens.js.map +0 -1
  277. package/dist/plugin/adapter.d.ts.map +0 -1
  278. package/dist/plugin/adapter.js.map +0 -1
  279. package/dist/plugin/build-config.d.ts.map +0 -1
  280. package/dist/plugin/build-config.js.map +0 -1
  281. package/dist/types/config.d.ts.map +0 -1
  282. package/dist/types/config.js.map +0 -1
  283. package/dist/types.d.ts.map +0 -1
  284. package/dist/types.js.map +0 -1
  285. package/dist/utils/asset-collection.d.ts.map +0 -1
  286. package/dist/utils/asset-collection.js.map +0 -1
  287. package/dist/utils/build-detection.d.ts.map +0 -1
  288. package/dist/utils/build-detection.js.map +0 -1
  289. package/dist/utils/config.d.ts.map +0 -1
  290. package/dist/utils/config.js.map +0 -1
  291. package/dist/utils/download-template.d.ts.map +0 -1
  292. package/dist/utils/download-template.js.map +0 -1
  293. package/dist/utils/env-management.d.ts.map +0 -1
  294. package/dist/utils/env-management.js.map +0 -1
  295. package/dist/utils/format.d.ts.map +0 -1
  296. package/dist/utils/format.js.map +0 -1
  297. package/dist/utils/formatter.d.ts.map +0 -1
  298. package/dist/utils/formatter.js.map +0 -1
  299. package/dist/utils/git.d.ts.map +0 -1
  300. package/dist/utils/git.js.map +0 -1
  301. package/dist/utils/is-debug.d.ts.map +0 -1
  302. package/dist/utils/is-debug.js.map +0 -1
  303. package/dist/utils/lambda-config.d.ts.map +0 -1
  304. package/dist/utils/lambda-config.js.map +0 -1
  305. package/dist/utils/log.d.ts.map +0 -1
  306. package/dist/utils/log.js.map +0 -1
  307. package/dist/utils/messages.d.ts.map +0 -1
  308. package/dist/utils/messages.js.map +0 -1
  309. package/dist/utils/package-manager.d.ts.map +0 -1
  310. package/dist/utils/package-manager.js.map +0 -1
  311. package/dist/utils/payload-config-ast.d.ts.map +0 -1
  312. package/dist/utils/payload-config-ast.js.map +0 -1
  313. package/dist/utils/payload-config-finder.d.ts.map +0 -1
  314. package/dist/utils/payload-config-finder.js.map +0 -1
  315. package/dist/utils/payload-config-modifier.d.ts.map +0 -1
  316. package/dist/utils/payload-config-modifier.js.map +0 -1
  317. package/dist/utils/payload-package-check.d.ts.map +0 -1
  318. package/dist/utils/payload-package-check.js.map +0 -1
  319. package/dist/utils/project.d.ts.map +0 -1
  320. package/dist/utils/project.js.map +0 -1
  321. package/dist/utils/s3-upload.d.ts.map +0 -1
  322. package/dist/utils/s3-upload.js.map +0 -1
  323. package/dist/utils/token-display.d.ts.map +0 -1
  324. package/dist/utils/token-display.js.map +0 -1
  325. package/dist/utils/typescript-validator.d.ts.map +0 -1
  326. package/dist/utils/typescript-validator.js.map +0 -1
@@ -0,0 +1,136 @@
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
+ * 4. **Localized relationship fields** - Locale-aware joins not implemented.
20
+ *
21
+ * Note: "Where querying through joins" (e.g., `where: { 'relatedPosts.title': { equals: 'x' } }`)
22
+ * is a separate Payload feature that filters documents based on joined data. This is NOT
23
+ * a join feature but a where clause feature, and would need separate Content API support.
24
+ *
25
+ * Payload's JoinQuery format (at runtime):
26
+ * {
27
+ * 'group.relatedPosts': { // joinPath - where results go in the document
28
+ * sort: '-title',
29
+ * limit: 10,
30
+ * page: 2, // page-based pagination
31
+ * where: { ... }, // Payload where format
32
+ * count: true
33
+ * }
34
+ * }
35
+ *
36
+ * Content API's join format:
37
+ * [{
38
+ * collectionId: 'posts', // collection to join FROM
39
+ * on: 'group.category', // field in joined collection pointing to this doc
40
+ * path: 'group.relatedPosts', // where to put results
41
+ * count: false,
42
+ * where: { ... }, // Content API where format
43
+ * sort: '-title',
44
+ * limit: 10,
45
+ * offset: 10 // offset-based pagination
46
+ * }]
47
+ *
48
+ * The mapping requires the collection config to resolve:
49
+ * - Which collection each join field refers to
50
+ * - What the 'on' field is for each join
51
+ */ export function convertPayloadJoinsToContentAPI(payload, collectionSlug, joins) {
52
+ const collectionConfig = payload.config.collections.find((c)=>c.slug === collectionSlug);
53
+ if (!collectionConfig) {
54
+ return undefined;
55
+ }
56
+ // joins === false means explicitly disable all joins
57
+ // joins === undefined means use defaults (no custom query params)
58
+ if (joins === false || !joins) {
59
+ return undefined;
60
+ }
61
+ const result = [];
62
+ // Iterate through all join paths in the query
63
+ for (const [joinPath, joinQueryValue] of Object.entries(joins)){
64
+ // joinQuery === false means skip this specific join
65
+ if (joinQueryValue === false) {
66
+ continue;
67
+ }
68
+ // Normalize undefined/empty to empty object
69
+ const joinQuery = joinQueryValue ?? {};
70
+ // Find the SanitizedJoin config for this joinPath
71
+ // SanitizedJoins is indexed by the collection being joined FROM
72
+ let foundJoin;
73
+ // Search through all collections in the joins config
74
+ for (const [collectionSlug, sanitizedJoins] of Object.entries(collectionConfig.joins)){
75
+ for (const sanitizedJoin of sanitizedJoins){
76
+ if (sanitizedJoin.joinPath === joinPath) {
77
+ foundJoin = {
78
+ collectionSlug,
79
+ on: sanitizedJoin.field.on
80
+ };
81
+ break;
82
+ }
83
+ }
84
+ if (foundJoin) {
85
+ break;
86
+ }
87
+ }
88
+ // Also check polymorphic joins
89
+ if (!foundJoin) {
90
+ for (const sanitizedJoin of collectionConfig.polymorphicJoins){
91
+ if (sanitizedJoin.joinPath === joinPath) {
92
+ // For polymorphic joins, collection is an array - use first one
93
+ const collections = sanitizedJoin.field.collection;
94
+ foundJoin = {
95
+ collectionSlug: Array.isArray(collections) ? collections[0] : collections,
96
+ on: sanitizedJoin.field.on
97
+ };
98
+ break;
99
+ }
100
+ }
101
+ }
102
+ if (!foundJoin) {
103
+ payload.logger.warn(`Join path '${joinPath}' not found in collection config for '${collectionConfig.slug}'`);
104
+ continue;
105
+ }
106
+ // Convert pagination: Payload uses page, Content API JoinClause uses offset
107
+ let offset;
108
+ if (joinQuery.page && joinQuery.page > 1 && joinQuery.limit) {
109
+ offset = (joinQuery.page - 1) * joinQuery.limit;
110
+ }
111
+ // Add fallback sort for the joined collection
112
+ const sortWithFallback = addFallbackSort(joinQuery.sort, payload, foundJoin.collectionSlug);
113
+ const contentAPIJoin = {
114
+ collectionId: foundJoin.collectionSlug,
115
+ count: joinQuery.count ?? false,
116
+ on: foundJoin.on,
117
+ path: joinPath,
118
+ ...joinQuery.limit !== undefined && {
119
+ limit: joinQuery.limit
120
+ },
121
+ ...offset !== undefined && {
122
+ offset
123
+ },
124
+ ...sortWithFallback && {
125
+ sort: sortWithFallback
126
+ },
127
+ ...joinQuery.where && {
128
+ where: convertPayloadWhereToContentAPI(joinQuery.where)
129
+ }
130
+ };
131
+ result.push(contentAPIJoin);
132
+ }
133
+ return result.length > 0 ? result : undefined;
134
+ }
135
+
136
+ //# sourceMappingURL=joins.js.map
@@ -0,0 +1,10 @@
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;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,21 @@
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
+ }
20
+
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
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[];
11
+ //# sourceMappingURL=buildLocalizedPaths.d.ts.map
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Extracts all localized field paths from a collection's field configuration.
3
+ * Recursively traverses nested structures (groups, arrays, blocks, tabs) to find fields marked as localized.
4
+ *
5
+ * @param payload - The Payload instance containing collection configurations
6
+ * @param collectionSlug - The slug of the collection to extract localized paths from
7
+ * @returns Array of dot-notation paths to localized fields (e.g., ['title', 'metadata.description'])
8
+ */ export function buildLocalizedPaths(payload, collectionSlug) {
9
+ const collectionConfig = payload.config.collections.find((c)=>c.slug === collectionSlug);
10
+ if (!collectionConfig) {
11
+ return [];
12
+ }
13
+ const localizedPaths = [];
14
+ traverseFields(collectionConfig.fields, localizedPaths);
15
+ // Add _status to localized paths if localizeStatus is enabled for this collection
16
+ // _status is a base field added by Payload when versions.drafts is enabled,
17
+ // and it becomes localized when versions.drafts.localizeStatus is true
18
+ // localizeStatus requires both experimental flag AND collection-level config
19
+ const experimentalLocalizeStatus = 'experimental' in payload.config && payload.config.experimental && typeof payload.config.experimental === 'object' && 'localizeStatus' in payload.config.experimental && payload.config.experimental.localizeStatus === true;
20
+ const drafts = collectionConfig.versions && typeof collectionConfig.versions === 'object' ? collectionConfig.versions.drafts : false;
21
+ const collectionLocalizeStatus = drafts && typeof drafts === 'object' && 'localizeStatus' in drafts && drafts.localizeStatus === true;
22
+ const hasLocalizeStatus = payload.config.localization && experimentalLocalizeStatus && collectionLocalizeStatus;
23
+ if (hasLocalizeStatus && !localizedPaths.includes('_status')) {
24
+ localizedPaths.push('_status');
25
+ }
26
+ return localizedPaths;
27
+ }
28
+ /** Recursively traverses fields to find and collect localized paths */ function traverseFields(fields, localizedPaths, parentPath = '', parentIsLocalized = false) {
29
+ for (const field of fields){
30
+ // Only field types that have names can support localization
31
+ // See: https://payloadcms.com/docs/configuration/localization
32
+ //
33
+ // This will skip presentational fields like ui, collapsible, row, tabs (if unnamed), groups (if unnamed)
34
+ // which do not store data in the database and thus are not relevant for querying localized paths
35
+ // See: https://payloadcms.com/docs/fields/overview#presentational-fields
36
+ if (!('name' in field)) {
37
+ continue;
38
+ }
39
+ const fieldPath = buildPath(parentPath, field.name);
40
+ const isLocalized = 'localized' in field && field.localized === true;
41
+ const includeNestedPaths = isLocalized || parentIsLocalized;
42
+ // Add field to results if localized or parent is localized
43
+ if (includeNestedPaths) {
44
+ localizedPaths.push(fieldPath);
45
+ }
46
+ // Handle blocks field - has a special 'blocks' array structure and each block has its own nested fields
47
+ if (field.type === 'blocks' && 'blocks' in field) {
48
+ for (const block of field.blocks){
49
+ if ('fields' in block) {
50
+ traverseFields(block.fields, localizedPaths, fieldPath, includeNestedPaths);
51
+ }
52
+ }
53
+ continue;
54
+ }
55
+ // Handle field type that support nested fields
56
+ // Recursively handle nested structures (groups, arrays, tab, etc)
57
+ if ('fields' in field) {
58
+ traverseFields(field.fields, localizedPaths, fieldPath, includeNestedPaths);
59
+ }
60
+ }
61
+ }
62
+ /** Builds a dot-notation path from parent path and field name */ function buildPath(parentPath, fieldName) {
63
+ return parentPath ? `${parentPath}.${fieldName}` : fieldName;
64
+ }
65
+
66
+ //# sourceMappingURL=buildLocalizedPaths.js.map
@@ -0,0 +1,37 @@
1
+ import type { Payload, Where } from 'payload';
2
+ import type { components } from '../../generated/content-api-types.js';
3
+ import type { PathTypesRecord } from '../../temp-utilities/types.js';
4
+ /**
5
+ * Metadata sent to Content API for query processing.
6
+ *
7
+ * TODO: This interface is defined here temporarily so Content API can test the integration.
8
+ * Once Content API implements support for pathTypes with relationship info, this type
9
+ * should be generated from openapi.json and ContentAPIMeta can be removed.
10
+ */
11
+ export interface ContentAPIMeta {
12
+ localizedPaths?: string[];
13
+ pathTypes?: PathTypesRecord;
14
+ }
15
+ /**
16
+ * The type that Content API currently expects (from generated types).
17
+ * This is more restrictive than ContentAPIMeta until Content API is updated.
18
+ */
19
+ type ContentAPIMetaGenerated = components['schemas']['RequestMeta'];
20
+ export interface BuildMetaOptions {
21
+ collection: string;
22
+ locale: string | undefined;
23
+ where?: Where;
24
+ }
25
+ /**
26
+ * Builds the `meta` object for Content API requests.
27
+ * Combines pathTypes (for array field handling) and localizedPaths (for locale queries).
28
+ *
29
+ * @param payload - The Payload instance
30
+ * @param options - Options including collection slug, locale, and where clause
31
+ * @returns Object with meta property ready to spread into request body, or empty object if no meta needed
32
+ */
33
+ export declare function buildMeta(payload: Payload, options: BuildMetaOptions): {
34
+ meta?: ContentAPIMetaGenerated;
35
+ };
36
+ export {};
37
+ //# sourceMappingURL=buildMeta.d.ts.map
@@ -0,0 +1,33 @@
1
+ import { buildLocalizedPaths } from './buildLocalizedPaths.js';
2
+ import { buildPathTypes } from './buildPathTypes.js';
3
+ /**
4
+ * Builds the `meta` object for Content API requests.
5
+ * Combines pathTypes (for array field handling) and localizedPaths (for locale queries).
6
+ *
7
+ * @param payload - The Payload instance
8
+ * @param options - Options including collection slug, locale, and where clause
9
+ * @returns Object with meta property ready to spread into request body, or empty object if no meta needed
10
+ */ export function buildMeta(payload, options) {
11
+ const { collection, locale, where } = options;
12
+ const meta = {};
13
+ // Add pathTypes if there are array fields in the where clause
14
+ const pathTypes = buildPathTypes(payload, collection, where);
15
+ if (Object.keys(pathTypes).length > 0) {
16
+ meta.pathTypes = pathTypes;
17
+ }
18
+ // Add localizedPaths if locale is specified (but not 'all')
19
+ if (locale && locale !== 'all') {
20
+ const localizedPaths = buildLocalizedPaths(payload, collection);
21
+ if (localizedPaths.length > 0) {
22
+ meta.localizedPaths = localizedPaths;
23
+ }
24
+ }
25
+ // Cast to generated type - Content API will need to be updated to handle
26
+ // the new pathTypes format with relationship info. Until then, it will
27
+ // ignore the extra fields but still receive the data for testing.
28
+ return Object.keys(meta).length > 0 ? {
29
+ meta: meta
30
+ } : {};
31
+ }
32
+
33
+ //# sourceMappingURL=buildMeta.js.map
@@ -0,0 +1,13 @@
1
+ import type { Payload, Where } from 'payload';
2
+ import type { PathTypesRecord } from '../../temp-utilities/types.js';
3
+ /**
4
+ * Builds pathTypes metadata for Content API request.
5
+ * Returns a record of paths with their types for proper query generation.
6
+ *
7
+ * Includes:
8
+ * - Array fields (type: "array")
9
+ * - Relationship fields (type: { type: "relationship", collection, hasMany })
10
+ * - Join fields (type: { type: "join", collection, hasMany, on })
11
+ */
12
+ export declare function buildPathTypes(payload: Payload, collectionSlug: string, where: undefined | Where): PathTypesRecord;
13
+ //# sourceMappingURL=buildPathTypes.d.ts.map
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Extracts all field paths from a where clause recursively
3
+ */ function extractPathsFromWhere(where, paths = new Set()) {
4
+ if (!where || typeof where !== 'object') {
5
+ return paths;
6
+ }
7
+ // Handle 'and' operator
8
+ if ('and' in where && Array.isArray(where.and)) {
9
+ for (const clause of where.and){
10
+ extractPathsFromWhere(clause, paths);
11
+ }
12
+ return paths;
13
+ }
14
+ // Handle 'or' operator
15
+ if ('or' in where && Array.isArray(where.or)) {
16
+ for (const clause of where.or){
17
+ extractPathsFromWhere(clause, paths);
18
+ }
19
+ return paths;
20
+ }
21
+ // Handle regular conditions - keys are field paths
22
+ for(const key in where){
23
+ if (key === 'and' || key === 'or') {
24
+ continue;
25
+ }
26
+ // Add the path
27
+ paths.add(key);
28
+ // Check if the value is a nested where clause (for relationships)
29
+ const value = where[key];
30
+ if (value && typeof value === 'object' && !('equals' in value) && !('in' in value)) {
31
+ // Might be a nested where, recurse
32
+ extractPathsFromWhere(value, paths);
33
+ }
34
+ }
35
+ return paths;
36
+ }
37
+ /**
38
+ * Determines the type of a field based on its configuration.
39
+ * Returns PathTypeValue for fields that need special handling in Content API queries.
40
+ */ function getFieldType(field) {
41
+ // Array field
42
+ if (field.type === 'array') {
43
+ return 'array';
44
+ }
45
+ // Blocks field (array of objects)
46
+ if (field.type === 'blocks') {
47
+ return 'array';
48
+ }
49
+ // Relationship field - always include for JOIN support
50
+ if (field.type === 'relationship') {
51
+ const { hasMany = false, relationTo: collection } = field;
52
+ return {
53
+ type: 'relationship',
54
+ collection,
55
+ hasMany
56
+ };
57
+ }
58
+ // Upload field - treated like relationship
59
+ if (field.type === 'upload') {
60
+ const { hasMany = false, relationTo: collection } = field;
61
+ return {
62
+ type: 'relationship',
63
+ collection,
64
+ hasMany
65
+ };
66
+ }
67
+ // Join field - virtual reverse lookup
68
+ if (field.type === 'join') {
69
+ const { collection, on } = field;
70
+ return {
71
+ type: 'join',
72
+ collection,
73
+ hasMany: true,
74
+ on
75
+ };
76
+ }
77
+ // Select field with hasMany (array)
78
+ if (field.type === 'select' && 'hasMany' in field && field.hasMany) {
79
+ return 'array';
80
+ }
81
+ // Objects (group, collapsible, row, tabs) don't need traversal
82
+ return null;
83
+ }
84
+ /**
85
+ * Finds a field in the collection schema by its path
86
+ * Supports nested paths like "access.read.users"
87
+ */ function findFieldByPath(payload, collectionSlug, path) {
88
+ const collectionConfig = payload.config.collections.find((c)=>c.slug === collectionSlug);
89
+ if (!collectionConfig) {
90
+ return undefined;
91
+ }
92
+ const pathSegments = path.split('.');
93
+ // Walk through the path segments to find the field
94
+ let currentFields = collectionConfig.fields;
95
+ let currentField = undefined;
96
+ for(let i = 0; i < pathSegments.length; i++){
97
+ const segment = pathSegments[i];
98
+ // First try to find a direct match
99
+ currentField = currentFields.find((f)=>'name' in f && f.name === segment);
100
+ // If not found, check if any unnamed container fields (collapsible, row) contain it
101
+ if (!currentField) {
102
+ for (const field of currentFields){
103
+ if (!('name' in field) || !field.name) {
104
+ // This is an unnamed field, check its contents
105
+ if ('fields' in field && field.type === 'collapsible' || 'fields' in field && field.type === 'row') {
106
+ currentField = field.fields.find((f)=>'name' in f && f.name === segment);
107
+ if (currentField) {
108
+ break;
109
+ }
110
+ } else if ('tabs' in field && field.type === 'tabs') {
111
+ // Check all tabs
112
+ for (const tab of field.tabs){
113
+ currentField = tab.fields.find((f)=>'name' in f && f.name === segment);
114
+ if (currentField) {
115
+ break;
116
+ }
117
+ }
118
+ if (currentField) {
119
+ break;
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+ if (!currentField) {
126
+ return undefined;
127
+ }
128
+ // If we're not at the end, get nested fields
129
+ if (i < pathSegments.length - 1) {
130
+ if (currentField.type === 'group' && 'fields' in currentField) {
131
+ currentFields = currentField.fields;
132
+ } else if (currentField.type === 'array' && 'fields' in currentField) {
133
+ currentFields = currentField.fields;
134
+ } else if (currentField.type === 'blocks' && 'blocks' in currentField) {
135
+ // For blocks, we can't determine the exact field without knowing the block type
136
+ // Return the blocks field itself
137
+ return currentField;
138
+ } else {
139
+ // Field doesn't have nested fields, can't continue
140
+ return undefined;
141
+ }
142
+ }
143
+ }
144
+ return currentField;
145
+ }
146
+ /**
147
+ * Builds pathTypes metadata for Content API request.
148
+ * Returns a record of paths with their types for proper query generation.
149
+ *
150
+ * Includes:
151
+ * - Array fields (type: "array")
152
+ * - Relationship fields (type: { type: "relationship", collection, hasMany })
153
+ * - Join fields (type: { type: "join", collection, hasMany, on })
154
+ */ export function buildPathTypes(payload, collectionSlug, where) {
155
+ if (!where) {
156
+ return {};
157
+ }
158
+ const pathTypes = {};
159
+ const paths = extractPathsFromWhere(where);
160
+ for (const path of paths){
161
+ // For each path, we need to check all segments to see if any intermediate ones are arrays/relationships
162
+ const segments = path.split('.');
163
+ for(let i = 0; i < segments.length; i++){
164
+ const partialPath = segments.slice(0, i + 1).join('.');
165
+ // Skip if we already have this path
166
+ if (partialPath in pathTypes) {
167
+ continue;
168
+ }
169
+ const field = findFieldByPath(payload, collectionSlug, partialPath);
170
+ if (field) {
171
+ const fieldType = getFieldType(field);
172
+ if (fieldType !== null) {
173
+ pathTypes[partialPath] = fieldType;
174
+ }
175
+ }
176
+ }
177
+ }
178
+ return pathTypes;
179
+ }
180
+
181
+ //# sourceMappingURL=buildPathTypes.js.map
@@ -0,0 +1,20 @@
1
+ import type { Where } from 'payload';
2
+ import type { components } from '../generated/content-api-types.js';
3
+ type WhereClause = components['schemas']['WhereClause'];
4
+ type ConvertOptions = {
5
+ /** Internal flag to track if we're inside a logical operator (and/or) */
6
+ insideLogicalOperator?: boolean;
7
+ /** If true, transform 'parent' field to 'documentId' (used for version queries) */
8
+ parentToDocumentId?: boolean;
9
+ /**
10
+ * If true, strip 'version.' prefix from field paths (used for version queries).
11
+ *
12
+ * Payload queries version content with paths like 'version._status.en', but Content API
13
+ * stores version data directly in the 'data' column (not nested under 'version').
14
+ * The 'version' wrapper is only added in API responses for client compatibility.
15
+ */
16
+ stripVersionPrefix?: boolean;
17
+ };
18
+ export declare function convertPayloadWhereToContentAPI(where: undefined | Where, options?: ConvertOptions): WhereClause;
19
+ export {};
20
+ //# sourceMappingURL=where.d.ts.map
@@ -0,0 +1,127 @@
1
+ export function convertPayloadWhereToContentAPI(where, options = {}) {
2
+ // Empty where {} should be { and: [] } not undefined
3
+ // Content API requires a where clause structure even for "no filter"
4
+ if (!where || Object.keys(where).length === 0) {
5
+ return {
6
+ and: []
7
+ };
8
+ }
9
+ const conditions = [];
10
+ for (const [key, value] of Object.entries(where)){
11
+ if (key === 'and') {
12
+ // Recursively convert nested 'and' conditions, preserving options
13
+ const nestedConditions = value.map((item)=>convertPayloadWhereToContentAPI(item, {
14
+ ...options,
15
+ insideLogicalOperator: true
16
+ }))// TODO: A better solution would be to make the `where` schema of `zod` in `content-api`
17
+ // more permissive. For now I'll do it this way because I have an idea to simplify
18
+ // everything we're doing with `where` (Post EAP) anyway.
19
+ // Filter out empty conditions { and: [] } that would be invalid
20
+ .filter((condition)=>{
21
+ if ('and' in condition) {
22
+ return condition.and.length > 0;
23
+ }
24
+ if ('or' in condition) {
25
+ return condition.or.length > 0;
26
+ }
27
+ return true // Keep path/operator/value conditions
28
+ ;
29
+ });
30
+ // If filtering resulted in no conditions, return empty and
31
+ if (nestedConditions.length === 0) {
32
+ return {
33
+ and: []
34
+ };
35
+ }
36
+ return {
37
+ and: nestedConditions
38
+ };
39
+ } else if (key === 'or') {
40
+ // Recursively convert nested 'or' conditions, preserving options
41
+ const nestedConditions = value.map((item)=>convertPayloadWhereToContentAPI(item, {
42
+ ...options,
43
+ insideLogicalOperator: true
44
+ }))// Filter out empty conditions { and: [] } or { or: [] } that would be invalid
45
+ .filter((condition)=>{
46
+ if ('and' in condition) {
47
+ return condition.and.length > 0;
48
+ }
49
+ if ('or' in condition) {
50
+ return condition.or.length > 0;
51
+ }
52
+ return true // Keep path/operator/value conditions
53
+ ;
54
+ });
55
+ // If filtering resulted in no conditions, return empty and
56
+ if (nestedConditions.length === 0) {
57
+ return {
58
+ and: []
59
+ };
60
+ }
61
+ return {
62
+ or: nestedConditions
63
+ };
64
+ } else {
65
+ // TODO: fix this in content api
66
+ // WORKAROUND: Payload uses 'parent' for version queries, but Content API expects 'documentId'
67
+ let fieldPath = key;
68
+ if (options.parentToDocumentId && key === 'parent') {
69
+ fieldPath = 'documentId';
70
+ }
71
+ // Strip 'version.' prefix from field paths for version queries
72
+ // Payload uses paths like 'version._status.en' but Content API stores version data
73
+ // directly in the 'data' column, not nested under 'version'
74
+ if (options.stripVersionPrefix && fieldPath.startsWith('version.')) {
75
+ fieldPath = fieldPath.slice('version.'.length);
76
+ }
77
+ // Convert field conditions: { fieldName: { operator: value } }
78
+ // to: { path: fieldName, operator, value }
79
+ // Handle Payload's shorthand: { fieldName: value } → { fieldName: { equals: value } }
80
+ // If value is a primitive (string, number, boolean, null) or not a plain object,
81
+ // treat it as an implicit 'equals' operator
82
+ const isPrimitive = value === null || typeof value !== 'object' || Array.isArray(value);
83
+ if (isPrimitive) {
84
+ // Shorthand format: { id: "some-value" } means { id: { equals: "some-value" } }
85
+ conditions.push({
86
+ operator: 'equals',
87
+ path: fieldPath,
88
+ value
89
+ });
90
+ continue;
91
+ }
92
+ const operators = value;
93
+ // Skip empty operator objects { fieldName: {} }
94
+ if (Object.keys(operators).length === 0) {
95
+ continue;
96
+ }
97
+ for (const [op, operatorValue] of Object.entries(operators)){
98
+ // Skip operators with undefined values (e.g., { equals: undefined })
99
+ // This can happen when Payload sends incomplete where clauses
100
+ if (operatorValue === undefined) {
101
+ continue;
102
+ }
103
+ let finalValue = operatorValue;
104
+ // Convert string booleans to actual booleans for exists operator
105
+ // REST API sends "true"/"false" as strings, but Content API requires boolean
106
+ if (op === 'exists' && typeof operatorValue === 'string') {
107
+ finalValue = operatorValue === 'true';
108
+ }
109
+ conditions.push({
110
+ operator: op,
111
+ path: fieldPath,
112
+ value: finalValue
113
+ });
114
+ }
115
+ }
116
+ }
117
+ // If inside a logical operator (and/or), return conditions directly
118
+ // Otherwise, wrap in 'and' to match WhereClause type
119
+ if (options.insideLogicalOperator && conditions.length === 1) {
120
+ return conditions[0];
121
+ }
122
+ return {
123
+ and: conditions
124
+ };
125
+ }
126
+
127
+ //# sourceMappingURL=where.js.map
@@ -0,0 +1,3 @@
1
+ import type { Endpoint } from 'payload';
2
+ export declare const health: Endpoint;
3
+ //# sourceMappingURL=health.d.ts.map