[{"data":1,"prerenderedAt":1651},["ShallowReactive",2],{"navigation_docs_en":3,"-en-storage-s3":441,"-en-storage-s3-surround":1646},[4,45,60,81,112,129,146,173,197,213,242,279,356,372,384,403,429],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Coming from Laravel","\u002Fen\u002Fgetting-started\u002Fcoming-from-laravel","en\u002F1.getting-started\u002F2.coming-from-laravel","i-lucide-arrow-right-left",{"title":21,"path":22,"stem":23,"icon":19},"Coming from Symfony","\u002Fen\u002Fgetting-started\u002Fcoming-from-symfony","en\u002F1.getting-started\u002F3.coming-from-symfony",{"title":25,"path":26,"stem":27,"icon":28},"Installation","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F4.installation","i-lucide-download",{"title":30,"path":31,"stem":32,"icon":33},"Your first module","\u002Fen\u002Fgetting-started\u002Ffirst-module","en\u002F1.getting-started\u002F5.first-module","i-lucide-package-plus",{"title":35,"path":36,"stem":37,"icon":38},"Project structure","\u002Fen\u002Fgetting-started\u002Fproject-structure","en\u002F1.getting-started\u002F6.project-structure","i-lucide-folder-tree",{"title":40,"path":41,"stem":42,"icon":43},"The shop sample application","\u002Fen\u002Fgetting-started\u002Fsample-app","en\u002F1.getting-started\u002F7.sample-app","i-lucide-shopping-cart",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"queue","i-lucide-layers","\u002Fen\u002Fqueue","en\u002F10.queue",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Overview","\u002Fen\u002Fqueue\u002Foverview","en\u002F10.queue\u002F1.overview","i-lucide-list-ordered",{"title":57,"path":58,"stem":59,"icon":47},"Tasks","\u002Fen\u002Fqueue\u002Ftasks","en\u002F10.queue\u002F2.tasks",{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":44},"events","i-lucide-workflow","\u002Fen\u002Fevents","en\u002F11.events",[66,71,76],{"title":67,"path":68,"stem":69,"icon":70},"Events","\u002Fen\u002Fevents\u002Foverview","en\u002F11.events\u002F1.overview","i-lucide-radio",{"title":72,"path":73,"stem":74,"icon":75},"Outbox","\u002Fen\u002Fevents\u002Foutbox","en\u002F11.events\u002F2.outbox","i-lucide-inbox",{"title":77,"path":78,"stem":79,"icon":80},"Scheduling","\u002Fen\u002Fevents\u002Fscheduler","en\u002F11.events\u002F3.scheduler","i-lucide-calendar-clock",{"title":82,"icon":83,"path":84,"stem":85,"children":86,"page":44},"auth","i-lucide-shield-check","\u002Fen\u002Fauth","en\u002F12.auth",[87,92,97,102,107],{"title":88,"path":89,"stem":90,"icon":91},"Authentication","\u002Fen\u002Fauth\u002Foverview","en\u002F12.auth\u002F1.overview","i-lucide-key-round",{"title":93,"path":94,"stem":95,"icon":96},"RBAC","\u002Fen\u002Fauth\u002Frbac","en\u002F12.auth\u002F2.rbac","i-lucide-users",{"title":98,"path":99,"stem":100,"icon":101},"Policies","\u002Fen\u002Fauth\u002Fpolicy","en\u002F12.auth\u002F3.policy","i-lucide-gavel",{"title":103,"path":104,"stem":105,"icon":106},"Using auth standalone","\u002Fen\u002Fauth\u002Fstandalone","en\u002F12.auth\u002F4.standalone","i-lucide-plug",{"title":108,"path":109,"stem":110,"icon":111},"Social login with goth, standalone","\u002Fen\u002Fauth\u002Fsocial-standalone","en\u002F12.auth\u002F5.social-standalone","i-lucide-log-in",{"title":113,"icon":114,"path":115,"stem":116,"children":117,"page":44},"mail","i-lucide-mail","\u002Fen\u002Fmail","en\u002F13.mail",[118,121,125],{"title":52,"path":119,"stem":120,"icon":114},"\u002Fen\u002Fmail\u002Foverview","en\u002F13.mail\u002F1.overview",{"title":122,"path":123,"stem":124,"icon":114},"SMTP","\u002Fen\u002Fmail\u002Fsmtp","en\u002F13.mail\u002F2.smtp",{"title":126,"path":127,"stem":128,"icon":114},"MJML","\u002Fen\u002Fmail\u002Fmjml","en\u002F13.mail\u002F3.mjml",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":44},"notify","i-lucide-bell","\u002Fen\u002Fnotify","en\u002F14.notify",[135,138,142],{"title":52,"path":136,"stem":137,"icon":131},"\u002Fen\u002Fnotify\u002Foverview","en\u002F14.notify\u002F1.overview",{"title":139,"path":140,"stem":141,"icon":131},"Database channel","\u002Fen\u002Fnotify\u002Fdatabase","en\u002F14.notify\u002F2.database",{"title":143,"path":144,"stem":145,"icon":131},"Broadcast channel","\u002Fen\u002Fnotify\u002Fbroadcast","en\u002F14.notify\u002F3.broadcast",{"title":147,"icon":148,"path":149,"stem":150,"children":151,"page":44},"storage","i-lucide-hard-drive","\u002Fen\u002Fstorage","en\u002F15.storage",[152,155,159,163,168],{"title":52,"path":153,"stem":154,"icon":148},"\u002Fen\u002Fstorage\u002Foverview","en\u002F15.storage\u002F1.overview",{"title":156,"path":157,"stem":158},"Disk API","\u002Fen\u002Fstorage\u002Fdisk-api","en\u002F15.storage\u002F2.disk-api",{"title":160,"path":161,"stem":162,"icon":148},"Memory and local disk","\u002Fen\u002Fstorage\u002Flocal","en\u002F15.storage\u002F3.local",{"title":164,"path":165,"stem":166,"icon":167},"S3","\u002Fen\u002Fstorage\u002Fs3","en\u002F15.storage\u002F4.s3","i-lucide-cloud",{"title":169,"path":170,"stem":171,"icon":172},"Testing","\u002Fen\u002Fstorage\u002Ftesting","en\u002F15.storage\u002F5.testing","i-lucide-flask-conical",{"title":174,"icon":175,"path":176,"stem":177,"children":178,"page":44},"telemetry","i-lucide-activity","\u002Fen\u002Ftelemetry","en\u002F16.telemetry",[179,182,187,192],{"title":52,"path":180,"stem":181,"icon":175},"\u002Fen\u002Ftelemetry\u002Foverview","en\u002F16.telemetry\u002F1.overview",{"title":183,"path":184,"stem":185,"icon":186},"Logging","\u002Fen\u002Ftelemetry\u002Flogging","en\u002F16.telemetry\u002F2.logging","i-lucide-scroll-text",{"title":188,"path":189,"stem":190,"icon":191},"OpenTelemetry","\u002Fen\u002Ftelemetry\u002Fopentelemetry","en\u002F16.telemetry\u002F3.opentelemetry","i-lucide-radar",{"title":193,"path":194,"stem":195,"icon":196},"Sentry","\u002Fen\u002Ftelemetry\u002Fsentry","en\u002F16.telemetry\u002F4.sentry","i-lucide-bug",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":44},"Reference","i-lucide-book-open","\u002Fen\u002Freference","en\u002F17.reference",[203,208],{"title":204,"path":205,"stem":206,"icon":207},"Configuration","\u002Fen\u002Freference\u002Fconfiguration","en\u002F17.reference\u002F1.configuration","i-lucide-settings",{"title":209,"path":210,"stem":211,"icon":212},"External dependencies","\u002Fen\u002Freference\u002Fdependencies","en\u002F17.reference\u002F2.dependencies","i-lucide-package",{"title":214,"icon":215,"path":216,"stem":217,"children":218,"page":44},"Concepts","i-lucide-lightbulb","\u002Fen\u002Fconcepts","en\u002F2.concepts",[219,223,228,232,237],{"title":220,"path":221,"stem":222,"icon":47},"Architecture","\u002Fen\u002Fconcepts\u002Farchitecture","en\u002F2.concepts\u002F1.architecture",{"title":224,"path":225,"stem":226,"icon":227},"Error model","\u002Fen\u002Fconcepts\u002Ferror-model","en\u002F2.concepts\u002F2.error-model","i-lucide-shield-alert",{"title":204,"path":229,"stem":230,"icon":231},"\u002Fen\u002Fconcepts\u002Fconfiguration","en\u002F2.concepts\u002F3.configuration","i-lucide-settings-2",{"title":233,"path":234,"stem":235,"icon":236},"Codegen pipeline","\u002Fen\u002Fconcepts\u002Fcodegen-pipeline","en\u002F2.concepts\u002F4.codegen-pipeline","i-lucide-file-json",{"title":238,"path":239,"stem":240,"icon":241},"Design patterns","\u002Fen\u002Fconcepts\u002Fdesign-patterns","en\u002F2.concepts\u002F5.design-patterns","i-lucide-puzzle",{"title":243,"icon":244,"path":245,"stem":246,"children":247,"page":44},"Kit","i-lucide-box","\u002Fen\u002Fkit","en\u002F3.kit",[248,251,256,261,266,270,275],{"title":52,"path":249,"stem":250,"icon":244},"\u002Fen\u002Fkit\u002Foverview","en\u002F3.kit\u002F1.overview",{"title":252,"path":253,"stem":254,"icon":255},"Application lifecycle","\u002Fen\u002Fkit\u002Fapp","en\u002F3.kit\u002F2.app","i-lucide-power",{"title":257,"path":258,"stem":259,"icon":260},"Server","\u002Fen\u002Fkit\u002Fserver","en\u002F3.kit\u002F3.server","i-lucide-server",{"title":262,"path":263,"stem":264,"icon":265},"Worker","\u002Fen\u002Fkit\u002Fworker","en\u002F3.kit\u002F4.worker","i-lucide-cog",{"title":267,"path":268,"stem":269,"icon":70},"Realtime","\u002Fen\u002Fkit\u002Frealtime","en\u002F3.kit\u002F5.realtime",{"title":271,"path":272,"stem":273,"icon":274},"Migrations","\u002Fen\u002Fkit\u002Fmigrations","en\u002F3.kit\u002F6.migrations","i-lucide-file-stack",{"title":276,"path":277,"stem":278,"icon":111},"Social login","\u002Fen\u002Fkit\u002Fsocial-login","en\u002F3.kit\u002F7.social-login",{"title":280,"icon":281,"path":282,"stem":283,"children":284,"page":44},"CLI Reference","i-lucide-terminal","\u002Fen\u002Fcli","en\u002F4.cli",[285,288,293,298,303,308,313,318,323,328,333,337,342,347,351],{"title":52,"path":286,"stem":287,"icon":281},"\u002Fen\u002Fcli\u002Foverview","en\u002F4.cli\u002F1.overview",{"title":289,"path":290,"stem":291,"icon":292},"add db","\u002Fen\u002Fcli\u002Fadd-db","en\u002F4.cli\u002F10.add-db","i-lucide-database-zap",{"title":294,"path":295,"stem":296,"icon":297},"add compose \u002F add docker","\u002Fen\u002Fcli\u002Fadd-compose","en\u002F4.cli\u002F11.add-compose","i-lucide-container",{"title":299,"path":300,"stem":301,"icon":302},"add mail","\u002Fen\u002Fcli\u002Fadd-mail","en\u002F4.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":304,"path":305,"stem":306,"icon":307},"add notification","\u002Fen\u002Fcli\u002Fadd-notification","en\u002F4.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":309,"path":310,"stem":311,"icon":312},"add realtime","\u002Fen\u002Fcli\u002Fadd-realtime","en\u002F4.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":314,"path":315,"stem":316,"icon":317},"add seeder","\u002Fen\u002Fcli\u002Fadd-seeder","en\u002F4.cli\u002F15.add-seeder","i-lucide-sprout",{"title":319,"path":320,"stem":321,"icon":322},"new project","\u002Fen\u002Fcli\u002Fnew-project","en\u002F4.cli\u002F2.new-project","i-lucide-folder-plus",{"title":324,"path":325,"stem":326,"icon":327},"new module","\u002Fen\u002Fcli\u002Fnew-module","en\u002F4.cli\u002F3.new-module","i-lucide-blocks",{"title":329,"path":330,"stem":331,"icon":332},"add surface","\u002Fen\u002Fcli\u002Fadd-surface","en\u002F4.cli\u002F4.add-surface","i-lucide-layers-2",{"title":334,"path":335,"stem":336,"icon":244},"add core","\u002Fen\u002Fcli\u002Fadd-core","en\u002F4.cli\u002F5.add-core",{"title":338,"path":339,"stem":340,"icon":341},"add handler","\u002Fen\u002Fcli\u002Fadd-handler","en\u002F4.cli\u002F6.add-handler","i-lucide-webhook",{"title":343,"path":344,"stem":345,"icon":346},"new migration","\u002Fen\u002Fcli\u002Fnew-migration","en\u002F4.cli\u002F7.new-migration","i-lucide-file-plus",{"title":348,"path":349,"stem":350,"icon":265},"worker generators","\u002Fen\u002Fcli\u002Fworker-generators","en\u002F4.cli\u002F8.worker-generators",{"title":352,"path":353,"stem":354,"icon":355},"upgrade templates","\u002Fen\u002Fcli\u002Fupgrade-templates","en\u002F4.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"title":357,"icon":227,"path":358,"stem":359,"children":360,"page":44},"errs","\u002Fen\u002Ferrs","en\u002F5.errs",[361,364,368],{"title":52,"path":362,"stem":363,"icon":227},"\u002Fen\u002Ferrs\u002Foverview","en\u002F5.errs\u002F1.overview",{"title":365,"path":366,"stem":367},"API","\u002Fen\u002Ferrs\u002Fapi","en\u002F5.errs\u002F2.api",{"title":369,"path":370,"stem":371,"icon":227},"Integration","\u002Fen\u002Ferrs\u002Fintegration","en\u002F5.errs\u002F3.integration",{"title":373,"icon":231,"path":374,"stem":375,"children":376,"page":44},"envconf","\u002Fen\u002Fenvconf","en\u002F6.envconf",[377,380],{"title":52,"path":378,"stem":379,"icon":231},"\u002Fen\u002Fenvconf\u002Foverview","en\u002F6.envconf\u002F1.overview",{"title":381,"path":382,"stem":383},"Recipes","\u002Fen\u002Fenvconf\u002Frecipes","en\u002F6.envconf\u002F2.recipes",{"title":385,"icon":386,"path":387,"stem":388,"children":389,"page":44},"httperr","i-lucide-globe","\u002Fen\u002Fhttperr","en\u002F7.httperr",[390,393,398],{"title":52,"path":391,"stem":392,"icon":386},"\u002Fen\u002Fhttperr\u002Foverview","en\u002F7.httperr\u002F1.overview",{"title":394,"path":395,"stem":396,"icon":397},"Error responses","\u002Fen\u002Fhttperr\u002Ferror-responses","en\u002F7.httperr\u002F2.error-responses","i-lucide-octagon-alert",{"title":399,"path":400,"stem":401,"icon":402},"Validation","\u002Fen\u002Fhttperr\u002Fvalidation","en\u002F7.httperr\u002F3.validation","i-lucide-badge-check",{"title":404,"icon":405,"path":406,"stem":407,"children":408,"page":44},"dbx","i-lucide-database","\u002Fen\u002Fdbx","en\u002F8.dbx",[409,412,416,420,425],{"title":52,"path":410,"stem":411,"icon":405},"\u002Fen\u002Fdbx\u002Foverview","en\u002F8.dbx\u002F1.overview",{"title":413,"path":414,"stem":415,"icon":106},"pgx","\u002Fen\u002Fdbx\u002Fpg","en\u002F8.dbx\u002F2.pg",{"title":417,"path":418,"stem":419,"icon":47},"bun","\u002Fen\u002Fdbx\u002Fbunx","en\u002F8.dbx\u002F3.bunx",{"title":421,"path":422,"stem":423,"icon":424},"Transactions","\u002Fen\u002Fdbx\u002Ftransactions","en\u002F8.dbx\u002F4.transactions","i-lucide-git-merge",{"title":426,"path":427,"stem":428,"icon":317},"Seeders","\u002Fen\u002Fdbx\u002Fseed","en\u002F8.dbx\u002F5.seed",{"title":430,"icon":55,"path":431,"stem":432,"children":433,"page":44},"paginate","\u002Fen\u002Fpaginate","en\u002F9.paginate",[434,437],{"title":52,"path":435,"stem":436,"icon":55},"\u002Fen\u002Fpaginate\u002Foverview","en\u002F9.paginate\u002F1.overview",{"title":438,"path":439,"stem":440,"icon":19},"Cursor pagination","\u002Fen\u002Fpaginate\u002Fcursor","en\u002F9.paginate\u002F2.cursor",{"id":442,"title":164,"body":443,"description":1639,"extension":1640,"links":1641,"meta":1642,"navigation":1643,"path":165,"seo":1644,"stem":166,"__hash__":1645},"docs_en\u002Fen\u002F15.storage\u002F4.s3.md",{"type":444,"value":445,"toc":1631},"minimark",[446,496,501,526,542,546,676,687,736,860,866,870,906,956,966,970,998,1002,1591,1595,1627],[447,448,449,453,454,457,458,465,466,470,471,473,474,477,478,480,481,484,485,488,489,484,492,495],"p",{},[450,451,452],"code",{},"storage\u002Fdriver\u002Fs3"," is the production driver: an S3-compatible ",[450,455,456],{},"Driver"," built on ",[459,460,464],"a",{"href":461,"rel":462},"https:\u002F\u002Fgithub.com\u002Fminio\u002Fminio-go",[463],"nofollow","minio-go",". It's a ",[467,468,469],"strong",{},"separate Go module",", not a subpackage of the root ",[450,472,147],{}," module: it has its own ",[450,475,476],{},"go.mod"," and its own version, because it pulls in minio-go as a real dependency, and only the projects that actually talk to S3 should carry that weight. Everything else in ",[450,479,147],{}," (",[450,482,483],{},"Disk",", ",[450,486,487],{},"Manager",", the decorators, ",[450,490,491],{},"storage\u002Fmemory",[450,493,494],{},"storage\u002Flocal",") has no idea this module exists.",[497,498,500],"h2",{"id":499},"install","Install",[502,503,508],"pre",{"className":504,"code":505,"language":506,"meta":507,"style":507},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com\u002Fgp-system\u002Fstorage\u002Fdriver\u002Fs3@latest\n","sh","",[450,509,510],{"__ignoreMap":507},[511,512,515,519,523],"span",{"class":513,"line":514},"line",1,[511,516,518],{"class":517},"sBMFI","go",[511,520,522],{"class":521},"sfazB"," get",[511,524,525],{"class":521}," github.com\u002Fgp-system\u002Fstorage\u002Fdriver\u002Fs3@latest\n",[447,527,528,529,532,533,535,536,484,538,541],{},"This is versioned independently from ",[450,530,531],{},"github.com\u002Fgp-system\u002Fstorage"," itself: bumping the root module doesn't require bumping this one, and vice versa. Both are required in ",[450,534,476],{},", since the driver imports the root module's types (",[450,537,456],{},[450,539,540],{},"FileInfo",", and so on).",[497,543,545],{"id":544},"config","Config",[502,547,550],{"className":548,"code":549,"language":518,"meta":507,"style":507},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import \"github.com\u002Fgp-system\u002Fstorage\u002Fdriver\u002Fs3\"\n\ncfg := s3.Config{ \u002F* ... *\u002F }\ndriver, err := s3.New(cfg)\ndisk := storage.NewDisk(driver, storage.WithName(\"s3\"))\n",[450,551,552,568,575,603,634],{"__ignoreMap":507},[511,553,554,558,562,565],{"class":513,"line":514},[511,555,557],{"class":556},"s7zQu","import",[511,559,561],{"class":560},"sMK4o"," \"",[511,563,564],{"class":517},"github.com\u002Fgp-system\u002Fstorage\u002Fdriver\u002Fs3",[511,566,567],{"class":560},"\"\n",[511,569,571],{"class":513,"line":570},2,[511,572,574],{"emptyLinePlaceholder":573},true,"\n",[511,576,578,582,585,588,591,593,596,600],{"class":513,"line":577},3,[511,579,581],{"class":580},"sTEyZ","cfg ",[511,583,584],{"class":560},":=",[511,586,587],{"class":517}," s3",[511,589,590],{"class":560},".",[511,592,545],{"class":517},[511,594,595],{"class":560},"{",[511,597,599],{"class":598},"sHwdD"," \u002F* ... *\u002F",[511,601,602],{"class":560}," }\n",[511,604,606,609,612,615,617,619,621,625,628,631],{"class":513,"line":605},4,[511,607,608],{"class":580},"driver",[511,610,611],{"class":560},",",[511,613,614],{"class":580}," err ",[511,616,584],{"class":560},[511,618,587],{"class":580},[511,620,590],{"class":560},[511,622,624],{"class":623},"s2Zo4","New",[511,626,627],{"class":560},"(",[511,629,630],{"class":580},"cfg",[511,632,633],{"class":560},")\n",[511,635,637,640,642,645,647,650,652,654,656,658,660,663,665,668,671,673],{"class":513,"line":636},5,[511,638,639],{"class":580},"disk ",[511,641,584],{"class":560},[511,643,644],{"class":580}," storage",[511,646,590],{"class":560},[511,648,649],{"class":623},"NewDisk",[511,651,627],{"class":560},[511,653,608],{"class":580},[511,655,611],{"class":560},[511,657,644],{"class":580},[511,659,590],{"class":560},[511,661,662],{"class":623},"WithName",[511,664,627],{"class":560},[511,666,667],{"class":560},"\"",[511,669,670],{"class":521},"s3",[511,672,667],{"class":560},[511,674,675],{"class":560},"))\n",[447,677,678,679,682,683,686],{},"Compose ",[450,680,681],{},"s3.Config"," into your project config under an ",[450,684,685],{},"S3_"," prefix, the same way any gpsystem module's config composes:",[502,688,690],{"className":548,"code":689,"language":518,"meta":507,"style":507},"type Config struct {\n    \u002F\u002F ...\n    Storage s3.Config `envPrefix:\"S3_\"`\n}\n",[450,691,692,706,711,731],{"__ignoreMap":507},[511,693,694,697,700,703],{"class":513,"line":514},[511,695,696],{"class":560},"type",[511,698,699],{"class":517}," Config",[511,701,702],{"class":560}," struct",[511,704,705],{"class":560}," {\n",[511,707,708],{"class":513,"line":570},[511,709,710],{"class":598},"    \u002F\u002F ...\n",[511,712,713,716,718,720,722,725,728],{"class":513,"line":577},[511,714,715],{"class":580},"    Storage ",[511,717,670],{"class":517},[511,719,590],{"class":560},[511,721,545],{"class":517},[511,723,724],{"class":560}," `",[511,726,727],{"class":521},"envPrefix:\"S3_\"",[511,729,730],{"class":560},"`\n",[511,732,733],{"class":513,"line":605},[511,734,735],{"class":560},"}\n",[737,738,739,755],"table",{},[740,741,742],"thead",{},[743,744,745,749,752],"tr",{},[746,747,748],"th",{},"Variable",[746,750,751],{},"Default",[746,753,754],{},"Meaning",[756,757,758,778,792,805,822,844],"tbody",{},[743,759,760,766,771],{},[761,762,763],"td",{},[450,764,765],{},"S3_ENDPOINT",[761,767,768],{},[467,769,770],{},"required",[761,772,773,774,777],{},"the service address (",[450,775,776],{},"s3.amazonaws.com",", a MinIO host, ...)",[743,779,780,785,790],{},[761,781,782],{},[450,783,784],{},"S3_REGION",[761,786,787],{},[450,788,789],{},"us-east-1",[761,791],{},[743,793,794,799,803],{},[761,795,796],{},[450,797,798],{},"S3_BUCKET",[761,800,801],{},[467,802,770],{},[761,804],{},[743,806,807,816,819],{},[761,808,809,812,813],{},[450,810,811],{},"S3_ACCESS_KEY"," \u002F ",[450,814,815],{},"S3_SECRET_KEY",[761,817,818],{},"empty",[761,820,821],{},"credentials for the endpoint",[743,823,824,829,834],{},[761,825,826],{},[450,827,828],{},"S3_USE_PATH_STYLE",[761,830,831],{},[450,832,833],{},"false",[761,835,836,839,840,843],{},[450,837,838],{},"true"," for most self-hosted S3 (",[450,841,842],{},"\u002Fbucket\u002Fkey"," addressing instead of virtual-host-style)",[743,845,846,851,853],{},[761,847,848],{},[450,849,850],{},"S3_PUBLIC_BASE_URL",[761,852,818],{},[761,854,855,856,859],{},"base for ",[450,857,858],{},"Disk.URL"," (a CDN, or the bucket's own public endpoint)",[447,861,862,863,590],{},"The full list lives in the ",[459,864,865],{"href":205},"configuration reference",[497,867,869],{"id":868},"not-just-aws","Not just AWS",[447,871,872,873,484,878,883,884,886,887,889,890,892,893,897,898,901,902,905],{},"Because the driver is built on minio-go rather than the AWS SDK, it speaks to any service implementing the S3 API, not only AWS itself: AWS S3, ",[459,874,877],{"href":875,"rel":876},"https:\u002F\u002Fmin.io",[463],"MinIO",[459,879,882],{"href":880,"rel":881},"https:\u002F\u002Frustfs.com",[463],"RustFS",", Cloudflare R2, and Backblaze B2 all work behind the same ",[450,885,681],{},", generally just by pointing ",[450,888,765],{}," and ",[450,891,828],{}," at the right values. A project generated with ",[459,894,895],{"href":320},[450,896,319],{}," already runs a self-hosted, S3-compatible ",[450,899,900],{},"rustfs"," service in its dev ",[450,903,904],{},"compose.yml",", so local development never needs real AWS credentials.",[502,907,909],{"className":548,"code":908,"language":518,"meta":507,"style":507},"\u002F\u002F Client is an escape hatch for anything the Driver interface doesn't expose\nclient := driver.Client() \u002F\u002F *minio.Client\nbucket := driver.Bucket() \u002F\u002F the configured bucket name\n",[450,910,911,916,937],{"__ignoreMap":507},[511,912,913],{"class":513,"line":514},[511,914,915],{"class":598},"\u002F\u002F Client is an escape hatch for anything the Driver interface doesn't expose\n",[511,917,918,921,923,926,928,931,934],{"class":513,"line":570},[511,919,920],{"class":580},"client ",[511,922,584],{"class":560},[511,924,925],{"class":580}," driver",[511,927,590],{"class":560},[511,929,930],{"class":623},"Client",[511,932,933],{"class":560},"()",[511,935,936],{"class":598}," \u002F\u002F *minio.Client\n",[511,938,939,942,944,946,948,951,953],{"class":513,"line":577},[511,940,941],{"class":580},"bucket ",[511,943,584],{"class":560},[511,945,925],{"class":580},[511,947,590],{"class":560},[511,949,950],{"class":623},"Bucket",[511,952,933],{"class":560},[511,954,955],{"class":598}," \u002F\u002F the configured bucket name\n",[447,957,958,961,962,965],{},[450,959,960],{},"s3.New"," also accepts options; ",[450,963,964],{},"WithTransport(http.RoundTripper)"," lets you swap the underlying HTTP transport, useful for custom TLS configuration or for injecting an OTel-instrumented transport of your own.",[497,967,969],{"id":968},"presigned-urls","Presigned URLs",[447,971,972,889,975,978,979,982,983,986,987,989,990,993,994,997],{},[450,973,974],{},"TemporaryURL",[450,976,977],{},"TemporaryUploadURL"," are implemented with minio-go's native presigning (",[450,980,981],{},"PresignedGetObject","\u002F",[450,984,985],{},"PresignedPutObject","): the returned URL points directly at the S3-compatible endpoint, so the client downloads or uploads without the request passing through your service at all. This is the same ",[450,988,456],{}," contract every other driver implements, so code that calls ",[450,991,992],{},"disk.TemporaryURL(...)"," doesn't know or care that it's talking to S3 rather than the ",[459,995,996],{"href":161},"local driver","'s HMAC-signed links.",[497,999,1001],{"id":1000},"standalone-example","Standalone example",[502,1003,1006],{"className":548,"code":1004,"filename":1005,"language":518,"meta":507,"style":507},"package main\n\nimport (\n    \"context\"\n    \"log\"\n    \"strings\"\n    \"time\"\n\n    \"github.com\u002Fgp-system\u002Fstorage\"\n    \"github.com\u002Fgp-system\u002Fstorage\u002Fdriver\u002Fs3\"\n)\n\nfunc main() {\n    driver, err := s3.New(s3.Config{\n        Endpoint:      \"localhost:9000\",\n        Region:        \"us-east-1\",\n        Bucket:        \"uploads\",\n        AccessKey:     \"minioadmin\",\n        SecretKey:     \"minioadmin\",\n        UsePathStyle:  true,\n        PublicBaseURL: \"http:\u002F\u002Flocalhost:9000\u002Fuploads\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    disk := storage.NewDisk(driver, storage.WithName(\"s3\"))\n\n    ctx := context.Background()\n    if err := disk.Put(ctx, \"hello.txt\", strings.NewReader(\"hello, s3\"), storage.PutOptions{}); err != nil {\n        log.Fatal(err)\n    }\n\n    signed, err := disk.TemporaryURL(ctx, \"hello.txt\", storage.TemporaryURLOptions{TTL: 15 * time.Minute})\n    if err != nil {\n        log.Fatal(err)\n    }\n    log.Println(\"presigned link:\", signed)\n}\n","main.go",[450,1007,1008,1016,1020,1027,1037,1046,1056,1066,1071,1080,1089,1094,1099,1112,1141,1161,1178,1195,1213,1229,1243,1260,1266,1282,1300,1306,1342,1347,1366,1437,1452,1457,1462,1526,1539,1554,1559,1586],{"__ignoreMap":507},[511,1009,1010,1013],{"class":513,"line":514},[511,1011,1012],{"class":560},"package",[511,1014,1015],{"class":517}," main\n",[511,1017,1018],{"class":513,"line":570},[511,1019,574],{"emptyLinePlaceholder":573},[511,1021,1022,1024],{"class":513,"line":577},[511,1023,557],{"class":556},[511,1025,1026],{"class":560}," (\n",[511,1028,1029,1032,1035],{"class":513,"line":605},[511,1030,1031],{"class":560},"    \"",[511,1033,1034],{"class":517},"context",[511,1036,567],{"class":560},[511,1038,1039,1041,1044],{"class":513,"line":636},[511,1040,1031],{"class":560},[511,1042,1043],{"class":517},"log",[511,1045,567],{"class":560},[511,1047,1049,1051,1054],{"class":513,"line":1048},6,[511,1050,1031],{"class":560},[511,1052,1053],{"class":517},"strings",[511,1055,567],{"class":560},[511,1057,1059,1061,1064],{"class":513,"line":1058},7,[511,1060,1031],{"class":560},[511,1062,1063],{"class":517},"time",[511,1065,567],{"class":560},[511,1067,1069],{"class":513,"line":1068},8,[511,1070,574],{"emptyLinePlaceholder":573},[511,1072,1074,1076,1078],{"class":513,"line":1073},9,[511,1075,1031],{"class":560},[511,1077,531],{"class":517},[511,1079,567],{"class":560},[511,1081,1083,1085,1087],{"class":513,"line":1082},10,[511,1084,1031],{"class":560},[511,1086,564],{"class":517},[511,1088,567],{"class":560},[511,1090,1092],{"class":513,"line":1091},11,[511,1093,633],{"class":560},[511,1095,1097],{"class":513,"line":1096},12,[511,1098,574],{"emptyLinePlaceholder":573},[511,1100,1102,1105,1108,1110],{"class":513,"line":1101},13,[511,1103,1104],{"class":560},"func",[511,1106,1107],{"class":623}," main",[511,1109,933],{"class":560},[511,1111,705],{"class":560},[511,1113,1115,1118,1120,1122,1124,1126,1128,1130,1132,1134,1136,1138],{"class":513,"line":1114},14,[511,1116,1117],{"class":580},"    driver",[511,1119,611],{"class":560},[511,1121,614],{"class":580},[511,1123,584],{"class":560},[511,1125,587],{"class":580},[511,1127,590],{"class":560},[511,1129,624],{"class":623},[511,1131,627],{"class":560},[511,1133,670],{"class":517},[511,1135,590],{"class":560},[511,1137,545],{"class":517},[511,1139,1140],{"class":560},"{\n",[511,1142,1144,1147,1150,1153,1156,1158],{"class":513,"line":1143},15,[511,1145,1146],{"class":580},"        Endpoint",[511,1148,1149],{"class":560},":",[511,1151,1152],{"class":560},"      \"",[511,1154,1155],{"class":521},"localhost:9000",[511,1157,667],{"class":560},[511,1159,1160],{"class":560},",\n",[511,1162,1164,1167,1169,1172,1174,1176],{"class":513,"line":1163},16,[511,1165,1166],{"class":580},"        Region",[511,1168,1149],{"class":560},[511,1170,1171],{"class":560},"        \"",[511,1173,789],{"class":521},[511,1175,667],{"class":560},[511,1177,1160],{"class":560},[511,1179,1181,1184,1186,1188,1191,1193],{"class":513,"line":1180},17,[511,1182,1183],{"class":580},"        Bucket",[511,1185,1149],{"class":560},[511,1187,1171],{"class":560},[511,1189,1190],{"class":521},"uploads",[511,1192,667],{"class":560},[511,1194,1160],{"class":560},[511,1196,1198,1201,1203,1206,1209,1211],{"class":513,"line":1197},18,[511,1199,1200],{"class":580},"        AccessKey",[511,1202,1149],{"class":560},[511,1204,1205],{"class":560},"     \"",[511,1207,1208],{"class":521},"minioadmin",[511,1210,667],{"class":560},[511,1212,1160],{"class":560},[511,1214,1216,1219,1221,1223,1225,1227],{"class":513,"line":1215},19,[511,1217,1218],{"class":580},"        SecretKey",[511,1220,1149],{"class":560},[511,1222,1205],{"class":560},[511,1224,1208],{"class":521},[511,1226,667],{"class":560},[511,1228,1160],{"class":560},[511,1230,1232,1235,1237,1241],{"class":513,"line":1231},20,[511,1233,1234],{"class":580},"        UsePathStyle",[511,1236,1149],{"class":560},[511,1238,1240],{"class":1239},"sfNiH","  true",[511,1242,1160],{"class":560},[511,1244,1246,1249,1251,1253,1256,1258],{"class":513,"line":1245},21,[511,1247,1248],{"class":580},"        PublicBaseURL",[511,1250,1149],{"class":560},[511,1252,561],{"class":560},[511,1254,1255],{"class":521},"http:\u002F\u002Flocalhost:9000\u002Fuploads",[511,1257,667],{"class":560},[511,1259,1160],{"class":560},[511,1261,1263],{"class":513,"line":1262},22,[511,1264,1265],{"class":560},"    })\n",[511,1267,1269,1272,1274,1277,1280],{"class":513,"line":1268},23,[511,1270,1271],{"class":556},"    if",[511,1273,614],{"class":580},[511,1275,1276],{"class":560},"!=",[511,1278,1279],{"class":560}," nil",[511,1281,705],{"class":560},[511,1283,1285,1288,1290,1293,1295,1298],{"class":513,"line":1284},24,[511,1286,1287],{"class":580},"        log",[511,1289,590],{"class":560},[511,1291,1292],{"class":623},"Fatal",[511,1294,627],{"class":560},[511,1296,1297],{"class":580},"err",[511,1299,633],{"class":560},[511,1301,1303],{"class":513,"line":1302},25,[511,1304,1305],{"class":560},"    }\n",[511,1307,1309,1312,1314,1316,1318,1320,1322,1324,1326,1328,1330,1332,1334,1336,1338,1340],{"class":513,"line":1308},26,[511,1310,1311],{"class":580},"    disk ",[511,1313,584],{"class":560},[511,1315,644],{"class":580},[511,1317,590],{"class":560},[511,1319,649],{"class":623},[511,1321,627],{"class":560},[511,1323,608],{"class":580},[511,1325,611],{"class":560},[511,1327,644],{"class":580},[511,1329,590],{"class":560},[511,1331,662],{"class":623},[511,1333,627],{"class":560},[511,1335,667],{"class":560},[511,1337,670],{"class":521},[511,1339,667],{"class":560},[511,1341,675],{"class":560},[511,1343,1345],{"class":513,"line":1344},27,[511,1346,574],{"emptyLinePlaceholder":573},[511,1348,1350,1353,1355,1358,1360,1363],{"class":513,"line":1349},28,[511,1351,1352],{"class":580},"    ctx ",[511,1354,584],{"class":560},[511,1356,1357],{"class":580}," context",[511,1359,590],{"class":560},[511,1361,1362],{"class":623},"Background",[511,1364,1365],{"class":560},"()\n",[511,1367,1369,1371,1373,1375,1378,1380,1383,1385,1388,1390,1392,1395,1397,1399,1402,1404,1407,1409,1411,1414,1416,1419,1421,1423,1426,1429,1431,1433,1435],{"class":513,"line":1368},29,[511,1370,1271],{"class":556},[511,1372,614],{"class":580},[511,1374,584],{"class":560},[511,1376,1377],{"class":580}," disk",[511,1379,590],{"class":560},[511,1381,1382],{"class":623},"Put",[511,1384,627],{"class":560},[511,1386,1387],{"class":580},"ctx",[511,1389,611],{"class":560},[511,1391,561],{"class":560},[511,1393,1394],{"class":521},"hello.txt",[511,1396,667],{"class":560},[511,1398,611],{"class":560},[511,1400,1401],{"class":580}," strings",[511,1403,590],{"class":560},[511,1405,1406],{"class":623},"NewReader",[511,1408,627],{"class":560},[511,1410,667],{"class":560},[511,1412,1413],{"class":521},"hello, s3",[511,1415,667],{"class":560},[511,1417,1418],{"class":560},"),",[511,1420,644],{"class":517},[511,1422,590],{"class":560},[511,1424,1425],{"class":517},"PutOptions",[511,1427,1428],{"class":560},"{});",[511,1430,614],{"class":580},[511,1432,1276],{"class":560},[511,1434,1279],{"class":560},[511,1436,705],{"class":560},[511,1438,1440,1442,1444,1446,1448,1450],{"class":513,"line":1439},30,[511,1441,1287],{"class":580},[511,1443,590],{"class":560},[511,1445,1292],{"class":623},[511,1447,627],{"class":560},[511,1449,1297],{"class":580},[511,1451,633],{"class":560},[511,1453,1455],{"class":513,"line":1454},31,[511,1456,1305],{"class":560},[511,1458,1460],{"class":513,"line":1459},32,[511,1461,574],{"emptyLinePlaceholder":573},[511,1463,1465,1468,1470,1472,1474,1476,1478,1480,1482,1484,1486,1488,1490,1492,1494,1496,1498,1501,1503,1506,1508,1512,1515,1518,1520,1523],{"class":513,"line":1464},33,[511,1466,1467],{"class":580},"    signed",[511,1469,611],{"class":560},[511,1471,614],{"class":580},[511,1473,584],{"class":560},[511,1475,1377],{"class":580},[511,1477,590],{"class":560},[511,1479,974],{"class":623},[511,1481,627],{"class":560},[511,1483,1387],{"class":580},[511,1485,611],{"class":560},[511,1487,561],{"class":560},[511,1489,1394],{"class":521},[511,1491,667],{"class":560},[511,1493,611],{"class":560},[511,1495,644],{"class":517},[511,1497,590],{"class":560},[511,1499,1500],{"class":517},"TemporaryURLOptions",[511,1502,595],{"class":560},[511,1504,1505],{"class":580},"TTL",[511,1507,1149],{"class":560},[511,1509,1511],{"class":1510},"sbssI"," 15",[511,1513,1514],{"class":560}," *",[511,1516,1517],{"class":580}," time",[511,1519,590],{"class":560},[511,1521,1522],{"class":580},"Minute",[511,1524,1525],{"class":560},"})\n",[511,1527,1529,1531,1533,1535,1537],{"class":513,"line":1528},34,[511,1530,1271],{"class":556},[511,1532,614],{"class":580},[511,1534,1276],{"class":560},[511,1536,1279],{"class":560},[511,1538,705],{"class":560},[511,1540,1542,1544,1546,1548,1550,1552],{"class":513,"line":1541},35,[511,1543,1287],{"class":580},[511,1545,590],{"class":560},[511,1547,1292],{"class":623},[511,1549,627],{"class":560},[511,1551,1297],{"class":580},[511,1553,633],{"class":560},[511,1555,1557],{"class":513,"line":1556},36,[511,1558,1305],{"class":560},[511,1560,1562,1565,1567,1570,1572,1574,1577,1579,1581,1584],{"class":513,"line":1561},37,[511,1563,1564],{"class":580},"    log",[511,1566,590],{"class":560},[511,1568,1569],{"class":623},"Println",[511,1571,627],{"class":560},[511,1573,667],{"class":560},[511,1575,1576],{"class":521},"presigned link:",[511,1578,667],{"class":560},[511,1580,611],{"class":560},[511,1582,1583],{"class":580}," signed",[511,1585,633],{"class":560},[511,1587,1589],{"class":513,"line":1588},38,[511,1590,735],{"class":560},[497,1592,1594],{"id":1593},"related-pages","Related pages",[1596,1597,1598,1604,1612,1617,1622],"ul",{},[1599,1600,1601,1603],"li",{},[459,1602,52],{"href":153},": the Driver\u002FDisk\u002FManager model this driver plugs into.",[1599,1605,1606,1608,1609,1611],{},[459,1607,156],{"href":157},": the methods ",[450,1610,483],{}," exposes over any driver, including this one.",[1599,1613,1614,1616],{},[459,1615,160],{"href":161},": the drivers for tests and single-server deployments.",[1599,1618,1619,1621],{},[459,1620,169],{"href":170},": run the conformance suite against your own S3-compatible endpoint.",[1599,1623,1624,1626],{},[459,1625,209],{"href":210},": the minio-go version this driver pins.",[1628,1629,1630],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":507,"searchDepth":570,"depth":570,"links":1632},[1633,1634,1635,1636,1637,1638],{"id":499,"depth":570,"text":500},{"id":544,"depth":570,"text":545},{"id":868,"depth":570,"text":869},{"id":968,"depth":570,"text":969},{"id":1000,"depth":570,"text":1001},{"id":1593,"depth":570,"text":1594},"The S3-compatible driver, a separately versioned module built on minio-go.","md",null,{},{"icon":167},{"title":164,"description":1639},"fe_DGaTd03mrrOqRa7CwzmdI8vRRG3cFSnWmjHcxqQY",[1647,1649],{"title":160,"path":161,"stem":162,"description":1648,"icon":148,"children":-1},"The two drivers that ship in the root storage module, for tests and single-server deployments.",{"title":169,"path":170,"stem":171,"description":1650,"icon":172,"children":-1},"The storagetest conformance suite, and what a custom Driver needs to implement.",1785445902819]