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.
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/inspect.js +1 -1
- package/dist/cli/commands/inspect.js.map +1 -1
- package/dist/cli/commands/sync.d.ts +1 -2
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/commands/sync.js +13 -14
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/syncHighLevel.d.ts +1 -2
- package/dist/cli/commands/syncHighLevel.d.ts.map +1 -1
- package/dist/cli/commands/syncHighLevel.js +4 -8
- package/dist/cli/commands/syncHighLevel.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/config/configManager.d.ts.map +1 -1
- package/dist/config/configManager.js +4 -0
- package/dist/config/configManager.js.map +1 -1
- package/dist/downloader/hlsDownloader.d.ts.map +1 -1
- package/dist/downloader/hlsDownloader.js +23 -14
- package/dist/downloader/hlsDownloader.js.map +1 -1
- package/dist/downloader/hlsValidator.d.ts.map +1 -1
- package/dist/downloader/hlsValidator.js +6 -2
- package/dist/downloader/hlsValidator.js.map +1 -1
- package/dist/downloader/index.d.ts +3 -0
- package/dist/downloader/index.d.ts.map +1 -1
- package/dist/downloader/index.js +3 -0
- package/dist/downloader/index.js.map +1 -1
- package/dist/downloader/loomDownloader.d.ts.map +1 -1
- package/dist/downloader/loomDownloader.js +23 -20
- package/dist/downloader/loomDownloader.js.map +1 -1
- package/dist/downloader/queue.d.ts +4 -4
- package/dist/downloader/queue.d.ts.map +1 -1
- package/dist/downloader/queue.js.map +1 -1
- package/dist/downloader/vimeoDownloader.d.ts.map +1 -1
- package/dist/downloader/vimeoDownloader.js +7 -3
- package/dist/downloader/vimeoDownloader.js.map +1 -1
- package/dist/scraper/extractor.d.ts +4 -0
- package/dist/scraper/extractor.d.ts.map +1 -1
- package/dist/scraper/extractor.js +79 -79
- package/dist/scraper/extractor.js.map +1 -1
- package/dist/scraper/highlevel/extractor.d.ts +11 -19
- package/dist/scraper/highlevel/extractor.d.ts.map +1 -1
- package/dist/scraper/highlevel/extractor.js +72 -85
- package/dist/scraper/highlevel/extractor.js.map +1 -1
- package/dist/scraper/highlevel/navigator.d.ts +3 -10
- package/dist/scraper/highlevel/navigator.d.ts.map +1 -1
- package/dist/scraper/highlevel/navigator.js +140 -127
- package/dist/scraper/highlevel/navigator.js.map +1 -1
- package/dist/scraper/highlevel/schemas.d.ts +188 -0
- package/dist/scraper/highlevel/schemas.d.ts.map +1 -0
- package/dist/scraper/highlevel/schemas.js +139 -0
- package/dist/scraper/highlevel/schemas.js.map +1 -0
- package/dist/scraper/navigator.d.ts +14 -11
- package/dist/scraper/navigator.d.ts.map +1 -1
- package/dist/scraper/navigator.js +61 -104
- package/dist/scraper/navigator.js.map +1 -1
- package/dist/scraper/schemas.d.ts +57 -0
- package/dist/scraper/schemas.d.ts.map +1 -0
- package/dist/scraper/schemas.js +135 -0
- package/dist/scraper/schemas.js.map +1 -0
- package/dist/scraper/videoInterceptor.d.ts +4 -0
- package/dist/scraper/videoInterceptor.d.ts.map +1 -1
- package/dist/scraper/videoInterceptor.js +66 -51
- package/dist/scraper/videoInterceptor.js.map +1 -1
- package/dist/shared/auth.d.ts +9 -9
- package/dist/shared/auth.d.ts.map +1 -1
- package/dist/shared/auth.js +24 -38
- package/dist/shared/auth.js.map +1 -1
- package/dist/shared/firebase.d.ts +60 -0
- package/dist/shared/firebase.d.ts.map +1 -0
- package/dist/shared/firebase.js +102 -0
- package/dist/shared/firebase.js.map +1 -0
- package/dist/shared/fs.d.ts.map +1 -1
- package/dist/shared/fs.js +4 -0
- package/dist/shared/fs.js.map +1 -1
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +3 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/slug.d.ts +11 -0
- package/dist/shared/slug.d.ts.map +1 -0
- package/{src/shared/slug.ts → dist/shared/slug.js} +10 -11
- package/dist/shared/slug.js.map +1 -0
- package/dist/shared/url.d.ts +43 -0
- package/dist/shared/url.d.ts.map +1 -0
- package/{src/shared/url.ts → dist/shared/url.js} +12 -15
- package/dist/shared/url.js.map +1 -0
- package/dist/state/database.d.ts +1 -0
- package/dist/state/database.d.ts.map +1 -1
- package/dist/state/database.js +3 -0
- package/dist/state/database.js.map +1 -1
- package/dist/storage/fileSystem.d.ts +17 -17
- package/dist/storage/fileSystem.d.ts.map +1 -1
- package/dist/storage/fileSystem.js +39 -31
- package/dist/storage/fileSystem.js.map +1 -1
- package/package.json +5 -2
- package/.github/workflows/ci.yml +0 -50
- package/.husky/commit-msg +0 -2
- package/.husky/pre-commit +0 -1
- package/.husky/pre-push +0 -3
- package/.prettierrc +0 -8
- package/.release-it.json +0 -23
- package/ARCHITECTURE.md +0 -233
- package/CHANGELOG.md +0 -78
- package/commitlint.config.js +0 -4
- package/dist/ai/openRouter.d.ts +0 -47
- package/dist/ai/openRouter.d.ts.map +0 -1
- package/dist/ai/openRouter.js +0 -116
- package/dist/ai/openRouter.js.map +0 -1
- package/dist/ai/transcriptPolisher.d.ts +0 -24
- package/dist/ai/transcriptPolisher.d.ts.map +0 -1
- package/dist/ai/transcriptPolisher.js +0 -89
- package/dist/ai/transcriptPolisher.js.map +0 -1
- package/dist/cli/commands/enrich.d.ts +0 -14
- package/dist/cli/commands/enrich.d.ts.map +0 -1
- package/dist/cli/commands/enrich.js +0 -271
- package/dist/cli/commands/enrich.js.map +0 -1
- package/dist/cli/commands/syncGhl.d.ts +0 -20
- package/dist/cli/commands/syncGhl.d.ts.map +0 -1
- package/dist/cli/commands/syncGhl.js +0 -483
- package/dist/cli/commands/syncGhl.js.map +0 -1
- package/dist/cli/commands/syncHighLevel.test.d.ts +0 -2
- package/dist/cli/commands/syncHighLevel.test.d.ts.map +0 -1
- package/dist/cli/commands/syncHighLevel.test.js +0 -102
- package/dist/cli/commands/syncHighLevel.test.js.map +0 -1
- package/dist/config/paths.test.d.ts +0 -2
- package/dist/config/paths.test.d.ts.map +0 -1
- package/dist/config/paths.test.js +0 -70
- package/dist/config/paths.test.js.map +0 -1
- package/dist/config/schema.test.d.ts +0 -2
- package/dist/config/schema.test.d.ts.map +0 -1
- package/dist/config/schema.test.js +0 -151
- package/dist/config/schema.test.js.map +0 -1
- package/dist/downloader/hlsDownloader.test.d.ts +0 -2
- package/dist/downloader/hlsDownloader.test.d.ts.map +0 -1
- package/dist/downloader/hlsDownloader.test.js +0 -116
- package/dist/downloader/hlsDownloader.test.js.map +0 -1
- package/dist/downloader/loomDownloader.test.d.ts +0 -2
- package/dist/downloader/loomDownloader.test.d.ts.map +0 -1
- package/dist/downloader/loomDownloader.test.js +0 -36
- package/dist/downloader/loomDownloader.test.js.map +0 -1
- package/dist/downloader/queue.test.d.ts +0 -2
- package/dist/downloader/queue.test.d.ts.map +0 -1
- package/dist/downloader/queue.test.js +0 -158
- package/dist/downloader/queue.test.js.map +0 -1
- package/dist/downloader/videoDownloader.d.ts +0 -32
- package/dist/downloader/videoDownloader.d.ts.map +0 -1
- package/dist/downloader/videoDownloader.js +0 -173
- package/dist/downloader/videoDownloader.js.map +0 -1
- package/dist/downloader/vimeoDownloader.test.d.ts +0 -2
- package/dist/downloader/vimeoDownloader.test.d.ts.map +0 -1
- package/dist/downloader/vimeoDownloader.test.js +0 -51
- package/dist/downloader/vimeoDownloader.test.js.map +0 -1
- package/dist/scraper/auth.d.ts +0 -29
- package/dist/scraper/auth.d.ts.map +0 -1
- package/dist/scraper/auth.js +0 -115
- package/dist/scraper/auth.js.map +0 -1
- package/dist/scraper/extractor.test.d.ts +0 -2
- package/dist/scraper/extractor.test.d.ts.map +0 -1
- package/dist/scraper/extractor.test.js +0 -65
- package/dist/scraper/extractor.test.js.map +0 -1
- package/dist/scraper/ghl/auth.d.ts +0 -25
- package/dist/scraper/ghl/auth.d.ts.map +0 -1
- package/dist/scraper/ghl/auth.js +0 -187
- package/dist/scraper/ghl/auth.js.map +0 -1
- package/dist/scraper/ghl/extractor.d.ts +0 -96
- package/dist/scraper/ghl/extractor.d.ts.map +0 -1
- package/dist/scraper/ghl/extractor.js +0 -345
- package/dist/scraper/ghl/extractor.js.map +0 -1
- package/dist/scraper/ghl/index.d.ts +0 -4
- package/dist/scraper/ghl/index.d.ts.map +0 -1
- package/dist/scraper/ghl/index.js +0 -4
- package/dist/scraper/ghl/index.js.map +0 -1
- package/dist/scraper/ghl/navigator.d.ts +0 -93
- package/dist/scraper/ghl/navigator.d.ts.map +0 -1
- package/dist/scraper/ghl/navigator.js +0 -447
- package/dist/scraper/ghl/navigator.js.map +0 -1
- package/dist/scraper/highlevel/auth.d.ts +0 -25
- package/dist/scraper/highlevel/auth.d.ts.map +0 -1
- package/dist/scraper/highlevel/auth.js +0 -189
- package/dist/scraper/highlevel/auth.js.map +0 -1
- package/dist/scraper/highlevel/extractor.test.d.ts +0 -2
- package/dist/scraper/highlevel/extractor.test.d.ts.map +0 -1
- package/dist/scraper/highlevel/extractor.test.js +0 -101
- package/dist/scraper/highlevel/extractor.test.js.map +0 -1
- package/dist/scraper/highlevel/navigator.test.d.ts +0 -2
- package/dist/scraper/highlevel/navigator.test.d.ts.map +0 -1
- package/dist/scraper/highlevel/navigator.test.js +0 -78
- package/dist/scraper/highlevel/navigator.test.js.map +0 -1
- package/dist/scraper/navigator.test.d.ts +0 -2
- package/dist/scraper/navigator.test.d.ts.map +0 -1
- package/dist/scraper/navigator.test.js +0 -63
- package/dist/scraper/navigator.test.js.map +0 -1
- package/dist/scraper/skoolApi.d.ts +0 -17
- package/dist/scraper/skoolApi.d.ts.map +0 -1
- package/dist/scraper/skoolApi.js +0 -72
- package/dist/scraper/skoolApi.js.map +0 -1
- package/dist/state/database.test.d.ts +0 -2
- package/dist/state/database.test.d.ts.map +0 -1
- package/dist/state/database.test.js +0 -34
- package/dist/state/database.test.js.map +0 -1
- package/dist/transcription/whisperService.d.ts +0 -27
- package/dist/transcription/whisperService.d.ts.map +0 -1
- package/dist/transcription/whisperService.js +0 -102
- package/dist/transcription/whisperService.js.map +0 -1
- package/eslint.config.js +0 -55
- package/src/__fixtures__/highlevel-post-response.json +0 -68
- package/src/__fixtures__/hls-master-playlist.m3u8 +0 -24
- package/src/cli/commands/__snapshots__/syncHighLevel.test.ts.snap +0 -38
- package/src/cli/commands/config.ts +0 -74
- package/src/cli/commands/inspect.ts +0 -441
- package/src/cli/commands/login.ts +0 -68
- package/src/cli/commands/status.ts +0 -147
- package/src/cli/commands/sync.ts +0 -1235
- package/src/cli/commands/syncHighLevel.test.ts +0 -144
- package/src/cli/commands/syncHighLevel.ts +0 -639
- package/src/cli/index.ts +0 -121
- package/src/config/configManager.ts +0 -75
- package/src/config/paths.test.ts +0 -83
- package/src/config/paths.ts +0 -36
- package/src/config/schema.test.ts +0 -173
- package/src/config/schema.ts +0 -65
- package/src/downloader/hlsDownloader.test.ts +0 -148
- package/src/downloader/hlsDownloader.ts +0 -327
- package/src/downloader/hlsValidator.ts +0 -196
- package/src/downloader/index.ts +0 -122
- package/src/downloader/loomDownloader.test.ts +0 -43
- package/src/downloader/loomDownloader.ts +0 -742
- package/src/downloader/queue.test.ts +0 -199
- package/src/downloader/queue.ts +0 -118
- package/src/downloader/vimeoDownloader.test.ts +0 -62
- package/src/downloader/vimeoDownloader.ts +0 -722
- package/src/scraper/extractor.test.ts +0 -124
- package/src/scraper/extractor.ts +0 -757
- package/src/scraper/highlevel/__snapshots__/extractor.test.ts.snap +0 -41
- package/src/scraper/highlevel/extractor.test.ts +0 -134
- package/src/scraper/highlevel/extractor.ts +0 -537
- package/src/scraper/highlevel/index.ts +0 -2
- package/src/scraper/highlevel/navigator.test.ts +0 -110
- package/src/scraper/highlevel/navigator.ts +0 -668
- package/src/scraper/highlevel/schemas.ts +0 -183
- package/src/scraper/navigator.test.ts +0 -122
- package/src/scraper/navigator.ts +0 -355
- package/src/scraper/schemas.ts +0 -177
- package/src/scraper/videoInterceptor.ts +0 -435
- package/src/shared/auth.test.ts +0 -58
- package/src/shared/auth.ts +0 -251
- package/src/shared/firebase.ts +0 -151
- package/src/shared/fs.ts +0 -80
- package/src/shared/http.ts +0 -34
- package/src/shared/index.ts +0 -6
- package/src/shared/url.test.ts +0 -122
- package/src/state/database.test.ts +0 -49
- package/src/state/database.ts +0 -919
- package/src/state/index.ts +0 -14
- package/src/storage/fileSystem.test.ts +0 -64
- package/src/storage/fileSystem.ts +0 -175
- package/tsconfig.json +0 -28
- 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:
|
|
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;
|
|
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
|
|
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
|
-
|
|
17
|
-
|
|
18
|
+
// Get the raw JSON from the page
|
|
19
|
+
const nextDataJson = await page.evaluate(() => {
|
|
18
20
|
const nextDataScript = document.getElementById("__NEXT_DATA__");
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
|
|
98
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
284
|
-
|
|
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":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"navigator.js","sourceRoot":"","sources":["../../src/scraper/navigator.ts"],"names":[],"mappings":"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"}
|
|
@@ -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"}
|