@ganju/utils 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +9 -0
  3. package/README.md +23 -0
  4. package/dist/apiError.d.ts +3 -0
  5. package/dist/apiError.d.ts.map +1 -0
  6. package/dist/apiError.js +36 -0
  7. package/dist/attachment.d.ts +33 -0
  8. package/dist/attachment.d.ts.map +1 -0
  9. package/dist/attachment.js +59 -0
  10. package/dist/base64.d.ts +10 -0
  11. package/dist/base64.d.ts.map +1 -0
  12. package/dist/base64.js +50 -0
  13. package/dist/channelDebounce.d.ts +26 -0
  14. package/dist/channelDebounce.d.ts.map +1 -0
  15. package/dist/channelDebounce.js +35 -0
  16. package/dist/channelNotifier.d.ts +9 -0
  17. package/dist/channelNotifier.d.ts.map +1 -0
  18. package/dist/channelNotifier.js +31 -0
  19. package/dist/chunking.d.ts +28 -0
  20. package/dist/chunking.d.ts.map +1 -0
  21. package/dist/chunking.js +97 -0
  22. package/dist/cliConstants.d.ts +9 -0
  23. package/dist/cliConstants.d.ts.map +1 -0
  24. package/dist/cliConstants.js +47 -0
  25. package/dist/coerce.d.ts +2 -0
  26. package/dist/coerce.d.ts.map +1 -0
  27. package/dist/coerce.js +13 -0
  28. package/dist/constants.d.ts +624 -0
  29. package/dist/constants.d.ts.map +1 -0
  30. package/dist/constants.js +2220 -0
  31. package/dist/crypto.d.ts +14 -0
  32. package/dist/crypto.d.ts.map +1 -0
  33. package/dist/crypto.js +93 -0
  34. package/dist/customCodeProject.d.ts +91 -0
  35. package/dist/customCodeProject.d.ts.map +1 -0
  36. package/dist/customCodeProject.js +154 -0
  37. package/dist/customCodeToken.d.ts +41 -0
  38. package/dist/customCodeToken.d.ts.map +1 -0
  39. package/dist/customCodeToken.js +115 -0
  40. package/dist/deadline.d.ts +6 -0
  41. package/dist/deadline.d.ts.map +1 -0
  42. package/dist/deadline.js +45 -0
  43. package/dist/discordSend.d.ts +25 -0
  44. package/dist/discordSend.d.ts.map +1 -0
  45. package/dist/discordSend.js +8 -0
  46. package/dist/embeddable.d.ts +2 -0
  47. package/dist/embeddable.d.ts.map +1 -0
  48. package/dist/embeddable.js +6 -0
  49. package/dist/exposedResource.d.ts +6 -0
  50. package/dist/exposedResource.d.ts.map +1 -0
  51. package/dist/exposedResource.js +18 -0
  52. package/dist/extractedDocument.d.ts +70 -0
  53. package/dist/extractedDocument.d.ts.map +1 -0
  54. package/dist/extractedDocument.js +2 -0
  55. package/dist/fetcher.d.ts +8 -0
  56. package/dist/fetcher.d.ts.map +1 -0
  57. package/dist/fetcher.js +68 -0
  58. package/dist/formatFilename.d.ts +2 -0
  59. package/dist/formatFilename.d.ts.map +1 -0
  60. package/dist/formatFilename.js +19 -0
  61. package/dist/formatRelative.d.ts +12 -0
  62. package/dist/formatRelative.d.ts.map +1 -0
  63. package/dist/formatRelative.js +28 -0
  64. package/dist/formatRelativeTime.d.ts +2 -0
  65. package/dist/formatRelativeTime.d.ts.map +1 -0
  66. package/dist/formatRelativeTime.js +49 -0
  67. package/dist/getEnv.d.ts +5 -0
  68. package/dist/getEnv.d.ts.map +1 -0
  69. package/dist/getEnv.js +11 -0
  70. package/dist/gmailSend.d.ts +24 -0
  71. package/dist/gmailSend.d.ts.map +1 -0
  72. package/dist/gmailSend.js +9 -0
  73. package/dist/index.d.ts +2839 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +155 -0
  76. package/dist/jsonSchemaToZodShape.d.ts +38 -0
  77. package/dist/jsonSchemaToZodShape.d.ts.map +1 -0
  78. package/dist/jsonSchemaToZodShape.js +117 -0
  79. package/dist/l2Normalize.d.ts +2 -0
  80. package/dist/l2Normalize.d.ts.map +1 -0
  81. package/dist/l2Normalize.js +25 -0
  82. package/dist/languageCookieDomain.d.ts +21 -0
  83. package/dist/languageCookieDomain.d.ts.map +1 -0
  84. package/dist/languageCookieDomain.js +39 -0
  85. package/dist/localizeZodIssue.d.ts +43 -0
  86. package/dist/localizeZodIssue.d.ts.map +1 -0
  87. package/dist/localizeZodIssue.js +90 -0
  88. package/dist/mailHeaders.d.ts +4 -0
  89. package/dist/mailHeaders.d.ts.map +1 -0
  90. package/dist/mailHeaders.js +11 -0
  91. package/dist/mcpProxy.d.ts +2 -0
  92. package/dist/mcpProxy.d.ts.map +1 -0
  93. package/dist/mcpProxy.js +21 -0
  94. package/dist/mimeMessage.d.ts +21 -0
  95. package/dist/mimeMessage.d.ts.map +1 -0
  96. package/dist/mimeMessage.js +58 -0
  97. package/dist/oauth.d.ts +21 -0
  98. package/dist/oauth.d.ts.map +1 -0
  99. package/dist/oauth.js +75 -0
  100. package/dist/oauthProviders.d.ts +12 -0
  101. package/dist/oauthProviders.d.ts.map +1 -0
  102. package/dist/oauthProviders.js +99 -0
  103. package/dist/outlookSend.d.ts +19 -0
  104. package/dist/outlookSend.d.ts.map +1 -0
  105. package/dist/outlookSend.js +9 -0
  106. package/dist/parseHttpError.d.ts +2 -0
  107. package/dist/parseHttpError.d.ts.map +1 -0
  108. package/dist/parseHttpError.js +23 -0
  109. package/dist/planLimitError.d.ts +18 -0
  110. package/dist/planLimitError.d.ts.map +1 -0
  111. package/dist/planLimitError.js +35 -0
  112. package/dist/processQueueBatch.d.ts +17 -0
  113. package/dist/processQueueBatch.d.ts.map +1 -0
  114. package/dist/processQueueBatch.js +32 -0
  115. package/dist/reservedToolName.d.ts +16 -0
  116. package/dist/reservedToolName.d.ts.map +1 -0
  117. package/dist/reservedToolName.js +25 -0
  118. package/dist/resourceUri.d.ts +2 -0
  119. package/dist/resourceUri.d.ts.map +1 -0
  120. package/dist/resourceUri.js +19 -0
  121. package/dist/retry.d.ts +10 -0
  122. package/dist/retry.d.ts.map +1 -0
  123. package/dist/retry.js +37 -0
  124. package/dist/sanitize.d.ts +7 -0
  125. package/dist/sanitize.d.ts.map +1 -0
  126. package/dist/sanitize.js +69 -0
  127. package/dist/schema.d.ts +2175 -0
  128. package/dist/schema.d.ts.map +1 -0
  129. package/dist/schema.js +1382 -0
  130. package/dist/sdkConstants.d.ts +15 -0
  131. package/dist/sdkConstants.d.ts.map +1 -0
  132. package/dist/sdkConstants.js +43 -0
  133. package/dist/slackSend.d.ts +38 -0
  134. package/dist/slackSend.d.ts.map +1 -0
  135. package/dist/slackSend.js +14 -0
  136. package/dist/slug.d.ts +5 -0
  137. package/dist/slug.d.ts.map +1 -0
  138. package/dist/slug.js +34 -0
  139. package/dist/slugifyTitle.d.ts +2 -0
  140. package/dist/slugifyTitle.d.ts.map +1 -0
  141. package/dist/slugifyTitle.js +11 -0
  142. package/dist/sources.d.ts +43 -0
  143. package/dist/sources.d.ts.map +1 -0
  144. package/dist/sources.js +73 -0
  145. package/dist/ssrf.d.ts +3 -0
  146. package/dist/ssrf.d.ts.map +1 -0
  147. package/dist/ssrf.js +46 -0
  148. package/dist/tallyUsageKinds.d.ts +9 -0
  149. package/dist/tallyUsageKinds.d.ts.map +1 -0
  150. package/dist/tallyUsageKinds.js +20 -0
  151. package/dist/telegramSend.d.ts +28 -0
  152. package/dist/telegramSend.d.ts.map +1 -0
  153. package/dist/telegramSend.js +9 -0
  154. package/dist/toolCatalog.d.ts +452 -0
  155. package/dist/toolCatalog.d.ts.map +1 -0
  156. package/dist/toolCatalog.js +552 -0
  157. package/dist/validateMessageVariables.d.ts +7 -0
  158. package/dist/validateMessageVariables.d.ts.map +1 -0
  159. package/dist/validateMessageVariables.js +16 -0
  160. package/dist/vendorError.d.ts +2 -0
  161. package/dist/vendorError.d.ts.map +1 -0
  162. package/dist/vendorError.js +25 -0
  163. package/dist/whatsappSend.d.ts +31 -0
  164. package/dist/whatsappSend.d.ts.map +1 -0
  165. package/dist/whatsappSend.js +11 -0
  166. package/package.json +76 -0
  167. package/src/apiError.ts +40 -0
  168. package/src/attachment.ts +97 -0
  169. package/src/base64.ts +60 -0
  170. package/src/channelDebounce.ts +76 -0
  171. package/src/channelNotifier.ts +39 -0
  172. package/src/chunking.ts +131 -0
  173. package/src/cliConstants.ts +50 -0
  174. package/src/coerce.ts +9 -0
  175. package/src/constants.ts +2542 -0
  176. package/src/crypto.ts +108 -0
  177. package/src/customCodeProject.ts +182 -0
  178. package/src/customCodeToken.ts +198 -0
  179. package/src/deadline.ts +43 -0
  180. package/src/discordSend.ts +41 -0
  181. package/src/embeddable.ts +4 -0
  182. package/src/exposedResource.ts +40 -0
  183. package/src/extractedDocument.ts +62 -0
  184. package/src/fetcher.ts +82 -0
  185. package/src/formatFilename.ts +19 -0
  186. package/src/formatRelative.ts +36 -0
  187. package/src/formatRelativeTime.ts +45 -0
  188. package/src/getEnv.ts +13 -0
  189. package/src/gmailSend.ts +34 -0
  190. package/src/index.ts +397 -0
  191. package/src/jsonSchemaToZodShape.ts +111 -0
  192. package/src/l2Normalize.ts +19 -0
  193. package/src/languageCookieDomain.ts +37 -0
  194. package/src/localizeZodIssue.ts +124 -0
  195. package/src/mailHeaders.ts +12 -0
  196. package/src/mcpProxy.ts +20 -0
  197. package/src/mimeMessage.ts +82 -0
  198. package/src/oauth.ts +103 -0
  199. package/src/oauthProviders.ts +118 -0
  200. package/src/outlookSend.ts +44 -0
  201. package/src/parseHttpError.ts +16 -0
  202. package/src/planLimitError.ts +50 -0
  203. package/src/processQueueBatch.ts +46 -0
  204. package/src/reservedToolName.ts +27 -0
  205. package/src/resourceUri.ts +17 -0
  206. package/src/retry.ts +43 -0
  207. package/src/sanitize.ts +67 -0
  208. package/src/schema.ts +1624 -0
  209. package/src/sdkConstants.ts +44 -0
  210. package/src/slackSend.ts +65 -0
  211. package/src/slug.ts +37 -0
  212. package/src/slugifyTitle.ts +8 -0
  213. package/src/sources.ts +117 -0
  214. package/src/ssrf.ts +34 -0
  215. package/src/tallyUsageKinds.ts +20 -0
  216. package/src/telegramSend.ts +39 -0
  217. package/src/toolCatalog.ts +635 -0
  218. package/src/validateMessageVariables.ts +18 -0
  219. package/src/vendorError.ts +19 -0
  220. package/src/whatsappSend.ts +47 -0
