fix native scaffolding

This commit is contained in:
Aman Varshney
2025-04-19 18:59:02 +05:30
parent b8c3fd40ab
commit d82ad80ac4
7 changed files with 96 additions and 58 deletions

View File

@@ -0,0 +1,5 @@
---
"create-better-t-stack": patch
---
fix native scaffolding

View File

@@ -1,4 +1,5 @@
import * as path from "node:path";
import fs from "fs-extra";
import type { ProjectConfig } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
@@ -7,12 +8,15 @@ export async function setupApi(config: ProjectConfig): Promise<void> {
const projectDir = path.resolve(process.cwd(), projectName);
const webDir = path.join(projectDir, "apps/web");
const serverDir = path.join(projectDir, "apps/server");
const webDirExists = await fs.pathExists(webDir);
if (api === "orpc") {
await addPackageDependency({
dependencies: ["@orpc/react-query", "@orpc/server", "@orpc/client"],
projectDir: webDir,
});
if (webDirExists) {
await addPackageDependency({
dependencies: ["@orpc/react-query", "@orpc/server", "@orpc/client"],
projectDir: webDir,
});
}
await addPackageDependency({
dependencies: ["@orpc/server", "@orpc/client"],
projectDir: serverDir,
@@ -20,14 +24,16 @@ export async function setupApi(config: ProjectConfig): Promise<void> {
}
if (api === "trpc") {
await addPackageDependency({
dependencies: [
"@trpc/tanstack-react-query",
"@trpc/server",
"@trpc/client",
],
projectDir: webDir,
});
if (webDirExists) {
await addPackageDependency({
dependencies: [
"@trpc/tanstack-react-query",
"@trpc/server",
"@trpc/client",
],
projectDir: webDir,
});
}
await addPackageDependency({
dependencies: ["@trpc/server", "@trpc/client"],
projectDir: serverDir,

View File

@@ -1,20 +1,9 @@
import path from "node:path";
import consola from "consola";
import fs from "fs-extra";
import pc from "picocolors";
import { addPackageDependency } from "../utils/add-package-deps";
export function generateAuthSecret(length = 32): string {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
import type { ProjectConfig } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
export async function setupAuth(config: ProjectConfig): Promise<void> {
const { projectName, auth, frontend } = config;
@@ -27,22 +16,29 @@ export async function setupAuth(config: ProjectConfig): Promise<void> {
const clientDir = path.join(projectDir, "apps/web");
const nativeDir = path.join(projectDir, "apps/native");
const clientDirExists = await fs.pathExists(clientDir);
const nativeDirExists = await fs.pathExists(nativeDir);
try {
await addPackageDependency({
dependencies: ["better-auth"],
projectDir: serverDir,
});
if (
const hasWebFrontend =
frontend.includes("react-router") ||
frontend.includes("tanstack-router") ||
frontend.includes("tanstack-start")
) {
frontend.includes("tanstack-start") ||
frontend.includes("next");
if (hasWebFrontend && clientDirExists) {
await addPackageDependency({
dependencies: ["better-auth"],
projectDir: clientDir,
});
}
if (frontend.includes("native")) {
if (frontend.includes("native") && nativeDirExists) {
await addPackageDependency({
dependencies: ["better-auth", "@better-auth/expo"],
projectDir: nativeDir,
@@ -53,10 +49,20 @@ export async function setupAuth(config: ProjectConfig): Promise<void> {
});
}
} catch (error) {
consola.error(pc.red("Failed to configure authentication"));
consola.error(pc.red("Failed to configure authentication dependencies"));
if (error instanceof Error) {
consola.error(pc.red(error.message));
}
throw error;
}
}
export function generateAuthSecret(length = 32): string {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}

View File

@@ -1,4 +1,5 @@
import path from "node:path";
import fs from "fs-extra";
import type { ProjectConfig } from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
@@ -8,11 +9,16 @@ export async function setupExamples(config: ProjectConfig): Promise<void> {
if (examples.includes("ai")) {
const clientDir = path.join(projectDir, "apps/web");
await addPackageDependency({
dependencies: ["ai"],
projectDir: clientDir,
});
const serverDir = path.join(projectDir, "apps/server");
const clientDirExists = await fs.pathExists(clientDir);
if (clientDirExists) {
await addPackageDependency({
dependencies: ["ai"],
projectDir: clientDir,
});
}
await addPackageDependency({
dependencies: ["ai", "@ai-sdk/google"],
projectDir: serverDir,

View File

@@ -217,6 +217,11 @@ export async function setupAuthTemplate(
const serverAppDir = path.join(projectDir, "apps/server");
const webAppDir = path.join(projectDir, "apps/web");
const nativeAppDir = path.join(projectDir, "apps/native");
const serverAppDirExists = await fs.pathExists(serverAppDir);
const webAppDirExists = await fs.pathExists(webAppDir);
const nativeAppDirExists = await fs.pathExists(nativeAppDir);
const webFrontends = context.frontend.filter(
(f) =>
f === "tanstack-router" ||
@@ -226,7 +231,7 @@ export async function setupAuthTemplate(
);
const hasNative = context.frontend.includes("native");
if (await fs.pathExists(serverAppDir)) {
if (serverAppDirExists) {
const authServerBaseSrc = path.join(PKG_ROOT, "templates/auth/server/base");
if (await fs.pathExists(authServerBaseSrc)) {
await processAndCopyFiles(
@@ -243,20 +248,25 @@ export async function setupAuthTemplate(
);
}
const authServerNextSrc = path.join(PKG_ROOT, "templates/auth/server/next");
if (await fs.pathExists(authServerNextSrc)) {
await processAndCopyFiles(
"**/*",
authServerNextSrc,
serverAppDir,
context,
);
} else {
consola.warn(
pc.yellow(
`Warning: Next auth server template not found at ${authServerNextSrc}`,
),
if (context.backend === "next") {
const authServerNextSrc = path.join(
PKG_ROOT,
"templates/auth/server/next",
);
if (await fs.pathExists(authServerNextSrc)) {
await processAndCopyFiles(
"**/*",
authServerNextSrc,
serverAppDir,
context,
);
} else {
consola.warn(
pc.yellow(
`Warning: Next auth server template not found at ${authServerNextSrc}`,
),
);
}
}
if (context.orm !== "none" && context.database !== "none") {
@@ -287,12 +297,12 @@ export async function setupAuthTemplate(
} else {
consola.warn(
pc.yellow(
"Warning: apps/server directory does not exist, skipping server-side auth setup.",
"Warning: apps/server directory does not exist, skipping server-side auth template setup.",
),
);
}
if (webFrontends.length > 0 && (await fs.pathExists(webAppDir))) {
if (webFrontends.length > 0 && webAppDirExists) {
const authWebBaseSrc = path.join(PKG_ROOT, "templates/auth/web/base");
if (await fs.pathExists(authWebBaseSrc)) {
await processAndCopyFiles("**/*", authWebBaseSrc, webAppDir, context);
@@ -326,7 +336,7 @@ export async function setupAuthTemplate(
}
}
if (hasNative && (await fs.pathExists(nativeAppDir))) {
if (hasNative && nativeAppDirExists) {
const authNativeSrc = path.join(PKG_ROOT, "templates/auth/native");
if (await fs.pathExists(authNativeSrc)) {
await processAndCopyFiles("**/*", authNativeSrc, nativeAppDir, context);
@@ -374,13 +384,15 @@ export async function setupAddonsTemplate(
if (context.addons.includes("pwa")) {
const pwaSrcDir = path.join(PKG_ROOT, "templates/addons/pwa/apps/web");
const webAppDir = path.join(projectDir, "apps/web");
const webAppDirExists = await fs.pathExists(webAppDir);
if (await fs.pathExists(pwaSrcDir)) {
if (await fs.pathExists(webAppDir)) {
if (webAppDirExists) {
await processAndCopyFiles("**/*", pwaSrcDir, webAppDir, context);
} else {
consola.warn(
pc.yellow(
"Warning: apps/web directory not found, cannot setup PWA addon.",
"Warning: apps/web directory not found, cannot setup PWA addon template.",
),
);
}
@@ -399,10 +411,13 @@ export async function setupExamplesTemplate(
const serverAppDir = path.join(projectDir, "apps/server");
const webAppDir = path.join(projectDir, "apps/web");
const serverAppDirExists = await fs.pathExists(serverAppDir);
const webAppDirExists = await fs.pathExists(webAppDir);
for (const example of context.examples) {
const exampleBaseDir = path.join(PKG_ROOT, `templates/examples/${example}`);
if (await fs.pathExists(serverAppDir)) {
if (serverAppDirExists) {
const exampleServerSrc = path.join(exampleBaseDir, "server");
if (await fs.pathExists(exampleServerSrc)) {
if (context.orm !== "none") {
@@ -441,7 +456,7 @@ export async function setupExamplesTemplate(
}
}
if (await fs.pathExists(webAppDir)) {
if (webAppDirExists) {
const exampleWebSrc = path.join(exampleBaseDir, "web");
if (await fs.pathExists(exampleWebSrc)) {
const webFrameworks = context.frontend.filter((f) =>

View File

@@ -3,7 +3,7 @@ import { Stack } from "expo-router";
import {
DarkTheme,
DefaultTheme,
Theme,
type Theme,
ThemeProvider,
} from "@react-navigation/native";
import { StatusBar } from "expo-status-bar";

View File

@@ -14,7 +14,7 @@
},
"apps/cli": {
"name": "create-better-t-stack",
"version": "2.0.6-beta.0",
"version": "2.0.6",
"bin": {
"create-better-t-stack": "dist/index.js",
},