single-file-cli 2.0.45 → 2.0.47
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.sh +1 -1
- package/deno.json +1 -1
- package/lib/deno-polyfill.js +30 -3
- package/lib/single-file-bundle.js +1 -1
- package/lib/version.js +1 -1
- package/options.js +1 -0
- package/package.json +1 -1
- package/single-file-cli-api.js +33 -30
package/lib/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "2.0.
|
|
1
|
+
export const version = "2.0.47";
|
package/options.js
CHANGED
|
@@ -81,6 +81,7 @@ const OPTIONS_INFO = {
|
|
|
81
81
|
"dump-content": { description: "Dump the content of the processed page in the console ('true' when running in Docker)", type: "boolean" },
|
|
82
82
|
"emulate-media-feature": { description: "Emulate a media feature. The syntax is <name>:<value>, e.g. \"prefers-color-scheme:dark\"", type: "string[]" },
|
|
83
83
|
"error-file": { description: "Path of the file where to save the error messages", type: "string" },
|
|
84
|
+
"error-traces-disabled": { description: "Remove error stack traces in the error messages", type: "boolean", defaultValue: true },
|
|
84
85
|
"filename-template": { description: "Template used to generate the output filename (see help page of the extension for more info)", type: "string", defaultValue: "%if-empty<{page-title}|No title> ({date-locale} {time-locale}).{filename-extension}" },
|
|
85
86
|
"filename-conflict-action": { description: "Action when the filename is conflicting with existing one on the filesystem. The possible values are \"uniquify\" (default), \"overwrite\" and \"skip\"", type: "string", defaultValue: "uniquify" },
|
|
86
87
|
"filename-replacement-character": { description: "The character used for replacing invalid characters in filenames", type: "string", defaultValue: "_" },
|
package/package.json
CHANGED
package/single-file-cli-api.js
CHANGED
|
@@ -101,7 +101,7 @@ async function initialize(options) {
|
|
|
101
101
|
async function capture(urls, options) {
|
|
102
102
|
let newTasks;
|
|
103
103
|
const taskUrls = tasks.map(task => task.url);
|
|
104
|
-
newTasks = urls.map(url => createTask(url, options));
|
|
104
|
+
newTasks = await Promise.all(urls.map(url => createTask(url, options)));
|
|
105
105
|
newTasks = newTasks.filter(task => task && !taskUrls.includes(task.url));
|
|
106
106
|
if (newTasks.length) {
|
|
107
107
|
tasks = tasks.concat(newTasks);
|
|
@@ -161,13 +161,13 @@ async function runNextTask() {
|
|
|
161
161
|
if (pageData) {
|
|
162
162
|
task.filename = pageData.filename;
|
|
163
163
|
if (options.crawlLinks && testMaxDepth(task)) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
const urls = pageData.links;
|
|
165
|
+
let newTasks = await Promise.all(urls.map(url => createTask(url, options, task, tasks[0])));
|
|
166
|
+
newTasks = newTasks.filter(task => task &&
|
|
167
|
+
testMaxDepth(task) &&
|
|
168
|
+
!tasks.find(otherTask => otherTask.url == task.url) &&
|
|
169
|
+
(!options.crawlInnerLinksOnly || task.isInnerLink) &&
|
|
170
|
+
(!options.crawlNoParent || (task.isChild || !task.isInnerLink)));
|
|
171
171
|
tasks.splice(tasks.length, 0, ...newTasks);
|
|
172
172
|
}
|
|
173
173
|
}
|
|
@@ -182,30 +182,33 @@ function testMaxDepth(task) {
|
|
|
182
182
|
(options.crawlExternalLinksMaxDepth == 0 || task.externalLinkDepth < options.crawlExternalLinksMaxDepth);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
function createTask(url, options, parentTask, rootTask) {
|
|
185
|
+
async function createTask(url, options, parentTask, rootTask) {
|
|
186
186
|
url = parentTask ? rewriteURL(url, options.crawlRemoveURLFragment, options.crawlRewriteRules) : url;
|
|
187
|
-
if (
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
if (url) {
|
|
188
|
+
if (!VALID_URL_TEST.test(url)) {
|
|
189
|
+
try {
|
|
190
|
+
url = url.replace(/\\/g, "/");
|
|
191
|
+
url = url.replace(/#/g, "%23");
|
|
192
|
+
const baseURL = await path.toFileUrl((await Deno.cwd()) + path.SEPARATOR);
|
|
193
|
+
url = new URL(url, baseURL).href;
|
|
194
|
+
} catch (error) {
|
|
195
|
+
throw new Error("Invalid URL or file path: " + url, { cause: error });
|
|
196
|
+
}
|
|
194
197
|
}
|
|
198
|
+
const isInnerLink = rootTask && url.startsWith(getHostURL(rootTask.url));
|
|
199
|
+
const rootBaseURIMatch = rootTask && rootTask.url.match(/(.*?)[^/]*$/);
|
|
200
|
+
const isChild = isInnerLink && rootBaseURIMatch && rootBaseURIMatch[1] && url.startsWith(rootBaseURIMatch[1]);
|
|
201
|
+
return {
|
|
202
|
+
url,
|
|
203
|
+
isInnerLink,
|
|
204
|
+
isChild,
|
|
205
|
+
originalUrl: url,
|
|
206
|
+
rootBaseURI: rootBaseURIMatch && rootBaseURIMatch[1],
|
|
207
|
+
depth: parentTask ? parentTask.depth + 1 : 0,
|
|
208
|
+
externalLinkDepth: isInnerLink ? -1 : parentTask ? parentTask.externalLinkDepth + 1 : -1,
|
|
209
|
+
options
|
|
210
|
+
};
|
|
195
211
|
}
|
|
196
|
-
const isInnerLink = rootTask && url.startsWith(getHostURL(rootTask.url));
|
|
197
|
-
const rootBaseURIMatch = rootTask && rootTask.url.match(/(.*?)[^/]*$/);
|
|
198
|
-
const isChild = isInnerLink && rootBaseURIMatch && rootBaseURIMatch[1] && url.startsWith(rootBaseURIMatch[1]);
|
|
199
|
-
return {
|
|
200
|
-
url,
|
|
201
|
-
isInnerLink,
|
|
202
|
-
isChild,
|
|
203
|
-
originalUrl: url,
|
|
204
|
-
rootBaseURI: rootBaseURIMatch && rootBaseURIMatch[1],
|
|
205
|
-
depth: parentTask ? parentTask.depth + 1 : 0,
|
|
206
|
-
externalLinkDepth: isInnerLink ? -1 : parentTask ? parentTask.externalLinkDepth + 1 : -1,
|
|
207
|
-
options
|
|
208
|
-
};
|
|
209
212
|
}
|
|
210
213
|
|
|
211
214
|
async function saveTasks() {
|
|
@@ -268,7 +271,7 @@ async function capturePage(options) {
|
|
|
268
271
|
}
|
|
269
272
|
return pageData;
|
|
270
273
|
} catch (error) {
|
|
271
|
-
const message = "URL: " + options.url + "\nStack: " + error.stack + "\n";
|
|
274
|
+
const message = "URL: " + options.url + (options.errorTracesDisabled ? "" : "\nStack: " + error.stack) + "\n";
|
|
272
275
|
if (options.errorFile) {
|
|
273
276
|
await writeTextFile(options.errorFile, message, { append: true });
|
|
274
277
|
} else {
|