sfiledl 2.0.1 → 2.1.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/build/lib.cjs +362 -90
- package/build/lib.cjs.map +1 -1
- package/build/lib.d.ts +42 -26
- package/build/lib.mjs +335 -86
- package/build/lib.mjs.map +1 -1
- package/changelog +92 -0
- package/package.json +2 -2
- package/readme.md +170 -0
- package/readme +0 -3
package/build/lib.cjs
CHANGED
|
@@ -2,113 +2,385 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs/promises');
|
|
7
|
+
const playwright = require('playwright');
|
|
8
|
+
const os = require('os');
|
|
9
|
+
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
function _interopNamespace(e) {
|
|
13
|
+
if (e && e.__esModule) return e;
|
|
14
|
+
const n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
for (const k in e) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return n;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const path__default = /*#__PURE__*/_interopDefault(path);
|
|
31
|
+
const fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
32
|
+
const os__default = /*#__PURE__*/_interopDefault(os);
|
|
33
|
+
|
|
34
|
+
class AppError extends Error {
|
|
35
|
+
code;
|
|
36
|
+
retryable;
|
|
37
|
+
timestamp;
|
|
38
|
+
context;
|
|
39
|
+
constructor(message, code, retryable = false, context) {
|
|
40
|
+
super(message);
|
|
41
|
+
this.code = code;
|
|
42
|
+
this.retryable = retryable;
|
|
43
|
+
this.name = this.constructor.name;
|
|
44
|
+
this.timestamp = new Date().toISOString();
|
|
45
|
+
this.context = context ? { ...context } : undefined;
|
|
46
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
47
|
+
}
|
|
48
|
+
toJSON() {
|
|
49
|
+
return {
|
|
50
|
+
name: this.name,
|
|
51
|
+
message: this.message,
|
|
52
|
+
code: this.code,
|
|
53
|
+
retryable: this.retryable,
|
|
54
|
+
timestamp: this.timestamp,
|
|
55
|
+
context: this.context,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
class ValidationError extends AppError {
|
|
61
|
+
constructor(message, context) {
|
|
62
|
+
super(message, 'VALIDATION_ERROR', false, context);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
class NetworkError extends AppError {
|
|
66
|
+
constructor(message, context) {
|
|
67
|
+
super(message, 'NETWORK_ERROR', true, context);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
class FileError extends AppError {
|
|
71
|
+
constructor(message, context) {
|
|
72
|
+
super(message, 'FILE_ERROR', false, context);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
class BrowserError extends AppError {
|
|
76
|
+
constructor(message, context) {
|
|
77
|
+
super(message, 'BROWSER_ERROR', true, context);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const DEFAULTS = {
|
|
82
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
|
|
83
|
+
headless: true,
|
|
84
|
+
timeout: 100000,
|
|
85
|
+
downloadButtonTimeout: 100000,
|
|
86
|
+
fallbackWaitMs: 5000,
|
|
26
87
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
88
|
+
|
|
89
|
+
class SfilePageInteractions {
|
|
90
|
+
page;
|
|
91
|
+
logger;
|
|
92
|
+
constructor(page, logger) {
|
|
93
|
+
this.page = page;
|
|
94
|
+
this.logger = logger;
|
|
95
|
+
}
|
|
96
|
+
async waitForDownloadButton(timeout) {
|
|
97
|
+
this.logger.debug('Waiting for #download button to be visible');
|
|
98
|
+
const button = this.page.locator('#download');
|
|
99
|
+
await button.waitFor({ state: 'visible', timeout });
|
|
100
|
+
this.logger.debug('Waiting for button to become active (href != "#" and pointerEvents != "none")');
|
|
101
|
+
await this.page.waitForFunction(() => {
|
|
102
|
+
const btn = document.querySelector('#download');
|
|
103
|
+
if (!btn)
|
|
104
|
+
return false;
|
|
105
|
+
const href = btn.getAttribute('href');
|
|
106
|
+
const style = window.getComputedStyle(btn);
|
|
107
|
+
return href && href !== '#' && style.pointerEvents !== 'none';
|
|
108
|
+
}, { timeout });
|
|
109
|
+
}
|
|
110
|
+
async extractIntermediateUrl() {
|
|
111
|
+
this.logger.debug('Extracting href from #download');
|
|
112
|
+
const href = await this.page.$eval('#download', (el) => el.href);
|
|
113
|
+
if (!href || href === '#') {
|
|
114
|
+
throw new NetworkError('Download button href is invalid', { href });
|
|
115
|
+
}
|
|
116
|
+
return href;
|
|
117
|
+
}
|
|
30
118
|
}
|
|
31
|
-
|
|
32
|
-
|
|
119
|
+
|
|
120
|
+
function sanitizeFilename(name, replacement = '_') {
|
|
121
|
+
const sanitized = name
|
|
122
|
+
.replace(/[<>:"/\\|?*\x00-\x1F]/g, replacement)
|
|
123
|
+
.replace(new RegExp(`${replacement}+`, 'g'), replacement)
|
|
124
|
+
.trim()
|
|
125
|
+
.slice(0, 255);
|
|
126
|
+
return sanitized || 'file.bin';
|
|
127
|
+
}
|
|
128
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
129
|
+
function safeStringify(value) {
|
|
130
|
+
try {
|
|
131
|
+
return JSON.stringify(value);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return '[unserializable]';
|
|
135
|
+
}
|
|
33
136
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
137
|
+
|
|
138
|
+
class BrowserManager {
|
|
139
|
+
logger;
|
|
140
|
+
opts;
|
|
141
|
+
browser = null;
|
|
142
|
+
context = null;
|
|
143
|
+
page = null;
|
|
144
|
+
interactions = null;
|
|
145
|
+
debugDir = null;
|
|
146
|
+
constructor(logger, opts) {
|
|
147
|
+
this.logger = logger;
|
|
148
|
+
this.opts = opts;
|
|
38
149
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
150
|
+
async launch() {
|
|
151
|
+
try {
|
|
152
|
+
this.logger.info('Launching browser', { headless: this.opts.headless });
|
|
153
|
+
this.browser = await playwright.chromium.launch({
|
|
154
|
+
headless: this.opts.headless,
|
|
155
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
|
|
156
|
+
});
|
|
157
|
+
this.context = await this.browser.newContext({
|
|
158
|
+
userAgent: this.opts.userAgent,
|
|
159
|
+
acceptDownloads: true,
|
|
160
|
+
locale: 'en-US',
|
|
161
|
+
});
|
|
162
|
+
await this.context.addCookies([
|
|
163
|
+
{
|
|
164
|
+
name: 'safe_link_counter',
|
|
165
|
+
value: '1',
|
|
166
|
+
domain: '.sfile.co',
|
|
167
|
+
path: '/',
|
|
168
|
+
expires: Math.floor(Date.now() / 1000) + 3600,
|
|
169
|
+
},
|
|
170
|
+
]);
|
|
171
|
+
this.page = await this.context.newPage();
|
|
172
|
+
this.interactions = new SfilePageInteractions(this.page, this.logger);
|
|
173
|
+
if (this.opts.debug) {
|
|
174
|
+
this.page.on('console', (msg) => {
|
|
175
|
+
if (msg.type() === 'error')
|
|
176
|
+
this.logger.error(`[console] ${msg.text()}`);
|
|
177
|
+
else if (msg.type() === 'warning')
|
|
178
|
+
this.logger.warn(`[console] ${msg.text()}`);
|
|
179
|
+
});
|
|
180
|
+
this.page.on('pageerror', (err) => this.logger.error(`[pageerror] ${err.message}`));
|
|
181
|
+
}
|
|
182
|
+
this.logger.info('Browser ready');
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
throw new BrowserError(`Failed to launch browser: ${err.message}`);
|
|
42
186
|
}
|
|
43
|
-
return LibStatus.instance;
|
|
44
187
|
}
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
|
|
188
|
+
async goto(url, waitUntil = 'networkidle') {
|
|
189
|
+
if (!this.page)
|
|
190
|
+
throw new BrowserError('Page not initialized');
|
|
191
|
+
try {
|
|
192
|
+
this.logger.debug(`Navigating to ${url} (waitUntil=${waitUntil})`);
|
|
193
|
+
await this.page.goto(url, { waitUntil, timeout: this.opts.timeout });
|
|
48
194
|
}
|
|
49
|
-
|
|
50
|
-
|
|
195
|
+
catch (err) {
|
|
196
|
+
throw new NetworkError(`Navigation failed: ${err.message}`, { url });
|
|
51
197
|
}
|
|
52
|
-
|
|
198
|
+
}
|
|
199
|
+
async waitForDownloadButton() {
|
|
200
|
+
if (!this.interactions)
|
|
201
|
+
throw new BrowserError('Interactions not ready');
|
|
202
|
+
await this.interactions.waitForDownloadButton(DEFAULTS.downloadButtonTimeout);
|
|
203
|
+
}
|
|
204
|
+
async getIntermediateUrl() {
|
|
205
|
+
if (!this.interactions)
|
|
206
|
+
throw new BrowserError('Interactions not ready');
|
|
207
|
+
return this.interactions.extractIntermediateUrl();
|
|
208
|
+
}
|
|
209
|
+
async startDownloadAndWait(autoUrl) {
|
|
210
|
+
if (!this.page)
|
|
211
|
+
throw new BrowserError('Page not initialized');
|
|
212
|
+
const downloadPromise = this.page
|
|
213
|
+
.waitForEvent('download', { timeout: this.opts.timeout })
|
|
214
|
+
.catch((err) => {
|
|
215
|
+
this.logger.warn(`Download event wait failed: ${err.message}`);
|
|
216
|
+
return null;
|
|
217
|
+
});
|
|
218
|
+
this.logger.debug(`Navigating to auto URL: ${autoUrl}`);
|
|
219
|
+
await this.page.goto(autoUrl, { waitUntil: 'commit', timeout: this.opts.timeout });
|
|
220
|
+
const download = await downloadPromise;
|
|
221
|
+
if (download) {
|
|
222
|
+
this.logger.info('Download event captured');
|
|
223
|
+
return download;
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
async fallbackCollectFileResponse() {
|
|
228
|
+
if (!this.page)
|
|
229
|
+
throw new BrowserError('Page not initialized');
|
|
230
|
+
this.logger.warn('Falling back to response interception');
|
|
231
|
+
const responses = [];
|
|
232
|
+
const handler = (res) => responses.push(res);
|
|
233
|
+
this.page.on('response', handler);
|
|
234
|
+
await sleep(DEFAULTS.fallbackWaitMs);
|
|
235
|
+
this.page.off('response', handler);
|
|
236
|
+
const fileResponse = [...responses].reverse().find((r) => {
|
|
237
|
+
const disposition = r.headers()['content-disposition'];
|
|
238
|
+
return ((disposition && disposition.includes('attachment')) ||
|
|
239
|
+
r.url().includes('/downloadfile/'));
|
|
240
|
+
});
|
|
241
|
+
if (!fileResponse)
|
|
242
|
+
return null;
|
|
243
|
+
const buffer = await fileResponse.body();
|
|
244
|
+
let filename = fileResponse.url().split('/').pop()?.split('?')[0] || 'file.bin';
|
|
245
|
+
filename = filename.replace(/[<>:"/\\|?*]/g, '_');
|
|
246
|
+
return { buffer, filename };
|
|
247
|
+
}
|
|
248
|
+
async saveDebugArtifacts(errorMessage) {
|
|
249
|
+
if (!this.page)
|
|
53
250
|
return;
|
|
251
|
+
try {
|
|
252
|
+
this.debugDir = path__default.default.join(os__default.default.tmpdir(), `sfile_debug_${Date.now()}`);
|
|
253
|
+
await fs__namespace.mkdir(this.debugDir, { recursive: true });
|
|
254
|
+
await Promise.all([
|
|
255
|
+
this.page.screenshot({
|
|
256
|
+
path: path__default.default.join(this.debugDir, 'error.png'),
|
|
257
|
+
fullPage: true,
|
|
258
|
+
}),
|
|
259
|
+
fs__namespace.writeFile(path__default.default.join(this.debugDir, 'error.html'), await this.page.content()),
|
|
260
|
+
fs__namespace.writeFile(path__default.default.join(this.debugDir, 'error.txt'), errorMessage),
|
|
261
|
+
]);
|
|
262
|
+
this.logger.info(`Debug artifacts saved to ${this.debugDir}`);
|
|
54
263
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const highlight = `${COLORS.CYAN}`;
|
|
58
|
-
console.warn(`\n${border}`);
|
|
59
|
-
console.warn(`${label} DEVELOPMENT VERSION IN USE`);
|
|
60
|
-
console.warn(`${COLORS.GRAY}Library: ${COLORS.RESET}${highlight}${LIB_INFO.name}${COLORS.RESET}`);
|
|
61
|
-
console.warn(`${COLORS.GRAY}Current Version: ${COLORS.RESET}${highlight}${LIB_INFO.currentVersion}${COLORS.RESET}`);
|
|
62
|
-
console.warn(`${COLORS.GRAY}Previous Version: ${COLORS.RESET}${highlight}${LIB_INFO.previousVersion}${COLORS.RESET}`);
|
|
63
|
-
console.warn(`${COLORS.GRAY}Architecture: ${COLORS.RESET}${highlight}CLI -> Framework (Full Refactor)${COLORS.RESET}`);
|
|
64
|
-
console.warn(`\n${COLORS.RED}${COLORS.BRIGHT}DO NOT USE IN PRODUCTION ENVIRONMENTS${COLORS.RESET}`);
|
|
65
|
-
console.warn(`${COLORS.GRAY}API stability is not guaranteed. Breaking changes may occur without notice.${COLORS.RESET}`);
|
|
66
|
-
console.warn(`${COLORS.GRAY}To suppress this warning, set env MY_SUPER_FRAMEWORK_SUPPRESS_WARNING=true${COLORS.RESET}`);
|
|
67
|
-
console.warn(`${border}\n`);
|
|
68
|
-
warningDisplayed = true;
|
|
69
|
-
}
|
|
70
|
-
suppressWarning() {
|
|
71
|
-
warningDisplayed = true;
|
|
72
|
-
}
|
|
73
|
-
ensureStable() {
|
|
74
|
-
if (LIB_INFO.status === exports.LibraryStatus.UNDER_CONSTRUCTION) {
|
|
75
|
-
const errorMessage = `${COLORS.RED}${COLORS.BRIGHT}[${LIB_INFO.name}] Stability Check Failed${COLORS.RESET}\n` +
|
|
76
|
-
`${COLORS.GRAY}Library version ${LIB_INFO.currentVersion} is under active development.${COLORS.RESET}\n` +
|
|
77
|
-
`${COLORS.GRAY}Current status: ${LIB_INFO.status}${COLORS.RESET}`;
|
|
78
|
-
throw new Error(stripAnsi(errorMessage));
|
|
264
|
+
catch (e) {
|
|
265
|
+
this.logger.error(`Failed to save debug artifacts: ${e.message}`);
|
|
79
266
|
}
|
|
80
267
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
268
|
+
async close() {
|
|
269
|
+
if (this.page)
|
|
270
|
+
await this.page.close().catch(() => { });
|
|
271
|
+
if (this.context)
|
|
272
|
+
await this.context.close().catch(() => { });
|
|
273
|
+
if (this.browser)
|
|
274
|
+
await this.browser.close().catch(() => { });
|
|
275
|
+
this.logger.debug('Browser closed');
|
|
86
276
|
}
|
|
87
277
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
278
|
+
|
|
279
|
+
class Logger {
|
|
280
|
+
minLevel;
|
|
281
|
+
constructor(debugMode = false) {
|
|
282
|
+
this.minLevel = debugMode ? 'debug' : 'info';
|
|
283
|
+
}
|
|
284
|
+
setDebug(enabled) {
|
|
285
|
+
this.minLevel = enabled ? 'debug' : 'info';
|
|
286
|
+
}
|
|
287
|
+
shouldLog(level) {
|
|
288
|
+
const levels = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
289
|
+
return levels[level] >= levels[this.minLevel];
|
|
290
|
+
}
|
|
291
|
+
log(level, message, context) {
|
|
292
|
+
if (!this.shouldLog(level))
|
|
293
|
+
return;
|
|
294
|
+
const ts = new Date().toISOString();
|
|
295
|
+
const ctx = context ? ` ${safeStringify(context)}` : '';
|
|
296
|
+
console.log(`[${ts}] ${level.toUpperCase()}: ${message}${ctx}`);
|
|
297
|
+
}
|
|
298
|
+
debug(msg, ctx) {
|
|
299
|
+
this.log('debug', msg, ctx);
|
|
300
|
+
}
|
|
301
|
+
info(msg, ctx) {
|
|
302
|
+
this.log('info', msg, ctx);
|
|
303
|
+
}
|
|
304
|
+
warn(msg, ctx) {
|
|
305
|
+
this.log('warn', msg, ctx);
|
|
306
|
+
}
|
|
307
|
+
error(msg, ctx) {
|
|
308
|
+
this.log('error', msg, ctx);
|
|
309
|
+
}
|
|
94
310
|
}
|
|
95
|
-
|
|
96
|
-
|
|
311
|
+
|
|
312
|
+
function normalizeOptions(opts) {
|
|
313
|
+
return {
|
|
314
|
+
headless: opts?.headless ?? DEFAULTS.headless,
|
|
315
|
+
debug: opts?.debug ?? false,
|
|
316
|
+
userAgent: opts?.userAgent ?? DEFAULTS.userAgent,
|
|
317
|
+
timeout: opts?.timeout ?? DEFAULTS.timeout,
|
|
318
|
+
};
|
|
97
319
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
320
|
+
|
|
321
|
+
async function downloadSfile(url, saveDir, options) {
|
|
322
|
+
const opts = normalizeOptions(options);
|
|
323
|
+
const logger = new Logger(opts.debug);
|
|
324
|
+
if (!url || !url.includes('sfile.co')) {
|
|
325
|
+
throw new ValidationError('URL must contain sfile.co', { url });
|
|
326
|
+
}
|
|
327
|
+
await fs__namespace.default.mkdir(saveDir, { recursive: true });
|
|
328
|
+
const browserMgr = new BrowserManager(logger, {
|
|
329
|
+
headless: opts.headless,
|
|
330
|
+
userAgent: opts.userAgent,
|
|
331
|
+
timeout: opts.timeout,
|
|
332
|
+
debug: opts.debug,
|
|
333
|
+
});
|
|
334
|
+
try {
|
|
335
|
+
await browserMgr.launch();
|
|
336
|
+
await browserMgr.goto(url, 'networkidle');
|
|
337
|
+
await browserMgr.waitForDownloadButton();
|
|
338
|
+
const intermediateUrl = await browserMgr.getIntermediateUrl();
|
|
339
|
+
const autoUrl = intermediateUrl.includes('?')
|
|
340
|
+
? `${intermediateUrl}&auto=1`
|
|
341
|
+
: `${intermediateUrl}?auto=1`;
|
|
342
|
+
let download = await browserMgr.startDownloadAndWait(autoUrl);
|
|
343
|
+
let finalPath;
|
|
344
|
+
let fileSize;
|
|
345
|
+
let method;
|
|
346
|
+
if (download) {
|
|
347
|
+
const suggested = download.suggestedFilename() || 'file.bin';
|
|
348
|
+
const filename = sanitizeFilename(suggested);
|
|
349
|
+
finalPath = path__default.default.join(saveDir, filename);
|
|
350
|
+
await download.saveAs(finalPath);
|
|
351
|
+
const stat = await fs__namespace.default.stat(finalPath);
|
|
352
|
+
fileSize = stat.size;
|
|
353
|
+
method = 'direct';
|
|
354
|
+
logger.info(`Saved via direct download: ${finalPath} (${fileSize} bytes)`);
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
const fallback = await browserMgr.fallbackCollectFileResponse();
|
|
358
|
+
if (!fallback) {
|
|
359
|
+
throw new NetworkError('No download event and no file response found');
|
|
360
|
+
}
|
|
361
|
+
const { buffer, filename: rawName } = fallback;
|
|
362
|
+
const filename = sanitizeFilename(rawName);
|
|
363
|
+
finalPath = path__default.default.join(saveDir, filename);
|
|
364
|
+
await fs__namespace.default.writeFile(finalPath, buffer);
|
|
365
|
+
fileSize = buffer.length;
|
|
366
|
+
method = 'fallback';
|
|
367
|
+
logger.info(`Saved via fallback: ${finalPath} (${fileSize} bytes)`);
|
|
368
|
+
}
|
|
369
|
+
return { filePath: finalPath, size: fileSize, method };
|
|
370
|
+
}
|
|
371
|
+
catch (err) {
|
|
372
|
+
await browserMgr.saveDebugArtifacts(err.message);
|
|
373
|
+
throw err;
|
|
374
|
+
}
|
|
375
|
+
finally {
|
|
376
|
+
await browserMgr.close();
|
|
102
377
|
}
|
|
103
|
-
}
|
|
104
|
-
if (isDevelopmentVersion()) {
|
|
105
|
-
LibStatus.getInstance();
|
|
106
378
|
}
|
|
107
379
|
|
|
108
|
-
exports.
|
|
109
|
-
exports.
|
|
110
|
-
exports.
|
|
111
|
-
exports.
|
|
112
|
-
exports.
|
|
113
|
-
exports.
|
|
380
|
+
exports.AppError = AppError;
|
|
381
|
+
exports.BrowserError = BrowserError;
|
|
382
|
+
exports.FileError = FileError;
|
|
383
|
+
exports.NetworkError = NetworkError;
|
|
384
|
+
exports.ValidationError = ValidationError;
|
|
385
|
+
exports.downloadSfile = downloadSfile;
|
|
114
386
|
//# sourceMappingURL=lib.cjs.map
|
package/build/lib.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.cjs","sources":["../lib/lib.ts"],"sourcesContent":["/**\n * ====================================================================================================\n * WARNING: LIBRARY UNDER ACTIVE DEVELOPMENT - NOT FOR PRODUCTION USE\n * ====================================================================================================\n * \n * Status: DEPRECATED / UNSTABLE\n * Previous Version: 1.0.2 (CLI-based architecture)\n * Target Version: 2.0.1 (Full framework architecture)\n * \n * BREAKING CHANGES NOTICE:\n * - This library is undergoing a complete rewrite and architectural refactor.\n * - Legacy CLI-based implementation has been entirely removed.\n * - New framework-based architecture is currently under active development.\n * \n * PRODUCTION USE PROHIBITED:\n * - API surface is subject to change without notice.\n * - No backward compatibility guarantees.\n * - Use exclusively for development and testing purposes.\n * \n * ====================================================================================================\n */\n\n// ANSI color codes for terminal output\nconst COLORS = {\n RESET: \"\\x1b[0m\",\n BRIGHT: \"\\x1b[1m\",\n YELLOW: \"\\x1b[33m\",\n RED: \"\\x1b[31m\",\n CYAN: \"\\x1b[36m\",\n GRAY: \"\\x1b[90m\",\n} as const;\n\n/**\n * Development status of the library.\n */\nexport enum LibraryStatus {\n /** Library is under active construction, not ready for production. */\n UNDER_CONSTRUCTION = \"UNDER_CONSTRUCTION\",\n /** Library is stable and ready for production. (Future use) */\n STABLE = \"STABLE\",\n /** Library is deprecated. (Future use) */\n DEPRECATED = \"DEPRECATED\",\n}\n\n/**\n * Library metadata.\n */\nexport const LIB_INFO = {\n name: \"MySuperFramework\",\n currentVersion: \"2.0.1-dev\",\n previousVersion: \"1.0.2\",\n status: LibraryStatus.UNDER_CONSTRUCTION,\n isDeprecated: true,\n message: \"This version represents a complete architectural refactor from CLI to framework. Not stable.\",\n} as const;\n\n// Flag to ensure warning is displayed only once\nlet warningDisplayed = false;\n\n/**\n * Utility function to strip ANSI escape codes from a string.\n * Supports common ANSI sequences (colors, styles, etc.).\n * @param text - Text containing ANSI escape sequences.\n * @returns Plain text without ANSI formatting.\n */\nfunction stripAnsi(text: string): string {\n // Matches ANSI escape sequences: \\x1b[ (or \\u001b[) followed by any number of parameters and ending with a letter\n return text.replace(/\\x1b\\[[0-9;]*[a-zA-Z]/g, \"\");\n}\n\n/**\n * Checks if the library is currently in development mode.\n * @returns `true` if the library status is `UNDER_CONSTRUCTION`.\n */\nexport function isDevelopmentVersion(): boolean {\n return LIB_INFO.status === LibraryStatus.UNDER_CONSTRUCTION;\n}\n\n/**\n * Primary class for library status management and developer notifications.\n * Provides programmatic access to version information and stability checks.\n */\nexport class LibStatus {\n private static instance: LibStatus | undefined;\n\n private constructor() {\n this.displayDeveloperWarning();\n }\n\n /**\n * Gets the singleton instance of LibStatus.\n * @returns The LibStatus instance.\n */\n public static getInstance(): LibStatus {\n if (!LibStatus.instance) {\n LibStatus.instance = new LibStatus();\n }\n return LibStatus.instance;\n }\n\n /**\n * Outputs formatted warning message to console upon library initialization.\n * Uses ANSI color codes for enhanced visibility in terminal environments.\n * The warning is displayed only once per process, unless suppressed.\n */\n private displayDeveloperWarning(): void {\n // Skip if console is not available or warning already displayed\n if (typeof console === \"undefined\" || typeof console.warn !== \"function\") {\n return;\n }\n if (warningDisplayed) {\n return;\n }\n // Check environment variable to suppress warning (e.g., for testing)\n // Use bracket notation to avoid TypeScript index signature error\n if (typeof process !== \"undefined\" && process.env && process.env['MY_SUPER_FRAMEWORK_SUPPRESS_WARNING'] === \"true\") {\n return;\n }\n\n const border = `${COLORS.GRAY}${\"=\".repeat(80)}${COLORS.RESET}`;\n const label = `${COLORS.YELLOW}${COLORS.BRIGHT}[WARNING]${COLORS.RESET}`;\n const highlight = `${COLORS.CYAN}`;\n\n console.warn(`\\n${border}`);\n console.warn(`${label} DEVELOPMENT VERSION IN USE`);\n console.warn(`${COLORS.GRAY}Library: ${COLORS.RESET}${highlight}${LIB_INFO.name}${COLORS.RESET}`);\n console.warn(`${COLORS.GRAY}Current Version: ${COLORS.RESET}${highlight}${LIB_INFO.currentVersion}${COLORS.RESET}`);\n console.warn(`${COLORS.GRAY}Previous Version: ${COLORS.RESET}${highlight}${LIB_INFO.previousVersion}${COLORS.RESET}`);\n console.warn(`${COLORS.GRAY}Architecture: ${COLORS.RESET}${highlight}CLI -> Framework (Full Refactor)${COLORS.RESET}`);\n console.warn(`\\n${COLORS.RED}${COLORS.BRIGHT}DO NOT USE IN PRODUCTION ENVIRONMENTS${COLORS.RESET}`);\n console.warn(`${COLORS.GRAY}API stability is not guaranteed. Breaking changes may occur without notice.${COLORS.RESET}`);\n console.warn(`${COLORS.GRAY}To suppress this warning, set env MY_SUPER_FRAMEWORK_SUPPRESS_WARNING=true${COLORS.RESET}`);\n console.warn(`${border}\\n`);\n\n warningDisplayed = true;\n }\n\n /**\n * Suppresses the development warning for this instance.\n * Useful when you need to programmatically disable the warning (e.g., in tests).\n */\n public suppressWarning(): void {\n warningDisplayed = true;\n }\n\n /**\n * Validates library stability status.\n * @throws Error if library is marked as unstable or under construction.\n */\n public ensureStable(): void {\n if (LIB_INFO.status === LibraryStatus.UNDER_CONSTRUCTION) {\n const errorMessage = `${COLORS.RED}${COLORS.BRIGHT}[${LIB_INFO.name}] Stability Check Failed${COLORS.RESET}\\n` +\n `${COLORS.GRAY}Library version ${LIB_INFO.currentVersion} is under active development.${COLORS.RESET}\\n` +\n `${COLORS.GRAY}Current status: ${LIB_INFO.status}${COLORS.RESET}`;\n\n throw new Error(stripAnsi(errorMessage));\n }\n }\n\n /**\n * Returns the current library version string.\n * @returns Version identifier in semver format.\n */\n public getVersion(): string {\n return LIB_INFO.currentVersion;\n }\n\n /**\n * Returns detailed library metadata.\n * @returns Readonly object containing library information.\n */\n public getInfo(): Readonly<typeof LIB_INFO> {\n return LIB_INFO;\n }\n}\n\n/**\n * Placeholder entry point for framework initialization.\n * Intentionally throws error to prevent usage during development phase.\n * @throws Error indicating framework is not ready for use.\n */\nexport function initFramework(): never {\n const message = `${COLORS.RED}${COLORS.BRIGHT}[${LIB_INFO.name}] Initialization Blocked${COLORS.RESET}\\n` +\n `${COLORS.GRAY}Framework is undergoing complete architectural refactor.${COLORS.RESET}\\n` +\n `${COLORS.GRAY}Migration path: v${LIB_INFO.previousVersion} (CLI) -> v${LIB_INFO.currentVersion} (Framework)${COLORS.RESET}\\n` +\n `${COLORS.GRAY}Status: ${LIB_INFO.status}${COLORS.RESET}`;\n\n throw new Error(stripAnsi(message));\n}\n\n/**\n * Type guard to check if current version is stable.\n * @returns `false` if library is under construction, `true` otherwise.\n */\nexport function isStable(): boolean {\n return LIB_INFO.status !== LibraryStatus.UNDER_CONSTRUCTION;\n}\n\n/**\n * Throws an error if the library is not stable.\n * Use this at the start of your application to ensure you're not using an unstable version.\n * @throws Error when library is under construction.\n */\nexport function assertStable(): void {\n if (LIB_INFO.status === LibraryStatus.UNDER_CONSTRUCTION) {\n throw new Error(\n `[${LIB_INFO.name}] Cannot use unstable version ${LIB_INFO.currentVersion} in production. ` +\n `Status: ${LIB_INFO.status}`\n );\n }\n}\n\n// Immediate execution block: displays warning upon module import (only once)\n// Does not throw to allow type-checking and development workflows\nif (isDevelopmentVersion()) {\n // Trigger singleton instantiation which displays the warning\n LibStatus.getInstance();\n}"],"names":["LibraryStatus"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lib.cjs","sources":["../lib/errors/base.ts","../lib/errors/errors.ts","../lib/config/defaults.ts","../lib/browser/page-interactions.ts","../lib/utils/helpers.ts","../lib/browser/browser-manager.ts","../lib/utils/logger.ts","../lib/config/schema.ts","../lib/core/downloader.ts"],"sourcesContent":["export abstract class AppError extends Error {\n\tpublic readonly timestamp: string\n\tpublic readonly context: Record<string, unknown> | undefined\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly code: string,\n\t\tpublic readonly retryable: boolean = false,\n\t\tcontext?: Record<string, unknown>,\n\t) {\n\t\tsuper(message)\n\t\tthis.name = this.constructor.name\n\t\tthis.timestamp = new Date().toISOString()\n\t\tthis.context = context ? { ...context } : undefined\n\t\tError.captureStackTrace?.(this, this.constructor)\n\t}\n\ttoJSON() {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tmessage: this.message,\n\t\t\tcode: this.code,\n\t\t\tretryable: this.retryable,\n\t\t\ttimestamp: this.timestamp,\n\t\t\tcontext: this.context,\n\t\t}\n\t}\n}\n","import { AppError } from './base.js'\nexport class ValidationError extends AppError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'VALIDATION_ERROR', false, context)\n\t}\n}\nexport class NetworkError extends AppError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'NETWORK_ERROR', true, context)\n\t}\n}\nexport class FileError extends AppError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'FILE_ERROR', false, context)\n\t}\n}\nexport class BrowserError extends AppError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'BROWSER_ERROR', true, context)\n\t}\n}\n","export const DEFAULTS = {\n\tuserAgent:\n\t\t'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',\n\theadless: true,\n\ttimeout: 100000,\n\tdownloadButtonTimeout: 100000,\n\tfallbackWaitMs: 5000,\n}\n","import { Page } from 'playwright'\nimport { Logger } from '../utils/logger.js'\nimport { NetworkError } from '../errors/index.js'\nexport class SfilePageInteractions {\n\tconstructor(\n\t\tprivate page: Page,\n\t\tprivate logger: Logger,\n\t) {}\n\tasync waitForDownloadButton(timeout: number): Promise<void> {\n\t\tthis.logger.debug('Waiting for #download button to be visible')\n\t\tconst button = this.page.locator('#download')\n\t\tawait button.waitFor({ state: 'visible', timeout })\n\t\tthis.logger.debug(\n\t\t\t'Waiting for button to become active (href != \"#\" and pointerEvents != \"none\")',\n\t\t)\n\t\tawait this.page.waitForFunction(\n\t\t\t() => {\n\t\t\t\tconst btn = document.querySelector('#download') as HTMLAnchorElement | null\n\t\t\t\tif (!btn) return false\n\t\t\t\tconst href = btn.getAttribute('href')\n\t\t\t\tconst style = window.getComputedStyle(btn)\n\t\t\t\treturn href && href !== '#' && style.pointerEvents !== 'none'\n\t\t\t},\n\t\t\t{ timeout },\n\t\t)\n\t}\n\tasync extractIntermediateUrl(): Promise<string> {\n\t\tthis.logger.debug('Extracting href from #download')\n\t\tconst href = await this.page.$eval('#download', (el) => (el as HTMLAnchorElement).href)\n\t\tif (!href || href === '#') {\n\t\t\tthrow new NetworkError('Download button href is invalid', { href })\n\t\t}\n\t\treturn href\n\t}\n}\n","export function sanitizeFilename(name: string, replacement = '_'): string {\n\tconst sanitized = name\n\t\t.replace(/[<>:\"/\\\\|?*\\x00-\\x1F]/g, replacement)\n\t\t.replace(new RegExp(`${replacement}+`, 'g'), replacement)\n\t\t.trim()\n\t\t.slice(0, 255)\n\treturn sanitized || 'file.bin'\n}\nexport const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))\nexport function safeStringify(value: unknown): string {\n\ttry {\n\t\treturn JSON.stringify(value)\n\t} catch {\n\t\treturn '[unserializable]'\n\t}\n}\n","import { chromium, Browser, BrowserContext, Page, Download, Response } from 'playwright'\nimport * as fs from 'fs/promises'\nimport path from 'path'\nimport os from 'os'\nimport { Logger } from '../utils/logger.js'\nimport { BrowserError, NetworkError } from '../errors/index.js'\nimport { DEFAULTS } from '../config/defaults.js'\nimport { SfilePageInteractions } from './page-interactions.js'\nimport { sleep } from '../utils/helpers.js'\nexport interface BrowserManagerOptions {\n\theadless: boolean\n\tuserAgent: string\n\ttimeout: number\n\tdebug: boolean\n}\nexport class BrowserManager {\n\tprivate browser: Browser | null = null\n\tprivate context: BrowserContext | null = null\n\tprivate page: Page | null = null\n\tprivate interactions: SfilePageInteractions | null = null\n\tprivate debugDir: string | null = null\n\tconstructor(\n\t\tprivate logger: Logger,\n\t\tprivate opts: BrowserManagerOptions,\n\t) {}\n\tasync launch(): Promise<void> {\n\t\ttry {\n\t\t\tthis.logger.info('Launching browser', { headless: this.opts.headless })\n\t\t\tthis.browser = await chromium.launch({\n\t\t\t\theadless: this.opts.headless,\n\t\t\t\targs: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],\n\t\t\t})\n\t\t\tthis.context = await this.browser.newContext({\n\t\t\t\tuserAgent: this.opts.userAgent,\n\t\t\t\tacceptDownloads: true,\n\t\t\t\tlocale: 'en-US',\n\t\t\t})\n\t\t\tawait this.context.addCookies([\n\t\t\t\t{\n\t\t\t\t\tname: 'safe_link_counter',\n\t\t\t\t\tvalue: '1',\n\t\t\t\t\tdomain: '.sfile.co',\n\t\t\t\t\tpath: '/',\n\t\t\t\t\texpires: Math.floor(Date.now() / 1000) + 3600,\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.page = await this.context.newPage()\n\t\t\tthis.interactions = new SfilePageInteractions(this.page, this.logger)\n\t\t\tif (this.opts.debug) {\n\t\t\t\tthis.page.on('console', (msg) => {\n\t\t\t\t\tif (msg.type() === 'error') this.logger.error(`[console] ${msg.text()}`)\n\t\t\t\t\telse if (msg.type() === 'warning') this.logger.warn(`[console] ${msg.text()}`)\n\t\t\t\t})\n\t\t\t\tthis.page.on('pageerror', (err) => this.logger.error(`[pageerror] ${err.message}`))\n\t\t\t}\n\t\t\tthis.logger.info('Browser ready')\n\t\t} catch (err: any) {\n\t\t\tthrow new BrowserError(`Failed to launch browser: ${err.message}`)\n\t\t}\n\t}\n\tasync goto(\n\t\turl: string,\n\t\twaitUntil: 'load' | 'networkidle' | 'commit' = 'networkidle',\n\t): Promise<void> {\n\t\tif (!this.page) throw new BrowserError('Page not initialized')\n\t\ttry {\n\t\t\tthis.logger.debug(`Navigating to ${url} (waitUntil=${waitUntil})`)\n\t\t\tawait this.page.goto(url, { waitUntil, timeout: this.opts.timeout })\n\t\t} catch (err: any) {\n\t\t\tthrow new NetworkError(`Navigation failed: ${err.message}`, { url })\n\t\t}\n\t}\n\tasync waitForDownloadButton(): Promise<void> {\n\t\tif (!this.interactions) throw new BrowserError('Interactions not ready')\n\t\tawait this.interactions.waitForDownloadButton(DEFAULTS.downloadButtonTimeout)\n\t}\n\tasync getIntermediateUrl(): Promise<string> {\n\t\tif (!this.interactions) throw new BrowserError('Interactions not ready')\n\t\treturn this.interactions.extractIntermediateUrl()\n\t}\n\tasync startDownloadAndWait(autoUrl: string): Promise<Download | null> {\n\t\tif (!this.page) throw new BrowserError('Page not initialized')\n\t\tconst downloadPromise = this.page\n\t\t\t.waitForEvent('download', { timeout: this.opts.timeout })\n\t\t\t.catch((err) => {\n\t\t\t\tthis.logger.warn(`Download event wait failed: ${err.message}`)\n\t\t\t\treturn null\n\t\t\t})\n\t\tthis.logger.debug(`Navigating to auto URL: ${autoUrl}`)\n\t\tawait this.page.goto(autoUrl, { waitUntil: 'commit', timeout: this.opts.timeout })\n\t\tconst download = await downloadPromise\n\t\tif (download) {\n\t\t\tthis.logger.info('Download event captured')\n\t\t\treturn download\n\t\t}\n\t\treturn null\n\t}\n\tasync fallbackCollectFileResponse(): Promise<{ buffer: Buffer; filename: string } | null> {\n\t\tif (!this.page) throw new BrowserError('Page not initialized')\n\t\tthis.logger.warn('Falling back to response interception')\n\t\tconst responses: Response[] = []\n\t\tconst handler = (res: Response) => responses.push(res)\n\t\tthis.page.on('response', handler)\n\t\tawait sleep(DEFAULTS.fallbackWaitMs)\n\t\tthis.page.off('response', handler)\n\t\tconst fileResponse = [...responses].reverse().find((r) => {\n\t\t\tconst disposition = r.headers()['content-disposition']\n\t\t\treturn (\n\t\t\t\t(disposition && disposition.includes('attachment')) ||\n\t\t\t\tr.url().includes('/downloadfile/')\n\t\t\t)\n\t\t})\n\t\tif (!fileResponse) return null\n\t\tconst buffer = await fileResponse.body()\n\t\tlet filename = fileResponse.url().split('/').pop()?.split('?')[0] || 'file.bin'\n\t\tfilename = filename.replace(/[<>:\"/\\\\|?*]/g, '_')\n\t\treturn { buffer, filename }\n\t}\n\tasync saveDebugArtifacts(errorMessage: string): Promise<void> {\n\t\tif (!this.page) return\n\t\ttry {\n\t\t\tthis.debugDir = path.join(os.tmpdir(), `sfile_debug_${Date.now()}`)\n\t\t\tawait fs.mkdir(this.debugDir, { recursive: true })\n\t\t\tawait Promise.all([\n\t\t\t\tthis.page.screenshot({\n\t\t\t\t\tpath: path.join(this.debugDir, 'error.png'),\n\t\t\t\t\tfullPage: true,\n\t\t\t\t}),\n\t\t\t\tfs.writeFile(path.join(this.debugDir, 'error.html'), await this.page.content()),\n\t\t\t\tfs.writeFile(path.join(this.debugDir, 'error.txt'), errorMessage),\n\t\t\t])\n\t\t\tthis.logger.info(`Debug artifacts saved to ${this.debugDir}`)\n\t\t} catch (e: any) {\n\t\t\tthis.logger.error(`Failed to save debug artifacts: ${e.message}`)\n\t\t}\n\t}\n\tasync close(): Promise<void> {\n\t\tif (this.page) await this.page.close().catch(() => {})\n\t\tif (this.context) await this.context.close().catch(() => {})\n\t\tif (this.browser) await this.browser.close().catch(() => {})\n\t\tthis.logger.debug('Browser closed')\n\t}\n}\n","import { safeStringify } from './helpers.js'\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error'\nexport class Logger {\n\tprivate minLevel: LogLevel\n\tconstructor(debugMode = false) {\n\t\tthis.minLevel = debugMode ? 'debug' : 'info'\n\t}\n\tsetDebug(enabled: boolean) {\n\t\tthis.minLevel = enabled ? 'debug' : 'info'\n\t}\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\tconst levels: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 }\n\t\treturn levels[level] >= levels[this.minLevel]\n\t}\n\tprivate log(level: LogLevel, message: string, context?: any) {\n\t\tif (!this.shouldLog(level)) return\n\t\tconst ts = new Date().toISOString()\n\t\tconst ctx = context ? ` ${safeStringify(context)}` : ''\n\t\tconsole.log(`[${ts}] ${level.toUpperCase()}: ${message}${ctx}`)\n\t}\n\tdebug(msg: string, ctx?: any) {\n\t\tthis.log('debug', msg, ctx)\n\t}\n\tinfo(msg: string, ctx?: any) {\n\t\tthis.log('info', msg, ctx)\n\t}\n\twarn(msg: string, ctx?: any) {\n\t\tthis.log('warn', msg, ctx)\n\t}\n\terror(msg: string, ctx?: any) {\n\t\tthis.log('error', msg, ctx)\n\t}\n}\n","import { DEFAULTS } from './defaults.js'\nexport interface DownloadOptions {\n\theadless?: boolean\n\tdebug?: boolean\n\tuserAgent?: string\n\ttimeout?: number\n}\nexport interface DownloadResult {\n\tfilePath: string\n\tsize: number\n\tmethod: 'direct' | 'fallback'\n}\nexport function normalizeOptions(opts?: DownloadOptions) {\n\treturn {\n\t\theadless: opts?.headless ?? DEFAULTS.headless,\n\t\tdebug: opts?.debug ?? false,\n\t\tuserAgent: opts?.userAgent ?? DEFAULTS.userAgent,\n\t\ttimeout: opts?.timeout ?? DEFAULTS.timeout,\n\t}\n}\n","import path from 'path'\nimport fs from 'fs/promises'\nimport { BrowserManager } from '../browser/browser-manager.js'\nimport { Logger } from '../utils/logger.js'\nimport { ValidationError, NetworkError } from '../errors/index.js'\nimport { DownloadOptions, DownloadResult, normalizeOptions } from '../config/schema.js'\nimport { sanitizeFilename } from '../utils/helpers.js'\nexport async function downloadSfile(\n\turl: string,\n\tsaveDir: string,\n\toptions?: DownloadOptions,\n): Promise<DownloadResult> {\n\tconst opts = normalizeOptions(options)\n\tconst logger = new Logger(opts.debug)\n\tif (!url || !url.includes('sfile.co')) {\n\t\tthrow new ValidationError('URL must contain sfile.co', { url })\n\t}\n\tawait fs.mkdir(saveDir, { recursive: true })\n\tconst browserMgr = new BrowserManager(logger, {\n\t\theadless: opts.headless,\n\t\tuserAgent: opts.userAgent,\n\t\ttimeout: opts.timeout,\n\t\tdebug: opts.debug,\n\t})\n\ttry {\n\t\tawait browserMgr.launch()\n\t\tawait browserMgr.goto(url, 'networkidle')\n\t\tawait browserMgr.waitForDownloadButton()\n\t\tconst intermediateUrl = await browserMgr.getIntermediateUrl()\n\t\tconst autoUrl = intermediateUrl.includes('?')\n\t\t\t? `${intermediateUrl}&auto=1`\n\t\t\t: `${intermediateUrl}?auto=1`\n\t\tlet download = await browserMgr.startDownloadAndWait(autoUrl)\n\t\tlet finalPath: string\n\t\tlet fileSize: number\n\t\tlet method: 'direct' | 'fallback'\n\t\tif (download) {\n\t\t\tconst suggested = download.suggestedFilename() || 'file.bin'\n\t\t\tconst filename = sanitizeFilename(suggested)\n\t\t\tfinalPath = path.join(saveDir, filename)\n\t\t\tawait download.saveAs(finalPath)\n\t\t\tconst stat = await fs.stat(finalPath)\n\t\t\tfileSize = stat.size\n\t\t\tmethod = 'direct'\n\t\t\tlogger.info(`Saved via direct download: ${finalPath} (${fileSize} bytes)`)\n\t\t} else {\n\t\t\tconst fallback = await browserMgr.fallbackCollectFileResponse()\n\t\t\tif (!fallback) {\n\t\t\t\tthrow new NetworkError('No download event and no file response found')\n\t\t\t}\n\t\t\tconst { buffer, filename: rawName } = fallback\n\t\t\tconst filename = sanitizeFilename(rawName)\n\t\t\tfinalPath = path.join(saveDir, filename)\n\t\t\tawait fs.writeFile(finalPath, buffer)\n\t\t\tfileSize = buffer.length\n\t\t\tmethod = 'fallback'\n\t\t\tlogger.info(`Saved via fallback: ${finalPath} (${fileSize} bytes)`)\n\t\t}\n\t\treturn { filePath: finalPath, size: fileSize, method }\n\t} catch (err: any) {\n\t\tawait browserMgr.saveDebugArtifacts(err.message)\n\t\tthrow err\n\t} finally {\n\t\tawait browserMgr.close()\n\t}\n}\n"],"names":["chromium","path","os","fs"],"mappings":"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"}
|
package/build/lib.d.ts
CHANGED
|
@@ -1,29 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
interface DownloadOptions {
|
|
2
|
+
headless?: boolean;
|
|
3
|
+
debug?: boolean;
|
|
4
|
+
userAgent?: string;
|
|
5
|
+
timeout?: number;
|
|
5
6
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
readonly status: LibraryStatus.UNDER_CONSTRUCTION;
|
|
11
|
-
readonly isDeprecated: true;
|
|
12
|
-
readonly message: "This version represents a complete architectural refactor from CLI to framework. Not stable.";
|
|
13
|
-
};
|
|
14
|
-
declare function isDevelopmentVersion(): boolean;
|
|
15
|
-
declare class LibStatus {
|
|
16
|
-
private static instance;
|
|
17
|
-
private constructor();
|
|
18
|
-
static getInstance(): LibStatus;
|
|
19
|
-
private displayDeveloperWarning;
|
|
20
|
-
suppressWarning(): void;
|
|
21
|
-
ensureStable(): void;
|
|
22
|
-
getVersion(): string;
|
|
23
|
-
getInfo(): Readonly<typeof LIB_INFO>;
|
|
7
|
+
interface DownloadResult {
|
|
8
|
+
filePath: string;
|
|
9
|
+
size: number;
|
|
10
|
+
method: 'direct' | 'fallback';
|
|
24
11
|
}
|
|
25
|
-
declare function initFramework(): never;
|
|
26
|
-
declare function isStable(): boolean;
|
|
27
|
-
declare function assertStable(): void;
|
|
28
12
|
|
|
29
|
-
|
|
13
|
+
declare function downloadSfile(url: string, saveDir: string, options?: DownloadOptions): Promise<DownloadResult>;
|
|
14
|
+
|
|
15
|
+
declare abstract class AppError extends Error {
|
|
16
|
+
readonly code: string;
|
|
17
|
+
readonly retryable: boolean;
|
|
18
|
+
readonly timestamp: string;
|
|
19
|
+
readonly context: Record<string, unknown> | undefined;
|
|
20
|
+
constructor(message: string, code: string, retryable?: boolean, context?: Record<string, unknown>);
|
|
21
|
+
toJSON(): {
|
|
22
|
+
name: string;
|
|
23
|
+
message: string;
|
|
24
|
+
code: string;
|
|
25
|
+
retryable: boolean;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
context: Record<string, unknown> | undefined;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare class ValidationError extends AppError {
|
|
32
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
33
|
+
}
|
|
34
|
+
declare class NetworkError extends AppError {
|
|
35
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
36
|
+
}
|
|
37
|
+
declare class FileError extends AppError {
|
|
38
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
39
|
+
}
|
|
40
|
+
declare class BrowserError extends AppError {
|
|
41
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { AppError, BrowserError, FileError, NetworkError, ValidationError, downloadSfile };
|
|
45
|
+
export type { DownloadOptions, DownloadResult };
|