Skip to content

Commit 2b833de

Browse files
okj
1 parent f153a8e commit 2b833de

543 files changed

Lines changed: 43673 additions & 82 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/cli/src/helpers/addons/addons-setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ ${pc.cyan("Docs:")} ${pc.underline("https://turborepo.com/docs")}
5353
}
5454

5555
if (hasOxlint) {
56-
await setupOxlint(projectDir, packageManager);
56+
await setupOxlint(config);
5757
}
5858

5959
if (addons.includes("starlight")) {

apps/cli/src/helpers/addons/examples-setup.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

apps/cli/src/helpers/addons/oxlint-setup.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@
77
import { spinner } from "@clack/prompts";
88
import { $ } from "execa";
99

10-
import type { PackageManager } from "../../types";
10+
import type { ProjectConfig } from "../../types";
1111

1212
import { getPackageExecutionArgs } from "../../utils/package-runner";
1313

14-
export async function setupOxlint(projectDir: string, packageManager: PackageManager) {
14+
export async function setupOxlint(config: ProjectConfig) {
1515
// Dependencies (oxlint, oxfmt) and scripts are added by template-generator
1616
// This only runs the init CLIs
1717

1818
const s = spinner();
1919
s.start("Initializing oxlint and oxfmt...");
2020

21-
const oxlintArgs = getPackageExecutionArgs(packageManager, "oxlint@latest --init");
22-
await $({ cwd: projectDir, env: { CI: "true" } })`${oxlintArgs}`;
21+
const oxlintArgs = getPackageExecutionArgs(config.packageManager, "oxlint@latest --init");
22+
await $({ cwd: config.projectDir, env: { CI: "true" } })`${oxlintArgs}`;
2323

24-
const oxfmtArgs = getPackageExecutionArgs(packageManager, "oxfmt@latest --init");
25-
await $({ cwd: projectDir, env: { CI: "true" } })`${oxfmtArgs}`;
24+
const oxfmtArgs = getPackageExecutionArgs(config.packageManager, "oxfmt@latest --init");
25+
await $({ cwd: config.projectDir, env: { CI: "true" } })`${oxfmtArgs}`;
2626

2727
s.stop("oxlint and oxfmt initialized successfully!");
2828
}

apps/cli/src/helpers/core/create-project.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ import { setupBetterAuthPlugins } from "../../utils/better-auth-plugin-setup";
1111
import { writeBtsConfig } from "../../utils/bts-config";
1212
import { isSilent } from "../../utils/context";
1313
import { exitWithError } from "../../utils/errors";
14-
import { formatProjectFiles } from "../../utils/file-formatter";
14+
import { formatProject } from "../../utils/file-formatter";
1515
import { setupCatalogs } from "../../utils/setup-catalogs";
1616
import { setupAddons } from "../addons/addons-setup";
17-
import { setupExamples } from "../addons/examples-setup";
1817
import { setupDatabase } from "../core/db-setup";
1918
import { setupServerDeploy } from "../deployment/server-deploy-setup";
2019
import { setupWebDeploy } from "../deployment/web-deploy-setup";
@@ -44,17 +43,12 @@ export async function createProject(options: ProjectConfig, cliInput: CreateProj
4443
}
4544

4645
await writeTreeToFilesystem(result.tree, projectDir);
47-
await formatProjectFiles(projectDir);
4846
await setPackageManagerVersion(projectDir, options.packageManager);
4947

5048
if (!isConvex && options.database !== "none") {
5149
await setupDatabase(options, cliInput);
5250
}
5351

54-
if (options.examples.length > 0 && options.examples[0] !== "none") {
55-
await setupExamples(options);
56-
}
57-
5852
if (options.addons.length > 0 && options.addons[0] !== "none") {
5953
await setupAddons(options);
6054
}
@@ -69,9 +63,14 @@ export async function createProject(options: ProjectConfig, cliInput: CreateProj
6963
await setupEnvironmentVariables(options);
7064
await setupWebDeploy(options);
7165
await setupServerDeploy(options);
66+
67+
// Process catalogs after addons (which may create new apps/packages)
7268
await setupCatalogs(options.projectDir, options);
69+
7370
await writeBtsConfig(options);
7471

72+
await formatProject(projectDir);
73+
7574
if (!isSilent()) log.success("Project template successfully scaffolded!");
7675

7776
if (options.install) {
Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import fs from "fs-extra";
22
import path from "node:path";
33
import { format, type FormatOptions } from "oxfmt";
4-
import { glob } from "tinyglobby";
54

65
const formatOptions: FormatOptions = {
76
experimentalSortPackageJson: true,
@@ -10,7 +9,7 @@ const formatOptions: FormatOptions = {
109
},
1110
};
1211

13-
export async function formatFile(filePath: string, content: string): Promise<string | null> {
12+
export async function formatCode(filePath: string, content: string): Promise<string | null> {
1413
try {
1514
const result = await format(path.basename(filePath), content, formatOptions);
1615

@@ -24,27 +23,28 @@ export async function formatFile(filePath: string, content: string): Promise<str
2423
}
2524
}
2625

27-
/**
28-
* Format all files in a project directory using oxfmt
29-
*/
30-
export async function formatProjectFiles(projectDir: string): Promise<void> {
31-
const files = await glob(["**/*.{ts,tsx,js,jsx,json,mjs,cjs}"], {
32-
cwd: projectDir,
33-
absolute: true,
34-
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
35-
});
36-
37-
await Promise.all(
38-
files.map(async (filePath) => {
39-
try {
40-
const content = await fs.readFile(filePath, "utf-8");
41-
const formatted = await formatFile(filePath, content);
42-
if (formatted && formatted !== content) {
43-
await fs.writeFile(filePath, formatted, "utf-8");
26+
export async function formatProject(projectDir: string) {
27+
async function formatDirectory(dir: string) {
28+
const entries = await fs.readdir(dir, { withFileTypes: true });
29+
30+
await Promise.all(
31+
entries.map(async (entry) => {
32+
const fullPath = path.join(dir, entry.name);
33+
34+
if (entry.isDirectory()) {
35+
await formatDirectory(fullPath);
36+
} else if (entry.isFile()) {
37+
try {
38+
const content = await fs.readFile(fullPath, "utf-8");
39+
const formatted = await formatCode(fullPath, content);
40+
if (formatted && formatted !== content) {
41+
await fs.writeFile(fullPath, formatted, "utf-8");
42+
}
43+
} catch {}
4444
}
45-
} catch {
46-
// Silently skip files that can't be formatted
47-
}
48-
}),
49-
);
45+
}),
46+
);
47+
}
48+
49+
await formatDirectory(projectDir);
5050
}

apps/cli/src/utils/setup-catalogs.ts

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,52 @@ export async function setupCatalogs(projectDir: string, options: ProjectConfig)
2020
return;
2121
}
2222

23-
const packagePaths = [
24-
".", // root monorepo
25-
"apps/server",
26-
"apps/web",
27-
"apps/native",
28-
"apps/fumadocs",
29-
"apps/docs",
30-
"packages/api",
31-
"packages/db",
32-
"packages/auth",
33-
"packages/backend",
34-
"packages/config",
35-
"packages/env",
36-
"packages/infra",
37-
];
38-
3923
const packagesInfo: PackageInfo[] = [];
4024

41-
for (const pkgPath of packagePaths) {
42-
const fullPath = path.join(projectDir, pkgPath);
43-
const pkgJsonPath = path.join(fullPath, "package.json");
44-
45-
if (await fs.pathExists(pkgJsonPath)) {
46-
const pkgJson = await fs.readJson(pkgJsonPath);
47-
packagesInfo.push({
48-
path: fullPath,
49-
dependencies: pkgJson.dependencies || {},
50-
devDependencies: pkgJson.devDependencies || {},
51-
});
25+
// Add root package.json
26+
const rootPkgJsonPath = path.join(projectDir, "package.json");
27+
if (await fs.pathExists(rootPkgJsonPath)) {
28+
const pkgJson = await fs.readJson(rootPkgJsonPath);
29+
packagesInfo.push({
30+
path: projectDir,
31+
dependencies: pkgJson.dependencies || {},
32+
devDependencies: pkgJson.devDependencies || {},
33+
});
34+
}
35+
36+
// Dynamically discover packages in apps/ and packages/
37+
const appsDir = path.join(projectDir, "apps");
38+
const packagesDir = path.join(projectDir, "packages");
39+
40+
if (await fs.pathExists(appsDir)) {
41+
const appDirs = await fs.readdir(appsDir);
42+
for (const appDir of appDirs) {
43+
const appPath = path.join(appsDir, appDir);
44+
const pkgJsonPath = path.join(appPath, "package.json");
45+
if (await fs.pathExists(pkgJsonPath)) {
46+
const pkgJson = await fs.readJson(pkgJsonPath);
47+
packagesInfo.push({
48+
path: appPath,
49+
dependencies: pkgJson.dependencies || {},
50+
devDependencies: pkgJson.devDependencies || {},
51+
});
52+
}
53+
}
54+
}
55+
56+
if (await fs.pathExists(packagesDir)) {
57+
const packageDirs = await fs.readdir(packagesDir);
58+
for (const packageDir of packageDirs) {
59+
const packagePath = path.join(packagesDir, packageDir);
60+
const pkgJsonPath = path.join(packagePath, "package.json");
61+
if (await fs.pathExists(pkgJsonPath)) {
62+
const pkgJson = await fs.readJson(pkgJsonPath);
63+
packagesInfo.push({
64+
path: packagePath,
65+
dependencies: pkgJson.dependencies || {},
66+
devDependencies: pkgJson.devDependencies || {},
67+
});
68+
}
5269
}
5370
}
5471

cli/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/node_modules
2+
/dist
3+
.smoke

0 commit comments

Comments
 (0)