init
Some checks failed
Code Quality / lint-and-build (push) Failing after 29s
Release Packages / release (push) Failing after 41s

This commit is contained in:
2026-01-31 19:26:46 +01:00
commit 9a0900e3ff
42 changed files with 8346 additions and 0 deletions

228
packages/cli/src/index.ts Normal file
View File

@@ -0,0 +1,228 @@
import { Command } from "commander";
import fs from "fs-extra";
import path from "path";
import chalk from "chalk";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const program = new Command();
program
.name("mintel")
.description("CLI for Mintel monorepo management")
.version("1.0.0");
program
.command("init <path>")
.description("Initialize a new website project")
.action(async (projectPath) => {
const fullPath = path.isAbsolute(projectPath)
? projectPath
: path.resolve(process.cwd(), "../../", projectPath);
const projectName = path.basename(fullPath);
console.log(chalk.blue(`Initializing new project: ${projectName}...`));
try {
// Create directory
await fs.ensureDir(fullPath);
// Create package.json
const pkgJson = {
name: projectName,
version: "0.1.0",
private: true,
type: "module",
scripts: {
dev: "next dev",
build: "next build",
start: "next start",
lint: "next lint",
},
dependencies: {
next: "15.1.6",
react: "^19.0.0",
"react-dom": "^19.0.0",
"@mintel/next-utils": "workspace:*",
},
devDependencies: {
"@types/node": "^20.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
typescript: "^5.0.0",
"@mintel/tsconfig": "workspace:*",
"@mintel/eslint-config": "workspace:*",
"@mintel/next-config": "workspace:*",
},
};
await fs.writeJson(path.join(fullPath, "package.json"), pkgJson, {
spaces: 2,
});
// Create next.config.ts
const nextConfig = `import mintelNextConfig from "@mintel/next-config";
/** @type {import('next').NextConfig} */
const nextConfig = {};
export default mintelNextConfig(nextConfig);
`;
await fs.writeFile(path.join(fullPath, "next.config.ts"), nextConfig);
// Create tsconfig.json
const tsConfig = {
extends: "@mintel/tsconfig/nextjs.json",
compilerOptions: {
paths: {
"@/*": ["./src/*"],
},
},
include: [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
],
exclude: ["node_modules"],
};
await fs.writeJson(path.join(fullPath, "tsconfig.json"), tsConfig, {
spaces: 2,
});
// Create eslint.config.mjs
const eslintConfig = `import { nextConfig } from "@mintel/eslint-config/next";
export default nextConfig;
`;
await fs.writeFile(
path.join(fullPath, "eslint.config.mjs"),
eslintConfig
);
// Create basic src structure
await fs.ensureDir(path.join(fullPath, "src/app/[locale]"));
await fs.writeFile(
path.join(fullPath, "src/middleware.ts"),
`import { createMintelMiddleware } from "@mintel/next-utils";
export default createMintelMiddleware({
locales: ["en", "de"],
defaultLocale: "en",
logRequests: true,
});
export const config = {
matcher: ["/((?!api|_next|_vercel|health|.*\\\\..*).*)", "/", "/(de|en)/:path*"]
};
`
);
// Create i18n/request.ts
await fs.ensureDir(path.join(fullPath, "src/i18n"));
await fs.writeFile(
path.join(fullPath, "src/i18n/request.ts"),
`import { createMintelI18nRequestConfig } from "@mintel/next-utils";
export default createMintelI18nRequestConfig(
["en", "de"],
"en",
(locale) => import(\`../../messages/\${locale}.json\`)
);
`
);
// Create messages directory
await fs.ensureDir(path.join(fullPath, "messages"));
await fs.writeJson(path.join(fullPath, "messages/en.json"), {
Index: {
title: "Welcome"
}
}, { spaces: 2 });
await fs.writeJson(path.join(fullPath, "messages/de.json"), {
Index: {
title: "Willkommen"
}
}, { spaces: 2 });
// Create instrumentation.ts
await fs.writeFile(
path.join(fullPath, "src/instrumentation.ts"),
`import * as Sentry from '@sentry/nextjs';
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
// Server-side initialization
}
}
export const onRequestError = Sentry.captureRequestError;
`
);
await fs.writeFile(
path.join(fullPath, "src/app/[locale]/layout.tsx"),
`import type { Metadata } from "next";
export const metadata: Metadata = {
title: "${projectName}",
description: "Created with Mintel CLI",
};
export default function RootLayout({
children,
params: { locale }
}: {
children: React.ReactNode;
params: { locale: string };
}) {
return (
<html lang={locale}>
<body>{children}</body>
</html>
);
}
`
);
await fs.writeFile(
path.join(fullPath, "src/app/[locale]/page.tsx"),
`export default function Home() {
return (
<main>
<h1>Welcome to ${projectName}</h1>
</main>
);
}
`
);
// Copy infra templates
const infraPath = path.resolve(__dirname, "../../infra");
if (await fs.pathExists(infraPath)) {
await fs.copy(
path.join(infraPath, "docker/Dockerfile.nextjs"),
path.join(fullPath, "Dockerfile")
);
await fs.copy(
path.join(infraPath, "docker/docker-compose.template.yml"),
path.join(fullPath, "docker-compose.yml")
);
await fs.ensureDir(path.join(fullPath, ".gitea/workflows"));
await fs.copy(
path.join(infraPath, "gitea/deploy-action.yml"),
path.join(fullPath, ".gitea/workflows/deploy.yml")
);
}
console.log(
chalk.green(`Successfully initialized ${projectName} at ${fullPath}`)
);
console.log(chalk.yellow("\nNext steps:"));
console.log(chalk.cyan("1. pnpm install"));
console.log(chalk.cyan(`2. cd ${projectPath} && pnpm dev`));
} catch (error) {
console.error(chalk.red("Error initializing project:"), error);
}
});
program.parse();