diff --git a/.changeset/silly-turtles-explain.md b/.changeset/silly-turtles-explain.md new file mode 100644 index 00000000..8dedc6cf --- /dev/null +++ b/.changeset/silly-turtles-explain.md @@ -0,0 +1,20 @@ +--- +'@orbitkit/eslint': patch +'@orbitkit/vite': patch +'@orbitkit/utils': patch +'@orbitkit/auth': patch +'@orbitkit/env': patch +'@orbitkit/ui': patch +'@orbitkit/docs': patch +'@orbitkit/web': patch +'@orbitkit/marketing': patch +'@orbitkit/api': patch +'@orbitkit/assets': patch +'@orbitkit/storybook': patch +'@orbitkit/tailwind': patch +'@orbitkit/tsconfig': patch +'@orbitkit/core': patch +'@orbitkit/db': patch +--- + +refactor: switches from `tsup` to `vite` for bundling. diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 92107566..098aa89e 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -19,7 +19,7 @@ env: AUTH_GITHUB_SECRET: ${{ secrets.AUTH_GITHUB_SECRET }} AUTH_GOOGLE_ID: ${{ secrets.AUTH_GOOGLE_ID }} AUTH_GOOGLE_SECRET: ${{ secrets.AUTH_GOOGLE_SECRET }} - AUTH_GOOGLE_CODE_VERIFIER: ${{ secrets.AUTH_GOOGLE_CODE_VERIFIER }} + AUTH_SECRET: ${{ secrets.AUTH_SECRET }} # Uploadthing UPLOADTHING_SECRET: ${{ secrets.UPLOADTHING_SECRET }} diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index c29f681a..52080b68 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -16,7 +16,7 @@ env: AUTH_GITHUB_SECRET: ${{ secrets.AUTH_GITHUB_SECRET }} AUTH_GOOGLE_ID: ${{ secrets.AUTH_GOOGLE_ID }} AUTH_GOOGLE_SECRET: ${{ secrets.AUTH_GOOGLE_SECRET }} - AUTH_GOOGLE_CODE_VERIFIER: ${{ secrets.AUTH_GOOGLE_CODE_VERIFIER }} + AUTH_SECRET: ${{ secrets.AUTH_SECRET }} # Uploadthing UPLOADTHING_SECRET: ${{ secrets.UPLOADTHING_SECRET }} diff --git a/.gitignore b/.gitignore index 586d748e..02c7bcb6 100644 --- a/.gitignore +++ b/.gitignore @@ -136,9 +136,6 @@ storybook-static # Astro .astro -# Tsup -.tsup - # DS_Store files .DS_Store diff --git a/README.md b/README.md index 412094ab..1b2fd5e2 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - [**Github Actions**](https://github.com/features/actions): for CI/CD, with automatic DB branching & code checks. - [**next-themes**](https://github.com/pacocoursey/next-themes): for easy light/dark mode handling in the web app. - [**Changesets**](https://github.com/changesets/changesets): for managing versioning and changelogs. -- [**tsup**](https://github.com/egoist/tsup): for fast, easy to configure bundling of packages. +- [**vite**](https://vitejs.dev): for bundling & storybook. - [**ts-reset**](https://github.com/total-typescript/ts-reset): for the apps, improving the types for common JavaScript APIs. - [**ESLint**](https://eslint.org/), [**Prettier**](https://prettier.io), [**Markdownlint**](https://github.com/DavidAnson/markdownlint), [**Cspell**](https://cspell.org), [**Husky**](https://github.com/typicode/husky), [**Lint-staged**](https://github.com/lint-staged/lint-staged) and [**Commitlint**](https://github.com/conventional-changelog/commitlint) for code quality. - **ESM Only**: because CJS should be left in the past. diff --git a/apps/docs/decision-reasoning/why-all-built.mdx b/apps/docs/decision-reasoning/why-all-built.mdx index 79fbd168..49ca830a 100644 --- a/apps/docs/decision-reasoning/why-all-built.mdx +++ b/apps/docs/decision-reasoning/why-all-built.mdx @@ -1,7 +1,7 @@ --- title: Built packages icon: 'toolbox' -description: 'If you noticed, all the packages in the monorepo (except the env one) are built using tsc or tsup. Here is why.' +description: 'If you noticed, all the packages in the monorepo (except the env one) are built using tsc or vite. Here is why.' --- ## Types of Monorepo Packages @@ -10,7 +10,7 @@ In a typical TS monorepo, there are three ways of consuming the packages that yo 1. Shipping out the TS source code directly in the `exports` field of the `package.json` file or using `tsconfig` paths. 2. Transpiling the TS code to JS using `tsc` and shipping the JS code in the `exports` field of the package alongside the `.d.ts` files. -3. Bundling the TS code using something like `tsup` or `rollup` and shipping the bundled JS code in the `exports` field of the package alongside the `.d.ts` files. +3. Bundling the TS code using something like `vite`, `tsup` or `rollup` and shipping the bundled JS code in the `exports` field of the package alongside the `.d.ts` files. ## Comparing the approaches @@ -69,7 +69,7 @@ Typically, a package using this approach would be called a "Publishable Package" ## The OrbitKit Approach -- `ui package` is bundled with `tsup`. +- `ui package` is bundled with `vite`. - `env package` is shipped out as source code. - All other packages are compiled with `tsc`. diff --git a/apps/docs/installation.mdx b/apps/docs/installation.mdx index c1af1b74..49dae824 100644 --- a/apps/docs/installation.mdx +++ b/apps/docs/installation.mdx @@ -173,8 +173,8 @@ OrbitKit currently ships with two authentication providers, Google and Github. Y variable.
  • - For the `AUTH_GOOGLE_CODE_VERIFIER` environment variable, you can put - any random string. + For the `AUTH_SECRET` environment variable, you can put any random + string.
  • diff --git a/apps/docs/introduction.mdx b/apps/docs/introduction.mdx index 9ca81855..a63579a2 100644 --- a/apps/docs/introduction.mdx +++ b/apps/docs/introduction.mdx @@ -38,7 +38,7 @@ description: '🚀 OrbitKit is an enterprise ready monorepo StarterKit ready to - [**Github Actions**](https://github.com/features/actions): for CI/CD, with automatic DB branching & code checks. - [**next-themes**](https://github.com/pacocoursey/next-themes): for easy light/dark mode handling in the web app. - [**Changesets**](https://github.com/changesets/changesets): for managing versioning and changelogs. -- [**tsup**](https://github.com/egoist/tsup): for fast, easy to configure bundling of packages. +- [**vite**](https://vitejs.dev): for bundling & storybook. - [**ts-reset**](https://github.com/total-typescript/ts-reset): for the apps, improving the types for common JavaScript APIs. - [**ESLint**](https://eslint.org/), [**Prettier**](https://prettier.io), [**Markdownlint**](https://github.com/DavidAnson/markdownlint), [**Cspell**](https://cspell.org), [**Husky**](https://github.com/typicode/husky), [**Lint-staged**](https://github.com/lint-staged/lint-staged) and [**Commitlint**](https://github.com/conventional-changelog/commitlint) for code quality. - **ESM Only**: because CJS should be left in the past. diff --git a/apps/docs/package.json b/apps/docs/package.json index 2bc4ddb3..8261138f 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -11,7 +11,7 @@ }, "devDependencies": { "ajv": "^8.16.0", - "mintlify": "^4.0.167" + "mintlify": "^4.0.168" }, "volta": { "extends": "../../package.json" diff --git a/apps/marketing/.env.example b/apps/marketing/.env.example index c71fd3dc..9ee1df32 100644 --- a/apps/marketing/.env.example +++ b/apps/marketing/.env.example @@ -1,2 +1,3 @@ +# Posthog (optional) (https://posthog.com) PUBLIC_POSTHOG_KEY= PUBLIC_POSTHOG_HOST= \ No newline at end of file diff --git a/apps/marketing/package.json b/apps/marketing/package.json index 2e0457ab..0ace3506 100644 --- a/apps/marketing/package.json +++ b/apps/marketing/package.json @@ -23,7 +23,7 @@ "@t3-oss/env-core": "^0.10.1", "@total-typescript/ts-reset": "^0.5.1", "astro": "^4.10.2", - "posthog-js": "^1.139.1", + "posthog-js": "^1.139.2", "react": "^18.3.1", "react-dom": "^18.3.1", "zod": "^3.23.8" diff --git a/apps/web/.env.example b/apps/web/.env.example index 233e0618..178f841f 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -1,19 +1,18 @@ -# Neon Database URL (required) +################################################################################ +# 👇 REQUIRED ENVIRONMENT VARIABLES 👇 # +################################################################################ + +# Neon Database URL (https://neon.tech) DATABASE_URL= -# Uploadthing (required) +# Uploadthing (https://uploadthing.com) UPLOADTHING_SECRET= UPLOADTHING_APP_ID= -# Posthog (optional) -NEXT_PUBLIC_POSTHOG_HOST= -NEXT_PUBLIC_POSTHOG_KEY= +# Auth secret. +AUTH_SECRET= -# Unkey (optional) -UNKEY_NAMESPACE= -UNKEY_ROOT_KEY= - -# Auth, you will need at least one of these set +# !IMPORTANT: you don't need both Github & Google OAuth environment variables, you just need a minimum of one provider's environment variables (ie. you can set `AUTH_GITHUB_ID` and `AUTH_GITHUB_SECRET`, leave out the google ones and that would be fine.) # Github OAuth AUTH_GITHUB_ID= @@ -22,4 +21,17 @@ AUTH_GITHUB_SECRET= # Google OAuth AUTH_GOOGLE_ID= AUTH_GOOGLE_SECRET= -AUTH_GOOGLE_CODE_VERIFIER= \ No newline at end of file + + + +################################################################################ +# 👇 OPTIONAL ENVIRONMENT VARIABLES 👇 # +################################################################################ + +# Posthog (https://posthog.com) +NEXT_PUBLIC_POSTHOG_HOST= +NEXT_PUBLIC_POSTHOG_KEY= + +# Unkey (https://unkey.dev) +UNKEY_NAMESPACE= +UNKEY_ROOT_KEY= \ No newline at end of file diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 1c2a4b67..3a215212 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -5,7 +5,8 @@ import createJiti from 'jiti'; const jiti = createJiti(fileURLToPath(import.meta.url)); -jiti('@orbitkit/env/web'); +jiti('@orbitkit/env/web/server'); +jiti('@orbitkit/env/web/client'); const withBundleAnalyzer = bundleAnalyzerPlugin({ enabled: process.env['ANALYZE'] === 'true', diff --git a/apps/web/package.json b/apps/web/package.json index cea6116a..e28b0e45 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -33,7 +33,7 @@ "geist": "^1.3.0", "next": "14.2.4", "next-themes": "^0.3.0", - "posthog-js": "^1.139.1", + "posthog-js": "^1.139.2", "posthog-node": "^4.0.1", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/apps/web/src/app/(auth)/login/page.tsx b/apps/web/src/app/(auth)/login/page.tsx index 98a68ff5..5b8abf84 100644 --- a/apps/web/src/app/(auth)/login/page.tsx +++ b/apps/web/src/app/(auth)/login/page.tsx @@ -2,12 +2,10 @@ import Link from 'next/link'; import { redirect } from 'next/navigation'; import { auth } from '@orbitkit/auth'; -import { env } from '@orbitkit/env/web'; +import { env } from '@orbitkit/env/web/server'; const googleAuthIsEnabled = - env.AUTH_GOOGLE_ID !== undefined && - env.AUTH_GOOGLE_SECRET !== undefined && - env.AUTH_GOOGLE_CODE_VERIFIER !== undefined; + env.AUTH_GOOGLE_ID !== undefined && env.AUTH_GOOGLE_SECRET !== undefined; const githubAuthIsEnabled = env.AUTH_GITHUB_SECRET !== undefined && env.AUTH_GITHUB_ID !== undefined; diff --git a/apps/web/src/app/api/trpc/[trpc]/route.ts b/apps/web/src/app/api/trpc/[trpc]/route.ts index ac57c740..8e1f9b5f 100644 --- a/apps/web/src/app/api/trpc/[trpc]/route.ts +++ b/apps/web/src/app/api/trpc/[trpc]/route.ts @@ -3,7 +3,7 @@ import { type NextRequest } from 'next/server'; import { fetchRequestHandler } from '@trpc/server/adapters/fetch'; import { appRouter, createTRPCContext } from '@orbitkit/api'; -import { env } from '@orbitkit/env/web'; +import { env } from '@orbitkit/env/web/server'; const createContext = async (req: NextRequest) => { return createTRPCContext({ diff --git a/apps/web/src/lib/posthog/client.ts b/apps/web/src/lib/posthog/client.ts index 9ef38832..fb499a03 100644 --- a/apps/web/src/lib/posthog/client.ts +++ b/apps/web/src/lib/posthog/client.ts @@ -1,4 +1,4 @@ -import { env } from '@orbitkit/env/web'; +import { env } from '@orbitkit/env/web/client'; import { PostHog } from 'posthog-node'; /** diff --git a/apps/web/src/lib/posthog/react.tsx b/apps/web/src/lib/posthog/react.tsx index fa15961c..b33ef9d3 100644 --- a/apps/web/src/lib/posthog/react.tsx +++ b/apps/web/src/lib/posthog/react.tsx @@ -1,5 +1,5 @@ 'use client'; -import { env } from '@orbitkit/env/web'; +import { env } from '@orbitkit/env/web/client'; import posthog from 'posthog-js'; import { PostHogProvider } from 'posthog-js/react'; diff --git a/apps/web/src/middleware.ts b/apps/web/src/middleware.ts index 0db04e51..99d1d4a9 100644 --- a/apps/web/src/middleware.ts +++ b/apps/web/src/middleware.ts @@ -4,7 +4,7 @@ import type { NextRequest } from 'next/server'; import { Ratelimit } from '@unkey/ratelimit'; -import { env } from '@orbitkit/env/web'; +import { env } from '@orbitkit/env/web/server'; const unkey = env.UNKEY_ROOT_KEY && env.UNKEY_NAMESPACE diff --git a/apps/web/turbo.json b/apps/web/turbo.json index 2e0058a2..5d251556 100644 --- a/apps/web/turbo.json +++ b/apps/web/turbo.json @@ -16,7 +16,7 @@ "AUTH_GITHUB_SECRET", "AUTH_GOOGLE_ID", "AUTH_GOOGLE_SECRET", - "AUTH_GOOGLE_CODE_VERIFIER", + "AUTH_SECRET", "NEXT_PUBLIC_POSTHOG_HOST", "NEXT_PUBLIC_POSTHOG_KEY" ] @@ -32,7 +32,7 @@ "AUTH_GITHUB_SECRET", "AUTH_GOOGLE_ID", "AUTH_GOOGLE_SECRET", - "AUTH_GOOGLE_CODE_VERIFIER", + "AUTH_SECRET", "NEXT_PUBLIC_POSTHOG_HOST", "NEXT_PUBLIC_POSTHOG_KEY" ] diff --git a/bun.lockb b/bun.lockb index 41640b17..c62bd52f 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/cspell.config.yaml b/cspell.config.yaml index b5947279..bb69364e 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -31,6 +31,7 @@ words: - callees - classname - clsx + - tsup - cmdk - codespace - codespaces @@ -53,11 +54,15 @@ words: - lockb - lucide - Malyavko + - minimise - Mintlify + - monorepoing - neonctl - neondatabase - nextjs - nzst + - onwarn + - optimisations - orbitkit - Ornella - packagejson @@ -79,11 +84,12 @@ words: - thollander - todos - topbar + - transpiles + - treeshake - trpc - tsbuildinfo - tsconfigs - tseslint - - tsup - Tuite - turborepo - typecheck @@ -94,7 +100,3 @@ words: - vaul - viewports - WITA - - transpiles - - optimisations - - minimise - - monorepoing diff --git a/package.json b/package.json index fcf8a756..70e35fcf 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@types/yargs": "^17.0.32", "commitizen": "^4.3.0", "cspell": "^8.8.4", - "eslint": "^9.4.0", + "eslint": "^9.5.0", "husky": "^9.0.11", "lint-staged": "^15.2.7", "markdownlint": "^0.34.0", @@ -66,7 +66,7 @@ "prettier-plugin-astro": "^0.14.0", "prettier-plugin-curly": "^0.2.1", "prettier-plugin-packagejson": "^2.5.0", - "turbo": "^2.0.3", + "turbo": "^2.0.4", "typescript": "^5.4.5", "yargs": "^17.7.2" }, diff --git a/packages/auth/src/lucia.ts b/packages/auth/src/lucia.ts index 23a316d3..1a58c2af 100644 --- a/packages/auth/src/lucia.ts +++ b/packages/auth/src/lucia.ts @@ -3,7 +3,7 @@ import { Lucia } from 'lucia'; import { db } from '@orbitkit/db'; import { sessionTable, userTable } from '@orbitkit/db/schema'; -import { env } from '@orbitkit/env/web'; +import { env } from '@orbitkit/env/web/server'; const adapter = new DrizzlePostgreSQLAdapter(db, sessionTable, userTable); diff --git a/packages/auth/src/providers/github.ts b/packages/auth/src/providers/github.ts index 2230d902..0f11a0c5 100644 --- a/packages/auth/src/providers/github.ts +++ b/packages/auth/src/providers/github.ts @@ -5,7 +5,7 @@ import { generateId } from 'lucia'; import { db } from '@orbitkit/db'; import { oauthAccountTable, userTable } from '@orbitkit/db/schema'; -import { env } from '@orbitkit/env/web'; +import { env } from '@orbitkit/env/web/server'; import { lucia } from '../lucia'; diff --git a/packages/auth/src/providers/google.ts b/packages/auth/src/providers/google.ts index 9ef01203..a0151daa 100644 --- a/packages/auth/src/providers/google.ts +++ b/packages/auth/src/providers/google.ts @@ -6,7 +6,7 @@ import { z } from 'zod'; import { db } from '@orbitkit/db'; import { oauthAccountTable, userTable } from '@orbitkit/db/schema'; -import { env } from '@orbitkit/env/web'; +import { env } from '@orbitkit/env/web/server'; import { getBaseUrl } from '@orbitkit/utils/url'; import { lucia } from '../lucia'; @@ -35,18 +35,9 @@ export async function createGoogleAuthorizationURL(): Promise { } const state = generateState(); - const url = - env.AUTH_GOOGLE_CODE_VERIFIER !== undefined && - (await google.createAuthorizationURL(state, env.AUTH_GOOGLE_CODE_VERIFIER, { - scopes: ['profile', 'email'], - })); - - if (!url) { - return new Response(null, { - status: 404, - statusText: 'Not Found', - }); - } + const url = await google.createAuthorizationURL(state, env.AUTH_SECRET, { + scopes: ['profile', 'email'], + }); cookies().set('google_oauth_state', state, { path: '/', @@ -91,19 +82,10 @@ export async function validateGoogleCallback( } try { - const tokens = - env.AUTH_GOOGLE_CODE_VERIFIER !== undefined && - (await google.validateAuthorizationCode( - code, - env.AUTH_GOOGLE_CODE_VERIFIER, - )); - - if (!tokens) { - return new Response(null, { - status: 404, - statusText: 'Not Found', - }); - } + const tokens = await google.validateAuthorizationCode( + code, + env.AUTH_SECRET, + ); const googleUserResponse = await fetch( 'https://openidconnect.googleapis.com/v1/userinfo', diff --git a/packages/config/eslint/package.json b/packages/config/eslint/package.json index 6d9e01c1..e6632a42 100644 --- a/packages/config/eslint/package.json +++ b/packages/config/eslint/package.json @@ -21,18 +21,18 @@ "@eslint-community/eslint-plugin-eslint-comments": "^4.3.0", "@eslint/compat": "^1.1.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.4.0", + "@eslint/js": "^9.5.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-jsdoc": "^48.2.9", + "eslint-plugin-jsdoc": "^48.2.12", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-playwright": "^1.6.2", "eslint-plugin-react": "^7.34.2", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-regexp": "^2.6.0", - "eslint-plugin-security": "^3.0.0", + "eslint-plugin-security": "^3.0.1", "eslint-plugin-tailwindcss": "^3.17.3", - "eslint-plugin-turbo": "^2.0.3", - "globals": "^15.4.0", + "eslint-plugin-turbo": "^2.0.4", + "globals": "^15.5.0", "typescript-eslint": "^7.13.0" }, "devDependencies": { diff --git a/packages/config/eslint/src/configs/base.js b/packages/config/eslint/src/configs/base.js index d2702b03..856b3c82 100644 --- a/packages/config/eslint/src/configs/base.js +++ b/packages/config/eslint/src/configs/base.js @@ -13,7 +13,7 @@ import { compat, defineConfig } from '../utils.js'; export const base = defineConfig( { - ignores: ['.next', '.astro', 'dist', 'storybook-static', '.tsup'], + ignores: ['.next', '.astro', 'dist', 'storybook-static'], }, // Base JS/TS configs @@ -34,15 +34,15 @@ export const base = defineConfig( // Tailwind plugin ...fixupConfigRules(compat.extends('plugin:tailwindcss/recommended')), + // Prettier config to disable conflicting rules + prettierConfig, + // JSDoc plugin only for TypeScript files { files: ['**/*.{ts,tsx}'], extends: [jsdoc.configs['flat/recommended-typescript-error']], }, - // Prettier config to disable conflicting rules - prettierConfig, - { files: ['**/*.cjs'], languageOptions: { diff --git a/packages/config/storybook/package.json b/packages/config/storybook/package.json index f0b9be50..181d3e5c 100644 --- a/packages/config/storybook/package.json +++ b/packages/config/storybook/package.json @@ -36,21 +36,21 @@ "@orbitkit/assets": "workspace:^", "@orbitkit/utils": "workspace:^", "@radix-ui/colors": "^3.0.0", - "@storybook/addon-a11y": "^8.1.7", - "@storybook/addon-essentials": "^8.1.7", - "@storybook/addon-interactions": "^8.1.7", - "@storybook/addon-links": "^8.1.7", - "@storybook/addon-onboarding": "^8.1.7", - "@storybook/addon-themes": "^8.1.7", - "@storybook/addon-viewport": "^8.1.7", - "@storybook/manager-api": "^8.1.7", - "@storybook/react": "^8.1.7", - "@storybook/react-vite": "^8.1.7", - "@storybook/theming": "^8.1.7", - "@storybook/types": "^8.1.7", + "@storybook/addon-a11y": "^8.1.9", + "@storybook/addon-essentials": "^8.1.9", + "@storybook/addon-interactions": "^8.1.9", + "@storybook/addon-links": "^8.1.9", + "@storybook/addon-onboarding": "^8.1.9", + "@storybook/addon-themes": "^8.1.9", + "@storybook/addon-viewport": "^8.1.9", + "@storybook/manager-api": "^8.1.9", + "@storybook/react": "^8.1.9", + "@storybook/react-vite": "^8.1.9", + "@storybook/theming": "^8.1.9", + "@storybook/types": "^8.1.9", "react": "^18.3.1", "react-dom": "^18.3.1", - "storybook": "^8.1.7" + "storybook": "^8.1.9" }, "devDependencies": { "@orbitkit/eslint": "workspace:^", diff --git a/packages/config/vite/package.json b/packages/config/vite/package.json index 6b08173b..3a40d6e7 100644 --- a/packages/config/vite/package.json +++ b/packages/config/vite/package.json @@ -8,9 +8,9 @@ "sideEffects": false, "type": "module", "exports": { - "./react": { - "types": "./dist/react.d.ts", - "default": "./dist/react.js" + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" } }, "scripts": { @@ -22,11 +22,15 @@ }, "dependencies": { "@vitejs/plugin-react": "^4.3.1", - "vite": "^5.2.13", + "vite": "^5.3.1", "vite-tsconfig-paths": "^4.3.2" }, "devDependencies": { "@orbitkit/eslint": "workspace:^", - "@orbitkit/tsconfig": "workspace:^" + "@orbitkit/tsconfig": "workspace:^", + "globby": "^14.0.1", + "rollup-plugin-preserve-directives": "^0.4.0", + "vite-plugin-dts": "^3.9.1", + "vite-plugin-external": "^4.3.1" } } diff --git a/packages/config/vite/src/build.ts b/packages/config/vite/src/build.ts new file mode 100644 index 00000000..1903c90c --- /dev/null +++ b/packages/config/vite/src/build.ts @@ -0,0 +1,76 @@ +import type { LibraryOptions } from 'vite'; +import { defineConfig } from 'vite'; +import createExternal, { + type Options as ExternalPluginOptions, +} from 'vite-plugin-external'; +import dtsPlugin, { + type PluginOptions as DtsPluginOptions, +} from 'vite-plugin-dts'; +import { globbySync } from 'globby'; +import preserveDirectives from 'rollup-plugin-preserve-directives'; + +/** + * A vite config preset for bundling packages in lib mode. + * @param params The parameters that the function takes. + * @param params.lib override vite's `build.lib` options. + * @param params.dts override the `vite-plugin-dts` options. + * @param params.external override the `vite-plugin-external` options. + * @returns a vite configuration object + */ +export function buildConfig({ + lib, + dts = {}, + external = {}, +}: { + lib: LibraryOptions & { + entry: string[] | string; + }; + dts?: DtsPluginOptions; + external?: ExternalPluginOptions; +}) { + return defineConfig({ + plugins: [ + createExternal({ + nodeBuiltins: true, + ...external, + }), + dtsPlugin({ + compilerOptions: { + tsBuildInfoFile: 'tsconfig.build.tsbuildinfo', + outDir: 'dist', + rootDir: 'src', + noEmit: false, + ...dts.compilerOptions, + }, + include: ['src/**/*.ts', 'src/**/*.tsx'], + ...dts, + }), + ], + build: { + sourcemap: true, + rollupOptions: { + plugins: [ + preserveDirectives({ + suppressPreserveModulesWarning: true, + }), + ], + output: { + preserveModules: true, + }, + treeshake: true, + onwarn(warning, defaultHandler) { + if (warning.code === 'SOURCEMAP_ERROR') { + return; + } + + defaultHandler(warning); + }, + }, + lib: { + formats: ['es', 'cjs'], + ...lib, + entry: globbySync(lib.entry), + }, + }, + }); +} diff --git a/packages/config/vite/src/index.ts b/packages/config/vite/src/index.ts new file mode 100644 index 00000000..8453be74 --- /dev/null +++ b/packages/config/vite/src/index.ts @@ -0,0 +1,3 @@ +export * from './mergeConfig.js'; +export * from './build.js'; +export * from './react.js'; diff --git a/packages/config/vite/src/mergeConfig.ts b/packages/config/vite/src/mergeConfig.ts new file mode 100644 index 00000000..c30546d6 --- /dev/null +++ b/packages/config/vite/src/mergeConfig.ts @@ -0,0 +1,7 @@ +import type { UserConfig } from 'vite'; +import { mergeConfig as viteMergeConfig } from 'vite'; + +export const mergeConfig = ( + baseConfig: UserConfig, + overrideConfig: UserConfig, +) => viteMergeConfig(baseConfig, overrideConfig); diff --git a/packages/config/vite/src/react.ts b/packages/config/vite/src/react.ts index a02a332b..afcce7de 100644 --- a/packages/config/vite/src/react.ts +++ b/packages/config/vite/src/react.ts @@ -2,6 +2,6 @@ import react from '@vitejs/plugin-react'; import { defineConfig } from 'vite'; import tsconfigPaths from 'vite-tsconfig-paths'; -export default defineConfig({ +export const reactConfig = defineConfig({ plugins: [react(), tsconfigPaths()], }); diff --git a/packages/env/package.json b/packages/env/package.json index e50d3fdb..335cb27b 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -8,7 +8,8 @@ "sideEffects": false, "type": "module", "exports": { - "./web": "./src/web/index.ts", + "./web/server": "./src/web/server.ts", + "./web/client": "./src/web/client.ts", "./web/db": "./src/web/db.ts", "./marketing": "./src/marketing/index.ts" }, diff --git a/packages/env/src/shared.ts b/packages/env/src/shared.ts index 915e776a..a02f3f31 100644 --- a/packages/env/src/shared.ts +++ b/packages/env/src/shared.ts @@ -7,9 +7,7 @@ export const sharedEnv = createEnv({ shared: { NODE_ENV: z.enum(['development', 'test', 'production']).optional(), }, - experimental__runtimeEnv: { + runtimeEnv: { NODE_ENV: process.env.NODE_ENV, }, - emptyStringAsUndefined: true, - skipValidation: !!process.env['SKIP_ENV_VALIDATION'], }); diff --git a/packages/env/src/web/client.ts b/packages/env/src/web/client.ts new file mode 100644 index 00000000..9648956a --- /dev/null +++ b/packages/env/src/web/client.ts @@ -0,0 +1,15 @@ +import { createEnv } from '@t3-oss/env-nextjs'; +import { z } from 'zod'; + +export const env = createEnv({ + client: { + NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(), + NEXT_PUBLIC_POSTHOG_HOST: z.string().optional(), + }, + experimental__runtimeEnv: { + NEXT_PUBLIC_POSTHOG_KEY: process.env['NEXT_PUBLIC_POSTHOG_KEY'], + NEXT_PUBLIC_POSTHOG_HOST: process.env['NEXT_PUBLIC_POSTHOG_HOST'], + }, + emptyStringAsUndefined: true, + skipValidation: !!process.env['SKIP_ENV_VALIDATION'], +}); diff --git a/packages/env/src/web/index.ts b/packages/env/src/web/server.ts similarity index 63% rename from packages/env/src/web/index.ts rename to packages/env/src/web/server.ts index f57eb8d3..238e101a 100644 --- a/packages/env/src/web/index.ts +++ b/packages/env/src/web/server.ts @@ -1,34 +1,30 @@ import { createEnv } from '@t3-oss/env-nextjs'; import { z } from 'zod'; import { sharedEnv } from '../shared'; +import { env as dbEnv } from './db'; export const env = createEnv({ - extends: [sharedEnv], - server: { + extends: [sharedEnv, dbEnv], + shared: { PORT: z.coerce.number().default(3000), - - DATABASE_URL: z.string().url().startsWith('postgres'), - - UPLOADTHING_SECRET: z.string(), + }, + server: { UPLOADTHING_APP_ID: z.string(), + UPLOADTHING_SECRET: z.string(), UNKEY_ROOT_KEY: z.string().optional(), UNKEY_NAMESPACE: z.string().optional(), + AUTH_SECRET: z.string(), + AUTH_GITHUB_ID: z.string().optional(), AUTH_GITHUB_SECRET: z.string().optional(), AUTH_GOOGLE_ID: z.string().optional(), AUTH_GOOGLE_SECRET: z.string().optional(), - AUTH_GOOGLE_CODE_VERIFIER: z.string().optional(), - }, - client: { - NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(), - NEXT_PUBLIC_POSTHOG_HOST: z.string().optional(), }, experimental__runtimeEnv: { - NEXT_PUBLIC_POSTHOG_KEY: process.env['NEXT_PUBLIC_POSTHOG_KEY'], - NEXT_PUBLIC_POSTHOG_HOST: process.env['NEXT_PUBLIC_POSTHOG_HOST'], + PORT: process.env['PORT'], }, emptyStringAsUndefined: true, skipValidation: !!process.env['SKIP_ENV_VALIDATION'], diff --git a/packages/ui/package.json b/packages/ui/package.json index a5fc0b29..e4d85151 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -9,34 +9,24 @@ "type": "module", "exports": { "./*": { - "import": { - "types": "./dist/primitives/*/index.d.ts", - "default": "./dist/primitives/*/index.js" - }, - "require": { - "types": "./dist/primitives/*/index.d.cts", - "default": "./dist/primitives/*/index.cjs" - } + "types": "./dist/primitives/*/index.d.ts", + "require": "./dist/primitives/*/index.cjs", + "default": "./dist/primitives/*/index.js" }, "./cn": { - "import": { - "types": "./dist/utils/cn.d.ts", - "default": "./dist/utils/cn.js" - }, - "require": { - "types": "./dist/utils/cn.d.cts", - "default": "./dist/utils/cn.cjs" - } + "types": "./dist/utils/cn.d.ts", + "require": "./dist/utils/cn.cjs", + "default": "./dist/utils/cn.js" } }, "files": [ "dist" ], "scripts": { - "build": "tsup", + "build": "vite build", "build-storybook": "storybook build", - "clean": "bun run rm -rf dist .tsup storybook-static *.tsbuildinfo", - "dev": "tsup --watch", + "clean": "bun run rm -rf dist storybook-static *.tsbuildinfo", + "dev": "vite build -w", "lint": "eslint . --max-warnings 0", "storybook": "storybook dev -p 6006 --no-open", "test-storybook": "test-storybook", @@ -81,36 +71,32 @@ "react": "^18.3.1", "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", - "react-hook-form": "^7.51.5", + "react-hook-form": "^7.52.0", "react-resizable-panels": "^2.0.19", "tailwind-merge": "^2.3.0", "vaul": "^0.9.1", "zod": "^3.23.8" }, "devDependencies": { - "@microsoft/api-extractor": "^7.47.0", "@orbitkit/assets": "workspace:^", "@orbitkit/eslint": "workspace:^", "@orbitkit/storybook": "workspace:^", "@orbitkit/tailwind": "workspace:^", "@orbitkit/tsconfig": "workspace:^", - "@orbitkit/utils": "workspace:^", "@orbitkit/vite": "workspace:^", - "@storybook/addon-a11y": "^8.1.7", - "@storybook/addon-essentials": "^8.1.7", - "@storybook/addon-interactions": "^8.1.7", - "@storybook/addon-links": "^8.1.7", - "@storybook/addon-themes": "^8.1.7", - "@storybook/react": "^8.1.7", - "@storybook/test": "^8.1.7", + "@storybook/react": "^8.1.9", + "@storybook/test": "^8.1.9", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "autoprefixer": "^10.4.19", + "globby": "^14.0.1", "playwright": "^1.44.1", "postcss": "^8.4.38", - "storybook": "^8.1.7", + "rollup-plugin-preserve-directives": "^0.4.0", + "storybook": "^8.1.9", "tailwindcss": "^3.4.4", - "tsup": "^8.1.0", - "vite": "^5.2.13" + "vite": "^5.3.1", + "vite-plugin-dts": "^3.9.1", + "vite-plugin-external": "^4.3.1" } } diff --git a/packages/ui/tsconfig.build.json b/packages/ui/tsconfig.build.json deleted file mode 100644 index 27349274..00000000 --- a/packages/ui/tsconfig.build.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "tsBuildInfoFile": "tsconfig.build.tsbuildinfo" - }, - "include": ["**/*.ts", "**/*.tsx"], - "exclude": [ - "dist", - "node_modules", - "storybook-static", - "**/*.stories.tsx", - "src/storybook-utils" - ] -} diff --git a/packages/ui/tsup.config.ts b/packages/ui/tsup.config.ts deleted file mode 100644 index 83b65d8a..00000000 --- a/packages/ui/tsup.config.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { defineConfig } from 'tsup'; - -import { listDirectories } from '@orbitkit/utils/filesystem'; - -/** - * This function generates a list of entries for the build. - * @returns List of entries for tsup. - */ -function getEntries() { - const primitives = listDirectories('./src/primitives').map( - (d) => `./src/primitives/${d.name}/index.tsx`, - ); - - return [...primitives, './src/utils/cn.ts']; -} - -export default defineConfig((opts) => ({ - entry: getEntries(), - format: ['esm', 'cjs'], - splitting: true, - sourcemap: true, - minify: !opts.watch, - experimentalDts: true, - // We need to use a different tsconfig for the build because we need to exclude the story files from being compiled into the .d.ts bundle file. - tsconfig: './tsconfig.build.json', - outDir: 'dist', -})); diff --git a/packages/ui/turbo.json b/packages/ui/turbo.json index f2746720..1a5ccbb5 100644 --- a/packages/ui/turbo.json +++ b/packages/ui/turbo.json @@ -14,8 +14,7 @@ "$TURBO_DEFAULT$", "!CHANGELOG.md", "!eslint.config.js", - "!tsconfig.build.json", - "!tsup.config.ts" + "!tsconfig.build.json" ] } } diff --git a/packages/ui/vite.config.ts b/packages/ui/vite.config.ts index 41f99398..a840e13e 100644 --- a/packages/ui/vite.config.ts +++ b/packages/ui/vite.config.ts @@ -1,7 +1,22 @@ -import { mergeConfig } from 'vite'; +import { reactConfig, buildConfig, mergeConfig } from '@orbitkit/vite'; -import react from '@orbitkit/vite/react'; +import pkg from './package.json'; -export default mergeConfig(react, { - // your custom config & overrides on top here -}); +export default mergeConfig( + // Vite config to support React. + reactConfig, + /** + * This allows us to use vite to also bundle this package using the `vite build` script, it will also emit TS declaration files using the dts plugin. + */ + buildConfig({ + lib: { + entry: ['./src/primitives/*/index.tsx', './src/utils/cn.ts'], + }, + external: { + externalizeDeps: Object.keys(pkg.dependencies), + }, + dts: { + exclude: ['src/storybook-utils', '**/*.stories.tsx'], + }, + }), +); diff --git a/packages/utils/src/filesystem.ts b/packages/utils/src/filesystem.ts index 8d27fdb3..6a5dcf7d 100644 --- a/packages/utils/src/filesystem.ts +++ b/packages/utils/src/filesystem.ts @@ -1,18 +1,5 @@ -/* eslint-disable security/detect-non-literal-fs-filename */ -import { readdirSync, type Dirent } from 'fs'; import { dirname, join } from 'path'; -/** - * This function lists all directories in a given path. - * @param path The path to the parent directory - * @returns A list of directory names in the parent directory - */ -export function listDirectories(path: string): Dirent[] { - return readdirSync(path, { withFileTypes: true }).filter((d) => - d.isDirectory(), - ); -} - /** * This function is used to resolve the absolute path of a package. It is needed * in projects that use Yarn PnP or are set up within a monorepo. @@ -22,4 +9,3 @@ export function listDirectories(path: string): Dirent[] { export function getAbsolutePath(value: string) { return dirname(require.resolve(join(value, 'package.json'))); } -/* eslint-enable security/detect-non-literal-fs-filename */