@better-t-stack/template-generator 3.23.0 → 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.
- package/dist/core/template-reader.d.mts.map +1 -1
- package/dist/fs-writer.d.mts.map +1 -1
- package/dist/fs-writer.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +231 -170
- package/dist/index.mjs.map +1 -1
- package/dist/template-reader-DOXCnctl.mjs.map +1 -1
- package/dist/types-zSU486rU.d.mts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-reader.d.mts","names":[],"sources":["../../src/core/template-reader.ts"],"sourcesContent":[],"mappings":";;;
|
|
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"}
|
package/dist/fs-writer.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-writer.d.mts","names":[],"sources":["../src/fs-writer.ts"],"sourcesContent":[],"mappings":";;;;;
|
|
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"}
|
package/dist/fs-writer.mjs.map
CHANGED
|
@@ -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
|
|
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 =
|
|
77
|
+
declare const TEMPLATE_COUNT = 444;
|
|
78
78
|
//#endregion
|
|
79
79
|
//#region src/utils/add-deps.d.ts
|
|
80
80
|
declare const dependencyVersionMap: {
|
package/dist/index.d.mts.map
CHANGED
|
@@ -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;;
|
|
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") {
|
|
@@ -434,7 +441,13 @@ function updateRootPackageJson(vfs, config) {
|
|
|
434
441
|
else if (pkgJson.workspaces && typeof pkgJson.workspaces === "object" && pkgJson.workspaces.packages) workspaces = pkgJson.workspaces.packages;
|
|
435
442
|
pkgJson.workspaces = workspaces;
|
|
436
443
|
const scripts = pkgJson.scripts;
|
|
437
|
-
const { projectName, packageManager, backend, database, orm, dbSetup, addons } = config;
|
|
444
|
+
const { projectName, packageManager, backend, database, orm, dbSetup, addons, frontend } = config;
|
|
445
|
+
const hasWebApp = frontend.some((item) => desktopWebFrontends.includes(item));
|
|
446
|
+
const hasNativeApp = frontend.some((item) => [
|
|
447
|
+
"native-bare",
|
|
448
|
+
"native-uniwind",
|
|
449
|
+
"native-unistyles"
|
|
450
|
+
].includes(item));
|
|
438
451
|
const backendPackageName = backend === "convex" ? `@${projectName}/backend` : "server";
|
|
439
452
|
const dbPackageName = `@${projectName}/db`;
|
|
440
453
|
const hasTurborepo = addons.includes("turborepo");
|
|
@@ -449,8 +462,13 @@ function updateRootPackageJson(vfs, config) {
|
|
|
449
462
|
scripts.dev = pmConfig.dev;
|
|
450
463
|
scripts.build = pmConfig.build;
|
|
451
464
|
scripts["check-types"] = pmConfig.checkTypes;
|
|
452
|
-
scripts["dev:native"] = pmConfig.filter("native", "dev");
|
|
453
|
-
scripts["dev:web"] = pmConfig.filter("web", "dev");
|
|
465
|
+
if (hasNativeApp) scripts["dev:native"] = pmConfig.filter("native", "dev");
|
|
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
|
+
}
|
|
454
472
|
if (addons.includes("opentui")) scripts["dev:tui"] = pmConfig.filter("tui", "dev");
|
|
455
473
|
if (backend !== "self" && backend !== "none") scripts["dev:server"] = pmConfig.filter(backendPackageName, "dev");
|
|
456
474
|
if (backend === "convex") scripts["dev:setup"] = pmConfig.filter(backendPackageName, "dev:setup");
|
|
@@ -522,6 +540,53 @@ function getPackageManagerConfig(packageManager, options) {
|
|
|
522
540
|
};
|
|
523
541
|
}
|
|
524
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
|
+
}
|
|
525
590
|
function updateDbPackageJson(vfs, config) {
|
|
526
591
|
const pkgJson = vfs.readJson("packages/db/package.json");
|
|
527
592
|
if (!pkgJson) return;
|
|
@@ -576,15 +641,7 @@ function updateEnvPackageJson(vfs, config) {
|
|
|
576
641
|
const pkgJson = vfs.readJson("packages/env/package.json");
|
|
577
642
|
if (!pkgJson) return;
|
|
578
643
|
pkgJson.name = `@${config.projectName}/env`;
|
|
579
|
-
const hasWebFrontend = config.frontend.some((f) =>
|
|
580
|
-
"tanstack-router",
|
|
581
|
-
"react-router",
|
|
582
|
-
"tanstack-start",
|
|
583
|
-
"next",
|
|
584
|
-
"nuxt",
|
|
585
|
-
"svelte",
|
|
586
|
-
"solid"
|
|
587
|
-
].includes(f));
|
|
644
|
+
const hasWebFrontend = config.frontend.some((f) => desktopWebFrontends.includes(f));
|
|
588
645
|
const hasNative = config.frontend.some((f) => [
|
|
589
646
|
"native-bare",
|
|
590
647
|
"native-uniwind",
|
|
@@ -2359,6 +2416,18 @@ function processPwaPlugins(vfs, config) {
|
|
|
2359
2416
|
|
|
2360
2417
|
//#endregion
|
|
2361
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
|
+
}
|
|
2362
2431
|
function processReadme(vfs, config) {
|
|
2363
2432
|
const content = generateReadmeContent(config);
|
|
2364
2433
|
vfs.writeFile("README.md", content);
|
|
@@ -2623,6 +2692,7 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
|
|
|
2623
2692
|
const addonFeatures = {
|
|
2624
2693
|
pwa: "- **PWA** - Progressive Web App support",
|
|
2625
2694
|
tauri: "- **Tauri** - Build native desktop applications",
|
|
2695
|
+
electrobun: "- **Electrobun** - Lightweight desktop shell for web frontends",
|
|
2626
2696
|
biome: "- **Biome** - Linting and formatting",
|
|
2627
2697
|
oxlint: "- **Oxlint** - Oxlint + Oxfmt (linting & formatting)",
|
|
2628
2698
|
husky: "- **Husky** - Git hooks for code quality",
|
|
@@ -2679,13 +2749,23 @@ ${packageManagerRunCmd} db:push
|
|
|
2679
2749
|
return setup;
|
|
2680
2750
|
}
|
|
2681
2751
|
function generateScriptsList(packageManagerRunCmd, config, hasNative) {
|
|
2682
|
-
const { database, addons, backend, dbSetup } = config;
|
|
2752
|
+
const { database, addons, backend, dbSetup, frontend } = config;
|
|
2683
2753
|
const isConvex = backend === "convex";
|
|
2684
2754
|
const isBackendSelf = backend === "self";
|
|
2755
|
+
const hasWeb = frontend.some((f) => [
|
|
2756
|
+
"tanstack-router",
|
|
2757
|
+
"react-router",
|
|
2758
|
+
"tanstack-start",
|
|
2759
|
+
"next",
|
|
2760
|
+
"nuxt",
|
|
2761
|
+
"svelte",
|
|
2762
|
+
"solid",
|
|
2763
|
+
"astro"
|
|
2764
|
+
].includes(f));
|
|
2685
2765
|
const dbSupport = getDbScriptSupport(config);
|
|
2686
2766
|
let scripts = `- \`${packageManagerRunCmd} dev\`: Start all applications in development mode
|
|
2687
2767
|
- \`${packageManagerRunCmd} build\`: Build all applications`;
|
|
2688
|
-
if (
|
|
2768
|
+
if (hasWeb) scripts += `\n- \`${packageManagerRunCmd} dev:web\`: Start only the web application`;
|
|
2689
2769
|
if (isConvex) scripts += `\n- \`${packageManagerRunCmd} dev:setup\`: Setup and configure your Convex project`;
|
|
2690
2770
|
else if (backend !== "none" && !isBackendSelf) scripts += `\n- \`${packageManagerRunCmd} dev:server\`: Start only the server`;
|
|
2691
2771
|
scripts += `\n- \`${packageManagerRunCmd} check-types\`: Check TypeScript types across all apps`;
|
|
@@ -2700,8 +2780,19 @@ function generateScriptsList(packageManagerRunCmd, config, hasNative) {
|
|
|
2700
2780
|
if (addons.includes("biome")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Biome formatting and linting`;
|
|
2701
2781
|
if (addons.includes("oxlint")) scripts += `\n- \`${packageManagerRunCmd} check\`: Run Oxlint and Oxfmt`;
|
|
2702
2782
|
if (addons.includes("pwa")) scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} generate-pwa-assets\`: Generate PWA assets`;
|
|
2703
|
-
if (addons.includes("tauri"))
|
|
2783
|
+
if (addons.includes("tauri")) {
|
|
2784
|
+
scripts += `\n- \`cd apps/web && ${packageManagerRunCmd} desktop:dev\`: Start Tauri desktop app in development
|
|
2704
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
|
+
}
|
|
2705
2796
|
if (addons.includes("starlight")) scripts += `\n- \`cd apps/docs && ${packageManagerRunCmd} dev\`: Start documentation site
|
|
2706
2797
|
- \`cd apps/docs && ${packageManagerRunCmd} build\`: Build documentation site`;
|
|
2707
2798
|
return scripts;
|
|
@@ -3648,6 +3739,114 @@ const EMBEDDED_TEMPLATES = new Map([
|
|
|
3648
3739
|
]
|
|
3649
3740
|
{{/if}}
|
|
3650
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
|
+
}
|
|
3651
3850
|
`],
|
|
3652
3851
|
["addons/husky/.husky/pre-commit", `lint-staged
|
|
3653
3852
|
`],
|
|
@@ -3748,142 +3947,6 @@ export default defineConfig({
|
|
|
3748
3947
|
preset,
|
|
3749
3948
|
images: ["public/logo.png"],
|
|
3750
3949
|
});
|
|
3751
|
-
`],
|
|
3752
|
-
["addons/ruler/.ruler/bts.md.hbs", `# Better-T-Stack Project Rules
|
|
3753
|
-
|
|
3754
|
-
This is a {{projectName}} project created with Better-T-Stack CLI.
|
|
3755
|
-
|
|
3756
|
-
## Project Structure
|
|
3757
|
-
|
|
3758
|
-
This is a monorepo with the following structure:
|
|
3759
|
-
|
|
3760
|
-
{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
|
|
3761
|
-
(includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
|
|
3762
|
-
- **\`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}}
|
|
3763
|
-
{{/if}}
|
|
3764
|
-
|
|
3765
|
-
{{#if (ne backend "convex")}}
|
|
3766
|
-
{{#if (and (ne backend "none") (ne backend "self"))}}
|
|
3767
|
-
- **\`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}}
|
|
3768
|
-
{{/if}}
|
|
3769
|
-
{{else}}
|
|
3770
|
-
- **\`packages/backend/\`** - Convex backend functions
|
|
3771
|
-
{{/if}}
|
|
3772
|
-
|
|
3773
|
-
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
3774
|
-
- **\`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}}
|
|
3775
|
-
{{/if}}
|
|
3776
|
-
|
|
3777
|
-
{{#if (ne backend "convex")}}
|
|
3778
|
-
{{#if (ne api "none")}}
|
|
3779
|
-
- **\`packages/api/\`** - Shared API logic and types
|
|
3780
|
-
{{/if}}
|
|
3781
|
-
{{#if (and (ne auth "none") (ne backend "convex"))}}
|
|
3782
|
-
- **\`packages/auth/\`** - Authentication logic and utilities
|
|
3783
|
-
{{/if}}
|
|
3784
|
-
{{#if (and (ne database "none") (ne orm "none"))}}
|
|
3785
|
-
- **\`packages/db/\`** - Database schema and utilities
|
|
3786
|
-
{{/if}}
|
|
3787
|
-
- **\`packages/env/\`** - Shared environment variables and validation
|
|
3788
|
-
- **\`packages/config/\`** - Shared TypeScript configuration
|
|
3789
|
-
{{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare"))}}
|
|
3790
|
-
- **\`packages/infra/\`** - Infrastructure as code (Alchemy for Cloudflare)
|
|
3791
|
-
{{/if}}
|
|
3792
|
-
{{/if}}
|
|
3793
|
-
|
|
3794
|
-
## Available Scripts
|
|
3795
|
-
|
|
3796
|
-
- \`{{packageManager}} run dev\` - Start all apps in development mode
|
|
3797
|
-
{{#if (and (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
|
|
3798
|
-
(includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid")) (ne backend "self"))}}
|
|
3799
|
-
- \`{{packageManager}} run dev:web\` - Start only the web app
|
|
3800
|
-
{{/if}}
|
|
3801
|
-
{{#if (and (ne backend "none") (ne backend "convex") (ne backend "self"))}}
|
|
3802
|
-
- \`{{packageManager}} run dev:server\` - Start only the server
|
|
3803
|
-
{{/if}}
|
|
3804
|
-
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
3805
|
-
- \`{{packageManager}} run dev:native\` - Start only the native app
|
|
3806
|
-
{{/if}}
|
|
3807
|
-
- \`{{packageManager}} run build\` - Build all apps
|
|
3808
|
-
- \`{{packageManager}} run lint\` - Lint all packages
|
|
3809
|
-
- \`{{packageManager}} run typecheck\` - Type check all packages
|
|
3810
|
-
|
|
3811
|
-
{{#if (and (ne database "none") (ne orm "none") (ne backend "convex"))}}
|
|
3812
|
-
## Database Commands
|
|
3813
|
-
|
|
3814
|
-
All database operations should be run from the {{#if (eq backend "self")}}web{{else}}server{{/if}} workspace:
|
|
3815
|
-
|
|
3816
|
-
- \`{{packageManager}} run db:push\` - Push schema changes to database
|
|
3817
|
-
- \`{{packageManager}} run db:studio\` - Open database studio
|
|
3818
|
-
- \`{{packageManager}} run db:generate\` - Generate {{#if (eq orm "drizzle")}}Drizzle{{else if (eq orm "prisma")}}Prisma{{else}}{{orm}}{{/if}} files
|
|
3819
|
-
- \`{{packageManager}} run db:migrate\` - Run database migrations
|
|
3820
|
-
|
|
3821
|
-
{{#if (eq orm "drizzle")}}
|
|
3822
|
-
Database schema files are located in {{#if (eq backend "self")}}\`apps/web/src/db/schema/\`{{else}}\`packages/db/src/schema/\`{{/if}}
|
|
3823
|
-
{{else if (eq orm "prisma")}}
|
|
3824
|
-
Database schema is located in {{#if (eq backend "self")}}\`apps/web/prisma/schema.prisma\`{{else}}\`packages/db/prisma/schema.prisma\`{{/if}}
|
|
3825
|
-
{{else if (eq orm "mongoose")}}
|
|
3826
|
-
Database models are located in {{#if (eq backend "self")}}\`apps/web/src/db/models/\`{{else}}\`packages/db/src/models/\`{{/if}}
|
|
3827
|
-
{{/if}}
|
|
3828
|
-
{{/if}}
|
|
3829
|
-
|
|
3830
|
-
{{#if (ne api "none")}}
|
|
3831
|
-
## API Structure
|
|
3832
|
-
|
|
3833
|
-
{{#if (eq api "trpc")}}
|
|
3834
|
-
- tRPC routers are in \`packages/api/src/routers/\`
|
|
3835
|
-
- Client-side tRPC utils are in \`apps/web/src/utils/trpc.ts\`
|
|
3836
|
-
{{else if (eq api "orpc")}}
|
|
3837
|
-
- oRPC contracts and routers are in \`packages/api/src/\`
|
|
3838
|
-
- Client-side oRPC client is in \`apps/web/src/utils/orpc.ts\`
|
|
3839
|
-
{{/if}}
|
|
3840
|
-
{{/if}}
|
|
3841
|
-
|
|
3842
|
-
{{#if (eq auth "better-auth")}}
|
|
3843
|
-
## Authentication
|
|
3844
|
-
|
|
3845
|
-
Authentication is powered by Better Auth:
|
|
3846
|
-
- Auth configuration is in \`packages/auth/src/\`
|
|
3847
|
-
{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start")
|
|
3848
|
-
(includes frontend "next") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
|
|
3849
|
-
- Web app auth client is in \`apps/web/src/lib/auth-client.ts\`
|
|
3850
|
-
{{/if}}
|
|
3851
|
-
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
3852
|
-
- Native app auth client is in \`apps/native/src/lib/auth-client.ts\`
|
|
3853
|
-
{{/if}}
|
|
3854
|
-
{{/if}}
|
|
3855
|
-
|
|
3856
|
-
## Project Configuration
|
|
3857
|
-
|
|
3858
|
-
This project includes a \`bts.jsonc\` configuration file that stores your Better-T-Stack settings:
|
|
3859
|
-
|
|
3860
|
-
- Contains your selected stack configuration (database, ORM, backend, frontend, etc.)
|
|
3861
|
-
- Used by the CLI to understand your project structure
|
|
3862
|
-
- Safe to delete if not needed
|
|
3863
|
-
|
|
3864
|
-
## Key Points
|
|
3865
|
-
|
|
3866
|
-
- This is a {{#if (includes addons "turborepo")}}Turborepo {{/if}}monorepo using {{packageManager}} workspaces
|
|
3867
|
-
- Each app has its own \`package.json\` and dependencies
|
|
3868
|
-
- Run commands from the root to execute across all workspaces
|
|
3869
|
-
- Run workspace-specific commands with \`{{packageManager}} run command-name\`
|
|
3870
|
-
{{#if (includes addons "turborepo")}}
|
|
3871
|
-
- Turborepo handles build caching and parallel execution
|
|
3872
|
-
{{/if}}
|
|
3873
|
-
{{#if (or (includes addons "husky") (includes addons "lefthook"))}}
|
|
3874
|
-
- Git hooks are configured with {{#if (includes addons "husky")}}Husky{{else}}Lefthook{{/if}} for pre-commit checks
|
|
3875
|
-
{{/if}}
|
|
3876
|
-
`],
|
|
3877
|
-
["addons/ruler/.ruler/ruler.toml.hbs", `# Ruler Configuration File
|
|
3878
|
-
# See https://okigu.com/ruler for documentation.
|
|
3879
|
-
|
|
3880
|
-
# Default agents to run when --agents is not specified
|
|
3881
|
-
default_agents = []
|
|
3882
|
-
|
|
3883
|
-
# --- Global .gitignore Configuration ---
|
|
3884
|
-
[gitignore]
|
|
3885
|
-
# Enable/disable automatic .gitignore updates (default: true)
|
|
3886
|
-
enabled = true
|
|
3887
3950
|
`],
|
|
3888
3951
|
["api/orpc/fullstack/astro/src/pages/rpc/[...rest].ts.hbs", `import type { APIRoute } from "astro";
|
|
3889
3952
|
import { RPCHandler } from "@orpc/server/fetch";
|
|
@@ -4147,24 +4210,23 @@ export const queryClient = new QueryClient({
|
|
|
4147
4210
|
|
|
4148
4211
|
export const link = new RPCLink({
|
|
4149
4212
|
{{#if (eq backend "self")}}
|
|
4150
|
-
{{#
|
|
4213
|
+
{{#if (or (includes frontend "next") (includes frontend "tanstack-start"))}}
|
|
4151
4214
|
url: \`\${env.EXPO_PUBLIC_SERVER_URL}/api/rpc\`,
|
|
4152
4215
|
{{else}}
|
|
4153
4216
|
url: \`\${env.EXPO_PUBLIC_SERVER_URL}/rpc\`,
|
|
4154
|
-
{{/
|
|
4217
|
+
{{/if}}
|
|
4155
4218
|
{{else}}
|
|
4156
4219
|
url: \`\${env.EXPO_PUBLIC_SERVER_URL}/rpc\`,
|
|
4157
4220
|
{{/if}}
|
|
4158
4221
|
{{#if (eq auth "better-auth")}}
|
|
4159
4222
|
fetch:
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
},
|
|
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
|
+
},
|
|
4168
4230
|
headers() {
|
|
4169
4231
|
if (Platform.OS === "web") {
|
|
4170
4232
|
return {};
|
|
@@ -4852,14 +4914,13 @@ const trpcClient = createTRPCClient<AppRouter>({
|
|
|
4852
4914
|
{{/if}}
|
|
4853
4915
|
{{#if (eq auth "better-auth")}}
|
|
4854
4916
|
fetch:
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
},
|
|
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
|
+
},
|
|
4863
4924
|
headers() {
|
|
4864
4925
|
if (Platform.OS === "web") {
|
|
4865
4926
|
return {};
|
|
@@ -30323,7 +30384,7 @@ function SuccessPage() {
|
|
|
30323
30384
|
</div>
|
|
30324
30385
|
`]
|
|
30325
30386
|
]);
|
|
30326
|
-
const TEMPLATE_COUNT =
|
|
30387
|
+
const TEMPLATE_COUNT = 444;
|
|
30327
30388
|
|
|
30328
30389
|
//#endregion
|
|
30329
30390
|
export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processTemplateString, transformFilename, writeBtsConfigToVfs };
|