apple-numbers-mcp 1.2.1 → 1.2.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/build/index.js CHANGED
@@ -3104,15 +3104,33 @@ var require_data = __commonJS({
3104
3104
  }
3105
3105
  });
3106
3106
 
3107
- // node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/utils.js
3107
+ // node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/lib/utils.js
3108
3108
  var require_utils = __commonJS({
3109
- "node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/utils.js"(exports, module) {
3109
+ "node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/lib/utils.js"(exports, module) {
3110
3110
  "use strict";
3111
3111
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3112
3112
  var isIPv4 = 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);
3113
3113
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
3114
3114
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
3115
- var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
3115
+ var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
3116
+ var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
3117
+ var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
3118
+ var BYTE_HEX = new Array(256);
3119
+ {
3120
+ const HEX_DIGITS = "0123456789ABCDEF";
3121
+ for (let i = 0; i < 256; i++) {
3122
+ BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
3123
+ }
3124
+ }
3125
+ function percentEncodeNonAscii(cp) {
3126
+ if (cp < 2048) {
3127
+ return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
3128
+ }
3129
+ if (cp < 65536) {
3130
+ return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
3131
+ }
3132
+ return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
3133
+ }
3116
3134
  function stringArrayToHexStripped(input) {
3117
3135
  let acc = "";
3118
3136
  let code = 0;
@@ -3137,91 +3155,105 @@ var require_utils = __commonJS({
3137
3155
  }
3138
3156
  return acc;
3139
3157
  }
3158
+ var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
3159
+ var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
3160
+ var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
3140
3161
  var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
3141
- function consumeIsZone(buffer) {
3142
- buffer.length = 0;
3143
- return true;
3144
- }
3145
- function consumeHextets(buffer, address, output) {
3146
- if (buffer.length) {
3147
- const hex = stringArrayToHexStripped(buffer);
3148
- if (hex !== "") {
3149
- address.push(hex);
3150
- } else {
3151
- output.error = true;
3152
- return false;
3162
+ function isZoneIdentifier(zone) {
3163
+ if (zone.length === 0) return false;
3164
+ for (let i = 0; i < zone.length; i++) {
3165
+ if (isZoneCharacter(zone[i])) continue;
3166
+ if (zone[i] === "%" && i + 2 < zone.length && isHexPair(zone.slice(i + 1, i + 3))) {
3167
+ i += 2;
3168
+ continue;
3153
3169
  }
3154
- buffer.length = 0;
3170
+ return false;
3155
3171
  }
3156
3172
  return true;
3157
3173
  }
3158
- function getIPV6(input) {
3159
- let tokenCount = 0;
3160
- const output = { error: false, address: "", zone: "" };
3161
- const address = [];
3162
- const buffer = [];
3163
- let endipv6Encountered = false;
3164
- let endIpv6 = false;
3165
- let consume = consumeHextets;
3166
- for (let i = 0; i < input.length; i++) {
3167
- const cursor = input[i];
3168
- if (cursor === "[" || cursor === "]") {
3169
- continue;
3170
- }
3171
- if (cursor === ":") {
3172
- if (endipv6Encountered === true) {
3173
- endIpv6 = true;
3174
- }
3175
- if (!consume(buffer, address, output)) {
3176
- break;
3177
- }
3178
- if (++tokenCount > 7) {
3179
- output.error = true;
3180
- break;
3181
- }
3182
- if (i > 0 && input[i - 1] === ":") {
3183
- endipv6Encountered = true;
3184
- }
3185
- address.push(":");
3186
- continue;
3187
- } else if (cursor === "%") {
3188
- if (!consume(buffer, address, output)) {
3189
- break;
3174
+ function compressIPv6ZeroRun(hextets) {
3175
+ let bestStart = -1;
3176
+ let bestLength = 0;
3177
+ let runStart = -1;
3178
+ let runLength = 0;
3179
+ for (let i = 0; i < hextets.length; i++) {
3180
+ if (hextets[i] === "0") {
3181
+ if (runStart === -1) runStart = i;
3182
+ runLength++;
3183
+ if (runLength > bestLength) {
3184
+ bestLength = runLength;
3185
+ bestStart = runStart;
3190
3186
  }
3191
- consume = consumeIsZone;
3192
3187
  } else {
3193
- buffer.push(cursor);
3188
+ runStart = -1;
3189
+ runLength = 0;
3190
+ }
3191
+ }
3192
+ if (bestLength < 2) return hextets.join(":");
3193
+ const head = hextets.slice(0, bestStart).join(":");
3194
+ const tail = hextets.slice(bestStart + bestLength).join(":");
3195
+ return head + "::" + tail;
3196
+ }
3197
+ function normalizeIPv6Address(input) {
3198
+ const compression = input.indexOf("::");
3199
+ if (compression !== -1 && input.indexOf("::", compression + 1) !== -1) return void 0;
3200
+ const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
3201
+ const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
3202
+ if (compression !== -1) {
3203
+ if (left.length === 1 && left[0] === "") left.length = 0;
3204
+ if (right.length === 1 && right[0] === "") right.length = 0;
3205
+ }
3206
+ const parts = left.concat(right);
3207
+ let hextetCount = 0;
3208
+ for (let i = 0; i < parts.length; i++) {
3209
+ const part = parts[i];
3210
+ if (part === "") return void 0;
3211
+ if (part.indexOf(".") !== -1) {
3212
+ if (i !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part)) return void 0;
3213
+ hextetCount += 2;
3194
3214
  continue;
3195
3215
  }
3216
+ if (!isHextet(part)) return void 0;
3217
+ parts[i] = parseInt(part, 16).toString(16);
3218
+ hextetCount++;
3196
3219
  }
3197
- if (buffer.length) {
3198
- if (consume === consumeIsZone) {
3199
- output.zone = buffer.join("");
3200
- } else if (endIpv6) {
3201
- address.push(buffer.join(""));
3202
- } else {
3203
- address.push(stringArrayToHexStripped(buffer));
3204
- }
3220
+ if (compression === -1) {
3221
+ if (hextetCount !== 8) return void 0;
3222
+ return compressIPv6ZeroRun(parts);
3205
3223
  }
3206
- output.address = address.join("");
3207
- return output;
3224
+ if (hextetCount >= 8) return void 0;
3225
+ const expanded = parts.slice(0, left.length);
3226
+ for (let i = hextetCount; i < 8; i++) expanded.push("0");
3227
+ for (let i = left.length; i < parts.length; i++) expanded.push(parts[i]);
3228
+ return compressIPv6ZeroRun(expanded);
3208
3229
  }
3209
3230
  function normalizeIPv6(host) {
3210
- if (findToken(host, ":") < 2) {
3211
- return { host, isIPV6: false };
3212
- }
3213
- const ipv62 = getIPV6(host);
3214
- if (!ipv62.error) {
3215
- let newHost = ipv62.address;
3216
- let escapedHost = ipv62.address;
3217
- if (ipv62.zone) {
3218
- newHost += "%" + ipv62.zone;
3219
- escapedHost += "%25" + ipv62.zone;
3220
- }
3221
- return { host: newHost, isIPV6: true, escapedHost };
3222
- } else {
3223
- return { host, isIPV6: false };
3224
- }
3231
+ const bracketed = host[0] === "[" && host[host.length - 1] === "]";
3232
+ const hasBracket = host[0] === "[" || host[host.length - 1] === "]";
3233
+ if (hasBracket && !bracketed) return { host, isIPV6: false, error: true };
3234
+ let input = bracketed ? host.slice(1, -1) : host;
3235
+ if (bracketed && isIPvFuture(input)) {
3236
+ input = input.toLowerCase();
3237
+ return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
3238
+ }
3239
+ if (findToken(input, ":") < 2) {
3240
+ return { host, isIPV6: false, error: bracketed };
3241
+ }
3242
+ let zoneIdentifier = "";
3243
+ const zoneSeparator = input.indexOf("%");
3244
+ if (zoneSeparator !== -1) {
3245
+ const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
3246
+ zoneIdentifier = input.slice(zoneSeparator + separatorLength);
3247
+ if (!isZoneIdentifier(zoneIdentifier)) return { host, isIPV6: false, error: true };
3248
+ input = input.slice(0, zoneSeparator);
3249
+ }
3250
+ const address = normalizeIPv6Address(input);
3251
+ if (address === void 0) return { host, isIPV6: false, error: true };
3252
+ return {
3253
+ host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
3254
+ escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
3255
+ isIPV6: true
3256
+ };
3225
3257
  }
3226
3258
  function findToken(str, token) {
3227
3259
  let ind = 0;
@@ -3340,7 +3372,8 @@ var require_utils = __commonJS({
3340
3372
  function normalizePathEncoding(input) {
3341
3373
  let output = "";
3342
3374
  for (let i = 0; i < input.length; i++) {
3343
- if (input[i] === "%" && i + 2 < input.length) {
3375
+ const ch = input[i];
3376
+ if (ch === "%" && i + 2 < input.length) {
3344
3377
  const hex = input.slice(i + 1, i + 3);
3345
3378
  if (isHexPair(hex)) {
3346
3379
  const normalizedHex = hex.toUpperCase();
@@ -3354,10 +3387,152 @@ var require_utils = __commonJS({
3354
3387
  continue;
3355
3388
  }
3356
3389
  }
3357
- if (isPathCharacter(input[i])) {
3358
- output += input[i];
3390
+ if (isPathCharacter(ch)) {
3391
+ output += ch;
3359
3392
  } else {
3360
- output += escape(input[i]);
3393
+ const code = input.charCodeAt(i);
3394
+ if (code < 128) {
3395
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
3396
+ } else if (code < 55296 || code > 57343) {
3397
+ output += percentEncodeNonAscii(code);
3398
+ } else if (code <= 56319 && i + 1 < input.length) {
3399
+ const low = input.charCodeAt(i + 1);
3400
+ if (low >= 56320 && low <= 57343) {
3401
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
3402
+ i++;
3403
+ } else {
3404
+ output += percentEncodeNonAscii(65533);
3405
+ }
3406
+ } else {
3407
+ output += percentEncodeNonAscii(65533);
3408
+ }
3409
+ }
3410
+ }
3411
+ return output;
3412
+ }
3413
+ function serializePathEncoding(input, pathNoScheme = false) {
3414
+ let output = "";
3415
+ let firstSegment = pathNoScheme && input[0] !== "/";
3416
+ for (let i = 0; i < input.length; i++) {
3417
+ const ch = input[i];
3418
+ if (ch === "%" && i + 2 < input.length) {
3419
+ const hex = input.slice(i + 1, i + 3);
3420
+ if (isHexPair(hex)) {
3421
+ output += "%" + hex.toUpperCase();
3422
+ i += 2;
3423
+ continue;
3424
+ }
3425
+ }
3426
+ if (ch === "/") {
3427
+ firstSegment = false;
3428
+ }
3429
+ if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) {
3430
+ output += ch;
3431
+ } else {
3432
+ const code = input.charCodeAt(i);
3433
+ if (code < 128) {
3434
+ output += BYTE_HEX[code];
3435
+ } else if (code < 55296 || code > 57343) {
3436
+ output += percentEncodeNonAscii(code);
3437
+ } else if (code <= 56319 && i + 1 < input.length) {
3438
+ const low = input.charCodeAt(i + 1);
3439
+ if (low >= 56320 && low <= 57343) {
3440
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
3441
+ i++;
3442
+ } else {
3443
+ output += percentEncodeNonAscii(65533);
3444
+ }
3445
+ } else {
3446
+ output += percentEncodeNonAscii(65533);
3447
+ }
3448
+ }
3449
+ }
3450
+ return output;
3451
+ }
3452
+ function encodeComponent(input, isAllowed) {
3453
+ let output = "";
3454
+ for (let i = 0; i < input.length; i++) {
3455
+ const ch = input[i];
3456
+ if (ch === "%" && i + 2 < input.length) {
3457
+ const hex = input.slice(i + 1, i + 3);
3458
+ if (isHexPair(hex)) {
3459
+ output += "%" + hex.toUpperCase();
3460
+ i += 2;
3461
+ continue;
3462
+ }
3463
+ }
3464
+ if (isAllowed(ch)) {
3465
+ output += ch;
3466
+ } else {
3467
+ const code = input.charCodeAt(i);
3468
+ if (code < 128) {
3469
+ output += BYTE_HEX[code];
3470
+ } else if (code < 55296 || code > 57343) {
3471
+ output += percentEncodeNonAscii(code);
3472
+ } else if (code <= 56319 && i + 1 < input.length) {
3473
+ const low = input.charCodeAt(i + 1);
3474
+ if (low >= 56320 && low <= 57343) {
3475
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
3476
+ i++;
3477
+ } else {
3478
+ output += percentEncodeNonAscii(65533);
3479
+ }
3480
+ } else {
3481
+ output += percentEncodeNonAscii(65533);
3482
+ }
3483
+ }
3484
+ }
3485
+ return output;
3486
+ }
3487
+ function encodeUserinfo(input) {
3488
+ return encodeComponent(input, isUserinfoCharacter);
3489
+ }
3490
+ function encodeQuery(input) {
3491
+ return encodeComponent(input, isQueryFragmentCharacter);
3492
+ }
3493
+ function encodeFragment(input) {
3494
+ return encodeComponent(input, isQueryFragmentCharacter);
3495
+ }
3496
+ function isEscapeSafe(cp) {
3497
+ return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
3498
+ }
3499
+ function normalizeQueryFragmentEncoding(input) {
3500
+ let output = "";
3501
+ for (let i = 0; i < input.length; i++) {
3502
+ const ch = input[i];
3503
+ if (ch === "%" && i + 2 < input.length) {
3504
+ const hex = input.slice(i + 1, i + 3);
3505
+ if (isHexPair(hex)) {
3506
+ const normalizedHex = hex.toUpperCase();
3507
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
3508
+ if (isUnreserved(decoded)) {
3509
+ output += decoded;
3510
+ } else {
3511
+ output += "%" + normalizedHex;
3512
+ }
3513
+ i += 2;
3514
+ continue;
3515
+ }
3516
+ }
3517
+ if (isQueryFragmentCharacter(ch)) {
3518
+ output += ch;
3519
+ } else {
3520
+ const code = input.charCodeAt(i);
3521
+ if (code < 128) {
3522
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
3523
+ } else if (code < 55296 || code > 57343) {
3524
+ output += percentEncodeNonAscii(code);
3525
+ } else if (code <= 56319 && i + 1 < input.length) {
3526
+ const low = input.charCodeAt(i + 1);
3527
+ if (low >= 56320 && low <= 57343) {
3528
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
3529
+ i++;
3530
+ } else {
3531
+ output += percentEncodeNonAscii(65533);
3532
+ }
3533
+ } else {
3534
+ output += percentEncodeNonAscii(65533);
3535
+ }
3361
3536
  }
3362
3537
  }
3363
3538
  return output;
@@ -3380,14 +3555,18 @@ var require_utils = __commonJS({
3380
3555
  function recomposeAuthority(component) {
3381
3556
  const uriTokens = [];
3382
3557
  if (component.userinfo !== void 0) {
3383
- uriTokens.push(component.userinfo);
3558
+ uriTokens.push(encodeUserinfo(component.userinfo));
3384
3559
  uriTokens.push("@");
3385
3560
  }
3386
3561
  if (component.host !== void 0) {
3387
- let host = unescape(component.host);
3562
+ let host = component.host;
3388
3563
  if (!isIPv4(host)) {
3389
- const ipV6res = normalizeIPv6(host);
3390
- if (ipV6res.isIPV6 === true) {
3564
+ let ipV6res = normalizeIPv6(host);
3565
+ if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
3566
+ host = normalizePercentEncoding(host, true);
3567
+ ipV6res = normalizeIPv6(host);
3568
+ }
3569
+ if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
3391
3570
  host = `[${ipV6res.escapedHost}]`;
3392
3571
  } else {
3393
3572
  host = reescapeHostDelimiters(host, false);
@@ -3407,6 +3586,11 @@ var require_utils = __commonJS({
3407
3586
  reescapeHostDelimiters,
3408
3587
  normalizePercentEncoding,
3409
3588
  normalizePathEncoding,
3589
+ serializePathEncoding,
3590
+ normalizeQueryFragmentEncoding,
3591
+ encodeUserinfo,
3592
+ encodeQuery,
3593
+ encodeFragment,
3410
3594
  escapePreservingEscapes,
3411
3595
  removeDotSegments,
3412
3596
  isIPv4,
@@ -3417,12 +3601,12 @@ var require_utils = __commonJS({
3417
3601
  }
3418
3602
  });
3419
3603
 
3420
- // node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/schemes.js
3604
+ // node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/lib/schemes.js
3421
3605
  var require_schemes = __commonJS({
3422
- "node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3606
+ "node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3423
3607
  "use strict";
3424
3608
  var { isUUID } = require_utils();
3425
- var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
3609
+ var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
3426
3610
  var supportedSchemeNames = (
3427
3611
  /** @type {const} */
3428
3612
  [
@@ -3483,9 +3667,10 @@ var require_schemes = __commonJS({
3483
3667
  wsComponent.secure = void 0;
3484
3668
  }
3485
3669
  if (wsComponent.resourceName) {
3486
- const [path, query] = wsComponent.resourceName.split("?");
3670
+ const queryIndex = wsComponent.resourceName.indexOf("?");
3671
+ const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
3487
3672
  wsComponent.path = path && path !== "/" ? path : void 0;
3488
- wsComponent.query = query;
3673
+ wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
3489
3674
  wsComponent.resourceName = void 0;
3490
3675
  }
3491
3676
  wsComponent.fragment = void 0;
@@ -3497,7 +3682,7 @@ var require_schemes = __commonJS({
3497
3682
  return urnComponent;
3498
3683
  }
3499
3684
  const matches = urnComponent.path.match(URN_REG);
3500
- if (matches) {
3685
+ if (matches && matches[0] === urnComponent.path) {
3501
3686
  const scheme = options.scheme || urnComponent.scheme || "urn";
3502
3687
  urnComponent.nid = matches[1].toLowerCase();
3503
3688
  urnComponent.nss = matches[2];
@@ -3627,12 +3812,21 @@ var require_schemes = __commonJS({
3627
3812
  }
3628
3813
  });
3629
3814
 
3630
- // node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/index.js
3815
+ // node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/index.js
3631
3816
  var require_fast_uri = __commonJS({
3632
- "node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/index.js"(exports, module) {
3817
+ "node_modules/.pnpm/fast-uri@3.1.6/node_modules/fast-uri/index.js"(exports, module) {
3633
3818
  "use strict";
3634
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3819
+ var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3635
3820
  var { SCHEMES, getSchemeHandler } = require_schemes();
3821
+ var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
3822
+ var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
3823
+ function decodeValidScheme(scheme) {
3824
+ const decodedScheme = unescape(String(scheme));
3825
+ if (!VALID_SCHEME.test(decodedScheme)) {
3826
+ throw new TypeError(MALFORMED_SCHEME_ERROR);
3827
+ }
3828
+ return decodedScheme;
3829
+ }
3636
3830
  function normalize(uri, options) {
3637
3831
  if (typeof uri === "string") {
3638
3832
  uri = /** @type {T} */
@@ -3645,12 +3839,34 @@ var require_fast_uri = __commonJS({
3645
3839
  }
3646
3840
  function resolve3(baseURI, relativeURI, options) {
3647
3841
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3648
- const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
3649
- const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
3650
- if (baseMalformed || relativeMalformed) {
3842
+ const {
3843
+ parsed: baseParsed,
3844
+ malformedAuthorityOrPort: baseMalformed,
3845
+ malformedPercentEncoding: baseMalformedPercentEncoding,
3846
+ malformedSchemeSpecific: baseMalformedSchemeSpecific,
3847
+ malformedHost: baseMalformedHost,
3848
+ malformedScheme: baseMalformedScheme
3849
+ } = parseWithStatus(baseURI, schemelessOptions);
3850
+ const {
3851
+ parsed: relativeParsed,
3852
+ malformedAuthorityOrPort: relativeMalformed,
3853
+ malformedPercentEncoding: relativeMalformedPercentEncoding,
3854
+ malformedSchemeSpecific: relativeMalformedSchemeSpecific,
3855
+ malformedHost: relativeMalformedHost,
3856
+ malformedScheme: relativeMalformedScheme
3857
+ } = parseWithStatus(relativeURI, schemelessOptions);
3858
+ if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
3651
3859
  throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
3652
3860
  }
3653
3861
  const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
3862
+ const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
3863
+ const resolvedHost = resolved.host;
3864
+ const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
3865
+ canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
3866
+ const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !new RegExp("\\P{ASCII}", "u").test(resolvedHost);
3867
+ if (resolved.error && !encodedASCIIHost) {
3868
+ throw new Error(resolved.error);
3869
+ }
3654
3870
  schemelessOptions.skipEscape = true;
3655
3871
  return serialize(resolved, schemelessOptions);
3656
3872
  }
@@ -3710,7 +3926,7 @@ var require_fast_uri = __commonJS({
3710
3926
  function equal(uriA, uriB, options) {
3711
3927
  const normalizedA = normalizeComparableURI(uriA, options);
3712
3928
  const normalizedB = normalizeComparableURI(uriB, options);
3713
- return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA.toLowerCase() === normalizedB.toLowerCase();
3929
+ return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
3714
3930
  }
3715
3931
  function serialize(cmpts, opts) {
3716
3932
  const component = {
@@ -3731,19 +3947,22 @@ var require_fast_uri = __commonJS({
3731
3947
  };
3732
3948
  const options = Object.assign({}, opts);
3733
3949
  const uriTokens = [];
3950
+ if (component.scheme) {
3951
+ component.scheme = decodeValidScheme(component.scheme);
3952
+ }
3734
3953
  const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
3735
3954
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
3955
+ const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
3956
+ const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
3736
3957
  if (component.path !== void 0) {
3737
3958
  if (!options.skipEscape) {
3738
- component.path = escapePreservingEscapes(component.path);
3739
- if (component.scheme !== void 0) {
3740
- component.path = component.path.split("%3A").join(":");
3741
- }
3959
+ component.path = serializePathEncoding(component.path, pathNoScheme);
3742
3960
  } else {
3743
3961
  component.path = normalizePercentEncoding(component.path);
3744
3962
  }
3745
3963
  }
3746
3964
  if (options.reference !== "suffix" && component.scheme) {
3965
+ component.scheme = decodeValidScheme(component.scheme);
3747
3966
  uriTokens.push(component.scheme, ":");
3748
3967
  }
3749
3968
  const authority = recomposeAuthority(component);
@@ -3761,16 +3980,19 @@ var require_fast_uri = __commonJS({
3761
3980
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
3762
3981
  s = removeDotSegments(s);
3763
3982
  }
3983
+ if (pathNoScheme) {
3984
+ s = serializePathEncoding(s, true);
3985
+ }
3764
3986
  if (authority === void 0 && s[0] === "/" && s[1] === "/") {
3765
3987
  s = "/%2F" + s.slice(2);
3766
3988
  }
3767
3989
  uriTokens.push(s);
3768
3990
  }
3769
3991
  if (component.query !== void 0) {
3770
- uriTokens.push("?", component.query);
3992
+ uriTokens.push("?", encodeQuery(component.query));
3771
3993
  }
3772
3994
  if (component.fragment !== void 0) {
3773
- uriTokens.push("#", component.fragment);
3995
+ uriTokens.push("#", encodeFragment(component.fragment));
3774
3996
  }
3775
3997
  return uriTokens.join("");
3776
3998
  }
@@ -3786,6 +4008,32 @@ var require_fast_uri = __commonJS({
3786
4008
  }
3787
4009
  return void 0;
3788
4010
  }
4011
+ function hasMalformedPercentEncoding(component) {
4012
+ if (component === void 0) return false;
4013
+ let percent = component.indexOf("%");
4014
+ while (percent !== -1) {
4015
+ if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
4016
+ return true;
4017
+ }
4018
+ percent = component.indexOf("%", percent + 3);
4019
+ }
4020
+ return false;
4021
+ }
4022
+ function hasMalformedComponentPercentEncoding(matches) {
4023
+ const host = matches[4];
4024
+ return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !(host[0] === "[" && host[host.length - 1] === "]") && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4025
+ }
4026
+ function canonicalizeHost(parsed, options, schemeHandler, isIP) {
4027
+ if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host[0] !== "[" && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4028
+ try {
4029
+ parsed.host = new URL("http://" + parsed.host).hostname;
4030
+ } catch (e) {
4031
+ parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
4032
+ return true;
4033
+ }
4034
+ }
4035
+ return false;
4036
+ }
3789
4037
  function parseWithStatus(uri, opts) {
3790
4038
  const options = Object.assign({}, opts);
3791
4039
  const parsed = {
@@ -3798,6 +4046,11 @@ var require_fast_uri = __commonJS({
3798
4046
  fragment: void 0
3799
4047
  };
3800
4048
  let malformedAuthorityOrPort = false;
4049
+ let malformedPercentEncoding = false;
4050
+ let malformedSchemeSpecific = false;
4051
+ let malformedHost = false;
4052
+ let malformedIPLiteral = false;
4053
+ let malformedScheme = false;
3801
4054
  let isIP = false;
3802
4055
  if (options.reference === "suffix") {
3803
4056
  if (options.scheme) {
@@ -3834,6 +4087,19 @@ var require_fast_uri = __commonJS({
3834
4087
  parsed.path = matches[6] || "";
3835
4088
  parsed.query = matches[7];
3836
4089
  parsed.fragment = matches[8];
4090
+ if (parsed.scheme !== void 0) {
4091
+ const decodedScheme = unescape(parsed.scheme);
4092
+ if (VALID_SCHEME.test(decodedScheme)) {
4093
+ parsed.scheme = decodedScheme.toLowerCase();
4094
+ } else {
4095
+ parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
4096
+ malformedScheme = true;
4097
+ }
4098
+ }
4099
+ malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
4100
+ if (malformedPercentEncoding) {
4101
+ parsed.error = parsed.error || "URI contains malformed percent-encoding.";
4102
+ }
3837
4103
  if (isNaN(parsed.port)) {
3838
4104
  parsed.port = matches[5];
3839
4105
  }
@@ -3845,9 +4111,15 @@ var require_fast_uri = __commonJS({
3845
4111
  if (parsed.host) {
3846
4112
  const ipv4result = isIPv4(parsed.host);
3847
4113
  if (ipv4result === false) {
4114
+ const bracketedIPLiteral = parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
3848
4115
  const ipv6result = normalizeIPv6(parsed.host);
3849
- parsed.host = ipv6result.host.toLowerCase();
3850
- isIP = ipv6result.isIPV6;
4116
+ isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
4117
+ malformedIPLiteral = bracketedIPLiteral && ipv6result.error === true;
4118
+ parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
4119
+ if (malformedIPLiteral) {
4120
+ parsed.error = parsed.error || "URI host is malformed.";
4121
+ malformedAuthorityOrPort = true;
4122
+ }
3851
4123
  } else {
3852
4124
  isIP = true;
3853
4125
  }
@@ -3865,42 +4137,34 @@ var require_fast_uri = __commonJS({
3865
4137
  parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
3866
4138
  }
3867
4139
  const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
3868
- if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
3869
- if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
3870
- try {
3871
- parsed.host = new URL("http://" + parsed.host).hostname;
3872
- } catch (e) {
3873
- parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
3874
- }
3875
- }
3876
- }
4140
+ malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
3877
4141
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
3878
4142
  if (uri.indexOf("%") !== -1) {
3879
- if (parsed.scheme !== void 0) {
3880
- parsed.scheme = unescape(parsed.scheme);
3881
- }
3882
- if (parsed.host !== void 0) {
3883
- parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
4143
+ if (parsed.host !== void 0 && !malformedIPLiteral) {
4144
+ const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
4145
+ parsed.host = reescapeHostDelimiters(host, isIP);
3884
4146
  }
3885
4147
  }
3886
4148
  if (parsed.path) {
3887
4149
  parsed.path = normalizePathEncoding(parsed.path);
3888
4150
  }
4151
+ if (parsed.query) {
4152
+ parsed.query = normalizeQueryFragmentEncoding(parsed.query);
4153
+ }
3889
4154
  if (parsed.fragment) {
3890
- try {
3891
- parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
3892
- } catch {
3893
- parsed.error = parsed.error || "URI malformed";
3894
- }
4155
+ parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
3895
4156
  }
3896
4157
  }
3897
4158
  if (schemeHandler && schemeHandler.parse) {
3898
4159
  schemeHandler.parse(parsed, options);
4160
+ if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) {
4161
+ malformedSchemeSpecific = true;
4162
+ }
3899
4163
  }
3900
4164
  } else {
3901
4165
  parsed.error = parsed.error || "URI can not be parsed.";
3902
4166
  }
3903
- return { parsed, malformedAuthorityOrPort };
4167
+ return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
3904
4168
  }
3905
4169
  function parse4(uri, opts) {
3906
4170
  return parseWithStatus(uri, opts).parsed;
@@ -3909,20 +4173,28 @@ var require_fast_uri = __commonJS({
3909
4173
  return normalizeStringWithStatus(uri, opts).normalized;
3910
4174
  }
3911
4175
  function normalizeStringWithStatus(uri, opts) {
3912
- const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
4176
+ const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
3913
4177
  return {
3914
- normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
3915
- malformedAuthorityOrPort
4178
+ normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
4179
+ malformedAuthorityOrPort,
4180
+ malformedPercentEncoding,
4181
+ malformedSchemeSpecific,
4182
+ malformedHost,
4183
+ malformedScheme
3916
4184
  };
3917
4185
  }
3918
4186
  function normalizeComparableURI(uri, opts) {
3919
- if (typeof uri === "string") {
3920
- const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
3921
- return malformedAuthorityOrPort ? void 0 : normalized;
4187
+ if (typeof uri !== "string" && typeof uri !== "object") {
4188
+ return void 0;
3922
4189
  }
3923
- if (typeof uri === "object") {
3924
- return serialize(uri, opts);
4190
+ let value;
4191
+ try {
4192
+ value = typeof uri === "string" ? uri : serialize(uri, opts);
4193
+ } catch {
4194
+ return void 0;
3925
4195
  }
4196
+ const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
4197
+ return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
3926
4198
  }
3927
4199
  var fastUri = {
3928
4200
  SCHEMES,
@@ -60,8 +60,8 @@ the MCP runtime from your Homebrew/dev Node, which can keep updating freely.
60
60
  curl -O https://nodejs.org/dist/$VER/node-$VER-$ARCH.tar.gz
61
61
  curl -O https://nodejs.org/dist/$VER/SHASUMS256.txt
62
62
  grep " node-$VER-$ARCH.tar.gz$" SHASUMS256.txt | shasum -a 256 -c - # must print OK
63
- tar -xzf node-$VER-$ARCH.tar.gz
64
- ln -sfn node-$VER-$ARCH node-current
63
+ mkdir -p node-current
64
+ tar -xzf node-$VER-$ARCH.tar.gz --strip-components=1 -C node-current
65
65
  ```
66
66
 
67
67
  2. Confirm it's Developer-ID signed:
@@ -98,12 +98,36 @@ the MCP runtime from your Homebrew/dev Node, which can keep updating freely.
98
98
  - *Automation*: the first time the server drives an app you'll get a one-time
99
99
  `"node" wants to control "<App>"` prompt — click **Allow**.
100
100
 
101
- Both grants are keyed to the official Node's stable signature, so you should
102
- not be asked again — including after future Node updates. You can delete the
103
- stale "node" rows from the Full Disk Access list.
101
+ ⚠️ **A TCC grant is keyed to the binary's resolved *path*, not only to its
102
+ signature.** Because the steps above unpack Node into a fixed directory
103
+ (`~/mcp-runtime/node-current`) rather than a versioned one, that path never
104
+ moves and the grants survive Node updates — see "Updating" below. If you
105
+ instead point `node-current` at a `node-vX.Y.Z-…` directory, every update
106
+ changes the resolved path, presents a brand-new ungranted identity, and you
107
+ will be re-prompted for all of it.
108
+
109
+ You can delete any stale "node" rows from the Full Disk Access list.
104
110
 
105
111
  ### Updating the dedicated Node later
106
112
 
107
- Drop a newer official LTS tarball into `~/mcp-runtime/`, repoint the
108
- `node-current` symlink, and restart your client. The signing identity is
109
- unchanged, so existing grants carry over — no re-approval.
113
+ Replace the **contents** of the same directory — do not create a new one and do
114
+ not repoint anything:
115
+
116
+ ```bash
117
+ VER=v24.19.0 ARCH=darwin-arm64
118
+ cd ~/mcp-runtime
119
+ curl -O https://nodejs.org/dist/$VER/node-$VER-$ARCH.tar.gz
120
+ curl -O https://nodejs.org/dist/$VER/SHASUMS256.txt
121
+ grep " node-$VER-$ARCH.tar.gz$" SHASUMS256.txt | shasum -a 256 -c - # must print OK
122
+ rm -rf node-current && mkdir -p node-current
123
+ tar -xzf node-$VER-$ARCH.tar.gz --strip-components=1 -C node-current
124
+ ```
125
+
126
+ The path is unchanged and the official builds are Developer-ID signed with a
127
+ requirement that pins identifier + Team ID (no cdhash), so **both** halves of
128
+ the grant still match: existing grants carry over with no re-approval.
129
+
130
+ ⚠️ **Restart your MCP client afterwards.** Replacing the binary unlinks the one
131
+ any already-running server is executing; macOS then cannot validate that path,
132
+ so those processes fail with *"Permission denied"* until they are restarted.
133
+ Nothing is wrong with your grants — a freshly launched server works fine.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apple-numbers-mcp",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "MCP server for Apple Numbers - read, write, search, and format .numbers spreadsheets via Claude and other AI assistants",
5
5
  "type": "module",
6
6
  "main": "build/index.js",