@pi-r/chrome 0.7.2 → 0.8.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/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  const path = require("path");
3
3
  const fs = require("fs");
4
- const asset_1 = require("@e-mc/document/asset");
5
- const util_1 = require("@e-mc/document/util");
6
- const types_1 = require("@e-mc/types");
4
+ const crypto_1 = require("crypto");
7
5
  const core_1 = require("@e-mc/core");
8
6
  const Cloud = require("@e-mc/cloud");
7
+ const types_1 = require("@e-mc/types");
8
+ const asset_1 = require("@e-mc/document/asset");
9
+ const util_1 = require("@e-mc/document/util");
9
10
  const dom_1 = require("@e-mc/document/parse/dom");
10
11
  const transform_1 = require("@e-mc/document/transform");
11
12
  const Document = require('@e-mc/document');
@@ -14,6 +15,8 @@ const CACHE_LOCALFILE = new Map();
14
15
  const CACHE_QUERY = new Map();
15
16
  const CACHE_SELECTOR = new Map();
16
17
  const CACHE_ETAG = new Map();
18
+ const CACHE_CONTENT = new Map();
19
+ const CACHE_FORMAT = new Map();
17
20
  const CACHE_DATASET = {};
18
21
  const CACHE_ATRULES = {};
19
22
  let CACHE_TOTAL = 0;
@@ -30,10 +33,10 @@ const [REGEXP_NTHCHILD, REGEXP_NTHCHILD_UNSAFE, REGEXP_REPLACECSS] = (function (
30
33
  ];
31
34
  })();
32
35
  const REGEXP_SRCSETSIZE = /~\s*([\d.]+)\s*([wx])/i;
