offcourse 1.0.0 → 1.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 (258) hide show
  1. package/dist/cli/commands/config.js.map +1 -1
  2. package/dist/cli/commands/inspect.js +1 -1
  3. package/dist/cli/commands/inspect.js.map +1 -1
  4. package/dist/cli/commands/sync.d.ts +1 -2
  5. package/dist/cli/commands/sync.d.ts.map +1 -1
  6. package/dist/cli/commands/sync.js +13 -14
  7. package/dist/cli/commands/sync.js.map +1 -1
  8. package/dist/cli/commands/syncHighLevel.d.ts +1 -2
  9. package/dist/cli/commands/syncHighLevel.d.ts.map +1 -1
  10. package/dist/cli/commands/syncHighLevel.js +4 -8
  11. package/dist/cli/commands/syncHighLevel.js.map +1 -1
  12. package/dist/cli/index.js +1 -1
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/config/configManager.d.ts.map +1 -1
  15. package/dist/config/configManager.js +4 -0
  16. package/dist/config/configManager.js.map +1 -1
  17. package/dist/downloader/hlsDownloader.d.ts.map +1 -1
  18. package/dist/downloader/hlsDownloader.js +23 -14
  19. package/dist/downloader/hlsDownloader.js.map +1 -1
  20. package/dist/downloader/hlsValidator.d.ts.map +1 -1
  21. package/dist/downloader/hlsValidator.js +6 -2
  22. package/dist/downloader/hlsValidator.js.map +1 -1
  23. package/dist/downloader/index.d.ts +3 -0
  24. package/dist/downloader/index.d.ts.map +1 -1
  25. package/dist/downloader/index.js +3 -0
  26. package/dist/downloader/index.js.map +1 -1
  27. package/dist/downloader/loomDownloader.d.ts.map +1 -1
  28. package/dist/downloader/loomDownloader.js +23 -20
  29. package/dist/downloader/loomDownloader.js.map +1 -1
  30. package/dist/downloader/queue.d.ts +4 -4
  31. package/dist/downloader/queue.d.ts.map +1 -1
  32. package/dist/downloader/queue.js.map +1 -1
  33. package/dist/downloader/vimeoDownloader.d.ts.map +1 -1
  34. package/dist/downloader/vimeoDownloader.js +7 -3
  35. package/dist/downloader/vimeoDownloader.js.map +1 -1
  36. package/dist/scraper/extractor.d.ts +4 -0
  37. package/dist/scraper/extractor.d.ts.map +1 -1
  38. package/dist/scraper/extractor.js +79 -79
  39. package/dist/scraper/extractor.js.map +1 -1
  40. package/dist/scraper/highlevel/extractor.d.ts +11 -19
  41. package/dist/scraper/highlevel/extractor.d.ts.map +1 -1
  42. package/dist/scraper/highlevel/extractor.js +72 -85
  43. package/dist/scraper/highlevel/extractor.js.map +1 -1
  44. package/dist/scraper/highlevel/navigator.d.ts +3 -10
  45. package/dist/scraper/highlevel/navigator.d.ts.map +1 -1
  46. package/dist/scraper/highlevel/navigator.js +140 -127
  47. package/dist/scraper/highlevel/navigator.js.map +1 -1
  48. package/dist/scraper/highlevel/schemas.d.ts +188 -0
  49. package/dist/scraper/highlevel/schemas.d.ts.map +1 -0
  50. package/dist/scraper/highlevel/schemas.js +139 -0
  51. package/dist/scraper/highlevel/schemas.js.map +1 -0
  52. package/dist/scraper/navigator.d.ts +14 -11
  53. package/dist/scraper/navigator.d.ts.map +1 -1
  54. package/dist/scraper/navigator.js +61 -104
  55. package/dist/scraper/navigator.js.map +1 -1
  56. package/dist/scraper/schemas.d.ts +57 -0
  57. package/dist/scraper/schemas.d.ts.map +1 -0
  58. package/dist/scraper/schemas.js +135 -0
  59. package/dist/scraper/schemas.js.map +1 -0
  60. package/dist/scraper/videoInterceptor.d.ts +4 -0
  61. package/dist/scraper/videoInterceptor.d.ts.map +1 -1
  62. package/dist/scraper/videoInterceptor.js +66 -51
  63. package/dist/scraper/videoInterceptor.js.map +1 -1
  64. package/dist/shared/auth.d.ts +9 -9
  65. package/dist/shared/auth.d.ts.map +1 -1
  66. package/dist/shared/auth.js +24 -38
  67. package/dist/shared/auth.js.map +1 -1
  68. package/dist/shared/firebase.d.ts +60 -0
  69. package/dist/shared/firebase.d.ts.map +1 -0
  70. package/dist/shared/firebase.js +102 -0
  71. package/dist/shared/firebase.js.map +1 -0
  72. package/dist/shared/fs.d.ts.map +1 -1
  73. package/dist/shared/fs.js +4 -0
  74. package/dist/shared/fs.js.map +1 -1
  75. package/dist/shared/index.d.ts +3 -0
  76. package/dist/shared/index.d.ts.map +1 -1
  77. package/dist/shared/index.js +3 -0
  78. package/dist/shared/index.js.map +1 -1
  79. package/dist/shared/slug.d.ts +11 -0
  80. package/dist/shared/slug.d.ts.map +1 -0
  81. package/{src/shared/slug.ts → dist/shared/slug.js} +10 -11
  82. package/dist/shared/slug.js.map +1 -0
  83. package/dist/shared/url.d.ts +43 -0
  84. package/dist/shared/url.d.ts.map +1 -0
  85. package/{src/shared/url.ts → dist/shared/url.js} +12 -15
  86. package/dist/shared/url.js.map +1 -0
  87. package/dist/state/database.d.ts +1 -0
  88. package/dist/state/database.d.ts.map +1 -1
  89. package/dist/state/database.js +3 -0
  90. package/dist/state/database.js.map +1 -1
  91. package/dist/storage/fileSystem.d.ts +17 -17
  92. package/dist/storage/fileSystem.d.ts.map +1 -1
  93. package/dist/storage/fileSystem.js +39 -31
  94. package/dist/storage/fileSystem.js.map +1 -1
  95. package/package.json +5 -2
  96. package/.github/workflows/ci.yml +0 -50
  97. package/.husky/commit-msg +0 -2
  98. package/.husky/pre-commit +0 -1
  99. package/.husky/pre-push +0 -3
  100. package/.prettierrc +0 -8
  101. package/.release-it.json +0 -23
  102. package/ARCHITECTURE.md +0 -233
  103. package/CHANGELOG.md +0 -78
  104. package/commitlint.config.js +0 -4
  105. package/dist/ai/openRouter.d.ts +0 -47
  106. package/dist/ai/openRouter.d.ts.map +0 -1
  107. package/dist/ai/openRouter.js +0 -116
  108. package/dist/ai/openRouter.js.map +0 -1
  109. package/dist/ai/transcriptPolisher.d.ts +0 -24
  110. package/dist/ai/transcriptPolisher.d.ts.map +0 -1
  111. package/dist/ai/transcriptPolisher.js +0 -89
  112. package/dist/ai/transcriptPolisher.js.map +0 -1
  113. package/dist/cli/commands/enrich.d.ts +0 -14
  114. package/dist/cli/commands/enrich.d.ts.map +0 -1
  115. package/dist/cli/commands/enrich.js +0 -271
  116. package/dist/cli/commands/enrich.js.map +0 -1
  117. package/dist/cli/commands/syncGhl.d.ts +0 -20
  118. package/dist/cli/commands/syncGhl.d.ts.map +0 -1
  119. package/dist/cli/commands/syncGhl.js +0 -483
  120. package/dist/cli/commands/syncGhl.js.map +0 -1
  121. package/dist/cli/commands/syncHighLevel.test.d.ts +0 -2
  122. package/dist/cli/commands/syncHighLevel.test.d.ts.map +0 -1
  123. package/dist/cli/commands/syncHighLevel.test.js +0 -102
  124. package/dist/cli/commands/syncHighLevel.test.js.map +0 -1
  125. package/dist/config/paths.test.d.ts +0 -2
  126. package/dist/config/paths.test.d.ts.map +0 -1
  127. package/dist/config/paths.test.js +0 -70
  128. package/dist/config/paths.test.js.map +0 -1
  129. package/dist/config/schema.test.d.ts +0 -2
  130. package/dist/config/schema.test.d.ts.map +0 -1
  131. package/dist/config/schema.test.js +0 -151
  132. package/dist/config/schema.test.js.map +0 -1
  133. package/dist/downloader/hlsDownloader.test.d.ts +0 -2
  134. package/dist/downloader/hlsDownloader.test.d.ts.map +0 -1
  135. package/dist/downloader/hlsDownloader.test.js +0 -116
  136. package/dist/downloader/hlsDownloader.test.js.map +0 -1
  137. package/dist/downloader/loomDownloader.test.d.ts +0 -2
  138. package/dist/downloader/loomDownloader.test.d.ts.map +0 -1
  139. package/dist/downloader/loomDownloader.test.js +0 -36
  140. package/dist/downloader/loomDownloader.test.js.map +0 -1
  141. package/dist/downloader/queue.test.d.ts +0 -2
  142. package/dist/downloader/queue.test.d.ts.map +0 -1
  143. package/dist/downloader/queue.test.js +0 -158
  144. package/dist/downloader/queue.test.js.map +0 -1
  145. package/dist/downloader/videoDownloader.d.ts +0 -32
  146. package/dist/downloader/videoDownloader.d.ts.map +0 -1
  147. package/dist/downloader/videoDownloader.js +0 -173
  148. package/dist/downloader/videoDownloader.js.map +0 -1
  149. package/dist/downloader/vimeoDownloader.test.d.ts +0 -2
  150. package/dist/downloader/vimeoDownloader.test.d.ts.map +0 -1
  151. package/dist/downloader/vimeoDownloader.test.js +0 -51
  152. package/dist/downloader/vimeoDownloader.test.js.map +0 -1
  153. package/dist/scraper/auth.d.ts +0 -29
  154. package/dist/scraper/auth.d.ts.map +0 -1
  155. package/dist/scraper/auth.js +0 -115
  156. package/dist/scraper/auth.js.map +0 -1
  157. package/dist/scraper/extractor.test.d.ts +0 -2
  158. package/dist/scraper/extractor.test.d.ts.map +0 -1
  159. package/dist/scraper/extractor.test.js +0 -65
  160. package/dist/scraper/extractor.test.js.map +0 -1
  161. package/dist/scraper/ghl/auth.d.ts +0 -25
  162. package/dist/scraper/ghl/auth.d.ts.map +0 -1
  163. package/dist/scraper/ghl/auth.js +0 -187
  164. package/dist/scraper/ghl/auth.js.map +0 -1
  165. package/dist/scraper/ghl/extractor.d.ts +0 -96
  166. package/dist/scraper/ghl/extractor.d.ts.map +0 -1
  167. package/dist/scraper/ghl/extractor.js +0 -345
  168. package/dist/scraper/ghl/extractor.js.map +0 -1
  169. package/dist/scraper/ghl/index.d.ts +0 -4
  170. package/dist/scraper/ghl/index.d.ts.map +0 -1
  171. package/dist/scraper/ghl/index.js +0 -4
  172. package/dist/scraper/ghl/index.js.map +0 -1
  173. package/dist/scraper/ghl/navigator.d.ts +0 -93
  174. package/dist/scraper/ghl/navigator.d.ts.map +0 -1
  175. package/dist/scraper/ghl/navigator.js +0 -447
  176. package/dist/scraper/ghl/navigator.js.map +0 -1
  177. package/dist/scraper/highlevel/auth.d.ts +0 -25
  178. package/dist/scraper/highlevel/auth.d.ts.map +0 -1
  179. package/dist/scraper/highlevel/auth.js +0 -189
  180. package/dist/scraper/highlevel/auth.js.map +0 -1
  181. package/dist/scraper/highlevel/extractor.test.d.ts +0 -2
  182. package/dist/scraper/highlevel/extractor.test.d.ts.map +0 -1
  183. package/dist/scraper/highlevel/extractor.test.js +0 -101
  184. package/dist/scraper/highlevel/extractor.test.js.map +0 -1
  185. package/dist/scraper/highlevel/navigator.test.d.ts +0 -2
  186. package/dist/scraper/highlevel/navigator.test.d.ts.map +0 -1
  187. package/dist/scraper/highlevel/navigator.test.js +0 -78
  188. package/dist/scraper/highlevel/navigator.test.js.map +0 -1
  189. package/dist/scraper/navigator.test.d.ts +0 -2
  190. package/dist/scraper/navigator.test.d.ts.map +0 -1
  191. package/dist/scraper/navigator.test.js +0 -63
  192. package/dist/scraper/navigator.test.js.map +0 -1
  193. package/dist/scraper/skoolApi.d.ts +0 -17
  194. package/dist/scraper/skoolApi.d.ts.map +0 -1
  195. package/dist/scraper/skoolApi.js +0 -72
  196. package/dist/scraper/skoolApi.js.map +0 -1
  197. package/dist/state/database.test.d.ts +0 -2
  198. package/dist/state/database.test.d.ts.map +0 -1
  199. package/dist/state/database.test.js +0 -34
  200. package/dist/state/database.test.js.map +0 -1
  201. package/dist/transcription/whisperService.d.ts +0 -27
  202. package/dist/transcription/whisperService.d.ts.map +0 -1
  203. package/dist/transcription/whisperService.js +0 -102
  204. package/dist/transcription/whisperService.js.map +0 -1
  205. package/eslint.config.js +0 -55
  206. package/src/__fixtures__/highlevel-post-response.json +0 -68
  207. package/src/__fixtures__/hls-master-playlist.m3u8 +0 -24
  208. package/src/cli/commands/__snapshots__/syncHighLevel.test.ts.snap +0 -38
  209. package/src/cli/commands/config.ts +0 -74
  210. package/src/cli/commands/inspect.ts +0 -441
  211. package/src/cli/commands/login.ts +0 -68
  212. package/src/cli/commands/status.ts +0 -147
  213. package/src/cli/commands/sync.ts +0 -1235
  214. package/src/cli/commands/syncHighLevel.test.ts +0 -144
  215. package/src/cli/commands/syncHighLevel.ts +0 -639
  216. package/src/cli/index.ts +0 -121
  217. package/src/config/configManager.ts +0 -75
  218. package/src/config/paths.test.ts +0 -83
  219. package/src/config/paths.ts +0 -36
  220. package/src/config/schema.test.ts +0 -173
  221. package/src/config/schema.ts +0 -65
  222. package/src/downloader/hlsDownloader.test.ts +0 -148
  223. package/src/downloader/hlsDownloader.ts +0 -327
  224. package/src/downloader/hlsValidator.ts +0 -196
  225. package/src/downloader/index.ts +0 -122
  226. package/src/downloader/loomDownloader.test.ts +0 -43
  227. package/src/downloader/loomDownloader.ts +0 -742
  228. package/src/downloader/queue.test.ts +0 -199
  229. package/src/downloader/queue.ts +0 -118
  230. package/src/downloader/vimeoDownloader.test.ts +0 -62
  231. package/src/downloader/vimeoDownloader.ts +0 -722
  232. package/src/scraper/extractor.test.ts +0 -124
  233. package/src/scraper/extractor.ts +0 -757
  234. package/src/scraper/highlevel/__snapshots__/extractor.test.ts.snap +0 -41
  235. package/src/scraper/highlevel/extractor.test.ts +0 -134
  236. package/src/scraper/highlevel/extractor.ts +0 -537
  237. package/src/scraper/highlevel/index.ts +0 -2
  238. package/src/scraper/highlevel/navigator.test.ts +0 -110
  239. package/src/scraper/highlevel/navigator.ts +0 -668
  240. package/src/scraper/highlevel/schemas.ts +0 -183
  241. package/src/scraper/navigator.test.ts +0 -122
  242. package/src/scraper/navigator.ts +0 -355
  243. package/src/scraper/schemas.ts +0 -177
  244. package/src/scraper/videoInterceptor.ts +0 -435
  245. package/src/shared/auth.test.ts +0 -58
  246. package/src/shared/auth.ts +0 -251
  247. package/src/shared/firebase.ts +0 -151
  248. package/src/shared/fs.ts +0 -80
  249. package/src/shared/http.ts +0 -34
  250. package/src/shared/index.ts +0 -6
  251. package/src/shared/url.test.ts +0 -122
  252. package/src/state/database.test.ts +0 -49
  253. package/src/state/database.ts +0 -919
  254. package/src/state/index.ts +0 -14
  255. package/src/storage/fileSystem.test.ts +0 -64
  256. package/src/storage/fileSystem.ts +0 -175
  257. package/tsconfig.json +0 -28
  258. package/vitest.config.ts +0 -29
