@chrischall/pickuppatrol-mcp 0.1.2 → 0.2.0
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +437 -150
- package/dist/tools/_confirm.js +2 -2
- package/dist/tools/account.js +6 -6
- package/dist/tools/defaults.js +5 -5
- package/dist/tools/plans.js +4 -4
- package/dist/tools/school.js +6 -6
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/mint.yaml +22 -0
- package/package.json +6 -5
- package/server.json +2 -2
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "PickUp Patrol school-dismissal tools for Claude Code",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.2.0"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"displayName": "PickUp Patrol",
|
|
15
15
|
"source": "./",
|
|
16
16
|
"description": "Read and change your children's school dismissal plans in PickUp Patrol — defaults, day-by-day changes and school cutoff times — via MCP",
|
|
17
|
-
"version": "0.
|
|
17
|
+
"version": "0.2.0",
|
|
18
18
|
"author": {
|
|
19
19
|
"name": "Chris Chall"
|
|
20
20
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pickuppatrol",
|
|
3
3
|
"displayName": "PickUp Patrol",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"description": "Read and change your children's school dismissal plans in PickUp Patrol — defaults, day-by-day changes and school cutoff times — via MCP",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Chall"
|
package/dist/bundle.js
CHANGED
|
@@ -3109,9 +3109,28 @@ var require_utils = __commonJS({
|
|
|
3109
3109
|
"use strict";
|
|
3110
3110
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
3111
3111
|
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);
|
|
3112
|
+
var isPort = RegExp.prototype.test.bind(/^\d*$/u);
|
|
3112
3113
|
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
3113
3114
|
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
3114
|
-
var isPathCharacter = RegExp.prototype.test.bind(/^[
|
|
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
|
+
}
|
|
3115
3134
|
function stringArrayToHexStripped(input) {
|
|
3116
3135
|
let acc = "";
|
|
3117
3136
|
let code = 0;
|
|
@@ -3136,91 +3155,105 @@ var require_utils = __commonJS({
|
|
|
3136
3155
|
}
|
|
3137
3156
|
return acc;
|
|
3138
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\-._~]$/);
|
|
3139
3161
|
var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
|
|
3140
|
-
function
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
if (hex3 !== "") {
|
|
3148
|
-
address.push(hex3);
|
|
3149
|
-
} else {
|
|
3150
|
-
output.error = true;
|
|
3151
|
-
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;
|
|
3152
3169
|
}
|
|
3153
|
-
|
|
3170
|
+
return false;
|
|
3154
3171
|
}
|
|
3155
3172
|
return true;
|
|
3156
3173
|
}
|
|
3157
|
-
function
|
|
3158
|
-
let
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
let
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
}
|
|
3170
|
-
if (cursor === ":") {
|
|
3171
|
-
if (endipv6Encountered === true) {
|
|
3172
|
-
endIpv6 = true;
|
|
3173
|
-
}
|
|
3174
|
-
if (!consume(buffer, address, output)) {
|
|
3175
|
-
break;
|
|
3176
|
-
}
|
|
3177
|
-
if (++tokenCount > 7) {
|
|
3178
|
-
output.error = true;
|
|
3179
|
-
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;
|
|
3180
3186
|
}
|
|
3181
|
-
if (i > 0 && input[i - 1] === ":") {
|
|
3182
|
-
endipv6Encountered = true;
|
|
3183
|
-
}
|
|
3184
|
-
address.push(":");
|
|
3185
|
-
continue;
|
|
3186
|
-
} else if (cursor === "%") {
|
|
3187
|
-
if (!consume(buffer, address, output)) {
|
|
3188
|
-
break;
|
|
3189
|
-
}
|
|
3190
|
-
consume = consumeIsZone;
|
|
3191
3187
|
} else {
|
|
3192
|
-
|
|
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;
|
|
3193
3214
|
continue;
|
|
3194
3215
|
}
|
|
3216
|
+
if (!isHextet(part)) return void 0;
|
|
3217
|
+
parts[i] = parseInt(part, 16).toString(16);
|
|
3218
|
+
hextetCount++;
|
|
3195
3219
|
}
|
|
3196
|
-
if (
|
|
3197
|
-
if (
|
|
3198
|
-
|
|
3199
|
-
} else if (endIpv6) {
|
|
3200
|
-
address.push(buffer.join(""));
|
|
3201
|
-
} else {
|
|
3202
|
-
address.push(stringArrayToHexStripped(buffer));
|
|
3203
|
-
}
|
|
3220
|
+
if (compression === -1) {
|
|
3221
|
+
if (hextetCount !== 8) return void 0;
|
|
3222
|
+
return compressIPv6ZeroRun(parts);
|
|
3204
3223
|
}
|
|
3205
|
-
|
|
3206
|
-
|
|
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);
|
|
3207
3229
|
}
|
|
3208
3230
|
function normalizeIPv6(host) {
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
}
|
|
3212
|
-
|
|
3213
|
-
if (
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
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
|
+
};
|
|
3224
3257
|
}
|
|
3225
3258
|
function findToken(str, token) {
|
|
3226
3259
|
let ind = 0;
|
|
@@ -3339,7 +3372,8 @@ var require_utils = __commonJS({
|
|
|
3339
3372
|
function normalizePathEncoding(input) {
|
|
3340
3373
|
let output = "";
|
|
3341
3374
|
for (let i = 0; i < input.length; i++) {
|
|
3342
|
-
|
|
3375
|
+
const ch = input[i];
|
|
3376
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3343
3377
|
const hex3 = input.slice(i + 1, i + 3);
|
|
3344
3378
|
if (isHexPair(hex3)) {
|
|
3345
3379
|
const normalizedHex = hex3.toUpperCase();
|
|
@@ -3353,10 +3387,152 @@ var require_utils = __commonJS({
|
|
|
3353
3387
|
continue;
|
|
3354
3388
|
}
|
|
3355
3389
|
}
|
|
3356
|
-
if (isPathCharacter(
|
|
3357
|
-
output +=
|
|
3390
|
+
if (isPathCharacter(ch)) {
|
|
3391
|
+
output += ch;
|
|
3358
3392
|
} else {
|
|
3359
|
-
|
|
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 hex3 = input.slice(i + 1, i + 3);
|
|
3420
|
+
if (isHexPair(hex3)) {
|
|
3421
|
+
output += "%" + hex3.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 hex3 = input.slice(i + 1, i + 3);
|
|
3458
|
+
if (isHexPair(hex3)) {
|
|
3459
|
+
output += "%" + hex3.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 hex3 = input.slice(i + 1, i + 3);
|
|
3505
|
+
if (isHexPair(hex3)) {
|
|
3506
|
+
const normalizedHex = hex3.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
|
+
}
|
|
3360
3536
|
}
|
|
3361
3537
|
}
|
|
3362
3538
|
return output;
|
|
@@ -3379,14 +3555,18 @@ var require_utils = __commonJS({
|
|
|
3379
3555
|
function recomposeAuthority(component) {
|
|
3380
3556
|
const uriTokens = [];
|
|
3381
3557
|
if (component.userinfo !== void 0) {
|
|
3382
|
-
uriTokens.push(component.userinfo);
|
|
3558
|
+
uriTokens.push(encodeUserinfo(component.userinfo));
|
|
3383
3559
|
uriTokens.push("@");
|
|
3384
3560
|
}
|
|
3385
3561
|
if (component.host !== void 0) {
|
|
3386
|
-
let host =
|
|
3562
|
+
let host = component.host;
|
|
3387
3563
|
if (!isIPv4(host)) {
|
|
3388
|
-
|
|
3389
|
-
if (ipV6res.isIPV6
|
|
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) {
|
|
3390
3570
|
host = `[${ipV6res.escapedHost}]`;
|
|
3391
3571
|
} else {
|
|
3392
3572
|
host = reescapeHostDelimiters(host, false);
|
|
@@ -3395,8 +3575,12 @@ var require_utils = __commonJS({
|
|
|
3395
3575
|
uriTokens.push(host);
|
|
3396
3576
|
}
|
|
3397
3577
|
if (typeof component.port === "number" || typeof component.port === "string") {
|
|
3578
|
+
const port = String(component.port);
|
|
3579
|
+
if (!isPort(port)) {
|
|
3580
|
+
throw new TypeError("URI port is malformed.");
|
|
3581
|
+
}
|
|
3398
3582
|
uriTokens.push(":");
|
|
3399
|
-
uriTokens.push(
|
|
3583
|
+
uriTokens.push(port);
|
|
3400
3584
|
}
|
|
3401
3585
|
return uriTokens.length ? uriTokens.join("") : void 0;
|
|
3402
3586
|
}
|
|
@@ -3406,6 +3590,11 @@ var require_utils = __commonJS({
|
|
|
3406
3590
|
reescapeHostDelimiters,
|
|
3407
3591
|
normalizePercentEncoding,
|
|
3408
3592
|
normalizePathEncoding,
|
|
3593
|
+
serializePathEncoding,
|
|
3594
|
+
normalizeQueryFragmentEncoding,
|
|
3595
|
+
encodeUserinfo,
|
|
3596
|
+
encodeQuery,
|
|
3597
|
+
encodeFragment,
|
|
3409
3598
|
escapePreservingEscapes,
|
|
3410
3599
|
removeDotSegments,
|
|
3411
3600
|
isIPv4,
|
|
@@ -3421,7 +3610,7 @@ var require_schemes = __commonJS({
|
|
|
3421
3610
|
"node_modules/fast-uri/lib/schemes.js"(exports, module) {
|
|
3422
3611
|
"use strict";
|
|
3423
3612
|
var { isUUID } = require_utils();
|
|
3424
|
-
var URN_REG =
|
|
3613
|
+
var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
|
|
3425
3614
|
var supportedSchemeNames = (
|
|
3426
3615
|
/** @type {const} */
|
|
3427
3616
|
[
|
|
@@ -3482,9 +3671,10 @@ var require_schemes = __commonJS({
|
|
|
3482
3671
|
wsComponent.secure = void 0;
|
|
3483
3672
|
}
|
|
3484
3673
|
if (wsComponent.resourceName) {
|
|
3485
|
-
const
|
|
3674
|
+
const queryIndex = wsComponent.resourceName.indexOf("?");
|
|
3675
|
+
const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
|
|
3486
3676
|
wsComponent.path = path && path !== "/" ? path : void 0;
|
|
3487
|
-
wsComponent.query =
|
|
3677
|
+
wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
|
|
3488
3678
|
wsComponent.resourceName = void 0;
|
|
3489
3679
|
}
|
|
3490
3680
|
wsComponent.fragment = void 0;
|
|
@@ -3496,7 +3686,7 @@ var require_schemes = __commonJS({
|
|
|
3496
3686
|
return urnComponent;
|
|
3497
3687
|
}
|
|
3498
3688
|
const matches = urnComponent.path.match(URN_REG);
|
|
3499
|
-
if (matches) {
|
|
3689
|
+
if (matches && matches[0] === urnComponent.path) {
|
|
3500
3690
|
const scheme = options.scheme || urnComponent.scheme || "urn";
|
|
3501
3691
|
urnComponent.nid = matches[1].toLowerCase();
|
|
3502
3692
|
urnComponent.nss = matches[2];
|
|
@@ -3630,8 +3820,17 @@ var require_schemes = __commonJS({
|
|
|
3630
3820
|
var require_fast_uri = __commonJS({
|
|
3631
3821
|
"node_modules/fast-uri/index.js"(exports, module) {
|
|
3632
3822
|
"use strict";
|
|
3633
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding,
|
|
3823
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
3634
3824
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
3825
|
+
var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
|
|
3826
|
+
var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
|
|
3827
|
+
function decodeValidScheme(scheme) {
|
|
3828
|
+
const decodedScheme = unescape(String(scheme));
|
|
3829
|
+
if (!VALID_SCHEME.test(decodedScheme)) {
|
|
3830
|
+
throw new TypeError(MALFORMED_SCHEME_ERROR);
|
|
3831
|
+
}
|
|
3832
|
+
return decodedScheme;
|
|
3833
|
+
}
|
|
3635
3834
|
function normalize(uri, options) {
|
|
3636
3835
|
if (typeof uri === "string") {
|
|
3637
3836
|
uri = /** @type {T} */
|
|
@@ -3644,12 +3843,34 @@ var require_fast_uri = __commonJS({
|
|
|
3644
3843
|
}
|
|
3645
3844
|
function resolve(baseURI, relativeURI, options) {
|
|
3646
3845
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3647
|
-
const {
|
|
3648
|
-
|
|
3649
|
-
|
|
3846
|
+
const {
|
|
3847
|
+
parsed: baseParsed,
|
|
3848
|
+
malformedAuthorityOrPort: baseMalformed,
|
|
3849
|
+
malformedPercentEncoding: baseMalformedPercentEncoding,
|
|
3850
|
+
malformedSchemeSpecific: baseMalformedSchemeSpecific,
|
|
3851
|
+
malformedHost: baseMalformedHost,
|
|
3852
|
+
malformedScheme: baseMalformedScheme
|
|
3853
|
+
} = parseWithStatus(baseURI, schemelessOptions);
|
|
3854
|
+
const {
|
|
3855
|
+
parsed: relativeParsed,
|
|
3856
|
+
malformedAuthorityOrPort: relativeMalformed,
|
|
3857
|
+
malformedPercentEncoding: relativeMalformedPercentEncoding,
|
|
3858
|
+
malformedSchemeSpecific: relativeMalformedSchemeSpecific,
|
|
3859
|
+
malformedHost: relativeMalformedHost,
|
|
3860
|
+
malformedScheme: relativeMalformedScheme
|
|
3861
|
+
} = parseWithStatus(relativeURI, schemelessOptions);
|
|
3862
|
+
if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
|
|
3650
3863
|
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
3651
3864
|
}
|
|
3652
3865
|
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
3866
|
+
const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
|
|
3867
|
+
const resolvedHost = resolved.host;
|
|
3868
|
+
const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
|
|
3869
|
+
canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
|
|
3870
|
+
const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !/\P{ASCII}/u.test(resolvedHost);
|
|
3871
|
+
if (resolved.error && !encodedASCIIHost) {
|
|
3872
|
+
throw new Error(resolved.error);
|
|
3873
|
+
}
|
|
3653
3874
|
schemelessOptions.skipEscape = true;
|
|
3654
3875
|
return serialize(resolved, schemelessOptions);
|
|
3655
3876
|
}
|
|
@@ -3709,7 +3930,7 @@ var require_fast_uri = __commonJS({
|
|
|
3709
3930
|
function equal(uriA, uriB, options) {
|
|
3710
3931
|
const normalizedA = normalizeComparableURI(uriA, options);
|
|
3711
3932
|
const normalizedB = normalizeComparableURI(uriB, options);
|
|
3712
|
-
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA
|
|
3933
|
+
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
|
|
3713
3934
|
}
|
|
3714
3935
|
function serialize(cmpts, opts) {
|
|
3715
3936
|
const component = {
|
|
@@ -3730,19 +3951,22 @@ var require_fast_uri = __commonJS({
|
|
|
3730
3951
|
};
|
|
3731
3952
|
const options = Object.assign({}, opts);
|
|
3732
3953
|
const uriTokens = [];
|
|
3954
|
+
if (component.scheme) {
|
|
3955
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
3956
|
+
}
|
|
3733
3957
|
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
|
|
3734
3958
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
3959
|
+
const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
|
|
3960
|
+
const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
|
|
3735
3961
|
if (component.path !== void 0) {
|
|
3736
3962
|
if (!options.skipEscape) {
|
|
3737
|
-
component.path =
|
|
3738
|
-
if (component.scheme !== void 0) {
|
|
3739
|
-
component.path = component.path.split("%3A").join(":");
|
|
3740
|
-
}
|
|
3963
|
+
component.path = serializePathEncoding(component.path, pathNoScheme);
|
|
3741
3964
|
} else {
|
|
3742
3965
|
component.path = normalizePercentEncoding(component.path);
|
|
3743
3966
|
}
|
|
3744
3967
|
}
|
|
3745
3968
|
if (options.reference !== "suffix" && component.scheme) {
|
|
3969
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
3746
3970
|
uriTokens.push(component.scheme, ":");
|
|
3747
3971
|
}
|
|
3748
3972
|
const authority = recomposeAuthority(component);
|
|
@@ -3760,16 +3984,19 @@ var require_fast_uri = __commonJS({
|
|
|
3760
3984
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
|
|
3761
3985
|
s = removeDotSegments(s);
|
|
3762
3986
|
}
|
|
3987
|
+
if (pathNoScheme) {
|
|
3988
|
+
s = serializePathEncoding(s, true);
|
|
3989
|
+
}
|
|
3763
3990
|
if (authority === void 0 && s[0] === "/" && s[1] === "/") {
|
|
3764
3991
|
s = "/%2F" + s.slice(2);
|
|
3765
3992
|
}
|
|
3766
3993
|
uriTokens.push(s);
|
|
3767
3994
|
}
|
|
3768
3995
|
if (component.query !== void 0) {
|
|
3769
|
-
uriTokens.push("?", component.query);
|
|
3996
|
+
uriTokens.push("?", encodeQuery(component.query));
|
|
3770
3997
|
}
|
|
3771
3998
|
if (component.fragment !== void 0) {
|
|
3772
|
-
uriTokens.push("#", component.fragment);
|
|
3999
|
+
uriTokens.push("#", encodeFragment(component.fragment));
|
|
3773
4000
|
}
|
|
3774
4001
|
return uriTokens.join("");
|
|
3775
4002
|
}
|
|
@@ -3785,6 +4012,35 @@ var require_fast_uri = __commonJS({
|
|
|
3785
4012
|
}
|
|
3786
4013
|
return void 0;
|
|
3787
4014
|
}
|
|
4015
|
+
function hasMalformedPercentEncoding(component) {
|
|
4016
|
+
if (component === void 0) return false;
|
|
4017
|
+
let percent = component.indexOf("%");
|
|
4018
|
+
while (percent !== -1) {
|
|
4019
|
+
if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
|
|
4020
|
+
return true;
|
|
4021
|
+
}
|
|
4022
|
+
percent = component.indexOf("%", percent + 3);
|
|
4023
|
+
}
|
|
4024
|
+
return false;
|
|
4025
|
+
}
|
|
4026
|
+
function isIPLiteral(host) {
|
|
4027
|
+
return host[0] === "[" && host[host.length - 1] === "]";
|
|
4028
|
+
}
|
|
4029
|
+
function hasMalformedComponentPercentEncoding(matches) {
|
|
4030
|
+
const host = matches[4];
|
|
4031
|
+
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
|
|
4032
|
+
}
|
|
4033
|
+
function canonicalizeHost(parsed, options, schemeHandler, isIP) {
|
|
4034
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
4035
|
+
try {
|
|
4036
|
+
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
4037
|
+
} catch (e) {
|
|
4038
|
+
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
4039
|
+
return true;
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
return false;
|
|
4043
|
+
}
|
|
3788
4044
|
function parseWithStatus(uri, opts) {
|
|
3789
4045
|
const options = Object.assign({}, opts);
|
|
3790
4046
|
const parsed = {
|
|
@@ -3797,6 +4053,11 @@ var require_fast_uri = __commonJS({
|
|
|
3797
4053
|
fragment: void 0
|
|
3798
4054
|
};
|
|
3799
4055
|
let malformedAuthorityOrPort = false;
|
|
4056
|
+
let malformedPercentEncoding = false;
|
|
4057
|
+
let malformedSchemeSpecific = false;
|
|
4058
|
+
let malformedHost = false;
|
|
4059
|
+
let malformedIPLiteral = false;
|
|
4060
|
+
let malformedScheme = false;
|
|
3800
4061
|
let isIP = false;
|
|
3801
4062
|
if (options.reference === "suffix") {
|
|
3802
4063
|
if (options.scheme) {
|
|
@@ -3833,6 +4094,19 @@ var require_fast_uri = __commonJS({
|
|
|
3833
4094
|
parsed.path = matches[6] || "";
|
|
3834
4095
|
parsed.query = matches[7];
|
|
3835
4096
|
parsed.fragment = matches[8];
|
|
4097
|
+
if (parsed.scheme !== void 0) {
|
|
4098
|
+
const decodedScheme = unescape(parsed.scheme);
|
|
4099
|
+
if (VALID_SCHEME.test(decodedScheme)) {
|
|
4100
|
+
parsed.scheme = decodedScheme.toLowerCase();
|
|
4101
|
+
} else {
|
|
4102
|
+
parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
|
|
4103
|
+
malformedScheme = true;
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
|
|
4107
|
+
if (malformedPercentEncoding) {
|
|
4108
|
+
parsed.error = parsed.error || "URI contains malformed percent-encoding.";
|
|
4109
|
+
}
|
|
3836
4110
|
if (isNaN(parsed.port)) {
|
|
3837
4111
|
parsed.port = matches[5];
|
|
3838
4112
|
}
|
|
@@ -3844,9 +4118,16 @@ var require_fast_uri = __commonJS({
|
|
|
3844
4118
|
if (parsed.host) {
|
|
3845
4119
|
const ipv4result = isIPv4(parsed.host);
|
|
3846
4120
|
if (ipv4result === false) {
|
|
4121
|
+
const bracketedIPLiteral = isIPLiteral(parsed.host);
|
|
4122
|
+
const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
|
|
3847
4123
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
3848
|
-
|
|
3849
|
-
|
|
4124
|
+
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
4125
|
+
malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
|
|
4126
|
+
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
4127
|
+
if (malformedIPLiteral) {
|
|
4128
|
+
parsed.error = parsed.error || "URI host is malformed.";
|
|
4129
|
+
malformedAuthorityOrPort = true;
|
|
4130
|
+
}
|
|
3850
4131
|
} else {
|
|
3851
4132
|
isIP = true;
|
|
3852
4133
|
}
|
|
@@ -3864,42 +4145,36 @@ var require_fast_uri = __commonJS({
|
|
|
3864
4145
|
parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
|
|
3865
4146
|
}
|
|
3866
4147
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
3867
|
-
if (!
|
|
3868
|
-
|
|
3869
|
-
try {
|
|
3870
|
-
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
3871
|
-
} catch (e) {
|
|
3872
|
-
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
3873
|
-
}
|
|
3874
|
-
}
|
|
4148
|
+
if (!malformedIPLiteral) {
|
|
4149
|
+
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
3875
4150
|
}
|
|
3876
4151
|
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
3877
4152
|
if (uri.indexOf("%") !== -1) {
|
|
3878
|
-
if (parsed.
|
|
3879
|
-
parsed.
|
|
3880
|
-
|
|
3881
|
-
if (parsed.host !== void 0) {
|
|
3882
|
-
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
|
|
4153
|
+
if (parsed.host !== void 0 && !malformedIPLiteral) {
|
|
4154
|
+
const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4155
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
3883
4156
|
}
|
|
3884
4157
|
}
|
|
3885
4158
|
if (parsed.path) {
|
|
3886
4159
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
3887
4160
|
}
|
|
4161
|
+
if (parsed.query) {
|
|
4162
|
+
parsed.query = normalizeQueryFragmentEncoding(parsed.query);
|
|
4163
|
+
}
|
|
3888
4164
|
if (parsed.fragment) {
|
|
3889
|
-
|
|
3890
|
-
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
3891
|
-
} catch {
|
|
3892
|
-
parsed.error = parsed.error || "URI malformed";
|
|
3893
|
-
}
|
|
4165
|
+
parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
|
|
3894
4166
|
}
|
|
3895
4167
|
}
|
|
3896
4168
|
if (schemeHandler && schemeHandler.parse) {
|
|
3897
4169
|
schemeHandler.parse(parsed, options);
|
|
4170
|
+
if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) {
|
|
4171
|
+
malformedSchemeSpecific = true;
|
|
4172
|
+
}
|
|
3898
4173
|
}
|
|
3899
4174
|
} else {
|
|
3900
4175
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
3901
4176
|
}
|
|
3902
|
-
return { parsed, malformedAuthorityOrPort };
|
|
4177
|
+
return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
|
|
3903
4178
|
}
|
|
3904
4179
|
function parse3(uri, opts) {
|
|
3905
4180
|
return parseWithStatus(uri, opts).parsed;
|
|
@@ -3908,20 +4183,28 @@ var require_fast_uri = __commonJS({
|
|
|
3908
4183
|
return normalizeStringWithStatus(uri, opts).normalized;
|
|
3909
4184
|
}
|
|
3910
4185
|
function normalizeStringWithStatus(uri, opts) {
|
|
3911
|
-
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
4186
|
+
const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
|
|
3912
4187
|
return {
|
|
3913
|
-
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
3914
|
-
malformedAuthorityOrPort
|
|
4188
|
+
normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
|
|
4189
|
+
malformedAuthorityOrPort,
|
|
4190
|
+
malformedPercentEncoding,
|
|
4191
|
+
malformedSchemeSpecific,
|
|
4192
|
+
malformedHost,
|
|
4193
|
+
malformedScheme
|
|
3915
4194
|
};
|
|
3916
4195
|
}
|
|
3917
4196
|
function normalizeComparableURI(uri, opts) {
|
|
3918
|
-
if (typeof uri
|
|
3919
|
-
|
|
3920
|
-
return malformedAuthorityOrPort ? void 0 : normalized;
|
|
4197
|
+
if (typeof uri !== "string" && typeof uri !== "object") {
|
|
4198
|
+
return void 0;
|
|
3921
4199
|
}
|
|
3922
|
-
|
|
3923
|
-
|
|
4200
|
+
let value;
|
|
4201
|
+
try {
|
|
4202
|
+
value = typeof uri === "string" ? uri : serialize(uri, opts);
|
|
4203
|
+
} catch {
|
|
4204
|
+
return void 0;
|
|
3924
4205
|
}
|
|
4206
|
+
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
|
|
4207
|
+
return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
|
|
3925
4208
|
}
|
|
3926
4209
|
var fastUri = {
|
|
3927
4210
|
SCHEMES,
|
|
@@ -31045,12 +31328,16 @@ function messageOf(err) {
|
|
|
31045
31328
|
return String(err);
|
|
31046
31329
|
}
|
|
31047
31330
|
|
|
31048
|
-
// node_modules/@chrischall/mcp-utils/dist/response/
|
|
31049
|
-
function
|
|
31050
|
-
return {
|
|
31051
|
-
content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
|
|
31052
|
-
};
|
|
31331
|
+
// node_modules/@chrischall/mcp-utils/dist/response/view.js
|
|
31332
|
+
function minifiedResult(data) {
|
|
31333
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
31053
31334
|
}
|
|
31335
|
+
|
|
31336
|
+
// node_modules/@chrischall/mcp-utils/dist/response/media.js
|
|
31337
|
+
var MEDIA_NOUN = "(?:avatar|tall_avatar|cover_photo|cover_image|picture|photo|thumbnail|thumb|image|icon|banner|profile_pic(?:ture)?|logo)";
|
|
31338
|
+
var MEDIA_KEY = new RegExp(`^${MEDIA_NOUN}s?(?:(?:link|uri|url)s?)?$`, "i");
|
|
31339
|
+
|
|
31340
|
+
// node_modules/@chrischall/mcp-utils/dist/response/index.js
|
|
31054
31341
|
function errorResult(message) {
|
|
31055
31342
|
return {
|
|
31056
31343
|
content: [{ type: "text", text: redactSecrets(message) }],
|
|
@@ -31525,7 +31812,7 @@ var PickUpPatrolClient = class {
|
|
|
31525
31812
|
var client = new PickUpPatrolClient();
|
|
31526
31813
|
|
|
31527
31814
|
// src/version.ts
|
|
31528
|
-
var VERSION = "0.
|
|
31815
|
+
var VERSION = "0.2.0";
|
|
31529
31816
|
|
|
31530
31817
|
// src/dates.ts
|
|
31531
31818
|
var WEEKDAY_NAMES = [
|
|
@@ -31590,7 +31877,7 @@ function registerAccountTools(server, client2) {
|
|
|
31590
31877
|
},
|
|
31591
31878
|
async () => {
|
|
31592
31879
|
const session = await client2.getSession();
|
|
31593
|
-
return
|
|
31880
|
+
return minifiedResult({
|
|
31594
31881
|
userId: session.UserId ?? null,
|
|
31595
31882
|
name: session.DisplayName ?? [session.FirstName, session.LastName].filter(Boolean).join(" "),
|
|
31596
31883
|
email: session.Email ?? session.PrimaryEmail ?? null,
|
|
@@ -31613,7 +31900,7 @@ function registerAccountTools(server, client2) {
|
|
|
31613
31900
|
client2.getDefaultPlansReviewNeeded()
|
|
31614
31901
|
]);
|
|
31615
31902
|
const needsReview = new Map(review.map((r) => [r.StudentId, r.NeedsReview]));
|
|
31616
|
-
return
|
|
31903
|
+
return minifiedResult(
|
|
31617
31904
|
students.map((student) => ({
|
|
31618
31905
|
...summarizeStudent(student),
|
|
31619
31906
|
needsDefaultsReview: needsReview.get(student.StudentId) ?? false
|
|
@@ -31633,7 +31920,7 @@ function registerAccountTools(server, client2) {
|
|
|
31633
31920
|
},
|
|
31634
31921
|
async ({ student_id, raw }) => {
|
|
31635
31922
|
const student = await client2.getStudent(student_id);
|
|
31636
|
-
return
|
|
31923
|
+
return minifiedResult(raw === true ? student : summarizeStudent(student));
|
|
31637
31924
|
}
|
|
31638
31925
|
);
|
|
31639
31926
|
server.registerTool(
|
|
@@ -31645,14 +31932,14 @@ function registerAccountTools(server, client2) {
|
|
|
31645
31932
|
async () => {
|
|
31646
31933
|
try {
|
|
31647
31934
|
const session = await client2.getSession();
|
|
31648
|
-
return
|
|
31935
|
+
return minifiedResult({
|
|
31649
31936
|
ok: true,
|
|
31650
31937
|
version: VERSION,
|
|
31651
31938
|
signedInAs: session.Email ?? session.PrimaryEmail ?? session.DisplayName ?? null,
|
|
31652
31939
|
studentCount: session.Children?.length ?? 0
|
|
31653
31940
|
});
|
|
31654
31941
|
} catch (err) {
|
|
31655
|
-
return
|
|
31942
|
+
return minifiedResult({ ok: false, version: VERSION, error: messageOf(err) });
|
|
31656
31943
|
}
|
|
31657
31944
|
}
|
|
31658
31945
|
);
|
|
@@ -31686,7 +31973,7 @@ function registerSchoolTools(server, client2) {
|
|
|
31686
31973
|
async ({ school_id, include_inactive }) => {
|
|
31687
31974
|
const options = await client2.getTransportations(school_id);
|
|
31688
31975
|
const visible = include_inactive === true ? options : options.filter((o) => o.IsActive !== false);
|
|
31689
|
-
return
|
|
31976
|
+
return minifiedResult(visible.map(summarizeTransportation));
|
|
31690
31977
|
}
|
|
31691
31978
|
);
|
|
31692
31979
|
server.registerTool(
|
|
@@ -31704,7 +31991,7 @@ function registerSchoolTools(server, client2) {
|
|
|
31704
31991
|
client2.getSchoolNotifyTimes(school_id),
|
|
31705
31992
|
client2.getSchoolSettings(school_id)
|
|
31706
31993
|
]);
|
|
31707
|
-
return
|
|
31994
|
+
return minifiedResult({ school, notifyTimes, settings });
|
|
31708
31995
|
}
|
|
31709
31996
|
);
|
|
31710
31997
|
server.registerTool(
|
|
@@ -31721,10 +32008,10 @@ function registerSchoolTools(server, client2) {
|
|
|
31721
32008
|
async ({ school_id, start_date, end_date }) => {
|
|
31722
32009
|
const invalidDates = await client2.getInvalidPlanDates(school_id);
|
|
31723
32010
|
if (start_date === void 0 || end_date === void 0) {
|
|
31724
|
-
return
|
|
32011
|
+
return minifiedResult({ invalidDates });
|
|
31725
32012
|
}
|
|
31726
32013
|
const changedDates = await client2.getBoldedDates(start_date, end_date);
|
|
31727
|
-
return
|
|
32014
|
+
return minifiedResult({ invalidDates, changedDates });
|
|
31728
32015
|
}
|
|
31729
32016
|
);
|
|
31730
32017
|
server.registerTool(
|
|
@@ -31736,7 +32023,7 @@ function registerSchoolTools(server, client2) {
|
|
|
31736
32023
|
school_id: external_exports.number().int().describe("School id, from pup_list_students")
|
|
31737
32024
|
}
|
|
31738
32025
|
},
|
|
31739
|
-
async ({ school_id }) =>
|
|
32026
|
+
async ({ school_id }) => minifiedResult(await client2.getCarNumbers(school_id))
|
|
31740
32027
|
);
|
|
31741
32028
|
}
|
|
31742
32029
|
|
|
@@ -31873,7 +32160,7 @@ function clearDefaultPlans(student) {
|
|
|
31873
32160
|
// src/tools/_confirm.ts
|
|
31874
32161
|
function previewUnlessConfirmed(confirm, action, method, dto, body) {
|
|
31875
32162
|
if (confirm === true) return null;
|
|
31876
|
-
return
|
|
32163
|
+
return minifiedResult({
|
|
31877
32164
|
dryRun: true,
|
|
31878
32165
|
action,
|
|
31879
32166
|
method,
|
|
@@ -31911,7 +32198,7 @@ function registerPlanTools(server, client2) {
|
|
|
31911
32198
|
end_date: external_exports.string().describe("YYYY-MM-DD")
|
|
31912
32199
|
}
|
|
31913
32200
|
},
|
|
31914
|
-
async ({ start_date, end_date }) =>
|
|
32201
|
+
async ({ start_date, end_date }) => minifiedResult(await client2.getParentPlans(start_date, end_date))
|
|
31915
32202
|
);
|
|
31916
32203
|
server.registerTool(
|
|
31917
32204
|
"pup_get_plan",
|
|
@@ -31923,7 +32210,7 @@ function registerPlanTools(server, client2) {
|
|
|
31923
32210
|
date: external_exports.string().describe("YYYY-MM-DD")
|
|
31924
32211
|
}
|
|
31925
32212
|
},
|
|
31926
|
-
async ({ student_id, date: date5 }) =>
|
|
32213
|
+
async ({ student_id, date: date5 }) => minifiedResult(await client2.getPlanEdit(date5, student_id))
|
|
31927
32214
|
);
|
|
31928
32215
|
server.registerTool(
|
|
31929
32216
|
"pup_set_plan",
|
|
@@ -31980,7 +32267,7 @@ function registerPlanTools(server, client2) {
|
|
|
31980
32267
|
})
|
|
31981
32268
|
);
|
|
31982
32269
|
const failed = verification.filter((v) => !v.verified);
|
|
31983
|
-
return
|
|
32270
|
+
return minifiedResult({
|
|
31984
32271
|
action,
|
|
31985
32272
|
applied: verification,
|
|
31986
32273
|
verified: failed.length === 0,
|
|
@@ -32028,7 +32315,7 @@ function registerDefaultPlanTools(server, client2) {
|
|
|
32028
32315
|
client2.getStudent(student_id),
|
|
32029
32316
|
client2.getDefaultPlansReviewNeeded()
|
|
32030
32317
|
]);
|
|
32031
|
-
return
|
|
32318
|
+
return minifiedResult({
|
|
32032
32319
|
studentId: student.StudentId,
|
|
32033
32320
|
name: [student.FirstName, student.LastName].filter(Boolean).join(" "),
|
|
32034
32321
|
schoolId: student.SchoolId,
|
|
@@ -32069,7 +32356,7 @@ function registerDefaultPlanTools(server, client2) {
|
|
|
32069
32356
|
await client2.updateStudent(payload2);
|
|
32070
32357
|
const after2 = await client2.getStudent(student_id);
|
|
32071
32358
|
const remaining = after2.DefaultPlans ?? [];
|
|
32072
|
-
return
|
|
32359
|
+
return minifiedResult({
|
|
32073
32360
|
action: "Cleared every weekday default",
|
|
32074
32361
|
defaultPlans: summarizeDefaultPlans(remaining),
|
|
32075
32362
|
verified: remaining.length === 0,
|
|
@@ -32113,7 +32400,7 @@ function registerDefaultPlanTools(server, client2) {
|
|
|
32113
32400
|
{ transportationId: transportation.TransportationId, note: sentNote }
|
|
32114
32401
|
);
|
|
32115
32402
|
});
|
|
32116
|
-
return
|
|
32403
|
+
return minifiedResult({
|
|
32117
32404
|
action,
|
|
32118
32405
|
defaultPlans: summarizeDefaultPlans(after.DefaultPlans),
|
|
32119
32406
|
verified: unchanged.length === 0,
|
|
@@ -32147,7 +32434,7 @@ function registerDefaultPlanTools(server, client2) {
|
|
|
32147
32434
|
await client2.setDefaultsReviewed(student_id, value);
|
|
32148
32435
|
const review = await client2.getDefaultPlansReviewNeeded();
|
|
32149
32436
|
const needsReview = review.find((r) => r.StudentId === student_id)?.NeedsReview ?? false;
|
|
32150
|
-
return
|
|
32437
|
+
return minifiedResult({
|
|
32151
32438
|
studentId: student_id,
|
|
32152
32439
|
needsDefaultsReview: needsReview,
|
|
32153
32440
|
verified: needsReview === !value
|
package/dist/tools/_confirm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { minifiedResult, schemaConfirm } from '@chrischall/mcp-utils';
|
|
2
2
|
export { schemaConfirm };
|
|
3
3
|
/**
|
|
4
4
|
* Confirm-gate for a mutating tool (the fleet convention). Without
|
|
@@ -12,7 +12,7 @@ export { schemaConfirm };
|
|
|
12
12
|
export function previewUnlessConfirmed(confirm, action, method, dto, body) {
|
|
13
13
|
if (confirm === true)
|
|
14
14
|
return null;
|
|
15
|
-
return
|
|
15
|
+
return minifiedResult({
|
|
16
16
|
dryRun: true,
|
|
17
17
|
action,
|
|
18
18
|
method,
|
package/dist/tools/account.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { messageOf, minifiedResult } from '@chrischall/mcp-utils';
|
|
3
3
|
import { dayIdToName } from '../dates.js';
|
|
4
4
|
import { VERSION } from '../version.js';
|
|
5
5
|
/** Project a student down to the fields a parent actually asks about. */
|
|
@@ -36,7 +36,7 @@ export function registerAccountTools(server, client) {
|
|
|
36
36
|
annotations: { readOnlyHint: true },
|
|
37
37
|
}, async () => {
|
|
38
38
|
const session = await client.getSession();
|
|
39
|
-
return
|
|
39
|
+
return minifiedResult({
|
|
40
40
|
userId: session.UserId ?? null,
|
|
41
41
|
name: session.DisplayName ?? [session.FirstName, session.LastName].filter(Boolean).join(' '),
|
|
42
42
|
email: session.Email ?? session.PrimaryEmail ?? null,
|
|
@@ -55,7 +55,7 @@ export function registerAccountTools(server, client) {
|
|
|
55
55
|
client.getDefaultPlansReviewNeeded(),
|
|
56
56
|
]);
|
|
57
57
|
const needsReview = new Map(review.map((r) => [r.StudentId, r.NeedsReview]));
|
|
58
|
-
return
|
|
58
|
+
return minifiedResult(students.map((student) => ({
|
|
59
59
|
...summarizeStudent(student),
|
|
60
60
|
needsDefaultsReview: needsReview.get(student.StudentId) ?? false,
|
|
61
61
|
})));
|
|
@@ -72,7 +72,7 @@ export function registerAccountTools(server, client) {
|
|
|
72
72
|
},
|
|
73
73
|
}, async ({ student_id, raw }) => {
|
|
74
74
|
const student = await client.getStudent(student_id);
|
|
75
|
-
return
|
|
75
|
+
return minifiedResult(raw === true ? student : summarizeStudent(student));
|
|
76
76
|
});
|
|
77
77
|
server.registerTool('pup_healthcheck', {
|
|
78
78
|
description: 'Verify the configured credentials sign in and the PickUp Patrol API answers. Reports the server version and the students the account can see.',
|
|
@@ -80,7 +80,7 @@ export function registerAccountTools(server, client) {
|
|
|
80
80
|
}, async () => {
|
|
81
81
|
try {
|
|
82
82
|
const session = await client.getSession();
|
|
83
|
-
return
|
|
83
|
+
return minifiedResult({
|
|
84
84
|
ok: true,
|
|
85
85
|
version: VERSION,
|
|
86
86
|
signedInAs: session.Email ?? session.PrimaryEmail ?? session.DisplayName ?? null,
|
|
@@ -91,7 +91,7 @@ export function registerAccountTools(server, client) {
|
|
|
91
91
|
// A healthcheck reports rather than throws: the whole point is to say
|
|
92
92
|
// what is wrong, and an exception here reads to the host as the tool
|
|
93
93
|
// itself being broken.
|
|
94
|
-
return
|
|
94
|
+
return minifiedResult({ ok: false, version: VERSION, error: messageOf(err) });
|
|
95
95
|
}
|
|
96
96
|
});
|
|
97
97
|
}
|
package/dist/tools/defaults.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { McpToolError,
|
|
2
|
+
import { McpToolError, minifiedResult } from '@chrischall/mcp-utils';
|
|
3
3
|
import { applyDefaultPlans, clearDefaultPlans } from '../plans.js';
|
|
4
4
|
import { dayIdToName, nameToDayId } from '../dates.js';
|
|
5
5
|
import { summarizeDefaultPlans } from './account.js';
|
|
@@ -42,7 +42,7 @@ export function registerDefaultPlanTools(server, client) {
|
|
|
42
42
|
client.getStudent(student_id),
|
|
43
43
|
client.getDefaultPlansReviewNeeded(),
|
|
44
44
|
]);
|
|
45
|
-
return
|
|
45
|
+
return minifiedResult({
|
|
46
46
|
studentId: student.StudentId,
|
|
47
47
|
name: [student.FirstName, student.LastName].filter(Boolean).join(' '),
|
|
48
48
|
schoolId: student.SchoolId,
|
|
@@ -91,7 +91,7 @@ export function registerDefaultPlanTools(server, client) {
|
|
|
91
91
|
await client.updateStudent(payload);
|
|
92
92
|
const after = await client.getStudent(student_id);
|
|
93
93
|
const remaining = after.DefaultPlans ?? [];
|
|
94
|
-
return
|
|
94
|
+
return minifiedResult({
|
|
95
95
|
action: 'Cleared every weekday default',
|
|
96
96
|
defaultPlans: summarizeDefaultPlans(remaining),
|
|
97
97
|
verified: remaining.length === 0,
|
|
@@ -138,7 +138,7 @@ export function registerDefaultPlanTools(server, client) {
|
|
|
138
138
|
return true;
|
|
139
139
|
return !proofsMatch({ transportationId: plan.TransportationId ?? null, note: plan.Note ?? null }, { transportationId: transportation.TransportationId, note: sentNote });
|
|
140
140
|
});
|
|
141
|
-
return
|
|
141
|
+
return minifiedResult({
|
|
142
142
|
action,
|
|
143
143
|
defaultPlans: summarizeDefaultPlans(after.DefaultPlans),
|
|
144
144
|
verified: unchanged.length === 0,
|
|
@@ -165,7 +165,7 @@ export function registerDefaultPlanTools(server, client) {
|
|
|
165
165
|
await client.setDefaultsReviewed(student_id, value);
|
|
166
166
|
const review = await client.getDefaultPlansReviewNeeded();
|
|
167
167
|
const needsReview = review.find((r) => r.StudentId === student_id)?.NeedsReview ?? false;
|
|
168
|
-
return
|
|
168
|
+
return minifiedResult({
|
|
169
169
|
studentId: student_id,
|
|
170
170
|
needsDefaultsReview: needsReview,
|
|
171
171
|
verified: needsReview === !value,
|
package/dist/tools/plans.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { McpToolError,
|
|
2
|
+
import { McpToolError, minifiedResult } from '@chrischall/mcp-utils';
|
|
3
3
|
import { buildPlanUpdates } from '../plans.js';
|
|
4
4
|
import { weekdayOf } from '../dates.js';
|
|
5
5
|
import { previewUnlessConfirmed, schemaConfirm } from './_confirm.js';
|
|
@@ -45,7 +45,7 @@ export function registerPlanTools(server, client) {
|
|
|
45
45
|
start_date: z.string().describe('YYYY-MM-DD'),
|
|
46
46
|
end_date: z.string().describe('YYYY-MM-DD'),
|
|
47
47
|
},
|
|
48
|
-
}, async ({ start_date, end_date }) =>
|
|
48
|
+
}, async ({ start_date, end_date }) => minifiedResult(await client.getParentPlans(start_date, end_date)));
|
|
49
49
|
server.registerTool('pup_get_plan', {
|
|
50
50
|
description: 'The dismissal plan for one student on one date — the option in force, any note, the early-dismissal time, and whether the date is locked because the cutoff has passed.',
|
|
51
51
|
annotations: { readOnlyHint: true },
|
|
@@ -53,7 +53,7 @@ export function registerPlanTools(server, client) {
|
|
|
53
53
|
student_id: z.number().int().describe('Student id, from pup_list_students'),
|
|
54
54
|
date: z.string().describe('YYYY-MM-DD'),
|
|
55
55
|
},
|
|
56
|
-
}, async ({ student_id, date }) =>
|
|
56
|
+
}, async ({ student_id, date }) => minifiedResult(await client.getPlanEdit(date, student_id)));
|
|
57
57
|
server.registerTool('pup_set_plan', {
|
|
58
58
|
description: "Change how a student is dismissed on one or more specific dates, or clear those dates back to the student's weekly default. This changes how a child actually leaves school, so it requires confirm: true; without it you get a dry-run of the exact payload. Read pup_list_transportations first — options differ in whether they require a note, a car number or an early-dismissal time.",
|
|
59
59
|
inputSchema: {
|
|
@@ -131,7 +131,7 @@ export function registerPlanTools(server, client) {
|
|
|
131
131
|
};
|
|
132
132
|
}));
|
|
133
133
|
const failed = verification.filter((v) => !v.verified);
|
|
134
|
-
return
|
|
134
|
+
return minifiedResult({
|
|
135
135
|
action,
|
|
136
136
|
applied: verification,
|
|
137
137
|
verified: failed.length === 0,
|
package/dist/tools/school.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { minifiedResult } from '@chrischall/mcp-utils';
|
|
3
3
|
/**
|
|
4
4
|
* Project a transportation to its identity plus the rules that decide what a
|
|
5
5
|
* plan using it must carry — an agent choosing an option needs those rules up
|
|
@@ -32,7 +32,7 @@ export function registerSchoolTools(server, client) {
|
|
|
32
32
|
}, async ({ school_id, include_inactive }) => {
|
|
33
33
|
const options = await client.getTransportations(school_id);
|
|
34
34
|
const visible = include_inactive === true ? options : options.filter((o) => o.IsActive !== false);
|
|
35
|
-
return
|
|
35
|
+
return minifiedResult(visible.map(summarizeTransportation));
|
|
36
36
|
});
|
|
37
37
|
server.registerTool('pup_get_school', {
|
|
38
38
|
description: 'A school profile together with its per-weekday notify times and plan cutoff times, and the settings that decide whether parents may set plans at all.',
|
|
@@ -46,7 +46,7 @@ export function registerSchoolTools(server, client) {
|
|
|
46
46
|
client.getSchoolNotifyTimes(school_id),
|
|
47
47
|
client.getSchoolSettings(school_id),
|
|
48
48
|
]);
|
|
49
|
-
return
|
|
49
|
+
return minifiedResult({ school, notifyTimes, settings });
|
|
50
50
|
});
|
|
51
51
|
server.registerTool('pup_list_non_school_days', {
|
|
52
52
|
description: 'Dates a plan cannot be set for at a school (holidays, closures, weekends), and optionally the dates in a range that already differ from the student defaults.',
|
|
@@ -62,10 +62,10 @@ export function registerSchoolTools(server, client) {
|
|
|
62
62
|
}, async ({ school_id, start_date, end_date }) => {
|
|
63
63
|
const invalidDates = await client.getInvalidPlanDates(school_id);
|
|
64
64
|
if (start_date === undefined || end_date === undefined) {
|
|
65
|
-
return
|
|
65
|
+
return minifiedResult({ invalidDates });
|
|
66
66
|
}
|
|
67
67
|
const changedDates = await client.getBoldedDates(start_date, end_date);
|
|
68
|
-
return
|
|
68
|
+
return minifiedResult({ invalidDates, changedDates });
|
|
69
69
|
});
|
|
70
70
|
server.registerTool('pup_list_car_numbers', {
|
|
71
71
|
description: 'The car numbers a school has issued to this account, for dismissal options where usesCarNumbers is true.',
|
|
@@ -73,5 +73,5 @@ export function registerSchoolTools(server, client) {
|
|
|
73
73
|
inputSchema: {
|
|
74
74
|
school_id: z.number().int().describe('School id, from pup_list_students'),
|
|
75
75
|
},
|
|
76
|
-
}, async ({ school_id }) =>
|
|
76
|
+
}, async ({ school_id }) => minifiedResult(await client.getCarNumbers(school_id)));
|
|
77
77
|
}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/mint.yaml
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
name: PickUp Patrol
|
|
3
|
+
slug: pickuppatrol
|
|
4
|
+
summary: >-
|
|
5
|
+
Read and change your children's school dismissal plans in PickUp Patrol —
|
|
6
|
+
defaults, day-by-day changes and school cutoff times
|
|
7
|
+
env:
|
|
8
|
+
- name: PICKUPPATROL_USERNAME
|
|
9
|
+
required: false
|
|
10
|
+
help: >-
|
|
11
|
+
The email address you sign in to app.pickuppatrol.net with.
|
|
12
|
+
- name: PICKUPPATROL_PASSWORD
|
|
13
|
+
secret: true
|
|
14
|
+
required: false
|
|
15
|
+
help: >-
|
|
16
|
+
Your PickUp Patrol password. Stored by the host, never logged by this
|
|
17
|
+
server.
|
|
18
|
+
egress:
|
|
19
|
+
allow:
|
|
20
|
+
# Only hosts the SERVER process actually fetches. Hosts that appear
|
|
21
|
+
# solely in a URL this server BUILDS and returns are excluded.
|
|
22
|
+
- app.pickuppatrol.net
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrischall/pickuppatrol-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"mcpName": "io.github.chrischall/pickuppatrol-mcp",
|
|
6
6
|
"description": "PickUp Patrol MCP server for Claude — developed and maintained by AI (Claude Code)",
|
|
@@ -44,19 +44,20 @@
|
|
|
44
44
|
".claude-plugin",
|
|
45
45
|
"skills",
|
|
46
46
|
".mcp.json",
|
|
47
|
-
"server.json"
|
|
47
|
+
"server.json",
|
|
48
|
+
"mint.yaml"
|
|
48
49
|
],
|
|
49
50
|
"scripts": {
|
|
50
51
|
"build": "tsc && npm run bundle",
|
|
51
52
|
"bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --external:dotenv --outfile=dist/bundle.js",
|
|
52
53
|
"dev": "node dist/index.js",
|
|
53
54
|
"typecheck": "tsc --noEmit",
|
|
54
|
-
"test": "vitest run",
|
|
55
|
-
"test:coverage": "vitest run --coverage",
|
|
55
|
+
"test": "npm run typecheck && vitest run",
|
|
56
|
+
"test:coverage": "npm run typecheck && vitest run --coverage",
|
|
56
57
|
"test:watch": "vitest"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
|
-
"@chrischall/mcp-utils": "^0.
|
|
60
|
+
"@chrischall/mcp-utils": "^0.23.0",
|
|
60
61
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
61
62
|
"dotenv": "^17.4.0",
|
|
62
63
|
"zod": "^4.4.3"
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/pickuppatrol-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.2.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@chrischall/pickuppatrol-mcp",
|
|
14
|
-
"version": "0.
|
|
14
|
+
"version": "0.2.0",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
}
|