@trops/dash-core 0.1.567 → 0.1.569

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.
@@ -22761,10 +22761,9 @@ function date$1(params) {
22761
22761
  */
22762
22762
  exports.TaskCreationParamsSchema = z.looseObject({
22763
22763
  /**
22764
- * Time in milliseconds to keep task results available after completion.
22765
- * If null, the task has unlimited lifetime until manually cleaned up.
22764
+ * Requested duration in milliseconds to retain task from creation.
22766
22765
  */
22767
- ttl: z.union([z.number(), z.null()]).optional(),
22766
+ ttl: z.number().optional(),
22768
22767
  /**
22769
22768
  * Time in milliseconds to wait between task status requests.
22770
22769
  */
@@ -23192,7 +23191,11 @@ function date$1(params) {
23192
23191
  /**
23193
23192
  * Present if the client supports task creation.
23194
23193
  */
23195
- tasks: exports.ClientTasksCapabilitySchema.optional()
23194
+ tasks: exports.ClientTasksCapabilitySchema.optional(),
23195
+ /**
23196
+ * Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name).
23197
+ */
23198
+ extensions: z.record(z.string(), AssertObjectSchema).optional()
23196
23199
  });
23197
23200
  exports.InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
23198
23201
  /**
@@ -23267,7 +23270,11 @@ function date$1(params) {
23267
23270
  /**
23268
23271
  * Present if the server supports task creation.
23269
23272
  */
23270
- tasks: exports.ServerTasksCapabilitySchema.optional()
23273
+ tasks: exports.ServerTasksCapabilitySchema.optional(),
23274
+ /**
23275
+ * Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name).
23276
+ */
23277
+ extensions: z.record(z.string(), AssertObjectSchema).optional()
23271
23278
  });
23272
23279
  /**
23273
23280
  * After receiving an initialize request from the client, the server sends this response.
@@ -23542,6 +23549,12 @@ function date$1(params) {
23542
23549
  * The MIME type of this resource, if known.
23543
23550
  */
23544
23551
  mimeType: z.optional(z.string()),
23552
+ /**
23553
+ * The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
23554
+ *
23555
+ * This can be used by Hosts to display file sizes and estimate context window usage.
23556
+ */
23557
+ size: z.optional(z.number()),
23545
23558
  /**
23546
23559
  * Optional annotations for the client.
23547
23560
  */
@@ -25332,17 +25345,21 @@ const AUTHORIZATION_CODE_CHALLENGE_METHOD = 'S256';
25332
25345
  */
25333
25346
  function selectClientAuthMethod(clientInformation, supportedMethods) {
25334
25347
  const hasClientSecret = clientInformation.client_secret !== undefined;
25335
- // If server doesn't specify supported methods, use RFC 6749 defaults
25336
- if (supportedMethods.length === 0) {
25337
- return hasClientSecret ? 'client_secret_post' : 'none';
25338
- }
25339
- // Prefer the method returned by the server during client registration if valid and supported
25348
+ // Prefer the method returned by the server during client registration, if valid.
25349
+ // When server metadata is present we also require the method to be listed as supported;
25350
+ // when supportedMethods is empty (metadata omitted the field) the DCR hint stands alone.
25340
25351
  if ('token_endpoint_auth_method' in clientInformation &&
25341
25352
  clientInformation.token_endpoint_auth_method &&
25342
25353
  isClientAuthMethod(clientInformation.token_endpoint_auth_method) &&
25343
- supportedMethods.includes(clientInformation.token_endpoint_auth_method)) {
25354
+ (supportedMethods.length === 0 || supportedMethods.includes(clientInformation.token_endpoint_auth_method))) {
25344
25355
  return clientInformation.token_endpoint_auth_method;
25345
25356
  }
25357
+ // If server metadata omits token_endpoint_auth_methods_supported, RFC 8414 §2 says the
25358
+ // default is client_secret_basic. RFC 6749 §2.3.1 also requires servers to support HTTP
25359
+ // Basic authentication for clients with a secret, making it the safest default.
25360
+ if (supportedMethods.length === 0) {
25361
+ return hasClientSecret ? 'client_secret_basic' : 'none';
25362
+ }
25346
25363
  // Try methods in priority order (most secure first)
25347
25364
  if (hasClientSecret && supportedMethods.includes('client_secret_basic')) {
25348
25365
  return 'client_secret_basic';
@@ -25516,6 +25533,12 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
25516
25533
  });
