diff options
Diffstat (limited to 'packages/create-astro/src')
-rw-r--r-- | packages/create-astro/src/actions/context.ts | 10 | ||||
-rw-r--r-- | packages/create-astro/src/actions/dependencies.ts | 46 | ||||
-rw-r--r-- | packages/create-astro/src/actions/help.ts | 2 | ||||
-rw-r--r-- | packages/create-astro/src/actions/template.ts | 4 | ||||
-rw-r--r-- | packages/create-astro/src/actions/typescript.ts | 166 | ||||
-rw-r--r-- | packages/create-astro/src/index.ts | 16 |
6 files changed, 53 insertions, 191 deletions
diff --git a/packages/create-astro/src/actions/context.ts b/packages/create-astro/src/actions/context.ts index 83a13eda7..59f85f88a 100644 --- a/packages/create-astro/src/actions/context.ts +++ b/packages/create-astro/src/actions/context.ts @@ -15,6 +15,7 @@ export interface Context { version: Promise<string>; skipHouston: boolean; fancy?: boolean; + add?: string[]; dryRun?: boolean; yes?: boolean; projectName?: string; @@ -43,11 +44,11 @@ export async function getContext(argv: string[]): Promise<Context> { '--no-install': Boolean, '--git': Boolean, '--no-git': Boolean, - '--typescript': String, '--skip-houston': Boolean, '--dry-run': Boolean, '--help': Boolean, '--fancy': Boolean, + '--add': [String], '-y': '--yes', '-n': '--no', @@ -67,11 +68,11 @@ export async function getContext(argv: string[]): Promise<Context> { '--no-install': noInstall, '--git': git, '--no-git': noGit, - '--typescript': typescript, '--fancy': fancy, '--skip-houston': skipHouston, '--dry-run': dryRun, '--ref': ref, + '--add': add, } = flags; let projectName = cwd; @@ -79,12 +80,11 @@ export async function getContext(argv: string[]): Promise<Context> { yes = false; if (install == undefined) install = false; if (git == undefined) git = false; - if (typescript == undefined) typescript = 'strict'; } skipHouston = ((os.platform() === 'win32' && !fancy) || skipHouston) ?? - [yes, no, install, git, typescript].some((v) => v !== undefined); + [yes, no, install, git].some((v) => v !== undefined); const { messages, hats, ties } = getSeasonalData({ fancy }); @@ -96,6 +96,7 @@ export async function getContext(argv: string[]): Promise<Context> { version: getVersion(packageManager, 'astro', process.env.ASTRO_VERSION), skipHouston, fancy, + add, dryRun, projectName, template, @@ -106,7 +107,6 @@ export async function getContext(argv: string[]): Promise<Context> { yes, install: install ?? (noInstall ? false : undefined), git: git ?? (noGit ? false : undefined), - typescript, cwd, exit(code) { process.exit(code); diff --git a/packages/create-astro/src/actions/dependencies.ts b/packages/create-astro/src/actions/dependencies.ts index 6a9b6fccb..d4990a8fb 100644 --- a/packages/create-astro/src/actions/dependencies.ts +++ b/packages/create-astro/src/actions/dependencies.ts @@ -6,7 +6,10 @@ import { shell } from '../shell.js'; import type { Context } from './context.js'; export async function dependencies( - ctx: Pick<Context, 'install' | 'yes' | 'prompt' | 'packageManager' | 'cwd' | 'dryRun' | 'tasks'>, + ctx: Pick< + Context, + 'install' | 'yes' | 'prompt' | 'packageManager' | 'cwd' | 'dryRun' | 'tasks' | 'add' + >, ) { let deps = ctx.install ?? ctx.yes; if (deps === undefined) { @@ -21,8 +24,13 @@ export async function dependencies( ctx.install = deps; } + ctx.add = ctx.add?.reduce<string[]>((acc, item) => acc.concat(item.split(',')), []); + if (ctx.dryRun) { - await info('--dry-run', `Skipping dependency installation`); + await info( + '--dry-run', + `Skipping dependency installation${ctx.add ? ` and adding ${ctx.add.join(', ')}` : ''}`, + ); } else if (deps) { ctx.tasks.push({ pending: 'Dependencies', @@ -39,6 +47,27 @@ export async function dependencies( }, while: () => install({ packageManager: ctx.packageManager, cwd: ctx.cwd }), }); + + let add = ctx.add; + + if (add) { + ctx.tasks.push({ + pending: 'Integrations', + start: `Adding integrations with astro add`, + end: 'Integrations added', + onError: (e) => { + error('error', e); + error( + 'error', + `Failed to add integrations, please run ${color.bold( + `astro add ${add.join(' ')}`, + )} to install them manually after setup.`, + ); + }, + while: () => + astroAdd({ integrations: add, packageManager: ctx.packageManager, cwd: ctx.cwd }), + }); + } } else { await info( ctx.yes === false ? 'deps [skip]' : 'No problem!', @@ -47,6 +76,19 @@ export async function dependencies( } } +async function astroAdd({ + integrations, + packageManager, + cwd, +}: { integrations: string[]; packageManager: string; cwd: string }) { + if (packageManager === 'yarn') await ensureYarnLock({ cwd }); + return shell( + packageManager === 'npm' ? 'npx' : `${packageManager} dlx`, + ['astro add', integrations.join(' '), '-y'], + { cwd, timeout: 90_000, stdio: 'ignore' }, + ); +} + async function install({ packageManager, cwd }: { packageManager: string; cwd: string }) { if (packageManager === 'yarn') await ensureYarnLock({ cwd }); return shell(packageManager, ['install'], { cwd, timeout: 90_000, stdio: 'ignore' }); diff --git a/packages/create-astro/src/actions/help.ts b/packages/create-astro/src/actions/help.ts index 097dfa701..1d5c7f609 100644 --- a/packages/create-astro/src/actions/help.ts +++ b/packages/create-astro/src/actions/help.ts @@ -10,6 +10,7 @@ export function help() { ['--help (-h)', 'See all available flags.'], ['--template <name>', 'Specify your template.'], ['--install / --no-install', 'Install dependencies (or not).'], + ['--add <integrations>', 'Add integrations.'], ['--git / --no-git', 'Initialize git repo (or not).'], ['--yes (-y)', 'Skip all prompts by accepting defaults.'], ['--no (-n)', 'Skip all prompts by declining defaults.'], @@ -17,7 +18,6 @@ export function help() { ['--skip-houston', 'Skip Houston animation.'], ['--ref', 'Choose astro branch (default: latest).'], ['--fancy', 'Enable full Unicode support for Windows.'], - ['--typescript <option>', 'TypeScript option: strict | strictest | relaxed.'], ], }, }); diff --git a/packages/create-astro/src/actions/template.ts b/packages/create-astro/src/actions/template.ts index a5d217e0e..512e1f921 100644 --- a/packages/create-astro/src/actions/template.ts +++ b/packages/create-astro/src/actions/template.ts @@ -21,9 +21,9 @@ export async function template( message: 'How would you like to start your new project?', initial: 'basics', choices: [ - { value: 'basics', label: 'Include sample files', hint: '(recommended)' }, + { value: 'basics', label: 'A basic, minimal starter', hint: '(recommended)' }, { value: 'blog', label: 'Use blog template' }, - { value: 'minimal', label: 'Empty' }, + { value: 'starlight', label: 'Use docs (Starlight) template' }, ], }); ctx.template = tmpl; diff --git a/packages/create-astro/src/actions/typescript.ts b/packages/create-astro/src/actions/typescript.ts deleted file mode 100644 index 6fb6c7104..000000000 --- a/packages/create-astro/src/actions/typescript.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { readFile, rm, writeFile } from 'node:fs/promises'; -import path from 'node:path'; -import { color } from '@astrojs/cli-kit'; -import stripJsonComments from 'strip-json-comments'; -import { error, getVersion, info, title, typescriptByDefault } from '../messages.js'; -import type { Context } from './context.js'; - -type PickedTypeScriptContext = Pick< - Context, - | 'typescript' - | 'yes' - | 'prompt' - | 'dryRun' - | 'cwd' - | 'exit' - | 'packageManager' - | 'install' - | 'tasks' ->; - -export async function typescript(ctx: PickedTypeScriptContext) { - let ts = ctx.typescript ?? (typeof ctx.yes !== 'undefined' ? 'strict' : undefined); - if (ts === undefined) { - const { useTs } = await ctx.prompt({ - name: 'useTs', - type: 'confirm', - label: title('ts'), - message: `Do you plan to write TypeScript?`, - initial: true, - }); - if (!useTs) { - await typescriptByDefault(); - return; - } - - ({ ts } = await ctx.prompt({ - name: 'ts', - type: 'select', - label: title('use'), - message: `How strict should TypeScript be?`, - initial: 'strict', - choices: [ - { value: 'strict', label: 'Strict', hint: `(recommended)` }, - { value: 'strictest', label: 'Strictest' }, - { value: 'base', label: 'Relaxed' }, - ], - })); - } else { - if (!['strict', 'strictest', 'relaxed', 'default', 'base'].includes(ts)) { - if (!ctx.dryRun) { - await rm(ctx.cwd, { recursive: true, force: true }); - } - error( - 'Error', - `Unknown TypeScript option ${color.reset(ts)}${color.dim( - '! Expected strict | strictest | relaxed', - )}`, - ); - ctx.exit(1); - } - await info('ts', `Using ${color.reset(ts)}${color.dim(' TypeScript configuration')}`); - } - - if (ctx.dryRun) { - await info('--dry-run', `Skipping TypeScript setup`); - } else if (ts && ts !== 'unsure') { - if (ts === 'relaxed' || ts === 'default') { - ts = 'base'; - } - ctx.tasks.push({ - pending: 'TypeScript', - start: 'TypeScript customizing...', - end: 'TypeScript customized', - while: () => - setupTypeScript(ts!, ctx).catch((e) => { - error('error', e); - process.exit(1); - }), - }); - } else { - } -} - -const FILES_TO_UPDATE = { - 'package.json': async ( - file: string, - options: { value: string; ctx: PickedTypeScriptContext }, - ) => { - try { - // inject additional command to build script - const data = await readFile(file, { encoding: 'utf-8' }); - const indent = /(^\s+)/m.exec(data)?.[1] ?? '\t'; - const parsedPackageJson = JSON.parse(data); - - const buildScript = parsedPackageJson.scripts?.build; - - // in case of any other template already have astro checks defined, we don't want to override it - if (typeof buildScript === 'string' && !buildScript.includes('astro check')) { - // Mutate the existing object to avoid changing user-defined script order - parsedPackageJson.scripts.build = `astro check && ${buildScript}`; - } - - const [astroCheckVersion, typescriptVersion] = await Promise.all([ - getVersion(options.ctx.packageManager, '@astrojs/check', process.env.ASTRO_CHECK_VERSION), - getVersion(options.ctx.packageManager, 'typescript', process.env.TYPESCRIPT_VERSION), - ]); - parsedPackageJson.dependencies ??= {}; - parsedPackageJson.dependencies['@astrojs/check'] = `^${astroCheckVersion}`; - parsedPackageJson.dependencies.typescript = `^${typescriptVersion}`; - - await writeFile(file, JSON.stringify(parsedPackageJson, null, indent) + '\n', 'utf-8'); - } catch (err) { - // if there's no package.json (which is very unlikely), then do nothing - if (err && (err as any).code === 'ENOENT') return; - if (err instanceof Error) throw new Error(err.message); - } - }, - 'tsconfig.json': async (file: string, options: { value: string }) => { - try { - const data = await readFile(file, { encoding: 'utf-8' }); - const templateTSConfig = JSON.parse(stripJsonComments(data)); - if (templateTSConfig && typeof templateTSConfig === 'object') { - const result = Object.assign(templateTSConfig, { - extends: `astro/tsconfigs/${options.value}`, - }); - - await writeFile(file, JSON.stringify(result, null, 2) + '\n'); - } else { - throw new Error( - "There was an error applying the requested TypeScript settings. This could be because the template's tsconfig.json is malformed", - ); - } - } catch (err) { - if (err && (err as any).code === 'ENOENT') { - // If the template doesn't have a tsconfig.json, let's add one instead - await writeFile( - file, - JSON.stringify({ extends: `astro/tsconfigs/${options.value}` }, null, 2) + '\n', - ); - } - } - }, - 'astro.config.mjs': async (file: string, options: { value: string }) => { - if (!(options.value === 'strict' || options.value === 'strictest')) { - return; - } - - try { - let data = await readFile(file, { encoding: 'utf-8' }); - data = `// @ts-check\n${data}`; - await writeFile(file, data, { encoding: 'utf-8' }); - } catch (err) { - // if there's no astro.config.mjs (which is very unlikely), then do nothing - if (err && (err as any).code === 'ENOENT') return; - if (err instanceof Error) throw new Error(err.message); - } - }, -}; - -export async function setupTypeScript(value: string, ctx: PickedTypeScriptContext) { - await Promise.all( - Object.entries(FILES_TO_UPDATE).map(async ([file, update]) => - update(path.resolve(path.join(ctx.cwd, file)), { value, ctx }), - ), - ); -} diff --git a/packages/create-astro/src/index.ts b/packages/create-astro/src/index.ts index fdd0aa32c..60816f75d 100644 --- a/packages/create-astro/src/index.ts +++ b/packages/create-astro/src/index.ts @@ -8,7 +8,6 @@ import { intro } from './actions/intro.js'; import { next } from './actions/next-steps.js'; import { projectName } from './actions/project-name.js'; import { template } from './actions/template.js'; -import { setupTypeScript, typescript } from './actions/typescript.js'; import { verify } from './actions/verify.js'; import { setStdout } from './messages.js'; @@ -36,7 +35,6 @@ export async function main() { intro, projectName, template, - typescript, dependencies, // Steps which write to files need to go above git @@ -61,16 +59,4 @@ export async function main() { process.exit(0); } -export { - dependencies, - getContext, - git, - intro, - next, - projectName, - setStdout, - setupTypeScript, - template, - typescript, - verify, -}; +export { dependencies, getContext, git, intro, next, projectName, setStdout, template, verify }; |