fixed it lol

This commit is contained in:
2025-09-03 21:02:43 +02:00
parent 8a35b5ba82
commit 9d2bd46e72

462
index.js
View File

@@ -1,49 +1,60 @@
#!/usr/bin/env node #!/usr/bin/env node
import * as p from '@clack/prompts'; import * as p from "@clack/prompts";
import color from 'picocolors'; import color from "picocolors";
import fs from 'fs-extra'; import fs from "fs-extra";
import path from 'path'; import path from "path";
import { spawn, spawnSync } from 'node:child_process'; import { spawn, spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
async function runCommand(cmd, args, cwd) { async function runCommand(cmd, args, cwd) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const proc = spawn(cmd, args, { cwd, stdio: 'ignore' }); const proc = spawn(cmd, args, { cwd, stdio: "ignore" });
proc.on('exit', (code) => (code === 0 ? resolve() : reject(new Error(`Command failed: ${cmd} ${args.join(' ')}`)))); proc.on("exit", (code) =>
code === 0
? resolve()
: reject(new Error(`Command failed: ${cmd} ${args.join(" ")}`)),
);
}); });
} }
async function main() { async function main() {
p.intro(`${color.bgRedBright(color.black(' ✨ Welcome to Lumify Sanity Template! ✨ '))}`); p.intro(
`${color.bgRedBright(color.black(" ✨ Welcome to Lumify Sanity Template! ✨ "))}`,
);
const project = await p.group( const project = await p.group(
{ {
projectName: () => projectName: () =>
p.text({ p.text({
message: `${color.cyan('🔖 Enter your project name (for display):')}`, message: `${color.cyan("🔖 Enter your project name (for display):")}`,
placeholder: 'My Sanity Lumify page', placeholder: "My Sanity Lumify page",
validate: (v) => (v.length < 2 ? `${color.red('❌ Too short!')}` : undefined), validate: (v) =>
v.length < 2 ? `${color.red("❌ Too short!")}` : undefined,
}), }),
dirName: ({ results }) => { dirName: ({ results }) => {
const defaultKebab = String(results.projectName) const defaultKebab = String(results.projectName)
.trim() .trim()
.toLowerCase() .toLowerCase()
.replace(/[^a-z0-9]+/g, '-') .replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, ''); .replace(/^-+|-+$/g, "");
return p.text({ return p.text({
message: `${color.cyan('📂 Enter a directory name for your project:')}`, message: `${color.cyan("📂 Enter a directory name for your project:")}`,
placeholder: `./${defaultKebab}`, placeholder: `./${defaultKebab}`,
initialValue: defaultKebab, initialValue: defaultKebab,
validate: (v) => { validate: (v) => {
if (v.length < 2) return `${color.red('❌ Too short!')}`; if (v.length < 2) return `${color.red("❌ Too short!")}`;
const kebab = String(v) const kebab = String(v)
.trim() .trim()
.toLowerCase() .toLowerCase()
.replace(/[^a-z0-9]+/g, '-') .replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, ''); .replace(/^-+|-+$/g, "");
const root = path.resolve(process.cwd(), kebab); const root = path.resolve(process.cwd(), kebab);
if (fs.existsSync(root)) { if (fs.existsSync(root)) {
return `${color.red('⚠️ Directory already exists:')} ${color.yellow(root)}`; return `${color.red("⚠️ Directory already exists:")} ${color.yellow(root)}`;
} }
return undefined; return undefined;
}, },
@@ -51,71 +62,73 @@ async function main() {
}, },
shouldGit: () => shouldGit: () =>
p.confirm({ p.confirm({
message: `${color.green('🌱 Do you want to initialize a git repository?')}`, message: `${color.green("🌱 Do you want to initialize a git repository?")}`,
initialValue: true, initialValue: true,
}), }),
packageManager: () => packageManager: () =>
p.select({ p.select({
message: `${color.magenta('📦 Which package manager do you want to use?')}`, message: `${color.magenta("📦 Which package manager do you want to use?")}`,
options: [ options: [
{ value: 'bun', label: `${color.yellow('bun 🥯')}` }, { value: "bun", label: `${color.yellow("bun 🥯")}` },
{ value: 'npm', label: `${color.green('npm 📦')}` }, { value: "npm", label: `${color.green("npm 📦")}` },
], ],
initialValue: 'bun', initialValue: "bun",
}), }),
lowerCaseName: ({ results }) => { lowerCaseName: ({ results }) => {
const defaultLowercase = String(results.dirName || results.projectName) const defaultLowercase = String(results.dirName || results.projectName)
.trim() .trim()
.toLowerCase() .toLowerCase()
.replace(/[^a-z0-9]+/g, '-') .replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, ''); .replace(/^-+|-+$/g, "");
return p.text({ return p.text({
message: `${color.cyan('📓 Enter a lowercase name for your project (e.g., used as')} ${color.yellow('<input>.sanity.studio')}${color.cyan('):')}`, message: `${color.cyan("📓 Enter a lowercase name for your project (e.g., used as")} ${color.yellow("<input>.sanity.studio")}${color.cyan("):")}`,
placeholder: `${defaultLowercase}`, placeholder: `${defaultLowercase}`,
initialValue: defaultLowercase, initialValue: defaultLowercase,
validate: (v) => { validate: (v) => {
if (v.length < 2) return `${color.red('❌ Too short!')}`; if (v.length < 2) return `${color.red("❌ Too short!")}`;
if (!/^[a-z0-9-]+$/.test(v)) return `${color.red('❌ Only lowercase letters, numbers, and hyphens allowed!')}`; if (!/^[a-z0-9-]+$/.test(v))
if (v.startsWith('-') || v.endsWith('-')) return `${color.red('❌ Cannot start or end with hyphen!')}`; return `${color.red("❌ Only lowercase letters, numbers, and hyphens allowed!")}`;
if (v.includes('.sanity.studio')) return `${color.red('❌ Do not include .sanity.studio - it will be added automatically!')}`; if (v.startsWith("-") || v.endsWith("-"))
return `${color.red("❌ Cannot start or end with hyphen!")}`;
if (v.includes(".sanity.studio"))
return `${color.red("❌ Do not include .sanity.studio - it will be added automatically!")}`;
}, },
}); });
}, },
faviconPath: () => faviconPath: () =>
p.text({ p.text({
message: `${color.cyan('🖼️ Path to favicon SVG (leave empty to skip):')}`, message: `${color.cyan("🖼️ Path to favicon SVG (leave empty to skip):")}`,
placeholder: './myicon.svg', placeholder: "./myicon.svg",
}), }),
extraDomain: () => extraDomain: () =>
p.text({ p.text({
message: `${color.cyan('🌍 Enter a domain this will run on later (leave empty to skip):')}`, message: `${color.cyan("🌍 Enter a domain this will run on later (leave empty to skip):")}`,
placeholder: 'youronlinedomain.com', placeholder: "youronlinedomain.com",
validate: () => undefined, validate: () => undefined,
}), }),
}, },
{ {
onCancel: () => { onCancel: () => {
p.cancel('Operation cancelled.'); p.cancel("Operation cancelled.");
process.exit(0); process.exit(0);
}, },
} },
); );
const kebabName = String(project.dirName) const kebabName = String(project.dirName)
.trim() .trim()
.toLowerCase() .toLowerCase()
.replace(/[^a-z0-9]+/g, '-') .replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, ''); .replace(/^-+|-+$/g, "");
const rootDir = path.join(process.cwd(), kebabName); const rootDir = path.join(process.cwd(), kebabName);
const pmx = project.packageManager === 'bun' ? 'bun x' : 'npx'; const pm = project.packageManager === "bun" ? "bun" : "npm";
const pm = project.packageManager === 'bun' ? 'bun' : 'npm'; const studioDir = path.join(rootDir, "apps", "studio");
const studioDir = path.join(rootDir, 'apps', 'studio');
await p.tasks([ await p.tasks([
{ {
title: `${color.yellow('📁 Copying template contents to root')}`, title: `${color.yellow("📁 Copying template contents to root")}`,
task: async () => { task: async () => {
const templateDir = path.join(process.cwd(), 'template'); const templateDir = path.join(__dirname, "template");
// Ensure root directory exists with proper permissions // Ensure root directory exists with proper permissions
await fs.ensureDir(rootDir); await fs.ensureDir(rootDir);
@@ -124,7 +137,7 @@ async function main() {
await fs.copy(templateDir, rootDir, { await fs.copy(templateDir, rootDir, {
overwrite: true, overwrite: true,
errorOnExist: false, errorOnExist: false,
preserveTimestamps: false preserveTimestamps: false,
}); });
} catch (error) { } catch (error) {
throw new Error(`Failed to copy template files: ${error.message}`); throw new Error(`Failed to copy template files: ${error.message}`);
@@ -140,160 +153,265 @@ async function main() {
if (stat.isDirectory()) { if (stat.isDirectory()) {
await renameGitignoreFiles(itemPath); await renameGitignoreFiles(itemPath);
} else if (item === 'gitignore') { } else if (item === "gitignore") {
const gitignorePath = path.join(dir, '.gitignore'); const gitignorePath = path.join(dir, ".gitignore");
await fs.move(itemPath, gitignorePath); await fs.move(itemPath, gitignorePath);
} }
} }
} catch (error) { } catch (error) {
throw new Error(`Failed to rename gitignore files: ${error.message}`); throw new Error(
`Failed to rename gitignore files: ${error.message}`,
);
} }
} }
await renameGitignoreFiles(rootDir); await renameGitignoreFiles(rootDir);
return 'Template copied!'; return "Template copied!";
}, },
}, },
{ {
title: `${color.green(`📦 Installing dependencies with ${project.packageManager}`)}`, title: `${color.green(`📦 Installing dependencies with ${project.packageManager}`)}`,
task: async () => { task: async () => {
await runCommand(project.packageManager === 'bun' ? 'bun' : 'npm', ['install'], rootDir); await runCommand(
return 'Dependencies installed successfully'; project.packageManager === "bun" ? "bun" : "npm",
["install"],
rootDir,
);
return "Dependencies installed successfully";
}, },
}, },
{ ]);
title: `${color.cyan('🔑 Checking Sanity login status')}`,
task: async () => { // Now check Sanity login status and prompt for provider if needed
await fs.ensureDir(studioDir); console.log(`${color.cyan("🔑 Checking Sanity login status...")}`);
let loggedIn = false; let loggedIn = false;
let hasProjects = false; let hasProjects = false;
try { try {
const result = await new Promise((res, rej) => { const result = await new Promise((res, rej) => {
let out = ''; let out = "";
const c = spawn(pmx, ['sanity', 'projects', 'list'], { cwd: studioDir, stdio: ['ignore', 'pipe', 'pipe'] }); const c = spawn(pm, ["x", "sanity", "projects", "list"], {
c.stdout.on('data', (d) => (out += d));
c.on('exit', (code) => (code === 0 ? res(out) : rej(new Error('fail'))));
});
if (result.includes('id ')) {
loggedIn = true;
hasProjects = result.split('\n').slice(1).some((l) => l.trim());
}
} catch { }
if (loggedIn) {
return hasProjects ? 'Already logged in to Sanity!' : 'Logged in to Sanity (no projects yet).';
} else {
await runCommand(pmx, ['sanity', 'login'], studioDir);
return 'Sanity login complete!';
}
},
},
{
title: `${color.magenta('🛠️ Creating Sanity project')}`,
task: async () => {
spawnSync(pmx, [
"sanity",
"projects",
"create",
project.projectName
], {
cwd: studioDir,
stdio: "inherit",
encoding: "utf-8"
})
const listProjects = spawnSync(pmx, [
"sanity",
"projects",
"list"
], {
cwd: studioDir, cwd: studioDir,
stdio: ["ignore", "pipe", "pipe"], stdio: ["ignore", "pipe", "pipe"],
encoding: "utf-8" });
}) c.stdout.on("data", (d) => (out += d));
c.on("exit", (code) =>
code === 0 ? res(out) : rej(new Error("Not logged in")),
);
});
if (result.includes("id ")) {
loggedIn = true;
hasProjects = result
.split("\n")
.slice(1)
.some((l) => l.trim());
}
} catch {}
if (!loggedIn) {
// Exit clack UI completely for interactive commands
p.outro(`${color.yellow("⚠️ Authentication required...")}`);
// Clear terminal and use clean console session
console.clear();
console.log(
`\n${color.bgRedBright(color.black(" ✨ Lumify Sanity Template - Authentication ✨ "))}\n`,
);
if (!loggedIn) {
p.log.warn(`${color.yellow("⚠️ You need to login to Sanity first.")}`);
const provider = await p.select({
message: `${color.cyan("🔐 Choose a provider to login to Sanity:")}`,
options: [
{ value: "sanity", label: "Sanity (email/password)" },
{ value: "google", label: "Google" },
{ value: "github", label: "GitHub" },
],
initialValue: "sanity",
});
p.log.info(`${color.cyan(`🚀 Logging in with provider: ${provider}`)}`);
try {
await runCommand(
pm,
["x", "sanity", "login", "--provider", provider],
studioDir,
);
p.log.success(`${color.green("✅ Sanity login complete!")}`);
} catch (error) {
p.log.error(`${color.red("❌ Sanity login failed:")}`);
p.log.error(error.message);
process.exit(1);
}
} else {
p.log.success(
hasProjects
? `${color.green("✅ Already logged in to Sanity!")}`
: `${color.green("✅ Logged in to Sanity (no projects yet).")}`,
);
}
// Clear terminal for clean project creation
// Create Sanity project (manual step to avoid interaction issues)
p.log.info(`${color.magenta("🛠️ Creating Sanity project...")}`);
p.log.warn(
`${color.yellow("⚠️ Due to terminal interaction issues, you need to run this command manually:")}`,
);
p.log.message(`${color.cyan("cd " + studioDir)}`);
p.log.message(
`${color.cyan(`${pm} x sanity projects create "${project.projectName}"`)}`,
);
await p.confirm({
message: `${color.green("Press Enter when the project is created successfully...")}`,
initialValue: true,
});
p.log.success(`${color.green("✅ Continuing with project configuration...")}`);
const listProjects = spawnSync(pm, ["x", "sanity", "projects", "list"], {
cwd: studioDir,
stdio: ["ignore", "pipe", "pipe"],
encoding: "utf-8",
});
let sanityJson; let sanityJson;
if (listProjects.stdout) { if (listProjects.stdout) {
try { try {
const lines = listProjects.stdout.split(/\r?\n/).filter(l => l.trim() && !l.startsWith('id') && !l.startsWith('─')); const lines = listProjects.stdout
const projectIds = lines.map(line => { .split(/\r?\n/)
.filter((l) => l.trim() && !l.startsWith("id") && !l.startsWith("─"));
const projectIds = lines
.map((line) => {
const match = line.match(/^([a-z0-9]{8})\b/); const match = line.match(/^([a-z0-9]{8})\b/);
return match ? match[1] : null; return match ? match[1] : null;
}).filter(id => !!id); })
.filter((id) => !!id);
if (projectIds.length > 0) { if (projectIds.length > 0) {
sanityJson = { projectId: projectIds[0] }; sanityJson = { projectId: projectIds[0] };
} }
} catch (e) { } catch (e) {
throw new Error("Could not parse Sanity project list output."); p.log.error(
`${color.red("❌ Could not parse Sanity project list output.")}`,
);
process.exit(1);
} }
} }
if (!sanityJson || !sanityJson.projectId) { if (!sanityJson || !sanityJson.projectId) {
throw new Error("Sanity project creation failed."); console.error(`${color.red("❌ Sanity project creation failed.")}`);
process.exit(1);
} }
// Update connection file with project ID // Update connection file with project ID
const connPath = path.join(rootDir, "packages/sanity-connection/index.ts"); const connPath = path.join(rootDir, "packages/sanity-connection/index.ts");
if (!(await fs.pathExists(connPath))) { if (!(await fs.pathExists(connPath))) {
throw new Error(`Connection file not found at ${connPath}`); console.error(
`${color.red("❌ Connection file not found at " + connPath)}`,
);
process.exit(1);
} }
let connFile = await fs.readFile(connPath, "utf8"); let connFile = await fs.readFile(connPath, "utf8");
if (!/projectId: "[^"]+"/.test(connFile)) { if (!/projectId: "[^"]+"/.test(connFile)) {
throw new Error(`Could not find projectId in ${connPath}. Please ensure the file contains a line like projectId: "${sanityJson.projectId}"`); console.error(
`${color.red("❌ Could not find projectId in connection file")}`,
);
process.exit(1);
} }
connFile = connFile.replace(/projectId: "[^"]+"/, `projectId: "${sanityJson.projectId}"`); connFile = connFile.replace(
/projectId: "[^"]+"/,
`projectId: "${sanityJson.projectId}"`,
);
await fs.writeFile(connPath, connFile); await fs.writeFile(connPath, connFile);
// Update wrangler.jsonc with project name // Update wrangler.jsonc with project name
const wranglerPath = path.join(rootDir, "apps/client/wrangler.jsonc"); const wranglerPath = path.join(rootDir, "apps/client/wrangler.jsonc");
if (await fs.pathExists(wranglerPath)) { if (await fs.pathExists(wranglerPath)) {
let wranglerFile = await fs.readFile(wranglerPath, "utf8"); let wranglerFile = await fs.readFile(wranglerPath, "utf8");
wranglerFile = wranglerFile.replace(/"name": "[^"]+"/, `"name": "${project.lowerCaseName}"`); wranglerFile = wranglerFile.replace(
/"name": "[^"]+"/,
`"name": "${project.lowerCaseName}"`,
);
await fs.writeFile(wranglerPath, wranglerFile); await fs.writeFile(wranglerPath, wranglerFile);
} }
return `Sanity project created with ID: ${sanityJson.projectId}`; p.log.success(
}, `${color.green("✅ Sanity project created with ID: " + sanityJson.projectId)}`,
}, );
await p.tasks([
{ {
title: `${color.blue('🗄️ Setting up production dataset for Sanity CMS')}`, title: `${color.blue("🗄️ Setting up production dataset for Sanity CMS")}`,
task: async () => { task: async () => {
if (!(await fs.pathExists(studioDir))) throw new Error(`Studio directory not found at ${studioDir}`); if (!(await fs.pathExists(studioDir)))
throw new Error(`Studio directory not found at ${studioDir}`);
try { try {
await runCommand(pmx, ['sanity', 'dataset', 'create', 'production'], studioDir); await runCommand(
return 'Production dataset created successfully'; pm,
["x", "sanity", "dataset", "create", "production"],
studioDir,
);
return "Production dataset created successfully";
} catch (error) { } catch (error) {
// Check if dataset already exists // Check if dataset already exists
if (error.message && error.message.includes('already exists')) { if (error.message && error.message.includes("already exists")) {
return 'Production dataset already exists'; return "Production dataset already exists";
} }
throw new Error(`Failed to create production dataset: ${error.message}`); throw new Error(
`Failed to create production dataset: ${error.message}`,
);
} }
}, },
}, },
{ {
title: `${color.green('🔐 Creating Sanity viewer token')}`, title: `${color.green("🔐 Creating Sanity viewer token")}`,
task: async () => { task: async () => {
if (!(await fs.pathExists(studioDir))) throw new Error(`Studio directory not found at ${studioDir}`); if (!(await fs.pathExists(studioDir)))
throw new Error(`Studio directory not found at ${studioDir}`);
const addOut = await new Promise((res, rej) => { const addOut = await new Promise((res, rej) => {
let buf = ''; let buf = "";
const c = spawn( const c = spawn(
pmx, pm,
['sanity', 'tokens', 'add', 'Main Viewer API Token', '--role=viewer', '-y', '--json'], [
{ cwd: studioDir, stdio: ['ignore', 'pipe', 'pipe'] } "x",
"sanity",
"tokens",
"add",
"Main Viewer API Token",
"--role=viewer",
"-y",
"--json",
],
{ cwd: studioDir, stdio: ["ignore", "pipe", "pipe"] },
);
c.stdout.on("data", (d) => (buf += d));
c.on("exit", (code) =>
code === 0 ? res(buf) : rej(new Error("token failed")),
); );
c.stdout.on('data', (d) => (buf += d));
c.on('exit', (code) => (code === 0 ? res(buf) : rej(new Error('token failed'))));
}); });
const token = JSON.parse(addOut); const token = JSON.parse(addOut);
const connPath = path.join(rootDir, 'packages/sanity-connection/index.ts'); const connPath = path.join(
let content = await fs.readFile(connPath, 'utf8'); rootDir,
"packages/sanity-connection/index.ts",
);
let content = await fs.readFile(connPath, "utf8");
content = content content = content
.replace(/publicViewerToken: "[^"]+"/, `publicViewerToken: "${token.key}"`) .replace(
.replace(/studioHost: "[^"]+"/, `studioHost: "${project.lowerCaseName}"`) /publicViewerToken: "[^"]+"/,
.replace(/studioUrl: "[^"]+"/, `studioUrl: "https://${project.lowerCaseName}.sanity.studio"`); `publicViewerToken: "${token.key}"`,
)
.replace(
/studioHost: "[^"]+"/,
`studioHost: "${project.lowerCaseName}"`,
)
.replace(
/studioUrl: "[^"]+"/,
`studioUrl: "https://${project.lowerCaseName}.sanity.studio"`,
);
await fs.writeFile(connPath, content); await fs.writeFile(connPath, content);
return 'Viewer token created and configured!'; return "Viewer token created and configured!";
}, },
}, },
]); ]);
@@ -301,21 +419,33 @@ async function main() {
if (project.faviconPath && project.faviconPath.trim()) { if (project.faviconPath && project.faviconPath.trim()) {
await p.tasks([ await p.tasks([
{ {
title: `${color.yellow('🌟 Generating favicon')}`, title: `${color.yellow("🌟 Generating favicon")}`,
task: async () => { task: async () => {
await runCommand(pm, ['create', "favicon", project.faviconPath, 'packages/ui/favicon'], rootDir); await runCommand(
await fs.copy(path.join(rootDir, 'packages/ui/favicon/'), path.join(rootDir, 'apps/client/public/'), { overwrite: true }); pm,
await fs.copy(path.join(rootDir, 'packages/ui/favicon/'), path.join(rootDir, 'apps/studio/static/'), { overwrite: true }); ["create", "favicon", project.faviconPath, "packages/ui/favicon"],
return 'Favicon generated and copied!'; rootDir,
);
await fs.copy(
path.join(rootDir, "packages/ui/favicon/"),
path.join(rootDir, "apps/client/public/"),
{ overwrite: true },
);
await fs.copy(
path.join(rootDir, "packages/ui/favicon/"),
path.join(rootDir, "apps/studio/static/"),
{ overwrite: true },
);
return "Favicon generated and copied!";
}, },
}, },
]); ]);
} }
const corsOrigins = [ const corsOrigins = [
'http://localhost:5173', "http://localhost:5173",
'https://*.api.sanity.io', "https://*.api.sanity.io",
'wss://*.api.sanity.io', "wss://*.api.sanity.io",
`https://${project.lowerCaseName}.sanity.studio`, `https://${project.lowerCaseName}.sanity.studio`,
]; ];
if (project.extraDomain && project.extraDomain.trim()) { if (project.extraDomain && project.extraDomain.trim()) {
@@ -323,27 +453,39 @@ async function main() {
} }
await p.tasks( await p.tasks(
corsOrigins.map((origin) => ({ corsOrigins.map((origin) => ({
title: `${color.cyan('🌐 Adding Sanity CORS origin:')} ${color.yellow(origin)}`, title: `${color.cyan("🌐 Adding Sanity CORS origin:")} ${color.yellow(origin)}`,
task: async () => { task: async () => {
const args = ['sanity', 'cors', 'add', origin, '--yes']; const args = ["x", "sanity", "cors", "add", origin, "--yes"];
if (origin === `https://${project.lowerCaseName}.sanity.studio`) args.push('--credentials'); if (origin === `https://${project.lowerCaseName}.sanity.studio`)
await runCommand(pmx, args, studioDir); args.push("--credentials");
return `CORS added: ${origin}` + (args.includes('--credentials') ? ' (credentials allowed)' : ''); await runCommand(pm, args, studioDir);
return (
`CORS added: ${origin}` +
(args.includes("--credentials") ? " (credentials allowed)" : "")
);
}, },
})) })),
); );
if (project.shouldGit) { if (project.shouldGit) {
await p.tasks([ await p.tasks([
{ {
title: `${color.green('🌱 Setting up Git repository')}`, title: `${color.green("🌱 Setting up Git repository")}`,
task: async () => { task: async () => {
await runCommand('git', ['config', '--global', 'init.defaultBranch', 'main'], process.cwd()); await runCommand(
await runCommand('git', ['init'], rootDir); "git",
await runCommand('git', ['add', '.'], rootDir); ["config", "--global", "init.defaultBranch", "main"],
await runCommand('git', ['commit', '-m', 'Initiated from Lumify Sanity template :rocket:'], rootDir); process.cwd(),
await runCommand('git', ['branch', '-M', 'main'], rootDir); );
return 'Git repository initialized with main branch'; await runCommand("git", ["init"], rootDir);
await runCommand("git", ["add", "."], rootDir);
await runCommand(
"git",
["commit", "-m", "Initiated from Lumify Sanity template :rocket:"],
rootDir,
);
await runCommand("git", ["branch", "-M", "main"], rootDir);
return "Git repository initialized with main branch";
}, },
}, },
]); ]);
@@ -353,27 +495,27 @@ async function main() {
const pmDeploy = `${project.packageManager} run deploy`; const pmDeploy = `${project.packageManager} run deploy`;
p.text({ p.text({
message: message: `${color.bgGreen(color.black("✨ Setup complete! ✨"))}\n${color.dim("Need help?")} ${color.underline(color.cyan("https://duckduckgo.com/"))} ${color.yellow("💡")}`,
`${color.bgGreen(color.black('✨ Setup complete! ✨'))}\n${color.dim('Need help?')} ${color.underline(color.cyan('https://duckduckgo.com/'))} ${color.yellow('💡')}`,
}); });
p.outro( p.outro(
color.bold(color.cyan('🎉 All done! Your project is ready! 🎉')) + '\n\n' + color.bold(color.cyan("🎉 All done! Your project is ready! 🎉")) +
color.bold('Next steps:\n') + "\n\n" +
` ${color.bold(color.green('cd'))} ${color.cyan(kebabName)}\n` + color.bold("Next steps:\n") +
` ${color.bold(color.green(pmRun))} ${color.dim('# Start your local dev server')} ${color.yellow('🖥️')}\n` + ` ${color.bold(color.green("cd"))} ${color.cyan(kebabName)}\n` +
` ${color.bold(color.green(pmDeploy))} ${color.dim('# Deploy your Sanity Studio')} ${color.yellow('🚀')}\n\n` + ` ${color.bold(color.green(pmRun))} ${color.dim("# Start your local dev server")} ${color.yellow("🖥️")}\n` +
color.dim('Local development:\n') + ` ${color.bold(color.green(pmDeploy))} ${color.dim("# Deploy your Sanity Studio")} ${color.yellow("🚀")}\n\n` +
` • App: ${color.cyan('http://localhost:5173')} ${color.yellow('🌐')}\n` + color.dim("Local development:\n") +
`Studio: ${color.cyan('http://localhost:3333')} ${color.yellow('🛠️')}\n\n` + `App: ${color.cyan("http://localhost:5173")} ${color.yellow("🌐")}\n` +
color.dim('After deploying:\n') + ` • Studio: ${color.cyan("http://localhost:3333")} ${color.yellow("🛠️")}\n\n` +
` • Studio: ${color.cyan(`https://${project.lowerCaseName}.sanity.studio`)} ${color.yellow('✨')}` color.dim("After deploying:\n") +
` • Studio: ${color.cyan(`https://${project.lowerCaseName}.sanity.studio`)} ${color.yellow("✨")}`,
); );
process.exit(0); process.exit(0);
} }
main().catch((err) => { main().catch((err) => {
p.log.error('An error occurred during setup:'); p.log.error("An error occurred during setup:");
p.log.error(err.message || err); p.log.error(err.message || err);
process.exit(1); process.exit(1);
}); });