convex-cms 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. package/dist/cli/commands/admin.d.ts +16 -0
  2. package/dist/cli/commands/admin.d.ts.map +1 -0
  3. package/dist/cli/commands/admin.js +88 -0
  4. package/dist/cli/commands/admin.js.map +1 -0
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +18 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/cli/utils/detectConvexUrl.d.ts +13 -0
  10. package/dist/cli/utils/detectConvexUrl.d.ts.map +1 -0
  11. package/dist/cli/utils/detectConvexUrl.js +48 -0
  12. package/dist/cli/utils/detectConvexUrl.js.map +1 -0
  13. package/dist/cli/utils/openBrowser.d.ts +7 -0
  14. package/dist/cli/utils/openBrowser.d.ts.map +1 -0
  15. package/dist/cli/utils/openBrowser.js +17 -0
  16. package/dist/cli/utils/openBrowser.js.map +1 -0
  17. package/dist/client/admin-config.d.ts +126 -0
  18. package/dist/client/admin-config.d.ts.map +1 -0
  19. package/dist/client/admin-config.js +117 -0
  20. package/dist/client/admin-config.js.map +1 -0
  21. package/dist/client/adminApi.d.ts +2273 -0
  22. package/dist/client/adminApi.d.ts.map +1 -0
  23. package/dist/client/adminApi.js +716 -0
  24. package/dist/client/adminApi.js.map +1 -0
  25. package/dist/client/agentTools.d.ts +933 -0
  26. package/dist/client/agentTools.d.ts.map +1 -0
  27. package/dist/client/agentTools.js +1004 -0
  28. package/dist/client/agentTools.js.map +1 -0
  29. package/dist/client/argTypes.d.ts +212 -0
  30. package/dist/client/argTypes.d.ts.map +1 -0
  31. package/dist/client/argTypes.js +5 -0
  32. package/dist/client/argTypes.js.map +1 -0
  33. package/dist/client/field-types.d.ts +55 -0
  34. package/dist/client/field-types.d.ts.map +1 -0
  35. package/dist/client/field-types.js +152 -0
  36. package/dist/client/field-types.js.map +1 -0
  37. package/dist/client/index.d.ts +189 -0
  38. package/dist/client/index.d.ts.map +1 -0
  39. package/dist/client/index.js +668 -0
  40. package/dist/client/index.js.map +1 -0
  41. package/dist/client/queryBuilder.d.ts +765 -0
  42. package/dist/client/queryBuilder.d.ts.map +1 -0
  43. package/dist/client/queryBuilder.js +970 -0
  44. package/dist/client/queryBuilder.js.map +1 -0
  45. package/dist/client/schema/codegen.d.ts +128 -0
  46. package/dist/client/schema/codegen.d.ts.map +1 -0
  47. package/dist/client/schema/codegen.js +318 -0
  48. package/dist/client/schema/codegen.js.map +1 -0
  49. package/dist/client/schema/defineContentType.d.ts +221 -0
  50. package/dist/client/schema/defineContentType.d.ts.map +1 -0
  51. package/dist/client/schema/defineContentType.js +380 -0
  52. package/dist/client/schema/defineContentType.js.map +1 -0
  53. package/dist/client/schema/index.d.ts +85 -0
  54. package/dist/client/schema/index.d.ts.map +1 -0
  55. package/dist/client/schema/index.js +92 -0
  56. package/dist/client/schema/index.js.map +1 -0
  57. package/dist/client/schema/schemaDrift.d.ts +199 -0
  58. package/dist/client/schema/schemaDrift.d.ts.map +1 -0
  59. package/dist/client/schema/schemaDrift.js +340 -0
  60. package/dist/client/schema/schemaDrift.js.map +1 -0
  61. package/dist/client/schema/typedClient.d.ts +401 -0
  62. package/dist/client/schema/typedClient.d.ts.map +1 -0
  63. package/dist/client/schema/typedClient.js +269 -0
  64. package/dist/client/schema/typedClient.js.map +1 -0
  65. package/dist/client/schema/types.d.ts +477 -0
  66. package/dist/client/schema/types.d.ts.map +1 -0
  67. package/dist/client/schema/types.js +39 -0
  68. package/dist/client/schema/types.js.map +1 -0
  69. package/dist/client/types.d.ts +449 -0
  70. package/dist/client/types.d.ts.map +1 -0
  71. package/dist/client/types.js +149 -0
  72. package/dist/client/types.js.map +1 -0
  73. package/dist/client/workflows.d.ts +51 -0
  74. package/dist/client/workflows.d.ts.map +1 -0
  75. package/dist/client/workflows.js +103 -0
  76. package/dist/client/workflows.js.map +1 -0
  77. package/dist/client/wrapper.d.ts +2198 -0
  78. package/dist/client/wrapper.d.ts.map +1 -0
  79. package/dist/client/wrapper.js +2651 -0
  80. package/dist/client/wrapper.js.map +1 -0
  81. package/dist/component/_generated/api.d.ts +124 -0
  82. package/dist/component/_generated/api.d.ts.map +1 -0
  83. package/dist/component/_generated/api.js +31 -0
  84. package/dist/component/_generated/api.js.map +1 -0
  85. package/dist/component/_generated/component.d.ts +4321 -0
  86. package/dist/component/_generated/component.d.ts.map +1 -0
  87. package/dist/component/_generated/component.js +11 -0
  88. package/dist/component/_generated/component.js.map +1 -0
  89. package/dist/component/_generated/dataModel.d.ts +46 -0
  90. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  91. package/dist/component/_generated/dataModel.js +11 -0
  92. package/dist/component/_generated/dataModel.js.map +1 -0
  93. package/dist/component/_generated/server.d.ts +121 -0
  94. package/dist/component/_generated/server.d.ts.map +1 -0
  95. package/dist/component/_generated/server.js +78 -0
  96. package/dist/component/_generated/server.js.map +1 -0
  97. package/dist/component/auditLog.d.ts +410 -0
  98. package/dist/component/auditLog.d.ts.map +1 -0
  99. package/dist/component/auditLog.js +607 -0
  100. package/dist/component/auditLog.js.map +1 -0
  101. package/dist/component/authorization.d.ts +323 -0
  102. package/dist/component/authorization.d.ts.map +1 -0
  103. package/dist/component/authorization.js +464 -0
  104. package/dist/component/authorization.js.map +1 -0
  105. package/dist/component/authorizationHooks.d.ts +184 -0
  106. package/dist/component/authorizationHooks.d.ts.map +1 -0
  107. package/dist/component/authorizationHooks.js +521 -0
  108. package/dist/component/authorizationHooks.js.map +1 -0
  109. package/dist/component/bulkOperations.d.ts +200 -0
  110. package/dist/component/bulkOperations.d.ts.map +1 -0
  111. package/dist/component/bulkOperations.js +568 -0
  112. package/dist/component/bulkOperations.js.map +1 -0
  113. package/dist/component/contentEntries.d.ts +719 -0
  114. package/dist/component/contentEntries.d.ts.map +1 -0
  115. package/dist/component/contentEntries.js +1617 -0
  116. package/dist/component/contentEntries.js.map +1 -0
  117. package/dist/component/contentEntryMutations.d.ts +505 -0
  118. package/dist/component/contentEntryMutations.d.ts.map +1 -0
  119. package/dist/component/contentEntryMutations.js +1009 -0
  120. package/dist/component/contentEntryMutations.js.map +1 -0
  121. package/dist/component/contentEntryValidation.d.ts +115 -0
  122. package/dist/component/contentEntryValidation.d.ts.map +1 -0
  123. package/dist/component/contentEntryValidation.js +546 -0
  124. package/dist/component/contentEntryValidation.js.map +1 -0
  125. package/dist/component/contentLock.d.ts +328 -0
  126. package/dist/component/contentLock.d.ts.map +1 -0
  127. package/dist/component/contentLock.js +471 -0
  128. package/dist/component/contentLock.js.map +1 -0
  129. package/dist/component/contentTypeMigration.d.ts +411 -0
  130. package/dist/component/contentTypeMigration.d.ts.map +1 -0
  131. package/dist/component/contentTypeMigration.js +805 -0
  132. package/dist/component/contentTypeMigration.js.map +1 -0
  133. package/dist/component/contentTypeMutations.d.ts +975 -0
  134. package/dist/component/contentTypeMutations.d.ts.map +1 -0
  135. package/dist/component/contentTypeMutations.js +768 -0
  136. package/dist/component/contentTypeMutations.js.map +1 -0
  137. package/dist/component/contentTypes.d.ts +538 -0
  138. package/dist/component/contentTypes.d.ts.map +1 -0
  139. package/dist/component/contentTypes.js +304 -0
  140. package/dist/component/contentTypes.js.map +1 -0
  141. package/dist/component/convex.config.d.ts +42 -0
  142. package/dist/component/convex.config.d.ts.map +1 -0
  143. package/dist/component/convex.config.js +43 -0
  144. package/dist/component/convex.config.js.map +1 -0
  145. package/dist/component/documentTypes.d.ts +186 -0
  146. package/dist/component/documentTypes.d.ts.map +1 -0
  147. package/dist/component/documentTypes.js +23 -0
  148. package/dist/component/documentTypes.js.map +1 -0
  149. package/dist/component/eventEmitter.d.ts +281 -0
  150. package/dist/component/eventEmitter.d.ts.map +1 -0
  151. package/dist/component/eventEmitter.js +300 -0
  152. package/dist/component/eventEmitter.js.map +1 -0
  153. package/dist/component/exportImport.d.ts +1120 -0
  154. package/dist/component/exportImport.d.ts.map +1 -0
  155. package/dist/component/exportImport.js +931 -0
  156. package/dist/component/exportImport.js.map +1 -0
  157. package/dist/component/index.d.ts +28 -0
  158. package/dist/component/index.d.ts.map +1 -0
  159. package/dist/component/index.js +142 -0
  160. package/dist/component/index.js.map +1 -0
  161. package/dist/component/lib/deepReferenceResolver.d.ts +252 -0
  162. package/dist/component/lib/deepReferenceResolver.d.ts.map +1 -0
  163. package/dist/component/lib/deepReferenceResolver.js +601 -0
  164. package/dist/component/lib/deepReferenceResolver.js.map +1 -0
  165. package/dist/component/lib/errors.d.ts +306 -0
  166. package/dist/component/lib/errors.d.ts.map +1 -0
  167. package/dist/component/lib/errors.js +407 -0
  168. package/dist/component/lib/errors.js.map +1 -0
  169. package/dist/component/lib/index.d.ts +10 -0
  170. package/dist/component/lib/index.d.ts.map +1 -0
  171. package/dist/component/lib/index.js +33 -0
  172. package/dist/component/lib/index.js.map +1 -0
  173. package/dist/component/lib/mediaReferenceResolver.d.ts +217 -0
  174. package/dist/component/lib/mediaReferenceResolver.d.ts.map +1 -0
  175. package/dist/component/lib/mediaReferenceResolver.js +326 -0
  176. package/dist/component/lib/mediaReferenceResolver.js.map +1 -0
  177. package/dist/component/lib/metadataExtractor.d.ts +245 -0
  178. package/dist/component/lib/metadataExtractor.d.ts.map +1 -0
  179. package/dist/component/lib/metadataExtractor.js +548 -0
  180. package/dist/component/lib/metadataExtractor.js.map +1 -0
  181. package/dist/component/lib/mutationAuth.d.ts +95 -0
  182. package/dist/component/lib/mutationAuth.d.ts.map +1 -0
  183. package/dist/component/lib/mutationAuth.js +146 -0
  184. package/dist/component/lib/mutationAuth.js.map +1 -0
  185. package/dist/component/lib/queries.d.ts +17 -0
  186. package/dist/component/lib/queries.d.ts.map +1 -0
  187. package/dist/component/lib/queries.js +49 -0
  188. package/dist/component/lib/queries.js.map +1 -0
  189. package/dist/component/lib/ragContentChunker.d.ts +423 -0
  190. package/dist/component/lib/ragContentChunker.d.ts.map +1 -0
  191. package/dist/component/lib/ragContentChunker.js +897 -0
  192. package/dist/component/lib/ragContentChunker.js.map +1 -0
  193. package/dist/component/lib/referenceResolver.d.ts +175 -0
  194. package/dist/component/lib/referenceResolver.d.ts.map +1 -0
  195. package/dist/component/lib/referenceResolver.js +293 -0
  196. package/dist/component/lib/referenceResolver.js.map +1 -0
  197. package/dist/component/lib/slugGenerator.d.ts +71 -0
  198. package/dist/component/lib/slugGenerator.d.ts.map +1 -0
  199. package/dist/component/lib/slugGenerator.js +207 -0
  200. package/dist/component/lib/slugGenerator.js.map +1 -0
  201. package/dist/component/lib/slugUniqueness.d.ts +131 -0
  202. package/dist/component/lib/slugUniqueness.d.ts.map +1 -0
  203. package/dist/component/lib/slugUniqueness.js +229 -0
  204. package/dist/component/lib/slugUniqueness.js.map +1 -0
  205. package/dist/component/lib/softDelete.d.ts +18 -0
  206. package/dist/component/lib/softDelete.d.ts.map +1 -0
  207. package/dist/component/lib/softDelete.js +29 -0
  208. package/dist/component/lib/softDelete.js.map +1 -0
  209. package/dist/component/localeFallbackChain.d.ts +410 -0
  210. package/dist/component/localeFallbackChain.d.ts.map +1 -0
  211. package/dist/component/localeFallbackChain.js +467 -0
  212. package/dist/component/localeFallbackChain.js.map +1 -0
  213. package/dist/component/localeFields.d.ts +508 -0
  214. package/dist/component/localeFields.d.ts.map +1 -0
  215. package/dist/component/localeFields.js +592 -0
  216. package/dist/component/localeFields.js.map +1 -0
  217. package/dist/component/mediaAssetMutations.d.ts +235 -0
  218. package/dist/component/mediaAssetMutations.d.ts.map +1 -0
  219. package/dist/component/mediaAssetMutations.js +558 -0
  220. package/dist/component/mediaAssetMutations.js.map +1 -0
  221. package/dist/component/mediaAssets.d.ts +168 -0
  222. package/dist/component/mediaAssets.d.ts.map +1 -0
  223. package/dist/component/mediaAssets.js +618 -0
  224. package/dist/component/mediaAssets.js.map +1 -0
  225. package/dist/component/mediaFolderMutations.d.ts +642 -0
  226. package/dist/component/mediaFolderMutations.d.ts.map +1 -0
  227. package/dist/component/mediaFolderMutations.js +849 -0
  228. package/dist/component/mediaFolderMutations.js.map +1 -0
  229. package/dist/component/mediaUploadMutations.d.ts +136 -0
  230. package/dist/component/mediaUploadMutations.d.ts.map +1 -0
  231. package/dist/component/mediaUploadMutations.js +205 -0
  232. package/dist/component/mediaUploadMutations.js.map +1 -0
  233. package/dist/component/mediaVariantMutations.d.ts +468 -0
  234. package/dist/component/mediaVariantMutations.d.ts.map +1 -0
  235. package/dist/component/mediaVariantMutations.js +737 -0
  236. package/dist/component/mediaVariantMutations.js.map +1 -0
  237. package/dist/component/mediaVariants.d.ts +525 -0
  238. package/dist/component/mediaVariants.d.ts.map +1 -0
  239. package/dist/component/mediaVariants.js +661 -0
  240. package/dist/component/mediaVariants.js.map +1 -0
  241. package/dist/component/ragContentIndexer.d.ts +595 -0
  242. package/dist/component/ragContentIndexer.d.ts.map +1 -0
  243. package/dist/component/ragContentIndexer.js +794 -0
  244. package/dist/component/ragContentIndexer.js.map +1 -0
  245. package/dist/component/rateLimitHooks.d.ts +266 -0
  246. package/dist/component/rateLimitHooks.d.ts.map +1 -0
  247. package/dist/component/rateLimitHooks.js +412 -0
  248. package/dist/component/rateLimitHooks.js.map +1 -0
  249. package/dist/component/roles.d.ts +649 -0
  250. package/dist/component/roles.d.ts.map +1 -0
  251. package/dist/component/roles.js +884 -0
  252. package/dist/component/roles.js.map +1 -0
  253. package/dist/component/scheduledPublish.d.ts +182 -0
  254. package/dist/component/scheduledPublish.d.ts.map +1 -0
  255. package/dist/component/scheduledPublish.js +304 -0
  256. package/dist/component/scheduledPublish.js.map +1 -0
  257. package/dist/component/schema.d.ts +4114 -0
  258. package/dist/component/schema.d.ts.map +1 -0
  259. package/dist/component/schema.js +469 -0
  260. package/dist/component/schema.js.map +1 -0
  261. package/dist/component/taxonomies.d.ts +476 -0
  262. package/dist/component/taxonomies.d.ts.map +1 -0
  263. package/dist/component/taxonomies.js +785 -0
  264. package/dist/component/taxonomies.js.map +1 -0
  265. package/dist/component/taxonomyMutations.d.ts +206 -0
  266. package/dist/component/taxonomyMutations.d.ts.map +1 -0
  267. package/dist/component/taxonomyMutations.js +1001 -0
  268. package/dist/component/taxonomyMutations.js.map +1 -0
  269. package/dist/component/trash.d.ts +265 -0
  270. package/dist/component/trash.d.ts.map +1 -0
  271. package/dist/component/trash.js +621 -0
  272. package/dist/component/trash.js.map +1 -0
  273. package/dist/component/types.d.ts +4 -0
  274. package/dist/component/types.d.ts.map +1 -0
  275. package/dist/component/types.js +2 -0
  276. package/dist/component/types.js.map +1 -0
  277. package/dist/component/userContext.d.ts +508 -0
  278. package/dist/component/userContext.d.ts.map +1 -0
  279. package/dist/component/userContext.js +615 -0
  280. package/dist/component/userContext.js.map +1 -0
  281. package/dist/component/validation.d.ts +387 -0
  282. package/dist/component/validation.d.ts.map +1 -0
  283. package/dist/component/validation.js +1052 -0
  284. package/dist/component/validation.js.map +1 -0
  285. package/dist/component/validators.d.ts +4645 -0
  286. package/dist/component/validators.d.ts.map +1 -0
  287. package/dist/component/validators.js +641 -0
  288. package/dist/component/validators.js.map +1 -0
  289. package/dist/component/versionMutations.d.ts +216 -0
  290. package/dist/component/versionMutations.d.ts.map +1 -0
  291. package/dist/component/versionMutations.js +321 -0
  292. package/dist/component/versionMutations.js.map +1 -0
  293. package/dist/component/webhookTrigger.d.ts +770 -0
  294. package/dist/component/webhookTrigger.d.ts.map +1 -0
  295. package/dist/component/webhookTrigger.js +1413 -0
  296. package/dist/component/webhookTrigger.js.map +1 -0
  297. package/dist/react/index.d.ts +316 -0
  298. package/dist/react/index.d.ts.map +1 -0
  299. package/dist/react/index.js +558 -0
  300. package/dist/react/index.js.map +1 -0
  301. package/dist/test.d.ts +2230 -0
  302. package/dist/test.d.ts.map +1 -0
  303. package/dist/test.js +1107 -0
  304. package/dist/test.js.map +1 -0
  305. package/package.json +95 -0
  306. package/src/cli/commands/admin.ts +104 -0
  307. package/src/cli/index.ts +21 -0
  308. package/src/cli/utils/detectConvexUrl.ts +54 -0
  309. package/src/cli/utils/openBrowser.ts +16 -0
  310. package/src/client/admin-config.ts +138 -0
  311. package/src/client/adminApi.ts +942 -0
  312. package/src/client/agentTools.ts +1311 -0
  313. package/src/client/argTypes.ts +316 -0
  314. package/src/client/field-types.ts +187 -0
  315. package/src/client/index.ts +1301 -0
  316. package/src/client/queryBuilder.ts +1100 -0
  317. package/src/client/schema/codegen.ts +500 -0
  318. package/src/client/schema/defineContentType.ts +501 -0
  319. package/src/client/schema/index.ts +169 -0
  320. package/src/client/schema/schemaDrift.ts +574 -0
  321. package/src/client/schema/typedClient.ts +688 -0
  322. package/src/client/schema/types.ts +666 -0
  323. package/src/client/types.ts +723 -0
  324. package/src/client/workflows.ts +141 -0
  325. package/src/client/wrapper.ts +4304 -0
  326. package/src/component/_generated/api.ts +140 -0
  327. package/src/component/_generated/component.ts +5029 -0
  328. package/src/component/_generated/dataModel.ts +60 -0
  329. package/src/component/_generated/server.ts +156 -0
  330. package/src/component/authorization.ts +647 -0
  331. package/src/component/authorizationHooks.ts +668 -0
  332. package/src/component/bulkOperations.ts +687 -0
  333. package/src/component/contentEntries.ts +1976 -0
  334. package/src/component/contentEntryMutations.ts +1223 -0
  335. package/src/component/contentEntryValidation.ts +707 -0
  336. package/src/component/contentLock.ts +550 -0
  337. package/src/component/contentTypeMigration.ts +1064 -0
  338. package/src/component/contentTypeMutations.ts +969 -0
  339. package/src/component/contentTypes.ts +346 -0
  340. package/src/component/convex.config.ts +44 -0
  341. package/src/component/documentTypes.ts +240 -0
  342. package/src/component/eventEmitter.ts +485 -0
  343. package/src/component/exportImport.ts +1169 -0
  344. package/src/component/index.ts +491 -0
  345. package/src/component/lib/deepReferenceResolver.ts +999 -0
  346. package/src/component/lib/errors.ts +816 -0
  347. package/src/component/lib/index.ts +145 -0
  348. package/src/component/lib/mediaReferenceResolver.ts +495 -0
  349. package/src/component/lib/metadataExtractor.ts +792 -0
  350. package/src/component/lib/mutationAuth.ts +199 -0
  351. package/src/component/lib/queries.ts +79 -0
  352. package/src/component/lib/ragContentChunker.ts +1371 -0
  353. package/src/component/lib/referenceResolver.ts +430 -0
  354. package/src/component/lib/slugGenerator.ts +262 -0
  355. package/src/component/lib/slugUniqueness.ts +333 -0
  356. package/src/component/lib/softDelete.ts +44 -0
  357. package/src/component/localeFallbackChain.ts +673 -0
  358. package/src/component/localeFields.ts +896 -0
  359. package/src/component/mediaAssetMutations.ts +725 -0
  360. package/src/component/mediaAssets.ts +932 -0
  361. package/src/component/mediaFolderMutations.ts +1046 -0
  362. package/src/component/mediaUploadMutations.ts +224 -0
  363. package/src/component/mediaVariantMutations.ts +900 -0
  364. package/src/component/mediaVariants.ts +793 -0
  365. package/src/component/ragContentIndexer.ts +1067 -0
  366. package/src/component/rateLimitHooks.ts +572 -0
  367. package/src/component/roles.ts +1360 -0
  368. package/src/component/scheduledPublish.ts +358 -0
  369. package/src/component/schema.ts +617 -0
  370. package/src/component/taxonomies.ts +949 -0
  371. package/src/component/taxonomyMutations.ts +1210 -0
  372. package/src/component/trash.ts +724 -0
  373. package/src/component/userContext.ts +898 -0
  374. package/src/component/validation.ts +1388 -0
  375. package/src/component/validators.ts +949 -0
  376. package/src/component/versionMutations.ts +392 -0
  377. package/src/component/webhookTrigger.ts +1922 -0
  378. package/src/react/index.ts +898 -0
  379. package/src/test.ts +1580 -0
