turned template into create cli
This commit is contained in:
17
debug.js
Executable file
17
debug.js
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import * as p from '@clack/prompts';
|
||||
|
||||
async function demoSpinner() {
|
||||
await p.tasks([
|
||||
{
|
||||
title: 'Running demo task',
|
||||
task: async () => {
|
||||
await new Promise((r) => setTimeout(r, 1500));
|
||||
return 'Demo completed!';
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
demoSpinner().catch(console.error);
|
||||
336
index.js
Executable file
336
index.js
Executable file
@@ -0,0 +1,336 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import * as p from '@clack/prompts';
|
||||
import color from 'picocolors';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { spawn, spawnSync } from 'node:child_process';
|
||||
|
||||
async function runCommand(cmd, args, cwd) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn(cmd, args, { cwd, stdio: 'ignore' });
|
||||
proc.on('exit', (code) => (code === 0 ? resolve() : reject(new Error(`Command failed: ${cmd} ${args.join(' ')}`))));
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
p.intro(`${color.bgRedBright(color.black(' ✨ Welcome to Lumify Sanity Template! ✨ '))}`);
|
||||
|
||||
const project = await p.group(
|
||||
{
|
||||
projectName: () =>
|
||||
p.text({
|
||||
message: `${color.cyan('🔖 Enter your project name (for display):')}`,
|
||||
placeholder: 'My Sanity Lumify page',
|
||||
validate: (v) => (v.length < 2 ? `${color.red('❌ Too short!')}` : undefined),
|
||||
}),
|
||||
dirName: ({ results }) => {
|
||||
const defaultKebab = String(results.projectName)
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '');
|
||||
return p.text({
|
||||
message: `${color.cyan('📂 Enter a directory name for your project:')}`,
|
||||
placeholder: `./${defaultKebab}`,
|
||||
initialValue: defaultKebab,
|
||||
validate: (v) => {
|
||||
if (v.length < 2) return `${color.red('❌ Too short!')}`;
|
||||
const kebab = String(v)
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '');
|
||||
const root = path.resolve(process.cwd(), kebab);
|
||||
if (fs.existsSync(root)) {
|
||||
return `${color.red('⚠️ Directory already exists:')} ${color.yellow(root)}`;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
},
|
||||
shouldGit: () =>
|
||||
p.confirm({
|
||||
message: `${color.green('🌱 Do you want to initialize a git repository?')}`,
|
||||
initialValue: true,
|
||||
}),
|
||||
gitOrg: ({ results }) => {
|
||||
if (!results.shouldGit) return undefined;
|
||||
return p.text({
|
||||
message: `${color.cyan('🐙 Enter the GitHub organization/user to push to (leave empty to skip remote):')}`,
|
||||
placeholder: 'my-org-or-username',
|
||||
initialValue: 'lumify-systems',
|
||||
validate: (v) => (v && !/^([\w-]+)$/.test(v) ? `${color.red('❌ Invalid org/user name!')}` : undefined),
|
||||
});
|
||||
},
|
||||
packageManager: () =>
|
||||
p.select({
|
||||
message: `${color.magenta('📦 Which package manager do you want to use?')}`,
|
||||
options: [
|
||||
{ value: 'bun', label: `${color.yellow('bun 🥯')}` },
|
||||
{ value: 'npm', label: `${color.green('npm 📦')}` },
|
||||
],
|
||||
initialValue: 'bun',
|
||||
}),
|
||||
faviconPath: () =>
|
||||
p.text({
|
||||
message: `${color.cyan('🖼️ Path to favicon SVG (leave empty to skip):')}`,
|
||||
placeholder: './myicon.svg',
|
||||
}),
|
||||
extraDomain: () =>
|
||||
p.text({
|
||||
message: `${color.cyan('🌍 Enter a domain this will run on later (leave empty to skip):')}`,
|
||||
placeholder: 'youronlinedomain.com',
|
||||
validate: () => undefined,
|
||||
}),
|
||||
},
|
||||
{
|
||||
onCancel: () => {
|
||||
p.cancel('Operation cancelled.');
|
||||
process.exit(0);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const kebabName = String(project.dirName)
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '');
|
||||
const rootDir = path.resolve(process.cwd(), kebabName);
|
||||
const pmx = project.packageManager === 'bun' ? 'bunx' : 'npx';
|
||||
const studioDir = path.join(rootDir, 'apps', 'studio');
|
||||
|
||||
await p.tasks([
|
||||
{
|
||||
title: `${color.yellow('📁 Copying template contents to root...')}`,
|
||||
task: async () => {
|
||||
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
||||
const templateDir = path.resolve(__dirname, 'template');
|
||||
await fs.ensureDir(rootDir);
|
||||
await fs.copy(templateDir, rootDir, { overwrite: true });
|
||||
return 'Template copied!';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: `${color.green(`📦 Installing dependencies with ${project.packageManager}...`)}`,
|
||||
task: async () => {
|
||||
await runCommand(project.packageManager === 'bun' ? 'bun' : 'npm', ['install'], rootDir);
|
||||
return 'Dependencies installed successfully';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: `${color.cyan('🔑 Checking Sanity login status...')}`,
|
||||
task: async () => {
|
||||
await fs.ensureDir(studioDir);
|
||||
let loggedIn = false;
|
||||
let hasProjects = false;
|
||||
try {
|
||||
const result = await new Promise((res, rej) => {
|
||||
let out = '';
|
||||
const c = spawn(pmx, ['sanity', 'projects', 'list'], { cwd: studioDir, stdio: ['ignore', 'pipe', 'pipe'] });
|
||||
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,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
encoding: "utf-8"
|
||||
})
|
||||
|
||||
let sanityJson;
|
||||
if (listProjects.stdout) {
|
||||
try {
|
||||
const lines = listProjects.stdout.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/);
|
||||
return match ? match[1] : null;
|
||||
}).filter(id => !!id);
|
||||
|
||||
if (projectIds.length > 0) {
|
||||
sanityJson = { projectId: projectIds[0] };
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error("Could not parse Sanity project list output.");
|
||||
}
|
||||
}
|
||||
if (!sanityJson || !sanityJson.projectId) {
|
||||
throw new Error("Sanity project creation failed.");
|
||||
}
|
||||
|
||||
// Update connection file with project ID
|
||||
const connPath = path.join(rootDir, "packages/sanity-connection/index.ts");
|
||||
if (!(await fs.pathExists(connPath))) {
|
||||
throw new Error(`Connection file not found at ${connPath}`);
|
||||
}
|
||||
let connFile = await fs.readFile(connPath, "utf8");
|
||||
if (!/projectId: "[^"]+"/.test(connFile)) {
|
||||
throw new Error(`Could not find projectId in ${connPath}. Please ensure the file contains a line like projectId: "${sanityJson.projectId}"`);
|
||||
}
|
||||
connFile = connFile.replace(/projectId: "[^"]+"/, `projectId: "${sanityJson.projectId}"`);
|
||||
await fs.writeFile(connPath, connFile);
|
||||
|
||||
return `Sanity project created with ID: ${sanityJson.projectId}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: `${color.green('🔐 Creating Sanity viewer token...')}`,
|
||||
task: async () => {
|
||||
if (!(await fs.pathExists(studioDir))) throw new Error(`Studio directory not found at ${studioDir}`);
|
||||
const addOut = await new Promise((res, rej) => {
|
||||
let buf = '';
|
||||
const c = spawn(
|
||||
pmx,
|
||||
['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'))));
|
||||
});
|
||||
const token = JSON.parse(addOut);
|
||||
const connPath = path.join(rootDir, 'packages/sanity-connection/index.ts');
|
||||
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"`);
|
||||
await fs.writeFile(connPath, content);
|
||||
return 'Viewer token created and configured!';
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
if (project.faviconPath && project.faviconPath.trim()) {
|
||||
await p.tasks([
|
||||
{
|
||||
title: `${color.yellow('🌟 Generating favicon...')}`,
|
||||
task: async () => {
|
||||
await runCommand(pmx, ['bun-create-favicon', project.faviconPath, 'packages/ui/favicon/'], 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 = [
|
||||
'http://localhost:3000',
|
||||
'https://*.api.sanity.io',
|
||||
'wss://*.api.sanity.io',
|
||||
`https://${kebabName}.sanity.studio`,
|
||||
];
|
||||
if (project.extraDomain && project.extraDomain.trim()) {
|
||||
corsOrigins.push(`https://${project.extraDomain.trim()}`);
|
||||
}
|
||||
await p.tasks(
|
||||
corsOrigins.map((origin) => ({
|
||||
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');
|
||||
await runCommand(pmx, args, studioDir);
|
||||
return `CORS added: ${origin}` + (args.includes('--credentials') ? ' (credentials allowed)' : '');
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
||||
if (project.shouldGit) {
|
||||
await p.tasks([
|
||||
{
|
||||
title: `${color.green('🌱 Setting up Git repository...')}`,
|
||||
task: async () => {
|
||||
await runCommand('git', ['config', '--global', 'init.defaultBranch', 'main'], process.cwd());
|
||||
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';
|
||||
},
|
||||
},
|
||||
]);
|
||||
const org = typeof project.gitOrg === 'string' ? project.gitOrg.trim() : '';
|
||||
if (org) {
|
||||
const githubUrl = `https://github.com/new?name=${kebabName}&owner=${org}`;
|
||||
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'
|
||||
);
|
||||
await runCommand('xdg-open', [githubUrl], process.cwd());
|
||||
await p.text({
|
||||
message: 'Press Enter after you have created the GitHub repository to continue...',
|
||||
placeholder: '',
|
||||
validate: () => undefined,
|
||||
});
|
||||
await p.tasks([
|
||||
{
|
||||
title: `${color.magenta('🚀 Pushing to GitHub...')}`,
|
||||
task: async () => {
|
||||
await runCommand('git', ['remote', 'add', 'origin', `git@github.com:${org}/${kebabName}.git`], rootDir);
|
||||
await runCommand('git', ['push', '-u', 'origin', 'main'], rootDir);
|
||||
return 'Pushed to GitHub successfully!';
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
const pmRun = `${project.packageManager} run dev`;
|
||||
const pmDeploy = `${project.packageManager} run deploy`;
|
||||
|
||||
p.text({
|
||||
message:
|
||||
`${color.bgGreen(color.black('✨ Setup complete! ✨'))}\n${color.dim('Need help?')} ${color.underline(color.cyan('https://docs.lumify.systems/'))} ${color.yellow('💡')}`,
|
||||
});
|
||||
|
||||
p.outro(
|
||||
color.bold(color.cyan('🎉 All done! Your project is ready! 🎉')) + '\n\n' +
|
||||
color.bold('Next steps:\n') +
|
||||
` ${color.bold(color.green('cd'))} ${color.cyan(kebabName)}\n` +
|
||||
` ${color.bold(color.green(pmRun))} ${color.dim('# Start your local dev server')} ${color.yellow('🖥️')}\n` +
|
||||
` ${color.bold(color.green(pmDeploy))} ${color.dim('# Deploy your Sanity Studio')} ${color.yellow('🚀')}\n\n` +
|
||||
color.dim('Local development:\n') +
|
||||
` • App: ${color.cyan('http://localhost:3000')} ${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('✨')}`
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
p.log.error('An error occurred during setup:');
|
||||
p.log.error(err.message || err);
|
||||
process.exit(1);
|
||||
});
|
||||
42
package.json
42
package.json
@@ -1,26 +1,24 @@
|
||||
{
|
||||
"name": "web",
|
||||
"name": "lumify-sanity-template",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"dev": "turbo run dev",
|
||||
"lint": "turbo run lint",
|
||||
"deploy": "turbo run deploy",
|
||||
"generate": "turbo run generate",
|
||||
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
|
||||
"check-types": "turbo run check-types"
|
||||
"description": "Bun create template for Lumify web/studio monorepo setup.",
|
||||
"bin": {
|
||||
"create-lumify-template": "./index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.6.2",
|
||||
"turbo": "^2.5.4",
|
||||
"typescript": "5.8.3"
|
||||
},
|
||||
"engines": {
|
||||
"bun": ">=1.2.12"
|
||||
},
|
||||
"packageManager": "bun@1.2.12",
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"packages/*"
|
||||
]
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"bun",
|
||||
"create",
|
||||
"template",
|
||||
"lumify",
|
||||
"sanity"
|
||||
],
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.11.0",
|
||||
"@types/bun": "^1.2.19",
|
||||
"colorette": "^2.0.20",
|
||||
"fs-extra": "^11.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
38
template/.gitignore
vendored
Normal file
38
template/.gitignore
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# Dependencies
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# Testing
|
||||
coverage
|
||||
|
||||
# Turbo
|
||||
.turbo
|
||||
|
||||
# Vercel
|
||||
.vercel
|
||||
|
||||
# Build Outputs
|
||||
.next/
|
||||
out/
|
||||
build
|
||||
dist
|
||||
|
||||
|
||||
# Debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
@@ -16,30 +16,30 @@
|
||||
"dependencies": {
|
||||
"@radix-ui/react-accordion": "^1.2.11",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@sanity/client": "^7.8.1",
|
||||
"@repo/sanity-connection": "*",
|
||||
"@repo/typescript-config": "*",
|
||||
"@repo/ui": "*",
|
||||
"@sanity/client": "^7.6.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^12.23.6",
|
||||
"framer-motion": "^12.23.9",
|
||||
"lucide-react": "^0.525.0",
|
||||
"next": "15.3.5",
|
||||
"next-sanity": "^9.12.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"next": "15.4.3",
|
||||
"next-sanity": "^10.0.4",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tailwind-merge": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3",
|
||||
"@repo/typescript-config": "*",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "15.3.5",
|
||||
"tailwindcss": "^4",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
"@types/node": "^24.1.0",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-config-next": "15.4.3",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"tw-animate-css": "^1.3.5",
|
||||
"typescript": "^5"
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "website",
|
||||
"name": "studio",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "package.json",
|
||||
@@ -16,23 +16,23 @@
|
||||
"sanity"
|
||||
],
|
||||
"dependencies": {
|
||||
"@repo/ui": "*",
|
||||
"@repo/sanity-connection": "*",
|
||||
"@repo/ui": "*",
|
||||
"@sanity/document-internationalization": "^3.3.3",
|
||||
"@sanity/vision": "^3.99.0",
|
||||
"@sanity/vision": "^4.1.1",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"sanity": "^3.99.0",
|
||||
"sanity": "^4.1.1",
|
||||
"sanity-plugin-link-field": "^1.4.0",
|
||||
"sanity-plugin-media": "^3.0.4",
|
||||
"sanity-plugin-seo": "^1.3.0",
|
||||
"sanity-plugin-simpler-color-input": "^3.1.0",
|
||||
"sanity-plugin-seo": "^1.3.1",
|
||||
"sanity-plugin-simpler-color-input": "^3.1.1",
|
||||
"styled-components": "^6.1.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sanity/eslint-config-studio": "^5.0.2",
|
||||
"@types/react": "^19.1.8",
|
||||
"eslint": "^9.30.1",
|
||||
"eslint": "^9.31.0",
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
3294
template/bun.lock
Normal file
3294
template/bun.lock
Normal file
File diff suppressed because it is too large
Load Diff
31
template/package.json
Normal file
31
template/package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "web",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"dev": "turbo run dev",
|
||||
"lint": "turbo run lint",
|
||||
"deploy": "turbo run deploy",
|
||||
"generate": "turbo run generate",
|
||||
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
|
||||
"check-types": "turbo run check-types"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.6.2",
|
||||
"turbo": "^2.5.5",
|
||||
"typescript": "5.8.3"
|
||||
},
|
||||
"engines": {
|
||||
"bun": ">=1.2.12"
|
||||
},
|
||||
"packageManager": "bun@1.2.12",
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"packages/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.11.0",
|
||||
"colorette": "^2.0.20",
|
||||
"fs-extra": "^11.3.0"
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,6 @@ export const sanityConnection = {
|
||||
studioHost: "vaporvee",
|
||||
studioUrl: "https://vaporvee.sanity.studio", // normaly https://<studioHost>.sanity.studio
|
||||
projectId: "ax04yw0e",
|
||||
previewUrl: "https://vaporvee.vercel.app",
|
||||
previewUrl: "http://localhost:3000",
|
||||
dataset: "production", // leave as "production" for the main dataset
|
||||
};
|
||||
0
template/packages/ui/favicon/.gitkeep
Normal file
0
template/packages/ui/favicon/.gitkeep
Normal file
Reference in New Issue
Block a user