25517
25534
  }
25518
25535
  const resource = await selectResourceURL(serverUrl, provider, resourceMetadata);
25536
+ // Apply scope selection strategy (SEP-835):
25537
+ // 1. WWW-Authenticate scope (passed via `scope` param)
25538
+ // 2. PRM scopes_supported
25539
+ // 3. Client metadata scope (user-configured fallback)
25540
+ // The resolved scope is used consistently for both DCR and the authorization request.
25541
+ const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(' ') || provider.clientMetadata.scope;
25519
25542
  // Handle client registration if needed
25520
25543
  let clientInformation = await Promise.resolve(provider.clientInformation());
25521
25544
  if (!clientInformation) {
@@ -25543,6 +25566,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
25543
25566
  const fullInformation = await registerClient(authorizationServerUrl, {
25544
25567
  metadata,
25545
25568
  clientMetadata: provider.clientMetadata,
25569
+ scope: resolvedScope,
25546
25570
  fetchFn
25547
25571
  });
25548
25572
  await provider.saveClientInformation(fullInformation);
@@ -25594,7 +25618,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
25594
25618
  clientInformation,
25595
25619
  state,
25596
25620
  redirectUrl: provider.redirectUrl,
25597
- scope: scope || resourceMetadata?.scopes_supported?.join(' ') || provider.clientMetadata.scope,
25621
+ scope: resolvedScope,
25598
25622
  resource
25599
25623
  });
25600
25624
  await provider.saveCodeVerifier(codeVerifier);
@@ -26175,8 +26199,12 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
26175
26199
  }
26176
26200
  /**
26177
26201
  * Performs OAuth 2.0 Dynamic Client Registration according to RFC 7591.
26202
+ *
26203
+ * If `scope` is provided, it overrides `clientMetadata.scope` in the registration
26204
+ * request body. This allows callers to apply the Scope Selection Strategy (SEP-835)
26205
+ * consistently across both DCR and the subsequent authorization request.
26178
26206
  */
