@@ -4,6 +4,7 @@ package plugin
44
55import (
66 "encoding/json"
7+ "fmt"
78 "unsafe"
89)
910
@@ -206,6 +207,56 @@ func RecordActivity(taskID, projectID, actorUserID, activityType string, content
206207 hostActivityRecord (int64 (ptrOf (payloadBytes )), int64 (len (payloadBytes )))
207208}
208209
210+ // ── Fetch ─────────────────────────────────────────────────────────────────────
211+
212+ // FetchResponse is the result of a Fetch call.
213+ type FetchResponse struct {
214+ Status int `json:"status"`
215+ Body string `json:"body"`
216+ Headers map [string ]string `json:"headers"`
217+ Error string `json:"error"`
218+ }
219+
220+ // Fetch makes an outbound HTTP request via the paca.fetch host function.
221+ // The URL's domain must be listed in the plugin manifest's allowedOutboundDomains.
222+ func Fetch (method , rawURL string , headers map [string ]string , body string ) (* FetchResponse , error ) {
223+ req := struct {
224+ Method string `json:"method"`
225+ URL string `json:"url"`
226+ Headers map [string ]string `json:"headers"`
227+ Body string `json:"body"`
228+ }{
229+ Method : method ,
230+ URL : rawURL ,
231+ Headers : headers ,
232+ Body : body ,
233+ }
234+ reqJSON , err := json .Marshal (req )
235+ if err != nil {
236+ return nil , err
237+ }
238+ outputBuf := make ([]byte , 8 )
239+ hostFetch (
240+ int64 (ptrOf (reqJSON )), int64 (len (reqJSON )),
241+ int64 (ptrOf (outputBuf )), int64 (ptrOf (outputBuf [4 :])),
242+ )
243+ resPtr := int32 (uint32 (outputBuf [0 ]) | uint32 (outputBuf [1 ])<< 8 | uint32 (outputBuf [2 ])<< 16 | uint32 (outputBuf [3 ])<< 24 )
244+ resLen := int32 (uint32 (outputBuf [4 ]) | uint32 (outputBuf [5 ])<< 8 | uint32 (outputBuf [6 ])<< 16 | uint32 (outputBuf [7 ])<< 24 )
245+ if resLen == 0 {
246+ return nil , fmt .Errorf ("plugin: fetch: empty response from host" )
247+ }
248+ resBytes := append ([]byte (nil ), wasmSlice (resPtr , resLen )... )
249+ wasmResetAllocator ()
250+ var resp FetchResponse
251+ if err := json .Unmarshal (resBytes , & resp ); err != nil {
252+ return nil , fmt .Errorf ("plugin: fetch: decode response: %w" , err )
253+ }
254+ if resp .Error != "" {
255+ return nil , fmt .Errorf ("plugin: fetch: %s" , resp .Error )
256+ }
257+ return & resp , nil
258+ }
259+
209260// ── Helpers ───────────────────────────────────────────────────────────────────
210261
211262//go:nocheckptr
0 commit comments