xslt-processor 4.8.0 → 4.8.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.
package/index.js CHANGED
@@ -5759,7 +5759,7 @@ function getBuiltInFunction(name) {
5759
5759
  function getBuiltInFunctionArity(name) {
5760
5760
  return FUNCTION_ARITY[name];
5761
5761
  }
5762
- var BUILT_IN_FUNCTIONS, FUNCTION_ARITY, XPathFunctionCall;
5762
+ var toStringValue, BUILT_IN_FUNCTIONS, FUNCTION_ARITY, XPathFunctionCall;
5763
5763
  var init_function_call_expression = __esm({
5764
5764
  "src/xpath/lib/src/expressions/function-call-expression.ts"() {
5765
5765
  init_expression();
@@ -5778,10 +5778,30 @@ var init_function_call_expression = __esm({
5778
5778
  init_qname_functions();
5779
5779
  init_uri_functions();
5780
5780
  init_node_functions();
5781
+ toStringValue = (arg) => {
5782
+ var _a;
5783
+ if (arg && typeof arg === "object") {
5784
+ if (typeof arg.stringValue === "function") {
5785
+ return arg.stringValue();
5786
+ }
5787
+ if (Array.isArray(arg)) {
5788
+ if (arg.length === 0) return "";
5789
+ const firstNode = arg[0];
5790
+ return (_a = firstNode == null ? void 0 : firstNode.textContent) != null ? _a : String(firstNode);
5791
+ }
5792
+ if (typeof arg.textContent === "string") {
5793
+ return arg.textContent;
5794
+ }
5795
+ if (arg.nodeValue !== void 0 && arg.nodeValue !== null) {
5796
+ return String(arg.nodeValue);
5797
+ }
5798
+ }
5799
+ return String(arg != null ? arg : "");
5800
+ };
5781
5801
  BUILT_IN_FUNCTIONS = {
5782
5802
  // String functions
5783
- "upper-case": (_ctx, arg) => String(arg).toUpperCase(),
5784
- "lower-case": (_ctx, arg) => String(arg).toLowerCase(),
5803
+ "upper-case": (_ctx, arg) => toStringValue(arg).toUpperCase(),
5804
+ "lower-case": (_ctx, arg) => toStringValue(arg).toLowerCase(),
5785
5805
  concat: (_ctx, ...args) => args.map((a) => String(a)).join(""),
5786
5806
  "string-join": (_ctx, seq, sep = "") => {
5787
5807
  if (Array.isArray(seq)) {
@@ -6372,6 +6392,10 @@ var init_function_call_expression = __esm({
6372
6392
  return context.functions[this.name](context, ...evaluatedArgs);
6373
6393
  }
6374
6394
  let builtInFunc = BUILT_IN_FUNCTIONS[this.name];
6395
+ if (!builtInFunc && this.name.startsWith("fn:")) {
6396
+ const localName = this.name.substring(3);
6397
+ builtInFunc = BUILT_IN_FUNCTIONS[localName];
6398
+ }
6375
6399
  if (!builtInFunc && this.name.startsWith("Q{")) {
6376
6400
  const { namespace, localName } = this.parseEQName(this.name);
6377
6401
  builtInFunc = BUILT_IN_FUNCTIONS[localName];
@@ -12667,11 +12691,24 @@ function makeComponentKey(component) {
12667
12691
  return `unknown:${component.type}`;
12668
12692
  }
12669
12693
  }
12694
+ function isComponentVisible(component, fromPackage) {
12695
+ if (component.visibility === "private") {
12696
+ return fromPackage;
12697
+ }
12698
+ return true;
12699
+ }
12700
+ function canOverrideComponent(component) {
12701
+ if (component.visibility === "final") {
12702
+ return false;
12703
+ }
12704
+ return component.overridable;
12705
+ }
12670
12706
 
12671
12707
  // src/xslt/package-system/package-registry.ts
12672
12708
  var PackageRegistry = class {
12673
12709
  constructor() {
12674
12710
  this.packages = /* @__PURE__ */ new Map();
12711
+ this.loading = /* @__PURE__ */ new Set();
12675
12712
  }
12676
12713
  /**
12677
12714
  * Register a package in the registry.
@@ -12682,10 +12719,97 @@ var PackageRegistry = class {
12682
12719
  }
12683
12720
  /**
12684
12721
  * Retrieve a package from the registry.
12722
+ * Supports version constraints: exact, wildcards (1.*), ranges (>=1.0), and combined (>=1.0,<2.0).
12685
12723
  */
12686
12724
  get(name, version) {
12687
- const key = this.makePackageKey(name, version);
12688
- return this.packages.get(key);
12725
+ if (!version) {
12726
+ return this.packages.get(name);
12727
+ }
12728
+ const exactKey = this.makePackageKey(name, version);
12729
+ const exactMatch = this.packages.get(exactKey);
12730
+ if (exactMatch) {
12731
+ return exactMatch;
12732
+ }
12733
+ const hasConstraint = /[*<>=,]/.test(version);
12734
+ if (!hasConstraint) {
12735
+ return void 0;
12736
+ }
12737
+ const matchingPackages = [];
12738
+ this.packages.forEach((pkg, key) => {
12739
+ if (pkg.name === name && pkg.version && this.satisfiesVersion(pkg.version, version)) {
12740
+ matchingPackages.push(pkg);
12741
+ }
12742
+ });
12743
+ if (matchingPackages.length === 0) {
12744
+ return void 0;
12745
+ }
12746
+ matchingPackages.sort((a, b) => this.compareVersions(b.version, a.version));
12747
+ return matchingPackages[0];
12748
+ }
12749
+ /**
12750
+ * Check if a package version satisfies a version constraint.
12751
+ */
12752
+ satisfiesVersion(packageVersion, constraint) {
12753
+ if (constraint.includes(",")) {
12754
+ const constraints = constraint.split(",").map((c) => c.trim());
12755
+ return constraints.every((c) => this.satisfiesSingleConstraint(packageVersion, c));
12756
+ }
12757
+ return this.satisfiesSingleConstraint(packageVersion, constraint);
12758
+ }
12759
+ /**
12760
+ * Evaluate a single version constraint.
12761
+ */
12762
+ satisfiesSingleConstraint(packageVersion, constraint) {
12763
+ if (constraint.includes("*")) {
12764
+ const prefix = constraint.replace(/\*$/, "").replace(/\.$/, "");
12765
+ if (!prefix) {
12766
+ return true;
12767
+ }
12768
+ const pkgParts = packageVersion.split(".");
12769
+ const prefixParts = prefix.split(".");
12770
+ for (let i = 0; i < prefixParts.length; i++) {
12771
+ if (pkgParts[i] !== prefixParts[i]) {
12772
+ return false;
12773
+ }
12774
+ }
12775
+ return true;
12776
+ }
12777
+ const operatorMatch = constraint.match(/^(>=|<=|>|<|=)?(.+)$/);
12778
+ if (!operatorMatch) {
12779
+ return false;
12780
+ }
12781
+ const operator = operatorMatch[1] || "=";
12782
+ const targetVersion = operatorMatch[2].trim();
12783
+ const comparison = this.compareVersions(packageVersion, targetVersion);
12784
+ switch (operator) {
12785
+ case ">=":
12786
+ return comparison >= 0;
12787
+ case ">":
12788
+ return comparison > 0;
12789
+ case "<=":
12790
+ return comparison <= 0;
12791
+ case "<":
12792
+ return comparison < 0;
12793
+ case "=":
12794
+ default:
12795
+ return comparison === 0;
12796
+ }
12797
+ }
12798
+ /**
12799
+ * Compare two semantic versions.
12800
+ * @returns -1 if a < b, 0 if a === b, 1 if a > b
12801
+ */
12802
+ compareVersions(a, b) {
12803
+ const aParts = a.split(".").map((p) => parseInt(p, 10) || 0);
12804
+ const bParts = b.split(".").map((p) => parseInt(p, 10) || 0);
12805
+ const maxLength = Math.max(aParts.length, bParts.length);
12806
+ for (let i = 0; i < maxLength; i++) {
12807
+ const aPart = aParts[i] || 0;
12808
+ const bPart = bParts[i] || 0;
12809
+ if (aPart < bPart) return -1;
12810
+ if (aPart > bPart) return 1;
12811
+ }
12812
+ return 0;
12689
12813
  }
12690
12814
  /**
12691
12815
  * Check if a package exists in the registry.
@@ -12694,6 +12818,31 @@ var PackageRegistry = class {
12694
12818
  const key = this.makePackageKey(name, version);
12695
12819
  return this.packages.has(key);
12696
12820
  }
12821
+ /**
12822
+ * Mark a package as currently being loaded.
12823
+ * Used to detect circular dependencies.
12824
+ * @returns true if the package can be loaded, false if it's already being loaded (circular dependency)
12825
+ */
12826
+ beginLoading(packageKey) {
12827
+ if (this.loading.has(packageKey)) {
12828
+ return false;
12829
+ }
12830
+ this.loading.add(packageKey);
12831
+ return true;
12832
+ }
12833
+ /**
12834
+ * Mark a package as finished loading.
12835
+ */
12836
+ endLoading(packageKey) {
12837
+ this.loading.delete(packageKey);
12838
+ }
12839
+ /**
12840
+ * Check if a package is currently being loaded.
12841
+ * Used to detect circular dependencies when a package tries to use another package that is still loading.
12842
+ */
12843
+ isLoading(packageKey) {
12844
+ return this.loading.has(packageKey);
12845
+ }
12697
12846
  /**
12698
12847
  * Create a unique key for a package based on name and version.
12699
12848
  */
@@ -12705,6 +12854,7 @@ var PackageRegistry = class {
12705
12854
  */
12706
12855
  clear() {
12707
12856
  this.packages.clear();
12857
+ this.loading.clear();
12708
12858
  }
12709
12859
  };
12710
12860
 
@@ -13603,7 +13753,8 @@ function selectBestTemplate(templates, context, matchResolver, xPath, warningsCa
13603
13753
  return {
13604
13754
  selectedTemplate: winner.template,
13605
13755
  hasConflict: conflicts.length > 1,
13606
- conflictingTemplates: conflicts.length > 1 ? conflicts : []
13756
+ conflictingTemplates: conflicts.length > 1 ? conflicts : [],
13757
+ originalComponent: winner.originalComponent
13607
13758
  };
13608
13759
  }
13609
13760
  function emitConflictWarning(result, node, warningsCallback) {
@@ -13704,6 +13855,11 @@ var Xslt = class {
13704
13855
  * null if processing a non-package stylesheet.
13705
13856
  */
13706
13857
  this.currentPackage = null;
13858
+ /**
13859
+ * Current override context (for XSLT 3.0 xsl:original).
13860
+ * Tracks the original component when executing an override.
13861
+ */
13862
+ this.currentOverrideContext = null;
13707
13863
  /**
13708
13864
  * Accumulator registry for XSLT 3.0 accumulators.
13709
13865
  * Stores accumulator definitions and current state during processing.
@@ -13945,6 +14101,12 @@ var Xslt = class {
13945
14101
  case "accept":
13946
14102
  this.xsltAccept(context, template);
13947
14103
  break;
14104
+ case "override":
14105
+ yield this.xsltOverride(context, template, output);
14106
+ break;
14107
+ case "original":
14108
+ yield this.xsltOriginal(context, template, output);
14109
+ break;
13948
14110
  case "param":
13949
14111
  yield this.xsltVariable(context, template, false);
13950
14112
  break;
@@ -13982,6 +14144,11 @@ var Xslt = class {
13982
14144
  case "merge":
13983
14145
  yield this.xsltMerge(context, template, output);
13984
14146
  break;
14147
+ case "mode":
14148
+ if (this.currentPackage) {
14149
+ this.xsltMode(context, template);
14150
+ }
14151
+ break;
13985
14152
  case "template":
13986
14153
  yield this.xsltTemplate(context, template, output);
13987
14154
  break;
@@ -14063,8 +14230,10 @@ var Xslt = class {
14063
14230
  return;
14064
14231
  }
14065
14232
  const mode = xmlGetAttribute(template, "mode");
14233
+ const effectiveMode = mode || null;
14066
14234
  const top = template.ownerDocument.documentElement;
14067
- const expandedTemplates = collectAndExpandTemplates(top, mode, this.xPath, this.templateSourceMap);
14235
+ let expandedTemplates = collectAndExpandTemplates(top, effectiveMode, this.xPath, this.templateSourceMap);
14236
+ expandedTemplates = expandedTemplates.concat(this.collectAcceptedTemplates(effectiveMode));
14068
14237
  const paramContext = context.clone();
14069
14238
  yield this.xsltWithParam(paramContext, template);
14070
14239
  const modifiedContext = paramContext.clone(nodes);
@@ -14090,13 +14259,19 @@ var Xslt = class {
14090
14259
  this.currentTemplateStack.push({
14091
14260
  template: textSelection.selectedTemplate,
14092
14261
  stylesheetDepth: (_a = metadata == null ? void 0 : metadata.importDepth) != null ? _a : 0,
14093
- mode: modeAttr || mode,
14262
+ mode: modeAttr || effectiveMode,
14094
14263
  match: matchPattern
14095
14264
  });
14265
+ const previousOverrideContext = this.currentOverrideContext;
14266
+ const overrideContext = textSelection.originalComponent || textSelection.selectedTemplate.__originalComponent;
14267
+ if (overrideContext) {
14268
+ this.currentOverrideContext = overrideContext;
14269
+ }
14096
14270
  try {
14097
14271
  yield this.xsltChildNodes(textNodeContext, textSelection.selectedTemplate, output);
14098
14272
  } finally {
14099
14273
  this.currentTemplateStack.pop();
14274
+ this.currentOverrideContext = previousOverrideContext;
14100
14275
  }
14101
14276
  } else {
14102
14277
  const oldTextNodeContext = context.clone([currentNode], 0);
@@ -14125,13 +14300,19 @@ var Xslt = class {
14125
14300
  this.currentTemplateStack.push({
14126
14301
  template: selection.selectedTemplate,
14127
14302
  stylesheetDepth: (_b = metadata == null ? void 0 : metadata.importDepth) != null ? _b : 0,
14128
- mode: modeAttr || mode,
14303
+ mode: modeAttr || effectiveMode,
14129
14304
  match: matchPattern
14130
14305
  });
14306
+ const previousOverrideContext = this.currentOverrideContext;
14307
+ const overrideContext = selection.originalComponent || selection.selectedTemplate.__originalComponent;
14308
+ if (overrideContext) {
14309
+ this.currentOverrideContext = overrideContext;
14310
+ }
14131
14311
  try {
14132
14312
  yield this.xsltChildNodes(clonedContext, selection.selectedTemplate, output);
14133
14313
  } finally {
14134
14314
  this.currentTemplateStack.pop();
14315
+ this.currentOverrideContext = previousOverrideContext;
14135
14316
  }
14136
14317
  } else {
14137
14318
  if (currentNode.nodeType === DOM_ELEMENT_NODE && currentNode.childNodes && currentNode.childNodes.length > 0) {
@@ -14172,7 +14353,7 @@ var Xslt = class {
14172
14353
  this.currentTemplateStack.push({
14173
14354
  template: childSelection.selectedTemplate,
14174
14355
  stylesheetDepth: (_c = childMetadata == null ? void 0 : childMetadata.importDepth) != null ? _c : 0,
14175
- mode: childModeAttr || mode,
14356
+ mode: childModeAttr || effectiveMode,
14176
14357
  match: childMatchPattern
14177
14358
  });
14178
14359
  try {
@@ -14181,7 +14362,7 @@ var Xslt = class {
14181
14362
  this.currentTemplateStack.pop();
14182
14363
  }
14183
14364
  } else if (childNode.nodeType === DOM_ELEMENT_NODE) {
14184
- yield this.applyBuiltInTemplate(childNode, expandedTemplates, mode, paramContext, output);
14365
+ yield this.applyBuiltInTemplate(childNode, expandedTemplates, effectiveMode, paramContext, output);
14185
14366
  }
14186
14367
  }
14187
14368
  }
@@ -14218,7 +14399,16 @@ var Xslt = class {
14218
14399
  this.warningsCallback
14219
14400
  );
14220
14401
  if (textSelection.selectedTemplate) {
14221
- yield this.xsltChildNodes(textContext, textSelection.selectedTemplate, output);
14402
+ const previousOverrideContext = this.currentOverrideContext;
14403
+ const overrideContext = textSelection.originalComponent || textSelection.selectedTemplate.__originalComponent;
14404
+ if (overrideContext) {
14405
+ this.currentOverrideContext = overrideContext;
14406
+ }
14407
+ try {
14408
+ yield this.xsltChildNodes(textContext, textSelection.selectedTemplate, output);
14409
+ } finally {
14410
+ this.currentOverrideContext = previousOverrideContext;
14411
+ }
14222
14412
  } else {
14223
14413
  this.commonLogicTextNode(textContext, childNode, output);
14224
14414
  }
@@ -14242,10 +14432,16 @@ var Xslt = class {
14242
14432
  mode: childModeAttr || mode,
14243
14433
  match: childMatchPattern
14244
14434
  });
14435
+ const previousOverrideContext = this.currentOverrideContext;
14436
+ const overrideContext = childSelection.originalComponent || childSelection.selectedTemplate.__originalComponent;
14437
+ if (overrideContext) {
14438
+ this.currentOverrideContext = overrideContext;
14439
+ }
14245
14440
  try {
14246
14441
  yield this.xsltChildNodes(childContext, childSelection.selectedTemplate, output);
14247
14442
  } finally {
14248
14443
  this.currentTemplateStack.pop();
14444
+ this.currentOverrideContext = previousOverrideContext;
14249
14445
  }
14250
14446
  } else if (childNode.nodeType === DOM_ELEMENT_NODE) {
14251
14447
  yield this.applyBuiltInTemplate(childNode, expandedTemplates, mode, paramContext, output);
@@ -14284,23 +14480,39 @@ var Xslt = class {
14284
14480
  return;
14285
14481
  }
14286
14482
  const nodeContext = context.clone([currentNode], 0);
14287
- const selection = selectBestTemplate(importedTemplates, nodeContext, this.matchResolver, this.xPath, this.warningsCallback);
14483
+ const selection = selectBestTemplate(
14484
+ importedTemplates,
14485
+ nodeContext,
14486
+ this.matchResolver,
14487
+ this.xPath,
14488
+ this.warningsCallback
14489
+ );
14288
14490
  if (!selection.selectedTemplate) {
14289
14491
  return;
14290
14492
  }
14291
14493
  const importedContext = context.clone();
14292
- const expandedTemplates = collectAndExpandTemplates(top, currentMode, this.xPath, this.templateSourceMap);
14494
+ yield this.xsltWithParam(importedContext, template);
14293
14495
  const metadata = this.templateSourceMap.get(selection.selectedTemplate);
14294
14496
  if (metadata) {
14295
14497
  const matchPattern = xmlGetAttribute(selection.selectedTemplate, "match");
14498
+ const modeAttr = xmlGetAttribute(selection.selectedTemplate, "mode");
14296
14499
  this.currentTemplateStack.push({
14297
14500
  template: selection.selectedTemplate,
14298
14501
  stylesheetDepth: metadata.importDepth,
14299
- mode: currentMode,
14502
+ mode: modeAttr || currentMode,
14300
14503
  match: matchPattern
14301
14504
  });
14302
- yield this.xsltChildNodes(importedContext, selection.selectedTemplate, output);
14303
- this.currentTemplateStack.pop();
14505
+ const previousOverrideContext = this.currentOverrideContext;
14506
+ const overrideContext = selection.originalComponent || selection.selectedTemplate.__originalComponent;
14507
+ if (overrideContext) {
14508
+ this.currentOverrideContext = overrideContext;
14509
+ }
14510
+ try {
14511
+ yield this.xsltChildNodes(importedContext, selection.selectedTemplate, output);
14512
+ } finally {
14513
+ this.currentTemplateStack.pop();
14514
+ this.currentOverrideContext = previousOverrideContext;
14515
+ }
14304
14516
  }
14305
14517
  });
14306
14518
  }
@@ -14335,6 +14547,21 @@ var Xslt = class {
14335
14547
  const top = template.ownerDocument.documentElement;
14336
14548
  const paramContext = context.clone();
14337
14549
  yield this.xsltWithParam(paramContext, template);
14550
+ let foundTemplate = null;
14551
+ if (this.currentPackage) {
14552
+ this.currentPackage.usedPackages.forEach((usedPkg) => {
14553
+ usedPkg.acceptedComponents.forEach((component) => {
14554
+ if (component.type === "template" && component.name === name && component.isAccepted) {
14555
+ const effectiveComponent = this.getEffectiveComponent(component);
14556
+ foundTemplate = effectiveComponent.node;
14557
+ }
14558
+ });
14559
+ });
14560
+ }
14561
+ if (foundTemplate) {
14562
+ yield this.xsltChildNodes(paramContext, foundTemplate, output);
14563
+ return;
14564
+ }
14338
14565
  for (let i = 0; i < top.childNodes.length; ++i) {
14339
14566
  let childNode = top.childNodes[i];
14340
14567
  if (childNode.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(childNode, "template") && domGetAttributeValue(childNode, "name") === name) {
@@ -15146,16 +15373,27 @@ var Xslt = class {
15146
15373
  }
15147
15374
  const name = xmlGetAttribute(template, "name");
15148
15375
  const packageVersion = xmlGetAttribute(template, "package-version");
15376
+ const declaredModes = xmlGetAttribute(template, "declared-modes") || "yes";
15377
+ const inputTypeAnnotations = xmlGetAttribute(template, "input-type-annotations") || "unspecified";
15149
15378
  if (!name) {
15150
15379
  throw new Error('<xsl:package> requires a "name" attribute.');
15151
15380
  }
15381
+ const packageKey = packageVersion ? `${name}@${packageVersion}` : name;
15382
+ const wasAlreadyLoading = this.packageRegistry.isLoading(packageKey);
15383
+ if (!wasAlreadyLoading) {
15384
+ this.packageRegistry.beginLoading(packageKey);
15385
+ }
15152
15386
  const pkg = {
15153
15387
  name,
15154
15388
  version: packageVersion,
15155
15389
  root: template,
15156
15390
  components: /* @__PURE__ */ new Map(),
15157
15391
  usedPackages: /* @__PURE__ */ new Map(),
15158
- isTopLevel: this.currentPackage === null
15392
+ isTopLevel: this.currentPackage === null,
15393
+ overrides: /* @__PURE__ */ new Map(),
15394
+ modes: /* @__PURE__ */ new Map(),
15395
+ declaredModes,
15396
+ inputTypeAnnotations
15159
15397
  };
15160
15398
  const previousPackage = this.currentPackage;
15161
15399
  this.currentPackage = pkg;
@@ -15163,10 +15401,54 @@ var Xslt = class {
15163
15401
  this.packageRegistry.register(pkg);
15164
15402
  yield this.xsltTransformOrStylesheet(context, template, output);
15165
15403
  } finally {
15404
+ if (!wasAlreadyLoading) {
15405
+ this.packageRegistry.endLoading(packageKey);
15406
+ }
15166
15407
  this.currentPackage = previousPackage;
15167
15408
  }
15168
15409
  });
15169
15410
  }
15411
+ /**
15412
+ * Loads and registers an external package.
15413
+ * Creates a temporary context and processes the package document.
15414
+ *
15415
+ * @param name The package name/URI.
15416
+ * @param packageDoc The parsed package document.
15417
+ * @param version Optional semantic version string.
15418
+ */
15419
+ loadAndRegisterPackage(name, packageDoc, version) {
15420
+ return __async(this, null, function* () {
15421
+ const packageKey = version ? `${name}@${version}` : name;
15422
+ if (!this.packageRegistry.beginLoading(packageKey)) {
15423
+ throw new Error(`Circular package dependency detected: "${packageKey}".`);
15424
+ }
15425
+ try {
15426
+ let packageRoot = packageDoc;
15427
+ if (packageDoc.nodeType === DOM_DOCUMENT_NODE) {
15428
+ for (const child of packageDoc.childNodes) {
15429
+ if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child, "package")) {
15430
+ packageRoot = child;
15431
+ break;
15432
+ }
15433
+ }
15434
+ }
15435
+ if (packageRoot && this.isXsltElement(packageRoot, "package")) {
15436
+ if (name && !xmlGetAttribute(packageRoot, "name")) {
15437
+ domSetAttribute(packageRoot, "name", name);
15438
+ }
15439
+ if (version && !xmlGetAttribute(packageRoot, "package-version")) {
15440
+ domSetAttribute(packageRoot, "package-version", version);
15441
+ }
15442
+ const tempContext = new ExprContext([packageRoot]);
15443
+ yield this.xsltPackage(tempContext, packageRoot);
15444
+ } else {
15445
+ throw new Error("Package document does not contain an xsl:package root element.");
15446
+ }
15447
+ } finally {
15448
+ this.packageRegistry.endLoading(packageKey);
15449
+ }
15450
+ });
15451
+ }
15170
15452
  /**
15171
15453
  * Implements `<xsl:use-package>` (XSLT 3.0 Section 3.7).
15172
15454
  * Imports another package and makes its public components available.
@@ -15184,10 +15466,27 @@ var Xslt = class {
15184
15466
  if (!name) {
15185
15467
  throw new Error('<xsl:use-package> requires a "name" attribute.');
15186
15468
  }
15187
- const usedPackage = this.packageRegistry.get(name, packageVersion);
15469
+ const packageKey = packageVersion ? `${name}@${packageVersion}` : name;
15470
+ if (this.packageRegistry.isLoading(packageKey)) {
15471
+ throw new Error(`Circular package dependency detected: "${packageKey}".`);
15472
+ }
15473
+ let usedPackage = this.packageRegistry.get(name, packageVersion);
15474
+ if (!usedPackage && this.packageLoader) {
15475
+ try {
15476
+ const packageDoc = yield this.packageLoader(name, packageVersion);
15477
+ if (packageDoc) {
15478
+ yield this.loadAndRegisterPackage(name, packageDoc, packageVersion);
15479
+ usedPackage = this.packageRegistry.get(name, packageVersion);
15480
+ }
15481
+ } catch (error) {
15482
+ if (error instanceof Error && error.message.includes("Circular package dependency")) {
15483
+ throw error;
15484
+ }
15485
+ }
15486
+ }
15188
15487
  if (!usedPackage) {
15189
15488
  throw new Error(
15190
- `Package "${name}"${packageVersion ? `@${packageVersion}` : ""} not found. Packages must be loaded before they can be used.`
15489
+ `Package "${name}"${packageVersion ? `@${packageVersion}` : ""} not found. ` + (this.packageLoader ? "Package loader failed to load the package." : "Packages must be loaded before they can be used.")
15191
15490
  );
15192
15491
  }
15193
15492
  const usedPkg = {
@@ -15199,8 +15498,22 @@ var Xslt = class {
15199
15498
  for (const child of template.childNodes) {
15200
15499
  if (this.isXsltElement(child, "accept")) {
15201
15500
  this.xsltAccept(context, child);
15501
+ } else if (this.isXsltElement(child, "override")) {
15502
+ yield this.xsltOverride(context, child, output);
15202
15503
  }
15203
15504
  }
15505
+ yield this.registerAcceptedVariables(context);
15506
+ this.registerUserDefinedFunctionsInContext(context);
15507
+ usedPackage.components.forEach((component, key2) => {
15508
+ if (component.visibility === "abstract") {
15509
+ const hasOverride = this.currentPackage.overrides.has(key2);
15510
+ if (!hasOverride) {
15511
+ throw new Error(
15512
+ `Abstract component "${component.name || component.match || key2}" from package "${name}" must be overridden.`
15513
+ );
15514
+ }
15515
+ }
15516
+ });
15204
15517
  });
15205
15518
  }
15206
15519
  /**
@@ -15224,16 +15537,69 @@ var Xslt = class {
15224
15537
  throw new Error('<xsl:expose> requires a "names" attribute.');
15225
15538
  }
15226
15539
  for (const name of nameList) {
15227
- const component = {
15228
- type: componentType,
15229
- name: name === "*" ? void 0 : name,
15230
- visibility,
15231
- overridable: visibility !== "final",
15232
- node: template
15233
- };
15234
- const key = makeComponentKey(component);
15235
- this.currentPackage.components.set(key, component);
15540
+ const actualComponent = this.findComponentInPackageRoot(
15541
+ this.currentPackage.root,
15542
+ componentType,
15543
+ name === "*" ? null : name
15544
+ );
15545
+ if (actualComponent) {
15546
+ const component = {
15547
+ type: componentType,
15548
+ name: actualComponent.name || (name !== "*" ? name : void 0),
15549
+ match: actualComponent.match,
15550
+ mode: actualComponent.mode,
15551
+ visibility,
15552
+ overridable: visibility !== "final",
15553
+ node: actualComponent.node,
15554
+ priority: actualComponent.priority
15555
+ };
15556
+ const key = makeComponentKey(component);
15557
+ this.currentPackage.components.set(key, component);
15558
+ } else if (name !== "*") {
15559
+ }
15560
+ }
15561
+ }
15562
+ /**
15563
+ * Find a component definition in the package root.
15564
+ * @param packageRoot The package root element
15565
+ * @param type The component type to find
15566
+ * @param name The component name (null for all matching type)
15567
+ * @returns Component information or null if not found
15568
+ */
15569
+ findComponentInPackageRoot(packageRoot, type, name) {
15570
+ for (const child of packageRoot.childNodes) {
15571
+ if (child.nodeType !== DOM_ELEMENT_NODE) {
15572
+ continue;
15573
+ }
15574
+ if (type === "template" && this.isXsltElement(child, "template")) {
15575
+ const templateName = xmlGetAttribute(child, "name");
15576
+ const match = xmlGetAttribute(child, "match");
15577
+ const mode = xmlGetAttribute(child, "mode");
15578
+ if (name) {
15579
+ if (templateName === name) {
15580
+ return { node: child, name: templateName, match, mode };
15581
+ }
15582
+ } else {
15583
+ return { node: child, name: templateName, match, mode };
15584
+ }
15585
+ } else if (type === "function" && this.isXsltElement(child, "function")) {
15586
+ const functionName2 = xmlGetAttribute(child, "name");
15587
+ if (!name || functionName2 === name) {
15588
+ return { node: child, name: functionName2 };
15589
+ }
15590
+ } else if (type === "variable" && this.isXsltElement(child, "variable")) {
15591
+ const varName = xmlGetAttribute(child, "name");
15592
+ if (!name || varName === name) {
15593
+ return { node: child, name: varName };
15594
+ }
15595
+ } else if (type === "attribute-set" && this.isXsltElement(child, "attribute-set")) {
15596
+ const setName = xmlGetAttribute(child, "name");
15597
+ if (!name || setName === name) {
15598
+ return { node: child, name: setName };
15599
+ }
15600
+ }
15236
15601
  }
15602
+ return null;
15237
15603
  }
15238
15604
  /**
15239
15605
  * Implements `<xsl:accept>` (XSLT 3.0 Section 3.9).
@@ -15247,6 +15613,7 @@ var Xslt = class {
15247
15613
  }
15248
15614
  const componentType = xmlGetAttribute(template, "component");
15249
15615
  const names = xmlGetAttribute(template, "names");
15616
+ const visibilityOverride = xmlGetAttribute(template, "visibility");
15250
15617
  if (!componentType) {
15251
15618
  throw new Error('<xsl:accept> requires a "component" attribute.');
15252
15619
  }
@@ -15265,17 +15632,325 @@ var Xslt = class {
15265
15632
  if (!usedPkg) {
15266
15633
  throw new Error(`Internal error: used package "${key}" not found.`);
15267
15634
  }
15268
- for (const name of nameList) {
15269
- const component = {
15270
- type: componentType,
15271
- name: name === "*" ? void 0 : name,
15272
- visibility: "public",
15273
- overridable: true,
15635
+ const componentsToAccept = this.findComponentsInPackage(
15636
+ usedPkg.package,
15637
+ componentType,
15638
+ nameList
15639
+ );
15640
+ for (const component of componentsToAccept) {
15641
+ if (!isComponentVisible(component, false)) {
15642
+ const componentName = component.name || component.match || "unnamed";
15643
+ throw new Error(
15644
+ `Cannot accept private component "${componentName}" of type "${componentType}" from package "${usedPkg.package.name}".`
15645
+ );
15646
+ }
15647
+ const acceptedComponent = __spreadProps(__spreadValues({}, component), {
15648
+ sourcePackage: usedPkg.package.name,
15649
+ isAccepted: true,
15650
+ effectiveVisibility: visibilityOverride || component.visibility
15651
+ });
15652
+ const componentKey = makeComponentKey(acceptedComponent);
15653
+ usedPkg.acceptedComponents.set(componentKey, acceptedComponent);
15654
+ }
15655
+ }
15656
+ /**
15657
+ * Implements <xsl:override> (XSLT 3.0 Section 3.7.2).
15658
+ * Overrides components from a used package.
15659
+ */
15660
+ xsltOverride(context, template, output) {
15661
+ return __async(this, null, function* () {
15662
+ if (!this.currentPackage) {
15663
+ throw new Error("<xsl:override> can only appear as a child of <xsl:use-package>.");
15664
+ }
15665
+ const parentUsePackage = template.parentNode;
15666
+ if (!parentUsePackage || !this.isXsltElement(parentUsePackage, "use-package")) {
15667
+ throw new Error("<xsl:override> must be a child of <xsl:use-package>.");
15668
+ }
15669
+ const packageName = xmlGetAttribute(parentUsePackage, "name");
15670
+ const packageVersion = xmlGetAttribute(parentUsePackage, "package-version");
15671
+ const key = packageVersion ? `${packageName}@${packageVersion}` : packageName;
15672
+ const usedPkg = this.currentPackage.usedPackages.get(key);
15673
+ if (!usedPkg) {
15674
+ throw new Error(`Internal error: used package "${key}" not found.`);
15675
+ }
15676
+ for (let i = 0; i < template.childNodes.length; i++) {
15677
+ const child = template.childNodes[i];
15678
+ if (child.nodeType !== DOM_ELEMENT_NODE) {
15679
+ continue;
15680
+ }
15681
+ const localName = child.localName;
15682
+ let componentType = null;
15683
+ let componentName = null;
15684
+ let componentMatch = null;
15685
+ switch (localName) {
15686
+ case "template":
15687
+ componentType = "template";
15688
+ componentName = xmlGetAttribute(child, "name");
15689
+ componentMatch = xmlGetAttribute(child, "match");
15690
+ break;
15691
+ case "function":
15692
+ componentType = "function";
15693
+ componentName = xmlGetAttribute(child, "name");
15694
+ break;
15695
+ case "variable":
15696
+ componentType = "variable";
15697
+ componentName = xmlGetAttribute(child, "name");
15698
+ break;
15699
+ case "attribute-set":
15700
+ componentType = "attribute-set";
15701
+ componentName = xmlGetAttribute(child, "name");
15702
+ break;
15703
+ default:
15704
+ throw new Error(`<xsl:override> does not support <xsl:${localName}> elements.`);
15705
+ }
15706
+ if (!componentType) {
15707
+ continue;
15708
+ }
15709
+ let originalComponent;
15710
+ usedPkg.acceptedComponents.forEach((component) => {
15711
+ if (component.type !== componentType) {
15712
+ return;
15713
+ }
15714
+ if (componentName && component.name === componentName) {
15715
+ originalComponent = component;
15716
+ } else if (componentMatch && component.match === componentMatch) {
15717
+ originalComponent = component;
15718
+ }
15719
+ });
15720
+ if (!originalComponent) {
15721
+ usedPkg.package.components.forEach((component) => {
15722
+ if (component.type !== componentType) {
15723
+ return;
15724
+ }
15725
+ if (componentName && component.name === componentName) {
15726
+ originalComponent = component;
15727
+ } else if (componentMatch && component.match === componentMatch) {
15728
+ originalComponent = component;
15729
+ }
15730
+ });
15731
+ }
15732
+ if (!originalComponent) {
15733
+ const identifier = componentName || componentMatch || "unnamed";
15734
+ throw new Error(
15735
+ `Cannot override component "${identifier}" of type "${componentType}": component not found in package "${usedPkg.package.name}".`
15736
+ );
15737
+ }
15738
+ if (!canOverrideComponent(originalComponent)) {
15739
+ const identifier = componentName || componentMatch || "unnamed";
15740
+ throw new Error(
15741
+ `Cannot override component "${identifier}" of type "${componentType}": component is marked as "final" in package "${usedPkg.package.name}".`
15742
+ );
15743
+ }
15744
+ const overridingComponent = {
15745
+ type: componentType,
15746
+ name: componentName || void 0,
15747
+ match: componentMatch || void 0,
15748
+ mode: xmlGetAttribute(child, "mode") || void 0,
15749
+ visibility: originalComponent.visibility,
15750
+ // Inherit visibility from original
15751
+ overridable: false,
15752
+ // Overrides cannot themselves be overridden (unless explicitly marked)
15753
+ node: child,
15754
+ sourcePackage: this.currentPackage.name,
15755
+ isAccepted: false,
15756
+ effectiveVisibility: originalComponent.visibility
15757
+ };
15758
+ overridingComponent.originalComponent = originalComponent;
15759
+ overridingComponent.node.__originalComponent = originalComponent;
15760
+ const componentKey = makeComponentKey(originalComponent);
15761
+ this.currentPackage.overrides.set(componentKey, overridingComponent);
15762
+ if (componentType === "function") {
15763
+ this.xsltFunction(context, child);
15764
+ }
15765
+ }
15766
+ });
15767
+ }
15768
+ /**
15769
+ * Find components in a package matching the given criteria.
15770
+ * Used by xsl:accept to locate components from used packages.
15771
+ *
15772
+ * @param pkg The package to search in
15773
+ * @param componentType The type of component to find
15774
+ * @param namePatterns Array of name patterns ('*' for all, or specific names)
15775
+ * @returns Array of matching components
15776
+ */
15777
+ findComponentsInPackage(pkg, componentType, namePatterns) {
15778
+ const results = [];
15779
+ const isWildcard = namePatterns.includes("*");
15780
+ pkg.components.forEach((component, key) => {
15781
+ if (component.type !== componentType) {
15782
+ return;
15783
+ }
15784
+ if (isWildcard) {
15785
+ results.push(component);
15786
+ return;
15787
+ }
15788
+ const componentName = this.getComponentNameForMatching(component);
15789
+ if (componentName && namePatterns.includes(componentName)) {
15790
+ results.push(component);
15791
+ }
15792
+ });
15793
+ return results;
15794
+ }
15795
+ /**
15796
+ * Get the name to use when matching components.
15797
+ * For named components (functions, variables, attribute-sets), returns the name.
15798
+ * For templates, returns the name if present, otherwise returns null (match-based templates).
15799
+ *
15800
+ * @param component The component to get the name from
15801
+ * @returns The component name for matching, or null if unnamed
15802
+ */
15803
+ getComponentNameForMatching(component) {
15804
+ switch (component.type) {
15805
+ case "function":
15806
+ case "variable":
15807
+ case "attribute-set":
15808
+ case "mode":
15809
+ return component.name || null;
15810
+ case "template":
15811
+ return component.name || null;
15812
+ default:
15813
+ return null;
15814
+ }
15815
+ }
15816
+ /**
15817
+ * Implements <xsl:original> (XSLT 3.0 Section 3.7.2).
15818
+ * Calls the original component from within an override.
15819
+ */
15820
+ xsltOriginal(context, template, output) {
15821
+ return __async(this, null, function* () {
15822
+ if (!this.currentOverrideContext && this.currentTemplateStack.length > 0) {
15823
+ const currentTemplate = this.currentTemplateStack[this.currentTemplateStack.length - 1].template;
15824
+ const templateOverrideContext = currentTemplate.__originalComponent;
15825
+ if (templateOverrideContext) {
15826
+ this.currentOverrideContext = templateOverrideContext;
15827
+ }
15828
+ }
15829
+ if (!this.currentOverrideContext) {
15830
+ throw new Error("<xsl:original> can only be used within an overriding component.");
15831
+ }
15832
+ const originalComponent = this.currentOverrideContext;
15833
+ const originalNode = originalComponent.node;
15834
+ switch (originalComponent.type) {
15835
+ case "template":
15836
+ yield this.xsltChildNodes(context, originalNode, output);
15837
+ break;
15838
+ case "function":
15839
+ throw new Error("<xsl:original> for functions should be called as a function, not as an element.");
15840
+ case "variable":
15841
+ yield this.xsltVariable(context, originalNode, true);
15842
+ break;
15843
+ case "attribute-set":
15844
+ if (originalComponent.name && output) {
15845
+ yield this.applyAttributeSets(context, output, originalComponent.name);
15846
+ }
15847
+ break;
15848
+ default:
15849
+ throw new Error(`<xsl:original> does not support component type "${originalComponent.type}".`);
15850
+ }
15851
+ });
15852
+ }
15853
+ /**
15854
+ * Implements `<xsl:mode>` (XSLT 3.0 Section 3.5).
15855
+ * Declares a mode with visibility and other properties.
15856
+ * Only valid within an xsl:package.
15857
+ */
15858
+ xsltMode(context, template) {
15859
+ if (!this.currentPackage) {
15860
+ throw new Error("<xsl:mode> can only appear as a child of <xsl:package>.");
15861
+ }
15862
+ const name = xmlGetAttribute(template, "name");
15863
+ if (!name) {
15864
+ throw new Error('<xsl:mode> requires a "name" attribute.');
15865
+ }
15866
+ const visibility = xmlGetAttribute(template, "visibility") || "public";
15867
+ const streamableAttr = xmlGetAttribute(template, "streamable");
15868
+ const onNoMatch = xmlGetAttribute(template, "on-no-match");
15869
+ const onMultipleMatch = xmlGetAttribute(template, "on-multiple-match");
15870
+ const streamable = streamableAttr === "yes";
15871
+ if (!this.currentPackage.modes) {
15872
+ this.currentPackage.modes = /* @__PURE__ */ new Map();
15873
+ }
15874
+ const modeProperties = {
15875
+ name,
15876
+ visibility,
15877
+ streamable,
15878
+ onNoMatch,
15879
+ onMultipleMatch
15880
+ };
15881
+ this.currentPackage.modes.set(name, modeProperties);
15882
+ const componentKey = makeComponentKey({ type: "mode", name, visibility });
15883
+ if (!this.currentPackage.components.has(componentKey)) {
15884
+ this.currentPackage.components.set(componentKey, {
15885
+ type: "mode",
15886
+ name,
15887
+ visibility,
15888
+ overridable: false,
15274
15889
  node: template
15275
- };
15276
- const componentKey = makeComponentKey(component);
15277
- usedPkg.acceptedComponents.set(componentKey, component);
15890
+ });
15891
+ }
15892
+ }
15893
+ /**
15894
+ * Get the effective component, checking for overrides first.
15895
+ * If the component has been overridden in the current package, returns the override.
15896
+ * Otherwise, returns the original component.
15897
+ * @param component The original component
15898
+ * @returns The effective component (override or original)
15899
+ */
15900
+ getEffectiveComponent(component) {
15901
+ if (!this.currentPackage) {
15902
+ return component;
15278
15903
  }
15904
+ const componentKey = makeComponentKey(component);
15905
+ const override = this.currentPackage.overrides.get(componentKey);
15906
+ return override || component;
15907
+ }
15908
+ /**
15909
+ * Collect templates from accepted components in used packages.
15910
+ * @param mode The mode to match (null for default mode)
15911
+ * @returns Array of template priority interfaces
15912
+ */
15913
+ collectAcceptedTemplates(mode) {
15914
+ const templates = [];
15915
+ if (!this.currentPackage) {
15916
+ return templates;
15917
+ }
15918
+ this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {
15919
+ usedPkg.acceptedComponents.forEach((component, componentKey) => {
15920
+ if (component.type === "template" && component.isAccepted) {
15921
+ const effectiveComponent = this.getEffectiveComponent(component);
15922
+ const templateNode = effectiveComponent.node;
15923
+ const isOverride = effectiveComponent !== component;
15924
+ const originalForContext = isOverride ? component : void 0;
15925
+ const templateMode = xmlGetAttribute(templateNode, "mode") || null;
15926
+ const effectiveMode = mode || null;
15927
+ if (effectiveMode !== templateMode) {
15928
+ return;
15929
+ }
15930
+ const match = xmlGetAttribute(templateNode, "match");
15931
+ if (!match) {
15932
+ return;
15933
+ }
15934
+ const priorityAttr = xmlGetAttribute(templateNode, "priority");
15935
+ const explicitPriority = priorityAttr ? parseFloat(priorityAttr) : null;
15936
+ const defaultPriority = component.priority || 0;
15937
+ const effectivePriority = explicitPriority !== null && !isNaN(explicitPriority) ? explicitPriority : defaultPriority;
15938
+ templates.push({
15939
+ template: templateNode,
15940
+ explicitPriority: explicitPriority !== null && !isNaN(explicitPriority) ? explicitPriority : null,
15941
+ defaultPriority,
15942
+ effectivePriority,
15943
+ importPrecedence: 0,
15944
+ // Accepted templates have neutral precedence
15945
+ documentOrder: 0,
15946
+ matchPattern: match,
15947
+ originalComponent: originalForContext
15948
+ // Store original for xsl:original support
15949
+ });
15950
+ }
15951
+ });
15952
+ });
15953
+ return templates;
15279
15954
  }
15280
15955
  /**
15281
15956
  * Implements `<xsl:stream>` (XSLT 3.0 Section 16).
@@ -16364,6 +17039,30 @@ var Xslt = class {
16364
17039
  }
16365
17040
  this.userDefinedFunctions.set(name, template);
16366
17041
  }
17042
+ /**
17043
+ * Coerce a NodeValue to a specific type based on the 'as' attribute.
17044
+ *
17045
+ * @param value The value to coerce.
17046
+ * @param type The target type (e.g., "xs:integer", "xs:string", "xs:boolean").
17047
+ * @returns The coerced value.
17048
+ */
17049
+ coerceToType(value, type) {
17050
+ const normalizedType = type.replace(/^xs:/, "").toLowerCase();
17051
+ switch (normalizedType) {
17052
+ case "integer":
17053
+ case "int":
17054
+ case "double":
17055
+ case "decimal":
17056
+ case "number":
17057
+ return new NumberValue(value.numberValue());
17058
+ case "string":
17059
+ return new StringValue(value.stringValue());
17060
+ case "boolean":
17061
+ return new BooleanValue(value.booleanValue());
17062
+ default:
17063
+ return value;
17064
+ }
17065
+ }
16367
17066
  /**
16368
17067
  * Execute a user-defined xsl:function.
16369
17068
  * Called when a function from userDefinedFunctions is invoked from XPath.
@@ -16401,18 +17100,32 @@ var Xslt = class {
16401
17100
  const paramName = xmlGetAttribute(params[i], "name");
16402
17101
  if (paramName) {
16403
17102
  if (i < args.length) {
16404
- const argValue = args[i];
17103
+ let argValue = args[i];
17104
+ const paramType = xmlGetAttribute(params[i], "as");
17105
+ let paramValue;
16405
17106
  if (argValue && typeof argValue === "object" && "stringValue" in argValue) {
16406
- functionContext.setVariable(paramName, argValue);
17107
+ paramValue = argValue;
17108
+ if (paramType) {
17109
+ paramValue = this.coerceToType(paramValue, paramType);
17110
+ }
17111
+ } else if (argValue && typeof argValue === "object" && "nodeType" in argValue) {
17112
+ paramValue = new NodeSetValue([argValue]);
17113
+ if (paramType) {
17114
+ paramValue = this.coerceToType(paramValue, paramType);
17115
+ }
16407
17116
  } else if (Array.isArray(argValue)) {
16408
- functionContext.setVariable(paramName, new NodeSetValue(argValue));
17117
+ paramValue = new NodeSetValue(argValue);
17118
+ if (paramType) {
17119
+ paramValue = this.coerceToType(paramValue, paramType);
17120
+ }
16409
17121
  } else if (typeof argValue === "number") {
16410
- functionContext.setVariable(paramName, new NumberValue(argValue));
17122
+ paramValue = new NumberValue(argValue);
16411
17123
  } else if (typeof argValue === "boolean") {
16412
- functionContext.setVariable(paramName, new BooleanValue(argValue));
17124
+ paramValue = new BooleanValue(argValue);
16413
17125
  } else {
16414
- functionContext.setVariable(paramName, new StringValue(String(argValue != null ? argValue : "")));
17126
+ paramValue = new StringValue(String(argValue != null ? argValue : ""));
16415
17127
  }
17128
+ functionContext.setVariable(paramName, paramValue);
16416
17129
  } else {
16417
17130
  const selectExpr = xmlGetAttribute(params[i], "select");
16418
17131
  if (selectExpr) {
@@ -16491,6 +17204,30 @@ var Xslt = class {
16491
17204
  getResultDocuments() {
16492
17205
  return this.resultDocuments;
16493
17206
  }
17207
+ /**
17208
+ * Sets the package loader callback.
17209
+ * The callback is called when a package is referenced via xsl:use-package
17210
+ * but is not found in the registry.
17211
+ *
17212
+ * @param loader A function that loads package documents by URI and optional version.
17213
+ * Returns the parsed package document, or null if not found.
17214
+ */
17215
+ setPackageLoader(loader) {
17216
+ this.packageLoader = loader;
17217
+ }
17218
+ /**
17219
+ * Pre-registers a package for use in transformations.
17220
+ * The package is parsed and stored in the internal registry.
17221
+ *
17222
+ * @param name The package name/URI.
17223
+ * @param packageDoc The parsed package document.
17224
+ * @param version Optional semantic version string.
17225
+ */
17226
+ registerPackage(name, packageDoc, version) {
17227
+ return __async(this, null, function* () {
17228
+ yield this.loadAndRegisterPackage(name, packageDoc, version);
17229
+ });
17230
+ }
16494
17231
  /**
16495
17232
  * Implements `xsl:perform-sort` (XSLT 2.0).
16496
17233
  *
@@ -16605,6 +17342,25 @@ var Xslt = class {
16605
17342
  }
16606
17343
  });
16607
17344
  }
17345
+ /**
17346
+ * Register accepted variables from used packages into the context.
17347
+ * Called after processing package use-package declarations.
17348
+ * @param context The expression context.
17349
+ */
17350
+ registerAcceptedVariables(context) {
17351
+ return __async(this, null, function* () {
17352
+ if (!this.currentPackage) {
17353
+ return;
17354
+ }
17355
+ this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {
17356
+ usedPkg.acceptedComponents.forEach((component, componentKey) => {
17357
+ if (component.type === "variable" && component.name && component.isAccepted) {
17358
+ this.xsltVariable(context, component.node, false);
17359
+ }
17360
+ });
17361
+ });
17362
+ });
17363
+ }
16608
17364
  /**
16609
17365
  * Traverses the template node tree. Calls the main processing
16610
17366
  * function with the current input context for every child node of the
@@ -16699,13 +17455,7 @@ var Xslt = class {
16699
17455
  node = context.nodeList[context.position];
16700
17456
  let newNode;
16701
17457
  newNode = domCreateElement(this.outputDocument, template.nodeName);
16702
- if (node && node.siblingPosition !== void 0) {
16703
- newNode.siblingPosition = node.siblingPosition;
16704
- } else if (node === void 0 && context.nodeList.length === 0) {
16705
- newNode.siblingPosition = (output || this.outputDocument).childNodes.length;
16706
- } else {
16707
- newNode.siblingPosition = 0;
16708
- }
17458
+ newNode.siblingPosition = (output || this.outputDocument).childNodes.length;
16709
17459
  domAppendChild(output || this.outputDocument, newNode);
16710
17460
  const useAttributeSetsAttr = template.childNodes.find(
16711
17461
  (a) => (a == null ? void 0 : a.nodeType) === DOM_ATTRIBUTE_NODE && a.nodeName === "use-attribute-sets"
@@ -16944,7 +17694,7 @@ var Xslt = class {
16944
17694
  * @param context The expression context.
16945
17695
  */
16946
17696
  registerUserDefinedFunctionsInContext(context) {
16947
- if (this.userDefinedFunctions.size === 0) {
17697
+ if (this.userDefinedFunctions.size === 0 && !this.hasAcceptedFunctions()) {
16948
17698
  return;
16949
17699
  }
16950
17700
  const functionsMap = /* @__PURE__ */ new Map();
@@ -16956,8 +17706,48 @@ var Xslt = class {
16956
17706
  }
16957
17707
  });
16958
17708
  });
17709
+ this.registerAcceptedFunctions(functionsMap);
16959
17710
  context.userDefinedFunctions = functionsMap;
16960
17711
  }
17712
+ /**
17713
+ * Check if there are any accepted functions in used packages.
17714
+ */
17715
+ hasAcceptedFunctions() {
17716
+ if (!this.currentPackage) {
17717
+ return false;
17718
+ }
17719
+ let hasAccepted = false;
17720
+ this.currentPackage.usedPackages.forEach((usedPkg) => {
17721
+ usedPkg.acceptedComponents.forEach((component) => {
17722
+ if (component.type === "function" && component.isAccepted) {
17723
+ hasAccepted = true;
17724
+ }
17725
+ });
17726
+ });
17727
+ return hasAccepted;
17728
+ }
17729
+ /**
17730
+ * Register accepted functions from used packages.
17731
+ * @param functionsMap The map to register functions into.
17732
+ */
17733
+ registerAcceptedFunctions(functionsMap) {
17734
+ if (!this.currentPackage) {
17735
+ return;
17736
+ }
17737
+ this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {
17738
+ usedPkg.acceptedComponents.forEach((component, componentKey) => {
17739
+ if (component.type === "function" && component.name && component.isAccepted) {
17740
+ const effectiveComponent = this.getEffectiveComponent(component);
17741
+ functionsMap.set(component.name, {
17742
+ functionDef: effectiveComponent.node,
17743
+ executor: (ctx, funcDef, args) => {
17744
+ return this.executeUserDefinedFunctionSync(ctx, funcDef, args);
17745
+ }
17746
+ });
17747
+ }
17748
+ });
17749
+ });
17750
+ }
16961
17751
  /**
16962
17752
  * Apply one or more attribute sets to an element.
16963
17753
  * Parses space-separated attribute set names and applies them.