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/typescript.ts105
1 files changed, 76 insertions, 29 deletions
diff --git a/packages/create-astro/src/actions/typescript.ts b/packages/create-astro/src/actions/typescript.ts
index 97ae24303..1b6f5cc80 100644
--- a/packages/create-astro/src/actions/typescript.ts
+++ b/packages/create-astro/src/actions/typescript.ts
@@ -1,15 +1,18 @@
import type { Context } from './context.js';
import { color } from '@astrojs/cli-kit';
-import fs from 'node:fs';
-import { readFile } from 'node:fs/promises';
+import { readFile, writeFile, rm } from 'node:fs/promises';
import path from 'node:path';
import stripJsonComments from 'strip-json-comments';
import { error, info, spinner, title, typescriptByDefault } from '../messages.js';
+import { shell } from '../shell.js';
-export async function typescript(
- ctx: Pick<Context, 'typescript' | 'yes' | 'prompt' | 'dryRun' | 'cwd' | 'exit'>
-) {
+type PickedTypeScriptContext = Pick<
+ Context,
+ 'typescript' | 'yes' | 'prompt' | 'dryRun' | 'cwd' | 'exit' | 'packageManager' | 'install'
+>;
+
+export async function typescript(ctx: PickedTypeScriptContext) {
let ts = ctx.typescript ?? (typeof ctx.yes !== 'undefined' ? 'strict' : undefined);
if (ts === undefined) {
const { useTs } = await ctx.prompt({
@@ -39,7 +42,7 @@ export async function typescript(
} else {
if (!['strict', 'strictest', 'relaxed', 'default', 'base'].includes(ts)) {
if (!ctx.dryRun) {
- fs.rmSync(ctx.cwd, { recursive: true, force: true });
+ await rm(ctx.cwd, { recursive: true, force: true });
}
error(
'Error',
@@ -62,7 +65,7 @@ export async function typescript(
start: 'TypeScript customizing...',
end: 'TypeScript customized',
while: () =>
- setupTypeScript(ts!, { cwd: ctx.cwd }).catch((e) => {
+ setupTypeScript(ts!, ctx).catch((e) => {
error('error', e);
process.exit(1);
}),
@@ -71,29 +74,73 @@ export async function typescript(
}
}
-export async function setupTypeScript(value: string, { cwd }: { cwd: string }) {
- const templateTSConfigPath = path.join(cwd, 'tsconfig.json');
- try {
- const data = await readFile(templateTSConfigPath, { encoding: 'utf-8' });
- const templateTSConfig = JSON.parse(stripJsonComments(data));
- if (templateTSConfig && typeof templateTSConfig === 'object') {
- const result = Object.assign(templateTSConfig, {
- extends: `astro/tsconfigs/${value}`,
- });
+const FILES_TO_UPDATE = {
+ 'package.json': async (
+ file: string,
+ options: { value: string; ctx: PickedTypeScriptContext }
+ ) => {
+ try {
+ // add required dependencies for astro check
+ if (options.ctx.install)
+ await shell(options.ctx.packageManager, ['install', '@astrojs/check', 'typescript'], {
+ cwd: path.dirname(file),
+ stdio: 'ignore',
+ });
- fs.writeFileSync(templateTSConfigPath, JSON.stringify(result, null, 2));
- } else {
- throw new Error(
- "There was an error applying the requested TypeScript settings. This could be because the template's tsconfig.json is malformed"
- );
+ // inject addtional 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')) {
+ const newPackageJson = Object.assign(parsedPackageJson, {
+ scripts: {
+ build: 'astro check && ' + buildScript,
+ },
+ });
+
+ await writeFile(file, JSON.stringify(newPackageJson, null, indent), '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);
}
- } catch (err) {
- if (err && (err as any).code === 'ENOENT') {
- // If the template doesn't have a tsconfig.json, let's add one instead
- fs.writeFileSync(
- templateTSConfigPath,
- JSON.stringify({ extends: `astro/tsconfigs/${value}` }, null, 2)
- );
+ },
+ '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));
+ } 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)
+ );
+ }
}
- }
+ },
+};
+
+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 })
+ )
+ );
}