From 11a94e1edb6a2409e592591c8140f07cfeb82a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Wed, 21 Jun 2023 18:39:51 +0200 Subject: [PATCH 01/13] Format --- .../src/main/plugins/github-actions.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/create-next-stack/src/main/plugins/github-actions.ts b/packages/create-next-stack/src/main/plugins/github-actions.ts index 32a027e..08a4e67 100644 --- a/packages/create-next-stack/src/main/plugins/github-actions.ts +++ b/packages/create-next-stack/src/main/plugins/github-actions.ts @@ -21,14 +21,8 @@ export const githubActionsPlugin = createPlugin({ description: "GitHub Actions is a tool for automating software development workflows. It is integrated with GitHub repositories and enables developers to automate tasks such as building, testing, and deploying their applications.", links: [ - { - title: "Website", - url: "https://github.com/features/actions", - }, - { - title: "Docs", - url: "https://docs.github.com/en/actions", - }, + { title: "Website", url: "https://github.com/features/actions" }, + { title: "Docs", url: "https://docs.github.com/en/actions" }, { title: "Workflow syntax", url: "https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions", From 7b8c7dc0eedd597123bb99f0bca0da0273ceea28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 22 Jun 2023 11:36:44 +0200 Subject: [PATCH 02/13] Simplify dependency declarations --- CONTRIBUTING.md | 7 +---- packages/create-next-stack/src/main/plugin.ts | 6 ++-- .../src/main/plugins/chakra-ui/chakra-ui.ts | 14 +++------- .../create-next-stack/create-next-stack.ts | 4 +-- .../src/main/plugins/emotion.ts | 8 +++--- .../plugins/formatting-pre-commit-hook.ts | 28 ++++++------------- .../src/main/plugins/formik.ts | 7 +---- .../src/main/plugins/framer-motion.ts | 7 +---- .../src/main/plugins/mantine/mantine.ts | 24 ++++------------ .../main/plugins/material-ui/material-ui.ts | 7 +---- .../src/main/plugins/netlify.ts | 7 +---- .../src/main/plugins/plausible.ts | 7 +---- .../src/main/plugins/prettier.ts | 18 ++++++------ .../src/main/plugins/react-hook-form.ts | 7 +---- .../src/main/plugins/react-icons.ts | 4 +-- .../src/main/plugins/react-query.ts | 14 +++------- .../src/main/plugins/sass/sass.ts | 2 +- .../src/main/plugins/styled-components.ts | 11 ++------ .../src/main/plugins/tailwind-css.ts | 19 ++++--------- .../src/main/plugins/vercel.ts | 7 +---- 20 files changed, 58 insertions(+), 150 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7aef8ec..cfe7dd1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -116,12 +116,7 @@ export const framerMotionPlugin = createPlugin({ name: "Framer Motion", description: "Adds support for Framer Motion", active: ({ flags }) => Boolean(flags["framer-motion"]), - dependencies: { - "framer-motion": { - name: "framer-motion", - version: "^9.0.0", - }, - }, + dependencies: [{ name: "framer-motion", version: "^9.0.0" }], technologies: [ { id: "framerMotion", diff --git a/packages/create-next-stack/src/main/plugin.ts b/packages/create-next-stack/src/main/plugin.ts index 71d2fe7..9399a34 100644 --- a/packages/create-next-stack/src/main/plugin.ts +++ b/packages/create-next-stack/src/main/plugin.ts @@ -12,11 +12,11 @@ type PluginConfig = DeeplyReadonly<{ /** Whether the plugin is active or not. This determines if dependencies are installed, technologies and scripts added, steps run, and more. */ active: boolean | ((inputs: ValidCNSInputs) => boolean) /** Dependencies that are added to the package.json file. */ - dependencies?: Record + dependencies?: Package[] /** Dev dependencies that are added to the package.json file. */ - devDependencies?: Record + devDependencies?: Package[] /** Temporary dependencies uninstalled when Create Next Stack is done. */ - tmpDependencies?: Record + tmpDependencies?: Package[] /** Descriptions of the technologies supported by the plugin. */ technologies?: Technology[] /** Scripts that are added to the package.json file. */ diff --git a/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts b/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts index 72ee726..76422dc 100644 --- a/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts +++ b/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts @@ -8,16 +8,10 @@ export const chakraUIPlugin = createPlugin({ name: "Chakra UI", description: "Adds support for Chakra UI", active: ({ flags }) => Boolean(flags.chakra), - dependencies: { - "@chakra-ui/icons": { - name: "@chakra-ui/icons", - version: "^2.0.0", - }, - "@chakra-ui/react": { - name: "@chakra-ui/react", - version: "^2.0.0", - }, - }, + dependencies: [ + { name: "@chakra-ui/react", version: "^2.0.0" }, + { name: "@chakra-ui/icons", version: "^2.0.0" }, + ], technologies: [ { id: "chakraUI", diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts index 0a523da..d5891cb 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts @@ -15,7 +15,7 @@ import { logWarning } from "../../logging" import { createPlugin } from "../../plugin" import { getNameVersionCombo, install, uninstall } from "../../setup/packages" import { filterPlugins } from "../../setup/setup" -import { prettierPlugin } from "../prettier" +import { prettierPackage } from "../prettier" import { generateEnv } from "./add-content/generate-env" import { generateApp } from "./add-content/pages/generate-app" import { generateDocument } from "./add-content/pages/generate-document" @@ -174,7 +174,7 @@ export const createNextStackPlugin = createPlugin({ description: "formatting project", run: async () => { await runCommand("npx", [ - getNameVersionCombo(prettierPlugin.devDependencies.prettier), + getNameVersionCombo(prettierPackage), "--write", ".", ]) diff --git a/packages/create-next-stack/src/main/plugins/emotion.ts b/packages/create-next-stack/src/main/plugins/emotion.ts index d85834f..478036a 100644 --- a/packages/create-next-stack/src/main/plugins/emotion.ts +++ b/packages/create-next-stack/src/main/plugins/emotion.ts @@ -6,10 +6,10 @@ export const emotionPlugin = createPlugin({ name: "Emotion", description: "Adds support for Emotion", active: ({ flags }) => flags.styling === "emotion", - dependencies: { - "@emotion/react": { name: "@emotion/react", version: "^11.0.0" }, - "@emotion/styled": { name: "@emotion/styled", version: "^11.0.0" }, - }, + dependencies: [ + { name: "@emotion/react", version: "^11.0.0" }, + { name: "@emotion/styled", version: "^11.0.0" }, + ], technologies: [ { id: "emotion", diff --git a/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts b/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts index f102f5a..0d724af 100644 --- a/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts +++ b/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts @@ -12,26 +12,14 @@ export const formattingPreCommitHookPlugin = createPlugin({ "Adds support for a formatting pre-commit hook by setting up Husky and lint-staged using mrm", active: ({ flags }) => Boolean(flags.prettier && flags["formatting-pre-commit-hook"]), - tmpDependencies: { - mrm: { - name: "mrm", - version: "^4.0.0", - }, - "mrm-task-lint-staged": { - name: "mrm-task-lint-staged", - version: "^7.0.0", - }, - }, - devDependencies: { - "lint-staged": { - name: "lint-staged", - version: ">=10", - }, - husky: { - name: "husky", - version: ">=7", - }, - }, + tmpDependencies: [ + { name: "mrm", version: "^4.0.0" }, + { name: "mrm-task-lint-staged", version: "^7.0.0" }, + ], + devDependencies: [ + { name: "lint-staged", version: ">=10" }, + { name: "husky", version: ">=7" }, + ], technologies: [ { id: "husky", diff --git a/packages/create-next-stack/src/main/plugins/formik.ts b/packages/create-next-stack/src/main/plugins/formik.ts index 0f18a35..476c1b3 100644 --- a/packages/create-next-stack/src/main/plugins/formik.ts +++ b/packages/create-next-stack/src/main/plugins/formik.ts @@ -5,12 +5,7 @@ export const formikPlugin = createPlugin({ name: "Formik", description: "Adds support for Formik", active: ({ flags }) => Boolean(flags["formik"]), - dependencies: { - formik: { - name: "formik", - version: "^2.0.0", - }, - }, + dependencies: [{ name: "formik", version: "^2.0.0" }], technologies: [ { id: "formik", diff --git a/packages/create-next-stack/src/main/plugins/framer-motion.ts b/packages/create-next-stack/src/main/plugins/framer-motion.ts index 49f207e..d3e2a54 100644 --- a/packages/create-next-stack/src/main/plugins/framer-motion.ts +++ b/packages/create-next-stack/src/main/plugins/framer-motion.ts @@ -5,12 +5,7 @@ export const framerMotionPlugin = createPlugin({ name: "Framer Motion", description: "Adds support for Framer Motion", active: ({ flags }) => Boolean(flags["framer-motion"]), - dependencies: { - "framer-motion": { - name: "framer-motion", - version: "^9.0.0", - }, - }, + dependencies: [{ name: "framer-motion", version: "^9.0.0" }], technologies: [ { id: "framerMotion", diff --git a/packages/create-next-stack/src/main/plugins/mantine/mantine.ts b/packages/create-next-stack/src/main/plugins/mantine/mantine.ts index 49659e8..fc121d5 100644 --- a/packages/create-next-stack/src/main/plugins/mantine/mantine.ts +++ b/packages/create-next-stack/src/main/plugins/mantine/mantine.ts @@ -8,24 +8,12 @@ export const mantinePlugin = createPlugin({ name: "Mantine", description: "Adds support for Mantine", active: ({ flags }) => Boolean(flags.mantine), - dependencies: { - "@mantine/core": { - name: "@mantine/core", - version: "^6.0.0", - }, - "@mantine/hooks": { - name: "@mantine/hooks", - version: "^6.0.0", - }, - "@mantine/next": { - name: "@mantine/next", - version: "^6.0.0", - }, - "@emotion/server": { - name: "@emotion/server", - version: "^11.0.0", - }, - }, + dependencies: [ + { name: "@mantine/core", version: "^6.0.0" }, + { name: "@mantine/hooks", version: "^6.0.0" }, + { name: "@mantine/next", version: "^6.0.0" }, + { name: "@emotion/server", version: "^11.0.0" }, + ], technologies: [ { id: "mantine", diff --git a/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts b/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts index 1d93183..de2192a 100644 --- a/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts +++ b/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts @@ -8,12 +8,7 @@ export const materialUIPlugin = createPlugin({ name: "Material UI", description: "Adds support for Material UI", active: ({ flags }) => Boolean(flags["material-ui"]), - dependencies: { - "@mui/material": { - name: "@mui/material", - version: "^5.0.0", - }, - }, + dependencies: [{ name: "@mui/material", version: "^5.0.0" }], technologies: [ { id: "materialUI", diff --git a/packages/create-next-stack/src/main/plugins/netlify.ts b/packages/create-next-stack/src/main/plugins/netlify.ts index 50d8e9d..6464e85 100644 --- a/packages/create-next-stack/src/main/plugins/netlify.ts +++ b/packages/create-next-stack/src/main/plugins/netlify.ts @@ -5,12 +5,7 @@ export const netlifyPlugin = createPlugin({ name: "Netlify", description: "Adds support for Netlify", active: ({ flags }) => Boolean(flags["netlify"]), - devDependencies: { - "netlify-cli": { - name: "netlify-cli", - version: "^15.6.0", - }, - }, + devDependencies: [{ name: "netlify-cli", version: "^15.6.0" }], scripts: [ { name: "deploy:netlify", diff --git a/packages/create-next-stack/src/main/plugins/plausible.ts b/packages/create-next-stack/src/main/plugins/plausible.ts index 0244dfd..99435ab 100644 --- a/packages/create-next-stack/src/main/plugins/plausible.ts +++ b/packages/create-next-stack/src/main/plugins/plausible.ts @@ -8,12 +8,7 @@ export const plausiblePlugin = createPlugin({ name: "Plausible", description: "Adds support for Plausible Analytics", active: ({ flags }) => flags["plausible"], - dependencies: { - "next-plausible": { - name: "next-plausible", - version: "^3.0.0", - }, - }, + dependencies: [{ name: "next-plausible", version: "^3.0.0" }], technologies: [ { id: "plausible", diff --git a/packages/create-next-stack/src/main/plugins/prettier.ts b/packages/create-next-stack/src/main/plugins/prettier.ts index b134a35..0431c58 100644 --- a/packages/create-next-stack/src/main/plugins/prettier.ts +++ b/packages/create-next-stack/src/main/plugins/prettier.ts @@ -1,18 +1,20 @@ import { modifyJsonFile, toArray, writeJsonFile } from "../helpers/io" -import { createPlugin } from "../plugin" +import { createPlugin, Package } from "../plugin" + +export const prettierPackage = { + name: "prettier", + version: "^2.0.0", +} satisfies Package export const prettierPlugin = createPlugin({ id: "prettier", name: "Prettier", description: "Adds support for Prettier", active: ({ flags }) => Boolean(flags.prettier), - devDependencies: { - prettier: { name: "prettier", version: "^2.0.0" }, - "eslint-config-prettier": { - name: "eslint-config-prettier", - version: "^8.0.0", - }, - }, + devDependencies: [ + prettierPackage, + { name: "eslint-config-prettier", version: "^8.0.0" }, + ], technologies: [ { id: "prettier", diff --git a/packages/create-next-stack/src/main/plugins/react-hook-form.ts b/packages/create-next-stack/src/main/plugins/react-hook-form.ts index 63405cd..1f02ce8 100644 --- a/packages/create-next-stack/src/main/plugins/react-hook-form.ts +++ b/packages/create-next-stack/src/main/plugins/react-hook-form.ts @@ -5,12 +5,7 @@ export const reactHookFormPlugin = createPlugin({ name: "React Hook Form", description: "Adds support for React Hook Form", active: ({ flags }) => Boolean(flags["react-hook-form"]), - dependencies: { - "react-hook-form": { - name: "react-hook-form", - version: "^7.0.0", - }, - }, + dependencies: [{ name: "react-hook-form", version: "^7.0.0" }], technologies: [ { id: "reactHookForm", diff --git a/packages/create-next-stack/src/main/plugins/react-icons.ts b/packages/create-next-stack/src/main/plugins/react-icons.ts index a0b4dfd..5865884 100644 --- a/packages/create-next-stack/src/main/plugins/react-icons.ts +++ b/packages/create-next-stack/src/main/plugins/react-icons.ts @@ -5,9 +5,7 @@ export const reactIconsPlugin = createPlugin({ name: "React Icons", description: "Adds support for React Icons", active: ({ flags }) => Boolean(flags["react-icons"]), - devDependencies: { - "react-icons": { name: "react-icons", version: "^4.8.0" }, - }, + devDependencies: [{ name: "react-icons", version: "^4.8.0" }], technologies: [ { id: "reactIcons", diff --git a/packages/create-next-stack/src/main/plugins/react-query.ts b/packages/create-next-stack/src/main/plugins/react-query.ts index fcb9c33..60f6d36 100644 --- a/packages/create-next-stack/src/main/plugins/react-query.ts +++ b/packages/create-next-stack/src/main/plugins/react-query.ts @@ -6,16 +6,10 @@ export const reactQueryPlugin = createPlugin({ name: "React Query", description: "Adds support for React Query", active: ({ flags }) => Boolean(flags["react-query"]), - devDependencies: { - "@tanstack/react-query": { - name: "@tanstack/react-query", - version: "^4.0.0", - }, - "@tanstack/react-query-devtools": { - name: "@tanstack/react-query-devtools", - version: "^4.0.0", - }, - }, + devDependencies: [ + { name: "@tanstack/react-query", version: "^4.0.0" }, + { name: "@tanstack/react-query-devtools", version: "^4.0.0" }, + ], technologies: [ { id: "reactQuery", diff --git a/packages/create-next-stack/src/main/plugins/sass/sass.ts b/packages/create-next-stack/src/main/plugins/sass/sass.ts index e3c3a14..2e23356 100644 --- a/packages/create-next-stack/src/main/plugins/sass/sass.ts +++ b/packages/create-next-stack/src/main/plugins/sass/sass.ts @@ -8,7 +8,7 @@ export const sassPlugin = createPlugin({ name: "Sass", description: "Adds support for Sass", active: ({ flags }) => flags.styling === "css-modules-with-sass", - dependencies: { sass: { name: "sass", version: "^1.0.0" } }, + dependencies: [{ name: "sass", version: "^1.0.0" }], technologies: [ cssModulesPlugin.technologies[0], { diff --git a/packages/create-next-stack/src/main/plugins/styled-components.ts b/packages/create-next-stack/src/main/plugins/styled-components.ts index c58f142..da4a8ff 100644 --- a/packages/create-next-stack/src/main/plugins/styled-components.ts +++ b/packages/create-next-stack/src/main/plugins/styled-components.ts @@ -5,15 +5,8 @@ export const styledComponentsPlugin = createPlugin({ name: "Styled Components", description: "Adds support for Styled Components", active: ({ flags }) => Boolean(flags.styling === "styled-components"), - dependencies: { - "styled-components": { name: "styled-components", version: "^5.0.0" }, - }, - devDependencies: { - "@types/styled-components": { - name: "@types/styled-components", - version: "^5.0.0", - }, - }, + dependencies: [{ name: "styled-components", version: "^5.0.0" }], + devDependencies: [{ name: "@types/styled-components", version: "^5.0.0" }], technologies: [ { id: "styledComponents", diff --git a/packages/create-next-stack/src/main/plugins/tailwind-css.ts b/packages/create-next-stack/src/main/plugins/tailwind-css.ts index ef4b4e8..f79e97d 100644 --- a/packages/create-next-stack/src/main/plugins/tailwind-css.ts +++ b/packages/create-next-stack/src/main/plugins/tailwind-css.ts @@ -14,20 +14,11 @@ export const tailwindCSSPlugin = createPlugin({ name: "Tailwind CSS", description: "Adds support for Tailwind CSS", active: ({ flags }) => flags["styling"] === "tailwind-css", - devDependencies: { - tailwindcss: { - name: "tailwindcss", - version: "^3.0.0", - }, - autoprefixer: { - name: "autoprefixer", - version: "^10.0.0", - }, - postcss: { - name: "postcss", - version: "^8.0.0", - }, - }, + devDependencies: [ + { name: "tailwindcss", version: "^3.0.0" }, + { name: "autoprefixer", version: "^10.0.0" }, + { name: "postcss", version: "^8.0.0" }, + ], technologies: [ { id: "tailwindCSS", diff --git a/packages/create-next-stack/src/main/plugins/vercel.ts b/packages/create-next-stack/src/main/plugins/vercel.ts index 0d72505..01bc946 100644 --- a/packages/create-next-stack/src/main/plugins/vercel.ts +++ b/packages/create-next-stack/src/main/plugins/vercel.ts @@ -5,12 +5,7 @@ export const vercelPlugin = createPlugin({ name: "Vercel", description: "Adds support for Vercel", active: ({ flags }) => Boolean(flags["vercel"]), - devDependencies: { - vercel: { - name: "vercel", - version: "^30.2.2", - }, - }, + devDependencies: [{ name: "vercel", version: "^30.2.2" }], scripts: [ { name: "deploy:vercel", From afa853a80437a6e09161b43d1b6c0924c2051bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 22 Jun 2023 12:38:02 +0200 Subject: [PATCH 03/13] Update test error messages --- packages/create-next-stack/README.md | 1 + .../sort-orders/environment-variables.test.ts | 7 ++++++- .../plugins/create-next-stack/sort-orders/scripts.test.ts | 7 ++++++- .../create-next-stack/sort-orders/technologies.test.ts | 7 ++++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/create-next-stack/README.md b/packages/create-next-stack/README.md index ff5a718..cec12d1 100644 --- a/packages/create-next-stack/README.md +++ b/packages/create-next-stack/README.md @@ -64,6 +64,7 @@ The table below provides an overview of the technologies currently supported by | next-plausible | [Website](https://next-plausible.vercel.app/) - [GitHub](https://github.com/4lejandrito/next-plausible) | | Vercel | [Website](https://vercel.com/) - [Docs](https://vercel.com/docs) - [CLI Docs](https://vercel.com/docs/cli) | | Netlify | [Website](https://www.netlify.com/) - [Docs](https://docs.netlify.com/) - [CLI Docs](https://cli.netlify.com/) | +| Prisma | [Website](https://www.prisma.io/) - [Docs](https://www.prisma.io/docs) - [GitHub](https://github.com/prisma/prisma) | diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.test.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.test.ts index 649ef8c..ffc9908 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.test.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.test.ts @@ -1,4 +1,5 @@ import { test } from "@jest/globals" +import endent from "endent" import { plugins } from "../../../setup/setup" import { environmentVariablesSortOrder } from "./environment-variables" @@ -26,7 +27,11 @@ test("`environmentVariablesSortOrder` includes all plugins' environment variable for (const requiredEnvironmentVariable of requiredEnvironmentVariables) { if (!actualEnvironmentVariables.has(requiredEnvironmentVariable)) { throw new Error( - `Missing environment variable with name "${requiredEnvironmentVariable}" in environment-variables.ts` + endent` + Missing environment variable with name "${requiredEnvironmentVariable}" in environment-variables.ts + environment-variables.ts can be found here: + src/main/plugins/create-next-stack/sort-orders/environment-variables.ts + ` ) } } diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.test.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.test.ts index e509943..ce69688 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.test.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.test.ts @@ -1,4 +1,5 @@ import { test } from "@jest/globals" +import endent from "endent" import { plugins } from "../../../setup/setup" import { scriptsSortOrder } from "./scripts" @@ -24,7 +25,11 @@ test("`scriptsSortOrder` includes all plugins' scripts", () => { for (const requiredScript of requiredScripts) { if (!actualScripts.has(requiredScript)) { throw new Error( - `Missing script with name "${requiredScript}" in scripts.ts` + endent` + Missing script with name "${requiredScript}" in scripts.ts + scripts.ts can be found here: + src/main/plugins/create-next-stack/sort-orders/scripts.ts + ` ) } } diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.test.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.test.ts index 3730f38..be6d8b0 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.test.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.test.ts @@ -1,4 +1,5 @@ import { test } from "@jest/globals" +import endent from "endent" import { plugins } from "../../../setup/setup" import { technologiesSortOrder } from "./technologies" @@ -24,7 +25,11 @@ test("`technologiesSortOrder` includes all plugins' technologies", () => { for (const requiredTechnologyID of requiredTechnologyIDs) { if (!actualTechnologyIDs.has(requiredTechnologyID)) { throw new Error( - `Missing technology with ID "${requiredTechnologyID}" in technologies.ts` + endent` + Missing technology with ID "${requiredTechnologyID}" in technologies.ts + technologies.ts can be found here: + src/main/plugins/create-next-stack/sort-orders/technologies.ts + ` ) } } From 3ca7325cb1672f8cf4416e99784a0db24ec87494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 22 Jun 2023 12:41:07 +0200 Subject: [PATCH 04/13] Don't make unnecessary directories. Centrally remove next.js content --- .../main/plugins/create-next-stack/create-next-stack.ts | 5 +---- packages/create-next-stack/src/main/plugins/next.ts | 7 +++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts index d5891cb..bfd2b16 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts @@ -70,7 +70,6 @@ export const createNextStackPlugin = createPlugin({ id: "addContent", description: "adding content", run: async (inputs) => { - await makeDirectory("components") const environmentVariables = getSortedFilteredEnvironmentVariables(inputs) if (environmentVariables.length > 0) { @@ -96,10 +95,8 @@ export const createNextStackPlugin = createPlugin({ id: "addReadme", description: "adding Readme", run: async (inputs) => { - const readmeFileName = "README.md" - await remove(readmeFileName) const readmeString = await generateReadme(inputs) - await writeFile(readmeFileName, readmeString) + await writeFile("README.md", readmeString) }, }, initialCommit: { diff --git a/packages/create-next-stack/src/main/plugins/next.ts b/packages/create-next-stack/src/main/plugins/next.ts index bd42251..865bf68 100644 --- a/packages/create-next-stack/src/main/plugins/next.ts +++ b/packages/create-next-stack/src/main/plugins/next.ts @@ -139,18 +139,17 @@ export const nextPlugin = createPlugin({ remove("public/next.svg"), remove("public/thirteen.svg"), remove("public/vercel.svg"), + remove("README.md"), + remove("next.config.js"), ]) - await makeDirectory("pages") }, }, addNextConfig: { id: "addNextConfig", description: "adding next.config.js", run: async (inputs) => { - const nextConfigFileName = "next.config.js" - await remove(nextConfigFileName) const nextConfigString = await generateNextConfig(inputs) - await writeFile(nextConfigFileName, nextConfigString) + await writeFile("next.config.js", nextConfigString) }, }, }, From d8556ff7df574c5c283caed99e661efc3252223c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 22 Jun 2023 13:36:03 +0200 Subject: [PATCH 05/13] Add "addFiles" property to Plugin. Also refactor writeFile() and clean up --- packages/create-next-stack/README.md | 1 + .../create-next-stack/src/main/helpers/io.ts | 6 ++- packages/create-next-stack/src/main/plugin.ts | 7 +++ .../create-next-stack/create-next-stack.ts | 49 +++++++++++++------ .../main/plugins/css-modules/css-modules.ts | 3 +- .../src/main/plugins/github-actions.ts | 10 ++-- .../src/main/plugins/sass/sass.ts | 3 +- .../src/main/plugins/tailwind-css.ts | 3 +- 8 files changed, 54 insertions(+), 28 deletions(-) diff --git a/packages/create-next-stack/README.md b/packages/create-next-stack/README.md index cec12d1..148c80d 100644 --- a/packages/create-next-stack/README.md +++ b/packages/create-next-stack/README.md @@ -105,6 +105,7 @@ FLAGS --plausible Adds Plausible. (Analytics) --prettier Adds Prettier. (Code formatting) + --prisma Adds Prisma. (ORM) --react-hook-form Adds React Hook Form. (Form library) --react-icons Adds React Icons. (Icon library) --react-query Adds React Query. (Server state management diff --git a/packages/create-next-stack/src/main/helpers/io.ts b/packages/create-next-stack/src/main/helpers/io.ts index 3ae70fc..4df65e8 100644 --- a/packages/create-next-stack/src/main/helpers/io.ts +++ b/packages/create-next-stack/src/main/helpers/io.ts @@ -1,5 +1,6 @@ import { existsSync } from "fs" import fs from "fs/promises" +import path from "path" import { logDebug, logError } from "../logging" import { isUnknownArray } from "./is-unknown-array" import { isUnknownObject } from "./is-unknown-object" @@ -13,7 +14,10 @@ export const makeDirectory = async (path: string): Promise => { } export const writeFile: typeof fs.writeFile = async (file, data, options) => { - logDebug("Writing file:", file.toString()) + const fileString = file.toString() + const directory = path.dirname(fileString) + await makeDirectory(directory) + logDebug("Writing file:", fileString) return fs.writeFile(file, data, options) } diff --git a/packages/create-next-stack/src/main/plugin.ts b/packages/create-next-stack/src/main/plugin.ts index 9399a34..513e639 100644 --- a/packages/create-next-stack/src/main/plugin.ts +++ b/packages/create-next-stack/src/main/plugin.ts @@ -40,6 +40,13 @@ type PluginConfig = DeeplyReadonly<{ * The list will be added to the generated landing page, the README.md file and written to the console. */ todos?: string[] + /** Files to be added by the plugin. */ + addFiles?: Array<{ + /** Destination of the file to add. */ + destination: string + /** Content of the file. */ + content: string + }> /** Slots to fill in the generated files. */ slots?: { /** Slots to fill in the _app.tsx file. The file is generated using the following template: diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts index bfd2b16..fefff19 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts @@ -9,7 +9,7 @@ import { writeFile, } from "../../helpers/io" import { isGitInitialized } from "../../helpers/is-git-initialized" -import { remove } from "../../helpers/remove" +import { nonNull } from "../../helpers/non-null" import { runCommand } from "../../helpers/run-command" import { logWarning } from "../../logging" import { createPlugin } from "../../plugin" @@ -75,20 +75,41 @@ export const createNextStackPlugin = createPlugin({ if (environmentVariables.length > 0) { await writeFile(".env", generateEnv(inputs)) } - await Promise.all([ - writeFile("pages/index.tsx", generateIndexPage(inputs)), - writeFile("pages/_app.tsx", generateApp(inputs)), - writeFile("pages/_document.tsx", generateDocument(inputs)), - writeFile( - "templates/LandingPage/technologies.ts", - generateTechnologies(inputs) - ), - writeFile( - "templates/LandingPage/LandingPageTemplate.tsx", - generateLandingPageTemplate(inputs) - ), - ]) + const filesToWrite = [ + { + destination: "pages/index.tsx", + content: generateIndexPage(inputs), + }, + { + destination: "pages/_app.tsx", + content: generateApp(inputs), + }, + { + destination: "pages/_document.tsx", + content: generateDocument(inputs), + }, + { + destination: "templates/LandingPage/technologies.ts", + content: generateTechnologies(inputs), + }, + { + destination: "templates/LandingPage/LandingPageTemplate.tsx", + content: generateLandingPageTemplate(inputs), + }, + ] + + const pluginFilesToWrite = filterPlugins(inputs) + .flatMap((plugin) => plugin.addFiles) + .filter(nonNull) + + filesToWrite.push(...pluginFilesToWrite) + + await Promise.all( + filesToWrite.map(({ destination, content }) => + writeFile(destination, content) + ) + ) }, }, addReadme: { diff --git a/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts b/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts index f76c066..0c1eb09 100644 --- a/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts +++ b/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts @@ -1,4 +1,4 @@ -import { makeDirectory, writeFile } from "../../helpers/io" +import { writeFile } from "../../helpers/io" import { createPlugin } from "../../plugin" import { generateGlobalStyles } from "./add-content/styles/global-styles" @@ -28,7 +28,6 @@ export const cssModulesPlugin = createPlugin({ id: "setUpCssModules", description: "setting up CSS Modules", run: async () => { - await makeDirectory("styles") await writeFile("styles/global-styles.css", generateGlobalStyles()) }, }, diff --git a/packages/create-next-stack/src/main/plugins/github-actions.ts b/packages/create-next-stack/src/main/plugins/github-actions.ts index 08a4e67..8abbf48 100644 --- a/packages/create-next-stack/src/main/plugins/github-actions.ts +++ b/packages/create-next-stack/src/main/plugins/github-actions.ts @@ -1,7 +1,6 @@ import endent from "endent" -import path from "path" import { ValidCNSInputs } from "../create-next-stack-types" -import { makeDirectory, writeFile } from "../helpers/io" +import { writeFile } from "../helpers/io" import { cleanInstallCommandMap, runCommandMap, @@ -43,11 +42,8 @@ export const githubActionsPlugin = createPlugin({ id: "addGithubWorkflowStep", description: "adding GitHub workflow", run: async (inputs) => { - const directory = ".github/workflows" - const filename = "ci.yml" - await makeDirectory(directory) - const filePath = path.resolve(`${directory}/${filename}`) - await writeFile(filePath, generateCiYml(inputs)) + const filename = ".github/workflows/ci.yml" + await writeFile(filename, generateCiYml(inputs)) }, }, }, diff --git a/packages/create-next-stack/src/main/plugins/sass/sass.ts b/packages/create-next-stack/src/main/plugins/sass/sass.ts index 2e23356..3060bfd 100644 --- a/packages/create-next-stack/src/main/plugins/sass/sass.ts +++ b/packages/create-next-stack/src/main/plugins/sass/sass.ts @@ -1,4 +1,4 @@ -import { makeDirectory, writeFile } from "../../helpers/io" +import { writeFile } from "../../helpers/io" import { createPlugin } from "../../plugin" import { cssModulesPlugin } from "../css-modules/css-modules" import { generateGlobalStyles } from "./add-content/styles/global-styles" @@ -31,7 +31,6 @@ export const sassPlugin = createPlugin({ id: "setUpSass", description: "setting up Sass", run: async () => { - await makeDirectory("styles") await writeFile("styles/global-styles.scss", generateGlobalStyles()) }, }, diff --git a/packages/create-next-stack/src/main/plugins/tailwind-css.ts b/packages/create-next-stack/src/main/plugins/tailwind-css.ts index f79e97d..3c634dd 100644 --- a/packages/create-next-stack/src/main/plugins/tailwind-css.ts +++ b/packages/create-next-stack/src/main/plugins/tailwind-css.ts @@ -1,5 +1,5 @@ import endent from "endent" -import { makeDirectory, writeFile } from "../helpers/io" +import { writeFile } from "../helpers/io" import { createPlugin } from "../plugin" /** @@ -92,6 +92,5 @@ const addStylesGlobalsCss = async () => { @tailwind components; @tailwind utilities; ` - await makeDirectory("styles") await writeFile("styles/globals.css", stylesGlobalsCssString) } From 4e12adcf1e413340b7e9dfd700c5078eb3fe293a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 22 Jun 2023 14:36:01 +0200 Subject: [PATCH 06/13] Refactor plugins to use addFiles plugin property --- .../src/main/plugins/chakra-ui/chakra-ui.ts | 26 ++--- .../plugins/chakra-ui/setup/chakra-theme.ts | 12 --- .../add-next-config/generate-next-config.ts | 4 +- .../create-next-stack/create-next-stack.ts | 7 +- .../add-content/styles/global-styles.ts | 27 ----- .../main/plugins/css-modules/css-modules.ts | 44 ++++++--- .../src/main/plugins/mantine/mantine.ts | 23 ++--- .../plugins/mantine/setup/mantine-theme.ts | 9 -- .../main/plugins/material-ui/material-ui.ts | 48 ++++++--- .../material-ui/setup/material-theme.ts | 32 ------ .../sass/add-content/styles/global-styles.ts | 27 ----- .../src/main/plugins/sass/sass.ts | 44 ++++++--- .../src/main/plugins/tailwind-css.ts | 99 ++++++++----------- packages/create-next-stack/src/main/steps.ts | 14 --- 14 files changed, 174 insertions(+), 242 deletions(-) delete mode 100644 packages/create-next-stack/src/main/plugins/chakra-ui/setup/chakra-theme.ts delete mode 100644 packages/create-next-stack/src/main/plugins/css-modules/add-content/styles/global-styles.ts delete mode 100644 packages/create-next-stack/src/main/plugins/mantine/setup/mantine-theme.ts delete mode 100644 packages/create-next-stack/src/main/plugins/material-ui/setup/material-theme.ts delete mode 100644 packages/create-next-stack/src/main/plugins/sass/add-content/styles/global-styles.ts diff --git a/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts b/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts index 76422dc..561643f 100644 --- a/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts +++ b/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts @@ -1,7 +1,5 @@ import endent from "endent" -import { writeFile } from "../../helpers/io" import { createPlugin } from "../../plugin" -import { chakraTheme } from "./setup/chakra-theme" export const chakraUIPlugin = createPlugin({ id: "chakra-ui", @@ -25,15 +23,6 @@ export const chakraUIPlugin = createPlugin({ ], }, ], - steps: { - setUpChakraUI: { - id: "setUpChakraUI", - description: "setting up Chakra UI", - run: async () => { - await writeFile("chakra-theme.ts", chakraTheme) - }, - }, - }, slots: { app: { imports: endent` @@ -55,4 +44,19 @@ export const chakraUIPlugin = createPlugin({ body: ``, }, }, + addFiles: [ + { + destination: "chakra-theme.ts", + content: endent` + import { extendTheme, ThemeConfig } from "@chakra-ui/react"; + + const config: ThemeConfig = { + initialColorMode: "light", + useSystemColorMode: false, + }; + + export const chakraTheme = extendTheme({ config }); + `, + }, + ], } as const) diff --git a/packages/create-next-stack/src/main/plugins/chakra-ui/setup/chakra-theme.ts b/packages/create-next-stack/src/main/plugins/chakra-ui/setup/chakra-theme.ts deleted file mode 100644 index 5075400..0000000 --- a/packages/create-next-stack/src/main/plugins/chakra-ui/setup/chakra-theme.ts +++ /dev/null @@ -1,12 +0,0 @@ -import endent from "endent" - -export const chakraTheme = endent` - import { extendTheme, ThemeConfig } from "@chakra-ui/react"; - - const config: ThemeConfig = { - initialColorMode: "light", - useSystemColorMode: false, - }; - - export const chakraTheme = extendTheme({ config }); -` diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-next-config/generate-next-config.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-next-config/generate-next-config.ts index 3ae4b75..c334198 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-next-config/generate-next-config.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-next-config/generate-next-config.ts @@ -6,9 +6,7 @@ import { nonNull } from "../../../helpers/non-null" import { stringify } from "../../../helpers/stringify" import { filterPlugins } from "../../../setup/setup" -export const generateNextConfig = async ( - inputs: ValidCNSInputs -): Promise => { +export const generateNextConfig = (inputs: ValidCNSInputs): string => { const defaultNextConfig: NextConfig = { reactStrictMode: true, } diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts index fefff19..287b1a8 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts @@ -2,12 +2,7 @@ import endent from "endent" import path from "path" import { copyDirectory } from "../../helpers/copy-directory" import { getCreateNextStackDir } from "../../helpers/get-create-next-stack-dir" -import { - makeDirectory, - modifyJsonFile, - toObject, - writeFile, -} from "../../helpers/io" +import { modifyJsonFile, toObject, writeFile } from "../../helpers/io" import { isGitInitialized } from "../../helpers/is-git-initialized" import { nonNull } from "../../helpers/non-null" import { runCommand } from "../../helpers/run-command" diff --git a/packages/create-next-stack/src/main/plugins/css-modules/add-content/styles/global-styles.ts b/packages/create-next-stack/src/main/plugins/css-modules/add-content/styles/global-styles.ts deleted file mode 100644 index 4a2d368..0000000 --- a/packages/create-next-stack/src/main/plugins/css-modules/add-content/styles/global-styles.ts +++ /dev/null @@ -1,27 +0,0 @@ -import endent from "endent" - -export const generateGlobalStyles = (): string => endent` - * { - box-sizing: border-box; - } - - html, - body { - padding: 0; - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, - Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; - line-height: 1.5; - } - - code { - font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, - Bitstream Vera Sans Mono, Courier New, monospace; - } - - a { - color: inherit; - text-decoration: none; - font-weight: bold; - } -` diff --git a/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts b/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts index 0c1eb09..8ff284d 100644 --- a/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts +++ b/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts @@ -1,6 +1,31 @@ -import { writeFile } from "../../helpers/io" +import endent from "endent" import { createPlugin } from "../../plugin" -import { generateGlobalStyles } from "./add-content/styles/global-styles" + +const globalStyles = endent` + * { + box-sizing: border-box; + } + + html, + body { + padding: 0; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + line-height: 1.5; + } + + code { + font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, + Bitstream Vera Sans Mono, Courier New, monospace; + } + + a { + color: inherit; + text-decoration: none; + font-weight: bold; + } +` export const cssModulesPlugin = createPlugin({ id: "css-modules", @@ -23,18 +48,15 @@ export const cssModulesPlugin = createPlugin({ ], }, ], - steps: { - setUpCssModules: { - id: "setUpCssModules", - description: "setting up CSS Modules", - run: async () => { - await writeFile("styles/global-styles.css", generateGlobalStyles()) - }, - }, - }, slots: { app: { imports: `import "../styles/global-styles.css";`, }, }, + addFiles: [ + { + destination: "styles/global-styles.css", + content: globalStyles, + }, + ], } as const) diff --git a/packages/create-next-stack/src/main/plugins/mantine/mantine.ts b/packages/create-next-stack/src/main/plugins/mantine/mantine.ts index fc121d5..d93ceef 100644 --- a/packages/create-next-stack/src/main/plugins/mantine/mantine.ts +++ b/packages/create-next-stack/src/main/plugins/mantine/mantine.ts @@ -1,7 +1,5 @@ import endent from "endent" -import { writeFile } from "../../helpers/io" import { createPlugin } from "../../plugin" -import { mantineTheme } from "./setup/mantine-theme" export const mantinePlugin = createPlugin({ id: "mantine", @@ -27,15 +25,6 @@ export const mantinePlugin = createPlugin({ ], }, ], - steps: { - setUpMantine: { - id: "setUpMantine", - description: "setting up Mantine", - run: async () => { - await writeFile("mantine-theme.ts", mantineTheme) - }, - }, - }, slots: { app: { imports: endent` @@ -65,4 +54,16 @@ export const mantinePlugin = createPlugin({ `, }, }, + addFiles: [ + { + destination: "mantine-theme.ts", + content: endent` + import { MantineThemeOverride } from "@mantine/core"; + + export const mantineTheme: MantineThemeOverride = { + colorScheme: "light", + }; + `, + }, + ], } as const) diff --git a/packages/create-next-stack/src/main/plugins/mantine/setup/mantine-theme.ts b/packages/create-next-stack/src/main/plugins/mantine/setup/mantine-theme.ts deleted file mode 100644 index 71aac98..0000000 --- a/packages/create-next-stack/src/main/plugins/mantine/setup/mantine-theme.ts +++ /dev/null @@ -1,9 +0,0 @@ -import endent from "endent" - -export const mantineTheme = endent` - import { MantineThemeOverride } from "@mantine/core"; - - export const mantineTheme: MantineThemeOverride = { - colorScheme: "light", - }; -` diff --git a/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts b/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts index de2192a..a1156cf 100644 --- a/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts +++ b/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts @@ -1,7 +1,36 @@ import endent from "endent" -import { writeFile } from "../../helpers/io" import { createPlugin } from "../../plugin" -import { materialTheme } from "./setup/material-theme" + +const materialTheme = endent` + import { Roboto } from 'next/font/google'; + import { createTheme } from '@mui/material/styles'; + import { red } from '@mui/material/colors'; + + export const roboto = Roboto({ + weight: ['300', '400', '500', '700'], + subsets: ['latin'], + display: 'swap', + fallback: ['Helvetica', 'Arial', 'sans-serif'], + }); + + // Create a theme instance. + export default createTheme({ + palette: { + primary: { + main: '#556cd6', + }, + secondary: { + main: '#19857b', + }, + error: { + main: red.A400, + }, + }, + typography: { + fontFamily: roboto.style.fontFamily, + }, + }); +` export const materialUIPlugin = createPlugin({ id: "material-ui", @@ -25,15 +54,6 @@ export const materialUIPlugin = createPlugin({ ], }, ], - steps: { - setUpMaterialUI: { - id: "setUpMaterialUI", - description: "setting up Material UI", - run: async () => { - await writeFile("material-theme.ts", materialTheme) - }, - }, - }, slots: { app: { imports: endent` @@ -53,4 +73,10 @@ export const materialUIPlugin = createPlugin({ headTags: ``, }, }, + addFiles: [ + { + destination: "material-theme.ts", + content: materialTheme, + }, + ], } as const) diff --git a/packages/create-next-stack/src/main/plugins/material-ui/setup/material-theme.ts b/packages/create-next-stack/src/main/plugins/material-ui/setup/material-theme.ts deleted file mode 100644 index ad3109c..0000000 --- a/packages/create-next-stack/src/main/plugins/material-ui/setup/material-theme.ts +++ /dev/null @@ -1,32 +0,0 @@ -import endent from "endent" - -export const materialTheme = endent` - import { Roboto } from 'next/font/google'; - import { createTheme } from '@mui/material/styles'; - import { red } from '@mui/material/colors'; - - export const roboto = Roboto({ - weight: ['300', '400', '500', '700'], - subsets: ['latin'], - display: 'swap', - fallback: ['Helvetica', 'Arial', 'sans-serif'], - }); - - // Create a theme instance. - export default createTheme({ - palette: { - primary: { - main: '#556cd6', - }, - secondary: { - main: '#19857b', - }, - error: { - main: red.A400, - }, - }, - typography: { - fontFamily: roboto.style.fontFamily, - }, - }); -` diff --git a/packages/create-next-stack/src/main/plugins/sass/add-content/styles/global-styles.ts b/packages/create-next-stack/src/main/plugins/sass/add-content/styles/global-styles.ts deleted file mode 100644 index 4a2d368..0000000 --- a/packages/create-next-stack/src/main/plugins/sass/add-content/styles/global-styles.ts +++ /dev/null @@ -1,27 +0,0 @@ -import endent from "endent" - -export const generateGlobalStyles = (): string => endent` - * { - box-sizing: border-box; - } - - html, - body { - padding: 0; - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, - Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; - line-height: 1.5; - } - - code { - font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, - Bitstream Vera Sans Mono, Courier New, monospace; - } - - a { - color: inherit; - text-decoration: none; - font-weight: bold; - } -` diff --git a/packages/create-next-stack/src/main/plugins/sass/sass.ts b/packages/create-next-stack/src/main/plugins/sass/sass.ts index 3060bfd..dca61e6 100644 --- a/packages/create-next-stack/src/main/plugins/sass/sass.ts +++ b/packages/create-next-stack/src/main/plugins/sass/sass.ts @@ -1,7 +1,32 @@ -import { writeFile } from "../../helpers/io" +import endent from "endent" import { createPlugin } from "../../plugin" import { cssModulesPlugin } from "../css-modules/css-modules" -import { generateGlobalStyles } from "./add-content/styles/global-styles" + +const globalStyles = endent` + * { + box-sizing: border-box; + } + + html, + body { + padding: 0; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + line-height: 1.5; + } + + code { + font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, + Bitstream Vera Sans Mono, Courier New, monospace; + } + + a { + color: inherit; + text-decoration: none; + font-weight: bold; + } +` export const sassPlugin = createPlugin({ id: "sass", @@ -26,18 +51,15 @@ export const sassPlugin = createPlugin({ ], }, ], - steps: { - setUpSass: { - id: "setUpSass", - description: "setting up Sass", - run: async () => { - await writeFile("styles/global-styles.scss", generateGlobalStyles()) - }, - }, - }, slots: { app: { imports: `import "../styles/global-styles.scss";`, }, }, + addFiles: [ + { + destination: "styles/global-styles.scss", + content: globalStyles, + }, + ], } as const) diff --git a/packages/create-next-stack/src/main/plugins/tailwind-css.ts b/packages/create-next-stack/src/main/plugins/tailwind-css.ts index 3c634dd..ea39818 100644 --- a/packages/create-next-stack/src/main/plugins/tailwind-css.ts +++ b/packages/create-next-stack/src/main/plugins/tailwind-css.ts @@ -1,5 +1,4 @@ import endent from "endent" -import { writeFile } from "../helpers/io" import { createPlugin } from "../plugin" /** @@ -32,65 +31,51 @@ export const tailwindCSSPlugin = createPlugin({ ], }, ], - steps: { - setUpTailwindCss: { - id: "setUpTailwindCss", - description: "setting up Tailwind CSS", - run: async () => { - await Promise.all([ - addTailwindConfig(), - addPostcssConfig(), - addStylesGlobalsCss(), - ]) - }, - }, - }, slots: { app: { imports: `import "../styles/globals.css";`, }, }, -} as const) - -const addTailwindConfig = async () => { - // From running `npx tailwind init -p --types` and adding globs to the content array according to https://tailwindcss.com/docs/guides/nextjs - const tailwindConfigString = endent` - /** @type {import('tailwindcss/types').Config} */ - const config = { - content: [ - './pages/**/*.{js,ts,jsx,tsx}', - './components/**/*.{js,ts,jsx,tsx}', - ], - theme: { - extend: {}, - }, - plugins: [], - } - - module.exports = config; - ` - await writeFile("tailwind.config.js", tailwindConfigString) -} - -const addPostcssConfig = async () => { - // From https://github.com/vercel/next.js/blob/canary/examples/with-tailwindcss/postcss.config.js - const postcssConfigString = endent` - module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, - } - ` - await writeFile("postcss.config.js", postcssConfigString) -} + addFiles: [ + { + // From https://github.com/vercel/next.js/blob/canary/examples/with-tailwindcss/styles/globals.css` + destination: "styles/globals.css", + content: endent` + @tailwind base; + @tailwind components; + @tailwind utilities; + `, + }, + { + // From running `npx tailwind init -p --types` and adding globs to the content array according to https://tailwindcss.com/docs/guides/nextjs + destination: "tailwind.config.js", + content: endent` + /** @type {import('tailwindcss/types').Config} */ + const config = { + content: [ + './pages/**/*.{js,ts,jsx,tsx}', + './components/**/*.{js,ts,jsx,tsx}', + ], + theme: { + extend: {}, + }, + plugins: [], + } -const addStylesGlobalsCss = async () => { - // From https://github.com/vercel/next.js/blob/canary/examples/with-tailwindcss/styles/globals.css - const stylesGlobalsCssString = endent` - @tailwind base; - @tailwind components; - @tailwind utilities; - ` - await writeFile("styles/globals.css", stylesGlobalsCssString) -} + module.exports = config; + `, + }, + { + // From https://github.com/vercel/next.js/blob/canary/examples/with-tailwindcss/postcss.config.js + destination: "postcss.config.js", + content: endent` + module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, + } + `, + }, + ], +} as const) diff --git a/packages/create-next-stack/src/main/steps.ts b/packages/create-next-stack/src/main/steps.ts index 5223092..2ef8ed0 100644 --- a/packages/create-next-stack/src/main/steps.ts +++ b/packages/create-next-stack/src/main/steps.ts @@ -1,17 +1,11 @@ import { Step } from "./plugin" -import { chakraUIPlugin } from "./plugins/chakra-ui/chakra-ui" import { createNextStackPlugin } from "./plugins/create-next-stack/create-next-stack" -import { cssModulesPlugin } from "./plugins/css-modules/css-modules" import { emotionPlugin } from "./plugins/emotion" import { formattingPreCommitHookPlugin } from "./plugins/formatting-pre-commit-hook" import { githubActionsPlugin } from "./plugins/github-actions" -import { mantinePlugin } from "./plugins/mantine/mantine" -import { materialUIPlugin } from "./plugins/material-ui/material-ui" import { nextPlugin } from "./plugins/next" import { pnpmPlugin } from "./plugins/pnpm" import { prettierPlugin } from "./plugins/prettier" -import { sassPlugin } from "./plugins/sass/sass" -import { tailwindCSSPlugin } from "./plugins/tailwind-css" import { yarnPlugin } from "./plugins/yarn" export const steps: Step[] = [ @@ -32,9 +26,6 @@ export const steps: Step[] = [ nextPlugin.steps.addNextConfig, // Styling - tailwindCSSPlugin.steps.setUpTailwindCss, - cssModulesPlugin.steps.setUpCssModules, - sassPlugin.steps.setUpSass, emotionPlugin.steps.setUpEmotion, // Formatting @@ -49,11 +40,6 @@ export const steps: Step[] = [ createNextStackPlugin.steps.addContent, createNextStackPlugin.steps.addReadme, - // Component libraries - mantinePlugin.steps.setUpMantine, - chakraUIPlugin.steps.setUpChakraUI, - materialUIPlugin.steps.setUpMaterialUI, - // Uninstall temporary dependencies createNextStackPlugin.steps.uninstallTemporaryDependencies, From bacb4be5aafdc06fc055238abab7bfdc32296009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 22 Jun 2023 16:36:44 +0200 Subject: [PATCH 07/13] Refactor plugin creation UX --- packages/create-next-stack/README.md | 2 - packages/create-next-stack/src/main/plugin.ts | 112 ++++-------------- .../src/main/plugins/chakra-ui/chakra-ui.ts | 6 +- .../add-content/generate-env.ts | 4 +- .../generate-env-table-rows copy.ts | 4 +- .../add-readme/generate-script-table-rows.ts | 4 +- .../create-next-stack/create-next-stack.ts | 111 +++++++++-------- .../sort-orders/environment-variables.ts | 4 +- .../create-next-stack/sort-orders/scripts.ts | 2 +- .../main/plugins/css-modules/css-modules.ts | 38 +++--- .../src/main/plugins/emotion.ts | 12 +- .../src/main/plugins/eslint.ts | 6 +- .../plugins/formatting-pre-commit-hook.ts | 12 +- .../src/main/plugins/formik.ts | 6 +- .../src/main/plugins/framer-motion.ts | 6 +- .../src/main/plugins/github-actions.ts | 30 ++--- .../src/main/plugins/mantine/mantine.ts | 6 +- .../main/plugins/material-ui/material-ui.ts | 6 +- .../src/main/plugins/netlify.ts | 6 +- .../src/main/plugins/next.ts | 25 ++-- .../create-next-stack/src/main/plugins/npm.ts | 6 +- .../src/main/plugins/plausible.ts | 6 +- .../src/main/plugins/pnpm.ts | 12 +- .../src/main/plugins/prettier.ts | 46 ++++--- .../src/main/plugins/react-hook-form.ts | 6 +- .../src/main/plugins/react-icons.ts | 6 +- .../src/main/plugins/react-query.ts | 6 +- .../src/main/plugins/react.ts | 6 +- .../src/main/plugins/sass/sass.ts | 10 +- .../src/main/plugins/styled-components.ts | 6 +- .../src/main/plugins/tailwind-css.ts | 6 +- .../src/main/plugins/typescript.ts | 6 +- .../src/main/plugins/vercel.ts | 6 +- .../src/main/plugins/yarn.ts | 12 +- .../create-next-stack/src/main/setup/setup.ts | 17 ++- .../create-next-stack/src/main/steps.test.ts | 23 ++-- packages/create-next-stack/src/main/steps.ts | 64 +++++----- 37 files changed, 280 insertions(+), 366 deletions(-) diff --git a/packages/create-next-stack/README.md b/packages/create-next-stack/README.md index 148c80d..ff5a718 100644 --- a/packages/create-next-stack/README.md +++ b/packages/create-next-stack/README.md @@ -64,7 +64,6 @@ The table below provides an overview of the technologies currently supported by | next-plausible | [Website](https://next-plausible.vercel.app/) - [GitHub](https://github.com/4lejandrito/next-plausible) | | Vercel | [Website](https://vercel.com/) - [Docs](https://vercel.com/docs) - [CLI Docs](https://vercel.com/docs/cli) | | Netlify | [Website](https://www.netlify.com/) - [Docs](https://docs.netlify.com/) - [CLI Docs](https://cli.netlify.com/) | -| Prisma | [Website](https://www.prisma.io/) - [Docs](https://www.prisma.io/docs) - [GitHub](https://github.com/prisma/prisma) | @@ -105,7 +104,6 @@ FLAGS --plausible Adds Plausible. (Analytics) --prettier Adds Prettier. (Code formatting) - --prisma Adds Prisma. (ORM) --react-hook-form Adds React Hook Form. (Form library) --react-icons Adds React Icons. (Icon library) --react-query Adds React Query. (Server state management diff --git a/packages/create-next-stack/src/main/plugin.ts b/packages/create-next-stack/src/main/plugin.ts index 513e639..ea9cc91 100644 --- a/packages/create-next-stack/src/main/plugin.ts +++ b/packages/create-next-stack/src/main/plugin.ts @@ -2,7 +2,7 @@ import { NextConfig } from "next" import { ValidCNSInputs } from "./create-next-stack-types" import { DeeplyReadonly } from "./helpers/deeply-readonly" -type PluginConfig = DeeplyReadonly<{ +export type Plugin = DeeplyReadonly<{ /** ID that uniquely identifies the plugin */ id: string /** Name of the plugin */ @@ -10,7 +10,7 @@ type PluginConfig = DeeplyReadonly<{ /** Description of the plugin */ description: string /** Whether the plugin is active or not. This determines if dependencies are installed, technologies and scripts added, steps run, and more. */ - active: boolean | ((inputs: ValidCNSInputs) => boolean) + active: boolean | ((inputs: ValidCNSInputs) => boolean | Promise) /** Dependencies that are added to the package.json file. */ dependencies?: Package[] /** Dev dependencies that are added to the package.json file. */ @@ -22,7 +22,7 @@ type PluginConfig = DeeplyReadonly<{ /** Scripts that are added to the package.json file. */ scripts?: Script[] /** A series of functions that are run by Create Next Stack. */ - steps?: Record + steps?: Step[] /** * Environment variables needed by the plugin. * These variables are added to the generated .env and README.md files. @@ -45,7 +45,14 @@ type PluginConfig = DeeplyReadonly<{ /** Destination of the file to add. */ destination: string /** Content of the file. */ - content: string + content: string | ((inputs: ValidCNSInputs) => string | Promise) + /** + * Condition to determine if the file should be added. + * + */ + condition?: + | boolean + | ((inputs: ValidCNSInputs) => boolean | Promise) }> /** Slots to fill in the generated files. */ slots?: { @@ -203,97 +210,30 @@ type Script = { command: string } -type RawStep = { +export type Step = { /** ID that uniquely identified the technology across all plugins' steps. */ id: string - - /** - * `description` should be written in present continuous tense, without punctuation, and with a lowercase first letter unless the description starts with a name or similar. - * - * Eg. "setting up Prettier" or "adding ESLint" - */ + /** A description of the step. It should be written in present continuous tense, without punctuation, and with a lowercase first letter unless the description starts with a name or similar. */ description: string - - /** - * A boolean or function that determines whether the custom run function should run. - * - * Default is true - */ + /** A boolean or function that determines whether the custom run function should run. Default is true. */ shouldRun?: boolean | ((inputs: ValidCNSInputs) => Promise | boolean) - /** Custom run function. */ run: (inputs: ValidCNSInputs) => Promise } -export const createPlugin = ( - pluginConfig: TPluginConfig -): Plugin => { - const plugin = { - ...pluginConfig, - } - const enhancements = { - steps: - pluginConfig.steps != null - ? Object.entries(pluginConfig.steps).reduce( - (acc, [key, value]) => ({ - ...acc, - [key]: createStep(value, plugin as Plugin), - }), - {} as Record - ) - : undefined, - } - for (const [key, value] of Object.entries(enhancements)) { - Object.defineProperty(plugin, key, { - value, - enumerable: true, - }) - } - return plugin as Plugin -} - -export const createStep = ( - step: TRawStep, - plugin: Plugin -): Step => { - return { - // defaults - shouldRun: true, - - // TODO: Consider memoizing shouldRun, as it is sometimes called multiple times. See the lint-staged setup step. - - // step - ...step, - - // enhancements - plugin, - } -} - -export type Plugin = - TPluginConfig & { - steps?: { - [key in keyof TPluginConfig["steps"]]: Step // TODO: Fix type. This should be Step, but that doesn't work. - } - } - -export type Step = TStep & { - shouldRun: NonNullable - plugin: Plugin -} - -export const evalActive = ( - active: PluginConfig["active"], +export const evalProperty = async ( + value: T | ((inputs: ValidCNSInputs) => T | Promise), inputs: ValidCNSInputs -): boolean => { - if (typeof active === "function") return active(inputs) - return active +): Promise => { + if (typeof value === "function") return await value(inputs) + return value } -export const evalShouldRun = async ( - shouldRun: Step["shouldRun"], - inputs: ValidCNSInputs -): Promise => { - if (typeof shouldRun === "function") return await shouldRun(inputs) - return shouldRun +export const evalOptionalProperty = async ( + value: T | ((inputs: ValidCNSInputs) => T | Promise) | undefined, + inputs: ValidCNSInputs, + defaultValue: Exclude +): Promise => { + if (typeof value === "undefined") return defaultValue + return await evalProperty(value, inputs) } diff --git a/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts b/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts index 561643f..64472e8 100644 --- a/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts +++ b/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts @@ -1,7 +1,7 @@ import endent from "endent" -import { createPlugin } from "../../plugin" +import { Plugin } from "../../plugin" -export const chakraUIPlugin = createPlugin({ +export const chakraUIPlugin: Plugin = { id: "chakra-ui", name: "Chakra UI", description: "Adds support for Chakra UI", @@ -59,4 +59,4 @@ export const chakraUIPlugin = createPlugin({ `, }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/generate-env.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/generate-env.ts index c88862b..a25b5d4 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/generate-env.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/generate-env.ts @@ -1,9 +1,9 @@ import endent from "endent" import { ValidCNSInputs } from "../../../create-next-stack-types" -import { getSortedFilteredEnvironmentVariables } from "../sort-orders/environment-variables" +import { getEnvironmentVariables } from "../sort-orders/environment-variables" export const generateEnv = (inputs: ValidCNSInputs): string => { - const environmentVariables = getSortedFilteredEnvironmentVariables(inputs) + const environmentVariables = getEnvironmentVariables(inputs) .map((environmentVariable) => { const { name, description, defaultValue } = environmentVariable diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-env-table-rows copy.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-env-table-rows copy.ts index d751c01..33e54d0 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-env-table-rows copy.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-env-table-rows copy.ts @@ -1,10 +1,10 @@ import { ValidCNSInputs } from "../../../create-next-stack-types" -import { getSortedFilteredEnvironmentVariables } from "../sort-orders/environment-variables" +import { getEnvironmentVariables } from "../sort-orders/environment-variables" export const generateEnvironmentVariableTableRows = async ( inputs: ValidCNSInputs ): Promise => { - const environmentVariables = getSortedFilteredEnvironmentVariables(inputs) + const environmentVariables = getEnvironmentVariables(inputs) if (environmentVariables.length === 0) { return null } diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-script-table-rows.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-script-table-rows.ts index 1c5efb7..7af958a 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-script-table-rows.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-script-table-rows.ts @@ -1,10 +1,10 @@ import { ValidCNSInputs } from "../../../create-next-stack-types" -import { getSortedFilteredScripts } from "../sort-orders/scripts" +import { getScripts } from "../sort-orders/scripts" export const generateScriptTableRows = async ( inputs: ValidCNSInputs ): Promise => { - const scripts = getSortedFilteredScripts(inputs) + const scripts = getScripts(inputs) if (scripts.length === 0) { return null } diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts index 287b1a8..c9193f2 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts @@ -7,7 +7,7 @@ import { isGitInitialized } from "../../helpers/is-git-initialized" import { nonNull } from "../../helpers/non-null" import { runCommand } from "../../helpers/run-command" import { logWarning } from "../../logging" -import { createPlugin } from "../../plugin" +import { evalProperty, Plugin } from "../../plugin" import { getNameVersionCombo, install, uninstall } from "../../setup/packages" import { filterPlugins } from "../../setup/setup" import { prettierPackage } from "../prettier" @@ -17,24 +17,60 @@ import { generateDocument } from "./add-content/pages/generate-document" import { generateIndexPage } from "./add-content/pages/generate-index" import { generateLandingPageTemplate } from "./add-content/templates/LandingPage/generate-LandingPageTemplate" import { generateTechnologies } from "./add-content/templates/LandingPage/generate-technologies" +import { generateNextConfig } from "./add-next-config/generate-next-config" import { generateReadme } from "./add-readme/generate-readme" -import { getSortedFilteredEnvironmentVariables } from "./sort-orders/environment-variables" -import { getSortedFilteredScripts } from "./sort-orders/scripts" +import { getEnvironmentVariables } from "./sort-orders/environment-variables" +import { getScripts } from "./sort-orders/scripts" const gitAttributesFilename = ".gitattributes" -export const createNextStackPlugin = createPlugin({ +export const createNextStackPlugin: Plugin = { id: "create-next-stack", name: "Create Next Stack", description: "Adds various miscellaneous steps. Some necessities, some niceties.", active: true, - steps: { - addScripts: { + addFiles: [ + { + destination: ".env", + condition: (inputs) => getEnvironmentVariables(inputs).length > 0, + content: (inputs) => generateEnv(inputs), + }, + { + destination: "next.config.js", + content: (inputs) => generateNextConfig(inputs), + }, + { + destination: "pages/index.tsx", + content: (inputs) => generateIndexPage(inputs), + }, + { + destination: "pages/_app.tsx", + content: (inputs) => generateApp(inputs), + }, + { + destination: "pages/_document.tsx", + content: (inputs) => generateDocument(inputs), + }, + { + destination: "templates/LandingPage/technologies.ts", + content: (inputs) => generateTechnologies(inputs), + }, + { + destination: "templates/LandingPage/LandingPageTemplate.tsx", + content: (inputs) => generateLandingPageTemplate(inputs), + }, + { + destination: "README.md", + content: (inputs) => generateReadme(inputs), + }, + ], + steps: [ + { id: "addScripts", description: "adding scripts to package.json", run: async (inputs) => { - const scripts = getSortedFilteredScripts(inputs) + const scripts = getScripts(inputs) await modifyJsonFile("package.json", (packageJson) => ({ ...packageJson, @@ -51,7 +87,7 @@ export const createNextStackPlugin = createPlugin({ })) }, }, - copyAssets: { + { id: "copyAssets", description: "copying static assets", run: async (): Promise => { @@ -61,61 +97,22 @@ export const createNextStackPlugin = createPlugin({ await copyDirectory(source, destination) }, }, - addContent: { + { id: "addContent", description: "adding content", run: async (inputs) => { - const environmentVariables = - getSortedFilteredEnvironmentVariables(inputs) - if (environmentVariables.length > 0) { - await writeFile(".env", generateEnv(inputs)) - } - - const filesToWrite = [ - { - destination: "pages/index.tsx", - content: generateIndexPage(inputs), - }, - { - destination: "pages/_app.tsx", - content: generateApp(inputs), - }, - { - destination: "pages/_document.tsx", - content: generateDocument(inputs), - }, - { - destination: "templates/LandingPage/technologies.ts", - content: generateTechnologies(inputs), - }, - { - destination: "templates/LandingPage/LandingPageTemplate.tsx", - content: generateLandingPageTemplate(inputs), - }, - ] - const pluginFilesToWrite = filterPlugins(inputs) .flatMap((plugin) => plugin.addFiles) .filter(nonNull) - filesToWrite.push(...pluginFilesToWrite) - await Promise.all( - filesToWrite.map(({ destination, content }) => - writeFile(destination, content) + pluginFilesToWrite.map(async ({ destination, content }) => + writeFile(destination, await evalProperty(content, inputs)) ) ) }, }, - addReadme: { - id: "addReadme", - description: "adding Readme", - run: async (inputs) => { - const readmeString = await generateReadme(inputs) - await writeFile("README.md", readmeString) - }, - }, - initialCommit: { + { id: "initialCommit", description: "adding initial commit", shouldRun: async () => { @@ -136,7 +133,7 @@ export const createNextStackPlugin = createPlugin({ ]) }, }, - installDependencies: { + { id: "installDependencies", description: "installing dependencies", run: async (inputs) => { @@ -167,7 +164,7 @@ export const createNextStackPlugin = createPlugin({ } }, }, - uninstallTemporaryDependencies: { + { id: "uninstallTemporaryDependencies", description: "uninstalling temporary dependencies", run: async (inputs) => { @@ -182,7 +179,7 @@ export const createNextStackPlugin = createPlugin({ } }, }, - formatProject: { + { id: "formatProject", description: "formatting project", run: async () => { @@ -193,7 +190,7 @@ export const createNextStackPlugin = createPlugin({ ]) }, }, - addGitAttributes: { + { id: "addGitAttributes", description: `adding ${gitAttributesFilename}`, shouldRun: async () => { @@ -217,5 +214,5 @@ export const createNextStackPlugin = createPlugin({ ) }, }, - }, -} as const) + ], +} as const diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.ts index b0ee853..f7bb5fc 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.ts @@ -7,9 +7,7 @@ export const environmentVariablesSortOrder: string[] = [ "NEXT_PUBLIC_WEBSITE_DOMAIN", ] -export const getSortedFilteredEnvironmentVariables = ( - inputs: ValidCNSInputs -) => { +export const getEnvironmentVariables = (inputs: ValidCNSInputs) => { const pluginEnvironmentVariables = filterPlugins(inputs) .flatMap((plugin) => plugin.environmentVariables) .filter(nonNull) diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.ts index ba5d49b..6f08fa1 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.ts @@ -16,7 +16,7 @@ export const scriptsSortOrder: string[] = [ "deploy:netlify", ] -export const getSortedFilteredScripts = (inputs: ValidCNSInputs) => { +export const getScripts = (inputs: ValidCNSInputs) => { const pluginScripts = filterPlugins(inputs) .flatMap((plugin) => plugin.scripts) .filter(nonNull) diff --git a/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts b/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts index 8ff284d..0c41c5b 100644 --- a/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts +++ b/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts @@ -1,5 +1,5 @@ import endent from "endent" -import { createPlugin } from "../../plugin" +import { Plugin } from "../../plugin" const globalStyles = endent` * { @@ -27,27 +27,27 @@ const globalStyles = endent` } ` -export const cssModulesPlugin = createPlugin({ - id: "css-modules", +export const cssModuleTechnology = { + id: "cssModules", name: "CSS Modules", - description: "Adds relevant CSS Modules boilerplate and documentation", - active: ({ flags }) => Boolean(flags.styling === "css-modules"), - technologies: [ + description: + "CSS Modules are CSS files in which all class names are scoped locally to the component importing them. This means that developers can use the same CSS class name in different files without worrying about naming conflicts. Gone are the days of writing BEM class names!", + links: [ + { title: "Website", url: "https://github.com/css-modules/css-modules" }, + { title: "Docs", url: "https://github.com/css-modules/css-modules" }, { - id: "cssModules", - name: "CSS Modules", - description: - "CSS Modules are CSS files in which all class names are scoped locally to the component importing them. This means that developers can use the same CSS class name in different files without worrying about naming conflicts. Gone are the days of writing BEM class names!", - links: [ - { title: "Website", url: "https://github.com/css-modules/css-modules" }, - { title: "Docs", url: "https://github.com/css-modules/css-modules" }, - { - title: "Next.js-specific docs", - url: "https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css", - }, - ], + title: "Next.js-specific docs", + url: "https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css", }, ], +} + +export const cssModulesPlugin: Plugin = { + id: "css-modules", + name: "CSS Modules", + description: "Adds relevant CSS Modules boilerplate and documentation", + active: ({ flags }) => Boolean(flags.styling === "css-modules"), + technologies: [cssModuleTechnology], slots: { app: { imports: `import "../styles/global-styles.css";`, @@ -59,4 +59,4 @@ export const cssModulesPlugin = createPlugin({ content: globalStyles, }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/emotion.ts b/packages/create-next-stack/src/main/plugins/emotion.ts index 478036a..4154465 100644 --- a/packages/create-next-stack/src/main/plugins/emotion.ts +++ b/packages/create-next-stack/src/main/plugins/emotion.ts @@ -1,7 +1,7 @@ import { modifyJsonFile, toObject } from "../helpers/io" -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const emotionPlugin = createPlugin({ +export const emotionPlugin: Plugin = { id: "emotion", name: "Emotion", description: "Adds support for Emotion", @@ -23,8 +23,8 @@ export const emotionPlugin = createPlugin({ ], }, ], - steps: { - setUpEmotion: { + steps: [ + { id: "setUpEmotion", description: "setting up Emotion", run: async () => { @@ -40,7 +40,7 @@ export const emotionPlugin = createPlugin({ })) }, }, - }, + ], slots: { nextConfigJs: { nextConfig: { @@ -50,4 +50,4 @@ export const emotionPlugin = createPlugin({ }, }, }, -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/eslint.ts b/packages/create-next-stack/src/main/plugins/eslint.ts index 30e741c..579c858 100644 --- a/packages/create-next-stack/src/main/plugins/eslint.ts +++ b/packages/create-next-stack/src/main/plugins/eslint.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const eslintPlugin = createPlugin({ +export const eslintPlugin: Plugin = { id: "eslint", name: "ESLint", description: "Adds relevant documentation for ESLint", @@ -22,4 +22,4 @@ export const eslintPlugin = createPlugin({ ], }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts b/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts index 0d724af..93571f4 100644 --- a/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts +++ b/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts @@ -3,9 +3,9 @@ import { isGitInitialized } from "../helpers/is-git-initialized" import { remove } from "../helpers/remove" import { runCommand } from "../helpers/run-command" import { logWarning } from "../logging" -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const formattingPreCommitHookPlugin = createPlugin({ +export const formattingPreCommitHookPlugin: Plugin = { id: "formatting-pre-commit-hook", name: "formatting-pre-commit-hook", description: @@ -51,8 +51,8 @@ export const formattingPreCommitHookPlugin = createPlugin({ command: "husky install", }, ], - steps: { - setUpFormattingPreCommitHook: { + steps: [ + { id: "setUpFormattingPreCommitHook", description: "setting up formatting pre-commit hook", shouldRun: async () => { @@ -75,5 +75,5 @@ export const formattingPreCommitHookPlugin = createPlugin({ })) }, }, - }, -} as const) + ], +} as const diff --git a/packages/create-next-stack/src/main/plugins/formik.ts b/packages/create-next-stack/src/main/plugins/formik.ts index 476c1b3..e27bdce 100644 --- a/packages/create-next-stack/src/main/plugins/formik.ts +++ b/packages/create-next-stack/src/main/plugins/formik.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const formikPlugin = createPlugin({ +export const formikPlugin: Plugin = { id: "formik", name: "Formik", description: "Adds support for Formik", @@ -19,4 +19,4 @@ export const formikPlugin = createPlugin({ ], }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/framer-motion.ts b/packages/create-next-stack/src/main/plugins/framer-motion.ts index d3e2a54..914c06f 100644 --- a/packages/create-next-stack/src/main/plugins/framer-motion.ts +++ b/packages/create-next-stack/src/main/plugins/framer-motion.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const framerMotionPlugin = createPlugin({ +export const framerMotionPlugin: Plugin = { id: "framer-motion", name: "Framer Motion", description: "Adds support for Framer Motion", @@ -19,4 +19,4 @@ export const framerMotionPlugin = createPlugin({ ], }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/github-actions.ts b/packages/create-next-stack/src/main/plugins/github-actions.ts index 8abbf48..25e1ee2 100644 --- a/packages/create-next-stack/src/main/plugins/github-actions.ts +++ b/packages/create-next-stack/src/main/plugins/github-actions.ts @@ -1,14 +1,13 @@ import endent from "endent" import { ValidCNSInputs } from "../create-next-stack-types" -import { writeFile } from "../helpers/io" import { cleanInstallCommandMap, runCommandMap, } from "../helpers/package-manager-utils" -import { createPlugin, evalActive } from "../plugin" +import { evalProperty, Plugin } from "../plugin" import { prettierPlugin } from "./prettier" -export const githubActionsPlugin = createPlugin({ +export const githubActionsPlugin: Plugin = { id: "github-actions", name: "GitHub Actions", description: "Adds support for GitHub Actions", @@ -37,22 +36,23 @@ export const githubActionsPlugin = createPlugin({ command: "echo No tests found.", }, ], - steps: { - addGithubWorkflowStep: { - id: "addGithubWorkflowStep", - description: "adding GitHub workflow", - run: async (inputs) => { - const filename = ".github/workflows/ci.yml" - await writeFile(filename, generateCiYml(inputs)) - }, + addFiles: [ + { + destination: ".github/workflows/ci.yml", + content: (inputs) => generateCiYml(inputs), }, - }, -} as const) + ], +} as const -const generateCiYml = (inputs: ValidCNSInputs): string => { +const generateCiYml = async (inputs: ValidCNSInputs): Promise => { const { flags } = inputs const packageManager = flags["package-manager"] + const isPrettierPluginActive = await evalProperty( + prettierPlugin.active, + inputs + ) + return endent` name: "CI" @@ -89,7 +89,7 @@ const generateCiYml = (inputs: ValidCNSInputs): string => { run: ${cleanInstallCommandMap[packageManager]} ${ - evalActive(prettierPlugin.active, inputs) + isPrettierPluginActive ? endent` - name: "Check format" run: ${runCommandMap[packageManager]} format:check diff --git a/packages/create-next-stack/src/main/plugins/mantine/mantine.ts b/packages/create-next-stack/src/main/plugins/mantine/mantine.ts index d93ceef..ecdcab3 100644 --- a/packages/create-next-stack/src/main/plugins/mantine/mantine.ts +++ b/packages/create-next-stack/src/main/plugins/mantine/mantine.ts @@ -1,7 +1,7 @@ import endent from "endent" -import { createPlugin } from "../../plugin" +import { Plugin } from "../../plugin" -export const mantinePlugin = createPlugin({ +export const mantinePlugin: Plugin = { id: "mantine", name: "Mantine", description: "Adds support for Mantine", @@ -66,4 +66,4 @@ export const mantinePlugin = createPlugin({ `, }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts b/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts index a1156cf..8d611bf 100644 --- a/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts +++ b/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts @@ -1,5 +1,5 @@ import endent from "endent" -import { createPlugin } from "../../plugin" +import { Plugin } from "../../plugin" const materialTheme = endent` import { Roboto } from 'next/font/google'; @@ -32,7 +32,7 @@ const materialTheme = endent` }); ` -export const materialUIPlugin = createPlugin({ +export const materialUIPlugin: Plugin = { id: "material-ui", name: "Material UI", description: "Adds support for Material UI", @@ -79,4 +79,4 @@ export const materialUIPlugin = createPlugin({ content: materialTheme, }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/netlify.ts b/packages/create-next-stack/src/main/plugins/netlify.ts index 6464e85..ce06899 100644 --- a/packages/create-next-stack/src/main/plugins/netlify.ts +++ b/packages/create-next-stack/src/main/plugins/netlify.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const netlifyPlugin = createPlugin({ +export const netlifyPlugin: Plugin = { id: "netlify", name: "Netlify", description: "Adds support for Netlify", @@ -29,4 +29,4 @@ export const netlifyPlugin = createPlugin({ todos: [ "Integrate Netlify with your repository host for continuous deployments at https://app.netlify.com/start. The Netlify CLI, mainly used for preview deployments, won't auto-detect Next.js until you do.", ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/next.ts b/packages/create-next-stack/src/main/plugins/next.ts index 865bf68..4c5ac05 100644 --- a/packages/create-next-stack/src/main/plugins/next.ts +++ b/packages/create-next-stack/src/main/plugins/next.ts @@ -1,20 +1,19 @@ import chalk from "chalk" import endent from "endent" import path from "path" -import { makeDirectory, writeFile } from "../helpers/io" +import { makeDirectory } from "../helpers/io" import { remove } from "../helpers/remove" import { runCommand } from "../helpers/run-command" import { logDebug } from "../logging" -import { createPlugin, Package } from "../plugin" +import { Package, Plugin } from "../plugin" import { getNameVersionCombo } from "../setup/packages" -import { generateNextConfig } from "./create-next-stack/add-next-config/generate-next-config" const createNextAppPackage: Package = { name: "create-next-app", version: "13.2.3", } -export const nextPlugin = createPlugin({ +export const nextPlugin: Plugin = { id: "next", name: "Next.js", description: "Adds Next.js foundation", @@ -58,8 +57,8 @@ export const nextPlugin = createPlugin({ command: "next lint", }, ], - steps: { - createNextApp: { + steps: [ + { id: "createNextApp", description: "running Create Next App", @@ -129,7 +128,7 @@ export const nextPlugin = createPlugin({ process.chdir(args.app_name) }, }, - removeOfficialCNAContent: { + { id: "removeOfficialCNAContent", description: "removing content added by Create Next App", run: async () => { @@ -144,13 +143,5 @@ export const nextPlugin = createPlugin({ ]) }, }, - addNextConfig: { - id: "addNextConfig", - description: "adding next.config.js", - run: async (inputs) => { - const nextConfigString = await generateNextConfig(inputs) - await writeFile("next.config.js", nextConfigString) - }, - }, - }, -} as const) + ], +} as const diff --git a/packages/create-next-stack/src/main/plugins/npm.ts b/packages/create-next-stack/src/main/plugins/npm.ts index 8fc9d47..432b7e0 100644 --- a/packages/create-next-stack/src/main/plugins/npm.ts +++ b/packages/create-next-stack/src/main/plugins/npm.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const npmPlugin = createPlugin({ +export const npmPlugin: Plugin = { id: "npm", name: "npm", description: "Adds relevant npm documentation", @@ -18,4 +18,4 @@ export const npmPlugin = createPlugin({ ], }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/plausible.ts b/packages/create-next-stack/src/main/plugins/plausible.ts index 99435ab..8315156 100644 --- a/packages/create-next-stack/src/main/plugins/plausible.ts +++ b/packages/create-next-stack/src/main/plugins/plausible.ts @@ -1,9 +1,9 @@ import endent from "endent" -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" const websiteDomainEnvVar = "NEXT_PUBLIC_WEBSITE_DOMAIN" -export const plausiblePlugin = createPlugin({ +export const plausiblePlugin: Plugin = { id: "plausible", name: "Plausible", description: "Adds support for Plausible Analytics", @@ -72,4 +72,4 @@ export const plausiblePlugin = createPlugin({ `Set up an account in Plausible Analytics, and add your website in their dashboard.`, `Update the \`${websiteDomainEnvVar}\` environment variable to your website's domain to connect Plausible Analytics to your app.`, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/pnpm.ts b/packages/create-next-stack/src/main/plugins/pnpm.ts index ff60167..8b92573 100644 --- a/packages/create-next-stack/src/main/plugins/pnpm.ts +++ b/packages/create-next-stack/src/main/plugins/pnpm.ts @@ -1,8 +1,8 @@ import { runCommand } from "../helpers/run-command" -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" import { getNameVersionCombo } from "../setup/packages" -export const pnpmPlugin = createPlugin({ +export const pnpmPlugin: Plugin = { id: "pnpm", name: "pnpm", description: "Adds support for pnpm", @@ -20,8 +20,8 @@ export const pnpmPlugin = createPlugin({ ], }, ], - steps: { - updatePnpm: { + steps: [ + { id: "updatePnpm", description: "updating pnpm", run: async () => { @@ -32,5 +32,5 @@ export const pnpmPlugin = createPlugin({ ]) }, }, - }, -} as const) + ], +} as const diff --git a/packages/create-next-stack/src/main/plugins/prettier.ts b/packages/create-next-stack/src/main/plugins/prettier.ts index 0431c58..333e27c 100644 --- a/packages/create-next-stack/src/main/plugins/prettier.ts +++ b/packages/create-next-stack/src/main/plugins/prettier.ts @@ -1,12 +1,12 @@ -import { modifyJsonFile, toArray, writeJsonFile } from "../helpers/io" -import { createPlugin, Package } from "../plugin" +import { modifyJsonFile, toArray } from "../helpers/io" +import { Package, Plugin } from "../plugin" export const prettierPackage = { name: "prettier", version: "^2.0.0", } satisfies Package -export const prettierPlugin = createPlugin({ +export const prettierPlugin: Plugin = { id: "prettier", name: "Prettier", description: "Adds support for Prettier", @@ -41,30 +41,26 @@ export const prettierPlugin = createPlugin({ command: "prettier --check --ignore-path=.gitignore .", }, ], - steps: { - setUpPrettier: { + addFiles: [ + { + destination: ".prettierrc", + content: `{}`, + }, + ], + steps: [ + { id: "setUpPrettier", description: "setting up Prettier", run: async () => { - await Promise.all([addPrettierConfig(), setUpEslintConfigPrettier()]) + await modifyJsonFile(".eslintrc.json", (eslintrc) => ({ + ...eslintrc, + extends: [ + // + ...toArray(eslintrc["extends"]), + "eslint-config-prettier", + ], + })) }, }, - }, -} as const) - -const addPrettierConfig = async () => { - const prettierConfig = {} // Only provide overrides in this config. Not setting Prettier's defaults explicitly is preferred, so our rules will follow Prettier's defaults as much as possible. - - await writeJsonFile(".prettierrc", prettierConfig) -} - -const setUpEslintConfigPrettier = async () => { - await modifyJsonFile(".eslintrc.json", (eslintrc) => ({ - ...eslintrc, - extends: [ - // - ...toArray(eslintrc["extends"]), - "eslint-config-prettier", - ], - })) -} + ], +} as const diff --git a/packages/create-next-stack/src/main/plugins/react-hook-form.ts b/packages/create-next-stack/src/main/plugins/react-hook-form.ts index 1f02ce8..349ff75 100644 --- a/packages/create-next-stack/src/main/plugins/react-hook-form.ts +++ b/packages/create-next-stack/src/main/plugins/react-hook-form.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const reactHookFormPlugin = createPlugin({ +export const reactHookFormPlugin: Plugin = { id: "react-hook-form", name: "React Hook Form", description: "Adds support for React Hook Form", @@ -22,4 +22,4 @@ export const reactHookFormPlugin = createPlugin({ ], }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/react-icons.ts b/packages/create-next-stack/src/main/plugins/react-icons.ts index 5865884..fed1c0e 100644 --- a/packages/create-next-stack/src/main/plugins/react-icons.ts +++ b/packages/create-next-stack/src/main/plugins/react-icons.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const reactIconsPlugin = createPlugin({ +export const reactIconsPlugin: Plugin = { id: "react-icons", name: "React Icons", description: "Adds support for React Icons", @@ -18,4 +18,4 @@ export const reactIconsPlugin = createPlugin({ ], }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/react-query.ts b/packages/create-next-stack/src/main/plugins/react-query.ts index 60f6d36..7b14448 100644 --- a/packages/create-next-stack/src/main/plugins/react-query.ts +++ b/packages/create-next-stack/src/main/plugins/react-query.ts @@ -1,7 +1,7 @@ import endent from "endent" -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const reactQueryPlugin = createPlugin({ +export const reactQueryPlugin: Plugin = { id: "react-query", name: "React Query", description: "Adds support for React Query", @@ -48,4 +48,4 @@ export const reactQueryPlugin = createPlugin({ `, }, }, -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/react.ts b/packages/create-next-stack/src/main/plugins/react.ts index 933bd71..7696ba4 100644 --- a/packages/create-next-stack/src/main/plugins/react.ts +++ b/packages/create-next-stack/src/main/plugins/react.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const reactPlugin = createPlugin({ +export const reactPlugin: Plugin = { id: "react", name: "React", description: "Adds relevant React documentation", @@ -22,4 +22,4 @@ export const reactPlugin = createPlugin({ ], }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/sass/sass.ts b/packages/create-next-stack/src/main/plugins/sass/sass.ts index dca61e6..45e4212 100644 --- a/packages/create-next-stack/src/main/plugins/sass/sass.ts +++ b/packages/create-next-stack/src/main/plugins/sass/sass.ts @@ -1,6 +1,6 @@ import endent from "endent" -import { createPlugin } from "../../plugin" -import { cssModulesPlugin } from "../css-modules/css-modules" +import { Plugin } from "../../plugin" +import { cssModuleTechnology } from "../css-modules/css-modules" const globalStyles = endent` * { @@ -28,14 +28,14 @@ const globalStyles = endent` } ` -export const sassPlugin = createPlugin({ +export const sassPlugin: Plugin = { id: "sass", name: "Sass", description: "Adds support for Sass", active: ({ flags }) => flags.styling === "css-modules-with-sass", dependencies: [{ name: "sass", version: "^1.0.0" }], technologies: [ - cssModulesPlugin.technologies[0], + cssModuleTechnology, { id: "sass", name: "Sass", @@ -62,4 +62,4 @@ export const sassPlugin = createPlugin({ content: globalStyles, }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/styled-components.ts b/packages/create-next-stack/src/main/plugins/styled-components.ts index da4a8ff..f56b066 100644 --- a/packages/create-next-stack/src/main/plugins/styled-components.ts +++ b/packages/create-next-stack/src/main/plugins/styled-components.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const styledComponentsPlugin = createPlugin({ +export const styledComponentsPlugin: Plugin = { id: "styled-components", name: "Styled Components", description: "Adds support for Styled Components", @@ -32,4 +32,4 @@ export const styledComponentsPlugin = createPlugin({ }, }, }, -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/tailwind-css.ts b/packages/create-next-stack/src/main/plugins/tailwind-css.ts index ea39818..048def7 100644 --- a/packages/create-next-stack/src/main/plugins/tailwind-css.ts +++ b/packages/create-next-stack/src/main/plugins/tailwind-css.ts @@ -1,5 +1,5 @@ import endent from "endent" -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" /** * Follows a combination of the official Next.js template: @@ -8,7 +8,7 @@ import { createPlugin } from "../plugin" * https://tailwindcss.com/docs/guides/nextjs */ -export const tailwindCSSPlugin = createPlugin({ +export const tailwindCSSPlugin: Plugin = { id: "tailwind-css", name: "Tailwind CSS", description: "Adds support for Tailwind CSS", @@ -78,4 +78,4 @@ export const tailwindCSSPlugin = createPlugin({ `, }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/typescript.ts b/packages/create-next-stack/src/main/plugins/typescript.ts index 76fc957..363a259 100644 --- a/packages/create-next-stack/src/main/plugins/typescript.ts +++ b/packages/create-next-stack/src/main/plugins/typescript.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const typescriptPlugin = createPlugin({ +export const typescriptPlugin: Plugin = { id: "typescript", name: "Typescript", description: "Adds relevant Typescript documentation", @@ -19,4 +19,4 @@ export const typescriptPlugin = createPlugin({ ], }, ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/vercel.ts b/packages/create-next-stack/src/main/plugins/vercel.ts index 01bc946..fad4789 100644 --- a/packages/create-next-stack/src/main/plugins/vercel.ts +++ b/packages/create-next-stack/src/main/plugins/vercel.ts @@ -1,6 +1,6 @@ -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" -export const vercelPlugin = createPlugin({ +export const vercelPlugin: Plugin = { id: "vercel", name: "Vercel", description: "Adds support for Vercel", @@ -29,4 +29,4 @@ export const vercelPlugin = createPlugin({ todos: [ "Integrate Vercel with your repository host for continuous deployments at https://vercel.com/new", ], -} as const) +} as const diff --git a/packages/create-next-stack/src/main/plugins/yarn.ts b/packages/create-next-stack/src/main/plugins/yarn.ts index 6701f3a..bffbd56 100644 --- a/packages/create-next-stack/src/main/plugins/yarn.ts +++ b/packages/create-next-stack/src/main/plugins/yarn.ts @@ -1,8 +1,8 @@ import { runCommand } from "../helpers/run-command" -import { createPlugin } from "../plugin" +import { Plugin } from "../plugin" import { getNameVersionCombo } from "../setup/packages" -export const yarnPlugin = createPlugin({ +export const yarnPlugin: Plugin = { id: "yarn", name: "Yarn", description: "Adds support for Yarn", @@ -20,8 +20,8 @@ export const yarnPlugin = createPlugin({ ], }, ], - steps: { - updateYarn: { + steps: [ + { id: "updateYarn", description: "updating Yarn", run: async () => { @@ -32,5 +32,5 @@ export const yarnPlugin = createPlugin({ ]) }, }, - }, -} as const) + ], +} as const diff --git a/packages/create-next-stack/src/main/setup/setup.ts b/packages/create-next-stack/src/main/setup/setup.ts index 4025402..bbce289 100644 --- a/packages/create-next-stack/src/main/setup/setup.ts +++ b/packages/create-next-stack/src/main/setup/setup.ts @@ -5,7 +5,7 @@ import { getDiffString } from "../helpers/diff-string" import { inDebugMode } from "../helpers/in-debug-mode" import { time } from "../helpers/time" import { logDebug, logInfo } from "../logging" -import { evalActive, evalShouldRun, Plugin } from "../plugin" +import { evalOptionalProperty, evalProperty, Plugin } from "../plugin" import { chakraUIPlugin } from "../plugins/chakra-ui/chakra-ui" import { createNextStackPlugin } from "../plugins/create-next-stack/create-next-stack" import { cssModulesPlugin } from "../plugins/css-modules/css-modules" @@ -33,7 +33,7 @@ import { tailwindCSSPlugin } from "../plugins/tailwind-css" import { typescriptPlugin } from "../plugins/typescript" import { vercelPlugin } from "../plugins/vercel" import { yarnPlugin } from "../plugins/yarn" -import { steps } from "../steps" +import { getSteps } from "../steps" import { printFinalMessages } from "./print-final-messages" export const plugins: Plugin[] = [ @@ -67,16 +67,21 @@ export const plugins: Plugin[] = [ ] export const filterPlugins = (inputs: ValidCNSInputs): Plugin[] => - plugins.filter((plugin) => evalActive(plugin.active, inputs)) + plugins.filter(async (plugin) => await evalProperty(plugin.active, inputs)) export const performSetupSteps = async ( inputs: ValidCNSInputs ): Promise => { + const steps = getSteps(inputs) + const allStepsDiff = await time(async () => { for (const step of steps) { - const pluginActive = evalActive(step.plugin.active, inputs) - const stepShouldRun = await evalShouldRun(step.shouldRun, inputs) - if (!pluginActive || !stepShouldRun) { + const stepShouldRun = await evalOptionalProperty( + step.shouldRun, + inputs, + true + ) + if (!stepShouldRun) { continue } diff --git a/packages/create-next-stack/src/main/steps.test.ts b/packages/create-next-stack/src/main/steps.test.ts index f15f7b4..bf9ae71 100644 --- a/packages/create-next-stack/src/main/steps.test.ts +++ b/packages/create-next-stack/src/main/steps.test.ts @@ -1,25 +1,24 @@ import { test } from "@jest/globals" +import { nonNull } from "./helpers/non-null" import { plugins } from "./setup/setup" -import { steps } from "./steps" +import { stepsOrder } from "./steps" test("`steps` contains no duplicates", () => { const seenSteps = new Set() - for (const step of steps) { - const { id } = step - if (seenSteps.has(id)) { - throw new Error(`Duplicate step with ID "${id}" found in steps.ts`) + for (const stepId of stepsOrder) { + if (seenSteps.has(stepId)) { + throw new Error(`Duplicate step with ID "${stepId}" found in steps.ts`) } - seenSteps.add(id) + seenSteps.add(stepId) } }) test("`steps` includes all plugins' steps", () => { - const requiredStepIDs = plugins.flatMap((plugin) => - plugin.steps // - ? Object.values(plugin.steps).map((step) => step.id) - : [] - ) - const actualStepIDs = new Set(steps.map((step) => step.id)) + const requiredStepIDs = plugins + .flatMap((plugin) => plugin.steps) + .filter(nonNull) + .map((step) => step.id) + const actualStepIDs = new Set(stepsOrder) for (const requiredStepID of requiredStepIDs) { if (!actualStepIDs.has(requiredStepID)) { throw new Error(`Missing step with ID "${requiredStepID}" in steps.ts`) diff --git a/packages/create-next-stack/src/main/steps.ts b/packages/create-next-stack/src/main/steps.ts index 2ef8ed0..dac332f 100644 --- a/packages/create-next-stack/src/main/steps.ts +++ b/packages/create-next-stack/src/main/steps.ts @@ -1,49 +1,39 @@ +import { ValidCNSInputs } from "./create-next-stack-types" +import { nonNull } from "./helpers/non-null" +import { compareByOrder } from "./helpers/sort-by-order" import { Step } from "./plugin" -import { createNextStackPlugin } from "./plugins/create-next-stack/create-next-stack" -import { emotionPlugin } from "./plugins/emotion" -import { formattingPreCommitHookPlugin } from "./plugins/formatting-pre-commit-hook" -import { githubActionsPlugin } from "./plugins/github-actions" -import { nextPlugin } from "./plugins/next" -import { pnpmPlugin } from "./plugins/pnpm" -import { prettierPlugin } from "./plugins/prettier" -import { yarnPlugin } from "./plugins/yarn" +import { filterPlugins } from "./setup/setup" -export const steps: Step[] = [ +export const stepsOrder: string[] = [ // Update package manager - pnpmPlugin.steps.updatePnpm, - yarnPlugin.steps.updateYarn, - + "updatePnpm", + "updateYarn", // Create Next App - nextPlugin.steps.createNextApp, - nextPlugin.steps.removeOfficialCNAContent, - + "createNextApp", + "removeOfficialCNAContent", // Install dependencies - createNextStackPlugin.steps.installDependencies, - + "installDependencies", // Configuration - createNextStackPlugin.steps.addScripts, - createNextStackPlugin.steps.addGitAttributes, - nextPlugin.steps.addNextConfig, - + "addScripts", + "addGitAttributes", // Styling - emotionPlugin.steps.setUpEmotion, - + "setUpEmotion", // Formatting - prettierPlugin.steps.setUpPrettier, - formattingPreCommitHookPlugin.steps.setUpFormattingPreCommitHook, - - // Continuous integration - githubActionsPlugin.steps.addGithubWorkflowStep, - + "setUpPrettier", + "setUpFormattingPreCommitHook", // Add/generate content - createNextStackPlugin.steps.copyAssets, - createNextStackPlugin.steps.addContent, - createNextStackPlugin.steps.addReadme, - + "copyAssets", + "addContent", // Uninstall temporary dependencies - createNextStackPlugin.steps.uninstallTemporaryDependencies, - + "uninstallTemporaryDependencies", // Format & initial commit - createNextStackPlugin.steps.formatProject, - createNextStackPlugin.steps.initialCommit, + "formatProject", + "initialCommit", ] + +export const getSteps = (inputs: ValidCNSInputs): Step[] => { + return filterPlugins(inputs) + .flatMap((plugin) => plugin.steps) + .filter(nonNull) + .sort((a, b) => compareByOrder(a.id, b.id, stepsOrder)) +} From 3e7afdfac28aebb62478498f2b79933ca90fb164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 22 Jun 2023 16:37:56 +0200 Subject: [PATCH 08/13] Move plugins in folders to root --- .../src/main/plugins/{chakra-ui => }/chakra-ui.ts | 2 +- .../src/main/plugins/{css-modules => }/css-modules.ts | 2 +- .../src/main/plugins/{mantine => }/mantine.ts | 2 +- .../src/main/plugins/{material-ui => }/material-ui.ts | 2 +- .../src/main/plugins/{sass => }/sass.ts | 4 ++-- packages/create-next-stack/src/main/setup/setup.ts | 10 +++++----- 6 files changed, 11 insertions(+), 11 deletions(-) rename packages/create-next-stack/src/main/plugins/{chakra-ui => }/chakra-ui.ts (98%) rename packages/create-next-stack/src/main/plugins/{css-modules => }/css-modules.ts (97%) rename packages/create-next-stack/src/main/plugins/{mantine => }/mantine.ts (98%) rename packages/create-next-stack/src/main/plugins/{material-ui => }/material-ui.ts (98%) rename packages/create-next-stack/src/main/plugins/{sass => }/sass.ts (94%) diff --git a/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts b/packages/create-next-stack/src/main/plugins/chakra-ui.ts similarity index 98% rename from packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts rename to packages/create-next-stack/src/main/plugins/chakra-ui.ts index 64472e8..3e7cc4c 100644 --- a/packages/create-next-stack/src/main/plugins/chakra-ui/chakra-ui.ts +++ b/packages/create-next-stack/src/main/plugins/chakra-ui.ts @@ -1,5 +1,5 @@ import endent from "endent" -import { Plugin } from "../../plugin" +import { Plugin } from "../plugin" export const chakraUIPlugin: Plugin = { id: "chakra-ui", diff --git a/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts b/packages/create-next-stack/src/main/plugins/css-modules.ts similarity index 97% rename from packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts rename to packages/create-next-stack/src/main/plugins/css-modules.ts index 0c41c5b..4fe61f0 100644 --- a/packages/create-next-stack/src/main/plugins/css-modules/css-modules.ts +++ b/packages/create-next-stack/src/main/plugins/css-modules.ts @@ -1,5 +1,5 @@ import endent from "endent" -import { Plugin } from "../../plugin" +import { Plugin } from "../plugin" const globalStyles = endent` * { diff --git a/packages/create-next-stack/src/main/plugins/mantine/mantine.ts b/packages/create-next-stack/src/main/plugins/mantine.ts similarity index 98% rename from packages/create-next-stack/src/main/plugins/mantine/mantine.ts rename to packages/create-next-stack/src/main/plugins/mantine.ts index ecdcab3..fed1989 100644 --- a/packages/create-next-stack/src/main/plugins/mantine/mantine.ts +++ b/packages/create-next-stack/src/main/plugins/mantine.ts @@ -1,5 +1,5 @@ import endent from "endent" -import { Plugin } from "../../plugin" +import { Plugin } from "../plugin" export const mantinePlugin: Plugin = { id: "mantine", diff --git a/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts b/packages/create-next-stack/src/main/plugins/material-ui.ts similarity index 98% rename from packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts rename to packages/create-next-stack/src/main/plugins/material-ui.ts index 8d611bf..f6651a6 100644 --- a/packages/create-next-stack/src/main/plugins/material-ui/material-ui.ts +++ b/packages/create-next-stack/src/main/plugins/material-ui.ts @@ -1,5 +1,5 @@ import endent from "endent" -import { Plugin } from "../../plugin" +import { Plugin } from "../plugin" const materialTheme = endent` import { Roboto } from 'next/font/google'; diff --git a/packages/create-next-stack/src/main/plugins/sass/sass.ts b/packages/create-next-stack/src/main/plugins/sass.ts similarity index 94% rename from packages/create-next-stack/src/main/plugins/sass/sass.ts rename to packages/create-next-stack/src/main/plugins/sass.ts index 45e4212..bf36312 100644 --- a/packages/create-next-stack/src/main/plugins/sass/sass.ts +++ b/packages/create-next-stack/src/main/plugins/sass.ts @@ -1,6 +1,6 @@ import endent from "endent" -import { Plugin } from "../../plugin" -import { cssModuleTechnology } from "../css-modules/css-modules" +import { Plugin } from "../plugin" +import { cssModuleTechnology } from "./css-modules" const globalStyles = endent` * { diff --git a/packages/create-next-stack/src/main/setup/setup.ts b/packages/create-next-stack/src/main/setup/setup.ts index bbce289..9b526ce 100644 --- a/packages/create-next-stack/src/main/setup/setup.ts +++ b/packages/create-next-stack/src/main/setup/setup.ts @@ -6,17 +6,17 @@ import { inDebugMode } from "../helpers/in-debug-mode" import { time } from "../helpers/time" import { logDebug, logInfo } from "../logging" import { evalOptionalProperty, evalProperty, Plugin } from "../plugin" -import { chakraUIPlugin } from "../plugins/chakra-ui/chakra-ui" +import { chakraUIPlugin } from "../plugins/chakra-ui" import { createNextStackPlugin } from "../plugins/create-next-stack/create-next-stack" -import { cssModulesPlugin } from "../plugins/css-modules/css-modules" +import { cssModulesPlugin } from "../plugins/css-modules" import { emotionPlugin } from "../plugins/emotion" import { eslintPlugin } from "../plugins/eslint" import { formattingPreCommitHookPlugin } from "../plugins/formatting-pre-commit-hook" import { formikPlugin } from "../plugins/formik" import { framerMotionPlugin } from "../plugins/framer-motion" import { githubActionsPlugin } from "../plugins/github-actions" -import { mantinePlugin } from "../plugins/mantine/mantine" -import { materialUIPlugin } from "../plugins/material-ui/material-ui" +import { mantinePlugin } from "../plugins/mantine" +import { materialUIPlugin } from "../plugins/material-ui" import { netlifyPlugin } from "../plugins/netlify" import { nextPlugin } from "../plugins/next" import { npmPlugin } from "../plugins/npm" @@ -27,7 +27,7 @@ import { reactPlugin } from "../plugins/react" import { reactHookFormPlugin } from "../plugins/react-hook-form" import { reactIconsPlugin } from "../plugins/react-icons" import { reactQueryPlugin } from "../plugins/react-query" -import { sassPlugin } from "../plugins/sass/sass" +import { sassPlugin } from "../plugins/sass" import { styledComponentsPlugin } from "../plugins/styled-components" import { tailwindCSSPlugin } from "../plugins/tailwind-css" import { typescriptPlugin } from "../plugins/typescript" From 6ff755e4b58cac5fabb8efb719dc4b043341b4a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 22 Jun 2023 16:40:27 +0200 Subject: [PATCH 09/13] Add Prisma WIP --- packages/create-next-stack/README.md | 2 + .../src/main/commands/create-next-stack.ts | 5 ++ .../sort-orders/technologies.ts | 1 + .../src/main/plugins/prisma.ts | 89 +++++++++++++++++++ .../create-next-stack/src/main/setup/setup.ts | 2 + packages/create-next-stack/src/main/steps.ts | 2 + 6 files changed, 101 insertions(+) create mode 100644 packages/create-next-stack/src/main/plugins/prisma.ts diff --git a/packages/create-next-stack/README.md b/packages/create-next-stack/README.md index ff5a718..148c80d 100644 --- a/packages/create-next-stack/README.md +++ b/packages/create-next-stack/README.md @@ -64,6 +64,7 @@ The table below provides an overview of the technologies currently supported by | next-plausible | [Website](https://next-plausible.vercel.app/) - [GitHub](https://github.com/4lejandrito/next-plausible) | | Vercel | [Website](https://vercel.com/) - [Docs](https://vercel.com/docs) - [CLI Docs](https://vercel.com/docs/cli) | | Netlify | [Website](https://www.netlify.com/) - [Docs](https://docs.netlify.com/) - [CLI Docs](https://cli.netlify.com/) | +| Prisma | [Website](https://www.prisma.io/) - [Docs](https://www.prisma.io/docs) - [GitHub](https://github.com/prisma/prisma) | @@ -104,6 +105,7 @@ FLAGS --plausible Adds Plausible. (Analytics) --prettier Adds Prettier. (Code formatting) + --prisma Adds Prisma. (ORM) --react-hook-form Adds React Hook Form. (Form library) --react-icons Adds React Icons. (Icon library) --react-query Adds React Query. (Server state management diff --git a/packages/create-next-stack/src/main/commands/create-next-stack.ts b/packages/create-next-stack/src/main/commands/create-next-stack.ts index 5a0ae1c..6b6419a 100644 --- a/packages/create-next-stack/src/main/commands/create-next-stack.ts +++ b/packages/create-next-stack/src/main/commands/create-next-stack.ts @@ -112,6 +112,11 @@ export default class CreateNextStack extends Command { vercel: Flags.boolean({ description: "Adds Vercel. (Hosting)", }), + + // ORMs + prisma: Flags.boolean({ + description: "Adds Prisma. (ORM)", + }), } async run(): Promise { diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts index 8dfc4bf..05b11b2 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts @@ -34,6 +34,7 @@ export const technologiesSortOrder: string[] = [ "nextPlausible", "vercel", "netlify", + "prisma", ] export const getTechnologies = ( diff --git a/packages/create-next-stack/src/main/plugins/prisma.ts b/packages/create-next-stack/src/main/plugins/prisma.ts new file mode 100644 index 0000000..757bd80 --- /dev/null +++ b/packages/create-next-stack/src/main/plugins/prisma.ts @@ -0,0 +1,89 @@ +import endent from "endent" +import { runCommand } from "../helpers/run-command" +import { Plugin } from "../plugin" + +export const prismaPlugin: Plugin = { + id: "prisma", + name: "Prisma", + description: "Adds support for Prisma", + active: ({ flags }) => Boolean(flags["prisma"]), + dependencies: [{ name: "@prisma/client", version: "^4.16.0" }], + devDependencies: [{ name: "prisma", version: "^4.16.0" }], + technologies: [ + { + id: "prisma", + name: "Prisma", + description: + "Prisma is a next-generation ORM for Node.js. It is designed to simplify database access and declaratively define the schema for your database. Prisma replaces traditional ORMs and can be used to build GraphQL servers, REST APIs, microservices & more.", + links: [ + { title: "Website", url: "https://www.prisma.io/" }, + { title: "Docs", url: "https://www.prisma.io/docs" }, + { title: "GitHub", url: "https://github.com/prisma/prisma" }, + ], + }, + ], + steps: [ + { + id: "setUpPrisma", + description: "setting up Prisma", + run: async () => { + await runCommand("npx", ["prisma", "generate"]) + }, + }, + ], + addFiles: [ + { + destination: "prisma/schema.prisma", + content: endent` + generator client { + provider = "prisma-client-js" + } + + datasource db { + provider = "sqlite" + url = "file:./dev.db" + } + + model Todo { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + content String + } + `, + }, + { + destination: "prisma/seed.ts", + content: endent` + import { Prisma, PrismaClient } from "@prisma/client"; + + const prisma = new PrismaClient(); + + const todoCreateInputs: Prisma.TodoCreateInput[] = [ + { content: "This is a todo" }, + { content: "This is another todo" }, + ]; + + async function main() { + console.log(\`Start seeding ...\`); + for (const todoCreateInput of todoCreateInputs) { + const todo = await prisma.todo.create({ + data: todoCreateInput, + }); + console.log(\`Created todo with id: \${todo.id}\`); + } + console.log(\`Seeding finished.\`); + } + + main() + .then(async () => { + await prisma.$disconnect(); + }) + .catch(async (e) => { + console.error(e); + await prisma.$disconnect(); + process.exit(1); + }); + `, + }, + ], +} as const diff --git a/packages/create-next-stack/src/main/setup/setup.ts b/packages/create-next-stack/src/main/setup/setup.ts index 9b526ce..c704181 100644 --- a/packages/create-next-stack/src/main/setup/setup.ts +++ b/packages/create-next-stack/src/main/setup/setup.ts @@ -23,6 +23,7 @@ import { npmPlugin } from "../plugins/npm" import { plausiblePlugin } from "../plugins/plausible" import { pnpmPlugin } from "../plugins/pnpm" import { prettierPlugin } from "../plugins/prettier" +import { prismaPlugin } from "../plugins/prisma" import { reactPlugin } from "../plugins/react" import { reactHookFormPlugin } from "../plugins/react-hook-form" import { reactIconsPlugin } from "../plugins/react-icons" @@ -64,6 +65,7 @@ export const plugins: Plugin[] = [ plausiblePlugin, vercelPlugin, netlifyPlugin, + prismaPlugin, ] export const filterPlugins = (inputs: ValidCNSInputs): Plugin[] => diff --git a/packages/create-next-stack/src/main/steps.ts b/packages/create-next-stack/src/main/steps.ts index dac332f..c54e8bd 100644 --- a/packages/create-next-stack/src/main/steps.ts +++ b/packages/create-next-stack/src/main/steps.ts @@ -26,6 +26,8 @@ export const stepsOrder: string[] = [ "addContent", // Uninstall temporary dependencies "uninstallTemporaryDependencies", + // ORMs + "setUpPrisma", // Format & initial commit "formatProject", "initialCommit", From 39371f867c40b6c4896f54b4a449c8800131621e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 24 Jun 2023 16:31:30 +0200 Subject: [PATCH 10/13] Update contributing guide to match latest refactor --- CONTRIBUTING.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cfe7dd1..fbbc77d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -106,12 +106,12 @@ Make sure you are set up locally by following the [Getting Started](#getting-sta ## Writing a Plugin -Plugins aren't too scary. A Create Next Stack plugin consists of a simple TypeScript file that calls a `createPlugin()` function with JSON object. +Plugins aren't too scary. A Create Next Stack plugin consists of a simple TypeScript file that exports an object of type [`Plugin`](./packages/create-next-stack/src/main/plugin.ts). See the [Framer Motion plugin](packages/create-next-stack/src/main/plugins/framer-motion.ts) for example. This plugin adds the `framer-motion` npm dependency to the generated Next.js project, as well as adding some documentation about the technology. ```typescript -export const framerMotionPlugin = createPlugin({ +export const framerMotionPlugin: Plugin = { id: "framer-motion", name: "Framer Motion", description: "Adds support for Framer Motion", @@ -130,19 +130,20 @@ export const framerMotionPlugin = createPlugin({ ], }, ], -} as const) +} as const ``` -Below is a breakdown of the `createPlugin()` function's JSON object: +Below is a small breakdown of the properties of the above plugin object: +- The `id` property is a unique identifier for the plugin. - The `name` property is the name of the plugin. - The `description` property is a short description of the plugin. -- The `active` property is a function that returns a boolean indicating whether the plugin should be active. This function is passed the `flags` object, which contains all the flags passed to the `create-next-stack` command. -- The `dependencies` property is an object containing the npm dependencies that should be added to the generated Next.js project. The key and `name` property is the name of the dependency, and the `version` property is version of the dependency. -- The `technologies` property is an array of objects containing information about the technology. The `name` property is the name of the technology. The `description` property is a short description of the technology. The `links` property is an array of objects containing links to the technology's website, documentation, and GitHub repository. +- The `active` property is a function that returns a boolean indicating whether the plugin should be active. This function is passed the flags and arguments passed by users to the `create-next-stack` command. +- The `dependencies` property is an array of npm dependencies that should be added to the generated Next.js project. +- The `technologies` property is an array of objects containing documentation about the technologies supported by the plugin. -Some of these properties are optional, and some are required. Some properties are used by the CLI, some are used by the website, and some both. It's not too important to know everywhere these properties are used. As long as we specify as many properties as possible, the CLI and website is going to find out how to use it. +Some of these properties are optional, and some are required. Some properties are used by the CLI, some are used by the website, and some both. It's not too important to know exactly where these properties are used. As long as we specify all relevant properties, the CLI and website is going to find out how to use it. -For a complete list of properties that can be passed to the `createPlugin()` function, their explanations, and usage, see the [`Plugin` type definition](packages/create-next-stack/src/main/plugin.ts). You should find all the documentation you need there. If not, please [open an issue](https://github.com/akd-io/create-next-stack/issues/new). +For a complete list of properties of the `Plugin` type, their explanations, and usage, see the [`Plugin` type definition](packages/create-next-stack/src/main/plugin.ts). You should find all the documentation you need there. If not, please [open an issue](https://github.com/akd-io/create-next-stack/issues/new). For more examples, please take a look at the [existing plugins](packages/create-next-stack/src/main/plugins). From 122d9dcc887fe572ad204a98073489d58c0cfd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Sat, 24 Jun 2023 21:45:10 +0200 Subject: [PATCH 11/13] Add Prisma to website --- .../components/TechnologiesForm.tsx | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx index 1921eae..be6dabf 100644 --- a/apps/website/templates/LandingPage/components/TechnologiesForm.tsx +++ b/apps/website/templates/LandingPage/components/TechnologiesForm.tsx @@ -47,6 +47,7 @@ type OptionKey = | "plausible" | "vercel" | "netlify" + | "prisma" const options = { pnpm: { key: "pnpm", value: "pnpm", label: "pnpm" }, @@ -124,6 +125,11 @@ const options = { value: "netlify", label: "Netlify", }, + prisma: { + key: "prisma", + value: "prisma", + label: "Prisma", + }, } satisfies { [Key in OptionKey]: { key: Key @@ -173,6 +179,7 @@ const deploymentOptionKeys = [ optionKeys.vercel, optionKeys.netlify, ] satisfies OptionKey[] +const ormOptionKeys = [optionKeys.prisma] satisfies OptionKey[] type ProjectName = string type PackageManager = (typeof packageManagerOptionKeys)[number] @@ -187,6 +194,7 @@ type ServerStateManagementLibrary = (typeof serverStateManagementLibraryOptionKeys)[number] type Analytics = (typeof analyticsOptionKeys)[number] type Deployment = (typeof deploymentOptionKeys)[number] +type ORM = (typeof ormOptionKeys)[number] type TechnologiesFormData = { projectName: ProjectName @@ -201,6 +209,7 @@ type TechnologiesFormData = { serverStateManagementLibraries: ServerStateManagementLibrary[] analytics: Analytics[] deployment: Deployment[] + orm: ORM[] } const defaultFormData: TechnologiesFormData = { projectName: "my-app", @@ -215,6 +224,7 @@ const defaultFormData: TechnologiesFormData = { serverStateManagementLibraries: [optionKeys.reactQuery], analytics: [], deployment: [optionKeys.vercel], + orm: [], } const formDataKeys = objectToKeyToKeyMap(defaultFormData) @@ -233,6 +243,7 @@ const categoryLabels = { serverStateManagementLibraries: "Server State Management", analytics: "Analytics", deployment: "Deployment", + orm: "ORMs", } as const export const TechnologiesForm: React.FC = () => { @@ -271,6 +282,7 @@ export const TechnologiesForm: React.FC = () => { pushArgs(formData.serverStateManagementLibraries) pushArgs(formData.analytics) pushArgs(formData.deployment) + pushArgs(formData.orm) const projectNameSegments = formData.projectName.split("/") const lastPartOfProjectName = projectNameSegments.pop()! @@ -293,7 +305,8 @@ export const TechnologiesForm: React.FC = () => { | "continuousIntegration" | "serverStateManagementLibraries" | "analytics" - | "deployment", + | "deployment" + | "orm", optionKeys: Array, validators?: { [key in keyof typeof options]?: Array<{ @@ -455,6 +468,13 @@ export const TechnologiesForm: React.FC = () => { analyticsOptionKeys )} + + + + {categoryLabels.orm} + + {CheckboxesOfOptionKeys(formDataKeys.orm, ormOptionKeys)} + From 9f332cc5d1806e7aedaa8b42a6688a9c8c2b0b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Wed, 5 Jul 2023 17:55:24 +0200 Subject: [PATCH 12/13] Remove DeeplyReadonly type and usage --- .../src/main/helpers/deeply-readonly.ts | 11 ----------- packages/create-next-stack/src/main/plugin.ts | 5 ++--- .../create-next-stack/src/main/plugins/chakra-ui.ts | 2 +- .../templates/LandingPage/generate-technologies.ts | 5 ++--- .../add-readme/generate-technology-table-rows.ts | 3 +-- .../plugins/create-next-stack/create-next-stack.ts | 2 +- .../create-next-stack/sort-orders/technologies.ts | 7 ++----- .../create-next-stack/src/main/plugins/css-modules.ts | 2 +- .../create-next-stack/src/main/plugins/emotion.ts | 2 +- packages/create-next-stack/src/main/plugins/eslint.ts | 2 +- .../src/main/plugins/formatting-pre-commit-hook.ts | 2 +- packages/create-next-stack/src/main/plugins/formik.ts | 2 +- .../src/main/plugins/framer-motion.ts | 2 +- .../src/main/plugins/github-actions.ts | 2 +- .../create-next-stack/src/main/plugins/mantine.ts | 2 +- .../create-next-stack/src/main/plugins/material-ui.ts | 2 +- .../create-next-stack/src/main/plugins/netlify.ts | 2 +- packages/create-next-stack/src/main/plugins/next.ts | 2 +- packages/create-next-stack/src/main/plugins/npm.ts | 2 +- .../create-next-stack/src/main/plugins/plausible.ts | 2 +- packages/create-next-stack/src/main/plugins/pnpm.ts | 2 +- .../create-next-stack/src/main/plugins/prettier.ts | 2 +- packages/create-next-stack/src/main/plugins/prisma.ts | 2 +- .../src/main/plugins/react-hook-form.ts | 2 +- .../create-next-stack/src/main/plugins/react-icons.ts | 2 +- .../create-next-stack/src/main/plugins/react-query.ts | 2 +- packages/create-next-stack/src/main/plugins/react.ts | 2 +- packages/create-next-stack/src/main/plugins/sass.ts | 2 +- .../src/main/plugins/styled-components.ts | 2 +- .../src/main/plugins/tailwind-css.ts | 2 +- .../create-next-stack/src/main/plugins/typescript.ts | 2 +- packages/create-next-stack/src/main/plugins/vercel.ts | 2 +- packages/create-next-stack/src/main/plugins/yarn.ts | 2 +- 33 files changed, 35 insertions(+), 52 deletions(-) delete mode 100644 packages/create-next-stack/src/main/helpers/deeply-readonly.ts diff --git a/packages/create-next-stack/src/main/helpers/deeply-readonly.ts b/packages/create-next-stack/src/main/helpers/deeply-readonly.ts deleted file mode 100644 index bed2015..0000000 --- a/packages/create-next-stack/src/main/helpers/deeply-readonly.ts +++ /dev/null @@ -1,11 +0,0 @@ -export type DeeplyReadonly = T extends unknown[] - ? DeeplyReadonlyArray - : T extends Record - ? DeeplyReadonlyObject - : T - -export type DeeplyReadonlyArray = ReadonlyArray> - -export type DeeplyReadonlyObject = { - readonly [P in keyof T]: DeeplyReadonly -} diff --git a/packages/create-next-stack/src/main/plugin.ts b/packages/create-next-stack/src/main/plugin.ts index ea9cc91..bdf6f7a 100644 --- a/packages/create-next-stack/src/main/plugin.ts +++ b/packages/create-next-stack/src/main/plugin.ts @@ -1,8 +1,7 @@ import { NextConfig } from "next" import { ValidCNSInputs } from "./create-next-stack-types" -import { DeeplyReadonly } from "./helpers/deeply-readonly" -export type Plugin = DeeplyReadonly<{ +export type Plugin = { /** ID that uniquely identifies the plugin */ id: string /** Name of the plugin */ @@ -164,7 +163,7 @@ export type Plugin = DeeplyReadonly<{ wrappersEnd?: string } } -}> +} export type Package = { /** Name of the package. */ diff --git a/packages/create-next-stack/src/main/plugins/chakra-ui.ts b/packages/create-next-stack/src/main/plugins/chakra-ui.ts index 3e7cc4c..3f5fc0d 100644 --- a/packages/create-next-stack/src/main/plugins/chakra-ui.ts +++ b/packages/create-next-stack/src/main/plugins/chakra-ui.ts @@ -59,4 +59,4 @@ export const chakraUIPlugin: Plugin = { `, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-technologies.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-technologies.ts index 454f4a8..787804f 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-technologies.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-technologies.ts @@ -1,18 +1,17 @@ import endent from "endent" import { ValidCNSInputs } from "../../../../../create-next-stack-types" -import { DeeplyReadonly } from "../../../../../helpers/deeply-readonly" import { stringify } from "../../../../../helpers/stringify" import { getTechnologies } from "../../../sort-orders/technologies" // This type should match the one in the template below. -export type Technology = DeeplyReadonly<{ +export type Technology = { name: string description: string links: Array<{ title: string url: string }> -}> +} export const generateTechnologies = (inputs: ValidCNSInputs): string => { const technologies: Technology[] = getTechnologies(inputs) diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-technology-table-rows.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-technology-table-rows.ts index d835367..d9abe93 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-technology-table-rows.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-technology-table-rows.ts @@ -1,8 +1,7 @@ -import { DeeplyReadonly } from "../../../helpers/deeply-readonly" import { Technology } from "../../../plugin" export const generateTechnologyTableRows = async ( - technologies: Array, "id">> + technologies: Array> ): Promise => { if (technologies.length === 0) { return null diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts index c9193f2..6a99959 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts @@ -215,4 +215,4 @@ export const createNextStackPlugin: Plugin = { }, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts index 05b11b2..650c11d 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts @@ -1,5 +1,4 @@ import { ValidCNSInputs } from "../../../create-next-stack-types" -import { DeeplyReadonly } from "../../../helpers/deeply-readonly" import { nonNull } from "../../../helpers/non-null" import { compareByOrder } from "../../../helpers/sort-by-order" import { Technology } from "../../../plugin" @@ -39,7 +38,7 @@ export const technologiesSortOrder: string[] = [ export const getTechnologies = ( inputs: ValidCNSInputs -): Array, "id">> => { +): Array> => { return filterPlugins(inputs) .flatMap((plugin) => plugin.technologies) .filter(nonNull) @@ -49,9 +48,7 @@ export const getTechnologies = ( })) } -export const getAllTechnologies = (): Array< - Omit, "id"> -> => { +export const getAllTechnologies = (): Array> => { return plugins .flatMap((plugin) => plugin.technologies ?? []) .sort((a, b) => compareByOrder(a.id, b.id, technologiesSortOrder)) diff --git a/packages/create-next-stack/src/main/plugins/css-modules.ts b/packages/create-next-stack/src/main/plugins/css-modules.ts index 4fe61f0..fa97a5e 100644 --- a/packages/create-next-stack/src/main/plugins/css-modules.ts +++ b/packages/create-next-stack/src/main/plugins/css-modules.ts @@ -59,4 +59,4 @@ export const cssModulesPlugin: Plugin = { content: globalStyles, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/emotion.ts b/packages/create-next-stack/src/main/plugins/emotion.ts index 4154465..b146bfc 100644 --- a/packages/create-next-stack/src/main/plugins/emotion.ts +++ b/packages/create-next-stack/src/main/plugins/emotion.ts @@ -50,4 +50,4 @@ export const emotionPlugin: Plugin = { }, }, }, -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/eslint.ts b/packages/create-next-stack/src/main/plugins/eslint.ts index 579c858..6b37500 100644 --- a/packages/create-next-stack/src/main/plugins/eslint.ts +++ b/packages/create-next-stack/src/main/plugins/eslint.ts @@ -22,4 +22,4 @@ export const eslintPlugin: Plugin = { ], }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts b/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts index 93571f4..b8bb5b0 100644 --- a/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts +++ b/packages/create-next-stack/src/main/plugins/formatting-pre-commit-hook.ts @@ -76,4 +76,4 @@ export const formattingPreCommitHookPlugin: Plugin = { }, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/formik.ts b/packages/create-next-stack/src/main/plugins/formik.ts index e27bdce..affb36a 100644 --- a/packages/create-next-stack/src/main/plugins/formik.ts +++ b/packages/create-next-stack/src/main/plugins/formik.ts @@ -19,4 +19,4 @@ export const formikPlugin: Plugin = { ], }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/framer-motion.ts b/packages/create-next-stack/src/main/plugins/framer-motion.ts index 914c06f..fdf3069 100644 --- a/packages/create-next-stack/src/main/plugins/framer-motion.ts +++ b/packages/create-next-stack/src/main/plugins/framer-motion.ts @@ -19,4 +19,4 @@ export const framerMotionPlugin: Plugin = { ], }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/github-actions.ts b/packages/create-next-stack/src/main/plugins/github-actions.ts index 25e1ee2..fb2371d 100644 --- a/packages/create-next-stack/src/main/plugins/github-actions.ts +++ b/packages/create-next-stack/src/main/plugins/github-actions.ts @@ -42,7 +42,7 @@ export const githubActionsPlugin: Plugin = { content: (inputs) => generateCiYml(inputs), }, ], -} as const +} const generateCiYml = async (inputs: ValidCNSInputs): Promise => { const { flags } = inputs diff --git a/packages/create-next-stack/src/main/plugins/mantine.ts b/packages/create-next-stack/src/main/plugins/mantine.ts index fed1989..244dc1e 100644 --- a/packages/create-next-stack/src/main/plugins/mantine.ts +++ b/packages/create-next-stack/src/main/plugins/mantine.ts @@ -66,4 +66,4 @@ export const mantinePlugin: Plugin = { `, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/material-ui.ts b/packages/create-next-stack/src/main/plugins/material-ui.ts index f6651a6..d8ae15a 100644 --- a/packages/create-next-stack/src/main/plugins/material-ui.ts +++ b/packages/create-next-stack/src/main/plugins/material-ui.ts @@ -79,4 +79,4 @@ export const materialUIPlugin: Plugin = { content: materialTheme, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/netlify.ts b/packages/create-next-stack/src/main/plugins/netlify.ts index ce06899..bb43cdf 100644 --- a/packages/create-next-stack/src/main/plugins/netlify.ts +++ b/packages/create-next-stack/src/main/plugins/netlify.ts @@ -29,4 +29,4 @@ export const netlifyPlugin: Plugin = { todos: [ "Integrate Netlify with your repository host for continuous deployments at https://app.netlify.com/start. The Netlify CLI, mainly used for preview deployments, won't auto-detect Next.js until you do.", ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/next.ts b/packages/create-next-stack/src/main/plugins/next.ts index 4c5ac05..7372502 100644 --- a/packages/create-next-stack/src/main/plugins/next.ts +++ b/packages/create-next-stack/src/main/plugins/next.ts @@ -144,4 +144,4 @@ export const nextPlugin: Plugin = { }, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/npm.ts b/packages/create-next-stack/src/main/plugins/npm.ts index 432b7e0..bde4201 100644 --- a/packages/create-next-stack/src/main/plugins/npm.ts +++ b/packages/create-next-stack/src/main/plugins/npm.ts @@ -18,4 +18,4 @@ export const npmPlugin: Plugin = { ], }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/plausible.ts b/packages/create-next-stack/src/main/plugins/plausible.ts index 8315156..39894b9 100644 --- a/packages/create-next-stack/src/main/plugins/plausible.ts +++ b/packages/create-next-stack/src/main/plugins/plausible.ts @@ -72,4 +72,4 @@ export const plausiblePlugin: Plugin = { `Set up an account in Plausible Analytics, and add your website in their dashboard.`, `Update the \`${websiteDomainEnvVar}\` environment variable to your website's domain to connect Plausible Analytics to your app.`, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/pnpm.ts b/packages/create-next-stack/src/main/plugins/pnpm.ts index 8b92573..ffa67ea 100644 --- a/packages/create-next-stack/src/main/plugins/pnpm.ts +++ b/packages/create-next-stack/src/main/plugins/pnpm.ts @@ -33,4 +33,4 @@ export const pnpmPlugin: Plugin = { }, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/prettier.ts b/packages/create-next-stack/src/main/plugins/prettier.ts index 333e27c..1438d5e 100644 --- a/packages/create-next-stack/src/main/plugins/prettier.ts +++ b/packages/create-next-stack/src/main/plugins/prettier.ts @@ -63,4 +63,4 @@ export const prettierPlugin: Plugin = { }, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/prisma.ts b/packages/create-next-stack/src/main/plugins/prisma.ts index 757bd80..38f26c7 100644 --- a/packages/create-next-stack/src/main/plugins/prisma.ts +++ b/packages/create-next-stack/src/main/plugins/prisma.ts @@ -86,4 +86,4 @@ export const prismaPlugin: Plugin = { `, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/react-hook-form.ts b/packages/create-next-stack/src/main/plugins/react-hook-form.ts index 349ff75..4accf0f 100644 --- a/packages/create-next-stack/src/main/plugins/react-hook-form.ts +++ b/packages/create-next-stack/src/main/plugins/react-hook-form.ts @@ -22,4 +22,4 @@ export const reactHookFormPlugin: Plugin = { ], }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/react-icons.ts b/packages/create-next-stack/src/main/plugins/react-icons.ts index fed1c0e..81cb5da 100644 --- a/packages/create-next-stack/src/main/plugins/react-icons.ts +++ b/packages/create-next-stack/src/main/plugins/react-icons.ts @@ -18,4 +18,4 @@ export const reactIconsPlugin: Plugin = { ], }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/react-query.ts b/packages/create-next-stack/src/main/plugins/react-query.ts index 7b14448..1a89852 100644 --- a/packages/create-next-stack/src/main/plugins/react-query.ts +++ b/packages/create-next-stack/src/main/plugins/react-query.ts @@ -48,4 +48,4 @@ export const reactQueryPlugin: Plugin = { `, }, }, -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/react.ts b/packages/create-next-stack/src/main/plugins/react.ts index 7696ba4..cb10cea 100644 --- a/packages/create-next-stack/src/main/plugins/react.ts +++ b/packages/create-next-stack/src/main/plugins/react.ts @@ -22,4 +22,4 @@ export const reactPlugin: Plugin = { ], }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/sass.ts b/packages/create-next-stack/src/main/plugins/sass.ts index bf36312..f6ba57a 100644 --- a/packages/create-next-stack/src/main/plugins/sass.ts +++ b/packages/create-next-stack/src/main/plugins/sass.ts @@ -62,4 +62,4 @@ export const sassPlugin: Plugin = { content: globalStyles, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/styled-components.ts b/packages/create-next-stack/src/main/plugins/styled-components.ts index f56b066..65e76f9 100644 --- a/packages/create-next-stack/src/main/plugins/styled-components.ts +++ b/packages/create-next-stack/src/main/plugins/styled-components.ts @@ -32,4 +32,4 @@ export const styledComponentsPlugin: Plugin = { }, }, }, -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/tailwind-css.ts b/packages/create-next-stack/src/main/plugins/tailwind-css.ts index 048def7..8257d91 100644 --- a/packages/create-next-stack/src/main/plugins/tailwind-css.ts +++ b/packages/create-next-stack/src/main/plugins/tailwind-css.ts @@ -78,4 +78,4 @@ export const tailwindCSSPlugin: Plugin = { `, }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/typescript.ts b/packages/create-next-stack/src/main/plugins/typescript.ts index 363a259..96e5569 100644 --- a/packages/create-next-stack/src/main/plugins/typescript.ts +++ b/packages/create-next-stack/src/main/plugins/typescript.ts @@ -19,4 +19,4 @@ export const typescriptPlugin: Plugin = { ], }, ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/vercel.ts b/packages/create-next-stack/src/main/plugins/vercel.ts index fad4789..9b16f6e 100644 --- a/packages/create-next-stack/src/main/plugins/vercel.ts +++ b/packages/create-next-stack/src/main/plugins/vercel.ts @@ -29,4 +29,4 @@ export const vercelPlugin: Plugin = { todos: [ "Integrate Vercel with your repository host for continuous deployments at https://vercel.com/new", ], -} as const +} diff --git a/packages/create-next-stack/src/main/plugins/yarn.ts b/packages/create-next-stack/src/main/plugins/yarn.ts index bffbd56..f2309e2 100644 --- a/packages/create-next-stack/src/main/plugins/yarn.ts +++ b/packages/create-next-stack/src/main/plugins/yarn.ts @@ -33,4 +33,4 @@ export const yarnPlugin: Plugin = { }, }, ], -} as const +} From baba53fca03cf182e035b9f2c9c59b44a4a27d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Kj=C3=A6r=20Damgaard?= Date: Thu, 6 Jul 2023 13:38:55 +0200 Subject: [PATCH 13/13] Fix plugin filtering --- .../src/main/helpers/filterAsync.ts | 7 ++++ .../add-content/generate-env.ts | 4 +-- .../add-content/pages/generate-app.ts | 12 +++---- .../add-content/pages/generate-document.ts | 18 +++++----- .../generate-LandingPageTemplate.ts | 6 ++-- .../LandingPage/generate-technologies.ts | 6 ++-- .../add-next-config/generate-next-config.ts | 12 ++++--- .../generate-env-table-rows copy.ts | 2 +- .../add-readme/generate-readme.ts | 4 +-- .../add-readme/generate-script-table-rows.ts | 2 +- .../create-next-stack/create-next-stack.ts | 33 ++++++++++--------- .../sort-orders/environment-variables.ts | 4 +-- .../create-next-stack/sort-orders/scripts.ts | 4 +-- .../sort-orders/technologies.ts | 6 ++-- .../create-next-stack/src/main/setup/setup.ts | 13 ++++++-- packages/create-next-stack/src/main/steps.ts | 4 +-- 16 files changed, 81 insertions(+), 56 deletions(-) create mode 100644 packages/create-next-stack/src/main/helpers/filterAsync.ts diff --git a/packages/create-next-stack/src/main/helpers/filterAsync.ts b/packages/create-next-stack/src/main/helpers/filterAsync.ts new file mode 100644 index 0000000..4e30de2 --- /dev/null +++ b/packages/create-next-stack/src/main/helpers/filterAsync.ts @@ -0,0 +1,7 @@ +export const filterAsync = async ( + array: T[], + predicate: (item: T) => Promise +): Promise => { + const verdicts = await Promise.all(array.map(predicate)) + return array.filter((_, index) => verdicts[index]) +} diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/generate-env.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/generate-env.ts index a25b5d4..a926285 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/generate-env.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/generate-env.ts @@ -2,8 +2,8 @@ import endent from "endent" import { ValidCNSInputs } from "../../../create-next-stack-types" import { getEnvironmentVariables } from "../sort-orders/environment-variables" -export const generateEnv = (inputs: ValidCNSInputs): string => { - const environmentVariables = getEnvironmentVariables(inputs) +export const generateEnv = async (inputs: ValidCNSInputs): Promise => { + const environmentVariables = (await getEnvironmentVariables(inputs)) .map((environmentVariable) => { const { name, description, defaultValue } = environmentVariable diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/pages/generate-app.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/pages/generate-app.ts index 5d2e0b2..d8da670 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/pages/generate-app.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/pages/generate-app.ts @@ -3,28 +3,28 @@ import { ValidCNSInputs } from "../../../../create-next-stack-types" import { nonNull } from "../../../../helpers/non-null" import { filterPlugins } from "../../../../setup/setup" -export const generateApp = (inputs: ValidCNSInputs): string => { - const imports = filterPlugins(inputs) +export const generateApp = async (inputs: ValidCNSInputs): Promise => { + const imports = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.app?.imports) .filter(nonNull) .join("\n") - const postImports = filterPlugins(inputs) + const postImports = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.app?.postImports) .filter(nonNull) .join("\n") - const logic = filterPlugins(inputs) + const logic = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.app?.logic) .filter(nonNull) .join("\n\n") // Double new line to separate plugin logic - const componentsStart = filterPlugins(inputs) + const componentsStart = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.app?.componentsStart) .filter(nonNull) .join("\n") - const componentsEnd = filterPlugins(inputs) + const componentsEnd = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.app?.componentsEnd) .filter(nonNull) .reverse() diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/pages/generate-document.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/pages/generate-document.ts index 531d224..f69e867 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/pages/generate-document.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/pages/generate-document.ts @@ -3,32 +3,34 @@ import type { ValidCNSInputs } from "../../../../create-next-stack-types" import { nonNull } from "../../../../helpers/non-null" import { filterPlugins } from "../../../../setup/setup" -export const generateDocument = (inputs: ValidCNSInputs): string => { - const imports = filterPlugins(inputs) +export const generateDocument = async ( + inputs: ValidCNSInputs +): Promise => { + const imports = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.document?.imports) .filter(nonNull) .join("\n") - const afterImports = filterPlugins(inputs) + const afterImports = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.document?.afterImports) .filter(nonNull) .join("\n") - const classMembers = filterPlugins(inputs) + const classMembers = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.document?.classMembers) .filter(nonNull) .join("\n") - const renderLogic = filterPlugins(inputs) + const renderLogic = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.document?.renderLogic) .filter(nonNull) .join("\n") - const htmlAttributes = filterPlugins(inputs) + const htmlAttributes = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.document?.htmlAttributes) .filter(nonNull) .join(" ") - const headTags = filterPlugins(inputs) + const headTags = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.document?.headTags) .filter(nonNull) .join("\n") - const body = filterPlugins(inputs) + const body = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.document?.body) .filter(nonNull) .join("\n") diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-LandingPageTemplate.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-LandingPageTemplate.ts index 072afb5..9f0137e 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-LandingPageTemplate.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-LandingPageTemplate.ts @@ -4,8 +4,10 @@ import { getProjectNameOfPath } from "../../../../../helpers/get-project-name-of import { nonNull } from "../../../../../helpers/non-null" import { filterPlugins } from "../../../../../setup/setup" -export const generateLandingPageTemplate = (inputs: ValidCNSInputs): string => { - const todos = filterPlugins(inputs) +export const generateLandingPageTemplate = async ( + inputs: ValidCNSInputs +): Promise => { + const todos = (await filterPlugins(inputs)) .flatMap((plugin) => plugin.todos) .filter(nonNull) const hasTodos = todos.length > 0 diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-technologies.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-technologies.ts index 787804f..6e920ba 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-technologies.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-content/templates/LandingPage/generate-technologies.ts @@ -13,8 +13,10 @@ export type Technology = { }> } -export const generateTechnologies = (inputs: ValidCNSInputs): string => { - const technologies: Technology[] = getTechnologies(inputs) +export const generateTechnologies = async ( + inputs: ValidCNSInputs +): Promise => { + const technologies: Technology[] = await getTechnologies(inputs) return endent` export type Technology = { diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-next-config/generate-next-config.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-next-config/generate-next-config.ts index c334198..86ed6df 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-next-config/generate-next-config.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-next-config/generate-next-config.ts @@ -6,25 +6,27 @@ import { nonNull } from "../../../helpers/non-null" import { stringify } from "../../../helpers/stringify" import { filterPlugins } from "../../../setup/setup" -export const generateNextConfig = (inputs: ValidCNSInputs): string => { +export const generateNextConfig = async ( + inputs: ValidCNSInputs +): Promise => { const defaultNextConfig: NextConfig = { reactStrictMode: true, } - const nextConfigs = filterPlugins(inputs) + const nextConfigs = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.nextConfigJs?.nextConfig) .filter(nonNull) const mergedNextConfig = merge(defaultNextConfig, ...nextConfigs) - const imports = filterPlugins(inputs) + const imports = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.nextConfigJs?.imports) .filter(nonNull) .join("\n") - const wrappersStart = filterPlugins(inputs) + const wrappersStart = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.nextConfigJs?.wrappersStart) .filter(nonNull) - const wrappersEnd = filterPlugins(inputs) + const wrappersEnd = (await filterPlugins(inputs)) .map((plugin) => plugin.slots?.nextConfigJs?.wrappersEnd) .filter(nonNull) .reverse() diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-env-table-rows copy.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-env-table-rows copy.ts index 33e54d0..a094da5 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-env-table-rows copy.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-env-table-rows copy.ts @@ -4,7 +4,7 @@ import { getEnvironmentVariables } from "../sort-orders/environment-variables" export const generateEnvironmentVariableTableRows = async ( inputs: ValidCNSInputs ): Promise => { - const environmentVariables = getEnvironmentVariables(inputs) + const environmentVariables = await getEnvironmentVariables(inputs) if (environmentVariables.length === 0) { return null } diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-readme.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-readme.ts index 0484e5c..a059c1d 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-readme.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-readme.ts @@ -14,13 +14,13 @@ export const generateReadme = async ( ): Promise => { const { args, flags } = inputs - const todos = filterPlugins(inputs) + const todos = (await filterPlugins(inputs)) .flatMap((plugin) => plugin.todos) .filter(nonNull) const runCommand = runCommandMap[flags["package-manager"]] - const technologies = getTechnologies(inputs) + const technologies = await getTechnologies(inputs) const scriptTableRows = await generateScriptTableRows(inputs) const environmentVariableTableRows = diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-script-table-rows.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-script-table-rows.ts index 7af958a..9183e44 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-script-table-rows.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/add-readme/generate-script-table-rows.ts @@ -4,7 +4,7 @@ import { getScripts } from "../sort-orders/scripts" export const generateScriptTableRows = async ( inputs: ValidCNSInputs ): Promise => { - const scripts = getScripts(inputs) + const scripts = await getScripts(inputs) if (scripts.length === 0) { return null } diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts index 6a99959..9ed761c 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/create-next-stack.ts @@ -33,7 +33,8 @@ export const createNextStackPlugin: Plugin = { addFiles: [ { destination: ".env", - condition: (inputs) => getEnvironmentVariables(inputs).length > 0, + condition: async (inputs) => + (await getEnvironmentVariables(inputs)).length > 0, content: (inputs) => generateEnv(inputs), }, { @@ -70,7 +71,7 @@ export const createNextStackPlugin: Plugin = { id: "addScripts", description: "adding scripts to package.json", run: async (inputs) => { - const scripts = getScripts(inputs) + const scripts = await getScripts(inputs) await modifyJsonFile("package.json", (packageJson) => ({ ...packageJson, @@ -101,7 +102,7 @@ export const createNextStackPlugin: Plugin = { id: "addContent", description: "adding content", run: async (inputs) => { - const pluginFilesToWrite = filterPlugins(inputs) + const pluginFilesToWrite = (await filterPlugins(inputs)) .flatMap((plugin) => plugin.addFiles) .filter(nonNull) @@ -139,18 +140,20 @@ export const createNextStackPlugin: Plugin = { run: async (inputs) => { const { flags } = inputs - const depsAndTmpDeps = filterPlugins(inputs).flatMap((plugin) => { - return [ - ...(plugin.dependencies != null - ? Object.values(plugin.dependencies) - : []), - ...(plugin.tmpDependencies != null - ? Object.values(plugin.tmpDependencies) - : []), - ] - }) + const depsAndTmpDeps = (await filterPlugins(inputs)).flatMap( + (plugin) => { + return [ + ...(plugin.dependencies != null + ? Object.values(plugin.dependencies) + : []), + ...(plugin.tmpDependencies != null + ? Object.values(plugin.tmpDependencies) + : []), + ] + } + ) - const devDeps = filterPlugins(inputs).flatMap((plugin) => + const devDeps = (await filterPlugins(inputs)).flatMap((plugin) => plugin.devDependencies != null ? Object.values(plugin.devDependencies) : [] @@ -168,7 +171,7 @@ export const createNextStackPlugin: Plugin = { id: "uninstallTemporaryDependencies", description: "uninstalling temporary dependencies", run: async (inputs) => { - const tmpDeps = filterPlugins(inputs).flatMap((plugin) => + const tmpDeps = (await filterPlugins(inputs)).flatMap((plugin) => plugin.tmpDependencies != null ? Object.values(plugin.tmpDependencies) : [] diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.ts index f7bb5fc..ee010a3 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/environment-variables.ts @@ -7,8 +7,8 @@ export const environmentVariablesSortOrder: string[] = [ "NEXT_PUBLIC_WEBSITE_DOMAIN", ] -export const getEnvironmentVariables = (inputs: ValidCNSInputs) => { - const pluginEnvironmentVariables = filterPlugins(inputs) +export const getEnvironmentVariables = async (inputs: ValidCNSInputs) => { + const pluginEnvironmentVariables = (await filterPlugins(inputs)) .flatMap((plugin) => plugin.environmentVariables) .filter(nonNull) return pluginEnvironmentVariables.sort((a, b) => diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.ts index 6f08fa1..346c1b6 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/scripts.ts @@ -16,8 +16,8 @@ export const scriptsSortOrder: string[] = [ "deploy:netlify", ] -export const getScripts = (inputs: ValidCNSInputs) => { - const pluginScripts = filterPlugins(inputs) +export const getScripts = async (inputs: ValidCNSInputs) => { + const pluginScripts = (await filterPlugins(inputs)) .flatMap((plugin) => plugin.scripts) .filter(nonNull) return pluginScripts.sort((a, b) => diff --git a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts index 650c11d..bd3a34f 100644 --- a/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts +++ b/packages/create-next-stack/src/main/plugins/create-next-stack/sort-orders/technologies.ts @@ -36,10 +36,10 @@ export const technologiesSortOrder: string[] = [ "prisma", ] -export const getTechnologies = ( +export const getTechnologies = async ( inputs: ValidCNSInputs -): Array> => { - return filterPlugins(inputs) +): Promise>> => { + return (await filterPlugins(inputs)) .flatMap((plugin) => plugin.technologies) .filter(nonNull) .sort((a, b) => compareByOrder(a.id, b.id, technologiesSortOrder)) diff --git a/packages/create-next-stack/src/main/setup/setup.ts b/packages/create-next-stack/src/main/setup/setup.ts index c704181..0292102 100644 --- a/packages/create-next-stack/src/main/setup/setup.ts +++ b/packages/create-next-stack/src/main/setup/setup.ts @@ -2,6 +2,7 @@ import chalk from "chalk" import { ValidCNSInputs } from "../create-next-stack-types" import { capitalizeFirstLetter } from "../helpers/capitalize-first-letter" import { getDiffString } from "../helpers/diff-string" +import { filterAsync } from "../helpers/filterAsync" import { inDebugMode } from "../helpers/in-debug-mode" import { time } from "../helpers/time" import { logDebug, logInfo } from "../logging" @@ -68,13 +69,19 @@ export const plugins: Plugin[] = [ prismaPlugin, ] -export const filterPlugins = (inputs: ValidCNSInputs): Plugin[] => - plugins.filter(async (plugin) => await evalProperty(plugin.active, inputs)) +export const filterPlugins = async ( + inputs: ValidCNSInputs +): Promise => { + return await filterAsync( + plugins, + async (plugin) => await evalProperty(plugin.active, inputs) + ) +} export const performSetupSteps = async ( inputs: ValidCNSInputs ): Promise => { - const steps = getSteps(inputs) + const steps = await getSteps(inputs) const allStepsDiff = await time(async () => { for (const step of steps) { diff --git a/packages/create-next-stack/src/main/steps.ts b/packages/create-next-stack/src/main/steps.ts index c54e8bd..d853ade 100644 --- a/packages/create-next-stack/src/main/steps.ts +++ b/packages/create-next-stack/src/main/steps.ts @@ -33,8 +33,8 @@ export const stepsOrder: string[] = [ "initialCommit", ] -export const getSteps = (inputs: ValidCNSInputs): Step[] => { - return filterPlugins(inputs) +export const getSteps = async (inputs: ValidCNSInputs): Promise => { + return (await filterPlugins(inputs)) .flatMap((plugin) => plugin.steps) .filter(nonNull) .sort((a, b) => compareByOrder(a.id, b.id, stepsOrder))