flickr-sdk
Version:
Almost certainly the best Flickr API client in the world for node and the browser
1,326 lines (1,311 loc) • 66.8 kB
JavaScript
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 __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
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
));
// node_modules/@rgrove/parse-xml/dist/lib/StringScanner.js
var require_StringScanner = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/StringScanner.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StringScanner = void 0;
var emptyString = "";
var surrogatePair = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
var StringScanner = class {
constructor(string) {
this.charCount = this.charLength(string, true);
this.charIndex = 0;
this.length = string.length;
this.multiByteMode = this.charCount !== this.length;
this.string = string;
if (this.multiByteMode) {
let charsToBytes = [];
for (let byteIndex = 0, charIndex = 0; charIndex < this.charCount; ++charIndex) {
charsToBytes[charIndex] = byteIndex;
byteIndex += string.codePointAt(byteIndex) > 65535 ? 2 : 1;
}
this.charsToBytes = charsToBytes;
}
}
/**
* Whether the current character index is at the end of the input string.
*/
get isEnd() {
return this.charIndex >= this.charCount;
}
// -- Protected Methods ------------------------------------------------------
/**
* Returns the number of characters in the given string, which may differ from
* the byte length if the string contains multibyte characters.
*/
charLength(string, multiByteSafe = this.multiByteMode) {
return multiByteSafe ? string.replace(surrogatePair, "_").length : string.length;
}
// -- Public Methods ---------------------------------------------------------
/**
* Advances the scanner by the given number of characters, stopping if the end
* of the string is reached.
*/
advance(count = 1) {
this.charIndex = Math.min(this.charCount, this.charIndex + count);
}
/**
* Returns the byte index of the given character index in the string. The two
* may differ in strings that contain multibyte characters.
*/
charIndexToByteIndex(charIndex = this.charIndex) {
return this.multiByteMode ? this.charsToBytes[charIndex] ?? Infinity : charIndex;
}
/**
* Consumes and returns the given number of characters if possible, advancing
* the scanner and stopping if the end of the string is reached.
*
* If no characters could be consumed, an empty string will be returned.
*/
consume(charCount = 1) {
let chars2 = this.peek(charCount);
this.advance(charCount);
return chars2;
}
/**
* Consumes and returns the given number of bytes if possible, advancing the
* scanner and stopping if the end of the string is reached.
*
* It's up to the caller to ensure that the given byte count doesn't split a
* multibyte character.
*
* If no bytes could be consumed, an empty string will be returned.
*/
consumeBytes(byteCount) {
let byteIndex = this.charIndexToByteIndex();
let result = this.string.slice(byteIndex, byteIndex + byteCount);
this.advance(this.charLength(result));
return result;
}
/**
* Consumes and returns all characters for which the given function returns
* `true`, stopping when `false` is returned or the end of the input is
* reached.
*/
consumeMatchFn(fn) {
let { length, multiByteMode, string } = this;
let startByteIndex = this.charIndexToByteIndex();
let endByteIndex = startByteIndex;
if (multiByteMode) {
while (endByteIndex < length) {
let char = string[endByteIndex];
let isSurrogatePair = char >= "\uD800" && char <= "\uDBFF";
if (isSurrogatePair) {
char += string[endByteIndex + 1];
}
if (!fn(char)) {
break;
}
endByteIndex += isSurrogatePair ? 2 : 1;
}
} else {
while (endByteIndex < length && fn(string[endByteIndex])) {
++endByteIndex;
}
}
return this.consumeBytes(endByteIndex - startByteIndex);
}
/**
* Consumes the given string if it exists at the current character index, and
* advances the scanner.
*
* If the given string doesn't exist at the current character index, an empty
* string will be returned and the scanner will not be advanced.
*/
consumeString(stringToConsume) {
let { length } = stringToConsume;
let byteIndex = this.charIndexToByteIndex();
if (stringToConsume === this.string.slice(byteIndex, byteIndex + length)) {
this.advance(length === 1 ? 1 : this.charLength(stringToConsume));
return stringToConsume;
}
return emptyString;
}
/**
* Consumes characters until the given global regex is matched, advancing the
* scanner up to (but not beyond) the beginning of the match. If the regex
* doesn't match, nothing will be consumed.
*
* Returns the consumed string, or an empty string if nothing was consumed.
*/
consumeUntilMatch(regex2) {
let matchByteIndex = this.string.slice(this.charIndexToByteIndex()).search(regex2);
return matchByteIndex > 0 ? this.consumeBytes(matchByteIndex) : emptyString;
}
/**
* Consumes characters until the given string is found, advancing the scanner
* up to (but not beyond) that point. If the string is never found, nothing
* will be consumed.
*
* Returns the consumed string, or an empty string if nothing was consumed.
*/
consumeUntilString(searchString) {
let byteIndex = this.charIndexToByteIndex();
let matchByteIndex = this.string.indexOf(searchString, byteIndex);
return matchByteIndex > 0 ? this.consumeBytes(matchByteIndex - byteIndex) : emptyString;
}
/**
* Returns the given number of characters starting at the current character
* index, without advancing the scanner and without exceeding the end of the
* input string.
*/
peek(count = 1) {
let { charIndex, string } = this;
return this.multiByteMode ? string.slice(this.charIndexToByteIndex(charIndex), this.charIndexToByteIndex(charIndex + count)) : string.slice(charIndex, charIndex + count);
}
/**
* Resets the scanner position to the given character _index_, or to the start
* of the input string if no index is given.
*
* If _index_ is negative, the scanner position will be moved backward by that
* many characters, stopping if the beginning of the string is reached.
*/
reset(index = 0) {
this.charIndex = index >= 0 ? Math.min(this.charCount, index) : Math.max(0, this.charIndex + index);
}
};
exports.StringScanner = StringScanner;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/syntax.js
var require_syntax = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/syntax.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.predefinedEntities = exports.endCharData = exports.attValueNormalizedWhitespace = exports.attValueCharSingleQuote = exports.attValueCharDoubleQuote = void 0;
exports.isNameChar = isNameChar;
exports.isNameStartChar = isNameStartChar;
exports.isReferenceChar = isReferenceChar;
exports.isWhitespace = isWhitespace;
exports.isXmlCodePoint = isXmlCodePoint;
exports.attValueCharDoubleQuote = /["&<]/;
exports.attValueCharSingleQuote = /['&<]/;
exports.attValueNormalizedWhitespace = /\r\n|[\n\r\t]/g;
exports.endCharData = /<|&|]]>/;
exports.predefinedEntities = Object.freeze(Object.assign(/* @__PURE__ */ Object.create(null), {
amp: "&",
apos: "'",
gt: ">",
lt: "<",
quot: '"'
}));
function isNameChar(char) {
let cp = char.codePointAt(0);
return cp >= 97 && cp <= 122 || cp >= 65 && cp <= 90 || cp >= 48 && cp <= 57 || cp === 45 || cp === 46 || cp === 183 || cp >= 768 && cp <= 879 || cp === 8255 || cp === 8256 || isNameStartChar(char, cp);
}
function isNameStartChar(char, cp = char.codePointAt(0)) {
return cp >= 97 && cp <= 122 || cp >= 65 && cp <= 90 || cp === 58 || cp === 95 || cp >= 192 && cp <= 214 || cp >= 216 && cp <= 246 || cp >= 248 && cp <= 767 || cp >= 880 && cp <= 893 || cp >= 895 && cp <= 8191 || cp === 8204 || cp === 8205 || cp >= 8304 && cp <= 8591 || cp >= 11264 && cp <= 12271 || cp >= 12289 && cp <= 55295 || cp >= 63744 && cp <= 64975 || cp >= 65008 && cp <= 65533 || cp >= 65536 && cp <= 983039;
}
function isReferenceChar(char) {
return char === "#" || isNameChar(char);
}
function isWhitespace(char) {
let cp = char.codePointAt(0);
return cp === 32 || cp === 9 || cp === 10 || cp === 13;
}
function isXmlCodePoint(cp) {
return cp >= 32 && cp <= 55295 || cp === 10 || cp === 9 || cp === 13 || cp >= 57344 && cp <= 65533 || cp >= 65536 && cp <= 1114111;
}
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlNode.js
var require_XmlNode = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlNode.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlNode = void 0;
var XmlNode2 = class _XmlNode {
constructor() {
this.parent = null;
this.start = -1;
this.end = -1;
}
/**
* Document that contains this node, or `null` if this node is not associated
* with a document.
*/
get document() {
return this.parent?.document ?? null;
}
/**
* Whether this node is the root node of the document (also known as the
* document element).
*/
get isRootNode() {
return this.parent !== null && this.parent === this.document && this.type === _XmlNode.TYPE_ELEMENT;
}
/**
* Whether whitespace should be preserved in the content of this element and
* its children.
*
* This is influenced by the value of the special `xml:space` attribute, and
* will be `true` for any node whose `xml:space` attribute is set to
* "preserve". If a node has no such attribute, it will inherit the value of
* the nearest ancestor that does (if any).
*
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-white-space
*/
get preserveWhitespace() {
return !!this.parent?.preserveWhitespace;
}
/**
* Type of this node.
*
* The value of this property is a string that matches one of the static
* `TYPE_*` properties on the `XmlNode` class (e.g. `TYPE_ELEMENT`,
* `TYPE_TEXT`, etc.).
*
* The `XmlNode` class itself is a base class and doesn't have its own type
* name.
*/
get type() {
return "";
}
/**
* Returns a JSON-serializable object representing this node, minus properties
* that could result in circular references.
*/
toJSON() {
let json = {
type: this.type
};
if (this.isRootNode) {
json.isRootNode = true;
}
if (this.preserveWhitespace) {
json.preserveWhitespace = true;
}
if (this.start !== -1) {
json.start = this.start;
json.end = this.end;
}
return json;
}
};
exports.XmlNode = XmlNode2;
XmlNode2.TYPE_CDATA = "cdata";
XmlNode2.TYPE_COMMENT = "comment";
XmlNode2.TYPE_DOCUMENT = "document";
XmlNode2.TYPE_DOCUMENT_TYPE = "doctype";
XmlNode2.TYPE_ELEMENT = "element";
XmlNode2.TYPE_PROCESSING_INSTRUCTION = "pi";
XmlNode2.TYPE_TEXT = "text";
XmlNode2.TYPE_XML_DECLARATION = "xmldecl";
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlText.js
var require_XmlText = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlText.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlText = void 0;
var XmlNode_js_1 = require_XmlNode();
var XmlText2 = class extends XmlNode_js_1.XmlNode {
constructor(text = "") {
super();
this.text = text;
}
get type() {
return XmlNode_js_1.XmlNode.TYPE_TEXT;
}
toJSON() {
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
text: this.text
});
}
};
exports.XmlText = XmlText2;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.js
var require_XmlCdata = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlCdata.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlCdata = void 0;
var XmlNode_js_1 = require_XmlNode();
var XmlText_js_1 = require_XmlText();
var XmlCdata = class extends XmlText_js_1.XmlText {
get type() {
return XmlNode_js_1.XmlNode.TYPE_CDATA;
}
};
exports.XmlCdata = XmlCdata;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlComment.js
var require_XmlComment = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlComment.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlComment = void 0;
var XmlNode_js_1 = require_XmlNode();
var XmlComment = class extends XmlNode_js_1.XmlNode {
constructor(content = "") {
super();
this.content = content;
}
get type() {
return XmlNode_js_1.XmlNode.TYPE_COMMENT;
}
toJSON() {
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
content: this.content
});
}
};
exports.XmlComment = XmlComment;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.js
var require_XmlDeclaration = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlDeclaration.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlDeclaration = void 0;
var XmlNode_js_1 = require_XmlNode();
var XmlDeclaration = class extends XmlNode_js_1.XmlNode {
constructor(version, encoding, standalone) {
super();
this.version = version;
this.encoding = encoding ?? null;
this.standalone = standalone ?? null;
}
get type() {
return XmlNode_js_1.XmlNode.TYPE_XML_DECLARATION;
}
toJSON() {
let json = XmlNode_js_1.XmlNode.prototype.toJSON.call(this);
json.version = this.version;
for (let key of ["encoding", "standalone"]) {
if (this[key] !== null) {
json[key] = this[key];
}
}
return json;
}
};
exports.XmlDeclaration = XmlDeclaration;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlElement.js
var require_XmlElement = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlElement.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlElement = void 0;
var XmlNode_js_1 = require_XmlNode();
var XmlElement2 = class _XmlElement extends XmlNode_js_1.XmlNode {
constructor(name, attributes = /* @__PURE__ */ Object.create(null), children = []) {
super();
this.name = name;
this.attributes = attributes;
this.children = children;
}
/**
* Whether this element is empty (meaning it has no children).
*/
get isEmpty() {
return this.children.length === 0;
}
get preserveWhitespace() {
let node = this;
while (node instanceof _XmlElement) {
if ("xml:space" in node.attributes) {
return node.attributes["xml:space"] === "preserve";
}
node = node.parent;
}
return false;
}
/**
* Text content of this element and all its descendants.
*/
get text() {
return this.children.map((child) => "text" in child ? child.text : "").join("");
}
get type() {
return XmlNode_js_1.XmlNode.TYPE_ELEMENT;
}
toJSON() {
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
name: this.name,
attributes: this.attributes,
children: this.children.map((child) => child.toJSON())
});
}
};
exports.XmlElement = XmlElement2;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.js
var require_XmlDocument = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlDocument.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlDocument = void 0;
var XmlElement_js_1 = require_XmlElement();
var XmlNode_js_1 = require_XmlNode();
var XmlDocument = class extends XmlNode_js_1.XmlNode {
constructor(children = []) {
super();
this.children = children;
}
get document() {
return this;
}
/**
* Root element of this document, or `null` if this document is empty.
*/
get root() {
for (let child of this.children) {
if (child instanceof XmlElement_js_1.XmlElement) {
return child;
}
}
return null;
}
/**
* Text content of this document and all its descendants.
*/
get text() {
return this.children.map((child) => "text" in child ? child.text : "").join("");
}
get type() {
return XmlNode_js_1.XmlNode.TYPE_DOCUMENT;
}
toJSON() {
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
children: this.children.map((child) => child.toJSON())
});
}
};
exports.XmlDocument = XmlDocument;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.js
var require_XmlDocumentType = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlDocumentType.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlDocumentType = void 0;
var XmlNode_js_1 = require_XmlNode();
var XmlDocumentType = class extends XmlNode_js_1.XmlNode {
constructor(name, publicId, systemId, internalSubset) {
super();
this.name = name;
this.publicId = publicId ?? null;
this.systemId = systemId ?? null;
this.internalSubset = internalSubset ?? null;
}
get type() {
return XmlNode_js_1.XmlNode.TYPE_DOCUMENT_TYPE;
}
toJSON() {
let json = XmlNode_js_1.XmlNode.prototype.toJSON.call(this);
json.name = this.name;
for (let key of ["publicId", "systemId", "internalSubset"]) {
if (this[key] !== null) {
json[key] = this[key];
}
}
return json;
}
};
exports.XmlDocumentType = XmlDocumentType;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlError.js
var require_XmlError = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlError.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlError = void 0;
var XmlError = class extends Error {
constructor(message, charIndex, xml) {
let column = 1;
let excerpt = "";
let line = 1;
for (let i = 0; i < charIndex; ++i) {
let char = xml[i];
if (char === "\n") {
column = 1;
excerpt = "";
line += 1;
} else {
column += 1;
excerpt += char;
}
}
let eol = xml.indexOf("\n", charIndex);
excerpt += eol === -1 ? xml.slice(charIndex) : xml.slice(charIndex, eol);
let excerptStart = 0;
if (excerpt.length > 50) {
if (column < 40) {
excerpt = excerpt.slice(0, 50);
} else {
excerptStart = column - 20;
excerpt = excerpt.slice(excerptStart, column + 30);
}
}
super(`${message} (line ${line}, column ${column})
${excerpt}
` + " ".repeat(column - excerptStart + 1) + "^\n");
this.column = column;
this.excerpt = excerpt;
this.line = line;
this.name = "XmlError";
this.pos = charIndex;
}
};
exports.XmlError = XmlError;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.js
var require_XmlProcessingInstruction = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/XmlProcessingInstruction.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlProcessingInstruction = void 0;
var XmlNode_js_1 = require_XmlNode();
var XmlProcessingInstruction = class extends XmlNode_js_1.XmlNode {
constructor(name, content = "") {
super();
this.name = name;
this.content = content;
}
get type() {
return XmlNode_js_1.XmlNode.TYPE_PROCESSING_INSTRUCTION;
}
toJSON() {
return Object.assign(XmlNode_js_1.XmlNode.prototype.toJSON.call(this), {
name: this.name,
content: this.content
});
}
};
exports.XmlProcessingInstruction = XmlProcessingInstruction;
}
});
// node_modules/@rgrove/parse-xml/dist/lib/Parser.js
var require_Parser = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/Parser.js"(exports) {
"use strict";
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === void 0)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === void 0)
k2 = k;
o[k2] = m[k];
});
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
} : function(o, v) {
o["default"] = v;
});
var __importStar = exports && exports.__importStar || function(mod) {
if (mod && mod.__esModule)
return mod;
var result = {};
if (mod != null) {
for (var k in mod)
if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
__createBinding(result, mod, k);
}
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Parser = void 0;
var StringScanner_js_1 = require_StringScanner();
var syntax = __importStar(require_syntax());
var XmlCdata_js_1 = require_XmlCdata();
var XmlComment_js_1 = require_XmlComment();
var XmlDeclaration_js_1 = require_XmlDeclaration();
var XmlDocument_js_1 = require_XmlDocument();
var XmlDocumentType_js_1 = require_XmlDocumentType();
var XmlElement_js_1 = require_XmlElement();
var XmlError_js_1 = require_XmlError();
var XmlNode_js_1 = require_XmlNode();
var XmlProcessingInstruction_js_1 = require_XmlProcessingInstruction();
var XmlText_js_1 = require_XmlText();
var emptyString = "";
var Parser = class {
/**
* @param xml XML string to parse.
* @param options Parser options.
*/
constructor(xml, options = {}) {
let doc = this.document = new XmlDocument_js_1.XmlDocument();
this.currentNode = doc;
this.options = options;
this.scanner = new StringScanner_js_1.StringScanner(xml);
if (this.options.includeOffsets) {
doc.start = 0;
doc.end = xml.length;
}
this.parse();
}
/**
* Adds the given `XmlNode` as a child of `this.currentNode`.
*/
addNode(node, charIndex) {
node.parent = this.currentNode;
if (this.options.includeOffsets) {
node.start = this.scanner.charIndexToByteIndex(charIndex);
node.end = this.scanner.charIndexToByteIndex();
}
this.currentNode.children.push(node);
return true;
}
/**
* Adds the given _text_ to the document, either by appending it to a
* preceding `XmlText` node (if possible) or by creating a new `XmlText` node.
*/
addText(text, charIndex) {
let { children } = this.currentNode;
let { length } = children;
text = normalizeLineBreaks(text);
if (length > 0) {
let prevNode = children[length - 1];
if (prevNode?.type === XmlNode_js_1.XmlNode.TYPE_TEXT) {
let textNode = prevNode;
textNode.text += text;
if (this.options.includeOffsets) {
textNode.end = this.scanner.charIndexToByteIndex();
}
return true;
}
}
return this.addNode(new XmlText_js_1.XmlText(text), charIndex);
}
/**
* Consumes element attributes.
*
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-starttags
*/
consumeAttributes() {
let attributes = /* @__PURE__ */ Object.create(null);
while (this.consumeWhitespace()) {
let attrName = this.consumeName();
if (!attrName) {
break;
}
let attrValue = this.consumeEqual() && this.consumeAttributeValue();
if (attrValue === false) {
throw this.error("Attribute value expected");
}
if (attrName in attributes) {
throw this.error(`Duplicate attribute: ${attrName}`);
}
if (attrName === "xml:space" && attrValue !== "default" && attrValue !== "preserve") {
throw this.error('Value of the `xml:space` attribute must be "default" or "preserve"');
}
attributes[attrName] = attrValue;
}
if (this.options.sortAttributes) {
let attrNames = Object.keys(attributes).sort();
let sortedAttributes = /* @__PURE__ */ Object.create(null);
for (let i = 0; i < attrNames.length; ++i) {
let attrName = attrNames[i];
sortedAttributes[attrName] = attributes[attrName];
}
attributes = sortedAttributes;
}
return attributes;
}
/**
* Consumes an `AttValue` (attribute value) if possible.
*
* @returns
* Contents of the `AttValue` minus quotes, or `false` if nothing was
* consumed. An empty string indicates that an `AttValue` was consumed but
* was empty.
*
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-AttValue
*/
consumeAttributeValue() {
let { scanner } = this;
let quote = scanner.peek();
if (quote !== '"' && quote !== "'") {
return false;
}
scanner.advance();
let chars2;
let isClosed = false;
let value = emptyString;
let regex2 = quote === '"' ? syntax.attValueCharDoubleQuote : syntax.attValueCharSingleQuote;
matchLoop:
while (!scanner.isEnd) {
chars2 = scanner.consumeUntilMatch(regex2);
if (chars2) {
this.validateChars(chars2);
value += chars2.replace(syntax.attValueNormalizedWhitespace, " ");
}
switch (scanner.peek()) {
case quote:
isClosed = true;
break matchLoop;
case "&":
value += this.consumeReference();
continue;
case "<":
throw this.error("Unescaped `<` is not allowed in an attribute value");
default:
break matchLoop;
}
}
if (!isClosed) {
throw this.error("Unclosed attribute");
}
scanner.advance();
return value;
}
/**
* Consumes a CDATA section if possible.
*
* @returns Whether a CDATA section was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-cdata-sect
*/
consumeCdataSection() {
let { scanner } = this;
let startIndex = scanner.charIndex;
if (!scanner.consumeString("<![CDATA[")) {
return false;
}
let text = scanner.consumeUntilString("]]>");
this.validateChars(text);
if (!scanner.consumeString("]]>")) {
throw this.error("Unclosed CDATA section");
}
return this.options.preserveCdata ? this.addNode(new XmlCdata_js_1.XmlCdata(normalizeLineBreaks(text)), startIndex) : this.addText(text, startIndex);
}
/**
* Consumes character data if possible.
*
* @returns Whether character data was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dt-chardata
*/
consumeCharData() {
let { scanner } = this;
let startIndex = scanner.charIndex;
let charData = scanner.consumeUntilMatch(syntax.endCharData);
if (!charData) {
return false;
}
this.validateChars(charData);
if (scanner.peek(3) === "]]>") {
throw this.error("Element content may not contain the CDATA section close delimiter `]]>`");
}
return this.addText(charData, startIndex);
}
/**
* Consumes a comment if possible.
*
* @returns Whether a comment was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Comment
*/
consumeComment() {
let { scanner } = this;
let startIndex = scanner.charIndex;
if (!scanner.consumeString("<!--")) {
return false;
}
let content = scanner.consumeUntilString("--");
this.validateChars(content);
if (!scanner.consumeString("-->")) {
if (scanner.peek(2) === "--") {
throw this.error("The string `--` isn't allowed inside a comment");
}
throw this.error("Unclosed comment");
}
return this.options.preserveComments ? this.addNode(new XmlComment_js_1.XmlComment(normalizeLineBreaks(content)), startIndex) : true;
}
/**
* Consumes a reference in a content context if possible.
*
* This differs from `consumeReference()` in that a consumed reference will be
* added to the document as a text node instead of returned.
*
* @returns Whether a reference was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#entproc
*/
consumeContentReference() {
let startIndex = this.scanner.charIndex;
let ref = this.consumeReference();
return ref ? this.addText(ref, startIndex) : false;
}
/**
* Consumes a doctype declaration if possible.
*
* This is a loose implementation since doctype declarations are currently
* discarded without further parsing.
*
* @returns Whether a doctype declaration was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#dtd
*/
consumeDoctypeDeclaration() {
let { scanner } = this;
let startIndex = scanner.charIndex;
if (!scanner.consumeString("<!DOCTYPE")) {
return false;
}
let name = this.consumeWhitespace() && this.consumeName();
if (!name) {
throw this.error("Expected a name");
}
let publicId;
let systemId;
if (this.consumeWhitespace()) {
if (scanner.consumeString("PUBLIC")) {
publicId = this.consumeWhitespace() && this.consumePubidLiteral();
if (publicId === false) {
throw this.error("Expected a public identifier");
}
this.consumeWhitespace();
}
if (publicId !== void 0 || scanner.consumeString("SYSTEM")) {
this.consumeWhitespace();
systemId = this.consumeSystemLiteral();
if (systemId === false) {
throw this.error("Expected a system identifier");
}
this.consumeWhitespace();
}
}
let internalSubset;
if (scanner.consumeString("[")) {
internalSubset = scanner.consumeUntilMatch(/\][\x20\t\r\n]*>/);
if (!scanner.consumeString("]")) {
throw this.error("Unclosed internal subset");
}
this.consumeWhitespace();
}
if (!scanner.consumeString(">")) {
throw this.error("Unclosed doctype declaration");
}
return this.options.preserveDocumentType ? this.addNode(new XmlDocumentType_js_1.XmlDocumentType(name, publicId, systemId, internalSubset), startIndex) : true;
}
/**
* Consumes an element if possible.
*
* @returns Whether an element was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-element
*/
consumeElement() {
let { scanner } = this;
let startIndex = scanner.charIndex;
if (!scanner.consumeString("<")) {
return false;
}
let name = this.consumeName();
if (!name) {
scanner.reset(startIndex);
return false;
}
let attributes = this.consumeAttributes();
let isEmpty = !!scanner.consumeString("/>");
let element = new XmlElement_js_1.XmlElement(name, attributes);
element.parent = this.currentNode;
if (!isEmpty) {
if (!scanner.consumeString(">")) {
throw this.error(`Unclosed start tag for element \`${name}\``);
}
this.currentNode = element;
do {
this.consumeCharData();
} while (this.consumeElement() || this.consumeContentReference() || this.consumeCdataSection() || this.consumeProcessingInstruction() || this.consumeComment());
let endTagMark = scanner.charIndex;
let endTagName;
if (!scanner.consumeString("</") || !(endTagName = this.consumeName()) || endTagName !== name) {
scanner.reset(endTagMark);
throw this.error(`Missing end tag for element ${name}`);
}
this.consumeWhitespace();
if (!scanner.consumeString(">")) {
throw this.error(`Unclosed end tag for element ${name}`);
}
this.currentNode = element.parent;
}
return this.addNode(element, startIndex);
}
/**
* Consumes an `Eq` production if possible.
*
* @returns Whether an `Eq` production was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Eq
*/
consumeEqual() {
this.consumeWhitespace();
if (this.scanner.consumeString("=")) {
this.consumeWhitespace();
return true;
}
return false;
}
/**
* Consumes `Misc` content if possible.
*
* @returns Whether anything was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Misc
*/
consumeMisc() {
return this.consumeComment() || this.consumeProcessingInstruction() || this.consumeWhitespace();
}
/**
* Consumes one or more `Name` characters if possible.
*
* @returns `Name` characters, or an empty string if none were consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Name
*/
consumeName() {
return syntax.isNameStartChar(this.scanner.peek()) ? this.scanner.consumeMatchFn(syntax.isNameChar) : emptyString;
}
/**
* Consumes a processing instruction if possible.
*
* @returns Whether a processing instruction was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-pi
*/
consumeProcessingInstruction() {
let { scanner } = this;
let startIndex = scanner.charIndex;
if (!scanner.consumeString("<?")) {
return false;
}
let name = this.consumeName();
if (name) {
if (name.toLowerCase() === "xml") {
scanner.reset(startIndex);
throw this.error("XML declaration isn't allowed here");
}
} else {
throw this.error("Invalid processing instruction");
}
if (!this.consumeWhitespace()) {
if (scanner.consumeString("?>")) {
return this.addNode(new XmlProcessingInstruction_js_1.XmlProcessingInstruction(name), startIndex);
}
throw this.error("Whitespace is required after a processing instruction name");
}
let content = scanner.consumeUntilString("?>");
this.validateChars(content);
if (!scanner.consumeString("?>")) {
throw this.error("Unterminated processing instruction");
}
return this.addNode(new XmlProcessingInstruction_js_1.XmlProcessingInstruction(name, normalizeLineBreaks(content)), startIndex);
}
/**
* Consumes a prolog if possible.
*
* @returns Whether a prolog was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-prolog-dtd
*/
consumeProlog() {
let { scanner } = this;
let startIndex = scanner.charIndex;
this.consumeXmlDeclaration();
while (this.consumeMisc()) {
}
if (this.consumeDoctypeDeclaration()) {
while (this.consumeMisc()) {
}
}
return startIndex < scanner.charIndex;
}
/**
* Consumes a public identifier literal if possible.
*
* @returns
* Value of the public identifier literal minus quotes, or `false` if
* nothing was consumed. An empty string indicates that a public id literal
* was consumed but was empty.
*
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-PubidLiteral
*/
consumePubidLiteral() {
let startIndex = this.scanner.charIndex;
let value = this.consumeSystemLiteral();
if (value !== false && !/^[-\x20\r\na-zA-Z0-9'()+,./:=?;!*#@$_%]*$/.test(value)) {
this.scanner.reset(startIndex);
throw this.error("Invalid character in public identifier");
}
return value;
}
/**
* Consumes a reference if possible.
*
* This differs from `consumeContentReference()` in that a consumed reference
* will be returned rather than added to the document.
*
* @returns
* Parsed reference value, or `false` if nothing was consumed (to
* distinguish from a reference that resolves to an empty string).
*
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-Reference
*/
consumeReference() {
let { scanner } = this;
if (!scanner.consumeString("&")) {
return false;
}
let ref = scanner.consumeMatchFn(syntax.isReferenceChar);
if (scanner.consume() !== ";") {
throw this.error("Unterminated reference (a reference must end with `;`)");
}
let parsedValue;
if (ref[0] === "#") {
let codePoint = ref[1] === "x" ? parseInt(ref.slice(2), 16) : parseInt(ref.slice(1), 10);
if (isNaN(codePoint)) {
throw this.error("Invalid character reference");
}
if (!syntax.isXmlCodePoint(codePoint)) {
throw this.error("Character reference resolves to an invalid character");
}
parsedValue = String.fromCodePoint(codePoint);
} else {
parsedValue = syntax.predefinedEntities[ref];
if (parsedValue === void 0) {
let { ignoreUndefinedEntities, resolveUndefinedEntity } = this.options;
let wrappedRef = `&${ref};`;
if (resolveUndefinedEntity) {
let resolvedValue = resolveUndefinedEntity(wrappedRef);
if (resolvedValue !== null && resolvedValue !== void 0) {
let type = typeof resolvedValue;
if (type !== "string") {
throw new TypeError(`\`resolveUndefinedEntity()\` must return a string, \`null\`, or \`undefined\`, but returned a value of type ${type}`);
}
return resolvedValue;
}
}
if (ignoreUndefinedEntities) {
return wrappedRef;
}
scanner.reset(-wrappedRef.length);
throw this.error(`Named entity isn't defined: ${wrappedRef}`);
}
}
return parsedValue;
}
/**
* Consumes a `SystemLiteral` if possible.
*
* A `SystemLiteral` is similar to an attribute value, but allows the
* characters `<` and `&` and doesn't replace references.
*
* @returns
* Value of the `SystemLiteral` minus quotes, or `false` if nothing was
* consumed. An empty string indicates that a `SystemLiteral` was consumed
* but was empty.
*
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-SystemLiteral
*/
consumeSystemLiteral() {
let { scanner } = this;
let quote = scanner.consumeString('"') || scanner.consumeString("'");
if (!quote) {
return false;
}
let value = scanner.consumeUntilString(quote);
this.validateChars(value);
if (!scanner.consumeString(quote)) {
throw this.error("Missing end quote");
}
return value;
}
/**
* Consumes one or more whitespace characters if possible.
*
* @returns Whether any whitespace characters were consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#white
*/
consumeWhitespace() {
return !!this.scanner.consumeMatchFn(syntax.isWhitespace);
}
/**
* Consumes an XML declaration if possible.
*
* @returns Whether an XML declaration was consumed.
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#NT-XMLDecl
*/
consumeXmlDeclaration() {
let { scanner } = this;
let startIndex = scanner.charIndex;
if (!scanner.consumeString("<?xml")) {
return false;
}
if (!this.consumeWhitespace()) {
throw this.error("Invalid XML declaration");
}
let version = !!scanner.consumeString("version") && this.consumeEqual() && this.consumeSystemLiteral();
if (version === false) {
throw this.error("XML version is missing or invalid");
} else if (!/^1\.[0-9]+$/.test(version)) {
throw this.error("Invalid character in version number");
}
let encoding;
let standalone;
if (this.consumeWhitespace()) {
encoding = !!scanner.consumeString("encoding") && this.consumeEqual() && this.consumeSystemLiteral();
if (encoding) {
if (!/^[A-Za-z][\w.-]*$/.test(encoding)) {
throw this.error("Invalid character in encoding name");
}
this.consumeWhitespace();
}
standalone = !!scanner.consumeString("standalone") && this.consumeEqual() && this.consumeSystemLiteral();
if (standalone) {
if (standalone !== "yes" && standalone !== "no") {
throw this.error('Only "yes" and "no" are permitted as values of `standalone`');
}
this.consumeWhitespace();
}
}
if (!scanner.consumeString("?>")) {
throw this.error("Invalid or unclosed XML declaration");
}
return this.options.preserveXmlDeclaration ? this.addNode(new XmlDeclaration_js_1.XmlDeclaration(version, encoding || void 0, standalone || void 0), startIndex) : true;
}
/**
* Returns an `XmlError` for the current scanner position.
*/
error(message) {
let { scanner } = this;
return new XmlError_js_1.XmlError(message, scanner.charIndex, scanner.string);
}
/**
* Parses the XML input.
*/
parse() {
this.scanner.consumeString("\uFEFF");
this.consumeProlog();
if (!this.consumeElement()) {
throw this.error("Root element is missing or invalid");
}
while (this.consumeMisc()) {
}
if (!this.scanner.isEnd) {
throw this.error("Extra content at the end of the document");
}
}
/**
* Throws an invalid character error if any character in the given _string_
* isn't a valid XML character.
*/
validateChars(string) {
let { length } = string;
for (let i = 0; i < length; ++i) {
let cp = string.codePointAt(i);
if (!syntax.isXmlCodePoint(cp)) {
this.scanner.reset(-([...string].length - i));
throw this.error("Invalid character");
}
if (cp > 65535) {
i += 1;
}
}
}
};
exports.Parser = Parser;
function normalizeLineBreaks(text) {
let i = 0;
while ((i = text.indexOf("\r", i)) !== -1) {
text = text[i + 1] === "\n" ? text.slice(0, i) + text.slice(i + 1) : text.slice(0, i) + "\n" + text.slice(i + 1);
}
return text;
}
}
});
// node_modules/@rgrove/parse-xml/dist/lib/types.js
var require_types = __commonJS({
"node_modules/@rgrove/parse-xml/dist/lib/types.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
}
});
// node_modules/@rgrove/parse-xml/dist/index.js
var require_dist = __commonJS({
"node_modules/@rgrove/parse-xml/dist/index.js"(exports) {
"use strict";
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === void 0)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === void 0)
k2 = k;
o[k2] = m[k];
});
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
__createBinding(exports2, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.XmlText = exports.XmlProcessingInstruction = exports.XmlNode = exports.XmlError = exports.XmlElement = exports.XmlDocumentType = exports.XmlDocument = exports.XmlDeclaration = exports.XmlComment = exports.XmlCdata = void 0;
exports.parseXml = parseXml2;
var Parser_js_1 = require_Parser();
__exportStar(require_types(), exports);
var XmlCdata_js_1 = require_XmlCdata();
Object.defineProperty(exports, "XmlCdata", { enumerable: true, get: function() {
return XmlCdata_js_1.XmlCdata;
} });
var XmlComment_js_1 = require_XmlComment();
Object.defineProperty(exports, "XmlComment", { enumerable: true, get: function() {
return XmlComment_js_1.XmlComment;
} });
var XmlDeclaration_js_1 = require_XmlDeclaration();
Object.defineProperty(exports, "XmlDeclaration", { enumerable: true, get: function() {
return XmlDeclaration_js_1.XmlDeclaration;
} });
var XmlDocument_js_1 = require_XmlDocument();
Object.defineProperty(exports, "XmlDocument", { enumerable: true, get: function() {
return XmlDocument_js_1.XmlDocument;
} });
var XmlDocumentType_js_1 = require_XmlDocumentType();
Object.defineProperty(exports, "XmlDocumentType", { enumerable: true, get: function() {
return XmlDocumentType_js_1.XmlDocumentType;
} });
var XmlElement_js_1 = require_XmlElement();
Object.defineProperty(exports, "XmlElement", { enumerable: true, get: function() {
return XmlElement_js_1.Xml