1"use strict";(globalThis.webpackChunkvoiden_docs=globalThis.webpackChunkvoiden_docs||[]).push([[1296],{3434:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>a,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"plugins/core-plugins/bruno-collection-importer","title":"Bruno Collection Importer","description":"Switching over from Bruno? The Bruno Collection","source":"@site/docs/plugins/core-plugins/bruno-collection-importer.md","sourceDirName":"plugins/core-plugins","slug":"/plugins/core-plugins/bruno-collection-importer","permalink":"/docs/plugins/core-plugins/bruno-collection-importer","draft":false,"unlisted":false,"editUrl":"https://github.com/VoidenHQ/docs/tree/main/docs/plugins/core-plugins/bruno-collection-importer.md","tags":[],"version":"current","lastUpdatedAt":1788509063000,"frontMatter":{"id":"bruno-collection-importer","title":"Bruno Collection Importer","sidebar_label":"Bruno Collection Importer"},"sidebar":"tutorialSidebar","previous":{"title":"Postman Collection Importer","permalink":"/docs/plugins/core-plugins/postman-collection-importer"},"next":{"title":"Simple Assertions Plugin","permalink":"/docs/plugins/core-plugins/simple-assertion"}}');var s=r(4848),i=r(8453);const o={id:"bruno-collection-importer",title:"Bruno Collection Importer",sidebar_label:"Bruno Collection Importer"},l="Bruno Collection Importer Plugin",d={},c=[{value:"How It Works",id:"how-it-works",level:2},{value:"What gets imported",id:"what-gets-imported",level:2},{value:"How requests are converted",id:"how-requests-are-converted",level:2},{value:"Body types",id:"body-types",level:3},{value:"Everything else",id:"everything-else",level:3},{value:"Scripts & assertions",id:"scripts--assertions",level:3},{value:"Requirements",id:"requirements",level:2},{value:"Good to know",id:"good-to-know",level:2}];function h(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"bruno-collection-importer-plugin",children:"Bruno Collection Importer Plugin"})}),"\n",(0,s.jsxs)(n.p,{children:["Switching over from ",(0,s.jsx)(n.a,{href:"https://www.usebruno.com",children:"Bruno"}),"? The ",(0,s.jsx)(n.strong,{children:"Bruno Collection\nImporter"})," plugin makes it painless \u2014 it moves your API collections straight\ninto fully native Voiden ",(0,s.jsx)(n.code,{children:".void"})," request files, so you're not stuck re-typing\nendpoints and headers by hand."]}),"\n",(0,s.jsxs)(n.p,{children:["It works with Bruno 3.0+'s whole-collection ",(0,s.jsx)(n.strong,{children:"OpenCollection"})," YAML export\nand with individual Bruno environment files, converting requests,\nfolders, environments, auth, and scripts into Voiden automatically. Importing\na standalone classic ",(0,s.jsx)(n.code,{children:".bru"})," request file on its own isn't supported \u2014 bring\nin the full collection export instead."]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"how-it-works",children:"How It Works"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Open a Bruno environment file or an exported OpenCollection YAML file\nin Voiden."}),"\n",(0,s.jsxs)(n.li,{children:["Look for the ",(0,s.jsx)(n.strong,{children:"Import into Voiden"})," button in the file's tab toolbar."]}),"\n",(0,s.jsx)(n.li,{children:"Click it \u2014 if you opened a whole OpenCollection export, Voiden builds a\nfolder tree that matches your Bruno collection's structure exactly; if you\nopened just a single request from a directory-based OpenCollection layout,\nit converts that one."}),"\n",(0,s.jsxs)(n.li,{children:["That's it \u2014 every request lands as its own ",(0,s.jsx)(n.code,{children:".void"})," file, with its endpoint,\nparams, auth, and (where it's safe to) live scripts all included."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"what-gets-imported",children:"What gets imported"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"You open in Voiden"}),(0,s.jsx)(n.th,{children:"You get"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"A whole OpenCollection YAML export"}),(0,s.jsxs)(n.td,{children:["A folder tree matching your Bruno collection, one ",(0,s.jsx)(n.code,{children:".void"})," file per request"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"A single request from a directory-based OpenCollection layout"}),(0,s.jsxs)(n.td,{children:["One ",(0,s.jsx)(n.code,{children:".void"})," file"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsxs)(n.td,{children:["A Bruno environment file (",(0,s.jsx)(n.code,{children:"environments/<name>.bru"}),")"]}),(0,s.jsx)(n.td,{children:"A named Voiden environment \u2014 merged into your existing environments, not overwritten"})]})]})]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["A standalone classic ",(0,s.jsx)(n.code,{children:".bru"})," request file (outside of an OpenCollection export) can't be imported on its own."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"how-requests-are-converted",children:"How requests are converted"}),"\n",(0,s.jsx)(n.h3,{id:"body-types",children:"Body types"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Bruno body"}),(0,s.jsx)(n.th,{children:"Voiden block"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"JSON / XML / plain text"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"json_body"})," / ",(0,s.jsx)(n.code,{children:"xml_body"})," / ",(0,s.jsx)(n.code,{children:"text_body"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Form URL-encoded"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"url-table"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Multipart form"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"multipart-table"})," \u2014 file fields become ",(0,s.jsx)(n.code,{children:"fileLink"})," attachments when the original file still exists"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Raw file"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"restFile"})," placeholder"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"GraphQL"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"gqlquery"})," / ",(0,s.jsx)(n.code,{children:"gqlvariables"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"gRPC"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"socket-request"}),", wired to the request's ",(0,s.jsx)(n.code,{children:".proto"})," file, method, and streaming type"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"WebSocket"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"socket-request"})," (url + protocol)"]})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"everything-else",children:"Everything else"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Headers"})," \u2192 ",(0,s.jsx)(n.code,{children:"headers-table"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Query & path params"})," \u2192 ",(0,s.jsx)(n.code,{children:"query-table"})," / ",(0,s.jsx)(n.code,{children:"path-table"})," \u2014 if a request has a\nquery string but no explicit ",(0,s.jsx)(n.code,{children:"params:query"})," list, the importer parses it\nfrom the URL instead"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.strong,{children:[(0,s.jsx)(n.code,{children:":param"})," URL segments"]})," \u2192 converted to Voiden's ",(0,s.jsx)(n.code,{children:"{param}"})," placeholder style"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Auth"})," \u2014 Basic, Bearer, API Key, Digest, AWS Signature v4, NTLM, OAuth1,\nand OAuth2 (all four grant types) all convert into a Voiden ",(0,s.jsx)(n.code,{children:"auth"})," block"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"scripts--assertions",children:"Scripts & assertions"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A well-formed Bruno ",(0,s.jsx)(n.code,{children:"assert{}"})," block becomes a live ",(0,s.jsx)(n.code,{children:"assertions-table"})," block."]}),"\n",(0,s.jsxs)(n.li,{children:["Pre-request and post-response scripts become live ",(0,s.jsx)(n.code,{children:"pre_script"}),"/",(0,s.jsx)(n.code,{children:"post_script"}),"\nblocks \u2014 but only when every line matches a pattern the importer recognizes\nas safe. If anything looks unfamiliar, the whole script is imported\n",(0,s.jsx)(n.strong,{children:"commented out"})," instead, so you can review it before it runs."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsxs)(n.p,{children:["The importer always needs the ",(0,s.jsx)(n.strong,{children:"Voiden REST API"})," plugin \u2014 it generates the\nmethod/URL, headers, params, and body blocks every imported request is built\nfrom."]}),"\n",(0,s.jsx)(n.p,{children:"A few other core plugins kick in automatically, only when a request actually\nneeds them:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Plugin"}),(0,s.jsx)(n.th,{children:"Used for"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Voiden GraphQL"}),(0,s.jsx)(n.td,{children:"GraphQL request bodies"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Simple Assertions"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"assert{}"})," blocks"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Socket & gRPC"}),(0,s.jsx)(n.td,{children:"gRPC and WebSocket requests"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Advanced Authentication"}),(0,s.jsx)(n.td,{children:"OAuth1 / OAuth2"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"good-to-know",children:"Good to know"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"File and folder names are sanitized for filesystem compatibility, and\nnested folders are supported with no depth limit."}),"\n",(0,s.jsx)(n.li,{children:"Malformed field names and special characters in your Bruno collection are\nhandled gracefully rather than failing the import."}),"\n",(0,s.jsx)(n.li,{children:"A whole-collection import shows live progress and can be cancelled midway."}),"\n"]})]})}function a(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},8453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>l});var t=r(6540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.