[{"data":1,"prerenderedAt":419},["ShallowReactive",2],{"navigation_docs":3,"-modules":36,"-modules-surround":416},[4,8,12,16,20,24,28,32],{"title":5,"path":6,"stem":7},"Getting started","\u002Fgetting-started","1.getting-started",{"title":9,"path":10,"stem":11},"Core concepts","\u002Fcore-concepts","2.core-concepts",{"title":13,"path":14,"stem":15},"Cross-cutting concerns","\u002Fcross-cutting","3.cross-cutting",{"title":17,"path":18,"stem":19},"Tenancy & RLS","\u002Ftenancy-and-rls","4.tenancy-and-rls",{"title":21,"path":22,"stem":23},"How the codegen works","\u002Fhow-the-codegen-works","5.how-the-codegen-works",{"title":25,"path":26,"stem":27},"vs. NestJS","\u002Fvs-nestjs","6.vs-nestjs",{"title":29,"path":30,"stem":31},"Before \u002F after","\u002Fbefore-after","7.before-after",{"title":33,"path":34,"stem":35},"Modules","\u002Fmodules","8.modules",{"id":37,"title":33,"body":38,"description":409,"extension":410,"links":411,"meta":412,"navigation":413,"path":34,"seo":414,"stem":35,"__hash__":415},"docs\u002F8.modules.md",{"type":39,"value":40,"toc":402},"minimark",[41,59,157,171,176,241,264,268,275,283,298,302,328,334,348,374,378,385,388,392,398],[42,43,44,45,49,50,54,55,58],"p",{},"A feature folder is already a roost ",[46,47,48],"strong",{},"module",". Most apps never need more than that. When you do\nwant cross-feature wiring or a chain that applies to a whole folder, drop an optional\n",[51,52,53],"code",{},"*.module.ts"," and decorate a class with ",[51,56,57],{},"@RoostModule",".",[60,61,66],"pre",{"className":62,"code":63,"language":64,"meta":65,"style":65},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F server\u002Ffeatures\u002Fprojects\u002Fprojects.module.ts\n@RoostModule({\n  guards: [MemberGuard], \u002F\u002F applies to every route in projects\u002F\n  exports: [ProjectsService], \u002F\u002F the module's public surface\n})\nexport class ProjectsModule {}\n","ts","",[51,67,68,77,95,114,130,139],{"__ignoreMap":65},[69,70,73],"span",{"class":71,"line":72},"line",1,[69,74,76],{"class":75},"sHwdD","\u002F\u002F server\u002Ffeatures\u002Fprojects\u002Fprojects.module.ts\n",[69,78,80,84,88,92],{"class":71,"line":79},2,[69,81,83],{"class":82},"sMK4o","@",[69,85,87],{"class":86},"s2Zo4","RoostModule",[69,89,91],{"class":90},"sTEyZ","(",[69,93,94],{"class":82},"{\n",[69,96,98,102,105,108,111],{"class":71,"line":97},3,[69,99,101],{"class":100},"swJcz","  guards",[69,103,104],{"class":82},":",[69,106,107],{"class":90}," [MemberGuard]",[69,109,110],{"class":82},",",[69,112,113],{"class":75}," \u002F\u002F applies to every route in projects\u002F\n",[69,115,117,120,122,125,127],{"class":71,"line":116},4,[69,118,119],{"class":100},"  exports",[69,121,104],{"class":82},[69,123,124],{"class":90}," [ProjectsService]",[69,126,110],{"class":82},[69,128,129],{"class":75}," \u002F\u002F the module's public surface\n",[69,131,133,136],{"class":71,"line":132},5,[69,134,135],{"class":82},"}",[69,137,138],{"class":90},")\n",[69,140,142,146,150,154],{"class":71,"line":141},6,[69,143,145],{"class":144},"s7zQu","export",[69,147,149],{"class":148},"spNyl"," class",[69,151,153],{"class":152},"sBMFI"," ProjectsModule",[69,155,156],{"class":82}," {}\n",[42,158,159,160,162,163,166,167,170],{},"It's named ",[51,161,57],{}," (not ",[51,164,165],{},"@Module",") on purpose — a roost module lives in\n",[51,168,169],{},"server\u002Ffeatures\u002F**"," and is a different layer from a Nuxt module or layer.",[172,173,175],"h2",{"id":174},"what-it-declares","What it declares",[177,178,179,192],"table",{},[180,181,182],"thead",{},[183,184,185,189],"tr",{},[186,187,188],"th",{},"Field",[186,190,191],{},"Effect",[193,194,195,210,220],"tbody",{},[183,196,197,203],{},[198,199,200],"td",{},[51,201,202],{},"imports",[198,204,205,206,209],{},"other modules whose ",[46,207,208],{},"exported"," providers this module may depend on",[183,211,212,217],{},[198,213,214],{},[51,215,216],{},"exports",[198,218,219],{},"which of this module's providers are visible to importing modules",[183,221,222,234],{},[198,223,224,227,228,227,231],{},[51,225,226],{},"guards"," \u002F ",[51,229,230],{},"interceptors",[51,232,233],{},"filters",[198,235,236,237,240],{},"chains applied to ",[46,238,239],{},"every route"," in the folder, between the global and class levels",[42,242,243,244,255,256,259,260,263],{},"There is intentionally ",[46,245,246,247,250,251,254],{},"no ",[51,248,249],{},"providers","\u002F",[51,252,253],{},"controllers"," list"," — the folder is the discovery unit, so\nnothing is hand-maintained — and no ",[51,257,258],{},"forRoot","\u002Fdynamic form (config lives in ",[51,261,262],{},"nuxt.config",").",[172,265,267],{"id":266},"module-scoped-chains","Module-scoped chains",[42,269,270,271,274],{},"A chain on the module applies to every route in the folder, so you declare it once instead of\nrepeating an ",[51,272,273],{},"@UseGuards"," on each controller. The effective order is:",[60,276,281],{"className":277,"code":279,"language":280},[278],"language-text","global → module → class → method\n","text",[51,282,279],{"__ignoreMap":65},[42,284,285,286,289,290,293,294,297],{},"In ",[51,287,288],{},"manifest.json"," the module-contributed tokens are tagged ",[51,291,292],{},"(module)",", just as globals are tagged\n",[51,295,296],{},"(global)"," — so the full effective chain stays visible on disk.",[172,299,301],{"id":300},"encapsulation-enforced-at-build-time","Encapsulation (enforced at build time)",[42,303,304,305,307,308,311,312,315,316,318,319,318,322,324,325,327],{},"By default any provider can be injected anywhere (the container is flat). A ",[51,306,57],{}," adds a\nboundary: a provider in another folder can depend on ",[51,309,310],{},"ProjectsService"," only if ",[46,313,314],{},"its"," module\n",[51,317,202],{}," the projects module ",[46,320,321],{},"and",[51,323,216],{}," ",[51,326,310],{},". Otherwise the\ncodegen throws:",[60,329,332],{"className":330,"code":331,"language":280},[278],"[nuxt-roost] OrdersService depends on ProjectsService (module 'projects'),\nbut module 'orders' does not import ProjectsModule. Declare it via\n@RoostModule({ imports: [...] }) on the consumer and @RoostModule({ exports: [...] }) on the owner.\n",[51,333,331],{"__ignoreMap":65},[42,335,336,339,340,343,344,347],{},[51,337,338],{},"_shared\u002F"," — and any ",[51,341,342],{},"_","-prefixed folder — is ",[46,345,346],{},"implicitly global",": its providers (the usual home\nfor shared guards\u002Ffilters) are visible everywhere with no import\u002Fexport.",[349,350,351,362,363,366,367,369,370,373],"callout",{},[46,352,353,354,358,359,58],{},"Encapsulation gates DI ",[355,356,357],"em",{},"wiring",", not name ",[355,360,361],{},"visibility"," With ",[51,364,365],{},"autoImportFeatures"," every feature\nsymbol is in one flat auto-import namespace, so a name is always referenceable; ",[51,368,216],{}," controls\nonly what can be ",[46,371,372],{},"DI-resolved"," across a module boundary.",[172,375,377],{"id":376},"no-runtime-cost","No runtime cost",[42,379,380,381,384],{},"The boundary is a ",[46,382,383],{},"compile-time check"," — the generated awilix container is byte-for-byte what it\nwas without modules (no token namespacing, no per-module child containers). Modules are a build\nerror, not a resolver feature.",[42,386,387],{},"One consequence of the global token space: two providers can't share a class name. roost reports that\nas a clear duplicate-name error rather than letting one silently shadow the other.",[172,389,391],{"id":390},"adopt-incrementally","Adopt incrementally",[42,393,394,395,397],{},"Add one ",[51,396,53],{}," at a time. Folders without one keep working exactly as before — modules are\nopt-in.",[399,400,401],"style",{},"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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);}",{"title":65,"searchDepth":79,"depth":79,"links":403},[404,405,406,407,408],{"id":174,"depth":79,"text":175},{"id":266,"depth":79,"text":267},{"id":300,"depth":79,"text":301},{"id":376,"depth":79,"text":377},{"id":390,"depth":79,"text":391},"@RoostModule: cross-feature wiring and folder-wide chains, with encapsulation enforced at build time over a flat container.","md",null,{},true,{"title":33,"description":409},"ALmPnBKluK0vFI1BG6B0V6krz78rrvL5tIphQFg5Axw",[417,411],{"title":29,"path":30,"stem":31,"description":418,"children":-1},"The same feature hand-wired in plain Nitro vs. with roost — proven identical in behavior.",1780506502632]