@@ -0,0 +1,661 @@
1
+ /**
2
+ * Media Variants Query Functions
3
+ *
4
+ * Provides query functions for retrieving media variants (optimized versions
5
+ * of media assets like thumbnails, responsive sizes, and format conversions).
6
+ *
7
+ * Key features:
8
+ * - Get individual variants by ID
9
+ * - List all variants for a media asset
10
+ * - Find best matching variant for target dimensions
11
+ * - Generate responsive srcset data for HTML img tags
12
+ * - Support for variant presets (thumbnail, small, medium, large, etc.)
13
+ */
14
+ import { v } from "convex/values";
15
+ import { isDeleted } from "./lib/softDelete.js";
16
+ import { query } from "./_generated/server.js";
17
+ import { mediaVariantDoc, mediaVariantWithUrlDoc, listMediaVariantsArgs, getMediaVariantArgs, getBestVariantArgs, variantTypeValidator, responsiveSrcsetResult, } from "./validators.js";
18
+ /**
19
+ * Default variant presets for common use cases.
20
+ * These define standard sizes for responsive images and thumbnails.
21
+ */
22
+ export const DEFAULT_VARIANT_PRESETS = {
23
+ thumbnail: {
24
+ name: "thumbnail",
25
+ variantType: "thumbnail",
26
+ width: 150,
27
+ height: 150,
28
+ format: "webp",
29
+ quality: 80,
30
+ description: "Small square thumbnail for previews and lists",
31
+ },
32
+ small: {
33
+ name: "small",
34
+ variantType: "responsive",
35
+ width: 480,
36
+ format: "webp",
37
+ quality: 80,
38
+ description: "Small responsive image (480px wide)",
39
+ },
40
+ medium: {
41
+ name: "medium",
42
+ variantType: "responsive",
43
+ width: 768,
44
+ format: "webp",
45
+ quality: 80,
46
+ description: "Medium responsive image (768px wide)",
47
+ },
48
+ large: {
49
+ name: "large",
50
+ variantType: "responsive",
51
+ width: 1024,
52
+ format: "webp",
53
+ quality: 80,
54
+ description: "Large responsive image (1024px wide)",
55
+ },
56
+ xlarge: {
57
+ name: "xlarge",
58
+ variantType: "responsive",
59
+ width: 1440,
60
+ format: "webp",
61
+ quality: 85,
62
+ description: "Extra large responsive image (1440px wide)",
63
+ },
64
+ webp: {
65
+ name: "webp",
66
+ variantType: "format",
67
+ format: "webp",
68
+ quality: 85,
69
+ description: "WebP format conversion (same dimensions)",
70
+ },
71
+ avif: {
72
+ name: "avif",
73
+ variantType: "format",
74
+ format: "avif",
75
+ quality: 80,
76
+ description: "AVIF format conversion (same dimensions)",
77
+ },
78
+ };
79
+ // =============================================================================
80
+ // Get Single Variant
81
+ // =============================================================================
82
+ /**
83
+ * Query to retrieve a single media variant by ID.
84
+ *
85
+ * Returns the variant metadata along with a resolved storage URL.
86
+ *
87
+ * @param id - The media variant ID to retrieve
88
+ * @param includeDeleted - Whether to include soft-deleted variants (default: false)
89
+ * @returns The media variant document with URL, or null if not found
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const variant = await ctx.runQuery(api.mediaVariants.get, {
94
+ * id: variantId,
95
+ * });
96
+ *
97
+ * if (variant && variant.status === "completed") {
98
+ * console.log("Variant URL:", variant.url);
99
+ * console.log("Dimensions:", variant.width, "x", variant.height);
100
+ * }
101
+ * ```
102
+ */
103
+ export const get = query({
104
+ args: getMediaVariantArgs.fields,
105
+ returns: v.union(mediaVariantWithUrlDoc, v.null()),
106
+ handler: async (ctx, args) => {
107
+ const { id, includeDeleted = false } = args;
108
+ const variant = await ctx.db.get(id);
109
+ if (!variant) {
110
+ return null;
111
+ }
112
+ // Filter out soft-deleted variants unless explicitly requested
113
+ if (!includeDeleted && isDeleted(variant)) {
114
+ return null;
115
+ }
116
+ // Resolve the storage URL
117
+ const url = await ctx.storage.getUrl(variant.storageId);
118
+ return {
119
+ ...variant,
120
+ url,
121
+ };
122
+ },
123
+ });
124
+ // =============================================================================
125
+ // List Variants for Asset
126
+ // =============================================================================
127
+ /**
128
+ * Query to list all variants for a media asset.
129
+ *
130
+ * Supports filtering by variant type, format, preset, and status.
131
+ *
132
+ * @param assetId - The parent media asset ID
133
+ * @param variantType - Filter by variant type (thumbnail, responsive, format)
134
+ * @param format - Filter by output format (webp, avif, jpeg, etc.)
135
+ * @param preset - Filter by preset name
136
+ * @param status - Filter by generation status
137
+ * @param includeDeleted - Include soft-deleted variants (default: false)
138
+ * @returns Array of media variant documents with URLs
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * // List all completed responsive variants
143
+ * const variants = await ctx.runQuery(api.mediaVariants.list, {
144
+ * assetId: assetId,
145
+ * variantType: "responsive",
146
+ * status: "completed",
147
+ * });
148
+ *
149
+ * // List all WebP variants
150
+ * const webpVariants = await ctx.runQuery(api.mediaVariants.list, {
151
+ * assetId: assetId,
152
+ * format: "webp",
153
+ * });
154
+ * ```
155
+ */
156
+ export const list = query({
157
+ args: listMediaVariantsArgs.fields,
158
+ returns: v.array(mediaVariantWithUrlDoc),
159
+ handler: async (ctx, args) => {
160
+ const { assetId, variantType, format, preset, status, includeDeleted = false, } = args;
161
+ // Start with the base query using the asset index
162
+ let variants;
163
+ if (variantType) {
164
+ // Use the compound index for type filtering
165
+ variants = await ctx.db
166
+ .query("mediaVariants")
167
+ .withIndex("by_asset_and_type", (q) => q.eq("assetId", assetId).eq("variantType", variantType))
168
+ .collect();
169
+ }
170
+ else if (preset) {
171
+ // Use the preset index
172
+ variants = await ctx.db
173
+ .query("mediaVariants")
174
+ .withIndex("by_asset_and_preset", (q) => q.eq("assetId", assetId).eq("preset", preset))
175
+ .collect();
176
+ }
177
+ else if (format) {
178
+ // Use the format index
179
+ variants = await ctx.db
180
+ .query("mediaVariants")
181
+ .withIndex("by_asset_and_format", (q) => q.eq("assetId", assetId).eq("format", format))
182
+ .collect();
183
+ }
184
+ else {
185
+ // Default: get all variants for the asset
186
+ variants = await ctx.db
187
+ .query("mediaVariants")
188
+ .withIndex("by_asset", (q) => q.eq("assetId", assetId))
189
+ .collect();
190
+ }
191
+ // Apply post-filters
192
+ let filteredVariants = variants;
193
+ // Filter by soft-delete status
194
+ if (!includeDeleted) {
195
+ filteredVariants = filteredVariants.filter((v) => !isDeleted(v));
196
+ }
197
+ // Apply additional filters that weren't covered by the index
198
+ if (format && !preset && variantType) {
199
+ filteredVariants = filteredVariants.filter((v) => v.format === format);
200
+ }
201
+ if (preset && !format && variantType) {
202
+ filteredVariants = filteredVariants.filter((v) => v.preset === preset);
203
+ }
204
+ if (status) {
205
+ filteredVariants = filteredVariants.filter((v) => v.status === status);
206
+ }
207
+ // Resolve URLs for all variants
208
+ const variantsWithUrls = await Promise.all(filteredVariants.map(async (variant) => {
209
+ const url = await ctx.storage.getUrl(variant.storageId);
210
+ return {
211
+ ...variant,
212
+ url,
213
+ };
214
+ }));
215
+ return variantsWithUrls;
216
+ },
217
+ });
218
+ // =============================================================================
219
+ // Get Best Matching Variant
220
+ // =============================================================================
221
+ /**
222
+ * Query to find the best matching variant for target dimensions.
223
+ *
224
+ * This is useful for serving appropriately sized images based on
225
+ * the display context (e.g., viewport width, container size).
226
+ *
227
+ * Selection logic:
228
+ * 1. Prefer variants matching the preferred format
229
+ * 2. Choose smallest variant that is >= target dimensions
230
+ * 3. If no variant is large enough, choose the largest available
231
+ * 4. Optionally fall back to original asset
232
+ *
233
+ * @param assetId - The parent media asset ID
234
+ * @param targetWidth - Target display width in pixels
235
+ * @param targetHeight - Target display height in pixels
236
+ * @param preferredFormat - Preferred format (e.g., "webp")
237
+ * @param fallbackToOriginal - Return original if no variant matches (default: true)
238
+ * @returns Best matching variant with URL, or null if none found
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * // Get best variant for a 400px wide container, preferring WebP
243
+ * const variant = await ctx.runQuery(api.mediaVariants.getBestVariant, {
244
+ * assetId: assetId,
245
+ * targetWidth: 400,
246
+ * preferredFormat: "webp",
247
+ * });
248
+ *
249
+ * if (variant) {
250
+ * console.log("Using variant:", variant.width, "x", variant.height);
251
+ * console.log("URL:", variant.url);
252
+ * }
253
+ * ```
254
+ */
255
+ export const getBestVariant = query({
256
+ args: getBestVariantArgs.fields,
257
+ returns: v.union(v.object({
258
+ ...mediaVariantWithUrlDoc.fields,
259
+ isOriginal: v.boolean(),
260
+ }), v.null()),
261
+ handler: async (ctx, args) => {
262
+ const { assetId, targetWidth, targetHeight, preferredFormat, fallbackToOriginal = true, } = args;
263
+ // Get all completed variants for the asset
264
+ const variants = await ctx.db
265
+ .query("mediaVariants")
266
+ .withIndex("by_asset", (q) => q.eq("assetId", assetId))
267
+ .filter((q) => q.and(q.eq(q.field("status"), "completed"), q.eq(q.field("deletedAt"), undefined)))
268
+ .collect();
269
+ if (variants.length === 0) {
270
+ // No variants available, try fallback to original
271
+ if (fallbackToOriginal) {
272
+ const item = await ctx.db.get(assetId);
273
+ // Must be an asset (not folder) and not deleted
274
+ if (item && item.kind === "asset" && !isDeleted(item)) {
275
+ const asset = item;
276
+ const url = await ctx.storage.getUrl(asset.storageId);
277
+ return {
278
+ // When isOriginal=true, _id is actually an asset ID, not variant ID.
279
+ // Consumers should check isOriginal before using _id.
280
+ _id: asset._id,
281
+ _creationTime: asset._creationTime,
282
+ assetId: asset._id,
283
+ storageId: asset.storageId,
284
+ variantType: "format",
285
+ width: asset.width,
286
+ height: asset.height,
287
+ format: getFormatFromMimeType(asset.mimeType),
288
+ mimeType: asset.mimeType,
289
+ size: asset.size ?? 0,
290
+ quality: undefined,
291
+ preset: undefined,
292
+ autoGenerated: false,
293
+ status: "completed",
294
+ errorMessage: undefined,
295
+ processingStartedAt: undefined,
296
+ processingCompletedAt: undefined,
297
+ deletedAt: undefined,
298
+ createdBy: asset.createdBy,
299
+ url,
300
+ isOriginal: true,
301
+ };
302
+ }
303
+ }
304
+ return null;
305
+ }
306
+ // Score variants based on match quality
307
+ const scoredVariants = variants.map((variant) => {
308
+ let score = 0;
309
+ // Prefer matching format (+10 points)
310
+ if (preferredFormat && variant.format === preferredFormat) {
311
+ score += 10;
312
+ }
313
+ // Score based on size match
314
+ if (targetWidth && variant.width) {
315
+ if (variant.width >= targetWidth) {
316
+ // Variant is large enough
317
+ // Smaller oversizing is better (less wasted bandwidth)
318
+ const oversizeRatio = variant.width / targetWidth;
319
+ score += 5 - Math.min(4, oversizeRatio - 1); // 5 points for perfect match, down to 1
320
+ }
321
+ else {
322
+ // Variant is too small, but still usable
323
+ const undersizeRatio = variant.width / targetWidth;
324
+ score += undersizeRatio * 2; // Up to 2 points based on how close
325
+ }
326
+ }
327
+ if (targetHeight && variant.height) {
328
+ if (variant.height >= targetHeight) {
329
+ const oversizeRatio = variant.height / targetHeight;
330
+ score += 5 - Math.min(4, oversizeRatio - 1);
331
+ }
332
+ else {
333
+ const undersizeRatio = variant.height / targetHeight;
334
+ score += undersizeRatio * 2;
335
+ }
336
+ }
337
+ // Prefer smaller file sizes for equally scored variants
338
+ score -= variant.size / 1000000; // Subtract MB
339
+ return { variant, score };
340
+ });
341
+ // Sort by score (descending) and pick the best
342
+ scoredVariants.sort((a, b) => b.score - a.score);
343
+ const bestVariant = scoredVariants[0].variant;
344
+ const url = await ctx.storage.getUrl(bestVariant.storageId);
345
+ return {
346
+ ...bestVariant,
347
+ url,
348
+ isOriginal: false,
349
+ };
350
+ },
351
+ });
352
+ // =============================================================================
353
+ // Get Responsive Srcset
354
+ // =============================================================================
355
+ /**
356
+ * Query to generate responsive srcset data for HTML img/picture tags.
357
+ *
358
+ * Returns a complete srcset string and entries array for building
359
+ * responsive images with proper format support.
360
+ *
361
+ * @param assetId - The parent media asset ID
362
+ * @param format - Filter variants by format (optional)
363
+ * @returns Srcset data including src fallback, srcset string, and entries array
364
+ *
365
+ * @example
366
+ * ```typescript
367
+ * const srcsetData = await ctx.runQuery(api.mediaVariants.getResponsiveSrcset, {
368
+ * assetId: assetId,
369
+ * format: "webp",
370
+ * });
371
+ *
372
+ * // Use in HTML:
373
+ * // <img src={srcsetData.src} srcset={srcsetData.srcset} sizes="100vw" />
374
+ *
375
+ * // Or build a picture element:
376
+ * // <picture>
377
+ * // <source srcset={srcsetData.srcset} type="image/webp" />
378
+ * // <img src={srcsetData.src} />
379
+ * // </picture>
380
+ * ```
381
+ */
382
+ export const getResponsiveSrcset = query({
383
+ args: {
384
+ assetId: v.id("mediaItems"),
385
+ format: v.optional(v.string()),
386
+ },
387
+ returns: responsiveSrcsetResult,
388
+ handler: async (ctx, args) => {
389
+ const { assetId, format } = args;
390
+ // Get the original asset for fallback
391
+ const item = await ctx.db.get(assetId);
392
+ // Must be an asset (not folder) and not deleted
393
+ if (!item || item.kind !== "asset" || isDeleted(item)) {
394
+ return {
395
+ src: null,
396
+ srcset: "",
397
+ entries: [],
398
+ sizes: undefined,
399
+ };
400
+ }
401
+ const asset = item;
402
+ const originalUrl = await ctx.storage.getUrl(asset.storageId);
403
+ // Get all completed responsive variants
404
+ let variants;
405
+ if (format) {
406
+ variants = await ctx.db
407
+ .query("mediaVariants")
408
+ .withIndex("by_asset_and_format", (q) => q.eq("assetId", assetId).eq("format", format))
409
+ .filter((q) => q.and(q.eq(q.field("status"), "completed"), q.eq(q.field("deletedAt"), undefined), q.or(q.eq(q.field("variantType"), "responsive"), q.eq(q.field("variantType"), "format"))))
410
+ .collect();
411
+ }
412
+ else {
413
+ variants = await ctx.db
414
+ .query("mediaVariants")
415
+ .withIndex("by_asset", (q) => q.eq("assetId", assetId))
416
+ .filter((q) => q.and(q.eq(q.field("status"), "completed"), q.eq(q.field("deletedAt"), undefined), q.or(q.eq(q.field("variantType"), "responsive"), q.eq(q.field("variantType"), "format"))))
417
+ .collect();
418
+ }
419
+ // Build srcset entries, filtering for variants with width
420
+ const entries = [];
421
+ for (const variant of variants) {
422
+ if (variant.width) {
423
+ const url = await ctx.storage.getUrl(variant.storageId);
424
+ if (url) {
425
+ entries.push({
426
+ url,
427
+ descriptor: `${variant.width}w`,
428
+ width: variant.width,
429
+ format: variant.format,
430
+ });
431
+ }
432
+ }
433
+ }
434
+ // Sort by width ascending
435
+ entries.sort((a, b) => a.width - b.width);
436
+ // Build srcset string
437
+ const srcset = entries.map((e) => `${e.url} ${e.descriptor}`).join(", ");
438
+ // Generate a sizes hint based on available widths
439
+ let sizes;
440
+ if (entries.length > 0) {
441
+ const maxWidth = entries[entries.length - 1].width;
442
+ sizes = `(max-width: ${maxWidth}px) 100vw, ${maxWidth}px`;
443
+ }
444
+ return {
445
+ src: originalUrl,
446
+ srcset,
447
+ entries,
448
+ sizes,
449
+ };
450
+ },
451
+ });
452
+ // =============================================================================
453
+ // Get Variant Presets
454
+ // =============================================================================
455
+ /**
456
+ * Query to get available variant presets.
457
+ *
458
+ * Returns the default preset configurations that can be used
459
+ * when requesting variant generation.
460
+ *
461
+ * @returns Array of preset definitions
462
+ *
463
+ * @example
464
+ * ```typescript
465
+ * const presets = await ctx.runQuery(api.mediaVariants.getPresets);
466
+ *
467
+ * // Available presets: thumbnail, small, medium, large, xlarge, webp, avif
468
+ * for (const preset of presets) {
469
+ * console.log(`${preset.name}: ${preset.width}x${preset.height} ${preset.format}`);
470
+ * }
471
+ * ```
472
+ */
473
+ export const getPresets = query({
474
+ args: {},
475
+ returns: v.array(v.object({
476
+ name: v.string(),
477
+ variantType: variantTypeValidator,
478
+ width: v.optional(v.number()),
479
+ height: v.optional(v.number()),
480
+ format: v.string(),
481
+ quality: v.optional(v.number()),
482
+ description: v.optional(v.string()),
483
+ })),
484
+ handler: async () => {
485
+ return Object.values(DEFAULT_VARIANT_PRESETS);
486
+ },
487
+ });
488
+ // =============================================================================
489
+ // Get Pending Variants (for processing queue)
490
+ // =============================================================================
491
+ /**
492
+ * Query to get variants that are pending or processing.
493
+ *
494
+ * Useful for monitoring the variant generation queue or
495
+ * building a processing system.
496
+ *
497
+ * @param status - Filter by status (pending or processing)
498
+ * @param limit - Maximum number of variants to return (default: 100)
499
+ * @returns Array of variants awaiting processing
500
+ *
501
+ * @example
502
+ * ```typescript
503
+ * // Get pending variants for processing
504
+ * const pending = await ctx.runQuery(api.mediaVariants.getPendingVariants, {
505
+ * status: "pending",
506
+ * limit: 10,
507
+ * });
508
+ *
509
+ * for (const variant of pending) {
510
+ * // Process variant...
511
+ * }
512
+ * ```
513
+ */
514
+ export const getPendingVariants = query({
515
+ args: {
516
+ status: v.optional(v.union(v.literal("pending"), v.literal("processing"))),
517
+ limit: v.optional(v.number()),
518
+ },
519
+ returns: v.array(mediaVariantDoc),
520
+ handler: async (ctx, args) => {
521
+ const { status, limit = 100 } = args;
522
+ let variants;
523
+ if (status) {
524
+ variants = await ctx.db
525
+ .query("mediaVariants")
526
+ .withIndex("by_status", (q) => q.eq("status", status))
527
+ .order("asc") // Process oldest first
528
+ .take(limit);
529
+ }
530
+ else {
531
+ // Get both pending and processing
532
+ const pending = await ctx.db
533
+ .query("mediaVariants")
534
+ .withIndex("by_status", (q) => q.eq("status", "pending"))
535
+ .order("asc")
536
+ .take(limit);
537
+ const processing = await ctx.db
538
+ .query("mediaVariants")
539
+ .withIndex("by_status", (q) => q.eq("status", "processing"))
540
+ .order("asc")
541
+ .take(limit);
542
+ variants = [...pending, ...processing].slice(0, limit);
543
+ }
544
+ return variants;
545
+ },
546
+ });
547
+ // =============================================================================
548
+ // Get Asset with Variants
549
+ // =============================================================================
550
+ /**
551
+ * Query to get a media asset with all its completed variants.
552
+ *
553
+ * Combines the original asset with all available variants
554
+ * for comprehensive media delivery.
555
+ *
556
+ * @param assetId - The media asset ID
557
+ * @returns Asset with variants and URLs
558
+ *
559
+ * @example
560
+ * ```typescript
561
+ * const assetWithVariants = await ctx.runQuery(api.mediaVariants.getAssetWithVariants, {
562
+ * assetId: assetId,
563
+ * });
564
+ *
565
+ * if (assetWithVariants) {
566
+ * console.log("Original:", assetWithVariants.original.url);
567
+ * console.log("Variants:", assetWithVariants.variants.length);
568
+ *
569
+ * // Find thumbnail
570
+ * const thumbnail = assetWithVariants.variants.find(v => v.preset === "thumbnail");
571
+ * }
572
+ * ```
573
+ */
574
+ export const getAssetWithVariants = query({
575
+ args: {
576
+ assetId: v.id("mediaItems"),
577
+ },
578
+ returns: v.union(v.object({
579
+ original: v.object({
580
+ _id: v.id("mediaItems"),
581
+ _creationTime: v.number(),
582
+ name: v.string(),
583
+ mimeType: v.string(),
584
+ size: v.number(),
585
+ width: v.optional(v.number()),
586
+ height: v.optional(v.number()),
587
+ url: v.union(v.string(), v.null()),
588
+ }),
589
+ variants: v.array(mediaVariantWithUrlDoc),
590
+ variantsByType: v.object({
591
+ thumbnail: v.optional(mediaVariantWithUrlDoc),
592
+ responsive: v.array(mediaVariantWithUrlDoc),
593
+ format: v.array(mediaVariantWithUrlDoc),
594
+ }),
595
+ }), v.null()),
596
+ handler: async (ctx, args) => {
597
+ const { assetId } = args;
598
+ // Get the original asset
599
+ const item = await ctx.db.get(assetId);
600
+ // Must be an asset (not folder) and not deleted
601
+ if (!item || item.kind !== "asset" || isDeleted(item)) {
602
+ return null;
603
+ }
604
+ const asset = item;
605
+ const originalUrl = await ctx.storage.getUrl(asset.storageId);
606
+ // Get all completed variants
607
+ const variants = await ctx.db
608
+ .query("mediaVariants")
609
+ .withIndex("by_asset", (q) => q.eq("assetId", assetId))
610
+ .filter((q) => q.and(q.eq(q.field("status"), "completed"), q.eq(q.field("deletedAt"), undefined)))
611
+ .collect();
612
+ // Resolve URLs for all variants
613
+ const variantsWithUrls = await Promise.all(variants.map(async (variant) => {
614
+ const url = await ctx.storage.getUrl(variant.storageId);
615
+ return { ...variant, url };
616
+ }));
617
+ // Organize variants by type
618
+ const thumbnail = variantsWithUrls.find((v) => v.variantType === "thumbnail");
619
+ const responsive = variantsWithUrls
620
+ .filter((v) => v.variantType === "responsive")
621
+ .sort((a, b) => (a.width || 0) - (b.width || 0));
622
+ const formatVariants = variantsWithUrls.filter((v) => v.variantType === "format");
623
+ return {
624
+ original: {
625
+ _id: asset._id,
626
+ _creationTime: asset._creationTime,
627
+ name: asset.name,
628
+ mimeType: asset.mimeType,
629
+ size: asset.size ?? 0,
630
+ width: asset.width,
631
+ height: asset.height,
632
+ url: originalUrl,
633
+ },
634
+ variants: variantsWithUrls,
635
+ variantsByType: {
636
+ thumbnail,
637
+ responsive,
638
+ format: formatVariants,
639
+ },
640
+ };
641
+ },
642
+ });
643
+ // =============================================================================
644
+ // Helper Functions
645
+ // =============================================================================
646
+ /**
647
+ * Extract format string from MIME type.
648
+ */
649
+ function getFormatFromMimeType(mimeType) {
650
+ const formatMap = {
651
+ "image/jpeg": "jpeg",
652
+ "image/jpg": "jpg",
653
+ "image/png": "png",
654
+ "image/webp": "webp",
655
+ "image/avif": "avif",
656
+ "image/gif": "gif",
657
+ "image/svg+xml": "svg",
658
+ };
659
+ return formatMap[mimeType] || mimeType.split("/")[1] || "unknown";
660
+ }
661
+ //# sourceMappingURL=mediaVariants.js.map