vidspotai-shared 1.0.82-dev.0 → 1.0.83

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 (468) hide show
  1. package/lib/globals/aiModels/enums.d.ts +11 -1
  2. package/lib/globals/aiModels/enums.d.ts.map +1 -1
  3. package/lib/globals/aiModels/enums.js +24 -1
  4. package/lib/globals/aiModels/index.d.ts.map +1 -1
  5. package/lib/globals/aiModels/index.js +2 -0
  6. package/lib/globals/aiModels/providers/anthropic.d.ts +12 -0
  7. package/lib/globals/aiModels/providers/anthropic.d.ts.map +1 -0
  8. package/lib/globals/aiModels/providers/anthropic.js +88 -0
  9. package/lib/globals/aiModels/providers/google.d.ts.map +1 -1
  10. package/lib/globals/aiModels/providers/google.js +115 -10
  11. package/lib/globals/aiModels/providers/openai.d.ts.map +1 -1
  12. package/lib/globals/aiModels/providers/openai.js +63 -4
  13. package/lib/globals/aiModels/tierHelpers.d.ts +12 -0
  14. package/lib/globals/aiModels/tierHelpers.d.ts.map +1 -1
  15. package/lib/globals/aiModels/tierHelpers.js +83 -0
  16. package/lib/globals/aiModels/types.d.ts +19 -0
  17. package/lib/globals/aiModels/types.d.ts.map +1 -1
  18. package/lib/globals/types.d.ts +120 -1
  19. package/lib/globals/types.d.ts.map +1 -1
  20. package/lib/globals/types.js +135 -1
  21. package/lib/models/agent.model.d.ts +41 -1
  22. package/lib/models/agent.model.d.ts.map +1 -1
  23. package/lib/models/index.d.ts +1 -0
  24. package/lib/models/index.d.ts.map +1 -1
  25. package/lib/models/index.js +1 -0
  26. package/lib/models/social.model.d.ts +180 -0
  27. package/lib/models/social.model.d.ts.map +1 -0
  28. package/lib/models/social.model.js +2 -0
  29. package/lib/models/user.model.d.ts +10 -0
  30. package/lib/models/user.model.d.ts.map +1 -1
  31. package/lib/models/video.model.d.ts +6 -0
  32. package/lib/models/video.model.d.ts.map +1 -1
  33. package/lib/schemas/brief.schema.d.ts +46 -0
  34. package/lib/schemas/brief.schema.d.ts.map +1 -1
  35. package/lib/schemas/brief.schema.js +72 -1
  36. package/lib/schemas/index.d.ts +1 -0
  37. package/lib/schemas/index.d.ts.map +1 -1
  38. package/lib/schemas/index.js +1 -0
  39. package/lib/schemas/project.schema.d.ts +70 -3
  40. package/lib/schemas/project.schema.d.ts.map +1 -1
  41. package/lib/schemas/project.schema.js +12 -0
  42. package/lib/schemas/social.schema.d.ts +91 -0
  43. package/lib/schemas/social.schema.d.ts.map +1 -0
  44. package/lib/schemas/social.schema.js +114 -0
  45. package/lib/schemas/videoPlan.schema.d.ts +117 -3
  46. package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
  47. package/lib/schemas/videoPlan.schema.js +141 -1
  48. package/lib/services/agent/chatAgent.d.ts +25 -1
  49. package/lib/services/agent/chatAgent.d.ts.map +1 -1
  50. package/lib/services/agent/chatAgent.js +145 -9
  51. package/lib/services/agent/costPreflight.d.ts +11 -1
  52. package/lib/services/agent/costPreflight.d.ts.map +1 -1
  53. package/lib/services/agent/costPreflight.js +18 -1
  54. package/lib/services/agent/covers/coverPlanner.d.ts +41 -0
  55. package/lib/services/agent/covers/coverPlanner.d.ts.map +1 -0
  56. package/lib/services/agent/covers/coverPlanner.js +278 -0
  57. package/lib/services/agent/covers/covers.schema.d.ts +158 -0
  58. package/lib/services/agent/covers/covers.schema.d.ts.map +1 -0
  59. package/lib/services/agent/covers/covers.schema.js +166 -0
  60. package/lib/services/agent/covers/index.d.ts +3 -0
  61. package/lib/services/agent/covers/index.d.ts.map +1 -0
  62. package/lib/services/agent/covers/index.js +18 -0
  63. package/lib/services/agent/critic.d.ts +10 -0
  64. package/lib/services/agent/critic.d.ts.map +1 -1
  65. package/lib/services/agent/critic.js +37 -1
  66. package/lib/services/agent/editClassifier.d.ts +4 -4
  67. package/lib/services/agent/editClassifier.js +2 -2
  68. package/lib/services/agent/editExisting/editAssembler.d.ts +78 -0
  69. package/lib/services/agent/editExisting/editAssembler.d.ts.map +1 -0
  70. package/lib/services/agent/editExisting/editAssembler.js +172 -0
  71. package/lib/services/agent/editExisting/editExisting.schema.d.ts +119 -0
  72. package/lib/services/agent/editExisting/editExisting.schema.d.ts.map +1 -0
  73. package/lib/services/agent/editExisting/editExisting.schema.js +157 -0
  74. package/lib/services/agent/editExisting/highlightPicker.d.ts +48 -0
  75. package/lib/services/agent/editExisting/highlightPicker.d.ts.map +1 -0
  76. package/lib/services/agent/editExisting/highlightPicker.js +199 -0
  77. package/lib/services/agent/editExisting/index.d.ts +4 -0
  78. package/lib/services/agent/editExisting/index.d.ts.map +1 -0
  79. package/lib/services/agent/editExisting/index.js +19 -0
  80. package/lib/services/agent/eval/recorder.d.ts +13 -1
  81. package/lib/services/agent/eval/recorder.d.ts.map +1 -1
  82. package/lib/services/agent/eval/recorder.js +59 -0
  83. package/lib/services/agent/eval/seedBriefs.d.ts +4 -3
  84. package/lib/services/agent/eval/seedBriefs.d.ts.map +1 -1
  85. package/lib/services/agent/eval/seedBriefs.js +283 -3
  86. package/lib/services/agent/eval/types.d.ts +10 -0
  87. package/lib/services/agent/eval/types.d.ts.map +1 -1
  88. package/lib/services/agent/executor/core.d.ts +70 -0
  89. package/lib/services/agent/executor/core.d.ts.map +1 -0
  90. package/lib/services/agent/executor/core.js +250 -0
  91. package/lib/services/agent/executor/duration.d.ts +20 -0
  92. package/lib/services/agent/executor/duration.d.ts.map +1 -0
  93. package/lib/services/agent/executor/duration.js +46 -0
  94. package/lib/services/agent/executor/index.d.ts +15 -0
  95. package/lib/services/agent/executor/index.d.ts.map +1 -0
  96. package/lib/services/agent/executor/index.js +32 -0
  97. package/lib/services/agent/executor/types.d.ts +183 -0
  98. package/lib/services/agent/executor/types.d.ts.map +1 -0
  99. package/lib/services/agent/executor/types.js +29 -0
  100. package/lib/services/agent/executor/visual.d.ts +32 -0
  101. package/lib/services/agent/executor/visual.d.ts.map +1 -0
  102. package/lib/services/agent/executor/visual.js +400 -0
  103. package/lib/services/agent/executor/voice.d.ts +17 -0
  104. package/lib/services/agent/executor/voice.d.ts.map +1 -0
  105. package/lib/services/agent/executor/voice.js +119 -0
  106. package/lib/services/agent/extendChain.d.ts +101 -0
  107. package/lib/services/agent/extendChain.d.ts.map +1 -0
  108. package/lib/services/agent/extendChain.js +177 -0
  109. package/lib/services/agent/index.d.ts +11 -1
  110. package/lib/services/agent/index.d.ts.map +1 -1
  111. package/lib/services/agent/index.js +11 -1
  112. package/lib/services/agent/llmCaller.d.ts +7 -8
  113. package/lib/services/agent/llmCaller.d.ts.map +1 -1
  114. package/lib/services/agent/llmCallerAnthropic.d.ts +44 -31
  115. package/lib/services/agent/llmCallerAnthropic.d.ts.map +1 -1
  116. package/lib/services/agent/llmCallerAnthropic.js +135 -60
  117. package/lib/services/agent/llmCallerFactory.d.ts +34 -0
  118. package/lib/services/agent/llmCallerFactory.d.ts.map +1 -0
  119. package/lib/services/agent/llmCallerFactory.js +31 -0
  120. package/lib/services/agent/llmCallerGemini.d.ts +62 -0
  121. package/lib/services/agent/llmCallerGemini.d.ts.map +1 -0
  122. package/lib/services/agent/llmCallerGemini.js +235 -0
  123. package/lib/services/agent/llmCallerOpenai.d.ts +56 -0
  124. package/lib/services/agent/llmCallerOpenai.d.ts.map +1 -0
  125. package/lib/services/agent/llmCallerOpenai.js +230 -0
  126. package/lib/services/agent/llmCallerRegistry.d.ts.map +1 -1
  127. package/lib/services/agent/llmCallerRegistry.js +7 -7
  128. package/lib/services/agent/llmCallerRouting.d.ts +63 -0
  129. package/lib/services/agent/llmCallerRouting.d.ts.map +1 -0
  130. package/lib/services/agent/llmCallerRouting.js +124 -0
  131. package/lib/services/agent/llmModelRegistry.d.ts +59 -0
  132. package/lib/services/agent/llmModelRegistry.d.ts.map +1 -0
  133. package/lib/services/agent/llmModelRegistry.js +168 -0
  134. package/lib/services/agent/llmRetry.d.ts +57 -0
  135. package/lib/services/agent/llmRetry.d.ts.map +1 -0
  136. package/lib/services/agent/llmRetry.js +102 -0
  137. package/lib/services/agent/modelRouter.d.ts +3 -3
  138. package/lib/services/agent/modelRouter.d.ts.map +1 -1
  139. package/lib/services/agent/modelRouter.js +27 -13
  140. package/lib/services/agent/planMutations.d.ts +54 -1
  141. package/lib/services/agent/planMutations.d.ts.map +1 -1
  142. package/lib/services/agent/planMutations.js +78 -0
  143. package/lib/services/agent/planner/Planner.d.ts +0 -17
  144. package/lib/services/agent/planner/Planner.d.ts.map +1 -1
  145. package/lib/services/agent/planner/Planner.js +67 -303
  146. package/lib/services/agent/planner/overlayRegen.d.ts +38 -0
  147. package/lib/services/agent/planner/overlayRegen.d.ts.map +1 -0
  148. package/lib/services/agent/planner/overlayRegen.js +145 -0
  149. package/lib/services/agent/planner/plannerMessages.d.ts +34 -0
  150. package/lib/services/agent/planner/plannerMessages.d.ts.map +1 -0
  151. package/lib/services/agent/planner/plannerMessages.js +185 -0
  152. package/lib/services/agent/planner/promptSections.d.ts +12 -0
  153. package/lib/services/agent/planner/promptSections.d.ts.map +1 -1
  154. package/lib/services/agent/planner/promptSections.js +57 -0
  155. package/lib/services/agent/planner/scriptFirstPlanner.d.ts +35 -0
  156. package/lib/services/agent/planner/scriptFirstPlanner.d.ts.map +1 -0
  157. package/lib/services/agent/planner/scriptFirstPlanner.js +140 -0
  158. package/lib/services/agent/planner/structuralRules.d.ts +10 -0
  159. package/lib/services/agent/planner/structuralRules.d.ts.map +1 -1
  160. package/lib/services/agent/planner/structuralRules.js +92 -9
  161. package/lib/services/agent/planner/validators.d.ts +18 -0
  162. package/lib/services/agent/planner/validators.d.ts.map +1 -1
  163. package/lib/services/agent/planner/validators.js +97 -0
  164. package/lib/services/agent/planner.d.ts +2 -1
  165. package/lib/services/agent/planner.d.ts.map +1 -1
  166. package/lib/services/agent/planner.js +5 -1
  167. package/lib/services/agent/priorProject.d.ts +26 -0
  168. package/lib/services/agent/priorProject.d.ts.map +1 -0
  169. package/lib/services/agent/priorProject.js +51 -0
  170. package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
  171. package/lib/services/agent/providerFallback/chains.js +27 -15
  172. package/lib/services/agent/repurpose/index.d.ts +3 -0
  173. package/lib/services/agent/repurpose/index.d.ts.map +1 -0
  174. package/lib/services/agent/repurpose/index.js +18 -0
  175. package/lib/services/agent/repurpose/repurpose.schema.d.ts +132 -0
  176. package/lib/services/agent/repurpose/repurpose.schema.d.ts.map +1 -0
  177. package/lib/services/agent/repurpose/repurpose.schema.js +144 -0
  178. package/lib/services/agent/repurpose/shortsPicker.d.ts +25 -0
  179. package/lib/services/agent/repurpose/shortsPicker.d.ts.map +1 -0
  180. package/lib/services/agent/repurpose/shortsPicker.js +218 -0
  181. package/lib/services/agent/runHelpers.d.ts +21 -2
  182. package/lib/services/agent/runHelpers.d.ts.map +1 -1
  183. package/lib/services/agent/runHelpers.js +71 -2
  184. package/lib/services/agent/tools/animateImage.tool.d.ts +1 -0
  185. package/lib/services/agent/tools/animateImage.tool.d.ts.map +1 -1
  186. package/lib/services/agent/tools/animateImage.tool.js +12 -0
  187. package/lib/services/agent/tools/chapterOutline.tool.d.ts +42 -0
  188. package/lib/services/agent/tools/chapterOutline.tool.d.ts.map +1 -0
  189. package/lib/services/agent/tools/chapterOutline.tool.js +115 -0
  190. package/lib/services/agent/tools/composeScene.tool.d.ts +65 -2
  191. package/lib/services/agent/tools/composeScene.tool.d.ts.map +1 -1
  192. package/lib/services/agent/tools/estimateCost.tool.d.ts +28 -1
  193. package/lib/services/agent/tools/estimateCost.tool.d.ts.map +1 -1
  194. package/lib/services/agent/tools/estimateCost.tool.js +55 -7
  195. package/lib/services/agent/tools/extendVideo.tool.d.ts +26 -0
  196. package/lib/services/agent/tools/extendVideo.tool.d.ts.map +1 -0
  197. package/lib/services/agent/tools/extendVideo.tool.js +149 -0
  198. package/lib/services/agent/tools/generateScript.tool.d.ts +184 -0
  199. package/lib/services/agent/tools/generateScript.tool.d.ts.map +1 -0
  200. package/lib/services/agent/tools/generateScript.tool.js +123 -0
  201. package/lib/services/agent/tools/generateVideo.tool.d.ts +1 -0
  202. package/lib/services/agent/tools/generateVideo.tool.d.ts.map +1 -1
  203. package/lib/services/agent/tools/generateVideo.tool.js +20 -1
  204. package/lib/services/agent/tools/index.d.ts +4 -0
  205. package/lib/services/agent/tools/index.d.ts.map +1 -1
  206. package/lib/services/agent/tools/index.js +4 -0
  207. package/lib/services/agent/tools/matchBrollToScript.tool.d.ts +50 -0
  208. package/lib/services/agent/tools/matchBrollToScript.tool.d.ts.map +1 -0
  209. package/lib/services/agent/tools/matchBrollToScript.tool.js +139 -0
  210. package/lib/services/agent/tools/planVideo.tool.d.ts +57 -1
  211. package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -1
  212. package/lib/services/agent/tools/planVideo.tool.js +3 -3
  213. package/lib/services/agent/tools/render.tool.d.ts +22 -1
  214. package/lib/services/agent/tools/render.tool.d.ts.map +1 -1
  215. package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
  216. package/lib/services/aiGen/aiGenFactory.service.js +18 -3
  217. package/lib/services/aiGen/helpers.d.ts +8 -0
  218. package/lib/services/aiGen/helpers.d.ts.map +1 -1
  219. package/lib/services/aiGen/helpers.js +12 -0
  220. package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts +26 -0
  221. package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts.map +1 -0
  222. package/lib/services/aiGen/providers/anthropic/anthropic.service.js +95 -0
  223. package/lib/services/aiGen/providers/google/google.service.d.ts +25 -1
  224. package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
  225. package/lib/services/aiGen/providers/google/google.service.js +136 -237
  226. package/lib/services/aiGen/providers/google/googleApiKeys.d.ts +71 -0
  227. package/lib/services/aiGen/providers/google/googleApiKeys.d.ts.map +1 -0
  228. package/lib/services/aiGen/providers/google/googleApiKeys.js +137 -0
  229. package/lib/services/aiGen/providers/google/googleErrors.d.ts +13 -0
  230. package/lib/services/aiGen/providers/google/googleErrors.d.ts.map +1 -0
  231. package/lib/services/aiGen/providers/google/googleErrors.js +102 -0
  232. package/lib/services/aiGen/providers/google/googleFetch.d.ts +8 -0
  233. package/lib/services/aiGen/providers/google/googleFetch.d.ts.map +1 -0
  234. package/lib/services/aiGen/providers/google/googleFetch.js +96 -0
  235. package/lib/services/aiGen/providers/google/googleKeyPool.d.ts +52 -0
  236. package/lib/services/aiGen/providers/google/googleKeyPool.d.ts.map +1 -0
  237. package/lib/services/aiGen/providers/google/googleKeyPool.js +129 -0
  238. package/lib/services/aiGen/providers/google/googleMusic.d.ts +15 -0
  239. package/lib/services/aiGen/providers/google/googleMusic.d.ts.map +1 -0
  240. package/lib/services/aiGen/providers/google/googleMusic.js +77 -0
  241. package/lib/services/aiGen/providers/kling/kling.service.d.ts +7 -3
  242. package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
  243. package/lib/services/aiGen/providers/kling/kling.service.js +23 -367
  244. package/lib/services/aiGen/providers/kling/klingCredits.d.ts +9 -0
  245. package/lib/services/aiGen/providers/kling/klingCredits.d.ts.map +1 -0
  246. package/lib/services/aiGen/providers/kling/klingCredits.js +63 -0
  247. package/lib/services/aiGen/providers/kling/klingRequests.d.ts +32 -0
  248. package/lib/services/aiGen/providers/kling/klingRequests.d.ts.map +1 -0
  249. package/lib/services/aiGen/providers/kling/klingRequests.js +194 -0
  250. package/lib/services/aiGen/providers/kling/klingStatus.d.ts +16 -0
  251. package/lib/services/aiGen/providers/kling/klingStatus.d.ts.map +1 -0
  252. package/lib/services/aiGen/providers/kling/klingStatus.js +173 -0
  253. package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
  254. package/lib/services/aiGen/providers/pixverse/pixverse.service.js +7 -1
  255. package/lib/services/bullmq.service.d.ts +61 -0
  256. package/lib/services/bullmq.service.d.ts.map +1 -1
  257. package/lib/services/bullmq.service.js +124 -2
  258. package/lib/services/crypto/index.d.ts +2 -0
  259. package/lib/services/crypto/index.d.ts.map +1 -0
  260. package/lib/services/crypto/index.js +17 -0
  261. package/lib/services/crypto/tokenVault.d.ts +47 -0
  262. package/lib/services/crypto/tokenVault.d.ts.map +1 -0
  263. package/lib/services/crypto/tokenVault.js +179 -0
  264. package/lib/services/editor/captionStyleHint.d.ts +3 -0
  265. package/lib/services/editor/captionStyleHint.d.ts.map +1 -0
  266. package/lib/services/editor/captionStyleHint.js +112 -0
  267. package/lib/services/editor/planToProject.d.ts +7 -66
  268. package/lib/services/editor/planToProject.d.ts.map +1 -1
  269. package/lib/services/editor/planToProject.helpers.d.ts +40 -0
  270. package/lib/services/editor/planToProject.helpers.d.ts.map +1 -0
  271. package/lib/services/editor/planToProject.helpers.js +177 -0
  272. package/lib/services/editor/planToProject.js +197 -180
  273. package/lib/services/editor/planToProject.types.d.ts +94 -0
  274. package/lib/services/editor/planToProject.types.d.ts.map +1 -0
  275. package/lib/services/editor/planToProject.types.js +2 -0
  276. package/lib/services/firestore.service.d.ts +5 -0
  277. package/lib/services/firestore.service.d.ts.map +1 -1
  278. package/lib/services/firestore.service.js +13 -0
  279. package/lib/services/index.d.ts +13 -0
  280. package/lib/services/index.d.ts.map +1 -1
  281. package/lib/services/index.js +13 -0
  282. package/lib/services/promptEnhancer/index.d.ts +18 -0
  283. package/lib/services/promptEnhancer/index.d.ts.map +1 -0
  284. package/lib/services/promptEnhancer/index.js +33 -0
  285. package/lib/services/promptEnhancer/models.d.ts +54 -0
  286. package/lib/services/promptEnhancer/models.d.ts.map +1 -0
  287. package/lib/services/promptEnhancer/models.js +37 -0
  288. package/lib/services/promptEnhancer/profiles/agent.profile.d.ts +14 -0
  289. package/lib/services/promptEnhancer/profiles/agent.profile.d.ts.map +1 -0
  290. package/lib/services/promptEnhancer/profiles/agent.profile.js +40 -0
  291. package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts +13 -0
  292. package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts.map +1 -0
  293. package/lib/services/promptEnhancer/profiles/avatar.profile.js +40 -0
  294. package/lib/services/promptEnhancer/profiles/base.d.ts +28 -0
  295. package/lib/services/promptEnhancer/profiles/base.d.ts.map +1 -0
  296. package/lib/services/promptEnhancer/profiles/base.js +35 -0
  297. package/lib/services/promptEnhancer/profiles/image.profile.d.ts +11 -0
  298. package/lib/services/promptEnhancer/profiles/image.profile.d.ts.map +1 -0
  299. package/lib/services/promptEnhancer/profiles/image.profile.js +42 -0
  300. package/lib/services/promptEnhancer/profiles/index.d.ts +12 -0
  301. package/lib/services/promptEnhancer/profiles/index.d.ts.map +1 -0
  302. package/lib/services/promptEnhancer/profiles/index.js +33 -0
  303. package/lib/services/promptEnhancer/profiles/video.profile.d.ts +15 -0
  304. package/lib/services/promptEnhancer/profiles/video.profile.d.ts.map +1 -0
  305. package/lib/services/promptEnhancer/profiles/video.profile.js +81 -0
  306. package/lib/services/promptEnhancer/promptEnhancer.service.d.ts +45 -0
  307. package/lib/services/promptEnhancer/promptEnhancer.service.d.ts.map +1 -0
  308. package/lib/services/promptEnhancer/promptEnhancer.service.js +157 -0
  309. package/lib/services/promptEnhancer/schema.d.ts +19 -0
  310. package/lib/services/promptEnhancer/schema.d.ts.map +1 -0
  311. package/lib/services/promptEnhancer/schema.js +43 -0
  312. package/lib/services/promptEnhancer/types.d.ts +112 -0
  313. package/lib/services/promptEnhancer/types.d.ts.map +1 -0
  314. package/lib/services/promptEnhancer/types.js +2 -0
  315. package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts +60 -5
  316. package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts.map +1 -1
  317. package/lib/services/rateLimiter/distributedRateLimiter.service.js +184 -16
  318. package/lib/services/socialAI/captionGen.d.ts +81 -0
  319. package/lib/services/socialAI/captionGen.d.ts.map +1 -0
  320. package/lib/services/socialAI/captionGen.js +206 -0
  321. package/lib/services/socialAI/hookScore.d.ts +85 -0
  322. package/lib/services/socialAI/hookScore.d.ts.map +1 -0
  323. package/lib/services/socialAI/hookScore.js +170 -0
  324. package/lib/services/socialAI/index.d.ts +3 -0
  325. package/lib/services/socialAI/index.d.ts.map +1 -0
  326. package/lib/services/socialAI/index.js +18 -0
  327. package/lib/services/socialAccounts/index.d.ts +2 -0
  328. package/lib/services/socialAccounts/index.d.ts.map +1 -0
  329. package/lib/services/socialAccounts/index.js +17 -0
  330. package/lib/services/socialAccounts/socialAccountService.d.ts +25 -0
  331. package/lib/services/socialAccounts/socialAccountService.d.ts.map +1 -0
  332. package/lib/services/socialAccounts/socialAccountService.js +105 -0
  333. package/lib/services/socialEngage/factory.d.ts +7 -0
  334. package/lib/services/socialEngage/factory.d.ts.map +1 -0
  335. package/lib/services/socialEngage/factory.js +25 -0
  336. package/lib/services/socialEngage/index.d.ts +6 -0
  337. package/lib/services/socialEngage/index.d.ts.map +1 -0
  338. package/lib/services/socialEngage/index.js +21 -0
  339. package/lib/services/socialEngage/meta.engage.d.ts +17 -0
  340. package/lib/services/socialEngage/meta.engage.d.ts.map +1 -0
  341. package/lib/services/socialEngage/meta.engage.js +128 -0
  342. package/lib/services/socialEngage/metaWebhook.d.ts +50 -0
  343. package/lib/services/socialEngage/metaWebhook.d.ts.map +1 -0
  344. package/lib/services/socialEngage/metaWebhook.js +93 -0
  345. package/lib/services/socialEngage/types.d.ts +72 -0
  346. package/lib/services/socialEngage/types.d.ts.map +1 -0
  347. package/lib/services/socialEngage/types.js +10 -0
  348. package/lib/services/socialEngage/youtube.engage.d.ts +9 -0
  349. package/lib/services/socialEngage/youtube.engage.d.ts.map +1 -0
  350. package/lib/services/socialEngage/youtube.engage.js +87 -0
  351. package/lib/services/socialFormat/aspectGeometry.d.ts +74 -0
  352. package/lib/services/socialFormat/aspectGeometry.d.ts.map +1 -0
  353. package/lib/services/socialFormat/aspectGeometry.js +135 -0
  354. package/lib/services/socialFormat/index.d.ts +2 -0
  355. package/lib/services/socialFormat/index.d.ts.map +1 -0
  356. package/lib/services/socialFormat/index.js +19 -0
  357. package/lib/services/socialInsights/index.d.ts +3 -0
  358. package/lib/services/socialInsights/index.d.ts.map +1 -0
  359. package/lib/services/socialInsights/index.js +18 -0
  360. package/lib/services/socialInsights/recommendations.d.ts +131 -0
  361. package/lib/services/socialInsights/recommendations.d.ts.map +1 -0
  362. package/lib/services/socialInsights/recommendations.js +277 -0
  363. package/lib/services/socialInsights/timeBuckets.d.ts +35 -0
  364. package/lib/services/socialInsights/timeBuckets.d.ts.map +1 -0
  365. package/lib/services/socialInsights/timeBuckets.js +78 -0
  366. package/lib/services/socialMetrics/factory.d.ts +5 -0
  367. package/lib/services/socialMetrics/factory.d.ts.map +1 -0
  368. package/lib/services/socialMetrics/factory.js +24 -0
  369. package/lib/services/socialMetrics/index.d.ts +6 -0
  370. package/lib/services/socialMetrics/index.d.ts.map +1 -0
  371. package/lib/services/socialMetrics/index.js +21 -0
  372. package/lib/services/socialMetrics/meta.metrics.d.ts +22 -0
  373. package/lib/services/socialMetrics/meta.metrics.d.ts.map +1 -0
  374. package/lib/services/socialMetrics/meta.metrics.js +137 -0
  375. package/lib/services/socialMetrics/tiktok.metrics.d.ts +8 -0
  376. package/lib/services/socialMetrics/tiktok.metrics.d.ts.map +1 -0
  377. package/lib/services/socialMetrics/tiktok.metrics.js +43 -0
  378. package/lib/services/socialMetrics/types.d.ts +54 -0
  379. package/lib/services/socialMetrics/types.d.ts.map +1 -0
  380. package/lib/services/socialMetrics/types.js +2 -0
  381. package/lib/services/socialMetrics/youtube.metrics.d.ts +8 -0
  382. package/lib/services/socialMetrics/youtube.metrics.d.ts.map +1 -0
  383. package/lib/services/socialMetrics/youtube.metrics.js +43 -0
  384. package/lib/services/socialOAuth/factory.d.ts +7 -0
  385. package/lib/services/socialOAuth/factory.d.ts.map +1 -0
  386. package/lib/services/socialOAuth/factory.js +42 -0
  387. package/lib/services/socialOAuth/index.d.ts +11 -0
  388. package/lib/services/socialOAuth/index.d.ts.map +1 -0
  389. package/lib/services/socialOAuth/index.js +26 -0
  390. package/lib/services/socialOAuth/linkedin.oauth.d.ts +14 -0
  391. package/lib/services/socialOAuth/linkedin.oauth.d.ts.map +1 -0
  392. package/lib/services/socialOAuth/linkedin.oauth.js +127 -0
  393. package/lib/services/socialOAuth/meta.oauth.d.ts +31 -0
  394. package/lib/services/socialOAuth/meta.oauth.d.ts.map +1 -0
  395. package/lib/services/socialOAuth/meta.oauth.js +214 -0
  396. package/lib/services/socialOAuth/oauthState.d.ts +14 -0
  397. package/lib/services/socialOAuth/oauthState.d.ts.map +1 -0
  398. package/lib/services/socialOAuth/oauthState.js +66 -0
  399. package/lib/services/socialOAuth/pinterest.oauth.d.ts +15 -0
  400. package/lib/services/socialOAuth/pinterest.oauth.d.ts.map +1 -0
  401. package/lib/services/socialOAuth/pinterest.oauth.js +126 -0
  402. package/lib/services/socialOAuth/threads.oauth.d.ts +14 -0
  403. package/lib/services/socialOAuth/threads.oauth.d.ts.map +1 -0
  404. package/lib/services/socialOAuth/threads.oauth.js +129 -0
  405. package/lib/services/socialOAuth/tiktok.oauth.d.ts +15 -0
  406. package/lib/services/socialOAuth/tiktok.oauth.d.ts.map +1 -0
  407. package/lib/services/socialOAuth/tiktok.oauth.js +151 -0
  408. package/lib/services/socialOAuth/types.d.ts +67 -0
  409. package/lib/services/socialOAuth/types.d.ts.map +1 -0
  410. package/lib/services/socialOAuth/types.js +2 -0
  411. package/lib/services/socialOAuth/x.oauth.d.ts +17 -0
  412. package/lib/services/socialOAuth/x.oauth.d.ts.map +1 -0
  413. package/lib/services/socialOAuth/x.oauth.js +134 -0
  414. package/lib/services/socialOAuth/youtube.oauth.d.ts +15 -0
  415. package/lib/services/socialOAuth/youtube.oauth.d.ts.map +1 -0
  416. package/lib/services/socialOAuth/youtube.oauth.js +156 -0
  417. package/lib/services/socialPublish/factory.d.ts +5 -0
  418. package/lib/services/socialPublish/factory.d.ts.map +1 -0
  419. package/lib/services/socialPublish/factory.js +32 -0
  420. package/lib/services/socialPublish/index.d.ts +10 -0
  421. package/lib/services/socialPublish/index.d.ts.map +1 -0
  422. package/lib/services/socialPublish/index.js +25 -0
  423. package/lib/services/socialPublish/linkedin.publish.d.ts +9 -0
  424. package/lib/services/socialPublish/linkedin.publish.d.ts.map +1 -0
  425. package/lib/services/socialPublish/linkedin.publish.js +143 -0
  426. package/lib/services/socialPublish/meta.publish.d.ts +28 -0
  427. package/lib/services/socialPublish/meta.publish.d.ts.map +1 -0
  428. package/lib/services/socialPublish/meta.publish.js +149 -0
  429. package/lib/services/socialPublish/pinterest.publish.d.ts +13 -0
  430. package/lib/services/socialPublish/pinterest.publish.d.ts.map +1 -0
  431. package/lib/services/socialPublish/pinterest.publish.js +130 -0
  432. package/lib/services/socialPublish/threads.publish.d.ts +12 -0
  433. package/lib/services/socialPublish/threads.publish.d.ts.map +1 -0
  434. package/lib/services/socialPublish/threads.publish.js +96 -0
  435. package/lib/services/socialPublish/tiktok.publish.d.ts +13 -0
  436. package/lib/services/socialPublish/tiktok.publish.d.ts.map +1 -0
  437. package/lib/services/socialPublish/tiktok.publish.js +118 -0
  438. package/lib/services/socialPublish/types.d.ts +47 -0
  439. package/lib/services/socialPublish/types.d.ts.map +1 -0
  440. package/lib/services/socialPublish/types.js +2 -0
  441. package/lib/services/socialPublish/x.publish.d.ts +12 -0
  442. package/lib/services/socialPublish/x.publish.d.ts.map +1 -0
  443. package/lib/services/socialPublish/x.publish.js +147 -0
  444. package/lib/services/socialPublish/youtube.publish.d.ts +9 -0
  445. package/lib/services/socialPublish/youtube.publish.d.ts.map +1 -0
  446. package/lib/services/socialPublish/youtube.publish.js +107 -0
  447. package/lib/services/stock/index.d.ts +2 -0
  448. package/lib/services/stock/index.d.ts.map +1 -0
  449. package/lib/services/stock/index.js +17 -0
  450. package/lib/services/stock/realPersonSafety.d.ts +99 -0
  451. package/lib/services/stock/realPersonSafety.d.ts.map +1 -0
  452. package/lib/services/stock/realPersonSafety.js +248 -0
  453. package/lib/services/translation/index.d.ts +2 -0
  454. package/lib/services/translation/index.d.ts.map +1 -0
  455. package/lib/services/translation/index.js +9 -0
  456. package/lib/services/translation/translation.service.d.ts +50 -0
  457. package/lib/services/translation/translation.service.d.ts.map +1 -0
  458. package/lib/services/translation/translation.service.js +211 -0
  459. package/lib/utils/helpers.d.ts +2 -4
  460. package/lib/utils/helpers.d.ts.map +1 -1
  461. package/lib/utils/helpers.js +9 -63
  462. package/lib/utils/index.d.ts +1 -0
  463. package/lib/utils/index.d.ts.map +1 -1
  464. package/lib/utils/index.js +1 -0
  465. package/lib/utils/renderTier.d.ts +26 -0
  466. package/lib/utils/renderTier.d.ts.map +1 -0
  467. package/lib/utils/renderTier.js +34 -0
  468. package/package.json +1 -1
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TikTokOAuthProvider = void 0;
4
+ const types_1 = require("../../globals/types");
5
+ const logger_1 = require("../../utils/logger");
6
+ /**
7
+ * TikTok (Login Kit v2) OAuth provider. Phase 6 — TikTok publish.
8
+ *
9
+ * Config (env):
10
+ * TIKTOK_CLIENT_KEY — app client key
11
+ * TIKTOK_CLIENT_SECRET — app client secret
12
+ *
13
+ * Notes / gates (plan §3, §G):
14
+ * - Access token lives 24h; refresh token 365d WITH rotation (a refresh returns
15
+ * a NEW refresh token — we persist it). The refresh daemon is mandatory.
16
+ * - `video.publish` (direct post) + `video.upload` (draft) require the Content
17
+ * Posting API audit; until approved, posts are forced SELF_ONLY/draft and only
18
+ * test users can connect.
19
+ * - PULL_FROM_URL publishing needs the media domain (our CDN) verified in the
20
+ * TikTok developer portal.
21
+ */
22
+ const AUTH_ENDPOINT = "https://www.tiktok.com/v2/auth/authorize/";
23
+ const TOKEN_ENDPOINT = "https://open.tiktokapis.com/v2/oauth/token/";
24
+ const REVOKE_ENDPOINT = "https://open.tiktokapis.com/v2/oauth/revoke/";
25
+ const USERINFO_ENDPOINT = "https://open.tiktokapis.com/v2/user/info/?fields=open_id,union_id,avatar_url,display_name,username";
26
+ /** Basic scopes: identity + publish. `video.list` (read) gates metrics. */
27
+ const BASE_SCOPES = ["user.info.basic", "video.publish", "video.upload"];
28
+ const BUSINESS_SCOPES = ["video.list"];
29
+ class TikTokOAuthProvider {
30
+ constructor() {
31
+ this.provider = types_1.ESocialProvider.TIKTOK;
32
+ }
33
+ clientKey() {
34
+ const k = process.env.TIKTOK_CLIENT_KEY;
35
+ if (!k)
36
+ throw new Error("TikTokOAuth: TIKTOK_CLIENT_KEY not set");
37
+ return k;
38
+ }
39
+ clientSecret() {
40
+ const s = process.env.TIKTOK_CLIENT_SECRET;
41
+ if (!s)
42
+ throw new Error("TikTokOAuth: TIKTOK_CLIENT_SECRET not set");
43
+ return s;
44
+ }
45
+ getAuthUrl({ state, redirectUri, requestBusinessScopes, }) {
46
+ const scopes = requestBusinessScopes
47
+ ? [...BASE_SCOPES, ...BUSINESS_SCOPES]
48
+ : BASE_SCOPES;
49
+ const params = new URLSearchParams({
50
+ client_key: this.clientKey(),
51
+ scope: scopes.join(","),
52
+ response_type: "code",
53
+ redirect_uri: redirectUri,
54
+ state,
55
+ });
56
+ return `${AUTH_ENDPOINT}?${params.toString()}`;
57
+ }
58
+ async exchangeCode({ code, redirectUri, }) {
59
+ const body = new URLSearchParams({
60
+ client_key: this.clientKey(),
61
+ client_secret: this.clientSecret(),
62
+ code,
63
+ grant_type: "authorization_code",
64
+ redirect_uri: redirectUri,
65
+ });
66
+ const token = await this.postToken(body);
67
+ if (!token.access_token) {
68
+ throw new Error("TikTokOAuth: token exchange returned no access_token");
69
+ }
70
+ const tokens = this.toTokens(token);
71
+ const account = await this.resolveAccount(token.access_token);
72
+ return { account, tokens };
73
+ }
74
+ async refresh(refreshToken) {
75
+ const body = new URLSearchParams({
76
+ client_key: this.clientKey(),
77
+ client_secret: this.clientSecret(),
78
+ grant_type: "refresh_token",
79
+ refresh_token: refreshToken,
80
+ });
81
+ const token = await this.postToken(body);
82
+ if (!token.access_token) {
83
+ throw new Error("TikTokOAuth: refresh returned no access_token");
84
+ }
85
+ // TikTok ROTATES the refresh token — keep whatever it returned.
86
+ return this.toTokens(token);
87
+ }
88
+ async revoke(token) {
89
+ try {
90
+ await fetch(REVOKE_ENDPOINT, {
91
+ method: "POST",
92
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
93
+ body: new URLSearchParams({
94
+ client_key: this.clientKey(),
95
+ client_secret: this.clientSecret(),
96
+ token,
97
+ }).toString(),
98
+ });
99
+ }
100
+ catch (err) {
101
+ logger_1.logger.warn("TikTokOAuth.revoke: failed (non-fatal)", {
102
+ error: err instanceof Error ? err.message : String(err),
103
+ });
104
+ }
105
+ }
106
+ async postToken(body) {
107
+ const resp = await fetch(TOKEN_ENDPOINT, {
108
+ method: "POST",
109
+ headers: {
110
+ "Content-Type": "application/x-www-form-urlencoded",
111
+ "Cache-Control": "no-cache",
112
+ },
113
+ body: body.toString(),
114
+ });
115
+ const json = (await resp.json());
116
+ if (!resp.ok || json.error) {
117
+ throw new Error(`TikTokOAuth: token endpoint ${resp.status} ${json.error ?? ""} ${json.error_description ?? ""}`.trim());
118
+ }
119
+ return json;
120
+ }
121
+ toTokens(token) {
122
+ const now = Date.now();
123
+ return {
124
+ accessToken: token.access_token,
125
+ refreshToken: token.refresh_token,
126
+ expiresAt: now + (token.expires_in ?? 86400) * 1000,
127
+ refreshExpiresAt: token.refresh_expires_in
128
+ ? now + token.refresh_expires_in * 1000
129
+ : undefined,
130
+ scopes: token.scope ? token.scope.split(",").filter(Boolean) : [],
131
+ };
132
+ }
133
+ async resolveAccount(accessToken) {
134
+ const resp = await fetch(USERINFO_ENDPOINT, {
135
+ headers: { Authorization: `Bearer ${accessToken}` },
136
+ });
137
+ const json = (await resp.json());
138
+ const user = json.data?.user;
139
+ if (!resp.ok || json.error?.code || !user?.open_id) {
140
+ throw new Error(`TikTokOAuth: user info ${resp.status} ${json.error?.message ?? ""}`.trim());
141
+ }
142
+ return {
143
+ providerAccountId: user.open_id,
144
+ displayName: user.display_name ?? "TikTok account",
145
+ handle: user.username,
146
+ avatarUrl: user.avatar_url,
147
+ kind: types_1.ESocialAccountKind.CREATOR,
148
+ };
149
+ }
150
+ }
151
+ exports.TikTokOAuthProvider = TikTokOAuthProvider;
@@ -0,0 +1,67 @@
1
+ import { ESocialAccountKind, ESocialProvider } from "../../globals/types";
2
+ /**
3
+ * X8 Social Suite — OAuth provider abstraction. One implementation per platform
4
+ * behind a single interface so the connect/callback controllers and the token
5
+ * refresh daemon are provider-agnostic. See notes/SOCIAL_SUITE_PLAN.md §4.
6
+ *
7
+ * IMPORTANT: this layer deals in CLEARTEXT tokens. Encryption (tokenVault) is
8
+ * applied by the persistence layer right before writing to Firestore, and
9
+ * decryption right after reading — providers never see ciphertext.
10
+ */
11
+ /** Cleartext OAuth credential bundle returned by exchange/refresh. */
12
+ export interface OAuthTokens {
13
+ accessToken: string;
14
+ refreshToken?: string;
15
+ /** Unix ms when the access token expires. */
16
+ expiresAt: number;
17
+ /** Unix ms when the refresh token expires, if applicable. */
18
+ refreshExpiresAt?: number;
19
+ /** Scopes actually granted (may differ from requested). */
20
+ scopes: string[];
21
+ }
22
+ /** Identity of the connected account, resolved after token exchange. */
23
+ export interface ResolvedSocialAccount {
24
+ providerAccountId: string;
25
+ displayName: string;
26
+ handle?: string;
27
+ avatarUrl?: string;
28
+ kind: ESocialAccountKind;
29
+ }
30
+ export interface AuthUrlParams {
31
+ /** Opaque CSRF state we generate + verify on callback. */
32
+ state: string;
33
+ /** The OAuth redirect URI registered with the provider. */
34
+ redirectUri: string;
35
+ /** Ask for premium/business scopes (G-features) where supported. */
36
+ requestBusinessScopes?: boolean;
37
+ }
38
+ export interface ExchangeCodeParams {
39
+ code: string;
40
+ redirectUri: string;
41
+ }
42
+ /** Result of a successful connect: who they are + their (cleartext) tokens. */
43
+ export interface ConnectResult {
44
+ account: ResolvedSocialAccount;
45
+ tokens: OAuthTokens;
46
+ }
47
+ /** Abstract OAuth provider. Implementations are stateless + config-driven. */
48
+ export interface ISocialOAuthProvider {
49
+ readonly provider: ESocialProvider;
50
+ /** Build the provider authorization URL to redirect the user to. */
51
+ getAuthUrl(params: AuthUrlParams): string;
52
+ /** Exchange the callback `code` for tokens + resolve the account identity. */
53
+ exchangeCode(params: ExchangeCodeParams): Promise<ConnectResult>;
54
+ /**
55
+ * Multi-account variant: a single OAuth grant can yield several accounts (e.g.
56
+ * Meta returns every FB Page + linked IG Business account the user manages).
57
+ * When present, the callback upserts ALL returned accounts. Providers that map
58
+ * one grant → one account (YouTube) leave this undefined and the callback uses
59
+ * `exchangeCode`. See notes/SOCIAL_SUITE_PLAN.md §4.
60
+ */
61
+ exchangeCodeMulti?(params: ExchangeCodeParams): Promise<ConnectResult[]>;
62
+ /** Refresh an expiring access token using the stored refresh token. */
63
+ refresh(refreshToken: string): Promise<OAuthTokens>;
64
+ /** Best-effort revoke at the provider (called on disconnect). */
65
+ revoke?(token: string): Promise<void>;
66
+ }
67
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/socialOAuth/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE1E;;;;;;;;GAQG;AAEH,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,qBAAqB,CAAC;IAC/B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,8EAA8E;AAC9E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,oEAAoE;IACpE,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC;IAC1C,8EAA8E;IAC9E,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACjE;;;;;;OAMG;IACH,iBAAiB,CAAC,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACzE,uEAAuE;IACvE,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACpD,iEAAiE;IACjE,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ import { ESocialProvider } from "../../globals/types";
2
+ import { AuthUrlParams, ConnectResult, ExchangeCodeParams, ISocialOAuthProvider, OAuthTokens } from "./types";
3
+ export declare class XOAuthProvider implements ISocialOAuthProvider {
4
+ readonly provider = ESocialProvider.X;
5
+ private clientId;
6
+ private clientSecret;
7
+ /** Deterministic PKCE verifier (base64url, 43 chars) — see header note. */
8
+ private codeVerifier;
9
+ private basicAuth;
10
+ getAuthUrl({ state, redirectUri }: AuthUrlParams): string;
11
+ exchangeCode({ code, redirectUri, }: ExchangeCodeParams): Promise<ConnectResult>;
12
+ refresh(refreshToken: string): Promise<OAuthTokens>;
13
+ private postToken;
14
+ private toTokens;
15
+ private resolveAccount;
16
+ }
17
+ //# sourceMappingURL=x.oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x.oauth.d.ts","sourceRoot":"","sources":["../../../src/services/socialOAuth/x.oauth.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EACL,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACZ,MAAM,SAAS,CAAC;AAuCjB,qBAAa,cAAe,YAAW,oBAAoB;IACzD,QAAQ,CAAC,QAAQ,qBAAqB;IAEtC,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,YAAY;IAKpB,2EAA2E;IAC3E,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,SAAS;IAMjB,UAAU,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,aAAa,GAAG,MAAM;IAenD,YAAY,CAAC,EACjB,IAAI,EACJ,WAAW,GACZ,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBxC,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;YAiB3C,SAAS;IAoBvB,OAAO,CAAC,QAAQ;YASF,cAAc;CAkB7B"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XOAuthProvider = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const types_1 = require("../../globals/types");
6
+ /**
7
+ * X (Twitter) OAuth 2.0 provider with PKCE. Phase 6 — fast-follow adapter.
8
+ *
9
+ * Config (env):
10
+ * X_CLIENT_ID
11
+ * X_CLIENT_SECRET — confidential client (sent via HTTP Basic on token calls)
12
+ *
13
+ * PKCE note: X mandates PKCE even for confidential clients, but the OAuth
14
+ * callback hands `exchangeCode` only {code, redirectUri} — not the per-session
15
+ * `state`. So we use a DETERMINISTIC app-level verifier derived from the client
16
+ * secret (method=plain): `getAuthUrl` and `exchangeCode` both recompute the same
17
+ * value with no shared session storage. With a confidential client the secret
18
+ * (Basic auth) is the real protection; the static verifier just satisfies the
19
+ * PKCE requirement. `offline.access` is required to receive a refresh token.
20
+ */
21
+ const AUTH_ENDPOINT = "https://twitter.com/i/oauth2/authorize";
22
+ const TOKEN_ENDPOINT = "https://api.twitter.com/2/oauth2/token";
23
+ const ME_ENDPOINT = "https://api.twitter.com/2/users/me?user.fields=profile_image_url,username,name";
24
+ const BASE_SCOPES = ["tweet.read", "tweet.write", "users.read", "offline.access"];
25
+ class XOAuthProvider {
26
+ constructor() {
27
+ this.provider = types_1.ESocialProvider.X;
28
+ }
29
+ clientId() {
30
+ const v = process.env.X_CLIENT_ID;
31
+ if (!v)
32
+ throw new Error("XOAuth: X_CLIENT_ID not set");
33
+ return v;
34
+ }
35
+ clientSecret() {
36
+ const v = process.env.X_CLIENT_SECRET;
37
+ if (!v)
38
+ throw new Error("XOAuth: X_CLIENT_SECRET not set");
39
+ return v;
40
+ }
41
+ /** Deterministic PKCE verifier (base64url, 43 chars) — see header note. */
42
+ codeVerifier() {
43
+ return (0, crypto_1.createHash)("sha256")
44
+ .update(`${this.clientSecret()}:vidspot-x-pkce`)
45
+ .digest("base64url");
46
+ }
47
+ basicAuth() {
48
+ return Buffer.from(`${this.clientId()}:${this.clientSecret()}`).toString("base64");
49
+ }
50
+ getAuthUrl({ state, redirectUri }) {
51
+ const verifier = this.codeVerifier();
52
+ const params = new URLSearchParams({
53
+ response_type: "code",
54
+ client_id: this.clientId(),
55
+ redirect_uri: redirectUri,
56
+ scope: BASE_SCOPES.join(" "),
57
+ state,
58
+ // method=plain → challenge equals verifier verbatim.
59
+ code_challenge: verifier,
60
+ code_challenge_method: "plain",
61
+ });
62
+ return `${AUTH_ENDPOINT}?${params.toString()}`;
63
+ }
64
+ async exchangeCode({ code, redirectUri, }) {
65
+ const token = await this.postToken(new URLSearchParams({
66
+ grant_type: "authorization_code",
67
+ code,
68
+ redirect_uri: redirectUri,
69
+ client_id: this.clientId(),
70
+ code_verifier: this.codeVerifier(),
71
+ }));
72
+ if (!token.access_token) {
73
+ throw new Error("XOAuth: token exchange returned no access_token");
74
+ }
75
+ const tokens = this.toTokens(token);
76
+ const account = await this.resolveAccount(token.access_token);
77
+ return { account, tokens };
78
+ }
79
+ async refresh(refreshToken) {
80
+ const token = await this.postToken(new URLSearchParams({
81
+ grant_type: "refresh_token",
82
+ refresh_token: refreshToken,
83
+ client_id: this.clientId(),
84
+ }));
85
+ if (!token.access_token) {
86
+ throw new Error("XOAuth: refresh returned no access_token");
87
+ }
88
+ const tokens = this.toTokens(token);
89
+ // X rotates refresh tokens; keep the old one only if none came back.
90
+ if (!tokens.refreshToken)
91
+ tokens.refreshToken = refreshToken;
92
+ return tokens;
93
+ }
94
+ async postToken(body) {
95
+ const resp = await fetch(TOKEN_ENDPOINT, {
96
+ method: "POST",
97
+ headers: {
98
+ "Content-Type": "application/x-www-form-urlencoded",
99
+ Authorization: `Basic ${this.basicAuth()}`,
100
+ },
101
+ body: body.toString(),
102
+ });
103
+ const json = (await resp.json());
104
+ if (!resp.ok || json.error) {
105
+ throw new Error(`XOAuth: token endpoint ${resp.status} ${json.error ?? ""} ${json.error_description ?? ""}`.trim());
106
+ }
107
+ return json;
108
+ }
109
+ toTokens(token) {
110
+ return {
111
+ accessToken: token.access_token,
112
+ refreshToken: token.refresh_token,
113
+ expiresAt: Date.now() + (token.expires_in ?? 7200) * 1000,
114
+ scopes: token.scope ? token.scope.split(" ").filter(Boolean) : [],
115
+ };
116
+ }
117
+ async resolveAccount(accessToken) {
118
+ const resp = await fetch(ME_ENDPOINT, {
119
+ headers: { Authorization: `Bearer ${accessToken}` },
120
+ });
121
+ const json = (await resp.json());
122
+ if (!resp.ok || !json.data?.id) {
123
+ throw new Error(`XOAuth: /users/me ${resp.status} ${json.errors?.[0]?.detail ?? ""}`.trim());
124
+ }
125
+ return {
126
+ providerAccountId: json.data.id,
127
+ displayName: json.data.name ?? "X account",
128
+ handle: json.data.username,
129
+ avatarUrl: json.data.profile_image_url,
130
+ kind: types_1.ESocialAccountKind.PERSONAL,
131
+ };
132
+ }
133
+ }
134
+ exports.XOAuthProvider = XOAuthProvider;
@@ -0,0 +1,15 @@
1
+ import { ESocialProvider } from "../../globals/types";
2
+ import { AuthUrlParams, ConnectResult, ExchangeCodeParams, ISocialOAuthProvider, OAuthTokens } from "./types";
3
+ export declare class YouTubeOAuthProvider implements ISocialOAuthProvider {
4
+ readonly provider = ESocialProvider.YOUTUBE;
5
+ private clientId;
6
+ private clientSecret;
7
+ getAuthUrl({ state, redirectUri, requestBusinessScopes, }: AuthUrlParams): string;
8
+ exchangeCode({ code, redirectUri, }: ExchangeCodeParams): Promise<ConnectResult>;
9
+ refresh(refreshToken: string): Promise<OAuthTokens>;
10
+ revoke(token: string): Promise<void>;
11
+ private postToken;
12
+ private toTokens;
13
+ private resolveAccount;
14
+ }
15
+ //# sourceMappingURL=youtube.oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"youtube.oauth.d.ts","sourceRoot":"","sources":["../../../src/services/socialOAuth/youtube.oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EACL,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACZ,MAAM,SAAS,CAAC;AAoDjB,qBAAa,oBAAqB,YAAW,oBAAoB;IAC/D,QAAQ,CAAC,QAAQ,2BAA2B;IAE5C,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,YAAY;IAOpB,UAAU,CAAC,EACT,KAAK,EACL,WAAW,EACX,qBAAqB,GACtB,EAAE,aAAa,GAAG,MAAM;IAiBnB,YAAY,CAAC,EACjB,IAAI,EACJ,WAAW,GACZ,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAiBxC,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAiBnD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAc5B,SAAS;IAmBvB,OAAO,CAAC,QAAQ;YAUF,cAAc;CAwB7B"}
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.YouTubeOAuthProvider = void 0;
4
+ const types_1 = require("../../globals/types");
5
+ const logger_1 = require("../../utils/logger");
6
+ /**
7
+ * YouTube (Google) OAuth 2.0 provider. Phase 1 of the Social Suite — the first
8
+ * end-to-end platform (cleanest API + native scheduling). See SOCIAL_SUITE_PLAN.md.
9
+ *
10
+ * Config (env):
11
+ * GOOGLE_OAUTH_CLIENT_ID — OAuth client id (Web application)
12
+ * GOOGLE_OAUTH_CLIENT_SECRET — OAuth client secret
13
+ *
14
+ * Notes:
15
+ * - `access_type=offline` + `prompt=consent` are required to reliably receive a
16
+ * refresh token (Google only returns it on first consent unless prompted).
17
+ * - While the OAuth app is in "Testing", refresh tokens expire after 7 days —
18
+ * publish the consent screen before production. (Plan §3.)
19
+ */
20
+ const AUTH_ENDPOINT = "https://accounts.google.com/o/oauth2/v2/auth";
21
+ const TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
22
+ const REVOKE_ENDPOINT = "https://oauth2.googleapis.com/revoke";
23
+ const CHANNELS_ENDPOINT = "https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true";
24
+ /** Scopes needed to upload + read analytics + manage comments. */
25
+ const BASE_SCOPES = [
26
+ "https://www.googleapis.com/auth/youtube.upload",
27
+ "https://www.googleapis.com/auth/youtube.readonly",
28
+ "https://www.googleapis.com/auth/yt-analytics.readonly",
29
+ ];
30
+ /** force-ssl is required for comment list/insert/moderate (premium engage). */
31
+ const COMMENT_SCOPES = ["https://www.googleapis.com/auth/youtube.force-ssl"];
32
+ class YouTubeOAuthProvider {
33
+ constructor() {
34
+ this.provider = types_1.ESocialProvider.YOUTUBE;
35
+ }
36
+ clientId() {
37
+ const id = process.env.GOOGLE_OAUTH_CLIENT_ID;
38
+ if (!id)
39
+ throw new Error("YouTubeOAuth: GOOGLE_OAUTH_CLIENT_ID not set");
40
+ return id;
41
+ }
42
+ clientSecret() {
43
+ const secret = process.env.GOOGLE_OAUTH_CLIENT_SECRET;
44
+ if (!secret)
45
+ throw new Error("YouTubeOAuth: GOOGLE_OAUTH_CLIENT_SECRET not set");
46
+ return secret;
47
+ }
48
+ getAuthUrl({ state, redirectUri, requestBusinessScopes, }) {
49
+ const scopes = requestBusinessScopes
50
+ ? [...BASE_SCOPES, ...COMMENT_SCOPES]
51
+ : BASE_SCOPES;
52
+ const params = new URLSearchParams({
53
+ client_id: this.clientId(),
54
+ redirect_uri: redirectUri,
55
+ response_type: "code",
56
+ scope: scopes.join(" "),
57
+ access_type: "offline",
58
+ include_granted_scopes: "true",
59
+ prompt: "consent",
60
+ state,
61
+ });
62
+ return `${AUTH_ENDPOINT}?${params.toString()}`;
63
+ }
64
+ async exchangeCode({ code, redirectUri, }) {
65
+ const body = new URLSearchParams({
66
+ code,
67
+ client_id: this.clientId(),
68
+ client_secret: this.clientSecret(),
69
+ redirect_uri: redirectUri,
70
+ grant_type: "authorization_code",
71
+ });
72
+ const token = await this.postToken(body);
73
+ if (!token.access_token) {
74
+ throw new Error("YouTubeOAuth: token exchange returned no access_token");
75
+ }
76
+ const tokens = this.toTokens(token);
77
+ const account = await this.resolveAccount(token.access_token);
78
+ return { account, tokens };
79
+ }
80
+ async refresh(refreshToken) {
81
+ const body = new URLSearchParams({
82
+ client_id: this.clientId(),
83
+ client_secret: this.clientSecret(),
84
+ refresh_token: refreshToken,
85
+ grant_type: "refresh_token",
86
+ });
87
+ const token = await this.postToken(body);
88
+ if (!token.access_token) {
89
+ throw new Error("YouTubeOAuth: refresh returned no access_token");
90
+ }
91
+ // Google does not re-issue a refresh token on refresh; preserve the old one.
92
+ const tokens = this.toTokens(token);
93
+ if (!tokens.refreshToken)
94
+ tokens.refreshToken = refreshToken;
95
+ return tokens;
96
+ }
97
+ async revoke(token) {
98
+ try {
99
+ await fetch(REVOKE_ENDPOINT, {
100
+ method: "POST",
101
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
102
+ body: new URLSearchParams({ token }).toString(),
103
+ });
104
+ }
105
+ catch (err) {
106
+ logger_1.logger.warn("YouTubeOAuth.revoke: failed (non-fatal)", {
107
+ error: err instanceof Error ? err.message : String(err),
108
+ });
109
+ }
110
+ }
111
+ async postToken(body) {
112
+ const resp = await fetch(TOKEN_ENDPOINT, {
113
+ method: "POST",
114
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
115
+ body: body.toString(),
116
+ });
117
+ const json = (await resp.json());
118
+ if (!resp.ok || json.error) {
119
+ throw new Error(`YouTubeOAuth: token endpoint ${resp.status} ${json.error ?? ""} ${json.error_description ?? ""}`.trim());
120
+ }
121
+ return json;
122
+ }
123
+ toTokens(token) {
124
+ const expiresInMs = (token.expires_in ?? 3600) * 1000;
125
+ return {
126
+ accessToken: token.access_token,
127
+ refreshToken: token.refresh_token,
128
+ expiresAt: Date.now() + expiresInMs,
129
+ scopes: token.scope ? token.scope.split(" ").filter(Boolean) : [],
130
+ };
131
+ }
132
+ async resolveAccount(accessToken) {
133
+ const resp = await fetch(CHANNELS_ENDPOINT, {
134
+ headers: { Authorization: `Bearer ${accessToken}` },
135
+ });
136
+ if (!resp.ok) {
137
+ throw new Error(`YouTubeOAuth: channels lookup ${resp.status}`);
138
+ }
139
+ const json = (await resp.json());
140
+ const channel = json.items?.[0];
141
+ if (!channel?.id) {
142
+ throw new Error("YouTubeOAuth: no channel on this Google account");
143
+ }
144
+ const thumb = channel.snippet?.thumbnails?.high?.url ??
145
+ channel.snippet?.thumbnails?.default?.url;
146
+ return {
147
+ providerAccountId: channel.id,
148
+ displayName: channel.snippet?.title ?? "YouTube channel",
149
+ handle: channel.snippet?.customUrl,
150
+ avatarUrl: thumb,
151
+ // YouTube has no API "business" flag; channels are creator-grade by default.
152
+ kind: types_1.ESocialAccountKind.CREATOR,
153
+ };
154
+ }
155
+ }
156
+ exports.YouTubeOAuthProvider = YouTubeOAuthProvider;
@@ -0,0 +1,5 @@
1
+ import { ESocialProvider } from "../../globals/types";
2
+ import { ISocialPublisher } from "./types";
3
+ export declare function getSocialPublisher(provider: ESocialProvider): ISocialPublisher;
4
+ export declare function isSocialPublishSupported(provider: ESocialProvider): boolean;
5
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/services/socialPublish/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAe3C,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,eAAe,GACxB,gBAAgB,CAMlB;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAE3E"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSocialPublisher = getSocialPublisher;
4
+ exports.isSocialPublishSupported = isSocialPublishSupported;
5
+ const types_1 = require("../../globals/types");
6
+ const linkedin_publish_1 = require("./linkedin.publish");
7
+ const meta_publish_1 = require("./meta.publish");
8
+ const pinterest_publish_1 = require("./pinterest.publish");
9
+ const threads_publish_1 = require("./threads.publish");
10
+ const tiktok_publish_1 = require("./tiktok.publish");
11
+ const x_publish_1 = require("./x.publish");
12
+ const youtube_publish_1 = require("./youtube.publish");
13
+ const registry = {
14
+ [types_1.ESocialProvider.YOUTUBE]: () => new youtube_publish_1.YouTubePublisher(),
15
+ [types_1.ESocialProvider.INSTAGRAM]: () => new meta_publish_1.InstagramPublisher(),
16
+ [types_1.ESocialProvider.FACEBOOK]: () => new meta_publish_1.FacebookPublisher(),
17
+ [types_1.ESocialProvider.TIKTOK]: () => new tiktok_publish_1.TikTokPublisher(),
18
+ [types_1.ESocialProvider.THREADS]: () => new threads_publish_1.ThreadsPublisher(),
19
+ [types_1.ESocialProvider.LINKEDIN]: () => new linkedin_publish_1.LinkedInPublisher(),
20
+ [types_1.ESocialProvider.X]: () => new x_publish_1.XPublisher(),
21
+ [types_1.ESocialProvider.PINTEREST]: () => new pinterest_publish_1.PinterestPublisher(),
22
+ };
23
+ function getSocialPublisher(provider) {
24
+ const make = registry[provider];
25
+ if (!make) {
26
+ throw new Error(`Social publishing not implemented for '${provider}'`);
27
+ }
28
+ return make();
29
+ }
30
+ function isSocialPublishSupported(provider) {
31
+ return Boolean(registry[provider]);
32
+ }
@@ -0,0 +1,10 @@
1
+ export * from "./types";
2
+ export * from "./youtube.publish";
3
+ export * from "./meta.publish";
4
+ export * from "./tiktok.publish";
5
+ export * from "./threads.publish";
6
+ export * from "./linkedin.publish";
7
+ export * from "./x.publish";
8
+ export * from "./pinterest.publish";
9
+ export * from "./factory";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/socialPublish/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./youtube.publish"), exports);
19
+ __exportStar(require("./meta.publish"), exports);
20
+ __exportStar(require("./tiktok.publish"), exports);
21
+ __exportStar(require("./threads.publish"), exports);
22
+ __exportStar(require("./linkedin.publish"), exports);
23
+ __exportStar(require("./x.publish"), exports);
24
+ __exportStar(require("./pinterest.publish"), exports);
25
+ __exportStar(require("./factory"), exports);
@@ -0,0 +1,9 @@
1
+ import { ESocialProvider } from "../../globals/types";
2
+ import { ISocialPublisher, PublishInput, PublishResult } from "./types";
3
+ export declare class LinkedInPublisher implements ISocialPublisher {
4
+ readonly provider = ESocialProvider.LINKEDIN;
5
+ publish(input: PublishInput): Promise<PublishResult>;
6
+ private resolveVisibility;
7
+ private buildCommentary;
8
+ }
9
+ //# sourceMappingURL=linkedin.publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkedin.publish.d.ts","sourceRoot":"","sources":["../../../src/services/socialPublish/linkedin.publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AA0CxE,qBAAa,iBAAkB,YAAW,gBAAgB;IACxD,QAAQ,CAAC,QAAQ,4BAA4B;IAEvC,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAwG1D,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,eAAe;CAQxB"}