26179
- async function registerClient(authorizationServerUrl, { metadata, clientMetadata, fetchFn }) {
26207
+ async function registerClient(authorizationServerUrl, { metadata, clientMetadata, scope, fetchFn }) {
26180
26208
  let registrationUrl;
26181
26209
  if (metadata) {
26182
26210
  if (!metadata.registration_endpoint) {
@@ -26192,7 +26220,10 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
26192
26220
  headers: {
26193
26221
  'Content-Type': 'application/json'
26194
26222
  },
26195
- body: JSON.stringify(clientMetadata)
26223
+ body: JSON.stringify({
26224
+ ...clientMetadata,
26225
+ ...(scope !== undefined ? { scope } : {})
26226
+ })
26196
26227
  });
26197
26228
  if (!response.ok) {
26198
26229
  throw await parseErrorResponse(response);
@@ -26210,6 +26241,7 @@ class ParseError extends Error {
26210
26241
  super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;
26211
26242
  }
26212
26243
  }
26244
+ const LF = 10, CR = 13, SPACE = 32;
26213
26245
  function noop(_arg) {
26214
26246
  }
26215
26247
  function createParser(callbacks) {
@@ -26217,39 +26249,109 @@ function createParser(callbacks) {
26217
26249
  throw new TypeError(
26218
26250
  "`callbacks` must be an object, got a function instead. Did you mean `{onEvent: fn}`?"
26219
26251
  );
26220
- const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks;
26221
- let incompleteLine = "", isFirstChunk = !0, id, data = "", eventType = "";
26222
- function feed(newChunk) {
26223
- const chunk = isFirstChunk ? newChunk.replace(/^\xEF\xBB\xBF/, "") : newChunk, [complete, incomplete] = splitLines(`${incompleteLine}${chunk}`);
26224
- for (const line of complete)
26225
- parseLine(line);
26226
- incompleteLine = incomplete, isFirstChunk = !1;
26227
- }
26228
- function parseLine(line) {
26229
- if (line === "") {
26252
+ const { onEvent = noop, onError = noop, onRetry = noop, onComment } = callbacks, pendingFragments = [];
26253
+ let isFirstChunk = !0, id, data = "", dataLines = 0, eventType;
26254
+ function feed(chunk) {
26255
+ if (isFirstChunk && (isFirstChunk = !1, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {
26256
+ const trailing2 = processLines(chunk);
26257
+ trailing2 !== "" && pendingFragments.push(trailing2);
26258
+ return;
26259
+ }
26260
+ if (chunk.indexOf(`
26261
+ `) === -1 && chunk.indexOf("\r") === -1) {
26262
+ pendingFragments.push(chunk);
26263
+ return;
26264
+ }
26265
+ pendingFragments.push(chunk);
26266
+ const input = pendingFragments.join("");
26267
+ pendingFragments.length = 0;
26268
+ const trailing = processLines(input);
26269
+ trailing !== "" && pendingFragments.push(trailing);
26270
+ }
26271
+ function processLines(chunk) {
26272
+ let searchIndex = 0;
26273
+ if (chunk.indexOf("\r") === -1) {
26274
+ let lfIndex = chunk.indexOf(`
26275
+ `, searchIndex);
26276
+ for (; lfIndex !== -1; ) {
26277
+ if (searchIndex === lfIndex) {
26278
+ dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = "", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
26279
+ `, searchIndex);
26280
+ continue;
26281
+ }
26282
+ const firstCharCode = chunk.charCodeAt(searchIndex);
26283
+ if (isDataPrefix(chunk, searchIndex, firstCharCode)) {
26284
+ const valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex);
26285
+ if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {
26286
+ onEvent({ id, event: eventType, data: value }), id = void 0, data = "", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(`
26287
+ `, searchIndex);
26288
+ continue;
26289
+ }
26290
+ data = dataLines === 0 ? value : `${data}
26291
+ ${value}`, dataLines++;
26292
+ } else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(
26293
+ chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,
26294
+ lfIndex
26295
+ ) || void 0 : parseLine(chunk, searchIndex, lfIndex);
26296
+ searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
26297
+ `, searchIndex);
26298
+ }
26299
+ return chunk.slice(searchIndex);
26300
+ }
26301
+ for (; searchIndex < chunk.length; ) {
26302
+ const crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(`
26303
+ `, searchIndex);
26304
+ let lineEnd = -1;
26305
+ if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = crIndex < lfIndex ? crIndex : lfIndex : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1)
26306
+ break;
26307
+ parseLine(chunk, searchIndex, lineEnd), searchIndex = lineEnd + 1, chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF && searchIndex++;
26308
+ }
26309
+ return chunk.slice(searchIndex);
26310
+ }
26311
+ function parseLine(chunk, start, end) {
26312
+ if (start === end) {
26230
26313
  dispatchEvent();
26231
26314
  return;
26232
26315
  }
26233
- if (line.startsWith(":")) {
26234
- onComment && onComment(line.slice(line.startsWith(": ") ? 2 : 1));
26316
+ const firstCharCode = chunk.charCodeAt(start);
26317
+ if (isDataPrefix(chunk, start, firstCharCode)) {
26318
+ const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end);
26319
+ data = dataLines === 0 ? value2 : `${data}
26320
+ ${value2}`, dataLines++;
26235
26321
  return;
26236
26322
  }
26237
- const fieldSeparatorIndex = line.indexOf(":");
26238
- if (fieldSeparatorIndex !== -1) {
26239
- const field = line.slice(0, fieldSeparatorIndex), offset = line[fieldSeparatorIndex + 1] === " " ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);
26240
- processField(field, value, line);
26323
+ if (isEventPrefix(chunk, start, firstCharCode)) {
26324
+ eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0;
26241
26325
  return;
26242
26326
  }
26243
- processField(line, "", line);
26327
+ if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) {
26328
+ const value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end);
26329
+ id = value2.includes("\0") ? void 0 : value2;
26330
+ return;
26331
+ }
26332
+ if (firstCharCode === 58) {
26333
+ if (onComment) {
26334
+ const line2 = chunk.slice(start, end);
26335
+ onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1));
26336
+ }
26337
+ return;
26338
+ }
26339
+ const line = chunk.slice(start, end), fieldSeparatorIndex = line.indexOf(":");
26340
+ if (fieldSeparatorIndex === -1) {
26341
+ processField(line, "", line);
26342
+ return;
26343
+ }
26344
+ const field = line.slice(0, fieldSeparatorIndex), offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);
26345
+ processField(field, value, line);
26244
26346
  }
26245
26347
  function processField(field, value, line) {
26246
26348
  switch (field) {
26247
26349
  case "event":
26248
- eventType = value;
26350
+ eventType = value || void 0;
26249
26351
  break;
26250
26352
  case "data":
26251
- data = `${data}${value}
26252
- `;
26353
+ data = dataLines === 0 ? value : `${data}
26354
+ ${value}`, dataLines++;
26253
26355
  break;
26254
26356
  case "id":
26255
26357
  id = value.includes("\0") ? void 0 : value;
@@ -26274,37 +26376,26 @@ function createParser(callbacks) {
26274
26376
  }
26275
26377
  }
26276
26378
  function dispatchEvent() {
26277
- data.length > 0 && onEvent({
26379
+ dataLines > 0 && onEvent({
26278
26380
  id,
26279
- event: eventType || void 0,
26280
- // If the data buffer's last character is a U+000A LINE FEED (LF) character,
26281
- // then remove the last character from the data buffer.
26282
- data: data.endsWith(`
26283
- `) ? data.slice(0, -1) : data
26284
- }), id = void 0, data = "", eventType = "";
26381
+ event: eventType,
26382
+ data
26383
+ }), id = void 0, data = "", dataLines = 0, eventType = void 0;
26285
26384
  }
26286
26385
  function reset(options = {}) {
26287
- incompleteLine && options.consume && parseLine(incompleteLine), isFirstChunk = !0, id = void 0, data = "", eventType = "", incompleteLine = "";
26386
+ if (options.consume && pendingFragments.length > 0) {
26387
+ const incompleteLine = pendingFragments.join("");
26388
+ parseLine(incompleteLine, 0, incompleteLine.length);
26389
+ }
26390
+ isFirstChunk = !0, id = void 0, data = "", dataLines = 0, eventType = void 0, pendingFragments.length = 0;
26288
26391
  }
26289
26392
  return { feed, reset };
26290
26393
  }
26291
- function splitLines(chunk) {
26292
- const lines = [];
26293
- let incompleteLine = "", searchIndex = 0;
26294
- for (; searchIndex < chunk.length; ) {
26295
- const crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(`
26296
- `, searchIndex);
26297
- let lineEnd = -1;
26298
- if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = Math.min(crIndex, lfIndex) : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1) {
26299
- incompleteLine = chunk.slice(searchIndex);
26300
- break;
26301
- } else {
26302
- const line = chunk.slice(searchIndex, lineEnd);
26303
- lines.push(line), searchIndex = lineEnd + 1, chunk[searchIndex - 1] === "\r" && chunk[searchIndex] === `
26304
- ` && searchIndex++;
26305
- }
26306
- }
26307
- return [lines, incompleteLine];
26394
+ function isDataPrefix(chunk, i, firstCharCode) {
26395
+ return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58;
26396
+ }
26397
+ function isEventPrefix(chunk, i, firstCharCode) {
26398
+ return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58;
26308
26399
  }
26309
26400
  dist$2.ParseError = ParseError;
26310
26401
  dist$2.createParser = createParser;
@@ -36579,6 +36670,10 @@ function parseWithCompat(schema, data) {
36579
36670
  this._progressHandlers.clear();
36580
36671
  this._taskProgressTokens.clear();
36581
36672
  this._pendingDebouncedNotifications.clear();
36673
+ for (const info of this._timeoutInfo.values()) {
36674
+ clearTimeout(info.timeoutId);
36675
+ }
36676
+ this._timeoutInfo.clear();
36582
36677
  // Abort all in-flight request handlers so they stop sending messages
36583
36678
  for (const controller of this._requestHandlerAbortControllers.values()) {
36584
36679
  controller.abort();
@@ -36738,7 +36833,11 @@ function parseWithCompat(schema, data) {
36738
36833
  })
36739
36834
  .catch(error => this._onerror(new Error(`Failed to send response: ${error}`)))
36740
36835
  .finally(() => {
36741
- this._requestHandlerAbortControllers.delete(request.id);
36836
+ // Only delete if the stored controller is still ours; after close()+connect(),
36837
+ // a new connection may have reused the same request ID with a different controller.
36838
+ if (this._requestHandlerAbortControllers.get(request.id) === abortController) {
36839
+ this._requestHandlerAbortControllers.delete(request.id);
36840
+ }
36742
36841
  });
36743
36842
  }
36744
36843
  _onprogress(notification) {
@@ -40686,6 +40785,15 @@ const isUUID$1 = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[
40686
40785
  /** @type {(value: string) => boolean} */
40687
40786
  const isIPv4$1 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
40688
40787
 
40788
+ /** @type {(value: string) => boolean} */
40789
+ const isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
40790
+
40791
+ /** @type {(value: string) => boolean} */
40792
+ const isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
40793
+
40794
+ /** @type {(value: string) => boolean} */
40795
+ const isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
40796
+
40689
40797
  /**
40690
40798
  * @param {Array<string>} input
40691
40799
  * @returns {string}
@@ -40944,31 +41052,126 @@ function removeDotSegments$1 (path) {
40944
41052
  }
40945
41053
 
40946
41054
  /**
40947
- * @param {import('../types/index').URIComponent} component
40948
- * @param {boolean} esc
40949
- * @returns {import('../types/index').URIComponent}
41055
+ * Re-escape RFC 3986 gen-delims that must not appear literally in the host.
41056
+ * After the URI regex parses, these characters cannot be literal in the host
41057
+ * field, so any that appear after decoding came from percent-encoding and
41058
+ * must be restored to prevent authority structure changes.
41059
+ *
41060
+ * @param {string} host
41061
+ * @param {boolean} isIP - true for IPv4/IPv6 hosts (skip colon re-escaping)
41062
+ * @returns {string}
40950
41063
  */
40951
- function normalizeComponentEncoding$1 (component, esc) {
40952
- const func = esc !== true ? escape : unescape;
40953
- if (component.scheme !== undefined) {
40954
- component.scheme = func(component.scheme);
40955
- }
40956
- if (component.userinfo !== undefined) {
40957
- component.userinfo = func(component.userinfo);
40958
- }
40959
- if (component.host !== undefined) {
40960
- component.host = func(component.host);
41064
+ const HOST_DELIMS = { '@': '%40', '/': '%2F', '?': '%3F', '#': '%23', ':': '%3A' };
41065
+ const HOST_DELIM_RE = /[@/?#:]/g;
41066
+ const HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
41067
+
41068
+ function reescapeHostDelimiters$1 (host, isIP) {
41069
+ const re = isIP ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
41070
+ re.lastIndex = 0;
41071
+ return host.replace(re, (ch) => HOST_DELIMS[ch])
41072
+ }
41073
+
41074
+ /**
41075
+ * Normalizes percent escapes and optionally decodes only unreserved ASCII bytes.
41076
+ * Reserved delimiters such as `%2F` and `%2E` stay escaped.
41077
+ *
41078
+ * @param {string} input
41079
+ * @param {boolean} [decodeUnreserved=false]
41080
+ * @returns {string}
41081
+ */
41082
+ function normalizePercentEncoding$1 (input, decodeUnreserved = false) {
41083
+ if (input.indexOf('%') === -1) {
41084
+ return input
40961
41085
  }
40962
- if (component.path !== undefined) {
40963
- component.path = func(component.path);
41086
+
41087
+ let output = '';
41088
+
41089
+ for (let i = 0; i < input.length; i++) {
41090
+ if (input[i] === '%' && i + 2 < input.length) {
41091
+ const hex = input.slice(i + 1, i + 3);
41092
+ if (isHexPair(hex)) {
41093
+ const normalizedHex = hex.toUpperCase();
41094
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
41095
+
41096
+ if (decodeUnreserved && isUnreserved(decoded)) {
41097
+ output += decoded;
41098
+ } else {
41099
+ output += '%' + normalizedHex;
41100
+ }
41101
+
41102
+ i += 2;
41103
+ continue
41104
+ }
41105
+ }
41106
+
41107
+ output += input[i];
40964
41108
  }
40965
- if (component.query !== undefined) {
40966
- component.query = func(component.query);
41109
+
41110
+ return output
41111
+ }
41112
+
41113
+ /**
41114
+ * Normalizes path data without turning reserved escapes into live path syntax.
41115
+ * Valid escapes are uppercased, raw unsafe characters are escaped, and only
41116
+ * unreserved bytes that are not `.` are decoded.
41117
+ *
41118
+ * @param {string} input
41119
+ * @returns {string}
41120
+ */
41121
+ function normalizePathEncoding$1 (input) {
41122
+ let output = '';
41123
+
41124
+ for (let i = 0; i < input.length; i++) {
41125
+ if (input[i] === '%' && i + 2 < input.length) {
41126
+ const hex = input.slice(i + 1, i + 3);
41127
+ if (isHexPair(hex)) {
41128
+ const normalizedHex = hex.toUpperCase();
41129
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
41130
+
41131
+ if (decoded !== '.' && isUnreserved(decoded)) {
41132
+ output += decoded;
41133
+ } else {
41134
+ output += '%' + normalizedHex;
41135
+ }
41136
+
41137
+ i += 2;
41138
+ continue
41139
+ }
41140
+ }
41141
+
41142
+ if (isPathCharacter(input[i])) {
41143
+ output += input[i];
41144
+ } else {
41145
+ output += escape(input[i]);
41146
+ }
40967
41147
  }
40968
- if (component.fragment !== undefined) {
40969
- component.fragment = func(component.fragment);
41148
+
41149
+ return output
41150
+ }
41151
+
41152
+ /**
41153
+ * Escapes a component while preserving existing valid percent escapes.
41154
+ *
41155
+ * @param {string} input
41156
+ * @returns {string}
41157
+ */
41158
+ function escapePreservingEscapes$1 (input) {
41159
+ let output = '';
41160
+
41161
+ for (let i = 0; i < input.length; i++) {
41162
+ if (input[i] === '%' && i + 2 < input.length) {
41163
+ const hex = input.slice(i + 1, i + 3);
41164
+ if (isHexPair(hex)) {
41165
+ output += '%' + hex.toUpperCase();
41166
+ i += 2;
41167
+ continue
41168
+ }
41169
+ }
41170
+
41171
+ output += escape(input[i]);
40970
41172
  }
40971
- return component
41173
+
41174
+ return output
40972
41175
  }
40973
41176
 
40974
41177
  /**
@@ -40990,7 +41193,7 @@ function recomposeAuthority$1 (component) {
40990
41193
  if (ipV6res.isIPV6 === true) {
40991
41194
  host = `[${ipV6res.escapedHost}]`;
40992
41195
  } else {
40993
- host = component.host;
41196
+ host = reescapeHostDelimiters$1(host, false);
40994
41197
  }
40995
41198
  }
40996
41199
  uriTokens.push(host);
@@ -41006,7 +41209,10 @@ function recomposeAuthority$1 (component) {
41006
41209
  var utils = {
41007
41210
  nonSimpleDomain: nonSimpleDomain$1,
41008
41211
  recomposeAuthority: recomposeAuthority$1,
41009
- normalizeComponentEncoding: normalizeComponentEncoding$1,
41212
+ reescapeHostDelimiters: reescapeHostDelimiters$1,
41213
+ normalizePercentEncoding: normalizePercentEncoding$1,
41214
+ normalizePathEncoding: normalizePathEncoding$1,
41215
+ escapePreservingEscapes: escapePreservingEscapes$1,
41010
41216
  removeDotSegments: removeDotSegments$1,
41011
41217
  isIPv4: isIPv4$1,
41012
41218
  isUUID: isUUID$1,
@@ -41280,7 +41486,7 @@ var schemes = {
41280
41486
  getSchemeHandler: getSchemeHandler$1,
41281
41487
  };
41282
41488
 
41283
- const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = utils;
41489
+ const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = utils;
41284
41490
  const { SCHEMES, getSchemeHandler } = schemes;
41285
41491
 
41286
41492
  /**
@@ -41291,7 +41497,7 @@ const { SCHEMES, getSchemeHandler } = schemes;
41291
41497
  */
41292
41498
  function normalize (uri, options) {
41293
41499
  if (typeof uri === 'string') {
41294
- uri = /** @type {T} */ (serialize(parse(uri, options), options));
41500
+ uri = /** @type {T} */ (normalizeString(uri, options));
41295
41501
  } else if (typeof uri === 'object') {
41296
41502
  uri = /** @type {T} */ (parse(serialize(uri, options), options));
41297
41503
  }
@@ -41386,21 +41592,10 @@ function resolveComponent (base, relative, options, skipNormalization) {
41386
41592
  * @returns {boolean}
41387
41593
  */
41388
41594
  function equal$2 (uriA, uriB, options) {
41389
- if (typeof uriA === 'string') {
41390
- uriA = unescape(uriA);
41391
- uriA = serialize(normalizeComponentEncoding(parse(uriA, options), true), { ...options, skipEscape: true });
41392
- } else if (typeof uriA === 'object') {
41393
- uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
41394
- }
41395
-
41396
- if (typeof uriB === 'string') {
41397
- uriB = unescape(uriB);
41398
- uriB = serialize(normalizeComponentEncoding(parse(uriB, options), true), { ...options, skipEscape: true });
41399
- } else if (typeof uriB === 'object') {
41400
- uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
41401
- }
41595
+ const normalizedA = normalizeComparableURI(uriA, options);
41596
+ const normalizedB = normalizeComparableURI(uriB, options);
41402
41597
 
41403
- return uriA.toLowerCase() === uriB.toLowerCase()
41598
+ return normalizedA !== undefined && normalizedB !== undefined && normalizedA.toLowerCase() === normalizedB.toLowerCase()
41404
41599
  }
41405
41600
 
41406
41601
  /**
@@ -41436,13 +41631,13 @@ function serialize (cmpts, opts) {
41436
41631
 
41437
41632
  if (component.path !== undefined) {
41438
41633
  if (!options.skipEscape) {
41439
- component.path = escape(component.path);
41634
+ component.path = escapePreservingEscapes(component.path);
41440
41635
 
41441
41636
  if (component.scheme !== undefined) {
41442
41637
  component.path = component.path.split('%3A').join(':');
41443
41638
  }
41444
41639
  } else {
41445
- component.path = unescape(component.path);
41640
+ component.path = normalizePercentEncoding(component.path);
41446
41641
  }
41447
41642
  }
41448
41643
 
@@ -41493,12 +41688,29 @@ function serialize (cmpts, opts) {
41493
41688
 
41494
41689
  const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
41495
41690
 
41691
+ /**
41692
+ * @param {import('./types/index').URIComponent} parsed
41693
+ * @param {RegExpMatchArray} matches
41694
+ * @returns {string|undefined}
41695
+ */
41696
+ function getParseError (parsed, matches) {
41697
+ if (matches[2] !== undefined && parsed.path && parsed.path[0] !== '/') {
41698
+ return 'URI path must start with "/" when authority is present.'
41699
+ }
41700
+
41701
+ if (typeof parsed.port === 'number' && (parsed.port < 0 || parsed.port > 65535)) {
41702
+ return 'URI port is malformed.'
41703
+ }
41704
+
41705
+ return undefined
41706
+ }
41707
+
41496
41708
  /**
41497
41709
  * @param {string} uri
41498
41710
  * @param {import('./types/index').Options} [opts]
41499
- * @returns
41711
+ * @returns {{ parsed: import('./types/index').URIComponent, malformedAuthorityOrPort: boolean }}
41500
41712
  */
41501
- function parse (uri, opts) {
41713
+ function parseWithStatus (uri, opts) {
41502
41714
  const options = Object.assign({}, opts);
41503
41715
  /** @type {import('./types/index').URIComponent} */
41504
41716
  const parsed = {
@@ -41511,6 +41723,8 @@ function parse (uri, opts) {
41511
41723
  fragment: undefined
41512
41724
  };
41513
41725
 
41726
+ let malformedAuthorityOrPort = false;
41727
+
41514
41728
  let isIP = false;
41515
41729
  if (options.reference === 'suffix') {
41516
41730
  if (options.scheme) {
@@ -41536,6 +41750,13 @@ function parse (uri, opts) {
41536
41750
  if (isNaN(parsed.port)) {
41537
41751
  parsed.port = matches[5];
41538
41752
  }
41753
+
41754
+ const parseError = getParseError(parsed, matches);
41755
+ if (parseError !== undefined) {
41756
+ parsed.error = parsed.error || parseError;
41757
+ malformedAuthorityOrPort = true;
41758
+ }
41759
+
41539
41760
  if (parsed.host) {
41540
41761
  const ipv4result = isIPv4(parsed.host);
41541
41762
  if (ipv4result === false) {
@@ -41584,14 +41805,18 @@ function parse (uri, opts) {
41584
41805
  parsed.scheme = unescape(parsed.scheme);
41585
41806
  }
41586
41807
  if (parsed.host !== undefined) {
41587
- parsed.host = unescape(parsed.host);
41808
+ parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
41588
41809
  }
41589
41810
  }
41590
41811
  if (parsed.path) {
41591
- parsed.path = escape(unescape(parsed.path));
41812
+ parsed.path = normalizePathEncoding(parsed.path);
41592
41813
  }
41593
41814
  if (parsed.fragment) {
41594
- parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
41815
+ try {
41816
+ parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
41817
+ } catch {
41818
+ parsed.error = parsed.error || 'URI malformed';
41819
+ }
41595
41820
  }
41596
41821
  }
41597
41822
 
@@ -41602,7 +41827,54 @@ function parse (uri, opts) {
41602
41827
  } else {
41603
41828
  parsed.error = parsed.error || 'URI can not be parsed.';
41604
41829
  }
41605
- return parsed
41830
+ return { parsed, malformedAuthorityOrPort }
41831
+ }
41832
+
41833
+ /**
41834
+ * @param {string} uri
41835
+ * @param {import('./types/index').Options} [opts]
41836
+ * @returns
41837
+ */
41838
+ function parse (uri, opts) {
41839
+ return parseWithStatus(uri, opts).parsed
41840
+ }
41841
+
41842
+ /**
41843
+ * @param {string} uri
41844
+ * @param {import('./types/index').Options} [opts]
41845
+ * @returns {string}
41846
+ */
41847
+ function normalizeString (uri, opts) {
41848
+ return normalizeStringWithStatus(uri, opts).normalized
41849
+ }
41850
+
41851
+ /**
41852
+ * @param {string} uri
41853
+ * @param {import('./types/index').Options} [opts]
41854
+ * @returns {{ normalized: string, malformedAuthorityOrPort: boolean }}
41855
+ */
41856
+ function normalizeStringWithStatus (uri, opts) {
41857
+ const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
41858
+ return {
41859
+ normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
41860
+ malformedAuthorityOrPort
41861
+ }
41862
+ }
41863
+
41864
+ /**
41865
+ * @param {import ('./types/index').URIComponent|string} uri
41866
+ * @param {import('./types/index').Options} [opts]
41867
+ * @returns {string|undefined}
41868
+ */
41869
+ function normalizeComparableURI (uri, opts) {
41870
+ if (typeof uri === 'string') {
41871
+ const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
41872
+ return malformedAuthorityOrPort ? undefined : normalized
41873
+ }
41874
+
41875
+ if (typeof uri === 'object') {
41876
+ return serialize(uri, opts)
41877
+ }
41606
41878
  }
41607
41879
 
41608
41880
  const fastUri = {
@@ -41722,7 +41994,7 @@ uri$1.default = uri;
41722
41994
  constructor(opts = {}) {
41723
41995
  this.schemas = {};
41724
41996
  this.refs = {};
41725
- this.formats = {};
41997
+ this.formats = Object.create(null);
41726
41998
  this._compilations = new Set();
41727
41999
  this._loading = {};
41728
42000
  this._cache = new Map();
@@ -46552,9 +46824,10 @@ let McpServer$1 = class McpServer {
46552
46824
  }
46553
46825
  }
46554
46826
  else if (typeof firstArg === 'object' && firstArg !== null) {
46555
- // Not a ZodRawShapeCompat, so must be annotations in this position
46556
- // Case: tool(name, annotations, cb)
46557
- // Or: tool(name, description, annotations, cb)
46827
+ // ToolAnnotations values are primitives. Nested objects indicate a misplaced schema
46828
+ if (Object.values(firstArg).some(v => typeof v === 'object' && v !== null)) {
46829
+ throw new Error(`Tool ${name} expected a Zod schema or ToolAnnotations, but received an unrecognized object`);
46830
+ }
46558
46831
  annotations = rest.shift();
46559
46832
  }
46560
46833
  }
@@ -46726,7 +46999,7 @@ function isZodRawShapeCompat(obj) {
46726
46999
  }
46727
47000
  /**
46728
47001
  * Converts a provided Zod schema to a Zod object if it is a ZodRawShapeCompat,
46729
- * otherwise returns the schema as is.
47002
+ * otherwise returns the schema as is. Throws if the value is not a valid Zod schema.
46730
47003
  */
46731
47004
  function getZodSchemaObject(schema) {
46732
47005
  if (!schema) {
@@ -46735,6 +47008,9 @@ function getZodSchemaObject(schema) {
46735
47008
  if (isZodRawShapeCompat(schema)) {
46736
47009
  return (0, zod_compat_js_1.objectFromShape)(schema);
46737
47010
  }
47011
+ if (!isZodSchemaInstance(schema)) {
47012
+ throw new Error('inputSchema must be a Zod schema or raw shape, received an unrecognized object');
47013
+ }
46738
47014
  return schema;
46739
47015
  }
46740
47016
  function promptArgumentsFromSchema(schema) {