skool-cli 1.0.0
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/LICENSE +21 -0
- package/README.md +179 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +33 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/create-folder.d.ts +3 -0
- package/dist/commands/create-folder.d.ts.map +1 -0
- package/dist/commands/create-folder.js +24 -0
- package/dist/commands/create-folder.js.map +1 -0
- package/dist/commands/create-lesson.d.ts +3 -0
- package/dist/commands/create-lesson.d.ts.map +1 -0
- package/dist/commands/create-lesson.js +35 -0
- package/dist/commands/create-lesson.js.map +1 -0
- package/dist/commands/create-post.d.ts +3 -0
- package/dist/commands/create-post.d.ts.map +1 -0
- package/dist/commands/create-post.js +36 -0
- package/dist/commands/create-post.js.map +1 -0
- package/dist/commands/debug-api.d.ts +3 -0
- package/dist/commands/debug-api.d.ts.map +1 -0
- package/dist/commands/debug-api.js +112 -0
- package/dist/commands/debug-api.js.map +1 -0
- package/dist/commands/debug-manual.d.ts +3 -0
- package/dist/commands/debug-manual.d.ts.map +1 -0
- package/dist/commands/debug-manual.js +66 -0
- package/dist/commands/debug-manual.js.map +1 -0
- package/dist/commands/debug.d.ts +3 -0
- package/dist/commands/debug.d.ts.map +1 -0
- package/dist/commands/debug.js +114 -0
- package/dist/commands/debug.js.map +1 -0
- package/dist/commands/delete-lesson.d.ts +3 -0
- package/dist/commands/delete-lesson.d.ts.map +1 -0
- package/dist/commands/delete-lesson.js +17 -0
- package/dist/commands/delete-lesson.js.map +1 -0
- package/dist/commands/get-categories.d.ts +3 -0
- package/dist/commands/get-categories.d.ts.map +1 -0
- package/dist/commands/get-categories.js +34 -0
- package/dist/commands/get-categories.js.map +1 -0
- package/dist/commands/get-members.d.ts +3 -0
- package/dist/commands/get-members.d.ts.map +1 -0
- package/dist/commands/get-members.js +35 -0
- package/dist/commands/get-members.js.map +1 -0
- package/dist/commands/get-posts.d.ts +3 -0
- package/dist/commands/get-posts.d.ts.map +1 -0
- package/dist/commands/get-posts.js +41 -0
- package/dist/commands/get-posts.js.map +1 -0
- package/dist/commands/list-lessons.d.ts +3 -0
- package/dist/commands/list-lessons.d.ts.map +1 -0
- package/dist/commands/list-lessons.js +45 -0
- package/dist/commands/list-lessons.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +30 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/test-api.d.ts +3 -0
- package/dist/commands/test-api.d.ts.map +1 -0
- package/dist/commands/test-api.js +143 -0
- package/dist/commands/test-api.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +17 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/core/browser-manager.d.ts +25 -0
- package/dist/core/browser-manager.d.ts.map +1 -0
- package/dist/core/browser-manager.js +104 -0
- package/dist/core/browser-manager.js.map +1 -0
- package/dist/core/config.d.ts +15 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +17 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/html-generator.d.ts +15 -0
- package/dist/core/html-generator.d.ts.map +1 -0
- package/dist/core/html-generator.js +254 -0
- package/dist/core/html-generator.js.map +1 -0
- package/dist/core/page-ops.d.ts +69 -0
- package/dist/core/page-ops.d.ts.map +1 -0
- package/dist/core/page-ops.js +511 -0
- package/dist/core/page-ops.js.map +1 -0
- package/dist/core/skool-api.d.ts +74 -0
- package/dist/core/skool-api.d.ts.map +1 -0
- package/dist/core/skool-api.js +389 -0
- package/dist/core/skool-api.js.map +1 -0
- package/dist/core/skool-client.d.ts +63 -0
- package/dist/core/skool-client.d.ts.map +1 -0
- package/dist/core/skool-client.js +501 -0
- package/dist/core/skool-client.js.map +1 -0
- package/dist/core/types.d.ts +58 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import { SKOOL_BASE_URL, SPA_NAV_DELAY, MAX_TITLE_LENGTH, DEFAULT_TIMEOUT, } from "./config.js";
|
|
2
|
+
/**
|
|
3
|
+
* Low-level page operations for Skool automation.
|
|
4
|
+
*
|
|
5
|
+
* Encapsulates all 6 production workarounds:
|
|
6
|
+
* 1. SAVE disabled after HTML injection -> space+backspace dirty trigger
|
|
7
|
+
* 2. Dropdown overlay blocks clicks -> pointerEvents:none fix
|
|
8
|
+
* 3. Volatile refs -> N/A with Playwright native locators
|
|
9
|
+
* 4. SPA timing -> wait after navigation
|
|
10
|
+
* 5. HTML conversion -> handled by html-generator
|
|
11
|
+
* 6. 50-char title limit -> auto-truncate
|
|
12
|
+
*/
|
|
13
|
+
export class PageOps {
|
|
14
|
+
browser;
|
|
15
|
+
constructor(browser) {
|
|
16
|
+
this.browser = browser;
|
|
17
|
+
}
|
|
18
|
+
/** Get the current page */
|
|
19
|
+
async page() {
|
|
20
|
+
return this.browser.getPage();
|
|
21
|
+
}
|
|
22
|
+
// ----------------------------------------------------------
|
|
23
|
+
// Navigation
|
|
24
|
+
// ----------------------------------------------------------
|
|
25
|
+
/** Navigate to a Skool URL with SPA delay (workaround #4) */
|
|
26
|
+
async goto(path) {
|
|
27
|
+
const page = await this.page();
|
|
28
|
+
const url = path.startsWith("http") ? path : `${SKOOL_BASE_URL}/${path}`;
|
|
29
|
+
await page.goto(url, { waitUntil: "domcontentloaded" });
|
|
30
|
+
await page.waitForTimeout(SPA_NAV_DELAY);
|
|
31
|
+
}
|
|
32
|
+
/** Navigate to a group's community page */
|
|
33
|
+
async gotoCommunity(groupSlug) {
|
|
34
|
+
await this.goto(groupSlug);
|
|
35
|
+
}
|
|
36
|
+
/** Navigate to a group's classroom page */
|
|
37
|
+
async gotoClassroom(groupSlug) {
|
|
38
|
+
await this.goto(`${groupSlug}/classroom`);
|
|
39
|
+
}
|
|
40
|
+
/** Navigate to a group's members page */
|
|
41
|
+
async gotoMembers(groupSlug) {
|
|
42
|
+
await this.goto(`${groupSlug}/members`);
|
|
43
|
+
}
|
|
44
|
+
// ----------------------------------------------------------
|
|
45
|
+
// Auth detection
|
|
46
|
+
// ----------------------------------------------------------
|
|
47
|
+
/** Check if user is authenticated on the current page */
|
|
48
|
+
async isAuthenticated() {
|
|
49
|
+
const page = await this.page();
|
|
50
|
+
const content = await page.content();
|
|
51
|
+
// If we see login/signup prompts, we're not authenticated
|
|
52
|
+
const unauthIndicators = [
|
|
53
|
+
'href="/login"',
|
|
54
|
+
"Log in",
|
|
55
|
+
"Sign in",
|
|
56
|
+
"Sign up",
|
|
57
|
+
"Create your free account",
|
|
58
|
+
];
|
|
59
|
+
for (const indicator of unauthIndicators) {
|
|
60
|
+
if (content.includes(indicator)) {
|
|
61
|
+
// Could be a false positive on a public page -- check more carefully
|
|
62
|
+
const loginButton = page.locator('a[href="/login"], button:has-text("Log in"), button:has-text("Sign in")');
|
|
63
|
+
if ((await loginButton.count()) > 0) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
// ----------------------------------------------------------
|
|
71
|
+
// Login
|
|
72
|
+
// ----------------------------------------------------------
|
|
73
|
+
/** Perform login with email and password */
|
|
74
|
+
async login(email, password) {
|
|
75
|
+
const page = await this.page();
|
|
76
|
+
await this.goto("login");
|
|
77
|
+
// Fill email
|
|
78
|
+
const emailInput = page.locator('input[name="email"], input[type="email"]');
|
|
79
|
+
await emailInput.first().fill(email);
|
|
80
|
+
// Fill password
|
|
81
|
+
const passwordInput = page.locator('input[name="password"], input[type="password"]');
|
|
82
|
+
await passwordInput.first().fill(password);
|
|
83
|
+
// Submit
|
|
84
|
+
const submitBtn = page.locator('button[type="submit"]');
|
|
85
|
+
await submitBtn.first().click();
|
|
86
|
+
// Wait for navigation away from login page
|
|
87
|
+
try {
|
|
88
|
+
await page.waitForURL((url) => !url.pathname.includes("/login"), {
|
|
89
|
+
timeout: DEFAULT_TIMEOUT,
|
|
90
|
+
});
|
|
91
|
+
await page.waitForTimeout(3000);
|
|
92
|
+
// Save auth state to disk so it persists across CLI invocations
|
|
93
|
+
await this.browser.saveAuthState();
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// ----------------------------------------------------------
|
|
101
|
+
// Click helpers (workaround #2: dropdown overlay)
|
|
102
|
+
// ----------------------------------------------------------
|
|
103
|
+
/** Remove all known overlays that block pointer events */
|
|
104
|
+
async clearOverlays() {
|
|
105
|
+
const page = await this.page();
|
|
106
|
+
await page.evaluate(() => {
|
|
107
|
+
const selectors = [
|
|
108
|
+
'[class*="DropdownBackground"]',
|
|
109
|
+
'[class*="InputBackdrop"]',
|
|
110
|
+
'[class*="Backdrop"]',
|
|
111
|
+
'[class*="Overlay"]',
|
|
112
|
+
];
|
|
113
|
+
selectors.forEach((sel) => {
|
|
114
|
+
document.querySelectorAll(sel).forEach((el) => {
|
|
115
|
+
el.style.pointerEvents = "none";
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/** Click a locator, fixing overlays if needed */
|
|
121
|
+
async safeClick(locator) {
|
|
122
|
+
const page = await this.page();
|
|
123
|
+
try {
|
|
124
|
+
await locator.click({ timeout: 5000 });
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Workaround: remove all known overlays blocking clicks
|
|
128
|
+
await page.evaluate(() => {
|
|
129
|
+
const selectors = [
|
|
130
|
+
'[class*="DropdownBackground"]',
|
|
131
|
+
'[class*="dropdown-background"]',
|
|
132
|
+
'[class*="InputBackdrop"]',
|
|
133
|
+
'[class*="Backdrop"]',
|
|
134
|
+
];
|
|
135
|
+
selectors.forEach((sel) => {
|
|
136
|
+
document.querySelectorAll(sel).forEach((el) => {
|
|
137
|
+
el.style.pointerEvents = "none";
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
await locator.click({ timeout: 10000 });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// ----------------------------------------------------------
|
|
145
|
+
// Title filling (workaround #6: 50-char limit)
|
|
146
|
+
// ----------------------------------------------------------
|
|
147
|
+
/** Fill a title field, truncating to MAX_TITLE_LENGTH */
|
|
148
|
+
async fillTitle(locator, title) {
|
|
149
|
+
const truncated = title.length > MAX_TITLE_LENGTH
|
|
150
|
+
? title.slice(0, MAX_TITLE_LENGTH - 3) + "..."
|
|
151
|
+
: title;
|
|
152
|
+
await locator.fill(truncated);
|
|
153
|
+
return truncated;
|
|
154
|
+
}
|
|
155
|
+
// ----------------------------------------------------------
|
|
156
|
+
// TipTap HTML injection (workaround #1: dirty trigger)
|
|
157
|
+
// ----------------------------------------------------------
|
|
158
|
+
/**
|
|
159
|
+
* Inject HTML content into the TipTap editor.
|
|
160
|
+
* Includes the space+backspace dirty trigger so SAVE becomes enabled.
|
|
161
|
+
*/
|
|
162
|
+
async injectTipTapContent(html) {
|
|
163
|
+
const page = await this.page();
|
|
164
|
+
// Click into the body area first to ensure it's focused
|
|
165
|
+
// The body editor is the TipTap ProseMirror element (not the title)
|
|
166
|
+
const bodyEditor = page.locator('div.tiptap.ProseMirror, div[class*="skool-editor"], div.ProseMirror').first();
|
|
167
|
+
if ((await bodyEditor.count()) > 0) {
|
|
168
|
+
await bodyEditor.click();
|
|
169
|
+
await page.waitForTimeout(300);
|
|
170
|
+
}
|
|
171
|
+
const result = await page.evaluate((htmlContent) => {
|
|
172
|
+
// Try multiple selectors for the TipTap editor (body, not title)
|
|
173
|
+
const selectors = [
|
|
174
|
+
'div.tiptap.ProseMirror',
|
|
175
|
+
'div[class*="skool-editor"]',
|
|
176
|
+
'div.ProseMirror[contenteditable]',
|
|
177
|
+
'[contenteditable="true"]',
|
|
178
|
+
];
|
|
179
|
+
let ce = null;
|
|
180
|
+
for (const sel of selectors) {
|
|
181
|
+
const candidates = document.querySelectorAll(sel);
|
|
182
|
+
// If multiple, pick the last one (body is usually after title)
|
|
183
|
+
if (candidates.length > 0) {
|
|
184
|
+
ce = candidates[candidates.length - 1];
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (!ce)
|
|
189
|
+
return { ok: false, error: "No contenteditable element found" };
|
|
190
|
+
// Access TipTap editor instance
|
|
191
|
+
const editor = ce.editor;
|
|
192
|
+
if (!editor)
|
|
193
|
+
return { ok: false, error: "No TipTap editor instance found on element: " + ce.className };
|
|
194
|
+
try {
|
|
195
|
+
editor.commands.focus();
|
|
196
|
+
editor.commands.setContent(htmlContent, true);
|
|
197
|
+
return { ok: true, length: editor.getHTML().length };
|
|
198
|
+
}
|
|
199
|
+
catch (e) {
|
|
200
|
+
return {
|
|
201
|
+
ok: false,
|
|
202
|
+
error: `setContent failed: ${e.message}`,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}, html);
|
|
206
|
+
if (!result.ok) {
|
|
207
|
+
throw new Error(`TipTap injection failed: ${result.error}`);
|
|
208
|
+
}
|
|
209
|
+
// Workaround #1: trigger dirty state so SAVE button becomes enabled
|
|
210
|
+
const editor = page.locator("[contenteditable=true]").first();
|
|
211
|
+
await editor.click();
|
|
212
|
+
await page.keyboard.press("End");
|
|
213
|
+
await page.keyboard.type(" ");
|
|
214
|
+
await page.keyboard.press("Backspace");
|
|
215
|
+
await page.waitForTimeout(1000);
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
// ----------------------------------------------------------
|
|
219
|
+
// Save and verify
|
|
220
|
+
// ----------------------------------------------------------
|
|
221
|
+
/** Click SAVE and verify it completes (button becomes disabled) */
|
|
222
|
+
async clickSaveAndVerify() {
|
|
223
|
+
const page = await this.page();
|
|
224
|
+
const saveBtn = page.getByRole("button", { name: "SAVE" });
|
|
225
|
+
// Ensure SAVE is enabled before clicking
|
|
226
|
+
const isDisabled = await saveBtn.getAttribute("disabled");
|
|
227
|
+
if (isDisabled !== null) {
|
|
228
|
+
// Already saved / nothing to save
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
await this.safeClick(saveBtn);
|
|
232
|
+
// Wait for SAVE to become disabled (= saved successfully)
|
|
233
|
+
try {
|
|
234
|
+
await saveBtn.waitFor({ state: "visible", timeout: 10000 });
|
|
235
|
+
// Poll for disabled state
|
|
236
|
+
for (let i = 0; i < 20; i++) {
|
|
237
|
+
const disabled = await saveBtn.getAttribute("disabled");
|
|
238
|
+
if (disabled !== null)
|
|
239
|
+
return true;
|
|
240
|
+
await page.waitForTimeout(500);
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// ----------------------------------------------------------
|
|
249
|
+
// Community post operations
|
|
250
|
+
// ----------------------------------------------------------
|
|
251
|
+
/** Create a community post */
|
|
252
|
+
async createCommunityPost(groupSlug, title, body, category) {
|
|
253
|
+
const page = await this.page();
|
|
254
|
+
await this.gotoCommunity(groupSlug);
|
|
255
|
+
// Click "Write something" area to open post form
|
|
256
|
+
const postTrigger = page.getByText("Write something");
|
|
257
|
+
await this.safeClick(postTrigger.first());
|
|
258
|
+
await page.waitForTimeout(1500);
|
|
259
|
+
// Fill title
|
|
260
|
+
const titleInput = page.locator('input[placeholder="Title"]');
|
|
261
|
+
await titleInput.fill(title);
|
|
262
|
+
// Fill body via TipTap editor (div.tiptap.ProseMirror.skool-editor)
|
|
263
|
+
const bodyEditor = page.locator("div.tiptap.ProseMirror.skool-editor");
|
|
264
|
+
await bodyEditor.click();
|
|
265
|
+
await bodyEditor.fill(body);
|
|
266
|
+
// Select category if provided
|
|
267
|
+
if (category) {
|
|
268
|
+
await this.clearOverlays();
|
|
269
|
+
const categoryBtn = page.getByText("Select a category");
|
|
270
|
+
await categoryBtn.click({ timeout: 5000 });
|
|
271
|
+
await page.waitForTimeout(500);
|
|
272
|
+
// Clear overlays again after dropdown opens
|
|
273
|
+
await this.clearOverlays();
|
|
274
|
+
// Click the category option via JS to bypass any remaining overlays
|
|
275
|
+
const clicked = await page.evaluate((cat) => {
|
|
276
|
+
let found = false;
|
|
277
|
+
// Find elements with the category text inside a dropdown
|
|
278
|
+
document.querySelectorAll('[class*="Dropdown"] *').forEach((el) => {
|
|
279
|
+
if (!found && el.textContent?.trim() === cat && el.children.length === 0) {
|
|
280
|
+
el.click();
|
|
281
|
+
found = true;
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
if (found)
|
|
285
|
+
return true;
|
|
286
|
+
// Fallback: find by GroupFeedLinkLabel class (the dropdown option)
|
|
287
|
+
document.querySelectorAll('[class*="GroupFeedLinkLabel"]').forEach((el) => {
|
|
288
|
+
if (!found && el.textContent?.trim() === cat) {
|
|
289
|
+
el.click();
|
|
290
|
+
found = true;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
return found;
|
|
294
|
+
}, category);
|
|
295
|
+
if (!clicked) {
|
|
296
|
+
throw new Error(`Category "${category}" not found in dropdown`);
|
|
297
|
+
}
|
|
298
|
+
await page.waitForTimeout(500);
|
|
299
|
+
}
|
|
300
|
+
// Click Post button (the submit button with SubmitButtonWrapper class)
|
|
301
|
+
const postBtn = page.locator('button[class*="SubmitButtonWrapper"]');
|
|
302
|
+
await this.safeClick(postBtn.first());
|
|
303
|
+
await page.waitForTimeout(3000);
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
// ----------------------------------------------------------
|
|
307
|
+
// Classroom lesson operations
|
|
308
|
+
// ----------------------------------------------------------
|
|
309
|
+
/**
|
|
310
|
+
* Create a new lesson in a classroom module.
|
|
311
|
+
*
|
|
312
|
+
* Flow: enter course → "..." menu → "Add page" → click pencil → fill title → inject HTML → save
|
|
313
|
+
*/
|
|
314
|
+
async createLesson(groupSlug, moduleName, title, html, courseName) {
|
|
315
|
+
const page = await this.page();
|
|
316
|
+
// Step 1: Navigate to classroom and enter course
|
|
317
|
+
await this.gotoClassroom(groupSlug);
|
|
318
|
+
if (courseName) {
|
|
319
|
+
await this.safeClick(page.getByText(courseName, { exact: false }).first());
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
const courseLink = page.locator('a[href*="/classroom/"]').first();
|
|
323
|
+
if ((await courseLink.count()) > 0)
|
|
324
|
+
await courseLink.click();
|
|
325
|
+
}
|
|
326
|
+
await page.waitForTimeout(SPA_NAV_DELAY);
|
|
327
|
+
// Step 2: Open "..." menu and click "Add page"
|
|
328
|
+
const courseTopArea = page.locator('div[class*="CourseMenuTop"]').first();
|
|
329
|
+
await courseTopArea.hover();
|
|
330
|
+
await page.waitForTimeout(500);
|
|
331
|
+
// Click "..." via JS (needed because it's an SVG icon)
|
|
332
|
+
await page.evaluate(() => {
|
|
333
|
+
const topArea = document.querySelector('div[class*="CourseMenuTop"]');
|
|
334
|
+
if (!topArea)
|
|
335
|
+
return;
|
|
336
|
+
topArea.querySelectorAll('div, button, span, svg').forEach((el) => {
|
|
337
|
+
const rect = el.getBoundingClientRect();
|
|
338
|
+
const text = el.textContent?.trim() || "";
|
|
339
|
+
if (rect.width > 10 && rect.width < 50 && rect.height > 10 && rect.height < 50 && text.length < 4) {
|
|
340
|
+
el.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
await page.waitForTimeout(800);
|
|
345
|
+
// Click "Add page" from dropdown
|
|
346
|
+
try {
|
|
347
|
+
await page.getByText("Add page", { exact: true }).click({ timeout: 5000 });
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
await this.clearOverlays();
|
|
351
|
+
await page.getByText("Add page", { exact: true }).click({ force: true, timeout: 5000 });
|
|
352
|
+
}
|
|
353
|
+
await page.waitForTimeout(3000);
|
|
354
|
+
// Step 3: Click the pencil (edit) icon using REAL Playwright click
|
|
355
|
+
// The pencil is the last SVG inside ModuleTitleRow in the content panel
|
|
356
|
+
const titleRow = page.locator('div[class*="ModuleTitleRow"]').first();
|
|
357
|
+
const pencilSvg = titleRow.locator("svg").last();
|
|
358
|
+
try {
|
|
359
|
+
await pencilSvg.click({ timeout: 5000 });
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
// Fallback: click by coordinates near the right edge of the title row
|
|
363
|
+
const box = await titleRow.boundingBox();
|
|
364
|
+
if (box) {
|
|
365
|
+
await page.mouse.click(box.x + box.width - 25, box.y + box.height / 2);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
await page.waitForTimeout(2000);
|
|
369
|
+
// Verify edit mode (SAVE button visible)
|
|
370
|
+
const inEditMode = (await page.locator('button:has-text("SAVE")').count()) > 0;
|
|
371
|
+
if (!inEditMode) {
|
|
372
|
+
throw new Error("Could not enter edit mode. Try running with SKOOL_CLI_HEADLESS=false to debug.");
|
|
373
|
+
}
|
|
374
|
+
// Step 4: Fill title + inject content
|
|
375
|
+
// In edit mode, the entire page is one TipTap editor.
|
|
376
|
+
// The title "New page" is the first text, body is below it.
|
|
377
|
+
// Strategy: select "New page" text, type new title, press Enter, then inject HTML for body.
|
|
378
|
+
const truncatedTitle = title.length > MAX_TITLE_LENGTH
|
|
379
|
+
? title.slice(0, MAX_TITLE_LENGTH - 3) + "..."
|
|
380
|
+
: title;
|
|
381
|
+
// Click the "New page" title text in the content area
|
|
382
|
+
const contentTitle = page.locator('div[class*="CourseModuleWrapper"] div[class*="ModuleTitle"]').first();
|
|
383
|
+
if ((await contentTitle.count()) > 0) {
|
|
384
|
+
await contentTitle.click();
|
|
385
|
+
}
|
|
386
|
+
// Select all title text and replace
|
|
387
|
+
await page.keyboard.press("Meta+a");
|
|
388
|
+
await page.keyboard.type(truncatedTitle);
|
|
389
|
+
await page.waitForTimeout(300);
|
|
390
|
+
// Move to body: press Enter to create a new line below the title
|
|
391
|
+
await page.keyboard.press("Enter");
|
|
392
|
+
await page.waitForTimeout(300);
|
|
393
|
+
// Now inject HTML into the TipTap editor for the body content
|
|
394
|
+
// The editor already has focus, so we inject into the current editor instance
|
|
395
|
+
await this.injectTipTapContent(html);
|
|
396
|
+
// Step 6: Click SAVE
|
|
397
|
+
const saved = await this.clickSaveAndVerify();
|
|
398
|
+
if (!saved) {
|
|
399
|
+
throw new Error(`Lesson "${truncatedTitle}" created but SAVE not confirmed.`);
|
|
400
|
+
}
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
// ----------------------------------------------------------
|
|
404
|
+
// Read operations
|
|
405
|
+
// ----------------------------------------------------------
|
|
406
|
+
/** Extract posts from the community page */
|
|
407
|
+
async extractPosts(groupSlug) {
|
|
408
|
+
const page = await this.page();
|
|
409
|
+
await this.gotoCommunity(groupSlug);
|
|
410
|
+
// Posts are rendered as links with href pattern /{group}/{post-slug}
|
|
411
|
+
// Each post block has: author link, category link, title link, preview text
|
|
412
|
+
// We find post title links by their href pattern (not category or author links)
|
|
413
|
+
return page.evaluate((slug) => {
|
|
414
|
+
const posts = [];
|
|
415
|
+
// Post title links match /{group}/{post-slug} but NOT /{group}?c= (categories)
|
|
416
|
+
// and NOT /@username (authors) and NOT /{group}/classroom etc.
|
|
417
|
+
const reservedPaths = ["classroom", "calendar", "about", "-", "?", "signup", "legal"];
|
|
418
|
+
const allLinks = document.querySelectorAll(`a[href^="/${slug}/"]`);
|
|
419
|
+
allLinks.forEach((link) => {
|
|
420
|
+
const href = link.getAttribute("href") || "";
|
|
421
|
+
const path = href.replace(`/${slug}/`, "");
|
|
422
|
+
// Skip non-post links
|
|
423
|
+
if (!path || path.includes("?") || reservedPaths.some((r) => path.startsWith(r)))
|
|
424
|
+
return;
|
|
425
|
+
// This is a post title link - find surrounding context
|
|
426
|
+
const text = link.textContent?.trim() || "";
|
|
427
|
+
if (!text || text.length < 5)
|
|
428
|
+
return;
|
|
429
|
+
// Look for author and category in nearby sibling/parent elements
|
|
430
|
+
const container = link.closest('[class*="Post"], [class*="card"], div') || link.parentElement;
|
|
431
|
+
let author = "";
|
|
432
|
+
let category = "";
|
|
433
|
+
let preview = "";
|
|
434
|
+
if (container) {
|
|
435
|
+
// Author links have href starting with /@ — pick the one with a real name (not "1" avatar)
|
|
436
|
+
const authorLinks = container.querySelectorAll('a[href^="/@"]');
|
|
437
|
+
authorLinks.forEach((al) => {
|
|
438
|
+
if (!author) {
|
|
439
|
+
const t = al.textContent?.trim() || "";
|
|
440
|
+
if (t.length > 1)
|
|
441
|
+
author = t;
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
// Category links have href with ?c=
|
|
445
|
+
const catLink = container.querySelector('a[href*="?c="]');
|
|
446
|
+
if (catLink)
|
|
447
|
+
category = catLink.textContent?.trim() || "";
|
|
448
|
+
// Preview is the first <p> or text block after the title
|
|
449
|
+
const pEl = container.querySelector("p");
|
|
450
|
+
if (pEl)
|
|
451
|
+
preview = pEl.textContent?.trim().slice(0, 200) || "";
|
|
452
|
+
}
|
|
453
|
+
posts.push({ title: text, author, category, preview, url: href });
|
|
454
|
+
});
|
|
455
|
+
return posts;
|
|
456
|
+
}, groupSlug);
|
|
457
|
+
}
|
|
458
|
+
/** Extract categories from the community page */
|
|
459
|
+
async extractCategories(groupSlug) {
|
|
460
|
+
const page = await this.page();
|
|
461
|
+
await this.gotoCommunity(groupSlug);
|
|
462
|
+
// Categories are rendered as button chips with class ChipWrapper
|
|
463
|
+
return page.evaluate(() => {
|
|
464
|
+
const categories = [];
|
|
465
|
+
// Skool uses buttons with ChipWrapper class for category filters
|
|
466
|
+
const chips = document.querySelectorAll('button[class*="ChipWrapper"]');
|
|
467
|
+
chips.forEach((btn) => {
|
|
468
|
+
const text = btn.textContent?.trim();
|
|
469
|
+
if (text && text !== "All" && text !== "More..." && !categories.includes(text)) {
|
|
470
|
+
categories.push(text);
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
return categories;
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
/** Extract members from the members page */
|
|
477
|
+
async extractMembers(groupSlug, search) {
|
|
478
|
+
const page = await this.page();
|
|
479
|
+
await this.gotoMembers(groupSlug);
|
|
480
|
+
// If search query provided, fill search box
|
|
481
|
+
if (search) {
|
|
482
|
+
const searchInput = page.locator('input[placeholder="Search"]');
|
|
483
|
+
if ((await searchInput.count()) > 0) {
|
|
484
|
+
await searchInput.first().fill(search);
|
|
485
|
+
await page.waitForTimeout(1500);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
// Members are listed as links with href /@username?g=group
|
|
489
|
+
return page.evaluate((slug) => {
|
|
490
|
+
const members = [];
|
|
491
|
+
const seen = new Set();
|
|
492
|
+
const memberLinks = document.querySelectorAll(`a[href*="?g=${slug}"]`);
|
|
493
|
+
memberLinks.forEach((link) => {
|
|
494
|
+
const href = link.getAttribute("href") || "";
|
|
495
|
+
if (!href.startsWith("/@"))
|
|
496
|
+
return;
|
|
497
|
+
const name = link.textContent?.trim() || "";
|
|
498
|
+
if (!name || name.length < 2 || seen.has(name))
|
|
499
|
+
return;
|
|
500
|
+
seen.add(name);
|
|
501
|
+
members.push({
|
|
502
|
+
name,
|
|
503
|
+
level: 0,
|
|
504
|
+
contributions: 0,
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
return members;
|
|
508
|
+
}, groupSlug);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
//# sourceMappingURL=page-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-ops.js","sourceRoot":"","sources":["../../src/core/page-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct HTTP API client for Skool's internal API (api2.skool.com).
|
|
3
|
+
* Discovered via network interception.
|
|
4
|
+
*
|
|
5
|
+
* Uses auth cookies from the browser session for authentication.
|
|
6
|
+
*/
|
|
7
|
+
import { BrowserManager } from "./browser-manager.js";
|
|
8
|
+
export declare class SkoolApi {
|
|
9
|
+
private browser;
|
|
10
|
+
constructor(browser: BrowserManager);
|
|
11
|
+
/** Get auth cookies from the browser session */
|
|
12
|
+
private getCookies;
|
|
13
|
+
/** Make an authenticated API request */
|
|
14
|
+
private request;
|
|
15
|
+
/**
|
|
16
|
+
* Create a new page (lesson) in a course.
|
|
17
|
+
*
|
|
18
|
+
* @param groupId - Group ID (from the classroom URL or course data)
|
|
19
|
+
* @param userId - User ID (the logged-in user)
|
|
20
|
+
* @param parentId - Parent folder/module ID
|
|
21
|
+
* @param rootId - Root course ID
|
|
22
|
+
* @param title - Page title
|
|
23
|
+
* @param content - HTML content for the page body
|
|
24
|
+
*/
|
|
25
|
+
createPage(options: {
|
|
26
|
+
groupId: string;
|
|
27
|
+
userId: string;
|
|
28
|
+
parentId: string;
|
|
29
|
+
rootId: string;
|
|
30
|
+
title: string;
|
|
31
|
+
content?: string;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
success: boolean;
|
|
34
|
+
pageId: string;
|
|
35
|
+
message: string;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* List courses and their modules for a group.
|
|
39
|
+
* This gives us the real root_id and parent_id (folder IDs) needed for API calls.
|
|
40
|
+
*/
|
|
41
|
+
listCourses(groupId: string): Promise<Record<string, unknown>[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Create a folder (module) in a course.
|
|
44
|
+
*/
|
|
45
|
+
createFolder(options: {
|
|
46
|
+
groupId: string;
|
|
47
|
+
parentId: string;
|
|
48
|
+
rootId: string;
|
|
49
|
+
title: string;
|
|
50
|
+
}): Promise<{
|
|
51
|
+
success: boolean;
|
|
52
|
+
folderId: string;
|
|
53
|
+
message: string;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* List all items (folders + pages) in a course.
|
|
57
|
+
*/
|
|
58
|
+
listCourseItems(groupId: string, rootId: string): Promise<Record<string, unknown>[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Delete a page by ID.
|
|
61
|
+
*/
|
|
62
|
+
deletePage(pageId: string): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* Extract group_id, user_id, root_id from the classroom page.
|
|
65
|
+
* These IDs are needed for API calls.
|
|
66
|
+
*/
|
|
67
|
+
getClassroomIds(groupSlug: string, courseName?: string): Promise<{
|
|
68
|
+
groupId: string;
|
|
69
|
+
userId: string;
|
|
70
|
+
rootId: string;
|
|
71
|
+
courseUrl: string;
|
|
72
|
+
} | null>;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=skool-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skool-api.d.ts","sourceRoot":"","sources":["../../src/core/skool-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAyJtD,qBAAa,QAAQ;IACP,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,cAAc;IAE3C,gDAAgD;YAClC,UAAU;IAOxB,wCAAwC;YAC1B,OAAO;IAgCrB;;;;;;;;;OASG;IACG,UAAU,CAAC,OAAO,EAAE;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAsDlE;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAatE;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAyBpE;;OAEG;IACG,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAuBrC;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlD;;;OAGG;IACG,eAAe,CACnB,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;CAoEV"}
|