diff options
Diffstat (limited to 'packages/create-astro')
-rw-r--r-- | packages/create-astro/CHANGELOG.md | 11 | ||||
-rw-r--r-- | packages/create-astro/README.md | 26 | ||||
-rw-r--r-- | packages/create-astro/package.json | 4 | ||||
-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 | ||||
-rw-r--r-- | packages/create-astro/test/context.test.js | 10 | ||||
-rw-r--r-- | packages/create-astro/test/integrations.test.js | 64 | ||||
-rw-r--r-- | packages/create-astro/test/typescript.test.js | 155 |
12 files changed, 148 insertions, 366 deletions
diff --git a/packages/create-astro/CHANGELOG.md b/packages/create-astro/CHANGELOG.md index e696dcec6..83bd93e10 100644 --- a/packages/create-astro/CHANGELOG.md +++ b/packages/create-astro/CHANGELOG.md @@ -1,5 +1,16 @@ # create-astro +## 4.11.0-beta.0 + +### Minor Changes + +- [#12083](https://github.com/withastro/astro/pull/12083) [`9263e96`](https://github.com/withastro/astro/commit/9263e965932b9a6a116801c063c6b7105c39643e) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Reworks the experience of creating a new Astro project using the `create astro` CLI command. + + - Updates the list of templates to include Starlight and combines the "minimal" and "basics" templates into a new, refreshed "Basics" template to serve as the single, minimal Astro project starter. + - Removes the TypeScript question. Astro is TypeScript-only, so this question was often misleading. The "Strict" preset is now the default, but it can still be changed manually in `tsconfig.json`. + - `astro check` is no longer automatically added to the build script. + - Added a new `--add` flag to install additional integrations after creating a project. For example, `pnpm create astro --add react` will create a new Astro project and install the React integration. + ## 4.10.0 ### Minor Changes diff --git a/packages/create-astro/README.md b/packages/create-astro/README.md index bfdfb13e3..260922b0a 100644 --- a/packages/create-astro/README.md +++ b/packages/create-astro/README.md @@ -45,19 +45,19 @@ npm create astro@latest my-astro-project -- --template cassidoo/shopify-react-as May be provided in place of prompts -| Name | Description | -| :--------------------------- | :----------------------------------------------------- | -| `--help` (`-h`) | Display available flags. | -| `--template <name>` | Specify your template. | -| `--install` / `--no-install` | Install dependencies (or not). | -| `--git` / `--no-git` | Initialize git repo (or not). | -| `--yes` (`-y`) | Skip all prompts by accepting defaults. | -| `--no` (`-n`) | Skip all prompts by declining defaults. | -| `--dry-run` | Walk through steps without executing. | -| `--skip-houston` | Skip Houston animation. | -| `--ref` | Specify an Astro branch (default: latest). | -| `--fancy` | Enable full Unicode support for Windows. | -| `--typescript <option>` | TypeScript option: `strict` / `strictest` / `relaxed`. | +| Name | Description | +| :--------------------------- | :----------------------------------------- | +| `--help` (`-h`) | Display 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. | +| `--dry-run` | Walk through steps without executing. | +| `--skip-houston` | Skip Houston animation. | +| `--ref` | Specify an Astro branch (default: latest). | +| `--fancy` | Enable full Unicode support for Windows. | [examples]: https://github.com/withastro/astro/tree/main/examples [typescript]: https://github.com/withastro/astro/tree/main/packages/astro/tsconfigs diff --git a/packages/create-astro/package.json b/packages/create-astro/package.json index 1601e4f7c..5d1846d85 100644 --- a/packages/create-astro/package.json +++ b/packages/create-astro/package.json @@ -1,6 +1,6 @@ { "name": "create-astro", - "version": "4.10.0", + "version": "4.11.0-beta.0", "type": "module", "author": "withastro", "license": "MIT", @@ -40,7 +40,7 @@ "strip-json-comments": "^5.0.1" }, "engines": { - "node": "^18.17.1 || ^20.3.0 || >=21.0.0" + "node": "^18.17.1 || ^20.3.0 || >=22.0.0" }, "publishConfig": { "provenance": true 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 }; diff --git a/packages/create-astro/test/context.test.js b/packages/create-astro/test/context.test.js index 48d2d4297..b4e67a8c6 100644 --- a/packages/create-astro/test/context.test.js +++ b/packages/create-astro/test/context.test.js @@ -51,6 +51,11 @@ describe('context', () => { assert.deepEqual(ctx.install, true); }); + it('add', async () => { + const ctx = await getContext(['--add', 'node']); + assert.deepEqual(ctx.add, ['node']); + }); + it('no install', async () => { const ctx = await getContext(['--no-install']); assert.deepEqual(ctx.install, false); @@ -65,9 +70,4 @@ describe('context', () => { const ctx = await getContext(['--no-git']); assert.deepEqual(ctx.git, false); }); - - it('typescript', async () => { - const ctx = await getContext(['--typescript', 'strict']); - assert.deepEqual(ctx.typescript, 'strict'); - }); }); diff --git a/packages/create-astro/test/integrations.test.js b/packages/create-astro/test/integrations.test.js new file mode 100644 index 000000000..412285223 --- /dev/null +++ b/packages/create-astro/test/integrations.test.js @@ -0,0 +1,64 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { dependencies } from '../dist/index.js'; +import { setup } from './utils.js'; +describe('integrations', () => { + const fixture = setup(); + + it('--add node', async () => { + const context = { + cwd: '', + yes: true, + packageManager: 'npm', + dryRun: true, + add: ['node'], + }; + + await dependencies(context); + + assert.ok(fixture.hasMessage('--dry-run Skipping dependency installation and adding node')); + }); + + it('--add node --add react', async () => { + const context = { + cwd: '', + yes: true, + packageManager: 'npm', + dryRun: true, + add: ['node', 'react'], + }; + + await dependencies(context); + + assert.ok( + fixture.hasMessage('--dry-run Skipping dependency installation and adding node, react'), + ); + }); + + it('--add node,react', async () => { + const context = { + cwd: '', + yes: true, + packageManager: 'npm', + dryRun: true, + add: ['node,react'], + }; + + await dependencies(context); + + assert.ok( + fixture.hasMessage('--dry-run Skipping dependency installation and adding node, react'), + ); + }); + + it('-y', async () => { + const context = { + cwd: '', + yes: true, + packageManager: 'npm', + dryRun: true, + }; + await dependencies(context); + assert.ok(fixture.hasMessage('--dry-run Skipping dependency installation')); + }); +}); diff --git a/packages/create-astro/test/typescript.test.js b/packages/create-astro/test/typescript.test.js deleted file mode 100644 index 0cd6a858c..000000000 --- a/packages/create-astro/test/typescript.test.js +++ /dev/null @@ -1,155 +0,0 @@ -import assert from 'node:assert/strict'; -import fs from 'node:fs'; -import { after, beforeEach, describe, it } from 'node:test'; -import { fileURLToPath } from 'node:url'; - -import { setupTypeScript, typescript } from '../dist/index.js'; -import { resetFixtures, setup } from './utils.js'; - -describe('typescript', async () => { - const fixture = setup(); - - it('none', async () => { - const context = { cwd: '', dryRun: true, prompt: () => ({ ts: 'strict', useTs: true }) }; - await typescript(context); - - assert.ok(fixture.hasMessage('Skipping TypeScript setup')); - }); - - it('use false', async () => { - const context = { cwd: '', dryRun: true, prompt: () => ({ ts: 'strict', useTs: false }) }; - await typescript(context); - - assert.ok(fixture.hasMessage('No worries')); - }); - - it('strict', async () => { - const context = { - typescript: 'strict', - cwd: '', - dryRun: true, - prompt: () => ({ ts: 'strict' }), - }; - await typescript(context); - assert.ok(fixture.hasMessage('Using strict TypeScript configuration')); - assert.ok(fixture.hasMessage('Skipping TypeScript setup')); - }); - - it('default', async () => { - const context = { - typescript: 'default', - cwd: '', - dryRun: true, - prompt: () => ({ ts: 'strict' }), - }; - await typescript(context); - assert.ok(fixture.hasMessage('Using default TypeScript configuration')); - assert.ok(fixture.hasMessage('Skipping TypeScript setup')); - }); - - it('relaxed', async () => { - const context = { - typescript: 'relaxed', - cwd: '', - dryRun: true, - prompt: () => ({ ts: 'strict' }), - }; - await typescript(context); - assert.ok(fixture.hasMessage('Using relaxed TypeScript configuration')); - assert.ok(fixture.hasMessage('Skipping TypeScript setup')); - }); - - it('other', async () => { - const context = { - typescript: 'other', - cwd: '', - dryRun: true, - prompt: () => ({ ts: 'strict' }), - exit(code) { - throw code; - }, - }; - let err = null; - try { - await typescript(context); - } catch (e) { - err = e; - } - assert.equal(err, 1); - }); -}); - -describe('typescript: setup tsconfig', async () => { - beforeEach(() => resetFixtures()); - after(() => resetFixtures()); - - it('none', async () => { - const root = new URL('./fixtures/empty/', import.meta.url); - const tsconfig = new URL('./tsconfig.json', root); - - await setupTypeScript('strict', { cwd: fileURLToPath(root) }); - assert.deepEqual(JSON.parse(fs.readFileSync(tsconfig, { encoding: 'utf-8' })), { - extends: 'astro/tsconfigs/strict', - }); - assert( - fs.readFileSync(tsconfig, { encoding: 'utf-8' }).endsWith('\n'), - 'The file does not end with a newline', - ); - }); - - it('exists', async () => { - const root = new URL('./fixtures/not-empty/', import.meta.url); - const tsconfig = new URL('./tsconfig.json', root); - await setupTypeScript('strict', { cwd: fileURLToPath(root) }); - assert.deepEqual(JSON.parse(fs.readFileSync(tsconfig, { encoding: 'utf-8' })), { - extends: 'astro/tsconfigs/strict', - }); - assert( - fs.readFileSync(tsconfig, { encoding: 'utf-8' }).endsWith('\n'), - 'The file does not end with a newline', - ); - }); -}); - -describe('typescript: setup package', async () => { - beforeEach(() => resetFixtures()); - after(() => resetFixtures()); - - it('none', async () => { - const root = new URL('./fixtures/empty/', import.meta.url); - const packageJson = new URL('./package.json', root); - - await setupTypeScript('strictest', { cwd: fileURLToPath(root), install: false }); - assert.ok(!fs.existsSync(packageJson)); - }); - - it('none', async () => { - const root = new URL('./fixtures/not-empty/', import.meta.url); - const packageJson = new URL('./package.json', root); - assert.equal( - JSON.parse(fs.readFileSync(packageJson, { encoding: 'utf-8' })).scripts.build, - 'astro build', - ); - - await setupTypeScript('strictest', { cwd: fileURLToPath(root), install: false }); - assert( - fs.readFileSync(packageJson, { encoding: 'utf-8' }).endsWith('\n'), - 'The file does not end with a newline', - ); - const { scripts, dependencies } = JSON.parse( - fs.readFileSync(packageJson, { encoding: 'utf-8' }), - ); - - assert.deepEqual( - Object.keys(scripts), - ['dev', 'build', 'preview'], - 'does not override existing scripts', - ); - - for (const value of Object.values(dependencies)) { - assert.doesNotMatch(value, /undefined$/, 'does not include undefined values'); - } - - assert.equal(scripts.build, 'astro check && astro build', 'prepends astro check command'); - }); -}); |