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
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Zod schemas for HighLevel API responses.
3
+ * These provide runtime validation and type inference.
4
+ */
5
+ import { z } from "zod";
6
+ // Re-export Firebase auth types (Firebase is used by HighLevel for auth)
7
+ export { FirebaseAuthTokenSchema, } from "../../shared/firebase.js";
8
+ // ============================================================================
9
+ // Portal Settings API
10
+ // ============================================================================
11
+ export const PortalSettingsResponseSchema = z.object({
12
+ locationId: z.string(),
13
+ portalName: z.string().optional(),
14
+ name: z.string().optional(),
15
+ });
16
+ // ============================================================================
17
+ // Video License API
18
+ // ============================================================================
19
+ export const VideoLicenseResponseSchema = z.object({
20
+ url: z.string(),
21
+ token: z.string(),
22
+ });
23
+ // ============================================================================
24
+ // Post Details API
25
+ // ============================================================================
26
+ const VideoAssetSchema = z.object({
27
+ id: z.string().optional(),
28
+ assetId: z.string().optional(),
29
+ assetsLicenseId: z.string().optional(),
30
+ url: z.string().optional(),
31
+ });
32
+ const PosterImageSchema = z.object({
33
+ assetId: z.string().optional(),
34
+ url: z.string().optional(),
35
+ });
36
+ const ContentBlockSchema = z.object({
37
+ type: z.string(),
38
+ id: z.string().optional(),
39
+ assetId: z.string().optional(),
40
+ assetsLicenseId: z.string().optional(),
41
+ url: z.string().optional(),
42
+ });
43
+ const MaterialSchema = z.object({
44
+ id: z.string().optional(),
45
+ name: z.string().optional(),
46
+ url: z.string().optional(),
47
+ type: z.string().optional(),
48
+ });
49
+ export const PostDetailsSchema = z.object({
50
+ title: z.string().optional(),
51
+ description: z.string().nullable().optional(),
52
+ video: VideoAssetSchema.nullable().optional(),
53
+ posterImage: PosterImageSchema.nullable().optional(),
54
+ contentBlock: z.array(ContentBlockSchema).optional(),
55
+ materials: z.array(MaterialSchema).optional(),
56
+ post_materials: z.array(MaterialSchema).optional(),
57
+ });
58
+ // Response can have data directly or wrapped in "post"
59
+ export const PostDetailsResponseSchema = z.object({
60
+ post: PostDetailsSchema.optional(),
61
+ // Also allow all post fields directly on root
62
+ title: z.string().optional(),
63
+ description: z.string().nullable().optional(),
64
+ video: VideoAssetSchema.nullable().optional(),
65
+ posterImage: PosterImageSchema.nullable().optional(),
66
+ contentBlock: z.array(ContentBlockSchema).optional(),
67
+ materials: z.array(MaterialSchema).optional(),
68
+ post_materials: z.array(MaterialSchema).optional(),
69
+ });
70
+ // ============================================================================
71
+ // Categories API
72
+ // ============================================================================
73
+ export const CategorySchema = z.object({
74
+ id: z.string(),
75
+ title: z.string(),
76
+ description: z.string().nullable().optional(),
77
+ position: z.number().optional(),
78
+ postCount: z.number().optional(),
79
+ visibility: z.string().optional(),
80
+ });
81
+ export const CategoriesResponseSchema = z.object({
82
+ categories: z.array(CategorySchema),
83
+ });
84
+ // ============================================================================
85
+ // Posts (Lessons) API
86
+ // ============================================================================
87
+ export const PostSchema = z.object({
88
+ id: z.string(),
89
+ title: z.string(),
90
+ indexPosition: z.number().optional(),
91
+ visibility: z.string().optional(),
92
+ });
93
+ export const PostsResponseSchema = z.object({
94
+ category: z
95
+ .object({
96
+ posts: z.array(PostSchema),
97
+ })
98
+ .optional(),
99
+ });
100
+ // ============================================================================
101
+ // Product (Course) API
102
+ // ============================================================================
103
+ export const ProductSchema = z.object({
104
+ id: z.string().optional(),
105
+ title: z.string(),
106
+ description: z.string().optional(),
107
+ posterImage: z.string().nullable().optional(),
108
+ instructor: z.string().nullable().optional(),
109
+ postCount: z.number().optional(),
110
+ });
111
+ export const ProductResponseSchema = z.object({
112
+ product: ProductSchema.optional(),
113
+ // Also allow fields directly on root
114
+ id: z.string().optional(),
115
+ title: z.string().optional(),
116
+ description: z.string().optional(),
117
+ posterImage: z.string().nullable().optional(),
118
+ instructor: z.string().nullable().optional(),
119
+ postCount: z.number().optional(),
120
+ });
121
+ // ============================================================================
122
+ // Helper: Safe parse with logging
123
+ // ============================================================================
124
+ /**
125
+ * Safely parses data with a Zod schema.
126
+ * Returns the parsed data or null if validation fails.
127
+ * Logs validation errors for debugging.
128
+ */
129
+ export function safeParse(schema, data, context) {
130
+ const result = schema.safeParse(data);
131
+ if (result.success) {
132
+ return result.data;
133
+ }
134
+ if (context) {
135
+ console.warn(`[${context}] Validation failed:`, z.treeifyError(result.error));
136
+ }
137
+ return null;
138
+ }
139
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/scraper/highlevel/schemas.ts"],"names":[],"mappings":"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"}
@@ -15,9 +15,9 @@ export interface Lesson {
15
15
  export interface CourseStructure {
16
16
  name: string;
17
17
  url: string;
18
- modules: Array<CourseModule & {
18
+ modules: (CourseModule & {
19
19
  lessons: Lesson[];
20
- }>;
20
+ })[];
21
21
  }
22
22
  /**
23
23
  * Extracts the course/community name from page data.
@@ -37,6 +37,17 @@ export declare function extractLessons(page: Page, moduleUrl: string): Promise<L
37
37
  * Alternative: Extract modules from the classroom overview page links.
38
38
  */
39
39
  export declare function extractModulesFromPage(page: Page): Promise<CourseModule[]>;
40
+ /**
41
+ * Checks if a URL points to a specific module (has 8-char hex slug).
42
+ */
43
+ export declare function isModuleUrl(url: string): {
44
+ isModule: boolean;
45
+ moduleSlug: string | null;
46
+ };
47
+ /**
48
+ * Gets the classroom base URL (without module slug).
49
+ */
50
+ export declare function getClassroomBaseUrl(url: string): string;
40
51
  /**
41
52
  * Progress callback for buildCourseStructure.
42
53
  */
@@ -53,13 +64,5 @@ export interface ScanProgress {
53
64
  * Builds the complete course structure by crawling all modules and lessons.
54
65
  */
55
66
  export declare function buildCourseStructure(page: Page, classroomUrl: string, onProgress?: (progress: ScanProgress) => void): Promise<CourseStructure>;
56
- /**
57
- * Creates a filesystem-safe name from a string.
58
- * Uses @sindresorhus/slugify for proper transliteration.
59
- */
60
- export declare function slugify(name: string): string;
61
- /**
62
- * Creates a folder name with index prefix.
63
- */
64
- export declare function createFolderName(index: number, name: string): string;
67
+ export { slugify, createFolderName } from "../shared/slug.js";
65
68
  //# sourceMappingURL=navigator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigator.d.ts","sourceRoot":"","sources":["../../src/scraper/navigator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,KAAK,CAAC,YAAY,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAKnE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAkFhF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsFrF;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA0ChF;AAqBD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,GAC5C,OAAO,CAAC,eAAe,CAAC,CA4E1B;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIpE"}
1
+ {"version":3,"file":"navigator.d.ts","sourceRoot":"","sources":["../../src/scraper/navigator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAOvC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,CAAC,YAAY,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,EAAE,CAAC;CACnD;AAKD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAKnE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAqEhF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkErF;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA0ChF;AAGD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAMzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAGD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,GAC5C,OAAO,CAAC,eAAe,CAAC,CA0E1B;AAID,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,4 +1,6 @@
1
- import slugifyLib from "@sindresorhus/slugify";
1
+ import { parseNextData, extractModulesFromNextData, extractLessonAccessFromNextData, } from "./schemas.js";
2
+ // Browser automation - requires Playwright
3
+ /* v8 ignore start */
2
4
  /**
3
5
  * Extracts the course/community name from page data.
4
6
  */
@@ -13,41 +15,29 @@ export async function extractCourseName(page) {
13
15
  * Skool embeds course structure as JSON in a script tag.
14
16
  */
15
17
  export async function extractModulesFromJson(page) {
16
- const modules = await page.evaluate(() => {
17
- // Try to get module data from __NEXT_DATA__
18
+ // Get the raw JSON from the page
19
+ const nextDataJson = await page.evaluate(() => {
18
20
  const nextDataScript = document.getElementById("__NEXT_DATA__");
19
- if (nextDataScript?.textContent) {
20
- try {
21
- const json = JSON.parse(nextDataScript.textContent);
22
- const courseChildren = json?.props?.pageProps?.course?.children;
23
- if (Array.isArray(courseChildren)) {
24
- const results = [];
25
- for (const child of courseChildren) {
26
- const course = child?.course;
27
- if (!course?.name || !/^[a-f0-9]{8}$/.test(course.name))
28
- continue;
29
- const slug = course.name;
30
- const title = course.metadata?.title ?? `Module ${results.length + 1}`;
31
- // Check hasAccess field - if false, the module/lesson is locked
32
- const hasAccess = child?.hasAccess !== false;
33
- if (!results.some((m) => m.slug === slug)) {
34
- results.push({
35
- name: title,
36
- slug,
37
- url: "",
38
- isLocked: !hasAccess,
39
- });
40
- }
41
- }
42
- if (results.length > 0)
43
- return results;
44
- }
45
- }
46
- catch {
47
- // Fall through to regex approach
21
+ return nextDataScript?.textContent ?? null;
22
+ });
23
+ // Parse and validate with Zod schema (in Node context)
24
+ if (nextDataJson) {
25
+ const parsed = parseNextData(nextDataJson);
26
+ if (parsed) {
27
+ const skoolModules = extractModulesFromNextData(parsed);
28
+ if (skoolModules.length > 0) {
29
+ const baseUrl = page.url().split("/classroom")[0];
30
+ return skoolModules.map((m) => ({
31
+ name: m.title,
32
+ slug: m.slug,
33
+ url: `${baseUrl}/classroom/${m.slug}`,
34
+ isLocked: !m.hasAccess,
35
+ }));
48
36
  }
49
37
  }
50
- // Fallback: Find script tags that contain course data
38
+ }
39
+ // Fallback: Find script tags that contain course data (regex approach)
40
+ const modules = await page.evaluate(() => {
51
41
  const scripts = Array.from(document.querySelectorAll("script"));
52
42
  const results = [];
53
43
  for (const script of scripts) {
@@ -94,29 +84,22 @@ export async function extractLessons(page, moduleUrl) {
94
84
  await page.waitForLoadState("domcontentloaded");
95
85
  await page.waitForTimeout(2000);
96
86
  }
97
- const lessons = await page.evaluate(() => {
98
- const results = [];
99
- // First try to get hasAccess from __NEXT_DATA__
100
- const accessMap = new Map();
87
+ // Get __NEXT_DATA__ and parse it in Node context
88
+ const nextDataJson = await page.evaluate(() => {
101
89
  const nextDataScript = document.getElementById("__NEXT_DATA__");
102
- if (nextDataScript?.textContent) {
103
- try {
104
- const json = JSON.parse(nextDataScript.textContent);
105
- const courseChildren = json?.props?.pageProps?.course?.children;
106
- if (Array.isArray(courseChildren)) {
107
- for (const child of courseChildren) {
108
- const lessonId = child?.course?.id;
109
- const hasAccess = child?.hasAccess;
110
- if (lessonId && typeof hasAccess === "boolean") {
111
- accessMap.set(lessonId, hasAccess);
112
- }
113
- }
114
- }
115
- }
116
- catch {
117
- // Ignore parse errors
118
- }
90
+ return nextDataScript?.textContent ?? null;
91
+ });
92
+ // Build access map from validated data
93
+ let accessMap = new Map();
94
+ if (nextDataJson) {
95
+ const parsed = parseNextData(nextDataJson);
96
+ if (parsed) {
97
+ accessMap = extractLessonAccessFromNextData(parsed);
119
98
  }
99
+ }
100
+ // Extract lesson links from DOM
101
+ const lessonData = await page.evaluate(() => {
102
+ const results = [];
120
103
  // Skool uses styled-components with "ChildrenLink" in the class name
121
104
  const lessonLinks = document.querySelectorAll('a[class*="ChildrenLink"]');
122
105
  lessonLinks.forEach((link, index) => {
@@ -126,39 +109,27 @@ export async function extractLessons(page, moduleUrl) {
126
109
  // Extract lesson ID from URL (?md=...)
127
110
  const urlParams = new URL(href).searchParams;
128
111
  const lessonId = urlParams.get("md") ?? "";
129
- // Check hasAccess from JSON data first
130
- let isLocked = false;
131
- if (accessMap.has(lessonId)) {
132
- isLocked = !accessMap.get(lessonId);
133
- }
134
- else {
135
- // Fallback: Check for lock icon in DOM
136
- let parent = anchor;
137
- for (let i = 0; i < 3 && parent; i++) {
138
- if (parent.querySelector('[class*="lock"], [class*="Lock"], svg[class*="lock"], svg[class*="Lock"]')) {
139
- isLocked = true;
140
- break;
141
- }
142
- parent = parent.parentElement;
143
- }
144
- // Also check if the link itself has a lock indicator
145
- if (anchor.querySelector('[class*="lock"], [class*="Lock"]')) {
146
- isLocked = true;
147
- }
148
- }
149
112
  if (lessonId && !results.some((l) => l.slug === lessonId)) {
150
- results.push({
151
- name,
152
- slug: lessonId,
153
- url: href,
154
- index: results.length,
155
- isLocked,
156
- });
113
+ results.push({ name, slug: lessonId, href });
157
114
  }
158
115
  });
159
116
  return results;
160
117
  });
161
- return lessons;
118
+ // Build final lesson list with access info
119
+ return lessonData.map((lesson, index) => {
120
+ let isLocked = false;
121
+ // Check access map from __NEXT_DATA__
122
+ if (accessMap.has(lesson.slug)) {
123
+ isLocked = !accessMap.get(lesson.slug);
124
+ }
125
+ return {
126
+ name: lesson.name,
127
+ slug: lesson.slug,
128
+ url: lesson.href,
129
+ index,
130
+ isLocked,
131
+ };
132
+ });
162
133
  }
163
134
  /**
164
135
  * Alternative: Extract modules from the classroom overview page links.
@@ -198,10 +169,11 @@ export async function extractModulesFromPage(page) {
198
169
  });
199
170
  return modules;
200
171
  }
172
+ /* v8 ignore stop */
201
173
  /**
202
174
  * Checks if a URL points to a specific module (has 8-char hex slug).
203
175
  */
204
- function isModuleUrl(url) {
176
+ export function isModuleUrl(url) {
205
177
  const match = /\/classroom\/([a-f0-9]{8})(?:\?|$)/.exec(url);
206
178
  return {
207
179
  isModule: !!match,
@@ -211,10 +183,11 @@ function isModuleUrl(url) {
211
183
  /**
212
184
  * Gets the classroom base URL (without module slug).
213
185
  */
214
- function getClassroomBaseUrl(url) {
186
+ export function getClassroomBaseUrl(url) {
215
187
  // Remove module slug and query params
216
188
  return url.replace(/\/classroom\/[a-f0-9]{8}.*$/, "/classroom");
217
189
  }
190
+ /* v8 ignore start */
218
191
  /**
219
192
  * Builds the complete course structure by crawling all modules and lessons.
220
193
  */
@@ -242,8 +215,7 @@ export async function buildCourseStructure(page, classroomUrl, onProgress) {
242
215
  }
243
216
  onProgress?.({ phase: "modules", totalModules: modules.length });
244
217
  const modulesWithLessons = [];
245
- for (let i = 0; i < modules.length; i++) {
246
- const module = modules[i];
218
+ for (const [i, module] of modules.entries()) {
247
219
  if (module.isLocked) {
248
220
  onProgress?.({
249
221
  phase: "lessons",
@@ -279,22 +251,7 @@ export async function buildCourseStructure(page, classroomUrl, onProgress) {
279
251
  modules: modulesWithLessons,
280
252
  };
281
253
  }
282
- /**
283
- * Creates a filesystem-safe name from a string.
284
- * Uses @sindresorhus/slugify for proper transliteration.
285
- */
286
- export function slugify(name) {
287
- return slugifyLib(name, {
288
- lowercase: true,
289
- separator: "-",
290
- }).substring(0, 100);
291
- }
292
- /**
293
- * Creates a folder name with index prefix.
294
- */
295
- export function createFolderName(index, name) {
296
- const prefix = String(index + 1).padStart(2, "0");
297
- const slug = slugify(name);
298
- return `${prefix}-${slug}`;
299
- }
254
+ /* v8 ignore stop */
255
+ // Re-export shared utilities for backwards compatibility
256
+ export { slugify, createFolderName } from "../shared/slug.js";
300
257
  //# sourceMappingURL=navigator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigator.js","sourceRoot":"","sources":["../../src/scraper/navigator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"navigator.js","sourceRoot":"","sources":["../../src/scraper/navigator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,0BAA0B,EAC1B,+BAA+B,GAChC,MAAM,cAAc,CAAC;AAuBtB,2CAA2C;AAC3C,qBAAqB;AAErB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAU;IAChD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACjC,6CAA6C;IAC7C,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,gBAAgB,CAAC;AAC3F,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAU;IACrD,iCAAiC;IACjC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;QAC5C,MAAM,cAAc,GAAG,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QAChE,OAAO,cAAc,EAAE,WAAW,IAAI,IAAI,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,uDAAuD;IACvD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,YAAY,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;YACxD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClD,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC9B,IAAI,EAAE,CAAC,CAAC,KAAK;oBACb,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,GAAG,EAAE,GAAG,OAAO,cAAc,CAAC,CAAC,IAAI,EAAE;oBACrC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS;iBACvB,CAAC,CAAC,CAAC;YACN,CAAC;QACH,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;QACvC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChE,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;YAEzC,2CAA2C;YAC3C,yEAAyE;YACzE,yEAAyE;YACzE,MAAM,aAAa,GAAG,6DAA6D,CAAC;YACpF,IAAI,KAAK,CAAC;YAEV,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBACtD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBAEvB,wBAAwB;gBACxB,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;oBAC3D,6CAA6C;oBAC7C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC,EAAE,IAAY,EAAE,EAAE,CAC7E,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CACxC,CAAC;oBAEF,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,YAAY;wBAClB,IAAI;wBACJ,GAAG,EAAE,EAAE,EAAE,oBAAoB;wBAC7B,QAAQ,EAAE,KAAK;qBAChB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,6BAA6B;IAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAElD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9B,GAAG,MAAM;QACT,GAAG,EAAE,GAAG,OAAO,cAAc,MAAM,CAAC,IAAI,EAAE;KAC3C,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAU,EAAE,SAAiB;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE9B,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IAC5D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;QAChD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,iDAAiD;IACjD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;QAC5C,MAAM,cAAc,GAAG,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QAChE,OAAO,cAAc,EAAE,WAAW,IAAI,IAAI,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,uCAAuC;IACvC,IAAI,SAAS,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC3C,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACX,SAAS,GAAG,+BAA+B,CAAC,MAAM,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;QAC1C,MAAM,OAAO,GAAmD,EAAE,CAAC;QAEnE,qEAAqE;QACrE,MAAM,WAAW,GAAG,QAAQ,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;QAE1E,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAClC,MAAM,MAAM,GAAG,IAAyB,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,UAAU,KAAK,GAAG,CAAC,EAAE,CAAC;YAEjE,uCAAuC;YACvC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC;YAC7C,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAE3C,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAC1D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,2CAA2C;IAC3C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACtC,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,sCAAsC;QACtC,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,QAAQ,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QAED,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,GAAG,EAAE,MAAM,CAAC,IAAI;YAChB,KAAK;YACL,QAAQ;SACT,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAU;IACrD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAEhC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;QACvC,wEAAwE;QACxE,MAAM,WAAW,GAAG,QAAQ,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;QACxE,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAE/B,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAG,IAAyB,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YAEzB,iDAAiD;YACjD,MAAM,SAAS,GAAG,oCAAoC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;gBAAE,OAAO;YAE5B,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO;YAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAEf,kDAAkD;YAClD,MAAM,OAAO,GACX,IAAI,CAAC,aAAa,CAAC,4CAA4C,CAAC;gBAChE,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;YACxC,MAAM,IAAI,GAAG,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,UAAU,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAE5E,sBAAsB;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,kCAAkC,CAAC,KAAK,IAAI,CAAC;YAEjF,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,IAAI;gBACJ,GAAG,EAAE,IAAI;gBACT,QAAQ;aACT,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AACD,oBAAoB;AAEpB;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,KAAK,GAAG,oCAAoC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7D,OAAO;QACL,QAAQ,EAAE,CAAC,CAAC,KAAK;QACjB,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI;KAC/B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,sCAAsC;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,6BAA6B,EAAE,YAAY,CAAC,CAAC;AAClE,CAAC;AAeD,qBAAqB;AACrB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAU,EACV,YAAoB,EACpB,UAA6C;IAE7C,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;IAE3D,uEAAuE;IACvE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;IAErF,wDAAwD;IACxD,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,MAAM,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IAChD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAEhC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACjD,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAE5C,wEAAwE;IACxE,IAAI,OAAO,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAEjD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,+DAA+D;IAC/D,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAChE,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEjE,MAAM,kBAAkB,GAA+B,EAAE,CAAC;IAE1D,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAC5C,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,UAAU,EAAE,CAAC;gBACX,KAAK,EAAE,SAAS;gBAChB,aAAa,EAAE,MAAM,CAAC,IAAI;gBAC1B,kBAAkB,EAAE,CAAC;gBACrB,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,UAAU,EAAE,CAAC;YACX,KAAK,EAAE,SAAS;YAChB,aAAa,EAAE,MAAM,CAAC,IAAI;YAC1B,kBAAkB,EAAE,CAAC;SACtB,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YAEvD,UAAU,EAAE,CAAC;gBACX,KAAK,EAAE,SAAS;gBAChB,aAAa,EAAE,MAAM,CAAC,IAAI;gBAC1B,kBAAkB,EAAE,CAAC;gBACrB,YAAY,EAAE,OAAO,CAAC,MAAM;aAC7B,CAAC,CAAC;YAEH,kBAAkB,CAAC,IAAI,CAAC;gBACtB,GAAG,MAAM;gBACT,OAAO;aACR,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAEhC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,GAAG,EAAE,gBAAgB;QACrB,OAAO,EAAE,kBAAkB;KAC5B,CAAC;AACJ,CAAC;AACD,oBAAoB;AAEpB,yDAAyD;AACzD,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Zod schemas for Skool/Next.js __NEXT_DATA__ responses.
3
+ * These validate only the fields we actually use, ignoring everything else.
4
+ */
5
+ import { z } from "zod";
6
+ export declare const SkoolNextDataSchema: z.ZodObject<{
7
+ props: z.ZodOptional<z.ZodObject<{
8
+ pageProps: z.ZodOptional<z.ZodObject<{
9
+ course: z.ZodOptional<z.ZodObject<{
10
+ children: z.ZodOptional<z.ZodArray<z.ZodObject<{
11
+ course: z.ZodOptional<z.ZodObject<{
12
+ id: z.ZodOptional<z.ZodString>;
13
+ name: z.ZodOptional<z.ZodString>;
14
+ metadata: z.ZodOptional<z.ZodObject<{
15
+ title: z.ZodOptional<z.ZodString>;
16
+ videoLink: z.ZodOptional<z.ZodString>;
17
+ }, z.core.$loose>>;
18
+ }, z.core.$loose>>;
19
+ hasAccess: z.ZodOptional<z.ZodBoolean>;
20
+ }, z.core.$loose>>>;
21
+ }, z.core.$loose>>;
22
+ selectedModule: z.ZodOptional<z.ZodString>;
23
+ }, z.core.$loose>>;
24
+ }, z.core.$loose>>;
25
+ }, z.core.$loose>;
26
+ export type SkoolNextData = z.infer<typeof SkoolNextDataSchema>;
27
+ export interface SkoolModule {
28
+ slug: string;
29
+ title: string;
30
+ hasAccess: boolean;
31
+ }
32
+ export interface SkoolLesson {
33
+ id: string;
34
+ hasAccess: boolean;
35
+ }
36
+ export interface SkoolVideoInfo {
37
+ url: string;
38
+ type: "loom" | "vimeo" | "youtube" | "wistia" | "unknown";
39
+ }
40
+ /**
41
+ * Safely parses __NEXT_DATA__ JSON from a script element.
42
+ * Returns null if parsing fails.
43
+ */
44
+ export declare function parseNextData(json: string): SkoolNextData | null;
45
+ /**
46
+ * Extracts modules from parsed __NEXT_DATA__.
47
+ */
48
+ export declare function extractModulesFromNextData(data: SkoolNextData): SkoolModule[];
49
+ /**
50
+ * Extracts lesson access info from parsed __NEXT_DATA__.
51
+ */
52
+ export declare function extractLessonAccessFromNextData(data: SkoolNextData): Map<string, boolean>;
53
+ /**
54
+ * Extracts video URL from parsed __NEXT_DATA__ for a specific module.
55
+ */
56
+ export declare function extractVideoFromNextData(data: SkoolNextData, selectedModuleId: string): SkoolVideoInfo | null;
57
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/scraper/schemas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmCxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;iBAM9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAMhE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC3D;AAMD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAYhE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,aAAa,GAAG,WAAW,EAAE,CAyB7E;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAezF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,aAAa,EACnB,gBAAgB,EAAE,MAAM,GACvB,cAAc,GAAG,IAAI,CA4BvB"}