@better-t-stack/template-generator 3.23.1 → 3.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"template-reader.d.mts","names":[],"sources":["../../src/core/template-reader.ts"],"sourcesContent":[],"mappings":";;;iBASgB,gBAAA,CAAA;iBAcA,sBAAA,CAAA;AAdA,iBA4BM,aAAA,CA5BU,MAAA,CAAA,EAAA,MAAA,CAAA,EA4BsB,OA5BtB,CA4B8B,GA5B9B,CAAA,MAAA,EAAA,MAAA,CAAA,CAAA;AAchB,iBAyCA,YAAA,CAzCsB,YAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,SAAA;AAchB,iBAkCA,aAAA,CAlCgC,MAAO,CAAA,EAAA,MAAA,CAAA,EAkCP,OAlCO,CAAA,MAAA,EAAA,CAAA"}
1
+ {"version":3,"file":"template-reader.d.mts","names":[],"sources":["../../src/core/template-reader.ts"],"sourcesContent":[],"mappings":";;;iBAUgB,gBAAA,CAAA;iBAcA,sBAAA,CAAA;AAdA,iBA4BM,aAAA,CA5BU,MAAA,CAAA,EAAA,MAAA,CAAA,EA4BsB,OA5BtB,CA4B8B,GA5B9B,CAAA,MAAA,EAAA,MAAA,CAAA,CAAA;AAchB,iBAyCA,YAAA,CAzCsB,YAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,SAAA;AAchB,iBAkCA,aAAA,CAlCgC,MAAO,CAAA,EAAA,MAAA,CAAA,EAkCP,OAlCO,CAAA,MAAA,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"fs-writer.d.mts","names":[],"sources":["../src/fs-writer.ts"],"sourcesContent":[],"mappings":";;;;;cAI2F,qBAAA,cAAA,CAAA;;;EAAA,KAAA,CAAA,EAAA,OAAA;AAS3F,CAAA,CAAA;AAUA;;;AAGW,cAbE,cAAA,SAAuB,mBAAA,CAazB;;AA8CX;;;AAIW,iBArDW,SAAA,CAqDX,IAAA,EApDH,eAoDG,EAAA,OAAA,EAAA,MAAA,CAAA,EAlDR,OAkDQ,CAlDA,MAkDA,CAAA,IAAA,EAlDa,cAkDb,CAAA,CAAA;;;;;iBAJW,aAAA,OACd,0EAGL,QAAQ,iBAAiB"}
1
+ {"version":3,"file":"fs-writer.d.mts","names":[],"sources":["../src/fs-writer.ts"],"sourcesContent":[],"mappings":";;;;;cAM2F,qBAAA,cAAA,CAAA;;;EAAA,KAAA,CAAA,EAAA,OAAA;AAO3F,CAAA,CAAA;AAUA;;;AAGW,cAbE,cAAA,SAAuB,mBAAA,CAazB;;AA8CX;;;AAIW,iBArDW,SAAA,CAqDX,IAAA,EApDH,eAoDG,EAAA,OAAA,EAAA,MAAA,CAAA,EAlDR,OAkDQ,CAlDA,MAkDA,CAAA,IAAA,EAlDa,cAkDb,CAAA,CAAA;;;;;iBAJW,aAAA,OACd,0EAGL,QAAQ,iBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"fs-writer.mjs","names":["writtenFiles: string[]"],"sources":["../src/fs-writer.ts"],"sourcesContent":["import { Result, TaggedError } from \"better-result\";\nimport * as fs from \"node:fs/promises\";\nimport { join, dirname } from \"pathe\";\n\nimport type { VirtualFileTree, VirtualNode, VirtualFile, VirtualDirectory } from \"./types\";\n\nimport { getBinaryTemplatesRoot } from \"./core/template-reader\";\n\nconst BINARY_FILE_MARKER = \"[Binary file]\";\n\n/**\n * Error class for filesystem write failures\n */\nexport class FileWriteError extends TaggedError(\"FileWriteError\")<{\n message: string;\n path?: string;\n cause?: unknown;\n}>() {}\n\n/**\n * Writes a virtual file tree to the filesystem.\n * Returns a Result type for type-safe error handling.\n */\nexport async function writeTree(\n tree: VirtualFileTree,\n destDir: string,\n): Promise<Result<void, FileWriteError>> {\n return Result.tryPromise({\n try: async () => {\n for (const child of tree.root.children) {\n await writeNodeInternal(child, destDir, \"\");\n }\n },\n catch: (e) => {\n if (FileWriteError.is(e)) return e;\n return new FileWriteError({\n message: e instanceof Error ? e.message : String(e),\n cause: e,\n });\n },\n });\n}\n\nasync function writeNodeInternal(\n node: VirtualNode,\n baseDir: string,\n relativePath: string,\n): Promise<void> {\n const fullPath = join(baseDir, relativePath, node.name);\n const nodePath = relativePath ? join(relativePath, node.name) : node.name;\n\n if (node.type === \"file\") {\n const fileNode = node as VirtualFile;\n await fs.mkdir(dirname(fullPath), { recursive: true });\n\n if (fileNode.content === BINARY_FILE_MARKER && fileNode.sourcePath) {\n await copyBinaryFile(fileNode.sourcePath, fullPath);\n } else if (fileNode.content !== BINARY_FILE_MARKER) {\n await fs.writeFile(fullPath, fileNode.content, \"utf-8\");\n }\n } else {\n await fs.mkdir(fullPath, { recursive: true });\n for (const child of (node as VirtualDirectory).children) {\n await writeNodeInternal(child, baseDir, nodePath);\n }\n }\n}\n\n/**\n * Writes selected files from a virtual file tree to the filesystem.\n * Returns a Result with the list of written file paths.\n */\nexport async function writeSelected(\n tree: VirtualFileTree,\n destDir: string,\n filter: (filePath: string) => boolean,\n): Promise<Result<string[], FileWriteError>> {\n return Result.tryPromise({\n try: async () => {\n const writtenFiles: string[] = [];\n await writeSelectedNodeInternal(tree.root, destDir, \"\", filter, writtenFiles);\n return writtenFiles;\n },\n catch: (e) => {\n if (FileWriteError.is(e)) return e;\n return new FileWriteError({\n message: e instanceof Error ? e.message : String(e),\n cause: e,\n });\n },\n });\n}\n\nasync function writeSelectedNodeInternal(\n node: VirtualNode,\n baseDir: string,\n relativePath: string,\n filter: (filePath: string) => boolean,\n writtenFiles: string[],\n): Promise<void> {\n const nodePath = relativePath ? `${relativePath}/${node.name}` : node.name;\n\n if (node.type === \"file\") {\n if (filter(nodePath)) {\n const fileNode = node as VirtualFile;\n await fs.mkdir(dirname(join(baseDir, nodePath)), { recursive: true });\n\n if (fileNode.content === BINARY_FILE_MARKER && fileNode.sourcePath) {\n await copyBinaryFile(fileNode.sourcePath, join(baseDir, nodePath));\n } else if (fileNode.content !== BINARY_FILE_MARKER) {\n await fs.writeFile(join(baseDir, nodePath), fileNode.content, \"utf-8\");\n }\n writtenFiles.push(nodePath);\n }\n } else {\n for (const child of (node as VirtualDirectory).children) {\n await writeSelectedNodeInternal(child, baseDir, nodePath, filter, writtenFiles);\n }\n }\n}\n\nasync function copyBinaryFile(templatePath: string, destPath: string): Promise<void> {\n const templatesRoot = getBinaryTemplatesRoot();\n const sourcePath = join(templatesRoot, templatePath);\n // Let errors propagate - they'll be caught by the Result wrapper\n await fs.copyFile(sourcePath, destPath);\n}\n"],"mappings":";;;;;;AAQA,MAAM,qBAAqB;;;;AAK3B,IAAa,iBAAb,cAAoC,YAAY,iBAAiB,EAI7D,CAAC;;;;;AAML,eAAsB,UACpB,MACA,SACuC;AACvC,QAAO,OAAO,WAAW;EACvB,KAAK,YAAY;AACf,QAAK,MAAM,SAAS,KAAK,KAAK,SAC5B,OAAM,kBAAkB,OAAO,SAAS,GAAG;;EAG/C,QAAQ,MAAM;AACZ,OAAI,eAAe,GAAG,EAAE,CAAE,QAAO;AACjC,UAAO,IAAI,eAAe;IACxB,SAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;IACnD,OAAO;IACR,CAAC;;EAEL,CAAC;;AAGJ,eAAe,kBACb,MACA,SACA,cACe;CACf,MAAM,WAAW,KAAK,SAAS,cAAc,KAAK,KAAK;CACvD,MAAM,WAAW,eAAe,KAAK,cAAc,KAAK,KAAK,GAAG,KAAK;AAErE,KAAI,KAAK,SAAS,QAAQ;EACxB,MAAM,WAAW;AACjB,QAAM,GAAG,MAAM,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AAEtD,MAAI,SAAS,YAAY,sBAAsB,SAAS,WACtD,OAAM,eAAe,SAAS,YAAY,SAAS;WAC1C,SAAS,YAAY,mBAC9B,OAAM,GAAG,UAAU,UAAU,SAAS,SAAS,QAAQ;QAEpD;AACL,QAAM,GAAG,MAAM,UAAU,EAAE,WAAW,MAAM,CAAC;AAC7C,OAAK,MAAM,SAAU,KAA0B,SAC7C,OAAM,kBAAkB,OAAO,SAAS,SAAS;;;;;;;AASvD,eAAsB,cACpB,MACA,SACA,QAC2C;AAC3C,QAAO,OAAO,WAAW;EACvB,KAAK,YAAY;GACf,MAAMA,eAAyB,EAAE;AACjC,SAAM,0BAA0B,KAAK,MAAM,SAAS,IAAI,QAAQ,aAAa;AAC7E,UAAO;;EAET,QAAQ,MAAM;AACZ,OAAI,eAAe,GAAG,EAAE,CAAE,QAAO;AACjC,UAAO,IAAI,eAAe;IACxB,SAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;IACnD,OAAO;IACR,CAAC;;EAEL,CAAC;;AAGJ,eAAe,0BACb,MACA,SACA,cACA,QACA,cACe;CACf,MAAM,WAAW,eAAe,GAAG,aAAa,GAAG,KAAK,SAAS,KAAK;AAEtE,KAAI,KAAK,SAAS,QAChB;MAAI,OAAO,SAAS,EAAE;GACpB,MAAM,WAAW;AACjB,SAAM,GAAG,MAAM,QAAQ,KAAK,SAAS,SAAS,CAAC,EAAE,EAAE,WAAW,MAAM,CAAC;AAErE,OAAI,SAAS,YAAY,sBAAsB,SAAS,WACtD,OAAM,eAAe,SAAS,YAAY,KAAK,SAAS,SAAS,CAAC;YACzD,SAAS,YAAY,mBAC9B,OAAM,GAAG,UAAU,KAAK,SAAS,SAAS,EAAE,SAAS,SAAS,QAAQ;AAExE,gBAAa,KAAK,SAAS;;OAG7B,MAAK,MAAM,SAAU,KAA0B,SAC7C,OAAM,0BAA0B,OAAO,SAAS,UAAU,QAAQ,aAAa;;AAKrF,eAAe,eAAe,cAAsB,UAAiC;CAEnF,MAAM,aAAa,KADG,wBAAwB,EACP,aAAa;AAEpD,OAAM,GAAG,SAAS,YAAY,SAAS"}
1
+ {"version":3,"file":"fs-writer.mjs","names":["writtenFiles: string[]"],"sources":["../src/fs-writer.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\n\nimport { Result, TaggedError } from \"better-result\";\nimport { join, dirname } from \"pathe\";\n\nimport { getBinaryTemplatesRoot } from \"./core/template-reader\";\nimport type { VirtualFileTree, VirtualNode, VirtualFile, VirtualDirectory } from \"./types\";\n\nconst BINARY_FILE_MARKER = \"[Binary file]\";\n\n/**\n * Error class for filesystem write failures\n */\nexport class FileWriteError extends TaggedError(\"FileWriteError\")<{\n message: string;\n path?: string;\n cause?: unknown;\n}>() {}\n\n/**\n * Writes a virtual file tree to the filesystem.\n * Returns a Result type for type-safe error handling.\n */\nexport async function writeTree(\n tree: VirtualFileTree,\n destDir: string,\n): Promise<Result<void, FileWriteError>> {\n return Result.tryPromise({\n try: async () => {\n for (const child of tree.root.children) {\n await writeNodeInternal(child, destDir, \"\");\n }\n },\n catch: (e) => {\n if (FileWriteError.is(e)) return e;\n return new FileWriteError({\n message: e instanceof Error ? e.message : String(e),\n cause: e,\n });\n },\n });\n}\n\nasync function writeNodeInternal(\n node: VirtualNode,\n baseDir: string,\n relativePath: string,\n): Promise<void> {\n const fullPath = join(baseDir, relativePath, node.name);\n const nodePath = relativePath ? join(relativePath, node.name) : node.name;\n\n if (node.type === \"file\") {\n const fileNode = node as VirtualFile;\n await fs.mkdir(dirname(fullPath), { recursive: true });\n\n if (fileNode.content === BINARY_FILE_MARKER && fileNode.sourcePath) {\n await copyBinaryFile(fileNode.sourcePath, fullPath);\n } else if (fileNode.content !== BINARY_FILE_MARKER) {\n await fs.writeFile(fullPath, fileNode.content, \"utf-8\");\n }\n } else {\n await fs.mkdir(fullPath, { recursive: true });\n for (const child of (node as VirtualDirectory).children) {\n await writeNodeInternal(child, baseDir, nodePath);\n }\n }\n}\n\n/**\n * Writes selected files from a virtual file tree to the filesystem.\n * Returns a Result with the list of written file paths.\n */\nexport async function writeSelected(\n tree: VirtualFileTree,\n destDir: string,\n filter: (filePath: string) => boolean,\n): Promise<Result<string[], FileWriteError>> {\n return Result.tryPromise({\n try: async () => {\n const writtenFiles: string[] = [];\n await writeSelectedNodeInternal(tree.root, destDir, \"\", filter, writtenFiles);\n return writtenFiles;\n },\n catch: (e) => {\n if (FileWriteError.is(e)) return e;\n return new FileWriteError({\n message: e instanceof Error ? e.message : String(e),\n cause: e,\n });\n },\n });\n}\n\nasync function writeSelectedNodeInternal(\n node: VirtualNode,\n baseDir: string,\n relativePath: string,\n filter: (filePath: string) => boolean,\n writtenFiles: string[],\n): Promise<void> {\n const nodePath = relativePath ? `${relativePath}/${node.name}` : node.name;\n\n if (node.type === \"file\") {\n if (filter(nodePath)) {\n const fileNode = node as VirtualFile;\n await fs.mkdir(dirname(join(baseDir, nodePath)), { recursive: true });\n\n if (fileNode.content === BINARY_FILE_MARKER && fileNode.sourcePath) {\n await copyBinaryFile(fileNode.sourcePath, join(baseDir, nodePath));\n } else if (fileNode.content !== BINARY_FILE_MARKER) {\n await fs.writeFile(join(baseDir, nodePath), fileNode.content, \"utf-8\");\n }\n writtenFiles.push(nodePath);\n }\n } else {\n for (const child of (node as VirtualDirectory).children) {\n await writeSelectedNodeInternal(child, baseDir, nodePath, filter, writtenFiles);\n }\n }\n}\n\nasync function copyBinaryFile(templatePath: string, destPath: string): Promise<void> {\n const templatesRoot = getBinaryTemplatesRoot();\n const sourcePath = join(templatesRoot, templatePath);\n // Let errors propagate - they'll be caught by the Result wrapper\n await fs.copyFile(sourcePath, destPath);\n}\n"],"mappings":";;;;;;AAQA,MAAM,qBAAqB;;;;AAK3B,IAAa,iBAAb,cAAoC,YAAY,iBAAiB,EAI7D,CAAC;;;;;AAML,eAAsB,UACpB,MACA,SACuC;AACvC,QAAO,OAAO,WAAW;EACvB,KAAK,YAAY;AACf,QAAK,MAAM,SAAS,KAAK,KAAK,SAC5B,OAAM,kBAAkB,OAAO,SAAS,GAAG;;EAG/C,QAAQ,MAAM;AACZ,OAAI,eAAe,GAAG,EAAE,CAAE,QAAO;AACjC,UAAO,IAAI,eAAe;IACxB,SAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;IACnD,OAAO;IACR,CAAC;;EAEL,CAAC;;AAGJ,eAAe,kBACb,MACA,SACA,cACe;CACf,MAAM,WAAW,KAAK,SAAS,cAAc,KAAK,KAAK;CACvD,MAAM,WAAW,eAAe,KAAK,cAAc,KAAK,KAAK,GAAG,KAAK;AAErE,KAAI,KAAK,SAAS,QAAQ;EACxB,MAAM,WAAW;AACjB,QAAM,GAAG,MAAM,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AAEtD,MAAI,SAAS,YAAY,sBAAsB,SAAS,WACtD,OAAM,eAAe,SAAS,YAAY,SAAS;WAC1C,SAAS,YAAY,mBAC9B,OAAM,GAAG,UAAU,UAAU,SAAS,SAAS,QAAQ;QAEpD;AACL,QAAM,GAAG,MAAM,UAAU,EAAE,WAAW,MAAM,CAAC;AAC7C,OAAK,MAAM,SAAU,KAA0B,SAC7C,OAAM,kBAAkB,OAAO,SAAS,SAAS;;;;;;;AASvD,eAAsB,cACpB,MACA,SACA,QAC2C;AAC3C,QAAO,OAAO,WAAW;EACvB,KAAK,YAAY;GACf,MAAMA,eAAyB,EAAE;AACjC,SAAM,0BAA0B,KAAK,MAAM,SAAS,IAAI,QAAQ,aAAa;AAC7E,UAAO;;EAET,QAAQ,MAAM;AACZ,OAAI,eAAe,GAAG,EAAE,CAAE,QAAO;AACjC,UAAO,IAAI,eAAe;IACxB,SAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;IACnD,OAAO;IACR,CAAC;;EAEL,CAAC;;AAGJ,eAAe,0BACb,MACA,SACA,cACA,QACA,cACe;CACf,MAAM,WAAW,eAAe,GAAG,aAAa,GAAG,KAAK,SAAS,KAAK;AAEtE,KAAI,KAAK,SAAS,QAChB;MAAI,OAAO,SAAS,EAAE;GACpB,MAAM,WAAW;AACjB,SAAM,GAAG,MAAM,QAAQ,KAAK,SAAS,SAAS,CAAC,EAAE,EAAE,WAAW,MAAM,CAAC;AAErE,OAAI,SAAS,YAAY,sBAAsB,SAAS,WACtD,OAAM,eAAe,SAAS,YAAY,KAAK,SAAS,SAAS,CAAC;YACzD,SAAS,YAAY,mBAC9B,OAAM,GAAG,UAAU,KAAK,SAAS,SAAS,EAAE,SAAS,SAAS,QAAQ;AAExE,gBAAa,KAAK,SAAS;;OAG7B,MAAK,MAAM,SAAU,KAA0B,SAC7C,OAAM,0BAA0B,OAAO,SAAS,UAAU,QAAQ,aAAa;;AAKrF,eAAe,eAAe,cAAsB,UAAiC;CAEnF,MAAM,aAAa,KADG,wBAAwB,EACP,aAAa;AAEpD,OAAM,GAAG,SAAS,YAAY,SAAS"}
package/dist/index.d.mts CHANGED
@@ -74,7 +74,7 @@ declare function writeBtsConfigToVfs(vfs: VirtualFileSystem, projectConfig: Proj
74
74
  //#endregion
75
75
  //#region src/templates.generated.d.ts
76
76
  declare const EMBEDDED_TEMPLATES: Map<string, string>;
77
- declare const TEMPLATE_COUNT = 441;
77
+ declare const TEMPLATE_COUNT = 444;
78
78
  //#endregion
79
79
  //#region src/utils/add-deps.d.ts
80
80
  declare const dependencyVersionMap: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/virtual-fs.ts","../src/core/template-processor.ts","../src/template-handlers/utils.ts","../src/template-handlers/addons.ts","../src/generator.ts","../src/processors/addons-deps.ts","../src/bts-config.ts","../src/templates.generated.ts","../src/utils/add-deps.ts","../src/utils/reproducible-command.ts"],"sourcesContent":[],"mappings":";;;;;;;cAOa,iBAAA;;;;;;EAAA,QAAA,CAAA,QAAA,EAAA,MAAiB,CAAA,EAAA,MAAA,GAAA,SAAA;EA6Ea,MAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,OAAA;EAkCX,UAAA,CAAA,QAAA,EAAA,MAAA,CAAA,EAAA,OAAA;EAAgB,eAcrC,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,OAAA;EAAA,KAGJ,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAA,UAAA,CAAA,QAAA,EAAA,MAAA,CAAA,EAAA,OAAA;;2CAnDoC;;ECzE3B,WAAA,CAAA,CAAA,EAAA,MAAA,EAAA;EAIA,iBAAY,CAAA,CAAA,EAAA,MAAA,EAAA;EAIZ,YAAA,CAAA,CAAA,EAAA,MAAiB;EAUjB,iBAAA,CAAA,CAAA,EAAkB,MAAA;6BDyFF;;eAAgB,MAAA,CAcrC;EE9HC,KAAA,CAAA,CAAA,EF8HD,MAAA,CAGJ,GEjIoB;;;;ECAL,QAAA,aAAA;;;;iBFKN,qBAAA,2BAAgD;iBAIhD,YAAA;iBAIA,iBAAA;iBAUA,kBAAA,6CAGL;;;KC1BC,YAAA,GAAe;;;iBCAL,qBAAA,MACf,8BACM,sBACH,gBACP;;;;;AHHH;;;;;;;;;ACIA;AAIA;AAIgB,iBG+BM,QAAA,CH/BW,OAAA,EGgCtB,gBHhCsB,CAAA,EGiC9B,OHjC8B,CGiCtB,MHjCsB,CGiCf,eHjCe,EGiCE,cHjCF,CAAA,CAAA;;;iBIJjB,iBAAA,MAAuB,2BAA2B;;;;;;;iBCLlD,mBAAA,MACT,kCACU;;;cCTJ,oBAAoB;cAsp0BpB,cAAA;;;cC5o0BA;;;ERNA,SAAA,mBAAiB,EAAA,OAAA;EA6Ea,SAAA,eAAA,EAAA,SAAA;EAkCX,SAAA,oBAAA,EAAA,SAAA;EAAgB,SAcrC,6BAAA,EAAA,SAAA;EAAA,SAGJ,mBAAA,EAAA,UAAA;EAAA,SAAA,aAAA,EAAA,SAAA;;;;EC5HS,SAAA,MAAA,EAAA,QAAqB;EAIrB,SAAA,0BAAY,EAAA,QAAA;EAIZ,SAAA,EAAA,EAAA,SAAiB;EAUjB,SAAA,WAAA,EAAkB,SAAA;;;;ECvBtB,SAAA,gBAAY,EAAG,QAAG;;;;ECAR,SAAA,yBAAqB,EAAA,QAAA;EACpC,SAAA,wBAAA,EAAA,QAAA;EACM,SAAA,gCAAA,EAAA,QAAA;EACH,SAAA,oBAAA,EAAA,QAAA;EACP,SAAA,6BAAA,EAAA,QAAA;EAAO,SAAA,QAAA,EAAA,SAAA;;;;ECwCY,SAAA,gBAAQ,EAAA,QAAA;EACnB,SAAA,MAAA,EAAA,SAAA;EACO,SAAA,KAAA,EAAA,SAAA;EAAiB,SAAA,KAAA,EAAA,QAAA;EAAxB,SAAA,QAAA,EAAA,SAAA;EAAR,SAAA,aAAA,EAAA,SAAA;EAAO,SAAA,GAAA,EAAA,SAAA;;;;ECrCM,SAAA,gBAAiB,EAAA,QAAM;;;;ECLvB,SAAA,mBAAmB,EAAA,QAC5B;;;;ECRM,SAAA,gBAop0BX,EAAA,QApp0B+B;EAsp0BpB,SAAA,aAAc,EAAA,SAAA;;;;EC5o0Bd,SAAA,EAAA,EAAA,SAAA;EAiJD,SAAA,EAAA,EAAA,QAAA;;;;ECnII,SAAA,eAAA,EAAA,QAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KDmI/B,qBAAA,gBAAqC;;;iBCnIjC,2BAAA,SAAoC"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/virtual-fs.ts","../src/core/template-processor.ts","../src/template-handlers/utils.ts","../src/template-handlers/addons.ts","../src/generator.ts","../src/processors/addons-deps.ts","../src/bts-config.ts","../src/templates.generated.ts","../src/utils/add-deps.ts","../src/utils/reproducible-command.ts"],"sourcesContent":[],"mappings":";;;;;;;cAOa,iBAAA;;;;;;EAAA,QAAA,CAAA,QAAA,EAAA,MAAiB,CAAA,EAAA,MAAA,GAAA,SAAA;EA6Ea,MAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAAA,OAAA;EAkCX,UAAA,CAAA,QAAA,EAAA,MAAA,CAAA,EAAA,OAAA;EAAgB,eAcrC,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,OAAA;EAAA,KAGJ,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAA,UAAA,CAAA,QAAA,EAAA,MAAA,CAAA,EAAA,OAAA;;2CAnDoC;;EC1E3B,WAAA,CAAA,CAAA,EAAA,MAAA,EAAA;EAIA,iBAAY,CAAA,CAAA,EAAA,MAAA,EAAA;EAIZ,YAAA,CAAA,CAAA,EAAA,MAAiB;EAUjB,iBAAA,CAAA,CAAA,EAAkB,MAAA;6BD0FF;;eAAgB,MAAA,CAcrC;EE/HC,KAAA,CAAA,CAAA,EF+HD,MAAA,CAGJ,GElIoB;;;;ECAL,QAAA,aAAA;;;;iBFKN,qBAAA,2BAAgD;iBAIhD,YAAA;iBAIA,iBAAA;iBAUA,kBAAA,6CAGL;;;KC1BC,YAAA,GAAe;;;iBCAL,qBAAA,MACf,8BACM,sBACH,gBACP;;;;;AHFH;;;;;;;;;ACGA;AAIA;AAIgB,iBG+BM,QAAA,CH/BW,OAAA,EGgCtB,gBHhCsB,CAAA,EGiC9B,OHjC8B,CGiCtB,MHjCsB,CGiCf,eHjCe,EGiCE,cHjCF,CAAA,CAAA;;;iBIJjB,iBAAA,MAAuB,2BAA2B;;;;;;;iBCJlD,mBAAA,MACT,kCACU;;;cCTJ,oBAAoB;cAwn0BpB,cAAA;;;cC9m0BA;;;ERNA,SAAA,mBAAiB,EAAA,OAAA;EA6Ea,SAAA,eAAA,EAAA,SAAA;EAkCX,SAAA,oBAAA,EAAA,SAAA;EAAgB,SAcrC,6BAAA,EAAA,SAAA;EAAA,SAGJ,mBAAA,EAAA,UAAA;EAAA,SAAA,aAAA,EAAA,SAAA;;;;EC7HS,SAAA,MAAA,EAAA,QAAqB;EAIrB,SAAA,0BAAY,EAAA,QAAA;EAIZ,SAAA,EAAA,EAAA,SAAiB;EAUjB,SAAA,WAAA,EAAkB,SAAA;;;;ECvBtB,SAAA,gBAAY,EAAG,QAAG;;;;ECAR,SAAA,yBAAqB,EAAA,QAAA;EACpC,SAAA,wBAAA,EAAA,QAAA;EACM,SAAA,gCAAA,EAAA,QAAA;EACH,SAAA,oBAAA,EAAA,QAAA;EACP,SAAA,6BAAA,EAAA,QAAA;EAAO,SAAA,QAAA,EAAA,SAAA;;;;ECwCY,SAAA,gBAAQ,EAAA,QAAA;EACnB,SAAA,MAAA,EAAA,SAAA;EACO,SAAA,KAAA,EAAA,SAAA;EAAiB,SAAA,KAAA,EAAA,QAAA;EAAxB,SAAA,QAAA,EAAA,SAAA;EAAR,SAAA,aAAA,EAAA,SAAA;EAAO,SAAA,GAAA,EAAA,SAAA;;;;ECrCM,SAAA,gBAAiB,EAAA,QAAM;;;;ECJvB,SAAA,mBAAmB,EAAA,QAC5B;;;;ECRM,SAAA,gBAsn0BX,EAAA,QAtn0B+B;EAwn0BpB,SAAA,aAAc,EAAA,SAAA;;;;EC9m0Bd,SAAA,EAAA,EAAA,SAAA;EAiJD,SAAA,EAAA,EAAA,QAAA;;;;ECnII,SAAA,eAAA,EAAA,QAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KDmI/B,qBAAA,gBAAqC;;;iBCnIjC,2BAAA,SAAoC"}
