@fre4x/arxiv 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +10 -10
  2. package/dist/index.js +1177 -429
  3. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -7065,9 +7065,9 @@ var require_combined_stream = __commonJS({
7065
7065
  }
7066
7066
  });
7067
7067
 
7068
- // ../node_modules/form-data/node_modules/mime-types/node_modules/mime-db/db.json
7068
+ // ../node_modules/form-data/node_modules/mime-db/db.json
7069
7069
  var require_db = __commonJS({
7070
- "../node_modules/form-data/node_modules/mime-types/node_modules/mime-db/db.json"(exports2, module) {
7070
+ "../node_modules/form-data/node_modules/mime-db/db.json"(exports2, module) {
7071
7071
  module.exports = {
7072
7072
  "application/1d-interleaved-parityfec": {
7073
7073
  source: "iana"
@@ -15590,9 +15590,9 @@ var require_db = __commonJS({
15590
15590
  }
15591
15591
  });
15592
15592
 
15593
- // ../node_modules/form-data/node_modules/mime-types/node_modules/mime-db/index.js
15593
+ // ../node_modules/form-data/node_modules/mime-db/index.js
15594
15594
  var require_mime_db = __commonJS({
15595
- "../node_modules/form-data/node_modules/mime-types/node_modules/mime-db/index.js"(exports2, module) {
15595
+ "../node_modules/form-data/node_modules/mime-db/index.js"(exports2, module) {
15596
15596
  module.exports = require_db();
15597
15597
  }
15598
15598
  });
@@ -16764,7 +16764,7 @@ var require_form_data = __commonJS({
16764
16764
  var path = __require("path");
16765
16765
  var http3 = __require("http");
16766
16766
  var https3 = __require("https");
16767
- var parseUrl = __require("url").parse;
16767
+ var parseUrl2 = __require("url").parse;
16768
16768
  var fs = __require("fs");
16769
16769
  var Stream = __require("stream").Stream;
16770
16770
  var crypto2 = __require("crypto");
@@ -17017,7 +17017,7 @@ var require_form_data = __commonJS({
17017
17017
  var options;
17018
17018
  var defaults2 = { method: "post" };
17019
17019
  if (typeof params === "string") {
17020
- params = parseUrl(params);
17020
+ params = parseUrl2(params);
17021
17021
  options = populate({
17022
17022
  port: params.port,
17023
17023
  path: params.pathname,
@@ -17074,76 +17074,6 @@ var require_form_data = __commonJS({
17074
17074
  }
17075
17075
  });
17076
17076
 
17077
- // ../node_modules/proxy-from-env/index.js
17078
- var require_proxy_from_env = __commonJS({
17079
- "../node_modules/proxy-from-env/index.js"(exports2) {
17080
- "use strict";
17081
- var parseUrl = __require("url").parse;
17082
- var DEFAULT_PORTS = {
17083
- ftp: 21,
17084
- gopher: 70,
17085
- http: 80,
17086
- https: 443,
17087
- ws: 80,
17088
- wss: 443
17089
- };
17090
- var stringEndsWith = String.prototype.endsWith || function(s) {
17091
- return s.length <= this.length && this.indexOf(s, this.length - s.length) !== -1;
17092
- };
17093
- function getProxyForUrl(url3) {
17094
- var parsedUrl = typeof url3 === "string" ? parseUrl(url3) : url3 || {};
17095
- var proto = parsedUrl.protocol;
17096
- var hostname3 = parsedUrl.host;
17097
- var port = parsedUrl.port;
17098
- if (typeof hostname3 !== "string" || !hostname3 || typeof proto !== "string") {
17099
- return "";
17100
- }
17101
- proto = proto.split(":", 1)[0];
17102
- hostname3 = hostname3.replace(/:\d*$/, "");
17103
- port = parseInt(port) || DEFAULT_PORTS[proto] || 0;
17104
- if (!shouldProxy(hostname3, port)) {
17105
- return "";
17106
- }
17107
- var proxy = getEnv("npm_config_" + proto + "_proxy") || getEnv(proto + "_proxy") || getEnv("npm_config_proxy") || getEnv("all_proxy");
17108
- if (proxy && proxy.indexOf("://") === -1) {
17109
- proxy = proto + "://" + proxy;
17110
- }
17111
- return proxy;
17112
- }
17113
- function shouldProxy(hostname3, port) {
17114
- var NO_PROXY = (getEnv("npm_config_no_proxy") || getEnv("no_proxy")).toLowerCase();
17115
- if (!NO_PROXY) {
17116
- return true;
17117
- }
17118
- if (NO_PROXY === "*") {
17119
- return false;
17120
- }
17121
- return NO_PROXY.split(/[,\s]/).every(function(proxy) {
17122
- if (!proxy) {
17123
- return true;
17124
- }
17125
- var parsedProxy = proxy.match(/^(.+):(\d+)$/);
17126
- var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy;
17127
- var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
17128
- if (parsedProxyPort && parsedProxyPort !== port) {
17129
- return true;
17130
- }
17131
- if (!/^[.*]/.test(parsedProxyHostname)) {
17132
- return hostname3 !== parsedProxyHostname;
17133
- }
17134
- if (parsedProxyHostname.charAt(0) === "*") {
17135
- parsedProxyHostname = parsedProxyHostname.slice(1);
17136
- }
17137
- return !stringEndsWith.call(hostname3, parsedProxyHostname);
17138
- });
17139
- }
17140
- function getEnv(key) {
17141
- return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || "";
17142
- }
17143
- exports2.getProxyForUrl = getProxyForUrl;
17144
- }
17145
- });
17146
-
17147
17077
  // ../node_modules/ms/index.js
17148
17078
  var require_ms = __commonJS({
17149
17079
  "../node_modules/ms/index.js"(exports2, module) {
@@ -18261,7 +18191,7 @@ var require_follow_redirects = __commonJS({
18261
18191
  removeMatchingHeaders(/^content-/i, this._options.headers);
18262
18192
  }
18263
18193
  var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
18264
- var currentUrlParts = parseUrl(this._currentUrl);
18194
+ var currentUrlParts = parseUrl2(this._currentUrl);
18265
18195
  var currentHost = currentHostHeader || currentUrlParts.host;
18266
18196
  var currentUrl = /^\w+:/.test(location) ? this._currentUrl : url3.format(Object.assign(currentUrlParts, { host: currentHost }));
18267
18197
  var redirectUrl = resolveUrl(location, currentUrl);
@@ -18300,7 +18230,7 @@ var require_follow_redirects = __commonJS({
18300
18230
  if (isURL(input)) {
18301
18231
  input = spreadUrlObject(input);
18302
18232
  } else if (isString2(input)) {
18303
- input = spreadUrlObject(parseUrl(input));
18233
+ input = spreadUrlObject(parseUrl2(input));
18304
18234
  } else {
18305
18235
  callback = options;
18306
18236
  options = validateUrl(input);
@@ -18336,7 +18266,7 @@ var require_follow_redirects = __commonJS({
18336
18266
  }
18337
18267
  function noop2() {
18338
18268
  }
18339
- function parseUrl(input) {
18269
+ function parseUrl2(input) {
18340
18270
  var parsed;
18341
18271
  if (useNativeURL) {
18342
18272
  parsed = new URL2(input);
@@ -18349,7 +18279,7 @@ var require_follow_redirects = __commonJS({
18349
18279
  return parsed;
18350
18280
  }
18351
18281
  function resolveUrl(relative, base) {
18352
- return useNativeURL ? new URL2(relative, base) : parseUrl(url3.resolve(base, relative));
18282
+ return useNativeURL ? new URL2(relative, base) : parseUrl2(url3.resolve(base, relative));
18353
18283
  }
18354
18284
  function validateUrl(input) {
18355
18285
  if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
@@ -32473,8 +32403,7 @@ config(en_default());
32473
32403
  var zod_default = external_exports;
32474
32404
 
32475
32405
  // ../packages/shared/dist/pagination.js
32476
- var zodCompat = zod_exports;
32477
- var z2 = zodCompat.z ?? zodCompat.default?.z ?? zodCompat.default ?? zodCompat;
32406
+ var z2 = external_exports || zod_default || zod_exports;
32478
32407
  var paginationSchema = z2.object({
32479
32408
  limit: z2.number().int().min(1).max(100).default(20).describe("Maximum results to return (1\u2013100, default 20)"),
32480
32409
  offset: z2.number().int().min(0).default(0).describe("Number of results to skip for pagination (default 0)")
@@ -32492,14 +32421,6 @@ function applyPagination(items, params) {
32492
32421
  };
32493
32422
  }
32494
32423
 
32495
- // ../packages/shared/dist/package.js
32496
- import { createRequire as createJsonRequire } from "node:module";
32497
- function getPackageVersion(moduleUrl) {
32498
- const require2 = createJsonRequire(moduleUrl);
32499
- const packageJson = require2("../package.json");
32500
- return packageJson.version ?? "0.0.0";
32501
- }
32502
-
32503
32424
  // ../node_modules/zod/v3/helpers/util.js
32504
32425
  var util;
32505
32426
  (function(util4) {
@@ -43083,7 +43004,7 @@ function normalizeValue(value) {
43083
43004
  if (value === false || value == null) {
43084
43005
  return value;
43085
43006
  }
43086
- return utils_default.isArray(value) ? value.map(normalizeValue) : String(value);
43007
+ return utils_default.isArray(value) ? value.map(normalizeValue) : String(value).replace(/[\r\n]+$/, "");
43087
43008
  }
43088
43009
  function parseTokens(str) {
43089
43010
  const tokens = /* @__PURE__ */ Object.create(null);
@@ -43387,8 +43308,74 @@ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
43387
43308
  return requestedURL;
43388
43309
  }
43389
43310
 
43311
+ // ../node_modules/proxy-from-env/index.js
43312
+ var DEFAULT_PORTS = {
43313
+ ftp: 21,
43314
+ gopher: 70,
43315
+ http: 80,
43316
+ https: 443,
43317
+ ws: 80,
43318
+ wss: 443
43319
+ };
43320
+ function parseUrl(urlString) {
43321
+ try {
43322
+ return new URL(urlString);
43323
+ } catch {
43324
+ return null;
43325
+ }
43326
+ }
43327
+ function getProxyForUrl(url3) {
43328
+ var parsedUrl = (typeof url3 === "string" ? parseUrl(url3) : url3) || {};
43329
+ var proto = parsedUrl.protocol;
43330
+ var hostname3 = parsedUrl.host;
43331
+ var port = parsedUrl.port;
43332
+ if (typeof hostname3 !== "string" || !hostname3 || typeof proto !== "string") {
43333
+ return "";
43334
+ }
43335
+ proto = proto.split(":", 1)[0];
43336
+ hostname3 = hostname3.replace(/:\d*$/, "");
43337
+ port = parseInt(port) || DEFAULT_PORTS[proto] || 0;
43338
+ if (!shouldProxy(hostname3, port)) {
43339
+ return "";
43340
+ }
43341
+ var proxy = getEnv(proto + "_proxy") || getEnv("all_proxy");
43342
+ if (proxy && proxy.indexOf("://") === -1) {
43343
+ proxy = proto + "://" + proxy;
43344
+ }
43345
+ return proxy;
43346
+ }
43347
+ function shouldProxy(hostname3, port) {
43348
+ var NO_PROXY = getEnv("no_proxy").toLowerCase();
43349
+ if (!NO_PROXY) {
43350
+ return true;
43351
+ }
43352
+ if (NO_PROXY === "*") {
43353
+ return false;
43354
+ }
43355
+ return NO_PROXY.split(/[,\s]/).every(function(proxy) {
43356
+ if (!proxy) {
43357
+ return true;
43358
+ }
43359
+ var parsedProxy = proxy.match(/^(.+):(\d+)$/);
43360
+ var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy;
43361
+ var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
43362
+ if (parsedProxyPort && parsedProxyPort !== port) {
43363
+ return true;
43364
+ }
43365
+ if (!/^[.*]/.test(parsedProxyHostname)) {
43366
+ return hostname3 !== parsedProxyHostname;
43367
+ }
43368
+ if (parsedProxyHostname.charAt(0) === "*") {
43369
+ parsedProxyHostname = parsedProxyHostname.slice(1);
43370
+ }
43371
+ return !hostname3.endsWith(parsedProxyHostname);
43372
+ });
43373
+ }
43374
+ function getEnv(key) {
43375
+ return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || "";
43376
+ }
43377
+
43390
43378
  // ../node_modules/axios/lib/adapters/http.js
43391
- var import_proxy_from_env = __toESM(require_proxy_from_env(), 1);
43392
43379
  var import_follow_redirects = __toESM(require_follow_redirects(), 1);
43393
43380
  import http from "http";
43394
43381
  import https from "https";
@@ -43397,7 +43384,7 @@ import util3 from "util";
43397
43384
  import zlib from "zlib";
43398
43385
 
43399
43386
  // ../node_modules/axios/lib/env/data.js
43400
- var VERSION = "1.13.6";
43387
+ var VERSION = "1.14.0";
43401
43388
 
43402
43389
  // ../node_modules/axios/lib/helpers/parseProtocol.js
43403
43390
  function parseProtocol(url3) {
@@ -43918,6 +43905,9 @@ var Http2Sessions = class {
43918
43905
  } else {
43919
43906
  entries.splice(i, 1);
43920
43907
  }
43908
+ if (!session.closed) {
43909
+ session.close();
43910
+ }
43921
43911
  return;
43922
43912
  }
43923
43913
  }
@@ -43963,7 +43953,7 @@ function dispatchBeforeRedirect(options, responseDetails) {
43963
43953
  function setProxy(options, configProxy, location) {
43964
43954
  let proxy = configProxy;
43965
43955
  if (!proxy && proxy !== false) {
43966
- const proxyUrl = import_proxy_from_env.default.getProxyForUrl(location);
43956
+ const proxyUrl = getProxyForUrl(location);
43967
43957
  if (proxyUrl) {
43968
43958
  proxy = new URL(proxyUrl);
43969
43959
  }
@@ -45009,14 +44999,16 @@ var factory = (env) => {
45009
44999
  const encodeText = isFetchSupported && (typeof TextEncoder2 === "function" ? /* @__PURE__ */ ((encoder) => (str) => encoder.encode(str))(new TextEncoder2()) : async (str) => new Uint8Array(await new Request(str).arrayBuffer()));
45010
45000
  const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
45011
45001
  let duplexAccessed = false;
45002
+ const body = new ReadableStream2();
45012
45003
  const hasContentType = new Request(platform_default.origin, {
45013
- body: new ReadableStream2(),
45004
+ body,
45014
45005
  method: "POST",
45015
45006
  get duplex() {
45016
45007
  duplexAccessed = true;
45017
45008
  return "half";
45018
45009
  }
45019
45010
  }).headers.has("Content-Type");
45011
+ body.cancel();
45020
45012
  return duplexAccessed && !hasContentType;
45021
45013
  });
45022
45014
  const supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(() => utils_default.isReadableStream(new Response("").body));
@@ -45829,6 +45821,19 @@ var isName = function(string4) {
45829
45821
  function isExist(v) {
45830
45822
  return typeof v !== "undefined";
45831
45823
  }
45824
+ var DANGEROUS_PROPERTY_NAMES = [
45825
+ // '__proto__',
45826
+ // 'constructor',
45827
+ // 'prototype',
45828
+ "hasOwnProperty",
45829
+ "toString",
45830
+ "valueOf",
45831
+ "__defineGetter__",
45832
+ "__defineSetter__",
45833
+ "__lookupGetter__",
45834
+ "__lookupSetter__"
45835
+ ];
45836
+ var criticalProperties = ["__proto__", "constructor", "prototype"];
45832
45837
 
45833
45838
  // ../node_modules/fast-xml-parser/src/validator.js
45834
45839
  var defaultOptions2 = {
@@ -46137,6 +46142,12 @@ function getPositionFromMatch(match) {
46137
46142
  }
46138
46143
 
46139
46144
  // ../node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js
46145
+ var defaultOnDangerousProperty = (name) => {
46146
+ if (DANGEROUS_PROPERTY_NAMES.includes(name)) {
46147
+ return "__" + name;
46148
+ }
46149
+ return name;
46150
+ };
46140
46151
  var defaultOptions3 = {
46141
46152
  preserveOrder: false,
46142
46153
  attributeNamePrefix: "@_",
@@ -46182,8 +46193,27 @@ var defaultOptions3 = {
46182
46193
  // skipEmptyListItem: false
46183
46194
  captureMetaData: false,
46184
46195
  maxNestedTags: 100,
46185
- strictReservedNames: true
46196
+ strictReservedNames: true,
46197
+ jPath: true,
46198
+ // if true, pass jPath string to callbacks; if false, pass matcher instance
46199
+ onDangerousProperty: defaultOnDangerousProperty
46186
46200
  };
46201
+ function validatePropertyName(propertyName, optionName) {
46202
+ if (typeof propertyName !== "string") {
46203
+ return;
46204
+ }
46205
+ const normalized = propertyName.toLowerCase();
46206
+ if (DANGEROUS_PROPERTY_NAMES.some((dangerous) => normalized === dangerous.toLowerCase())) {
46207
+ throw new Error(
46208
+ `[SECURITY] Invalid ${optionName}: "${propertyName}" is a reserved JavaScript keyword that could cause prototype pollution`
46209
+ );
46210
+ }
46211
+ if (criticalProperties.some((dangerous) => normalized === dangerous.toLowerCase())) {
46212
+ throw new Error(
46213
+ `[SECURITY] Invalid ${optionName}: "${propertyName}" is a reserved JavaScript keyword that could cause prototype pollution`
46214
+ );
46215
+ }
46216
+ }
46187
46217
  function normalizeProcessEntities(value) {
46188
46218
  if (typeof value === "boolean") {
46189
46219
  return {
@@ -46193,6 +46223,7 @@ function normalizeProcessEntities(value) {
46193
46223
  maxExpansionDepth: 10,
46194
46224
  maxTotalExpansions: 1e3,
46195
46225
  maxExpandedLength: 1e5,
46226
+ maxEntityCount: 100,
46196
46227
  allowedTags: null,
46197
46228
  tagFilter: null
46198
46229
  };
@@ -46200,11 +46231,11 @@ function normalizeProcessEntities(value) {
46200
46231
  if (typeof value === "object" && value !== null) {
46201
46232
  return {
46202
46233
  enabled: value.enabled !== false,
46203
- // default true if not specified
46204
- maxEntitySize: value.maxEntitySize ?? 1e4,
46205
- maxExpansionDepth: value.maxExpansionDepth ?? 10,
46206
- maxTotalExpansions: value.maxTotalExpansions ?? 1e3,
46207
- maxExpandedLength: value.maxExpandedLength ?? 1e5,
46234
+ maxEntitySize: Math.max(1, value.maxEntitySize ?? 1e4),
46235
+ maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10),
46236
+ maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? 1e3),
46237
+ maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 1e5),
46238
+ maxEntityCount: Math.max(1, value.maxEntityCount ?? 100),
46208
46239
  allowedTags: value.allowedTags ?? null,
46209
46240
  tagFilter: value.tagFilter ?? null
46210
46241
  };
@@ -46213,7 +46244,30 @@ function normalizeProcessEntities(value) {
46213
46244
  }
46214
46245
  var buildOptions = function(options) {
46215
46246
  const built = Object.assign({}, defaultOptions3, options);
46247
+ const propertyNameOptions = [
46248
+ { value: built.attributeNamePrefix, name: "attributeNamePrefix" },
46249
+ { value: built.attributesGroupName, name: "attributesGroupName" },
46250
+ { value: built.textNodeName, name: "textNodeName" },
46251
+ { value: built.cdataPropName, name: "cdataPropName" },
46252
+ { value: built.commentPropName, name: "commentPropName" }
46253
+ ];
46254
+ for (const { value, name } of propertyNameOptions) {
46255
+ if (value) {
46256
+ validatePropertyName(value, name);
46257
+ }
46258
+ }
46259
+ if (built.onDangerousProperty === null) {
46260
+ built.onDangerousProperty = defaultOnDangerousProperty;
46261
+ }
46216
46262
  built.processEntities = normalizeProcessEntities(built.processEntities);
46263
+ if (built.stopNodes && Array.isArray(built.stopNodes)) {
46264
+ built.stopNodes = built.stopNodes.map((node) => {
46265
+ if (typeof node === "string" && node.startsWith("*.")) {
46266
+ return ".." + node.substring(2);
46267
+ }
46268
+ return node;
46269
+ });
46270
+ }
46217
46271
  return built;
46218
46272
  };
46219
46273
 
@@ -46259,6 +46313,7 @@ var DocTypeReader = class {
46259
46313
  }
46260
46314
  readDocType(xmlData, i) {
46261
46315
  const entities = /* @__PURE__ */ Object.create(null);
46316
+ let entityCount = 0;
46262
46317
  if (xmlData[i + 3] === "O" && xmlData[i + 4] === "C" && xmlData[i + 5] === "T" && xmlData[i + 6] === "Y" && xmlData[i + 7] === "P" && xmlData[i + 8] === "E") {
46263
46318
  i = i + 9;
46264
46319
  let angleBracketsCount = 1;
@@ -46271,11 +46326,17 @@ var DocTypeReader = class {
46271
46326
  let entityName, val;
46272
46327
  [entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);
46273
46328
  if (val.indexOf("&") === -1) {
46274
- const escaped = entityName.replace(/[.\-+*:]/g, "\\.");
46329
+ if (this.options.enabled !== false && this.options.maxEntityCount != null && entityCount >= this.options.maxEntityCount) {
46330
+ throw new Error(
46331
+ `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`
46332
+ );
46333
+ }
46334
+ const escaped = entityName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
46275
46335
  entities[entityName] = {
46276
46336
  regx: RegExp(`&${escaped};`, "g"),
46277
46337
  val
46278
46338
  };
46339
+ entityCount++;
46279
46340
  }
46280
46341
  } else if (hasBody && hasSeq(xmlData, "!ELEMENT", i)) {
46281
46342
  i += 8;
@@ -46319,11 +46380,11 @@ var DocTypeReader = class {
46319
46380
  }
46320
46381
  readEntityExp(xmlData, i) {
46321
46382
  i = skipWhitespace(xmlData, i);
46322
- let entityName = "";
46383
+ const startIndex = i;
46323
46384
  while (i < xmlData.length && !/\s/.test(xmlData[i]) && xmlData[i] !== '"' && xmlData[i] !== "'") {
46324
- entityName += xmlData[i];
46325
46385
  i++;
46326
46386
  }
46387
+ let entityName = xmlData.substring(startIndex, i);
46327
46388
  validateEntityName(entityName);
46328
46389
  i = skipWhitespace(xmlData, i);
46329
46390
  if (!this.suppressValidationErr) {
@@ -46335,7 +46396,7 @@ var DocTypeReader = class {
46335
46396
  }
46336
46397
  let entityValue = "";
46337
46398
  [i, entityValue] = this.readIdentifierVal(xmlData, i, "entity");
46338
- if (this.options.enabled !== false && this.options.maxEntitySize && entityValue.length > this.options.maxEntitySize) {
46399
+ if (this.options.enabled !== false && this.options.maxEntitySize != null && entityValue.length > this.options.maxEntitySize) {
46339
46400
  throw new Error(
46340
46401
  `Entity "${entityName}" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`
46341
46402
  );
@@ -46345,11 +46406,11 @@ var DocTypeReader = class {
46345
46406
  }
46346
46407
  readNotationExp(xmlData, i) {
46347
46408
  i = skipWhitespace(xmlData, i);
46348
- let notationName = "";
46409
+ const startIndex = i;
46349
46410
  while (i < xmlData.length && !/\s/.test(xmlData[i])) {
46350
- notationName += xmlData[i];
46351
46411
  i++;
46352
46412
  }
46413
+ let notationName = xmlData.substring(startIndex, i);
46353
46414
  !this.suppressValidationErr && validateEntityName(notationName);
46354
46415
  i = skipWhitespace(xmlData, i);
46355
46416
  const identifierType = xmlData.substring(i, i + 6).toUpperCase();
@@ -46381,10 +46442,11 @@ var DocTypeReader = class {
46381
46442
  throw new Error(`Expected quoted string, found "${startChar}"`);
46382
46443
  }
46383
46444
  i++;
46445
+ const startIndex = i;
46384
46446
  while (i < xmlData.length && xmlData[i] !== startChar) {
46385
- identifierVal += xmlData[i];
46386
46447
  i++;
46387
46448
  }
46449
+ identifierVal = xmlData.substring(startIndex, i);
46388
46450
  if (xmlData[i] !== startChar) {
46389
46451
  throw new Error(`Unterminated ${type} value`);
46390
46452
  }
@@ -46393,11 +46455,11 @@ var DocTypeReader = class {
46393
46455
  }
46394
46456
  readElementExp(xmlData, i) {
46395
46457
  i = skipWhitespace(xmlData, i);
46396
- let elementName = "";
46458
+ const startIndex = i;
46397
46459
  while (i < xmlData.length && !/\s/.test(xmlData[i])) {
46398
- elementName += xmlData[i];
46399
46460
  i++;
46400
46461
  }
46462
+ let elementName = xmlData.substring(startIndex, i);
46401
46463
  if (!this.suppressValidationErr && !isName(elementName)) {
46402
46464
  throw new Error(`Invalid element name: "${elementName}"`);
46403
46465
  }
@@ -46407,10 +46469,11 @@ var DocTypeReader = class {
46407
46469
  else if (xmlData[i] === "A" && hasSeq(xmlData, "NY", i)) i += 2;
46408
46470
  else if (xmlData[i] === "(") {
46409
46471
  i++;
46472
+ const startIndex2 = i;
46410
46473
  while (i < xmlData.length && xmlData[i] !== ")") {
46411
- contentModel += xmlData[i];
46412
46474
  i++;
46413
46475
  }
46476
+ contentModel = xmlData.substring(startIndex2, i);
46414
46477
  if (xmlData[i] !== ")") {
46415
46478
  throw new Error("Unterminated content model");
46416
46479
  }
@@ -46425,18 +46488,18 @@ var DocTypeReader = class {
46425
46488
  }
46426
46489
  readAttlistExp(xmlData, i) {
46427
46490
  i = skipWhitespace(xmlData, i);
46428
- let elementName = "";
46491
+ let startIndex = i;
46429
46492
  while (i < xmlData.length && !/\s/.test(xmlData[i])) {
46430
- elementName += xmlData[i];
46431
46493
  i++;
46432
46494
  }
46495
+ let elementName = xmlData.substring(startIndex, i);
46433
46496
  validateEntityName(elementName);
46434
46497
  i = skipWhitespace(xmlData, i);
46435
- let attributeName = "";
46498
+ startIndex = i;
46436
46499
  while (i < xmlData.length && !/\s/.test(xmlData[i])) {
46437
- attributeName += xmlData[i];
46438
46500
  i++;
46439
46501
  }
46502
+ let attributeName = xmlData.substring(startIndex, i);
46440
46503
  if (!validateEntityName(attributeName)) {
46441
46504
  throw new Error(`Invalid attribute name: "${attributeName}"`);
46442
46505
  }
@@ -46452,11 +46515,11 @@ var DocTypeReader = class {
46452
46515
  i++;
46453
46516
  let allowedNotations = [];
46454
46517
  while (i < xmlData.length && xmlData[i] !== ")") {
46455
- let notation = "";
46518
+ const startIndex2 = i;
46456
46519
  while (i < xmlData.length && xmlData[i] !== "|" && xmlData[i] !== ")") {
46457
- notation += xmlData[i];
46458
46520
  i++;
46459
46521
  }
46522
+ let notation = xmlData.substring(startIndex2, i);
46460
46523
  notation = notation.trim();
46461
46524
  if (!validateEntityName(notation)) {
46462
46525
  throw new Error(`Invalid notation name: "${notation}"`);
@@ -46473,10 +46536,11 @@ var DocTypeReader = class {
46473
46536
  i++;
46474
46537
  attributeType += " (" + allowedNotations.join("|") + ")";
46475
46538
  } else {
46539
+ const startIndex2 = i;
46476
46540
  while (i < xmlData.length && !/\s/.test(xmlData[i])) {
46477
- attributeType += xmlData[i];
46478
46541
  i++;
46479
46542
  }
46543
+ attributeType += xmlData.substring(startIndex2, i);
46480
46544
  const validTypes = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
46481
46545
  if (!this.suppressValidationErr && !validTypes.includes(attributeType.toUpperCase())) {
46482
46546
  throw new Error(`Invalid attribute type: "${attributeType}"`);
@@ -46529,17 +46593,22 @@ var consider = {
46529
46593
  // oct: false,
46530
46594
  leadingZeros: true,
46531
46595
  decimalPoint: ".",
46532
- eNotation: true
46533
- //skipLike: /regex/
46596
+ eNotation: true,
46597
+ //skipLike: /regex/,
46598
+ infinity: "original"
46599
+ // "null", "infinity" (Infinity type), "string" ("Infinity" (the string literal))
46534
46600
  };
46535
46601
  function toNumber(str, options = {}) {
46536
46602
  options = Object.assign({}, consider, options);
46537
46603
  if (!str || typeof str !== "string") return str;
46538
46604
  let trimmedStr = str.trim();
46539
- if (options.skipLike !== void 0 && options.skipLike.test(trimmedStr)) return str;
46540
- else if (str === "0") return 0;
46605
+ if (trimmedStr.length === 0) return str;
46606
+ else if (options.skipLike !== void 0 && options.skipLike.test(trimmedStr)) return str;
46607
+ else if (trimmedStr === "0") return 0;
46541
46608
  else if (options.hex && hexRegex.test(trimmedStr)) {
46542
46609
  return parse_int(trimmedStr, 16);
46610
+ } else if (!isFinite(trimmedStr)) {
46611
+ return handleInfinity(str, Number(trimmedStr), options);
46543
46612
  } else if (trimmedStr.includes("e") || trimmedStr.includes("E")) {
46544
46613
  return resolveEnotation(str, trimmedStr, options);
46545
46614
  } else {
@@ -46594,10 +46663,14 @@ function resolveEnotation(str, trimmedStr, options) {
46594
46663
  if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
46595
46664
  else if (leadingZeros.length === 1 && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {
46596
46665
  return Number(trimmedStr);
46597
- } else if (options.leadingZeros && !eAdjacentToLeadingZeros) {
46598
- trimmedStr = (notation[1] || "") + notation[3];
46666
+ } else if (leadingZeros.length > 0) {
46667
+ if (options.leadingZeros && !eAdjacentToLeadingZeros) {
46668
+ trimmedStr = (notation[1] || "") + notation[3];
46669
+ return Number(trimmedStr);
46670
+ } else return str;
46671
+ } else {
46599
46672
  return Number(trimmedStr);
46600
- } else return str;
46673
+ }
46601
46674
  } else {
46602
46675
  return str;
46603
46676
  }
@@ -46618,6 +46691,21 @@ function parse_int(numStr, base) {
46618
46691
  else if (window && window.parseInt) return window.parseInt(numStr, base);
46619
46692
  else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported");
46620
46693
  }
46694
+ function handleInfinity(str, num, options) {
46695
+ const isPositive = num === Infinity;
46696
+ switch (options.infinity.toLowerCase()) {
46697
+ case "null":
46698
+ return null;
46699
+ case "infinity":
46700
+ return num;
46701
+ // Return Infinity or -Infinity
46702
+ case "string":
46703
+ return isPositive ? "Infinity" : "-Infinity";
46704
+ case "original":
46705
+ default:
46706
+ return str;
46707
+ }
46708
+ }
46621
46709
 
46622
46710
  // ../node_modules/fast-xml-parser/src/ignoreAttributes.js
46623
46711
  function getIgnoreAttributesFn(ignoreAttributes) {
@@ -46639,7 +46727,567 @@ function getIgnoreAttributesFn(ignoreAttributes) {
46639
46727
  return () => false;
46640
46728
  }
46641
46729
 
46730
+ // ../node_modules/path-expression-matcher/src/Expression.js
46731
+ var Expression = class {
46732
+ /**
46733
+ * Create a new Expression
46734
+ * @param {string} pattern - Pattern string (e.g., "root.users.user", "..user[id]")
46735
+ * @param {Object} options - Configuration options
46736
+ * @param {string} options.separator - Path separator (default: '.')
46737
+ */
46738
+ constructor(pattern, options = {}) {
46739
+ this.pattern = pattern;
46740
+ this.separator = options.separator || ".";
46741
+ this.segments = this._parse(pattern);
46742
+ this._hasDeepWildcard = this.segments.some((seg) => seg.type === "deep-wildcard");
46743
+ this._hasAttributeCondition = this.segments.some((seg) => seg.attrName !== void 0);
46744
+ this._hasPositionSelector = this.segments.some((seg) => seg.position !== void 0);
46745
+ }
46746
+ /**
46747
+ * Parse pattern string into segments
46748
+ * @private
46749
+ * @param {string} pattern - Pattern to parse
46750
+ * @returns {Array} Array of segment objects
46751
+ */
46752
+ _parse(pattern) {
46753
+ const segments = [];
46754
+ let i = 0;
46755
+ let currentPart = "";
46756
+ while (i < pattern.length) {
46757
+ if (pattern[i] === this.separator) {
46758
+ if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {
46759
+ if (currentPart.trim()) {
46760
+ segments.push(this._parseSegment(currentPart.trim()));
46761
+ currentPart = "";
46762
+ }
46763
+ segments.push({ type: "deep-wildcard" });
46764
+ i += 2;
46765
+ } else {
46766
+ if (currentPart.trim()) {
46767
+ segments.push(this._parseSegment(currentPart.trim()));
46768
+ }
46769
+ currentPart = "";
46770
+ i++;
46771
+ }
46772
+ } else {
46773
+ currentPart += pattern[i];
46774
+ i++;
46775
+ }
46776
+ }
46777
+ if (currentPart.trim()) {
46778
+ segments.push(this._parseSegment(currentPart.trim()));
46779
+ }
46780
+ return segments;
46781
+ }
46782
+ /**
46783
+ * Parse a single segment
46784
+ * @private
46785
+ * @param {string} part - Segment string (e.g., "user", "ns::user", "user[id]", "ns::user:first")
46786
+ * @returns {Object} Segment object
46787
+ */
46788
+ _parseSegment(part) {
46789
+ const segment = { type: "tag" };
46790
+ let bracketContent = null;
46791
+ let withoutBrackets = part;
46792
+ const bracketMatch = part.match(/^([^\[]+)(\[[^\]]*\])(.*)$/);
46793
+ if (bracketMatch) {
46794
+ withoutBrackets = bracketMatch[1] + bracketMatch[3];
46795
+ if (bracketMatch[2]) {
46796
+ const content = bracketMatch[2].slice(1, -1);
46797
+ if (content) {
46798
+ bracketContent = content;
46799
+ }
46800
+ }
46801
+ }
46802
+ let namespace = void 0;
46803
+ let tagAndPosition = withoutBrackets;
46804
+ if (withoutBrackets.includes("::")) {
46805
+ const nsIndex = withoutBrackets.indexOf("::");
46806
+ namespace = withoutBrackets.substring(0, nsIndex).trim();
46807
+ tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim();
46808
+ if (!namespace) {
46809
+ throw new Error(`Invalid namespace in pattern: ${part}`);
46810
+ }
46811
+ }
46812
+ let tag = void 0;
46813
+ let positionMatch = null;
46814
+ if (tagAndPosition.includes(":")) {
46815
+ const colonIndex = tagAndPosition.lastIndexOf(":");
46816
+ const tagPart = tagAndPosition.substring(0, colonIndex).trim();
46817
+ const posPart = tagAndPosition.substring(colonIndex + 1).trim();
46818
+ const isPositionKeyword = ["first", "last", "odd", "even"].includes(posPart) || /^nth\(\d+\)$/.test(posPart);
46819
+ if (isPositionKeyword) {
46820
+ tag = tagPart;
46821
+ positionMatch = posPart;
46822
+ } else {
46823
+ tag = tagAndPosition;
46824
+ }
46825
+ } else {
46826
+ tag = tagAndPosition;
46827
+ }
46828
+ if (!tag) {
46829
+ throw new Error(`Invalid segment pattern: ${part}`);
46830
+ }
46831
+ segment.tag = tag;
46832
+ if (namespace) {
46833
+ segment.namespace = namespace;
46834
+ }
46835
+ if (bracketContent) {
46836
+ if (bracketContent.includes("=")) {
46837
+ const eqIndex = bracketContent.indexOf("=");
46838
+ segment.attrName = bracketContent.substring(0, eqIndex).trim();
46839
+ segment.attrValue = bracketContent.substring(eqIndex + 1).trim();
46840
+ } else {
46841
+ segment.attrName = bracketContent.trim();
46842
+ }
46843
+ }
46844
+ if (positionMatch) {
46845
+ const nthMatch = positionMatch.match(/^nth\((\d+)\)$/);
46846
+ if (nthMatch) {
46847
+ segment.position = "nth";
46848
+ segment.positionValue = parseInt(nthMatch[1], 10);
46849
+ } else {
46850
+ segment.position = positionMatch;
46851
+ }
46852
+ }
46853
+ return segment;
46854
+ }
46855
+ /**
46856
+ * Get the number of segments
46857
+ * @returns {number}
46858
+ */
46859
+ get length() {
46860
+ return this.segments.length;
46861
+ }
46862
+ /**
46863
+ * Check if expression contains deep wildcard
46864
+ * @returns {boolean}
46865
+ */
46866
+ hasDeepWildcard() {
46867
+ return this._hasDeepWildcard;
46868
+ }
46869
+ /**
46870
+ * Check if expression has attribute conditions
46871
+ * @returns {boolean}
46872
+ */
46873
+ hasAttributeCondition() {
46874
+ return this._hasAttributeCondition;
46875
+ }
46876
+ /**
46877
+ * Check if expression has position selectors
46878
+ * @returns {boolean}
46879
+ */
46880
+ hasPositionSelector() {
46881
+ return this._hasPositionSelector;
46882
+ }
46883
+ /**
46884
+ * Get string representation
46885
+ * @returns {string}
46886
+ */
46887
+ toString() {
46888
+ return this.pattern;
46889
+ }
46890
+ };
46891
+
46892
+ // ../node_modules/path-expression-matcher/src/Matcher.js
46893
+ var MUTATING_METHODS = /* @__PURE__ */ new Set(["push", "pop", "reset", "updateCurrent", "restore"]);
46894
+ var Matcher = class {
46895
+ /**
46896
+ * Create a new Matcher
46897
+ * @param {Object} options - Configuration options
46898
+ * @param {string} options.separator - Default path separator (default: '.')
46899
+ */
46900
+ constructor(options = {}) {
46901
+ this.separator = options.separator || ".";
46902
+ this.path = [];
46903
+ this.siblingStacks = [];
46904
+ }
46905
+ /**
46906
+ * Push a new tag onto the path
46907
+ * @param {string} tagName - Name of the tag
46908
+ * @param {Object} attrValues - Attribute key-value pairs for current node (optional)
46909
+ * @param {string} namespace - Namespace for the tag (optional)
46910
+ */
46911
+ push(tagName, attrValues = null, namespace = null) {
46912
+ if (this.path.length > 0) {
46913
+ const prev = this.path[this.path.length - 1];
46914
+ prev.values = void 0;
46915
+ }
46916
+ const currentLevel = this.path.length;
46917
+ if (!this.siblingStacks[currentLevel]) {
46918
+ this.siblingStacks[currentLevel] = /* @__PURE__ */ new Map();
46919
+ }
46920
+ const siblings = this.siblingStacks[currentLevel];
46921
+ const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;
46922
+ const counter = siblings.get(siblingKey) || 0;
46923
+ let position = 0;
46924
+ for (const count of siblings.values()) {
46925
+ position += count;
46926
+ }
46927
+ siblings.set(siblingKey, counter + 1);
46928
+ const node = {
46929
+ tag: tagName,
46930
+ position,
46931
+ counter
46932
+ };
46933
+ if (namespace !== null && namespace !== void 0) {
46934
+ node.namespace = namespace;
46935
+ }
46936
+ if (attrValues !== null && attrValues !== void 0) {
46937
+ node.values = attrValues;
46938
+ }
46939
+ this.path.push(node);
46940
+ }
46941
+ /**
46942
+ * Pop the last tag from the path
46943
+ * @returns {Object|undefined} The popped node
46944
+ */
46945
+ pop() {
46946
+ if (this.path.length === 0) {
46947
+ return void 0;
46948
+ }
46949
+ const node = this.path.pop();
46950
+ if (this.siblingStacks.length > this.path.length + 1) {
46951
+ this.siblingStacks.length = this.path.length + 1;
46952
+ }
46953
+ return node;
46954
+ }
46955
+ /**
46956
+ * Update current node's attribute values
46957
+ * Useful when attributes are parsed after push
46958
+ * @param {Object} attrValues - Attribute values
46959
+ */
46960
+ updateCurrent(attrValues) {
46961
+ if (this.path.length > 0) {
46962
+ const current = this.path[this.path.length - 1];
46963
+ if (attrValues !== null && attrValues !== void 0) {
46964
+ current.values = attrValues;
46965
+ }
46966
+ }
46967
+ }
46968
+ /**
46969
+ * Get current tag name
46970
+ * @returns {string|undefined}
46971
+ */
46972
+ getCurrentTag() {
46973
+ return this.path.length > 0 ? this.path[this.path.length - 1].tag : void 0;
46974
+ }
46975
+ /**
46976
+ * Get current namespace
46977
+ * @returns {string|undefined}
46978
+ */
46979
+ getCurrentNamespace() {
46980
+ return this.path.length > 0 ? this.path[this.path.length - 1].namespace : void 0;
46981
+ }
46982
+ /**
46983
+ * Get current node's attribute value
46984
+ * @param {string} attrName - Attribute name
46985
+ * @returns {*} Attribute value or undefined
46986
+ */
46987
+ getAttrValue(attrName) {
46988
+ if (this.path.length === 0) return void 0;
46989
+ const current = this.path[this.path.length - 1];
46990
+ return current.values?.[attrName];
46991
+ }
46992
+ /**
46993
+ * Check if current node has an attribute
46994
+ * @param {string} attrName - Attribute name
46995
+ * @returns {boolean}
46996
+ */
46997
+ hasAttr(attrName) {
46998
+ if (this.path.length === 0) return false;
46999
+ const current = this.path[this.path.length - 1];
47000
+ return current.values !== void 0 && attrName in current.values;
47001
+ }
47002
+ /**
47003
+ * Get current node's sibling position (child index in parent)
47004
+ * @returns {number}
47005
+ */
47006
+ getPosition() {
47007
+ if (this.path.length === 0) return -1;
47008
+ return this.path[this.path.length - 1].position ?? 0;
47009
+ }
47010
+ /**
47011
+ * Get current node's repeat counter (occurrence count of this tag name)
47012
+ * @returns {number}
47013
+ */
47014
+ getCounter() {
47015
+ if (this.path.length === 0) return -1;
47016
+ return this.path[this.path.length - 1].counter ?? 0;
47017
+ }
47018
+ /**
47019
+ * Get current node's sibling index (alias for getPosition for backward compatibility)
47020
+ * @returns {number}
47021
+ * @deprecated Use getPosition() or getCounter() instead
47022
+ */
47023
+ getIndex() {
47024
+ return this.getPosition();
47025
+ }
47026
+ /**
47027
+ * Get current path depth
47028
+ * @returns {number}
47029
+ */
47030
+ getDepth() {
47031
+ return this.path.length;
47032
+ }
47033
+ /**
47034
+ * Get path as string
47035
+ * @param {string} separator - Optional separator (uses default if not provided)
47036
+ * @param {boolean} includeNamespace - Whether to include namespace in output (default: true)
47037
+ * @returns {string}
47038
+ */
47039
+ toString(separator, includeNamespace = true) {
47040
+ const sep = separator || this.separator;
47041
+ return this.path.map((n) => {
47042
+ if (includeNamespace && n.namespace) {
47043
+ return `${n.namespace}:${n.tag}`;
47044
+ }
47045
+ return n.tag;
47046
+ }).join(sep);
47047
+ }
47048
+ /**
47049
+ * Get path as array of tag names
47050
+ * @returns {string[]}
47051
+ */
47052
+ toArray() {
47053
+ return this.path.map((n) => n.tag);
47054
+ }
47055
+ /**
47056
+ * Reset the path to empty
47057
+ */
47058
+ reset() {
47059
+ this.path = [];
47060
+ this.siblingStacks = [];
47061
+ }
47062
+ /**
47063
+ * Match current path against an Expression
47064
+ * @param {Expression} expression - The expression to match against
47065
+ * @returns {boolean} True if current path matches the expression
47066
+ */
47067
+ matches(expression) {
47068
+ const segments = expression.segments;
47069
+ if (segments.length === 0) {
47070
+ return false;
47071
+ }
47072
+ if (expression.hasDeepWildcard()) {
47073
+ return this._matchWithDeepWildcard(segments);
47074
+ }
47075
+ return this._matchSimple(segments);
47076
+ }
47077
+ /**
47078
+ * Match simple path (no deep wildcards)
47079
+ * @private
47080
+ */
47081
+ _matchSimple(segments) {
47082
+ if (this.path.length !== segments.length) {
47083
+ return false;
47084
+ }
47085
+ for (let i = 0; i < segments.length; i++) {
47086
+ const segment = segments[i];
47087
+ const node = this.path[i];
47088
+ const isCurrentNode = i === this.path.length - 1;
47089
+ if (!this._matchSegment(segment, node, isCurrentNode)) {
47090
+ return false;
47091
+ }
47092
+ }
47093
+ return true;
47094
+ }
47095
+ /**
47096
+ * Match path with deep wildcards
47097
+ * @private
47098
+ */
47099
+ _matchWithDeepWildcard(segments) {
47100
+ let pathIdx = this.path.length - 1;
47101
+ let segIdx = segments.length - 1;
47102
+ while (segIdx >= 0 && pathIdx >= 0) {
47103
+ const segment = segments[segIdx];
47104
+ if (segment.type === "deep-wildcard") {
47105
+ segIdx--;
47106
+ if (segIdx < 0) {
47107
+ return true;
47108
+ }
47109
+ const nextSeg = segments[segIdx];
47110
+ let found = false;
47111
+ for (let i = pathIdx; i >= 0; i--) {
47112
+ const isCurrentNode = i === this.path.length - 1;
47113
+ if (this._matchSegment(nextSeg, this.path[i], isCurrentNode)) {
47114
+ pathIdx = i - 1;
47115
+ segIdx--;
47116
+ found = true;
47117
+ break;
47118
+ }
47119
+ }
47120
+ if (!found) {
47121
+ return false;
47122
+ }
47123
+ } else {
47124
+ const isCurrentNode = pathIdx === this.path.length - 1;
47125
+ if (!this._matchSegment(segment, this.path[pathIdx], isCurrentNode)) {
47126
+ return false;
47127
+ }
47128
+ pathIdx--;
47129
+ segIdx--;
47130
+ }
47131
+ }
47132
+ return segIdx < 0;
47133
+ }
47134
+ /**
47135
+ * Match a single segment against a node
47136
+ * @private
47137
+ * @param {Object} segment - Segment from Expression
47138
+ * @param {Object} node - Node from path
47139
+ * @param {boolean} isCurrentNode - Whether this is the current (last) node
47140
+ * @returns {boolean}
47141
+ */
47142
+ _matchSegment(segment, node, isCurrentNode) {
47143
+ if (segment.tag !== "*" && segment.tag !== node.tag) {
47144
+ return false;
47145
+ }
47146
+ if (segment.namespace !== void 0) {
47147
+ if (segment.namespace !== "*" && segment.namespace !== node.namespace) {
47148
+ return false;
47149
+ }
47150
+ }
47151
+ if (segment.attrName !== void 0) {
47152
+ if (!isCurrentNode) {
47153
+ return false;
47154
+ }
47155
+ if (!node.values || !(segment.attrName in node.values)) {
47156
+ return false;
47157
+ }
47158
+ if (segment.attrValue !== void 0) {
47159
+ const actualValue = node.values[segment.attrName];
47160
+ if (String(actualValue) !== String(segment.attrValue)) {
47161
+ return false;
47162
+ }
47163
+ }
47164
+ }
47165
+ if (segment.position !== void 0) {
47166
+ if (!isCurrentNode) {
47167
+ return false;
47168
+ }
47169
+ const counter = node.counter ?? 0;
47170
+ if (segment.position === "first" && counter !== 0) {
47171
+ return false;
47172
+ } else if (segment.position === "odd" && counter % 2 !== 1) {
47173
+ return false;
47174
+ } else if (segment.position === "even" && counter % 2 !== 0) {
47175
+ return false;
47176
+ } else if (segment.position === "nth") {
47177
+ if (counter !== segment.positionValue) {
47178
+ return false;
47179
+ }
47180
+ }
47181
+ }
47182
+ return true;
47183
+ }
47184
+ /**
47185
+ * Create a snapshot of current state
47186
+ * @returns {Object} State snapshot
47187
+ */
47188
+ snapshot() {
47189
+ return {
47190
+ path: this.path.map((node) => ({ ...node })),
47191
+ siblingStacks: this.siblingStacks.map((map2) => new Map(map2))
47192
+ };
47193
+ }
47194
+ /**
47195
+ * Restore state from snapshot
47196
+ * @param {Object} snapshot - State snapshot
47197
+ */
47198
+ restore(snapshot) {
47199
+ this.path = snapshot.path.map((node) => ({ ...node }));
47200
+ this.siblingStacks = snapshot.siblingStacks.map((map2) => new Map(map2));
47201
+ }
47202
+ /**
47203
+ * Return a read-only view of this matcher.
47204
+ *
47205
+ * The returned object exposes all query/inspection methods but throws a
47206
+ * TypeError if any state-mutating method is called (`push`, `pop`, `reset`,
47207
+ * `updateCurrent`, `restore`). Property reads (e.g. `.path`, `.separator`)
47208
+ * are allowed but the returned arrays/objects are frozen so callers cannot
47209
+ * mutate internal state through them either.
47210
+ *
47211
+ * @returns {ReadOnlyMatcher} A proxy that forwards read operations and blocks writes.
47212
+ *
47213
+ * @example
47214
+ * const matcher = new Matcher();
47215
+ * matcher.push("root", {});
47216
+ *
47217
+ * const ro = matcher.readOnly();
47218
+ * ro.matches(expr); // ✓ works
47219
+ * ro.getCurrentTag(); // ✓ works
47220
+ * ro.push("child", {}); // ✗ throws TypeError
47221
+ * ro.reset(); // ✗ throws TypeError
47222
+ */
47223
+ readOnly() {
47224
+ const self2 = this;
47225
+ return new Proxy(self2, {
47226
+ get(target, prop, receiver) {
47227
+ if (MUTATING_METHODS.has(prop)) {
47228
+ return () => {
47229
+ throw new TypeError(
47230
+ `Cannot call '${prop}' on a read-only Matcher. Obtain a writable instance to mutate state.`
47231
+ );
47232
+ };
47233
+ }
47234
+ const value = Reflect.get(target, prop, receiver);
47235
+ if (prop === "path" || prop === "siblingStacks") {
47236
+ return Object.freeze(
47237
+ Array.isArray(value) ? value.map(
47238
+ (item) => item instanceof Map ? Object.freeze(new Map(item)) : Object.freeze({ ...item })
47239
+ // freeze a copy of each node
47240
+ ) : value
47241
+ );
47242
+ }
47243
+ if (typeof value === "function") {
47244
+ return value.bind(target);
47245
+ }
47246
+ return value;
47247
+ },
47248
+ // Prevent any property assignment on the read-only view
47249
+ set(_target, prop) {
47250
+ throw new TypeError(
47251
+ `Cannot set property '${String(prop)}' on a read-only Matcher.`
47252
+ );
47253
+ },
47254
+ // Prevent property deletion
47255
+ deleteProperty(_target, prop) {
47256
+ throw new TypeError(
47257
+ `Cannot delete property '${String(prop)}' from a read-only Matcher.`
47258
+ );
47259
+ }
47260
+ });
47261
+ }
47262
+ };
47263
+
46642
47264
  // ../node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js
47265
+ function extractRawAttributes(prefixedAttrs, options) {
47266
+ if (!prefixedAttrs) return {};
47267
+ const attrs = options.attributesGroupName ? prefixedAttrs[options.attributesGroupName] : prefixedAttrs;
47268
+ if (!attrs) return {};
47269
+ const rawAttrs = {};
47270
+ for (const key in attrs) {
47271
+ if (key.startsWith(options.attributeNamePrefix)) {
47272
+ const rawName = key.substring(options.attributeNamePrefix.length);
47273
+ rawAttrs[rawName] = attrs[key];
47274
+ } else {
47275
+ rawAttrs[key] = attrs[key];
47276
+ }
47277
+ }
47278
+ return rawAttrs;
47279
+ }
47280
+ function extractNamespace(rawTagName) {
47281
+ if (!rawTagName || typeof rawTagName !== "string") return void 0;
47282
+ const colonIndex = rawTagName.indexOf(":");
47283
+ if (colonIndex !== -1 && colonIndex > 0) {
47284
+ const ns = rawTagName.substring(0, colonIndex);
47285
+ if (ns !== "xmlns") {
47286
+ return ns;
47287
+ }
47288
+ }
47289
+ return void 0;
47290
+ }
46643
47291
  var OrderedObjParser = class {
46644
47292
  constructor(options) {
46645
47293
  this.options = options;
@@ -46683,16 +47331,17 @@ var OrderedObjParser = class {
46683
47331
  this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes);
46684
47332
  this.entityExpansionCount = 0;
46685
47333
  this.currentExpandedLength = 0;
47334
+ this.matcher = new Matcher();
47335
+ this.readonlyMatcher = this.matcher.readOnly();
47336
+ this.isCurrentNodeStopNode = false;
46686
47337
  if (this.options.stopNodes && this.options.stopNodes.length > 0) {
46687
- this.stopNodesExact = /* @__PURE__ */ new Set();
46688
- this.stopNodesWildcard = /* @__PURE__ */ new Set();
47338
+ this.stopNodeExpressions = [];
46689
47339
  for (let i = 0; i < this.options.stopNodes.length; i++) {
46690
47340
  const stopNodeExp = this.options.stopNodes[i];
46691
- if (typeof stopNodeExp !== "string") continue;
46692
- if (stopNodeExp.startsWith("*.")) {
46693
- this.stopNodesWildcard.add(stopNodeExp.substring(2));
46694
- } else {
46695
- this.stopNodesExact.add(stopNodeExp);
47341
+ if (typeof stopNodeExp === "string") {
47342
+ this.stopNodeExpressions.push(new Expression(stopNodeExp));
47343
+ } else if (stopNodeExp instanceof Expression) {
47344
+ this.stopNodeExpressions.push(stopNodeExp);
46696
47345
  }
46697
47346
  }
46698
47347
  }
@@ -46716,7 +47365,8 @@ function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode,
46716
47365
  }
46717
47366
  if (val.length > 0) {
46718
47367
  if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);
46719
- const newval = this.options.tagValueProcessor(tagName, val, jPath, hasAttributes, isLeafNode);
47368
+ const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
47369
+ const newval = this.options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);
46720
47370
  if (newval === null || newval === void 0) {
46721
47371
  return val;
46722
47372
  } else if (typeof newval !== typeof val || newval !== val) {
@@ -46753,9 +47403,26 @@ function buildAttributesMap(attrStr, jPath, tagName) {
46753
47403
  const matches = getAllMatches(attrStr, attrsRegx);
46754
47404
  const len = matches.length;
46755
47405
  const attrs = {};
47406
+ const rawAttrsForMatcher = {};
47407
+ for (let i = 0; i < len; i++) {
47408
+ const attrName = this.resolveNameSpace(matches[i][1]);
47409
+ const oldVal = matches[i][4];
47410
+ if (attrName.length && oldVal !== void 0) {
47411
+ let parsedVal = oldVal;
47412
+ if (this.options.trimValues) {
47413
+ parsedVal = parsedVal.trim();
47414
+ }
47415
+ parsedVal = this.replaceEntitiesValue(parsedVal, tagName, this.readonlyMatcher);
47416
+ rawAttrsForMatcher[attrName] = parsedVal;
47417
+ }
47418
+ }
47419
+ if (Object.keys(rawAttrsForMatcher).length > 0 && typeof jPath === "object" && jPath.updateCurrent) {
47420
+ jPath.updateCurrent(rawAttrsForMatcher);
47421
+ }
46756
47422
  for (let i = 0; i < len; i++) {
46757
47423
  const attrName = this.resolveNameSpace(matches[i][1]);
46758
- if (this.ignoreAttributesFn(attrName, jPath)) {
47424
+ const jPathStr = this.options.jPath ? jPath.toString() : this.readonlyMatcher;
47425
+ if (this.ignoreAttributesFn(attrName, jPathStr)) {
46759
47426
  continue;
46760
47427
  }
46761
47428
  let oldVal = matches[i][4];
@@ -46764,13 +47431,14 @@ function buildAttributesMap(attrStr, jPath, tagName) {
46764
47431
  if (this.options.transformAttributeName) {
46765
47432
  aName = this.options.transformAttributeName(aName);
46766
47433
  }
46767
- if (aName === "__proto__") aName = "#__proto__";
47434
+ aName = sanitizeName(aName, this.options);
46768
47435
  if (oldVal !== void 0) {
46769
47436
  if (this.options.trimValues) {
46770
47437
  oldVal = oldVal.trim();
46771
47438
  }
46772
- oldVal = this.replaceEntitiesValue(oldVal, tagName, jPath);
46773
- const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPath);
47439
+ oldVal = this.replaceEntitiesValue(oldVal, tagName, this.readonlyMatcher);
47440
+ const jPathOrMatcher = this.options.jPath ? jPath.toString() : this.readonlyMatcher;
47441
+ const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPathOrMatcher);
46774
47442
  if (newVal === null || newVal === void 0) {
46775
47443
  attrs[aName] = oldVal;
46776
47444
  } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {
@@ -46803,7 +47471,7 @@ var parseXml = function(xmlData) {
46803
47471
  const xmlObj = new XmlNode("!xml");
46804
47472
  let currentNode = xmlObj;
46805
47473
  let textData = "";
46806
- let jPath = "";
47474
+ this.matcher.reset();
46807
47475
  this.entityExpansionCount = 0;
46808
47476
  this.currentExpandedLength = 0;
46809
47477
  const docTypeReader = new DocTypeReader(this.options.processEntities);
@@ -46819,46 +47487,42 @@ var parseXml = function(xmlData) {
46819
47487
  tagName = tagName.substr(colonIndex + 1);
46820
47488
  }
46821
47489
  }
46822
- if (this.options.transformTagName) {
46823
- tagName = this.options.transformTagName(tagName);
46824
- }
47490
+ tagName = transformTagName(this.options.transformTagName, tagName, "", this.options).tagName;
46825
47491
  if (currentNode) {
46826
- textData = this.saveTextToParentTag(textData, currentNode, jPath);
47492
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
46827
47493
  }
46828
- const lastTagName = jPath.substring(jPath.lastIndexOf(".") + 1);
47494
+ const lastTagName = this.matcher.getCurrentTag();
46829
47495
  if (tagName && this.options.unpairedTags.indexOf(tagName) !== -1) {
46830
47496
  throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
46831
47497
  }
46832
- let propIndex = 0;
46833
47498
  if (lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1) {
46834
- propIndex = jPath.lastIndexOf(".", jPath.lastIndexOf(".") - 1);
47499
+ this.matcher.pop();
46835
47500
  this.tagsNodeStack.pop();
46836
- } else {
46837
- propIndex = jPath.lastIndexOf(".");
46838
47501
  }
46839
- jPath = jPath.substring(0, propIndex);
47502
+ this.matcher.pop();
47503
+ this.isCurrentNodeStopNode = false;
46840
47504
  currentNode = this.tagsNodeStack.pop();
46841
47505
  textData = "";
46842
47506
  i = closeIndex;
46843
47507
  } else if (xmlData[i + 1] === "?") {
46844
47508
  let tagData = readTagExp(xmlData, i, false, "?>");
46845
47509
  if (!tagData) throw new Error("Pi Tag is not closed.");
46846
- textData = this.saveTextToParentTag(textData, currentNode, jPath);
47510
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
46847
47511
  if (this.options.ignoreDeclaration && tagData.tagName === "?xml" || this.options.ignorePiTags) {
46848
47512
  } else {
46849
47513
  const childNode = new XmlNode(tagData.tagName);
46850
47514
  childNode.add(this.options.textNodeName, "");
46851
47515
  if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent) {
46852
- childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName);
47516
+ childNode[":@"] = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName);
46853
47517
  }
46854
- this.addChild(currentNode, childNode, jPath, i);
47518
+ this.addChild(currentNode, childNode, this.readonlyMatcher, i);
46855
47519
  }
46856
47520
  i = tagData.closeIndex + 1;
46857
47521
  } else if (xmlData.substr(i + 1, 3) === "!--") {
46858
47522
  const endIndex = findClosingIndex(xmlData, "-->", i + 4, "Comment is not closed.");
46859
47523
  if (this.options.commentPropName) {
46860
47524
  const comment = xmlData.substring(i + 4, endIndex - 2);
46861
- textData = this.saveTextToParentTag(textData, currentNode, jPath);
47525
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
46862
47526
  currentNode.add(this.options.commentPropName, [{ [this.options.textNodeName]: comment }]);
46863
47527
  }
46864
47528
  i = endIndex;
@@ -46869,8 +47533,8 @@ var parseXml = function(xmlData) {
46869
47533
  } else if (xmlData.substr(i + 1, 2) === "![") {
46870
47534
  const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2;
46871
47535
  const tagExp = xmlData.substring(i + 9, closeIndex);
46872
- textData = this.saveTextToParentTag(textData, currentNode, jPath);
46873
- let val = this.parseTextData(tagExp, currentNode.tagname, jPath, true, false, true, true);
47536
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
47537
+ let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);
46874
47538
  if (val == void 0) val = "";
46875
47539
  if (this.options.cdataPropName) {
46876
47540
  currentNode.add(this.options.cdataPropName, [{ [this.options.textNodeName]: tagExp }]);
@@ -46880,45 +47544,60 @@ var parseXml = function(xmlData) {
46880
47544
  i = closeIndex + 2;
46881
47545
  } else {
46882
47546
  let result = readTagExp(xmlData, i, this.options.removeNSPrefix);
47547
+ if (!result) {
47548
+ const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlData.length, i + 50));
47549
+ throw new Error(`readTagExp returned undefined at position ${i}. Context: "${context}"`);
47550
+ }
46883
47551
  let tagName = result.tagName;
46884
47552
  const rawTagName = result.rawTagName;
46885
47553
  let tagExp = result.tagExp;
46886
47554
  let attrExpPresent = result.attrExpPresent;
46887
47555
  let closeIndex = result.closeIndex;
46888
- if (this.options.transformTagName) {
46889
- const newTagName = this.options.transformTagName(tagName);
46890
- if (tagExp === tagName) {
46891
- tagExp = newTagName;
46892
- }
46893
- tagName = newTagName;
46894
- }
46895
- if (this.options.strictReservedNames && (tagName === this.options.commentPropName || tagName === this.options.cdataPropName)) {
47556
+ ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options));
47557
+ if (this.options.strictReservedNames && (tagName === this.options.commentPropName || tagName === this.options.cdataPropName || tagName === this.options.textNodeName || tagName === this.options.attributesGroupName)) {
46896
47558
  throw new Error(`Invalid tag name: ${tagName}`);
46897
47559
  }
46898
47560
  if (currentNode && textData) {
46899
47561
  if (currentNode.tagname !== "!xml") {
46900
- textData = this.saveTextToParentTag(textData, currentNode, jPath, false);
47562
+ textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);
46901
47563
  }
46902
47564
  }
46903
47565
  const lastTag = currentNode;
46904
47566
  if (lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1) {
46905
47567
  currentNode = this.tagsNodeStack.pop();
46906
- jPath = jPath.substring(0, jPath.lastIndexOf("."));
47568
+ this.matcher.pop();
47569
+ }
47570
+ let isSelfClosing = false;
47571
+ if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
47572
+ isSelfClosing = true;
47573
+ if (tagName[tagName.length - 1] === "/") {
47574
+ tagName = tagName.substr(0, tagName.length - 1);
47575
+ tagExp = tagName;
47576
+ } else {
47577
+ tagExp = tagExp.substr(0, tagExp.length - 1);
47578
+ }
47579
+ attrExpPresent = tagName !== tagExp;
46907
47580
  }
47581
+ let prefixedAttrs = null;
47582
+ let rawAttrs = {};
47583
+ let namespace = void 0;
47584
+ namespace = extractNamespace(rawTagName);
46908
47585
  if (tagName !== xmlObj.tagname) {
46909
- jPath += jPath ? "." + tagName : tagName;
47586
+ this.matcher.push(tagName, {}, namespace);
47587
+ }
47588
+ if (tagName !== tagExp && attrExpPresent) {
47589
+ prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);
47590
+ if (prefixedAttrs) {
47591
+ rawAttrs = extractRawAttributes(prefixedAttrs, this.options);
47592
+ }
47593
+ }
47594
+ if (tagName !== xmlObj.tagname) {
47595
+ this.isCurrentNodeStopNode = this.isItStopNode(this.stopNodeExpressions, this.matcher);
46910
47596
  }
46911
47597
  const startIndex = i;
46912
- if (this.isItStopNode(this.stopNodesExact, this.stopNodesWildcard, jPath, tagName)) {
47598
+ if (this.isCurrentNodeStopNode) {
46913
47599
  let tagContent = "";
46914
- if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
46915
- if (tagName[tagName.length - 1] === "/") {
46916
- tagName = tagName.substr(0, tagName.length - 1);
46917
- jPath = jPath.substr(0, jPath.length - 1);
46918
- tagExp = tagName;
46919
- } else {
46920
- tagExp = tagExp.substr(0, tagExp.length - 1);
46921
- }
47600
+ if (isSelfClosing) {
46922
47601
  i = result.closeIndex;
46923
47602
  } else if (this.options.unpairedTags.indexOf(tagName) !== -1) {
46924
47603
  i = result.closeIndex;
@@ -46929,44 +47608,31 @@ var parseXml = function(xmlData) {
46929
47608
  tagContent = result2.tagContent;
46930
47609
  }
46931
47610
  const childNode = new XmlNode(tagName);
46932
- if (tagName !== tagExp && attrExpPresent) {
46933
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
47611
+ if (prefixedAttrs) {
47612
+ childNode[":@"] = prefixedAttrs;
46934
47613
  }
46935
- if (tagContent) {
46936
- tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true);
46937
- }
46938
- jPath = jPath.substr(0, jPath.lastIndexOf("."));
46939
47614
  childNode.add(this.options.textNodeName, tagContent);
46940
- this.addChild(currentNode, childNode, jPath, startIndex);
47615
+ this.matcher.pop();
47616
+ this.isCurrentNodeStopNode = false;
47617
+ this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
46941
47618
  } else {
46942
- if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
46943
- if (tagName[tagName.length - 1] === "/") {
46944
- tagName = tagName.substr(0, tagName.length - 1);
46945
- jPath = jPath.substr(0, jPath.length - 1);
46946
- tagExp = tagName;
46947
- } else {
46948
- tagExp = tagExp.substr(0, tagExp.length - 1);
46949
- }
46950
- if (this.options.transformTagName) {
46951
- const newTagName = this.options.transformTagName(tagName);
46952
- if (tagExp === tagName) {
46953
- tagExp = newTagName;
46954
- }
46955
- tagName = newTagName;
46956
- }
47619
+ if (isSelfClosing) {
47620
+ ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options));
46957
47621
  const childNode = new XmlNode(tagName);
46958
- if (tagName !== tagExp && attrExpPresent) {
46959
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
47622
+ if (prefixedAttrs) {
47623
+ childNode[":@"] = prefixedAttrs;
46960
47624
  }
46961
- this.addChild(currentNode, childNode, jPath, startIndex);
46962
- jPath = jPath.substr(0, jPath.lastIndexOf("."));
47625
+ this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
47626
+ this.matcher.pop();
47627
+ this.isCurrentNodeStopNode = false;
46963
47628
  } else if (this.options.unpairedTags.indexOf(tagName) !== -1) {
46964
47629
  const childNode = new XmlNode(tagName);
46965
- if (tagName !== tagExp && attrExpPresent) {
46966
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
47630
+ if (prefixedAttrs) {
47631
+ childNode[":@"] = prefixedAttrs;
46967
47632
  }
46968
- this.addChild(currentNode, childNode, jPath, startIndex);
46969
- jPath = jPath.substr(0, jPath.lastIndexOf("."));
47633
+ this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
47634
+ this.matcher.pop();
47635
+ this.isCurrentNodeStopNode = false;
46970
47636
  i = result.closeIndex;
46971
47637
  continue;
46972
47638
  } else {
@@ -46975,10 +47641,10 @@ var parseXml = function(xmlData) {
46975
47641
  throw new Error("Maximum nested tags exceeded");
46976
47642
  }
46977
47643
  this.tagsNodeStack.push(currentNode);
46978
- if (tagName !== tagExp && attrExpPresent) {
46979
- childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
47644
+ if (prefixedAttrs) {
47645
+ childNode[":@"] = prefixedAttrs;
46980
47646
  }
46981
- this.addChild(currentNode, childNode, jPath, startIndex);
47647
+ this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
46982
47648
  currentNode = childNode;
46983
47649
  }
46984
47650
  textData = "";
@@ -46991,9 +47657,10 @@ var parseXml = function(xmlData) {
46991
47657
  }
46992
47658
  return xmlObj.child;
46993
47659
  };
46994
- function addChild(currentNode, childNode, jPath, startIndex) {
47660
+ function addChild(currentNode, childNode, matcher, startIndex) {
46995
47661
  if (!this.options.captureMetaData) startIndex = void 0;
46996
- const result = this.options.updateTag(childNode.tagname, jPath, childNode[":@"]);
47662
+ const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;
47663
+ const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[":@"]);
46997
47664
  if (result === false) {
46998
47665
  } else if (typeof result === "string") {
46999
47666
  childNode.tagname = result;
@@ -47002,25 +47669,25 @@ function addChild(currentNode, childNode, jPath, startIndex) {
47002
47669
  currentNode.addChild(childNode, startIndex);
47003
47670
  }
47004
47671
  }
47005
- var replaceEntitiesValue = function(val, tagName, jPath) {
47006
- if (val.indexOf("&") === -1) {
47007
- return val;
47008
- }
47672
+ function replaceEntitiesValue(val, tagName, jPath) {
47009
47673
  const entityConfig = this.options.processEntities;
47010
- if (!entityConfig.enabled) {
47674
+ if (!entityConfig || !entityConfig.enabled) {
47011
47675
  return val;
47012
47676
  }
47013
47677
  if (entityConfig.allowedTags) {
47014
- if (!entityConfig.allowedTags.includes(tagName)) {
47678
+ const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
47679
+ const allowed = Array.isArray(entityConfig.allowedTags) ? entityConfig.allowedTags.includes(tagName) : entityConfig.allowedTags(tagName, jPathOrMatcher);
47680
+ if (!allowed) {
47015
47681
  return val;
47016
47682
  }
47017
47683
  }
47018
47684
  if (entityConfig.tagFilter) {
47019
- if (!entityConfig.tagFilter(tagName, jPath)) {
47685
+ const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
47686
+ if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {
47020
47687
  return val;
47021
47688
  }
47022
47689
  }
47023
- for (let entityName in this.docTypeEntities) {
47690
+ for (const entityName of Object.keys(this.docTypeEntities)) {
47024
47691
  const entity = this.docTypeEntities[entityName];
47025
47692
  const matches = val.match(entity.regx);
47026
47693
  if (matches) {
@@ -47042,28 +47709,45 @@ var replaceEntitiesValue = function(val, tagName, jPath) {
47042
47709
  }
47043
47710
  }
47044
47711
  }
47045
- if (val.indexOf("&") === -1) return val;
47046
- for (let entityName in this.lastEntities) {
47712
+ for (const entityName of Object.keys(this.lastEntities)) {
47047
47713
  const entity = this.lastEntities[entityName];
47714
+ const matches = val.match(entity.regex);
47715
+ if (matches) {
47716
+ this.entityExpansionCount += matches.length;
47717
+ if (entityConfig.maxTotalExpansions && this.entityExpansionCount > entityConfig.maxTotalExpansions) {
47718
+ throw new Error(
47719
+ `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
47720
+ );
47721
+ }
47722
+ }
47048
47723
  val = val.replace(entity.regex, entity.val);
47049
47724
  }
47050
47725
  if (val.indexOf("&") === -1) return val;
47051
47726
  if (this.options.htmlEntities) {
47052
- for (let entityName in this.htmlEntities) {
47727
+ for (const entityName of Object.keys(this.htmlEntities)) {
47053
47728
  const entity = this.htmlEntities[entityName];
47729
+ const matches = val.match(entity.regex);
47730
+ if (matches) {
47731
+ this.entityExpansionCount += matches.length;
47732
+ if (entityConfig.maxTotalExpansions && this.entityExpansionCount > entityConfig.maxTotalExpansions) {
47733
+ throw new Error(
47734
+ `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
47735
+ );
47736
+ }
47737
+ }
47054
47738
  val = val.replace(entity.regex, entity.val);
47055
47739
  }
47056
47740
  }
47057
47741
  val = val.replace(this.ampEntity.regex, this.ampEntity.val);
47058
47742
  return val;
47059
- };
47060
- function saveTextToParentTag(textData, parentNode, jPath, isLeafNode) {
47743
+ }
47744
+ function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {
47061
47745
  if (textData) {
47062
47746
  if (isLeafNode === void 0) isLeafNode = parentNode.child.length === 0;
47063
47747
  textData = this.parseTextData(
47064
47748
  textData,
47065
47749
  parentNode.tagname,
47066
- jPath,
47750
+ matcher,
47067
47751
  false,
47068
47752
  parentNode[":@"] ? Object.keys(parentNode[":@"]).length !== 0 : false,
47069
47753
  isLeafNode
@@ -47074,9 +47758,13 @@ function saveTextToParentTag(textData, parentNode, jPath, isLeafNode) {
47074
47758
  }
47075
47759
  return textData;
47076
47760
  }
47077
- function isItStopNode(stopNodesExact, stopNodesWildcard, jPath, currentTagName) {
47078
- if (stopNodesWildcard && stopNodesWildcard.has(currentTagName)) return true;
47079
- if (stopNodesExact && stopNodesExact.has(jPath)) return true;
47761
+ function isItStopNode(stopNodeExpressions, matcher) {
47762
+ if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;
47763
+ for (let i = 0; i < stopNodeExpressions.length; i++) {
47764
+ if (matcher.matches(stopNodeExpressions[i])) {
47765
+ return true;
47766
+ }
47767
+ }
47080
47768
  return false;
47081
47769
  }
47082
47770
  function tagExpWithClosingIndex(xmlData, i, closingChar = ">") {
@@ -47206,31 +47894,68 @@ function fromCodePoint(str, base, prefix) {
47206
47894
  return prefix + str + ";";
47207
47895
  }
47208
47896
  }
47897
+ function transformTagName(fn, tagName, tagExp, options) {
47898
+ if (fn) {
47899
+ const newTagName = fn(tagName);
47900
+ if (tagExp === tagName) {
47901
+ tagExp = newTagName;
47902
+ }
47903
+ tagName = newTagName;
47904
+ }
47905
+ tagName = sanitizeName(tagName, options);
47906
+ return { tagName, tagExp };
47907
+ }
47908
+ function sanitizeName(name, options) {
47909
+ if (criticalProperties.includes(name)) {
47910
+ throw new Error(`[SECURITY] Invalid name: "${name}" is a reserved JavaScript keyword that could cause prototype pollution`);
47911
+ } else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {
47912
+ return options.onDangerousProperty(name);
47913
+ }
47914
+ return name;
47915
+ }
47209
47916
 
47210
47917
  // ../node_modules/fast-xml-parser/src/xmlparser/node2json.js
47211
47918
  var METADATA_SYMBOL2 = XmlNode.getMetaDataSymbol();
47212
- function prettify(node, options) {
47213
- return compress(node, options);
47919
+ function stripAttributePrefix(attrs, prefix) {
47920
+ if (!attrs || typeof attrs !== "object") return {};
47921
+ if (!prefix) return attrs;
47922
+ const rawAttrs = {};
47923
+ for (const key in attrs) {
47924
+ if (key.startsWith(prefix)) {
47925
+ const rawName = key.substring(prefix.length);
47926
+ rawAttrs[rawName] = attrs[key];
47927
+ } else {
47928
+ rawAttrs[key] = attrs[key];
47929
+ }
47930
+ }
47931
+ return rawAttrs;
47932
+ }
47933
+ function prettify(node, options, matcher, readonlyMatcher) {
47934
+ return compress(node, options, matcher, readonlyMatcher);
47214
47935
  }
47215
- function compress(arr, options, jPath) {
47936
+ function compress(arr, options, matcher, readonlyMatcher) {
47216
47937
  let text;
47217
47938
  const compressedObj = {};
47218
47939
  for (let i = 0; i < arr.length; i++) {
47219
47940
  const tagObj = arr[i];
47220
47941
  const property = propName(tagObj);
47221
- let newJpath = "";
47222
- if (jPath === void 0) newJpath = property;
47223
- else newJpath = jPath + "." + property;
47942
+ if (property !== void 0 && property !== options.textNodeName) {
47943
+ const rawAttrs = stripAttributePrefix(
47944
+ tagObj[":@"] || {},
47945
+ options.attributeNamePrefix
47946
+ );
47947
+ matcher.push(property, rawAttrs);
47948
+ }
47224
47949
  if (property === options.textNodeName) {
47225
47950
  if (text === void 0) text = tagObj[property];
47226
47951
  else text += "" + tagObj[property];
47227
47952
  } else if (property === void 0) {
47228
47953
  continue;
47229
47954
  } else if (tagObj[property]) {
47230
- let val = compress(tagObj[property], options, newJpath);
47955
+ let val = compress(tagObj[property], options, matcher, readonlyMatcher);
47231
47956
  const isLeaf = isLeafTag(val, options);
47232
47957
  if (tagObj[":@"]) {
47233
- assignAttributes(val, tagObj[":@"], newJpath, options);
47958
+ assignAttributes(val, tagObj[":@"], readonlyMatcher, options);
47234
47959
  } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== void 0 && !options.alwaysCreateTextNode) {
47235
47960
  val = val[options.textNodeName];
47236
47961
  } else if (Object.keys(val).length === 0) {
@@ -47246,12 +47971,16 @@ function compress(arr, options, jPath) {
47246
47971
  }
47247
47972
  compressedObj[property].push(val);
47248
47973
  } else {
47249
- if (options.isArray(property, newJpath, isLeaf)) {
47974
+ const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher;
47975
+ if (options.isArray(property, jPathOrMatcher, isLeaf)) {
47250
47976
  compressedObj[property] = [val];
47251
47977
  } else {
47252
47978
  compressedObj[property] = val;
47253
47979
  }
47254
47980
  }
47981
+ if (property !== void 0 && property !== options.textNodeName) {
47982
+ matcher.pop();
47983
+ }
47255
47984
  }
47256
47985
  }
47257
47986
  if (typeof text === "string") {
@@ -47266,13 +47995,15 @@ function propName(obj) {
47266
47995
  if (key !== ":@") return key;
47267
47996
  }
47268
47997
  }
47269
- function assignAttributes(obj, attrMap, jpath, options) {
47998
+ function assignAttributes(obj, attrMap, readonlyMatcher, options) {
47270
47999
  if (attrMap) {
47271
48000
  const keys = Object.keys(attrMap);
47272
48001
  const len = keys.length;
47273
48002
  for (let i = 0; i < len; i++) {
47274
48003
  const atrrName = keys[i];
47275
- if (options.isArray(atrrName, jpath + "." + atrrName, true, true)) {
48004
+ const rawAttrName = atrrName.startsWith(options.attributeNamePrefix) ? atrrName.substring(options.attributeNamePrefix.length) : atrrName;
48005
+ const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() + "." + rawAttrName : readonlyMatcher;
48006
+ if (options.isArray(atrrName, jPathOrMatcher, true, true)) {
47276
48007
  obj[atrrName] = [attrMap[atrrName]];
47277
48008
  } else {
47278
48009
  obj[atrrName] = attrMap[atrrName];
@@ -47320,7 +48051,7 @@ var XMLParser = class {
47320
48051
  orderedObjParser.addExternalEntities(this.externalEntities);
47321
48052
  const orderedResult = orderedObjParser.parseXml(xmlData);
47322
48053
  if (this.options.preserveOrder || orderedResult === void 0) return orderedResult;
47323
- else return prettify(orderedResult, this.options);
48054
+ else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);
47324
48055
  }
47325
48056
  /**
47326
48057
  * Add Entity which is not by default supported by this library
@@ -47418,90 +48149,53 @@ var parser = new XMLParser({
47418
48149
  attributeNamePrefix: "@_",
47419
48150
  isArray: (tagName) => ["entry", "author", "category", "link"].includes(tagName)
47420
48151
  });
47421
- function isXmlNode(value) {
47422
- return typeof value === "object" && value !== null && !Array.isArray(value);
47423
- }
47424
- function getXmlNode(value) {
47425
- return isXmlNode(value) ? value : void 0;
47426
- }
47427
- function getXmlNodeArray(value) {
47428
- if (Array.isArray(value)) {
47429
- return value.filter(isXmlNode);
47430
- }
47431
- const node = getXmlNode(value);
47432
- return node ? [node] : [];
47433
- }
47434
- function getXmlString(value) {
47435
- return typeof value === "string" ? value : void 0;
47436
- }
47437
- function getXmlScalarText(value) {
47438
- if (typeof value === "string") {
47439
- return value;
47440
- }
47441
- if (typeof value === "number" || typeof value === "boolean") {
47442
- return String(value);
47443
- }
47444
- return void 0;
47445
- }
47446
- function getXmlText(value) {
47447
- const direct = getXmlScalarText(value);
47448
- if (direct !== void 0) {
47449
- return direct;
47450
- }
47451
- const node = getXmlNode(value);
47452
- if (!node) {
47453
- return "";
47454
- }
47455
- return getXmlScalarText(node["#text"]) ?? "";
47456
- }
47457
48152
  function extractArxivId(fullId) {
47458
48153
  const match = fullId.match(/abs\/([^v]+)/);
47459
48154
  return match ? match[1] : fullId;
47460
48155
  }
47461
48156
  function parsePaper(entry) {
47462
- const authors = getXmlNodeArray(entry.author).map(
47463
- (author) => ({
47464
- name: getXmlText(author.name)
47465
- })
47466
- );
47467
- const categories = getXmlNodeArray(entry.category).map(
47468
- (category) => ({
47469
- term: getXmlText(category["@_term"]),
47470
- scheme: getXmlString(category["@_scheme"]),
47471
- label: getXmlString(category["@_label"])
47472
- })
47473
- );
47474
- const links = getXmlNodeArray(entry.link).map((link) => ({
47475
- href: getXmlText(link["@_href"]),
47476
- rel: getXmlString(link["@_rel"]),
47477
- type: getXmlString(link["@_type"]),
47478
- title: getXmlString(link["@_title"])
48157
+ const rawAuthors = entry.author ?? [];
48158
+ const authors = rawAuthors.map((a) => ({
48159
+ name: String(a.name ?? "")
48160
+ }));
48161
+ const rawCategories = entry.category ?? [];
48162
+ const categories = rawCategories.map((c) => ({
48163
+ term: String(c["@_term"] ?? ""),
48164
+ scheme: c["@_scheme"],
48165
+ label: c["@_label"]
48166
+ }));
48167
+ const rawLinks = entry.link ?? [];
48168
+ const links = rawLinks.map((l) => ({
48169
+ href: String(l["@_href"] ?? ""),
48170
+ rel: l["@_rel"],
48171
+ type: l["@_type"],
48172
+ title: l["@_title"]
47479
48173
  }));
47480
48174
  const pdfLink = links.find(
47481
48175
  (l) => l.title === "pdf" || l.type === "application/pdf"
47482
48176
  );
47483
48177
  const pdfUrl = pdfLink?.href;
47484
- const primaryCategoryRaw = getXmlNode(entry["arxiv:primary_category"]);
48178
+ const primaryCategoryRaw = entry["arxiv:primary_category"];
47485
48179
  const primaryCategory = primaryCategoryRaw ? {
47486
- term: getXmlText(primaryCategoryRaw["@_term"]),
47487
- scheme: getXmlString(primaryCategoryRaw["@_scheme"])
48180
+ term: String(primaryCategoryRaw["@_term"] ?? ""),
48181
+ scheme: primaryCategoryRaw["@_scheme"]
47488
48182
  } : void 0;
47489
- const fullId = getXmlText(entry.id);
48183
+ const fullId = String(entry.id ?? "");
47490
48184
  return {
47491
48185
  id: fullId,
47492
48186
  arxivId: extractArxivId(fullId),
47493
- title: getXmlText(entry.title).replace(/\s+/g, " ").trim(),
47494
- summary: getXmlText(entry.summary).replace(/\s+/g, " ").trim(),
48187
+ title: String(entry.title ?? "").replace(/\s+/g, " ").trim(),
48188
+ summary: String(entry.summary ?? "").replace(/\s+/g, " ").trim(),
47495
48189
  authors,
47496
48190
  categories,
47497
48191
  primaryCategory,
47498
- published: getXmlText(entry.published),
47499
- updated: getXmlText(entry.updated),
48192
+ published: String(entry.published ?? ""),
48193
+ updated: String(entry.updated ?? ""),
47500
48194
  links,
47501
48195
  pdfUrl,
47502
- doi: getXmlString(entry["arxiv:doi"]),
47503
- journalRef: getXmlString(entry["arxiv:journal_ref"]),
47504
- comment: getXmlString(entry["arxiv:comment"])
48196
+ doi: entry["arxiv:doi"],
48197
+ journalRef: entry["arxiv:journal_ref"],
48198
+ comment: entry["arxiv:comment"]
47505
48199
  };
47506
48200
  }
47507
48201
  var ArxivApiClient = class {
@@ -47537,20 +48231,26 @@ var ArxivApiClient = class {
47537
48231
  }
47538
48232
  parseResponse(xml) {
47539
48233
  const parsed = parser.parse(xml);
47540
- const feed = parsed.feed ?? {};
48234
+ const feed = parsed.feed;
47541
48235
  const totalResults = parseInt(
47542
- getXmlText(feed["opensearch:totalResults"]) || "0",
48236
+ String(
48237
+ feed["opensearch:totalResults"]?.["#text"] ?? feed["opensearch:totalResults"] ?? "0"
48238
+ ),
47543
48239
  10
47544
48240
  );
47545
48241
  const startIndex = parseInt(
47546
- getXmlText(feed["opensearch:startIndex"]) || "0",
48242
+ String(
48243
+ feed["opensearch:startIndex"]?.["#text"] ?? feed["opensearch:startIndex"] ?? "0"
48244
+ ),
47547
48245
  10
47548
48246
  );
47549
48247
  const itemsPerPage = parseInt(
47550
- getXmlText(feed["opensearch:itemsPerPage"]) || "0",
48248
+ String(
48249
+ feed["opensearch:itemsPerPage"]?.["#text"] ?? feed["opensearch:itemsPerPage"] ?? "0"
48250
+ ),
47551
48251
  10
47552
48252
  );
47553
- const rawEntries = getXmlNodeArray(feed.entry);
48253
+ const rawEntries = feed.entry ?? [];
47554
48254
  const papers = rawEntries.map(parsePaper);
47555
48255
  return { totalResults, startIndex, itemsPerPage, papers };
47556
48256
  }
@@ -47591,10 +48291,9 @@ var MOCK_FIXTURES = {
47591
48291
 
47592
48292
  // src/index.ts
47593
48293
  var api = new ArxivApiClient();
47594
- var PACKAGE_VERSION = getPackageVersion(import.meta.url);
47595
48294
  var server = new McpServer({
47596
48295
  name: "arxiv-mcp-server",
47597
- version: PACKAGE_VERSION
48296
+ version: "1.0.0"
47598
48297
  });
47599
48298
  function formatPaperMarkdown(paper) {
47600
48299
  const lines = [];
@@ -47624,12 +48323,13 @@ ${paper.summary}`);
47624
48323
  }
47625
48324
  function formatPaperListMarkdown(papers, total, start) {
47626
48325
  const lines = [];
47627
- lines.push("# arXiv Search Results\n");
48326
+ lines.push(`# arXiv Search Results
48327
+ `);
47628
48328
  lines.push(
47629
48329
  `Showing ${papers.length} of ${total} results (offset: ${start})
47630
48330
  `
47631
48331
  );
47632
- for (const [i, paper] of papers.entries()) {
48332
+ papers.forEach((paper, i) => {
47633
48333
  lines.push(`### ${i + 1 + start}. ${paper.title}`);
47634
48334
  lines.push(
47635
48335
  `**arXiv**: [${paper.arxivId}](https://arxiv.org/abs/${paper.arxivId}) | **Authors**: ${paper.authors.slice(0, 3).map((a) => a.name).join(", ")}${paper.authors.length > 3 ? " et al." : ""}`
@@ -47641,7 +48341,7 @@ function formatPaperListMarkdown(papers, total, start) {
47641
48341
  `> ${paper.summary.substring(0, 300)}${paper.summary.length > 300 ? "..." : ""}`
47642
48342
  );
47643
48343
  lines.push("");
47644
- }
48344
+ });
47645
48345
  if (total > start + papers.length) {
47646
48346
  lines.push(
47647
48347
  `*${total - start - papers.length} more results available. Use \`offset=${start + papers.length}\` to continue.*`
@@ -47656,89 +48356,8 @@ var sortSchema = {
47656
48356
  var responseFormatSchema = {
47657
48357
  response_format: external_exports.enum(Object.values(ResponseFormat)).default("markdown" /* MARKDOWN */).describe("Output format: markdown or json")
47658
48358
  };
47659
- async function handleArxivSearch(params) {
47660
- try {
47661
- const result = IS_MOCK || process.env.MOCK === "true" ? MOCK_FIXTURES.search : await api.search({
47662
- query: params.query,
47663
- start: params.offset,
47664
- maxResults: params.limit,
47665
- sortBy: params.sort_by,
47666
- sortOrder: params.sort_order
47667
- });
47668
- if (params.response_format === "json" /* JSON */) {
47669
- return {
47670
- content: [
47671
- {
47672
- type: "text",
47673
- text: truncateToLimit(JSON.stringify(result, null, 2))
47674
- }
47675
- ],
47676
- structuredContent: {
47677
- totalResults: result.totalResults,
47678
- startIndex: result.startIndex,
47679
- itemsPerPage: result.itemsPerPage,
47680
- papers: result.papers
47681
- }
47682
- };
47683
- }
47684
- return {
47685
- content: [
47686
- {
47687
- type: "text",
47688
- text: truncateToLimit(
47689
- formatPaperListMarkdown(
47690
- result.papers,
47691
- result.totalResults,
47692
- result.startIndex
47693
- )
47694
- )
47695
- }
47696
- ]
47697
- };
47698
- } catch (err) {
47699
- return createInternalError(err);
47700
- }
47701
- }
47702
- async function handleArxivGetPaper(params) {
47703
- try {
47704
- const result = IS_MOCK || process.env.MOCK === "true" ? MOCK_FIXTURES.getById : await api.getById(params.ids);
47705
- if (result.papers.length === 0) {
47706
- return {
47707
- content: [
47708
- {
47709
- type: "text",
47710
- text: "No papers found for the given IDs."
47711
- }
47712
- ]
47713
- };
47714
- }
47715
- if (params.response_format === "json" /* JSON */) {
47716
- return {
47717
- content: [
47718
- {
47719
- type: "text",
47720
- text: truncateToLimit(
47721
- JSON.stringify(result.papers, null, 2)
47722
- )
47723
- }
47724
- ],
47725
- structuredContent: {
47726
- papers: result.papers
47727
- }
47728
- };
47729
- }
47730
- const markdown = result.papers.map((p) => formatPaperMarkdown(p)).join("\n\n---\n\n");
47731
- return {
47732
- content: [
47733
- { type: "text", text: truncateToLimit(markdown) }
47734
- ]
47735
- };
47736
- } catch (err) {
47737
- return createInternalError(err);
47738
- }
47739
- }
47740
48359
  server.registerTool(
47741
- "search_papers",
48360
+ "arxiv_search_papers",
47742
48361
  {
47743
48362
  title: "Search arXiv Papers",
47744
48363
  description: "Search arXiv for academic papers using a query.",
@@ -47754,11 +48373,49 @@ server.registerTool(
47754
48373
  openWorldHint: true
47755
48374
  }
47756
48375
  },
47757
- // @ts-expect-error - Schema inference can be tricky with split handlers
47758
- handleArxivSearch
48376
+ async (params) => {
48377
+ try {
48378
+ const result = IS_MOCK ? MOCK_FIXTURES.search : await api.search({
48379
+ query: params.query,
48380
+ start: params.offset,
48381
+ maxResults: params.limit,
48382
+ sortBy: params.sort_by,
48383
+ sortOrder: params.sort_order
48384
+ });
48385
+ if (params.response_format === "json" /* JSON */) {
48386
+ return {
48387
+ content: [
48388
+ {
48389
+ type: "text",
48390
+ text: truncateToLimit(
48391
+ JSON.stringify(result, null, 2)
48392
+ )
48393
+ }
48394
+ ],
48395
+ structuredContent: result
48396
+ };
48397
+ }
48398
+ return {
48399
+ content: [
48400
+ {
48401
+ type: "text",
48402
+ text: truncateToLimit(
48403
+ formatPaperListMarkdown(
48404
+ result.papers,
48405
+ result.totalResults,
48406
+ result.startIndex
48407
+ )
48408
+ )
48409
+ }
48410
+ ]
48411
+ };
48412
+ } catch (err) {
48413
+ return createInternalError(err);
48414
+ }
48415
+ }
47759
48416
  );
47760
48417
  server.registerTool(
47761
- "get_paper",
48418
+ "arxiv_get_paper",
47762
48419
  {
47763
48420
  title: "Get arXiv Paper Details",
47764
48421
  description: "Retrieve full details for one or more arXiv papers by ID.",
@@ -47772,11 +48429,47 @@ server.registerTool(
47772
48429
  openWorldHint: true
47773
48430
  }
47774
48431
  },
47775
- // @ts-expect-error
47776
- handleArxivGetPaper
48432
+ async (params) => {
48433
+ try {
48434
+ const result = IS_MOCK ? MOCK_FIXTURES.getById : await api.getById(params.ids);
48435
+ if (result.papers.length === 0) {
48436
+ return {
48437
+ content: [
48438
+ {
48439
+ type: "text",
48440
+ text: "No papers found for the given IDs."
48441
+ }
48442
+ ]
48443
+ };
48444
+ }
48445
+ if (params.response_format === "json" /* JSON */) {
48446
+ return {
48447
+ content: [
48448
+ {
48449
+ type: "text",
48450
+ text: truncateToLimit(
48451
+ JSON.stringify(result.papers, null, 2)
48452
+ )
48453
+ }
48454
+ ],
48455
+ structuredContent: {
48456
+ papers: result.papers
48457
+ }
48458
+ };
48459
+ }
48460
+ const markdown = result.papers.map((p) => formatPaperMarkdown(p)).join("\n\n---\n\n");
48461
+ return {
48462
+ content: [
48463
+ { type: "text", text: truncateToLimit(markdown) }
48464
+ ]
48465
+ };
48466
+ } catch (err) {
48467
+ return createInternalError(err);
48468
+ }
48469
+ }
47777
48470
  );
47778
48471
  server.registerTool(
47779
- "search_by_author",
48472
+ "arxiv_search_by_author",
47780
48473
  {
47781
48474
  title: "Search arXiv Papers by Author",
47782
48475
  description: "Search arXiv for papers by a specific author name.",
@@ -47793,17 +48486,48 @@ server.registerTool(
47793
48486
  }
47794
48487
  },
47795
48488
  async (params) => {
47796
- return handleArxivSearch({
47797
- ...params,
47798
- query: `au:${params.author}`,
47799
- sort_by: params.sort_by,
47800
- sort_order: params.sort_order,
47801
- response_format: params.response_format
47802
- });
48489
+ try {
48490
+ const result = IS_MOCK ? MOCK_FIXTURES.search : await api.search({
48491
+ query: `au:${params.author}`,
48492
+ start: params.offset,
48493
+ maxResults: params.limit,
48494
+ sortBy: params.sort_by,
48495
+ sortOrder: params.sort_order
48496
+ });
48497
+ if (params.response_format === "json" /* JSON */) {
48498
+ return {
48499
+ content: [
48500
+ {
48501
+ type: "text",
48502
+ text: truncateToLimit(
48503
+ JSON.stringify(result, null, 2)
48504
+ )
48505
+ }
48506
+ ],
48507
+ structuredContent: result
48508
+ };
48509
+ }
48510
+ return {
48511
+ content: [
48512
+ {
48513
+ type: "text",
48514
+ text: truncateToLimit(
48515
+ formatPaperListMarkdown(
48516
+ result.papers,
48517
+ result.totalResults,
48518
+ result.startIndex
48519
+ )
48520
+ )
48521
+ }
48522
+ ]
48523
+ };
48524
+ } catch (err) {
48525
+ return createInternalError(err);
48526
+ }
47803
48527
  }
47804
48528
  );
47805
48529
  server.registerTool(
47806
- "search_by_category",
48530
+ "arxiv_search_by_category",
47807
48531
  {
47808
48532
  title: "Search arXiv Papers by Category",
47809
48533
  description: "Browse or search papers within a specific arXiv subject category.",
@@ -47824,19 +48548,50 @@ server.registerTool(
47824
48548
  }
47825
48549
  },
47826
48550
  async (params) => {
47827
- const queryParts = [`cat:${params.category}`];
47828
- if (params.query) queryParts.push(`AND all:${params.query}`);
47829
- return handleArxivSearch({
47830
- ...params,
47831
- query: queryParts.join(" "),
47832
- sort_by: params.sort_by,
47833
- sort_order: params.sort_order,
47834
- response_format: params.response_format
47835
- });
48551
+ try {
48552
+ const queryParts = [`cat:${params.category}`];
48553
+ if (params.query) queryParts.push(`AND all:${params.query}`);
48554
+ const result = IS_MOCK ? MOCK_FIXTURES.search : await api.search({
48555
+ query: queryParts.join(" "),
48556
+ start: params.offset,
48557
+ maxResults: params.limit,
48558
+ sortBy: params.sort_by,
48559
+ sortOrder: params.sort_order
48560
+ });
48561
+ if (params.response_format === "json" /* JSON */) {
48562
+ return {
48563
+ content: [
48564
+ {
48565
+ type: "text",
48566
+ text: truncateToLimit(
48567
+ JSON.stringify(result, null, 2)
48568
+ )
48569
+ }
48570
+ ],
48571
+ structuredContent: result
48572
+ };
48573
+ }
48574
+ return {
48575
+ content: [
48576
+ {
48577
+ type: "text",
48578
+ text: truncateToLimit(
48579
+ formatPaperListMarkdown(
48580
+ result.papers,
48581
+ result.totalResults,
48582
+ result.startIndex
48583
+ )
48584
+ )
48585
+ }
48586
+ ]
48587
+ };
48588
+ } catch (err) {
48589
+ return createInternalError(err);
48590
+ }
47836
48591
  }
47837
48592
  );
47838
48593
  server.registerTool(
47839
- "list_categories",
48594
+ "arxiv_list_categories",
47840
48595
  {
47841
48596
  title: "List arXiv Subject Categories",
47842
48597
  description: "List the commonly used arXiv subject categories with their descriptions.",
@@ -47883,17 +48638,10 @@ async function main() {
47883
48638
  await server.connect(transport);
47884
48639
  console.error("arXiv MCP server running on stdio");
47885
48640
  }
47886
- if (process.env.NODE_ENV !== "test") {
47887
- main().catch((err) => {
47888
- console.error("Fatal error:", err);
47889
- process.exit(1);
47890
- });
47891
- }
47892
- export {
47893
- handleArxivGetPaper,
47894
- handleArxivSearch,
47895
- server
47896
- };
48641
+ main().catch((err) => {
48642
+ console.error("Fatal error:", err);
48643
+ process.exit(1);
48644
+ });
47897
48645
  /*! Bundled license information:
47898
48646
 
47899
48647
  mime-db/index.js: