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/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const version = "2.0.45";
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-cli",
3
- "version": "2.0.45",
3
+ "version": "2.0.47",
4
4
  "description": "SingleFile CLI",
5
5
  "author": "Gildas Lormeau",
6
6
  "engines": {
@@ -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
- let newTasks = pageData.links
165
- .map(urlLink => createTask(urlLink, options, task, tasks[0]))
166
- .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)));
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 (!VALID_URL_TEST.test(url)) {
188
- try {
189
- url = url.replace(/\\/g, "/");
190
- url = url.replace(/#/g, "%23");
191
- url = new URL(url, import.meta.url).href;
192
- } catch (error) {
193
- throw new Error("Invalid URL or file path: " + url);
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 {