summaryrefslogtreecommitdiff
path: root/packages/create-astro/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/create-astro/src')
-rw-r--r--packages/create-astro/src/actions/context.ts10
-rw-r--r--packages/create-astro/src/actions/dependencies.ts46
-rw-r--r--packages/create-astro/src/actions/help.ts2
-rw-r--r--packages/create-astro/src/actions/template.ts4
-rw-r--r--packages/create-astro/src/actions/typescript.ts166
-rw-r--r--packages/create-astro/src/index.ts16
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 };