From b97c2a8c626999faba70afeaa484431c8b063ddb Mon Sep 17 00:00:00 2001 From: Markus Blomqvist Date: Tue, 9 Jan 2024 23:17:54 +0200 Subject: [PATCH] Bundle to both ESM and CJS (#118) This adds `tsup` as a dev dependency to bundle for both ESM and CJS targets. This also adds full CI/CD automation for easier publish process and changelog managment using `@changesets/cli`. --- .github/workflows/ci.yml | 12 +- .github/workflows/publish.yml | 38 + .npmrc | 1 + CHANGELOG.md | 491 +- apps/example/.eslintrc.js | 5 - apps/example/.eslintrc.json | 6 + apps/example/.gitignore | 36 + apps/example/next.config.js | 7 +- apps/example/package.json | 10 +- apps/example/postcss.config.js | 6 + apps/example/src/actions.ts | 2 +- .../src/app/api/v2/rpc/[operationId]/route.ts | 2 +- apps/example/src/app/api/v2/todos/route.ts | 2 +- apps/example/src/app/client/ClientExample.tsx | 4 +- apps/example/src/app/client/page.tsx | 8 +- apps/example/src/app/components/Footer.tsx | 7 +- apps/example/src/app/components/Navbar.tsx | 6 +- apps/example/src/app/globals.css | 3 + apps/example/src/app/layout.tsx | 5 +- apps/example/src/app/page.tsx | 4 +- apps/example/src/pages/api/v1/rpc.ts | 2 +- apps/example/tailwind.config.ts | 12 + apps/example/tsconfig.json | 12 +- package.json | 5 +- .../next-rest-framework/.changeset/README.md | 8 + .../.changeset/config.json | 11 + .../.changeset/two-pots-own.md | 5 + packages/next-rest-framework/package.json | 12 +- .../src/app-router/rpc-route.ts | 2 +- .../src/shared/open-api.ts | 13 +- .../next-rest-framework/tsconfig.build.json | 4 - packages/next-rest-framework/tsconfig.json | 16 +- packages/tsconfig/package.json | 4 - packages/tsconfig/tsconfig.base.json | 17 - pnpm-lock.yaml | 6142 ++++++++++------- 35 files changed, 4034 insertions(+), 2886 deletions(-) create mode 100644 .github/workflows/publish.yml create mode 100644 .npmrc mode change 100644 => 120000 CHANGELOG.md delete mode 100644 apps/example/.eslintrc.js create mode 100644 apps/example/.eslintrc.json create mode 100644 apps/example/.gitignore create mode 100644 apps/example/postcss.config.js create mode 100644 apps/example/src/app/globals.css create mode 100644 apps/example/tailwind.config.ts create mode 100644 packages/next-rest-framework/.changeset/README.md create mode 100644 packages/next-rest-framework/.changeset/config.json create mode 100644 packages/next-rest-framework/.changeset/two-pots-own.md delete mode 100644 packages/next-rest-framework/tsconfig.build.json delete mode 100644 packages/tsconfig/package.json delete mode 100644 packages/tsconfig/tsconfig.base.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fde6ba9..6e6f015 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,8 +2,8 @@ name: "CI" on: push: - branches: [main] - pull_request: + branches: + - "**" jobs: build: @@ -11,17 +11,17 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [18] + node: [18, 20] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.4 + - uses: pnpm/action-setup@v2 with: - version: 7.5.1 + version: 7 - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node }} cache: "pnpm" - - run: pnpm i + - run: pnpm i --frozen-lockfile - run: pnpm run ci - name: Coverage diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..8051b87 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,38 @@ +name: "Publish" + +on: + workflow_run: + workflows: [CI] + branches: [main] + types: [completed] + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +permissions: + contents: write + pull-requests: write + +jobs: + publish: + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 7 + - uses: actions/setup-node@v3 + with: + node-version: 16.x + cache: "pnpm" + + - run: pnpm install --frozen-lockfile + - name: Create Release Pull Request or Publish + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm run release + cwd: "./packages/next-rest-framework" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..3e775ef --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +auto-install-peers=true diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 53cbfd3..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,490 +0,0 @@ -All notable changes to this project will be documented in this file. -We follow the [Semantic Versioning 2.0.0](http://semver.org/) format. - -### 4.2.0 - 2024-01-09 - -### Added - -- Add support for chaining up to three middlewares together and sharing data between the middlewares. - -### 4.1.2 - 2023-12-18 - -### Fixed - -- Fix typings for optional additional OpenAPI properties that are merged with the generated document. - -### 4.1.1 - 2023-12-18 - -### Fixed - -- Fix RPC data structure to merge in CLI commands. - -Thanks to @roothybrid7 for the fix! - -### 4.1.0 - 2023-12-13 - -### Changed - -- Improve typings, OpenAPI generation, RPC logic and documentation. Rename several public APIs and deprecate the old ones: - -* `docsRouteHandler` -> `docsRoute` -* `routeHandler` -> `route` -* `rpcRouteHandler` -> `rpcRoute` -* `apiRouteHandler` -> `apiRoute` -* `docsApiRouteHandler` -> `docsApiRoute` -* `rpcApiRouteHandler` -> `rpcApiRoute` - -### 4.0.0 - 2023-11-21 - -### Added - -- Add support for creating RPC endpoints. - -#### Breaking change: - -The `output` function has been renamed to `outputs` for clarity, simply renaming this will be enough for upgrading. - -### 3.4.7 - 2023-11-14 - -### Fixed - -- Fix `prettier` import potentially causing a module resolution issue in some Node.js environments. - -### 3.4.6 - 2023-11-12 - -### Added - -- Add CLI option to view additional logs for debugging purposes for the `generate` and `validate` commands. - -### 3.4.4 - 2023-11-06 - -### Changed - -- Use content-relative URL for fetching the `openapi.json` in the docs clients. - -### 3.4.3 - 2023-11-05 - -### Fixed - -- Fix OpenAPI generation with dynamic routes that contain multiple path parameters. - -### 3.4.2 - 2023-11-05 - -### Fixed - -- Fix npm install not working on Windows. - -### 3.4.1 - 2023-10-24 - -### Fixed - -- Fix TypedNextResponse usage. - -### 3.4.0 - 2023-10-24 - -### Added - -- Add support for strongly-typed response content-type headers. - -### 3.3.0 - 2023-10-23 - -### Added - -- Add support for strongly-typed NextResponse - -### 3.2.0 - 2023-10-23 - -### Added - -- Add an option to include a middleware function for the method handlers, that gets executed before the request input is validated. - -### 3.1.1 - 2023-10-19 - -### Fixed - -- Fix request handling when using a proxy or HTTPS connections locally. - -### 3.1.0 - 2023-10-19 - -### Added - -- Add new `next-rest-framework validate` CLI command, that checks that the generated `openapi.json` file is up to date. - -### Changed - -- Improves the CLI performance, making it supported in any runtime. - -### 3.0.1 - 2023-10-18 - -### Changed - -- Overrides the OpenAPI info `title` and `description` values with the docs config values when rendering the docs. - -### 3.0.0 - 2023-10-18 - -### Changed - -This is another breaking change before another -major release. This mostly changes the API on -creating new endpoints. The old object-based -definition of API endpoints is replaced by -a functional model, familiar from e.g. the trpc -library. - -The docs route handlers and route handler functions -are renamed, followed up with new utility function -used in conjunction with the new `routeHandler` and -`apiRouteHandler` functions. The new additional -`routeOperation` (App Router) and `apiRouteOperation` -(Pages Router) functions expose the same old API -including the input, output and handler definitions -in a slightly new format by chaining the oprations -after each other. - -We also recently dropped SwaggerUI that was replaced -by Redoc. This change allows the user to defined their -desired docs frontend, bringing back the option to -use SwaggerUI or even both Redoc and SwaggerUI at the -same time. - -### Fixed - -This fixes the query parameter typings -that were incorrect for both routers so that they -are safer to use. - -This also fixes duplicate inclusion of the parameters -in the OpenAPI spec when using dynamic routes. - -There are also some typings improvements for response -status codes, that we're not working previously. -Unfortunately, for App Router the status codes are -still not limited to the user-defined response statuses, -because the `NextResponse` API makes this impossible. - -### 2.0.1 - 2023-10-15 - -### Fixed - -This fixes a bug that caused an infinite request -loop when using pages router and the docs endpoint -was not ignored by the OpenAPI path generation. - -This fix also allows defining multiple different docs -endpoints, although that should be a rare case. -The request protocol parsing is also now handled -differently with pages router and cases where the -protocol headers contain multiple protocols should -be handled now. - -### 2.0.0 - 2023-10-15 - -Improve DX, API docs, router compability etc. - -This is another breaking change to multiple -components of the framework, changing the client -API, simplifying route definition etc. - -**Re-designed client API** - -Previously all features of the framework were -available via single client, initialized by the -user in their code base. This change removes the -concept of initializing a client and accessing route -definitions etc. via the client. - -The documentation part is now decoupled from defining -individual routes, meaning that the new simplified -workflow allows the developer to define a single route -for the generated documentation if they want it. - -Individual routes can still be defined like before, -without importing the route definitions from the client. - -The documentation endpoint also does not have to be a -catch-all route and it can be defined anywhere in the code -base without breaking things. - -In addition to having less boilerplate with the new -client API, we also get rid of configuring the paths -for the `app` and `pages` directories. The new smarter -approach handles this automatically by scanning these -folders automatically, detecting the `src` directory -is in use. - -**Streamlined OpenAPI spec generation** - -Previously, we were storing the generated `openapi.json` -file in the root of the project and serving that via another -internal endpoint. The new approach simply generates the spec -file directly to the `public` folder, where it will be served -for the API documentation. - -**Replacing SwaggerUI with Redoc** - -Redoc is a great open source project and replacement for -SwaggerUI, offering more features like richer endpoint -previews, search etc. The new rendered API documentation -uses Redocly and it can still be configured and customized -by the developer. - -### 1.2.4 - 2023-10-09 - -### Fixed - -- Fix query parameter validation on app router - now the search parameters are validated similarly to when using Pages Router. -- Fix content type validation when no user-defined content type validation is set. - -### 1.2.3 - 2023-10-07 - -### Fixed - -- Fix `appDirPath` handling when not using src directory. - -### 1.2.2 - 2023-10-01 - -### Fixed - -- Fix miscellaneous issues with generating the OpenAPI spec from Zod schema, by using `zod-to-json-schema`. - -### 1.2.1 - 2023-09-30 - -### Fixed - -- Fix request body validation with App Router. The new validation clones the request object before validating it, allowing the request body to be further parsed by the API handler. - -### 1.2.0 - 2023-09-27 - -### Added - -- Add option to allow/deny paths from Next REST Framework. This ensures better compability with other third-party server-side libraries and routes not using Next REST Framework. -- Add logging for error cases when the app/pages directory is not found based on the config options. -- Add logging for ignored paths based on the allow/deny lists. - -### 1.1.1 - 2023-09-26 - -### Fixed - -- Fix Pages Route example code snippets in readme and docs pages. - -### 1.1.0 - 2023-09-26 - -### Fixed - -- Fix an error of the pages directory not being found when only using Pages Router. -- Fix App Router catch-all route documentation in the readme. - -### Added - -- Add support for dark theme in the SwaggerUI. - -### 1.0.2 - 2023-09-23 - -### Fixed - -- Fixed an idempotency issue in the OpenAPI paths generation where the ordering of the generated paths was inconsistent between executions. - -### Changed - -- Changed the OpenAPI spec generation to not make file system calls for API routes files when the config option `apiRoutesPath` is not defined. - -### 1.0.1 - 2023-09-13 - -Full details available in this PR: https://github.com/blomqma/next-rest-framework/pull/49 - -### Added - -- Add support for Next.js App Router - -### Removed - -- Remove support for global, route and method middlewares. -- Remove support for HTTP TRACE. -- Removed support for Node.js 16. - -### Changed - -- Running `next-rest-framework generate` is no longer encouraged to be run together with `next build`. - -### 0.8.0 - 2023-05-27 - -### Removed - -- Drop support for Yup schemas in order to better support Zod that is the main object-schema validation library used with the framework. - -### Added - -- Add support for all applicable Zod schema types listed in their docs: https://zod.dev - -### 0.7.2 - 2023-05-19 - -### Fixed - -- Fix path finding for windows environments, and add path parameters to OpenAPI spec. - -### 0.7.1 - 2023-05-09 - -### Fixed - -- Fix miscellaneous bugs with Zod schemas, where `intersection`, `nullable` and `enum` types were not working with the OpenAPI spec generation. - -### 0.7.0 - 2023-04-17 - -### Added - -- Add a binary script that can be used programmatically to generate the OpenAPI spec e.g. before running `next build`. - -### 0.6.0 - 2023-04-11 - -### Added - -- Add SwaggerUI customization options for using custom title, description, logo and favicon. - -### Fixed - -- Fix bug that caused custom OpenAPI YAML file paths not working. -- Fix documentation and examples that were using Zod number schemas for query parameter validation, resulting in an error when following the examples. - -### 0.5.1 - 2023-03-28 - -### Fixed - -- Revert the addition of the `localOpenApiSpec` config option. Using a user-defined route resulted in the generated OpenAPI spec file not being included in the Vercel build artifacts, thus making it not work. This issue is fixed by using a static path for the spec file so it will be always called `openapi.json` and lies in the project root. - -### 0.5.0 - 2023-03-28 - -### Changed - -- Change OpenAPI generation by generating a local OpenAPI spec file that is dynamically updated in local development and used in production for the OpenAPI endpoints. Rename the `openApiSpec` config option to `openApiSpecOverrides` for better clarity with the added `localOpenApiSpec` path option. - -### 0.4.2 - 2023-03-21 - -### Fixed - -- Fix bug with middlewares and error handlers that responded to the API request and the execution was not stopped. - -### 0.4.1 - 2023-03-20 - -### Fixed - -- Fix the getting started docs containing a typo that caused an error. - -### 0.4.0 - 2023-03-15 - -### Fixed - -- Fix the OpenAPI instrumentation for dynamic routes containing parameters that were not displayed correctly in the Swagger UI. - -### Changed - -- Defining content type and request body are no longer required in the `input` object. Making the endpoint definition friendlier for different types of requests. - -### 0.3.7 - 2023-03-09 - -### Fixed - -- Fix previous release not reflecting the latest changes introduced in the release notes of v0.3.6. - -### 0.3.6 - 2023-03-08 - -### Fixed - -- Fix a bug that prevented nested API routes from being included into the OpenAPI spec. - -### 0.3.5 - 2023-02-21 - -### Fixed - -- Fix content type header bug by removing the content type header parameters from the header validation logic. This caused e.g. form data requests to fail at runtime. - -### 0.3.4 - 2023-02-20 - -### Fixed - -- Fix Zod/Yup typings so that both of those dependencies are no longer needed for using the framework. - -### 0.3.3 - 2023-02-20 - -### Fixed - -- This fixes some compability issues with user-defined - API routes that are not using Next REST Framework. - There was a bug in the API route path matching where - the comparison to the reserved paths was not exact, - making some user-defined API routes to be completely - skipped in some cases. -- Other fix here is that the instrumentation requests are now - aborted after 200ms in case the user-defined APIs do not - respond in that time. - -### 0.3.2 - 2023-02-20 - -### Added - -- Add support for projects using a `src` folder with a new config option called `apiRoutesPath`. - -### 0.3.1 - 2023-01-23 - -### Changed - -- Change miscellaneous copyright texts and contact emails. - -### 0.3.0 - 2023-01-15 - -### Added - -- Added support for typed query parameters. This changes the `input` - object API by renaming the `schema` attribute to `body` and adding a - `query` attribute that can be used to type and validate - query parameters for endpoints. - -### 0.2.3 - 2023-01-09 - -### Fixed - -- Fixed an issue when using multiple output objects with - different types - now the output types are combined - with a union type to allow multiple different outputs. - -### 0.2.2 - 2023-01-09 - -### Fixed - -Fix documentation on readme included with the NPM package. - -### 0.2.1 - 2023-01-07 - -### Changed - -- Changed the Swagger UI layout by adding a custom navbar and footer components. -- Changed the include Swagger UI by loading the assets from unpkg CDN and significantly reducing the bundle size. - -### 0.2.0 - 2023-01-03 - -### Changed - -- The public API is changed in a way that the OpenAPI spec generation is split out from the input/output validation. The validation is now done with `input` and `output` keywords within the `defineEndpoints` handler, that generates a minimal OpenAPI spec out of the contents of the input and output definitions and all other OpenAPI generation-related overrides are done inside the `openApiSpec` object. This makes the separation of the business logic and documentation clearer, while still auto-generating the definitions from the application logic. - -### 0.1.2 - 2022-12-09 - -### Fixed - -- Fix static URL that was used for API route instrumentation. The hardcoded value is now replaced with a dynamic value that should work in all environment. This change also caused the removal of the `getOpenApiSpec` function from the API. This is considered to be an API-breaking change but the early versions are not considered to be in use yet so it's safe to include it here. - -## 0.1.1 - 2022-12-09 - -### Fixed - -- Fix NPM package not working due to CommonJS and ESM interoperability issue. -- Fix missing `summary` field from OpenAPI paths. -- Fix miscellaneous typos in README. - -### Added - -- Add an example application with the installed NPM package. - -## 0.1.0 - 2022-12-03 - -### Added - -- Added initial version of Next REST Framework. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 120000 index 0000000..bdd4f61 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +packages/next-rest-framework/CHANGELOG.md \ No newline at end of file diff --git a/apps/example/.eslintrc.js b/apps/example/.eslintrc.js deleted file mode 100644 index df72793..0000000 --- a/apps/example/.eslintrc.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - rules: { - '@typescript-eslint/triple-slash-reference': 'off' - } -} diff --git a/apps/example/.eslintrc.json b/apps/example/.eslintrc.json new file mode 100644 index 0000000..c140af9 --- /dev/null +++ b/apps/example/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "next/core-web-vitals", + "rules": { + "@typescript-eslint/triple-slash-reference": "off" + } +} diff --git a/apps/example/.gitignore b/apps/example/.gitignore new file mode 100644 index 0000000..fd3dbb5 --- /dev/null +++ b/apps/example/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/example/next.config.js b/apps/example/next.config.js index 3d3bc99..767719f 100644 --- a/apps/example/next.config.js +++ b/apps/example/next.config.js @@ -1,7 +1,4 @@ /** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, - swcMinify: true, -}; +const nextConfig = {} -module.exports = nextConfig; +module.exports = nextConfig diff --git a/apps/example/package.json b/apps/example/package.json index cec69d1..e6913d2 100644 --- a/apps/example/package.json +++ b/apps/example/package.json @@ -5,12 +5,18 @@ "prebuild": "cd ../.. && pnpm build && cd apps/example", "dev": "pnpm prebuild && next dev", "build": "pnpm prebuild && next build", + "start": "next start", "generate": "pnpm prebuild && next-rest-framework generate --debug=true", "validate": "pnpm prebuild && next-rest-framework validate --debug=true", - "start": "next start", - "type-check": "tsc --noEmit" + "lint": "tsc && next lint" }, "dependencies": { "next-rest-framework": "workspace:*" + }, + "devDependencies": { + "autoprefixer": "10.0.1", + "postcss": "8.4.33", + "tailwindcss": "3.3.0", + "eslint-config-next": "14.0.4" } } diff --git a/apps/example/postcss.config.js b/apps/example/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/apps/example/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/apps/example/src/actions.ts b/apps/example/src/actions.ts index 42e7581..027e8d8 100644 --- a/apps/example/src/actions.ts +++ b/apps/example/src/actions.ts @@ -1,7 +1,7 @@ 'use server'; import { rpcOperation } from 'next-rest-framework'; -import { MOCK_TODOS, todoSchema } from 'utils'; +import { MOCK_TODOS, todoSchema } from '@/utils'; import { z } from 'zod'; // The RPC operations can be used as server-actions and imported in the RPC route handlers. diff --git a/apps/example/src/app/api/v2/rpc/[operationId]/route.ts b/apps/example/src/app/api/v2/rpc/[operationId]/route.ts index ddd0285..b2a9d0b 100644 --- a/apps/example/src/app/api/v2/rpc/[operationId]/route.ts +++ b/apps/example/src/app/api/v2/rpc/[operationId]/route.ts @@ -1,4 +1,4 @@ -import { createTodo, deleteTodo, getTodoById, getTodos } from 'actions'; +import { createTodo, deleteTodo, getTodoById, getTodos } from '@/actions'; import { rpcRoute } from 'next-rest-framework'; const { POST, client } = rpcRoute({ diff --git a/apps/example/src/app/api/v2/todos/route.ts b/apps/example/src/app/api/v2/todos/route.ts index d91c7fe..1c0f808 100644 --- a/apps/example/src/app/api/v2/todos/route.ts +++ b/apps/example/src/app/api/v2/todos/route.ts @@ -1,5 +1,5 @@ import { TypedNextResponse, route, routeOperation } from 'next-rest-framework'; -import { MOCK_TODOS, todoSchema } from 'utils'; +import { MOCK_TODOS, todoSchema } from '@/utils'; import { z } from 'zod'; // Example App Router route handler with GET/POST handlers. diff --git a/apps/example/src/app/client/ClientExample.tsx b/apps/example/src/app/client/ClientExample.tsx index 8683c56..9372459 100644 --- a/apps/example/src/app/client/ClientExample.tsx +++ b/apps/example/src/app/client/ClientExample.tsx @@ -1,9 +1,9 @@ 'use client'; -import { type RpcClient } from 'app/api/v2/rpc/[operationId]/route'; +import { type RpcClient } from '@/app/api/v2/rpc/[operationId]/route'; import { rpcClient } from 'next-rest-framework/dist/client/rpc-client'; import { useEffect, useState } from 'react'; -import { type Todo } from 'utils'; +import { type Todo } from '@/utils'; const client = rpcClient({ url: 'http://localhost:3000/api/v2/rpc' diff --git a/apps/example/src/app/client/page.tsx b/apps/example/src/app/client/page.tsx index 3347e14..feecec8 100644 --- a/apps/example/src/app/client/page.tsx +++ b/apps/example/src/app/client/page.tsx @@ -1,7 +1,7 @@ -import { getTodos } from 'actions'; -import { Footer } from '../components/Footer'; -import { Navbar } from '../components/Navbar'; -import { ClientExample } from './ClientExample'; +import { getTodos } from '@/actions'; +import { Footer } from '@/app/components/Footer'; +import { Navbar } from '@/app/components/Navbar'; +import { ClientExample } from '@/app/client/ClientExample'; export default async function Page() { const todos = await getTodos(); diff --git a/apps/example/src/app/components/Footer.tsx b/apps/example/src/app/components/Footer.tsx index 32726ab..fd5d26c 100644 --- a/apps/example/src/app/components/Footer.tsx +++ b/apps/example/src/app/components/Footer.tsx @@ -1,3 +1,5 @@ +import Image from 'next/image'; + export const Footer: React.FC = () => (