33
- const REGEXP_TEMPLATECONDITIONAL = /(\n\s+)?\{\{if\s+((?:[^}]|}(?!}))+?)\}\}(\s*)([\S\s]*?)(?:\s*\{\{else(?:\s+if\s+((?:[^}]|}(?!}))+?))?\}\}(\s*)([\S\s]*?)\s*)?\s*\{\{end\}\}/g;
36
+ const REGEXP_TEMPLATECONDITIONAL = /(\n\s+)?\{\{if\s+((?:[^}]|}(?!}))+?)\}\}(\s*)(.*?)(?:\s*\{\{else(?:\s+if\s+((?:[^}]|}(?!}))+?))?\}\}(\s*)(.*?)\s*)?\s*\{\{end\}\}/gs;
34
37
  const REGEXP_TEMPLATECOMPARISON = /\s*\(\s*(?:\b(eq|ne|lt|le|gt|ge)\s+)?("[^"]+"|'[^']+'|[^\s)]+)(?:\s+("[^"]+"|'[^']+'|[^\s)]+))?\s*\)/g;
35
38
  const REGEXP_TEMPLATEMATCH = new RegExp(`^(?:\\b(and|or|not)\\s+)?((?:${REGEXP_TEMPLATECOMPARISON.source})+)|(!|not\\s+)?([^\\s][\\S\\s]*)$`);
36
- const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')|.+?from\s+("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(?:[ \t]+assert[ \t]+\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\})?)|\bimport\(\s*("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*(?:,\s*\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\}\s*)?\))/g;
39
+ const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')|.+?from\s+("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(?:[ \t]+assert[ \t]+\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\})?)|\bimport\(\s*("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*(?:,\s*\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\}\s*)?\))/gd;
37
40
  const REGEXP_BLOCKEXCLUDE = new RegExp(`(\\s*)<!--\\s*exclude\\s*:\\s*(?:start|end)\\s*-->` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
38
41
  const REGEXP_COMMENT = new RegExp(dom_1.DomWriter.PATTERN_COMMENT, 'g');
39
42
  const REGEXP_QUOTEDVALUE = new RegExp(`\\b(?:@import${PATTERN_STRING_MANY}|content${PATTERN_STRING_SOME}:${PATTERN_STRING_SOME})(?:"[^"]*"|'[^']*')`, 'gi');
@@ -56,7 +59,8 @@ const REGEXP_URL = /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*
56
59
  const REGEXP_URL_JS = /\bimport\(/g;
57
60
  const REGEXP_URL_SVG = /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g;
58
61
  const REGEXP_IMAGESET = /\b(?:-webkit-)?image-set\(/gi;
59
- const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/g;
62
+ const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/gd;
63
+ const REGEXP_SANITIZEALL = new RegExp(`(?:\\s+|\\b)data-(?:pathname|filename|intl-locales|(?:use|exclude)-[^=\\s]+)\\s*${dom_1.DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g');
60
64
  function removeNamespace(name, source, newline, comments) {
61
65
  if (source.includes('-' + name)) {
62
66
  const [a, b, c, d, e] = CACHE_DATASET[name] ||= [
@@ -166,7 +170,9 @@ function addCacheItem(map, key, data, timeout) {
166
170
  map.set(key, [
167
171
  Date.now(),
168
172
  data,
169
- setTimeout(() => deleteCacheItem(map, key), timeout * 1000)
173
+ setTimeout(() => {
174
+ deleteCacheItem(map, key);
175
+ }, timeout * 1000)
170
176
  ]);
171
177
  }
172
178
  function deleteCacheItem(map, key) {
@@ -181,8 +187,17 @@ function spliceSource(source, startIndex, endIndex, pattern, leading = '', trail
181
187
  if (leading || trailing) {
182
188
  content += getNewlineString(leading, trailing);
183
189
  }
184
- pattern.lastIndex = startIndex + content.length;
185
- return spliceString(source, startIndex, endIndex, content);
190
+ return (0, util_1.spliceString)(source, startIndex, endIndex, content, pattern);
191
+ }
192
+ function parseArg(data, value) {
193
+ if (!isNaN(+value)) {
194
+ return +value;
195
+ }
196
+ const match = /^(["'])(.*)\1$/s.exec(value);
197
+ if (match) {
198
+ return match[2];
199
+ }
200
+ return getObjectValue(data, value);
186
201
  }
187
202
  function hasCondition(data, condition) {
188
203
  if (!condition) {
@@ -195,7 +210,7 @@ function hasCondition(data, condition) {
195
210
  const join = match[1];
196
211
  const items = [];
197
212
  while (match = REGEXP_TEMPLATECOMPARISON.exec(comparison)) {
198
- if (items.length && !isSpace(match[0][0])) {
213
+ if (items.length > 0 && !isSpace(match[0][0])) {
199
214
  return false;
200
215
  }
201
216
  items.push([match[1], match[2], match[3]]);
@@ -205,15 +220,6 @@ function hasCondition(data, condition) {
205
220
  if (length > 1 && !join) {
206
221
  return false;
207
222
  }
208
- const parseArg = (value) => {
209
- if (!isNaN(+value)) {
210
- return +value;
211
- }
212
- if (match = /^(["'])([\S\s]*)\1$/.exec(value)) {
213
- return match[2];
214
- }
215
- return getObjectValue(data, value);
216
- };
217
223
  for (let i = 0; i < length; ++i) {
218
224
  const item = items[i];
219
225
  const arg1 = item[1];
@@ -222,22 +228,22 @@ function hasCondition(data, condition) {
222
228
  if (arg2) {
223
229
  switch (item[0]) {
224
230
  case 'eq':
225
- valid = parseArg(arg1) == parseArg(arg2);
231
+ valid = parseArg(data, arg1) == parseArg(data, arg2);
226
232
  break;
227
233
  case 'ne':
228
- valid = parseArg(arg1) != parseArg(arg2);
234
+ valid = parseArg(data, arg1) != parseArg(data, arg2);
229
235
  break;
230
236
  case 'lt':
231
- valid = parseArg(arg1) < parseArg(arg2);
237
+ valid = parseArg(data, arg1) < parseArg(data, arg2);
232
238
  break;
233
239
  case 'le':
234
- valid = parseArg(arg1) <= parseArg(arg2);
240
+ valid = parseArg(data, arg1) <= parseArg(data, arg2);
235
241
  break;
236
242
  case 'gt':
237
- valid = parseArg(arg1) > parseArg(arg2);
243
+ valid = parseArg(data, arg1) > parseArg(data, arg2);
238
244
  break;
239
245
  case 'ge':
240
- valid = parseArg(arg1) >= parseArg(arg2);
246
+ valid = parseArg(data, arg1) >= parseArg(data, arg2);
241
247
  break;
242
248
  default:
243
249
  return false;
@@ -298,7 +304,11 @@ function hasSameOrigin(value, ...other) {
298
304
  function restoreSearchParams(value, prefix = '__sqd') {
299
305
  if (value?.includes(prefix)) {
300
306
  const params = new URLSearchParams(value);
301
- params.forEach((_, key) => key.startsWith(prefix) && params.delete(key));
307
+ params.forEach((_, key) => {
308
+ if (key.startsWith(prefix)) {
309
+ params.delete(key);
310
+ }
311
+ });
302
312
  if (value = params.toString()) {
303
313
  return '?' + value;
304
314
  }
@@ -307,7 +317,7 @@ function restoreSearchParams(value, prefix = '__sqd') {
307
317
  }
308
318
  function getBaseURLs(asset, baseUrl) {
309
319
  const result = [];
310
- let parentUrl = asset ? asset.url || asset.uri : undefined;
320
+ let parentUrl = asset ? asset.url || asset.uri : null;
311
321
  try {
312
322
  if (parentUrl) {
313
323
  if (typeof parentUrl === 'string') {
@@ -318,15 +328,18 @@ function getBaseURLs(asset, baseUrl) {
318
328
  }
319
329
  }
320
330
  catch {
321
- parentUrl = undefined;
331
+ parentUrl = null;
322
332
  }
323
333
  if (baseUrl) {
324
334
  const url = new URL(baseUrl);
325
335
  if (!parentUrl) {
326
336
  result.push(parentUrl = url);
327
337
  }
328
- else if (parentUrl.origin !== url.origin) {
329
- result.push(new URL(parentUrl.href.replace(parentUrl.origin, url.origin)), url);
338
+ else {
339
+ const { href, origin } = parentUrl;
340
+ if (origin !== url.origin) {
341
+ result.push(new URL(href.replace(origin, url.origin)), url);
342
+ }
330
343
  }
331
344
  }
332
345
  return result;
@@ -338,7 +351,7 @@ function createHash(host, file, hash, bufferMap) {
338
351
  if (buffer) {
339
352
  const [algorithm, length] = (0, util_1.getHashData)(hash);
340
353
  let value;
341
- if (algorithm && (value = Document.asHash(buffer, { algorithm, encoding: file.encoding }))) {
354
+ if (algorithm && (value = Document.asHash(buffer, algorithm, { encoding: file.encoding }))) {
342
355
  if (localUri) {
343
356
  bufferMap[localUri] = buffer;
344
357
  }
@@ -352,8 +365,8 @@ function createHash(host, file, hash, bufferMap) {
352
365
  host.writeFail(["Unable to read file", filename], err, 32);
353
366
  }
354
367
  }
355
- function getSrcURL(parent, file) {
356
- const relativeUrl = file.relativeUrl || this.host.removeCwd(file.localUri) && getRelativeURL(file);
368
+ function getSrcURL(instance, parent, file) {
369
+ const relativeUrl = file.relativeUrl || instance.host.removeCwd(file.localUri) && getRelativeURL(file);
357
370
  if (!relativeUrl) {
358
371
  return [''];
359
372
  }
@@ -361,12 +374,12 @@ function getSrcURL(parent, file) {
361
374
  return [relativeUrl];
362
375
  }
363
376
  let parentDir = parent.pathname, assetDir = file.pathname;
364
- if (!this.productionRelease) {
377
+ if (!instance.productionRelease) {
365
378
  if (parent.moveTo) {
366
- parentDir = joinPath(parent.moveTo, parentDir);
379
+ parentDir = Document.joinPath(parent.moveTo, parentDir);
367
380
  }
368
381
  if (file.moveTo) {
369
- assetDir = joinPath(file.moveTo, assetDir);
382
+ assetDir = Document.joinPath(file.moveTo, assetDir);
370
383
  }
371
384
  }
372
385
  if (parentDir === assetDir) {
@@ -376,16 +389,16 @@ function getSrcURL(parent, file) {
376
389
  const prefix = splitPath(parentDir);
377
390
  const suffix = splitPath(assetDir);
378
391
  let found;
379
- while (prefix.length && suffix.length && prefix[0] === suffix[0]) {
392
+ while (prefix.length > 0 && suffix.length > 0 && prefix[0] === suffix[0]) {
380
393
  prefix.shift();
381
394
  suffix.shift();
382
395
  found = true;
383
396
  }
384
- return [found ? joinPath('../'.repeat(prefix.length), suffix.join('/'), file.filename) : '../'.repeat(prefix.length) + relativeUrl];
397
+ return [found ? Document.joinPath('../'.repeat(prefix.length), suffix.join('/'), file.filename) : '../'.repeat(prefix.length) + relativeUrl];
385
398
  }
386
- function transformURL(host, parent, type, source, importFile) {
399
+ function transformURL(instance, host, parent, type, source, importFile) {
387
400
  const related = [];
388
- const baseHref = getBaseURLs(importFile || parent, this.baseUrl);
401
+ const baseHref = getBaseURLs(importFile || parent, instance.baseUrl);
389
402
  const isHtml = type === 'html';
390
403
  const isJs = type === 'js';
391
404
  const pattern = isJs ? REGEXP_URL_JS : type === 'svg' ? REGEXP_URL_SVG : REGEXP_URL;
@@ -399,15 +412,15 @@ function transformURL(host, parent, type, source, importFile) {
399
412
  continue;
400
413
  }
401
414
  REGEXP_IMAGESET_URL.lastIndex = 0;
402
- const original = source.substring(startIndex, endIndex);
403
- let content = original, url;
404
- while (url = REGEXP_IMAGESET_URL.exec(original)) {
415
+ let content = source.substring(startIndex, endIndex), url;
416
+ while (url = REGEXP_IMAGESET_URL.exec(content)) {
405
417
  const quote = url[2] ? '"' : "'";
406
- content = content.replace(url[1], `url(${quote + (url[2] || url[3]).trim() + quote})`);
418
+ const [a, b] = url.indices[1];
419
+ content = (0, util_1.spliceString)(content, a, b, `url(${quote + (url[2] || url[3]).trim() + quote})`, REGEXP_IMAGESET_URL);
407
420
  modified = true;
408
421
  }
409
422
  if (modified) {
410
- source = spliceString(source, startIndex, REGEXP_IMAGESET.lastIndex = endIndex, content);
423
+ source = (0, util_1.spliceString)(source, startIndex, endIndex, content, REGEXP_IMAGESET);
411
424
  modified = false;
412
425
  }
413
426
  }
@@ -476,12 +489,12 @@ function transformURL(host, parent, type, source, importFile) {
476
489
  if (asset) {
477
490
  if (!asset.inlineBase64) {
478
491
  if (host.Cloud?.getStorage('upload', asset.cloudStorage)) {
479
- const inlineUrlCloud = asset.inlineUrlCloud ||= (0, types_1.generateUUID)();
492
+ const inlineUrlCloud = asset.inlineUrlCloud ||= (0, crypto_1.randomUUID)();
480
493
  (parent.inlineUrlCloudMap ||= {})[inlineUrlCloud] = value;
481
494
  value = inlineUrlCloud;
482
495
  }
483
- else if (asset.hash && this.productionRelease) {
484
- const inlineUrl = asset.inlineUrl ||= (0, types_1.generateUUID)();
496
+ else if (asset.hash && instance.productionRelease) {
497
+ const inlineUrl = asset.inlineUrl ||= (0, crypto_1.randomUUID)();
485
498
  (parent.inlineUrlMap ||= {})[inlineUrl] = value;
486
499
  value = inlineUrl;
487
500
  }
@@ -533,9 +546,8 @@ function transformURL(host, parent, type, source, importFile) {
533
546
  value = quote + value + quote;
534
547
  }
535
548
  const revised = isJs ? 'import(' + value + trailing + ')' : isHref ? 'href=' + value : (isText ? '@import ' + value : `url(${value})`) + trailing;
536
- source = spliceString(source, startIndex, i + 1, revised);
549
+ source = (0, util_1.spliceString)(source, startIndex, i + 1, revised, pattern);
537
550
  length = source.length;
538
- pattern.lastIndex = startIndex + revised.length;
539
551
  modified = true;
540
552
  };
541
553
  let url;
@@ -558,18 +570,18 @@ function transformURL(host, parent, type, source, importFile) {
558
570
  if (url.startsWith('data:')) {
559
571
  const base64 = url.split(',')[1]?.trim();
560
572
  if (base64) {
561
- for (const item of this.assets) {
573
+ for (const item of instance.assets) {
562
574
  if (item.base64 === base64) {
563
- setOutputURL(getSrcURL.call(this, parent, item)[0], item);
575
+ setOutputURL(getSrcURL(instance, parent, item)[0], item);
564
576
  break;
565
577
  }
566
578
  }
567
579
  }
568
580
  }
569
- else if (baseHref.length) {
581
+ else if (baseHref.length > 0) {
570
582
  let fullUrl, asset;
571
583
  for (const parentUrl of baseHref) {
572
- if (asset = host.findAsset(fullUrl = resolvePath(url, parentUrl), { replaced: true }) || (this.related.has(parent) ? host.findAsset(fullUrl, { assets: Array.from(this.related.get(parent)), replaced: true }) : undefined)) {
584
+ if (asset = host.findAsset(fullUrl = Document.resolvePath(url, parentUrl), { replaced: true }) || (instance.related.has(parent) ? host.findAsset(fullUrl, { assets: Array.from(instance.related.get(parent)), replaced: true }) : undefined)) {
573
585
  break;
574
586
  }
575
587
  }
@@ -593,13 +605,13 @@ function transformURL(host, parent, type, source, importFile) {
593
605
  break;
594
606
  }
595
607
  }
596
- const layer = this.replaceContent(revised, source.substring(k, l + 1), 'text/css');
608
+ const layer = instance.replaceContent(revised, source.substring(k, l + 1), "text/css");
597
609
  if (layer) {
598
610
  revised = layer;
599
611
  }
600
- source = spliceString(source, k, l + 1, revised = transformURL.call(this, host, parent, type, this.removeServerRoot(revised), asset) || revised);
612
+ revised = transformURL(instance, host, parent, type, instance.removeServerRoot(revised), asset) || revised;
613
+ source = (0, util_1.spliceString)(source, k, l + 1, revised, pattern);
601
614
  length = source.length;
602
- pattern.lastIndex = k + revised.length;
603
615
  if (!parent.watch) {
604
616
  host.deleteFile(asset.localUri, { ignorePermission: true, emptyDir: true, all: true, id: asset.id });
605
617
  asset.invalid = true;
@@ -616,7 +628,7 @@ function transformURL(host, parent, type, source, importFile) {
616
628
  }
617
629
  if (hasSameOrigin(asset.url || fullUrl, ...baseHref)) {
618
630
  let sameDir;
619
- [fullUrl, sameDir] = getSrcURL.call(this, parent, asset);
631
+ [fullUrl, sameDir] = getSrcURL(instance, parent, asset);
620
632
  if (sameDir && isJs) {
621
633
  fullUrl = './' + fullUrl;
622
634
  }
@@ -628,7 +640,7 @@ function transformURL(host, parent, type, source, importFile) {
628
640
  }
629
641
  }
630
642
  else if (!asset.invalid) {
631
- fullUrl = asset.inlineBase64 ||= (0, types_1.generateUUID)();
643
+ fullUrl = asset.inlineBase64 ||= (0, crypto_1.randomUUID)();
632
644
  }
633
645
  if (url !== fullUrl) {
634
646
  setOutputURL(fullUrl, asset);
@@ -640,34 +652,33 @@ function transformURL(host, parent, type, source, importFile) {
640
652
  }
641
653
  }
642
654
  if (modified) {
643
- if (related.length) {
644
- const previous = this.related.get(parent);
655
+ if (related.length > 0) {
656
+ const previous = instance.related.get(parent);
645
657
  if (previous) {
646
- related.forEach(item => previous.add(item));
658
+ for (const item of related) {
659
+ previous.add(item);
660
+ }
647
661
  }
648
662
  else {
649
- this.related.set(parent, new Set(related));
663
+ instance.related.set(parent, new Set(related));
650
664
  }
651
665
  }
652
666
  return source;
653
667
  }
654
668
  }
655
- function getFormatUUID(attr, ext) {
656
- const format = 'formatMap' in this ? this.formatMap : this.module.format;
669
+ function getFormatUUID(instance, attr, ext) {
670
+ const format = 'formatMap' in instance ? instance.formatMap : instance.module.format;
657
671
  let pattern;
658
- if ((0, types_1.isObject)(format) && (0, types_1.isObject)(pattern = ext && ext in format ? format[ext] : format.uuid) && pattern[attr]) {
659
- return (0, types_1.randomString)(pattern[attr], pattern.dictionary);
660
- }
661
- return (0, types_1.generateUUID)();
672
+ return (0, types_1.isObject)(format) && (0, types_1.isObject)(pattern = ext && ext in format ? format[ext] : format.uuid) && pattern[attr] ? (0, types_1.randomString)(pattern[attr], pattern.dictionary) : (0, crypto_1.randomUUID)();
662
673
  }
663
- function setLocationUUID(data, file, ext) {
674
+ function setLocationUUID(instance, data, file, ext) {
664
675
  const { pathname, filename } = data;
665
676
  const assignUUID = ChromeDocument.INTERNAL_ASSIGNUUID;
666
677
  let index, modified;
667
678
  if (filename) {
668
679
  ext ||= path.extname(filename).substring(1);
669
680
  if ((index = filename.indexOf(assignUUID)) !== -1) {
670
- data.filename = spliceString(filename, index, index + assignUUID.length, getFormatUUID.call(this, 'filename', ext));
681
+ data.filename = (0, util_1.spliceString)(filename, index, index + assignUUID.length, getFormatUUID(instance, 'filename', ext));
671
682
  if (file) {
672
683
  file.inlineFilename = data.filename;
673
684
  }
@@ -675,7 +686,7 @@ function setLocationUUID(data, file, ext) {
675
686
  }
676
687
  }
677
688
  if (pathname && (index = pathname.indexOf(assignUUID)) !== -1) {
678
- data.pathname = spliceString(pathname, index, index + assignUUID.length, getFormatUUID.call(this, 'pathname', ext));
689
+ data.pathname = (0, util_1.spliceString)(pathname, index, index + assignUUID.length, getFormatUUID(instance, 'pathname', ext));
679
690
  modified = true;
680
691
  }
681
692
  if (file && modified) {
@@ -685,14 +696,14 @@ function setLocationUUID(data, file, ext) {
685
696
  }
686
697
  }
687
698
  }
688
- function transformOptions(file, mimeType, code, bundleContent) {
699
+ function transformOptions(instance, file, mimeType, code, bundleContent) {
689
700
  const { uri, localUri, exported } = file;
690
- const metadata = { userAgentData: this.userAgentData };
701
+ const metadata = { userAgentData: instance.userAgentData };
691
702
  switch (mimeType) {
692
- case 'text/html':
703
+ case "text/html":
693
704
  metadata.__fromhtml__ = true;
694
- case 'text/css':
695
- Object.assign(metadata, this.config);
705
+ case "text/css":
706
+ Object.assign(metadata, instance.config);
696
707
  default:
697
708
  if ((0, types_1.isObject)(file.metadata)) {
698
709
  Object.assign(metadata, file.metadata);
@@ -701,35 +712,35 @@ function transformOptions(file, mimeType, code, bundleContent) {
701
712
  }
702
713
  const [pathname, filename] = localUri ? [path.dirname(localUri), path.basename(localUri)] : ['', file.filename];
703
714
  const options = { pathname, filename, mimeType, metadata, imported: !!file.imports && file.imported !== false };
704
- const sourceFile = !exported && uri && this.findSourceRoot(uri);
715
+ const sourceFile = !exported && uri && instance.findSourceRoot(uri);
705
716
  if (sourceFile) {
706
- if (isPath(sourceFile)) {
717
+ if (Document.isPath(sourceFile)) {
707
718
  options.sourceFile = sourceFile;
708
719
  }
709
720
  options.sourceName = path.basename(sourceFile);
710
721
  options.sourcesRelativeTo = path.dirname(sourceFile);
711
- options.getMainFile = this.resolveSourceFile(file);
722
+ options.getMainFile = instance.resolveSourceFile(file);
712
723
  if (code) {
713
- options.getSourceFiles = this.locateSourceFiles(file, code, bundleContent);
724
+ options.getSourceFiles = instance.locateSourceFiles(file, code, bundleContent);
714
725
  }
715
726
  }
716
- if ((!this.productionRelease || this.productionIncremental) && !(0, types_1.modifiedFlag)(file.flags)) {
727
+ if ((!instance.productionRelease || instance.productionIncremental) && !(0, types_1.modifiedFlag)(file.flags)) {
717
728
  options.cacheData = { uri: !exported ? uri : undefined, etag: !file.modified ? file.etag : undefined, encoding: file.encoding };
718
729
  }
719
730
  return options;
720
731
  }
721
- function transformJs(host, file, output) {
732
+ function transformJs(instance, host, file, output) {
722
733
  const { sourceFiles, chunks, map } = output;
723
734
  const localUri = file.localUri;
724
- const emptySources = !!this.productionRelease;
735
+ const emptySources = !!instance.productionRelease;
725
736
  let uri;
726
- if (map && (uri = writeSourceMap(localUri, output, { hash: file.hash, emptySources, inlineMap: hasSourceMap(file.metadata, 'inline') }))) {
737
+ if (map && (uri = Document.writeSourceMap(localUri, output, { hash: file.hash, emptySources, inlineMap: hasSourceMap(file.metadata, 'inline') }))) {
727
738
  host.add(uri, file, types_1.FILE_TYPE.SOURCEMAP);
728
739
  }
729
740
  if (chunks) {
730
- const elements = this.elements;
741
+ const elements = instance.elements;
731
742
  const localDir = path.dirname(localUri);
732
- const relativeDir = joinPath(file.moveTo, file.pathname);
743
+ const relativeDir = Document.joinPath(file.moveTo, file.pathname);
733
744
  const element = file.element;
734
745
  let order = 0, index, appending;
735
746
  if (element) {
@@ -744,11 +755,11 @@ function transformJs(host, file, output) {
744
755
  for (const chunk of chunks) {
745
756
  let chunkName = chunk.filename;
746
757
  if (!chunkName) {
747
- chunkName = getFormatUUID.call(this, 'filename', 'js') + path.extname(localUri);
758
+ chunkName = getFormatUUID(instance, 'filename', 'js') + path.extname(localUri);
748
759
  chunk.entryPoint = true;
749
760
  }
750
761
  const chunkUri = path.join(localDir, chunkName);
751
- if (chunk.map && (uri = writeSourceMap(chunkUri, chunk, { emptySources, inlineMap: hasSourceMap(file.metadata, 'inline') }))) {
762
+ if (chunk.map && (uri = Document.writeSourceMap(chunkUri, chunk, { emptySources, inlineMap: hasSourceMap(file.metadata, 'inline') }))) {
752
763
  host.add(uri, file, types_1.FILE_TYPE.SOURCEMAP);
753
764
  }
754
765
  try {
@@ -756,7 +767,7 @@ function transformJs(host, file, output) {
756
767
  host.add(chunkUri, file);
757
768
  if (chunk.entryPoint) {
758
769
  if (element) {
759
- const attributes = { ...file.attributes, src: joinPath(relativeDir, chunkName) };
770
+ const attributes = { ...file.attributes, src: Document.joinPath(relativeDir, chunkName) };
760
771
  if (file.imports && file.imported !== false) {
761
772
  attributes.type ||= 'module';
762
773
  }
@@ -767,15 +778,17 @@ function transformJs(host, file, output) {
767
778
  });
768
779
  }
769
780
  else {
770
- this.writeFail(['Unable to create script entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4);
781
+ instance.writeFail(['Unable to create script entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4);
771
782
  }
772
783
  }
773
784
  }
774
785
  catch (err) {
775
- this.writeFail(["Unable to write file", path.basename(chunkUri)], err, 32);
786
+ instance.writeFail(["Unable to write file", path.basename(chunkUri)], err, 32);
776
787
  }
777
788
  }
778
- appending?.forEach(item => item.order += order);
789
+ appending?.forEach(item => {
790
+ item.order += order;
791
+ });
779
792
  }
780
793
  if ((0, types_1.isArray)(sourceFiles)) {
781
794
  file.sourceFiles = sourceFiles;
@@ -783,41 +796,40 @@ function transformJs(host, file, output) {
783
796
  file.modified = true;
784
797
  return file.sourceUTF8 = output.code;
785
798
  }
786
- function replaceCss(file) {
787
- const sanitize = (map) => {
788
- for (const id in map) {
789
- map[id] = this.removeServerRoot(map[id]);
790
- }
791
- };
792
- const { inlineUrlMap, inlineUrlCloudMap } = file;
793
- if (inlineUrlMap) {
794
- sanitize(inlineUrlMap);
799
+ function replaceCss(instance, file) {
800
+ if (file.inlineUrlMap) {
801
+ sanitizeCss(instance, file.inlineUrlMap);
795
802
  }
796
- if (inlineUrlCloudMap) {
797
- sanitize(inlineUrlCloudMap);
803
+ if (file.inlineUrlCloudMap) {
804
+ sanitizeCss(instance, file.inlineUrlCloudMap);
798
805
  }
799
806
  }
800
- function replaceHtml(source, { productionRelease, contentMap }, cssMap) {
801
- const finalize = (value, data) => {
802
- for (const id in data) {
803
- value = value.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
804
- }
805
- return value;
806
- };
807
+ function sanitizeCss(instance, map) {
808
+ for (const id in map) {
809
+ map[id] = instance.removeServerRoot(map[id]);
810
+ }
811
+ }
812
+ function replaceHtml(instance, source, { productionRelease, contentMap }, cssMap) {
807
813
  if (cssMap) {
808
- source = finalize(source, cssMap);
814
+ source = finalizeHtml(source, cssMap);
809
815
  }
810
- source = finalize(source, contentMap);
811
- return productionRelease ? this.removeServerRoot(source) : source;
816
+ source = finalizeHtml(source, contentMap);
817
+ return productionRelease ? instance.removeServerRoot(source) : source;
812
818
  }
813
- function isWatched(file) {
819
+ function finalizeHtml(value, data) {
820
+ for (const id in data) {
821
+ value = value.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
822
+ }
823
+ return value;
824
+ }
825
+ function isWatched(instance, file) {
814
826
  const { initialValue, format } = file;
815
- if (file.imported || file.bundleReplace || file.inlineContent || file.inlineBase64 || this.replaced.includes(file) || initialValue && (file.inlineFilename !== initialValue.inlineFilename || file.pathname !== initialValue.pathname || initialValue.cacheable === false) || format && ((0, util_1.hasValue)(format, 'base64') || (0, util_1.hasValue)(format, 'woff') || (0, util_1.hasValue)(format, 'woff2'))) {
827
+ if (file.imported || file.bundleReplace || file.inlineContent || file.inlineBase64 || instance.replaced.includes(file) || initialValue && (file.inlineFilename !== initialValue.inlineFilename || file.pathname !== initialValue.pathname || initialValue.cacheable === false) || format && ((0, util_1.hasValue)(format, 'base64') || (0, util_1.hasValue)(format, 'woff') || (0, util_1.hasValue)(format, 'woff2'))) {
816
828
  return true;
817
829
  }
818
830
  return false;
819
831
  }
820
- function loadLocalFile(item, pathname, cacheData, encoding, out) {
832
+ function loadLocalFile(instance, item, pathname, cacheData, encoding, out) {
821
833
  let content;
822
834
  encoding = (0, types_1.getEncoding)(encoding);
823
835
  if (out) {
@@ -829,15 +841,15 @@ function loadLocalFile(item, pathname, cacheData, encoding, out) {
829
841
  return require(pathname);
830
842
  }
831
843
  content ||= fs.readFileSync(pathname, encoding);
832
- const result = this.tryParse(content, ext);
844
+ const result = instance.tryParse(content, ext);
833
845
  if (result !== undefined && result !== null) {
834
- setCacheData.call(this, item, result, pathname, cacheData, true);
846
+ setCacheData(instance, item, result, pathname, cacheData, true);
835
847
  return result;
836
848
  }
837
849
  }
838
- function setCacheData(item, data, dataKey, cacheData, template) {
850
+ function setCacheData(instance, item, data, dataKey, cacheData, template) {
839
851
  if ((0, types_1.isObject)(data) || template) {
840
- const cache = this.settingsOf(item.source, template && item.source !== 'local' ? 'local_file' : 'cache');
852
+ const cache = instance.settingsOf(item.source, template && item.source !== 'local' ? 'local_file' : 'cache');
841
853
  let timeout;
842
854
  if (cache && (timeout = core_1.ClientDb.getTimeout(cache)) && timeout > 0) {
843
855
  addCacheItem(template ? CACHE_LOCALFILE : CACHE_DBRESULT, dataKey, data, timeout);
@@ -847,11 +859,11 @@ function setCacheData(item, data, dataKey, cacheData, template) {
847
859
  }
848
860
  }
849
861
  }
850
- async function checkData(item, name, result, validate) {
862
+ async function checkData(instance, item, name, result, validate) {
851
863
  let callback;
852
864
  if (typeof name === 'string') {
853
- const template = this.findDataValue(name) || name;
854
- callback = this.hasEval('userconfig') ? Document.parseFunction(template, this.hasEval('absolute')) : (0, types_1.asFunction)(template);
865
+ const template = instance.findDataValue(name) || name;
866
+ callback = instance.hasEval('userconfig') ? Document.parseFunction(template, instance.hasEval('absolute')) : (0, types_1.asFunction)(template);
855
867
  }
856
868
  else {
857
869
  callback = name;
@@ -871,32 +883,41 @@ async function checkData(item, name, result, validate) {
871
883
  }
872
884
  }
873
885
  catch (err) {
874
- this.writeFail(["Unable to parse inline method", name], err);
886
+ instance.writeFail(["Unable to parse inline method", name], err);
875
887
  }
876
888
  }
877
889
  }
878
- const getNewlineString = dom_1.DomWriter.getNewlineString.bind(dom_1.DomWriter);
890
+ function removeElement(instance, domBase, item, element) {
891
+ if (item.removeEmpty || item.type === 'display') {
892
+ (element ||= new dom_1.HtmlElement(instance.moduleName, item.element)).remove = true;
893
+ if (!domBase.write(element)) {
894
+ instance.writeFail('Unable to remove element', errorHtml(item.element), { type: 4 });
895
+ }
896
+ }
897
+ }
898
+ function errorCredential(instance, domBase, item, err) {
899
+ removeElement(instance, domBase, item);
900
+ const pkg = getPackageName(err);
901
+ if (!(pkg && instance.checkPackage(err, pkg))) {
902
+ instance.writeFail(["Invalid credentials", item.source], err);
903
+ }
904
+ }
879
905
  const isSpace = dom_1.DomWriter.isSpace.bind(dom_1.DomWriter);
880
906
  const replaceMatch = dom_1.DomWriter.replaceMatch.bind(dom_1.DomWriter);
881
- const joinPath = Document.joinPath.bind(Document);
882
- const isPath = Document.isPath.bind(Document);
883
- const writeSourceMap = Document.writeSourceMap.bind(Document);
884
- const asString = Document.asString.bind(Document);
885
- const resolvePath = Document.resolvePath.bind(Document);
886
- const toPosix = Document.toPosix.bind(Document);
887
- const isDir = Document.isDir.bind(Document);
888
- const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri ||= item.localUri) && isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
907
+ const getNewlineString = dom_1.DomWriter.getNewlineString.bind(dom_1.DomWriter);
908
+ const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri ||= item.localUri) && Document.isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
889
909
  const hasSourceMap = (metadata, value) => (0, types_1.isObject)(metadata) && metadata.__sourcemap__ === value;
890
910
  const isBundled = (value, main) => typeof value === 'number' && (value > 0 || main && value === 0);
891
911
  const isFont = (value) => value === 'truetype' || value === 'opentype' || value === 'woff' || value === 'woff2';
892
- const isImage = (value) => typeof value === 'string' && value.startsWith('image/') && value !== 'image/svg+xml';
912
+ const isImage = (value) => typeof value === 'string' && value.startsWith('image/') && value !== "image/svg+xml";
893
913
  const isRemoved = (item) => item.exclude === true || isBundled(item.bundleIndex);
894
914
  const isUnedited = (item) => !item.attributes && !item.inlineContent && !item.srcSet && !item.element.dynamic && item.element.textContent === undefined && (!item.uri && !isBundled(item.bundleIndex, true) || (0, util_1.hasValue)(item.format, 'crossorigin'));
895
915
  const isIgnored = (item, exists) => item.invalid || (0, types_1.ignoreFlag)(item.flags) || !exists && (0, types_1.existsFlag)(item.flags);
896
916
  const findFont = (value) => value && (Array.isArray(value) ? value : [value]).find(format => isFont(format));
897
- const spliceString = (source, startIndex, endIndex, content) => source.substring(0, startIndex) + content + source.substring(endIndex);
898
917
  const getEndIndex = (match) => match.index + match[0].length;
899
- const getRelativeURL = (file) => joinPath(file.moveTo, file.pathname, file.inlineFilename || file.filename) + (!file.static ? restoreSearchParams(file.url?.search) : '');
918
+ const getRelativeURL = (file) => Document.joinPath(file.moveTo, file.pathname, file.inlineFilename || file.filename) + (!file.static ? restoreSearchParams(file.url?.search) : '');
919
+ const validateDir = (value) => path.isAbsolute(value) && Document.isDir(value) ? value : '';
920
+ const valueAsString = (value, delimiter) => Array.isArray(value) && !value.some(child => typeof child === 'object') ? value.join(delimiter) : Document.asString(value);
900
921
  const errorHtml = ({ tagName, tagIndex = -1 }) => (0, types_1.errorMessage)('html', 'Location did not resolve', tagName.toLowerCase() + (tagIndex >= 0 ? ': ' + tagIndex : ''));
901
922
  const errorDataSource = (value, hint) => (0, types_1.errorMessage)('data-source', value, hint);
902
923
  const isHtmlOnly = (assets, items, htmlFile) => !items.find(item => item !== htmlFile && assets.includes(item));
@@ -934,6 +955,8 @@ class ChromeDocument extends Document {
934
955
  CACHE_QUERY.clear();
935
956
  CACHE_SELECTOR.clear();
936
957
  CACHE_ETAG.clear();
958
+ CACHE_CONTENT.clear();
959
+ CACHE_FORMAT.clear();
937
960
  }
938
961
  return result + (parent && result > 0 ? await super.purgeMemory(typeof parent === 'number' && parent > 0 ? parent : percent, limit, true) : 0);
939
962
  }
@@ -960,17 +983,27 @@ class ChromeDocument extends Document {
960
983
  if (outHtml) {
961
984
  const { etag, initialValue } = htmlFile;
962
985
  let buffer;
963
- if (!initialValue || !(etag && initialValue.etag === etag && (buffer = initialValue.buffer)) || fetched.find(item => item !== htmlFile && item.etag && CACHE_ETAG.get(item.localUri) !== item.etag && (item.inlineContent || item.bundleReplace && (!(0, types_1.isArray)(item.from) || item.from.includes('style'))))) {
964
- fetched.forEach(item => {
965
- if (item.etag && item !== htmlFile && !item.invalid) {
986
+ if (!initialValue || !(etag && initialValue.etag === etag && (buffer = initialValue.buffer)) || fetched.find(item => item !== htmlFile && item.etag && CACHE_ETAG.get(item.localUri) !== item.etag && (item.inlineContent || item.bundleReplace && (!Array.isArray(item.from) || item.from.includes('style'))))) {
987
+ const isValid = (item) => !!item.localUri && item !== htmlFile && !item.invalid;
988
+ for (const item of fetched) {
989
+ if (item.etag && !item.content && isValid(item)) {
966
990
  CACHE_ETAG.set(item.localUri, item.etag);
967
991
  }
968
- });
992
+ }
993
+ for (const item of instance.assets) {
994
+ if (isValid(item)) {
995
+ if (item.content) {
996
+ CACHE_CONTENT.set(item.localUri, item.content);
997
+ }
998
+ if (item.format) {
999
+ CACHE_FORMAT.set(item.localUri, item.format.toString());
1000
+ }
1001
+ }
1002
+ }
969
1003
  break;
970
1004
  }
971
1005
  try {
972
- const { localUri, encoding } = htmlFile;
973
- fs.writeFileSync(localUri, buffer, (0, types_1.getEncoding)(encoding));
1006
+ fs.writeFileSync(htmlFile.localUri, buffer, (0, types_1.getEncoding)(htmlFile.encoding));
974
1007
  htmlFile.buffer = buffer;
975
1008
  htmlFile.sourceUTF8 = undefined;
976
1009
  }
@@ -978,13 +1011,40 @@ class ChromeDocument extends Document {
978
1011
  break;
979
1012
  }
980
1013
  }
981
- const { jsFiles, cssFiles, svgFiles } = instance;
982
- const copiedAssets = this.copiedAssets;
983
- const wasModified = (item) => fetched.includes(item) || copiedAssets.includes(item) && (!(0, types_1.isEmpty)(item.bundleId) || !(0, types_1.isEmpty)(item.trailingContent));
984
- const js = jsFiles.filter(item => item.imports || wasModified(item));
985
- const css = cssFiles.filter(wasModified);
986
- const svg = svgFiles.filter(wasModified);
987
- if (js.length || css.length || svg.length) {
1014
+ const wasModified = (item) => {
1015
+ const localUri = item.localUri;
1016
+ let result = fetched.includes(item) || Array.isArray(item.from) && item.from.includes('style');
1017
+ if (localUri) {
1018
+ if (item.etag && !item.content && !item.invalid) {
1019
+ CACHE_ETAG.set(localUri, item.etag);
1020
+ }
1021
+ else {
1022
+ CACHE_ETAG.delete(localUri);
1023
+ }
1024
+ if (!item.content || item.invalid) {
1025
+ CACHE_CONTENT.delete(localUri);
1026
+ }
1027
+ else if (CACHE_CONTENT.get(localUri) !== item.content || !item.inlineContent && !Document.isPath(localUri)) {
1028
+ CACHE_CONTENT.set(localUri, item.content);
1029
+ result = true;
1030
+ }
1031
+ if (!item.format || item.invalid) {
1032
+ CACHE_FORMAT.delete(localUri);
1033
+ }
1034
+ else {
1035
+ const format = item.format.toString();
1036
+ if (CACHE_FORMAT.get(localUri) !== format || !item.inlineContent && !Document.isPath(localUri)) {
1037
+ CACHE_FORMAT.set(localUri, format);
1038
+ result = true;
1039
+ }
1040
+ }
1041
+ }
1042
+ return result || this.copiedAssets.includes(item) && (!(0, types_1.isEmpty)(item.bundleId) || !(0, types_1.isEmpty)(item.trailingContent));
1043
+ };
1044
+ const js = instance.jsFiles.filter(item => wasModified(item) || !!item.imports);
1045
+ const css = instance.cssFiles.filter(wasModified);
1046
+ const svg = instance.svgFiles.filter(wasModified);
1047
+ if (js.length > 0 || css.length > 0 || svg.length > 0) {
988
1048
  instance.jsFiles = js;
989
1049
  instance.cssFiles = css;
990
1050
  instance.svgFiles = svg;
@@ -1003,7 +1063,7 @@ class ChromeDocument extends Document {
1003
1063
  }
1004
1064
  }
1005
1065
  instance.setInlinedAttributes(processing);
1006
- if (instance.editing.length) {
1066
+ if (instance.editing.length > 0) {
1007
1067
  await instance.applyTransforms(processing);
1008
1068
  if (instance.aborted) {
1009
1069
  return (0, types_1.createAbortError)(true);
@@ -1033,7 +1093,7 @@ class ChromeDocument extends Document {
1033
1093
  (function recurse(children) {
1034
1094
  for (const item of children) {
1035
1095
  if (!items.has(item)) {
1036
- if (isWatched.call(instance, item)) {
1096
+ if (isWatched(instance, item)) {
1037
1097
  item.flags |= 8;
1038
1098
  }
1039
1099
  items.add(item);
@@ -1048,40 +1108,126 @@ class ChromeDocument extends Document {
1048
1108
  }
1049
1109
  }
1050
1110
  }
1051
- let productionRelease = instance.productionRelease;
1111
+ const productionRelease = instance.productionRelease;
1052
1112
  if ((0, types_1.isString)(productionRelease)) {
1053
- if (path.isAbsolute(productionRelease = path.normalize(productionRelease)) && isDir(productionRelease)) {
1054
- if (this.canWrite(productionRelease)) {
1055
- const serverRoot = ChromeDocument.INTERNAL_SERVERROOT;
1056
- const srcDir = path.join(this.baseDirectory, serverRoot);
1057
- if (isDir(srcDir)) {
1058
- const result = await Document.copyDir(srcDir, productionRelease, this.incremental !== 'staging');
1113
+ const errorDirectory = (value) => {
1114
+ instance.writeFail(["Unable to read directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Invalid directory', value), 32);
1115
+ };
1116
+ const errorAccess = (value) => {
1117
+ instance.writeFail(["Unable to write directory", instance.moduleName], (0, types_1.errorMessage)('production', "Unsupported access", value), 8192);
1118
+ };
1119
+ const errorMove = (err) => {
1120
+ instance.writeFail(["Unable to move file", instance.moduleName], err, { type: 32, fatal: true });
1121
+ };
1122
+ const outputDir = validateDir(productionRelease);
1123
+ if (outputDir) {
1124
+ if (this.canWrite(outputDir)) {
1125
+ const srcDir = path.join(this.baseDirectory, ChromeDocument.INTERNAL_SERVERROOT);
1126
+ if (Document.isDir(srcDir)) {
1127
+ const serverRootMapping = instance.serverRootMapping;
1128
+ const mapped = [];
1129
+ for (const localDir in serverRootMapping) {
1130
+ const subDir = serverRootMapping[localDir];
1131
+ const destDir = validateDir(Document.normalizePath(/[\\/]$/.test(subDir) ? path.join(outputDir, subDir, localDir) : path.join(outputDir, subDir), true));
1132
+ if (destDir.startsWith(outputDir)) {
1133
+ if (this.canWrite(destDir)) {
1134
+ mapped.push([Document.normalizePath(localDir, true), destDir, 0]);
1135
+ }
1136
+ else {
1137
+ errorAccess(localDir);
1138
+ return;
1139
+ }
1140
+ }
1141
+ else {
1142
+ errorDirectory(localDir);
1143
+ return;
1144
+ }
1145
+ }
1146
+ if (mapped.length > 0) {
1147
+ const emptyDir = new Set();
1148
+ for (const value of this.files) {
1149
+ if (value.startsWith(ChromeDocument.INTERNAL_SERVERROOT)) {
1150
+ const subDir = value.split(path.sep).slice(1);
1151
+ const start = subDir.length - 1;
1152
+ for (let i = start; i > 0; --i) {
1153
+ const localDir = subDir.slice(0, i).join(path.sep) + path.sep;
1154
+ const target = mapped.find(item => item[0] === localDir);
1155
+ if (target) {
1156
+ const src = path.join(this.baseDirectory, value);
1157
+ try {
1158
+ let destDir = target[1];
1159
+ if (i !== start && !Document.createDir(destDir = path.join(destDir, ...subDir.slice(i, start)))) {
1160
+ throw (0, types_1.errorMessage)('production', destDir, 'create');
1161
+ }
1162
+ const dest = path.join(destDir, subDir[subDir.length - 1]);
1163
+ Document.renameFile(src, dest);
1164
+ instance.addLog(types_1.STATUS_TYPE.INFO, `production: ${dest} (mapped)`, instance.moduleName, subDir.join(path.sep));
1165
+ emptyDir.add(path.dirname(src));
1166
+ if (i !== start) {
1167
+ for (let j = 0; j < i; ++j) {
1168
+ emptyDir.add(path.join(this.baseDirectory, ChromeDocument.INTERNAL_SERVERROOT, ...subDir.slice(0, j + 1)));
1169
+ }
1170
+ }
1171
+ ++target[2];
1172
+ }
1173
+ catch (err) {
1174
+ errorMove(err);
1175
+ if (Document.isPath(src)) {
1176
+ fs.unlink(src, error => {
1177
+ if (error) {
1178
+ instance.addLog(types_1.STATUS_TYPE.WARN, error);
1179
+ }
1180
+ });
1181
+ }
1182
+ }
1183
+ finally {
1184
+ this.delete(value);
1185
+ }
1186
+ break;
1187
+ }
1188
+ }
1189
+ }
1190
+ }
1191
+ for (const item of mapped) {
1192
+ if (item[2] === 0) {
1193
+ instance.addLog(types_1.STATUS_TYPE.INFO, `production: ${item[1]} (mapped: 0)`, instance.moduleName, item[0]);
1194
+ }
1195
+ }
1196
+ for (const pathname of Array.from(emptyDir).sort((a, b) => b.length - a.length)) {
1197
+ try {
1198
+ fs.rmdirSync(pathname);
1199
+ }
1200
+ catch {
1201
+ }
1202
+ }
1203
+ }
1204
+ const result = await Document.copyDir(srcDir, outputDir, this.incremental !== 'staging');
1059
1205
  const failed = result.failed.map(value => this.removeCwd(value));
1060
1206
  for (const value of this.files) {
1061
- if (value.startsWith(serverRoot)) {
1207
+ if (value.startsWith(ChromeDocument.INTERNAL_SERVERROOT)) {
1062
1208
  if (!failed.includes(value)) {
1063
1209
  this.delete(value);
1064
1210
  }
1065
1211
  else {
1066
- instance.writeFail(["Unable to move file", instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
1212
+ errorMove((0, types_1.errorMessage)('production', path.join(this.baseDirectory, value), 'move'));
1067
1213
  }
1068
1214
  }
1069
1215
  }
1070
1216
  }
1071
1217
  }
1072
1218
  else {
1073
- instance.writeFail(["Unable to write directory", instance.moduleName], (0, types_1.errorMessage)('production', "Unsupported access", productionRelease));
1219
+ errorAccess(productionRelease);
1074
1220
  }
1075
1221
  }
1076
1222
  else {
1077
- instance.writeFail(["Unable to read directory", instance.moduleName], (0, types_1.errorMessage)('production', 'Invalid directory', productionRelease), 32);
1223
+ errorDirectory(productionRelease);
1078
1224
  }
1079
1225
  }
1080
1226
  }
1081
1227
  static sanitizeAssets(assets, exclusions = []) {
1082
- assets.forEach(item => {
1228
+ for (const item of assets) {
1083
1229
  if ((0, types_1.ignoreFlag)(item.flags)) {
1084
- return;
1230
+ continue;
1085
1231
  }
1086
1232
  for (const attr in item) {
1087
1233
  switch (attr) {
@@ -1099,7 +1245,8 @@ class ChromeDocument extends Document {
1099
1245
  break;
1100
1246
  }
1101
1247
  }
1102
- });
1248
+ }
1249
+ return assets;
1103
1250
  }
1104
1251
  config = {
1105
1252
  usedVariables: undefined,
@@ -1128,6 +1275,8 @@ class ChromeDocument extends Document {
1128
1275
  baseUrl = '';
1129
1276
  productionRelease = false;
1130
1277
  productionIncremental = false;
1278
+ serverRootMapping = undefined;
1279
+ sanitizeFramework = undefined;
1131
1280
  templateMap = {};
1132
1281
  userAgentData = {};
1133
1282
  related = new Map();
@@ -1141,7 +1290,7 @@ class ChromeDocument extends Document {
1141
1290
  _cloudUrlMap;
1142
1291
  _cloudUploaded;
1143
1292
  _cloudEndpoint;
1144
- _idMap = Object.create(null);
1293
+ _idMap = {};
1145
1294
  _editing = [];
1146
1295
  _queryMap = new Map();
1147
1296
  _selectorMap = new Map();
@@ -1165,7 +1314,7 @@ class ChromeDocument extends Document {
1165
1314
  }
1166
1315
  if (item.editing) {
1167
1316
  switch (item.mimeType) {
1168
- case 'text/html':
1317
+ case "text/html":
1169
1318
  if (!this.htmlFile) {
1170
1319
  this.htmlFile = item;
1171
1320
  item.editing = true;
@@ -1175,15 +1324,15 @@ class ChromeDocument extends Document {
1175
1324
  item.editing = false;
1176
1325
  }
1177
1326
  break;
1178
- case 'text/css':
1327
+ case "text/css":
1179
1328
  this.cssFiles.push(item);
1180
1329
  this._editing.push(item);
1181
1330
  break;
1182
- case 'text/javascript':
1183
- case 'application/javascript':
1331
+ case "text/javascript":
1332
+ item.mimeType = "application/javascript";
1333
+ case "application/javascript":
1184
1334
  this.jsFiles.push(item);
1185
1335
  this._editing.push(item);
1186
- item.mimeType = 'application/javascript';
1187
1336
  break;
1188
1337
  }
1189
1338
  }
@@ -1199,7 +1348,7 @@ class ChromeDocument extends Document {
1199
1348
  });
1200
1349
  let imports;
1201
1350
  if (config) {
1202
- const { useUnsafeReplace, baseUrl, productionRelease, productionIncremental, templateMap, userAgentData, cache } = config;
1351
+ const { useUnsafeReplace, baseUrl, productionRelease, productionIncremental, serverRootMapping, templateMap, sanitizeFramework, userAgentData, cache } = config;
1203
1352
  const target = this.config;
1204
1353
  for (const attr in config) {
1205
1354
  if (attr in target) {
@@ -1232,12 +1381,31 @@ class ChromeDocument extends Document {
1232
1381
  catch {
1233
1382
  }
1234
1383
  }
1235
- if (productionRelease === true || (0, types_1.isString)(productionRelease)) {
1236
- this.productionRelease = productionRelease;
1384
+ if ((0, types_1.isString)(productionRelease)) {
1385
+ this.productionRelease = Document.normalizePath(productionRelease, 2);
1386
+ const baseDir = Document.normalizePath(this.productionRelease, 1 | 2);
1387
+ let baseMap;
1388
+ found: {
1389
+ for (const map of [this.getUserSettings()?.server_root, this.settings.server_root]) {
1390
+ for (const pathname in map) {
1391
+ if (Document.normalizePath(pathname, 1 | 2) === baseDir && (0, types_1.isObject)(map[pathname])) {
1392
+ baseMap = map[pathname];
1393
+ break found;
1394
+ }
1395
+ }
1396
+ }
1397
+ }
1398
+ this.serverRootMapping = (0, types_1.isObject)(serverRootMapping) ? baseMap ? Object.assign(baseMap, serverRootMapping) : serverRootMapping : baseMap;
1399
+ }
1400
+ else if (productionRelease) {
1401
+ this.productionRelease = true;
1237
1402
  }
1238
1403
  if (productionIncremental) {
1239
1404
  this.productionIncremental = true;
1240
1405
  }
1406
+ if ((0, types_1.isArray)(sanitizeFramework)) {
1407
+ this.sanitizeFramework = sanitizeFramework;
1408
+ }
1241
1409
  if ((0, types_1.isObject)(templateMap)) {
1242
1410
  this.templateMap = templateMap;
1243
1411
  }
@@ -1278,10 +1446,10 @@ class ChromeDocument extends Document {
1278
1446
  for (const storage of cloud) {
1279
1447
  for (const { service, upload, download } of storage) {
1280
1448
  if (upload) {
1281
- setLocationUUID.call(this, upload, null, service);
1449
+ setLocationUUID(this, upload, null, service);
1282
1450
  }
1283
1451
  if (download) {
1284
- setLocationUUID.call(this, download, null, service);
1452
+ setLocationUUID(this, download, null, service);
1285
1453
  }
1286
1454
  }
1287
1455
  }
@@ -1333,22 +1501,22 @@ class ChromeDocument extends Document {
1333
1501
  const { localUri, mimeType, format } = file;
1334
1502
  const hash = productionRelease && file.hash;
1335
1503
  switch (mimeType) {
1336
- case 'text/html':
1504
+ case "text/html":
1337
1505
  if (format) {
1338
- const output = await this.transform('html', host.getUTF8String(file, localUri), format, transformOptions.call(this, file, mimeType));
1506
+ const output = await this.transform('html', host.getUTF8String(file, localUri), format, transformOptions(this, file, mimeType));
1339
1507
  if (output) {
1340
1508
  file.modified = true;
1341
1509
  file.sourceUTF8 = output.code;
1342
1510
  }
1343
1511
  }
1344
1512
  break;
1345
- case 'text/css':
1513
+ case "text/css":
1346
1514
  if (format) {
1347
1515
  const source = host.getUTF8String(file, localUri);
1348
- const output = await this.transform('css', source, format, transformOptions.call(this, file, mimeType, source));
1516
+ const output = await this.transform('css', source, format, transformOptions(this, file, mimeType, source));
1349
1517
  if (output) {
1350
1518
  if (output.map) {
1351
- const uri = writeSourceMap(localUri, output, { mimeType, hash, emptySources: productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
1519
+ const uri = Document.writeSourceMap(localUri, output, { mimeType, hash, emptySources: productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
1352
1520
  if (uri) {
1353
1521
  host.add(uri, file, types_1.FILE_TYPE.SOURCEMAP);
1354
1522
  }
@@ -1358,8 +1526,8 @@ class ChromeDocument extends Document {
1358
1526
  }
1359
1527
  }
1360
1528
  break;
1361
- case 'text/javascript':
1362
- case 'application/javascript': {
1529
+ case "text/javascript":
1530
+ case "application/javascript": {
1363
1531
  let source = host.getUTF8String(file, localUri);
1364
1532
  if (!(file.bundleIndex >= 0)) {
1365
1533
  source = host.setAssetContent(file, source);
@@ -1370,15 +1538,15 @@ class ChromeDocument extends Document {
1370
1538
  file.modified = true;
1371
1539
  }
1372
1540
  if (format) {
1373
- const output = await this.transform('js', source, format, transformOptions.call(this, file, mimeType, source, host.contentToAppend.get(localUri)));
1541
+ const output = await this.transform('js', source, format, transformOptions(this, file, mimeType, source, host.contentToAppend.get(localUri)));
1374
1542
  if (output) {
1375
- source = transformJs.call(this, host, file, output);
1543
+ source = transformJs(this, host, file, output);
1376
1544
  }
1377
1545
  }
1378
1546
  file.sourceUTF8 = source;
1379
1547
  break;
1380
1548
  }
1381
- case 'image/svg+xml': {
1549
+ case "image/svg+xml": {
1382
1550
  const source = host.getUTF8String(file, localUri);
1383
1551
  if (/\burl\(/i.test(source)) {
1384
1552
  file.editing = true;
@@ -1386,7 +1554,7 @@ class ChromeDocument extends Document {
1386
1554
  this.svgFiles.push(file);
1387
1555
  }
1388
1556
  else if (format) {
1389
- const output = await this.transform('html', source, format, transformOptions.call(this, file, mimeType, source));
1557
+ const output = await this.transform('html', source, format, transformOptions(this, file, mimeType, source));
1390
1558
  if (output) {
1391
1559
  file.modified = true;
1392
1560
  file.sourceUTF8 = output.code;
@@ -1482,7 +1650,7 @@ class ChromeDocument extends Document {
1482
1650
  this.replaced.push(file);
1483
1651
  }
1484
1652
  else {
1485
- setLocationUUID.call(this, file, file);
1653
+ setLocationUUID(this, file, file);
1486
1654
  }
1487
1655
  file.relativeUrl = getRelativeURL(file);
1488
1656
  }
@@ -1490,8 +1658,8 @@ class ChromeDocument extends Document {
1490
1658
  const host = this.host;
1491
1659
  if (host) {
1492
1660
  switch (file.mimeType) {
1493
- case 'text/javascript':
1494
- case 'application/javascript':
1661
+ case "text/javascript":
1662
+ case "application/javascript":
1495
1663
  if (file.imports) {
1496
1664
  [[file.uri, source], [this.baseUrl, trailing]].forEach(([uri, code], index) => {
1497
1665
  let localFile;
@@ -1503,24 +1671,26 @@ class ChromeDocument extends Document {
1503
1671
  output = this.resolveImports(file, code, bundleMain || file);
1504
1672
  }
1505
1673
  else if (index === 0 && !exported) {
1506
- if (!isDir(localFile)) {
1674
+ if (!Document.isDir(localFile)) {
1507
1675
  localFile = path.dirname(localFile);
1508
1676
  }
1677
+ output = code;
1509
1678
  let mainFile, pathname, match;
1510
- const ignorePath = bundleMain && (mainFile = this.findSourceRoot(bundleMain.uri)) && (isDir(mainFile) || (mainFile = path.dirname(mainFile))) && mainFile === localFile;
1511
- while (match = REGEXP_IMPORTMODULE.exec(code)) {
1512
- const value = match[1] || match[2] || match[4];
1679
+ const ignorePath = bundleMain && (mainFile = this.findSourceRoot(bundleMain.uri)) && (Document.isDir(mainFile) || (mainFile = path.dirname(mainFile))) && mainFile === localFile;
1680
+ while (match = REGEXP_IMPORTMODULE.exec(output)) {
1513
1681
  const assert = match[3] || match[5];
1514
- const from = trimQuote(value);
1682
+ const idx = match[1] ? 1 : match[2] ? 2 : 4;
1683
+ const [a, b] = match.indices[idx];
1684
+ const from = trimQuote(match[idx]);
1685
+ const quote = output[a];
1515
1686
  const relative = /^\.{0,2}\//.test(from);
1516
1687
  if (assert && /\btype\s*:\s*(["'`])css\1/.test(assert)) {
1517
1688
  try {
1518
1689
  const asset = host.findAsset(relative ? new URL(from, uri) : from);
1519
1690
  if (asset) {
1520
- const [relativeUrl, sameDir] = getSrcURL.call(this, bundleMain || file, asset);
1691
+ const [relativeUrl, sameDir] = getSrcURL(this, bundleMain || file, asset);
1521
1692
  if (relativeUrl) {
1522
- const quote = value[0];
1523
- output = (output || code).replace(value, quote + (sameDir ? './' : '') + relativeUrl + quote);
1693
+ output = (0, util_1.spliceString)(output, a, b, quote + (sameDir ? './' : '') + relativeUrl + quote, REGEXP_IMPORTMODULE);
1524
1694
  }
1525
1695
  }
1526
1696
  }
@@ -1534,23 +1704,20 @@ class ChromeDocument extends Document {
1534
1704
  }
1535
1705
  pathname = path.join(localFile, from);
1536
1706
  }
1537
- else if (!(pathname = this.findSourceRoot(from)) || !isPath(pathname)) {
1707
+ else if (!(pathname = this.findSourceRoot(from)) || !Document.isPath(pathname)) {
1538
1708
  const asset = host.findAsset(from);
1539
- if (asset && !asset.invalid) {
1540
- pathname = asset.localUri;
1541
- }
1542
- else {
1709
+ if (!asset || asset.invalid) {
1543
1710
  continue;
1544
1711
  }
1712
+ pathname = asset.localUri;
1545
1713
  }
1546
- if (pathname && isPath(pathname)) {
1547
- const quote = value[0];
1548
- output = (output || code).replace(value, quote + pathname + quote);
1714
+ if (pathname && Document.isPath(pathname)) {
1715
+ output = (0, util_1.spliceString)(output, a, b, quote + pathname + quote, REGEXP_IMPORTMODULE);
1549
1716
  }
1550
1717
  }
1551
1718
  REGEXP_IMPORTMODULE.lastIndex = 0;
1552
1719
  }
1553
- if (output) {
1720
+ if (output && output !== code) {
1554
1721
  if (index === 0) {
1555
1722
  source = output;
1556
1723
  }
@@ -1562,14 +1729,14 @@ class ChromeDocument extends Document {
1562
1729
  });
1563
1730
  }
1564
1731
  break;
1565
- case 'text/css':
1732
+ case "text/css":
1566
1733
  if (file.editing) {
1567
1734
  const htmlFile = this.htmlFile;
1568
1735
  const bundleId = file.bundleId;
1569
1736
  if (!(0, types_1.isEmpty)(bundleId)) {
1570
1737
  for (const asset of this.assets) {
1571
1738
  if (asset.bundleIndex === 0 && asset.bundleId === bundleId) {
1572
- const output = transformURL.call(this, host, file, 'css', source, asset);
1739
+ const output = transformURL(this, host, file, 'css', source, asset);
1573
1740
  if (output) {
1574
1741
  source = output;
1575
1742
  file.modified = true;
@@ -1579,7 +1746,7 @@ class ChromeDocument extends Document {
1579
1746
  }
1580
1747
  }
1581
1748
  if (trailing && htmlFile) {
1582
- const output = transformURL.call(this, host, file, 'css', trailing, htmlFile);
1749
+ const output = transformURL(this, host, file, 'css', trailing, htmlFile);
1583
1750
  if (output) {
1584
1751
  trailing = output;
1585
1752
  }
@@ -1620,7 +1787,7 @@ class ChromeDocument extends Document {
1620
1787
  if (hosted) {
1621
1788
  const asset = this.host?.findAsset(uri);
1622
1789
  if (asset) {
1623
- const [relativeUrl, sameDir] = getSrcURL.call(this, bundleMain || file, asset);
1790
+ const [relativeUrl, sameDir] = getSrcURL(this, bundleMain || file, asset);
1624
1791
  if (relativeUrl) {
1625
1792
  value = (sameDir ? './' : '') + relativeUrl;
1626
1793
  }
@@ -1636,7 +1803,7 @@ class ChromeDocument extends Document {
1636
1803
  }
1637
1804
  value = found || original;
1638
1805
  }
1639
- code = spliceString(code, index, index + placeholder.length, value);
1806
+ code = (0, util_1.spliceString)(code, index, index + placeholder.length, value);
1640
1807
  modified = true;
1641
1808
  break;
1642
1809
  }
@@ -1648,7 +1815,7 @@ class ChromeDocument extends Document {
1648
1815
  }
1649
1816
  replaceContent(source, statement, mimeType) {
1650
1817
  switch (mimeType) {
1651
- case 'text/css': {
1818
+ case "text/css": {
1652
1819
  const match = REGEXP_REPLACECSS.exec((typeof statement === 'string' ? statement : statement[0]).trim());
1653
1820
  if (match) {
1654
1821
  const layer = match[1];
@@ -1693,7 +1860,7 @@ class ChromeDocument extends Document {
1693
1860
  if (output && command && file.element?.outerXml) {
1694
1861
  const match = REGEXP_SRCSETSIZE.exec(command);
1695
1862
  if (match) {
1696
- (file.srcSet ||= []).push(toPosix(data.baseDirectory ? output.substring(data.baseDirectory.length + 1) : output), match[1] + match[2].toLowerCase());
1863
+ (file.srcSet ||= []).push(Document.toPosix(data.baseDirectory ? output.substring(data.baseDirectory.length + 1) : output), match[1] + match[2].toLowerCase());
1697
1864
  file.modified = true;
1698
1865
  return true;
1699
1866
  }
@@ -1708,7 +1875,7 @@ class ChromeDocument extends Document {
1708
1875
  if (htmlFile) {
1709
1876
  const endpoint = instance.getStorage('upload', htmlFile.cloudStorage)?.upload?.endpoint;
1710
1877
  if (endpoint) {
1711
- this._cloudEndpoint = new RegExp((0, types_1.escapePattern)(toPosix(endpoint)) + '/', 'g');
1878
+ this._cloudEndpoint = new RegExp((0, types_1.escapePattern)(Document.toPosix(endpoint)) + '/', 'g');
1712
1879
  }
1713
1880
  }
1714
1881
  }
@@ -1793,7 +1960,7 @@ class ChromeDocument extends Document {
1793
1960
  const { admin, bucket, upload } = storage;
1794
1961
  const website = admin?.configBucket?.website;
1795
1962
  if ((0, types_1.isPlainObject)(website) && bucket && upload) {
1796
- let filename = joinPath(upload.pathname, upload.filename || path.basename(htmlFile.localUri));
1963
+ let filename = Document.joinPath(upload.pathname, upload.filename || path.basename(htmlFile.localUri));
1797
1964
  if (website.indexPage === true) {
1798
1965
  website.indexPage = filename;
1799
1966
  filename = '';
@@ -1809,14 +1976,14 @@ class ChromeDocument extends Document {
1809
1976
  if (website.errorPath === true) {
1810
1977
  website.errorPath = filename;
1811
1978
  }
1812
- instance.setBucketWebsite(storage.service, instance.getCredential(storage), bucket, website);
1979
+ void instance.setBucketWebsite(storage.service, instance.getCredential(storage), bucket, website);
1813
1980
  }
1814
1981
  }
1815
1982
  }
1816
1983
  if (htmlFile.compress) {
1817
1984
  await host.compressFile(htmlFile);
1818
1985
  }
1819
- return Promise.all(Cloud.uploadAsset(state, htmlFile, { preferBuffer, contentType: 'text/html', ignoreProcess: true }));
1986
+ return Promise.all(Cloud.uploadAsset(state, htmlFile, { preferBuffer, contentType: "text/html", ignoreProcess: true }));
1820
1987
  }
1821
1988
  }
1822
1989
  return [];
@@ -1827,7 +1994,7 @@ class ChromeDocument extends Document {
1827
1994
  }
1828
1995
  const main = watch.main;
1829
1996
  let result;
1830
- if (main?.editing && main.mimeType === 'text/html') {
1997
+ if (main?.editing && main.mimeType === "text/html") {
1831
1998
  const inlineUrlCloudMap = main.inlineUrlCloudMap || {};
1832
1999
  const using = [];
1833
2000
  let found;
@@ -1840,7 +2007,7 @@ class ChromeDocument extends Document {
1840
2007
  found = true;
1841
2008
  using.push(asset);
1842
2009
  }
1843
- else if (isWatched.call(this, asset) ||
2010
+ else if (isWatched(this, asset) ||
1844
2011
  (0, types_1.watchFlag)(asset.flags) ||
1845
2012
  asset.base64 && watch.related.find(item => (0, asset_1.isEqual)(item, asset)) ||
1846
2013
  (0, types_1.isArray)(asset.cloudStorage) && asset.cloudStorage.some(item => (upload = item.upload) && upload.active)) {
@@ -1869,8 +2036,9 @@ class ChromeDocument extends Document {
1869
2036
  }
1870
2037
  const asset = watch.bundleMain || watch.assets[0];
1871
2038
  const pathname = (asset.cloudUrl || asset.relativeUrl || '').split('?')[0];
1872
- let next, value, search;
1873
- if (assets && (next = assets.find(item => (0, asset_1.isEqual)(item, asset)))) {
2039
+ const next = assets?.find(item => (0, asset_1.isEqual)(item, asset));
2040
+ let value, search;
2041
+ if (next) {
1874
2042
  if (next.cloudUrl) {
1875
2043
  value = next.cloudUrl;
1876
2044
  asset.cloudUrl = value;
@@ -1919,7 +2087,7 @@ class ChromeDocument extends Document {
1919
2087
  const srcset = element.getAttribute('srcset');
1920
2088
  if (srcset) {
1921
2089
  const htmlFile = this.htmlFile;
1922
- const uri = toPosix(file.uri);
2090
+ const uri = Document.toPosix(file.uri);
1923
2091
  const items = new Set([uri]);
1924
2092
  const baseHref = getBaseURLs(htmlFile, this.baseUrl);
1925
2093
  const sameOrigin = hasSameOrigin(file.url || uri, ...baseHref);
@@ -1927,7 +2095,7 @@ class ChromeDocument extends Document {
1927
2095
  const src = element.getAttribute('src');
1928
2096
  for (const baseUri of baseHref) {
1929
2097
  let url;
1930
- if (src && uri === resolvePath(url = toPosix(src), baseUri)) {
2098
+ if (src && uri === Document.resolvePath(url = Document.toPosix(src), baseUri)) {
1931
2099
  items.add(url);
1932
2100
  }
1933
2101
  items.add(uri.startsWith(this.baseDirectory) ? uri.substring(this.baseDirectory.length) : uri.replace(baseUri.origin, ''));
@@ -1940,7 +2108,7 @@ class ChromeDocument extends Document {
1940
2108
  const pattern = new RegExp(`(,?\\s*)(${(resolve && !url.startsWith('.') ? `(?:\\.\\.[\\\\/])*\\.\\.${pathname}|` : '') + pathname})(` + (!url.includes('?') ? '(?:(?!,)(?:[^?]|$)[^,]*)|(?!\\?)[^,]*)' : '[^,]*)'), 'g');
1941
2109
  while (match = pattern.exec(current)) {
1942
2110
  const partial = match[2];
1943
- if (!resolve || baseHref.some(baseUri => uri === resolvePath(partial, baseUri))) {
2111
+ if (!resolve || baseHref.some(baseUri => uri === Document.resolvePath(partial, baseUri))) {
1944
2112
  current = replaceMatch(match, current, match[1] + value + match[3], pattern);
1945
2113
  }
1946
2114
  }
@@ -1978,7 +2146,7 @@ class ChromeDocument extends Document {
1978
2146
  readBase64(item, item.inlineBase64);
1979
2147
  }
1980
2148
  else if (!item.invalid && (0, util_1.hasValue)(item.format, 'base64')) {
1981
- const uuid = (0, types_1.generateUUID)();
2149
+ const uuid = (0, crypto_1.randomUUID)();
1982
2150
  if (readBase64(item, uuid)) {
1983
2151
  item.inlineBase64 = uuid;
1984
2152
  }
@@ -2022,9 +2190,9 @@ class ChromeDocument extends Document {
2022
2190
  const { host, hashed, bufferMap, productionRelease } = processing;
2023
2191
  const sanitizeSource = (item, source) => {
2024
2192
  if (productionRelease) {
2025
- replaceCss.call(this, item);
2193
+ replaceCss(this, item);
2026
2194
  }
2027
- const output = replaceHtml.call(this, source, processing, item.inlineUrlMap);
2195
+ const output = replaceHtml(this, source, processing, item.inlineUrlMap);
2028
2196
  if (source !== output) {
2029
2197
  item.modified = true;
2030
2198
  return output;
@@ -2053,7 +2221,7 @@ class ChromeDocument extends Document {
2053
2221
  continue;
2054
2222
  }
2055
2223
  let source = host.getUTF8String(item);
2056
- const output = transformURL.call(this, host, item, 'svg', source);
2224
+ const output = transformURL(this, host, item, 'svg', source);
2057
2225
  if (output) {
2058
2226
  source = output;
2059
2227
  item.modified = true;
@@ -2061,7 +2229,7 @@ class ChromeDocument extends Document {
2061
2229
  source = sanitizeSource(item, source);
2062
2230
  const format = item.format;
2063
2231
  if (format) {
2064
- const result = await this.transform('html', source, format, transformOptions.call(this, item, 'image/svg+xml'));
2232
+ const result = await this.transform('html', source, format, transformOptions(this, item, "image/svg+xml"));
2065
2233
  if (result) {
2066
2234
  item.modified = true;
2067
2235
  source = result.code;
@@ -2088,7 +2256,7 @@ class ChromeDocument extends Document {
2088
2256
  source = output;
2089
2257
  item.modified = true;
2090
2258
  }
2091
- if (output = transformURL.call(this, host, item, 'css', source)) {
2259
+ if (output = transformURL(this, host, item, 'css', source)) {
2092
2260
  source = output;
2093
2261
  item.modified = true;
2094
2262
  }
@@ -2096,7 +2264,7 @@ class ChromeDocument extends Document {
2096
2264
  item.sourceUTF8 = source;
2097
2265
  if (item.format) {
2098
2266
  transforms.push(item);
2099
- tasks.push(this.transform('css', source, item.format, transformOptions.call(this, item, 'text/css', source, host.contentToAppend.get(item.localUri))));
2267
+ tasks.push(this.transform('css', source, item.format, transformOptions(this, item, "text/css", source, host.contentToAppend.get(item.localUri))));
2100
2268
  }
2101
2269
  }
2102
2270
  for (const item of this.jsFiles) {
@@ -2112,7 +2280,7 @@ class ChromeDocument extends Document {
2112
2280
  source = output;
2113
2281
  item.modified = true;
2114
2282
  }
2115
- if (output = transformURL.call(this, host, item, 'js', source)) {
2283
+ if (output = transformURL(this, host, item, 'js', source)) {
2116
2284
  source = output;
2117
2285
  item.modified = true;
2118
2286
  }
@@ -2120,7 +2288,7 @@ class ChromeDocument extends Document {
2120
2288
  item.sourceUTF8 = source;
2121
2289
  if (format) {
2122
2290
  transforms.push(item);
2123
- tasks.push(this.transform('js', source, format, transformOptions.call(this, item, 'application/javascript', source, host.contentToAppend.get(item.localUri))));
2291
+ tasks.push(this.transform('js', source, format, transformOptions(this, item, "application/javascript", source, host.contentToAppend.get(item.localUri))));
2124
2292
  }
2125
2293
  }
2126
2294
  return Promise.allSettled(tasks).then(items => {
@@ -2130,7 +2298,7 @@ class ChromeDocument extends Document {
2130
2298
  const target = transforms[i];
2131
2299
  if (value.type === 'css') {
2132
2300
  if (value.map && !target.bundleReplace) {
2133
- const output = writeSourceMap(target.localUri, value, { mimeType: 'text/css', hash: productionRelease ? target.hash : undefined, emptySources: productionRelease, inlineMap: hasSourceMap(target.metadata, 'inline') });
2301
+ const output = Document.writeSourceMap(target.localUri, value, { mimeType: "text/css", hash: productionRelease ? target.hash : undefined, emptySources: productionRelease, inlineMap: hasSourceMap(target.metadata, 'inline') });
2134
2302
  if (output) {
2135
2303
  host.add(output, target, types_1.FILE_TYPE.SOURCEMAP);
2136
2304
  }
@@ -2139,7 +2307,7 @@ class ChromeDocument extends Document {
2139
2307
  target.sourceUTF8 = value.code;
2140
2308
  }
2141
2309
  else {
2142
- transformJs.call(this, host, target, value);
2310
+ transformJs(this, host, target, value);
2143
2311
  }
2144
2312
  }
2145
2313
  }
@@ -2166,7 +2334,7 @@ class ChromeDocument extends Document {
2166
2334
  domBase.ignoreTag(config.ignoreServerCodeBlocks);
2167
2335
  }
2168
2336
  if (productionRelease) {
2169
- replaceCss.call(this, htmlFile);
2337
+ replaceCss(this, htmlFile);
2170
2338
  }
2171
2339
  await this.setElementAttributes(processing, domBase);
2172
2340
  await this.applyDataSource(processing, domBase);
@@ -2181,6 +2349,11 @@ class ChromeDocument extends Document {
2181
2349
  }
2182
2350
  }
2183
2351
  source = removeNamespace(moduleName, domBase.modified ? domBase.close() : source, domBase.newline, domBase.getComments());
2352
+ if (this.sanitizeFramework) {
2353
+ for (const name of this.sanitizeFramework) {
2354
+ source = source.replace(name === '*' ? REGEXP_SANITIZEALL : new RegExp(`(?:\\s+|\\b)data-(?:${(0, types_1.escapePattern)(name)}-[^=\\s]+|.+?-${(0, types_1.escapePattern)(name)})\\s*${dom_1.DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g'), '');
2355
+ }
2356
+ }
2184
2357
  if (!htmlFile.preserve) {
2185
2358
  let match;
2186
2359
  while (match = REGEXP_STYLE.exec(source)) {
@@ -2190,10 +2363,10 @@ class ChromeDocument extends Document {
2190
2363
  }
2191
2364
  REGEXP_STYLE.lastIndex = 0;
2192
2365
  }
2193
- if (output = transformURL.call(this, host, htmlFile, 'html', source)) {
2366
+ if (output = transformURL(this, host, htmlFile, 'html', source)) {
2194
2367
  source = output;
2195
2368
  }
2196
- source = replaceHtml.call(this, source, processing, htmlFile.inlineUrlMap);
2369
+ source = replaceHtml(this, source, processing, htmlFile.inlineUrlMap);
2197
2370
  if ((0, types_1.isString)(config.stripCommentsAndCDATA)) {
2198
2371
  source = dom_1.DomWriter.getCommentsAndCDATA(source, config.stripCommentsAndCDATA, true, true);
2199
2372
  }
@@ -2203,7 +2376,7 @@ class ChromeDocument extends Document {
2203
2376
  const result = await this.transform('html', source, format, {
2204
2377
  pathname: path.dirname(localUri),
2205
2378
  filename,
2206
- mimeType: 'text/html',
2379
+ mimeType: "text/html",
2207
2380
  metadata: Object.assign({ '__fromhtml__': true, ...this.config }, metadata),
2208
2381
  cacheData: !productionRelease || this.productionIncremental ? { uri, encoding } : undefined
2209
2382
  });
@@ -2213,17 +2386,21 @@ class ChromeDocument extends Document {
2213
2386
  }
2214
2387
  if (domBase.hasErrors()) {
2215
2388
  const timeStamp = Date.now();
2216
- domBase.errors.forEach(err => this.addLog(types_1.STATUS_TYPE.WARN, 'dom-writer -> ' + err.message, timeStamp));
2389
+ for (const err of domBase.errors) {
2390
+ this.addLog(types_1.STATUS_TYPE.WARN, 'dom-writer: ' + err.message, timeStamp);
2391
+ }
2217
2392
  }
2218
2393
  if (domBase.failCount > 0) {
2219
2394
  this.writeFail(['Unable to update document', moduleName], (0, types_1.errorMessage)('html', 'DOM rewrite failed', domBase.failCount + ' errors'), { type: 4, startTime });
2220
2395
  }
2221
2396
  else {
2222
- this.writeTimeProcess('html', `dom-writer (${domBase.modifyCount} modified) -> ` + path.basename(localUri), startTime);
2223
- if (cacheMiss.length) {
2397
+ this.writeTimeProcess('html', `dom-writer: ${domBase.modifyCount} modified > ` + path.basename(localUri), startTime);
2398
+ if (cacheMiss.length > 0) {
2224
2399
  const data = {};
2225
2400
  const message = [];
2226
- cacheMiss.forEach(name => data[name] = (data[name] || 0) + 1);
2401
+ for (const name of cacheMiss) {
2402
+ data[name] = (data[name] || 0) + 1;
2403
+ }
2227
2404
  for (const name in data) {
2228
2405
  message.push(name + `(${data[name]})`);
2229
2406
  }
@@ -2247,7 +2424,7 @@ class ChromeDocument extends Document {
2247
2424
  let [innerXml, sourceMappingURL, inlineMap] = transform_1.SourceMap.removeSourceMappingURL(host.getUTF8String(item).trim());
2248
2425
  if (sourceMappingURL && !inlineMap && item.localUri) {
2249
2426
  let mapUri = path.resolve(sourceMappingURL = decodeURIComponent(sourceMappingURL));
2250
- if (!isPath(mapUri)) {
2427
+ if (!Document.isPath(mapUri)) {
2251
2428
  mapUri = path.join(path.dirname(item.localUri), sourceMappingURL);
2252
2429
  }
2253
2430
  host.deleteFile(mapUri);
@@ -2270,7 +2447,7 @@ class ChromeDocument extends Document {
2270
2447
  }
2271
2448
  if (uri && !(0, util_1.hasValue)(item.format, 'crossorigin') && item !== htmlFile) {
2272
2449
  if (cloud?.getStorage('upload', item.cloudStorage)) {
2273
- const inlineUrlCloud = item.inlineUrlCloud ||= (0, types_1.generateUUID)();
2450
+ const inlineUrlCloud = item.inlineUrlCloud ||= (0, crypto_1.randomUUID)();
2274
2451
  (htmlFile.inlineUrlCloudMap ||= {})[inlineUrlCloud] = productionRelease ? this.removeServerRoot(uri) : uri;
2275
2452
  uri = inlineUrlCloud;
2276
2453
  }
@@ -2301,7 +2478,9 @@ class ChromeDocument extends Document {
2301
2478
  const detectHeight = domElement.getAttribute('height') === 'detect';
2302
2479
  if (detectWidth || detectHeight) {
2303
2480
  let width = 0, height = 0, buffer = null, packageName;
2304
- const addLog = (dimension) => this.addLog(types_1.STATUS_TYPE.WARN, 'Could not detect image ' + dimension, packageName || this.moduleName, item.localUri ? path.basename(item.localUri) : item.filename);
2481
+ const addLog = (dimension) => {
2482
+ this.addLog(types_1.STATUS_TYPE.WARN, 'Could not detect image ' + dimension, packageName || this.moduleName, item.localUri ? path.basename(item.localUri) : item.filename);
2483
+ };
2305
2484
  if (isImage(item.mimeType) && (buffer = host.getBuffer(item))) {
2306
2485
  try {
2307
2486
  ({ width, height } = require(packageName = 'image-size').imageSize(buffer));
@@ -2358,29 +2537,20 @@ class ChromeDocument extends Document {
2358
2537
  if (this.dataSource.length === 0) {
2359
2538
  return;
2360
2539
  }
2361
- const { moduleName, Db: db } = this;
2540
+ const db = this.Db;
2362
2541
  const cloud = host.Cloud;
2363
- const sessionKey = (0, types_1.generateUUID)();
2542
+ const sessionKey = (0, crypto_1.randomUUID)();
2364
2543
  const cacheData = Object.create(null);
2365
- const coerceMap = {};
2366
2544
  const dataItems = [];
2367
2545
  const displayItems = [];
2368
- this.dataSource.forEach(item => item.type === 'display' ? displayItems.push(item) : dataItems.push(item));
2369
- const removeElement = (item, element) => {
2370
- if (item.removeEmpty || item.type === 'display') {
2371
- (element ||= new dom_1.HtmlElement(moduleName, item.element)).remove = true;
2372
- if (!domBase.write(element)) {
2373
- this.writeFail('Unable to remove element', errorHtml(item.element), { type: 4, startTime });
2374
- }
2546
+ for (const item of this.dataSource) {
2547
+ if (item.type === 'display') {
2548
+ displayItems.push(item);
2375
2549
  }
2376
- };
2377
- const errorCredential = (item, err) => {
2378
- removeElement(item);
2379
- const pkg = getPackageName(err);
2380
- if (!(pkg && this.checkPackage(err, pkg))) {
2381
- this.writeFail(["Invalid credentials", item.source], err);
2550
+ else {
2551
+ dataItems.push(item);
2382
2552
  }
2383
- };
2553
+ }
2384
2554
  const checkObject = (item, data, type) => {
2385
2555
  const { query, cascade } = item;
2386
2556
  if ((0, types_1.isString)(cascade)) {
@@ -2411,7 +2581,7 @@ class ChromeDocument extends Document {
2411
2581
  this.checkPackage(err, pkg, ["Unable to filter results", item.source]);
2412
2582
  }
2413
2583
  }
2414
- if (type && !item.ignoreCoerce && (coerceMap[type] ??= this.settingsOf(type, 'coerce') === true)) {
2584
+ if (type && !item.ignoreCoerce && this.settingsOf(type, 'coerce') === true) {
2415
2585
  (0, types_1.coerceObject)(data);
2416
2586
  }
2417
2587
  }
@@ -2422,7 +2592,7 @@ class ChromeDocument extends Document {
2422
2592
  const batchGroup = [];
2423
2593
  for (const item of sourceSet) {
2424
2594
  if (!item.element) {
2425
- this.addLog(types_1.STATUS_TYPE.WARN, `Missing target element {${JSON.stringify(item)}}`);
2595
+ this.addLog(types_1.STATUS_TYPE.WARN, `dom-writer: Missing target element {${JSON.stringify(item)}}`);
2426
2596
  continue;
2427
2597
  }
2428
2598
  const type = item.source;
@@ -2430,11 +2600,11 @@ class ChromeDocument extends Document {
2430
2600
  case 'cloud': {
2431
2601
  const { service, credential } = item;
2432
2602
  if (cloud) {
2433
- const key = service + '_' + (service === 'atlas' && item.uri || '') + '_' + asString(credential, true);
2603
+ const key = service + '_' + (service === 'atlas' && item.uri || '') + '_' + Document.asString(credential, true);
2434
2604
  (batchMap[key] ||= []).push(item);
2435
2605
  }
2436
2606
  else {
2437
- errorCredential(item, (0, types_1.errorValue)("Cloud module not installed", service));
2607
+ errorCredential(this, domBase, item, (0, types_1.errorValue)("Cloud module not installed", service));
2438
2608
  }
2439
2609
  break;
2440
2610
  }
@@ -2464,11 +2634,11 @@ class ChromeDocument extends Document {
2464
2634
  (batchMap[key] ||= []).push(item);
2465
2635
  }
2466
2636
  catch (err) {
2467
- errorCredential(item, err);
2637
+ errorCredential(this, domBase, item, err);
2468
2638
  }
2469
2639
  }
2470
2640
  else {
2471
- errorCredential(item, (0, types_1.errorValue)(db ? "Database provider not found" : "Db module not installed", type));
2641
+ errorCredential(this, domBase, item, (0, types_1.errorValue)(db ? "Database provider not found" : "Db module not installed", type));
2472
2642
  }
2473
2643
  break;
2474
2644
  }
@@ -2479,11 +2649,11 @@ class ChromeDocument extends Document {
2479
2649
  return this.allSettled(batchGroup.map(async (batch) => {
2480
2650
  return new Promise(async (resolve, reject) => {
2481
2651
  const errorRemove = (item, reason) => {
2482
- removeElement(item);
2652
+ removeElement(this, domBase, item);
2483
2653
  reject(reason);
2484
2654
  };
2485
2655
  const errorClient = (item, reason) => {
2486
- removeElement(item);
2656
+ removeElement(this, domBase, item);
2487
2657
  if (reason) {
2488
2658
  this.writeFail(["Unable to configure client", item.source], reason);
2489
2659
  }
@@ -2535,7 +2705,7 @@ class ChromeDocument extends Document {
2535
2705
  }
2536
2706
  catch (err) {
2537
2707
  this.abort(type);
2538
- this.writeFail(["Unable to read file", path.basename(location)], err, { type: 32, startTime });
2708
+ this.writeFail(["Unable to read file", path.basename(location)], err, 32);
2539
2709
  errorRemove(current);
2540
2710
  return;
2541
2711
  }
@@ -2605,7 +2775,7 @@ class ChromeDocument extends Document {
2605
2775
  }
2606
2776
  catch (err) {
2607
2777
  this.abort(type);
2608
- this.writeFail(["Unable to read file", path.basename(pathname)], err, { type: 32, startTime });
2778
+ this.writeFail(["Unable to read file", path.basename(pathname)], err, 32);
2609
2779
  errorRemove(current);
2610
2780
  return;
2611
2781
  }
@@ -2622,7 +2792,7 @@ class ChromeDocument extends Document {
2622
2792
  }
2623
2793
  catch (err) {
2624
2794
  this.abort(type);
2625
- this.writeFail(["Unable to parse inline object", format], err, { type: 4, startTime });
2795
+ this.writeFail(["Unable to parse inline object", format], err, 4);
2626
2796
  errorRemove(current);
2627
2797
  return;
2628
2798
  }
@@ -2637,7 +2807,7 @@ class ChromeDocument extends Document {
2637
2807
  return;
2638
2808
  }
2639
2809
  if (cacheKey) {
2640
- setCacheData.call(this, current, data, cacheKey, cacheData);
2810
+ setCacheData(this, current, data, cacheKey, cacheData);
2641
2811
  }
2642
2812
  if ((result[0] = checkObject(current, data, type)) === null) {
2643
2813
  this.abort(type);
@@ -2647,7 +2817,7 @@ class ChromeDocument extends Document {
2647
2817
  break;
2648
2818
  }
2649
2819
  case 'export': {
2650
- const cacheKey = asString(current, true);
2820
+ const cacheKey = Document.asString(current, true);
2651
2821
  if (!current.ignoreCache && CACHE_DBRESULT.has(cacheKey)) {
2652
2822
  result[0] = getCacheItem(CACHE_DBRESULT, cacheKey);
2653
2823
  }
@@ -2672,7 +2842,7 @@ class ChromeDocument extends Document {
2672
2842
  target = pathname;
2673
2843
  hint = pathname;
2674
2844
  }
2675
- else if ((target = this.resolveDir(type, pathname)) && (getData = core_1.ClientDb.parseFunction(target, true))) {
2845
+ else if ((target = this.resolveDir(type, pathname)) && (getData = Document.parseFunction(target, true))) {
2676
2846
  hint = pathname;
2677
2847
  }
2678
2848
  else {
@@ -2722,7 +2892,7 @@ class ChromeDocument extends Document {
2722
2892
  });
2723
2893
  }
2724
2894
  }
2725
- setCacheData.call(this, current, data, cacheKey, cacheData);
2895
+ setCacheData(this, current, data, cacheKey, cacheData);
2726
2896
  }
2727
2897
  catch (err) {
2728
2898
  this.abort(type);
@@ -2767,10 +2937,10 @@ class ChromeDocument extends Document {
2767
2937
  }
2768
2938
  if (!(search.schema = cacheData[pathname])) {
2769
2939
  try {
2770
- search.schema = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding);
2940
+ search.schema = loadLocalFile(this, current, pathname, cacheData, cmd.encoding);
2771
2941
  }
2772
2942
  catch (err) {
2773
- this.writeFail(['Unable to parse document', path.basename(pathname)], err instanceof Error ? errors = err : err, { startTime });
2943
+ this.writeFail(['Unable to parse document', path.basename(pathname)], err instanceof Error ? errors = err : err, 32);
2774
2944
  search.schema = undefined;
2775
2945
  }
2776
2946
  }
@@ -2804,10 +2974,10 @@ class ChromeDocument extends Document {
2804
2974
  if (!(cmd.query = cacheData[pathname])) {
2805
2975
  const out = { content: '' };
2806
2976
  try {
2807
- cmd.query = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding, out);
2977
+ cmd.query = loadLocalFile(this, current, pathname, cacheData, cmd.encoding, out);
2808
2978
  }
2809
2979
  catch {
2810
- setCacheData.call(this, current, cmd.query = out.content, pathname, cacheData, true);
2980
+ setCacheData(this, current, cmd.query = out.content, pathname, cacheData, true);
2811
2981
  }
2812
2982
  }
2813
2983
  }
@@ -2818,7 +2988,7 @@ class ChromeDocument extends Document {
2818
2988
  }
2819
2989
  catch (err) {
2820
2990
  this.abort(type);
2821
- this.writeFail(["Unable to read file", pathname ? path.basename(pathname) : query], err, { startTime });
2991
+ this.writeFail(["Unable to read file", pathname ? path.basename(pathname) : query], err, 32);
2822
2992
  errorRemove(current);
2823
2993
  return;
2824
2994
  }
@@ -2835,7 +3005,7 @@ class ChromeDocument extends Document {
2835
3005
  }
2836
3006
  else if (db.hasSource(type, db.sourceType.KEYVALUE)) {
2837
3007
  aborting = commandType !== db.commandType.UPDATE;
2838
- message = asString(data.search || data.key);
3008
+ message = Document.asString(data.search || data.key);
2839
3009
  }
2840
3010
  else {
2841
3011
  const credential = data.credential;
@@ -2874,7 +3044,7 @@ class ChromeDocument extends Document {
2874
3044
  const empty = (items = result[i]) === null;
2875
3045
  if ((items ||= []).length === 0) {
2876
3046
  if (whenEmpty) {
2877
- const data = await checkData.call(this, item, whenEmpty, items, row => Array.isArray(row));
3047
+ const data = await checkData(this, item, whenEmpty, items, row => Array.isArray(row));
2878
3048
  if (data) {
2879
3049
  items = data;
2880
3050
  item.transactionFail = false;
@@ -2892,22 +3062,21 @@ class ChromeDocument extends Document {
2892
3062
  items = items.slice(0, limit);
2893
3063
  }
2894
3064
  if (postQuery) {
2895
- const data = await checkData.call(this, item, postQuery, items = items.slice(0), row => Array.isArray(row));
3065
+ const data = await checkData(this, item, postQuery, items = items.slice(0), row => Array.isArray(row));
2896
3066
  if (data) {
2897
3067
  items = data;
2898
3068
  }
2899
3069
  }
2900
- if (items.length && !item.transactionFail) {
3070
+ if (items.length > 0 && !item.transactionFail) {
2901
3071
  const { element, preRender } = item;
2902
- const domElement = new dom_1.HtmlElement(moduleName, element);
3072
+ const domElement = new dom_1.HtmlElement(this.moduleName, element);
2903
3073
  let value = '';
2904
3074
  const checkValue = async (name) => {
2905
- const data = await checkData.call(this, item, name, value, row => typeof row === 'string');
3075
+ const data = await checkData(this, item, name, value, row => typeof row === 'string');
2906
3076
  if (data) {
2907
3077
  value = data;
2908
3078
  }
2909
3079
  };
2910
- const valueAsString = (data, joinString) => Array.isArray(data) && !data.some(child => typeof child === 'object') ? data.join(joinString) : asString(data);
2911
3080
  if (item.template) {
2912
3081
  const pathname = this.resolveDir('template', item.template);
2913
3082
  if (pathname) {
@@ -2921,10 +3090,10 @@ class ChromeDocument extends Document {
2921
3090
  if (!(item.value = cacheData[pathname])) {
2922
3091
  try {
2923
3092
  item.value = fs.readFileSync(pathname, item.encoding || 'utf-8');
2924
- setCacheData.call(this, item, item.value, pathname, cacheData, true);
3093
+ setCacheData(this, item, item.value, pathname, cacheData, true);
2925
3094
  }
2926
3095
  catch (err) {
2927
- this.writeFail(["Unable to read file", path.basename(pathname)], err, { type: 32, startTime });
3096
+ this.writeFail(["Unable to read file", path.basename(pathname)], err, 32);
2928
3097
  errors = true;
2929
3098
  }
2930
3099
  }
@@ -2943,7 +3112,7 @@ class ChromeDocument extends Document {
2943
3112
  const content = await this.parseTemplate(item.viewEngine, template, items);
2944
3113
  if (content === null) {
2945
3114
  ++domBase.failCount;
2946
- removeElement(item, domElement);
3115
+ removeElement(this, domBase, item, domElement);
2947
3116
  if (length === 1) {
2948
3117
  resolve();
2949
3118
  return;
@@ -2971,7 +3140,7 @@ class ChromeDocument extends Document {
2971
3140
  continue;
2972
3141
  }
2973
3142
  try {
2974
- let content = new Function('return ' + literal + ';').call(row);
3143
+ let content = new Function('return ' + literal + ';')(row);
2975
3144
  if (!segment.startsWith('`')) {
2976
3145
  content = segment.substring(0, segment.indexOf('`')) + content;
2977
3146
  }
@@ -3042,7 +3211,7 @@ class ChromeDocument extends Document {
3042
3211
  for (const row of items) {
3043
3212
  for (let seg of segment) {
3044
3213
  seg = seg.trim();
3045
- if (seg.startsWith(':') && (match = /^:join\(([\S\s]*)\)$/i.exec(seg))) {
3214
+ if (seg.startsWith(':') && (match = /^:join\((.*)\)$/is.exec(seg))) {
3046
3215
  joinString = match[1];
3047
3216
  continue;
3048
3217
  }
@@ -3051,7 +3220,7 @@ class ChromeDocument extends Document {
3051
3220
  valid = true;
3052
3221
  }
3053
3222
  if (seg) {
3054
- if (match = /^:text\(([\S\s]*)\)$/i.exec(seg)) {
3223
+ if (match = /^:text\((.*)\)$/is.exec(seg)) {
3055
3224
  value += (value ? joinString : '') + match[1];
3056
3225
  valid = true;
3057
3226
  }
@@ -3188,7 +3357,7 @@ class ChromeDocument extends Document {
3188
3357
  break;
3189
3358
  }
3190
3359
  default:
3191
- removeElement(item, domElement);
3360
+ removeElement(this, domBase, item, domElement);
3192
3361
  if (length === 1) {
3193
3362
  reject(errorDataSource('Invalid action', item.type || "Unknown"));
3194
3363
  return;
@@ -3209,18 +3378,18 @@ class ChromeDocument extends Document {
3209
3378
  switch (item.source) {
3210
3379
  case 'cloud': {
3211
3380
  const { service, table, id, query } = item;
3212
- const queryString = (table ? 'table=' + table : '') + (id || query ? (table ? ';' : '') + (id ? 'id=' + id : 'query=' + asString(query)) : '');
3381
+ const queryString = (table ? 'table=' + table : '') + (id || query ? (table ? ';' : '') + (id ? 'id=' + id : 'query=' + Document.asString(query)) : '');
3213
3382
  (cloud || this).formatFail(64, service, ["Unable to execute query", queryString], emptyResponse(queryString, service), { ...Cloud.LOG_CLOUD_FAIL, startTime });
3214
3383
  break;
3215
3384
  }
3216
3385
  case 'uri': {
3217
3386
  const { uri, format = uri && path.extname(uri).substring(1) } = item;
3218
- this.formatFail(4, format || 'URI', ['No records were found', uri], emptyResponse(uri), { startTime });
3387
+ this.formatFail(4, format || 'URI', ['No records were found', uri], emptyResponse(uri));
3219
3388
  break;
3220
3389
  }
3221
3390
  case 'local': {
3222
3391
  const { pathname, format = pathname && path.extname(pathname).substring(1) } = item;
3223
- this.formatFail(4, format || 'LOCAL', ['No records were found', pathname], emptyResponse(pathname), { startTime });
3392
+ this.formatFail(4, format || 'LOCAL', ['No records were found', pathname], emptyResponse(pathname));
3224
3393
  break;
3225
3394
  }
3226
3395
  case 'export': {
@@ -3229,22 +3398,22 @@ class ChromeDocument extends Document {
3229
3398
  if (typeof target === 'function') {
3230
3399
  target = target.name;
3231
3400
  }
3232
- this.formatFail(4, 'EXPORT', ['No records were retrieved', target], emptyResponse(target), { startTime });
3401
+ this.formatFail(4, 'EXPORT', ['No records were retrieved', target], emptyResponse(target));
3233
3402
  break;
3234
3403
  }
3235
3404
  }
3236
3405
  }
3237
- removeElement(item);
3406
+ removeElement(this, domBase, item);
3238
3407
  }
3239
3408
  }
3240
3409
  resolve();
3241
3410
  });
3242
3411
  }), 'Element text or attribute replacement');
3243
3412
  };
3244
- if (dataItems.length) {
3413
+ if (dataItems.length > 0) {
3245
3414
  await setElements(dataItems);
3246
3415
  }
3247
- if (displayItems.length) {
3416
+ if (displayItems.length > 0) {
3248
3417
  await setElements(displayItems);
3249
3418
  }
3250
3419
  }
@@ -3486,7 +3655,7 @@ class ChromeDocument extends Document {
3486
3655
  while (bracket = pattern.exec(current)) {
3487
3656
  const segment = bracket[0];
3488
3657
  if (/[{}]/.test(segment)) {
3489
- const placeholder = '`' + (0, types_1.generateUUID)() + '`';
3658
+ const placeholder = '`' + (0, crypto_1.randomUUID)() + '`';
3490
3659
  replaceMap.push([placeholder, segment]);
3491
3660
  current = replaceMatch(bracket, current, placeholder, pattern);
3492
3661
  }
@@ -3498,11 +3667,11 @@ class ChromeDocument extends Document {
3498
3667
  const values = (0, util_1.splitEnclosing)(current, /\burl/gi);
3499
3668
  for (let i = 0, length = values.length; i < length; ++i) {
3500
3669
  const seg = values[i];
3501
- if (/^url\([^{}]*[{}][\S\s]*\)$/i.test(seg)) {
3502
- replaceMap.push([values[i] = (0, types_1.generateUUID)(), seg]);
3670
+ if (/^url\([^{}]*[{}].*\)$/is.test(seg)) {
3671
+ replaceMap.push([values[i] = (0, crypto_1.randomUUID)(), seg]);
3503
3672
  }
3504
3673
  }
3505
- if (replaceMap.length) {
3674
+ if (replaceMap.length > 0) {
3506
3675
  current = values.join('');
3507
3676
  }
3508
3677
  }
@@ -3571,7 +3740,7 @@ class ChromeDocument extends Document {
3571
3740
  invalid = 1;
3572
3741
  break;
3573
3742
  }
3574
- else if (leading !== -1 && empty[1] === ';') {
3743
+ if (leading !== -1 && empty[1] === ';') {
3575
3744
  content = target.substring(index, found).substring(0, leading).replace(/[^\n;]+$/, '');
3576
3745
  invalid = 1;
3577
3746
  break;
@@ -3647,7 +3816,7 @@ class ChromeDocument extends Document {
3647
3816
  const fontFamily = useUnsafeCssReplace ? REGEXP_FONTFAMILY_UNSAFE : REGEXP_FONTFAMILY;
3648
3817
  while (match = pattern.exec(current)) {
3649
3818
  const font = fontFamily.exec(match[0]);
3650
- if (font && !usedFontFace.includes(font[1].trim().replace(/^(["'])([\S\s]+)\1$/, (...content) => content[2]))) {
3819
+ if (font && !usedFontFace.includes(font[1].trim().replace(/^(["'])(.+)\1$/s, (...content) => content[2]))) {
3651
3820
  current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[3]);
3652
3821
  modified = true;
3653
3822
  }
@@ -3675,7 +3844,7 @@ class ChromeDocument extends Document {
3675
3844
  }
3676
3845
  pattern.lastIndex = 0;
3677
3846
  }
3678
- if (replaceMap.length) {
3847
+ if (replaceMap.length > 0) {
3679
3848
  for (const [placeholder, content] of replaceMap.reverse()) {
3680
3849
  current = current.replace(placeholder, content);
3681
3850
  }
@@ -3692,21 +3861,23 @@ class ChromeDocument extends Document {
3692
3861
  const host = this.host;
3693
3862
  const restartable = host ? host.restartable || this.watching : false;
3694
3863
  const idMap = this._idMap;
3695
- this.assets.forEach(item => {
3864
+ for (const item of this.assets) {
3696
3865
  const { element, id, flags } = item;
3697
3866
  if (element) {
3698
3867
  if (restartable && id && !(0, types_1.cloneFlag)(flags)) {
3699
3868
  const backup = idMap[id];
3700
3869
  if (backup) {
3701
3870
  elements.add(item.element = (0, types_1.cloneObject)(backup, true));
3702
- return;
3871
+ continue;
3703
3872
  }
3704
3873
  idMap[id] = (0, types_1.cloneObject)(element, true);
3705
3874
  }
3706
3875
  elements.add(element);
3707
3876
  }
3708
- });
3709
- this.dataSource.forEach(item => elements.add(item.element));
3877
+ }
3878
+ for (const item of this.dataSource) {
3879
+ elements.add(item.element);
3880
+ }
3710
3881
  return this._elements = Array.from(elements);
3711
3882
  }
3712
3883
  get editing() {
@@ -3718,18 +3889,13 @@ class ChromeDocument extends Document {
3718
3889
  }
3719
3890
  }
3720
3891
  get dataSource() {
3721
- const result = this._dataSource;
3722
- if (result) {
3723
- return result;
3892
+ if (this._dataSource) {
3893
+ return this._dataSource;
3724
3894
  }
3725
3895
  const host = this.host;
3726
3896
  if (host) {
3727
- try {
3728
- const items = host.getDataSourceItems(this);
3729
- return this._dataSource = host.restartable || this.watching ? items.map(item => (0, types_1.cloneObject)(item, true)) : items;
3730
- }
3731
- catch {
3732
- }
3897
+ const items = host.getDataSourceItems(this);
3898
+ return this._dataSource = host.restartable || this.watching ? items.map(item => (0, types_1.cloneObject)(item, true)) : items;
3733
3899
  }
3734
3900
  return [];
3735
3901
  }