@slates/provider 1.0.0-rc.26 → 1.0.0-rc.28
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/index.cjs +35 -9
- package/dist/index.d.cts +51 -5
- package/dist/index.d.ts +51 -5
- package/dist/index.module.js +34 -9
- package/package.json +1 -1
- package/src/action/getFileUrlTool.ts +2 -1
- package/src/action/triggerGroup.ts +65 -3
- package/src/auth/redact.test.ts +31 -2
- package/src/auth/redact.ts +24 -11
- package/src/auth/types.ts +4 -0
- package/src/axios/trace.test.ts +21 -0
- package/src/axios/trace.ts +7 -1
- package/src/error/base.ts +1 -1
- package/src/error/declaration.ts +1 -1
- package/src/error/utils.ts +6 -2
package/dist/index.cjs
CHANGED
|
@@ -86,6 +86,7 @@ __export(index_exports, {
|
|
|
86
86
|
isApiErrorRecord: () => isApiErrorRecord,
|
|
87
87
|
isAxiosErrorLike: () => isAxiosErrorLike,
|
|
88
88
|
isServiceErrorData: () => isServiceErrorData,
|
|
89
|
+
isUrlEmbeddedCredential: () => isUrlEmbeddedCredential,
|
|
89
90
|
mapServiceErrorCode: () => mapServiceErrorCode,
|
|
90
91
|
mapServiceErrorToSlateErrorInput: () => mapServiceErrorToSlateErrorInput,
|
|
91
92
|
mergeScopes: () => mergeScopes,
|
|
@@ -406,7 +407,7 @@ var normalizeRetryable = (code, retryable) => {
|
|
|
406
407
|
};
|
|
407
408
|
var getDefaultMessage = (code, message) => {
|
|
408
409
|
if (message?.trim()) return message;
|
|
409
|
-
return DEFAULT_MESSAGES[code] ?? DEFAULT_MESSAGES[DEFAULT_CODE];
|
|
410
|
+
return DEFAULT_MESSAGES[code] ?? DEFAULT_MESSAGES[DEFAULT_CODE] ?? "An unexpected internal error occurred.";
|
|
410
411
|
};
|
|
411
412
|
var cleanRecord = (value) => {
|
|
412
413
|
if (!value) return void 0;
|
|
@@ -1074,10 +1075,14 @@ var AuthConfigSecretRedactor = class {
|
|
|
1074
1075
|
return this.secretToPlaceholder.get(stringValue) ?? stringValue;
|
|
1075
1076
|
});
|
|
1076
1077
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1078
|
+
/** `embeddable` limits which secrets are also replaced inside longer strings. */
|
|
1079
|
+
redactEmbedded(value, embeddable = () => true) {
|
|
1080
|
+
let secrets = [...this.secretToPlaceholder.entries()].filter(
|
|
1081
|
+
([secret, placeholder]) => embeddable(secret, placeholder.slice(AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX.length))
|
|
1082
|
+
).map(([secret]) => secret);
|
|
1083
|
+
if (secrets.length === 0) return this.redact(value);
|
|
1079
1084
|
let pattern = new RegExp(
|
|
1080
|
-
|
|
1085
|
+
secrets.sort((a, b) => b.length - a.length).map((secret) => secret.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"),
|
|
1081
1086
|
"g"
|
|
1082
1087
|
);
|
|
1083
1088
|
return this.transform(value, (stringValue) => {
|
|
@@ -1130,18 +1135,21 @@ var AuthConfigSecretRedactor = class {
|
|
|
1130
1135
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1131
1136
|
}
|
|
1132
1137
|
};
|
|
1138
|
+
var URL_CREDENTIAL_KEY = /^(?:.*[-_])?(?:token|secret|password|api[-_]?key)$/i;
|
|
1139
|
+
var isUrlEmbeddedCredential = (secret, path) => secret.length >= 8 && URL_CREDENTIAL_KEY.test(path.split(".").pop() ?? "");
|
|
1133
1140
|
var redactUrlAttachmentSecrets = (attachments, authConfig) => {
|
|
1134
1141
|
if (!authConfig || !attachments) return attachments;
|
|
1135
1142
|
let redactor = new AuthConfigSecretRedactor(authConfig);
|
|
1136
1143
|
return attachments.map((attachment) => {
|
|
1137
1144
|
if (attachment.content.type !== "url") return attachment;
|
|
1138
|
-
|
|
1145
|
+
let { url, headers, query } = attachment.content;
|
|
1139
1146
|
return {
|
|
1140
1147
|
...attachment,
|
|
1141
1148
|
content: {
|
|
1142
1149
|
...attachment.content,
|
|
1143
|
-
|
|
1144
|
-
|
|
1150
|
+
url: redactor.redactEmbedded(url, isUrlEmbeddedCredential),
|
|
1151
|
+
...headers ? { headers: redactor.redactEmbedded(headers) } : {},
|
|
1152
|
+
...query ? { query: redactor.redactEmbedded(query) } : {}
|
|
1145
1153
|
}
|
|
1146
1154
|
};
|
|
1147
1155
|
});
|
|
@@ -1191,6 +1199,7 @@ var getFileUrlTool = (spec2, handleGetFileUrl) => tool(spec2, {
|
|
|
1191
1199
|
return {
|
|
1192
1200
|
output: {
|
|
1193
1201
|
...output,
|
|
1202
|
+
url: redactor.redactEmbedded(output.url, isUrlEmbeddedCredential),
|
|
1194
1203
|
...output.headers ? { headers: redactor.redactEmbedded(output.headers) } : {},
|
|
1195
1204
|
...output.query ? { query: redactor.redactEmbedded(output.query) } : {}
|
|
1196
1205
|
},
|
|
@@ -1288,6 +1297,9 @@ var SlateTriggerGroup = class _SlateTriggerGroup {
|
|
|
1288
1297
|
get webhook() {
|
|
1289
1298
|
return this._params.webhook;
|
|
1290
1299
|
}
|
|
1300
|
+
get gateway() {
|
|
1301
|
+
return this._params.gateway;
|
|
1302
|
+
}
|
|
1291
1303
|
get routingMatchers() {
|
|
1292
1304
|
return this._params.routingMatchers;
|
|
1293
1305
|
}
|
|
@@ -1304,6 +1316,7 @@ var SlateTriggerGroupBuilder = class {
|
|
|
1304
1316
|
#source = null;
|
|
1305
1317
|
#polling = null;
|
|
1306
1318
|
#webhook = null;
|
|
1319
|
+
#gateway = null;
|
|
1307
1320
|
#routingMatchers = null;
|
|
1308
1321
|
polling(props) {
|
|
1309
1322
|
if (this.#source) {
|
|
@@ -1333,6 +1346,15 @@ var SlateTriggerGroupBuilder = class {
|
|
|
1333
1346
|
};
|
|
1334
1347
|
return this;
|
|
1335
1348
|
}
|
|
1349
|
+
/** Receive events over a platform-managed persistent connection (e.g. a WebSocket gateway). */
|
|
1350
|
+
gateway(props) {
|
|
1351
|
+
if (this.#source) {
|
|
1352
|
+
throw new SlateDeclarationError("Trigger group invocation is already defined");
|
|
1353
|
+
}
|
|
1354
|
+
this.#source = "gateway";
|
|
1355
|
+
this.#gateway = { connect: props.connect, receive: props.receive };
|
|
1356
|
+
return this;
|
|
1357
|
+
}
|
|
1336
1358
|
routingMatchers(handler) {
|
|
1337
1359
|
this.#routingMatchers = handler;
|
|
1338
1360
|
return this;
|
|
@@ -1340,7 +1362,7 @@ var SlateTriggerGroupBuilder = class {
|
|
|
1340
1362
|
build() {
|
|
1341
1363
|
if (!this.#source) {
|
|
1342
1364
|
throw new SlateDeclarationError(
|
|
1343
|
-
"Trigger group invocation (polling or
|
|
1365
|
+
"Trigger group invocation (polling, webhook, or gateway) is not defined"
|
|
1344
1366
|
);
|
|
1345
1367
|
}
|
|
1346
1368
|
if (!this.#routingMatchers) {
|
|
@@ -1351,6 +1373,7 @@ var SlateTriggerGroupBuilder = class {
|
|
|
1351
1373
|
source: this.#source,
|
|
1352
1374
|
polling: this.#polling ?? void 0,
|
|
1353
1375
|
webhook: this.#webhook ?? void 0,
|
|
1376
|
+
gateway: this.#gateway ?? void 0,
|
|
1354
1377
|
routingMatchers: this.#routingMatchers
|
|
1355
1378
|
});
|
|
1356
1379
|
}
|
|
@@ -2140,6 +2163,7 @@ var redactHashFragment = (hash, redactor) => {
|
|
|
2140
2163
|
);
|
|
2141
2164
|
return redacted ? `#${redacted}` : "";
|
|
2142
2165
|
};
|
|
2166
|
+
var isEmbeddedPathSecret = (secret, path) => secret.length >= 8 && isSecretKeyName(path.split(".").pop() ?? "");
|
|
2143
2167
|
var sanitizeUrl = (value, redactor) => {
|
|
2144
2168
|
if (!value) return value;
|
|
2145
2169
|
try {
|
|
@@ -2148,6 +2172,7 @@ var sanitizeUrl = (value, redactor) => {
|
|
|
2148
2172
|
url.username = "";
|
|
2149
2173
|
url.password = "";
|
|
2150
2174
|
}
|
|
2175
|
+
if (redactor) url.pathname = redactor.redactEmbedded(url.pathname, isEmbeddedPathSecret);
|
|
2151
2176
|
for (let key of Array.from(url.searchParams.keys())) {
|
|
2152
2177
|
if (isUrlFormSecretKeyName(key)) {
|
|
2153
2178
|
url.searchParams.set(key, REDACTED_VALUE);
|
|
@@ -2160,7 +2185,7 @@ var sanitizeUrl = (value, redactor) => {
|
|
|
2160
2185
|
url.hash = redactHashFragment(url.hash, redactor);
|
|
2161
2186
|
return decodeRedactedMarker(url.toString());
|
|
2162
2187
|
} catch {
|
|
2163
|
-
let text = redactor ? redactor.
|
|
2188
|
+
let text = redactor ? redactor.redactEmbedded(value, isEmbeddedPathSecret) : value;
|
|
2164
2189
|
return text.replace(
|
|
2165
2190
|
/([?&]([^=&#]+)=)([^&#]+)/g,
|
|
2166
2191
|
(_match, prefix, key, rawValue) => isUrlFormSecretKeyName(key) ? `${prefix}${REDACTED_VALUE}` : `${prefix}${rawValue}`
|
|
@@ -3012,6 +3037,7 @@ var skipWebhook = (reason, response) => ({
|
|
|
3012
3037
|
isApiErrorRecord,
|
|
3013
3038
|
isAxiosErrorLike,
|
|
3014
3039
|
isServiceErrorData,
|
|
3040
|
+
isUrlEmbeddedCredential,
|
|
3015
3041
|
mapServiceErrorCode,
|
|
3016
3042
|
mapServiceErrorToSlateErrorInput,
|
|
3017
3043
|
mergeScopes,
|
package/dist/index.d.cts
CHANGED
|
@@ -50,15 +50,17 @@ declare class AuthConfigSecretRedactor {
|
|
|
50
50
|
private readonly secretToPlaceholder;
|
|
51
51
|
constructor(authConfig: Record<string, unknown> | undefined);
|
|
52
52
|
redact<T>(value: T): T;
|
|
53
|
-
|
|
53
|
+
/** `embeddable` limits which secrets are also replaced inside longer strings. */
|
|
54
|
+
redactEmbedded<T>(value: T, embeddable?: (secret: string, path: string) => boolean): T;
|
|
54
55
|
private buildSecretMap;
|
|
55
56
|
private transform;
|
|
56
57
|
private isPlainObject;
|
|
57
58
|
}
|
|
59
|
+
declare let isUrlEmbeddedCredential: (secret: string, path: string) => boolean;
|
|
58
60
|
/**
|
|
59
61
|
* Applied to every finalized attachment list right before it's sent over
|
|
60
62
|
* `slates/action.tool.invoke` (see @slates/provider-handler). Only `type: 'url'` attachments
|
|
61
|
-
* carry
|
|
63
|
+
* carry credentials -- content/upload_reference attachments pass through untouched.
|
|
62
64
|
*/
|
|
63
65
|
declare let redactUrlAttachmentSecrets: (attachments: SlateAttachment[] | undefined, authConfig: Record<string, unknown> | undefined) => SlateAttachment[] | undefined;
|
|
64
66
|
|
|
@@ -150,6 +152,7 @@ type SlateAuthWithOauth<InputType extends {}, OutputType extends {
|
|
|
150
152
|
scope: string;
|
|
151
153
|
}[];
|
|
152
154
|
adapters?: string[];
|
|
155
|
+
syncTokensAcrossConnections?: boolean;
|
|
153
156
|
docs?: SlateAuthDocsReference[];
|
|
154
157
|
inputSchema?: z.ZodType<InputType>;
|
|
155
158
|
onInputChanged?: (params: {
|
|
@@ -522,6 +525,41 @@ type SlateTriggerGroupPollHandler<ConfigType extends {}, AuthType extends {}> =
|
|
|
522
525
|
}[];
|
|
523
526
|
updatedState?: any;
|
|
524
527
|
}>;
|
|
528
|
+
interface SlateGatewayEvent {
|
|
529
|
+
payload: any;
|
|
530
|
+
idempotencyKey?: string;
|
|
531
|
+
}
|
|
532
|
+
type SlateTriggerGroupGatewayConnectHandler<ConfigType extends {}, AuthType extends {}> = (context: SlateContext<ConfigType, AuthType, {
|
|
533
|
+
state: any | null;
|
|
534
|
+
}>) => Promise<{
|
|
535
|
+
url: string;
|
|
536
|
+
state?: any;
|
|
537
|
+
}>;
|
|
538
|
+
/** `closed` is set, with no frames, when the socket closed unexpectedly. */
|
|
539
|
+
type SlateTriggerGroupGatewayReceiveHandler<ConfigType extends {}, AuthType extends {}> = (context: SlateContext<ConfigType, AuthType, {
|
|
540
|
+
state: any | null;
|
|
541
|
+
frames: string[];
|
|
542
|
+
closed?: {
|
|
543
|
+
code: number;
|
|
544
|
+
reason: string;
|
|
545
|
+
} | null;
|
|
546
|
+
}>) => Promise<{
|
|
547
|
+
state?: any;
|
|
548
|
+
send?: string[];
|
|
549
|
+
events?: SlateGatewayEvent[];
|
|
550
|
+
/** With `expectsAck`, the hub reconnects when no `heartbeatAcked` arrives before the next beat. */
|
|
551
|
+
heartbeat?: {
|
|
552
|
+
intervalMs: number;
|
|
553
|
+
frame: string;
|
|
554
|
+
expectsAck?: boolean;
|
|
555
|
+
} | null;
|
|
556
|
+
/** Set when `frames` included the provider's heartbeat acknowledgement. */
|
|
557
|
+
heartbeatAcked?: boolean;
|
|
558
|
+
close?: {
|
|
559
|
+
reconnect: boolean;
|
|
560
|
+
reason?: string;
|
|
561
|
+
} | null;
|
|
562
|
+
}>;
|
|
525
563
|
type SlateWebhookTargetListHandler<ConfigType extends {}, AuthType extends {}> = (context: SlateContext<ConfigType, AuthType, {
|
|
526
564
|
pageToken: any | null;
|
|
527
565
|
}>) => Promise<{
|
|
@@ -573,6 +611,10 @@ interface SlateTriggerGroupPollingParameters<ConfigType extends {}, AuthType ext
|
|
|
573
611
|
intervalSeconds: number;
|
|
574
612
|
pollEvents: SlateTriggerGroupPollHandler<ConfigType, AuthType>;
|
|
575
613
|
}
|
|
614
|
+
interface SlateTriggerGroupGatewayParameters<ConfigType extends {}, AuthType extends {}> {
|
|
615
|
+
connect: SlateTriggerGroupGatewayConnectHandler<ConfigType, AuthType>;
|
|
616
|
+
receive: SlateTriggerGroupGatewayReceiveHandler<ConfigType, AuthType>;
|
|
617
|
+
}
|
|
576
618
|
interface SlateTriggerGroupWebhookAutoRegistrationParameters<ConfigType extends {}, AuthType extends {}> {
|
|
577
619
|
webhookTargetList: SlateWebhookTargetListHandler<ConfigType, AuthType>;
|
|
578
620
|
webhookRegister: SlateWebhookRegisterHandler<ConfigType, AuthType>;
|
|
@@ -597,9 +639,10 @@ interface SlateTriggerGroupCreateParameters<InputType extends {} = Record<string
|
|
|
597
639
|
eventSchema?: z$1.ZodType<InputType>;
|
|
598
640
|
}
|
|
599
641
|
interface SlateTriggerGroupParameters<ConfigType extends {}, AuthType extends {}, InputType extends {} = Record<string, unknown>> extends SlateTriggerGroupCreateParameters<InputType> {
|
|
600
|
-
source: 'polling' | 'webhook';
|
|
642
|
+
source: 'polling' | 'webhook' | 'gateway';
|
|
601
643
|
polling?: SlateTriggerGroupPollingParameters<ConfigType, AuthType>;
|
|
602
644
|
webhook?: SlateTriggerGroupWebhookParameters<ConfigType, AuthType>;
|
|
645
|
+
gateway?: SlateTriggerGroupGatewayParameters<ConfigType, AuthType>;
|
|
603
646
|
routingMatchers: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>;
|
|
604
647
|
}
|
|
605
648
|
declare class SlateTriggerGroup<ConfigType extends {}, AuthType extends {}, InputType extends {} = Record<string, unknown>> {
|
|
@@ -613,9 +656,10 @@ declare class SlateTriggerGroup<ConfigType extends {}, AuthType extends {}, Inpu
|
|
|
613
656
|
get description(): string | undefined;
|
|
614
657
|
get metadata(): Record<string, any> | undefined;
|
|
615
658
|
get eventSchema(): z$1.ZodType<InputType, unknown, z$1.core.$ZodTypeInternals<InputType, unknown>>;
|
|
616
|
-
get source(): "polling" | "webhook";
|
|
659
|
+
get source(): "polling" | "webhook" | "gateway";
|
|
617
660
|
get polling(): SlateTriggerGroupPollingParameters<ConfigType, AuthType> | undefined;
|
|
618
661
|
get webhook(): SlateTriggerGroupWebhookParameters<ConfigType, AuthType> | undefined;
|
|
662
|
+
get gateway(): SlateTriggerGroupGatewayParameters<ConfigType, AuthType> | undefined;
|
|
619
663
|
get routingMatchers(): SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>;
|
|
620
664
|
}
|
|
621
665
|
declare class SlateTriggerGroupBuilder<ConfigType extends {}, AuthType extends {}, InputType extends {} = Record<string, unknown>> {
|
|
@@ -633,6 +677,8 @@ declare class SlateTriggerGroupBuilder<ConfigType extends {}, AuthType extends {
|
|
|
633
677
|
manualRegistration?: SlateTriggerGroupWebhookManualRegistrationParameters<UserConfigSchema, FullConfigSchema>;
|
|
634
678
|
process: SlateWebhookProcessHandler;
|
|
635
679
|
}): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType>;
|
|
680
|
+
/** Receive events over a platform-managed persistent connection (e.g. a WebSocket gateway). */
|
|
681
|
+
gateway(props: SlateTriggerGroupGatewayParameters<ConfigType, AuthType>): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType>;
|
|
636
682
|
routingMatchers(handler: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType>;
|
|
637
683
|
build(): SlateTriggerGroup<ConfigType, AuthType, InputType>;
|
|
638
684
|
}
|
|
@@ -1093,4 +1139,4 @@ declare let skipWebhook: (reason: string, response?: Response | SlateWebhookHttp
|
|
|
1093
1139
|
response: Response | SlateWebhookHttpResponseInit;
|
|
1094
1140
|
};
|
|
1095
1141
|
|
|
1096
|
-
export { AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX, type ApiErrorBuildHelpers, type ApiErrorDetailOptions, type ApiErrorResponse, type ApiErrorStatus, type ApiServiceError, AuthConfigSecretRedactor, type BuildApiServiceErrorOptions, type CreateHmacSignatureOptions, GET_FILE_URL_TOOL_ID, type GetFileUrlHandler, type GetFileUrlToolInput, type GetFileUrlToolOutput, type NormalizeOAuthTokenResponseOptions, type OAuthExpiresAtOptions, type OAuthRefreshTokenFallbackMode, type OAuthTokenResponse, Slate, SlateAction, SlateActionBuilder, type SlateActionCreateParameters, type SlateActionDocsReference, type SlateActionParameters, type SlateActionParametersAny, type SlateActionParametersTool, type SlateActionParametersTrigger, type SlateActionScopeClause, type SlateActionScopeClauseInput, type SlateActionScopeValue, type SlateActionScopes, type SlateActionScopesInput, type SlateActionType, SlateAdapter, type SlateAdapterCapability, SlateAdapterSpec, type SlateAdapterSpecParameters, type SlateAddAttachmentContent, type SlateAddAttachmentInput, type SlateAttachment, type SlateAttachmentInlineContent, type SlateAttachmentUploadReferenceContent, type SlateAttachmentUrlContent, SlateAuth, type SlateAuthDocsReference, type SlateAuthType, type SlateAuthWithCustomData, type SlateAuthWithNone, type SlateAuthWithOauth, type SlateAuthWithServiceAccount, type SlateAuthWithToken, type SlateAuthenticatedAxiosDefaults, type SlateAxiosDefaults, type SlateAxiosErrorAdapter, type SlateAxiosErrorOptions, SlateConfig, type SlateConfigDocsReference, SlateContext, SlateDeclarationError, SlateDefaultPollingIntervalSeconds, type SlateDirectUploadInput, type SlateDocsReference, SlateError, type SlateErrorInput, type SlateErrorIssue, type SlateErrorKind, type SlateErrorProviderInfo, type SlateErrorResponse, type SlateErrorUpstreamInfo, type SlateLiveInvocationInfo, type SlateLogEntry, type SlateLogFields, type SlateLogListener, type SlateLogMessageInput, type SlateLogType, SlateLogger, type SlateProviderDocsReference, SlatePublicContext, SlatePublicTool, type SlatePublicToolInvocationHandler, type SlatePublicToolParameters, type SlateServiceErrorData, SlateSpecification, type SlateSpecificationCreateParameters, type SlateSpecificationParameters, SlateTool, type SlateToolInvocationHandler, type SlateToolParameters, SlateTrigger, SlateTriggerGroup, SlateTriggerGroupBuilder, type SlateTriggerGroupCreateParameters, type SlateTriggerGroupParameters, type SlateTriggerGroupPollHandler, type SlateTriggerGroupPollingParameters, type SlateTriggerGroupRoutingMatchersHandler, type SlateTriggerGroupWebhookAutoRegistrationParameters, type SlateTriggerGroupWebhookManualRegistrationParameters, type SlateTriggerGroupWebhookParameters, type SlateTriggerMappingHandler, type SlateTriggerMatchesHandler, type SlateTriggerParameters, type SlateTriggerRoutingMatcher, type SlateTypedDocsReference, type SlateWebhookHttpResponseInit, type SlateWebhookManualFinishHandler, type SlateWebhookManualSetupHandler, type SlateWebhookProcessHandler, type SlateWebhookRegisterHandler, type SlateWebhookSkipped, type SlateWebhookTarget, type SlateWebhookTargetListHandler, type SlateWebhookTargetOwnership, type SlateWebhookUnregisterHandler, type VerifyHmacSignatureOptions, adapterSpec, allOf, anyOf, auth, axios, buildApiServiceError, collectApiErrorDetails, config, createApiServiceError, createAuthenticatedAxios, createAxios, createBase64Attachment, createHmacSignature, createSlateError, createTextAttachment, createUrlAttachment, extractApiErrorMessage, getApiErrorResponse, getApiErrorStatus, getBase64ByteLength, getCurrentContext, getFileUrlTool, getFileUrlToolInputSchema, getFileUrlToolOutputSchema, getGraphWebhookValidationResponse, getMetaWebhookVerificationResponse, getOAuthExpiresAtFromExpiresIn, getResponseHeaderValue, getServiceErrorData, graphWebhookHttp, inferSlateErrorFromAxios, isApiErrorRecord, isAxiosErrorLike, isServiceErrorData, mapServiceErrorCode, mapServiceErrorToSlateErrorInput, mergeScopes, metaWebhookHttp, normalizeOAuthTokenResponse, pickDefined, publicTool, redactUrlAttachmentSecrets, requestAxios, requestAxiosData, runWithContext, scopeClause, setIfDefined, skipWebhook, spec, statusLabelForApiError, tool, trigger, triggerGroup, uploadAttachmentDirect, validateScopes, verifyHmacSignature };
|
|
1142
|
+
export { AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX, type ApiErrorBuildHelpers, type ApiErrorDetailOptions, type ApiErrorResponse, type ApiErrorStatus, type ApiServiceError, AuthConfigSecretRedactor, type BuildApiServiceErrorOptions, type CreateHmacSignatureOptions, GET_FILE_URL_TOOL_ID, type GetFileUrlHandler, type GetFileUrlToolInput, type GetFileUrlToolOutput, type NormalizeOAuthTokenResponseOptions, type OAuthExpiresAtOptions, type OAuthRefreshTokenFallbackMode, type OAuthTokenResponse, Slate, SlateAction, SlateActionBuilder, type SlateActionCreateParameters, type SlateActionDocsReference, type SlateActionParameters, type SlateActionParametersAny, type SlateActionParametersTool, type SlateActionParametersTrigger, type SlateActionScopeClause, type SlateActionScopeClauseInput, type SlateActionScopeValue, type SlateActionScopes, type SlateActionScopesInput, type SlateActionType, SlateAdapter, type SlateAdapterCapability, SlateAdapterSpec, type SlateAdapterSpecParameters, type SlateAddAttachmentContent, type SlateAddAttachmentInput, type SlateAttachment, type SlateAttachmentInlineContent, type SlateAttachmentUploadReferenceContent, type SlateAttachmentUrlContent, SlateAuth, type SlateAuthDocsReference, type SlateAuthType, type SlateAuthWithCustomData, type SlateAuthWithNone, type SlateAuthWithOauth, type SlateAuthWithServiceAccount, type SlateAuthWithToken, type SlateAuthenticatedAxiosDefaults, type SlateAxiosDefaults, type SlateAxiosErrorAdapter, type SlateAxiosErrorOptions, SlateConfig, type SlateConfigDocsReference, SlateContext, SlateDeclarationError, SlateDefaultPollingIntervalSeconds, type SlateDirectUploadInput, type SlateDocsReference, SlateError, type SlateErrorInput, type SlateErrorIssue, type SlateErrorKind, type SlateErrorProviderInfo, type SlateErrorResponse, type SlateErrorUpstreamInfo, type SlateGatewayEvent, type SlateLiveInvocationInfo, type SlateLogEntry, type SlateLogFields, type SlateLogListener, type SlateLogMessageInput, type SlateLogType, SlateLogger, type SlateProviderDocsReference, SlatePublicContext, SlatePublicTool, type SlatePublicToolInvocationHandler, type SlatePublicToolParameters, type SlateServiceErrorData, SlateSpecification, type SlateSpecificationCreateParameters, type SlateSpecificationParameters, SlateTool, type SlateToolInvocationHandler, type SlateToolParameters, SlateTrigger, SlateTriggerGroup, SlateTriggerGroupBuilder, type SlateTriggerGroupCreateParameters, type SlateTriggerGroupGatewayConnectHandler, type SlateTriggerGroupGatewayParameters, type SlateTriggerGroupGatewayReceiveHandler, type SlateTriggerGroupParameters, type SlateTriggerGroupPollHandler, type SlateTriggerGroupPollingParameters, type SlateTriggerGroupRoutingMatchersHandler, type SlateTriggerGroupWebhookAutoRegistrationParameters, type SlateTriggerGroupWebhookManualRegistrationParameters, type SlateTriggerGroupWebhookParameters, type SlateTriggerMappingHandler, type SlateTriggerMatchesHandler, type SlateTriggerParameters, type SlateTriggerRoutingMatcher, type SlateTypedDocsReference, type SlateWebhookHttpResponseInit, type SlateWebhookManualFinishHandler, type SlateWebhookManualSetupHandler, type SlateWebhookProcessHandler, type SlateWebhookRegisterHandler, type SlateWebhookSkipped, type SlateWebhookTarget, type SlateWebhookTargetListHandler, type SlateWebhookTargetOwnership, type SlateWebhookUnregisterHandler, type VerifyHmacSignatureOptions, adapterSpec, allOf, anyOf, auth, axios, buildApiServiceError, collectApiErrorDetails, config, createApiServiceError, createAuthenticatedAxios, createAxios, createBase64Attachment, createHmacSignature, createSlateError, createTextAttachment, createUrlAttachment, extractApiErrorMessage, getApiErrorResponse, getApiErrorStatus, getBase64ByteLength, getCurrentContext, getFileUrlTool, getFileUrlToolInputSchema, getFileUrlToolOutputSchema, getGraphWebhookValidationResponse, getMetaWebhookVerificationResponse, getOAuthExpiresAtFromExpiresIn, getResponseHeaderValue, getServiceErrorData, graphWebhookHttp, inferSlateErrorFromAxios, isApiErrorRecord, isAxiosErrorLike, isServiceErrorData, isUrlEmbeddedCredential, mapServiceErrorCode, mapServiceErrorToSlateErrorInput, mergeScopes, metaWebhookHttp, normalizeOAuthTokenResponse, pickDefined, publicTool, redactUrlAttachmentSecrets, requestAxios, requestAxiosData, runWithContext, scopeClause, setIfDefined, skipWebhook, spec, statusLabelForApiError, tool, trigger, triggerGroup, uploadAttachmentDirect, validateScopes, verifyHmacSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -50,15 +50,17 @@ declare class AuthConfigSecretRedactor {
|
|
|
50
50
|
private readonly secretToPlaceholder;
|
|
51
51
|
constructor(authConfig: Record<string, unknown> | undefined);
|
|
52
52
|
redact<T>(value: T): T;
|
|
53
|
-
|
|
53
|
+
/** `embeddable` limits which secrets are also replaced inside longer strings. */
|
|
54
|
+
redactEmbedded<T>(value: T, embeddable?: (secret: string, path: string) => boolean): T;
|
|
54
55
|
private buildSecretMap;
|
|
55
56
|
private transform;
|
|
56
57
|
private isPlainObject;
|
|
57
58
|
}
|
|
59
|
+
declare let isUrlEmbeddedCredential: (secret: string, path: string) => boolean;
|
|
58
60
|
/**
|
|
59
61
|
* Applied to every finalized attachment list right before it's sent over
|
|
60
62
|
* `slates/action.tool.invoke` (see @slates/provider-handler). Only `type: 'url'` attachments
|
|
61
|
-
* carry
|
|
63
|
+
* carry credentials -- content/upload_reference attachments pass through untouched.
|
|
62
64
|
*/
|
|
63
65
|
declare let redactUrlAttachmentSecrets: (attachments: SlateAttachment[] | undefined, authConfig: Record<string, unknown> | undefined) => SlateAttachment[] | undefined;
|
|
64
66
|
|
|
@@ -150,6 +152,7 @@ type SlateAuthWithOauth<InputType extends {}, OutputType extends {
|
|
|
150
152
|
scope: string;
|
|
151
153
|
}[];
|
|
152
154
|
adapters?: string[];
|
|
155
|
+
syncTokensAcrossConnections?: boolean;
|
|
153
156
|
docs?: SlateAuthDocsReference[];
|
|
154
157
|
inputSchema?: z.ZodType<InputType>;
|
|
155
158
|
onInputChanged?: (params: {
|
|
@@ -522,6 +525,41 @@ type SlateTriggerGroupPollHandler<ConfigType extends {}, AuthType extends {}> =
|
|
|
522
525
|
}[];
|
|
523
526
|
updatedState?: any;
|
|
524
527
|
}>;
|
|
528
|
+
interface SlateGatewayEvent {
|
|
529
|
+
payload: any;
|
|
530
|
+
idempotencyKey?: string;
|
|
531
|
+
}
|
|
532
|
+
type SlateTriggerGroupGatewayConnectHandler<ConfigType extends {}, AuthType extends {}> = (context: SlateContext<ConfigType, AuthType, {
|
|
533
|
+
state: any | null;
|
|
534
|
+
}>) => Promise<{
|
|
535
|
+
url: string;
|
|
536
|
+
state?: any;
|
|
537
|
+
}>;
|
|
538
|
+
/** `closed` is set, with no frames, when the socket closed unexpectedly. */
|
|
539
|
+
type SlateTriggerGroupGatewayReceiveHandler<ConfigType extends {}, AuthType extends {}> = (context: SlateContext<ConfigType, AuthType, {
|
|
540
|
+
state: any | null;
|
|
541
|
+
frames: string[];
|
|
542
|
+
closed?: {
|
|
543
|
+
code: number;
|
|
544
|
+
reason: string;
|
|
545
|
+
} | null;
|
|
546
|
+
}>) => Promise<{
|
|
547
|
+
state?: any;
|
|
548
|
+
send?: string[];
|
|
549
|
+
events?: SlateGatewayEvent[];
|
|
550
|
+
/** With `expectsAck`, the hub reconnects when no `heartbeatAcked` arrives before the next beat. */
|
|
551
|
+
heartbeat?: {
|
|
552
|
+
intervalMs: number;
|
|
553
|
+
frame: string;
|
|
554
|
+
expectsAck?: boolean;
|
|
555
|
+
} | null;
|
|
556
|
+
/** Set when `frames` included the provider's heartbeat acknowledgement. */
|
|
557
|
+
heartbeatAcked?: boolean;
|
|
558
|
+
close?: {
|
|
559
|
+
reconnect: boolean;
|
|
560
|
+
reason?: string;
|
|
561
|
+
} | null;
|
|
562
|
+
}>;
|
|
525
563
|
type SlateWebhookTargetListHandler<ConfigType extends {}, AuthType extends {}> = (context: SlateContext<ConfigType, AuthType, {
|
|
526
564
|
pageToken: any | null;
|
|
527
565
|
}>) => Promise<{
|
|
@@ -573,6 +611,10 @@ interface SlateTriggerGroupPollingParameters<ConfigType extends {}, AuthType ext
|
|
|
573
611
|
intervalSeconds: number;
|
|
574
612
|
pollEvents: SlateTriggerGroupPollHandler<ConfigType, AuthType>;
|
|
575
613
|
}
|
|
614
|
+
interface SlateTriggerGroupGatewayParameters<ConfigType extends {}, AuthType extends {}> {
|
|
615
|
+
connect: SlateTriggerGroupGatewayConnectHandler<ConfigType, AuthType>;
|
|
616
|
+
receive: SlateTriggerGroupGatewayReceiveHandler<ConfigType, AuthType>;
|
|
617
|
+
}
|
|
576
618
|
interface SlateTriggerGroupWebhookAutoRegistrationParameters<ConfigType extends {}, AuthType extends {}> {
|
|
577
619
|
webhookTargetList: SlateWebhookTargetListHandler<ConfigType, AuthType>;
|
|
578
620
|
webhookRegister: SlateWebhookRegisterHandler<ConfigType, AuthType>;
|
|
@@ -597,9 +639,10 @@ interface SlateTriggerGroupCreateParameters<InputType extends {} = Record<string
|
|
|
597
639
|
eventSchema?: z$1.ZodType<InputType>;
|
|
598
640
|
}
|
|
599
641
|
interface SlateTriggerGroupParameters<ConfigType extends {}, AuthType extends {}, InputType extends {} = Record<string, unknown>> extends SlateTriggerGroupCreateParameters<InputType> {
|
|
600
|
-
source: 'polling' | 'webhook';
|
|
642
|
+
source: 'polling' | 'webhook' | 'gateway';
|
|
601
643
|
polling?: SlateTriggerGroupPollingParameters<ConfigType, AuthType>;
|
|
602
644
|
webhook?: SlateTriggerGroupWebhookParameters<ConfigType, AuthType>;
|
|
645
|
+
gateway?: SlateTriggerGroupGatewayParameters<ConfigType, AuthType>;
|
|
603
646
|
routingMatchers: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>;
|
|
604
647
|
}
|
|
605
648
|
declare class SlateTriggerGroup<ConfigType extends {}, AuthType extends {}, InputType extends {} = Record<string, unknown>> {
|
|
@@ -613,9 +656,10 @@ declare class SlateTriggerGroup<ConfigType extends {}, AuthType extends {}, Inpu
|
|
|
613
656
|
get description(): string | undefined;
|
|
614
657
|
get metadata(): Record<string, any> | undefined;
|
|
615
658
|
get eventSchema(): z$1.ZodType<InputType, unknown, z$1.core.$ZodTypeInternals<InputType, unknown>>;
|
|
616
|
-
get source(): "polling" | "webhook";
|
|
659
|
+
get source(): "polling" | "webhook" | "gateway";
|
|
617
660
|
get polling(): SlateTriggerGroupPollingParameters<ConfigType, AuthType> | undefined;
|
|
618
661
|
get webhook(): SlateTriggerGroupWebhookParameters<ConfigType, AuthType> | undefined;
|
|
662
|
+
get gateway(): SlateTriggerGroupGatewayParameters<ConfigType, AuthType> | undefined;
|
|
619
663
|
get routingMatchers(): SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>;
|
|
620
664
|
}
|
|
621
665
|
declare class SlateTriggerGroupBuilder<ConfigType extends {}, AuthType extends {}, InputType extends {} = Record<string, unknown>> {
|
|
@@ -633,6 +677,8 @@ declare class SlateTriggerGroupBuilder<ConfigType extends {}, AuthType extends {
|
|
|
633
677
|
manualRegistration?: SlateTriggerGroupWebhookManualRegistrationParameters<UserConfigSchema, FullConfigSchema>;
|
|
634
678
|
process: SlateWebhookProcessHandler;
|
|
635
679
|
}): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType>;
|
|
680
|
+
/** Receive events over a platform-managed persistent connection (e.g. a WebSocket gateway). */
|
|
681
|
+
gateway(props: SlateTriggerGroupGatewayParameters<ConfigType, AuthType>): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType>;
|
|
636
682
|
routingMatchers(handler: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType>;
|
|
637
683
|
build(): SlateTriggerGroup<ConfigType, AuthType, InputType>;
|
|
638
684
|
}
|
|
@@ -1093,4 +1139,4 @@ declare let skipWebhook: (reason: string, response?: Response | SlateWebhookHttp
|
|
|
1093
1139
|
response: Response | SlateWebhookHttpResponseInit;
|
|
1094
1140
|
};
|
|
1095
1141
|
|
|
1096
|
-
export { AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX, type ApiErrorBuildHelpers, type ApiErrorDetailOptions, type ApiErrorResponse, type ApiErrorStatus, type ApiServiceError, AuthConfigSecretRedactor, type BuildApiServiceErrorOptions, type CreateHmacSignatureOptions, GET_FILE_URL_TOOL_ID, type GetFileUrlHandler, type GetFileUrlToolInput, type GetFileUrlToolOutput, type NormalizeOAuthTokenResponseOptions, type OAuthExpiresAtOptions, type OAuthRefreshTokenFallbackMode, type OAuthTokenResponse, Slate, SlateAction, SlateActionBuilder, type SlateActionCreateParameters, type SlateActionDocsReference, type SlateActionParameters, type SlateActionParametersAny, type SlateActionParametersTool, type SlateActionParametersTrigger, type SlateActionScopeClause, type SlateActionScopeClauseInput, type SlateActionScopeValue, type SlateActionScopes, type SlateActionScopesInput, type SlateActionType, SlateAdapter, type SlateAdapterCapability, SlateAdapterSpec, type SlateAdapterSpecParameters, type SlateAddAttachmentContent, type SlateAddAttachmentInput, type SlateAttachment, type SlateAttachmentInlineContent, type SlateAttachmentUploadReferenceContent, type SlateAttachmentUrlContent, SlateAuth, type SlateAuthDocsReference, type SlateAuthType, type SlateAuthWithCustomData, type SlateAuthWithNone, type SlateAuthWithOauth, type SlateAuthWithServiceAccount, type SlateAuthWithToken, type SlateAuthenticatedAxiosDefaults, type SlateAxiosDefaults, type SlateAxiosErrorAdapter, type SlateAxiosErrorOptions, SlateConfig, type SlateConfigDocsReference, SlateContext, SlateDeclarationError, SlateDefaultPollingIntervalSeconds, type SlateDirectUploadInput, type SlateDocsReference, SlateError, type SlateErrorInput, type SlateErrorIssue, type SlateErrorKind, type SlateErrorProviderInfo, type SlateErrorResponse, type SlateErrorUpstreamInfo, type SlateLiveInvocationInfo, type SlateLogEntry, type SlateLogFields, type SlateLogListener, type SlateLogMessageInput, type SlateLogType, SlateLogger, type SlateProviderDocsReference, SlatePublicContext, SlatePublicTool, type SlatePublicToolInvocationHandler, type SlatePublicToolParameters, type SlateServiceErrorData, SlateSpecification, type SlateSpecificationCreateParameters, type SlateSpecificationParameters, SlateTool, type SlateToolInvocationHandler, type SlateToolParameters, SlateTrigger, SlateTriggerGroup, SlateTriggerGroupBuilder, type SlateTriggerGroupCreateParameters, type SlateTriggerGroupParameters, type SlateTriggerGroupPollHandler, type SlateTriggerGroupPollingParameters, type SlateTriggerGroupRoutingMatchersHandler, type SlateTriggerGroupWebhookAutoRegistrationParameters, type SlateTriggerGroupWebhookManualRegistrationParameters, type SlateTriggerGroupWebhookParameters, type SlateTriggerMappingHandler, type SlateTriggerMatchesHandler, type SlateTriggerParameters, type SlateTriggerRoutingMatcher, type SlateTypedDocsReference, type SlateWebhookHttpResponseInit, type SlateWebhookManualFinishHandler, type SlateWebhookManualSetupHandler, type SlateWebhookProcessHandler, type SlateWebhookRegisterHandler, type SlateWebhookSkipped, type SlateWebhookTarget, type SlateWebhookTargetListHandler, type SlateWebhookTargetOwnership, type SlateWebhookUnregisterHandler, type VerifyHmacSignatureOptions, adapterSpec, allOf, anyOf, auth, axios, buildApiServiceError, collectApiErrorDetails, config, createApiServiceError, createAuthenticatedAxios, createAxios, createBase64Attachment, createHmacSignature, createSlateError, createTextAttachment, createUrlAttachment, extractApiErrorMessage, getApiErrorResponse, getApiErrorStatus, getBase64ByteLength, getCurrentContext, getFileUrlTool, getFileUrlToolInputSchema, getFileUrlToolOutputSchema, getGraphWebhookValidationResponse, getMetaWebhookVerificationResponse, getOAuthExpiresAtFromExpiresIn, getResponseHeaderValue, getServiceErrorData, graphWebhookHttp, inferSlateErrorFromAxios, isApiErrorRecord, isAxiosErrorLike, isServiceErrorData, mapServiceErrorCode, mapServiceErrorToSlateErrorInput, mergeScopes, metaWebhookHttp, normalizeOAuthTokenResponse, pickDefined, publicTool, redactUrlAttachmentSecrets, requestAxios, requestAxiosData, runWithContext, scopeClause, setIfDefined, skipWebhook, spec, statusLabelForApiError, tool, trigger, triggerGroup, uploadAttachmentDirect, validateScopes, verifyHmacSignature };
|
|
1142
|
+
export { AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX, type ApiErrorBuildHelpers, type ApiErrorDetailOptions, type ApiErrorResponse, type ApiErrorStatus, type ApiServiceError, AuthConfigSecretRedactor, type BuildApiServiceErrorOptions, type CreateHmacSignatureOptions, GET_FILE_URL_TOOL_ID, type GetFileUrlHandler, type GetFileUrlToolInput, type GetFileUrlToolOutput, type NormalizeOAuthTokenResponseOptions, type OAuthExpiresAtOptions, type OAuthRefreshTokenFallbackMode, type OAuthTokenResponse, Slate, SlateAction, SlateActionBuilder, type SlateActionCreateParameters, type SlateActionDocsReference, type SlateActionParameters, type SlateActionParametersAny, type SlateActionParametersTool, type SlateActionParametersTrigger, type SlateActionScopeClause, type SlateActionScopeClauseInput, type SlateActionScopeValue, type SlateActionScopes, type SlateActionScopesInput, type SlateActionType, SlateAdapter, type SlateAdapterCapability, SlateAdapterSpec, type SlateAdapterSpecParameters, type SlateAddAttachmentContent, type SlateAddAttachmentInput, type SlateAttachment, type SlateAttachmentInlineContent, type SlateAttachmentUploadReferenceContent, type SlateAttachmentUrlContent, SlateAuth, type SlateAuthDocsReference, type SlateAuthType, type SlateAuthWithCustomData, type SlateAuthWithNone, type SlateAuthWithOauth, type SlateAuthWithServiceAccount, type SlateAuthWithToken, type SlateAuthenticatedAxiosDefaults, type SlateAxiosDefaults, type SlateAxiosErrorAdapter, type SlateAxiosErrorOptions, SlateConfig, type SlateConfigDocsReference, SlateContext, SlateDeclarationError, SlateDefaultPollingIntervalSeconds, type SlateDirectUploadInput, type SlateDocsReference, SlateError, type SlateErrorInput, type SlateErrorIssue, type SlateErrorKind, type SlateErrorProviderInfo, type SlateErrorResponse, type SlateErrorUpstreamInfo, type SlateGatewayEvent, type SlateLiveInvocationInfo, type SlateLogEntry, type SlateLogFields, type SlateLogListener, type SlateLogMessageInput, type SlateLogType, SlateLogger, type SlateProviderDocsReference, SlatePublicContext, SlatePublicTool, type SlatePublicToolInvocationHandler, type SlatePublicToolParameters, type SlateServiceErrorData, SlateSpecification, type SlateSpecificationCreateParameters, type SlateSpecificationParameters, SlateTool, type SlateToolInvocationHandler, type SlateToolParameters, SlateTrigger, SlateTriggerGroup, SlateTriggerGroupBuilder, type SlateTriggerGroupCreateParameters, type SlateTriggerGroupGatewayConnectHandler, type SlateTriggerGroupGatewayParameters, type SlateTriggerGroupGatewayReceiveHandler, type SlateTriggerGroupParameters, type SlateTriggerGroupPollHandler, type SlateTriggerGroupPollingParameters, type SlateTriggerGroupRoutingMatchersHandler, type SlateTriggerGroupWebhookAutoRegistrationParameters, type SlateTriggerGroupWebhookManualRegistrationParameters, type SlateTriggerGroupWebhookParameters, type SlateTriggerMappingHandler, type SlateTriggerMatchesHandler, type SlateTriggerParameters, type SlateTriggerRoutingMatcher, type SlateTypedDocsReference, type SlateWebhookHttpResponseInit, type SlateWebhookManualFinishHandler, type SlateWebhookManualSetupHandler, type SlateWebhookProcessHandler, type SlateWebhookRegisterHandler, type SlateWebhookSkipped, type SlateWebhookTarget, type SlateWebhookTargetListHandler, type SlateWebhookTargetOwnership, type SlateWebhookUnregisterHandler, type VerifyHmacSignatureOptions, adapterSpec, allOf, anyOf, auth, axios, buildApiServiceError, collectApiErrorDetails, config, createApiServiceError, createAuthenticatedAxios, createAxios, createBase64Attachment, createHmacSignature, createSlateError, createTextAttachment, createUrlAttachment, extractApiErrorMessage, getApiErrorResponse, getApiErrorStatus, getBase64ByteLength, getCurrentContext, getFileUrlTool, getFileUrlToolInputSchema, getFileUrlToolOutputSchema, getGraphWebhookValidationResponse, getMetaWebhookVerificationResponse, getOAuthExpiresAtFromExpiresIn, getResponseHeaderValue, getServiceErrorData, graphWebhookHttp, inferSlateErrorFromAxios, isApiErrorRecord, isAxiosErrorLike, isServiceErrorData, isUrlEmbeddedCredential, mapServiceErrorCode, mapServiceErrorToSlateErrorInput, mergeScopes, metaWebhookHttp, normalizeOAuthTokenResponse, pickDefined, publicTool, redactUrlAttachmentSecrets, requestAxios, requestAxiosData, runWithContext, scopeClause, setIfDefined, skipWebhook, spec, statusLabelForApiError, tool, trigger, triggerGroup, uploadAttachmentDirect, validateScopes, verifyHmacSignature };
|
package/dist/index.module.js
CHANGED
|
@@ -293,7 +293,7 @@ var normalizeRetryable = (code, retryable) => {
|
|
|
293
293
|
};
|
|
294
294
|
var getDefaultMessage = (code, message) => {
|
|
295
295
|
if (message?.trim()) return message;
|
|
296
|
-
return DEFAULT_MESSAGES[code] ?? DEFAULT_MESSAGES[DEFAULT_CODE];
|
|
296
|
+
return DEFAULT_MESSAGES[code] ?? DEFAULT_MESSAGES[DEFAULT_CODE] ?? "An unexpected internal error occurred.";
|
|
297
297
|
};
|
|
298
298
|
var cleanRecord = (value) => {
|
|
299
299
|
if (!value) return void 0;
|
|
@@ -961,10 +961,14 @@ var AuthConfigSecretRedactor = class {
|
|
|
961
961
|
return this.secretToPlaceholder.get(stringValue) ?? stringValue;
|
|
962
962
|
});
|
|
963
963
|
}
|
|
964
|
-
|
|
965
|
-
|
|
964
|
+
/** `embeddable` limits which secrets are also replaced inside longer strings. */
|
|
965
|
+
redactEmbedded(value, embeddable = () => true) {
|
|
966
|
+
let secrets = [...this.secretToPlaceholder.entries()].filter(
|
|
967
|
+
([secret, placeholder]) => embeddable(secret, placeholder.slice(AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX.length))
|
|
968
|
+
).map(([secret]) => secret);
|
|
969
|
+
if (secrets.length === 0) return this.redact(value);
|
|
966
970
|
let pattern = new RegExp(
|
|
967
|
-
|
|
971
|
+
secrets.sort((a, b) => b.length - a.length).map((secret) => secret.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"),
|
|
968
972
|
"g"
|
|
969
973
|
);
|
|
970
974
|
return this.transform(value, (stringValue) => {
|
|
@@ -1017,18 +1021,21 @@ var AuthConfigSecretRedactor = class {
|
|
|
1017
1021
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1018
1022
|
}
|
|
1019
1023
|
};
|
|
1024
|
+
var URL_CREDENTIAL_KEY = /^(?:.*[-_])?(?:token|secret|password|api[-_]?key)$/i;
|
|
1025
|
+
var isUrlEmbeddedCredential = (secret, path) => secret.length >= 8 && URL_CREDENTIAL_KEY.test(path.split(".").pop() ?? "");
|
|
1020
1026
|
var redactUrlAttachmentSecrets = (attachments, authConfig) => {
|
|
1021
1027
|
if (!authConfig || !attachments) return attachments;
|
|
1022
1028
|
let redactor = new AuthConfigSecretRedactor(authConfig);
|
|
1023
1029
|
return attachments.map((attachment) => {
|
|
1024
1030
|
if (attachment.content.type !== "url") return attachment;
|
|
1025
|
-
|
|
1031
|
+
let { url, headers, query } = attachment.content;
|
|
1026
1032
|
return {
|
|
1027
1033
|
...attachment,
|
|
1028
1034
|
content: {
|
|
1029
1035
|
...attachment.content,
|
|
1030
|
-
|
|
1031
|
-
|
|
1036
|
+
url: redactor.redactEmbedded(url, isUrlEmbeddedCredential),
|
|
1037
|
+
...headers ? { headers: redactor.redactEmbedded(headers) } : {},
|
|
1038
|
+
...query ? { query: redactor.redactEmbedded(query) } : {}
|
|
1032
1039
|
}
|
|
1033
1040
|
};
|
|
1034
1041
|
});
|
|
@@ -1078,6 +1085,7 @@ var getFileUrlTool = (spec2, handleGetFileUrl) => tool(spec2, {
|
|
|
1078
1085
|
return {
|
|
1079
1086
|
output: {
|
|
1080
1087
|
...output,
|
|
1088
|
+
url: redactor.redactEmbedded(output.url, isUrlEmbeddedCredential),
|
|
1081
1089
|
...output.headers ? { headers: redactor.redactEmbedded(output.headers) } : {},
|
|
1082
1090
|
...output.query ? { query: redactor.redactEmbedded(output.query) } : {}
|
|
1083
1091
|
},
|
|
@@ -1175,6 +1183,9 @@ var SlateTriggerGroup = class _SlateTriggerGroup {
|
|
|
1175
1183
|
get webhook() {
|
|
1176
1184
|
return this._params.webhook;
|
|
1177
1185
|
}
|
|
1186
|
+
get gateway() {
|
|
1187
|
+
return this._params.gateway;
|
|
1188
|
+
}
|
|
1178
1189
|
get routingMatchers() {
|
|
1179
1190
|
return this._params.routingMatchers;
|
|
1180
1191
|
}
|
|
@@ -1191,6 +1202,7 @@ var SlateTriggerGroupBuilder = class {
|
|
|
1191
1202
|
#source = null;
|
|
1192
1203
|
#polling = null;
|
|
1193
1204
|
#webhook = null;
|
|
1205
|
+
#gateway = null;
|
|
1194
1206
|
#routingMatchers = null;
|
|
1195
1207
|
polling(props) {
|
|
1196
1208
|
if (this.#source) {
|
|
@@ -1220,6 +1232,15 @@ var SlateTriggerGroupBuilder = class {
|
|
|
1220
1232
|
};
|
|
1221
1233
|
return this;
|
|
1222
1234
|
}
|
|
1235
|
+
/** Receive events over a platform-managed persistent connection (e.g. a WebSocket gateway). */
|
|
1236
|
+
gateway(props) {
|
|
1237
|
+
if (this.#source) {
|
|
1238
|
+
throw new SlateDeclarationError("Trigger group invocation is already defined");
|
|
1239
|
+
}
|
|
1240
|
+
this.#source = "gateway";
|
|
1241
|
+
this.#gateway = { connect: props.connect, receive: props.receive };
|
|
1242
|
+
return this;
|
|
1243
|
+
}
|
|
1223
1244
|
routingMatchers(handler) {
|
|
1224
1245
|
this.#routingMatchers = handler;
|
|
1225
1246
|
return this;
|
|
@@ -1227,7 +1248,7 @@ var SlateTriggerGroupBuilder = class {
|
|
|
1227
1248
|
build() {
|
|
1228
1249
|
if (!this.#source) {
|
|
1229
1250
|
throw new SlateDeclarationError(
|
|
1230
|
-
"Trigger group invocation (polling or
|
|
1251
|
+
"Trigger group invocation (polling, webhook, or gateway) is not defined"
|
|
1231
1252
|
);
|
|
1232
1253
|
}
|
|
1233
1254
|
if (!this.#routingMatchers) {
|
|
@@ -1238,6 +1259,7 @@ var SlateTriggerGroupBuilder = class {
|
|
|
1238
1259
|
source: this.#source,
|
|
1239
1260
|
polling: this.#polling ?? void 0,
|
|
1240
1261
|
webhook: this.#webhook ?? void 0,
|
|
1262
|
+
gateway: this.#gateway ?? void 0,
|
|
1241
1263
|
routingMatchers: this.#routingMatchers
|
|
1242
1264
|
});
|
|
1243
1265
|
}
|
|
@@ -2027,6 +2049,7 @@ var redactHashFragment = (hash, redactor) => {
|
|
|
2027
2049
|
);
|
|
2028
2050
|
return redacted ? `#${redacted}` : "";
|
|
2029
2051
|
};
|
|
2052
|
+
var isEmbeddedPathSecret = (secret, path) => secret.length >= 8 && isSecretKeyName(path.split(".").pop() ?? "");
|
|
2030
2053
|
var sanitizeUrl = (value, redactor) => {
|
|
2031
2054
|
if (!value) return value;
|
|
2032
2055
|
try {
|
|
@@ -2035,6 +2058,7 @@ var sanitizeUrl = (value, redactor) => {
|
|
|
2035
2058
|
url.username = "";
|
|
2036
2059
|
url.password = "";
|
|
2037
2060
|
}
|
|
2061
|
+
if (redactor) url.pathname = redactor.redactEmbedded(url.pathname, isEmbeddedPathSecret);
|
|
2038
2062
|
for (let key of Array.from(url.searchParams.keys())) {
|
|
2039
2063
|
if (isUrlFormSecretKeyName(key)) {
|
|
2040
2064
|
url.searchParams.set(key, REDACTED_VALUE);
|
|
@@ -2047,7 +2071,7 @@ var sanitizeUrl = (value, redactor) => {
|
|
|
2047
2071
|
url.hash = redactHashFragment(url.hash, redactor);
|
|
2048
2072
|
return decodeRedactedMarker(url.toString());
|
|
2049
2073
|
} catch {
|
|
2050
|
-
let text = redactor ? redactor.
|
|
2074
|
+
let text = redactor ? redactor.redactEmbedded(value, isEmbeddedPathSecret) : value;
|
|
2051
2075
|
return text.replace(
|
|
2052
2076
|
/([?&]([^=&#]+)=)([^&#]+)/g,
|
|
2053
2077
|
(_match, prefix, key, rawValue) => isUrlFormSecretKeyName(key) ? `${prefix}${REDACTED_VALUE}` : `${prefix}${rawValue}`
|
|
@@ -2898,6 +2922,7 @@ export {
|
|
|
2898
2922
|
isApiErrorRecord,
|
|
2899
2923
|
isAxiosErrorLike,
|
|
2900
2924
|
isServiceErrorData,
|
|
2925
|
+
isUrlEmbeddedCredential,
|
|
2901
2926
|
mapServiceErrorCode,
|
|
2902
2927
|
mapServiceErrorToSlateErrorInput,
|
|
2903
2928
|
mergeScopes,
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { AuthConfigSecretRedactor } from '../auth/redact';
|
|
2
|
+
import { AuthConfigSecretRedactor, isUrlEmbeddedCredential } from '../auth/redact';
|
|
3
3
|
import type { SlateContext } from '../context/context';
|
|
4
4
|
import type { SlateSpecification } from '../specification/specification';
|
|
5
5
|
import { tool } from './tool';
|
|
@@ -42,6 +42,7 @@ export let getFileUrlTool = <ConfigType extends {}, AuthType extends {}>(
|
|
|
42
42
|
return {
|
|
43
43
|
output: {
|
|
44
44
|
...output,
|
|
45
|
+
url: redactor.redactEmbedded(output.url, isUrlEmbeddedCredential),
|
|
45
46
|
...(output.headers ? { headers: redactor.redactEmbedded(output.headers) } : {}),
|
|
46
47
|
...(output.query ? { query: redactor.redactEmbedded(output.query) } : {})
|
|
47
48
|
},
|
|
@@ -31,6 +31,39 @@ export type SlateTriggerGroupPollHandler<ConfigType extends {}, AuthType extends
|
|
|
31
31
|
updatedState?: any;
|
|
32
32
|
}>;
|
|
33
33
|
|
|
34
|
+
export interface SlateGatewayEvent {
|
|
35
|
+
payload: any;
|
|
36
|
+
idempotencyKey?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type SlateTriggerGroupGatewayConnectHandler<
|
|
40
|
+
ConfigType extends {},
|
|
41
|
+
AuthType extends {}
|
|
42
|
+
> = (
|
|
43
|
+
context: SlateContext<ConfigType, AuthType, { state: any | null }>
|
|
44
|
+
) => Promise<{ url: string; state?: any }>;
|
|
45
|
+
|
|
46
|
+
/** `closed` is set, with no frames, when the socket closed unexpectedly. */
|
|
47
|
+
export type SlateTriggerGroupGatewayReceiveHandler<
|
|
48
|
+
ConfigType extends {},
|
|
49
|
+
AuthType extends {}
|
|
50
|
+
> = (
|
|
51
|
+
context: SlateContext<
|
|
52
|
+
ConfigType,
|
|
53
|
+
AuthType,
|
|
54
|
+
{ state: any | null; frames: string[]; closed?: { code: number; reason: string } | null }
|
|
55
|
+
>
|
|
56
|
+
) => Promise<{
|
|
57
|
+
state?: any;
|
|
58
|
+
send?: string[];
|
|
59
|
+
events?: SlateGatewayEvent[];
|
|
60
|
+
/** With `expectsAck`, the hub reconnects when no `heartbeatAcked` arrives before the next beat. */
|
|
61
|
+
heartbeat?: { intervalMs: number; frame: string; expectsAck?: boolean } | null;
|
|
62
|
+
/** Set when `frames` included the provider's heartbeat acknowledgement. */
|
|
63
|
+
heartbeatAcked?: boolean;
|
|
64
|
+
close?: { reconnect: boolean; reason?: string } | null;
|
|
65
|
+
}>;
|
|
66
|
+
|
|
34
67
|
export type SlateWebhookTargetListHandler<ConfigType extends {}, AuthType extends {}> = (
|
|
35
68
|
context: SlateContext<ConfigType, AuthType, { pageToken: any | null }>
|
|
36
69
|
) => Promise<{
|
|
@@ -121,6 +154,14 @@ export interface SlateTriggerGroupPollingParameters<
|
|
|
121
154
|
pollEvents: SlateTriggerGroupPollHandler<ConfigType, AuthType>;
|
|
122
155
|
}
|
|
123
156
|
|
|
157
|
+
export interface SlateTriggerGroupGatewayParameters<
|
|
158
|
+
ConfigType extends {},
|
|
159
|
+
AuthType extends {}
|
|
160
|
+
> {
|
|
161
|
+
connect: SlateTriggerGroupGatewayConnectHandler<ConfigType, AuthType>;
|
|
162
|
+
receive: SlateTriggerGroupGatewayReceiveHandler<ConfigType, AuthType>;
|
|
163
|
+
}
|
|
164
|
+
|
|
124
165
|
export interface SlateTriggerGroupWebhookAutoRegistrationParameters<
|
|
125
166
|
ConfigType extends {},
|
|
126
167
|
AuthType extends {}
|
|
@@ -164,9 +205,10 @@ export interface SlateTriggerGroupParameters<
|
|
|
164
205
|
AuthType extends {},
|
|
165
206
|
InputType extends {} = Record<string, unknown>
|
|
166
207
|
> extends SlateTriggerGroupCreateParameters<InputType> {
|
|
167
|
-
source: 'polling' | 'webhook';
|
|
208
|
+
source: 'polling' | 'webhook' | 'gateway';
|
|
168
209
|
polling?: SlateTriggerGroupPollingParameters<ConfigType, AuthType>;
|
|
169
210
|
webhook?: SlateTriggerGroupWebhookParameters<ConfigType, AuthType>;
|
|
211
|
+
gateway?: SlateTriggerGroupGatewayParameters<ConfigType, AuthType>;
|
|
170
212
|
routingMatchers: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>;
|
|
171
213
|
}
|
|
172
214
|
|
|
@@ -227,6 +269,10 @@ export class SlateTriggerGroup<
|
|
|
227
269
|
return this._params.webhook;
|
|
228
270
|
}
|
|
229
271
|
|
|
272
|
+
get gateway() {
|
|
273
|
+
return this._params.gateway;
|
|
274
|
+
}
|
|
275
|
+
|
|
230
276
|
get routingMatchers() {
|
|
231
277
|
return this._params.routingMatchers;
|
|
232
278
|
}
|
|
@@ -237,9 +283,10 @@ export class SlateTriggerGroupBuilder<
|
|
|
237
283
|
AuthType extends {},
|
|
238
284
|
InputType extends {} = Record<string, unknown>
|
|
239
285
|
> {
|
|
240
|
-
#source: 'polling' | 'webhook' | null = null;
|
|
286
|
+
#source: 'polling' | 'webhook' | 'gateway' | null = null;
|
|
241
287
|
#polling: SlateTriggerGroupPollingParameters<ConfigType, AuthType> | null = null;
|
|
242
288
|
#webhook: SlateTriggerGroupWebhookParameters<ConfigType, AuthType> | null = null;
|
|
289
|
+
#gateway: SlateTriggerGroupGatewayParameters<ConfigType, AuthType> | null = null;
|
|
243
290
|
#routingMatchers: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType> | null =
|
|
244
291
|
null;
|
|
245
292
|
|
|
@@ -302,6 +349,20 @@ export class SlateTriggerGroupBuilder<
|
|
|
302
349
|
return this;
|
|
303
350
|
}
|
|
304
351
|
|
|
352
|
+
/** Receive events over a platform-managed persistent connection (e.g. a WebSocket gateway). */
|
|
353
|
+
gateway(
|
|
354
|
+
props: SlateTriggerGroupGatewayParameters<ConfigType, AuthType>
|
|
355
|
+
): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType> {
|
|
356
|
+
if (this.#source) {
|
|
357
|
+
throw new SlateDeclarationError('Trigger group invocation is already defined');
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
this.#source = 'gateway';
|
|
361
|
+
this.#gateway = { connect: props.connect, receive: props.receive };
|
|
362
|
+
|
|
363
|
+
return this;
|
|
364
|
+
}
|
|
365
|
+
|
|
305
366
|
routingMatchers(
|
|
306
367
|
handler: SlateTriggerGroupRoutingMatchersHandler<ConfigType, AuthType>
|
|
307
368
|
): SlateTriggerGroupBuilder<ConfigType, AuthType, InputType> {
|
|
@@ -312,7 +373,7 @@ export class SlateTriggerGroupBuilder<
|
|
|
312
373
|
build(): SlateTriggerGroup<ConfigType, AuthType, InputType> {
|
|
313
374
|
if (!this.#source) {
|
|
314
375
|
throw new SlateDeclarationError(
|
|
315
|
-
'Trigger group invocation (polling or
|
|
376
|
+
'Trigger group invocation (polling, webhook, or gateway) is not defined'
|
|
316
377
|
);
|
|
317
378
|
}
|
|
318
379
|
if (!this.#routingMatchers) {
|
|
@@ -324,6 +385,7 @@ export class SlateTriggerGroupBuilder<
|
|
|
324
385
|
source: this.#source,
|
|
325
386
|
polling: this.#polling ?? undefined,
|
|
326
387
|
webhook: this.#webhook ?? undefined,
|
|
388
|
+
gateway: this.#gateway ?? undefined,
|
|
327
389
|
routingMatchers: this.#routingMatchers
|
|
328
390
|
});
|
|
329
391
|
}
|
package/src/auth/redact.test.ts
CHANGED
|
@@ -167,7 +167,7 @@ describe('redactUrlAttachmentSecrets', () => {
|
|
|
167
167
|
]);
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
-
it('only changes
|
|
170
|
+
it('only changes credential values, preserving metadata and the original attachment', () => {
|
|
171
171
|
let attachment: SlateAttachment = {
|
|
172
172
|
mimeType: 'application/pdf',
|
|
173
173
|
attachmentHash: 'file-hash',
|
|
@@ -187,6 +187,7 @@ describe('redactUrlAttachmentSecrets', () => {
|
|
|
187
187
|
...original,
|
|
188
188
|
content: {
|
|
189
189
|
...original.content,
|
|
190
|
+
url: 'https://example.com/$$MT$secret$authConfig$token$$/file.pdf',
|
|
190
191
|
headers: { Authorization: 'Bearer $$MT$secret$authConfig$token$$' },
|
|
191
192
|
query: { key: '$$MT$secret$authConfig$nested.token2$$-suffix' }
|
|
192
193
|
}
|
|
@@ -195,7 +196,35 @@ describe('redactUrlAttachmentSecrets', () => {
|
|
|
195
196
|
expect(attachment).toEqual(original);
|
|
196
197
|
});
|
|
197
198
|
|
|
198
|
-
it('
|
|
199
|
+
it('redacts a bot token embedded in the url path', () => {
|
|
200
|
+
let attachments = [
|
|
201
|
+
urlAttachment({ url: 'https://api.telegram.org/file/bot123:ABCDEFGH/photos/a.jpg' })
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
expect(
|
|
205
|
+
redactUrlAttachmentSecrets(attachments, { token: '123:ABCDEFGH', botId: '12345678' })
|
|
206
|
+
).toEqual([
|
|
207
|
+
urlAttachment({
|
|
208
|
+
url: 'https://api.telegram.org/file/bot$$MT$secret$authConfig$token$$/photos/a.jpg'
|
|
209
|
+
})
|
|
210
|
+
]);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('keeps non-credential and short auth values in the url', () => {
|
|
214
|
+
let attachments = [
|
|
215
|
+
urlAttachment({ url: 'https://example.com/AC12345678/12345678/abc/file.pdf' })
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
expect(
|
|
219
|
+
redactUrlAttachmentSecrets(attachments, {
|
|
220
|
+
account_sid: 'AC12345678',
|
|
221
|
+
botId: '12345678',
|
|
222
|
+
token: 'abc'
|
|
223
|
+
})
|
|
224
|
+
).toEqual(attachments);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('leaves url attachments with no credentials untouched', () => {
|
|
199
228
|
let attachments = [urlAttachment()];
|
|
200
229
|
expect(redactUrlAttachmentSecrets(attachments, authConfig)).toEqual(attachments);
|
|
201
230
|
});
|
package/src/auth/redact.ts
CHANGED
|
@@ -25,11 +25,20 @@ export class AuthConfigSecretRedactor {
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
/** `embeddable` limits which secrets are also replaced inside longer strings. */
|
|
29
|
+
public redactEmbedded<T>(
|
|
30
|
+
value: T,
|
|
31
|
+
embeddable: (secret: string, path: string) => boolean = () => true
|
|
32
|
+
): T {
|
|
33
|
+
let secrets = [...this.secretToPlaceholder.entries()]
|
|
34
|
+
.filter(([secret, placeholder]) =>
|
|
35
|
+
embeddable(secret, placeholder.slice(AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX.length))
|
|
36
|
+
)
|
|
37
|
+
.map(([secret]) => secret);
|
|
38
|
+
if (secrets.length === 0) return this.redact(value);
|
|
30
39
|
|
|
31
40
|
let pattern = new RegExp(
|
|
32
|
-
|
|
41
|
+
secrets
|
|
33
42
|
.sort((a, b) => b.length - a.length)
|
|
34
43
|
// Escape regex metacharacters so values match literally; $& inserts the matched character.
|
|
35
44
|
.map(secret => secret.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
|
@@ -102,10 +111,17 @@ export class AuthConfigSecretRedactor {
|
|
|
102
111
|
}
|
|
103
112
|
}
|
|
104
113
|
|
|
114
|
+
// Credentials replaced inside URLs (e.g. Telegram's `/file/bot<token>/` path). Kept narrow:
|
|
115
|
+
// a placeholder in a URL makes the hub proxy the download instead of handing out the link.
|
|
116
|
+
let URL_CREDENTIAL_KEY = /^(?:.*[-_])?(?:token|secret|password|api[-_]?key)$/i;
|
|
117
|
+
|
|
118
|
+
export let isUrlEmbeddedCredential = (secret: string, path: string) =>
|
|
119
|
+
secret.length >= 8 && URL_CREDENTIAL_KEY.test(path.split('.').pop() ?? '');
|
|
120
|
+
|
|
105
121
|
/**
|
|
106
122
|
* Applied to every finalized attachment list right before it's sent over
|
|
107
123
|
* `slates/action.tool.invoke` (see @slates/provider-handler). Only `type: 'url'` attachments
|
|
108
|
-
* carry
|
|
124
|
+
* carry credentials -- content/upload_reference attachments pass through untouched.
|
|
109
125
|
*/
|
|
110
126
|
export let redactUrlAttachmentSecrets = (
|
|
111
127
|
attachments: SlateAttachment[] | undefined,
|
|
@@ -117,18 +133,15 @@ export let redactUrlAttachmentSecrets = (
|
|
|
117
133
|
|
|
118
134
|
return attachments.map(attachment => {
|
|
119
135
|
if (attachment.content.type !== 'url') return attachment;
|
|
120
|
-
if (!attachment.content.headers && !attachment.content.query) return attachment;
|
|
121
136
|
|
|
137
|
+
let { url, headers, query } = attachment.content;
|
|
122
138
|
return {
|
|
123
139
|
...attachment,
|
|
124
140
|
content: {
|
|
125
141
|
...attachment.content,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
query: attachment.content.query
|
|
130
|
-
? redactor.redactEmbedded(attachment.content.query)
|
|
131
|
-
: undefined
|
|
142
|
+
url: redactor.redactEmbedded(url, isUrlEmbeddedCredential),
|
|
143
|
+
...(headers ? { headers: redactor.redactEmbedded(headers) } : {}),
|
|
144
|
+
...(query ? { query: redactor.redactEmbedded(query) } : {})
|
|
132
145
|
}
|
|
133
146
|
};
|
|
134
147
|
});
|
package/src/auth/types.ts
CHANGED
|
@@ -24,6 +24,10 @@ export type SlateAuthWithOauth<
|
|
|
24
24
|
|
|
25
25
|
adapters?: string[];
|
|
26
26
|
|
|
27
|
+
// Set when the provider issues the same rotating token pair to every
|
|
28
|
+
// connection of one installation, so a refresh must update all of them.
|
|
29
|
+
syncTokensAcrossConnections?: boolean;
|
|
30
|
+
|
|
27
31
|
docs?: SlateAuthDocsReference[];
|
|
28
32
|
|
|
29
33
|
inputSchema?: z.ZodType<InputType>;
|
package/src/axios/trace.test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { AuthConfigSecretRedactor } from '../auth/redact';
|
|
2
3
|
import { __traceInternals } from './trace';
|
|
3
4
|
|
|
4
5
|
let {
|
|
@@ -272,6 +273,26 @@ describe('sanitizeUrl', () => {
|
|
|
272
273
|
expect(out).toContain('expires_in=3600');
|
|
273
274
|
});
|
|
274
275
|
|
|
276
|
+
it('redacts long auth-config secrets embedded in the path', () => {
|
|
277
|
+
let redactor = new AuthConfigSecretRedactor({
|
|
278
|
+
token: '123456:ABCdefGHIjklMNOpqrSTU',
|
|
279
|
+
botId: '123456',
|
|
280
|
+
applicationId: '1503442063478362305'
|
|
281
|
+
});
|
|
282
|
+
expect(
|
|
283
|
+
sanitizeUrl('https://api.telegram.org/bot123456:ABCdefGHIjklMNOpqrSTU/getMe', redactor)
|
|
284
|
+
).toBe('https://api.telegram.org/bot$$MT$secret$authConfig$token$$/getMe');
|
|
285
|
+
expect(sanitizeUrl('https://example.com/bots/123456/info', redactor)).toBe(
|
|
286
|
+
'https://example.com/bots/123456/info'
|
|
287
|
+
);
|
|
288
|
+
expect(
|
|
289
|
+
sanitizeUrl(
|
|
290
|
+
'https://discord.com/api/applications/1503442063478362305/commands',
|
|
291
|
+
redactor
|
|
292
|
+
)
|
|
293
|
+
).toBe('https://discord.com/api/applications/1503442063478362305/commands');
|
|
294
|
+
});
|
|
295
|
+
|
|
275
296
|
it('leaves innocuous URLs unchanged', () => {
|
|
276
297
|
expect(sanitizeUrl('https://example.com/api?page=2&limit=10')).toBe(
|
|
277
298
|
'https://example.com/api?page=2&limit=10'
|
package/src/axios/trace.ts
CHANGED
|
@@ -563,6 +563,10 @@ let redactHashFragment = (hash: string, redactor?: AuthConfigSecretRedactor) =>
|
|
|
563
563
|
return redacted ? `#${redacted}` : '';
|
|
564
564
|
};
|
|
565
565
|
|
|
566
|
+
// Redacts secret-keyed auth values embedded in URL paths (e.g. Telegram's `/bot<token>/...`).
|
|
567
|
+
let isEmbeddedPathSecret = (secret: string, path: string) =>
|
|
568
|
+
secret.length >= 8 && isSecretKeyName(path.split('.').pop() ?? '');
|
|
569
|
+
|
|
566
570
|
let sanitizeUrl = (value: string, redactor?: AuthConfigSecretRedactor) => {
|
|
567
571
|
if (!value) return value;
|
|
568
572
|
|
|
@@ -574,6 +578,8 @@ let sanitizeUrl = (value: string, redactor?: AuthConfigSecretRedactor) => {
|
|
|
574
578
|
url.password = '';
|
|
575
579
|
}
|
|
576
580
|
|
|
581
|
+
if (redactor) url.pathname = redactor.redactEmbedded(url.pathname, isEmbeddedPathSecret);
|
|
582
|
+
|
|
577
583
|
for (let key of Array.from(url.searchParams.keys())) {
|
|
578
584
|
if (isUrlFormSecretKeyName(key)) {
|
|
579
585
|
url.searchParams.set(key, REDACTED_VALUE);
|
|
@@ -590,7 +596,7 @@ let sanitizeUrl = (value: string, redactor?: AuthConfigSecretRedactor) => {
|
|
|
590
596
|
|
|
591
597
|
return decodeRedactedMarker(url.toString());
|
|
592
598
|
} catch {
|
|
593
|
-
let text = redactor ? redactor.
|
|
599
|
+
let text = redactor ? redactor.redactEmbedded(value, isEmbeddedPathSecret) : value;
|
|
594
600
|
return text.replace(
|
|
595
601
|
/([?&]([^=&#]+)=)([^&#]+)/g,
|
|
596
602
|
(_match, prefix: string, key: string, rawValue: string) =>
|
package/src/error/base.ts
CHANGED
package/src/error/declaration.ts
CHANGED
|
@@ -11,7 +11,7 @@ export class SlateDeclarationError extends SlateError {
|
|
|
11
11
|
this.name = 'SlateError.DeclarationError';
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
static is(error: unknown): error is SlateDeclarationError {
|
|
14
|
+
static override is(error: unknown): error is SlateDeclarationError {
|
|
15
15
|
return error instanceof SlateDeclarationError;
|
|
16
16
|
}
|
|
17
17
|
}
|
package/src/error/utils.ts
CHANGED
|
@@ -61,9 +61,13 @@ export let normalizeRetryable = (code: string, retryable?: boolean) => {
|
|
|
61
61
|
);
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
export let getDefaultMessage = (code: string, message?: string) => {
|
|
64
|
+
export let getDefaultMessage = (code: string, message?: string): string => {
|
|
65
65
|
if (message?.trim()) return message;
|
|
66
|
-
return
|
|
66
|
+
return (
|
|
67
|
+
DEFAULT_MESSAGES[code] ??
|
|
68
|
+
DEFAULT_MESSAGES[DEFAULT_CODE] ??
|
|
69
|
+
'An unexpected internal error occurred.'
|
|
70
|
+
);
|
|
67
71
|
};
|
|
68
72
|
|
|
69
73
|
export let cleanRecord = <Value extends Record<string, unknown> | undefined>(value: Value) => {
|