cli improvements and typescript config changes
This commit is contained in:
84
index.js
84
index.js
@@ -72,6 +72,24 @@ async function main() {
|
||||
],
|
||||
initialValue: 'bun',
|
||||
}),
|
||||
lowerCaseName: ({ results }) => {
|
||||
const defaultLowercase = String(results.dirName || results.projectName)
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '');
|
||||
return p.text({
|
||||
message: `${color.cyan('📓 Enter a lowercase name for your project (e.g., used as')} ${color.yellow('<input>.sanity.studio')}${color.cyan('):')}`,
|
||||
placeholder: `${defaultLowercase}`,
|
||||
initialValue: defaultLowercase,
|
||||
validate: (v) => {
|
||||
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 (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: () =>
|
||||
p.text({
|
||||
message: `${color.cyan('🖼️ Path to favicon SVG (leave empty to skip):')}`,
|
||||
@@ -107,8 +125,41 @@ async function main() {
|
||||
task: async () => {
|
||||
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
||||
const templateDir = path.resolve(__dirname, 'template');
|
||||
|
||||
// Ensure root directory exists with proper permissions
|
||||
await fs.ensureDir(rootDir);
|
||||
await fs.copy(templateDir, rootDir, { overwrite: true });
|
||||
|
||||
try {
|
||||
await fs.copy(templateDir, rootDir, {
|
||||
overwrite: true,
|
||||
errorOnExist: false,
|
||||
preserveTimestamps: false
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to copy template files: ${error.message}`);
|
||||
}
|
||||
|
||||
// Rename gitignore files to .gitignore (dotfiles get lost in npm packages)
|
||||
async function renameGitignoreFiles(dir) {
|
||||
try {
|
||||
const items = await fs.readdir(dir);
|
||||
for (const item of items) {
|
||||
const itemPath = path.join(dir, item);
|
||||
const stat = await fs.stat(itemPath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
await renameGitignoreFiles(itemPath);
|
||||
} else if (item === 'gitignore') {
|
||||
const gitignorePath = path.join(dir, '.gitignore');
|
||||
await fs.move(itemPath, gitignorePath);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to rename gitignore files: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
await renameGitignoreFiles(rootDir);
|
||||
return 'Template copied!';
|
||||
},
|
||||
},
|
||||
@@ -205,13 +256,30 @@ async function main() {
|
||||
const wranglerPath = path.join(rootDir, "apps/client/wrangler.jsonc");
|
||||
if (await fs.pathExists(wranglerPath)) {
|
||||
let wranglerFile = await fs.readFile(wranglerPath, "utf8");
|
||||
wranglerFile = wranglerFile.replace(/"name": "[^"]+"/, `"name": "${kebabName}"`);
|
||||
wranglerFile = wranglerFile.replace(/"name": "[^"]+"/, `"name": "${project.lowerCaseName}"`);
|
||||
await fs.writeFile(wranglerPath, wranglerFile);
|
||||
}
|
||||
|
||||
return `Sanity project created with ID: ${sanityJson.projectId}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: `${color.blue('🗄️ Setting up production dataset for Sanity CMS')}`,
|
||||
task: async () => {
|
||||
if (!(await fs.pathExists(studioDir))) throw new Error(`Studio directory not found at ${studioDir}`);
|
||||
|
||||
try {
|
||||
await runCommand(pmx, ['sanity', 'dataset', 'create', 'production'], studioDir);
|
||||
return 'Production dataset created successfully';
|
||||
} catch (error) {
|
||||
// Check if dataset already exists
|
||||
if (error.message && error.message.includes('already exists')) {
|
||||
return 'Production dataset already exists';
|
||||
}
|
||||
throw new Error(`Failed to create production dataset: ${error.message}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: `${color.green('🔐 Creating Sanity viewer token')}`,
|
||||
task: async () => {
|
||||
@@ -231,8 +299,8 @@ async function main() {
|
||||
let content = await fs.readFile(connPath, 'utf8');
|
||||
content = content
|
||||
.replace(/publicViewerToken: "[^"]+"/, `publicViewerToken: "${token.key}"`)
|
||||
.replace(/studioHost: "[^"]+"/, `studioHost: "${kebabName}"`)
|
||||
.replace(/studioUrl: "[^"]+"/, `studioUrl: "https://${kebabName}.sanity.studio"`);
|
||||
.replace(/studioHost: "[^"]+"/, `studioHost: "${project.lowerCaseName}"`)
|
||||
.replace(/studioUrl: "[^"]+"/, `studioUrl: "https://${project.lowerCaseName}.sanity.studio"`);
|
||||
await fs.writeFile(connPath, content);
|
||||
return 'Viewer token created and configured!';
|
||||
},
|
||||
@@ -257,7 +325,7 @@ async function main() {
|
||||
'http://localhost:5173',
|
||||
'https://*.api.sanity.io',
|
||||
'wss://*.api.sanity.io',
|
||||
`https://${kebabName}.sanity.studio`,
|
||||
`https://${project.lowerCaseName}.sanity.studio`,
|
||||
];
|
||||
if (project.extraDomain && project.extraDomain.trim()) {
|
||||
corsOrigins.push(`https://${project.extraDomain.trim()}`);
|
||||
@@ -267,7 +335,7 @@ async function main() {
|
||||
title: `${color.cyan('🌐 Adding Sanity CORS origin:')} ${color.yellow(origin)}`,
|
||||
task: async () => {
|
||||
const args = ['sanity', 'cors', 'add', origin, '--yes'];
|
||||
if (origin === `https://${kebabName}.sanity.studio`) args.push('--credentials');
|
||||
if (origin === `https://${project.lowerCaseName}.sanity.studio`) args.push('--credentials');
|
||||
await runCommand(pmx, args, studioDir);
|
||||
return `CORS added: ${origin}` + (args.includes('--credentials') ? ' (credentials allowed)' : '');
|
||||
},
|
||||
@@ -290,7 +358,7 @@ async function main() {
|
||||
]);
|
||||
const org = typeof project.gitOrg === 'string' ? project.gitOrg.trim() : '';
|
||||
if (org) {
|
||||
const githubUrl = `https://github.com/new?name=${kebabName}&owner=${org}`;
|
||||
const githubUrl = `https://github.com/new?name=${kebabName}&owner=${org}&visibility=private&description=${encodeURIComponent('This website was built using the official Lumify starter template for building with Sveltekit, Sanity, Bun, and Shadcn UI — bundled into a NX monorepo.')}`;
|
||||
p.note(
|
||||
`Please create a new GitHub repository named\n\`${kebabName}\` under \`${org}\` at:\n\n${color.cyan(githubUrl)}\n\nThe browser will open for you.`,
|
||||
'GitHub Setup Required'
|
||||
@@ -332,7 +400,7 @@ async function main() {
|
||||
` • App: ${color.cyan('http://localhost:5173')} ${color.yellow('🌐')}\n` +
|
||||
` • Studio: ${color.cyan('http://localhost:3333')} ${color.yellow('🛠️')}\n\n` +
|
||||
color.dim('After deploying:\n') +
|
||||
` • Studio: ${color.cyan(`https://${kebabName}.sanity.studio`)} ${color.yellow('✨')}`
|
||||
` • Studio: ${color.cyan(`https://${project.lowerCaseName}.sanity.studio`)} ${color.yellow('✨')}`
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user