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,548 @@
1
+ /**
2
+ * Media Metadata Extractor
3
+ *
4
+ * Internal utility functions for extracting and normalizing metadata from uploaded files.
5
+ * This module provides type-safe metadata extraction based on file MIME types.
6
+ *
7
+ * Since Convex functions don't have direct file access (files are in storage),
8
+ * this extractor works with:
9
+ * 1. Client-provided metadata (dimensions, duration from browser APIs)
10
+ * 2. MIME type analysis for capability detection
11
+ * 3. Filename analysis for additional hints
12
+ *
13
+ * The extractor normalizes and validates this information into a structured format
14
+ * that can be stored in the media asset's metadata field.
15
+ */
16
+ // =============================================================================
17
+ // MIME Type Mappings
18
+ // =============================================================================
19
+ /**
20
+ * MIME types classified as images.
21
+ */
22
+ const IMAGE_MIME_TYPES = new Set([
23
+ "image/jpeg",
24
+ "image/jpg",
25
+ "image/png",
26
+ "image/gif",
27
+ "image/webp",
28
+ "image/avif",
29
+ "image/svg+xml",
30
+ "image/bmp",
31
+ "image/tiff",
32
+ "image/x-icon",
33
+ "image/ico",
34
+ "image/heic",
35
+ "image/heif",
36
+ ]);
37
+ /**
38
+ * MIME types classified as videos.
39
+ */
40
+ const VIDEO_MIME_TYPES = new Set([
41
+ "video/mp4",
42
+ "video/webm",
43
+ "video/ogg",
44
+ "video/quicktime",
45
+ "video/x-msvideo",
46
+ "video/mpeg",
47
+ "video/3gpp",
48
+ "video/x-matroska",
49
+ "video/x-flv",
50
+ ]);
51
+ /**
52
+ * MIME types classified as audio.
53
+ */
54
+ const AUDIO_MIME_TYPES = new Set([
55
+ "audio/mpeg",
56
+ "audio/mp3",
57
+ "audio/ogg",
58
+ "audio/wav",
59
+ "audio/webm",
60
+ "audio/aac",
61
+ "audio/flac",
62
+ "audio/x-m4a",
63
+ "audio/mp4",
64
+ "audio/x-wav",
65
+ ]);
66
+ /**
67
+ * MIME types classified as documents.
68
+ */
69
+ const DOCUMENT_MIME_TYPES = new Set([
70
+ "application/pdf",
71
+ "application/msword",
72
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
73
+ "application/vnd.ms-excel",
74
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
75
+ "application/vnd.ms-powerpoint",
76
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
77
+ "text/plain",
78
+ "text/csv",
79
+ "text/markdown",
80
+ "application/rtf",
81
+ "application/json",
82
+ "application/xml",
83
+ "text/xml",
84
+ ]);
85
+ /**
86
+ * MIME types that support transparency.
87
+ */
88
+ const TRANSPARENT_MIME_TYPES = new Set([
89
+ "image/png",
90
+ "image/webp",
91
+ "image/gif",
92
+ "image/avif",
93
+ "image/svg+xml",
94
+ ]);
95
+ /**
96
+ * Vector image MIME types.
97
+ */
98
+ const VECTOR_MIME_TYPES = new Set(["image/svg+xml"]);
99
+ /**
100
+ * MIME types that support animation.
101
+ */
102
+ const ANIMATED_MIME_TYPES = new Set([
103
+ "image/gif",
104
+ "image/webp",
105
+ "image/avif",
106
+ "image/png", // APNG
107
+ ]);
108
+ /**
109
+ * Web-compatible image MIME types (work natively in all modern browsers).
110
+ */
111
+ const WEB_COMPATIBLE_IMAGE_TYPES = new Set([
112
+ "image/jpeg",
113
+ "image/jpg",
114
+ "image/png",
115
+ "image/gif",
116
+ "image/webp",
117
+ "image/svg+xml",
118
+ "image/avif",
119
+ ]);
120
+ /**
121
+ * Web-compatible video MIME types.
122
+ */
123
+ const WEB_COMPATIBLE_VIDEO_TYPES = new Set([
124
+ "video/mp4",
125
+ "video/webm",
126
+ "video/ogg",
127
+ ]);
128
+ /**
129
+ * Web-compatible audio MIME types.
130
+ */
131
+ const WEB_COMPATIBLE_AUDIO_TYPES = new Set([
132
+ "audio/mpeg",
133
+ "audio/mp3",
134
+ "audio/ogg",
135
+ "audio/wav",
136
+ "audio/webm",
137
+ "audio/aac",
138
+ ]);
139
+ // =============================================================================
140
+ // Helper Functions
141
+ // =============================================================================
142
+ /**
143
+ * Extracts the file extension from a filename.
144
+ *
145
+ * @param filename - The filename to extract the extension from
146
+ * @returns The lowercase extension without the dot, or empty string if none
147
+ */
148
+ export function extractExtension(filename) {
149
+ const lastDot = filename.lastIndexOf(".");
150
+ if (lastDot === -1 || lastDot === filename.length - 1) {
151
+ return "";
152
+ }
153
+ return filename.slice(lastDot + 1).toLowerCase();
154
+ }
155
+ /**
156
+ * Classifies a MIME type into a media category.
157
+ *
158
+ * @param mimeType - The MIME type to classify
159
+ * @returns The media type category
160
+ */
161
+ export function classifyMimeType(mimeType) {
162
+ const normalizedMime = mimeType.toLowerCase();
163
+ if (IMAGE_MIME_TYPES.has(normalizedMime)) {
164
+ return "image";
165
+ }
166
+ if (VIDEO_MIME_TYPES.has(normalizedMime)) {
167
+ return "video";
168
+ }
169
+ if (AUDIO_MIME_TYPES.has(normalizedMime)) {
170
+ return "audio";
171
+ }
172
+ if (DOCUMENT_MIME_TYPES.has(normalizedMime)) {
173
+ return "document";
174
+ }
175
+ // Fallback: check MIME type prefix
176
+ if (normalizedMime.startsWith("image/")) {
177
+ return "image";
178
+ }
179
+ if (normalizedMime.startsWith("video/")) {
180
+ return "video";
181
+ }
182
+ if (normalizedMime.startsWith("audio/")) {
183
+ return "audio";
184
+ }
185
+ if (normalizedMime.startsWith("text/") ||
186
+ normalizedMime.startsWith("application/")) {
187
+ // Check for common document patterns
188
+ if (normalizedMime.includes("document") ||
189
+ normalizedMime.includes("sheet") ||
190
+ normalizedMime.includes("presentation")) {
191
+ return "document";
192
+ }
193
+ }
194
+ return "other";
195
+ }
196
+ /**
197
+ * Calculates aspect ratio from dimensions.
198
+ *
199
+ * @param width - Width in pixels
200
+ * @param height - Height in pixels
201
+ * @returns Aspect ratio rounded to 3 decimal places, or undefined if invalid
202
+ */
203
+ export function calculateAspectRatio(width, height) {
204
+ if (!width || !height || height <= 0 || width <= 0) {
205
+ return undefined;
206
+ }
207
+ return Math.round((width / height) * 1000) / 1000;
208
+ }
209
+ /**
210
+ * Formats duration in seconds to HH:MM:SS format.
211
+ *
212
+ * @param seconds - Duration in seconds
213
+ * @returns Formatted duration string, or undefined if invalid
214
+ */
215
+ export function formatDuration(seconds) {
216
+ if (seconds === undefined || seconds < 0 || !Number.isFinite(seconds)) {
217
+ return undefined;
218
+ }
219
+ const hours = Math.floor(seconds / 3600);
220
+ const minutes = Math.floor((seconds % 3600) / 60);
221
+ const secs = Math.floor(seconds % 60);
222
+ if (hours > 0) {
223
+ return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
224
+ }
225
+ return `${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
226
+ }
227
+ /**
228
+ * Determines the optimal image format for web delivery.
229
+ *
230
+ * @param mimeType - Original MIME type
231
+ * @param supportsTransparency - Whether transparency is needed
232
+ * @returns Suggested format for optimization
233
+ */
234
+ export function suggestImageFormat(mimeType, supportsTransparency) {
235
+ const normalizedMime = mimeType.toLowerCase();
236
+ // SVG stays as SVG (vector)
237
+ if (normalizedMime === "image/svg+xml") {
238
+ return "svg";
239
+ }
240
+ // For photos/complex images, suggest modern formats
241
+ if (supportsTransparency) {
242
+ return "webp"; // WebP supports transparency and has broad support
243
+ }
244
+ // For photos without transparency, AVIF or WebP
245
+ if (normalizedMime === "image/jpeg" || normalizedMime === "image/jpg") {
246
+ return "webp"; // Better compression than JPEG
247
+ }
248
+ return "webp"; // Default to WebP for best compatibility
249
+ }
250
+ /**
251
+ * Categorizes document MIME types into subcategories.
252
+ *
253
+ * @param mimeType - The document MIME type
254
+ * @returns Document category
255
+ */
256
+ export function categorizeDocument(mimeType) {
257
+ const normalizedMime = mimeType.toLowerCase();
258
+ if (normalizedMime === "application/pdf") {
259
+ return "pdf";
260
+ }
261
+ if (normalizedMime === "application/msword" ||
262
+ normalizedMime.includes("wordprocessingml")) {
263
+ return "word";
264
+ }
265
+ if (normalizedMime === "application/vnd.ms-excel" ||
266
+ normalizedMime.includes("spreadsheetml") ||
267
+ normalizedMime === "text/csv") {
268
+ return "spreadsheet";
269
+ }
270
+ if (normalizedMime === "application/vnd.ms-powerpoint" ||
271
+ normalizedMime.includes("presentationml")) {
272
+ return "presentation";
273
+ }
274
+ if (normalizedMime.startsWith("text/") ||
275
+ normalizedMime === "application/json" ||
276
+ normalizedMime === "application/xml") {
277
+ return "text";
278
+ }
279
+ return "other";
280
+ }
281
+ /**
282
+ * Determines if a document can be previewed in the browser.
283
+ *
284
+ * @param mimeType - The document MIME type
285
+ * @returns Whether the document can be previewed
286
+ */
287
+ export function canPreviewDocument(mimeType) {
288
+ const normalizedMime = mimeType.toLowerCase();
289
+ // PDFs can be previewed in most browsers
290
+ if (normalizedMime === "application/pdf") {
291
+ return true;
292
+ }
293
+ // Text-based formats can be displayed
294
+ if (normalizedMime.startsWith("text/")) {
295
+ return true;
296
+ }
297
+ // JSON and XML can be displayed
298
+ if (normalizedMime === "application/json" ||
299
+ normalizedMime === "application/xml" ||
300
+ normalizedMime === "text/xml") {
301
+ return true;
302
+ }
303
+ return false;
304
+ }
305
+ // =============================================================================
306
+ // Main Extraction Function
307
+ // =============================================================================
308
+ /**
309
+ * Extracts and normalizes metadata from uploaded file information.
310
+ *
311
+ * This is the main function to call for metadata extraction. It analyzes
312
+ * the MIME type, filename, and any provided dimensions/duration to build
313
+ * a comprehensive metadata object specific to the file type.
314
+ *
315
+ * @param input - The file information to extract metadata from
316
+ * @returns Structured metadata object with type-specific properties
317
+ *
318
+ * @example
319
+ * ```typescript
320
+ * // Image with dimensions from browser
321
+ * const imageMetadata = extractMetadata({
322
+ * filename: "photo.jpg",
323
+ * mimeType: "image/jpeg",
324
+ * size: 500000,
325
+ * width: 1920,
326
+ * height: 1080,
327
+ * });
328
+ * // Returns ImageMetadata with aspectRatio, suggestedFormat, etc.
329
+ *
330
+ * // Video with duration from browser
331
+ * const videoMetadata = extractMetadata({
332
+ * filename: "clip.mp4",
333
+ * mimeType: "video/mp4",
334
+ * size: 10000000,
335
+ * width: 1920,
336
+ * height: 1080,
337
+ * duration: 120,
338
+ * });
339
+ * // Returns VideoMetadata with durationFormatted, hasBroadBrowserSupport, etc.
340
+ *
341
+ * // Document
342
+ * const docMetadata = extractMetadata({
343
+ * filename: "report.pdf",
344
+ * mimeType: "application/pdf",
345
+ * size: 2000000,
346
+ * pageCount: 15,
347
+ * });
348
+ * // Returns DocumentMetadata with documentCategory, canPreviewInBrowser, etc.
349
+ * ```
350
+ */
351
+ export function extractMetadata(input) {
352
+ const { filename, mimeType, size, width, height, duration, pageCount } = input;
353
+ const normalizedMime = mimeType.toLowerCase();
354
+ const extension = extractExtension(filename);
355
+ const mediaType = classifyMimeType(normalizedMime);
356
+ // Build base metadata
357
+ const base = {
358
+ filename,
359
+ mimeType: normalizedMime,
360
+ size,
361
+ mediaType,
362
+ extension,
363
+ isWebCompatible: false, // Will be set by type-specific logic
364
+ };
365
+ switch (mediaType) {
366
+ case "image":
367
+ return extractImageMetadata(base, normalizedMime, width, height);
368
+ case "video":
369
+ return extractVideoMetadata(base, normalizedMime, width, height, duration);
370
+ case "audio":
371
+ return extractAudioMetadata(base, normalizedMime, duration);
372
+ case "document":
373
+ return extractDocumentMetadata(base, normalizedMime, pageCount);
374
+ default:
375
+ return {
376
+ ...base,
377
+ mediaType: "other",
378
+ isWebCompatible: false,
379
+ };
380
+ }
381
+ }
382
+ /**
383
+ * Extracts image-specific metadata.
384
+ */
385
+ function extractImageMetadata(base, mimeType, width, height) {
386
+ const supportsTransparency = TRANSPARENT_MIME_TYPES.has(mimeType);
387
+ const isVector = VECTOR_MIME_TYPES.has(mimeType);
388
+ const supportsAnimation = ANIMATED_MIME_TYPES.has(mimeType);
389
+ const isWebCompatible = WEB_COMPATIBLE_IMAGE_TYPES.has(mimeType);
390
+ const metadata = {
391
+ ...base,
392
+ mediaType: "image",
393
+ isWebCompatible,
394
+ supportsTransparency,
395
+ isVector,
396
+ supportsAnimation,
397
+ };
398
+ if (width !== undefined && width > 0) {
399
+ metadata.width = width;
400
+ }
401
+ if (height !== undefined && height > 0) {
402
+ metadata.height = height;
403
+ }
404
+ const aspectRatio = calculateAspectRatio(width, height);
405
+ if (aspectRatio !== undefined) {
406
+ metadata.aspectRatio = aspectRatio;
407
+ }
408
+ const suggestedFormat = suggestImageFormat(mimeType, supportsTransparency);
409
+ if (suggestedFormat) {
410
+ metadata.suggestedFormat = suggestedFormat;
411
+ }
412
+ return metadata;
413
+ }
414
+ /**
415
+ * Extracts video-specific metadata.
416
+ */
417
+ function extractVideoMetadata(base, mimeType, width, height, duration) {
418
+ const hasBroadBrowserSupport = WEB_COMPATIBLE_VIDEO_TYPES.has(mimeType);
419
+ const isWebCompatible = hasBroadBrowserSupport;
420
+ const metadata = {
421
+ ...base,
422
+ mediaType: "video",
423
+ isWebCompatible,
424
+ hasBroadBrowserSupport,
425
+ };
426
+ if (width !== undefined && width > 0) {
427
+ metadata.width = width;
428
+ }
429
+ if (height !== undefined && height > 0) {
430
+ metadata.height = height;
431
+ }
432
+ const aspectRatio = calculateAspectRatio(width, height);
433
+ if (aspectRatio !== undefined) {
434
+ metadata.aspectRatio = aspectRatio;
435
+ }
436
+ if (duration !== undefined && duration >= 0) {
437
+ metadata.duration = duration;
438
+ metadata.durationFormatted = formatDuration(duration);
439
+ }
440
+ // Infer codec from MIME type
441
+ if (mimeType === "video/mp4") {
442
+ metadata.codec = "H.264/AVC";
443
+ }
444
+ else if (mimeType === "video/webm") {
445
+ metadata.codec = "VP8/VP9";
446
+ }
447
+ else if (mimeType === "video/ogg") {
448
+ metadata.codec = "Theora";
449
+ }
450
+ return metadata;
451
+ }
452
+ /**
453
+ * Extracts audio-specific metadata.
454
+ */
455
+ function extractAudioMetadata(base, mimeType, duration) {
456
+ const hasBroadBrowserSupport = WEB_COMPATIBLE_AUDIO_TYPES.has(mimeType);
457
+ const isWebCompatible = hasBroadBrowserSupport;
458
+ const metadata = {
459
+ ...base,
460
+ mediaType: "audio",
461
+ isWebCompatible,
462
+ hasBroadBrowserSupport,
463
+ };
464
+ if (duration !== undefined && duration >= 0) {
465
+ metadata.duration = duration;
466
+ metadata.durationFormatted = formatDuration(duration);
467
+ }
468
+ // Infer codec from MIME type
469
+ if (mimeType === "audio/mpeg" || mimeType === "audio/mp3") {
470
+ metadata.codec = "MP3";
471
+ }
472
+ else if (mimeType === "audio/ogg") {
473
+ metadata.codec = "Vorbis";
474
+ }
475
+ else if (mimeType === "audio/wav" || mimeType === "audio/x-wav") {
476
+ metadata.codec = "PCM";
477
+ }
478
+ else if (mimeType === "audio/aac") {
479
+ metadata.codec = "AAC";
480
+ }
481
+ else if (mimeType === "audio/flac") {
482
+ metadata.codec = "FLAC";
483
+ }
484
+ return metadata;
485
+ }
486
+ /**
487
+ * Extracts document-specific metadata.
488
+ */
489
+ function extractDocumentMetadata(base, mimeType, pageCount) {
490
+ const documentCategory = categorizeDocument(mimeType);
491
+ const canPreview = canPreviewDocument(mimeType);
492
+ const metadata = {
493
+ ...base,
494
+ mediaType: "document",
495
+ isWebCompatible: canPreview,
496
+ documentCategory,
497
+ canPreviewInBrowser: canPreview,
498
+ };
499
+ if (pageCount !== undefined && pageCount > 0) {
500
+ metadata.pageCount = pageCount;
501
+ }
502
+ return metadata;
503
+ }
504
+ // =============================================================================
505
+ // Validation Helpers
506
+ // =============================================================================
507
+ /**
508
+ * Validates that dimensions are positive integers.
509
+ *
510
+ * @param width - Width to validate
511
+ * @param height - Height to validate
512
+ * @returns Whether both dimensions are valid
513
+ */
514
+ export function validateDimensions(width, height) {
515
+ if (width !== undefined) {
516
+ if (!Number.isInteger(width) || width <= 0) {
517
+ return false;
518
+ }
519
+ }
520
+ if (height !== undefined) {
521
+ if (!Number.isInteger(height) || height <= 0) {
522
+ return false;
523
+ }
524
+ }
525
+ return true;
526
+ }
527
+ /**
528
+ * Validates that duration is a non-negative number.
529
+ *
530
+ * @param duration - Duration to validate
531
+ * @returns Whether the duration is valid
532
+ */
533
+ export function validateDuration(duration) {
534
+ if (duration === undefined) {
535
+ return true;
536
+ }
537
+ return Number.isFinite(duration) && duration >= 0;
538
+ }
539
+ /**
540
+ * Validates that file size is a positive integer.
541
+ *
542
+ * @param size - File size to validate
543
+ * @returns Whether the size is valid
544
+ */
545
+ export function validateFileSize(size) {
546
+ return Number.isInteger(size) && size > 0;
547
+ }
548
+ //# sourceMappingURL=metadataExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadataExtractor.js","sourceRoot":"","sources":["../../../src/component/lib/metadataExtractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAyIH,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,YAAY;IACZ,WAAW;IACX,WAAW;IACX,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,WAAW;IACX,YAAY;IACZ,cAAc;IACd,WAAW;IACX,YAAY;IACZ,YAAY;CACb,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,WAAW;IACX,YAAY;IACZ,WAAW;IACX,iBAAiB;IACjB,iBAAiB;IACjB,YAAY;IACZ,YAAY;IACZ,kBAAkB;IAClB,aAAa;CACd,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,YAAY;IACZ,WAAW;IACX,WAAW;IACX,WAAW;IACX,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,aAAa;IACb,WAAW;IACX,aAAa;CACd,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,iBAAiB;IACjB,oBAAoB;IACpB,yEAAyE;IACzE,0BAA0B;IAC1B,mEAAmE;IACnE,+BAA+B;IAC/B,2EAA2E;IAC3E,YAAY;IACZ,UAAU;IACV,eAAe;IACf,iBAAiB;IACjB,kBAAkB;IAClB,iBAAiB;IACjB,UAAU;CACX,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACrC,WAAW;IACX,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,eAAe;CAChB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,WAAW,EAAE,OAAO;CACrB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC;IACzC,YAAY;IACZ,WAAW;IACX,WAAW;IACX,WAAW;IACX,YAAY;IACZ,eAAe;IACf,YAAY;CACb,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC;IACzC,WAAW;IACX,YAAY;IACZ,WAAW;CACZ,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC;IACzC,YAAY;IACZ,WAAW;IACX,WAAW;IACX,WAAW;IACX,YAAY;IACZ,WAAW;CACZ,CAAC,CAAC;AAEH,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAgB;IAEhB,MAAM,cAAc,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE9C,IAAI,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QACzC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QACzC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QACzC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,mCAAmC;IACnC,IAAI,cAAc,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,cAAc,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,cAAc,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IACE,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC;QAClC,cAAc,CAAC,UAAU,CAAC,cAAc,CAAC,EACzC,CAAC;QACD,qCAAqC;QACrC,IACE,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC;YACnC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC;YAChC,cAAc,CAAC,QAAQ,CAAC,cAAc,CAAC,EACvC,CAAC;YACD,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAc,EACd,MAAe;IAEf,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IAEtC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IAC3H,CAAC;IACD,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACtF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAgB,EAChB,oBAA6B;IAE7B,MAAM,cAAc,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE9C,4BAA4B;IAC5B,IAAI,cAAc,KAAK,eAAe,EAAE,CAAC;QACvC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oDAAoD;IACpD,IAAI,oBAAoB,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,CAAC,mDAAmD;IACpE,CAAC;IAED,gDAAgD;IAChD,IAAI,cAAc,KAAK,YAAY,IAAI,cAAc,KAAK,WAAW,EAAE,CAAC;QACtE,OAAO,MAAM,CAAC,CAAC,+BAA+B;IAChD,CAAC;IAED,OAAO,MAAM,CAAC,CAAC,yCAAyC;AAC1D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAgB;IAEhB,MAAM,cAAc,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE9C,IAAI,cAAc,KAAK,iBAAiB,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IACE,cAAc,KAAK,oBAAoB;QACvC,cAAc,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAC3C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IACE,cAAc,KAAK,0BAA0B;QAC7C,cAAc,CAAC,QAAQ,CAAC,eAAe,CAAC;QACxC,cAAc,KAAK,UAAU,EAC7B,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IACE,cAAc,KAAK,+BAA+B;QAClD,cAAc,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EACzC,CAAC;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IACE,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC;QAClC,cAAc,KAAK,kBAAkB;QACrC,cAAc,KAAK,iBAAiB,EACpC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,cAAc,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE9C,yCAAyC;IACzC,IAAI,cAAc,KAAK,iBAAiB,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sCAAsC;IACtC,IAAI,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gCAAgC;IAChC,IACE,cAAc,KAAK,kBAAkB;QACrC,cAAc,KAAK,iBAAiB;QACpC,cAAc,KAAK,UAAU,EAC7B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,UAAU,eAAe,CAAC,KAA8B;IAC5D,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE/E,MAAM,cAAc,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC9C,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAEnD,sBAAsB;IACtB,MAAM,IAAI,GAAiB;QACzB,QAAQ;QACR,QAAQ,EAAE,cAAc;QACxB,IAAI;QACJ,SAAS;QACT,SAAS;QACT,eAAe,EAAE,KAAK,EAAE,qCAAqC;KAC9D,CAAC;IAEF,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,oBAAoB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAEnE,KAAK,OAAO;YACV,OAAO,oBAAoB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAE7E,KAAK,OAAO;YACV,OAAO,oBAAoB,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;QAE9D,KAAK,UAAU;YACb,OAAO,uBAAuB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;QAElE;YACE,OAAO;gBACL,GAAG,IAAI;gBACP,SAAS,EAAE,OAAO;gBAClB,eAAe,EAAE,KAAK;aACvB,CAAC;IACN,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,IAAkB,EAClB,QAAgB,EAChB,KAAc,EACd,MAAe;IAEf,MAAM,oBAAoB,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5D,MAAM,eAAe,GAAG,0BAA0B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEjE,MAAM,QAAQ,GAAkB;QAC9B,GAAG,IAAI;QACP,SAAS,EAAE,OAAO;QAClB,eAAe;QACf,oBAAoB;QACpB,QAAQ;QACR,iBAAiB;KAClB,CAAC;IAEF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;IACzB,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IAC3B,CAAC;IAED,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,QAAQ,CAAC,WAAW,GAAG,WAAW,CAAC;IACrC,CAAC;IAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;IAC3E,IAAI,eAAe,EAAE,CAAC;QACpB,QAAQ,CAAC,eAAe,GAAG,eAAe,CAAC;IAC7C,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,IAAkB,EAClB,QAAgB,EAChB,KAAc,EACd,MAAe,EACf,QAAiB;IAEjB,MAAM,sBAAsB,GAAG,0BAA0B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,eAAe,GAAG,sBAAsB,CAAC;IAE/C,MAAM,QAAQ,GAAkB;QAC9B,GAAG,IAAI;QACP,SAAS,EAAE,OAAO;QAClB,eAAe;QACf,sBAAsB;KACvB,CAAC;IAEF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;IACzB,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IAC3B,CAAC;IAED,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,QAAQ,CAAC,WAAW,GAAG,WAAW,CAAC;IACrC,CAAC;IAED,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAC5C,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC7B,QAAQ,CAAC,iBAAiB,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC;IAED,6BAA6B;IAC7B,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,QAAQ,CAAC,KAAK,GAAG,WAAW,CAAC;IAC/B,CAAC;SAAM,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QACrC,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;IAC7B,CAAC;SAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,IAAkB,EAClB,QAAgB,EAChB,QAAiB;IAEjB,MAAM,sBAAsB,GAAG,0BAA0B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,eAAe,GAAG,sBAAsB,CAAC;IAE/C,MAAM,QAAQ,GAAkB;QAC9B,GAAG,IAAI;QACP,SAAS,EAAE,OAAO;QAClB,eAAe;QACf,sBAAsB;KACvB,CAAC;IAEF,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAC5C,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC7B,QAAQ,CAAC,iBAAiB,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC;IAED,6BAA6B;IAC7B,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC1D,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;IACzB,CAAC;SAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC;IAC5B,CAAC;SAAM,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;QAClE,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;IACzB,CAAC;SAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;IACzB,CAAC;SAAM,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QACrC,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC;IAC1B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAC9B,IAAkB,EAClB,QAAgB,EAChB,SAAkB;IAElB,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAqB;QACjC,GAAG,IAAI;QACP,SAAS,EAAE,UAAU;QACrB,eAAe,EAAE,UAAU;QAC3B,gBAAgB;QAChB,mBAAmB,EAAE,UAAU;KAChC,CAAC;IAEF,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAC7C,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC;IACjC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc,EAAE,MAAe;IAChE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAC7C,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAiB;IAChD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Mutation-Level Authorization Helper
3
+ *
4
+ * Provides defense-in-depth authorization for component mutations.
5
+ * When auth context is provided, mutations verify the role has permission.
6
+ *
7
+ * This complements the client wrapper's authorization:
8
+ * - Client wrapper: Primary authorization layer (runs hooks, RBAC)
9
+ * - Mutation auth: Secondary validation layer (pure RBAC check)
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { requireMutationAuth } from "./lib/mutationAuth.js";
14
+ *
15
+ * export const createEntry = mutation({
16
+ * args: {
17
+ * ...createContentEntryArgs.fields,
18
+ * _auth: v.optional(mutationAuthContext),
19
+ * },
20
+ * handler: async (ctx, args) => {
21
+ * requireMutationAuth(args._auth, "contentEntries", "create");
22
+ * // ... mutation logic
23
+ * },
24
+ * });
25
+ * ```
26
+ */
27
+ import type { MutationAuthContext } from "../validators.js";
28
+ import { type Resource, type Action, type RoleDefinition } from "../roles.js";
29
+ /**
30
+ * Options for mutation authorization check.
31
+ */
32
+ export interface MutationAuthOptions {
33
+ /**
34
+ * Custom role definitions to include in permission checks.
35
+ * These are in addition to the default roles (admin, editor, author, viewer).
36
+ */
37
+ customRoles?: Record<string, RoleDefinition>;
38
+ }
39
+ /**
40
+ * Verify the auth context has permission for the requested operation.
41
+ *
42
+ * This function:
43
+ * 1. If `_auth` is undefined, does nothing (backwards compatible)
44
+ * 2. If `_auth` is provided, checks the role has permission
45
+ * 3. Throws CMSError with PERMISSION_DENIED if check fails
46
+ *
47
+ * For ownership-scoped permissions (e.g., author editing their own content):
48
+ * - If the role only has "own" scope, verifies resourceOwnerId matches userId
49
+ * - If the role has "all" scope, ownership is not checked
50
+ *
51
+ * @param auth - The auth context from mutation args (may be undefined)
52
+ * @param resource - The resource being accessed (e.g., "contentEntries")
53
+ * @param action - The action being performed (e.g., "create", "update")
54
+ * @param options - Optional configuration including custom roles
55
+ * @throws CMSError with code PERMISSION_DENIED if authorization fails
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * // Basic usage - check if role can create content entries
60
+ * requireMutationAuth(args._auth, "contentEntries", "create");
61
+ *
62
+ * // For update/delete - include resource owner for "own" scope check
63
+ * const entry = await ctx.db.get(args.id);
64
+ * requireMutationAuth(
65
+ * { ...args._auth, resourceOwnerId: entry.createdBy },
66
+ * "contentEntries",
67
+ * "update"
68
+ * );
69
+ * ```
70
+ */
71
+ export declare function requireMutationAuth(auth: MutationAuthContext | undefined, resource: Resource, action: Action, options?: MutationAuthOptions): void;
72
+ /**
73
+ * Check if auth context has permission without throwing.
74
+ *
75
+ * Useful for conditional logic based on permissions.
76
+ *
77
+ * @param auth - The auth context from mutation args
78
+ * @param resource - The resource being accessed
79
+ * @param action - The action being performed
80
+ * @param options - Optional configuration including custom roles
81
+ * @returns true if authorized, false otherwise
82
+ */
83
+ export declare function hasMutationAuth(auth: MutationAuthContext | undefined, resource: Resource, action: Action, options?: MutationAuthOptions): boolean;
84
+ /**
85
+ * Augment auth context with resource owner information.
86
+ *
87
+ * Use this when you have an auth context and need to add ownership info
88
+ * for permission checks on existing resources.
89
+ *
90
+ * @param auth - The original auth context
91
+ * @param resourceOwnerId - The owner of the resource being accessed
92
+ * @returns Auth context with resourceOwnerId set
93
+ */
94
+ export declare function withResourceOwner(auth: MutationAuthContext | undefined, resourceOwnerId: string | undefined): MutationAuthContext | undefined;
95
+ //# sourceMappingURL=mutationAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutationAuth.d.ts","sourceRoot":"","sources":["../../../src/component/lib/mutationAuth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAiB,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7F;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,mBAAmB,GAAG,SAAS,EACrC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,mBAAmB,GAC5B,IAAI,CAoDN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,mBAAmB,GAAG,SAAS,EACrC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CA6BT;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,mBAAmB,GAAG,SAAS,EACrC,eAAe,EAAE,MAAM,GAAG,SAAS,GAClC,mBAAmB,GAAG,SAAS,CAKjC"}