@mo7yw4ng/openape 1.0.5 → 2.0.3
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/bin/openape +29 -0
- package/bin/openape.js +29 -0
- package/package.json +22 -28
- package/LICENSE +0 -21
- package/README.md +0 -135
- package/esm/_dnt.polyfills.d.ts +0 -101
- package/esm/_dnt.polyfills.d.ts.map +0 -1
- package/esm/_dnt.polyfills.js +0 -127
- package/esm/_dnt.shims.d.ts +0 -6
- package/esm/_dnt.shims.d.ts.map +0 -1
- package/esm/_dnt.shims.js +0 -61
- package/esm/deno.d.ts +0 -25
- package/esm/deno.d.ts.map +0 -1
- package/esm/deno.js +0 -23
- package/esm/package.json +0 -3
- package/esm/src/commands/announcements.d.ts +0 -3
- package/esm/src/commands/announcements.d.ts.map +0 -1
- package/esm/src/commands/announcements.js +0 -134
- package/esm/src/commands/assignments.d.ts +0 -3
- package/esm/src/commands/assignments.d.ts.map +0 -1
- package/esm/src/commands/assignments.js +0 -230
- package/esm/src/commands/auth.d.ts +0 -3
- package/esm/src/commands/auth.d.ts.map +0 -1
- package/esm/src/commands/auth.js +0 -290
- package/esm/src/commands/calendar.d.ts +0 -3
- package/esm/src/commands/calendar.d.ts.map +0 -1
- package/esm/src/commands/calendar.js +0 -179
- package/esm/src/commands/courses.d.ts +0 -3
- package/esm/src/commands/courses.d.ts.map +0 -1
- package/esm/src/commands/courses.js +0 -348
- package/esm/src/commands/forums.d.ts +0 -3
- package/esm/src/commands/forums.d.ts.map +0 -1
- package/esm/src/commands/forums.js +0 -318
- package/esm/src/commands/grades.d.ts +0 -3
- package/esm/src/commands/grades.d.ts.map +0 -1
- package/esm/src/commands/grades.js +0 -121
- package/esm/src/commands/materials.d.ts +0 -3
- package/esm/src/commands/materials.d.ts.map +0 -1
- package/esm/src/commands/materials.js +0 -413
- package/esm/src/commands/quizzes.d.ts +0 -3
- package/esm/src/commands/quizzes.d.ts.map +0 -1
- package/esm/src/commands/quizzes.js +0 -271
- package/esm/src/commands/skills.d.ts +0 -3
- package/esm/src/commands/skills.d.ts.map +0 -1
- package/esm/src/commands/skills.js +0 -106
- package/esm/src/commands/upload.d.ts +0 -3
- package/esm/src/commands/upload.d.ts.map +0 -1
- package/esm/src/commands/upload.js +0 -58
- package/esm/src/commands/videos.d.ts +0 -3
- package/esm/src/commands/videos.d.ts.map +0 -1
- package/esm/src/commands/videos.js +0 -336
- package/esm/src/index.d.ts +0 -27
- package/esm/src/index.d.ts.map +0 -1
- package/esm/src/index.js +0 -160
- package/esm/src/lib/auth.d.ts +0 -47
- package/esm/src/lib/auth.d.ts.map +0 -1
- package/esm/src/lib/auth.js +0 -227
- package/esm/src/lib/config.d.ts +0 -6
- package/esm/src/lib/config.d.ts.map +0 -1
- package/esm/src/lib/config.js +0 -36
- package/esm/src/lib/logger.d.ts +0 -3
- package/esm/src/lib/logger.d.ts.map +0 -1
- package/esm/src/lib/logger.js +0 -27
- package/esm/src/lib/moodle.d.ts +0 -433
- package/esm/src/lib/moodle.d.ts.map +0 -1
- package/esm/src/lib/moodle.js +0 -1318
- package/esm/src/lib/session.d.ts +0 -8
- package/esm/src/lib/session.d.ts.map +0 -1
- package/esm/src/lib/session.js +0 -42
- package/esm/src/lib/token.d.ts +0 -38
- package/esm/src/lib/token.d.ts.map +0 -1
- package/esm/src/lib/token.js +0 -178
- package/esm/src/lib/types.d.ts +0 -189
- package/esm/src/lib/types.d.ts.map +0 -1
- package/esm/src/lib/types.js +0 -2
- package/esm/src/lib/utils.d.ts +0 -57
- package/esm/src/lib/utils.d.ts.map +0 -1
- package/esm/src/lib/utils.js +0 -129
- package/script/_dnt.polyfills.d.ts +0 -101
- package/script/_dnt.polyfills.d.ts.map +0 -1
- package/script/_dnt.polyfills.js +0 -130
- package/script/_dnt.shims.d.ts +0 -6
- package/script/_dnt.shims.d.ts.map +0 -1
- package/script/_dnt.shims.js +0 -65
- package/script/deno.d.ts +0 -25
- package/script/deno.d.ts.map +0 -1
- package/script/deno.js +0 -25
- package/script/package.json +0 -3
- package/script/src/commands/announcements.d.ts +0 -3
- package/script/src/commands/announcements.d.ts.map +0 -1
- package/script/src/commands/announcements.js +0 -140
- package/script/src/commands/assignments.d.ts +0 -3
- package/script/src/commands/assignments.d.ts.map +0 -1
- package/script/src/commands/assignments.js +0 -269
- package/script/src/commands/auth.d.ts +0 -3
- package/script/src/commands/auth.d.ts.map +0 -1
- package/script/src/commands/auth.js +0 -296
- package/script/src/commands/calendar.d.ts +0 -3
- package/script/src/commands/calendar.d.ts.map +0 -1
- package/script/src/commands/calendar.js +0 -185
- package/script/src/commands/courses.d.ts +0 -3
- package/script/src/commands/courses.d.ts.map +0 -1
- package/script/src/commands/courses.js +0 -354
- package/script/src/commands/forums.d.ts +0 -3
- package/script/src/commands/forums.d.ts.map +0 -1
- package/script/src/commands/forums.js +0 -324
- package/script/src/commands/grades.d.ts +0 -3
- package/script/src/commands/grades.d.ts.map +0 -1
- package/script/src/commands/grades.js +0 -127
- package/script/src/commands/materials.d.ts +0 -3
- package/script/src/commands/materials.d.ts.map +0 -1
- package/script/src/commands/materials.js +0 -419
- package/script/src/commands/quizzes.d.ts +0 -3
- package/script/src/commands/quizzes.d.ts.map +0 -1
- package/script/src/commands/quizzes.js +0 -277
- package/script/src/commands/skills.d.ts +0 -3
- package/script/src/commands/skills.d.ts.map +0 -1
- package/script/src/commands/skills.js +0 -112
- package/script/src/commands/upload.d.ts +0 -3
- package/script/src/commands/upload.d.ts.map +0 -1
- package/script/src/commands/upload.js +0 -64
- package/script/src/commands/videos.d.ts +0 -3
- package/script/src/commands/videos.d.ts.map +0 -1
- package/script/src/commands/videos.js +0 -342
- package/script/src/index.d.ts +0 -27
- package/script/src/index.d.ts.map +0 -1
- package/script/src/index.js +0 -167
- package/script/src/lib/auth.d.ts +0 -47
- package/script/src/lib/auth.d.ts.map +0 -1
- package/script/src/lib/auth.js +0 -269
- package/script/src/lib/config.d.ts +0 -6
- package/script/src/lib/config.d.ts.map +0 -1
- package/script/src/lib/config.js +0 -42
- package/script/src/lib/logger.d.ts +0 -3
- package/script/src/lib/logger.d.ts.map +0 -1
- package/script/src/lib/logger.js +0 -30
- package/script/src/lib/moodle.d.ts +0 -433
- package/script/src/lib/moodle.d.ts.map +0 -1
- package/script/src/lib/moodle.js +0 -1389
- package/script/src/lib/session.d.ts +0 -8
- package/script/src/lib/session.d.ts.map +0 -1
- package/script/src/lib/session.js +0 -45
- package/script/src/lib/token.d.ts +0 -38
- package/script/src/lib/token.d.ts.map +0 -1
- package/script/src/lib/token.js +0 -189
- package/script/src/lib/types.d.ts +0 -189
- package/script/src/lib/types.d.ts.map +0 -1
- package/script/src/lib/types.js +0 -3
- package/script/src/lib/utils.d.ts +0 -57
- package/script/src/lib/utils.d.ts.map +0 -1
- package/script/src/lib/utils.js +0 -175
- package/skills/openape/SKILL.md +0 -115
package/script/src/lib/auth.js
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.findEdgePath = findEdgePath;
|
|
40
|
-
exports.launchAuthenticated = launchAuthenticated;
|
|
41
|
-
exports.closeBrowserSafely = closeBrowserSafely;
|
|
42
|
-
exports.createApiContext = createApiContext;
|
|
43
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
44
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
45
|
-
const playwright_core_1 = require("playwright-core");
|
|
46
|
-
const token_js_1 = require("./token.js");
|
|
47
|
-
/**
|
|
48
|
-
* Find a Chromium-based browser executable on Windows.
|
|
49
|
-
* Priority: Edge → Chrome → Brave
|
|
50
|
-
*/
|
|
51
|
-
function findEdgePath() {
|
|
52
|
-
const roots = [
|
|
53
|
-
process.env.PROGRAMFILES,
|
|
54
|
-
process.env["PROGRAMFILES(X86)"],
|
|
55
|
-
process.env.LOCALAPPDATA,
|
|
56
|
-
].filter(Boolean);
|
|
57
|
-
const browsers = [
|
|
58
|
-
{ name: "Edge", suffix: "Microsoft\\Edge\\Application\\msedge.exe" },
|
|
59
|
-
{ name: "Chrome", suffix: "Google\\Chrome\\Application\\chrome.exe" },
|
|
60
|
-
{ name: "Brave", suffix: "BraveSoftware\\Brave-Browser\\Application\\brave.exe" },
|
|
61
|
-
];
|
|
62
|
-
for (const { suffix } of browsers) {
|
|
63
|
-
for (const root of roots) {
|
|
64
|
-
const candidate = node_path_1.default.join(root, suffix);
|
|
65
|
-
if (node_fs_1.default.existsSync(candidate))
|
|
66
|
-
return candidate;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
throw new Error("找不到可用的瀏覽器(Edge / Chrome / Brave)。請確認已安裝其中一種。");
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Launch a browser and return an authenticated context.
|
|
73
|
-
* Tries to restore a saved session first; falls back to fresh OAuth login.
|
|
74
|
-
* Also acquires Moodle Web Service Token for API calls.
|
|
75
|
-
*/
|
|
76
|
-
async function launchAuthenticated(config, log) {
|
|
77
|
-
const edgePath = findEdgePath();
|
|
78
|
-
log.debug(`Using Edge: ${edgePath}`);
|
|
79
|
-
// Wait a bit to ensure any previous browser process has fully terminated
|
|
80
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
81
|
-
const browser = await playwright_core_1.chromium.launch({
|
|
82
|
-
executablePath: edgePath,
|
|
83
|
-
headless: config.headless,
|
|
84
|
-
slowMo: config.slowMo,
|
|
85
|
-
});
|
|
86
|
-
// Try loading saved WS token first
|
|
87
|
-
let wsToken = (0, token_js_1.loadWsToken)(config.authStatePath) ?? undefined;
|
|
88
|
-
if (wsToken) {
|
|
89
|
-
log.info("Loaded saved Web Service Token.");
|
|
90
|
-
}
|
|
91
|
-
// Try restoring a saved session
|
|
92
|
-
const restored = await tryRestoreSession(browser, config, log);
|
|
93
|
-
if (restored) {
|
|
94
|
-
const page = restored.pages()[0] ?? (await restored.newPage());
|
|
95
|
-
// If no saved WS token, try to acquire one
|
|
96
|
-
if (!wsToken) {
|
|
97
|
-
try {
|
|
98
|
-
wsToken = await (0, token_js_1.acquireWsToken)(page, config, log);
|
|
99
|
-
(0, token_js_1.saveWsToken)(config.authStatePath, wsToken);
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
log.warn("Failed to acquire WS Token with restored session, continuing without it.");
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return { browser, context: restored, page, wsToken };
|
|
106
|
-
}
|
|
107
|
-
// Fresh login
|
|
108
|
-
if (config.headless) {
|
|
109
|
-
await browser.close().catch(() => { });
|
|
110
|
-
throw new Error("找不到有效的 Session 或是 Session 已過期。\n" +
|
|
111
|
-
"請先執行 `openape login` 進行手動登入,或是加上 `--headed` 參數執行目前的指令以開啟登入畫面。");
|
|
112
|
-
}
|
|
113
|
-
const context = await browser.newContext();
|
|
114
|
-
const page = await context.newPage();
|
|
115
|
-
await login(page, config, log);
|
|
116
|
-
await saveSession(context, config.authStatePath, log);
|
|
117
|
-
// Acquire WS Token after successful login
|
|
118
|
-
if (!wsToken) {
|
|
119
|
-
try {
|
|
120
|
-
wsToken = await (0, token_js_1.acquireWsToken)(page, config, log);
|
|
121
|
-
(0, token_js_1.saveWsToken)(config.authStatePath, wsToken);
|
|
122
|
-
}
|
|
123
|
-
catch {
|
|
124
|
-
log.warn("Failed to acquire WS Token, continuing with sesskey-only auth.");
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return { browser, context, page, wsToken };
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Safely close browser and context with timeout.
|
|
131
|
-
* Designed for AI agent usage - no human interaction needed.
|
|
132
|
-
* If noWait is true, initiates cleanup but doesn't wait for completion.
|
|
133
|
-
*
|
|
134
|
-
* Note: Closes sequentially (context first, then browser) to avoid libuv
|
|
135
|
-
* assertion failures on Windows when handles are closed concurrently.
|
|
136
|
-
*/
|
|
137
|
-
async function closeBrowserSafely(browser, context, timeoutMs = 5000, noWait = false) {
|
|
138
|
-
const closePromises = [];
|
|
139
|
-
// Close context first with error handling
|
|
140
|
-
if (context) {
|
|
141
|
-
closePromises.push(Promise.race([
|
|
142
|
-
context.close().catch(() => { }),
|
|
143
|
-
new Promise(resolve => setTimeout(() => resolve(), timeoutMs))
|
|
144
|
-
]));
|
|
145
|
-
}
|
|
146
|
-
// Close browser after context with error handling
|
|
147
|
-
closePromises.push(Promise.race([
|
|
148
|
-
browser.close().catch(() => { }),
|
|
149
|
-
new Promise(resolve => setTimeout(() => resolve(), timeoutMs))
|
|
150
|
-
]));
|
|
151
|
-
if (noWait) {
|
|
152
|
-
// Fire and forget - don't wait for cleanup
|
|
153
|
-
Promise.allSettled(closePromises);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
// Wait sequentially to avoid libuv issues on Windows
|
|
157
|
-
for (const promise of closePromises) {
|
|
158
|
-
await promise.catch(() => { });
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Attempt to restore a session from stored state.
|
|
163
|
-
* Returns null if the stored state doesn't exist or the session is expired.
|
|
164
|
-
*/
|
|
165
|
-
async function tryRestoreSession(browser, config, log) {
|
|
166
|
-
const statePath = node_path_1.default.resolve(config.authStatePath);
|
|
167
|
-
if (!node_fs_1.default.existsSync(statePath)) {
|
|
168
|
-
log.debug("No saved session found, will perform fresh login.");
|
|
169
|
-
return null;
|
|
170
|
-
}
|
|
171
|
-
log.info("Restoring saved session...");
|
|
172
|
-
const context = await browser.newContext({ storageState: statePath });
|
|
173
|
-
const page = await context.newPage();
|
|
174
|
-
try {
|
|
175
|
-
await page.goto(`${config.moodleBaseUrl}/my/`, {
|
|
176
|
-
waitUntil: "domcontentloaded",
|
|
177
|
-
timeout: 15000,
|
|
178
|
-
});
|
|
179
|
-
// If we got redirected to a login page, the session is expired
|
|
180
|
-
const url = page.url();
|
|
181
|
-
if (url.includes("login") || url.includes("microsoftonline")) {
|
|
182
|
-
log.warn("Saved session expired, will re-authenticate.");
|
|
183
|
-
await context.close();
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
log.success("Session restored successfully.");
|
|
187
|
-
return context;
|
|
188
|
-
}
|
|
189
|
-
catch {
|
|
190
|
-
log.warn("Failed to restore session, will re-authenticate.");
|
|
191
|
-
await context.close();
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Save the current session state to disk for future reuse.
|
|
197
|
-
*/
|
|
198
|
-
async function saveSession(context, statePath, log) {
|
|
199
|
-
try {
|
|
200
|
-
await context.storageState({ path: statePath });
|
|
201
|
-
log.debug("Session saved for future reuse.");
|
|
202
|
-
}
|
|
203
|
-
catch (err) {
|
|
204
|
-
log.warn(`Failed to save session: ${err}`);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Perform Microsoft OAuth login flow.
|
|
209
|
-
*/
|
|
210
|
-
async function login(page, config, log) {
|
|
211
|
-
log.info("Starting Microsoft OAuth login...");
|
|
212
|
-
await page.goto(`${config.moodleBaseUrl}/auth/oauth2/login.php`, {
|
|
213
|
-
waitUntil: "domcontentloaded",
|
|
214
|
-
timeout: 30000,
|
|
215
|
-
});
|
|
216
|
-
// Wait for Microsoft login page or redirect back to Moodle
|
|
217
|
-
try {
|
|
218
|
-
await page.waitForURL((url) => url.toString().includes("microsoftonline") ||
|
|
219
|
-
url.toString().includes("login.microsoftonline") ||
|
|
220
|
-
(url.toString().includes("ilearning.cycu.edu.tw") &&
|
|
221
|
-
!url.toString().includes("auth/oauth2/login")), { timeout: 10000 });
|
|
222
|
-
const url = page.url().toString();
|
|
223
|
-
if (url.includes("microsoftonline") || url.includes("login.microsoftonline")) {
|
|
224
|
-
log.info("Microsoft login page detected. Please complete login in the browser.");
|
|
225
|
-
log.info("Waiting for redirect back to Moodle...");
|
|
226
|
-
await page.waitForURL((u) => u.toString().includes("ilearning.cycu.edu.tw") &&
|
|
227
|
-
!u.toString().includes("microsoftonline") &&
|
|
228
|
-
!u.toString().includes("login.microsoftonline"), { timeout: 300000 });
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
catch {
|
|
232
|
-
// Already logged in or redirected
|
|
233
|
-
}
|
|
234
|
-
// Verify we're logged in
|
|
235
|
-
const finalUrl = page.url().toString();
|
|
236
|
-
if (finalUrl.includes("login") ||
|
|
237
|
-
finalUrl.includes("microsoftonline") ||
|
|
238
|
-
finalUrl === config.moodleBaseUrl + "/auth/oauth2/login.php") {
|
|
239
|
-
throw new Error(`登入後未重新導向回 Moodle。目前 URL: ${finalUrl}`);
|
|
240
|
-
}
|
|
241
|
-
log.success("Login completed successfully.");
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Create API context for WS token operations (no browser required).
|
|
245
|
-
* Returns null if session is invalid or WS token is missing.
|
|
246
|
-
*/
|
|
247
|
-
async function createApiContext(options, command) {
|
|
248
|
-
const { createLogger } = await Promise.resolve().then(() => __importStar(require("./logger.js")));
|
|
249
|
-
const { loadWsToken } = await Promise.resolve().then(() => __importStar(require("./token.js")));
|
|
250
|
-
const { getOutputFormat, getSessionPath } = await Promise.resolve().then(() => __importStar(require("./utils.js")));
|
|
251
|
-
const opts = command?.optsWithGlobals ? command.optsWithGlobals() : options;
|
|
252
|
-
const outputFormat = command ? getOutputFormat(command) : "json";
|
|
253
|
-
const silent = outputFormat === "json" && !opts.verbose;
|
|
254
|
-
const log = createLogger(opts.verbose, silent, outputFormat);
|
|
255
|
-
const sessionPath = getSessionPath();
|
|
256
|
-
// Try to load WS token
|
|
257
|
-
const wsToken = loadWsToken(sessionPath);
|
|
258
|
-
if (!wsToken) {
|
|
259
|
-
console.error("未找到 WS token。請先執行 'openape login' 進行登入。");
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
return {
|
|
263
|
-
log,
|
|
264
|
-
session: {
|
|
265
|
-
wsToken,
|
|
266
|
-
moodleBaseUrl: "https://ilearning.cycu.edu.tw",
|
|
267
|
-
},
|
|
268
|
-
};
|
|
269
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/src/lib/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAgBtD"}
|
package/script/src/lib/config.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.loadConfig = loadConfig;
|
|
7
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
/**
|
|
10
|
-
* Load config from .env file (if it exists).
|
|
11
|
-
*/
|
|
12
|
-
function loadConfig(baseDir) {
|
|
13
|
-
const envPath = baseDir ? node_path_1.default.resolve(baseDir, ".env") : node_path_1.default.resolve(".env");
|
|
14
|
-
if (node_fs_1.default.existsSync(envPath)) {
|
|
15
|
-
const envContent = node_fs_1.default.readFileSync(envPath, "utf8");
|
|
16
|
-
for (const line of envContent.split("\n")) {
|
|
17
|
-
const trimmed = line.trim();
|
|
18
|
-
if (!trimmed || trimmed.startsWith("#"))
|
|
19
|
-
continue;
|
|
20
|
-
const eqIdx = trimmed.indexOf("=");
|
|
21
|
-
if (eqIdx === -1)
|
|
22
|
-
continue;
|
|
23
|
-
const key = trimmed.slice(0, eqIdx).trim();
|
|
24
|
-
const value = trimmed.slice(eqIdx + 1).trim();
|
|
25
|
-
if (!process.env[key])
|
|
26
|
-
process.env[key] = value;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return buildConfig();
|
|
30
|
-
}
|
|
31
|
-
function buildConfig() {
|
|
32
|
-
const moodleBaseUrl = (process.env.MOODLE_BASE_URL ?? "https://ilearning.cycu.edu.tw").replace(/\/$/, "");
|
|
33
|
-
return {
|
|
34
|
-
courseUrl: "",
|
|
35
|
-
moodleBaseUrl,
|
|
36
|
-
headless: process.env.HEADLESS !== "false",
|
|
37
|
-
slowMo: parseInt(process.env.SLOW_MO ?? "0", 10),
|
|
38
|
-
authStatePath: process.env.AUTH_STATE_PATH ?? ".auth/storage-state.json",
|
|
39
|
-
ollamaModel: process.env.MODEL,
|
|
40
|
-
ollamaBaseUrl: (process.env.OLLAMA_BASE_URL ?? "http://localhost:11434").replace(/\/$/, ""),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAOzC,wBAAgB,YAAY,CAAC,OAAO,UAAQ,EAAE,MAAM,UAAQ,EAAE,YAAY,GAAE,MAAe,GAAG,MAAM,CAwBnG"}
|
package/script/src/lib/logger.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createLogger = createLogger;
|
|
4
|
-
const NO_COLOR = !!process.env.NO_COLOR;
|
|
5
|
-
const c = (code, text) => NO_COLOR ? text : `\x1b[${code}m${text}\x1b[0m`;
|
|
6
|
-
function createLogger(verbose = false, silent = false, outputFormat = "json") {
|
|
7
|
-
const jsonError = outputFormat === "json";
|
|
8
|
-
const errorFn = jsonError
|
|
9
|
-
? (msg) => console.error(JSON.stringify({ error: msg }))
|
|
10
|
-
: (msg) => console.error(c("31", "[ERR]") + ` ${msg}`);
|
|
11
|
-
if (silent) {
|
|
12
|
-
return {
|
|
13
|
-
info: (_msg) => { },
|
|
14
|
-
success: (_msg) => { },
|
|
15
|
-
warn: (_msg) => { },
|
|
16
|
-
error: errorFn,
|
|
17
|
-
debug: (_msg) => { },
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
return {
|
|
21
|
-
info: (msg) => console.error(c("36", "[INFO]") + ` ${msg}`),
|
|
22
|
-
success: (msg) => console.error(c("32", "[OK]") + ` ${msg}`),
|
|
23
|
-
warn: (msg) => console.error(c("33", "[WARN]") + ` ${msg}`),
|
|
24
|
-
error: errorFn,
|
|
25
|
-
debug: (msg) => {
|
|
26
|
-
if (verbose)
|
|
27
|
-
console.error(c("90", "[DBG]") + ` ${msg}`);
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|