@ganju/utils 0.0.14 → 0.0.16
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/dist/channelCustomer.d.ts +99 -0
- package/dist/channelCustomer.d.ts.map +1 -0
- package/dist/channelCustomer.js +533 -0
- package/dist/channelDebounce.d.ts +7 -0
- package/dist/channelDebounce.d.ts.map +1 -1
- package/dist/chunkOverlap.d.ts +2 -0
- package/dist/chunkOverlap.d.ts.map +1 -0
- package/dist/chunkOverlap.js +9 -0
- package/dist/chunking.d.ts.map +1 -1
- package/dist/chunking.js +24 -4
- package/dist/citations.d.ts +28 -0
- package/dist/citations.d.ts.map +1 -0
- package/dist/citations.js +111 -0
- package/dist/constants.d.ts +49 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +202 -17
- package/dist/data.d.ts +9 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +78 -0
- package/dist/dataApi.d.ts +511 -0
- package/dist/dataApi.d.ts.map +1 -0
- package/dist/dataApi.js +355 -0
- package/dist/dataCompiler.d.ts +68 -0
- package/dist/dataCompiler.d.ts.map +1 -0
- package/dist/dataCompiler.js +726 -0
- package/dist/dataDdl.d.ts +29 -0
- package/dist/dataDdl.d.ts.map +1 -0
- package/dist/dataDdl.js +354 -0
- package/dist/dataEngine.d.ts +143 -0
- package/dist/dataEngine.d.ts.map +1 -0
- package/dist/dataEngine.js +2022 -0
- package/dist/dataIdentifiers.d.ts +8 -0
- package/dist/dataIdentifiers.d.ts.map +1 -0
- package/dist/dataIdentifiers.js +55 -0
- package/dist/dataImport.d.ts +77 -0
- package/dist/dataImport.d.ts.map +1 -0
- package/dist/dataImport.js +450 -0
- package/dist/dataRpc.d.ts +131 -0
- package/dist/dataRpc.d.ts.map +1 -0
- package/dist/dataRpc.js +2 -0
- package/dist/dataTypes.d.ts +157 -0
- package/dist/dataTypes.d.ts.map +1 -0
- package/dist/dataTypes.js +160 -0
- package/dist/index.d.ts +570 -36
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +72 -0
- package/dist/jsonSchemaToZodShape.d.ts +5 -1
- package/dist/jsonSchemaToZodShape.d.ts.map +1 -1
- package/dist/jsonSchemaToZodShape.js +21 -9
- package/dist/oauth.d.ts +14 -0
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +42 -2
- package/dist/pagination.d.ts +47 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +160 -0
- package/dist/processQueueBatch.d.ts +6 -1
- package/dist/processQueueBatch.d.ts.map +1 -1
- package/dist/processQueueBatch.js +23 -10
- package/dist/queueFailure.d.ts +14 -0
- package/dist/queueFailure.d.ts.map +1 -0
- package/dist/queueFailure.js +43 -0
- package/dist/resourceRerank.d.ts +3 -2
- package/dist/resourceRerank.d.ts.map +1 -1
- package/dist/resourceRerank.js +8 -3
- package/dist/schema.d.ts +374 -29
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +290 -6
- package/dist/ssrf.d.ts +1 -0
- package/dist/ssrf.d.ts.map +1 -1
- package/dist/ssrf.js +48 -12
- package/dist/toolConfirmation.d.ts +48 -0
- package/dist/toolConfirmation.d.ts.map +1 -1
- package/dist/toolConfirmation.js +75 -1
- package/dist/toolCount.d.ts +13 -0
- package/dist/toolCount.d.ts.map +1 -0
- package/dist/toolCount.js +45 -0
- package/dist/toolLint.d.ts +1 -1
- package/dist/toolLint.d.ts.map +1 -1
- package/dist/toolLint.js +20 -0
- package/dist/untrustedContent.d.ts +135 -0
- package/dist/untrustedContent.d.ts.map +1 -0
- package/dist/untrustedContent.js +402 -0
- package/package.json +17 -1
- package/src/channelCustomer.ts +604 -0
- package/src/channelDebounce.ts +17 -0
- package/src/chunkOverlap.ts +6 -0
- package/src/chunking.ts +25 -4
- package/src/citations.ts +127 -0
- package/src/constants.ts +219 -17
- package/src/data.ts +74 -0
- package/src/dataApi.ts +428 -0
- package/src/dataCompiler.ts +948 -0
- package/src/dataDdl.ts +419 -0
- package/src/dataEngine.ts +2753 -0
- package/src/dataIdentifiers.ts +63 -0
- package/src/dataImport.ts +554 -0
- package/src/dataRpc.ts +121 -0
- package/src/dataTypes.ts +312 -0
- package/src/index.ts +156 -2
- package/src/jsonSchemaToZodShape.ts +31 -13
- package/src/oauth.ts +42 -1
- package/src/pagination.ts +193 -0
- package/src/processQueueBatch.ts +42 -12
- package/src/queueFailure.ts +63 -0
- package/src/resourceRerank.ts +10 -3
- package/src/schema.ts +346 -4
- package/src/ssrf.ts +40 -11
- package/src/toolConfirmation.ts +123 -0
- package/src/toolCount.ts +53 -0
- package/src/toolLint.ts +27 -0
- package/src/untrustedContent.ts +476 -0
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA0hCxB,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgGrB,CAAC;AAyDN,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4CpB,CAAC;AAWH,QAAA,MAAM,kBAAkB;;;;;;;;;;iBA+CtB,CAAC;AAqCH,QAAA,MAAM,gBAAgB;;;;;kBAOX,CAAC;AAEZ,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAcpB,CAAC;AAYH,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCxB,CAAC;AA2OH,QAAA,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4DpC,CAAC;AA4BL,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAkDzB,CAAC;AAuHH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4IlB,CAAC;AAGF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAG1E,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAIlE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAMtE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAGtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIvE,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC5C,OAAO,kCAAkC,CAC1C,CAAC;AAKF,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IAIrB,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;CAChD;AAKD,MAAM,WAAW,0BAA0B;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAC1E;AAMD,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACzC,OAAO,CAAC,EAAE,wBAAwB,EAAE,CAAC;CACtC"}
|
package/dist/schema.js
CHANGED
|
@@ -5,9 +5,12 @@ const zod_1 = require("zod");
|
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
6
|
const llmBaseUrl_1 = require("./llmBaseUrl");
|
|
7
7
|
const slug_1 = require("./slug");
|
|
8
|
+
const ssrf_1 = require("./ssrf");
|
|
8
9
|
const reservedToolName_1 = require("./reservedToolName");
|
|
9
10
|
const slugifyTitle_1 = require("./slugifyTitle");
|
|
10
11
|
const toolConfirmation_1 = require("./toolConfirmation");
|
|
12
|
+
const channelCustomer_1 = require("./channelCustomer");
|
|
13
|
+
const dataTypes_1 = require("./dataTypes");
|
|
11
14
|
// A prompt title becomes a slash command; it must not collide with a command
|
|
12
15
|
// the channel runner handles itself (e.g. `/link`).
|
|
13
16
|
const PROMPT_TITLE = zod_1.z
|
|
@@ -149,6 +152,13 @@ const INVITATION_RESPOND = zod_1.z.object({
|
|
|
149
152
|
userId: zod_1.z.uuid(),
|
|
150
153
|
action: zod_1.z.enum(constants_1.constants.INVITATION_RESPONSES)
|
|
151
154
|
});
|
|
155
|
+
const TOOL_APPROVAL_GET = zod_1.z.object({
|
|
156
|
+
approvalId: zod_1.z.uuid()
|
|
157
|
+
});
|
|
158
|
+
const TOOL_APPROVAL_DECIDE = zod_1.z.object({
|
|
159
|
+
approvalId: zod_1.z.uuid(),
|
|
160
|
+
decision: zod_1.z.enum(constants_1.constants.TOOL_APPROVAL_DECISIONS)
|
|
161
|
+
});
|
|
152
162
|
const INVITATION_GET_BY_TOKEN = zod_1.z.object({
|
|
153
163
|
token: zod_1.z.string().min(8).max(128)
|
|
154
164
|
});
|
|
@@ -230,7 +240,8 @@ const ARTIFACT_CREATE_WEBSITE_VIEW = zod_1.z.object({
|
|
|
230
240
|
title: zod_1.z.string().min(3).max(200),
|
|
231
241
|
uri: zod_1.z
|
|
232
242
|
.url('Enter a valid URL')
|
|
233
|
-
.refine(v => /^https?:\/\//i.test(v), 'Only http and https URLs are supported')
|
|
243
|
+
.refine(v => /^https?:\/\//i.test(v), 'Only http and https URLs are supported')
|
|
244
|
+
.refine(v => !(0, ssrf_1.isBlockedUrl)(v), "This address points to a private network and can't be crawled"),
|
|
234
245
|
description: zod_1.z.string().optional(),
|
|
235
246
|
maxPages: zod_1.z.number().int().min(1).max(constants_1.constants.CRAWL_MAX_PAGES_LIMIT),
|
|
236
247
|
maxDepth: zod_1.z.number().int().min(0).max(constants_1.constants.CRAWL_MAX_DEPTH_LIMIT)
|
|
@@ -239,7 +250,8 @@ const ARTIFACT_CREATE_WEBSITE = zod_1.z.object({
|
|
|
239
250
|
title: zod_1.z.string().min(3).max(200),
|
|
240
251
|
uri: zod_1.z
|
|
241
252
|
.url('Enter a valid URL')
|
|
242
|
-
.refine(v => /^https?:\/\//i.test(v), 'Only http and https URLs are supported')
|
|
253
|
+
.refine(v => /^https?:\/\//i.test(v), 'Only http and https URLs are supported')
|
|
254
|
+
.refine(v => !(0, ssrf_1.isBlockedUrl)(v), "This address points to a private network and can't be crawled"),
|
|
243
255
|
description: zod_1.z.string().optional(),
|
|
244
256
|
crawlConfig: zod_1.z.object({
|
|
245
257
|
maxPages: zod_1.z.number().int().min(1).max(constants_1.constants.CRAWL_MAX_PAGES_LIMIT),
|
|
@@ -416,6 +428,183 @@ const ARTIFACT_REMOVE_RESOURCE = zod_1.z.object({
|
|
|
416
428
|
userId: zod_1.z.uuid(),
|
|
417
429
|
organizationId: zod_1.z.uuid()
|
|
418
430
|
});
|
|
431
|
+
const DATA_DATABASE_GET = zod_1.z.object({
|
|
432
|
+
projectId: zod_1.z.uuid(),
|
|
433
|
+
userId: zod_1.z.uuid(),
|
|
434
|
+
organizationId: zod_1.z.uuid()
|
|
435
|
+
});
|
|
436
|
+
// The name is what the owner types to delete it; it defaults to the
|
|
437
|
+
// project's slug. `replaceDeleted` starts over while a deleted database is
|
|
438
|
+
// still in its grace period, giving up the chance to restore it.
|
|
439
|
+
const DATA_DATABASE_CREATE = DATA_DATABASE_GET.extend({
|
|
440
|
+
name: zod_1.z.string().trim().min(1).max(100).optional(),
|
|
441
|
+
replaceDeleted: zod_1.z.boolean().optional()
|
|
442
|
+
});
|
|
443
|
+
const DATA_DATABASE_DELETE = DATA_DATABASE_GET.extend({
|
|
444
|
+
confirmName: zod_1.z.string().min(1)
|
|
445
|
+
});
|
|
446
|
+
// The bodies and query strings of the Data API. Each one is what a client
|
|
447
|
+
// sends; the route schemas below add the path's ids. The database object
|
|
448
|
+
// checks every rule again (names, types, relations), so these describe the
|
|
449
|
+
// shape and leave the meaning to it.
|
|
450
|
+
const DATA_IDENTIFIER = zod_1.z.string().min(1).max(63);
|
|
451
|
+
const DATA_DEFAULT_VALUE = zod_1.z.union([
|
|
452
|
+
zod_1.z.string(),
|
|
453
|
+
zod_1.z.number(),
|
|
454
|
+
zod_1.z.boolean(),
|
|
455
|
+
zod_1.z.null()
|
|
456
|
+
]);
|
|
457
|
+
const DATA_TEXT = (max) => zod_1.z.string().max(max).nullable().optional();
|
|
458
|
+
const DATA_COLUMN_INPUT = zod_1.z.strictObject({
|
|
459
|
+
name: DATA_IDENTIFIER,
|
|
460
|
+
type: zod_1.z.enum(dataTypes_1.DATA_COLUMN_TYPES),
|
|
461
|
+
label: DATA_TEXT(dataTypes_1.DATA_MAX_LABEL),
|
|
462
|
+
description: DATA_TEXT(dataTypes_1.DATA_MAX_DESCRIPTION),
|
|
463
|
+
required: zod_1.z.boolean().optional(),
|
|
464
|
+
unique: zod_1.z.boolean().optional(),
|
|
465
|
+
filterable: zod_1.z.boolean().optional(),
|
|
466
|
+
searchable: zod_1.z.boolean().optional(),
|
|
467
|
+
personal: zod_1.z.boolean().optional(),
|
|
468
|
+
values: zod_1.z.array(zod_1.z.string().min(1)).max(dataTypes_1.DATA_MAX_ENUM_VALUES).optional(),
|
|
469
|
+
table: DATA_IDENTIFIER.optional(),
|
|
470
|
+
onDelete: zod_1.z.enum(dataTypes_1.DATA_ON_DELETE).optional(),
|
|
471
|
+
min: zod_1.z.number().nullable().optional(),
|
|
472
|
+
default: DATA_DEFAULT_VALUE.optional()
|
|
473
|
+
});
|
|
474
|
+
// The CLI's schema file holds a list of these.
|
|
475
|
+
const DATA_TABLE_INPUT = zod_1.z.strictObject({
|
|
476
|
+
name: DATA_IDENTIFIER,
|
|
477
|
+
label: DATA_TEXT(dataTypes_1.DATA_MAX_LABEL),
|
|
478
|
+
description: DATA_TEXT(dataTypes_1.DATA_MAX_DESCRIPTION),
|
|
479
|
+
displayColumn: DATA_IDENTIFIER.nullable().optional(),
|
|
480
|
+
access: zod_1.z.enum(dataTypes_1.DATA_ACCESS_LEVELS).optional(),
|
|
481
|
+
customerScoped: zod_1.z.boolean().optional(),
|
|
482
|
+
history: zod_1.z.boolean().optional(),
|
|
483
|
+
columns: zod_1.z.array(DATA_COLUMN_INPUT).max(dataTypes_1.DATA_MAX_COLUMNS)
|
|
484
|
+
});
|
|
485
|
+
const DATA_TABLE_PATCH = DATA_TABLE_INPUT.omit({ columns: true }).partial();
|
|
486
|
+
// A null puts the setting back to its default.
|
|
487
|
+
const DATA_COLUMN_PATCH = DATA_COLUMN_INPUT.partial();
|
|
488
|
+
const DATA_TABLE_DROP_BODY = zod_1.z.strictObject({ confirmName: zod_1.z.string().min(1) });
|
|
489
|
+
const DATA_ROW_VALUES = zod_1.z.record(zod_1.z.string(), zod_1.z.unknown());
|
|
490
|
+
// A JSON value carried in a query string, e.g. `where={"status":"open"}`.
|
|
491
|
+
const DATA_JSON_PARAM = zod_1.z.string().transform((text, ctx) => {
|
|
492
|
+
try {
|
|
493
|
+
return JSON.parse(text);
|
|
494
|
+
}
|
|
495
|
+
catch {
|
|
496
|
+
ctx.addIssue({
|
|
497
|
+
code: 'custom',
|
|
498
|
+
message: 'This is JSON, e.g. {"status":"open"}'
|
|
499
|
+
});
|
|
500
|
+
return zod_1.z.NEVER;
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
// A comma-separated list in a query string: `sort=-created_at,name`.
|
|
504
|
+
const DATA_LIST_PARAM = zod_1.z.string().transform(text => text
|
|
505
|
+
.split(',')
|
|
506
|
+
.map(item => item.trim())
|
|
507
|
+
.filter(Boolean));
|
|
508
|
+
const DATA_ROW_LIST_QUERY = zod_1.z.strictObject({
|
|
509
|
+
where: DATA_JSON_PARAM.optional(),
|
|
510
|
+
sort: DATA_LIST_PARAM.optional(),
|
|
511
|
+
include: DATA_LIST_PARAM.optional(),
|
|
512
|
+
limit: zod_1.z.coerce.number().int().min(1).max(dataTypes_1.DATA_MAX_PAGE).optional(),
|
|
513
|
+
cursor: zod_1.z.string().max(2000).optional(),
|
|
514
|
+
q: zod_1.z.string().max(500).optional(),
|
|
515
|
+
timeZone: zod_1.z.string().max(64).optional()
|
|
516
|
+
});
|
|
517
|
+
const DATA_ROW_GET_QUERY = DATA_ROW_LIST_QUERY.pick({
|
|
518
|
+
include: true,
|
|
519
|
+
timeZone: true
|
|
520
|
+
});
|
|
521
|
+
const DATA_ROW_CREATE_BODY = zod_1.z.union([
|
|
522
|
+
zod_1.z.strictObject({ values: DATA_ROW_VALUES }),
|
|
523
|
+
zod_1.z.strictObject({
|
|
524
|
+
rows: zod_1.z.array(DATA_ROW_VALUES).min(1).max(dataTypes_1.DATA_MAX_INSERT_ROWS)
|
|
525
|
+
})
|
|
526
|
+
]);
|
|
527
|
+
const DATA_ROW_VERSION = zod_1.z.number().int().min(1);
|
|
528
|
+
// `set` takes values, or relative changes such as { "stock": { "decrement": 2 } }.
|
|
529
|
+
const DATA_ROW_UPDATE_BODY = zod_1.z.strictObject({
|
|
530
|
+
set: DATA_ROW_VALUES,
|
|
531
|
+
version: DATA_ROW_VERSION.optional()
|
|
532
|
+
});
|
|
533
|
+
const DATA_ROW_DELETE_BODY = zod_1.z.strictObject({
|
|
534
|
+
version: DATA_ROW_VERSION.optional()
|
|
535
|
+
});
|
|
536
|
+
const DATA_ROW_ID = zod_1.z.coerce.number().int().min(1);
|
|
537
|
+
// Without `ids`, every row of the table.
|
|
538
|
+
const DATA_DELETE_PREVIEW_BODY = zod_1.z.strictObject({
|
|
539
|
+
ids: zod_1.z.array(zod_1.z.number().int().min(1)).min(1).max(dataTypes_1.DATA_IMPACT_MAX_IDS).optional()
|
|
540
|
+
});
|
|
541
|
+
const DATA_WRITE_TARGET = {
|
|
542
|
+
table: DATA_IDENTIFIER,
|
|
543
|
+
id: zod_1.z
|
|
544
|
+
.union([
|
|
545
|
+
zod_1.z.number().int().min(1),
|
|
546
|
+
zod_1.z.strictObject({ $ref: zod_1.z.number().int().min(0) })
|
|
547
|
+
])
|
|
548
|
+
.optional(),
|
|
549
|
+
where: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
|
|
550
|
+
expect: zod_1.z.number().int().min(0).optional(),
|
|
551
|
+
version: DATA_ROW_VERSION.optional()
|
|
552
|
+
};
|
|
553
|
+
// Applied together or not at all. A later step can use an earlier insert's
|
|
554
|
+
// id as { "$ref": <step> }.
|
|
555
|
+
const DATA_WRITE_OPERATION = zod_1.z.discriminatedUnion('op', [
|
|
556
|
+
zod_1.z.strictObject({
|
|
557
|
+
op: zod_1.z.literal('insert'),
|
|
558
|
+
table: DATA_IDENTIFIER,
|
|
559
|
+
values: DATA_ROW_VALUES.optional(),
|
|
560
|
+
rows: zod_1.z.array(DATA_ROW_VALUES).min(1).max(dataTypes_1.DATA_MAX_INSERT_ROWS).optional()
|
|
561
|
+
}),
|
|
562
|
+
zod_1.z.strictObject({
|
|
563
|
+
op: zod_1.z.literal('update'),
|
|
564
|
+
...DATA_WRITE_TARGET,
|
|
565
|
+
set: DATA_ROW_VALUES
|
|
566
|
+
}),
|
|
567
|
+
zod_1.z.strictObject({ op: zod_1.z.literal('delete'), ...DATA_WRITE_TARGET })
|
|
568
|
+
]);
|
|
569
|
+
const DATA_WRITE_BODY = zod_1.z.strictObject({
|
|
570
|
+
operations: zod_1.z
|
|
571
|
+
.array(DATA_WRITE_OPERATION)
|
|
572
|
+
.min(1)
|
|
573
|
+
.max(dataTypes_1.DATA_MAX_WRITE_OPERATIONS)
|
|
574
|
+
});
|
|
575
|
+
const DATA_ROW_HISTORY_QUERY = zod_1.z.strictObject({
|
|
576
|
+
limit: zod_1.z.coerce.number().int().min(1).max(100).optional(),
|
|
577
|
+
cursor: zod_1.z.coerce.number().int().min(1).optional(),
|
|
578
|
+
timeZone: zod_1.z.string().max(64).optional()
|
|
579
|
+
});
|
|
580
|
+
// A time within the last 30 days, or a bookmark this API handed out (a drop,
|
|
581
|
+
// a type change, or the restore to undo).
|
|
582
|
+
const DATA_RESTORE_POINT_BODY = zod_1.z.union([
|
|
583
|
+
zod_1.z.strictObject({
|
|
584
|
+
timestamp: zod_1.z.union([zod_1.z.iso.datetime({ offset: true }), zod_1.z.number().int()])
|
|
585
|
+
}),
|
|
586
|
+
zod_1.z.strictObject({ bookmark: zod_1.z.string().min(1).max(200) })
|
|
587
|
+
]);
|
|
588
|
+
const DATA_EXPORT_BODY = zod_1.z.strictObject({
|
|
589
|
+
format: zod_1.z.enum(['jsonl', 'csv']).optional()
|
|
590
|
+
});
|
|
591
|
+
const DATA_EXPORT_QUERY = zod_1.z.strictObject({
|
|
592
|
+
exportId: zod_1.z.uuid().optional()
|
|
593
|
+
});
|
|
594
|
+
// Without `table`, the export's schema.json.
|
|
595
|
+
const DATA_EXPORT_FILE_QUERY = zod_1.z.strictObject({
|
|
596
|
+
exportId: zod_1.z.uuid(),
|
|
597
|
+
table: DATA_IDENTIFIER.optional()
|
|
598
|
+
});
|
|
599
|
+
const DATA_CHANGE_LIST_QUERY = zod_1.z.strictObject({
|
|
600
|
+
limit: zod_1.z.coerce.number().int().min(1).max(100).optional(),
|
|
601
|
+
cursor: zod_1.z.uuid().optional()
|
|
602
|
+
});
|
|
603
|
+
const DATA_TABLE_PARAMS = DATA_DATABASE_GET.extend({ table: DATA_IDENTIFIER });
|
|
604
|
+
const DATA_COLUMN_PARAMS = DATA_TABLE_PARAMS.extend({
|
|
605
|
+
column: DATA_IDENTIFIER
|
|
606
|
+
});
|
|
607
|
+
const DATA_ROW_PARAMS = DATA_TABLE_PARAMS.extend({ id: DATA_ROW_ID });
|
|
419
608
|
const ARTIFACT_UPLOAD_RESOURCE_FILE = zod_1.z.object({
|
|
420
609
|
resourceId: zod_1.z.uuid(),
|
|
421
610
|
projectId: zod_1.z.uuid(),
|
|
@@ -600,18 +789,27 @@ const ORGANIZATION_UPDATE_LLM_VIEW = refineUpdateBaseUrl(ORGANIZATION_UPDATE_LLM
|
|
|
600
789
|
userId: true,
|
|
601
790
|
organizationId: true
|
|
602
791
|
}));
|
|
603
|
-
//
|
|
604
|
-
//
|
|
792
|
+
// The channel settings an owner can write. Strict: a typo or a setting that
|
|
793
|
+
// no longer exists is refused rather than stored, where nothing would read it.
|
|
605
794
|
// `debounceMs` is how long a burst from one participant is buffered before the
|
|
606
795
|
// agent answers it as a single turn; 0 disables buffering.
|
|
607
|
-
const CHANNEL_CONFIG = zod_1.z.
|
|
796
|
+
const CHANNEL_CONFIG = zod_1.z.strictObject({
|
|
608
797
|
debounceMs: zod_1.z
|
|
609
798
|
.number()
|
|
610
799
|
.int()
|
|
611
800
|
.refine(value => value === constants_1.constants.CHANNEL_DEBOUNCE_DISABLED ||
|
|
612
801
|
(value >= constants_1.constants.CHANNEL_DEBOUNCE_MIN_MS &&
|
|
613
802
|
value <= constants_1.constants.CHANNEL_DEBOUNCE_MAX_MS), `debounceMs must be 0 (disabled) or between ${constants_1.constants.CHANNEL_DEBOUNCE_MIN_MS} and ${constants_1.constants.CHANNEL_DEBOUNCE_MAX_MS} ms`)
|
|
614
|
-
.optional()
|
|
803
|
+
.optional(),
|
|
804
|
+
// Replies one customer gets in 24 hours; 0 turns the limit off.
|
|
805
|
+
participantDailyLimit: zod_1.z
|
|
806
|
+
.number()
|
|
807
|
+
.int()
|
|
808
|
+
.min(channelCustomer_1.PARTICIPANT_DAILY_LIMIT_OFF)
|
|
809
|
+
.max(channelCustomer_1.PARTICIPANT_DAILY_LIMIT_MAX)
|
|
810
|
+
.optional(),
|
|
811
|
+
// Remember each customer's name, address, allergies and dates.
|
|
812
|
+
participantMemory: zod_1.z.boolean().optional()
|
|
615
813
|
});
|
|
616
814
|
const CHANNEL_CREATE = zod_1.z.object({
|
|
617
815
|
platform: zod_1.z.enum(constants_1.constants.CHANNEL_PLATFORMS),
|
|
@@ -626,6 +824,9 @@ const CHANNEL_UPDATE = zod_1.z.object({
|
|
|
626
824
|
channelId: zod_1.z.uuid(),
|
|
627
825
|
status: zod_1.z.enum(constants_1.constants.CHANNEL_STATUS).optional(),
|
|
628
826
|
config: CHANNEL_CONFIG.optional(),
|
|
827
|
+
// Keys to change on the stored config, merged by the database, so two
|
|
828
|
+
// settings saved at once don't overwrite each other.
|
|
829
|
+
configPatch: CHANNEL_CONFIG.optional(),
|
|
629
830
|
credentials: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
|
|
630
831
|
llmId: zod_1.z.uuid().nullable().optional(),
|
|
631
832
|
projectId: zod_1.z.uuid(),
|
|
@@ -827,6 +1028,15 @@ const MCP_PROXY_CONFIG = zod_1.z.object({
|
|
|
827
1028
|
allowedResources: zod_1.z.array(zod_1.z.string().min(1).max(2048)).max(500).optional(),
|
|
828
1029
|
allowedPrompts: zod_1.z.array(zod_1.z.string().min(1).max(256)).max(500).optional(),
|
|
829
1030
|
auth: MCP_PROXY_AUTH.default({ kind: constants_1.constants.MCP_PROXY_AUTH_KIND_NONE }),
|
|
1031
|
+
// Whether the remote's own readOnlyHint / destructiveHint decide which of its
|
|
1032
|
+
// tools are confirmed. Off (or absent), every proxied tool counts as
|
|
1033
|
+
// sensitive unless the owner marked it below: a server that labels its
|
|
1034
|
+
// delete "read-only" would otherwise skip the question.
|
|
1035
|
+
trustAnnotations: zod_1.z.boolean().optional(),
|
|
1036
|
+
// Remote tool names the owner marked as only reading. Read-only whatever the
|
|
1037
|
+
// remote says, trusted or not. Left optional rather than defaulted, so a
|
|
1038
|
+
// save that doesn't mention it keeps the stored marks.
|
|
1039
|
+
readOnlyTools: zod_1.z.array(zod_1.z.string().min(1).max(256)).max(500).optional(),
|
|
830
1040
|
timeoutMs: zod_1.z
|
|
831
1041
|
.number()
|
|
832
1042
|
.int()
|
|
@@ -1080,6 +1290,49 @@ const ARTIFACT_CUSTOM_CODE_LIST_LOGS = zod_1.z.object({
|
|
|
1080
1290
|
userId: zod_1.z.uuid(),
|
|
1081
1291
|
organizationId: zod_1.z.uuid()
|
|
1082
1292
|
});
|
|
1293
|
+
// Tool observability on the project home: per-tool health over a window.
|
|
1294
|
+
const PROJECT_TOOL_HEALTH = zod_1.z.object({
|
|
1295
|
+
days: zod_1.z.coerce
|
|
1296
|
+
.number()
|
|
1297
|
+
.int()
|
|
1298
|
+
.refine(days => constants_1.constants.OBSERVABILITY_RANGE_DAYS.includes(days), {
|
|
1299
|
+
message: 'Range is not valid'
|
|
1300
|
+
})
|
|
1301
|
+
.default(7),
|
|
1302
|
+
projectId: zod_1.z.uuid(),
|
|
1303
|
+
userId: zod_1.z.uuid(),
|
|
1304
|
+
organizationId: zod_1.z.uuid()
|
|
1305
|
+
});
|
|
1306
|
+
// The calls behind a row of that table, newest first. Paged by the id of the
|
|
1307
|
+
// last call shown, not its time: calls written in one insert share a
|
|
1308
|
+
// timestamp, and the client only sees it to the millisecond.
|
|
1309
|
+
const PROJECT_TOOL_CALLS = zod_1.z.object({
|
|
1310
|
+
tool: zod_1.z.string().min(1).max(256).optional(),
|
|
1311
|
+
status: zod_1.z.enum(['all', 'error']).default('all'),
|
|
1312
|
+
limit: zod_1.z.coerce
|
|
1313
|
+
.number()
|
|
1314
|
+
.int()
|
|
1315
|
+
.min(1)
|
|
1316
|
+
.max(constants_1.constants.OBSERVABILITY_CALLS_MAX_LIMIT)
|
|
1317
|
+
.default(constants_1.constants.OBSERVABILITY_CALLS_DEFAULT_LIMIT),
|
|
1318
|
+
after: zod_1.z.uuid().optional(),
|
|
1319
|
+
projectId: zod_1.z.uuid(),
|
|
1320
|
+
userId: zod_1.z.uuid(),
|
|
1321
|
+
organizationId: zod_1.z.uuid()
|
|
1322
|
+
});
|
|
1323
|
+
// One recorded call, whole, and the session timeline it belongs to.
|
|
1324
|
+
const PROJECT_TOOL_CALL = zod_1.z.object({
|
|
1325
|
+
requestId: zod_1.z.uuid(),
|
|
1326
|
+
projectId: zod_1.z.uuid(),
|
|
1327
|
+
userId: zod_1.z.uuid(),
|
|
1328
|
+
organizationId: zod_1.z.uuid()
|
|
1329
|
+
});
|
|
1330
|
+
const PROJECT_MCP_SESSION = zod_1.z.object({
|
|
1331
|
+
sessionId: zod_1.z.uuid(),
|
|
1332
|
+
projectId: zod_1.z.uuid(),
|
|
1333
|
+
userId: zod_1.z.uuid(),
|
|
1334
|
+
organizationId: zod_1.z.uuid()
|
|
1335
|
+
});
|
|
1083
1336
|
// Reads the artifact's version history and which one is currently active.
|
|
1084
1337
|
const ARTIFACT_CUSTOM_CODE_LIST_VERSIONS = zod_1.z.object({
|
|
1085
1338
|
projectId: zod_1.z.uuid(),
|
|
@@ -1402,6 +1655,8 @@ exports.Schema = {
|
|
|
1402
1655
|
PROJECT_INVITATION_REMOVE,
|
|
1403
1656
|
INVITATION_RESPOND,
|
|
1404
1657
|
INVITATION_GET_BY_TOKEN,
|
|
1658
|
+
TOOL_APPROVAL_GET,
|
|
1659
|
+
TOOL_APPROVAL_DECIDE,
|
|
1405
1660
|
ORGANIZATION_MEMBER_LIST,
|
|
1406
1661
|
ORGANIZATION_MEMBER_REMOVE,
|
|
1407
1662
|
PROJECT_MEMBER_LIST,
|
|
@@ -1428,6 +1683,31 @@ exports.Schema = {
|
|
|
1428
1683
|
ARTIFACT_UPDATE_RESOURCE_VIEW,
|
|
1429
1684
|
ARTIFACT_GET_RESOURCE,
|
|
1430
1685
|
ARTIFACT_GET_RESOURCE_BY_ID,
|
|
1686
|
+
DATA_DATABASE_GET,
|
|
1687
|
+
DATA_DATABASE_CREATE,
|
|
1688
|
+
DATA_DATABASE_DELETE,
|
|
1689
|
+
DATA_COLUMN_INPUT,
|
|
1690
|
+
DATA_TABLE_INPUT,
|
|
1691
|
+
DATA_TABLE_PATCH,
|
|
1692
|
+
DATA_COLUMN_PATCH,
|
|
1693
|
+
DATA_TABLE_DROP_BODY,
|
|
1694
|
+
DATA_ROW_LIST_QUERY,
|
|
1695
|
+
DATA_ROW_GET_QUERY,
|
|
1696
|
+
DATA_ROW_CREATE_BODY,
|
|
1697
|
+
DATA_ROW_UPDATE_BODY,
|
|
1698
|
+
DATA_ROW_DELETE_BODY,
|
|
1699
|
+
DATA_DELETE_PREVIEW_BODY,
|
|
1700
|
+
DATA_WRITE_OPERATION,
|
|
1701
|
+
DATA_WRITE_BODY,
|
|
1702
|
+
DATA_ROW_HISTORY_QUERY,
|
|
1703
|
+
DATA_RESTORE_POINT_BODY,
|
|
1704
|
+
DATA_EXPORT_BODY,
|
|
1705
|
+
DATA_EXPORT_QUERY,
|
|
1706
|
+
DATA_EXPORT_FILE_QUERY,
|
|
1707
|
+
DATA_CHANGE_LIST_QUERY,
|
|
1708
|
+
DATA_TABLE_PARAMS,
|
|
1709
|
+
DATA_COLUMN_PARAMS,
|
|
1710
|
+
DATA_ROW_PARAMS,
|
|
1431
1711
|
ARTIFACT_REMOVE_RESOURCE,
|
|
1432
1712
|
ARTIFACT_UPLOAD_RESOURCE_FILE,
|
|
1433
1713
|
ARTIFACT_DOWNLOAD_RESOURCE_FILE,
|
|
@@ -1481,6 +1761,10 @@ exports.Schema = {
|
|
|
1481
1761
|
ARTIFACT_CUSTOM_CODE_ROLLBACK,
|
|
1482
1762
|
ARTIFACT_CUSTOM_CODE_LIST_LOGS,
|
|
1483
1763
|
ARTIFACT_CUSTOM_CODE_LIST_VERSIONS,
|
|
1764
|
+
PROJECT_TOOL_HEALTH,
|
|
1765
|
+
PROJECT_TOOL_CALLS,
|
|
1766
|
+
PROJECT_TOOL_CALL,
|
|
1767
|
+
PROJECT_MCP_SESSION,
|
|
1484
1768
|
CUSTOM_CODE_INVOKE_REQUEST,
|
|
1485
1769
|
CUSTOM_CODE_INVOKE_RESPONSE,
|
|
1486
1770
|
CUSTOM_CODE_BROKER_CONNECTION,
|
package/dist/ssrf.d.ts
CHANGED
package/dist/ssrf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssrf.d.ts","sourceRoot":"","sources":["../src/ssrf.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"ssrf.d.ts","sourceRoot":"","sources":["../src/ssrf.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,OAYjD,CAAC;AAeF,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,KAAG,OAiBhD,CAAC;AAIF,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,OAS1C,CAAC"}
|
package/dist/ssrf.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isBlockedHost = exports.ipv4InPrivateRange = void 0;
|
|
3
|
+
exports.isBlockedUrl = exports.isBlockedHost = exports.ipv4InPrivateRange = void 0;
|
|
4
4
|
// Literal-host SSRF screening shared by the proxied tool dispatchers
|
|
5
|
-
// (http-endpoint, mcp-proxy). The Workers runtime can't resolve DNS, so we can
|
|
5
|
+
// (http-endpoint, mcp-proxy) and the website crawler. The Workers runtime can't resolve DNS, so we can
|
|
6
6
|
// only screen literal hosts and IPs (not DNS rebinding). Private/loopback/
|
|
7
7
|
// link-local ranges are always rejected; callers may further narrow with an
|
|
8
8
|
// allowlist.
|
|
@@ -22,25 +22,61 @@ const ipv4InPrivateRange = (host) => {
|
|
|
22
22
|
return true; // private
|
|
23
23
|
if (a === 172 && b >= 16 && b <= 31)
|
|
24
24
|
return true; // private
|
|
25
|
+
if (a === 100 && b >= 64 && b <= 127)
|
|
26
|
+
return true; // carrier-grade NAT
|
|
25
27
|
return false;
|
|
26
28
|
};
|
|
27
29
|
exports.ipv4InPrivateRange = ipv4InPrivateRange;
|
|
30
|
+
// The IPv4 address an IPv4-mapped IPv6 literal reaches. URL parsing rewrites
|
|
31
|
+
// `[::ffff:127.0.0.1]` to `[::ffff:7f00:1]`, so both spellings are read.
|
|
32
|
+
const mappedIpv4 = (host) => {
|
|
33
|
+
if (!host.startsWith('::ffff:'))
|
|
34
|
+
return null;
|
|
35
|
+
const rest = host.slice('::ffff:'.length);
|
|
36
|
+
if (rest.includes('.'))
|
|
37
|
+
return rest;
|
|
38
|
+
const match = /^([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(rest);
|
|
39
|
+
if (!match)
|
|
40
|
+
return null;
|
|
41
|
+
const hi = Number.parseInt(match[1], 16);
|
|
42
|
+
const lo = Number.parseInt(match[2], 16);
|
|
43
|
+
return [hi >> 8, hi & 0xff, lo >> 8, lo & 0xff].join('.');
|
|
44
|
+
};
|
|
28
45
|
const isBlockedHost = (hostname) => {
|
|
29
|
-
const host = hostname
|
|
46
|
+
const host = hostname
|
|
47
|
+
.toLowerCase()
|
|
48
|
+
.replace(/^\[|\]$/g, '')
|
|
49
|
+
.replace(/\.$/, '');
|
|
30
50
|
if (!host)
|
|
31
51
|
return true;
|
|
32
52
|
if (host === 'localhost' || host.endsWith('.localhost'))
|
|
33
53
|
return true;
|
|
34
|
-
if (host
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
54
|
+
if (host.includes(':')) {
|
|
55
|
+
// An IPv6 literal. Its prefixes are only checked here: a domain name such
|
|
56
|
+
// as fdic.gov or fcbarcelona.com starts with the same letters.
|
|
57
|
+
if (host === '::1' || host === '::')
|
|
58
|
+
return true;
|
|
59
|
+
// Link-local (fe80::/10) and unique-local (fc00::/7).
|
|
60
|
+
if (/^fe[89ab]/.test(host) || /^f[cd]/.test(host))
|
|
61
|
+
return true;
|
|
62
|
+
const mapped = mappedIpv4(host);
|
|
63
|
+
return mapped !== null && (0, exports.ipv4InPrivateRange)(mapped);
|
|
64
|
+
}
|
|
65
|
+
return (0, exports.ipv4InPrivateRange)(host);
|
|
66
|
+
};
|
|
67
|
+
exports.isBlockedHost = isBlockedHost;
|
|
68
|
+
// Whether a URL may not be fetched on a user's behalf: not http(s), not a URL
|
|
69
|
+
// at all, or pointing at a private, loopback or link-local host.
|
|
70
|
+
const isBlockedUrl = (url) => {
|
|
71
|
+
let parsed;
|
|
72
|
+
try {
|
|
73
|
+
parsed = new URL(url);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
40
76
|
return true;
|
|
41
77
|
}
|
|
42
|
-
if (
|
|
78
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
|
|
43
79
|
return true;
|
|
44
|
-
return
|
|
80
|
+
return (0, exports.isBlockedHost)(parsed.hostname);
|
|
45
81
|
};
|
|
46
|
-
exports.
|
|
82
|
+
exports.isBlockedUrl = isBlockedUrl;
|
|
@@ -54,5 +54,53 @@ export declare const isSensitiveTool: (annotations: {
|
|
|
54
54
|
readOnlyHint?: boolean;
|
|
55
55
|
destructiveHint?: boolean;
|
|
56
56
|
} | null | undefined) => boolean;
|
|
57
|
+
export interface ProxiedToolTrust {
|
|
58
|
+
trustHints: boolean;
|
|
59
|
+
readOnly: boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare const proxiedToolTrust: (config: {
|
|
62
|
+
trustAnnotations?: unknown;
|
|
63
|
+
readOnlyTools?: unknown;
|
|
64
|
+
} | null | undefined, remoteToolName: string) => ProxiedToolTrust;
|
|
65
|
+
/**
|
|
66
|
+
* The annotations a proxied tool is registered with. A remote server's hints
|
|
67
|
+
* are its own claim about itself, and one that marks a delete read-only would
|
|
68
|
+
* skip every confirmation — so unless the organization chose to trust that
|
|
69
|
+
* server, the read-only and destructive hints are dropped and the tool reads
|
|
70
|
+
* as sensitive by the defaults above. A tool the owner marked as only reading
|
|
71
|
+
* is read-only whatever the remote says, trusted or not. Clients see the
|
|
72
|
+
* same, so they ask about the same tools. The harmless parts (title,
|
|
73
|
+
* openWorldHint, idempotentHint) pass through.
|
|
74
|
+
*/
|
|
75
|
+
export declare const proxiedToolAnnotations: <T extends {
|
|
76
|
+
readOnlyHint?: boolean;
|
|
77
|
+
destructiveHint?: boolean;
|
|
78
|
+
}>(annotations: T | null | undefined, trust: ProxiedToolTrust) => Partial<T> | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* An install's new config with the owner's trust marks carried over from the
|
|
81
|
+
* stored one wherever the new one doesn't say. A save that only knew about
|
|
82
|
+
* the allow-lists (an older dashboard, a script) must not quietly turn the
|
|
83
|
+
* marks off; one that sends them, even as false or empty, decides.
|
|
84
|
+
*/
|
|
85
|
+
export declare const keepProxiedToolMarks: (stored: unknown, incoming: unknown) => unknown;
|
|
86
|
+
/** Whether a proxied tool is confirmed, decided as its registration is. */
|
|
87
|
+
export declare const isSensitiveProxiedTool: (annotations: {
|
|
88
|
+
readOnlyHint?: boolean;
|
|
89
|
+
destructiveHint?: boolean;
|
|
90
|
+
} | null | undefined, trust: ProxiedToolTrust) => boolean;
|
|
57
91
|
export declare const stableJson: (value: unknown) => string;
|
|
92
|
+
export type ToolApprovalStatus = 'pending' | 'approved' | 'denied' | 'used' | 'expired';
|
|
93
|
+
/**
|
|
94
|
+
* Where an approval stands. Spent and refused come first, since an answer
|
|
95
|
+
* stays the answer after the window closes; past its time, one never answered
|
|
96
|
+
* or never used can no longer be.
|
|
97
|
+
*/
|
|
98
|
+
export declare const toolApprovalStatus: (approval: {
|
|
99
|
+
expiresAt: Date;
|
|
100
|
+
approvedAt: Date | null;
|
|
101
|
+
deniedAt: Date | null;
|
|
102
|
+
usedAt: Date | null;
|
|
103
|
+
}, now?: number) => ToolApprovalStatus;
|
|
104
|
+
/** The dashboard page where the user answers one approval. */
|
|
105
|
+
export declare const toolApprovalUrl: (webUrl: string, path: string, approvalId: string) => string;
|
|
58
106
|
//# sourceMappingURL=toolConfirmation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolConfirmation.d.ts","sourceRoot":"","sources":["../src/toolConfirmation.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,uBAAuB;IAEtC,EAAE,EAAE,MAAM,CAAC;IAGX,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,CAAC,CAAC;CACJ;AAKD,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;AAO/E,eAAO,MAAM,YAAY,yCAA0C,CAAC;AAEpE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,UAAU,KACjB;IAAE,YAAY,EAAE,OAAO,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAKE,CAAC;AAmHvD,eAAO,MAAM,uBAAuB,GAAI,OAAO,MAAM,KAAG,MAAM,GAAG,IAOhE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,SAAS,MAAM,GAAG,IAAI,KACrB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAG3B,CAAC;AAQF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,KAAK,GAAG,IAAI,EACpB,uBAAuB,MAAM,KAC5B,MAA4E,CAAC;AAEhF,eAAO,MAAM,uBAAuB,GAClC,IAAI,MAAM,KACT;IAAE,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IAAC,qBAAqB,EAAE,MAAM,CAAA;CAAE,GAAG,IAQ1D,CAAC;AAWF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,OAIlD,CAAC;AAmBF;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GACpC,OAAO,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,EAClE,SAAS,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,KAChC,MAcc,CAAC;AAElB;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,aACI;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GACrD,IAAI,GACJ,SAAS,KACZ,OAC2E,CAAC;
|
|
1
|
+
{"version":3,"file":"toolConfirmation.d.ts","sourceRoot":"","sources":["../src/toolConfirmation.ts"],"names":[],"mappings":"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"}
|
package/dist/toolConfirmation.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// participant's next message is a plain yes. These are the pieces of that rule
|
|
5
5
|
// that aren't the runner's own bookkeeping.
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.stableJson = exports.isSensitiveTool = exports.formatConfirmationSummary = exports.isConfirmationReply = exports.parseConfirmationButton = exports.confirmationButtonId = exports.confirmationButtonLabels = exports.languageFromPhoneNumber = exports.annotationsForEffect = exports.TOOL_EFFECTS = void 0;
|
|
7
|
+
exports.toolApprovalUrl = exports.toolApprovalStatus = exports.stableJson = exports.isSensitiveProxiedTool = exports.keepProxiedToolMarks = exports.proxiedToolAnnotations = exports.proxiedToolTrust = exports.isSensitiveTool = exports.formatConfirmationSummary = exports.isConfirmationReply = exports.parseConfirmationButton = exports.confirmationButtonId = exports.confirmationButtonLabels = exports.languageFromPhoneNumber = exports.annotationsForEffect = exports.TOOL_EFFECTS = void 0;
|
|
8
8
|
// What an owner says a tool they wrote does, in the words the dashboard asks
|
|
9
9
|
// it in, and the MCP annotations each answer stands for: `read` only looks
|
|
10
10
|
// things up, `write` changes things that can be undone, `sensitive` sends,
|
|
@@ -223,6 +223,62 @@ exports.formatConfirmationSummary = formatConfirmationSummary;
|
|
|
223
223
|
*/
|
|
224
224
|
const isSensitiveTool = (annotations) => annotations?.readOnlyHint !== true && annotations?.destructiveHint !== false;
|
|
225
225
|
exports.isSensitiveTool = isSensitiveTool;
|
|
226
|
+
const proxiedToolTrust = (config, remoteToolName) => ({
|
|
227
|
+
trustHints: config?.trustAnnotations === true,
|
|
228
|
+
readOnly: Array.isArray(config?.readOnlyTools) &&
|
|
229
|
+
config.readOnlyTools.includes(remoteToolName)
|
|
230
|
+
});
|
|
231
|
+
exports.proxiedToolTrust = proxiedToolTrust;
|
|
232
|
+
/**
|
|
233
|
+
* The annotations a proxied tool is registered with. A remote server's hints
|
|
234
|
+
* are its own claim about itself, and one that marks a delete read-only would
|
|
235
|
+
* skip every confirmation — so unless the organization chose to trust that
|
|
236
|
+
* server, the read-only and destructive hints are dropped and the tool reads
|
|
237
|
+
* as sensitive by the defaults above. A tool the owner marked as only reading
|
|
238
|
+
* is read-only whatever the remote says, trusted or not. Clients see the
|
|
239
|
+
* same, so they ask about the same tools. The harmless parts (title,
|
|
240
|
+
* openWorldHint, idempotentHint) pass through.
|
|
241
|
+
*/
|
|
242
|
+
const proxiedToolAnnotations = (annotations, trust) => {
|
|
243
|
+
const result = { ...annotations };
|
|
244
|
+
if (trust.readOnly) {
|
|
245
|
+
delete result.destructiveHint;
|
|
246
|
+
return { ...result, readOnlyHint: true };
|
|
247
|
+
}
|
|
248
|
+
if (!trust.trustHints) {
|
|
249
|
+
delete result.readOnlyHint;
|
|
250
|
+
delete result.destructiveHint;
|
|
251
|
+
}
|
|
252
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
253
|
+
};
|
|
254
|
+
exports.proxiedToolAnnotations = proxiedToolAnnotations;
|
|
255
|
+
// The install-config keys that hold the owner's trust marks above.
|
|
256
|
+
const PROXIED_TOOL_MARK_KEYS = ['trustAnnotations', 'readOnlyTools'];
|
|
257
|
+
/**
|
|
258
|
+
* An install's new config with the owner's trust marks carried over from the
|
|
259
|
+
* stored one wherever the new one doesn't say. A save that only knew about
|
|
260
|
+
* the allow-lists (an older dashboard, a script) must not quietly turn the
|
|
261
|
+
* marks off; one that sends them, even as false or empty, decides.
|
|
262
|
+
*/
|
|
263
|
+
const keepProxiedToolMarks = (stored, incoming) => {
|
|
264
|
+
if (!stored ||
|
|
265
|
+
typeof stored !== 'object' ||
|
|
266
|
+
!incoming ||
|
|
267
|
+
typeof incoming !== 'object') {
|
|
268
|
+
return incoming;
|
|
269
|
+
}
|
|
270
|
+
const merged = { ...incoming };
|
|
271
|
+
for (const key of PROXIED_TOOL_MARK_KEYS) {
|
|
272
|
+
if (merged[key] === undefined && key in stored) {
|
|
273
|
+
merged[key] = stored[key];
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return merged;
|
|
277
|
+
};
|
|
278
|
+
exports.keepProxiedToolMarks = keepProxiedToolMarks;
|
|
279
|
+
/** Whether a proxied tool is confirmed, decided as its registration is. */
|
|
280
|
+
const isSensitiveProxiedTool = (annotations, trust) => (0, exports.isSensitiveTool)((0, exports.proxiedToolAnnotations)(annotations, trust));
|
|
281
|
+
exports.isSensitiveProxiedTool = isSensitiveProxiedTool;
|
|
226
282
|
// JSON with keys sorted at every depth, so two argument objects that say the
|
|
227
283
|
// same thing serialize the same whatever order the model emitted them in.
|
|
228
284
|
const stableJson = (value) => {
|
|
@@ -237,3 +293,21 @@ const stableJson = (value) => {
|
|
|
237
293
|
return JSON.stringify(value) ?? 'null';
|
|
238
294
|
};
|
|
239
295
|
exports.stableJson = stableJson;
|
|
296
|
+
/**
|
|
297
|
+
* Where an approval stands. Spent and refused come first, since an answer
|
|
298
|
+
* stays the answer after the window closes; past its time, one never answered
|
|
299
|
+
* or never used can no longer be.
|
|
300
|
+
*/
|
|
301
|
+
const toolApprovalStatus = (approval, now = Date.now()) => {
|
|
302
|
+
if (approval.usedAt)
|
|
303
|
+
return 'used';
|
|
304
|
+
if (approval.deniedAt)
|
|
305
|
+
return 'denied';
|
|
306
|
+
if (approval.expiresAt.getTime() <= now)
|
|
307
|
+
return 'expired';
|
|
308
|
+
return approval.approvedAt ? 'approved' : 'pending';
|
|
309
|
+
};
|
|
310
|
+
exports.toolApprovalStatus = toolApprovalStatus;
|
|
311
|
+
/** The dashboard page where the user answers one approval. */
|
|
312
|
+
const toolApprovalUrl = (webUrl, path, approvalId) => `${webUrl.replace(/\/+$/, '')}${path}/${encodeURIComponent(approvalId)}`;
|
|
313
|
+
exports.toolApprovalUrl = toolApprovalUrl;
|