@casys/mcp-erpnext 3.0.2 → 3.1.0-beta.1
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/README.md +42 -31
- package/mcp-erpnext.mjs +1799 -493
- package/package.json +1 -1
- package/ui-dist/chart-viewer/index.html +57 -99
- package/ui-dist/doclist-viewer/index.html +43 -82
- package/ui-dist/funnel-viewer/index.html +41 -80
- package/ui-dist/invoice-viewer/index.html +41 -80
- package/ui-dist/kanban-viewer/index.html +41 -80
- package/ui-dist/kpi-viewer/index.html +41 -80
- package/ui-dist/stock-viewer/index.html +41 -80
package/mcp-erpnext.mjs
CHANGED
|
@@ -3117,7 +3117,25 @@ var require_utils2 = __commonJS({
|
|
|
3117
3117
|
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);
|
|
3118
3118
|
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
3119
3119
|
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
3120
|
-
var isPathCharacter = RegExp.prototype.test.bind(/^[
|
|
3120
|
+
var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
|
|
3121
|
+
var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
|
|
3122
|
+
var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
|
|
3123
|
+
var BYTE_HEX = new Array(256);
|
|
3124
|
+
{
|
|
3125
|
+
const HEX_DIGITS = "0123456789ABCDEF";
|
|
3126
|
+
for (let i = 0; i < 256; i++) {
|
|
3127
|
+
BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
function percentEncodeNonAscii(cp) {
|
|
3131
|
+
if (cp < 2048) {
|
|
3132
|
+
return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
|
|
3133
|
+
}
|
|
3134
|
+
if (cp < 65536) {
|
|
3135
|
+
return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
3136
|
+
}
|
|
3137
|
+
return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
3138
|
+
}
|
|
3121
3139
|
function stringArrayToHexStripped(input) {
|
|
3122
3140
|
let acc = "";
|
|
3123
3141
|
let code = 0;
|
|
@@ -3142,91 +3160,105 @@ var require_utils2 = __commonJS({
|
|
|
3142
3160
|
}
|
|
3143
3161
|
return acc;
|
|
3144
3162
|
}
|
|
3163
|
+
var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
|
|
3164
|
+
var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
|
|
3165
|
+
var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
|
|
3145
3166
|
var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
|
|
3146
|
-
function
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
if (hex !== "") {
|
|
3154
|
-
address.push(hex);
|
|
3155
|
-
} else {
|
|
3156
|
-
output.error = true;
|
|
3157
|
-
return false;
|
|
3167
|
+
function isZoneIdentifier(zone) {
|
|
3168
|
+
if (zone.length === 0) return false;
|
|
3169
|
+
for (let i = 0; i < zone.length; i++) {
|
|
3170
|
+
if (isZoneCharacter(zone[i])) continue;
|
|
3171
|
+
if (zone[i] === "%" && i + 2 < zone.length && isHexPair(zone.slice(i + 1, i + 3))) {
|
|
3172
|
+
i += 2;
|
|
3173
|
+
continue;
|
|
3158
3174
|
}
|
|
3159
|
-
|
|
3175
|
+
return false;
|
|
3160
3176
|
}
|
|
3161
3177
|
return true;
|
|
3162
3178
|
}
|
|
3163
|
-
function
|
|
3164
|
-
let
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
let
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
}
|
|
3176
|
-
if (cursor === ":") {
|
|
3177
|
-
if (endipv6Encountered === true) {
|
|
3178
|
-
endIpv6 = true;
|
|
3179
|
+
function compressIPv6ZeroRun(hextets) {
|
|
3180
|
+
let bestStart = -1;
|
|
3181
|
+
let bestLength = 0;
|
|
3182
|
+
let runStart = -1;
|
|
3183
|
+
let runLength = 0;
|
|
3184
|
+
for (let i = 0; i < hextets.length; i++) {
|
|
3185
|
+
if (hextets[i] === "0") {
|
|
3186
|
+
if (runStart === -1) runStart = i;
|
|
3187
|
+
runLength++;
|
|
3188
|
+
if (runLength > bestLength) {
|
|
3189
|
+
bestLength = runLength;
|
|
3190
|
+
bestStart = runStart;
|
|
3179
3191
|
}
|
|
3180
|
-
if (!consume(buffer, address, output)) {
|
|
3181
|
-
break;
|
|
3182
|
-
}
|
|
3183
|
-
if (++tokenCount > 7) {
|
|
3184
|
-
output.error = true;
|
|
3185
|
-
break;
|
|
3186
|
-
}
|
|
3187
|
-
if (i > 0 && input[i - 1] === ":") {
|
|
3188
|
-
endipv6Encountered = true;
|
|
3189
|
-
}
|
|
3190
|
-
address.push(":");
|
|
3191
|
-
continue;
|
|
3192
|
-
} else if (cursor === "%") {
|
|
3193
|
-
if (!consume(buffer, address, output)) {
|
|
3194
|
-
break;
|
|
3195
|
-
}
|
|
3196
|
-
consume = consumeIsZone;
|
|
3197
3192
|
} else {
|
|
3198
|
-
|
|
3193
|
+
runStart = -1;
|
|
3194
|
+
runLength = 0;
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
if (bestLength < 2) return hextets.join(":");
|
|
3198
|
+
const head = hextets.slice(0, bestStart).join(":");
|
|
3199
|
+
const tail = hextets.slice(bestStart + bestLength).join(":");
|
|
3200
|
+
return head + "::" + tail;
|
|
3201
|
+
}
|
|
3202
|
+
function normalizeIPv6Address(input) {
|
|
3203
|
+
const compression = input.indexOf("::");
|
|
3204
|
+
if (compression !== -1 && input.indexOf("::", compression + 1) !== -1) return void 0;
|
|
3205
|
+
const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
|
|
3206
|
+
const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
|
|
3207
|
+
if (compression !== -1) {
|
|
3208
|
+
if (left.length === 1 && left[0] === "") left.length = 0;
|
|
3209
|
+
if (right.length === 1 && right[0] === "") right.length = 0;
|
|
3210
|
+
}
|
|
3211
|
+
const parts = left.concat(right);
|
|
3212
|
+
let hextetCount = 0;
|
|
3213
|
+
for (let i = 0; i < parts.length; i++) {
|
|
3214
|
+
const part = parts[i];
|
|
3215
|
+
if (part === "") return void 0;
|
|
3216
|
+
if (part.indexOf(".") !== -1) {
|
|
3217
|
+
if (i !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part)) return void 0;
|
|
3218
|
+
hextetCount += 2;
|
|
3199
3219
|
continue;
|
|
3200
3220
|
}
|
|
3221
|
+
if (!isHextet(part)) return void 0;
|
|
3222
|
+
parts[i] = parseInt(part, 16).toString(16);
|
|
3223
|
+
hextetCount++;
|
|
3201
3224
|
}
|
|
3202
|
-
if (
|
|
3203
|
-
if (
|
|
3204
|
-
|
|
3205
|
-
} else if (endIpv6) {
|
|
3206
|
-
address.push(buffer.join(""));
|
|
3207
|
-
} else {
|
|
3208
|
-
address.push(stringArrayToHexStripped(buffer));
|
|
3209
|
-
}
|
|
3225
|
+
if (compression === -1) {
|
|
3226
|
+
if (hextetCount !== 8) return void 0;
|
|
3227
|
+
return compressIPv6ZeroRun(parts);
|
|
3210
3228
|
}
|
|
3211
|
-
|
|
3212
|
-
|
|
3229
|
+
if (hextetCount >= 8) return void 0;
|
|
3230
|
+
const expanded = parts.slice(0, left.length);
|
|
3231
|
+
for (let i = hextetCount; i < 8; i++) expanded.push("0");
|
|
3232
|
+
for (let i = left.length; i < parts.length; i++) expanded.push(parts[i]);
|
|
3233
|
+
return compressIPv6ZeroRun(expanded);
|
|
3213
3234
|
}
|
|
3214
3235
|
function normalizeIPv6(host) {
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
}
|
|
3218
|
-
|
|
3219
|
-
if (
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3236
|
+
const bracketed = host[0] === "[" && host[host.length - 1] === "]";
|
|
3237
|
+
const hasBracket = host[0] === "[" || host[host.length - 1] === "]";
|
|
3238
|
+
if (hasBracket && !bracketed) return { host, isIPV6: false, error: true };
|
|
3239
|
+
let input = bracketed ? host.slice(1, -1) : host;
|
|
3240
|
+
if (bracketed && isIPvFuture(input)) {
|
|
3241
|
+
input = input.toLowerCase();
|
|
3242
|
+
return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
|
|
3243
|
+
}
|
|
3244
|
+
if (findToken(input, ":") < 2) {
|
|
3245
|
+
return { host, isIPV6: false, error: bracketed };
|
|
3246
|
+
}
|
|
3247
|
+
let zoneIdentifier = "";
|
|
3248
|
+
const zoneSeparator = input.indexOf("%");
|
|
3249
|
+
if (zoneSeparator !== -1) {
|
|
3250
|
+
const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
|
|
3251
|
+
zoneIdentifier = input.slice(zoneSeparator + separatorLength);
|
|
3252
|
+
if (!isZoneIdentifier(zoneIdentifier)) return { host, isIPV6: false, error: true };
|
|
3253
|
+
input = input.slice(0, zoneSeparator);
|
|
3254
|
+
}
|
|
3255
|
+
const address = normalizeIPv6Address(input);
|
|
3256
|
+
if (address === void 0) return { host, isIPV6: false, error: true };
|
|
3257
|
+
return {
|
|
3258
|
+
host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
|
|
3259
|
+
escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
|
|
3260
|
+
isIPV6: true
|
|
3261
|
+
};
|
|
3230
3262
|
}
|
|
3231
3263
|
function findToken(str, token) {
|
|
3232
3264
|
let ind = 0;
|
|
@@ -3345,7 +3377,8 @@ var require_utils2 = __commonJS({
|
|
|
3345
3377
|
function normalizePathEncoding(input) {
|
|
3346
3378
|
let output = "";
|
|
3347
3379
|
for (let i = 0; i < input.length; i++) {
|
|
3348
|
-
|
|
3380
|
+
const ch = input[i];
|
|
3381
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3349
3382
|
const hex = input.slice(i + 1, i + 3);
|
|
3350
3383
|
if (isHexPair(hex)) {
|
|
3351
3384
|
const normalizedHex = hex.toUpperCase();
|
|
@@ -3359,10 +3392,152 @@ var require_utils2 = __commonJS({
|
|
|
3359
3392
|
continue;
|
|
3360
3393
|
}
|
|
3361
3394
|
}
|
|
3362
|
-
if (isPathCharacter(
|
|
3363
|
-
output +=
|
|
3395
|
+
if (isPathCharacter(ch)) {
|
|
3396
|
+
output += ch;
|
|
3397
|
+
} else {
|
|
3398
|
+
const code = input.charCodeAt(i);
|
|
3399
|
+
if (code < 128) {
|
|
3400
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
3401
|
+
} else if (code < 55296 || code > 57343) {
|
|
3402
|
+
output += percentEncodeNonAscii(code);
|
|
3403
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
3404
|
+
const low = input.charCodeAt(i + 1);
|
|
3405
|
+
if (low >= 56320 && low <= 57343) {
|
|
3406
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
3407
|
+
i++;
|
|
3408
|
+
} else {
|
|
3409
|
+
output += percentEncodeNonAscii(65533);
|
|
3410
|
+
}
|
|
3411
|
+
} else {
|
|
3412
|
+
output += percentEncodeNonAscii(65533);
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
}
|
|
3416
|
+
return output;
|
|
3417
|
+
}
|
|
3418
|
+
function serializePathEncoding(input, pathNoScheme = false) {
|
|
3419
|
+
let output = "";
|
|
3420
|
+
let firstSegment = pathNoScheme && input[0] !== "/";
|
|
3421
|
+
for (let i = 0; i < input.length; i++) {
|
|
3422
|
+
const ch = input[i];
|
|
3423
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3424
|
+
const hex = input.slice(i + 1, i + 3);
|
|
3425
|
+
if (isHexPair(hex)) {
|
|
3426
|
+
output += "%" + hex.toUpperCase();
|
|
3427
|
+
i += 2;
|
|
3428
|
+
continue;
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
if (ch === "/") {
|
|
3432
|
+
firstSegment = false;
|
|
3433
|
+
}
|
|
3434
|
+
if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) {
|
|
3435
|
+
output += ch;
|
|
3364
3436
|
} else {
|
|
3365
|
-
|
|
3437
|
+
const code = input.charCodeAt(i);
|
|
3438
|
+
if (code < 128) {
|
|
3439
|
+
output += BYTE_HEX[code];
|
|
3440
|
+
} else if (code < 55296 || code > 57343) {
|
|
3441
|
+
output += percentEncodeNonAscii(code);
|
|
3442
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
3443
|
+
const low = input.charCodeAt(i + 1);
|
|
3444
|
+
if (low >= 56320 && low <= 57343) {
|
|
3445
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
3446
|
+
i++;
|
|
3447
|
+
} else {
|
|
3448
|
+
output += percentEncodeNonAscii(65533);
|
|
3449
|
+
}
|
|
3450
|
+
} else {
|
|
3451
|
+
output += percentEncodeNonAscii(65533);
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
return output;
|
|
3456
|
+
}
|
|
3457
|
+
function encodeComponent(input, isAllowed) {
|
|
3458
|
+
let output = "";
|
|
3459
|
+
for (let i = 0; i < input.length; i++) {
|
|
3460
|
+
const ch = input[i];
|
|
3461
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3462
|
+
const hex = input.slice(i + 1, i + 3);
|
|
3463
|
+
if (isHexPair(hex)) {
|
|
3464
|
+
output += "%" + hex.toUpperCase();
|
|
3465
|
+
i += 2;
|
|
3466
|
+
continue;
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
if (isAllowed(ch)) {
|
|
3470
|
+
output += ch;
|
|
3471
|
+
} else {
|
|
3472
|
+
const code = input.charCodeAt(i);
|
|
3473
|
+
if (code < 128) {
|
|
3474
|
+
output += BYTE_HEX[code];
|
|
3475
|
+
} else if (code < 55296 || code > 57343) {
|
|
3476
|
+
output += percentEncodeNonAscii(code);
|
|
3477
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
3478
|
+
const low = input.charCodeAt(i + 1);
|
|
3479
|
+
if (low >= 56320 && low <= 57343) {
|
|
3480
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
3481
|
+
i++;
|
|
3482
|
+
} else {
|
|
3483
|
+
output += percentEncodeNonAscii(65533);
|
|
3484
|
+
}
|
|
3485
|
+
} else {
|
|
3486
|
+
output += percentEncodeNonAscii(65533);
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
return output;
|
|
3491
|
+
}
|
|
3492
|
+
function encodeUserinfo(input) {
|
|
3493
|
+
return encodeComponent(input, isUserinfoCharacter);
|
|
3494
|
+
}
|
|
3495
|
+
function encodeQuery(input) {
|
|
3496
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
3497
|
+
}
|
|
3498
|
+
function encodeFragment(input) {
|
|
3499
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
3500
|
+
}
|
|
3501
|
+
function isEscapeSafe(cp) {
|
|
3502
|
+
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;
|
|
3503
|
+
}
|
|
3504
|
+
function normalizeQueryFragmentEncoding(input) {
|
|
3505
|
+
let output = "";
|
|
3506
|
+
for (let i = 0; i < input.length; i++) {
|
|
3507
|
+
const ch = input[i];
|
|
3508
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
3509
|
+
const hex = input.slice(i + 1, i + 3);
|
|
3510
|
+
if (isHexPair(hex)) {
|
|
3511
|
+
const normalizedHex = hex.toUpperCase();
|
|
3512
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3513
|
+
if (isUnreserved(decoded)) {
|
|
3514
|
+
output += decoded;
|
|
3515
|
+
} else {
|
|
3516
|
+
output += "%" + normalizedHex;
|
|
3517
|
+
}
|
|
3518
|
+
i += 2;
|
|
3519
|
+
continue;
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
if (isQueryFragmentCharacter(ch)) {
|
|
3523
|
+
output += ch;
|
|
3524
|
+
} else {
|
|
3525
|
+
const code = input.charCodeAt(i);
|
|
3526
|
+
if (code < 128) {
|
|
3527
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
3528
|
+
} else if (code < 55296 || code > 57343) {
|
|
3529
|
+
output += percentEncodeNonAscii(code);
|
|
3530
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
3531
|
+
const low = input.charCodeAt(i + 1);
|
|
3532
|
+
if (low >= 56320 && low <= 57343) {
|
|
3533
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
3534
|
+
i++;
|
|
3535
|
+
} else {
|
|
3536
|
+
output += percentEncodeNonAscii(65533);
|
|
3537
|
+
}
|
|
3538
|
+
} else {
|
|
3539
|
+
output += percentEncodeNonAscii(65533);
|
|
3540
|
+
}
|
|
3366
3541
|
}
|
|
3367
3542
|
}
|
|
3368
3543
|
return output;
|
|
@@ -3385,14 +3560,18 @@ var require_utils2 = __commonJS({
|
|
|
3385
3560
|
function recomposeAuthority(component) {
|
|
3386
3561
|
const uriTokens = [];
|
|
3387
3562
|
if (component.userinfo !== void 0) {
|
|
3388
|
-
uriTokens.push(component.userinfo);
|
|
3563
|
+
uriTokens.push(encodeUserinfo(component.userinfo));
|
|
3389
3564
|
uriTokens.push("@");
|
|
3390
3565
|
}
|
|
3391
3566
|
if (component.host !== void 0) {
|
|
3392
|
-
let host =
|
|
3567
|
+
let host = component.host;
|
|
3393
3568
|
if (!isIPv4(host)) {
|
|
3394
|
-
|
|
3395
|
-
if (ipV6res.isIPV6
|
|
3569
|
+
let ipV6res = normalizeIPv6(host);
|
|
3570
|
+
if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
|
|
3571
|
+
host = normalizePercentEncoding(host, true);
|
|
3572
|
+
ipV6res = normalizeIPv6(host);
|
|
3573
|
+
}
|
|
3574
|
+
if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
|
|
3396
3575
|
host = `[${ipV6res.escapedHost}]`;
|
|
3397
3576
|
} else {
|
|
3398
3577
|
host = reescapeHostDelimiters(host, false);
|
|
@@ -3412,6 +3591,11 @@ var require_utils2 = __commonJS({
|
|
|
3412
3591
|
reescapeHostDelimiters,
|
|
3413
3592
|
normalizePercentEncoding,
|
|
3414
3593
|
normalizePathEncoding,
|
|
3594
|
+
serializePathEncoding,
|
|
3595
|
+
normalizeQueryFragmentEncoding,
|
|
3596
|
+
encodeUserinfo,
|
|
3597
|
+
encodeQuery,
|
|
3598
|
+
encodeFragment,
|
|
3415
3599
|
escapePreservingEscapes,
|
|
3416
3600
|
removeDotSegments,
|
|
3417
3601
|
isIPv4,
|
|
@@ -3427,7 +3611,7 @@ var require_schemes2 = __commonJS({
|
|
|
3427
3611
|
"node_modules/fast-uri/lib/schemes.js"(exports, module) {
|
|
3428
3612
|
"use strict";
|
|
3429
3613
|
var { isUUID } = require_utils2();
|
|
3430
|
-
var URN_REG =
|
|
3614
|
+
var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
|
|
3431
3615
|
var supportedSchemeNames = (
|
|
3432
3616
|
/** @type {const} */
|
|
3433
3617
|
[
|
|
@@ -3488,9 +3672,10 @@ var require_schemes2 = __commonJS({
|
|
|
3488
3672
|
wsComponent.secure = void 0;
|
|
3489
3673
|
}
|
|
3490
3674
|
if (wsComponent.resourceName) {
|
|
3491
|
-
const
|
|
3675
|
+
const queryIndex = wsComponent.resourceName.indexOf("?");
|
|
3676
|
+
const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
|
|
3492
3677
|
wsComponent.path = path && path !== "/" ? path : void 0;
|
|
3493
|
-
wsComponent.query =
|
|
3678
|
+
wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
|
|
3494
3679
|
wsComponent.resourceName = void 0;
|
|
3495
3680
|
}
|
|
3496
3681
|
wsComponent.fragment = void 0;
|
|
@@ -3502,7 +3687,7 @@ var require_schemes2 = __commonJS({
|
|
|
3502
3687
|
return urnComponent;
|
|
3503
3688
|
}
|
|
3504
3689
|
const matches = urnComponent.path.match(URN_REG);
|
|
3505
|
-
if (matches) {
|
|
3690
|
+
if (matches && matches[0] === urnComponent.path) {
|
|
3506
3691
|
const scheme = options.scheme || urnComponent.scheme || "urn";
|
|
3507
3692
|
urnComponent.nid = matches[1].toLowerCase();
|
|
3508
3693
|
urnComponent.nss = matches[2];
|
|
@@ -3636,8 +3821,17 @@ var require_schemes2 = __commonJS({
|
|
|
3636
3821
|
var require_fast_uri2 = __commonJS({
|
|
3637
3822
|
"node_modules/fast-uri/index.js"(exports, module) {
|
|
3638
3823
|
"use strict";
|
|
3639
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding,
|
|
3824
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
|
|
3640
3825
|
var { SCHEMES, getSchemeHandler } = require_schemes2();
|
|
3826
|
+
var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
|
|
3827
|
+
var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
|
|
3828
|
+
function decodeValidScheme(scheme) {
|
|
3829
|
+
const decodedScheme = unescape(String(scheme));
|
|
3830
|
+
if (!VALID_SCHEME.test(decodedScheme)) {
|
|
3831
|
+
throw new TypeError(MALFORMED_SCHEME_ERROR);
|
|
3832
|
+
}
|
|
3833
|
+
return decodedScheme;
|
|
3834
|
+
}
|
|
3641
3835
|
function normalize2(uri, options) {
|
|
3642
3836
|
if (typeof uri === "string") {
|
|
3643
3837
|
uri = /** @type {T} */
|
|
@@ -3650,12 +3844,34 @@ var require_fast_uri2 = __commonJS({
|
|
|
3650
3844
|
}
|
|
3651
3845
|
function resolve(baseURI, relativeURI, options) {
|
|
3652
3846
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3653
|
-
const {
|
|
3654
|
-
|
|
3655
|
-
|
|
3847
|
+
const {
|
|
3848
|
+
parsed: baseParsed,
|
|
3849
|
+
malformedAuthorityOrPort: baseMalformed,
|
|
3850
|
+
malformedPercentEncoding: baseMalformedPercentEncoding,
|
|
3851
|
+
malformedSchemeSpecific: baseMalformedSchemeSpecific,
|
|
3852
|
+
malformedHost: baseMalformedHost,
|
|
3853
|
+
malformedScheme: baseMalformedScheme
|
|
3854
|
+
} = parseWithStatus(baseURI, schemelessOptions);
|
|
3855
|
+
const {
|
|
3856
|
+
parsed: relativeParsed,
|
|
3857
|
+
malformedAuthorityOrPort: relativeMalformed,
|
|
3858
|
+
malformedPercentEncoding: relativeMalformedPercentEncoding,
|
|
3859
|
+
malformedSchemeSpecific: relativeMalformedSchemeSpecific,
|
|
3860
|
+
malformedHost: relativeMalformedHost,
|
|
3861
|
+
malformedScheme: relativeMalformedScheme
|
|
3862
|
+
} = parseWithStatus(relativeURI, schemelessOptions);
|
|
3863
|
+
if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
|
|
3656
3864
|
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
3657
3865
|
}
|
|
3658
3866
|
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
3867
|
+
const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
|
|
3868
|
+
const resolvedHost = resolved.host;
|
|
3869
|
+
const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
|
|
3870
|
+
canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
|
|
3871
|
+
const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !new RegExp("\\P{ASCII}", "u").test(resolvedHost);
|
|
3872
|
+
if (resolved.error && !encodedASCIIHost) {
|
|
3873
|
+
throw new Error(resolved.error);
|
|
3874
|
+
}
|
|
3659
3875
|
schemelessOptions.skipEscape = true;
|
|
3660
3876
|
return serialize(resolved, schemelessOptions);
|
|
3661
3877
|
}
|
|
@@ -3715,7 +3931,7 @@ var require_fast_uri2 = __commonJS({
|
|
|
3715
3931
|
function equal(uriA, uriB, options) {
|
|
3716
3932
|
const normalizedA = normalizeComparableURI(uriA, options);
|
|
3717
3933
|
const normalizedB = normalizeComparableURI(uriB, options);
|
|
3718
|
-
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA
|
|
3934
|
+
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
|
|
3719
3935
|
}
|
|
3720
3936
|
function serialize(cmpts, opts) {
|
|
3721
3937
|
const component = {
|
|
@@ -3736,19 +3952,22 @@ var require_fast_uri2 = __commonJS({
|
|
|
3736
3952
|
};
|
|
3737
3953
|
const options = Object.assign({}, opts);
|
|
3738
3954
|
const uriTokens = [];
|
|
3955
|
+
if (component.scheme) {
|
|
3956
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
3957
|
+
}
|
|
3739
3958
|
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
|
|
3740
3959
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
3960
|
+
const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
|
|
3961
|
+
const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
|
|
3741
3962
|
if (component.path !== void 0) {
|
|
3742
3963
|
if (!options.skipEscape) {
|
|
3743
|
-
component.path =
|
|
3744
|
-
if (component.scheme !== void 0) {
|
|
3745
|
-
component.path = component.path.split("%3A").join(":");
|
|
3746
|
-
}
|
|
3964
|
+
component.path = serializePathEncoding(component.path, pathNoScheme);
|
|
3747
3965
|
} else {
|
|
3748
3966
|
component.path = normalizePercentEncoding(component.path);
|
|
3749
3967
|
}
|
|
3750
3968
|
}
|
|
3751
3969
|
if (options.reference !== "suffix" && component.scheme) {
|
|
3970
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
3752
3971
|
uriTokens.push(component.scheme, ":");
|
|
3753
3972
|
}
|
|
3754
3973
|
const authority = recomposeAuthority(component);
|
|
@@ -3766,16 +3985,19 @@ var require_fast_uri2 = __commonJS({
|
|
|
3766
3985
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
|
|
3767
3986
|
s = removeDotSegments(s);
|
|
3768
3987
|
}
|
|
3988
|
+
if (pathNoScheme) {
|
|
3989
|
+
s = serializePathEncoding(s, true);
|
|
3990
|
+
}
|
|
3769
3991
|
if (authority === void 0 && s[0] === "/" && s[1] === "/") {
|
|
3770
3992
|
s = "/%2F" + s.slice(2);
|
|
3771
3993
|
}
|
|
3772
3994
|
uriTokens.push(s);
|
|
3773
3995
|
}
|
|
3774
3996
|
if (component.query !== void 0) {
|
|
3775
|
-
uriTokens.push("?", component.query);
|
|
3997
|
+
uriTokens.push("?", encodeQuery(component.query));
|
|
3776
3998
|
}
|
|
3777
3999
|
if (component.fragment !== void 0) {
|
|
3778
|
-
uriTokens.push("#", component.fragment);
|
|
4000
|
+
uriTokens.push("#", encodeFragment(component.fragment));
|
|
3779
4001
|
}
|
|
3780
4002
|
return uriTokens.join("");
|
|
3781
4003
|
}
|
|
@@ -3791,6 +4013,32 @@ var require_fast_uri2 = __commonJS({
|
|
|
3791
4013
|
}
|
|
3792
4014
|
return void 0;
|
|
3793
4015
|
}
|
|
4016
|
+
function hasMalformedPercentEncoding(component) {
|
|
4017
|
+
if (component === void 0) return false;
|
|
4018
|
+
let percent = component.indexOf("%");
|
|
4019
|
+
while (percent !== -1) {
|
|
4020
|
+
if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
|
|
4021
|
+
return true;
|
|
4022
|
+
}
|
|
4023
|
+
percent = component.indexOf("%", percent + 3);
|
|
4024
|
+
}
|
|
4025
|
+
return false;
|
|
4026
|
+
}
|
|
4027
|
+
function hasMalformedComponentPercentEncoding(matches) {
|
|
4028
|
+
const host = matches[4];
|
|
4029
|
+
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !(host[0] === "[" && host[host.length - 1] === "]") && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
|
|
4030
|
+
}
|
|
4031
|
+
function canonicalizeHost(parsed, options, schemeHandler, isIP) {
|
|
4032
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host[0] !== "[" && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
4033
|
+
try {
|
|
4034
|
+
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
4035
|
+
} catch (e) {
|
|
4036
|
+
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
4037
|
+
return true;
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4040
|
+
return false;
|
|
4041
|
+
}
|
|
3794
4042
|
function parseWithStatus(uri, opts) {
|
|
3795
4043
|
const options = Object.assign({}, opts);
|
|
3796
4044
|
const parsed = {
|
|
@@ -3803,6 +4051,11 @@ var require_fast_uri2 = __commonJS({
|
|
|
3803
4051
|
fragment: void 0
|
|
3804
4052
|
};
|
|
3805
4053
|
let malformedAuthorityOrPort = false;
|
|
4054
|
+
let malformedPercentEncoding = false;
|
|
4055
|
+
let malformedSchemeSpecific = false;
|
|
4056
|
+
let malformedHost = false;
|
|
4057
|
+
let malformedIPLiteral = false;
|
|
4058
|
+
let malformedScheme = false;
|
|
3806
4059
|
let isIP = false;
|
|
3807
4060
|
if (options.reference === "suffix") {
|
|
3808
4061
|
if (options.scheme) {
|
|
@@ -3839,6 +4092,19 @@ var require_fast_uri2 = __commonJS({
|
|
|
3839
4092
|
parsed.path = matches[6] || "";
|
|
3840
4093
|
parsed.query = matches[7];
|
|
3841
4094
|
parsed.fragment = matches[8];
|
|
4095
|
+
if (parsed.scheme !== void 0) {
|
|
4096
|
+
const decodedScheme = unescape(parsed.scheme);
|
|
4097
|
+
if (VALID_SCHEME.test(decodedScheme)) {
|
|
4098
|
+
parsed.scheme = decodedScheme.toLowerCase();
|
|
4099
|
+
} else {
|
|
4100
|
+
parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
|
|
4101
|
+
malformedScheme = true;
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
4104
|
+
malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
|
|
4105
|
+
if (malformedPercentEncoding) {
|
|
4106
|
+
parsed.error = parsed.error || "URI contains malformed percent-encoding.";
|
|
4107
|
+
}
|
|
3842
4108
|
if (isNaN(parsed.port)) {
|
|
3843
4109
|
parsed.port = matches[5];
|
|
3844
4110
|
}
|
|
@@ -3850,9 +4116,15 @@ var require_fast_uri2 = __commonJS({
|
|
|
3850
4116
|
if (parsed.host) {
|
|
3851
4117
|
const ipv4result = isIPv4(parsed.host);
|
|
3852
4118
|
if (ipv4result === false) {
|
|
4119
|
+
const bracketedIPLiteral = parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
|
|
3853
4120
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
3854
|
-
|
|
3855
|
-
|
|
4121
|
+
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
4122
|
+
malformedIPLiteral = bracketedIPLiteral && ipv6result.error === true;
|
|
4123
|
+
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
4124
|
+
if (malformedIPLiteral) {
|
|
4125
|
+
parsed.error = parsed.error || "URI host is malformed.";
|
|
4126
|
+
malformedAuthorityOrPort = true;
|
|
4127
|
+
}
|
|
3856
4128
|
} else {
|
|
3857
4129
|
isIP = true;
|
|
3858
4130
|
}
|
|
@@ -3870,42 +4142,34 @@ var require_fast_uri2 = __commonJS({
|
|
|
3870
4142
|
parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
|
|
3871
4143
|
}
|
|
3872
4144
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
3873
|
-
|
|
3874
|
-
if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
3875
|
-
try {
|
|
3876
|
-
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
3877
|
-
} catch (e) {
|
|
3878
|
-
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
3879
|
-
}
|
|
3880
|
-
}
|
|
3881
|
-
}
|
|
4145
|
+
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
3882
4146
|
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
3883
4147
|
if (uri.indexOf("%") !== -1) {
|
|
3884
|
-
if (parsed.
|
|
3885
|
-
parsed.
|
|
3886
|
-
|
|
3887
|
-
if (parsed.host !== void 0) {
|
|
3888
|
-
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
|
|
4148
|
+
if (parsed.host !== void 0 && !malformedIPLiteral) {
|
|
4149
|
+
const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4150
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
3889
4151
|
}
|
|
3890
4152
|
}
|
|
3891
4153
|
if (parsed.path) {
|
|
3892
4154
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
3893
4155
|
}
|
|
4156
|
+
if (parsed.query) {
|
|
4157
|
+
parsed.query = normalizeQueryFragmentEncoding(parsed.query);
|
|
4158
|
+
}
|
|
3894
4159
|
if (parsed.fragment) {
|
|
3895
|
-
|
|
3896
|
-
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
3897
|
-
} catch {
|
|
3898
|
-
parsed.error = parsed.error || "URI malformed";
|
|
3899
|
-
}
|
|
4160
|
+
parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
|
|
3900
4161
|
}
|
|
3901
4162
|
}
|
|
3902
4163
|
if (schemeHandler && schemeHandler.parse) {
|
|
3903
4164
|
schemeHandler.parse(parsed, options);
|
|
4165
|
+
if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) {
|
|
4166
|
+
malformedSchemeSpecific = true;
|
|
4167
|
+
}
|
|
3904
4168
|
}
|
|
3905
4169
|
} else {
|
|
3906
4170
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
3907
4171
|
}
|
|
3908
|
-
return { parsed, malformedAuthorityOrPort };
|
|
4172
|
+
return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
|
|
3909
4173
|
}
|
|
3910
4174
|
function parse3(uri, opts) {
|
|
3911
4175
|
return parseWithStatus(uri, opts).parsed;
|
|
@@ -3914,20 +4178,28 @@ var require_fast_uri2 = __commonJS({
|
|
|
3914
4178
|
return normalizeStringWithStatus(uri, opts).normalized;
|
|
3915
4179
|
}
|
|
3916
4180
|
function normalizeStringWithStatus(uri, opts) {
|
|
3917
|
-
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
4181
|
+
const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
|
|
3918
4182
|
return {
|
|
3919
|
-
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
3920
|
-
malformedAuthorityOrPort
|
|
4183
|
+
normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
|
|
4184
|
+
malformedAuthorityOrPort,
|
|
4185
|
+
malformedPercentEncoding,
|
|
4186
|
+
malformedSchemeSpecific,
|
|
4187
|
+
malformedHost,
|
|
4188
|
+
malformedScheme
|
|
3921
4189
|
};
|
|
3922
4190
|
}
|
|
3923
4191
|
function normalizeComparableURI(uri, opts) {
|
|
3924
|
-
if (typeof uri
|
|
3925
|
-
|
|
3926
|
-
return malformedAuthorityOrPort ? void 0 : normalized;
|
|
4192
|
+
if (typeof uri !== "string" && typeof uri !== "object") {
|
|
4193
|
+
return void 0;
|
|
3927
4194
|
}
|
|
3928
|
-
|
|
3929
|
-
|
|
4195
|
+
let value;
|
|
4196
|
+
try {
|
|
4197
|
+
value = typeof uri === "string" ? uri : serialize(uri, opts);
|
|
4198
|
+
} catch {
|
|
4199
|
+
return void 0;
|
|
3930
4200
|
}
|
|
4201
|
+
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
|
|
4202
|
+
return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
|
|
3931
4203
|
}
|
|
3932
4204
|
var fastUri = {
|
|
3933
4205
|
SCHEMES,
|
|
@@ -37072,13 +37344,13 @@ var HonoRequest = class {
|
|
|
37072
37344
|
return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
|
|
37073
37345
|
}
|
|
37074
37346
|
#getDecodedParam(key) {
|
|
37075
|
-
const paramKey = this.#matchResult[0][this.routeIndex][1][key];
|
|
37347
|
+
const paramKey = this.#matchResult[0][this.routeIndex]?.[1][key];
|
|
37076
37348
|
const param = this.#getParamValue(paramKey);
|
|
37077
37349
|
return param && tryDecodeURIComponent(param);
|
|
37078
37350
|
}
|
|
37079
37351
|
#getAllDecodedParams() {
|
|
37080
37352
|
const decoded = {};
|
|
37081
|
-
const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
|
|
37353
|
+
const keys = Object.keys(this.#matchResult[0][this.routeIndex]?.[1] ?? {});
|
|
37082
37354
|
for (const key of keys) {
|
|
37083
37355
|
const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
|
|
37084
37356
|
if (value !== void 0) {
|
|
@@ -38165,6 +38437,9 @@ var Hono = class _Hono {
|
|
|
38165
38437
|
};
|
|
38166
38438
|
};
|
|
38167
38439
|
|
|
38440
|
+
// node_modules/hono/dist/router/utils.js
|
|
38441
|
+
var createNullObject = () => /* @__PURE__ */ Object.create(null);
|
|
38442
|
+
|
|
38168
38443
|
// node_modules/hono/dist/router/reg-exp-router/matcher.js
|
|
38169
38444
|
var emptyParam = [];
|
|
38170
38445
|
function match(method, path) {
|
|
@@ -38215,7 +38490,7 @@ var Node = class _Node {
|
|
|
38215
38490
|
// handler index of a dynamic path, or -1 for a static path terminal
|
|
38216
38491
|
#index;
|
|
38217
38492
|
#varIndex;
|
|
38218
|
-
#children =
|
|
38493
|
+
#children = createNullObject();
|
|
38219
38494
|
insert(tokens, index, paramMap, context2, isStatic) {
|
|
38220
38495
|
let node = this;
|
|
38221
38496
|
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
@@ -38299,7 +38574,7 @@ var Trie = class {
|
|
|
38299
38574
|
#root = new Node();
|
|
38300
38575
|
#index = 0;
|
|
38301
38576
|
// dynamic path -> [handler index, param assoc]; static paths are not registered
|
|
38302
|
-
paths =
|
|
38577
|
+
paths = createNullObject();
|
|
38303
38578
|
insert(path, isStatic) {
|
|
38304
38579
|
if (isStatic) {
|
|
38305
38580
|
this.#root.insert(path.split(""), 0, [], this.#context, true);
|
|
@@ -38358,22 +38633,16 @@ var Trie = class {
|
|
|
38358
38633
|
};
|
|
38359
38634
|
|
|
38360
38635
|
// node_modules/hono/dist/router/reg-exp-router/router.js
|
|
38361
|
-
var wildcardRegExpCache =
|
|
38636
|
+
var wildcardRegExpCache = createNullObject();
|
|
38362
38637
|
function buildWildcardRegExp(path) {
|
|
38363
38638
|
return wildcardRegExpCache[path] ??= new RegExp(
|
|
38364
|
-
|
|
38365
|
-
|
|
38366
|
-
(
|
|
38639
|
+
`^${path.replace(
|
|
38640
|
+
/\/:[^/{}]+(?:\{\[\^\/]\+})?(?=[/{]|$)|\/?\*$|([.\\+*[^\]$()?{}|])/g,
|
|
38641
|
+
(match2, metaChar) => metaChar ? `\\${metaChar}` : match2 === "/*" ? TAIL_WILDCARD_REG_EXP_STR : match2 === "*" ? ONLY_WILDCARD_REG_EXP_STR : `/:${LABEL_REG_EXP_STR}`
|
|
38367
38642
|
)}$`
|
|
38368
38643
|
);
|
|
38369
38644
|
}
|
|
38370
|
-
function clearWildcardRegExpCache() {
|
|
38371
|
-
wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
38372
|
-
}
|
|
38373
38645
|
function findMiddleware(middleware, path) {
|
|
38374
|
-
if (!middleware) {
|
|
38375
|
-
return void 0;
|
|
38376
|
-
}
|
|
38377
38646
|
for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
|
|
38378
38647
|
if (buildWildcardRegExp(k).test(path)) {
|
|
38379
38648
|
return [...middleware[k]];
|
|
@@ -38387,8 +38656,8 @@ var RegExpRouter = class {
|
|
|
38387
38656
|
#routes;
|
|
38388
38657
|
#tries;
|
|
38389
38658
|
constructor() {
|
|
38390
|
-
this.#middleware = { [METHOD_NAME_ALL]:
|
|
38391
|
-
this.#routes = { [METHOD_NAME_ALL]:
|
|
38659
|
+
this.#middleware = { [METHOD_NAME_ALL]: createNullObject() };
|
|
38660
|
+
this.#routes = { [METHOD_NAME_ALL]: createNullObject() };
|
|
38392
38661
|
this.#tries = { [METHOD_NAME_ALL]: new Trie() };
|
|
38393
38662
|
}
|
|
38394
38663
|
#insertPath(method, path) {
|
|
@@ -38401,117 +38670,86 @@ var RegExpRouter = class {
|
|
|
38401
38670
|
add(method, path, handler) {
|
|
38402
38671
|
const middleware = this.#middleware;
|
|
38403
38672
|
const routes = this.#routes;
|
|
38404
|
-
if (!middleware
|
|
38673
|
+
if (!middleware) {
|
|
38405
38674
|
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
|
|
38406
38675
|
}
|
|
38407
38676
|
if (!middleware[method]) {
|
|
38408
38677
|
this.#tries[method] = new Trie();
|
|
38409
|
-
[middleware, routes]
|
|
38410
|
-
handlerMap[method] =
|
|
38411
|
-
|
|
38678
|
+
for (const handlerMap of [middleware, routes]) {
|
|
38679
|
+
handlerMap[method] = createNullObject();
|
|
38680
|
+
for (const p in handlerMap[METHOD_NAME_ALL]) {
|
|
38412
38681
|
handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];
|
|
38413
38682
|
this.#insertPath(method, p);
|
|
38414
|
-
}
|
|
38415
|
-
}
|
|
38683
|
+
}
|
|
38684
|
+
}
|
|
38416
38685
|
}
|
|
38417
38686
|
if (path === "/*") {
|
|
38418
38687
|
path = "*";
|
|
38419
38688
|
}
|
|
38420
|
-
const
|
|
38689
|
+
const methods = method === METHOD_NAME_ALL ? Object.keys(middleware) : [method];
|
|
38421
38690
|
if (/\*$/.test(path)) {
|
|
38422
38691
|
const re2 = buildWildcardRegExp(path);
|
|
38423
|
-
|
|
38424
|
-
if (
|
|
38692
|
+
for (const m of methods) {
|
|
38693
|
+
if (!middleware[m][path]) {
|
|
38425
38694
|
this.#insertPath(m, path);
|
|
38426
38695
|
middleware[m][path] = findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
|
|
38427
38696
|
}
|
|
38428
|
-
}
|
|
38429
|
-
|
|
38430
|
-
|
|
38431
|
-
|
|
38432
|
-
re2.test(p) &&
|
|
38433
|
-
}
|
|
38434
|
-
}
|
|
38435
|
-
});
|
|
38436
|
-
Object.keys(routes).forEach((m) => {
|
|
38437
|
-
if (method === METHOD_NAME_ALL || method === m) {
|
|
38438
|
-
Object.keys(routes[m]).forEach(
|
|
38439
|
-
(p) => re2.test(p) && routes[m][p].push([handler, paramCount])
|
|
38440
|
-
);
|
|
38697
|
+
}
|
|
38698
|
+
for (const handlerMap of [middleware, routes]) {
|
|
38699
|
+
for (const m of methods) {
|
|
38700
|
+
for (const p in handlerMap[m]) {
|
|
38701
|
+
re2.test(p) && handlerMap[m][p].push([handler, path]);
|
|
38702
|
+
}
|
|
38441
38703
|
}
|
|
38442
|
-
}
|
|
38704
|
+
}
|
|
38443
38705
|
return;
|
|
38444
38706
|
}
|
|
38445
38707
|
const paths = checkOptionalParameter(path) || [path];
|
|
38446
|
-
for (
|
|
38447
|
-
const
|
|
38448
|
-
|
|
38449
|
-
|
|
38450
|
-
|
|
38451
|
-
this.#insertPath(m, path2);
|
|
38452
|
-
routes[m][path2] = [
|
|
38453
|
-
...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []
|
|
38454
|
-
];
|
|
38455
|
-
}
|
|
38456
|
-
routes[m][path2].push([handler, paramCount - len + i + 1]);
|
|
38708
|
+
for (const path2 of paths) {
|
|
38709
|
+
for (const m of methods) {
|
|
38710
|
+
if (!routes[m][path2]) {
|
|
38711
|
+
this.#insertPath(m, path2);
|
|
38712
|
+
routes[m][path2] = findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || [];
|
|
38457
38713
|
}
|
|
38458
|
-
|
|
38714
|
+
routes[m][path2].push([handler, path2]);
|
|
38715
|
+
}
|
|
38459
38716
|
}
|
|
38460
38717
|
}
|
|
38461
38718
|
match = match;
|
|
38462
38719
|
buildAllMatchers() {
|
|
38463
|
-
const matchers =
|
|
38464
|
-
Object.keys(this.#routes)
|
|
38465
|
-
matchers[method]
|
|
38466
|
-
}
|
|
38720
|
+
const matchers = createNullObject();
|
|
38721
|
+
for (const method of Object.keys(this.#routes)) {
|
|
38722
|
+
matchers[method] = this.#buildMatcher(method);
|
|
38723
|
+
}
|
|
38467
38724
|
this.#middleware = this.#routes = this.#tries = void 0;
|
|
38468
|
-
|
|
38725
|
+
wildcardRegExpCache = createNullObject();
|
|
38469
38726
|
return matchers;
|
|
38470
38727
|
}
|
|
38471
38728
|
#buildMatcher(method) {
|
|
38472
38729
|
const middleware = this.#middleware[method];
|
|
38473
38730
|
const routes = this.#routes[method];
|
|
38474
38731
|
const trie = this.#tries[method];
|
|
38475
|
-
const staticMap =
|
|
38732
|
+
const staticMap = createNullObject();
|
|
38476
38733
|
const handlerData = [];
|
|
38477
|
-
[
|
|
38734
|
+
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
38735
|
+
for (const r of [middleware, routes]) {
|
|
38478
38736
|
for (const path in r) {
|
|
38479
38737
|
const handlers = r[path];
|
|
38480
38738
|
const pathData = trie.paths[path];
|
|
38481
38739
|
if (!pathData) {
|
|
38482
|
-
staticMap[path] = [handlers.map(([h]) => [h,
|
|
38483
|
-
continue;
|
|
38484
|
-
}
|
|
38485
|
-
const paramAssoc = pathData[1];
|
|
38486
|
-
handlerData[pathData[0]] = handlers.map(([h, paramCount]) => {
|
|
38487
|
-
const paramIndexMap = /* @__PURE__ */ Object.create(null);
|
|
38488
|
-
paramCount -= 1;
|
|
38489
|
-
for (; paramCount >= 0; paramCount--) {
|
|
38490
|
-
const [key, value] = paramAssoc[paramCount];
|
|
38491
|
-
paramIndexMap[key] = value;
|
|
38492
|
-
}
|
|
38493
|
-
return [h, paramIndexMap];
|
|
38494
|
-
});
|
|
38495
|
-
}
|
|
38496
|
-
});
|
|
38497
|
-
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
38498
|
-
for (let i = 0, len = handlerData.length; i < len; i++) {
|
|
38499
|
-
for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
|
|
38500
|
-
const map = handlerData[i][j]?.[1];
|
|
38501
|
-
if (!map) {
|
|
38740
|
+
staticMap[path] = [handlers.map(([h]) => [h, createNullObject()]), emptyParam];
|
|
38502
38741
|
continue;
|
|
38503
38742
|
}
|
|
38504
|
-
|
|
38505
|
-
|
|
38506
|
-
|
|
38507
|
-
|
|
38743
|
+
handlerData[pathData[0]] = handlers.map(([h, handlerPath]) => [
|
|
38744
|
+
h,
|
|
38745
|
+
trie.paths[handlerPath][1].reduceRight((map, [key], i) => {
|
|
38746
|
+
map[key] = paramReplacementMap[pathData[1][i][1]];
|
|
38747
|
+
return map;
|
|
38748
|
+
}, createNullObject())
|
|
38749
|
+
]);
|
|
38508
38750
|
}
|
|
38509
38751
|
}
|
|
38510
|
-
|
|
38511
|
-
for (const i in indexReplacementMap) {
|
|
38512
|
-
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
38513
|
-
}
|
|
38514
|
-
return [regexp, handlerMap, staticMap];
|
|
38752
|
+
return [regexp, indexReplacementMap.map((i) => handlerData[i]), staticMap];
|
|
38515
38753
|
}
|
|
38516
38754
|
};
|
|
38517
38755
|
|
|
@@ -38571,11 +38809,11 @@ var SmartRouter = class {
|
|
|
38571
38809
|
};
|
|
38572
38810
|
|
|
38573
38811
|
// node_modules/hono/dist/router/trie-router/node.js
|
|
38574
|
-
var emptyParams =
|
|
38812
|
+
var emptyParams = createNullObject();
|
|
38575
38813
|
var order = 0;
|
|
38576
38814
|
var Node2 = class _Node2 {
|
|
38577
38815
|
#methods = [];
|
|
38578
|
-
#children =
|
|
38816
|
+
#children = createNullObject();
|
|
38579
38817
|
#patterns = [];
|
|
38580
38818
|
#pattern;
|
|
38581
38819
|
#params = emptyParams;
|
|
@@ -38612,7 +38850,7 @@ var Node2 = class _Node2 {
|
|
|
38612
38850
|
const m = node.#methods[i];
|
|
38613
38851
|
const handlerSet = m[method] || m[METHOD_NAME_ALL];
|
|
38614
38852
|
if (handlerSet) {
|
|
38615
|
-
handlerSet.params =
|
|
38853
|
+
handlerSet.params = createNullObject();
|
|
38616
38854
|
handlerSets.push(handlerSet);
|
|
38617
38855
|
for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {
|
|
38618
38856
|
const key = handlerSet.possibleKeys[i2];
|
|
@@ -40550,33 +40788,11 @@ function isObject2(input) {
|
|
|
40550
40788
|
return false;
|
|
40551
40789
|
}
|
|
40552
40790
|
const prototype = Object.getPrototypeOf(input);
|
|
40553
|
-
|
|
40554
|
-
return true;
|
|
40555
|
-
}
|
|
40556
|
-
let proto = prototype;
|
|
40557
|
-
while (Object.getPrototypeOf(proto) !== null) {
|
|
40558
|
-
proto = Object.getPrototypeOf(proto);
|
|
40559
|
-
}
|
|
40560
|
-
return prototype === proto;
|
|
40791
|
+
return prototype === null || Object.getPrototypeOf(prototype) === null;
|
|
40561
40792
|
}
|
|
40562
|
-
function
|
|
40563
|
-
|
|
40564
|
-
for (const header of headers) {
|
|
40565
|
-
if (!header)
|
|
40566
|
-
continue;
|
|
40567
|
-
for (const parameter of Object.keys(header)) {
|
|
40568
|
-
if (parameters.has(parameter)) {
|
|
40569
|
-
return false;
|
|
40570
|
-
}
|
|
40571
|
-
parameters.add(parameter);
|
|
40572
|
-
}
|
|
40573
|
-
}
|
|
40574
|
-
return true;
|
|
40793
|
+
function isJwkSet(input) {
|
|
40794
|
+
return isObject2(input) && Array.isArray(input.keys) && Array.from(input.keys).every(isObject2);
|
|
40575
40795
|
}
|
|
40576
|
-
var isJWK = (key) => isObject2(key) && typeof key.kty === "string";
|
|
40577
|
-
var isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
|
|
40578
|
-
var isPublicJWK = (key) => key.kty !== "oct" && key.d === void 0 && key.priv === void 0;
|
|
40579
|
-
var isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
|
|
40580
40796
|
|
|
40581
40797
|
// node_modules/jose/dist/webapi/lib/helpers.js
|
|
40582
40798
|
var unprotected = Symbol();
|
|
@@ -40625,6 +40841,26 @@ async function jwkToKey(entry, jwk) {
|
|
|
40625
40841
|
return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? !isPrivate, jwk.key_ops ?? entry.usages[isPrivate ? 1 : 0]);
|
|
40626
40842
|
}
|
|
40627
40843
|
|
|
40844
|
+
// node_modules/jose/dist/webapi/lib/jwk_metadata.js
|
|
40845
|
+
function snapshotJwk(jwk) {
|
|
40846
|
+
return { __proto__: null, ...jwk };
|
|
40847
|
+
}
|
|
40848
|
+
function normalizeJwk(jwk) {
|
|
40849
|
+
const normalized = snapshotJwk(jwk);
|
|
40850
|
+
if (normalized.ext !== void 0 && typeof normalized.ext !== "boolean") {
|
|
40851
|
+
throw new TypeError('"ext" (Extractable) Parameter must be a boolean');
|
|
40852
|
+
}
|
|
40853
|
+
if (normalized.key_ops !== void 0) {
|
|
40854
|
+
const value = normalized.key_ops;
|
|
40855
|
+
const keyOps = Array.isArray(value) ? [...value] : void 0;
|
|
40856
|
+
if (!keyOps || keyOps.some((operation) => typeof operation !== "string") || new Set(keyOps).size !== keyOps.length) {
|
|
40857
|
+
throw new TypeError('"key_ops" (Key Operations) Parameter must be an array of unique strings');
|
|
40858
|
+
}
|
|
40859
|
+
normalized.key_ops = keyOps;
|
|
40860
|
+
}
|
|
40861
|
+
return normalized;
|
|
40862
|
+
}
|
|
40863
|
+
|
|
40628
40864
|
// node_modules/jose/dist/webapi/lib/key.js
|
|
40629
40865
|
var tag = (key) => key[Symbol.toStringTag];
|
|
40630
40866
|
var jwkMatchesOp = (entry, key, usage) => {
|
|
@@ -40650,12 +40886,17 @@ function checkKeyType(entry, key, usage) {
|
|
|
40650
40886
|
const privateKey = usage === "decrypt" || usage === "sign";
|
|
40651
40887
|
if (secret && key instanceof Uint8Array)
|
|
40652
40888
|
return [BYTES, key];
|
|
40653
|
-
if (
|
|
40654
|
-
|
|
40889
|
+
if (isObject2(key)) {
|
|
40890
|
+
const normalized = normalizeJwk(key);
|
|
40891
|
+
if (typeof normalized.kty !== "string") {
|
|
40892
|
+
throw new TypeError(secret ? withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array") : withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
40893
|
+
}
|
|
40894
|
+
const valid = secret ? normalized.kty === "oct" && typeof normalized.k === "string" : normalized.kty !== "oct" && (privateKey ? normalized.kty === "AKP" && typeof normalized.priv === "string" || typeof normalized.d === "string" : normalized.d === void 0 && normalized.priv === void 0);
|
|
40895
|
+
if (!valid) {
|
|
40655
40896
|
throw new TypeError(secret ? `JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present` : `JSON Web Key for this operation must be a ${privateKey ? "private" : "public"} JWK`);
|
|
40656
40897
|
}
|
|
40657
|
-
jwkMatchesOp(entry,
|
|
40658
|
-
return [JWK, key];
|
|
40898
|
+
jwkMatchesOp(entry, normalized, usage);
|
|
40899
|
+
return [JWK, key, normalized];
|
|
40659
40900
|
}
|
|
40660
40901
|
if (!isKeyLike(key)) {
|
|
40661
40902
|
throw new TypeError(secret ? withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array") : withAlg(alg, key, "CryptoKey", "KeyObject", "JSON Web Key"));
|
|
@@ -40694,7 +40935,7 @@ function cached2(key, alg, value) {
|
|
|
40694
40935
|
if (entry) {
|
|
40695
40936
|
entry[alg] = value;
|
|
40696
40937
|
} else {
|
|
40697
|
-
cache.set(key, {
|
|
40938
|
+
cache.set(key, { [alg]: value });
|
|
40698
40939
|
}
|
|
40699
40940
|
}
|
|
40700
40941
|
return value ?? entry?.[alg];
|
|
@@ -40719,8 +40960,9 @@ async function prepareKey(entry, key, usage) {
|
|
|
40719
40960
|
return tagged[1];
|
|
40720
40961
|
case JWK: {
|
|
40721
40962
|
const key2 = tagged[1];
|
|
40722
|
-
|
|
40723
|
-
|
|
40963
|
+
const normalized = tagged[2];
|
|
40964
|
+
if (normalized.kty === "oct") {
|
|
40965
|
+
return decode2(normalized.k);
|
|
40724
40966
|
}
|
|
40725
40967
|
if (!Object.isFrozen(key2)) {
|
|
40726
40968
|
const { key_ops } = key2;
|
|
@@ -40728,7 +40970,7 @@ async function prepareKey(entry, key, usage) {
|
|
|
40728
40970
|
Object.freeze(key_ops);
|
|
40729
40971
|
Object.freeze(key2);
|
|
40730
40972
|
}
|
|
40731
|
-
return handleJWK(key2,
|
|
40973
|
+
return handleJWK(key2, normalized, entry);
|
|
40732
40974
|
}
|
|
40733
40975
|
case KEYOBJECT: {
|
|
40734
40976
|
const keyObject = tagged[1];
|
|
@@ -40787,6 +41029,16 @@ function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader,
|
|
|
40787
41029
|
}
|
|
40788
41030
|
return protectedHeader.crit;
|
|
40789
41031
|
}
|
|
41032
|
+
function validateB64(protectedHeader, extensions) {
|
|
41033
|
+
if (extensions.includes("b64")) {
|
|
41034
|
+
const b64 = protectedHeader.b64;
|
|
41035
|
+
if (typeof b64 !== "boolean") {
|
|
41036
|
+
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
41037
|
+
}
|
|
41038
|
+
return b64;
|
|
41039
|
+
}
|
|
41040
|
+
return true;
|
|
41041
|
+
}
|
|
40790
41042
|
|
|
40791
41043
|
// node_modules/jose/dist/webapi/lib/signing.js
|
|
40792
41044
|
async function getSigKey(entry, key, usage) {
|
|
@@ -40886,64 +41138,42 @@ function jwsAlgorithm(alg) {
|
|
|
40886
41138
|
function prepareVerify(options) {
|
|
40887
41139
|
return [options && validateAlgorithms("algorithms", options.algorithms), options?.crit];
|
|
40888
41140
|
}
|
|
40889
|
-
|
|
40890
|
-
|
|
40891
|
-
|
|
40892
|
-
|
|
40893
|
-
|
|
40894
|
-
|
|
40895
|
-
let joseHeader;
|
|
40896
|
-
if (header !== void 0) {
|
|
40897
|
-
if (!isDisjoint(parsedProt, header)) {
|
|
40898
|
-
throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
|
|
40899
|
-
}
|
|
40900
|
-
joseHeader = { ...parsedProt, ...header };
|
|
40901
|
-
} else {
|
|
40902
|
-
joseHeader = parsedProt;
|
|
40903
|
-
}
|
|
40904
|
-
const extensions = validateCrit(JWSInvalid, JWS_RECOGNIZED, shared[1], parsedProt, joseHeader);
|
|
40905
|
-
let b64 = true;
|
|
40906
|
-
if (extensions.includes("b64")) {
|
|
40907
|
-
b64 = parsedProt.b64;
|
|
40908
|
-
if (typeof b64 !== "boolean") {
|
|
40909
|
-
throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
|
|
40910
|
-
}
|
|
40911
|
-
}
|
|
40912
|
-
const { alg } = joseHeader;
|
|
41141
|
+
function parseProtectedHeader(encodedProtected, parsedProtected = encodedProtected === void 0 ? {} : parseJoseHeader(encodedProtected, JWSInvalid, "JWS Protected Header is invalid")) {
|
|
41142
|
+
return parsedProtected;
|
|
41143
|
+
}
|
|
41144
|
+
function validateJwsHeaders(parsedProt, joseHeader, shared) {
|
|
41145
|
+
const b64 = validateB64(parsedProt, validateCrit(JWSInvalid, JWS_RECOGNIZED, shared[1], parsedProt, joseHeader));
|
|
41146
|
+
const alg = joseHeader.alg;
|
|
40913
41147
|
if (typeof alg !== "string" || !alg) {
|
|
40914
41148
|
throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
|
|
40915
41149
|
}
|
|
40916
41150
|
if (shared[0] && !shared[0].has(alg)) {
|
|
40917
41151
|
throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
|
|
40918
41152
|
}
|
|
40919
|
-
|
|
40920
|
-
|
|
40921
|
-
|
|
40922
|
-
|
|
40923
|
-
|
|
40924
|
-
|
|
41153
|
+
return [b64, alg];
|
|
41154
|
+
}
|
|
41155
|
+
function encodeCompactUnencodedPayload(payload) {
|
|
41156
|
+
try {
|
|
41157
|
+
return encode2(payload);
|
|
41158
|
+
} catch {
|
|
41159
|
+
throw new JWSInvalid("JWS Compact Serialization payload must use only ASCII characters");
|
|
40925
41160
|
}
|
|
41161
|
+
}
|
|
41162
|
+
async function verifyPrepared(jws, shared, key, encodedProtected, parsedProt, alg, signingPayload) {
|
|
40926
41163
|
let resolvedKey = false;
|
|
40927
41164
|
if (typeof key === "function") {
|
|
40928
41165
|
key = await key(parsedProt, jws);
|
|
40929
41166
|
resolvedKey = true;
|
|
40930
41167
|
}
|
|
41168
|
+
const b64 = typeof signingPayload === "string";
|
|
40931
41169
|
const entry = jwsAlgorithm(alg);
|
|
40932
|
-
const data = concat(encodedProtected !== void 0 ? encode2(encodedProtected) : new Uint8Array(), encode2("."),
|
|
41170
|
+
const data = concat(encodedProtected !== void 0 ? encode2(encodedProtected) : new Uint8Array(), encode2("."), b64 ? shared[2] ??= encodeBase64url(signingPayload, "payload", JWSInvalid) : signingPayload);
|
|
40933
41171
|
const signature = decodeBase64url(jws.signature, "signature", JWSInvalid);
|
|
40934
41172
|
const k = await prepareKey(entry, key, "verify");
|
|
40935
|
-
|
|
40936
|
-
if (!verified) {
|
|
41173
|
+
if (!await verify(entry, k, signature, data)) {
|
|
40937
41174
|
throw new JWSSignatureVerificationFailed();
|
|
40938
41175
|
}
|
|
40939
|
-
|
|
40940
|
-
if (b64) {
|
|
40941
|
-
payload = decodeBase64url(inputPayload, "payload", JWSInvalid);
|
|
40942
|
-
} else if (typeof inputPayload === "string") {
|
|
40943
|
-
payload = encoder.encode(inputPayload);
|
|
40944
|
-
} else {
|
|
40945
|
-
payload = inputPayload;
|
|
40946
|
-
}
|
|
41176
|
+
const payload = b64 ? decodeBase64url(signingPayload, "payload", JWSInvalid) : signingPayload;
|
|
40947
41177
|
return [payload, parsedProt, b64, k, resolvedKey];
|
|
40948
41178
|
}
|
|
40949
41179
|
async function verifyCompact(jws, shared, key) {
|
|
@@ -40957,7 +41187,11 @@ async function verifyCompact(jws, shared, key) {
|
|
|
40957
41187
|
if (length !== 3) {
|
|
40958
41188
|
throw new JWSInvalid("Invalid Compact JWS");
|
|
40959
41189
|
}
|
|
40960
|
-
|
|
41190
|
+
const compactJws = { payload, protected: protectedHeader, signature };
|
|
41191
|
+
const parsedProt = parseProtectedHeader(protectedHeader);
|
|
41192
|
+
const [b64, alg] = validateJwsHeaders(parsedProt, parsedProt, shared);
|
|
41193
|
+
const signingPayload = b64 ? payload : encodeCompactUnencodedPayload(payload);
|
|
41194
|
+
return verifyPrepared(compactJws, shared, key, protectedHeader, parsedProt, alg, signingPayload);
|
|
40961
41195
|
}
|
|
40962
41196
|
|
|
40963
41197
|
// node_modules/jose/dist/webapi/lib/jwt_claims_set.js
|
|
@@ -40972,13 +41206,22 @@ var multipliers = {
|
|
|
40972
41206
|
};
|
|
40973
41207
|
var REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;
|
|
40974
41208
|
var checkFailed = "check_failed";
|
|
41209
|
+
function invalidDuration() {
|
|
41210
|
+
throw new TypeError("Invalid time period format");
|
|
41211
|
+
}
|
|
40975
41212
|
function secs(str) {
|
|
41213
|
+
if (typeof str !== "string") {
|
|
41214
|
+
invalidDuration();
|
|
41215
|
+
}
|
|
40976
41216
|
const matched = REGEX.exec(str);
|
|
40977
41217
|
if (!matched || matched[4] && matched[1]) {
|
|
40978
|
-
|
|
41218
|
+
invalidDuration();
|
|
40979
41219
|
}
|
|
40980
41220
|
const value = parseFloat(matched[2]);
|
|
40981
41221
|
const numericDate = Math.round(value * multipliers[matched[3][0].toLowerCase()]);
|
|
41222
|
+
if (!Number.isFinite(numericDate)) {
|
|
41223
|
+
invalidDuration();
|
|
41224
|
+
}
|
|
40982
41225
|
if (matched[1] === "-" || matched[4] === "ago") {
|
|
40983
41226
|
return -numericDate;
|
|
40984
41227
|
}
|
|
@@ -40991,10 +41234,8 @@ function validateInput(label, input) {
|
|
|
40991
41234
|
return input;
|
|
40992
41235
|
}
|
|
40993
41236
|
var normalizeTyp = (value) => {
|
|
40994
|
-
|
|
40995
|
-
|
|
40996
|
-
}
|
|
40997
|
-
return `application/${value.toLowerCase()}`;
|
|
41237
|
+
const normalized = value.toLowerCase();
|
|
41238
|
+
return value.includes("/") ? normalized : `application/${normalized}`;
|
|
40998
41239
|
};
|
|
40999
41240
|
var checkAudiencePresence = (audPayload, audOption) => {
|
|
41000
41241
|
if (typeof audPayload === "string") {
|
|
@@ -41027,7 +41268,7 @@ function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
|
|
|
41027
41268
|
throw new JWTInvalid("JWT Claims Set must be a top-level JSON object");
|
|
41028
41269
|
}
|
|
41029
41270
|
const { typ } = options;
|
|
41030
|
-
if (typ && (typeof protectedHeader.typ !== "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) {
|
|
41271
|
+
if (typ !== void 0 && (typeof protectedHeader.typ !== "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) {
|
|
41031
41272
|
throw new JWTClaimValidationFailed('unexpected "typ" JWT header value', payload, "typ", checkFailed);
|
|
41032
41273
|
}
|
|
41033
41274
|
const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options;
|
|
@@ -41066,7 +41307,7 @@ function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
|
|
|
41066
41307
|
}
|
|
41067
41308
|
validateInput("clockTolerance option", tolerance);
|
|
41068
41309
|
const { currentDate } = options;
|
|
41069
|
-
const now = validateInput("currentDate option", epoch(currentDate
|
|
41310
|
+
const now = validateInput("currentDate option", epoch(currentDate === void 0 ? /* @__PURE__ */ new Date() : currentDate));
|
|
41070
41311
|
const iat = validateNumericDate(payload, "iat", maxTokenAge !== void 0);
|
|
41071
41312
|
const nbf = validateNumericDate(payload, "nbf");
|
|
41072
41313
|
if (nbf !== void 0) {
|
|
@@ -41082,11 +41323,11 @@ function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
|
|
|
41082
41323
|
}
|
|
41083
41324
|
if (maxTokenAge !== void 0) {
|
|
41084
41325
|
const age = now - iat;
|
|
41085
|
-
const max = typeof maxTokenAge === "number" ? maxTokenAge : secs(maxTokenAge);
|
|
41326
|
+
const max = validateInput("maxTokenAge option", typeof maxTokenAge === "number" ? maxTokenAge : secs(maxTokenAge));
|
|
41086
41327
|
if (age - tolerance > max) {
|
|
41087
41328
|
throw new JWTExpired('"iat" claim timestamp check failed (too far in the past)', payload, "iat", checkFailed);
|
|
41088
41329
|
}
|
|
41089
|
-
if (age <
|
|
41330
|
+
if (age < -tolerance) {
|
|
41090
41331
|
throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', payload, "iat", checkFailed);
|
|
41091
41332
|
}
|
|
41092
41333
|
}
|
|
@@ -41108,74 +41349,61 @@ async function jwtVerify(jwt, key, options) {
|
|
|
41108
41349
|
}
|
|
41109
41350
|
|
|
41110
41351
|
// node_modules/jose/dist/webapi/jwks/local.js
|
|
41111
|
-
function
|
|
41112
|
-
const
|
|
41113
|
-
|
|
41114
|
-
|
|
41115
|
-
}
|
|
41116
|
-
return entry;
|
|
41352
|
+
function isUsableJWK(jwk, entry, alg, kid) {
|
|
41353
|
+
const { kty, key_ops, ext, kid: jwkKid, alg: jwkAlg, use, crv } = snapshotJwk(jwk);
|
|
41354
|
+
const keyOps = Array.isArray(key_ops) ? [...key_ops] : key_ops;
|
|
41355
|
+
return (ext === void 0 || typeof ext === "boolean") && (keyOps === void 0 || Array.isArray(keyOps) && keyOps.every((operation, index) => typeof operation === "string" && keyOps.indexOf(operation) === index) && keyOps.includes("verify")) && entry.kty.includes(kty) && (kid === void 0 || typeof kid === "string" && kid === jwkKid) && (jwkAlg === void 0 ? kty !== "AKP" : alg === jwkAlg) && (use === void 0 || use === "sig") && (!entry.crv || crv === entry.crv);
|
|
41117
41356
|
}
|
|
41118
|
-
function
|
|
41119
|
-
|
|
41120
|
-
|
|
41357
|
+
async function importWithAlgCache(cache2, jwk, entry) {
|
|
41358
|
+
const cached3 = cache2.get(jwk) || cache2.set(jwk, {}).get(jwk);
|
|
41359
|
+
const { alg } = entry;
|
|
41360
|
+
if (cached3[alg] === void 0) {
|
|
41361
|
+
const key = await jwkToKey(entry, { ...jwk, alg, ext: true });
|
|
41362
|
+
if (key.type !== "public") {
|
|
41363
|
+
throw new JWKSInvalid("JSON Web Key Set members must be public keys");
|
|
41364
|
+
}
|
|
41365
|
+
cached3[alg] = key;
|
|
41121
41366
|
}
|
|
41122
|
-
|
|
41123
|
-
return Array.isArray(keys) && keys.every(isObject2);
|
|
41367
|
+
return cached3[alg];
|
|
41124
41368
|
}
|
|
41125
|
-
|
|
41126
|
-
|
|
41127
|
-
|
|
41128
|
-
|
|
41129
|
-
|
|
41130
|
-
throw new JWKSInvalid("JSON Web Key Set malformed");
|
|
41131
|
-
}
|
|
41132
|
-
this.#jwks = structuredClone(jwks);
|
|
41369
|
+
function createLocalJWKSet(jwks) {
|
|
41370
|
+
let snapshot;
|
|
41371
|
+
try {
|
|
41372
|
+
snapshot = structuredClone(jwks);
|
|
41373
|
+
} catch {
|
|
41133
41374
|
}
|
|
41134
|
-
|
|
41135
|
-
|
|
41375
|
+
if (!isJwkSet(snapshot)) {
|
|
41376
|
+
throw new JWKSInvalid("JSON Web Key Set malformed");
|
|
41136
41377
|
}
|
|
41137
|
-
|
|
41378
|
+
const cached3 = /* @__PURE__ */ new WeakMap();
|
|
41379
|
+
const localJWKSet = async (protectedHeader, token) => {
|
|
41138
41380
|
const { alg, kid } = { ...protectedHeader, ...token?.header };
|
|
41139
|
-
const entry =
|
|
41140
|
-
|
|
41381
|
+
const entry = typeof alg === "string" ? JWS[alg] : void 0;
|
|
41382
|
+
if (!entry || entry.secret) {
|
|
41383
|
+
throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');
|
|
41384
|
+
}
|
|
41385
|
+
const candidates = snapshot.keys.filter((jwk2) => isUsableJWK(jwk2, entry, alg, kid));
|
|
41141
41386
|
const { 0: jwk, length } = candidates;
|
|
41142
|
-
if (length
|
|
41387
|
+
if (!length) {
|
|
41143
41388
|
throw new JWKSNoMatchingKey();
|
|
41144
41389
|
}
|
|
41145
41390
|
if (length !== 1) {
|
|
41146
41391
|
const error2 = new JWKSMultipleMatchingKeys();
|
|
41147
|
-
const _cached = this.#cached;
|
|
41148
41392
|
error2[Symbol.asyncIterator] = async function* () {
|
|
41149
41393
|
for (const jwk2 of candidates) {
|
|
41150
41394
|
try {
|
|
41151
|
-
yield await importWithAlgCache(
|
|
41395
|
+
yield await importWithAlgCache(cached3, jwk2, entry);
|
|
41152
41396
|
} catch {
|
|
41153
41397
|
}
|
|
41154
41398
|
}
|
|
41155
41399
|
};
|
|
41156
41400
|
throw error2;
|
|
41157
41401
|
}
|
|
41158
|
-
return importWithAlgCache(
|
|
41159
|
-
}
|
|
41160
|
-
|
|
41161
|
-
|
|
41162
|
-
const cached3 = cache2.get(jwk) || cache2.set(jwk, { __proto__: null }).get(jwk);
|
|
41163
|
-
if (cached3[entry.alg] === void 0) {
|
|
41164
|
-
const key = await jwkToKey(entry, { ...jwk, alg: entry.alg, ext: true });
|
|
41165
|
-
if (key.type !== "public") {
|
|
41166
|
-
throw new JWKSInvalid("JSON Web Key Set members must be public keys");
|
|
41167
|
-
}
|
|
41168
|
-
cached3[entry.alg] = key;
|
|
41169
|
-
}
|
|
41170
|
-
return cached3[entry.alg];
|
|
41171
|
-
}
|
|
41172
|
-
function createLocalJWKSet(jwks) {
|
|
41173
|
-
const set = new LocalJWKSetImpl(jwks);
|
|
41174
|
-
const localJWKSet = async (protectedHeader, token) => set.getKey(protectedHeader, token);
|
|
41175
|
-
Object.defineProperty(localJWKSet, "jwks", {
|
|
41176
|
-
value: () => structuredClone(set.jwks())
|
|
41402
|
+
return importWithAlgCache(cached3, jwk, entry);
|
|
41403
|
+
};
|
|
41404
|
+
return Object.defineProperty(localJWKSet, "jwks", {
|
|
41405
|
+
value: () => structuredClone(snapshot)
|
|
41177
41406
|
});
|
|
41178
|
-
return localJWKSet;
|
|
41179
41407
|
}
|
|
41180
41408
|
|
|
41181
41409
|
// node_modules/jose/dist/webapi/jwks/remote.js
|
|
@@ -41185,7 +41413,7 @@ function isCloudflareWorkers() {
|
|
|
41185
41413
|
var USER_AGENT;
|
|
41186
41414
|
if (typeof navigator === "undefined" || !navigator.userAgent?.startsWith?.("Mozilla/5.0 ")) {
|
|
41187
41415
|
const NAME = "jose";
|
|
41188
|
-
const VERSION2 = "v6.2.
|
|
41416
|
+
const VERSION2 = "v6.2.10";
|
|
41189
41417
|
USER_AGENT = `${NAME}/${VERSION2}`;
|
|
41190
41418
|
}
|
|
41191
41419
|
var customFetch = Symbol();
|
|
@@ -41211,130 +41439,112 @@ async function fetchJwks(url2, headers, signal, fetchImpl = fetch) {
|
|
|
41211
41439
|
}
|
|
41212
41440
|
}
|
|
41213
41441
|
var jwksCache = Symbol();
|
|
41214
|
-
function
|
|
41215
|
-
|
|
41216
|
-
|
|
41217
|
-
|
|
41218
|
-
if (
|
|
41219
|
-
|
|
41220
|
-
}
|
|
41221
|
-
if (!("jwks" in input) || !isObject2(input.jwks) || !Array.isArray(input.jwks.keys) || !Array.prototype.every.call(input.jwks.keys, isObject2)) {
|
|
41222
|
-
return false;
|
|
41442
|
+
function isFreshFor(timestamp, duration3) {
|
|
41443
|
+
return Number.isFinite(timestamp) && Date.now() < timestamp + duration3;
|
|
41444
|
+
}
|
|
41445
|
+
function validateDuration(value, fallback, option) {
|
|
41446
|
+
if (Number.isNaN(value)) {
|
|
41447
|
+
throw new TypeError(`"${option}" option must not be NaN`);
|
|
41223
41448
|
}
|
|
41224
|
-
return
|
|
41449
|
+
return typeof value === "number" ? value : fallback;
|
|
41225
41450
|
}
|
|
41226
|
-
|
|
41227
|
-
|
|
41228
|
-
|
|
41229
|
-
|
|
41230
|
-
|
|
41231
|
-
|
|
41232
|
-
|
|
41233
|
-
|
|
41234
|
-
|
|
41235
|
-
|
|
41236
|
-
|
|
41237
|
-
|
|
41238
|
-
|
|
41239
|
-
|
|
41240
|
-
|
|
41241
|
-
|
|
41242
|
-
|
|
41243
|
-
|
|
41244
|
-
|
|
41245
|
-
|
|
41246
|
-
|
|
41247
|
-
|
|
41248
|
-
|
|
41249
|
-
|
|
41250
|
-
|
|
41251
|
-
|
|
41252
|
-
|
|
41253
|
-
|
|
41254
|
-
|
|
41255
|
-
|
|
41256
|
-
|
|
41257
|
-
|
|
41258
|
-
|
|
41259
|
-
|
|
41260
|
-
|
|
41261
|
-
|
|
41262
|
-
|
|
41263
|
-
|
|
41264
|
-
|
|
41265
|
-
|
|
41266
|
-
|
|
41267
|
-
|
|
41268
|
-
|
|
41269
|
-
|
|
41270
|
-
|
|
41271
|
-
|
|
41272
|
-
|
|
41273
|
-
|
|
41274
|
-
|
|
41275
|
-
|
|
41276
|
-
|
|
41277
|
-
|
|
41278
|
-
|
|
41279
|
-
|
|
41280
|
-
|
|
41281
|
-
|
|
41451
|
+
function createRemoteJWKSet(url2, options) {
|
|
41452
|
+
if (!(url2 instanceof URL)) {
|
|
41453
|
+
throw new TypeError("url must be an instance of URL");
|
|
41454
|
+
}
|
|
41455
|
+
const href = new URL(url2.href).href;
|
|
41456
|
+
const opts = options ?? {};
|
|
41457
|
+
const timeoutOption = opts.timeoutDuration;
|
|
41458
|
+
if (typeof timeoutOption === "number" && (!Number.isInteger(timeoutOption) || timeoutOption < 0)) {
|
|
41459
|
+
throw new TypeError('"timeoutDuration" option must be a non-negative integer');
|
|
41460
|
+
}
|
|
41461
|
+
const timeoutDuration = typeof timeoutOption === "number" ? timeoutOption : 5e3;
|
|
41462
|
+
const cooldownDuration = validateDuration(opts.cooldownDuration, 3e4, "cooldownDuration");
|
|
41463
|
+
const cacheMaxAge = validateDuration(opts.cacheMaxAge, 6e5, "cacheMaxAge");
|
|
41464
|
+
const headers = new Headers(opts.headers);
|
|
41465
|
+
if (USER_AGENT && !headers.has("User-Agent")) {
|
|
41466
|
+
headers.set("User-Agent", USER_AGENT);
|
|
41467
|
+
}
|
|
41468
|
+
if (!headers.has("accept")) {
|
|
41469
|
+
headers.set("accept", "application/json, application/jwk-set+json");
|
|
41470
|
+
}
|
|
41471
|
+
const fetchImpl = opts[customFetch];
|
|
41472
|
+
const cache2 = opts[jwksCache];
|
|
41473
|
+
let jwksTimestamp;
|
|
41474
|
+
let pendingFetch;
|
|
41475
|
+
let reloadSequence = 0;
|
|
41476
|
+
let appliedSequence = 0;
|
|
41477
|
+
let local;
|
|
41478
|
+
if (cache2 && typeof cache2 === "object") {
|
|
41479
|
+
const { uat, jwks } = cache2;
|
|
41480
|
+
if (isFreshFor(uat, cacheMaxAge) && isJwkSet(jwks)) {
|
|
41481
|
+
jwksTimestamp = uat;
|
|
41482
|
+
local = createLocalJWKSet(jwks);
|
|
41483
|
+
}
|
|
41484
|
+
}
|
|
41485
|
+
const reload = async () => {
|
|
41486
|
+
if (pendingFetch && isCloudflareWorkers()) {
|
|
41487
|
+
pendingFetch = void 0;
|
|
41488
|
+
}
|
|
41489
|
+
if (!pendingFetch) {
|
|
41490
|
+
const sequence = ++reloadSequence;
|
|
41491
|
+
const current = pendingFetch = fetchJwks(href, headers, AbortSignal.timeout(timeoutDuration), fetchImpl).then((json) => {
|
|
41492
|
+
const next = createLocalJWKSet(json);
|
|
41493
|
+
if (sequence <= appliedSequence) {
|
|
41494
|
+
return;
|
|
41495
|
+
}
|
|
41496
|
+
local = next;
|
|
41497
|
+
const updatedAt = Date.now();
|
|
41498
|
+
if (cache2) {
|
|
41499
|
+
cache2.uat = updatedAt;
|
|
41500
|
+
cache2.jwks = json;
|
|
41501
|
+
}
|
|
41502
|
+
jwksTimestamp = updatedAt;
|
|
41503
|
+
appliedSequence = sequence;
|
|
41504
|
+
}).finally(() => {
|
|
41505
|
+
if (pendingFetch === current) {
|
|
41506
|
+
pendingFetch = void 0;
|
|
41507
|
+
}
|
|
41508
|
+
});
|
|
41509
|
+
}
|
|
41510
|
+
await pendingFetch;
|
|
41511
|
+
};
|
|
41512
|
+
const remoteJWKSet = async (protectedHeader, token) => {
|
|
41513
|
+
if (!local || !isFreshFor(jwksTimestamp, cacheMaxAge)) {
|
|
41514
|
+
await reload();
|
|
41282
41515
|
}
|
|
41283
41516
|
try {
|
|
41284
|
-
return await
|
|
41517
|
+
return await local(protectedHeader, token);
|
|
41285
41518
|
} catch (err) {
|
|
41286
|
-
if (err instanceof JWKSNoMatchingKey) {
|
|
41287
|
-
|
|
41288
|
-
|
|
41289
|
-
return this.#local(protectedHeader, token);
|
|
41290
|
-
}
|
|
41519
|
+
if (err instanceof JWKSNoMatchingKey && !isFreshFor(jwksTimestamp, cooldownDuration)) {
|
|
41520
|
+
await reload();
|
|
41521
|
+
return local(protectedHeader, token);
|
|
41291
41522
|
}
|
|
41292
41523
|
throw err;
|
|
41293
41524
|
}
|
|
41294
|
-
}
|
|
41295
|
-
|
|
41296
|
-
if (this.#pendingFetch && isCloudflareWorkers()) {
|
|
41297
|
-
this.#pendingFetch = void 0;
|
|
41298
|
-
}
|
|
41299
|
-
this.#pendingFetch ||= fetchJwks(this.#url.href, this.#headers, AbortSignal.timeout(this.#timeoutDuration), this.#customFetch).then((json) => {
|
|
41300
|
-
this.#local = createLocalJWKSet(json);
|
|
41301
|
-
if (this.#cache) {
|
|
41302
|
-
this.#cache.uat = Date.now();
|
|
41303
|
-
this.#cache.jwks = json;
|
|
41304
|
-
}
|
|
41305
|
-
this.#jwksTimestamp = Date.now();
|
|
41306
|
-
}).finally(() => {
|
|
41307
|
-
this.#pendingFetch = void 0;
|
|
41308
|
-
});
|
|
41309
|
-
await this.#pendingFetch;
|
|
41310
|
-
}
|
|
41311
|
-
};
|
|
41312
|
-
function createRemoteJWKSet(url2, options) {
|
|
41313
|
-
const set = new RemoteJWKSetImpl(url2, options);
|
|
41314
|
-
const remoteJWKSet = async (protectedHeader, token) => set.getKey(protectedHeader, token);
|
|
41315
|
-
Object.defineProperties(remoteJWKSet, {
|
|
41525
|
+
};
|
|
41526
|
+
return Object.defineProperties(remoteJWKSet, {
|
|
41316
41527
|
coolingDown: {
|
|
41317
|
-
get: () =>
|
|
41528
|
+
get: () => isFreshFor(jwksTimestamp, cooldownDuration),
|
|
41318
41529
|
enumerable: true
|
|
41319
41530
|
},
|
|
41320
41531
|
fresh: {
|
|
41321
|
-
get: () =>
|
|
41532
|
+
get: () => isFreshFor(jwksTimestamp, cacheMaxAge),
|
|
41322
41533
|
enumerable: true
|
|
41323
41534
|
},
|
|
41324
41535
|
reload: {
|
|
41325
|
-
value:
|
|
41536
|
+
value: reload,
|
|
41326
41537
|
enumerable: true
|
|
41327
41538
|
},
|
|
41328
41539
|
reloading: {
|
|
41329
|
-
get: () =>
|
|
41540
|
+
get: () => !!pendingFetch,
|
|
41330
41541
|
enumerable: true
|
|
41331
41542
|
},
|
|
41332
41543
|
jwks: {
|
|
41333
|
-
value: () =>
|
|
41544
|
+
value: () => local?.jwks(),
|
|
41334
41545
|
enumerable: true
|
|
41335
41546
|
}
|
|
41336
41547
|
});
|
|
41337
|
-
return remoteJWKSet;
|
|
41338
41548
|
}
|
|
41339
41549
|
|
|
41340
41550
|
// node_modules/@casys/mcp-server/src/auth/provider.ts
|
|
@@ -47626,6 +47836,14 @@ function roundedTotalFallbackWarning(original, patched) {
|
|
|
47626
47836
|
}
|
|
47627
47837
|
|
|
47628
47838
|
// src/tools/sales.ts
|
|
47839
|
+
function viewerDocument(value, doctype, name) {
|
|
47840
|
+
const record2 = typeof value === "object" && value !== null ? value : {};
|
|
47841
|
+
return {
|
|
47842
|
+
...record2,
|
|
47843
|
+
...typeof record2.name === "string" || !name ? {} : { name },
|
|
47844
|
+
doctype
|
|
47845
|
+
};
|
|
47846
|
+
}
|
|
47629
47847
|
function mapLineItems(items, options) {
|
|
47630
47848
|
if (!Array.isArray(items) || items.length === 0) {
|
|
47631
47849
|
throw new Error(
|
|
@@ -47906,7 +48124,7 @@ var salesTools = [
|
|
|
47906
48124
|
throw new Error("[erpnext_sales_order_get] 'name' is required");
|
|
47907
48125
|
}
|
|
47908
48126
|
const doc = await ctx.client.get("Sales Order", input.name);
|
|
47909
|
-
return { data: doc };
|
|
48127
|
+
return { data: viewerDocument(doc, "Sales Order", input.name) };
|
|
47910
48128
|
}
|
|
47911
48129
|
},
|
|
47912
48130
|
{
|
|
@@ -47987,8 +48205,12 @@ var salesTools = [
|
|
|
47987
48205
|
}
|
|
47988
48206
|
const doc = await ctx.client.create("Sales Order", data);
|
|
47989
48207
|
return {
|
|
47990
|
-
data: doc,
|
|
47991
|
-
message: `Sales Order ${doc.name} created successfully
|
|
48208
|
+
data: viewerDocument(doc, "Sales Order"),
|
|
48209
|
+
message: `Sales Order ${doc.name} created successfully`,
|
|
48210
|
+
refreshRequest: {
|
|
48211
|
+
toolName: "erpnext_sales_order_get",
|
|
48212
|
+
arguments: { name: doc.name }
|
|
48213
|
+
}
|
|
47992
48214
|
};
|
|
47993
48215
|
}
|
|
47994
48216
|
},
|
|
@@ -48078,8 +48300,16 @@ var salesTools = [
|
|
|
48078
48300
|
ctx.client.invalidate("Sales Order", input.name);
|
|
48079
48301
|
const warnings = roundedTotalFallbackWarning(docWithDoctype, patchedDoc);
|
|
48080
48302
|
return {
|
|
48081
|
-
data:
|
|
48303
|
+
data: viewerDocument(
|
|
48304
|
+
result,
|
|
48305
|
+
"Sales Order",
|
|
48306
|
+
input.name
|
|
48307
|
+
),
|
|
48082
48308
|
message: `Sales Order ${input.name} submitted successfully`,
|
|
48309
|
+
refreshRequest: {
|
|
48310
|
+
toolName: "erpnext_sales_order_get",
|
|
48311
|
+
arguments: { name: input.name }
|
|
48312
|
+
},
|
|
48083
48313
|
...warnings.length > 0 ? { warnings } : {}
|
|
48084
48314
|
};
|
|
48085
48315
|
}
|
|
@@ -48205,7 +48435,11 @@ var salesTools = [
|
|
|
48205
48435
|
}
|
|
48206
48436
|
const doc = await ctx.client.get("Sales Invoice", input.name);
|
|
48207
48437
|
return {
|
|
48208
|
-
data:
|
|
48438
|
+
data: viewerDocument(
|
|
48439
|
+
doc,
|
|
48440
|
+
"Sales Invoice",
|
|
48441
|
+
input.name
|
|
48442
|
+
),
|
|
48209
48443
|
_meta: INVOICE_META
|
|
48210
48444
|
};
|
|
48211
48445
|
}
|
|
@@ -48291,9 +48525,13 @@ var salesTools = [
|
|
|
48291
48525
|
}
|
|
48292
48526
|
const doc = await ctx.client.create("Sales Invoice", data);
|
|
48293
48527
|
return {
|
|
48294
|
-
data: doc,
|
|
48528
|
+
data: viewerDocument(doc, "Sales Invoice"),
|
|
48295
48529
|
message: `Sales Invoice ${doc.name} created successfully`,
|
|
48296
|
-
_meta: INVOICE_META
|
|
48530
|
+
_meta: INVOICE_META,
|
|
48531
|
+
refreshRequest: {
|
|
48532
|
+
toolName: "erpnext_sales_invoice_get",
|
|
48533
|
+
arguments: { name: doc.name }
|
|
48534
|
+
}
|
|
48297
48535
|
};
|
|
48298
48536
|
}
|
|
48299
48537
|
},
|
|
@@ -48327,9 +48565,17 @@ var salesTools = [
|
|
|
48327
48565
|
ctx.client.invalidate("Sales Invoice", input.name);
|
|
48328
48566
|
const warnings = roundedTotalFallbackWarning(docWithDoctype, patchedDoc);
|
|
48329
48567
|
return {
|
|
48330
|
-
data:
|
|
48568
|
+
data: viewerDocument(
|
|
48569
|
+
result,
|
|
48570
|
+
"Sales Invoice",
|
|
48571
|
+
input.name
|
|
48572
|
+
),
|
|
48331
48573
|
message: `Sales Invoice ${input.name} submitted successfully`,
|
|
48332
48574
|
_meta: INVOICE_META,
|
|
48575
|
+
refreshRequest: {
|
|
48576
|
+
toolName: "erpnext_sales_invoice_get",
|
|
48577
|
+
arguments: { name: input.name }
|
|
48578
|
+
},
|
|
48333
48579
|
...warnings.length > 0 ? { warnings } : {}
|
|
48334
48580
|
};
|
|
48335
48581
|
}
|
|
@@ -48435,7 +48681,7 @@ var salesTools = [
|
|
|
48435
48681
|
throw new Error("[erpnext_quotation_get] 'name' is required");
|
|
48436
48682
|
}
|
|
48437
48683
|
const doc = await ctx.client.get("Quotation", input.name);
|
|
48438
|
-
return { data: doc };
|
|
48684
|
+
return { data: viewerDocument(doc, "Quotation", input.name) };
|
|
48439
48685
|
}
|
|
48440
48686
|
},
|
|
48441
48687
|
{
|
|
@@ -48529,8 +48775,12 @@ var salesTools = [
|
|
|
48529
48775
|
}
|
|
48530
48776
|
const doc = await ctx.client.create("Quotation", data);
|
|
48531
48777
|
return {
|
|
48532
|
-
data: doc,
|
|
48533
|
-
message: `Quotation ${doc.name} created successfully
|
|
48778
|
+
data: viewerDocument(doc, "Quotation"),
|
|
48779
|
+
message: `Quotation ${doc.name} created successfully`,
|
|
48780
|
+
refreshRequest: {
|
|
48781
|
+
toolName: "erpnext_quotation_get",
|
|
48782
|
+
arguments: { name: doc.name }
|
|
48783
|
+
}
|
|
48534
48784
|
};
|
|
48535
48785
|
}
|
|
48536
48786
|
}
|
|
@@ -48816,12 +49066,16 @@ var inventoryTools = [
|
|
|
48816
49066
|
name: "erpnext_stock_entry_list",
|
|
48817
49067
|
annotations: { readOnlyHint: true },
|
|
48818
49068
|
_meta: DOCLIST_META,
|
|
48819
|
-
description: "List Stock Entries (material transfers, receipts, issues). Fields: name, stock_entry_type, posting_date, from_warehouse, to_warehouse, total_amount. Filterable by stock_entry_type, date range.",
|
|
49069
|
+
description: "List Stock Entries (material transfers, receipts, issues). Fields: name, stock_entry_type, posting_date, from_warehouse, to_warehouse, total_amount. Filterable by item_code, stock_entry_type, date range.",
|
|
48820
49070
|
category: "inventory",
|
|
48821
49071
|
inputSchema: {
|
|
48822
49072
|
type: "object",
|
|
48823
49073
|
properties: {
|
|
48824
49074
|
limit: { type: "number", description: "Max results (default 20)" },
|
|
49075
|
+
item_code: {
|
|
49076
|
+
type: "string",
|
|
49077
|
+
description: "Exact item code present in a Stock Entry line"
|
|
49078
|
+
},
|
|
48825
49079
|
stock_entry_type: {
|
|
48826
49080
|
type: "string",
|
|
48827
49081
|
description: "Filter by type (Material Issue, Material Receipt, Material Transfer, etc.)"
|
|
@@ -48836,6 +49090,14 @@ var inventoryTools = [
|
|
|
48836
49090
|
handler: async (input, ctx) => {
|
|
48837
49091
|
const limit = input.limit ?? 20;
|
|
48838
49092
|
const filters = [];
|
|
49093
|
+
if (input.item_code) {
|
|
49094
|
+
filters.push([
|
|
49095
|
+
"Stock Entry Detail",
|
|
49096
|
+
"item_code",
|
|
49097
|
+
"=",
|
|
49098
|
+
input.item_code
|
|
49099
|
+
]);
|
|
49100
|
+
}
|
|
48839
49101
|
if (input.stock_entry_type) {
|
|
48840
49102
|
filters.push([
|
|
48841
49103
|
"stock_entry_type",
|
|
@@ -52453,6 +52715,81 @@ var assetsTools = [
|
|
|
52453
52715
|
// src/tools/operations.ts
|
|
52454
52716
|
var operationsTools = [
|
|
52455
52717
|
// ── File Attachments ───────────────────────────────────────────────────────
|
|
52718
|
+
{
|
|
52719
|
+
name: "erpnext_file_list",
|
|
52720
|
+
annotations: { readOnlyHint: true },
|
|
52721
|
+
description: "List the files attached to an ERPNext document. Returns name, size, privacy and URL for each attachment. Pairs with erpnext_file_upload: that one attaches, this one reads back.",
|
|
52722
|
+
category: "operations",
|
|
52723
|
+
inputSchema: {
|
|
52724
|
+
type: "object",
|
|
52725
|
+
properties: {
|
|
52726
|
+
attached_to_doctype: {
|
|
52727
|
+
type: "string",
|
|
52728
|
+
description: "DocType of the document whose attachments to list.",
|
|
52729
|
+
minLength: 1
|
|
52730
|
+
},
|
|
52731
|
+
attached_to_name: {
|
|
52732
|
+
type: "string",
|
|
52733
|
+
description: "Name/ID of the document whose attachments to list.",
|
|
52734
|
+
minLength: 1
|
|
52735
|
+
},
|
|
52736
|
+
limit: {
|
|
52737
|
+
type: "number",
|
|
52738
|
+
description: "Maximum number of files to return. Defaults to 50.",
|
|
52739
|
+
minimum: 1,
|
|
52740
|
+
maximum: 500
|
|
52741
|
+
}
|
|
52742
|
+
},
|
|
52743
|
+
required: ["attached_to_doctype", "attached_to_name"]
|
|
52744
|
+
},
|
|
52745
|
+
handler: async (input, ctx) => {
|
|
52746
|
+
for (const field of ["attached_to_doctype", "attached_to_name"]) {
|
|
52747
|
+
if (typeof input[field] !== "string" || !input[field].trim()) {
|
|
52748
|
+
throw new Error(
|
|
52749
|
+
`[erpnext_file_list] '${field}' must be a non-empty string`
|
|
52750
|
+
);
|
|
52751
|
+
}
|
|
52752
|
+
}
|
|
52753
|
+
if (input.limit !== void 0 && (typeof input.limit !== "number" || !Number.isInteger(input.limit) || input.limit < 1 || input.limit > 500)) {
|
|
52754
|
+
throw new Error(
|
|
52755
|
+
"[erpnext_file_list] 'limit' must be an integer between 1 and 500"
|
|
52756
|
+
);
|
|
52757
|
+
}
|
|
52758
|
+
const files = await ctx.client.list("File", {
|
|
52759
|
+
fields: [
|
|
52760
|
+
"name",
|
|
52761
|
+
"file_name",
|
|
52762
|
+
"file_url",
|
|
52763
|
+
"file_size",
|
|
52764
|
+
"is_private",
|
|
52765
|
+
"attached_to_field",
|
|
52766
|
+
"creation",
|
|
52767
|
+
"modified",
|
|
52768
|
+
"owner"
|
|
52769
|
+
],
|
|
52770
|
+
filters: [
|
|
52771
|
+
["attached_to_doctype", "=", input.attached_to_doctype],
|
|
52772
|
+
["attached_to_name", "=", input.attached_to_name]
|
|
52773
|
+
],
|
|
52774
|
+
order_by: "creation desc",
|
|
52775
|
+
limit: input.limit ?? 50
|
|
52776
|
+
});
|
|
52777
|
+
return {
|
|
52778
|
+
count: files.length,
|
|
52779
|
+
data: files.map((file) => ({
|
|
52780
|
+
name: file.name,
|
|
52781
|
+
file_name: file.file_name,
|
|
52782
|
+
file_url: file.file_url,
|
|
52783
|
+
file_size: file.file_size ?? null,
|
|
52784
|
+
is_private: file.is_private === 1,
|
|
52785
|
+
attached_to_field: file.attached_to_field ?? null,
|
|
52786
|
+
creation: file.creation,
|
|
52787
|
+
modified: file.modified,
|
|
52788
|
+
owner: file.owner
|
|
52789
|
+
}))
|
|
52790
|
+
};
|
|
52791
|
+
}
|
|
52792
|
+
},
|
|
52456
52793
|
{
|
|
52457
52794
|
name: "erpnext_file_upload",
|
|
52458
52795
|
annotations: { destructiveHint: true },
|
|
@@ -52805,10 +53142,52 @@ var operationsTools = [
|
|
|
52805
53142
|
},
|
|
52806
53143
|
filters: {
|
|
52807
53144
|
type: "array",
|
|
52808
|
-
description: 'Frappe filters as array of [fieldname, operator, value] tuples. Example: [["status","=","Open"],["company","=","Acme"]]',
|
|
53145
|
+
description: 'Frappe filters as array of [fieldname, operator, value] tuples, or [child doctype, fieldname, operator, value] to filter on a child table. Values may be strings, numbers, booleans, null, or string/number arrays for in/not in. Example: [["status","=","Open"],["company","=","Acme"]]',
|
|
52809
53146
|
items: {
|
|
52810
53147
|
type: "array",
|
|
52811
|
-
|
|
53148
|
+
anyOf: [
|
|
53149
|
+
{
|
|
53150
|
+
prefixItems: [
|
|
53151
|
+
{ type: "string", minLength: 1 },
|
|
53152
|
+
{ type: "string", minLength: 1 },
|
|
53153
|
+
{
|
|
53154
|
+
oneOf: [
|
|
53155
|
+
{ type: ["string", "number", "boolean", "null"] },
|
|
53156
|
+
{
|
|
53157
|
+
type: "array",
|
|
53158
|
+
items: { type: ["string", "number"] }
|
|
53159
|
+
}
|
|
53160
|
+
]
|
|
53161
|
+
}
|
|
53162
|
+
],
|
|
53163
|
+
minItems: 3,
|
|
53164
|
+
maxItems: 3
|
|
53165
|
+
},
|
|
53166
|
+
{
|
|
53167
|
+
prefixItems: [
|
|
53168
|
+
{ type: "string", minLength: 1 },
|
|
53169
|
+
{ type: "string", minLength: 1 },
|
|
53170
|
+
{ type: "string", minLength: 1 },
|
|
53171
|
+
{
|
|
53172
|
+
oneOf: [
|
|
53173
|
+
{ type: ["string", "number", "boolean", "null"] },
|
|
53174
|
+
{
|
|
53175
|
+
type: "array",
|
|
53176
|
+
items: { type: ["string", "number"] }
|
|
53177
|
+
}
|
|
53178
|
+
]
|
|
53179
|
+
}
|
|
53180
|
+
],
|
|
53181
|
+
minItems: 4,
|
|
53182
|
+
maxItems: 4
|
|
53183
|
+
},
|
|
53184
|
+
{
|
|
53185
|
+
// 3.0.x advertised arbitrary string arrays. Keep accepting
|
|
53186
|
+
// that legacy surface while describing real 3/4-part Frappe
|
|
53187
|
+
// tuples precisely for modern clients.
|
|
53188
|
+
items: { type: "string" }
|
|
53189
|
+
}
|
|
53190
|
+
]
|
|
52812
53191
|
}
|
|
52813
53192
|
},
|
|
52814
53193
|
limit: { type: "number", description: "Max results (default 20)" },
|
|
@@ -53215,7 +53594,6 @@ var analyticsTools = [
|
|
|
53215
53594
|
const invoices2 = await ctx.client.list("Sales Invoice", {
|
|
53216
53595
|
fields: ["name", "status", "grand_total"],
|
|
53217
53596
|
filters: [["docstatus", "!=", 2]],
|
|
53218
|
-
// exclude cancelled
|
|
53219
53597
|
limit: 500,
|
|
53220
53598
|
order_by: "modified desc"
|
|
53221
53599
|
});
|
|
@@ -53551,6 +53929,7 @@ var analyticsTools = [
|
|
|
53551
53929
|
color: "#fbbf24",
|
|
53552
53930
|
type: "line",
|
|
53553
53931
|
yAxisId: "right",
|
|
53932
|
+
unit: "orders",
|
|
53554
53933
|
showDots: true
|
|
53555
53934
|
}
|
|
53556
53935
|
],
|
|
@@ -54006,7 +54385,9 @@ var analyticsTools = [
|
|
|
54006
54385
|
category: "analytics",
|
|
54007
54386
|
inputSchema: { type: "object", properties: {} },
|
|
54008
54387
|
handler: async (_input, ctx) => {
|
|
54009
|
-
const
|
|
54388
|
+
const now = /* @__PURE__ */ new Date();
|
|
54389
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
54390
|
+
const today = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
|
|
54010
54391
|
const invoices = await ctx.client.list("Sales Invoice", {
|
|
54011
54392
|
fields: ["outstanding_amount", "due_date"],
|
|
54012
54393
|
filters: [
|
|
@@ -55616,46 +55997,190 @@ var DOCTYPE_GET_TOOLS = {
|
|
|
55616
55997
|
};
|
|
55617
55998
|
var DOCTYPE_SEND_MESSAGE_HINTS = {
|
|
55618
55999
|
"Customer": [
|
|
55619
|
-
{
|
|
55620
|
-
|
|
56000
|
+
{
|
|
56001
|
+
key: "orders",
|
|
56002
|
+
label: "Orders",
|
|
56003
|
+
message: "Show sales orders for customer {id}",
|
|
56004
|
+
tool: "erpnext_sales_order_list",
|
|
56005
|
+
args: { customer: "{id}", limit: 20 }
|
|
56006
|
+
},
|
|
56007
|
+
{
|
|
56008
|
+
key: "invoices",
|
|
56009
|
+
label: "Invoices",
|
|
56010
|
+
message: "Show sales invoices for customer {id}",
|
|
56011
|
+
tool: "erpnext_sales_invoice_list",
|
|
56012
|
+
args: { customer: "{id}", limit: 20 }
|
|
56013
|
+
}
|
|
55621
56014
|
],
|
|
55622
56015
|
"Sales Order": [
|
|
55623
|
-
{
|
|
55624
|
-
|
|
56016
|
+
{
|
|
56017
|
+
key: "invoice",
|
|
56018
|
+
label: "Invoice",
|
|
56019
|
+
message: "Show invoices linked to sales order {id}",
|
|
56020
|
+
tool: "erpnext_doc_list",
|
|
56021
|
+
args: {
|
|
56022
|
+
doctype: "Sales Invoice",
|
|
56023
|
+
fields: ["name", "customer", "posting_date", "status", "grand_total"],
|
|
56024
|
+
filters: [["Sales Invoice Item", "sales_order", "=", "{id}"]],
|
|
56025
|
+
limit: 20
|
|
56026
|
+
}
|
|
56027
|
+
},
|
|
56028
|
+
{
|
|
56029
|
+
key: "delivery",
|
|
56030
|
+
label: "Delivery",
|
|
56031
|
+
message: "Show delivery notes for sales order {id}",
|
|
56032
|
+
tool: "erpnext_doc_list",
|
|
56033
|
+
args: {
|
|
56034
|
+
doctype: "Delivery Note",
|
|
56035
|
+
fields: ["name", "customer", "posting_date", "status"],
|
|
56036
|
+
filters: [["Delivery Note Item", "against_sales_order", "=", "{id}"]],
|
|
56037
|
+
limit: 20
|
|
56038
|
+
}
|
|
56039
|
+
}
|
|
55625
56040
|
],
|
|
55626
56041
|
"Sales Invoice": [
|
|
55627
|
-
{
|
|
56042
|
+
{
|
|
56043
|
+
key: "payments",
|
|
56044
|
+
label: "Payments",
|
|
56045
|
+
message: "Show payment entries for invoice {id}",
|
|
56046
|
+
tool: "erpnext_doc_list",
|
|
56047
|
+
args: {
|
|
56048
|
+
doctype: "Payment Entry",
|
|
56049
|
+
fields: [
|
|
56050
|
+
"name",
|
|
56051
|
+
"posting_date",
|
|
56052
|
+
"paid_amount",
|
|
56053
|
+
"mode_of_payment",
|
|
56054
|
+
"docstatus"
|
|
56055
|
+
],
|
|
56056
|
+
filters: [["Payment Entry Reference", "reference_name", "=", "{id}"]],
|
|
56057
|
+
limit: 20
|
|
56058
|
+
}
|
|
56059
|
+
}
|
|
55628
56060
|
],
|
|
55629
56061
|
"Item": [
|
|
55630
|
-
{
|
|
55631
|
-
|
|
56062
|
+
{
|
|
56063
|
+
key: "stock",
|
|
56064
|
+
label: "Stock",
|
|
56065
|
+
message: "Show stock balance for item {id}",
|
|
56066
|
+
tool: "erpnext_stock_balance",
|
|
56067
|
+
args: { item_code: "{id}" }
|
|
56068
|
+
},
|
|
56069
|
+
{
|
|
56070
|
+
key: "orders",
|
|
56071
|
+
label: "Orders",
|
|
56072
|
+
message: "Show sales orders containing item {id}",
|
|
56073
|
+
tool: "erpnext_doc_list",
|
|
56074
|
+
args: {
|
|
56075
|
+
doctype: "Sales Order",
|
|
56076
|
+
fields: ["name", "customer", "transaction_date", "status"],
|
|
56077
|
+
filters: [["Sales Order Item", "item_code", "=", "{id}"]],
|
|
56078
|
+
limit: 20
|
|
56079
|
+
}
|
|
56080
|
+
}
|
|
55632
56081
|
],
|
|
55633
56082
|
"Supplier": [
|
|
55634
|
-
{
|
|
55635
|
-
|
|
56083
|
+
{
|
|
56084
|
+
key: "po",
|
|
56085
|
+
label: "PO",
|
|
56086
|
+
message: "Show purchase orders for supplier {id}",
|
|
56087
|
+
tool: "erpnext_purchase_order_list",
|
|
56088
|
+
args: { supplier: "{id}", limit: 20 }
|
|
56089
|
+
},
|
|
56090
|
+
{
|
|
56091
|
+
key: "invoices",
|
|
56092
|
+
label: "Invoices",
|
|
56093
|
+
message: "Show purchase invoices for supplier {id}",
|
|
56094
|
+
tool: "erpnext_purchase_invoice_list",
|
|
56095
|
+
args: { supplier: "{id}", limit: 20 }
|
|
56096
|
+
}
|
|
55636
56097
|
],
|
|
55637
56098
|
"Purchase Order": [
|
|
55638
|
-
{
|
|
55639
|
-
|
|
56099
|
+
{
|
|
56100
|
+
key: "receipt",
|
|
56101
|
+
label: "Receipt",
|
|
56102
|
+
message: "Show purchase receipts for order {id}",
|
|
56103
|
+
tool: "erpnext_doc_list",
|
|
56104
|
+
args: {
|
|
56105
|
+
doctype: "Purchase Receipt",
|
|
56106
|
+
fields: ["name", "supplier", "posting_date", "status"],
|
|
56107
|
+
filters: [["Purchase Receipt Item", "purchase_order", "=", "{id}"]],
|
|
56108
|
+
limit: 20
|
|
56109
|
+
}
|
|
56110
|
+
},
|
|
56111
|
+
{
|
|
56112
|
+
key: "invoice",
|
|
56113
|
+
label: "Invoice",
|
|
56114
|
+
message: "Show purchase invoices for order {id}",
|
|
56115
|
+
tool: "erpnext_doc_list",
|
|
56116
|
+
args: {
|
|
56117
|
+
doctype: "Purchase Invoice",
|
|
56118
|
+
fields: ["name", "supplier", "posting_date", "status", "grand_total"],
|
|
56119
|
+
filters: [["Purchase Invoice Item", "purchase_order", "=", "{id}"]],
|
|
56120
|
+
limit: 20
|
|
56121
|
+
}
|
|
56122
|
+
}
|
|
55640
56123
|
],
|
|
55641
56124
|
"Employee": [
|
|
55642
|
-
{
|
|
55643
|
-
|
|
56125
|
+
{
|
|
56126
|
+
key: "attendance",
|
|
56127
|
+
label: "Attendance",
|
|
56128
|
+
message: "Show attendance for employee {id}",
|
|
56129
|
+
tool: "erpnext_attendance_list",
|
|
56130
|
+
args: { employee: "{id}", limit: 20 }
|
|
56131
|
+
},
|
|
56132
|
+
{
|
|
56133
|
+
key: "leaves",
|
|
56134
|
+
label: "Leaves",
|
|
56135
|
+
message: "Show leave applications for employee {id}",
|
|
56136
|
+
tool: "erpnext_leave_application_list",
|
|
56137
|
+
args: { employee: "{id}", limit: 20 }
|
|
56138
|
+
}
|
|
55644
56139
|
],
|
|
55645
56140
|
"Project": [
|
|
55646
|
-
{
|
|
55647
|
-
|
|
56141
|
+
{
|
|
56142
|
+
key: "tasks",
|
|
56143
|
+
label: "Tasks",
|
|
56144
|
+
message: "Show tasks for project {id}",
|
|
56145
|
+
tool: "erpnext_task_list",
|
|
56146
|
+
args: { project: "{id}", limit: 20 }
|
|
56147
|
+
},
|
|
56148
|
+
{
|
|
56149
|
+
key: "timesheets",
|
|
56150
|
+
label: "Timesheets",
|
|
56151
|
+
message: "Show timesheets for project {id}",
|
|
56152
|
+
tool: "erpnext_timesheet_list",
|
|
56153
|
+
args: { project: "{id}", limit: 20 }
|
|
56154
|
+
}
|
|
55648
56155
|
],
|
|
55649
56156
|
"Task": [
|
|
55650
|
-
{
|
|
56157
|
+
{
|
|
56158
|
+
key: "timesheets",
|
|
56159
|
+
label: "Timesheets",
|
|
56160
|
+
message: "Show timesheets for task {id}",
|
|
56161
|
+
tool: "erpnext_doc_list",
|
|
56162
|
+
args: {
|
|
56163
|
+
doctype: "Timesheet",
|
|
56164
|
+
fields: ["name", "employee", "start_date", "total_hours", "status"],
|
|
56165
|
+
filters: [["Timesheet Detail", "task", "=", "{id}"]],
|
|
56166
|
+
limit: 20
|
|
56167
|
+
}
|
|
56168
|
+
}
|
|
55651
56169
|
],
|
|
55652
56170
|
"Lead": [
|
|
55653
|
-
{
|
|
56171
|
+
{
|
|
56172
|
+
key: "opportunities",
|
|
56173
|
+
label: "Opportunities",
|
|
56174
|
+
message: "Show opportunities for lead {id}",
|
|
56175
|
+
tool: "erpnext_opportunity_list",
|
|
56176
|
+
// Le handler exige opportunity_from avec party_name.
|
|
56177
|
+
args: { opportunity_from: "Lead", party_name: "{id}", limit: 20 }
|
|
56178
|
+
}
|
|
55654
56179
|
]
|
|
55655
56180
|
};
|
|
55656
56181
|
var KPI_DRILL_DOWN = {
|
|
55657
56182
|
"erpnext_kpi_revenue": {
|
|
55658
|
-
_drillDown: "Show all sales
|
|
56183
|
+
_drillDown: "Show all sales orders for this month",
|
|
55659
56184
|
_trendDrillDown: "Show revenue trend chart for the last 12 months"
|
|
55660
56185
|
},
|
|
55661
56186
|
"erpnext_kpi_outstanding": {
|
|
@@ -55667,7 +56192,7 @@ var KPI_DRILL_DOWN = {
|
|
|
55667
56192
|
_trendDrillDown: "Show order breakdown chart for the last 6 months"
|
|
55668
56193
|
},
|
|
55669
56194
|
"erpnext_kpi_gross_margin": {
|
|
55670
|
-
_drillDown: "Show
|
|
56195
|
+
_drillDown: "Show the non-cancelled Sales Order Items and Bin valuation rates used to estimate this gross margin",
|
|
55671
56196
|
_trendDrillDown: "Show profit and loss chart for the last 12 months"
|
|
55672
56197
|
},
|
|
55673
56198
|
"erpnext_kpi_overdue": {
|
|
@@ -55678,12 +56203,521 @@ var KPI_DRILL_DOWN = {
|
|
|
55678
56203
|
var CHART_DRILL_DOWN = {
|
|
55679
56204
|
"erpnext_sales_chart": "Show sales invoices for {label}",
|
|
55680
56205
|
"erpnext_stock_chart": "Show stock balance for item {label}",
|
|
55681
|
-
"erpnext_revenue_trend": "Show sales
|
|
56206
|
+
"erpnext_revenue_trend": "Show sales orders for month {label}",
|
|
55682
56207
|
"erpnext_order_breakdown": "Show sales orders for {label}",
|
|
55683
|
-
"erpnext_ar_aging": "Show
|
|
56208
|
+
"erpnext_ar_aging": "Show outstanding sales invoices for customer {label}",
|
|
55684
56209
|
"erpnext_gross_profit": "Show gross profit details for {label}",
|
|
55685
|
-
"erpnext_profit_loss": "Show
|
|
56210
|
+
"erpnext_profit_loss": "Show submitted sales and purchase orders for month {label}"
|
|
56211
|
+
};
|
|
56212
|
+
var INVOICE_ITEM_HINTS = [
|
|
56213
|
+
{
|
|
56214
|
+
key: "item",
|
|
56215
|
+
label: "Item",
|
|
56216
|
+
message: "Show item {item}",
|
|
56217
|
+
tool: "erpnext_item_get",
|
|
56218
|
+
args: { name: "{item}" },
|
|
56219
|
+
kind: "record"
|
|
56220
|
+
},
|
|
56221
|
+
{
|
|
56222
|
+
key: "stock",
|
|
56223
|
+
label: "Stock",
|
|
56224
|
+
message: "Show stock balance for item {item}",
|
|
56225
|
+
tool: "erpnext_stock_balance",
|
|
56226
|
+
args: { item_code: "{item}", limit: 50 },
|
|
56227
|
+
kind: "list"
|
|
56228
|
+
}
|
|
56229
|
+
];
|
|
56230
|
+
var INVOICE_HINTS = {
|
|
56231
|
+
"Sales Invoice": [
|
|
56232
|
+
{
|
|
56233
|
+
key: "payments",
|
|
56234
|
+
label: "Payments",
|
|
56235
|
+
message: "Show payment entries for invoice {id}",
|
|
56236
|
+
tool: "erpnext_doc_list",
|
|
56237
|
+
args: {
|
|
56238
|
+
doctype: "Payment Entry",
|
|
56239
|
+
fields: [
|
|
56240
|
+
"name",
|
|
56241
|
+
"posting_date",
|
|
56242
|
+
"paid_amount",
|
|
56243
|
+
"mode_of_payment",
|
|
56244
|
+
"docstatus"
|
|
56245
|
+
],
|
|
56246
|
+
filters: [["Payment Entry Reference", "reference_name", "=", "{id}"]],
|
|
56247
|
+
limit: 20
|
|
56248
|
+
},
|
|
56249
|
+
kind: "list"
|
|
56250
|
+
},
|
|
56251
|
+
{
|
|
56252
|
+
key: "customer",
|
|
56253
|
+
label: "Customer",
|
|
56254
|
+
message: "Show customer {party}",
|
|
56255
|
+
tool: "erpnext_customer_get",
|
|
56256
|
+
args: { name: "{party}" },
|
|
56257
|
+
kind: "record"
|
|
56258
|
+
},
|
|
56259
|
+
...INVOICE_ITEM_HINTS
|
|
56260
|
+
],
|
|
56261
|
+
"Purchase Invoice": [
|
|
56262
|
+
{
|
|
56263
|
+
key: "payments",
|
|
56264
|
+
label: "Payments",
|
|
56265
|
+
message: "Show payment entries for invoice {id}",
|
|
56266
|
+
tool: "erpnext_doc_list",
|
|
56267
|
+
args: {
|
|
56268
|
+
doctype: "Payment Entry",
|
|
56269
|
+
fields: [
|
|
56270
|
+
"name",
|
|
56271
|
+
"posting_date",
|
|
56272
|
+
"paid_amount",
|
|
56273
|
+
"mode_of_payment",
|
|
56274
|
+
"docstatus"
|
|
56275
|
+
],
|
|
56276
|
+
filters: [["Payment Entry Reference", "reference_name", "=", "{id}"]],
|
|
56277
|
+
limit: 20
|
|
56278
|
+
},
|
|
56279
|
+
kind: "list"
|
|
56280
|
+
},
|
|
56281
|
+
{
|
|
56282
|
+
key: "supplier",
|
|
56283
|
+
label: "Supplier",
|
|
56284
|
+
message: "Show supplier {party}",
|
|
56285
|
+
tool: "erpnext_supplier_get",
|
|
56286
|
+
args: { name: "{party}" },
|
|
56287
|
+
kind: "record"
|
|
56288
|
+
},
|
|
56289
|
+
...INVOICE_ITEM_HINTS
|
|
56290
|
+
]
|
|
56291
|
+
};
|
|
56292
|
+
var STOCK_HINTS = [
|
|
56293
|
+
{
|
|
56294
|
+
key: "item",
|
|
56295
|
+
label: "Item",
|
|
56296
|
+
message: "Show item {id}",
|
|
56297
|
+
tool: "erpnext_item_get",
|
|
56298
|
+
args: { name: "{id}" },
|
|
56299
|
+
kind: "record"
|
|
56300
|
+
},
|
|
56301
|
+
{
|
|
56302
|
+
key: "movements",
|
|
56303
|
+
label: "Stock entries",
|
|
56304
|
+
message: "Show stock entries for item {id}",
|
|
56305
|
+
tool: "erpnext_doc_list",
|
|
56306
|
+
args: {
|
|
56307
|
+
doctype: "Stock Entry",
|
|
56308
|
+
fields: ["name", "posting_date", "stock_entry_type", "docstatus"],
|
|
56309
|
+
filters: [["Stock Entry Detail", "item_code", "=", "{id}"]],
|
|
56310
|
+
limit: 20
|
|
56311
|
+
},
|
|
56312
|
+
kind: "list"
|
|
56313
|
+
},
|
|
56314
|
+
{
|
|
56315
|
+
key: "warehouse",
|
|
56316
|
+
label: "Warehouse stock",
|
|
56317
|
+
message: "Show stock chart for warehouse {warehouse}",
|
|
56318
|
+
tool: "erpnext_stock_chart",
|
|
56319
|
+
args: { warehouse: "{warehouse}", limit: 10 },
|
|
56320
|
+
kind: "chart"
|
|
56321
|
+
}
|
|
56322
|
+
];
|
|
56323
|
+
function monthRange(now) {
|
|
56324
|
+
const y = now.getFullYear();
|
|
56325
|
+
const m = now.getMonth();
|
|
56326
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
56327
|
+
const last = new Date(y, m + 1, 0).getDate();
|
|
56328
|
+
return {
|
|
56329
|
+
from: `${y}-${pad(m + 1)}-01`,
|
|
56330
|
+
to: `${y}-${pad(m + 1)}-${pad(last)}`,
|
|
56331
|
+
today: `${y}-${pad(m + 1)}-${pad(now.getDate())}`
|
|
56332
|
+
};
|
|
56333
|
+
}
|
|
56334
|
+
var INVOICE_LIST_FIELDS = [
|
|
56335
|
+
"name",
|
|
56336
|
+
"customer",
|
|
56337
|
+
"posting_date",
|
|
56338
|
+
"due_date",
|
|
56339
|
+
"status",
|
|
56340
|
+
"outstanding_amount"
|
|
56341
|
+
];
|
|
56342
|
+
var KPI_JUMPS = {
|
|
56343
|
+
"erpnext_kpi_revenue": (r) => ({
|
|
56344
|
+
number: {
|
|
56345
|
+
key: "sales_orders_month",
|
|
56346
|
+
label: "Sales orders this month",
|
|
56347
|
+
tool: "erpnext_doc_list",
|
|
56348
|
+
args: {
|
|
56349
|
+
doctype: "Sales Order",
|
|
56350
|
+
fields: [
|
|
56351
|
+
"name",
|
|
56352
|
+
"customer",
|
|
56353
|
+
"transaction_date",
|
|
56354
|
+
"status",
|
|
56355
|
+
"grand_total"
|
|
56356
|
+
],
|
|
56357
|
+
filters: [
|
|
56358
|
+
["transaction_date", ">=", r.from],
|
|
56359
|
+
["transaction_date", "<=", r.to],
|
|
56360
|
+
// comme le KPI : les commandes annulées ne comptent pas
|
|
56361
|
+
["docstatus", "<", 2]
|
|
56362
|
+
],
|
|
56363
|
+
limit: 20
|
|
56364
|
+
},
|
|
56365
|
+
kind: "list"
|
|
56366
|
+
},
|
|
56367
|
+
trend: {
|
|
56368
|
+
key: "revenue_trend",
|
|
56369
|
+
label: "Revenue trend",
|
|
56370
|
+
tool: "erpnext_revenue_trend",
|
|
56371
|
+
args: { months: 12 },
|
|
56372
|
+
kind: "chart"
|
|
56373
|
+
}
|
|
56374
|
+
}),
|
|
56375
|
+
"erpnext_kpi_outstanding": () => ({
|
|
56376
|
+
number: {
|
|
56377
|
+
key: "unpaid_invoices",
|
|
56378
|
+
label: "Unpaid invoices",
|
|
56379
|
+
tool: "erpnext_doc_list",
|
|
56380
|
+
args: {
|
|
56381
|
+
doctype: "Sales Invoice",
|
|
56382
|
+
fields: INVOICE_LIST_FIELDS,
|
|
56383
|
+
filters: [["outstanding_amount", ">", 0], ["docstatus", "=", 1]],
|
|
56384
|
+
limit: 20
|
|
56385
|
+
},
|
|
56386
|
+
kind: "list"
|
|
56387
|
+
},
|
|
56388
|
+
trend: {
|
|
56389
|
+
key: "receivables_aging",
|
|
56390
|
+
label: "Receivables aging",
|
|
56391
|
+
tool: "erpnext_ar_aging",
|
|
56392
|
+
args: {},
|
|
56393
|
+
kind: "chart"
|
|
56394
|
+
}
|
|
56395
|
+
}),
|
|
56396
|
+
"erpnext_kpi_orders": (r) => ({
|
|
56397
|
+
number: {
|
|
56398
|
+
key: "sales_orders_month",
|
|
56399
|
+
label: "Sales orders this month",
|
|
56400
|
+
tool: "erpnext_doc_list",
|
|
56401
|
+
args: {
|
|
56402
|
+
doctype: "Sales Order",
|
|
56403
|
+
fields: [
|
|
56404
|
+
"name",
|
|
56405
|
+
"customer",
|
|
56406
|
+
"transaction_date",
|
|
56407
|
+
"status",
|
|
56408
|
+
"grand_total"
|
|
56409
|
+
],
|
|
56410
|
+
filters: [
|
|
56411
|
+
["transaction_date", ">=", r.from],
|
|
56412
|
+
["transaction_date", "<=", r.to],
|
|
56413
|
+
// comme le KPI : les commandes annulées ne comptent pas
|
|
56414
|
+
["docstatus", "<", 2]
|
|
56415
|
+
],
|
|
56416
|
+
limit: 20
|
|
56417
|
+
},
|
|
56418
|
+
kind: "list"
|
|
56419
|
+
},
|
|
56420
|
+
trend: {
|
|
56421
|
+
key: "order_breakdown",
|
|
56422
|
+
label: "Order breakdown",
|
|
56423
|
+
tool: "erpnext_order_breakdown",
|
|
56424
|
+
args: {},
|
|
56425
|
+
kind: "chart"
|
|
56426
|
+
}
|
|
56427
|
+
}),
|
|
56428
|
+
"erpnext_kpi_gross_margin": () => ({
|
|
56429
|
+
trend: {
|
|
56430
|
+
key: "profit_loss",
|
|
56431
|
+
label: "Profit and loss",
|
|
56432
|
+
tool: "erpnext_profit_loss",
|
|
56433
|
+
args: { months: 12 },
|
|
56434
|
+
kind: "chart"
|
|
56435
|
+
}
|
|
56436
|
+
}),
|
|
56437
|
+
"erpnext_kpi_overdue": (r) => ({
|
|
56438
|
+
number: {
|
|
56439
|
+
key: "overdue_invoices",
|
|
56440
|
+
label: "Overdue invoices",
|
|
56441
|
+
tool: "erpnext_doc_list",
|
|
56442
|
+
args: {
|
|
56443
|
+
doctype: "Sales Invoice",
|
|
56444
|
+
fields: INVOICE_LIST_FIELDS,
|
|
56445
|
+
filters: [
|
|
56446
|
+
["due_date", "<", r.today],
|
|
56447
|
+
["outstanding_amount", ">", 0],
|
|
56448
|
+
["docstatus", "=", 1]
|
|
56449
|
+
],
|
|
56450
|
+
limit: 20
|
|
56451
|
+
},
|
|
56452
|
+
kind: "list"
|
|
56453
|
+
},
|
|
56454
|
+
trend: {
|
|
56455
|
+
key: "receivables_aging",
|
|
56456
|
+
label: "Receivables aging",
|
|
56457
|
+
tool: "erpnext_ar_aging",
|
|
56458
|
+
args: {},
|
|
56459
|
+
kind: "chart"
|
|
56460
|
+
}
|
|
56461
|
+
})
|
|
56462
|
+
};
|
|
56463
|
+
var FUNNEL_LIST_FIELDS = {
|
|
56464
|
+
"Leads": [
|
|
56465
|
+
"name",
|
|
56466
|
+
"lead_name",
|
|
56467
|
+
"company_name",
|
|
56468
|
+
"status",
|
|
56469
|
+
"lead_owner",
|
|
56470
|
+
"creation"
|
|
56471
|
+
],
|
|
56472
|
+
"Opportunities": [
|
|
56473
|
+
"name",
|
|
56474
|
+
"opportunity_from",
|
|
56475
|
+
"party_name",
|
|
56476
|
+
"status",
|
|
56477
|
+
"opportunity_amount",
|
|
56478
|
+
"currency",
|
|
56479
|
+
"probability",
|
|
56480
|
+
"opportunity_owner",
|
|
56481
|
+
"transaction_date"
|
|
56482
|
+
],
|
|
56483
|
+
"Quotations": [
|
|
56484
|
+
"name",
|
|
56485
|
+
"party_name",
|
|
56486
|
+
"transaction_date",
|
|
56487
|
+
"status",
|
|
56488
|
+
"grand_total"
|
|
56489
|
+
],
|
|
56490
|
+
"Orders": [
|
|
56491
|
+
"name",
|
|
56492
|
+
"customer",
|
|
56493
|
+
"transaction_date",
|
|
56494
|
+
"status",
|
|
56495
|
+
"grand_total"
|
|
56496
|
+
]
|
|
56497
|
+
};
|
|
56498
|
+
var FUNNEL_STAGE_JUMPS = {
|
|
56499
|
+
"Leads": {
|
|
56500
|
+
key: "leads",
|
|
56501
|
+
label: "Leads",
|
|
56502
|
+
tool: "erpnext_lead_list",
|
|
56503
|
+
args: { limit: 20 },
|
|
56504
|
+
kind: "list"
|
|
56505
|
+
},
|
|
56506
|
+
"Opportunities": {
|
|
56507
|
+
key: "opportunities",
|
|
56508
|
+
label: "Opportunities",
|
|
56509
|
+
tool: "erpnext_opportunity_list",
|
|
56510
|
+
args: { limit: 20 },
|
|
56511
|
+
kind: "list"
|
|
56512
|
+
},
|
|
56513
|
+
"Quotations": {
|
|
56514
|
+
key: "quotations",
|
|
56515
|
+
label: "Quotations",
|
|
56516
|
+
tool: "erpnext_doc_list",
|
|
56517
|
+
args: {
|
|
56518
|
+
doctype: "Quotation",
|
|
56519
|
+
fields: FUNNEL_LIST_FIELDS.Quotations,
|
|
56520
|
+
filters: [["docstatus", "!=", 2]],
|
|
56521
|
+
limit: 20
|
|
56522
|
+
},
|
|
56523
|
+
kind: "list"
|
|
56524
|
+
},
|
|
56525
|
+
"Orders": {
|
|
56526
|
+
key: "sales_orders",
|
|
56527
|
+
label: "Sales orders",
|
|
56528
|
+
tool: "erpnext_doc_list",
|
|
56529
|
+
args: {
|
|
56530
|
+
doctype: "Sales Order",
|
|
56531
|
+
fields: FUNNEL_LIST_FIELDS.Orders,
|
|
56532
|
+
filters: [["docstatus", "!=", 2]],
|
|
56533
|
+
limit: 20
|
|
56534
|
+
},
|
|
56535
|
+
kind: "list"
|
|
56536
|
+
}
|
|
55686
56537
|
};
|
|
56538
|
+
function funnelPeriodStart(period, now) {
|
|
56539
|
+
const year = now.getFullYear();
|
|
56540
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
56541
|
+
if (period === "this_month") {
|
|
56542
|
+
return `${year}-${pad(now.getMonth() + 1)}-01`;
|
|
56543
|
+
}
|
|
56544
|
+
if (period === "this_quarter") {
|
|
56545
|
+
const firstMonth = Math.floor(now.getMonth() / 3) * 3 + 1;
|
|
56546
|
+
return `${year}-${pad(firstMonth)}-01`;
|
|
56547
|
+
}
|
|
56548
|
+
if (period === "this_year") return `${year}-01-01`;
|
|
56549
|
+
return void 0;
|
|
56550
|
+
}
|
|
56551
|
+
function funnelStageJumps(args, now) {
|
|
56552
|
+
const since = funnelPeriodStart(args.period, now);
|
|
56553
|
+
if (!since) return FUNNEL_STAGE_JUMPS;
|
|
56554
|
+
const scopedJump = (stage, doctype, dateField) => {
|
|
56555
|
+
const base = FUNNEL_STAGE_JUMPS[stage];
|
|
56556
|
+
const baseFilters = Array.isArray(base.args.filters) ? base.args.filters : [];
|
|
56557
|
+
return {
|
|
56558
|
+
...base,
|
|
56559
|
+
tool: "erpnext_doc_list",
|
|
56560
|
+
args: {
|
|
56561
|
+
doctype,
|
|
56562
|
+
fields: FUNNEL_LIST_FIELDS[stage],
|
|
56563
|
+
filters: [[dateField, ">=", since], ...baseFilters],
|
|
56564
|
+
limit: 20
|
|
56565
|
+
}
|
|
56566
|
+
};
|
|
56567
|
+
};
|
|
56568
|
+
return {
|
|
56569
|
+
"Leads": scopedJump("Leads", "Lead", "creation"),
|
|
56570
|
+
"Opportunities": scopedJump(
|
|
56571
|
+
"Opportunities",
|
|
56572
|
+
"Opportunity",
|
|
56573
|
+
"transaction_date"
|
|
56574
|
+
),
|
|
56575
|
+
"Quotations": scopedJump(
|
|
56576
|
+
"Quotations",
|
|
56577
|
+
"Quotation",
|
|
56578
|
+
"transaction_date"
|
|
56579
|
+
),
|
|
56580
|
+
"Orders": scopedJump("Orders", "Sales Order", "transaction_date")
|
|
56581
|
+
};
|
|
56582
|
+
}
|
|
56583
|
+
var SALES_ORDER_LIST_FIELDS = [
|
|
56584
|
+
"name",
|
|
56585
|
+
"customer",
|
|
56586
|
+
"transaction_date",
|
|
56587
|
+
"status",
|
|
56588
|
+
"grand_total"
|
|
56589
|
+
];
|
|
56590
|
+
var PURCHASE_ORDER_LIST_FIELDS = [
|
|
56591
|
+
"name",
|
|
56592
|
+
"supplier",
|
|
56593
|
+
"transaction_date",
|
|
56594
|
+
"status",
|
|
56595
|
+
"grand_total"
|
|
56596
|
+
];
|
|
56597
|
+
function monthLabel(d) {
|
|
56598
|
+
return `${d.toLocaleString("en", { month: "short" })} ${d.getFullYear().toString().slice(2)}`;
|
|
56599
|
+
}
|
|
56600
|
+
function monthBuckets(monthsBack, now) {
|
|
56601
|
+
const buckets = [];
|
|
56602
|
+
for (let m = 0; m < monthsBack; m++) {
|
|
56603
|
+
const d = new Date(
|
|
56604
|
+
now.getFullYear(),
|
|
56605
|
+
now.getMonth() - monthsBack + 1 + m,
|
|
56606
|
+
1
|
|
56607
|
+
);
|
|
56608
|
+
buckets.push({ label: monthLabel(d), range: monthRange(d) });
|
|
56609
|
+
}
|
|
56610
|
+
return buckets;
|
|
56611
|
+
}
|
|
56612
|
+
var docList = (label, doctype, fields, filters) => ({
|
|
56613
|
+
label,
|
|
56614
|
+
tool: "erpnext_doc_list",
|
|
56615
|
+
args: { doctype, fields, filters, limit: 20 },
|
|
56616
|
+
kind: "list"
|
|
56617
|
+
});
|
|
56618
|
+
function chartPointJumps(toolName, args, labels, now) {
|
|
56619
|
+
const jumps = {};
|
|
56620
|
+
const byLabel = (make) => {
|
|
56621
|
+
for (const label of labels) {
|
|
56622
|
+
if (label === "Unknown") continue;
|
|
56623
|
+
jumps[label] = make(label);
|
|
56624
|
+
}
|
|
56625
|
+
};
|
|
56626
|
+
switch (toolName) {
|
|
56627
|
+
case "erpnext_revenue_trend": {
|
|
56628
|
+
const months = Number(args.months ?? 6);
|
|
56629
|
+
for (const { label, range } of monthBuckets(months, now)) {
|
|
56630
|
+
if (!labels.includes(label)) continue;
|
|
56631
|
+
jumps[label] = docList(label, "Sales Order", SALES_ORDER_LIST_FIELDS, [
|
|
56632
|
+
["transaction_date", ">=", range.from],
|
|
56633
|
+
["transaction_date", "<=", range.to],
|
|
56634
|
+
["docstatus", "<", 2]
|
|
56635
|
+
]);
|
|
56636
|
+
}
|
|
56637
|
+
break;
|
|
56638
|
+
}
|
|
56639
|
+
case "erpnext_sales_chart": {
|
|
56640
|
+
const groupBy = String(args.group_by ?? "customer");
|
|
56641
|
+
byLabel((label) => {
|
|
56642
|
+
const filters = [
|
|
56643
|
+
groupBy === "item" ? ["Sales Invoice Item", "item_name", "=", label] : groupBy === "status" ? ["status", "=", label] : ["customer_name", "=", label]
|
|
56644
|
+
];
|
|
56645
|
+
if (groupBy === "status") {
|
|
56646
|
+
filters.push(["docstatus", "!=", 2]);
|
|
56647
|
+
} else if (groupBy === "item" || args.include_drafts !== true) {
|
|
56648
|
+
filters.push(["docstatus", "=", 1]);
|
|
56649
|
+
}
|
|
56650
|
+
return docList(label, "Sales Invoice", INVOICE_LIST_FIELDS, filters);
|
|
56651
|
+
});
|
|
56652
|
+
break;
|
|
56653
|
+
}
|
|
56654
|
+
case "erpnext_order_breakdown":
|
|
56655
|
+
case "erpnext_revenue_vs_orders":
|
|
56656
|
+
byLabel(
|
|
56657
|
+
(label) => docList(label, "Sales Order", SALES_ORDER_LIST_FIELDS, [
|
|
56658
|
+
["customer_name", "=", label],
|
|
56659
|
+
["docstatus", "<", 2]
|
|
56660
|
+
])
|
|
56661
|
+
);
|
|
56662
|
+
break;
|
|
56663
|
+
case "erpnext_ar_aging":
|
|
56664
|
+
case "erpnext_profit_loss":
|
|
56665
|
+
return void 0;
|
|
56666
|
+
case "erpnext_gross_profit": {
|
|
56667
|
+
const groupBy = String(args.group_by ?? "item");
|
|
56668
|
+
byLabel(
|
|
56669
|
+
(label) => docList(label, "Sales Invoice", INVOICE_LIST_FIELDS, [
|
|
56670
|
+
groupBy === "customer" ? ["customer_name", "=", label] : ["Sales Invoice Item", "item_name", "=", label],
|
|
56671
|
+
["docstatus", "=", 1]
|
|
56672
|
+
])
|
|
56673
|
+
);
|
|
56674
|
+
break;
|
|
56675
|
+
}
|
|
56676
|
+
case "erpnext_stock_chart":
|
|
56677
|
+
byLabel((label) => ({
|
|
56678
|
+
label,
|
|
56679
|
+
tool: "erpnext_stock_balance",
|
|
56680
|
+
args: {
|
|
56681
|
+
item_code: label,
|
|
56682
|
+
...typeof args.warehouse === "string" ? { warehouse: args.warehouse } : {},
|
|
56683
|
+
limit: 50
|
|
56684
|
+
},
|
|
56685
|
+
kind: "list"
|
|
56686
|
+
}));
|
|
56687
|
+
break;
|
|
56688
|
+
default:
|
|
56689
|
+
return void 0;
|
|
56690
|
+
}
|
|
56691
|
+
return Object.keys(jumps).length > 0 ? jumps : void 0;
|
|
56692
|
+
}
|
|
56693
|
+
function chartSeriesPointJumps(toolName, args, labels, now) {
|
|
56694
|
+
if (toolName !== "erpnext_profit_loss") return void 0;
|
|
56695
|
+
const jumps = {};
|
|
56696
|
+
const months = Number(args.months ?? 6);
|
|
56697
|
+
for (const { label, range } of monthBuckets(months, now)) {
|
|
56698
|
+
if (!labels.includes(label)) continue;
|
|
56699
|
+
const filters = [
|
|
56700
|
+
["transaction_date", ">=", range.from],
|
|
56701
|
+
["transaction_date", "<=", range.to],
|
|
56702
|
+
["docstatus", "=", 1]
|
|
56703
|
+
];
|
|
56704
|
+
jumps[label] = {
|
|
56705
|
+
"Income": docList(
|
|
56706
|
+
`${label} \xB7 Income`,
|
|
56707
|
+
"Sales Order",
|
|
56708
|
+
SALES_ORDER_LIST_FIELDS,
|
|
56709
|
+
filters
|
|
56710
|
+
),
|
|
56711
|
+
"Expenses": docList(
|
|
56712
|
+
`${label} \xB7 Expenses`,
|
|
56713
|
+
"Purchase Order",
|
|
56714
|
+
PURCHASE_ORDER_LIST_FIELDS,
|
|
56715
|
+
filters
|
|
56716
|
+
)
|
|
56717
|
+
};
|
|
56718
|
+
}
|
|
56719
|
+
return Object.keys(jumps).length > 0 ? jumps : void 0;
|
|
56720
|
+
}
|
|
55687
56721
|
function isChartViewer(result) {
|
|
55688
56722
|
const uri = result._meta?.ui?.resourceUri;
|
|
55689
56723
|
return uri === "ui://mcp-erpnext/chart-viewer";
|
|
@@ -55692,6 +56726,28 @@ function isKpiViewer(result) {
|
|
|
55692
56726
|
const uri = result._meta?.ui?.resourceUri;
|
|
55693
56727
|
return uri === "ui://mcp-erpnext/kpi-viewer";
|
|
55694
56728
|
}
|
|
56729
|
+
function isFunnelViewer(result) {
|
|
56730
|
+
const uri = result._meta?.ui?.resourceUri;
|
|
56731
|
+
return uri === "ui://mcp-erpnext/funnel-viewer";
|
|
56732
|
+
}
|
|
56733
|
+
function resultDoctype(result) {
|
|
56734
|
+
if (typeof result.doctype === "string") return result.doctype;
|
|
56735
|
+
const data = result.data;
|
|
56736
|
+
if (isRecord7(data) && typeof data.doctype === "string") return data.doctype;
|
|
56737
|
+
return void 0;
|
|
56738
|
+
}
|
|
56739
|
+
function isInvoiceViewer(result) {
|
|
56740
|
+
const uri = result._meta?.ui?.resourceUri;
|
|
56741
|
+
return uri === "ui://mcp-erpnext/invoice-viewer";
|
|
56742
|
+
}
|
|
56743
|
+
function isStockViewer(result) {
|
|
56744
|
+
const uri = result._meta?.ui?.resourceUri;
|
|
56745
|
+
return uri === "ui://mcp-erpnext/stock-viewer";
|
|
56746
|
+
}
|
|
56747
|
+
function isKanbanViewer(result) {
|
|
56748
|
+
const uri = result._meta?.ui?.resourceUri;
|
|
56749
|
+
return uri === "ui://mcp-erpnext/kanban-viewer";
|
|
56750
|
+
}
|
|
55695
56751
|
function isDoclistResult(result) {
|
|
55696
56752
|
return typeof result.doctype === "string" && Array.isArray(result.data);
|
|
55697
56753
|
}
|
|
@@ -55699,7 +56755,181 @@ function isDoclistViewer(result) {
|
|
|
55699
56755
|
const uri = result._meta?.ui?.resourceUri;
|
|
55700
56756
|
return uri === "ui://mcp-erpnext/doclist-viewer";
|
|
55701
56757
|
}
|
|
55702
|
-
|
|
56758
|
+
var VIEWER_TOOL_CANDIDATES = {
|
|
56759
|
+
"ui://mcp-erpnext/invoice-viewer": [
|
|
56760
|
+
"erpnext_item_get",
|
|
56761
|
+
"erpnext_stock_balance"
|
|
56762
|
+
],
|
|
56763
|
+
"ui://mcp-erpnext/doclist-viewer": [],
|
|
56764
|
+
"ui://mcp-erpnext/kanban-viewer": [
|
|
56765
|
+
"erpnext_doc_get",
|
|
56766
|
+
"erpnext_doc_update",
|
|
56767
|
+
"erpnext_user_list",
|
|
56768
|
+
"erpnext_doc_assign",
|
|
56769
|
+
"erpnext_doc_unassign"
|
|
56770
|
+
],
|
|
56771
|
+
"ui://mcp-erpnext/stock-viewer": [
|
|
56772
|
+
"erpnext_item_get",
|
|
56773
|
+
"erpnext_stock_entry_list"
|
|
56774
|
+
]
|
|
56775
|
+
};
|
|
56776
|
+
var SUBMITTABLE_VIEWER_DOCTYPES = /* @__PURE__ */ new Set([
|
|
56777
|
+
"Quotation",
|
|
56778
|
+
"Sales Order",
|
|
56779
|
+
"Delivery Note",
|
|
56780
|
+
"Sales Invoice",
|
|
56781
|
+
"Purchase Order",
|
|
56782
|
+
"Purchase Receipt",
|
|
56783
|
+
"Purchase Invoice",
|
|
56784
|
+
"Stock Entry",
|
|
56785
|
+
"Journal Entry",
|
|
56786
|
+
"Payment Entry",
|
|
56787
|
+
"Timesheet",
|
|
56788
|
+
"Leave Application",
|
|
56789
|
+
"Salary Slip",
|
|
56790
|
+
"BOM",
|
|
56791
|
+
"Work Order",
|
|
56792
|
+
"Job Card",
|
|
56793
|
+
"Asset",
|
|
56794
|
+
"Asset Movement",
|
|
56795
|
+
"Shipment"
|
|
56796
|
+
]);
|
|
56797
|
+
var INVOICE_DEDICATED_MUTATION_TOOLS = {
|
|
56798
|
+
"Sales Order": [
|
|
56799
|
+
"erpnext_sales_order_submit",
|
|
56800
|
+
"erpnext_sales_order_cancel"
|
|
56801
|
+
],
|
|
56802
|
+
"Sales Invoice": ["erpnext_sales_invoice_submit"]
|
|
56803
|
+
};
|
|
56804
|
+
function addDoctypeMutationCandidates(target, uri, doctype) {
|
|
56805
|
+
if (!doctype || !SUBMITTABLE_VIEWER_DOCTYPES.has(doctype)) return;
|
|
56806
|
+
if (uri === "ui://mcp-erpnext/invoice-viewer" || uri === "ui://mcp-erpnext/doclist-viewer") {
|
|
56807
|
+
target.add("erpnext_doc_submit");
|
|
56808
|
+
target.add("erpnext_doc_cancel");
|
|
56809
|
+
}
|
|
56810
|
+
if (uri === "ui://mcp-erpnext/invoice-viewer") {
|
|
56811
|
+
for (const tool of INVOICE_DEDICATED_MUTATION_TOOLS[doctype] ?? []) {
|
|
56812
|
+
target.add(tool);
|
|
56813
|
+
}
|
|
56814
|
+
}
|
|
56815
|
+
}
|
|
56816
|
+
function addJumpTools(target, jumps) {
|
|
56817
|
+
if (!jumps) return;
|
|
56818
|
+
for (const jump of Object.values(jumps)) target.add(jump.tool);
|
|
56819
|
+
}
|
|
56820
|
+
function addSeriesJumpTools(target, jumps) {
|
|
56821
|
+
if (!jumps) return;
|
|
56822
|
+
for (const seriesJumps of Object.values(jumps)) {
|
|
56823
|
+
addJumpTools(target, seriesJumps);
|
|
56824
|
+
}
|
|
56825
|
+
}
|
|
56826
|
+
function availableViewerToolNames(result, availableToolNames) {
|
|
56827
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
56828
|
+
const uri = result._meta?.ui?.resourceUri;
|
|
56829
|
+
for (const name of uri ? VIEWER_TOOL_CANDIDATES[uri] ?? [] : []) {
|
|
56830
|
+
candidates.add(name);
|
|
56831
|
+
}
|
|
56832
|
+
addDoctypeMutationCandidates(candidates, uri, resultDoctype(result));
|
|
56833
|
+
if (result.refreshRequest) candidates.add(result.refreshRequest.toolName);
|
|
56834
|
+
if (result._rowAction) candidates.add(result._rowAction.toolName);
|
|
56835
|
+
for (const hint of result._sendMessageHints ?? []) {
|
|
56836
|
+
if (hint.tool) candidates.add(hint.tool);
|
|
56837
|
+
}
|
|
56838
|
+
addJumpTools(
|
|
56839
|
+
candidates,
|
|
56840
|
+
result._jumps ? Object.fromEntries(
|
|
56841
|
+
Object.entries(result._jumps).filter(
|
|
56842
|
+
(entry) => entry[1] !== void 0
|
|
56843
|
+
)
|
|
56844
|
+
) : void 0
|
|
56845
|
+
);
|
|
56846
|
+
addJumpTools(candidates, result._stageJumps);
|
|
56847
|
+
addJumpTools(candidates, result._pointJumps);
|
|
56848
|
+
addSeriesJumpTools(candidates, result._seriesPointJumps);
|
|
56849
|
+
if (typeof result.moveToolName === "string") {
|
|
56850
|
+
candidates.add(result.moveToolName);
|
|
56851
|
+
}
|
|
56852
|
+
return [...candidates].filter((name) => availableToolNames.has(name)).sort();
|
|
56853
|
+
}
|
|
56854
|
+
function filterJumpMap(jumps, availableToolNames) {
|
|
56855
|
+
const available = Object.fromEntries(
|
|
56856
|
+
Object.entries(jumps).filter(
|
|
56857
|
+
([, jump]) => availableToolNames.has(jump.tool)
|
|
56858
|
+
)
|
|
56859
|
+
);
|
|
56860
|
+
return Object.keys(available).length > 0 ? available : void 0;
|
|
56861
|
+
}
|
|
56862
|
+
function filterSeriesJumpMap(jumps, availableToolNames) {
|
|
56863
|
+
const available = {};
|
|
56864
|
+
for (const [label, seriesJumps] of Object.entries(jumps)) {
|
|
56865
|
+
const filtered = filterJumpMap(seriesJumps, availableToolNames);
|
|
56866
|
+
if (filtered) available[label] = filtered;
|
|
56867
|
+
}
|
|
56868
|
+
return Object.keys(available).length > 0 ? available : void 0;
|
|
56869
|
+
}
|
|
56870
|
+
function filterNavJumpsByAvailableTools(result, availableToolNames) {
|
|
56871
|
+
if (!availableToolNames) return result;
|
|
56872
|
+
const filtered = { ...result };
|
|
56873
|
+
if (result._jumps) {
|
|
56874
|
+
const jumps = filterJumpMap(
|
|
56875
|
+
Object.fromEntries(
|
|
56876
|
+
Object.entries(result._jumps).filter(
|
|
56877
|
+
(entry) => entry[1] !== void 0
|
|
56878
|
+
)
|
|
56879
|
+
),
|
|
56880
|
+
availableToolNames
|
|
56881
|
+
);
|
|
56882
|
+
if (jumps) filtered._jumps = jumps;
|
|
56883
|
+
else delete filtered._jumps;
|
|
56884
|
+
}
|
|
56885
|
+
if (result._stageJumps) {
|
|
56886
|
+
const jumps = filterJumpMap(result._stageJumps, availableToolNames);
|
|
56887
|
+
if (jumps) filtered._stageJumps = jumps;
|
|
56888
|
+
else delete filtered._stageJumps;
|
|
56889
|
+
}
|
|
56890
|
+
if (result._pointJumps) {
|
|
56891
|
+
const jumps = filterJumpMap(result._pointJumps, availableToolNames);
|
|
56892
|
+
if (jumps) filtered._pointJumps = jumps;
|
|
56893
|
+
else delete filtered._pointJumps;
|
|
56894
|
+
}
|
|
56895
|
+
if (result._seriesPointJumps) {
|
|
56896
|
+
const jumps = filterSeriesJumpMap(
|
|
56897
|
+
result._seriesPointJumps,
|
|
56898
|
+
availableToolNames
|
|
56899
|
+
);
|
|
56900
|
+
if (jumps) filtered._seriesPointJumps = jumps;
|
|
56901
|
+
else delete filtered._seriesPointJumps;
|
|
56902
|
+
}
|
|
56903
|
+
if (result._rowAction && !availableToolNames.has(result._rowAction.toolName)) {
|
|
56904
|
+
const doctype = resultDoctype(result);
|
|
56905
|
+
if (doctype && availableToolNames.has("erpnext_doc_get")) {
|
|
56906
|
+
filtered._rowAction = {
|
|
56907
|
+
toolName: "erpnext_doc_get",
|
|
56908
|
+
idField: "name",
|
|
56909
|
+
argName: "name",
|
|
56910
|
+
extraArgs: { doctype }
|
|
56911
|
+
};
|
|
56912
|
+
} else {
|
|
56913
|
+
delete filtered._rowAction;
|
|
56914
|
+
}
|
|
56915
|
+
}
|
|
56916
|
+
if (result._sendMessageHints) {
|
|
56917
|
+
filtered._sendMessageHints = result._sendMessageHints.map((hint) => {
|
|
56918
|
+
if (!hint.tool || availableToolNames.has(hint.tool)) return hint;
|
|
56919
|
+
return { key: hint.key, label: hint.label, message: hint.message };
|
|
56920
|
+
});
|
|
56921
|
+
}
|
|
56922
|
+
filtered._availableTools = availableViewerToolNames(
|
|
56923
|
+
filtered,
|
|
56924
|
+
availableToolNames
|
|
56925
|
+
);
|
|
56926
|
+
return filtered;
|
|
56927
|
+
}
|
|
56928
|
+
function withViewerToolCapabilities(result, availableToolNames) {
|
|
56929
|
+
if (!isRecord7(result) || !hasUiResource(result)) return result;
|
|
56930
|
+
return filterNavJumpsByAvailableTools(result, availableToolNames);
|
|
56931
|
+
}
|
|
56932
|
+
function withUiRefreshRequest(result, toolName, args, now = /* @__PURE__ */ new Date(), availableToolNames) {
|
|
55703
56933
|
if (!isRecord7(result) || !hasUiResource(result)) {
|
|
55704
56934
|
return result;
|
|
55705
56935
|
}
|
|
@@ -55749,10 +56979,79 @@ function withUiRefreshRequest(result, toolName, args) {
|
|
|
55749
56979
|
}
|
|
55750
56980
|
}
|
|
55751
56981
|
}
|
|
55752
|
-
|
|
56982
|
+
if (isKpiViewer(enriched) && !enriched._jumps) {
|
|
56983
|
+
const jumps = KPI_JUMPS[toolName];
|
|
56984
|
+
if (jumps) enriched._jumps = jumps(monthRange(now));
|
|
56985
|
+
}
|
|
56986
|
+
if (isFunnelViewer(enriched) && !enriched._stageJumps) {
|
|
56987
|
+
enriched._stageJumps = funnelStageJumps(args, now);
|
|
56988
|
+
}
|
|
56989
|
+
if (isChartViewer(enriched) && Array.isArray(enriched.labels)) {
|
|
56990
|
+
const labels = enriched.labels.map(String);
|
|
56991
|
+
if (!enriched._pointJumps) {
|
|
56992
|
+
const jumps = chartPointJumps(toolName, args, labels, now);
|
|
56993
|
+
if (jumps) enriched._pointJumps = jumps;
|
|
56994
|
+
}
|
|
56995
|
+
if (!enriched._seriesPointJumps) {
|
|
56996
|
+
const jumps = chartSeriesPointJumps(toolName, args, labels, now);
|
|
56997
|
+
if (jumps) enriched._seriesPointJumps = jumps;
|
|
56998
|
+
}
|
|
56999
|
+
}
|
|
57000
|
+
if (!enriched._sendMessageHints) {
|
|
57001
|
+
const doctype = resultDoctype(enriched);
|
|
57002
|
+
if (isInvoiceViewer(enriched) && doctype) {
|
|
57003
|
+
const hints = INVOICE_HINTS[doctype];
|
|
57004
|
+
if (hints) enriched._sendMessageHints = hints;
|
|
57005
|
+
} else if (isStockViewer(enriched)) {
|
|
57006
|
+
enriched._sendMessageHints = STOCK_HINTS;
|
|
57007
|
+
} else if (isKanbanViewer(enriched) && doctype) {
|
|
57008
|
+
const hints = DOCTYPE_SEND_MESSAGE_HINTS[doctype];
|
|
57009
|
+
if (hints) enriched._sendMessageHints = hints;
|
|
57010
|
+
}
|
|
57011
|
+
}
|
|
57012
|
+
return filterNavJumpsByAvailableTools(enriched, availableToolNames);
|
|
55753
57013
|
}
|
|
55754
57014
|
|
|
55755
57015
|
// src/client.ts
|
|
57016
|
+
function isRecord8(value) {
|
|
57017
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
57018
|
+
}
|
|
57019
|
+
function withSafeUiRefresh(result, tool, args, availableToolNames) {
|
|
57020
|
+
const readOnly = tool.annotations?.readOnlyHint === true;
|
|
57021
|
+
if (!isRecord8(result)) {
|
|
57022
|
+
return result;
|
|
57023
|
+
}
|
|
57024
|
+
const resultMeta = isRecord8(result._meta) ? result._meta : {};
|
|
57025
|
+
const declaredUi = tool._meta?.ui;
|
|
57026
|
+
const viewerResult = declaredUi && !isRecord8(resultMeta.ui) ? {
|
|
57027
|
+
...result,
|
|
57028
|
+
_meta: { ...resultMeta, ...tool._meta, ui: declaredUi }
|
|
57029
|
+
} : result;
|
|
57030
|
+
const request = isRecord8(viewerResult.refreshRequest) ? viewerResult.refreshRequest : null;
|
|
57031
|
+
const target = request && typeof request.toolName === "string" ? getToolByName(request.toolName) : void 0;
|
|
57032
|
+
const hasSafeExplicitRefresh = request !== null && typeof request.toolName === "string" && availableToolNames.has(request.toolName) && isRecord8(request.arguments) && (request.toolName === tool.name ? readOnly : target?.annotations?.readOnlyHint === true);
|
|
57033
|
+
if (hasSafeExplicitRefresh) {
|
|
57034
|
+
return withUiRefreshRequest(
|
|
57035
|
+
viewerResult,
|
|
57036
|
+
tool.name,
|
|
57037
|
+
args,
|
|
57038
|
+
/* @__PURE__ */ new Date(),
|
|
57039
|
+
availableToolNames
|
|
57040
|
+
);
|
|
57041
|
+
}
|
|
57042
|
+
let sanitized = viewerResult;
|
|
57043
|
+
if ("refreshRequest" in viewerResult) {
|
|
57044
|
+
sanitized = { ...viewerResult };
|
|
57045
|
+
delete sanitized.refreshRequest;
|
|
57046
|
+
}
|
|
57047
|
+
return readOnly ? withUiRefreshRequest(
|
|
57048
|
+
sanitized,
|
|
57049
|
+
tool.name,
|
|
57050
|
+
args,
|
|
57051
|
+
/* @__PURE__ */ new Date(),
|
|
57052
|
+
availableToolNames
|
|
57053
|
+
) : withViewerToolCapabilities(sanitized, availableToolNames);
|
|
57054
|
+
}
|
|
55756
57055
|
var ErpNextToolsClient = class {
|
|
55757
57056
|
tools;
|
|
55758
57057
|
enableLinkDisambiguation;
|
|
@@ -55793,6 +57092,7 @@ var ErpNextToolsClient = class {
|
|
|
55793
57092
|
*/
|
|
55794
57093
|
buildHandlersMap() {
|
|
55795
57094
|
const handlers = /* @__PURE__ */ new Map();
|
|
57095
|
+
const availableToolNames = new Set(this.tools.map((tool) => tool.name));
|
|
55796
57096
|
for (const tool of this.tools) {
|
|
55797
57097
|
const toolMeta = tool._meta;
|
|
55798
57098
|
handlers.set(tool.name, async (args, mcpContext) => {
|
|
@@ -55815,10 +57115,11 @@ var ErpNextToolsClient = class {
|
|
|
55815
57115
|
if (execution.result !== null && typeof execution.result === "object" && !Array.isArray(execution.result) && execution.result.resultType === "input_required") {
|
|
55816
57116
|
return execution.result;
|
|
55817
57117
|
}
|
|
55818
|
-
const result =
|
|
57118
|
+
const result = withSafeUiRefresh(
|
|
55819
57119
|
execution.result,
|
|
55820
|
-
tool
|
|
55821
|
-
execution.args
|
|
57120
|
+
tool,
|
|
57121
|
+
execution.args,
|
|
57122
|
+
availableToolNames
|
|
55822
57123
|
);
|
|
55823
57124
|
const r = result !== null && typeof result === "object" && !Array.isArray(result) ? result : null;
|
|
55824
57125
|
const resultUi = r?._meta && typeof r._meta === "object" && r._meta.ui;
|
|
@@ -55845,7 +57146,12 @@ var ErpNextToolsClient = class {
|
|
|
55845
57146
|
}
|
|
55846
57147
|
const client = getFrappeClient();
|
|
55847
57148
|
const result = await tool.handler(args, { client });
|
|
55848
|
-
return
|
|
57149
|
+
return withSafeUiRefresh(
|
|
57150
|
+
result,
|
|
57151
|
+
tool,
|
|
57152
|
+
args,
|
|
57153
|
+
new Set(this.tools.map((candidate) => candidate.name))
|
|
57154
|
+
);
|
|
55849
57155
|
}
|
|
55850
57156
|
/** Get tool count */
|
|
55851
57157
|
get count() {
|
|
@@ -56102,7 +57408,7 @@ async function main() {
|
|
|
56102
57408
|
);
|
|
56103
57409
|
const server = new McpApp({
|
|
56104
57410
|
name: "mcp-erpnext",
|
|
56105
|
-
version: "3.0.
|
|
57411
|
+
version: "3.1.0-beta.1",
|
|
56106
57412
|
transport: "stateless",
|
|
56107
57413
|
cache: {
|
|
56108
57414
|
ttlMs: 36e5,
|