FRE-709: Document duplicate recovery wake - FRE-635 already recovered via FRE-708
This commit is contained in:
325
node_modules/postal-mime/dist/address-parser.cjs
generated
vendored
Normal file
325
node_modules/postal-mime/dist/address-parser.cjs
generated
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var address_parser_exports = {};
|
||||
__export(address_parser_exports, {
|
||||
default: () => address_parser_default
|
||||
});
|
||||
module.exports = __toCommonJS(address_parser_exports);
|
||||
var import_decode_strings = require("./decode-strings.cjs");
|
||||
function _handleAddress(tokens, depth) {
|
||||
let isGroup = false;
|
||||
let state = "text";
|
||||
let address;
|
||||
let addresses = [];
|
||||
let data = {
|
||||
address: [],
|
||||
comment: [],
|
||||
group: [],
|
||||
text: [],
|
||||
textWasQuoted: []
|
||||
// Track which text tokens came from inside quotes
|
||||
};
|
||||
let i;
|
||||
let len;
|
||||
let insideQuotes = false;
|
||||
for (i = 0, len = tokens.length; i < len; i++) {
|
||||
let token = tokens[i];
|
||||
let prevToken = i ? tokens[i - 1] : null;
|
||||
if (token.type === "operator") {
|
||||
switch (token.value) {
|
||||
case "<":
|
||||
state = "address";
|
||||
insideQuotes = false;
|
||||
break;
|
||||
case "(":
|
||||
state = "comment";
|
||||
insideQuotes = false;
|
||||
break;
|
||||
case ":":
|
||||
state = "group";
|
||||
isGroup = true;
|
||||
insideQuotes = false;
|
||||
break;
|
||||
case '"':
|
||||
insideQuotes = !insideQuotes;
|
||||
state = "text";
|
||||
break;
|
||||
default:
|
||||
state = "text";
|
||||
insideQuotes = false;
|
||||
break;
|
||||
}
|
||||
} else if (token.value) {
|
||||
if (state === "address") {
|
||||
token.value = token.value.replace(/^[^<]*<\s*/, "");
|
||||
}
|
||||
if (prevToken && prevToken.noBreak && data[state].length) {
|
||||
data[state][data[state].length - 1] += token.value;
|
||||
if (state === "text" && insideQuotes) {
|
||||
data.textWasQuoted[data.textWasQuoted.length - 1] = true;
|
||||
}
|
||||
} else {
|
||||
data[state].push(token.value);
|
||||
if (state === "text") {
|
||||
data.textWasQuoted.push(insideQuotes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!data.text.length && data.comment.length) {
|
||||
data.text = data.comment;
|
||||
data.comment = [];
|
||||
}
|
||||
if (isGroup) {
|
||||
data.text = data.text.join(" ");
|
||||
let groupMembers = [];
|
||||
if (data.group.length) {
|
||||
let parsedGroup = addressParser(data.group.join(","), { _depth: depth + 1 });
|
||||
parsedGroup.forEach((member) => {
|
||||
if (member.group) {
|
||||
groupMembers = groupMembers.concat(member.group);
|
||||
} else {
|
||||
groupMembers.push(member);
|
||||
}
|
||||
});
|
||||
}
|
||||
addresses.push({
|
||||
name: (0, import_decode_strings.decodeWords)(data.text || address && address.name),
|
||||
group: groupMembers
|
||||
});
|
||||
} else {
|
||||
if (!data.address.length && data.text.length) {
|
||||
for (i = data.text.length - 1; i >= 0; i--) {
|
||||
if (!data.textWasQuoted[i] && data.text[i].match(/^[^@\s]+@[^@\s]+$/)) {
|
||||
data.address = data.text.splice(i, 1);
|
||||
data.textWasQuoted.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let _regexHandler = function(address2) {
|
||||
if (!data.address.length) {
|
||||
data.address = [address2.trim()];
|
||||
return " ";
|
||||
} else {
|
||||
return address2;
|
||||
}
|
||||
};
|
||||
if (!data.address.length) {
|
||||
for (i = data.text.length - 1; i >= 0; i--) {
|
||||
if (!data.textWasQuoted[i]) {
|
||||
data.text[i] = data.text[i].replace(/\s*\b[^@\s]+@[^\s]+\b\s*/, _regexHandler).trim();
|
||||
if (data.address.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!data.text.length && data.comment.length) {
|
||||
data.text = data.comment;
|
||||
data.comment = [];
|
||||
}
|
||||
if (data.address.length > 1) {
|
||||
data.text = data.text.concat(data.address.splice(1));
|
||||
}
|
||||
data.text = data.text.join(" ");
|
||||
data.address = data.address.join(" ");
|
||||
if (!data.address && /^=\?[^=]+?=$/.test(data.text.trim())) {
|
||||
const decodedText = (0, import_decode_strings.decodeWords)(data.text);
|
||||
if (/<[^<>]+@[^<>]+>/.test(decodedText)) {
|
||||
const parsedSubAddresses = addressParser(decodedText);
|
||||
if (parsedSubAddresses && parsedSubAddresses.length) {
|
||||
return parsedSubAddresses;
|
||||
}
|
||||
}
|
||||
return [{ address: "", name: decodedText }];
|
||||
}
|
||||
address = {
|
||||
address: data.address || data.text || "",
|
||||
name: (0, import_decode_strings.decodeWords)(data.text || data.address || "")
|
||||
};
|
||||
if (address.address === address.name) {
|
||||
if ((address.address || "").match(/@/)) {
|
||||
address.name = "";
|
||||
} else {
|
||||
address.address = "";
|
||||
}
|
||||
}
|
||||
addresses.push(address);
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
class Tokenizer {
|
||||
constructor(str) {
|
||||
this.str = (str || "").toString();
|
||||
this.operatorCurrent = "";
|
||||
this.operatorExpecting = "";
|
||||
this.node = null;
|
||||
this.escaped = false;
|
||||
this.list = [];
|
||||
this.operators = {
|
||||
'"': '"',
|
||||
"(": ")",
|
||||
"<": ">",
|
||||
",": "",
|
||||
":": ";",
|
||||
// Semicolons are not a legal delimiter per the RFC2822 grammar other
|
||||
// than for terminating a group, but they are also not valid for any
|
||||
// other use in this context. Given that some mail clients have
|
||||
// historically allowed the semicolon as a delimiter equivalent to the
|
||||
// comma in their UI, it makes sense to treat them the same as a comma
|
||||
// when used outside of a group.
|
||||
";": ""
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Tokenizes the original input string
|
||||
*
|
||||
* @return {Array} An array of operator|text tokens
|
||||
*/
|
||||
tokenize() {
|
||||
let list = [];
|
||||
for (let i = 0, len = this.str.length; i < len; i++) {
|
||||
let chr = this.str.charAt(i);
|
||||
let nextChr = i < len - 1 ? this.str.charAt(i + 1) : null;
|
||||
this.checkChar(chr, nextChr);
|
||||
}
|
||||
this.list.forEach((node) => {
|
||||
node.value = (node.value || "").toString().trim();
|
||||
if (node.value) {
|
||||
list.push(node);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
/**
|
||||
* Checks if a character is an operator or text and acts accordingly
|
||||
*
|
||||
* @param {String} chr Character from the address field
|
||||
*/
|
||||
checkChar(chr, nextChr) {
|
||||
if (this.escaped) {
|
||||
} else if (chr === this.operatorExpecting) {
|
||||
this.node = {
|
||||
type: "operator",
|
||||
value: chr
|
||||
};
|
||||
if (nextChr && ![" ", " ", "\r", "\n", ",", ";"].includes(nextChr)) {
|
||||
this.node.noBreak = true;
|
||||
}
|
||||
this.list.push(this.node);
|
||||
this.node = null;
|
||||
this.operatorExpecting = "";
|
||||
this.escaped = false;
|
||||
return;
|
||||
} else if (!this.operatorExpecting && chr in this.operators) {
|
||||
this.node = {
|
||||
type: "operator",
|
||||
value: chr
|
||||
};
|
||||
this.list.push(this.node);
|
||||
this.node = null;
|
||||
this.operatorExpecting = this.operators[chr];
|
||||
this.escaped = false;
|
||||
return;
|
||||
} else if (this.operatorExpecting === '"' && chr === "\\") {
|
||||
this.escaped = true;
|
||||
return;
|
||||
}
|
||||
if (!this.node) {
|
||||
this.node = {
|
||||
type: "text",
|
||||
value: ""
|
||||
};
|
||||
this.list.push(this.node);
|
||||
}
|
||||
if (chr === "\n") {
|
||||
chr = " ";
|
||||
}
|
||||
if (chr.charCodeAt(0) >= 33 || [" ", " "].includes(chr)) {
|
||||
this.node.value += chr;
|
||||
}
|
||||
this.escaped = false;
|
||||
}
|
||||
}
|
||||
const MAX_NESTED_GROUP_DEPTH = 50;
|
||||
function addressParser(str, options) {
|
||||
options = options || {};
|
||||
let depth = options._depth || 0;
|
||||
if (depth > MAX_NESTED_GROUP_DEPTH) {
|
||||
return [];
|
||||
}
|
||||
let tokenizer = new Tokenizer(str);
|
||||
let tokens = tokenizer.tokenize();
|
||||
let addresses = [];
|
||||
let address = [];
|
||||
let parsedAddresses = [];
|
||||
tokens.forEach((token) => {
|
||||
if (token.type === "operator" && (token.value === "," || token.value === ";")) {
|
||||
if (address.length) {
|
||||
addresses.push(address);
|
||||
}
|
||||
address = [];
|
||||
} else {
|
||||
address.push(token);
|
||||
}
|
||||
});
|
||||
if (address.length) {
|
||||
addresses.push(address);
|
||||
}
|
||||
addresses.forEach((address2) => {
|
||||
address2 = _handleAddress(address2, depth);
|
||||
if (address2.length) {
|
||||
parsedAddresses = parsedAddresses.concat(address2);
|
||||
}
|
||||
});
|
||||
if (options.flatten) {
|
||||
let addresses2 = [];
|
||||
let walkAddressList = (list) => {
|
||||
list.forEach((address2) => {
|
||||
if (address2.group) {
|
||||
return walkAddressList(address2.group);
|
||||
} else {
|
||||
addresses2.push(address2);
|
||||
}
|
||||
});
|
||||
};
|
||||
walkAddressList(parsedAddresses);
|
||||
return addresses2;
|
||||
}
|
||||
return parsedAddresses;
|
||||
}
|
||||
var address_parser_default = addressParser;
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
75
node_modules/postal-mime/dist/base64-decoder.cjs
generated
vendored
Normal file
75
node_modules/postal-mime/dist/base64-decoder.cjs
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var base64_decoder_exports = {};
|
||||
__export(base64_decoder_exports, {
|
||||
default: () => Base64Decoder
|
||||
});
|
||||
module.exports = __toCommonJS(base64_decoder_exports);
|
||||
var import_decode_strings = require("./decode-strings.cjs");
|
||||
class Base64Decoder {
|
||||
constructor(opts) {
|
||||
opts = opts || {};
|
||||
this.decoder = opts.decoder || new TextDecoder();
|
||||
this.maxChunkSize = 100 * 1024;
|
||||
this.chunks = [];
|
||||
this.remainder = "";
|
||||
}
|
||||
update(buffer) {
|
||||
let str = this.decoder.decode(buffer);
|
||||
str = str.replace(/[^a-zA-Z0-9+\/]+/g, "");
|
||||
this.remainder += str;
|
||||
if (this.remainder.length >= this.maxChunkSize) {
|
||||
let allowedBytes = Math.floor(this.remainder.length / 4) * 4;
|
||||
let base64Str;
|
||||
if (allowedBytes === this.remainder.length) {
|
||||
base64Str = this.remainder;
|
||||
this.remainder = "";
|
||||
} else {
|
||||
base64Str = this.remainder.substr(0, allowedBytes);
|
||||
this.remainder = this.remainder.substr(allowedBytes);
|
||||
}
|
||||
if (base64Str.length) {
|
||||
this.chunks.push((0, import_decode_strings.decodeBase64)(base64Str));
|
||||
}
|
||||
}
|
||||
}
|
||||
finalize() {
|
||||
if (this.remainder && !/^=+$/.test(this.remainder)) {
|
||||
this.chunks.push((0, import_decode_strings.decodeBase64)(this.remainder));
|
||||
}
|
||||
return (0, import_decode_strings.blobToArrayBuffer)(new Blob(this.chunks, { type: "application/octet-stream" }));
|
||||
}
|
||||
}
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
75
node_modules/postal-mime/dist/base64-encoder.cjs
generated
vendored
Normal file
75
node_modules/postal-mime/dist/base64-encoder.cjs
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var base64_encoder_exports = {};
|
||||
__export(base64_encoder_exports, {
|
||||
base64ArrayBuffer: () => base64ArrayBuffer
|
||||
});
|
||||
module.exports = __toCommonJS(base64_encoder_exports);
|
||||
function base64ArrayBuffer(arrayBuffer) {
|
||||
var base64 = "";
|
||||
var encodings = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var bytes = new Uint8Array(arrayBuffer);
|
||||
var byteLength = bytes.byteLength;
|
||||
var byteRemainder = byteLength % 3;
|
||||
var mainLength = byteLength - byteRemainder;
|
||||
var a, b, c, d;
|
||||
var chunk;
|
||||
for (var i = 0; i < mainLength; i = i + 3) {
|
||||
chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
||||
a = (chunk & 16515072) >> 18;
|
||||
b = (chunk & 258048) >> 12;
|
||||
c = (chunk & 4032) >> 6;
|
||||
d = chunk & 63;
|
||||
base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
|
||||
}
|
||||
if (byteRemainder == 1) {
|
||||
chunk = bytes[mainLength];
|
||||
a = (chunk & 252) >> 2;
|
||||
b = (chunk & 3) << 4;
|
||||
base64 += encodings[a] + encodings[b] + "==";
|
||||
} else if (byteRemainder == 2) {
|
||||
chunk = bytes[mainLength] << 8 | bytes[mainLength + 1];
|
||||
a = (chunk & 64512) >> 10;
|
||||
b = (chunk & 1008) >> 4;
|
||||
c = (chunk & 15) << 2;
|
||||
base64 += encodings[a] + encodings[b] + encodings[c] + "=";
|
||||
}
|
||||
return base64;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
base64ArrayBuffer
|
||||
});
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
257
node_modules/postal-mime/dist/decode-strings.cjs
generated
vendored
Normal file
257
node_modules/postal-mime/dist/decode-strings.cjs
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var decode_strings_exports = {};
|
||||
__export(decode_strings_exports, {
|
||||
blobToArrayBuffer: () => blobToArrayBuffer,
|
||||
decodeBase64: () => decodeBase64,
|
||||
decodeParameterValueContinuations: () => decodeParameterValueContinuations,
|
||||
decodeURIComponentWithCharset: () => decodeURIComponentWithCharset,
|
||||
decodeWord: () => decodeWord,
|
||||
decodeWords: () => decodeWords,
|
||||
getDecoder: () => getDecoder,
|
||||
getHex: () => getHex,
|
||||
textEncoder: () => textEncoder
|
||||
});
|
||||
module.exports = __toCommonJS(decode_strings_exports);
|
||||
const textEncoder = new TextEncoder();
|
||||
const base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const base64Lookup = new Uint8Array(256);
|
||||
for (let i = 0; i < base64Chars.length; i++) {
|
||||
base64Lookup[base64Chars.charCodeAt(i)] = i;
|
||||
}
|
||||
function decodeBase64(base64) {
|
||||
let bufferLength = Math.ceil(base64.length / 4) * 3;
|
||||
const len = base64.length;
|
||||
let p = 0;
|
||||
if (base64.length % 4 === 3) {
|
||||
bufferLength--;
|
||||
} else if (base64.length % 4 === 2) {
|
||||
bufferLength -= 2;
|
||||
} else if (base64[base64.length - 1] === "=") {
|
||||
bufferLength--;
|
||||
if (base64[base64.length - 2] === "=") {
|
||||
bufferLength--;
|
||||
}
|
||||
}
|
||||
const arrayBuffer = new ArrayBuffer(bufferLength);
|
||||
const bytes = new Uint8Array(arrayBuffer);
|
||||
for (let i = 0; i < len; i += 4) {
|
||||
let encoded1 = base64Lookup[base64.charCodeAt(i)];
|
||||
let encoded2 = base64Lookup[base64.charCodeAt(i + 1)];
|
||||
let encoded3 = base64Lookup[base64.charCodeAt(i + 2)];
|
||||
let encoded4 = base64Lookup[base64.charCodeAt(i + 3)];
|
||||
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
|
||||
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
|
||||
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
|
||||
}
|
||||
return arrayBuffer;
|
||||
}
|
||||
function getDecoder(charset) {
|
||||
charset = charset || "utf8";
|
||||
let decoder;
|
||||
try {
|
||||
decoder = new TextDecoder(charset);
|
||||
} catch (err) {
|
||||
decoder = new TextDecoder("windows-1252");
|
||||
}
|
||||
return decoder;
|
||||
}
|
||||
async function blobToArrayBuffer(blob) {
|
||||
if ("arrayBuffer" in blob) {
|
||||
return await blob.arrayBuffer();
|
||||
}
|
||||
const fr = new FileReader();
|
||||
return new Promise((resolve, reject) => {
|
||||
fr.onload = function(e) {
|
||||
resolve(e.target.result);
|
||||
};
|
||||
fr.onerror = function(e) {
|
||||
reject(fr.error);
|
||||
};
|
||||
fr.readAsArrayBuffer(blob);
|
||||
});
|
||||
}
|
||||
function getHex(c) {
|
||||
if (c >= 48 && c <= 57 || c >= 97 && c <= 102 || c >= 65 && c <= 70) {
|
||||
return String.fromCharCode(c);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function decodeWord(charset, encoding, str) {
|
||||
let splitPos = charset.indexOf("*");
|
||||
if (splitPos >= 0) {
|
||||
charset = charset.substr(0, splitPos);
|
||||
}
|
||||
encoding = encoding.toUpperCase();
|
||||
let byteStr;
|
||||
if (encoding === "Q") {
|
||||
str = str.replace(/=\s+([0-9a-fA-F])/g, "=$1").replace(/[_\s]/g, " ");
|
||||
let buf = textEncoder.encode(str);
|
||||
let encodedBytes = [];
|
||||
for (let i = 0, len = buf.length; i < len; i++) {
|
||||
let c = buf[i];
|
||||
if (i <= len - 2 && c === 61) {
|
||||
let c1 = getHex(buf[i + 1]);
|
||||
let c2 = getHex(buf[i + 2]);
|
||||
if (c1 && c2) {
|
||||
let c3 = parseInt(c1 + c2, 16);
|
||||
encodedBytes.push(c3);
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
encodedBytes.push(c);
|
||||
}
|
||||
byteStr = new ArrayBuffer(encodedBytes.length);
|
||||
let dataView = new DataView(byteStr);
|
||||
for (let i = 0, len = encodedBytes.length; i < len; i++) {
|
||||
dataView.setUint8(i, encodedBytes[i]);
|
||||
}
|
||||
} else if (encoding === "B") {
|
||||
byteStr = decodeBase64(str.replace(/[^a-zA-Z0-9\+\/=]+/g, ""));
|
||||
} else {
|
||||
byteStr = textEncoder.encode(str);
|
||||
}
|
||||
return getDecoder(charset).decode(byteStr);
|
||||
}
|
||||
function decodeWords(str) {
|
||||
let joinString = true;
|
||||
let done = false;
|
||||
while (!done) {
|
||||
let result = (str || "").toString().replace(
|
||||
/(=\?([^?]+)\?[Bb]\?([^?]*)\?=)\s*(?==\?([^?]+)\?[Bb]\?[^?]*\?=)/g,
|
||||
(match, left, chLeft, encodedLeftStr, chRight) => {
|
||||
if (!joinString) {
|
||||
return match;
|
||||
}
|
||||
if (chLeft === chRight && encodedLeftStr.length % 4 === 0 && !/=$/.test(encodedLeftStr)) {
|
||||
return left + "__\0JOIN\0__";
|
||||
}
|
||||
return match;
|
||||
}
|
||||
).replace(
|
||||
/(=\?([^?]+)\?[Qq]\?[^?]*\?=)\s*(?==\?([^?]+)\?[Qq]\?[^?]*\?=)/g,
|
||||
(match, left, chLeft, chRight) => {
|
||||
if (!joinString) {
|
||||
return match;
|
||||
}
|
||||
if (chLeft === chRight) {
|
||||
return left + "__\0JOIN\0__";
|
||||
}
|
||||
return match;
|
||||
}
|
||||
).replace(/(\?=)?__\x00JOIN\x00__(=\?([^?]+)\?[QqBb]\?)?/g, "").replace(/(=\?[^?]+\?[QqBb]\?[^?]*\?=)\s+(?==\?[^?]+\?[QqBb]\?[^?]*\?=)/g, "$1").replace(
|
||||
/=\?([\w_\-*]+)\?([QqBb])\?([^?]*)\?=/g,
|
||||
(m, charset, encoding, text) => decodeWord(charset, encoding, text)
|
||||
);
|
||||
if (joinString && result.indexOf("\uFFFD") >= 0) {
|
||||
joinString = false;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
function decodeURIComponentWithCharset(encodedStr, charset) {
|
||||
charset = charset || "utf-8";
|
||||
let encodedBytes = [];
|
||||
for (let i = 0; i < encodedStr.length; i++) {
|
||||
let c = encodedStr.charAt(i);
|
||||
if (c === "%" && /^[a-f0-9]{2}/i.test(encodedStr.substr(i + 1, 2))) {
|
||||
let byte = encodedStr.substr(i + 1, 2);
|
||||
i += 2;
|
||||
encodedBytes.push(parseInt(byte, 16));
|
||||
} else if (c.charCodeAt(0) > 126) {
|
||||
c = textEncoder.encode(c);
|
||||
for (let j = 0; j < c.length; j++) {
|
||||
encodedBytes.push(c[j]);
|
||||
}
|
||||
} else {
|
||||
encodedBytes.push(c.charCodeAt(0));
|
||||
}
|
||||
}
|
||||
const byteStr = new ArrayBuffer(encodedBytes.length);
|
||||
const dataView = new DataView(byteStr);
|
||||
for (let i = 0, len = encodedBytes.length; i < len; i++) {
|
||||
dataView.setUint8(i, encodedBytes[i]);
|
||||
}
|
||||
return getDecoder(charset).decode(byteStr);
|
||||
}
|
||||
function decodeParameterValueContinuations(header) {
|
||||
let paramKeys = /* @__PURE__ */ new Map();
|
||||
Object.keys(header.params).forEach((key) => {
|
||||
let match = key.match(/\*((\d+)\*?)?$/);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
let actualKey = key.substr(0, match.index).toLowerCase();
|
||||
let nr = Number(match[2]) || 0;
|
||||
let paramVal;
|
||||
if (!paramKeys.has(actualKey)) {
|
||||
paramVal = {
|
||||
charset: false,
|
||||
values: []
|
||||
};
|
||||
paramKeys.set(actualKey, paramVal);
|
||||
} else {
|
||||
paramVal = paramKeys.get(actualKey);
|
||||
}
|
||||
let value = header.params[key];
|
||||
if (nr === 0 && match[0].charAt(match[0].length - 1) === "*" && (match = value.match(/^([^']*)'[^']*'(.*)$/))) {
|
||||
paramVal.charset = match[1] || "utf-8";
|
||||
value = match[2];
|
||||
}
|
||||
paramVal.values.push({ nr, value });
|
||||
delete header.params[key];
|
||||
});
|
||||
paramKeys.forEach((paramVal, key) => {
|
||||
header.params[key] = decodeURIComponentWithCharset(
|
||||
paramVal.values.sort((a, b) => a.nr - b.nr).map((a) => a.value).join(""),
|
||||
paramVal.charset
|
||||
);
|
||||
});
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
blobToArrayBuffer,
|
||||
decodeBase64,
|
||||
decodeParameterValueContinuations,
|
||||
decodeURIComponentWithCharset,
|
||||
decodeWord,
|
||||
decodeWords,
|
||||
getDecoder,
|
||||
getHex,
|
||||
textEncoder
|
||||
});
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
2279
node_modules/postal-mime/dist/html-entities.cjs
generated
vendored
Normal file
2279
node_modules/postal-mime/dist/html-entities.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
327
node_modules/postal-mime/dist/mime-node.cjs
generated
vendored
Normal file
327
node_modules/postal-mime/dist/mime-node.cjs
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var mime_node_exports = {};
|
||||
__export(mime_node_exports, {
|
||||
default: () => MimeNode
|
||||
});
|
||||
module.exports = __toCommonJS(mime_node_exports);
|
||||
var import_decode_strings = require("./decode-strings.cjs");
|
||||
var import_pass_through_decoder = __toESM(require("./pass-through-decoder.cjs"), 1);
|
||||
var import_base64_decoder = __toESM(require("./base64-decoder.cjs"), 1);
|
||||
var import_qp_decoder = __toESM(require("./qp-decoder.cjs"), 1);
|
||||
const defaultDecoder = (0, import_decode_strings.getDecoder)();
|
||||
class MimeNode {
|
||||
constructor(options) {
|
||||
this.options = options || {};
|
||||
this.postalMime = this.options.postalMime;
|
||||
this.root = !!this.options.parentNode;
|
||||
this.childNodes = [];
|
||||
if (this.options.parentNode) {
|
||||
this.parentNode = this.options.parentNode;
|
||||
this.depth = this.parentNode.depth + 1;
|
||||
if (this.depth > this.options.maxNestingDepth) {
|
||||
throw new Error(`Maximum MIME nesting depth of ${this.options.maxNestingDepth} levels exceeded`);
|
||||
}
|
||||
this.options.parentNode.childNodes.push(this);
|
||||
} else {
|
||||
this.depth = 0;
|
||||
}
|
||||
this.state = "header";
|
||||
this.headerLines = [];
|
||||
this.headerSize = 0;
|
||||
const parentMultipartType = this.options.parentMultipartType || null;
|
||||
const defaultContentType = parentMultipartType === "digest" ? "message/rfc822" : "text/plain";
|
||||
this.contentType = {
|
||||
value: defaultContentType,
|
||||
default: true
|
||||
};
|
||||
this.contentTransferEncoding = {
|
||||
value: "8bit"
|
||||
};
|
||||
this.contentDisposition = {
|
||||
value: ""
|
||||
};
|
||||
this.headers = [];
|
||||
this.contentDecoder = false;
|
||||
}
|
||||
setupContentDecoder(transferEncoding) {
|
||||
if (/base64/i.test(transferEncoding)) {
|
||||
this.contentDecoder = new import_base64_decoder.default();
|
||||
} else if (/quoted-printable/i.test(transferEncoding)) {
|
||||
this.contentDecoder = new import_qp_decoder.default({ decoder: (0, import_decode_strings.getDecoder)(this.contentType.parsed.params.charset) });
|
||||
} else {
|
||||
this.contentDecoder = new import_pass_through_decoder.default();
|
||||
}
|
||||
}
|
||||
async finalize() {
|
||||
if (this.state === "finished") {
|
||||
return;
|
||||
}
|
||||
if (this.state === "header") {
|
||||
this.processHeaders();
|
||||
}
|
||||
let boundaries = this.postalMime.boundaries;
|
||||
for (let i = boundaries.length - 1; i >= 0; i--) {
|
||||
let boundary = boundaries[i];
|
||||
if (boundary.node === this) {
|
||||
boundaries.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
await this.finalizeChildNodes();
|
||||
this.content = this.contentDecoder ? await this.contentDecoder.finalize() : null;
|
||||
this.state = "finished";
|
||||
}
|
||||
async finalizeChildNodes() {
|
||||
for (let childNode of this.childNodes) {
|
||||
await childNode.finalize();
|
||||
}
|
||||
}
|
||||
// Strip RFC 822 comments (parenthesized text) from structured header values
|
||||
stripComments(str) {
|
||||
let result = "";
|
||||
let depth = 0;
|
||||
let escaped = false;
|
||||
let inQuote = false;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const chr = str.charAt(i);
|
||||
if (escaped) {
|
||||
if (depth === 0) {
|
||||
result += chr;
|
||||
}
|
||||
escaped = false;
|
||||
continue;
|
||||
}
|
||||
if (chr === "\\") {
|
||||
escaped = true;
|
||||
if (depth === 0) {
|
||||
result += chr;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (chr === '"' && depth === 0) {
|
||||
inQuote = !inQuote;
|
||||
result += chr;
|
||||
continue;
|
||||
}
|
||||
if (!inQuote) {
|
||||
if (chr === "(") {
|
||||
depth++;
|
||||
continue;
|
||||
}
|
||||
if (chr === ")" && depth > 0) {
|
||||
depth--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (depth === 0) {
|
||||
result += chr;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
parseStructuredHeader(str) {
|
||||
str = this.stripComments(str);
|
||||
let response = {
|
||||
value: false,
|
||||
params: {}
|
||||
};
|
||||
let key = false;
|
||||
let value = "";
|
||||
let stage = "value";
|
||||
let quote = false;
|
||||
let escaped = false;
|
||||
let chr;
|
||||
for (let i = 0, len = str.length; i < len; i++) {
|
||||
chr = str.charAt(i);
|
||||
switch (stage) {
|
||||
case "key":
|
||||
if (chr === "=") {
|
||||
key = value.trim().toLowerCase();
|
||||
stage = "value";
|
||||
value = "";
|
||||
break;
|
||||
}
|
||||
value += chr;
|
||||
break;
|
||||
case "value":
|
||||
if (escaped) {
|
||||
value += chr;
|
||||
} else if (chr === "\\") {
|
||||
escaped = true;
|
||||
continue;
|
||||
} else if (quote && chr === quote) {
|
||||
quote = false;
|
||||
} else if (!quote && chr === '"') {
|
||||
quote = chr;
|
||||
} else if (!quote && chr === ";") {
|
||||
if (key === false) {
|
||||
response.value = value.trim();
|
||||
} else {
|
||||
response.params[key] = value.trim();
|
||||
}
|
||||
stage = "key";
|
||||
value = "";
|
||||
} else {
|
||||
value += chr;
|
||||
}
|
||||
escaped = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
value = value.trim();
|
||||
if (stage === "value") {
|
||||
if (key === false) {
|
||||
response.value = value;
|
||||
} else {
|
||||
response.params[key] = value;
|
||||
}
|
||||
} else if (value) {
|
||||
response.params[value.toLowerCase()] = "";
|
||||
}
|
||||
if (response.value) {
|
||||
response.value = response.value.toLowerCase();
|
||||
}
|
||||
(0, import_decode_strings.decodeParameterValueContinuations)(response);
|
||||
return response;
|
||||
}
|
||||
decodeFlowedText(str, delSp) {
|
||||
return str.split(/\r?\n/).reduce((previousValue, currentValue) => {
|
||||
if (previousValue.endsWith(" ") && previousValue !== "-- " && !previousValue.endsWith("\n-- ")) {
|
||||
if (delSp) {
|
||||
return previousValue.slice(0, -1) + currentValue;
|
||||
} else {
|
||||
return previousValue + currentValue;
|
||||
}
|
||||
} else {
|
||||
return previousValue + "\n" + currentValue;
|
||||
}
|
||||
}).replace(/^ /gm, "");
|
||||
}
|
||||
getTextContent() {
|
||||
if (!this.content) {
|
||||
return "";
|
||||
}
|
||||
let str = (0, import_decode_strings.getDecoder)(this.contentType.parsed.params.charset).decode(this.content);
|
||||
if (/^flowed$/i.test(this.contentType.parsed.params.format)) {
|
||||
str = this.decodeFlowedText(str, /^yes$/i.test(this.contentType.parsed.params.delsp));
|
||||
}
|
||||
return str;
|
||||
}
|
||||
processHeaders() {
|
||||
for (let i = this.headerLines.length - 1; i >= 0; i--) {
|
||||
let line = this.headerLines[i];
|
||||
if (i && /^\s/.test(line)) {
|
||||
this.headerLines[i - 1] += "\n" + line;
|
||||
this.headerLines.splice(i, 1);
|
||||
}
|
||||
}
|
||||
this.rawHeaderLines = [];
|
||||
for (let i = this.headerLines.length - 1; i >= 0; i--) {
|
||||
let rawLine = this.headerLines[i];
|
||||
let sep = rawLine.indexOf(":");
|
||||
let rawKey = sep < 0 ? rawLine.trim() : rawLine.substr(0, sep).trim();
|
||||
this.rawHeaderLines.push({
|
||||
key: rawKey.toLowerCase(),
|
||||
line: rawLine
|
||||
});
|
||||
let normalizedLine = rawLine.replace(/\s+/g, " ");
|
||||
sep = normalizedLine.indexOf(":");
|
||||
let key = sep < 0 ? normalizedLine.trim() : normalizedLine.substr(0, sep).trim();
|
||||
let value = sep < 0 ? "" : normalizedLine.substr(sep + 1).trim();
|
||||
this.headers.push({ key: key.toLowerCase(), originalKey: key, value });
|
||||
switch (key.toLowerCase()) {
|
||||
case "content-type":
|
||||
if (this.contentType.default) {
|
||||
this.contentType = { value, parsed: {} };
|
||||
}
|
||||
break;
|
||||
case "content-transfer-encoding":
|
||||
this.contentTransferEncoding = { value, parsed: {} };
|
||||
break;
|
||||
case "content-disposition":
|
||||
this.contentDisposition = { value, parsed: {} };
|
||||
break;
|
||||
case "content-id":
|
||||
this.contentId = value;
|
||||
break;
|
||||
case "content-description":
|
||||
this.contentDescription = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.contentType.parsed = this.parseStructuredHeader(this.contentType.value);
|
||||
this.contentType.multipart = /^multipart\//i.test(this.contentType.parsed.value) ? this.contentType.parsed.value.substr(this.contentType.parsed.value.indexOf("/") + 1) : false;
|
||||
if (this.contentType.multipart && this.contentType.parsed.params.boundary) {
|
||||
this.postalMime.boundaries.push({
|
||||
value: import_decode_strings.textEncoder.encode(this.contentType.parsed.params.boundary),
|
||||
node: this
|
||||
});
|
||||
}
|
||||
this.contentDisposition.parsed = this.parseStructuredHeader(this.contentDisposition.value);
|
||||
this.contentTransferEncoding.encoding = this.contentTransferEncoding.value.toLowerCase().split(/[^\w-]/).shift();
|
||||
this.setupContentDecoder(this.contentTransferEncoding.encoding);
|
||||
}
|
||||
feed(line) {
|
||||
switch (this.state) {
|
||||
case "header":
|
||||
if (!line.length) {
|
||||
this.state = "body";
|
||||
return this.processHeaders();
|
||||
}
|
||||
this.headerSize += line.length;
|
||||
if (this.headerSize > this.options.maxHeadersSize) {
|
||||
let error = new Error(`Maximum header size of ${this.options.maxHeadersSize} bytes exceeded`);
|
||||
throw error;
|
||||
}
|
||||
this.headerLines.push(defaultDecoder.decode(line));
|
||||
break;
|
||||
case "body": {
|
||||
this.contentDecoder.update(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
53
node_modules/postal-mime/dist/pass-through-decoder.cjs
generated
vendored
Normal file
53
node_modules/postal-mime/dist/pass-through-decoder.cjs
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var pass_through_decoder_exports = {};
|
||||
__export(pass_through_decoder_exports, {
|
||||
default: () => PassThroughDecoder
|
||||
});
|
||||
module.exports = __toCommonJS(pass_through_decoder_exports);
|
||||
var import_decode_strings = require("./decode-strings.cjs");
|
||||
class PassThroughDecoder {
|
||||
constructor() {
|
||||
this.chunks = [];
|
||||
}
|
||||
update(line) {
|
||||
this.chunks.push(line);
|
||||
this.chunks.push("\n");
|
||||
}
|
||||
finalize() {
|
||||
return (0, import_decode_strings.blobToArrayBuffer)(new Blob(this.chunks, { type: "application/octet-stream" }));
|
||||
}
|
||||
}
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
496
node_modules/postal-mime/dist/postal-mime.cjs
generated
vendored
Normal file
496
node_modules/postal-mime/dist/postal-mime.cjs
generated
vendored
Normal file
@@ -0,0 +1,496 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var postal_mime_exports = {};
|
||||
__export(postal_mime_exports, {
|
||||
addressParser: () => import_address_parser.default,
|
||||
decodeWords: () => import_decode_strings.decodeWords,
|
||||
default: () => PostalMime
|
||||
});
|
||||
module.exports = __toCommonJS(postal_mime_exports);
|
||||
var import_mime_node = __toESM(require("./mime-node.cjs"), 1);
|
||||
var import_text_format = require("./text-format.cjs");
|
||||
var import_address_parser = __toESM(require("./address-parser.cjs"), 1);
|
||||
var import_decode_strings = require("./decode-strings.cjs");
|
||||
var import_base64_encoder = require("./base64-encoder.cjs");
|
||||
const MAX_NESTING_DEPTH = 256;
|
||||
const MAX_HEADERS_SIZE = 2 * 1024 * 1024;
|
||||
function toCamelCase(key) {
|
||||
return key.replace(/-(.)/g, (o, c) => c.toUpperCase());
|
||||
}
|
||||
class PostalMime {
|
||||
static parse(buf, options) {
|
||||
const parser = new PostalMime(options);
|
||||
return parser.parse(buf);
|
||||
}
|
||||
constructor(options) {
|
||||
this.options = options || {};
|
||||
this.mimeOptions = {
|
||||
maxNestingDepth: this.options.maxNestingDepth || MAX_NESTING_DEPTH,
|
||||
maxHeadersSize: this.options.maxHeadersSize || MAX_HEADERS_SIZE
|
||||
};
|
||||
this.root = this.currentNode = new import_mime_node.default({
|
||||
postalMime: this,
|
||||
...this.mimeOptions
|
||||
});
|
||||
this.boundaries = [];
|
||||
this.textContent = {};
|
||||
this.attachments = [];
|
||||
this.attachmentEncoding = (this.options.attachmentEncoding || "").toString().replace(/[-_\s]/g, "").trim().toLowerCase() || "arraybuffer";
|
||||
this.started = false;
|
||||
}
|
||||
async finalize() {
|
||||
await this.root.finalize();
|
||||
}
|
||||
async processLine(line, isFinal) {
|
||||
let boundaries = this.boundaries;
|
||||
if (boundaries.length && line.length > 2 && line[0] === 45 && line[1] === 45) {
|
||||
for (let i = boundaries.length - 1; i >= 0; i--) {
|
||||
let boundary = boundaries[i];
|
||||
if (line.length < boundary.value.length + 2) {
|
||||
continue;
|
||||
}
|
||||
let boundaryMatches = true;
|
||||
for (let j = 0; j < boundary.value.length; j++) {
|
||||
if (line[j + 2] !== boundary.value[j]) {
|
||||
boundaryMatches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!boundaryMatches) {
|
||||
continue;
|
||||
}
|
||||
let boundaryEnd = boundary.value.length + 2;
|
||||
let isTerminator = false;
|
||||
if (line.length >= boundary.value.length + 4 && line[boundary.value.length + 2] === 45 && line[boundary.value.length + 3] === 45) {
|
||||
isTerminator = true;
|
||||
boundaryEnd = boundary.value.length + 4;
|
||||
}
|
||||
let hasValidTrailing = true;
|
||||
for (let j = boundaryEnd; j < line.length; j++) {
|
||||
if (line[j] !== 32 && line[j] !== 9) {
|
||||
hasValidTrailing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasValidTrailing) {
|
||||
continue;
|
||||
}
|
||||
if (isTerminator) {
|
||||
await boundary.node.finalize();
|
||||
this.currentNode = boundary.node.parentNode || this.root;
|
||||
} else {
|
||||
await boundary.node.finalizeChildNodes();
|
||||
this.currentNode = new import_mime_node.default({
|
||||
postalMime: this,
|
||||
parentNode: boundary.node,
|
||||
parentMultipartType: boundary.node.contentType.multipart,
|
||||
...this.mimeOptions
|
||||
});
|
||||
}
|
||||
if (isFinal) {
|
||||
return this.finalize();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.currentNode.feed(line);
|
||||
if (isFinal) {
|
||||
return this.finalize();
|
||||
}
|
||||
}
|
||||
readLine() {
|
||||
let startPos = this.readPos;
|
||||
let endPos = this.readPos;
|
||||
while (this.readPos < this.av.length) {
|
||||
const c = this.av[this.readPos++];
|
||||
if (c !== 13 && c !== 10) {
|
||||
endPos = this.readPos;
|
||||
}
|
||||
if (c === 10) {
|
||||
return {
|
||||
bytes: new Uint8Array(this.buf, startPos, endPos - startPos),
|
||||
done: this.readPos >= this.av.length
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
bytes: new Uint8Array(this.buf, startPos, endPos - startPos),
|
||||
done: this.readPos >= this.av.length
|
||||
};
|
||||
}
|
||||
async processNodeTree() {
|
||||
let textContent = {};
|
||||
let textTypes = /* @__PURE__ */ new Set();
|
||||
let textMap = this.textMap = /* @__PURE__ */ new Map();
|
||||
let forceRfc822Attachments = this.forceRfc822Attachments();
|
||||
let walk = async (node, alternative, related) => {
|
||||
var _a, _b, _c, _d, _e;
|
||||
alternative = alternative || false;
|
||||
related = related || false;
|
||||
if (!node.contentType.multipart) {
|
||||
if (this.isInlineMessageRfc822(node) && !forceRfc822Attachments) {
|
||||
const subParser = new PostalMime();
|
||||
node.subMessage = await subParser.parse(node.content);
|
||||
if (!textMap.has(node)) {
|
||||
textMap.set(node, {});
|
||||
}
|
||||
let textEntry = textMap.get(node);
|
||||
if (node.subMessage.text || !node.subMessage.html) {
|
||||
textEntry.plain = textEntry.plain || [];
|
||||
textEntry.plain.push({ type: "subMessage", value: node.subMessage });
|
||||
textTypes.add("plain");
|
||||
}
|
||||
if (node.subMessage.html) {
|
||||
textEntry.html = textEntry.html || [];
|
||||
textEntry.html.push({ type: "subMessage", value: node.subMessage });
|
||||
textTypes.add("html");
|
||||
}
|
||||
if (subParser.textMap) {
|
||||
subParser.textMap.forEach((subTextEntry, subTextNode) => {
|
||||
textMap.set(subTextNode, subTextEntry);
|
||||
});
|
||||
}
|
||||
for (let attachment of node.subMessage.attachments || []) {
|
||||
this.attachments.push(attachment);
|
||||
}
|
||||
} else if (this.isInlineTextNode(node)) {
|
||||
let textType = node.contentType.parsed.value.substr(node.contentType.parsed.value.indexOf("/") + 1);
|
||||
let selectorNode = alternative || node;
|
||||
if (!textMap.has(selectorNode)) {
|
||||
textMap.set(selectorNode, {});
|
||||
}
|
||||
let textEntry = textMap.get(selectorNode);
|
||||
textEntry[textType] = textEntry[textType] || [];
|
||||
textEntry[textType].push({ type: "text", value: node.getTextContent() });
|
||||
textTypes.add(textType);
|
||||
} else if (node.content) {
|
||||
const filename = ((_c = (_b = (_a = node.contentDisposition) == null ? void 0 : _a.parsed) == null ? void 0 : _b.params) == null ? void 0 : _c.filename) || node.contentType.parsed.params.name || null;
|
||||
const attachment = {
|
||||
filename: filename ? (0, import_decode_strings.decodeWords)(filename) : null,
|
||||
mimeType: node.contentType.parsed.value,
|
||||
disposition: ((_e = (_d = node.contentDisposition) == null ? void 0 : _d.parsed) == null ? void 0 : _e.value) || null
|
||||
};
|
||||
if (related && node.contentId) {
|
||||
attachment.related = true;
|
||||
}
|
||||
if (node.contentDescription) {
|
||||
attachment.description = node.contentDescription;
|
||||
}
|
||||
if (node.contentId) {
|
||||
attachment.contentId = node.contentId;
|
||||
}
|
||||
switch (node.contentType.parsed.value) {
|
||||
// Special handling for calendar events
|
||||
case "text/calendar":
|
||||
case "application/ics": {
|
||||
if (node.contentType.parsed.params.method) {
|
||||
attachment.method = node.contentType.parsed.params.method.toString().toUpperCase().trim();
|
||||
}
|
||||
const decodedText = node.getTextContent().replace(/\r?\n/g, "\n").replace(/\n*$/, "\n");
|
||||
attachment.content = import_decode_strings.textEncoder.encode(decodedText);
|
||||
break;
|
||||
}
|
||||
// Regular attachments
|
||||
default:
|
||||
attachment.content = node.content;
|
||||
}
|
||||
this.attachments.push(attachment);
|
||||
}
|
||||
} else if (node.contentType.multipart === "alternative") {
|
||||
alternative = node;
|
||||
} else if (node.contentType.multipart === "related") {
|
||||
related = node;
|
||||
}
|
||||
for (let childNode of node.childNodes) {
|
||||
await walk(childNode, alternative, related);
|
||||
}
|
||||
};
|
||||
await walk(this.root, false, false);
|
||||
textMap.forEach((mapEntry) => {
|
||||
textTypes.forEach((textType) => {
|
||||
if (!textContent[textType]) {
|
||||
textContent[textType] = [];
|
||||
}
|
||||
if (mapEntry[textType]) {
|
||||
mapEntry[textType].forEach((textEntry) => {
|
||||
switch (textEntry.type) {
|
||||
case "text":
|
||||
textContent[textType].push(textEntry.value);
|
||||
break;
|
||||
case "subMessage":
|
||||
{
|
||||
switch (textType) {
|
||||
case "html":
|
||||
textContent[textType].push((0, import_text_format.formatHtmlHeader)(textEntry.value));
|
||||
break;
|
||||
case "plain":
|
||||
textContent[textType].push((0, import_text_format.formatTextHeader)(textEntry.value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let alternativeType;
|
||||
switch (textType) {
|
||||
case "html":
|
||||
alternativeType = "plain";
|
||||
break;
|
||||
case "plain":
|
||||
alternativeType = "html";
|
||||
break;
|
||||
}
|
||||
(mapEntry[alternativeType] || []).forEach((textEntry) => {
|
||||
switch (textEntry.type) {
|
||||
case "text":
|
||||
switch (textType) {
|
||||
case "html":
|
||||
textContent[textType].push((0, import_text_format.textToHtml)(textEntry.value));
|
||||
break;
|
||||
case "plain":
|
||||
textContent[textType].push((0, import_text_format.htmlToText)(textEntry.value));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "subMessage":
|
||||
{
|
||||
switch (textType) {
|
||||
case "html":
|
||||
textContent[textType].push((0, import_text_format.formatHtmlHeader)(textEntry.value));
|
||||
break;
|
||||
case "plain":
|
||||
textContent[textType].push((0, import_text_format.formatTextHeader)(textEntry.value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
Object.keys(textContent).forEach((textType) => {
|
||||
textContent[textType] = textContent[textType].join("\n");
|
||||
});
|
||||
this.textContent = textContent;
|
||||
}
|
||||
isInlineTextNode(node) {
|
||||
var _a, _b, _c;
|
||||
if (((_b = (_a = node.contentDisposition) == null ? void 0 : _a.parsed) == null ? void 0 : _b.value) === "attachment") {
|
||||
return false;
|
||||
}
|
||||
switch ((_c = node.contentType.parsed) == null ? void 0 : _c.value) {
|
||||
case "text/html":
|
||||
case "text/plain":
|
||||
return true;
|
||||
case "text/calendar":
|
||||
case "text/csv":
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
isInlineMessageRfc822(node) {
|
||||
var _a, _b, _c;
|
||||
if (((_a = node.contentType.parsed) == null ? void 0 : _a.value) !== "message/rfc822") {
|
||||
return false;
|
||||
}
|
||||
let disposition = ((_c = (_b = node.contentDisposition) == null ? void 0 : _b.parsed) == null ? void 0 : _c.value) || (this.options.rfc822Attachments ? "attachment" : "inline");
|
||||
return disposition === "inline";
|
||||
}
|
||||
// Check if this is a specially crafted report email where message/rfc822 content should not be inlined
|
||||
forceRfc822Attachments() {
|
||||
if (this.options.forceRfc822Attachments) {
|
||||
return true;
|
||||
}
|
||||
let forceRfc822Attachments = false;
|
||||
let walk = (node) => {
|
||||
if (!node.contentType.multipart) {
|
||||
if (node.contentType.parsed && ["message/delivery-status", "message/feedback-report"].includes(node.contentType.parsed.value)) {
|
||||
forceRfc822Attachments = true;
|
||||
}
|
||||
}
|
||||
for (let childNode of node.childNodes) {
|
||||
walk(childNode);
|
||||
}
|
||||
};
|
||||
walk(this.root);
|
||||
return forceRfc822Attachments;
|
||||
}
|
||||
async resolveStream(stream) {
|
||||
let chunkLen = 0;
|
||||
let chunks = [];
|
||||
const reader = stream.getReader();
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
chunks.push(value);
|
||||
chunkLen += value.length;
|
||||
}
|
||||
const result = new Uint8Array(chunkLen);
|
||||
let chunkPointer = 0;
|
||||
for (let chunk of chunks) {
|
||||
result.set(chunk, chunkPointer);
|
||||
chunkPointer += chunk.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async parse(buf) {
|
||||
var _a, _b;
|
||||
if (this.started) {
|
||||
throw new Error("Can not reuse parser, create a new PostalMime object");
|
||||
}
|
||||
this.started = true;
|
||||
if (buf && typeof buf.getReader === "function") {
|
||||
buf = await this.resolveStream(buf);
|
||||
}
|
||||
buf = buf || new ArrayBuffer(0);
|
||||
if (typeof buf === "string") {
|
||||
buf = import_decode_strings.textEncoder.encode(buf);
|
||||
}
|
||||
if (buf instanceof Blob || Object.prototype.toString.call(buf) === "[object Blob]") {
|
||||
buf = await (0, import_decode_strings.blobToArrayBuffer)(buf);
|
||||
}
|
||||
if (buf.buffer instanceof ArrayBuffer) {
|
||||
buf = new Uint8Array(buf).buffer;
|
||||
}
|
||||
this.buf = buf;
|
||||
this.av = new Uint8Array(buf);
|
||||
this.readPos = 0;
|
||||
while (this.readPos < this.av.length) {
|
||||
const line = this.readLine();
|
||||
await this.processLine(line.bytes, line.done);
|
||||
}
|
||||
await this.processNodeTree();
|
||||
const message = {
|
||||
headers: this.root.headers.map((entry) => ({ key: entry.key, originalKey: entry.originalKey, value: entry.value })).reverse()
|
||||
};
|
||||
for (const key of ["from", "sender"]) {
|
||||
const addressHeader = this.root.headers.find((line) => line.key === key);
|
||||
if (addressHeader && addressHeader.value) {
|
||||
const addresses = (0, import_address_parser.default)(addressHeader.value);
|
||||
if (addresses && addresses.length) {
|
||||
message[key] = addresses[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const key of ["delivered-to", "return-path"]) {
|
||||
const addressHeader = this.root.headers.find((line) => line.key === key);
|
||||
if (addressHeader && addressHeader.value) {
|
||||
const addresses = (0, import_address_parser.default)(addressHeader.value);
|
||||
if (addresses && addresses.length && addresses[0].address) {
|
||||
const camelKey = toCamelCase(key);
|
||||
message[camelKey] = addresses[0].address;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const key of ["to", "cc", "bcc", "reply-to"]) {
|
||||
const addressHeaders = this.root.headers.filter((line) => line.key === key);
|
||||
let addresses = [];
|
||||
addressHeaders.filter((entry) => entry && entry.value).map((entry) => (0, import_address_parser.default)(entry.value)).forEach((parsed) => addresses = addresses.concat(parsed || []));
|
||||
if (addresses && addresses.length) {
|
||||
const camelKey = toCamelCase(key);
|
||||
message[camelKey] = addresses;
|
||||
}
|
||||
}
|
||||
for (const key of ["subject", "message-id", "in-reply-to", "references"]) {
|
||||
const header = this.root.headers.find((line) => line.key === key);
|
||||
if (header && header.value) {
|
||||
const camelKey = toCamelCase(key);
|
||||
message[camelKey] = (0, import_decode_strings.decodeWords)(header.value);
|
||||
}
|
||||
}
|
||||
let dateHeader = this.root.headers.find((line) => line.key === "date");
|
||||
if (dateHeader) {
|
||||
let date = new Date(dateHeader.value);
|
||||
if (date.toString() === "Invalid Date") {
|
||||
date = dateHeader.value;
|
||||
} else {
|
||||
date = date.toISOString();
|
||||
}
|
||||
message.date = date;
|
||||
}
|
||||
if ((_a = this.textContent) == null ? void 0 : _a.html) {
|
||||
message.html = this.textContent.html;
|
||||
}
|
||||
if ((_b = this.textContent) == null ? void 0 : _b.plain) {
|
||||
message.text = this.textContent.plain;
|
||||
}
|
||||
message.attachments = this.attachments;
|
||||
message.headerLines = (this.root.rawHeaderLines || []).slice().reverse();
|
||||
switch (this.attachmentEncoding) {
|
||||
case "arraybuffer":
|
||||
break;
|
||||
case "base64":
|
||||
for (let attachment of message.attachments || []) {
|
||||
if (attachment == null ? void 0 : attachment.content) {
|
||||
attachment.content = (0, import_base64_encoder.base64ArrayBuffer)(attachment.content);
|
||||
attachment.encoding = "base64";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "utf8":
|
||||
let attachmentDecoder = new TextDecoder("utf8");
|
||||
for (let attachment of message.attachments || []) {
|
||||
if (attachment == null ? void 0 : attachment.content) {
|
||||
attachment.content = attachmentDecoder.decode(attachment.content);
|
||||
attachment.encoding = "utf8";
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown attachment encoding");
|
||||
}
|
||||
return message;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
addressParser,
|
||||
decodeWords
|
||||
});
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
134
node_modules/postal-mime/dist/qp-decoder.cjs
generated
vendored
Normal file
134
node_modules/postal-mime/dist/qp-decoder.cjs
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var qp_decoder_exports = {};
|
||||
__export(qp_decoder_exports, {
|
||||
default: () => QPDecoder
|
||||
});
|
||||
module.exports = __toCommonJS(qp_decoder_exports);
|
||||
var import_decode_strings = require("./decode-strings.cjs");
|
||||
const VALID_QP_REGEX = /^=[a-f0-9]{2}$/i;
|
||||
const QP_SPLIT_REGEX = /(?==[a-f0-9]{2})/i;
|
||||
const SOFT_LINE_BREAK_REGEX = /=\r?\n/g;
|
||||
const PARTIAL_QP_ENDING_REGEX = /=[a-fA-F0-9]?$/;
|
||||
class QPDecoder {
|
||||
constructor(opts) {
|
||||
opts = opts || {};
|
||||
this.decoder = opts.decoder || new TextDecoder();
|
||||
this.maxChunkSize = 100 * 1024;
|
||||
this.remainder = "";
|
||||
this.chunks = [];
|
||||
}
|
||||
decodeQPBytes(encodedBytes) {
|
||||
let buf = new ArrayBuffer(encodedBytes.length);
|
||||
let dataView = new DataView(buf);
|
||||
for (let i = 0, len = encodedBytes.length; i < len; i++) {
|
||||
dataView.setUint8(i, parseInt(encodedBytes[i], 16));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
decodeChunks(str) {
|
||||
str = str.replace(SOFT_LINE_BREAK_REGEX, "");
|
||||
let list = str.split(QP_SPLIT_REGEX);
|
||||
let encodedBytes = [];
|
||||
for (let part of list) {
|
||||
if (part.charAt(0) !== "=") {
|
||||
if (encodedBytes.length) {
|
||||
this.chunks.push(this.decodeQPBytes(encodedBytes));
|
||||
encodedBytes = [];
|
||||
}
|
||||
this.chunks.push(part);
|
||||
continue;
|
||||
}
|
||||
if (part.length === 3) {
|
||||
if (VALID_QP_REGEX.test(part)) {
|
||||
encodedBytes.push(part.substr(1));
|
||||
} else {
|
||||
if (encodedBytes.length) {
|
||||
this.chunks.push(this.decodeQPBytes(encodedBytes));
|
||||
encodedBytes = [];
|
||||
}
|
||||
this.chunks.push(part);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (part.length > 3) {
|
||||
const firstThree = part.substr(0, 3);
|
||||
if (VALID_QP_REGEX.test(firstThree)) {
|
||||
encodedBytes.push(part.substr(1, 2));
|
||||
this.chunks.push(this.decodeQPBytes(encodedBytes));
|
||||
encodedBytes = [];
|
||||
part = part.substr(3);
|
||||
this.chunks.push(part);
|
||||
} else {
|
||||
if (encodedBytes.length) {
|
||||
this.chunks.push(this.decodeQPBytes(encodedBytes));
|
||||
encodedBytes = [];
|
||||
}
|
||||
this.chunks.push(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (encodedBytes.length) {
|
||||
this.chunks.push(this.decodeQPBytes(encodedBytes));
|
||||
}
|
||||
}
|
||||
update(buffer) {
|
||||
let str = this.decoder.decode(buffer) + "\n";
|
||||
str = this.remainder + str;
|
||||
if (str.length < this.maxChunkSize) {
|
||||
this.remainder = str;
|
||||
return;
|
||||
}
|
||||
this.remainder = "";
|
||||
let partialEnding = str.match(PARTIAL_QP_ENDING_REGEX);
|
||||
if (partialEnding) {
|
||||
if (partialEnding.index === 0) {
|
||||
this.remainder = str;
|
||||
return;
|
||||
}
|
||||
this.remainder = str.substr(partialEnding.index);
|
||||
str = str.substr(0, partialEnding.index);
|
||||
}
|
||||
this.decodeChunks(str);
|
||||
}
|
||||
finalize() {
|
||||
if (this.remainder.length) {
|
||||
this.decodeChunks(this.remainder);
|
||||
this.remainder = "";
|
||||
}
|
||||
return (0, import_decode_strings.blobToArrayBuffer)(new Blob(this.chunks, { type: "application/octet-stream" }));
|
||||
}
|
||||
}
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
284
node_modules/postal-mime/dist/text-format.cjs
generated
vendored
Normal file
284
node_modules/postal-mime/dist/text-format.cjs
generated
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var text_format_exports = {};
|
||||
__export(text_format_exports, {
|
||||
decodeHTMLEntities: () => decodeHTMLEntities,
|
||||
escapeHtml: () => escapeHtml,
|
||||
formatHtmlHeader: () => formatHtmlHeader,
|
||||
formatTextHeader: () => formatTextHeader,
|
||||
htmlToText: () => htmlToText,
|
||||
textToHtml: () => textToHtml
|
||||
});
|
||||
module.exports = __toCommonJS(text_format_exports);
|
||||
var import_html_entities = __toESM(require("./html-entities.cjs"), 1);
|
||||
function decodeHTMLEntities(str) {
|
||||
return str.replace(/&(#\d+|#x[a-f0-9]+|[a-z]+\d*);?/gi, (match, entity) => {
|
||||
if (typeof import_html_entities.default[match] === "string") {
|
||||
return import_html_entities.default[match];
|
||||
}
|
||||
if (entity.charAt(0) !== "#" || match.charAt(match.length - 1) !== ";") {
|
||||
return match;
|
||||
}
|
||||
let codePoint;
|
||||
if (entity.charAt(1) === "x") {
|
||||
codePoint = parseInt(entity.substr(2), 16);
|
||||
} else {
|
||||
codePoint = parseInt(entity.substr(1), 10);
|
||||
}
|
||||
let output = "";
|
||||
if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) {
|
||||
return "\uFFFD";
|
||||
}
|
||||
if (codePoint > 65535) {
|
||||
codePoint -= 65536;
|
||||
output += String.fromCharCode(codePoint >>> 10 & 1023 | 55296);
|
||||
codePoint = 56320 | codePoint & 1023;
|
||||
}
|
||||
output += String.fromCharCode(codePoint);
|
||||
return output;
|
||||
});
|
||||
}
|
||||
function escapeHtml(str) {
|
||||
return str.trim().replace(/[<>"'?&]/g, (c) => {
|
||||
let hex = c.charCodeAt(0).toString(16);
|
||||
if (hex.length < 2) {
|
||||
hex = "0" + hex;
|
||||
}
|
||||
return "&#x" + hex.toUpperCase() + ";";
|
||||
});
|
||||
}
|
||||
function textToHtml(str) {
|
||||
let html = escapeHtml(str).replace(/\n/g, "<br />");
|
||||
return "<div>" + html + "</div>";
|
||||
}
|
||||
function htmlToText(str) {
|
||||
str = str.replace(/\r?\n/g, "").replace(/<\!\-\-.*?\-\->/gi, " ").replace(/<br\b[^>]*>/gi, "\n").replace(/<\/?(p|div|table|tr|td|th)\b[^>]*>/gi, "\n\n").replace(/<script\b[^>]*>.*?<\/script\b[^>]*>/gi, " ").replace(/^.*<body\b[^>]*>/i, "").replace(/^.*<\/head\b[^>]*>/i, "").replace(/^.*<\!doctype\b[^>]*>/i, "").replace(/<\/body\b[^>]*>.*$/i, "").replace(/<\/html\b[^>]*>.*$/i, "").replace(/<a\b[^>]*href\s*=\s*["']?([^\s"']+)[^>]*>/gi, " ($1) ").replace(/<\/?(span|em|i|strong|b|u|a)\b[^>]*>/gi, "").replace(/<li\b[^>]*>[\n\u0001\s]*/gi, "* ").replace(/<hr\b[^>]*>/g, "\n-------------\n").replace(/<[^>]*>/g, " ").replace(/\u0001/g, "\n").replace(/[ \t]+/g, " ").replace(/^\s+$/gm, "").replace(/\n\n+/g, "\n\n").replace(/^\n+/, "\n").replace(/\n+$/, "\n");
|
||||
str = decodeHTMLEntities(str);
|
||||
return str;
|
||||
}
|
||||
function formatTextAddress(address) {
|
||||
return [].concat(address.name || []).concat(address.name ? `<${address.address}>` : address.address).join(" ");
|
||||
}
|
||||
function formatTextAddresses(addresses) {
|
||||
let parts = [];
|
||||
let processAddress = (address, partCounter) => {
|
||||
if (partCounter) {
|
||||
parts.push(", ");
|
||||
}
|
||||
if (address.group) {
|
||||
let groupStart = `${address.name}:`;
|
||||
let groupEnd = `;`;
|
||||
parts.push(groupStart);
|
||||
address.group.forEach(processAddress);
|
||||
parts.push(groupEnd);
|
||||
} else {
|
||||
parts.push(formatTextAddress(address));
|
||||
}
|
||||
};
|
||||
addresses.forEach(processAddress);
|
||||
return parts.join("");
|
||||
}
|
||||
function formatHtmlAddress(address) {
|
||||
return `<a href="mailto:${escapeHtml(address.address)}" class="postal-email-address">${escapeHtml(address.name || `<${address.address}>`)}</a>`;
|
||||
}
|
||||
function formatHtmlAddresses(addresses) {
|
||||
let parts = [];
|
||||
let processAddress = (address, partCounter) => {
|
||||
if (partCounter) {
|
||||
parts.push('<span class="postal-email-address-separator">, </span>');
|
||||
}
|
||||
if (address.group) {
|
||||
let groupStart = `<span class="postal-email-address-group">${escapeHtml(address.name)}:</span>`;
|
||||
let groupEnd = `<span class="postal-email-address-group">;</span>`;
|
||||
parts.push(groupStart);
|
||||
address.group.forEach(processAddress);
|
||||
parts.push(groupEnd);
|
||||
} else {
|
||||
parts.push(formatHtmlAddress(address));
|
||||
}
|
||||
};
|
||||
addresses.forEach(processAddress);
|
||||
return parts.join(" ");
|
||||
}
|
||||
function foldLines(str, lineLength, afterSpace) {
|
||||
str = (str || "").toString();
|
||||
lineLength = lineLength || 76;
|
||||
let pos = 0, len = str.length, result = "", line, match;
|
||||
while (pos < len) {
|
||||
line = str.substr(pos, lineLength);
|
||||
if (line.length < lineLength) {
|
||||
result += line;
|
||||
break;
|
||||
}
|
||||
if (match = line.match(/^[^\n\r]*(\r?\n|\r)/)) {
|
||||
line = match[0];
|
||||
result += line;
|
||||
pos += line.length;
|
||||
continue;
|
||||
} else if ((match = line.match(/(\s+)[^\s]*$/)) && match[0].length - (afterSpace ? (match[1] || "").length : 0) < line.length) {
|
||||
line = line.substr(0, line.length - (match[0].length - (afterSpace ? (match[1] || "").length : 0)));
|
||||
} else if (match = str.substr(pos + line.length).match(/^[^\s]+(\s*)/)) {
|
||||
line = line + match[0].substr(0, match[0].length - (!afterSpace ? (match[1] || "").length : 0));
|
||||
}
|
||||
result += line;
|
||||
pos += line.length;
|
||||
if (pos < len) {
|
||||
result += "\r\n";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function formatTextHeader(message) {
|
||||
let rows = [];
|
||||
if (message.from) {
|
||||
rows.push({ key: "From", val: formatTextAddress(message.from) });
|
||||
}
|
||||
if (message.subject) {
|
||||
rows.push({ key: "Subject", val: message.subject });
|
||||
}
|
||||
if (message.date) {
|
||||
let dateOptions = {
|
||||
year: "numeric",
|
||||
month: "numeric",
|
||||
day: "numeric",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
second: "numeric",
|
||||
hour12: false
|
||||
};
|
||||
let dateStr = typeof Intl === "undefined" ? message.date : new Intl.DateTimeFormat("default", dateOptions).format(new Date(message.date));
|
||||
rows.push({ key: "Date", val: dateStr });
|
||||
}
|
||||
if (message.to && message.to.length) {
|
||||
rows.push({ key: "To", val: formatTextAddresses(message.to) });
|
||||
}
|
||||
if (message.cc && message.cc.length) {
|
||||
rows.push({ key: "Cc", val: formatTextAddresses(message.cc) });
|
||||
}
|
||||
if (message.bcc && message.bcc.length) {
|
||||
rows.push({ key: "Bcc", val: formatTextAddresses(message.bcc) });
|
||||
}
|
||||
let maxKeyLength = rows.map((r) => r.key.length).reduce((acc, cur) => {
|
||||
return cur > acc ? cur : acc;
|
||||
}, 0);
|
||||
rows = rows.flatMap((row) => {
|
||||
let sepLen = maxKeyLength - row.key.length;
|
||||
let prefix = `${row.key}: ${" ".repeat(sepLen)}`;
|
||||
let emptyPrefix = `${" ".repeat(row.key.length + 1)} ${" ".repeat(sepLen)}`;
|
||||
let foldedLines = foldLines(row.val, 80, true).split(/\r?\n/).map((line) => line.trim());
|
||||
return foldedLines.map((line, i) => `${i ? emptyPrefix : prefix}${line}`);
|
||||
});
|
||||
let maxLineLength = rows.map((r) => r.length).reduce((acc, cur) => {
|
||||
return cur > acc ? cur : acc;
|
||||
}, 0);
|
||||
let lineMarker = "-".repeat(maxLineLength);
|
||||
let template = `
|
||||
${lineMarker}
|
||||
${rows.join("\n")}
|
||||
${lineMarker}
|
||||
`;
|
||||
return template;
|
||||
}
|
||||
function formatHtmlHeader(message) {
|
||||
let rows = [];
|
||||
if (message.from) {
|
||||
rows.push(
|
||||
`<div class="postal-email-header-key">From</div><div class="postal-email-header-value">${formatHtmlAddress(message.from)}</div>`
|
||||
);
|
||||
}
|
||||
if (message.subject) {
|
||||
rows.push(
|
||||
`<div class="postal-email-header-key">Subject</div><div class="postal-email-header-value postal-email-header-subject">${escapeHtml(
|
||||
message.subject
|
||||
)}</div>`
|
||||
);
|
||||
}
|
||||
if (message.date) {
|
||||
let dateOptions = {
|
||||
year: "numeric",
|
||||
month: "numeric",
|
||||
day: "numeric",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
second: "numeric",
|
||||
hour12: false
|
||||
};
|
||||
let dateStr = typeof Intl === "undefined" ? message.date : new Intl.DateTimeFormat("default", dateOptions).format(new Date(message.date));
|
||||
rows.push(
|
||||
`<div class="postal-email-header-key">Date</div><div class="postal-email-header-value postal-email-header-date" data-date="${escapeHtml(
|
||||
message.date
|
||||
)}">${escapeHtml(dateStr)}</div>`
|
||||
);
|
||||
}
|
||||
if (message.to && message.to.length) {
|
||||
rows.push(
|
||||
`<div class="postal-email-header-key">To</div><div class="postal-email-header-value">${formatHtmlAddresses(message.to)}</div>`
|
||||
);
|
||||
}
|
||||
if (message.cc && message.cc.length) {
|
||||
rows.push(
|
||||
`<div class="postal-email-header-key">Cc</div><div class="postal-email-header-value">${formatHtmlAddresses(message.cc)}</div>`
|
||||
);
|
||||
}
|
||||
if (message.bcc && message.bcc.length) {
|
||||
rows.push(
|
||||
`<div class="postal-email-header-key">Bcc</div><div class="postal-email-header-value">${formatHtmlAddresses(message.bcc)}</div>`
|
||||
);
|
||||
}
|
||||
let template = `<div class="postal-email-header">${rows.length ? '<div class="postal-email-header-row">' : ""}${rows.join(
|
||||
'</div>\n<div class="postal-email-header-row">'
|
||||
)}${rows.length ? "</div>" : ""}</div>`;
|
||||
return template;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
decodeHTMLEntities,
|
||||
escapeHtml,
|
||||
formatHtmlHeader,
|
||||
formatTextHeader,
|
||||
htmlToText,
|
||||
textToHtml
|
||||
});
|
||||
|
||||
// Make default export work naturally with require()
|
||||
if (module.exports.default) {
|
||||
var defaultExport = module.exports.default;
|
||||
var namedExports = {};
|
||||
for (var key in module.exports) {
|
||||
if (key !== 'default' && key !== '__esModule') {
|
||||
namedExports[key] = module.exports[key];
|
||||
}
|
||||
}
|
||||
module.exports = defaultExport;
|
||||
Object.assign(module.exports, namedExports);
|
||||
// Preserve __esModule and .default for bundler/transpiler interop
|
||||
Object.defineProperty(module.exports, '__esModule', { value: true });
|
||||
module.exports.default = defaultExport;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user