[{"data":1,"prerenderedAt":515},["ShallowReactive",2],{"navigation_docs":3,"-modules-module-kit":69,"-modules-module-kit-surround":510},[4,20,30,39,60],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Overview",false,"\u002Fgetting-started","1.getting-started",[10,15],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Local Development","\u002Fgetting-started\u002Flocal-development","1.getting-started\u002F3.local-development","i-lucide-terminal",{"title":21,"path":22,"stem":23,"children":24,"page":6},"Applications","\u002Fapplications","2.applications",[25],{"title":26,"path":27,"stem":28,"icon":29},"Website","\u002Fapplications\u002Fwebsite","2.applications\u002F1.website","i-lucide-layout-dashboard",{"title":31,"path":32,"stem":33,"children":34},"Layers","\u002Flayers","3.layers",[35],{"title":36,"path":37,"stem":38},"Base Layer","\u002Flayers\u002Fbase","3.layers\u002F1.base",{"title":40,"path":41,"stem":42,"children":43},"Modules","\u002Fmodules","4.modules",[44,48,52,56],{"title":45,"path":46,"stem":47},"Users Module","\u002Fmodules\u002Fusers","4.modules\u002F1.users",{"title":49,"path":50,"stem":51},"OAuth Server Module","\u002Fmodules\u002Foauth-server","4.modules\u002F2.oauth-server",{"title":53,"path":54,"stem":55},"UI Module","\u002Fmodules\u002Fui","4.modules\u002F3.ui",{"title":57,"path":58,"stem":59},"Module Kit","\u002Fmodules\u002Fmodule-kit","4.modules\u002Fmodule-kit",{"title":61,"path":62,"stem":63,"children":64},"Packages","\u002Fpackages","5.packages",[65],{"title":66,"path":67,"stem":68},"CLI","\u002Fpackages\u002Fcli","5.packages\u002F4.cli",{"id":70,"title":57,"body":71,"description":503,"extension":504,"links":505,"meta":506,"navigation":507,"path":58,"seo":508,"stem":59,"__hash__":509},"docs\u002F4.modules\u002Fmodule-kit.md",{"type":72,"value":73,"toc":499},"minimark",[74,78,83,93,104,108,119,286,298,380,386,476,495],[75,76,77],"p",{},"A shared toolkit for building Nuxt modules in the Frigear workspace. It currently provides helpers for composing and\nextending database schemas while keeping table-specific behavior in the modules that own those tables.",[79,80,82],"h2",{"id":81},"purpose","Purpose",[84,85,86,90],"ul",{},[87,88,89],"li",{},"Share common module-development utilities across Frigear packages.",[87,91,92],{},"Let one module add columns to a table owned by another module without replacing its schema.",[75,94,95,96,103],{},"This Nuxt module is consumed by modules such as ",[97,98,99],"a",{"href":46},[100,101,102],"code",{},"@frigear-nu\u002Fusers",".",[79,105,107],{"id":106},"extending-a-database-table","Extending a database table",[75,109,110,111,114,115,118],{},"The table-owning module registers its schema with ",[100,112,113],{},"extendDatabaseTable"," from\n",[100,116,117],{},"@frigear-nu\u002Fmodule-kit\u002Futils",":",[120,121,126],"pre",{"className":122,"code":123,"language":124,"meta":125,"style":125},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","extendDatabaseTable(nuxt, {\n  name: 'users',\n  factory: 'defineUsersTable',\n  resolver: createResolver(import.meta.url),\n  schema: dialect => `.\u002Fruntime\u002Fdb\u002Fschema.${dialect}`,\n  override: options.settings?.schemas?.users,\n})\n","ts","",[100,127,128,147,169,186,216,249,277],{"__ignoreMap":125},[129,130,133,136,140,144],"span",{"class":131,"line":132},"line",1,[129,134,113],{"class":135},"s2Zo4",[129,137,139],{"class":138},"sTEyZ","(nuxt",[129,141,143],{"class":142},"sMK4o",",",[129,145,146],{"class":142}," {\n",[129,148,150,154,156,159,163,166],{"class":131,"line":149},2,[129,151,153],{"class":152},"swJcz","  name",[129,155,118],{"class":142},[129,157,158],{"class":142}," '",[129,160,162],{"class":161},"sfazB","users",[129,164,165],{"class":142},"'",[129,167,168],{"class":142},",\n",[129,170,172,175,177,179,182,184],{"class":131,"line":171},3,[129,173,174],{"class":152},"  factory",[129,176,118],{"class":142},[129,178,158],{"class":142},[129,180,181],{"class":161},"defineUsersTable",[129,183,165],{"class":142},[129,185,168],{"class":142},[129,187,189,192,194,197,200,204,206,209,211,214],{"class":131,"line":188},4,[129,190,191],{"class":152},"  resolver",[129,193,118],{"class":142},[129,195,196],{"class":135}," createResolver",[129,198,199],{"class":138},"(",[129,201,203],{"class":202},"s7zQu","import",[129,205,103],{"class":142},[129,207,208],{"class":138},"meta",[129,210,103],{"class":142},[129,212,213],{"class":138},"url)",[129,215,168],{"class":142},[129,217,219,222,224,228,232,235,238,241,244,247],{"class":131,"line":218},5,[129,220,221],{"class":135},"  schema",[129,223,118],{"class":142},[129,225,227],{"class":226},"sHdIc"," dialect",[129,229,231],{"class":230},"spNyl"," =>",[129,233,234],{"class":142}," `",[129,236,237],{"class":161},".\u002Fruntime\u002Fdb\u002Fschema.",[129,239,240],{"class":142},"${",[129,242,243],{"class":138},"dialect",[129,245,246],{"class":142},"}`",[129,248,168],{"class":142},[129,250,252,255,257,260,262,265,268,271,273,275],{"class":131,"line":251},6,[129,253,254],{"class":152},"  override",[129,256,118],{"class":142},[129,258,259],{"class":138}," options",[129,261,103],{"class":142},[129,263,264],{"class":138},"settings",[129,266,267],{"class":142},"?.",[129,269,270],{"class":138},"schemas",[129,272,267],{"class":142},[129,274,162],{"class":138},[129,276,168],{"class":142},[129,278,280,283],{"class":131,"line":279},7,[129,281,282],{"class":142},"}",[129,284,285],{"class":138},")\n",[75,287,288,289,292,293,297],{},"The schema file exports the named factory, which accepts an object of additional columns and returns a table. The factory must spread the received ",[100,290,291],{},"extra"," columns ",[294,295,296],"em",{},"last"," in the object passed to the table builder (after every one of its own fields, including timestamps), so extended columns always end up last in the generated migration, matching the order they were registered in. Other modules can register column files during setup:",[120,299,301],{"className":122,"code":300,"language":124,"meta":125,"style":125},"registerDatabaseTableExtension(nuxt, {\n  name: 'users',\n  resolver: createResolver(import.meta.url),\n  file: dialect => `.\u002Fruntime\u002Fdb\u002Fextra.${dialect}`,\n})\n",[100,302,303,314,328,350,374],{"__ignoreMap":125},[129,304,305,308,310,312],{"class":131,"line":132},[129,306,307],{"class":135},"registerDatabaseTableExtension",[129,309,139],{"class":138},[129,311,143],{"class":142},[129,313,146],{"class":142},[129,315,316,318,320,322,324,326],{"class":131,"line":149},[129,317,153],{"class":152},[129,319,118],{"class":142},[129,321,158],{"class":142},[129,323,162],{"class":161},[129,325,165],{"class":142},[129,327,168],{"class":142},[129,329,330,332,334,336,338,340,342,344,346,348],{"class":131,"line":171},[129,331,191],{"class":152},[129,333,118],{"class":142},[129,335,196],{"class":135},[129,337,199],{"class":138},[129,339,203],{"class":202},[129,341,103],{"class":142},[129,343,208],{"class":138},[129,345,103],{"class":142},[129,347,213],{"class":138},[129,349,168],{"class":142},[129,351,352,355,357,359,361,363,366,368,370,372],{"class":131,"line":188},[129,353,354],{"class":135},"  file",[129,356,118],{"class":142},[129,358,227],{"class":226},[129,360,231],{"class":230},[129,362,234],{"class":142},[129,364,365],{"class":161},".\u002Fruntime\u002Fdb\u002Fextra.",[129,367,240],{"class":142},[129,369,243],{"class":138},[129,371,246],{"class":142},[129,373,168],{"class":142},[129,375,376,378],{"class":131,"line":218},[129,377,282],{"class":142},[129,379,285],{"class":138},[75,381,382,383,118],{},"Each extension file exports column objects named for their tables. For example, a Nuxt layer can extend multiple tables\nin ",[100,384,385],{},"server\u002Fdb\u002Fextend.sqlite.ts",[120,387,389],{"className":122,"code":388,"language":124,"meta":125,"style":125},"export const users = defineExtendedColumns({ locale: text().default('da') })\nexport const posts = defineExtendedColumns({ summary: text() })\n",[100,390,391,445],{"__ignoreMap":125},[129,392,393,396,399,402,405,408,410,413,416,418,421,424,426,429,431,433,436,438,441,443],{"class":131,"line":132},[129,394,395],{"class":202},"export",[129,397,398],{"class":230}," const",[129,400,401],{"class":138}," users ",[129,403,404],{"class":142},"=",[129,406,407],{"class":135}," defineExtendedColumns",[129,409,199],{"class":138},[129,411,412],{"class":142},"{",[129,414,415],{"class":152}," locale",[129,417,118],{"class":142},[129,419,420],{"class":135}," text",[129,422,423],{"class":138},"()",[129,425,103],{"class":142},[129,427,428],{"class":135},"default",[129,430,199],{"class":138},[129,432,165],{"class":142},[129,434,435],{"class":161},"da",[129,437,165],{"class":142},[129,439,440],{"class":138},") ",[129,442,282],{"class":142},[129,444,285],{"class":138},[129,446,447,449,451,454,456,458,460,462,465,467,469,472,474],{"class":131,"line":149},[129,448,395],{"class":202},[129,450,398],{"class":230},[129,452,453],{"class":138}," posts ",[129,455,404],{"class":142},[129,457,407],{"class":135},[129,459,199],{"class":138},[129,461,412],{"class":142},[129,463,464],{"class":152}," summary",[129,466,118],{"class":142},[129,468,420],{"class":135},[129,470,471],{"class":138},"() ",[129,473,282],{"class":142},[129,475,285],{"class":138},[75,477,478,479,482,483,486,487,490,491,494],{},"Only the export matching the table being built is used. Existing registered files are merged in registration order (later fields replace earlier fields); missing files for a dialect are skipped. Registered files with legacy default exports still work. Nuxt layer files are merged next, from base layers toward the host application. Older ",[100,480,481],{},"server\u002Fdb\u002F\u003Cname>.extend.\u003Cdialect>"," files with default exports are also loaded before each layer's shared file, so a shared export can override them. Pass ",[100,484,485],{},"extensionFile: dialect => 'path\u002Fto\u002Fcolumns.' + dialect + '.ts'"," to change the per-layer file location. If ",[100,488,489],{},"override"," is a path instead of ",[100,492,493],{},"'default'",", the host schema replaces the generated table entirely; the path is resolved from the application's root directory.",[496,497,498],"style",{},"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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":125,"searchDepth":149,"depth":149,"links":500},[501,502],{"id":81,"depth":149,"text":82},{"id":106,"depth":149,"text":107},"Helpers for building Frigear Nuxt modules and extending database schemas.","md",null,{},true,{"title":57,"description":503},"JdPcX2-O1-XVNy8nHZ4bOIrNEFoXdGhXxx8xn_e8vnw",[511,513],{"title":53,"path":54,"stem":55,"description":512,"children":-1},"Nuxt module providing shared Vue components, composables, and integrations.",{"title":61,"path":62,"stem":63,"children":-1,"description":514},"Shared libraries and tools in the Frigear Nuxt workspace.",1791115849669]