package/src/fetcher.ts ADDED
@@ -0,0 +1,82 @@
1
+ import { GetServerSidePropsContext } from 'next';
2
+
3
+ export interface IFetcherProps {
4
+ url: string;
5
+ config?: RequestInit;
6
+ ssrContext?: GetServerSidePropsContext;
7
+ }
8
+
9
+ /**
10
+ * The language the API should answer in.
11
+ *
12
+ * Not the browser's `Accept-Language`: someone in Bogotá running Chrome in
13
+ * English, or someone who picked a language in the switcher, would have the
14
+ * header disagree with the page they are looking at. This sends what the app is
15
+ * actually rendering, from the one place that always knows.
16
+ *
17
+ * `Accept-Language` is the right header for it and is CORS-safelisted, so
18
+ * cross-origin calls to the API pick up no preflight for carrying it.
19
+ */
20
+ const requestLanguage = (ssrContext?: GetServerSidePropsContext) => {
21
+ // On the server, the locale Next resolved for this request.
22
+ if (ssrContext?.locale) return ssrContext.locale;
23
+ // In the browser, `_document.tsx` sets `<html lang>` from that same locale,
24
+ // so it is guaranteed to match what the reader is looking at.
25
+ if (typeof document !== 'undefined') {
26
+ return document.documentElement.lang || undefined;
27
+ }
28
+ return undefined;
29
+ };
30
+
31
+ /** `HeadersInit` in any of its three shapes, flattened so it can be merged. */
32
+ const toRecord = (init?: HeadersInit): Record<string, string> => {
33
+ if (!init) return {};
34
+ const entries =
35
+ typeof Headers !== 'undefined' && init instanceof Headers
36
+ ? Array.from(init.entries())
37
+ : Array.isArray(init)
38
+ ? init
39
+ : Object.entries(init);
40
+ const record: Record<string, string> = {};
41
+ for (const [key, value] of entries) record[key] = value;
42
+ return record;
43
+ };
44
+
45
+ export const fetcher = async (props: IFetcherProps) => {
46
+ const { url, config: fetchConfig, ssrContext } = props;
47
+
48
+ const isFormData =
49
+ typeof FormData !== 'undefined' && fetchConfig?.body instanceof FormData;
50
+
51
+ const language = requestLanguage(ssrContext);
52
+
53
+ // FormData sets its own Content-Type, boundary included — naming it here
54
+ // would corrupt the body.
55
+ const headers: Record<string, string> = isFormData
56
+ ? {}
57
+ : { 'Content-Type': 'application/json' };
58
+
59
+ if (language) {
60
+ headers['Accept-Language'] = language;
61
+ }
62
+
63
+ const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}${url}`, {
64
+ ...fetchConfig,
65
+ // Merged rather than overwritten. Spreading `fetchConfig` last used to
66
+ // replace this object wholesale, so every SSR call that forwards a `cookie`
67
+ // header silently dropped the ones set here.
68
+ headers: { ...headers, ...toRecord(fetchConfig?.headers) }
69
+ });
70
+
71
+ if (ssrContext) {
72
+ const cookie = response.headers.get('set-cookie');
73
+
74
+ if (cookie) {
75
+ ssrContext.res.setHeader('Set-Cookie', cookie);
76
+ }
77
+ }
78
+
79
+ const json = await response.json();
80
+
81
+ return json;
82
+ };
@@ -0,0 +1,19 @@
1
+ const cleanFilenamePart = (s: string): string =>
2
+ s
3
+ .toLowerCase()
4
+ .replace(/[^a-z0-9]+/g, '-')
5
+ .replace(/^-+|-+$/g, '');
6
+
7
+ export const formatFilename = (filename: string): string => {
8
+ const lastDot = filename.lastIndexOf('.');
9
+ // lastDot > 0 skips dotfiles like ".gitignore"; the upper bound skips trailing-dot files like "foo."
10
+ const hasExtension = lastDot > 0 && lastDot < filename.length - 1;
11
+ const basename = hasExtension ? filename.slice(0, lastDot) : filename;
12
+ const extension = hasExtension ? filename.slice(lastDot + 1) : '';
13
+
14
+ const timestamp = Date.now();
15
+ const randomString = Math.random().toString(36).slice(2, 7);
16
+ const stem = cleanFilenamePart(`${basename}-${timestamp}-${randomString}`);
17
+
18
+ return extension ? `${stem}.${cleanFilenamePart(extension)}` : stem;
19
+ };
@@ -0,0 +1,36 @@
1
+ import dayjs from 'dayjs';
2
+ import relativeTime from 'dayjs/plugin/relativeTime';
3
+ import 'dayjs/locale/es';
4
+
5
+ dayjs.extend(relativeTime);
6
+
7
+ export interface FormatRelativeOptions {
8
+ /**
9
+ * BCP-47 tag of the language to answer in — `t.locale` in the dashboard.
10
+ * Anything that is not Spanish falls through to English.
11
+ */
12
+ locale?: string;
13
+ /** Rendered when there is no date to describe. Copy, so callers translate it. */
14
+ fallback?: string;
15
+ }
16
+
17
+ /**
18
+ * dayjs ships one file per language and matches on its own short names, not on
19
+ * BCP-47 tags: `es-CO` is not a locale it knows, `es` is.
20
+ */
21
+ const dayjsLocale = (locale?: string): string =>
22
+ locale?.startsWith('es') ? 'es' : 'en';
23
+
24
+ export const formatRelative = (
25
+ value: string | number | Date | null | undefined,
26
+ options: FormatRelativeOptions = {}
27
+ ): string => {
28
+ const { locale, fallback = 'Never' } = options;
29
+ if (!value) return fallback;
30
+ const d = dayjs(value);
31
+ if (!d.isValid()) return fallback;
32
+ // Per instance, never `dayjs.locale(…)`: that sets a module-level global, and
33
+ // a Workers isolate serves requests of mixed languages concurrently — the same
34
+ // reason `localizeZodIssue` refuses `z.config()`.
35
+ return d.locale(dayjsLocale(locale)).fromNow();
36
+ };
@@ -0,0 +1,45 @@
1
+ // Compact relative time — "5m ago", "3h ago", "2d ago", then falls back to a
2
+ // locale date once older than a week.
3
+ //
4
+ // The wording comes from `Intl.RelativeTimeFormat` in its narrow style, which
5
+ // renders exactly the shape the dashboard already used in English and gives
6
+ // Spanish "hace 5 min" for free. Nothing here is translatable copy.
7
+
8
+ const DEFAULT_LOCALE = 'en-US';
9
+
10
+ // The constructor is the expensive part and this runs inside lists, so build one
11
+ // per locale and keep it. `auto` lets the zero case read as "now" / "ahora"
12
+ // rather than "in 0 seconds".
13
+ const formatters = new Map<string, Intl.RelativeTimeFormat>();
14
+
15
+ const relativeFormat = (locale: string): Intl.RelativeTimeFormat => {
16
+ const hit = formatters.get(locale);
17
+ if (hit) return hit;
18
+ const made = new Intl.RelativeTimeFormat(locale, {
19
+ style: 'narrow',
20
+ numeric: 'auto'
21
+ });
22
+ formatters.set(locale, made);
23
+ return made;
24
+ };
25
+
26
+ export const formatRelativeTime = (
27
+ iso?: string | null,
28
+ locale: string = DEFAULT_LOCALE
29
+ ): string => {
30
+ if (!iso) return '';
31
+ const date = new Date(iso);
32
+ if (Number.isNaN(date.getTime())) return '';
33
+ const diff = Date.now() - date.getTime();
34
+ const minute = 60_000;
35
+ const hour = 60 * minute;
36
+ const day = 24 * hour;
37
+ const rtf = relativeFormat(locale);
38
+ // A future timestamp lands here too, and reads as "now" rather than a
39
+ // negative age — same as before.
40
+ if (diff < minute) return rtf.format(0, 'second');
41
+ if (diff < hour) return rtf.format(-Math.floor(diff / minute), 'minute');
42
+ if (diff < day) return rtf.format(-Math.floor(diff / hour), 'hour');
43
+ if (diff < 7 * day) return rtf.format(-Math.floor(diff / day), 'day');
44
+ return date.toLocaleDateString(locale);
45
+ };
package/src/getEnv.ts ADDED
@@ -0,0 +1,13 @@
1
+ export interface EnvSource {
2
+ env?: Record<string, unknown> | unknown;
3
+ }
4
+
5
+ export const getEnv = (
6
+ source: EnvSource,
7
+ key: string
8
+ ): string | undefined => {
9
+ const env = (source.env as Record<string, unknown> | undefined) || undefined;
10
+ const value = env?.[key];
11
+ if (typeof value === 'string') return value;
12
+ return process.env[key];
13
+ };
@@ -0,0 +1,34 @@
1
+ // Wire protocol shared between the worker (which constructs the request) and
2
+ // the resource-handler container (which parses it and calls the Gmail API).
3
+ //
4
+ // The worker sends a multipart/form-data POST with one `metadata` field (JSON
5
+ // matching GmailSendRequest) and zero-or-more `attachment` fields (binary
6
+ // files). Encoding the multipart MIME body and base64-ing attachments happens
7
+ // in the container, where memory isn't capped at 128MB.
8
+
9
+ export type GmailOperation =
10
+ | 'send-email'
11
+ | 'reply-email'
12
+ | 'create-draft'
13
+ | 'update-draft';
14
+
15
+ export interface GmailSendRequest {
16
+ accessToken: string;
17
+ operation: GmailOperation;
18
+ to: string;
19
+ body: string;
20
+ subject?: string;
21
+ cc?: string;
22
+ bcc?: string;
23
+ contentType?: 'text/html' | 'text/plain';
24
+ inReplyTo?: string;
25
+ references?: string;
26
+ threadId?: string;
27
+ draftId?: string;
28
+ }
29
+
30
+ export interface GmailSendResponse {
31
+ id: string;
32
+ threadId?: string;
33
+ message?: { id: string; threadId?: string };
34
+ }
package/src/index.ts ADDED
@@ -0,0 +1,397 @@
1
+ import { Schema } from './schema';
2
+ import type {
3
+ HttpEndpointToolConfig,
4
+ McpProxyToolConfig,
5
+ McpProxyDiscoveredTool,
6
+ McpProxyDiscoveredResource,
7
+ McpProxyDiscoveredPrompt,
8
+ McpProxyDiscovery,
9
+ CustomCodeToolConfig,
10
+ CustomCodeToolManifest,
11
+ CustomCodeManifest,
12
+ CustomCodeSendFile,
13
+ CustomCodeCreateResource
14
+ } from './schema';
15
+ import { getEnv } from './getEnv';
16
+ import type { EnvSource } from './getEnv';
17
+ import type { CalendarConfigField } from './constants';
18
+ import { fetcher } from './fetcher';
19
+ import { constants } from './constants';
20
+ import {
21
+ generateRandomSlug,
22
+ generateRandomToken,
23
+ isReservedSlug,
24
+ isValidSlugFormat
25
+ } from './slug';
26
+ import { isReservedToolName } from './reservedToolName';
27
+ import {
28
+ encryptString,
29
+ decryptString,
30
+ getCredentialEncryptionKey,
31
+ sha256Hex,
32
+ sha256Base64Url,
33
+ hmacSha256Hex,
34
+ timingSafeEqual
35
+ } from './crypto';
36
+ import {
37
+ bytesToBase64,
38
+ base64ToBytes,
39
+ hexToBytes,
40
+ utf8ToBase64,
41
+ base64ToUtf8,
42
+ toBase64Url,
43
+ fromBase64Url,
44
+ utf8ToBase64Url,
45
+ base64UrlToUtf8
46
+ } from './base64';
47
+ import {
48
+ sanitizeMailHeader,
49
+ encodeRfc2047,
50
+ formatMailHeader
51
+ } from './mailHeaders';
52
+ import {
53
+ buildMimeMessage,
54
+ sanitizeFilename,
55
+ formatFilenameHeader,
56
+ chunkBase64
57
+ } from './mimeMessage';
58
+ import type { MimeAttachment, MimeMessageInput } from './mimeMessage';
59
+ import type {
60
+ GmailOperation,
61
+ GmailSendRequest,
62
+ GmailSendResponse
63
+ } from './gmailSend';
64
+ import type {
65
+ TelegramSendRequest,
66
+ TelegramSendResponse,
67
+ TelegramSendRemoteResourceRequest
68
+ } from './telegramSend';
69
+ import type {
70
+ OutlookOperation,
71
+ OutlookSendRequest,
72
+ OutlookSendResponse
73
+ } from './outlookSend';
74
+ import type {
75
+ SlackOperation,
76
+ SlackSendRequest,
77
+ SlackSendResponse,
78
+ SlackSendRemoteResourceRequest
79
+ } from './slackSend';
80
+ import type {
81
+ DiscordSendRequest,
82
+ DiscordSendResponse,
83
+ DiscordSendRemoteResourceRequest
84
+ } from './discordSend';
85
+ import type {
86
+ WhatsappSendRequest,
87
+ WhatsappSendResponse,
88
+ WhatsappSendRemoteResourceRequest
89
+ } from './whatsappSend';
90
+ import { parseHttpErrorMessage } from './parseHttpError';
91
+ import { isApiError, getApiErrorMessage } from './apiError';
92
+ import { toStringArray } from './coerce';
93
+ import { validateMessageVariables } from './validateMessageVariables';
94
+ import {
95
+ JsonSchema,
96
+ jsonSchemaToZodShape,
97
+ validateAgainstJsonSchema
98
+ } from './jsonSchemaToZodShape';
99
+ import type { SchemaViolation } from './jsonSchemaToZodShape';
100
+ import { buildProxyToolName } from './mcpProxy';
101
+ import {
102
+ mintCustomCodeToken,
103
+ verifyCustomCodeToken,
104
+ customCodeScriptName,
105
+ customCodePreviewScriptName
106
+ } from './customCodeToken';
107
+ import type { CustomCodeTokenPayload } from './customCodeToken';
108
+ import { oauthProviders } from './oauthProviders';
109
+ import type { OAuthProviderConfig } from './oauthProviders';
110
+ import { resolveAttachment } from './attachment';
111
+ import { isExposedResource } from './exposedResource';
112
+ import type { ExposableResource } from './exposedResource';
113
+ import { describeVendorError } from './vendorError';
114
+ import { withDeadline, isDeadlineError } from './deadline';
115
+ import {
116
+ CUSTOM_CODE_PROJECT_MARKER,
117
+ encodeProject,
118
+ decodeProject,
119
+ validateProjectFiles,
120
+ validateProjectPath,
121
+ projectPathIssue
122
+ } from './customCodeProject';
123
+ import type { CustomCodeProject, ProjectPathIssue } from './customCodeProject';
124
+ import type {
125
+ AttachmentResource,
126
+ ResolvedAttachment,
127
+ ResolveAttachmentResult
128
+ } from './attachment';
129
+ import { ipv4InPrivateRange, isBlockedHost } from './ssrf';
130
+ import { formatRelative } from './formatRelative';
131
+ import { formatRelativeTime } from './formatRelativeTime';
132
+ import { languageCookieDomain } from './languageCookieDomain';
133
+ import { localizeZodIssue, languageFromHeader } from './localizeZodIssue';
134
+ import { slugifyTitle } from './slugifyTitle';
135
+ import { resourceUriFromTitle } from './resourceUri';
136
+ import {
137
+ TOOL_CATALOG,
138
+ TOOL_KEYS,
139
+ describeCatalogTool,
140
+ findCatalogGroup,
141
+ findCatalogTool,
142
+ isToolKey
143
+ } from './toolCatalog';
144
+ import type {
145
+ CatalogGroup,
146
+ CatalogTool,
147
+ CatalogToolDescriptor,
148
+ ToolGroupKey,
149
+ ToolKey
150
+ } from './toolCatalog';
151
+ import { tallyUsageKinds } from './tallyUsageKinds';
152
+ import { formatFilename } from './formatFilename';
153
+ import {
154
+ decodeEntities,
155
+ escapeHtml,
156
+ parseOpenXmlProps,
157
+ stripBase64Images,
158
+ sanitizeMetadataString,
159
+ serializeMetadataValue
160
+ } from './sanitize';
161
+ import {
162
+ chunkText,
163
+ splitRecursive,
164
+ buildHeader,
165
+ prepareChunks
166
+ } from './chunking';
167
+ import type { Separator, ChunkMetadata, PreparedChunk } from './chunking';
168
+ import { isEmbeddableMimeType } from './embeddable';
169
+ import { l2Normalize } from './l2Normalize';
170
+ import { sleep, isRateLimitError, withRateLimitRetry } from './retry';
171
+ import type { RateLimitRetryOptions } from './retry';
172
+ import { processQueueBatch } from './processQueueBatch';
173
+ import type {
174
+ QueueBatchLike,
175
+ QueueMessageLike,
176
+ ProcessQueueBatchHandlers
177
+ } from './processQueueBatch';
178
+ import type {
179
+ ExtractedDocument,
180
+ ExtractedDocumentMetadata,
181
+ ExtractedDocumentSource
182
+ } from './extractedDocument';
183
+ import { getToolStatusMessage } from './channelNotifier';
184
+ import type { ChannelNotifier, ToolStatusEvent } from './channelNotifier';
185
+ import {
186
+ resolveDebounceMs,
187
+ channelBufferKey,
188
+ joinBufferedMessages
189
+ } from './channelDebounce';
190
+ import type {
191
+ BufferedChannelMessage,
192
+ ChannelBufferEnvelope,
193
+ ChannelBufferFlush
194
+ } from './channelDebounce';
195
+ import {
196
+ isResourceSourceEnabled,
197
+ isDownloadableSource,
198
+ safeHostname,
199
+ buildResourceDownloadUrl,
200
+ formatSourcesAsMarkdown,
201
+ formatSourcesAsButtons
202
+ } from './sources';
203
+ import type { Source, ResourceUrlContext, SourceButton } from './sources';
204
+ import {
205
+ refreshOAuthToken,
206
+ OAuthReauthRequiredError,
207
+ buildReauthMetadata,
208
+ clearReauthMetadata,
209
+ isCredentialNeedingReauth
210
+ } from './oauth';
211
+ import type { RefreshOAuthTokenInput, RefreshedOAuthToken } from './oauth';
212
+ import { PlanLimitError, isPlanLimitError } from './planLimitError';
213
+ import type { PlanLimitDetails } from './planLimitError';
214
+ import type { PlanLimits } from './constants';
215
+
216
+ export const utils = {
217
+ Schema,
218
+ getEnv,
219
+ fetcher,
220
+ constants,
221
+ generateRandomSlug,
222
+ generateRandomToken,
223
+ isReservedSlug,
224
+ isValidSlugFormat,
225
+ isReservedToolName,
226
+ encryptString,
227
+ decryptString,
228
+ getCredentialEncryptionKey,
229
+ sha256Hex,
230
+ sha256Base64Url,
231
+ hmacSha256Hex,
232
+ timingSafeEqual,
233
+ bytesToBase64,
234
+ base64ToBytes,
235
+ hexToBytes,
236
+ utf8ToBase64,
237
+ base64ToUtf8,
238
+ toBase64Url,
239
+ fromBase64Url,
240
+ utf8ToBase64Url,
241
+ base64UrlToUtf8,
242
+ sanitizeMailHeader,
243
+ encodeRfc2047,
244
+ formatMailHeader,
245
+ buildMimeMessage,
246
+ sanitizeFilename,
247
+ formatFilenameHeader,
248
+ chunkBase64,
249
+ parseHttpErrorMessage,
250
+ isApiError,
251
+ getApiErrorMessage,
252
+ toStringArray,
253
+ jsonSchemaToZodShape,
254
+ validateAgainstJsonSchema,
255
+ buildProxyToolName,
256
+ mintCustomCodeToken,
257
+ verifyCustomCodeToken,
258
+ customCodeScriptName,
259
+ customCodePreviewScriptName,
260
+ oauthProviders,
261
+ resolveAttachment,
262
+ isExposedResource,
263
+ describeVendorError,
264
+ withDeadline,
265
+ isDeadlineError,
266
+ CUSTOM_CODE_PROJECT_MARKER,
267
+ encodeProject,
268
+ decodeProject,
269
+ validateProjectFiles,
270
+ validateProjectPath,
271
+ projectPathIssue,
272
+ ipv4InPrivateRange,
273
+ isBlockedHost,
274
+ validateMessageVariables,
275
+ formatRelative,
276
+ formatRelativeTime,
277
+ languageCookieDomain,
278
+ localizeZodIssue,
279
+ languageFromHeader,
280
+ slugifyTitle,
281
+ resourceUriFromTitle,
282
+ TOOL_CATALOG,
283
+ TOOL_KEYS,
284
+ describeCatalogTool,
285
+ findCatalogGroup,
286
+ findCatalogTool,
287
+ isToolKey,
288
+ tallyUsageKinds,
289
+ formatFilename,
290
+ decodeEntities,
291
+ escapeHtml,
292
+ parseOpenXmlProps,
293
+ stripBase64Images,
294
+ sanitizeMetadataString,
295
+ serializeMetadataValue,
296
+ chunkText,
297
+ splitRecursive,
298
+ buildHeader,
299
+ prepareChunks,
300
+ isEmbeddableMimeType,
301
+ l2Normalize,
302
+ sleep,
303
+ isRateLimitError,
304
+ withRateLimitRetry,
305
+ processQueueBatch,
306
+ getToolStatusMessage,
307
+ resolveDebounceMs,
308
+ channelBufferKey,
309
+ joinBufferedMessages,
310
+ isResourceSourceEnabled,
311
+ isDownloadableSource,
312
+ safeHostname,
313
+ buildResourceDownloadUrl,
314
+ formatSourcesAsMarkdown,
315
+ formatSourcesAsButtons,
316
+ refreshOAuthToken,
317
+ OAuthReauthRequiredError,
318
+ buildReauthMetadata,
319
+ clearReauthMetadata,
320
+ isCredentialNeedingReauth,
321
+ PlanLimitError,
322
+ isPlanLimitError
323
+ };
324
+
325
+ export type {
326
+ CustomCodeProject,
327
+ ProjectPathIssue,
328
+ CatalogGroup,
329
+ CatalogTool,
330
+ CatalogToolDescriptor,
331
+ ToolGroupKey,
332
+ ToolKey,
333
+ CalendarConfigField,
334
+ JsonSchema,
335
+ SchemaViolation,
336
+ MimeAttachment,
337
+ MimeMessageInput,
338
+ GmailOperation,
339
+ GmailSendRequest,
340
+ GmailSendResponse,
341
+ OutlookOperation,
342
+ OutlookSendRequest,
343
+ OutlookSendResponse,
344
+ SlackOperation,
345
+ SlackSendRequest,
346
+ SlackSendResponse,
347
+ SlackSendRemoteResourceRequest,
348
+ TelegramSendRequest,
349
+ TelegramSendResponse,
350
+ TelegramSendRemoteResourceRequest,
351
+ DiscordSendRequest,
352
+ DiscordSendResponse,
353
+ DiscordSendRemoteResourceRequest,
354
+ WhatsappSendRequest,
355
+ WhatsappSendResponse,
356
+ WhatsappSendRemoteResourceRequest,
357
+ EnvSource,
358
+ Separator,
359
+ ChunkMetadata,
360
+ PreparedChunk,
361
+ ExtractedDocument,
362
+ ExtractedDocumentMetadata,
363
+ ExtractedDocumentSource,
364
+ RateLimitRetryOptions,
365
+ QueueBatchLike,
366
+ QueueMessageLike,
367
+ ProcessQueueBatchHandlers,
368
+ ChannelNotifier,
369
+ ToolStatusEvent,
370
+ BufferedChannelMessage,
371
+ ChannelBufferEnvelope,
372
+ ChannelBufferFlush,
373
+ Source,
374
+ ResourceUrlContext,
375
+ SourceButton,
376
+ RefreshOAuthTokenInput,
377
+ RefreshedOAuthToken,
378
+ HttpEndpointToolConfig,
379
+ McpProxyToolConfig,
380
+ McpProxyDiscoveredTool,
381
+ McpProxyDiscoveredResource,
382
+ McpProxyDiscoveredPrompt,
383
+ McpProxyDiscovery,
384
+ CustomCodeToolConfig,
385
+ CustomCodeToolManifest,
386
+ CustomCodeManifest,
387
+ CustomCodeSendFile,
388
+ CustomCodeCreateResource,
389
+ CustomCodeTokenPayload,
390
+ OAuthProviderConfig,
391
+ AttachmentResource,
392
+ ResolvedAttachment,
393
+ ResolveAttachmentResult,
394
+ ExposableResource,
395
+ PlanLimitDetails,
396
+ PlanLimits
397
+ };