@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
@@ -0,0 +1,14 @@
1
+ import { Context } from 'hono';
2
+ export declare const getCredentialEncryptionKey: (c: Context) => string;
3
+ export declare const encryptString: (plaintext: string, rawKey: string) => string;
4
+ export declare const decryptString: (value: string, rawKey: string) => string;
5
+ export declare const sha256Hex: (input: string) => Promise<string>;
6
+ /**
7
+ * SHA-256 as unpadded base64url — the format `@better-auth/oauth-provider`
8
+ * stores hashed client secrets in. Anything comparing against a stored
9
+ * `oauth_client.client_secret` has to hash the candidate exactly this way.
10
+ */
11
+ export declare const sha256Base64Url: (input: string) => Promise<string>;
12
+ export declare const hmacSha256Hex: (key: string, message: string) => Promise<string>;
13
+ export declare const timingSafeEqual: (a: string, b: string) => boolean;
14
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAU/B,eAAO,MAAM,0BAA0B,GAAI,GAAG,OAAO,WAMpD,CAAC;AAYF,eAAO,MAAM,aAAa,GAAI,WAAW,MAAM,EAAE,QAAQ,MAAM,WAS9D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,WAS1D,CAAC;AAEF,eAAO,MAAM,SAAS,GAAU,OAAO,MAAM,oBAW5C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAU,OAAO,MAAM,oBASlD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,KAAK,MAAM,EAAE,SAAS,MAAM,oBAmB/D,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,YAOnD,CAAC"}
package/dist/crypto.js ADDED
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.timingSafeEqual = exports.hmacSha256Hex = exports.sha256Base64Url = exports.sha256Hex = exports.decryptString = exports.encryptString = exports.getCredentialEncryptionKey = void 0;
4
+ const chacha_js_1 = require("@noble/ciphers/chacha.js");
5
+ const getEnv_1 = require("./getEnv");
6
+ const base64_1 = require("./base64");
7
+ const PREFIX = 'enc:v1:';
8
+ const NONCE_BYTES = 24;
9
+ const KEY_BYTES = 32;
10
+ const KEY_ENV = 'CRYPTO_SECRET';
11
+ const getCredentialEncryptionKey = (c) => {
12
+ const rawKey = (0, getEnv_1.getEnv)(c, KEY_ENV);
13
+ if (!rawKey) {
14
+ throw new Error(`Missing env: ${KEY_ENV}`);
15
+ }
16
+ return rawKey;
17
+ };
18
+ exports.getCredentialEncryptionKey = getCredentialEncryptionKey;
19
+ const loadKey = (rawKey) => {
20
+ const bytes = (0, base64_1.base64ToBytes)(rawKey);
21
+ if (bytes.length !== KEY_BYTES) {
22
+ throw new Error(`CRYPTO_SECRET must decode to ${KEY_BYTES} bytes (got ${bytes.length})`);
23
+ }
24
+ return bytes;
25
+ };
26
+ const encryptString = (plaintext, rawKey) => {
27
+ const key = loadKey(rawKey);
28
+ const nonce = crypto.getRandomValues(new Uint8Array(NONCE_BYTES));
29
+ const cipher = (0, chacha_js_1.xchacha20poly1305)(key, nonce);
30
+ const ciphertext = cipher.encrypt(new TextEncoder().encode(plaintext));
31
+ const bundle = new Uint8Array(nonce.length + ciphertext.length);
32
+ bundle.set(nonce, 0);
33
+ bundle.set(ciphertext, nonce.length);
34
+ return `${PREFIX}${(0, base64_1.bytesToBase64)(bundle)}`;
35
+ };
36
+ exports.encryptString = encryptString;
37
+ const decryptString = (value, rawKey) => {
38
+ if (!value.startsWith(PREFIX))
39
+ return value;
40
+ const bundle = (0, base64_1.base64ToBytes)(value.slice(PREFIX.length));
41
+ const nonce = bundle.slice(0, NONCE_BYTES);
42
+ const ciphertext = bundle.slice(NONCE_BYTES);
43
+ const key = loadKey(rawKey);
44
+ const cipher = (0, chacha_js_1.xchacha20poly1305)(key, nonce);
45
+ const plaintext = cipher.decrypt(ciphertext);
46
+ return new TextDecoder().decode(plaintext);
47
+ };
48
+ exports.decryptString = decryptString;
49
+ const sha256Hex = async (input) => {
50
+ const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));
51
+ const bytes = new Uint8Array(digest);
52
+ let hex = '';
53
+ for (let i = 0; i < bytes.length; i++) {
54
+ hex += bytes[i].toString(16).padStart(2, '0');
55
+ }
56
+ return hex;
57
+ };
58
+ exports.sha256Hex = sha256Hex;
59
+ /**
60
+ * SHA-256 as unpadded base64url — the format `@better-auth/oauth-provider`
61
+ * stores hashed client secrets in. Anything comparing against a stored
62
+ * `oauth_client.client_secret` has to hash the candidate exactly this way.
63
+ */
64
+ const sha256Base64Url = async (input) => {
65
+ const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));
66
+ const bytes = new Uint8Array(digest);
67
+ let binary = '';
68
+ for (let i = 0; i < bytes.length; i++)
69
+ binary += String.fromCharCode(bytes[i]);
70
+ return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
71
+ };
72
+ exports.sha256Base64Url = sha256Base64Url;
73
+ const hmacSha256Hex = async (key, message) => {
74
+ const cryptoKey = await crypto.subtle.importKey('raw', new TextEncoder().encode(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
75
+ const signature = await crypto.subtle.sign('HMAC', cryptoKey, new TextEncoder().encode(message));
76
+ const bytes = new Uint8Array(signature);
77
+ let hex = '';
78
+ for (let i = 0; i < bytes.length; i++) {
79
+ hex += bytes[i].toString(16).padStart(2, '0');
80
+ }
81
+ return hex;
82
+ };
83
+ exports.hmacSha256Hex = hmacSha256Hex;
84
+ const timingSafeEqual = (a, b) => {
85
+ if (a.length !== b.length)
86
+ return false;
87
+ let diff = 0;
88
+ for (let i = 0; i < a.length; i++) {
89
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
90
+ }
91
+ return diff === 0;
92
+ };
93
+ exports.timingSafeEqual = timingSafeEqual;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * A dashboard-authored script is a set of files, not one file.
3
+ *
4
+ * The deploy path already uploads more than one module — the SDK travels beside
5
+ * every script as `ganju-sdk.js` — so the runtime has never been the thing
6
+ * holding this to a single file. What was single was the storage: one R2 object
7
+ * holding one module's text.
8
+ *
9
+ * So the object becomes an envelope. `sourceKind: 'editor'` bytes are JSON of
10
+ * this shape; `'bundle'` bytes stay exactly what the CLI compiled, because a
11
+ * bundle IS one module and wrapping it would mean the stored bytes are no longer
12
+ * the thing that runs. `decodeProject` tells the two apart by reading the marker,
13
+ * which is why there is a marker rather than a bare `{ files }` — arbitrary
14
+ * minified JS never parses as JSON, but a bundle that happens to be a JSON
15
+ * module would, and guessing is not a thing to do with someone's deploy.
16
+ */
17
+ export declare const CUSTOM_CODE_PROJECT_MARKER = "ganjuProject";
18
+ export interface CustomCodeProject {
19
+ [CUSTOM_CODE_PROJECT_MARKER]: 1;
20
+ files: Record<string, string>;
21
+ }
22
+ export declare const encodeProject: (files: Record<string, string>) => string;
23
+ /**
24
+ * Read stored bytes back as a set of files, or `null` when they are a single
25
+ * module — the CLI's bundle, and every editor version written before folders
26
+ * existed.
27
+ */
28
+ export declare const decodeProject: (text: string) => Record<string, string> | null;
29
+ /**
30
+ * Why one path is not a legal file in a script — the rule that refused it, and
31
+ * what it needs to say so.
32
+ *
33
+ * A code rather than a sentence, because there are two readers. The upload path
34
+ * throws it as English, which is what `error_log` has always held; the
35
+ * dashboard's file explorer renders it in whatever language the person is
36
+ * reading, at the keystroke. Returning prose would have forced the explorer to
37
+ * either show English or keep a second copy of these rules — and a second copy
38
+ * is how the two surfaces come to disagree about what a legal name is.
39
+ */
40
+ export type ProjectPathIssue = {
41
+ code: 'required';
42
+ } | {
43
+ code: 'tooLong';
44
+ path: string;
45
+ max: number;
46
+ } | {
47
+ code: 'charset';
48
+ path: string;
49
+ } | {
50
+ code: 'dots';
51
+ path: string;
52
+ } | {
53
+ code: 'extension';
54
+ path: string;
55
+ } | {
56
+ code: 'reserved';
57
+ path: string;
58
+ } | {
59
+ code: 'taken';
60
+ path: string;
61
+ };
62
+ /**
63
+ * Check ONE path against every rule a stored file has to satisfy.
64
+ *
65
+ * Split out of the set-level check below so the dashboard's file explorer can
66
+ * apply the identical rules as someone types a name, rather than letting them
67
+ * finish, click deploy, and read the same sentence back as a 400. There is one
68
+ * definition of what a legal path is, and both surfaces call it.
69
+ *
70
+ * `taken` is the paths already in the project, compared case-insensitively —
71
+ * pass the file being renamed's own path in it and the rename reports a
72
+ * collision with itself, so callers exclude it.
73
+ */
74
+ export declare const projectPathIssue: (path: string, taken?: Iterable<string>) => ProjectPathIssue | null;
75
+ /**
76
+ * The same check, rendered in English — what the upload path throws and what
77
+ * lands in `error_log`. Messages carry a word `matchStatus` recognises, so they
78
+ * land as 400s rather than opaque 500s.
79
+ */
80
+ export declare const validateProjectPath: (path: string, taken?: Iterable<string>) => string | null;
81
+ /**
82
+ * Check a set of files before anything is stored or deployed.
83
+ *
84
+ * Paths are the module names the Workers upload API receives, and a script's
85
+ * imports resolve against them — so a path that escapes the root, collides with
86
+ * the SDK's own module, or arrives twice under different spellings is a deploy
87
+ * that fails in the runtime rather than here. Messages carry a word `matchStatus`
88
+ * recognises, so these land as 400s rather than opaque 500s.
89
+ */
90
+ export declare const validateProjectFiles: (files: Record<string, string>) => void;
91
+ //# sourceMappingURL=customCodeProject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customCodeProject.d.ts","sourceRoot":"","sources":["../src/customCodeProject.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,0BAA0B,iBAAiB,CAAC;AAEzD,MAAM,WAAW,iBAAiB;IAChC,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,MACF,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAiBrE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,GAC3B,MAAM,MAAM,EACZ,QAAO,QAAQ,CAAC,MAAM,CAAM,KAC3B,gBAAgB,GAAG,IA8BrB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,MAAM,MAAM,EACZ,QAAO,QAAQ,CAAC,MAAM,CAAM,KAC3B,MAAM,GAAG,IAoBX,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,IAuBpE,CAAC"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateProjectFiles = exports.validateProjectPath = exports.projectPathIssue = exports.decodeProject = exports.encodeProject = exports.CUSTOM_CODE_PROJECT_MARKER = void 0;
4
+ const constants_1 = require("./constants");
5
+ /**
6
+ * A dashboard-authored script is a set of files, not one file.
7
+ *
8
+ * The deploy path already uploads more than one module — the SDK travels beside
9
+ * every script as `ganju-sdk.js` — so the runtime has never been the thing
10
+ * holding this to a single file. What was single was the storage: one R2 object
11
+ * holding one module's text.
12
+ *
13
+ * So the object becomes an envelope. `sourceKind: 'editor'` bytes are JSON of
14
+ * this shape; `'bundle'` bytes stay exactly what the CLI compiled, because a
15
+ * bundle IS one module and wrapping it would mean the stored bytes are no longer
16
+ * the thing that runs. `decodeProject` tells the two apart by reading the marker,
17
+ * which is why there is a marker rather than a bare `{ files }` — arbitrary
18
+ * minified JS never parses as JSON, but a bundle that happens to be a JSON
19
+ * module would, and guessing is not a thing to do with someone's deploy.
20
+ */
21
+ exports.CUSTOM_CODE_PROJECT_MARKER = 'ganjuProject';
22
+ const encodeProject = (files) => JSON.stringify({ [exports.CUSTOM_CODE_PROJECT_MARKER]: 1, files });
23
+ exports.encodeProject = encodeProject;
24
+ /**
25
+ * Read stored bytes back as a set of files, or `null` when they are a single
26
+ * module — the CLI's bundle, and every editor version written before folders
27
+ * existed.
28
+ */
29
+ const decodeProject = (text) => {
30
+ if (!text.trimStart().startsWith('{'))
31
+ return null;
32
+ let parsed;
33
+ try {
34
+ parsed = JSON.parse(text);
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ if (!parsed || typeof parsed !== 'object')
40
+ return null;
41
+ const envelope = parsed;
42
+ if (envelope[exports.CUSTOM_CODE_PROJECT_MARKER] !== 1)
43
+ return null;
44
+ if (!envelope.files || typeof envelope.files !== 'object')
45
+ return null;
46
+ const files = {};
47
+ for (const [path, content] of Object.entries(envelope.files)) {
48
+ if (typeof content === 'string')
49
+ files[path] = content;
50
+ }
51
+ return files;
52
+ };
53
+ exports.decodeProject = decodeProject;
54
+ /**
55
+ * Check ONE path against every rule a stored file has to satisfy.
56
+ *
57
+ * Split out of the set-level check below so the dashboard's file explorer can
58
+ * apply the identical rules as someone types a name, rather than letting them
59
+ * finish, click deploy, and read the same sentence back as a 400. There is one
60
+ * definition of what a legal path is, and both surfaces call it.
61
+ *
62
+ * `taken` is the paths already in the project, compared case-insensitively —
63
+ * pass the file being renamed's own path in it and the rename reports a
64
+ * collision with itself, so callers exclude it.
65
+ */
66
+ const projectPathIssue = (path, taken = []) => {
67
+ if (!path)
68
+ return { code: 'required' };
69
+ if (path.length > constants_1.constants.CUSTOM_CODE_MAX_FILE_PATH) {
70
+ return {
71
+ code: 'tooLong',
72
+ path,
73
+ max: constants_1.constants.CUSTOM_CODE_MAX_FILE_PATH
74
+ };
75
+ }
76
+ if (!/^[a-zA-Z0-9._-]+(\/[a-zA-Z0-9._-]+)*$/.test(path)) {
77
+ return { code: 'charset', path };
78
+ }
79
+ if (path.split('/').some(segment => segment === '.' || segment === '..')) {
80
+ return { code: 'dots', path };
81
+ }
82
+ if (!path.endsWith('.js')) {
83
+ return { code: 'extension', path };
84
+ }
85
+ if (path === constants_1.constants.CUSTOM_CODE_SDK_MODULE) {
86
+ return { code: 'reserved', path };
87
+ }
88
+ // Case-insensitively, because two files differing only in case are one file
89
+ // on the machine of whoever downloads them next.
90
+ const lower = path.toLowerCase();
91
+ for (const other of taken) {
92
+ if (other.toLowerCase() === lower) {
93
+ return { code: 'taken', path };
94
+ }
95
+ }
96
+ return null;
97
+ };
98
+ exports.projectPathIssue = projectPathIssue;
99
+ /**
100
+ * The same check, rendered in English — what the upload path throws and what
101
+ * lands in `error_log`. Messages carry a word `matchStatus` recognises, so they
102
+ * land as 400s rather than opaque 500s.
103
+ */
104
+ const validateProjectPath = (path, taken = []) => {
105
+ const issue = (0, exports.projectPathIssue)(path, taken);
106
+ if (!issue)
107
+ return null;
108
+ switch (issue.code) {
109
+ case 'required':
110
+ return 'A name is required';
111
+ case 'tooLong':
112
+ return `The path "${issue.path}" exceeds ${issue.max} characters`;
113
+ case 'charset':
114
+ return `Invalid file path "${issue.path}" — letters, digits, dot, dash, underscore and / only, with no leading or trailing slash`;
115
+ case 'dots':
116
+ return `Invalid file path "${issue.path}" — . and .. are not allowed`;
117
+ case 'extension':
118
+ return `Invalid file path "${issue.path}" — every file must end in .js, since it is deployed as a module exactly as written`;
119
+ case 'reserved':
120
+ return `Invalid file path "${issue.path}" — that name belongs to the SDK, which is attached to every deploy`;
121
+ case 'taken':
122
+ return `Invalid file path "${issue.path}" — it is already in use`;
123
+ }
124
+ };
125
+ exports.validateProjectPath = validateProjectPath;
126
+ /**
127
+ * Check a set of files before anything is stored or deployed.
128
+ *
129
+ * Paths are the module names the Workers upload API receives, and a script's
130
+ * imports resolve against them — so a path that escapes the root, collides with
131
+ * the SDK's own module, or arrives twice under different spellings is a deploy
132
+ * that fails in the runtime rather than here. Messages carry a word `matchStatus`
133
+ * recognises, so these land as 400s rather than opaque 500s.
134
+ */
135
+ const validateProjectFiles = (files) => {
136
+ const paths = Object.keys(files);
137
+ if (paths.length === 0) {
138
+ throw new Error('At least one file is required');
139
+ }
140
+ if (paths.length > constants_1.constants.CUSTOM_CODE_MAX_FILES) {
141
+ throw new Error(`The project exceeds the ${constants_1.constants.CUSTOM_CODE_MAX_FILES}-file limit`);
142
+ }
143
+ if (!files[constants_1.constants.CUSTOM_CODE_MAIN_MODULE]) {
144
+ throw new Error(`A file named ${constants_1.constants.CUSTOM_CODE_MAIN_MODULE} is required — it is the module the dispatcher calls`);
145
+ }
146
+ const seen = new Set();
147
+ for (const path of paths) {
148
+ const problem = (0, exports.validateProjectPath)(path, seen);
149
+ if (problem)
150
+ throw new Error(problem);
151
+ seen.add(path.toLowerCase());
152
+ }
153
+ };
154
+ exports.validateProjectFiles = validateProjectFiles;
@@ -0,0 +1,41 @@
1
+ export interface CustomCodeTokenPayload {
2
+ v: string;
3
+ artifactId: string;
4
+ versionId: string;
5
+ iat: number;
6
+ preview?: boolean;
7
+ exp?: number;
8
+ }
9
+ /**
10
+ * Mint a tool token for one artifact + version. Called by the publish pipeline
11
+ * immediately before upload; the result is written as a `secret_text` binding so
12
+ * it never appears in the bundle the user can read back.
13
+ */
14
+ export declare const mintCustomCodeToken: (payload: Omit<CustomCodeTokenPayload, "v" | "iat" | "exp"> & {
15
+ ttlMs?: number;
16
+ }, secret: string, issuedAt?: number) => Promise<string>;
17
+ /**
18
+ * Verify a tool token and return its payload, or null when it is malformed, of
19
+ * an unknown format version, or not signed by this deployment's secret.
20
+ *
21
+ * Returning null rather than throwing keeps the broker's failure path uniform:
22
+ * every rejection is the same 401, so a caller learns nothing about which check
23
+ * failed.
24
+ */
25
+ export declare const verifyCustomCodeToken: (token: string, secret: string, now?: number) => Promise<CustomCodeTokenPayload | null>;
26
+ /**
27
+ * The dispatch-namespace script name for an artifact: `artifact_<id>`.
28
+ *
29
+ * The id, never the slug — slugs are user-editable and a rename would orphan the
30
+ * deployed script while the database still pointed at a live version.
31
+ */
32
+ export declare const customCodeScriptName: (artifactId: string) => string;
33
+ /**
34
+ * The script name a test run deploys into: `artifact_<id>_preview`.
35
+ *
36
+ * A second script rather than a second version of the live one, because a test
37
+ * must not be able to disturb what MCP clients are being served — and the only
38
+ * way to be certain of that is for it to run under a name nothing dispatches to.
39
+ */
40
+ export declare const customCodePreviewScriptName: (artifactId: string) => string;
41
+ //# sourceMappingURL=customCodeToken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customCodeToken.d.ts","sourceRoot":"","sources":["../src/customCodeToken.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,sBAAsB;IAGrC,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IAGnB,SAAS,EAAE,MAAM,CAAC;IAIlB,GAAG,EAAE,MAAM,CAAC;IAOZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA0BD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,SAAS,IAAI,CAAC,sBAAsB,EAAE,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACD,QAAQ,MAAM,EACd,WAAU,MAAmB,KAC5B,OAAO,CAAC,MAAM,CAmBhB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,MAAM,EACb,QAAQ,MAAM,EACd,MAAM,MAAM,KACX,OAAO,CAAC,sBAAsB,GAAG,IAAI,CA+DvC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,YAAY,MAAM,KAAG,MACE,CAAC;AAE7D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,GAAI,YAAY,MAAM,KAAG,MACoB,CAAC"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.customCodePreviewScriptName = exports.customCodeScriptName = exports.verifyCustomCodeToken = exports.mintCustomCodeToken = void 0;
4
+ const base64_1 = require("./base64");
5
+ const constants_1 = require("./constants");
6
+ const encoder = new TextEncoder();
7
+ const importKey = (secret) => crypto.subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']);
8
+ const signPayload = async (encodedPayload, secret) => {
9
+ const key = await importKey(secret);
10
+ const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(encodedPayload));
11
+ return (0, base64_1.toBase64Url)((0, base64_1.bytesToBase64)(new Uint8Array(signature)));
12
+ };
13
+ /**
14
+ * Mint a tool token for one artifact + version. Called by the publish pipeline
15
+ * immediately before upload; the result is written as a `secret_text` binding so
16
+ * it never appears in the bundle the user can read back.
17
+ */
18
+ const mintCustomCodeToken = async (payload, secret, issuedAt = Date.now()) => {
19
+ const body = {
20
+ v: constants_1.constants.CUSTOM_CODE_TOKEN_VERSION,
21
+ artifactId: payload.artifactId,
22
+ versionId: payload.versionId,
23
+ iat: Math.floor(issuedAt / 1000),
24
+ ...(payload.preview ? { preview: true } : {}),
25
+ // Rounded up, not down: `exp` is in seconds, and truncating would make a
26
+ // stated ten-minute lifetime end up to a second early. A ceiling means the
27
+ // TTL is a floor, which is what the caller asked for.
28
+ ...(payload.ttlMs
29
+ ? { exp: Math.ceil((issuedAt + payload.ttlMs) / 1000) }
30
+ : {})
31
+ };
32
+ const encodedPayload = (0, base64_1.toBase64Url)((0, base64_1.bytesToBase64)(encoder.encode(JSON.stringify(body))));
33
+ const signature = await signPayload(encodedPayload, secret);
34
+ return `${encodedPayload}.${signature}`;
35
+ };
36
+ exports.mintCustomCodeToken = mintCustomCodeToken;
37
+ /**
38
+ * Verify a tool token and return its payload, or null when it is malformed, of
39
+ * an unknown format version, or not signed by this deployment's secret.
40
+ *
41
+ * Returning null rather than throwing keeps the broker's failure path uniform:
42
+ * every rejection is the same 401, so a caller learns nothing about which check
43
+ * failed.
44
+ */
45
+ const verifyCustomCodeToken = async (token, secret, now) => {
46
+ const separator = token.lastIndexOf('.');
47
+ if (separator <= 0)
48
+ return null;
49
+ const encodedPayload = token.slice(0, separator);
50
+ const signature = token.slice(separator + 1);
51
+ const key = await importKey(secret);
52
+ let valid;
53
+ try {
54
+ // Copied into a fresh view so its backing store is a plain ArrayBuffer —
55
+ // base64ToBytes is typed against ArrayBufferLike, which subtle.verify's
56
+ // BufferSource parameter does not accept.
57
+ const signatureBytes = new Uint8Array((0, base64_1.base64ToBytes)((0, base64_1.fromBase64Url)(signature)));
58
+ valid = await crypto.subtle.verify('HMAC', key, signatureBytes, encoder.encode(encodedPayload));
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ if (!valid)
64
+ return null;
65
+ let parsed;
66
+ try {
67
+ parsed = JSON.parse(new TextDecoder().decode((0, base64_1.base64ToBytes)((0, base64_1.fromBase64Url)(encodedPayload))));
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ if (!parsed || typeof parsed !== 'object')
73
+ return null;
74
+ const candidate = parsed;
75
+ if (candidate.v !== constants_1.constants.CUSTOM_CODE_TOKEN_VERSION)
76
+ return null;
77
+ if (typeof candidate.artifactId !== 'string' || !candidate.artifactId) {
78
+ return null;
79
+ }
80
+ if (typeof candidate.versionId !== 'string' || !candidate.versionId) {
81
+ return null;
82
+ }
83
+ // Checked here rather than in the broker so every caller gets it: a token past
84
+ // its expiry is as good as unsigned.
85
+ if (typeof candidate.exp === 'number' &&
86
+ candidate.exp * 1000 <= (now ?? Date.now())) {
87
+ return null;
88
+ }
89
+ return {
90
+ v: candidate.v,
91
+ artifactId: candidate.artifactId,
92
+ versionId: candidate.versionId,
93
+ iat: typeof candidate.iat === 'number' ? candidate.iat : 0,
94
+ ...(candidate.preview === true ? { preview: true } : {}),
95
+ ...(typeof candidate.exp === 'number' ? { exp: candidate.exp } : {})
96
+ };
97
+ };
98
+ exports.verifyCustomCodeToken = verifyCustomCodeToken;
99
+ /**
100
+ * The dispatch-namespace script name for an artifact: `artifact_<id>`.
101
+ *
102
+ * The id, never the slug — slugs are user-editable and a rename would orphan the
103
+ * deployed script while the database still pointed at a live version.
104
+ */
105
+ const customCodeScriptName = (artifactId) => `${constants_1.constants.CUSTOM_CODE_SCRIPT_NAME_PREFIX}${artifactId}`;
106
+ exports.customCodeScriptName = customCodeScriptName;
107
+ /**
108
+ * The script name a test run deploys into: `artifact_<id>_preview`.
109
+ *
110
+ * A second script rather than a second version of the live one, because a test
111
+ * must not be able to disturb what MCP clients are being served — and the only
112
+ * way to be certain of that is for it to run under a name nothing dispatches to.
113
+ */
114
+ const customCodePreviewScriptName = (artifactId) => `${(0, exports.customCodeScriptName)(artifactId)}${constants_1.constants.CUSTOM_CODE_PREVIEW_SCRIPT_SUFFIX}`;
115
+ exports.customCodePreviewScriptName = customCodePreviewScriptName;
@@ -0,0 +1,6 @@
1
+ export declare class DeadlineError extends Error {
2
+ constructor(ms: number);
3
+ }
4
+ export declare const withDeadline: <T>(work: Promise<T>, ms: number) => Promise<T>;
5
+ export declare const isDeadlineError: (error: unknown) => boolean;
6
+ //# sourceMappingURL=deadline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deadline.d.ts","sourceRoot":"","sources":["../src/deadline.ts"],"names":[],"mappings":"AAeA,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,EAAE,EAAE,MAAM;CAMvB;AAED,eAAO,MAAM,YAAY,GAAU,CAAC,EAClC,MAAM,OAAO,CAAC,CAAC,CAAC,EAChB,IAAI,MAAM,KACT,OAAO,CAAC,CAAC,CAYX,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,OACQ,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDeadlineError = exports.withDeadline = exports.DeadlineError = void 0;
4
+ // Bound how long we wait for a dispatched user script, without handing the
5
+ // binding an AbortSignal.
6
+ //
7
+ // The obvious version — `fetch(url, { signal })` on a Fetcher from a dispatch
8
+ // namespace — works when the binding is in the same process and fails when it is
9
+ // not: `AbortSignal serialization is not enabled`. A local `wrangler dev` proxies
10
+ // the dispatch namespace to the remote account, so every test run and every tool
11
+ // call raised that instead of running, while the deployed Worker was fine. A
12
+ // timeout that only works in production is worse than no timeout, because it
13
+ // breaks the environment where people are actually writing the code.
14
+ //
15
+ // What is lost by racing instead of aborting: the isolate keeps running after we
16
+ // stop waiting for it. That is what the per-script `limits.cpu_ms` ceiling is
17
+ // for, and this deadline was never a cost control — it bounds how long a person
18
+ // watches a spinner.
19
+ class DeadlineError extends Error {
20
+ constructor(ms) {
21
+ super(`Timed out after ${ms}ms`);
22
+ // Named the way an aborted fetch is, so a call site that already branches on
23
+ // the name keeps reading the same way.
24
+ this.name = 'TimeoutError';
25
+ }
26
+ }
27
+ exports.DeadlineError = DeadlineError;
28
+ const withDeadline = async (work, ms) => {
29
+ let timer;
30
+ try {
31
+ return await Promise.race([
32
+ work,
33
+ new Promise((_, reject) => {
34
+ timer = setTimeout(() => reject(new DeadlineError(ms)), ms);
35
+ })
36
+ ]);
37
+ }
38
+ finally {
39
+ if (timer !== undefined)
40
+ clearTimeout(timer);
41
+ }
42
+ };
43
+ exports.withDeadline = withDeadline;
44
+ const isDeadlineError = (error) => error instanceof Error && error.name === 'TimeoutError';
45
+ exports.isDeadlineError = isDeadlineError;
@@ -0,0 +1,25 @@
1
+ export interface DiscordSendRequest {
2
+ botToken: string;
3
+ channelId: string;
4
+ replyToMessageId?: string;
5
+ content?: string;
6
+ }
7
+ export interface DiscordSendResponse {
8
+ ok: boolean;
9
+ id?: string;
10
+ error?: string;
11
+ }
12
+ export interface DiscordSendRemoteResourceRequest {
13
+ discord: DiscordSendRequest;
14
+ remote: {
15
+ url: string;
16
+ transport: string;
17
+ authHeader?: {
18
+ name: string;
19
+ value: string;
20
+ } | null;
21
+ uri: string;
22
+ timeoutMs: number;
23
+ };
24
+ }
25
+ //# sourceMappingURL=discordSend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discordSend.d.ts","sourceRoot":"","sources":["../src/discordSend.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IAGjB,SAAS,EAAE,MAAM,CAAC;IAElB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAG1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAElB,UAAU,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QACpD,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ // Wire protocol shared between the worker (which constructs the request) and the
3
+ // resource-handler container (which parses it and calls the Discord API). The
4
+ // worker sends a multipart/form-data POST with one `metadata` field (JSON
5
+ // matching DiscordSendRequest) and exactly one `file` field (binary). Discord
6
+ // uploads a file by posting a `payload_json` + `files[0]` multipart to
7
+ // POST /channels/{channelId}/messages.
8
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export declare const isEmbeddableMimeType: (mimeType: string) => boolean;
2
+ //# sourceMappingURL=embeddable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddable.d.ts","sourceRoot":"","sources":["../src/embeddable.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,GAAI,UAAU,MAAM,KAAG,OACmB,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isEmbeddableMimeType = void 0;
4
+ const constants_1 = require("./constants");
5
+ const isEmbeddableMimeType = (mimeType) => constants_1.constants.EMBEDDABLE_MIME_TYPES.includes(mimeType);
6
+ exports.isEmbeddableMimeType = isEmbeddableMimeType;
@@ -0,0 +1,6 @@
1
+ export interface ExposableResource {
2
+ sourceType?: string | null;
3
+ parentResourceId?: string | null;
4
+ }
5
+ export declare const isExposedResource: (resource: ExposableResource) => boolean;
6
+ //# sourceMappingURL=exposedResource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposedResource.d.ts","sourceRoot":"","sources":["../src/exposedResource.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,eAAO,MAAM,iBAAiB,GAAI,UAAU,iBAAiB,KAAG,OAgB/D,CAAC"}