( fullPath: string, size: number, ctx: BriefUploadContext, )
| 90 | * Every early-return is intentional graceful degradation. |
| 91 | */ |
| 92 | export async function uploadBriefAttachment( |
| 93 | fullPath: string, |
| 94 | size: number, |
| 95 | ctx: BriefUploadContext, |
| 96 | ): Promise<string | undefined> { |
| 97 | // Positive pattern so bun:bundle eliminates the entire body from |
| 98 | // non-BRIDGE_MODE builds (negative `if (!feature(...)) return` does not). |
| 99 | if (feature('BRIDGE_MODE')) { |
| 100 | if (!ctx.replBridgeEnabled) return undefined |
| 101 | |
| 102 | if (size > MAX_UPLOAD_BYTES) { |
| 103 | debug(`skip ${fullPath}: ${size} bytes exceeds ${MAX_UPLOAD_BYTES} limit`) |
| 104 | return undefined |
| 105 | } |
| 106 | |
| 107 | const token = getBridgeAccessToken() |
| 108 | if (!token) { |
| 109 | debug('skip: no oauth token') |
| 110 | return undefined |
| 111 | } |
| 112 | |
| 113 | let content: Buffer |
| 114 | try { |
| 115 | content = await readFile(fullPath) |
| 116 | } catch (e) { |
| 117 | debug(`read failed for ${fullPath}: ${e}`) |
| 118 | return undefined |
| 119 | } |
| 120 | |
| 121 | const baseUrl = getBridgeBaseUrl() |
| 122 | const url = `${baseUrl}/api/oauth/file_upload` |
| 123 | const filename = basename(fullPath) |
| 124 | const mimeType = guessMimeType(filename) |
| 125 | const boundary = `----FormBoundary${randomUUID()}` |
| 126 | |
| 127 | // Manual multipart — same pattern as filesApi.ts. The oauth endpoint takes |
| 128 | // a single "file" part (no "purpose" field like the public Files API). |
| 129 | const body = Buffer.concat([ |
| 130 | Buffer.from( |
| 131 | `--${boundary}\r\n` + |
| 132 | `Content-Disposition: form-data; name="file"; filename="${filename}"\r\n` + |
| 133 | `Content-Type: ${mimeType}\r\n\r\n`, |
| 134 | ), |
| 135 | content, |
| 136 | Buffer.from(`\r\n--${boundary}--\r\n`), |
| 137 | ]) |
| 138 | |
| 139 | try { |
| 140 | const response = await axios.post(url, body, { |
| 141 | headers: { |
| 142 | Authorization: `Bearer ${token}`, |
| 143 | 'Content-Type': `multipart/form-data; boundary=${boundary}`, |
| 144 | 'Content-Length': body.length.toString(), |
| 145 | }, |
| 146 | timeout: UPLOAD_TIMEOUT_MS, |
| 147 | signal: ctx.signal, |
| 148 | validateStatus: () => true, |
| 149 | }) |
no test coverage detected