diff options
60 files changed, 367 insertions, 614 deletions
diff --git a/.changeset/old-actors-learn.md b/.changeset/old-actors-learn.md new file mode 100644 index 000000000..0691a7a5b --- /dev/null +++ b/.changeset/old-actors-learn.md @@ -0,0 +1,10 @@ +--- +'create-astro': minor +--- + +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. diff --git a/examples/basics/README.md b/examples/basics/README.md index 1db3fb399..ff19a3e7e 100644 --- a/examples/basics/README.md +++ b/examples/basics/README.md @@ -21,8 +21,6 @@ Inside of your Astro project, you'll see the following folders and files: ├── public/ │ └── favicon.svg ├── src/ -│ ├── components/ -│ │ └── Card.astro │ ├── layouts/ │ │ └── Layout.astro │ └── pages/ @@ -30,11 +28,7 @@ Inside of your Astro project, you'll see the following folders and files: └── package.json ``` -Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. - -There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. - -Any static assets, like images, can be placed in the `public/` directory. +To learn more about the folder structure of an Astro project, refer to [our guide on project structure](https://docs.astro.build/en/basics/project-structure/). ## 🧞 Commands diff --git a/examples/basics/astro.config.mjs b/examples/basics/astro.config.mjs index 882e6515a..e762ba5cf 100644 --- a/examples/basics/astro.config.mjs +++ b/examples/basics/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; // https://astro.build/config diff --git a/examples/basics/src/components/Card.astro b/examples/basics/src/components/Card.astro deleted file mode 100644 index bd6d5971e..000000000 --- a/examples/basics/src/components/Card.astro +++ /dev/null @@ -1,61 +0,0 @@ ---- -interface Props { - title: string; - body: string; - href: string; -} - -const { href, title, body } = Astro.props; ---- - -<li class="link-card"> - <a href={href}> - <h2> - {title} - <span>→</span> - </h2> - <p> - {body} - </p> - </a> -</li> -<style> - .link-card { - list-style: none; - display: flex; - padding: 1px; - background-color: #23262d; - background-image: none; - background-size: 400%; - border-radius: 7px; - background-position: 100%; - transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1); - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); - } - .link-card > a { - width: 100%; - text-decoration: none; - line-height: 1.4; - padding: calc(1.5rem - 1px); - border-radius: 8px; - color: white; - background-color: #23262d; - opacity: 0.8; - } - h2 { - margin: 0; - font-size: 1.25rem; - transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1); - } - p { - margin-top: 0.5rem; - margin-bottom: 0; - } - .link-card:is(:hover, :focus-within) { - background-position: 0; - background-image: var(--accent-gradient); - } - .link-card:is(:hover, :focus-within) h2 { - color: rgb(var(--accent-light)); - } -</style> diff --git a/examples/basics/src/layouts/Layout.astro b/examples/basics/src/layouts/Layout.astro index 181097125..a25b9e69d 100644 --- a/examples/basics/src/layouts/Layout.astro +++ b/examples/basics/src/layouts/Layout.astro @@ -1,50 +1,13 @@ ---- -interface Props { - title: string; -} - -const { title } = Astro.props; ---- - <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> - <meta name="description" content="Astro description" /> <meta name="viewport" content="width=device-width" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="generator" content={Astro.generator} /> - <title>{title}</title> + <title>Astro Basics</title> </head> <body> <slot /> </body> </html> -<style is:global> - :root { - --accent: 136, 58, 234; - --accent-light: 224, 204, 250; - --accent-dark: 49, 10, 101; - --accent-gradient: linear-gradient( - 45deg, - rgb(var(--accent)), - rgb(var(--accent-light)) 30%, - white 60% - ); - } - html { - font-family: system-ui, sans-serif; - background: #13151a; - } - code { - font-family: - Menlo, - Monaco, - Lucida Console, - Liberation Mono, - DejaVu Sans Mono, - Bitstream Vera Sans Mono, - Courier New, - monospace; - } -</style> diff --git a/examples/basics/src/pages/index.astro b/examples/basics/src/pages/index.astro index fb6262872..a2bf4ee37 100644 --- a/examples/basics/src/pages/index.astro +++ b/examples/basics/src/pages/index.astro @@ -1,123 +1,8 @@ --- +import { Welcome } from 'astro:components'; import Layout from '../layouts/Layout.astro'; -import Card from '../components/Card.astro'; --- -<Layout title="Welcome to Astro."> - <main> - <svg - class="astro-a" - width="495" - height="623" - viewBox="0 0 495 623" - fill="none" - xmlns="http://www.w3.org/2000/svg" - aria-hidden="true" - > - <path - fill-rule="evenodd" - clip-rule="evenodd" - d="M167.19 364.254C83.4786 364.254 0 404.819 0 404.819C0 404.819 141.781 19.4876 142.087 18.7291C146.434 7.33701 153.027 0 162.289 0H332.441C341.703 0 348.574 7.33701 352.643 18.7291C352.92 19.5022 494.716 404.819 494.716 404.819C494.716 404.819 426.67 364.254 327.525 364.254L264.41 169.408C262.047 159.985 255.147 153.581 247.358 153.581C239.569 153.581 232.669 159.985 230.306 169.408L167.19 364.254ZM160.869 530.172C160.877 530.18 160.885 530.187 160.894 530.195L160.867 530.181C160.868 530.178 160.868 530.175 160.869 530.172ZM136.218 411.348C124.476 450.467 132.698 504.458 160.869 530.172C160.997 529.696 161.125 529.242 161.248 528.804C161.502 527.907 161.737 527.073 161.917 526.233C165.446 509.895 178.754 499.52 195.577 500.01C211.969 500.487 220.67 508.765 223.202 527.254C224.141 534.12 224.23 541.131 224.319 548.105C224.328 548.834 224.337 549.563 224.347 550.291C224.563 566.098 228.657 580.707 237.264 593.914C245.413 606.426 256.108 615.943 270.749 622.478C270.593 621.952 270.463 621.508 270.35 621.126C270.045 620.086 269.872 619.499 269.685 618.911C258.909 585.935 266.668 563.266 295.344 543.933C298.254 541.971 301.187 540.041 304.12 538.112C310.591 533.854 317.059 529.599 323.279 525.007C345.88 508.329 360.09 486.327 363.431 457.844C364.805 446.148 363.781 434.657 359.848 423.275C358.176 424.287 356.587 425.295 355.042 426.275C351.744 428.366 348.647 430.33 345.382 431.934C303.466 452.507 259.152 455.053 214.03 448.245C184.802 443.834 156.584 436.019 136.218 411.348Z" - fill="url(#paint0_linear_1805_24383)"></path> - <defs> - <linearGradient - id="paint0_linear_1805_24383" - x1="247.358" - y1="0" - x2="247.358" - y2="622.479" - gradientUnits="userSpaceOnUse" - > - <stop stop-opacity="0.9"></stop> - <stop offset="1" stop-opacity="0.2"></stop> - </linearGradient> - </defs> - </svg> - <h1>Welcome to <span class="text-gradient">Astro</span></h1> - <p class="instructions"> - To get started, open the directory <code>src/pages</code> in your project.<br /> - <strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above. - </p> - <ul role="list" class="link-card-grid"> - <Card - href="https://docs.astro.build/" - title="Documentation" - body="Learn how Astro works and explore the official API docs." - /> - <Card - href="https://astro.build/integrations/" - title="Integrations" - body="Supercharge your project with new frameworks and libraries." - /> - <Card - href="https://astro.build/themes/" - title="Themes" - body="Explore a galaxy of community-built starter themes." - /> - <Card - href="https://astro.build/chat/" - title="Community" - body="Come say hi to our amazing Discord community. ❤️" - /> - </ul> - </main> +<Layout> + <Welcome title="Welcome to Astro" /> </Layout> - -<style> - main { - margin: auto; - padding: 1rem; - width: 800px; - max-width: calc(100% - 2rem); - color: white; - font-size: 20px; - line-height: 1.6; - } - .astro-a { - position: absolute; - top: -32px; - left: 50%; - transform: translatex(-50%); - width: 220px; - height: auto; - z-index: -1; - } - h1 { - font-size: 4rem; - font-weight: 700; - line-height: 1; - text-align: center; - margin-bottom: 1em; - } - .text-gradient { - background-image: var(--accent-gradient); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-size: 400%; - background-position: 0%; - } - .instructions { - margin-bottom: 2rem; - border: 1px solid rgba(var(--accent-light), 25%); - background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%)); - padding: 1.5rem; - border-radius: 8px; - } - .instructions code { - font-size: 0.8em; - font-weight: bold; - background: rgba(var(--accent-light), 12%); - color: rgb(var(--accent-light)); - border-radius: 4px; - padding: 0.3em 0.4em; - } - .instructions strong { - color: rgb(var(--accent-light)); - } - .link-card-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr)); - gap: 2rem; - padding: 0; - } -</style> diff --git a/examples/basics/tsconfig.json b/examples/basics/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/basics/tsconfig.json +++ b/examples/basics/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/blog/astro.config.mjs b/examples/blog/astro.config.mjs index 3b2f75c84..d45f3951e 100644 --- a/examples/blog/astro.config.mjs +++ b/examples/blog/astro.config.mjs @@ -1,6 +1,6 @@ +// @ts-check import { defineConfig } from 'astro/config'; import mdx from '@astrojs/mdx'; - import sitemap from '@astrojs/sitemap'; // https://astro.build/config diff --git a/examples/blog/tsconfig.json b/examples/blog/tsconfig.json index 676d1945a..0dc098dd7 100644 --- a/examples/blog/tsconfig.json +++ b/examples/blog/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/component/tsconfig.json b/examples/component/tsconfig.json index e2bdd98c6..f85ec795b 100644 --- a/examples/component/tsconfig.json +++ b/examples/component/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/container-with-vitest/tsconfig.json b/examples/container-with-vitest/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/container-with-vitest/tsconfig.json +++ b/examples/container-with-vitest/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/framework-alpine/astro.config.mjs b/examples/framework-alpine/astro.config.mjs index 60bfc7d45..5fddf7717 100644 --- a/examples/framework-alpine/astro.config.mjs +++ b/examples/framework-alpine/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import alpine from '@astrojs/alpinejs'; diff --git a/examples/framework-alpine/tsconfig.json b/examples/framework-alpine/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/framework-alpine/tsconfig.json +++ b/examples/framework-alpine/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/framework-multiple/astro.config.mjs b/examples/framework-multiple/astro.config.mjs index 36f75aec2..7609d3fc6 100644 --- a/examples/framework-multiple/astro.config.mjs +++ b/examples/framework-multiple/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import preact from '@astrojs/preact'; import react from '@astrojs/react'; diff --git a/examples/framework-multiple/tsconfig.json b/examples/framework-multiple/tsconfig.json index 1d2def771..a19c58a62 100644 --- a/examples/framework-multiple/tsconfig.json +++ b/examples/framework-multiple/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/framework-preact/astro.config.mjs b/examples/framework-preact/astro.config.mjs index b1c8d1150..1d726f9fe 100644 --- a/examples/framework-preact/astro.config.mjs +++ b/examples/framework-preact/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import preact from '@astrojs/preact'; diff --git a/examples/framework-preact/tsconfig.json b/examples/framework-preact/tsconfig.json index 50ad34429..c8983c2ef 100644 --- a/examples/framework-preact/tsconfig.json +++ b/examples/framework-preact/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/framework-react/astro.config.mjs b/examples/framework-react/astro.config.mjs index 4b5a68ec0..36ed34a5e 100644 --- a/examples/framework-react/astro.config.mjs +++ b/examples/framework-react/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; diff --git a/examples/framework-react/tsconfig.json b/examples/framework-react/tsconfig.json index 866156f07..92a18df90 100644 --- a/examples/framework-react/tsconfig.json +++ b/examples/framework-react/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/framework-solid/astro.config.mjs b/examples/framework-solid/astro.config.mjs index 623fb8ea5..8bdaa2679 100644 --- a/examples/framework-solid/astro.config.mjs +++ b/examples/framework-solid/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import solid from '@astrojs/solid-js'; diff --git a/examples/framework-solid/tsconfig.json b/examples/framework-solid/tsconfig.json index 7db18fbb3..76e1efdba 100644 --- a/examples/framework-solid/tsconfig.json +++ b/examples/framework-solid/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/framework-svelte/astro.config.mjs b/examples/framework-svelte/astro.config.mjs index 194e45917..5eeedb56e 100644 --- a/examples/framework-svelte/astro.config.mjs +++ b/examples/framework-svelte/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import svelte from '@astrojs/svelte'; diff --git a/examples/framework-svelte/tsconfig.json b/examples/framework-svelte/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/framework-svelte/tsconfig.json +++ b/examples/framework-svelte/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/framework-vue/astro.config.mjs b/examples/framework-vue/astro.config.mjs index f30130a95..5afe92269 100644 --- a/examples/framework-vue/astro.config.mjs +++ b/examples/framework-vue/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import vue from '@astrojs/vue'; diff --git a/examples/framework-vue/tsconfig.json b/examples/framework-vue/tsconfig.json index 1d2def771..a19c58a62 100644 --- a/examples/framework-vue/tsconfig.json +++ b/examples/framework-vue/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/hackernews/astro.config.mjs b/examples/hackernews/astro.config.mjs index 68ba7fac5..bf6f1a022 100644 --- a/examples/hackernews/astro.config.mjs +++ b/examples/hackernews/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import node from '@astrojs/node'; diff --git a/examples/hackernews/tsconfig.json b/examples/hackernews/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/hackernews/tsconfig.json +++ b/examples/hackernews/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/integration/tsconfig.json b/examples/integration/tsconfig.json index d78f81ec4..bcbf8b509 100644 --- a/examples/integration/tsconfig.json +++ b/examples/integration/tsconfig.json @@ -1,3 +1,3 @@ { - "extends": "astro/tsconfigs/base" + "extends": "astro/tsconfigs/strict" } diff --git a/examples/minimal/astro.config.mjs b/examples/minimal/astro.config.mjs index 882e6515a..e762ba5cf 100644 --- a/examples/minimal/astro.config.mjs +++ b/examples/minimal/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; // https://astro.build/config diff --git a/examples/minimal/tsconfig.json b/examples/minimal/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/minimal/tsconfig.json +++ b/examples/minimal/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/portfolio/astro.config.mjs b/examples/portfolio/astro.config.mjs index 882e6515a..e762ba5cf 100644 --- a/examples/portfolio/astro.config.mjs +++ b/examples/portfolio/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; // https://astro.build/config diff --git a/examples/portfolio/tsconfig.json b/examples/portfolio/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/portfolio/tsconfig.json +++ b/examples/portfolio/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/server-islands/tsconfig.json b/examples/server-islands/tsconfig.json new file mode 100644 index 000000000..8bf91d3bb --- /dev/null +++ b/examples/server-islands/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] +} diff --git a/examples/ssr/astro.config.mjs b/examples/ssr/astro.config.mjs index b79949397..78d88cb1a 100644 --- a/examples/ssr/astro.config.mjs +++ b/examples/ssr/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import svelte from '@astrojs/svelte'; import node from '@astrojs/node'; diff --git a/examples/ssr/tsconfig.json b/examples/ssr/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/ssr/tsconfig.json +++ b/examples/ssr/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/starlog/astro.config.mjs b/examples/starlog/astro.config.mjs index b093ec0e0..759bb082c 100644 --- a/examples/starlog/astro.config.mjs +++ b/examples/starlog/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; // https://astro.build/config diff --git a/examples/toolbar-app/tsconfig.json b/examples/toolbar-app/tsconfig.json index b3e754ea0..281fb7f92 100644 --- a/examples/toolbar-app/tsconfig.json +++ b/examples/toolbar-app/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "compilerOptions": { "outDir": "dist", "rootDir": "src" diff --git a/examples/with-markdoc/astro.config.mjs b/examples/with-markdoc/astro.config.mjs index 29d846359..517f5a62e 100644 --- a/examples/with-markdoc/astro.config.mjs +++ b/examples/with-markdoc/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import markdoc from '@astrojs/markdoc'; diff --git a/examples/with-markdoc/tsconfig.json b/examples/with-markdoc/tsconfig.json index 676d1945a..0dc098dd7 100644 --- a/examples/with-markdoc/tsconfig.json +++ b/examples/with-markdoc/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/with-mdx/astro.config.mjs b/examples/with-mdx/astro.config.mjs index d797941ec..93aeffbc5 100644 --- a/examples/with-mdx/astro.config.mjs +++ b/examples/with-mdx/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import mdx from '@astrojs/mdx'; import preact from '@astrojs/preact'; diff --git a/examples/with-mdx/tsconfig.json b/examples/with-mdx/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/with-mdx/tsconfig.json +++ b/examples/with-mdx/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/with-nanostores/astro.config.mjs b/examples/with-nanostores/astro.config.mjs index 3e161041b..9f7dbd219 100644 --- a/examples/with-nanostores/astro.config.mjs +++ b/examples/with-nanostores/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import preact from '@astrojs/preact'; diff --git a/examples/with-nanostores/tsconfig.json b/examples/with-nanostores/tsconfig.json index 50ad34429..c8983c2ef 100644 --- a/examples/with-nanostores/tsconfig.json +++ b/examples/with-nanostores/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { diff --git a/examples/with-tailwindcss/astro.config.mjs b/examples/with-tailwindcss/astro.config.mjs index 4ad396807..7c7ad346f 100644 --- a/examples/with-tailwindcss/astro.config.mjs +++ b/examples/with-tailwindcss/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; import tailwind from '@astrojs/tailwind'; diff --git a/examples/with-tailwindcss/tsconfig.json b/examples/with-tailwindcss/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/with-tailwindcss/tsconfig.json +++ b/examples/with-tailwindcss/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/examples/with-vitest/astro.config.ts b/examples/with-vitest/astro.config.ts index 882e6515a..e762ba5cf 100644 --- a/examples/with-vitest/astro.config.ts +++ b/examples/with-vitest/astro.config.ts @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; // https://astro.build/config diff --git a/examples/with-vitest/tsconfig.json b/examples/with-vitest/tsconfig.json index f11a46c8e..8bf91d3bb 100644 --- a/examples/with-vitest/tsconfig.json +++ b/examples/with-vitest/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "astro/tsconfigs/base", + "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"] } diff --git a/packages/astro/components/Welcome.astro b/packages/astro/components/Welcome.astro new file mode 100644 index 000000000..2f91eb5dd --- /dev/null +++ b/packages/astro/components/Welcome.astro @@ -0,0 +1,172 @@ +--- +interface Props { + title?: string; +} + +const cards = [ + { + href: 'https://docs.astro.build/', + title: 'Documentation', + body: 'Learn how Astro works and explore the official API docs.', + }, + { + href: 'https://astro.build/integrations/', + title: 'Integrations', + body: 'Supercharge your project with new frameworks and libraries.', + }, + { + href: 'https://astro.build/themes/', + title: 'Themes', + body: 'Explore a galaxy of community-built starter themes.', + }, + { + href: 'https://astro.build/chat/', + title: 'Community', + body: 'Come say hi to our amazing Discord community. ❤️', + }, +]; + +const { title = 'Welcome to Astro' } = Astro.props; +--- + +<main> + <svg + class="astro-a" + width="495" + height="623" + viewBox="0 0 495 623" + fill="none" + xmlns="http://www.w3.org/2000/svg" + aria-hidden="true" + > + <path + fill-rule="evenodd" + clip-rule="evenodd" + d="M167.19 364.254C83.4786 364.254 0 404.819 0 404.819C0 404.819 141.781 19.4876 142.087 18.7291C146.434 7.33701 153.027 0 162.289 0H332.441C341.703 0 348.574 7.33701 352.643 18.7291C352.92 19.5022 494.716 404.819 494.716 404.819C494.716 404.819 426.67 364.254 327.525 364.254L264.41 169.408C262.047 159.985 255.147 153.581 247.358 153.581C239.569 153.581 232.669 159.985 230.306 169.408L167.19 364.254ZM160.869 530.172C160.877 530.18 160.885 530.187 160.894 530.195L160.867 530.181C160.868 530.178 160.868 530.175 160.869 530.172ZM136.218 411.348C124.476 450.467 132.698 504.458 160.869 530.172C160.997 529.696 161.125 529.242 161.248 528.804C161.502 527.907 161.737 527.073 161.917 526.233C165.446 509.895 178.754 499.52 195.577 500.01C211.969 500.487 220.67 508.765 223.202 527.254C224.141 534.12 224.23 541.131 224.319 548.105C224.328 548.834 224.337 549.563 224.347 550.291C224.563 566.098 228.657 580.707 237.264 593.914C245.413 606.426 256.108 615.943 270.749 622.478C270.593 621.952 270.463 621.508 270.35 621.126C270.045 620.086 269.872 619.499 269.685 618.911C258.909 585.935 266.668 563.266 295.344 543.933C298.254 541.971 301.187 540.041 304.12 538.112C310.591 533.854 317.059 529.599 323.279 525.007C345.88 508.329 360.09 486.327 363.431 457.844C364.805 446.148 363.781 434.657 359.848 423.275C358.176 424.287 356.587 425.295 355.042 426.275C351.744 428.366 348.647 430.33 345.382 431.934C303.466 452.507 259.152 455.053 214.03 448.245C184.802 443.834 156.584 436.019 136.218 411.348Z" + fill="url(#paint0_linear_1805_24383)"></path> + <defs> + <linearGradient + id="paint0_linear_1805_24383" + x1="247.358" + y1="0" + x2="247.358" + y2="622.479" + gradientUnits="userSpaceOnUse" + > + <stop stop-opacity="0.9"></stop> + <stop offset="1" stop-opacity="0.2"></stop> + </linearGradient> + </defs> + </svg> + <h1>{title}</h1> + <p class="instructions"> + To get started, open the directory <code>src/pages</code> in your project.<br /> + <strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above. + </p> + <ul role="list" class="link-card-grid"> + { + cards.map((card) => ( + <li class="link-card"> + <a href={card.href}> + <h2> + {card.title} + <span>→</span> + </h2> + <p>{card.body}</p> + </a> + </li> + )) + } + </ul> +</main> + +<style> + main { + margin: auto; + padding: 1rem; + width: 800px; + max-width: calc(100% - 2rem); + color: white; + font-size: 20px; + line-height: 1.6; + } + .astro-a { + position: absolute; + top: -32px; + left: 50%; + transform: translatex(-50%); + width: 220px; + height: auto; + z-index: -1; + } + h1 { + font-size: 4rem; + font-weight: 700; + line-height: 1; + text-align: center; + margin-bottom: 1em; + } + .instructions { + margin-bottom: 2rem; + border: 1px solid rgba(var(--accent-light), 25%); + background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%)); + padding: 1.5rem; + border-radius: 8px; + } + .instructions code { + font-size: 0.8em; + font-weight: bold; + background: rgba(var(--accent-light), 12%); + color: rgb(var(--accent-light)); + border-radius: 4px; + padding: 0.3em 0.4em; + } + .instructions strong { + color: rgb(var(--accent-light)); + } + .link-card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr)); + gap: 2rem; + padding: 0; + } + + .link-card { + list-style: none; + display: flex; + padding: 1px; + background-color: #23262d; + background-image: none; + background-size: 400%; + border-radius: 7px; + background-position: 100%; + transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); + } + .link-card > a { + width: 100%; + text-decoration: none; + line-height: 1.4; + padding: calc(1.5rem - 1px); + border-radius: 8px; + color: white; + background-color: #23262d; + opacity: 0.8; + } + h2 { + margin: 0; + font-size: 1.25rem; + transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1); + } + p { + margin-top: 0.5rem; + margin-bottom: 0; + } + .link-card:is(:hover, :focus-within) { + background-position: 0; + background-image: var(--accent-gradient); + } + .link-card:is(:hover, :focus-within) h2 { + color: rgb(var(--accent-light)); + } +</style> diff --git a/packages/astro/components/index.ts b/packages/astro/components/index.ts index e5ac0251d..fb553b489 100644 --- a/packages/astro/components/index.ts +++ b/packages/astro/components/index.ts @@ -1,6 +1,8 @@ // The `ts-ignore` comments here are necessary because we're importing this file inside the `astro:components` -// virtual module's types, which means that `tsc` will try to resolve these imports. Don't mind the editor errors. +// virtual module's types, which means that `tsc` will try to resolve these imports. // @ts-ignore -export { default as Code } from './Code.astro'; +export { default as Code } from "./Code.astro"; // @ts-ignore -export { default as Debug } from './Debug.astro'; +export { default as Debug } from "./Debug.astro"; +// @ts-ignore +export { default as Welcome } from "./Welcome.astro"; diff --git a/packages/astro/test/fixtures/legacy-data-collections/astro.config.mjs b/packages/astro/test/fixtures/legacy-data-collections/astro.config.mjs index c342649f7..3f4722ff1 100644 --- a/packages/astro/test/fixtures/legacy-data-collections/astro.config.mjs +++ b/packages/astro/test/fixtures/legacy-data-collections/astro.config.mjs @@ -1,3 +1,4 @@ +// @ts-check import { defineConfig } from 'astro/config'; // https://astro.build/config 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/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..72dc9f353 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,10 @@ 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 +44,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 +73,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..8e27a3cfa --- /dev/null +++ b/packages/create-astro/test/integrations.test.js @@ -0,0 +1,60 @@ +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'); - }); -}); |