package/dist/index.mjs CHANGED
@@ -4,6 +4,7 @@ import { memfs } from "memfs";
4
4
  import { dirname, extname, join, normalize } from "pathe";
5
5
  import Handlebars from "handlebars";
6
6
  import yaml from "yaml";
7
+ import { desktopWebFrontends } from "@better-t-stack/types";
7
8
  import { IndentationText, Node, Project, QuoteKind, SyntaxKind } from "ts-morph";
8
9
 
9
10
  //#region src/types.ts
@@ -267,6 +268,7 @@ const PACKAGE_PATHS = [
267
268
  "apps/server",
268
269
  "apps/web",
269
270
  "apps/native",
271
+ "apps/desktop",
270
272
  "apps/fumadocs",
271
273
  "apps/docs",
272
274
  "packages/api",
@@ -408,6 +410,10 @@ function getDbScriptSupport(config) {
408
410
  //#endregion
409
411
  //#region src/post-process/package-configs.ts
410
412
  /**
413
+ * Package.json configuration post-processor
414
+ * Updates package names, scripts, and workspaces after template generation
415
+ */
416
+ /**
411
417
  * Update all package.json files with proper names, scripts, and workspaces
412
418
  */
413
419
  function processPackageConfigs(vfs, config) {
@@ -416,6 +422,7 @@ function processPackageConfigs(vfs, config) {
416
422
  updateEnvPackageJson(vfs, config);
417
423
  updateUiPackageJson(vfs, config);
418
424
  updateInfraPackageJson(vfs, config);
425
+ updateDesktopPackageJson(vfs, config);
419
426
  renameDevScriptsForAlchemy(vfs, config);
420
427
  if (config.backend === "convex") updateConvexPackageJson(vfs, config);
421
428
  else if (config.backend !== "none") {
@@ -435,16 +442,7 @@ function updateRootPackageJson(vfs, config) {
435
442
  pkgJson.workspaces = workspaces;
436
443
  const scripts = pkgJson.scripts;
437
444
  const { projectName, packageManager, backend, database, orm, dbSetup, addons, frontend } = config;
438
- const hasWebApp = frontend.some((item) => [
439
- "tanstack-router",
440
- "react-router",
441
- "tanstack-start",
442
- "next",
443
- "nuxt",
444
- "svelte",
445
- "solid",
446
- "astro"
447
- ].includes(item));
445
+ const hasWebApp = frontend.some((item) => desktopWebFrontends.includes(item));
448
446
  const hasNativeApp = frontend.some((item) => [
449
447
  "native-bare",
450
448
  "native-uniwind",
@@ -466,6 +464,11 @@ function updateRootPackageJson(vfs, config) {
466
464
  scripts["check-types"] = pmConfig.checkTypes;
467
465
  if (hasNativeApp) scripts["dev:native"] = pmConfig.filter("native", "dev");
468
466
  if (hasWebApp) scripts["dev:web"] = pmConfig.filter("web", "dev");
467
+ if (addons.includes("electrobun")) {
468
+ scripts["dev:desktop"] = pmConfig.filter("desktop", "dev:hmr");
469
+ scripts["build:desktop"] = pmConfig.filter("desktop", "build:stable");
470
+ scripts["build:desktop:canary"] = pmConfig.filter("desktop", "build:canary");
471
+ }
469
472
  if (addons.includes("opentui")) scripts["dev:tui"] = pmConfig.filter("tui", "dev");
470
473
  if (backend !== "self" && backend !== "none") scripts["dev:server"] = pmConfig.filter(backendPackageName, "dev");
471
474
  if (backend === "convex") scripts["dev:setup"] = pmConfig.filter(backendPackageName, "dev:setup");
@@ -537,6 +540,53 @@ function getPackageManagerConfig(packageManager, options) {
537
540
  };
538
541
  }
539
542
  }
543
+ function updateDesktopPackageJson(vfs, config) {
544
+ const pkgJson = vfs.readJson("apps/desktop/package.json");
545
+ if (!pkgJson) return;
546
+ const { packageManager, addons, frontend } = config;
547
+ const hasTurborepo = addons.includes("turborepo");
548
+ const hasNx = addons.includes("nx");
549
+ const desktopBuildScript = frontend.includes("nuxt") ? "generate" : "build";
550
+ const webBuildCommand = getDesktopWebCommand(packageManager, {
551
+ hasTurborepo,
552
+ hasNx
553
+ }, desktopBuildScript);
554
+ const webDevCommand = getDesktopWebCommand(packageManager, {
555
+ hasTurborepo,
556
+ hasNx
557
+ }, "dev");
558
+ const localRunCommand = getLocalRunCommand(packageManager);
559
+ pkgJson.scripts = {
560
+ ...pkgJson.scripts,
561
+ start: `${webBuildCommand} && electrobun dev`,
562
+ dev: "electrobun dev --watch",
563
+ "dev:hmr": `concurrently "${localRunCommand} hmr" "${localRunCommand} start"`,
564
+ hmr: webDevCommand,
565
+ build: `${webBuildCommand} && electrobun build`,
566
+ "build:stable": `${webBuildCommand} && electrobun build --env=stable`,
567
+ "build:canary": `${webBuildCommand} && electrobun build --env=canary`,
568
+ "check-types": "tsc --noEmit"
569
+ };
570
+ vfs.writeJson("apps/desktop/package.json", pkgJson);
571
+ }
572
+ function getDesktopWebCommand(packageManager, options, script) {
573
+ if (options.hasTurborepo) return `turbo -F web ${script}`;
574
+ if (options.hasNx) return `nx run-many -t ${script} --projects=web`;
575
+ switch (packageManager) {
576
+ case "npm": return `npm run ${script} --workspace web`;
577
+ case "pnpm": return `pnpm -w --filter web ${script}`;
578
+ case "bun":
579
+ default: return `bun run --filter web ${script}`;
580
+ }
581
+ }
582
+ function getLocalRunCommand(packageManager) {
583
+ switch (packageManager) {
584
+ case "npm": return "npm run";
585
+ case "pnpm": return "pnpm run";
586
+ case "bun":
587
+ default: return "bun run";
588
+ }
589
+ }
540
590
  function updateDbPackageJson(vfs, config) {
541
591
  const pkgJson = vfs.readJson("packages/db/package.json");
542
592
  if (!pkgJson) return;
@@ -591,15 +641,7 @@ function updateEnvPackageJson(vfs, config) {
591
641
  const pkgJson = vfs.readJson("packages/env/package.json");
592
642
  if (!pkgJson) return;
593
643
  pkgJson.name = `@${config.projectName}/env`;
594
- const hasWebFrontend = config.frontend.some((f) => [
595
- "tanstack-router",
596
- "react-router",
597
- "tanstack-start",
598
- "next",
599
- "nuxt",
600
- "svelte",
601
- "solid"
602
- ].includes(f));
644
+ const hasWebFrontend = config.frontend.some((f) => desktopWebFrontends.includes(f));
603
645
  const hasNative = config.frontend.some((f) => [
604
646
  "native-bare",
605
647
  "native-uniwind",
@@ -2374,6 +2416,18 @@ function processPwaPlugins(vfs, config) {
2374
2416
 
2375
2417
  //#endregion
2376
2418
  //#region src/processors/readme-generator.ts
2419
+ function getDesktopStaticBuildNote(frontend) {
2420
+ const staticBuildFrontends = new Map([
2421
+ ["tanstack-start", "TanStack Start"],
2422
+ ["next", "Next.js"],
2423
+ ["nuxt", "Nuxt"],
2424
+ ["svelte", "SvelteKit"],
2425
+ ["astro", "Astro"]
2426
+ ]);
2427
+ const staticBuildFrontend = frontend.find((value) => staticBuildFrontends.has(value));
2428
+ if (!staticBuildFrontend) return "";
2429
+ return `Desktop builds package static web assets. ${staticBuildFrontends.get(staticBuildFrontend)} needs a static/export build configuration before desktop packaging will work.`;
2430
+ }
2377
2431
  function processReadme(vfs, config) {
2378
2432
  const content = generateReadmeContent(config);
2379
2433
  vfs.writeFile("README.md", content);
@@ -2638,6 +2692,7 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
2638
2692
  const addonFeatures = {
2639
2693
  pwa: "- **PWA** - Progressive Web App support",
2640
2694
  tauri: "- **Tauri** - Build native desktop applications",
2695
+ electrobun: "- **Electrobun** - Lightweight desktop shell for web frontends",
2641
2696
  biome: "- **Biome** - Linting and formatting",
2642
2697
  oxlint: "- **Oxlint** - Oxlint + Oxfmt (linting & formatting)",
2643
2698
  husky: "- **Husky** - Git hooks for code quality",
@@ -2725,8 +2780,19 @@ function generateScriptsList(packageManagerRunCmd, config, hasNative) {
2725
2780
  if (addons.includes("biome")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Biome formatting and linting`;
2726
2781
  if (addons.includes("oxlint")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Oxlint and Oxfmt`;
2727
2782
  if (addons.includes("pwa")) scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} generate-pwa-assets\`: Generate PWA assets`;
2728
- if (addons.includes("tauri")) scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} desktop:dev\`: Start Tauri desktop app in development
2783
+ if (addons.includes("tauri")) {
2784
+ scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} desktop:dev\`: Start Tauri desktop app in development
2729
2785
  - \`cd apps/web && ${packageManagerRunCmd} desktop:build\`: Build Tauri desktop app`;
2786
+ const staticBuildNote = getDesktopStaticBuildNote(frontend);
2787
+ if (staticBuildNote) scripts += `\n- Note: ${staticBuildNote}`;
2788
+ }
2789
+ if (addons.includes("electrobun")) {
2790
+ scripts += `\n- \`${packageManagerRunCmd} dev:desktop\`: Start the Electrobun desktop app with HMR
2791
+ - \`${packageManagerRunCmd} build:desktop\`: Build the stable Electrobun desktop app
2792
+ - \`${packageManagerRunCmd} build:desktop:canary\`: Build the canary Electrobun desktop app`;
2793
+ const staticBuildNote = getDesktopStaticBuildNote(frontend);
2794
+ if (staticBuildNote) scripts += `\n- Note: ${staticBuildNote}`;
2795
+ }
2730
2796
  if (addons.includes("starlight")) scripts += `\n- \`cd apps/docs && ${packageManagerRunCmd} dev\`: Start documentation site
2731
2797
  - \`cd apps/docs && ${packageManagerRunCmd} build\`: Build documentation site`;
2732
2798
  return scripts;
@@ -3673,6 +3739,114 @@ const EMBEDDED_TEMPLATES = new Map([
3673
3739
  ]
3674
3740
  {{/if}}
3675
3741
  }
3742
+ `],
3743
+ ["addons/electrobun/apps/desktop/.gitignore", `artifacts
3744
+ `],
3745
+ ["addons/electrobun/apps/desktop/electrobun.config.ts.hbs", `import type { ElectrobunConfig } from "electrobun";
3746
+
3747
+ const webBuildDir =
3748
+ "{{#if (includes frontend "react-router")}}../web/build/client{{else if (includes frontend "tanstack-start")}}../web/dist/client{{else if (includes frontend "next")}}../web/out{{else if (includes frontend "nuxt")}}../web/.output/public{{else if (includes frontend "svelte")}}../web/build{{else}}../web/dist{{/if}}";
3749
+
3750
+ export default {
3751
+ app: {
3752
+ name: "{{projectName}}",
3753
+ identifier: "dev.bettertstack.{{projectName}}.desktop",
3754
+ version: "0.0.1",
3755
+ },
3756
+ runtime: {
3757
+ exitOnLastWindowClosed: true,
3758
+ },
3759
+ build: {
3760
+ bun: {
3761
+ entrypoint: "src/bun/index.ts",
3762
+ },
3763
+ copy: {
3764
+ [webBuildDir]: "views/mainview",
3765
+ },
3766
+ watchIgnore: [\`\${webBuildDir}/**\`],
3767
+ mac: {
3768
+ bundleCEF: true,
3769
+ defaultRenderer: "cef",
3770
+ },
3771
+ linux: {
3772
+ bundleCEF: true,
3773
+ defaultRenderer: "cef",
3774
+ },
3775
+ win: {
3776
+ bundleCEF: true,
3777
+ defaultRenderer: "cef",
3778
+ },
3779
+ },
3780
+ } satisfies ElectrobunConfig;
3781
+ `],
3782
+ ["addons/electrobun/apps/desktop/package.json.hbs", `{
3783
+ "name": "desktop",
3784
+ "private": true,
3785
+ "type": "module",
3786
+ "scripts": {},
3787
+ "dependencies": {
3788
+ "electrobun": "^1.15.1"
3789
+ },
3790
+ "devDependencies": {
3791
+ "@types/bun": "^1.3.4",
3792
+ "concurrently": "^9.1.0",
3793
+ "typescript": "^5"
3794
+ }
3795
+ }
3796
+ `],
3797
+ ["addons/electrobun/apps/desktop/src/bun/index.ts.hbs", `import { BrowserWindow, Updater } from "electrobun/bun";
3798
+
3799
+ const DEV_SERVER_PORT = {{#if (or (includes frontend "react-router") (includes frontend "svelte"))}}5173{{else if (includes frontend "astro")}}4321{{else}}3001{{/if}};
3800
+ const DEV_SERVER_URL = \`http://localhost:\${DEV_SERVER_PORT}\`;
3801
+
3802
+ // Check if the web dev server is running for HMR
3803
+ async function getMainViewUrl(): Promise<string> {
3804
+ const channel = await Updater.localInfo.channel();
3805
+ if (channel === "dev") {
3806
+ try {
3807
+ await fetch(DEV_SERVER_URL, { method: "HEAD" });
3808
+ console.log(\`HMR enabled: Using web dev server at \${DEV_SERVER_URL}\`);
3809
+ return DEV_SERVER_URL;
3810
+ } catch {
3811
+ console.log(
3812
+ 'Web dev server not running. Run "{{packageManager}} run dev:hmr" for HMR support.',
3813
+ );
3814
+ }
3815
+ }
3816
+
3817
+ return "views://mainview/index.html";
3818
+ }
3819
+
3820
+ const url = await getMainViewUrl();
3821
+
3822
+ new BrowserWindow({
3823
+ title: "{{projectName}}",
3824
+ url,
3825
+ frame: {
3826
+ width: 1280,
3827
+ height: 820,
3828
+ x: 120,
3829
+ y: 120,
3830
+ },
3831
+ });
3832
+
3833
+ console.log("Electrobun desktop shell started.");
3834
+ `],
3835
+ ["addons/electrobun/apps/desktop/tsconfig.json.hbs", `{
3836
+ "extends": "../../packages/config/tsconfig.base.json",
3837
+ "compilerOptions": {
3838
+ "lib": ["ESNext", "DOM"],
3839
+ "target": "ESNext",
3840
+ "module": "ESNext",
3841
+ "moduleResolution": "bundler",
3842
+ "noEmit": true,
3843
+ "baseUrl": ".",
3844
+ "paths": {
3845
+ "@/*": ["./src/*"]
3846
+ }
3847
+ },
3848
+ "include": ["src/**/*.ts", "electrobun.config.ts"]
3849
+ }
3676
3850
  `],
3677
3851
  ["addons/husky/.husky/pre-commit", `lint-staged
3678
3852
  `],
@@ -3773,142 +3947,6 @@ export default defineConfig({
3773
3947
  preset,
3774
3948
  images: ["public/logo.png"],
3775
3949
  });
3776
- `],
3777
- ["addons/ruler/.ruler/bts.md.hbs", `# Better-T-Stack Project Rules
3778
-
3779
- This is a {{projectName}} project created with Better-T-Stack CLI.
3780
-
3781
- ## Project Structure
3782
-
3783
- This is a monorepo with the following structure:
3784
-
3785
- {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
3786
- (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
3787
- - **\`apps/web/\`** - {{#if (eq backend "self")}}Fullstack application{{else}}Frontend application{{/if}}{{#if (includes frontend "tanstack-router")}} (React with TanStack Router){{else if (includes frontend "react-router")}} (React with React Router){{else if (includes frontend "tanstack-start")}} (TanStack Start){{else if (includes frontend "next")}} (Next.js){{else if (includes frontend "nuxt")}} (Nuxt.js){{else if (includes frontend "svelte")}} (SvelteKit){{else if (includes frontend "solid")}} (SolidStart){{/if}}
3788
- {{/if}}
3789
-
3790
- {{#if (ne backend "convex")}}
3791
- {{#if (and (ne backend "none") (ne backend "self"))}}
3792
- - **\`apps/server/\`** - Backend server{{#if (eq backend "hono")}} (Hono){{else if (eq backend "express")}} (Express){{else if (eq backend "fastify")}} (Fastify){{else if (eq backend "elysia")}} (Elysia){{/if}}
3793
- {{/if}}
3794
- {{else}}
3795
- - **\`packages/backend/\`** - Convex backend functions
3796
- {{/if}}
3797
-
3798
- {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
3799
- - **\`apps/native/\`** - React Native mobile app{{#if (includes frontend "native-uniwind")}} (with NativeWind){{else if (includes frontend "native-unistyles")}} (with Unistyles){{else if (includes frontend "native-bare")}} (bare styling){{/if}}
3800
- {{/if}}
3801
-
3802
- {{#if (ne backend "convex")}}
3803
- {{#if (ne api "none")}}
3804
- - **\`packages/api/\`** - Shared API logic and types
3805
- {{/if}}
3806
- {{#if (and (ne auth "none") (ne backend "convex"))}}
3807
- - **\`packages/auth/\`** - Authentication logic and utilities
3808
- {{/if}}
3809
- {{#if (and (ne database "none") (ne orm "none"))}}
3810
- - **\`packages/db/\`** - Database schema and utilities
3811
- {{/if}}
3812
- - **\`packages/env/\`** - Shared environment variables and validation
3813
- - **\`packages/config/\`** - Shared TypeScript configuration
3814
- {{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare"))}}
3815
- - **\`packages/infra/\`** - Infrastructure as code (Alchemy for Cloudflare)
3816
- {{/if}}
3817
- {{/if}}
3818
-
3819
- ## Available Scripts
3820
-
3821
- - \`{{packageManager}} run dev\` - Start all apps in development mode
3822
- {{#if (and (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
3823
- (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid")) (ne backend "self"))}}
3824
- - \`{{packageManager}} run dev:web\` - Start only the web app
3825
- {{/if}}
3826
- {{#if (and (ne backend "none") (ne backend "convex") (ne backend "self"))}}
3827
- - \`{{packageManager}} run dev:server\` - Start only the server
3828
- {{/if}}
3829
- {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
3830
- - \`{{packageManager}} run dev:native\` - Start only the native app
3831
- {{/if}}
3832
- - \`{{packageManager}} run build\` - Build all apps
3833
- - \`{{packageManager}} run lint\` - Lint all packages
3834
- - \`{{packageManager}} run typecheck\` - Type check all packages
3835
-
3836
- {{#if (and (ne database "none") (ne orm "none") (ne backend "convex"))}}
3837
- ## Database Commands
3838
-
3839
- All database operations should be run from the {{#if (eq backend "self")}}web{{else}}server{{/if}} workspace:
3840
-
3841
- - \`{{packageManager}} run db:push\` - Push schema changes to database
3842
- - \`{{packageManager}} run db:studio\` - Open database studio
3843
- - \`{{packageManager}} run db:generate\` - Generate {{#if (eq orm "drizzle")}}Drizzle{{else if (eq orm "prisma")}}Prisma{{else}}{{orm}}{{/if}} files
3844
- - \`{{packageManager}} run db:migrate\` - Run database migrations
3845
-
3846
- {{#if (eq orm "drizzle")}}
3847
- Database schema files are located in {{#if (eq backend "self")}}\`apps/web/src/db/schema/\`{{else}}\`packages/db/src/schema/\`{{/if}}
3848
- {{else if (eq orm "prisma")}}
3849
- Database schema is located in {{#if (eq backend "self")}}\`apps/web/prisma/schema.prisma\`{{else}}\`packages/db/prisma/schema.prisma\`{{/if}}
3850
- {{else if (eq orm "mongoose")}}
3851
- Database models are located in {{#if (eq backend "self")}}\`apps/web/src/db/models/\`{{else}}\`packages/db/src/models/\`{{/if}}
3852
- {{/if}}
3853
- {{/if}}
3854
-
3855
- {{#if (ne api "none")}}
3856
- ## API Structure
3857
-
3858
- {{#if (eq api "trpc")}}
3859
- - tRPC routers are in \`packages/api/src/routers/\`
3860
- - Client-side tRPC utils are in \`apps/web/src/utils/trpc.ts\`
3861
- {{else if (eq api "orpc")}}
3862
- - oRPC contracts and routers are in \`packages/api/src/\`
3863
- - Client-side oRPC client is in \`apps/web/src/utils/orpc.ts\`
3864
- {{/if}}
3865
- {{/if}}
3866
-
3867
- {{#if (eq auth "better-auth")}}
3868
- ## Authentication
3869
-
3870
- Authentication is powered by Better Auth:
3871
- - Auth configuration is in \`packages/auth/src/\`
3872
- {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
3873
- (includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
3874
- - Web app auth client is in \`apps/web/src/lib/auth-client.ts\`
3875
- {{/if}}
3876
- {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
3877
- - Native app auth client is in \`apps/native/src/lib/auth-client.ts\`
3878
- {{/if}}
3879
- {{/if}}
3880
-
3881
- ## Project Configuration
3882
-
3883
- This project includes a \`bts.jsonc\` configuration file that stores your Better-T-Stack settings:
3884
-
3885
- - Contains your selected stack configuration (database, ORM, backend, frontend, etc.)
3886
- - Used by the CLI to understand your project structure
3887
- - Safe to delete if not needed
3888
-
3889
- ## Key Points
3890
-
3891
- - This is a {{#if (includes addons "turborepo")}}Turborepo {{/if}}monorepo using {{packageManager}} workspaces
3892
- - Each app has its own \`package.json\` and dependencies
3893
- - Run commands from the root to execute across all workspaces
3894
- - Run workspace-specific commands with \`{{packageManager}} run command-name\`
3895
- {{#if (includes addons "turborepo")}}
3896
- - Turborepo handles build caching and parallel execution
3897
- {{/if}}
3898
- {{#if (or (includes addons "husky") (includes addons "lefthook"))}}
3899
- - Git hooks are configured with {{#if (includes addons "husky")}}Husky{{else}}Lefthook{{/if}} for pre-commit checks
3900
- {{/if}}
3901
- `],
3902
- ["addons/ruler/.ruler/ruler.toml.hbs", `# Ruler Configuration File
3903
- # See https://okigu.com/ruler for documentation.
3904
-
3905
- # Default agents to run when --agents is not specified
3906
- default_agents = []
3907
-
3908
- # --- Global .gitignore Configuration ---
3909
- [gitignore]
3910
- # Enable/disable automatic .gitignore updates (default: true)
3911
- enabled = true
3912
3950
  `],
3913
3951
  ["api/orpc/fullstack/astro/src/pages/rpc/[...rest].ts.hbs", `import type { APIRoute } from "astro";
3914
3952
  import { RPCHandler } from "@orpc/server/fetch";
@@ -4172,24 +4210,23 @@ export const queryClient = new QueryClient({
4172
4210
 
4173
4211
  export const link = new RPCLink({
4174
4212
  {{#if (eq backend "self")}}
4175
- {{#unless (includes frontend "astro")}}
4213
+ {{#if (or (includes frontend "next") (includes frontend "tanstack-start"))}}
4176
4214
  url: \`\${env.EXPO_PUBLIC_SERVER_URL}/api/rpc\`,
4177
4215
  {{else}}
4178
4216
  url: \`\${env.EXPO_PUBLIC_SERVER_URL}/rpc\`,
4179
- {{/unless}}
4217
+ {{/if}}
4180
4218
  {{else}}
4181
4219
  url: \`\${env.EXPO_PUBLIC_SERVER_URL}/rpc\`,
4182
4220
  {{/if}}
4183
4221
  {{#if (eq auth "better-auth")}}
4184
4222
  fetch:
4185
- Platform.OS !== "web"
4186
- ? undefined
4187
- : function (url, options) {
4188
- return fetch(url, {
4189
- ...options,
4190
- credentials: "include",
4191
- });
4192
- },
4223
+ function (url, options) {
4224
+ return fetch(url, {
4225
+ ...options,
4226
+ // Better Auth Expo forwards the session cookie manually on native.
4227
+ credentials: Platform.OS === "web" ? "include" : "omit",
4228
+ });
4229
+ },
4193
4230
  headers() {
4194
4231
  if (Platform.OS === "web") {
4195
4232
  return {};
@@ -4877,14 +4914,13 @@ const trpcClient = createTRPCClient<AppRouter>({
4877
4914
  {{/if}}
4878
4915
  {{#if (eq auth "better-auth")}}
4879
4916
  fetch:
4880
- Platform.OS !== "web"
4881
- ? undefined
4882
- : function (url, options) {
4883
- return fetch(url, {
4884
- ...options,
4885
- credentials: "include",
4886
- });
4887
- },
4917
+ function (url, options) {
4918
+ return fetch(url, {
4919
+ ...options,
4920
+ // Better Auth Expo forwards the session cookie manually on native.
4921
+ credentials: Platform.OS === "web" ? "include" : "omit",
4922
+ });
4923
+ },
4888
4924
  headers() {
4889
4925
  if (Platform.OS === "web") {
4890
4926
  return {};
@@ -30348,7 +30384,7 @@ function SuccessPage() {
30348
30384
  </div>
30349
30385
  `]
30350
30386
  ]);
30351
- const TEMPLATE_COUNT = 441;
30387
+ const TEMPLATE_COUNT = 444;
30352
30388
 
30353
30389
  //#endregion
30354
30390
  export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processTemplateString, transformFilename, writeBtsConfigToVfs };