@@ -1 +0,0 @@
1
- {"version":3,"file":"database.test.js","sourceRoot":"","sources":["../../src/state/database.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,oBAAoB,CAAC,oCAAoC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,oBAAoB,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,oBAAoB,CAAC,8CAA8C,CAAC,CAAC,CAAC,IAAI,CAC/E,cAAc,CACf,CAAC;QACF,MAAM,CAAC,oBAAoB,CAAC,0DAA0D,CAAC,CAAC,CAAC,IAAI,CAC3F,cAAc,CACf,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,0DAA0D;QAC1D,MAAM,CAAC,oBAAoB,CAAC,4CAA4C,CAAC,CAAC,CAAC,IAAI,CAC7E,sBAAsB,CACvB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,oBAAoB,CAAC,gDAAgD,CAAC,CAAC,CAAC,IAAI,CACjF,8BAA8B,CAC/B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,oBAAoB,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzE,MAAM,CAAC,oBAAoB,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1D,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvE,MAAM,CAAC,oBAAoB,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,27 +0,0 @@
1
- export type WhisperModel = "tiny" | "base" | "small" | "medium" | "large";
2
- export interface TranscriptionOptions {
3
- model?: WhisperModel;
4
- language?: string;
5
- }
6
- export interface TranscriptionResult {
7
- text: string;
8
- duration: number;
9
- processingTime: number;
10
- }
11
- /**
12
- * Extract audio from video file using ffmpeg.
13
- */
14
- export declare function extractAudio(videoPath: string): string;
15
- /**
16
- * Transcribe audio file using Whisper.
17
- */
18
- export declare function transcribeAudio(audioPath: string, options?: TranscriptionOptions): Promise<TranscriptionResult>;
19
- /**
20
- * Transcribe a video file (extracts audio first).
21
- */
22
- export declare function transcribeVideo(videoPath: string, options?: TranscriptionOptions): Promise<TranscriptionResult>;
23
- /**
24
- * Check if whisper model exists (models are auto-downloaded on first use).
25
- */
26
- export declare function checkModel(_model: WhisperModel): boolean;
27
- //# sourceMappingURL=whisperService.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"whisperService.d.ts","sourceRoot":"","sources":["../../src/transcription/whisperService.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAcD;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAoD9B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAkB9B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAIxD"}
@@ -1,102 +0,0 @@
1
- import { execSync } from "node:child_process";
2
- import { existsSync, unlinkSync, readFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join, basename } from "node:path";
5
- import { nodewhisper } from "nodejs-whisper";
6
- /**
7
- * Strip timestamps from Whisper output and return plain text.
8
- */
9
- function stripTimestamps(rawText) {
10
- return rawText
11
- .replace(/\[\d{2}:\d{2}:\d{2}\.\d{3}\s*-->\s*\d{2}:\d{2}:\d{2}\.\d{3}\]\s*/g, "")
12
- .split("\n")
13
- .map((line) => line.trim())
14
- .filter((line) => line.length > 0)
15
- .join(" ");
16
- }
17
- /**
18
- * Extract audio from video file using ffmpeg.
19
- */
20
- export function extractAudio(videoPath) {
21
- const tempDir = tmpdir();
22
- const audioPath = join(tempDir, `${basename(videoPath, ".mp4")}-${Date.now()}.wav`);
23
- execSync(`ffmpeg -i "${videoPath}" -ar 16000 -ac 1 -c:a pcm_s16le "${audioPath}" -y`, { stdio: "pipe" });
24
- return audioPath;
25
- }
26
- /**
27
- * Transcribe audio file using Whisper.
28
- */
29
- export async function transcribeAudio(audioPath, options = {}) {
30
- const model = options.model ?? "small";
31
- const language = options.language ?? "de";
32
- const startTime = performance.now();
33
- // nodejs-whisper writes output to a .txt file alongside the input
34
- await nodewhisper(audioPath, {
35
- modelName: model,
36
- autoDownloadModelName: model,
37
- removeWavFileAfterTranscription: false,
38
- whisperOptions: {
39
- outputInText: true,
40
- outputInSrt: false,
41
- outputInVtt: false,
42
- translateToEnglish: false,
43
- language: language,
44
- wordTimestamps: false,
45
- },
46
- });
47
- const processingTime = (performance.now() - startTime) / 1000;
48
- // Read the generated transcript file
49
- const txtPath = `${audioPath}.txt`;
50
- let rawText = "";
51
- if (existsSync(txtPath)) {
52
- rawText = readFileSync(txtPath, "utf-8").trim();
53
- // Clean up the txt file
54
- unlinkSync(txtPath);
55
- }
56
- // Strip timestamps, return plain text (LLM will format it)
57
- const text = stripTimestamps(rawText);
58
- // Get audio duration
59
- let duration = 0;
60
- try {
61
- const durationOutput = execSync(`ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${audioPath}"`, { encoding: "utf-8" });
62
- duration = parseFloat(durationOutput.trim()) || 0;
63
- }
64
- catch {
65
- // Ignore duration errors
66
- }
67
- return {
68
- text,
69
- duration,
70
- processingTime,
71
- };
72
- }
73
- /**
74
- * Transcribe a video file (extracts audio first).
75
- */
76
- export async function transcribeVideo(videoPath, options = {}) {
77
- if (!existsSync(videoPath)) {
78
- throw new Error(`Video file not found: ${videoPath}`);
79
- }
80
- // Extract audio
81
- const audioPath = extractAudio(videoPath);
82
- try {
83
- // Transcribe
84
- const result = await transcribeAudio(audioPath, options);
85
- return result;
86
- }
87
- finally {
88
- // Cleanup temp audio file
89
- if (existsSync(audioPath)) {
90
- unlinkSync(audioPath);
91
- }
92
- }
93
- }
94
- /**
95
- * Check if whisper model exists (models are auto-downloaded on first use).
96
- */
97
- export function checkModel(_model) {
98
- // Models are stored in nodejs-whisper's models directory
99
- // They are auto-downloaded on first actual transcription
100
- return true; // Let nodejs-whisper handle downloads
101
- }
102
- //# sourceMappingURL=whisperService.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"whisperService.js","sourceRoot":"","sources":["../../src/transcription/whisperService.ts"],"names":[],"mappings":"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"}
package/eslint.config.js DELETED
@@ -1,55 +0,0 @@
1
- import eslint from "@eslint/js";
2
- import tseslint from "typescript-eslint";
3
- import prettier from "eslint-config-prettier";
4
-
5
- export default tseslint.config(
6
- eslint.configs.recommended,
7
- ...tseslint.configs.strictTypeChecked,
8
- ...tseslint.configs.stylisticTypeChecked,
9
- {
10
- languageOptions: {
11
- parserOptions: {
12
- projectService: true,
13
- tsconfigRootDir: import.meta.dirname,
14
- },
15
- },
16
- },
17
- {
18
- files: ["src/**/*.ts"],
19
- rules: {
20
- // Allow underscore-prefixed unused vars (common pattern)
21
- "@typescript-eslint/no-unused-vars": [
22
- "error",
23
- { argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
24
- ],
25
- // Allow numbers/booleans in template literals
26
- "@typescript-eslint/restrict-template-expressions": [
27
- "error",
28
- { allowNumber: true, allowBoolean: true },
29
- ],
30
- // Empty callbacks are fine (e.g., .catch(() => {}))
31
- "@typescript-eslint/no-empty-function": "off",
32
- // Defensive coding with optional chains is fine
33
- "@typescript-eslint/no-unnecessary-condition": "off",
34
- },
35
- },
36
- {
37
- files: ["src/**/*.test.ts"],
38
- rules: {
39
- // Tests need more flexibility with mocks and fixtures
40
- "@typescript-eslint/require-await": "off",
41
- "@typescript-eslint/no-unsafe-assignment": "off",
42
- "@typescript-eslint/no-unsafe-member-access": "off",
43
- "@typescript-eslint/only-throw-error": "off",
44
- "@typescript-eslint/no-non-null-assertion": "off",
45
- },
46
- },
47
- {
48
- files: ["*.config.js", "*.config.ts"],
49
- ...tseslint.configs.disableTypeChecked,
50
- },
51
- prettier,
52
- {
53
- ignores: ["dist/**", "node_modules/**"],
54
- },
55
- );
@@ -1,68 +0,0 @@
1
- {
2
- "id": "7a06a12e-3501-42f6-bd60-4144d9d9d7ea",
3
- "locationId": "EREskxmNprHK9DrsVSDw",
4
- "originId": null,
5
- "userId": "internal",
6
- "title": "Introduction to the Course",
7
- "description": "Welcome to our comprehensive course! In this lesson, we'll cover the basics.",
8
- "categoryId": "cat-abc-123",
9
- "visibility": "published",
10
- "commentPermission": "enabled",
11
- "sequenceNo": 1,
12
- "posterImage": "/memberships/EREskxmNprHK9DrsVSDw/post/thumbnail.png",
13
- "commentStatus": "open",
14
- "contentId": null,
15
- "contentType": "video",
16
- "productId": "e5f64bf3-9d88-4d02-b10e-516f47866094",
17
- "lockedByPost": null,
18
- "lockedByCategory": null,
19
- "certificateTemplateId": null,
20
- "metaData": null,
21
- "createdAt": "2025-08-11T15:33:59.000Z",
22
- "updatedAt": "2025-08-11T15:47:25.000Z",
23
- "deletedAt": null,
24
- "video": {
25
- "id": "5b47db50-4043-43d2-a4d4-331471b88070",
26
- "locationId": "EREskxmNprHK9DrsVSDw",
27
- "originId": null,
28
- "userId": "internal",
29
- "title": "Introduction Video",
30
- "url": "https://storage.googleapis.com/revex-membership-production/memberships/EREskxmNprHK9DrsVSDw/videos/cts-184162b5f0747fcd_1080p.mp4",
31
- "thumbnail": null,
32
- "postId": "7a06a12e-3501-42f6-bd60-4144d9d9d7ea",
33
- "transcodingStatus": "completed",
34
- "hdTranscoded": null,
35
- "videoFormats": ["360", "1080", "480", "720"],
36
- "rawSize": null,
37
- "transcodedSize": "18463027",
38
- "assetsLicenseId": "689a0d672ea246086539f453",
39
- "transcoderWorkerVideoId": "184162b5f0747fcd",
40
- "transcodingEventHistory": [
41
- {
42
- "event": "VIDEO_TRANSCODED",
43
- "timestamp": "2025-08-11T15:47:25.705Z"
44
- }
45
- ],
46
- "metaData": null,
47
- "createdAt": "2025-08-11T15:33:59.000Z",
48
- "updatedAt": "2025-08-11T15:47:25.000Z",
49
- "deletedAt": null
50
- },
51
- "audio": null,
52
- "post_materials": [
53
- {
54
- "id": "mat-001",
55
- "name": "Course Workbook.pdf",
56
- "url": "https://storage.example.com/materials/workbook.pdf",
57
- "type": "pdf"
58
- },
59
- {
60
- "id": "mat-002",
61
- "name": "Resource Links.txt",
62
- "url": "https://storage.example.com/materials/links.txt",
63
- "type": "text"
64
- }
65
- ],
66
- "asset_urls": {}
67
- }
68
-
@@ -1,24 +0,0 @@
1
- #EXTM3U
2
- #EXT-X-VERSION:4
3
- #EXT-X-INDEPENDENT-SEGMENTS
4
-
5
- # 240p quality
6
- #EXT-X-STREAM-INF:BANDWIDTH=326400,AVERAGE-BANDWIDTH=246064,CODECS="avc1.4D401E,mp4a.40.2",RESOLUTION=426x240,FRAME-RATE=24.000
7
- https://cdn.example.com/video/240p/index.m3u8
8
-
9
- # 360p quality
10
- #EXT-X-STREAM-INF:BANDWIDTH=796800,AVERAGE-BANDWIDTH=602416,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=640x360,FRAME-RATE=24.000
11
- https://cdn.example.com/video/360p/index.m3u8
12
-
13
- # 480p quality
14
- #EXT-X-STREAM-INF:BANDWIDTH=1680000,AVERAGE-BANDWIDTH=1270416,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=854x480,FRAME-RATE=24.000
15
- https://cdn.example.com/video/480p/index.m3u8
16
-
17
- # 720p quality
18
- #EXT-X-STREAM-INF:BANDWIDTH=3200000,AVERAGE-BANDWIDTH=2400000,CODECS="avc1.4D4020,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=24.000
19
- https://cdn.example.com/video/720p/index.m3u8
20
-
21
- # 1080p quality
22
- #EXT-X-STREAM-INF:BANDWIDTH=6000000,AVERAGE-BANDWIDTH=4500000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=24.000
23
- https://cdn.example.com/video/1080p/index.m3u8
24
-
@@ -1,38 +0,0 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
-
3
- exports[`formatHighLevelMarkdown > snapshot: complete lesson with all parts 1`] = `
4
- "# Complete Module: Advanced Techniques
5
-
6
- In this comprehensive module, you'll learn advanced strategies.
7
-
8
- ## Video
9
-
10
- Video URL: https://cdn.example.com/videos/advanced-techniques.mp4
11
-
12
- ---
13
-
14
- Let's dive into the key concepts:
15
-
16
- - Concept A
17
- - Concept B
18
- - Concept C
19
- Remember to practice daily!
20
- "
21
- `;
22
-
23
- exports[`formatHighLevelMarkdown > snapshot: lesson with HTML entities and special chars 1`] = `
24
- "# Q&A Session: Common Questions
25
-
26
- Your questions answered!
27
-
28
- ---
29
-
30
- Q: What&apos;s the best approach?
31
-
32
- A: It depends on your goals & resources.
33
-
34
-
35
-
36
- <script> tags are blocked
37
- "
38
- `;
@@ -1,74 +0,0 @@
1
- import chalk from "chalk";
2
- import { getConfigValue, loadConfig, updateConfig } from "../../config/configManager.js";
3
- import { CONFIG_FILE } from "../../config/paths.js";
4
- import type { Config } from "../../config/schema.js";
5
- import { configSchema } from "../../config/schema.js";
6
-
7
- /**
8
- * Shows all current configuration values.
9
- */
10
- export function configShowCommand(): void {
11
- const config = loadConfig();
12
-
13
- console.log(chalk.blue("\n⚙️ Configuration\n"));
14
- console.log(chalk.gray(` File: ${CONFIG_FILE}\n`));
15
-
16
- for (const [key, value] of Object.entries(config)) {
17
- console.log(` ${chalk.cyan(key)}: ${chalk.white(String(value))}`);
18
- }
19
- console.log();
20
- }
21
-
22
- /**
23
- * Sets a configuration value.
24
- */
25
- export function configSetCommand(key: string, value: string): void {
26
- const validKeys = Object.keys(configSchema.shape) as (keyof Config)[];
27
-
28
- if (!validKeys.includes(key as keyof Config)) {
29
- console.log(chalk.red(`\n❌ Unknown config key: ${key}`));
30
- console.log(chalk.gray(` Valid keys: ${validKeys.join(", ")}\n`));
31
- process.exit(1);
32
- }
33
-
34
- // Parse value based on expected type
35
- const currentValue = getConfigValue(key as keyof Config);
36
- let parsedValue: string | number | boolean;
37
-
38
- if (typeof currentValue === "boolean") {
39
- parsedValue = value === "true" || value === "1";
40
- } else if (typeof currentValue === "number") {
41
- parsedValue = parseInt(value, 10);
42
- if (isNaN(parsedValue)) {
43
- console.log(chalk.red(`\n❌ Invalid number: ${value}\n`));
44
- process.exit(1);
45
- }
46
- } else {
47
- parsedValue = value;
48
- }
49
-
50
- try {
51
- updateConfig({ [key]: parsedValue });
52
- console.log(chalk.green(`\n✅ Set ${key} = ${parsedValue}\n`));
53
- } catch (error) {
54
- console.log(chalk.red(`\n❌ Invalid value for ${key}: ${value}`));
55
- console.log(chalk.gray(` ${String(error)}\n`));
56
- process.exit(1);
57
- }
58
- }
59
-
60
- /**
61
- * Gets a specific configuration value.
62
- */
63
- export function configGetCommand(key: string): void {
64
- const validKeys = Object.keys(configSchema.shape) as (keyof Config)[];
65
-
66
- if (!validKeys.includes(key as keyof Config)) {
67
- console.log(chalk.red(`\n❌ Unknown config key: ${key}`));
68
- console.log(chalk.gray(` Valid keys: ${validKeys.join(", ")}\n`));
69
- process.exit(1);
70
- }
71
-
72
- const value = getConfigValue(key as keyof Config);
73
- console.log(String(value));
74
- }