From 23c74cad0a876c02dc49519f886c2c2ece9abb6e Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 4 Apr 2024 23:12:49 +0700 Subject: [PATCH 01/14] chore(route-manifest): Add relativeFilePath to route manifest (#10416) --- packages/internal/src/routes.ts | 2 +- packages/vite/src/buildRouteManifest.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/internal/src/routes.ts b/packages/internal/src/routes.ts index 8f4935797793..c30903165db6 100644 --- a/packages/internal/src/routes.ts +++ b/packages/internal/src/routes.ts @@ -71,8 +71,8 @@ export interface RWRouteManifestItem { routeHooks: string | null bundle: string | null hasParams: boolean + relativeFilePath: string | undefined redirect: { to: string; permanent: boolean } | null - renderMode: 'html' | 'stream' // Probably want isNotFound here, so we can attach a separate 404 handler } diff --git a/packages/vite/src/buildRouteManifest.ts b/packages/vite/src/buildRouteManifest.ts index bbc5f6aa2665..2c518595d444 100644 --- a/packages/vite/src/buildRouteManifest.ts +++ b/packages/vite/src/buildRouteManifest.ts @@ -46,7 +46,7 @@ export async function buildRouteManifest() { permanent: false, } : null, - renderMode: route.renderMode, + relativeFilePath: route.relativeFilePath, } return acc From 93f36239c3f202f824a7a4b34dfb5b02fab7d9b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 22:55:01 +0100 Subject: [PATCH 02/14] chore(deps): bump undici from 5.28.3 to 5.28.4 in /.github/actions/check_changesets (#10421) Bumps [undici](https://github.com/nodejs/undici) from 5.28.3 to 5.28.4.
Release notes

Sourced from undici's releases.

v5.28.4

:warning: Security Release :warning:

Full Changelog: https://github.com/nodejs/undici/compare/v5.28.3...v5.28.4

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=undici&package-manager=npm_and_yarn&previous-version=5.28.3&new-version=5.28.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/redwoodjs/redwood/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/check_changesets/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/check_changesets/yarn.lock b/.github/actions/check_changesets/yarn.lock index d89dca47afe7..737ac337e013 100644 --- a/.github/actions/check_changesets/yarn.lock +++ b/.github/actions/check_changesets/yarn.lock @@ -205,11 +205,11 @@ __metadata: linkType: hard "undici@npm:^5.25.4": - version: 5.28.3 - resolution: "undici@npm:5.28.3" + version: 5.28.4 + resolution: "undici@npm:5.28.4" dependencies: "@fastify/busboy": "npm:^2.0.0" - checksum: 10c0/3c559ae50ef3104b7085251445dda6f4de871553b9e290845649d2f80b06c0c9cfcdf741b0029c6b20d36c82e6a74dc815b139fa9a26757d70728074ca6d6f5c + checksum: 10c0/08d0f2596553aa0a54ca6e8e9c7f45aef7d042c60918564e3a142d449eda165a80196f6ef19ea2ef2e6446959e293095d8e40af1236f0d67223b06afac5ecad7 languageName: node linkType: hard From f499e8603726e1a5ad9580bb33953eb633574244 Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Fri, 5 Apr 2024 14:21:13 +0200 Subject: [PATCH 03/14] chore(whatwg-fetch): Switch to importing instead of requiring (#10424) --- packages/auth/src/__tests__/AuthProvider.test.tsx | 3 ++- packages/testing/src/web/__tests__/MockHandlers.test.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/auth/src/__tests__/AuthProvider.test.tsx b/packages/auth/src/__tests__/AuthProvider.test.tsx index bad662ad8235..18aabac61f17 100644 --- a/packages/auth/src/__tests__/AuthProvider.test.tsx +++ b/packages/auth/src/__tests__/AuthProvider.test.tsx @@ -1,4 +1,4 @@ -require('whatwg-fetch') +// require('whatwg-fetch') import React, { useEffect, useState } from 'react' @@ -13,6 +13,7 @@ import { renderHook, act } from '@testing-library/react' import '@testing-library/jest-dom/jest-globals' import { graphql } from 'msw' import { setupServer } from 'msw/node' +import 'whatwg-fetch' import type { CustomTestAuthClient } from './fixtures/customTestAuth' import { createCustomTestAuth } from './fixtures/customTestAuth' diff --git a/packages/testing/src/web/__tests__/MockHandlers.test.tsx b/packages/testing/src/web/__tests__/MockHandlers.test.tsx index 55e86bb97aa3..1d1ad73c60c9 100644 --- a/packages/testing/src/web/__tests__/MockHandlers.test.tsx +++ b/packages/testing/src/web/__tests__/MockHandlers.test.tsx @@ -1,8 +1,8 @@ -import 'whatwg-fetch' import React, { useCallback, useState } from 'react' import { render, screen, fireEvent, waitFor } from '@testing-library/react' import { vi, describe, it, expect } from 'vitest' +import 'whatwg-fetch' import { mockGraphQLQuery } from '../mockRequests' From a44da7556d45129c87dc1753953bd81bca136a5e Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Fri, 5 Apr 2024 16:07:12 +0200 Subject: [PATCH 04/14] chore(test): Switch rwjs/auth over to vitest (#10423) --- .vscode/settings.json | 1 + packages/auth/jest.config.js | 5 -- packages/auth/modules.d.ts | 1 + packages/auth/package.json | 11 ++-- .../auth/src/__tests__/AuthProvider.test.tsx | 59 ++++++++++++------- .../src/__tests__/fixtures/customTestAuth.ts | 2 +- packages/auth/tsconfig.build.json | 8 +++ packages/auth/tsconfig.json | 12 +++- packages/auth/vitest.config.ts | 9 +++ packages/auth/vitest.setup.ts | 11 ++++ yarn.lock | 3 +- 11 files changed, 84 insertions(+), 38 deletions(-) delete mode 100644 packages/auth/jest.config.js create mode 100644 packages/auth/modules.d.ts create mode 100644 packages/auth/tsconfig.build.json create mode 100644 packages/auth/vitest.config.ts create mode 100644 packages/auth/vitest.setup.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 53cfbc6d3cc9..2ee344962552 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,6 +32,7 @@ "memfs", "opentelemetry", "pino", + "Pistorius", "redwoodjs", "RWJS", "tailwindcss", diff --git a/packages/auth/jest.config.js b/packages/auth/jest.config.js deleted file mode 100644 index e691bb8f6dbd..000000000000 --- a/packages/auth/jest.config.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @type {import('@jest/types').Config.InitialOptions} */ -module.exports = { - testEnvironment: 'jest-environment-jsdom', - testPathIgnorePatterns: ['fixtures', 'dist'], -} diff --git a/packages/auth/modules.d.ts b/packages/auth/modules.d.ts new file mode 100644 index 000000000000..574a2b1aa368 --- /dev/null +++ b/packages/auth/modules.d.ts @@ -0,0 +1 @@ +declare module 'whatwg-fetch' diff --git a/packages/auth/package.json b/packages/auth/package.json index dd8ba5b1fd61..b3c1164d5b5c 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -16,11 +16,11 @@ "build": "yarn build:js && yarn build:types", "build:js": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\"", "build:pack": "yarn pack -o redwoodjs-auth.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose tsconfig.build.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"", "prepublishOnly": "NODE_ENV=production yarn build", - "test": "jest src", - "test:watch": "yarn test --watch" + "test": "vitest run", + "test:watch": "vitest watch" }, "dependencies": { "@babel/runtime-corejs3": "7.24.1", @@ -32,10 +32,9 @@ "@babel/core": "^7.22.20", "@testing-library/jest-dom": "6.4.2", "@testing-library/react": "14.2.2", - "jest": "29.7.0", - "jest-environment-jsdom": "29.7.0", "msw": "1.3.3", - "typescript": "5.4.3" + "typescript": "5.4.3", + "vitest": "1.4.0" }, "gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1" } diff --git a/packages/auth/src/__tests__/AuthProvider.test.tsx b/packages/auth/src/__tests__/AuthProvider.test.tsx index 18aabac61f17..082f3032de06 100644 --- a/packages/auth/src/__tests__/AuthProvider.test.tsx +++ b/packages/auth/src/__tests__/AuthProvider.test.tsx @@ -1,19 +1,36 @@ -// require('whatwg-fetch') - import React, { useEffect, useState } from 'react' import { + act, render, + renderHook, screen, fireEvent, waitFor, configure, } from '@testing-library/react' -import { renderHook, act } from '@testing-library/react' -import '@testing-library/jest-dom/jest-globals' import { graphql } from 'msw' import { setupServer } from 'msw/node' -import 'whatwg-fetch' +import { + afterAll, + beforeAll, + beforeEach, + describe, + expect, + test, + vi, +} from 'vitest' +import { + fetch as fetchPolyfill, + Headers as HeadersPolyfill, + Request as RequestPolyfill, + Response as ResponsePolyfill, +} from 'whatwg-fetch' + +globalThis.fetch = fetchPolyfill +globalThis.Headers = HeadersPolyfill +globalThis.Request = RequestPolyfill +globalThis.Response = ResponsePolyfill import type { CustomTestAuthClient } from './fixtures/customTestAuth' import { createCustomTestAuth } from './fixtures/customTestAuth' @@ -62,7 +79,7 @@ const customTestAuth: CustomTestAuthClient = { signup: () => {}, logout: () => {}, getToken: () => 'hunter2', - getUserMetadata: jest.fn(() => null), + getUserMetadata: vi.fn(() => null), forgotPassword: () => {}, resetPassword: () => true, validateResetToken: () => ({}), @@ -83,7 +100,7 @@ beforeEach(() => { name: 'Peter Pistorius', email: 'nospam@example.net', } - customTestAuth.getUserMetadata = jest.fn(() => null) + customTestAuth.getUserMetadata = vi.fn(() => null) }) describe('Custom auth provider', () => { @@ -177,7 +194,7 @@ describe('Custom auth provider', () => { expect(mockAuthClient.getUserMetadata).toBeCalledTimes(1) // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -222,7 +239,7 @@ describe('Custom auth provider', () => { expect(mockAuthClient.getUserMetadata).toBeCalledTimes(1) // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -257,7 +274,7 @@ describe('Custom auth provider', () => { expect(mockAuthClient.getUserMetadata).toBeCalledTimes(1) // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -294,7 +311,7 @@ describe('Custom auth provider', () => { ) const mockAuthClient = customTestAuth - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -343,7 +360,7 @@ describe('Custom auth provider', () => { expect(screen.queryByText('Has Super User:')).not.toBeInTheDocument() // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -390,7 +407,7 @@ describe('Custom auth provider', () => { expect(screen.queryByText('Has Super User:')).not.toBeInTheDocument() // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -437,7 +454,7 @@ describe('Custom auth provider', () => { expect(screen.queryByText('Has Super User:')).not.toBeInTheDocument() // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -484,7 +501,7 @@ describe('Custom auth provider', () => { expect(screen.queryByText('Has Super User:')).not.toBeInTheDocument() // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -530,7 +547,7 @@ describe('Custom auth provider', () => { expect(screen.queryByText('Has Super User:')).not.toBeInTheDocument() // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -573,7 +590,7 @@ describe('Custom auth provider', () => { expect(screen.queryByText('Has Super User:')).not.toBeInTheDocument() // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -620,7 +637,7 @@ describe('Custom auth provider', () => { expect(screen.queryByText('Has Super User:')).not.toBeInTheDocument() // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -666,7 +683,7 @@ describe('Custom auth provider', () => { expect(screen.queryByText('Has Super User:')).not.toBeInTheDocument() // Replace "getUserMetadata" with actual data, and login! - mockAuthClient.getUserMetadata = jest.fn(() => { + mockAuthClient.getUserMetadata = vi.fn(() => { return { sub: 'abcdefg|123456', username: 'peterp', @@ -687,7 +704,7 @@ describe('Custom auth provider', () => { }) test('proxies forgotPassword() calls to client', async () => { - const mockedForgotPassword = jest.spyOn(customTestAuth, 'forgotPassword') + const mockedForgotPassword = vi.spyOn(customTestAuth, 'forgotPassword') mockedForgotPassword.mockImplementation((username: string) => { expect(username).toEqual('username') }) @@ -750,7 +767,7 @@ describe('Custom auth provider', () => { }) test("getToken doesn't fail if client throws an error", async () => { - customTestAuth.getToken = jest.fn(() => { + customTestAuth.getToken = vi.fn(() => { throw 'Login Required' }) diff --git a/packages/auth/src/__tests__/fixtures/customTestAuth.ts b/packages/auth/src/__tests__/fixtures/customTestAuth.ts index 6536c4eee079..9592f6d5465e 100644 --- a/packages/auth/src/__tests__/fixtures/customTestAuth.ts +++ b/packages/auth/src/__tests__/fixtures/customTestAuth.ts @@ -1,4 +1,4 @@ -import { CurrentUser, createAuthentication } from '../../index' +import { CurrentUser, createAuthentication } from '../../index.js' interface User { sub: string diff --git a/packages/auth/tsconfig.build.json b/packages/auth/tsconfig.build.json new file mode 100644 index 000000000000..9a2c0dd67621 --- /dev/null +++ b/packages/auth/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.compilerOption.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + }, + "include": ["src", "ambient.d.ts"], +} diff --git a/packages/auth/tsconfig.json b/packages/auth/tsconfig.json index 35c7dc051767..fc87e25a7c7d 100644 --- a/packages/auth/tsconfig.json +++ b/packages/auth/tsconfig.json @@ -1,8 +1,14 @@ { "extends": "../../tsconfig.compilerOption.json", "compilerOptions": { - "rootDir": "src", - "outDir": "dist", + "outDir": "dist" }, - "include": ["src", "ambient.d.ts"] + "include": [ + "src", + "ambient.d.ts", + "modules.d.ts", + "./vitest.setup.ts", + "__tests__" + ], + "exclude": ["dist", "node_modules", "**/__mocks__", "**/__fixtures__"] } diff --git a/packages/auth/vitest.config.ts b/packages/auth/vitest.config.ts new file mode 100644 index 000000000000..a832fed4d8b8 --- /dev/null +++ b/packages/auth/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig, configDefaults } from 'vitest/config' + +export default defineConfig({ + test: { + exclude: [...configDefaults.exclude, '**/fixtures'], + environment: 'jsdom', + setupFiles: ['vitest.setup.ts'], + }, +}) diff --git a/packages/auth/vitest.setup.ts b/packages/auth/vitest.setup.ts new file mode 100644 index 000000000000..5b6e47c1e415 --- /dev/null +++ b/packages/auth/vitest.setup.ts @@ -0,0 +1,11 @@ +import { cleanup } from '@testing-library/react' +import { afterEach } from 'vitest' +import '@testing-library/jest-dom/vitest' + +afterEach(() => { + // If vitest globals are enabled testing-library will clean up after each + // test automatically, but we don't enable globals, so we have to manually + // clean up here + // https://testing-library.com/docs/react-testing-library/api/#cleanup + cleanup() +}) diff --git a/yarn.lock b/yarn.lock index 7e8758897c43..45c81383a972 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7952,11 +7952,10 @@ __metadata: "@testing-library/jest-dom": "npm:6.4.2" "@testing-library/react": "npm:14.2.2" core-js: "npm:3.36.1" - jest: "npm:29.7.0" - jest-environment-jsdom: "npm:29.7.0" msw: "npm:1.3.3" react: "npm:18.3.0-canary-a870b2d54-20240314" typescript: "npm:5.4.3" + vitest: "npm:1.4.0" languageName: unknown linkType: soft From 9245b7449aca6f39c8934a5dc7bd4dc6bb1bd6fe Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Sat, 6 Apr 2024 17:50:36 +0200 Subject: [PATCH 05/14] chore(framework-tools): Warn about missing metafile (#10426) --- packages/framework-tools/src/buildDefaults.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/framework-tools/src/buildDefaults.ts b/packages/framework-tools/src/buildDefaults.ts index 3f6222a14af5..d292442b6d74 100644 --- a/packages/framework-tools/src/buildDefaults.ts +++ b/packages/framework-tools/src/buildDefaults.ts @@ -71,7 +71,15 @@ export async function build({ ...buildOptions, }) - await fs.writeJSON(path.join(cwd, metafileName), result.metafile, { - spaces: 2, - }) + if (result.metafile) { + await fs.writeJSON(path.join(cwd, metafileName), result.metafile, { + spaces: 2, + }) + } else { + console.warn("No metafile found in esbuild's result.") + console.warn( + 'This is unexpected and probably means something is wrong with the ' + + 'build.', + ) + } } From a148f516b3cb9a91f83693e2225721f77200d43c Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Sun, 7 Apr 2024 15:42:12 +0200 Subject: [PATCH 06/14] chore(auth): Convert `@redwoodjs/auth` to ESM+CJS dual build (#10417) Co-authored-by: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> --- .../auth-providers/supabase/web/package.json | 1 + packages/auth/.babelrc.js | 1 - packages/auth/build.ts | 36 +++++++++++++++++++ packages/auth/package.json | 17 +++++---- .../auth/src/AuthProvider/AuthProvider.tsx | 30 ++++++++-------- .../src/AuthProvider/AuthProviderState.ts | 2 +- .../src/AuthProvider/ServerAuthProvider.tsx | 4 +-- .../auth/src/AuthProvider/useCurrentUser.ts | 4 +-- .../src/AuthProvider/useForgotPassword.ts | 2 +- packages/auth/src/AuthProvider/useHasRole.ts | 2 +- packages/auth/src/AuthProvider/useLogIn.ts | 10 +++--- packages/auth/src/AuthProvider/useLogOut.ts | 4 +-- .../src/AuthProvider/useReauthenticate.ts | 8 ++--- .../auth/src/AuthProvider/useResetPassword.ts | 2 +- packages/auth/src/AuthProvider/useSignUp.ts | 8 ++--- packages/auth/src/AuthProvider/useToken.ts | 2 +- .../src/AuthProvider/useValidateResetToken.ts | 2 +- .../auth/src/__tests__/AuthProvider.test.tsx | 4 +-- packages/auth/src/authFactory.ts | 10 +++--- packages/auth/src/index.ts | 13 +++---- packages/auth/src/useAuth.ts | 2 +- packages/auth/tsconfig.build-esm.json | 14 ++++++++ packages/auth/tsconfig.build.json | 6 ++++ packages/auth/tsconfig.json | 8 ++++- packages/testing/src/web/mockAuth.tsx | 2 +- yarn.lock | 6 ++-- 26 files changed, 133 insertions(+), 67 deletions(-) delete mode 100644 packages/auth/.babelrc.js create mode 100644 packages/auth/build.ts create mode 100644 packages/auth/tsconfig.build-esm.json diff --git a/packages/auth-providers/supabase/web/package.json b/packages/auth-providers/supabase/web/package.json index be6238f9776c..d9244119c6ce 100644 --- a/packages/auth-providers/supabase/web/package.json +++ b/packages/auth-providers/supabase/web/package.json @@ -24,6 +24,7 @@ }, "dependencies": { "@babel/runtime-corejs3": "7.24.1", + "@redwoodjs/auth": "workspace:*", "core-js": "3.36.1" }, "devDependencies": { diff --git a/packages/auth/.babelrc.js b/packages/auth/.babelrc.js deleted file mode 100644 index 3b2c815712d9..000000000000 --- a/packages/auth/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../babel.config.js' } diff --git a/packages/auth/build.ts b/packages/auth/build.ts new file mode 100644 index 000000000000..c859e8581af0 --- /dev/null +++ b/packages/auth/build.ts @@ -0,0 +1,36 @@ +import { renameSync, writeFileSync } from 'node:fs' + +import { build, defaultBuildOptions } from '@redwoodjs/framework-tools' + +// ESM build +await build({ + buildOptions: { + ...defaultBuildOptions, + tsconfig: 'tsconfig.build-esm.json', + format: 'esm', + outdir: 'dist/esm', + packages: 'external', + }, +}) + +// CJS build +await build({ + buildOptions: { + ...defaultBuildOptions, + tsconfig: 'tsconfig.build.json', + packages: 'external', + }, +}) + +// Because the package.json files has `type: module` the CJS entry file can't +// be named `index.js` because in that case it would be treated as an ESM file. +// By changing it to .cjs it will be treated as a CommonJS file. +renameSync('dist/index.js', 'dist/index.cjs') + +// Place a package.json file with `type: commonjs` in the dist folder so that +// all .js files are treated as CommonJS files. +writeFileSync('dist/package.json', JSON.stringify({ type: 'commonjs' })) + +// Place a package.json file with `type: module` in the dist/esm folder so that +// all .js files are treated as ES Module files. +writeFileSync('dist/esm/package.json', JSON.stringify({ type: 'module' })) diff --git a/packages/auth/package.json b/packages/auth/package.json index b3c1164d5b5c..b60ee36b3145 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -7,32 +7,35 @@ "directory": "packages/auth" }, "license": "MIT", - "main": "./dist/index.js", + "type": "module", + "exports": { + "types": "./dist/esm/index.d.ts", + "import": "./dist/esm/index.js", + "default": "./dist/index.cjs" + }, "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { - "build": "yarn build:js && yarn build:types", - "build:js": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\"", + "build": "tsx ./build.ts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth.tgz", - "build:types": "tsc --build --verbose tsconfig.build.json", + "build:types": "tsc --build --verbose tsconfig.build.json && tsc --build --verbose tsconfig.build-esm.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.24.1", "core-js": "3.36.1", "react": "18.3.0-canary-a870b2d54-20240314" }, "devDependencies": { - "@babel/cli": "7.24.1", - "@babel/core": "^7.22.20", + "@redwoodjs/framework-tools": "workspace:*", "@testing-library/jest-dom": "6.4.2", "@testing-library/react": "14.2.2", "msw": "1.3.3", + "tsx": "4.7.1", "typescript": "5.4.3", "vitest": "1.4.0" }, diff --git a/packages/auth/src/AuthProvider/AuthProvider.tsx b/packages/auth/src/AuthProvider/AuthProvider.tsx index 1a0b17fe99d8..d992c05c4fb6 100644 --- a/packages/auth/src/AuthProvider/AuthProvider.tsx +++ b/packages/auth/src/AuthProvider/AuthProvider.tsx @@ -1,22 +1,22 @@ import type { ReactNode } from 'react' import React, { useContext, useEffect, useState } from 'react' -import type { AuthContextInterface, CurrentUser } from '../AuthContext' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthContextInterface, CurrentUser } from '../AuthContext.js' +import type { AuthImplementation } from '../AuthImplementation.js' -import type { AuthProviderState } from './AuthProviderState' -import { defaultAuthProviderState } from './AuthProviderState' -import { ServerAuthContext } from './ServerAuthProvider' -import { useCurrentUser } from './useCurrentUser' -import { useForgotPassword } from './useForgotPassword' -import { useHasRole } from './useHasRole' -import { useLogIn } from './useLogIn' -import { useLogOut } from './useLogOut' -import { useReauthenticate } from './useReauthenticate' -import { useResetPassword } from './useResetPassword' -import { useSignUp } from './useSignUp' -import { useToken } from './useToken' -import { useValidateResetToken } from './useValidateResetToken' +import type { AuthProviderState } from './AuthProviderState.js' +import { defaultAuthProviderState } from './AuthProviderState.js' +import { ServerAuthContext } from './ServerAuthProvider.js' +import { useCurrentUser } from './useCurrentUser.js' +import { useForgotPassword } from './useForgotPassword.js' +import { useHasRole } from './useHasRole.js' +import { useLogIn } from './useLogIn.js' +import { useLogOut } from './useLogOut.js' +import { useReauthenticate } from './useReauthenticate.js' +import { useResetPassword } from './useResetPassword.js' +import { useSignUp } from './useSignUp.js' +import { useToken } from './useToken.js' +import { useValidateResetToken } from './useValidateResetToken.js' export interface AuthProviderProps { skipFetchCurrentUser?: boolean diff --git a/packages/auth/src/AuthProvider/AuthProviderState.ts b/packages/auth/src/AuthProvider/AuthProviderState.ts index f9dbe07c02ff..3bcaa6ed6035 100644 --- a/packages/auth/src/AuthProvider/AuthProviderState.ts +++ b/packages/auth/src/AuthProvider/AuthProviderState.ts @@ -1,4 +1,4 @@ -import type { CurrentUser } from '../AuthContext' +import type { CurrentUser } from '../AuthContext.js' export type AuthProviderState = { loading: boolean diff --git a/packages/auth/src/AuthProvider/ServerAuthProvider.tsx b/packages/auth/src/AuthProvider/ServerAuthProvider.tsx index b9ca2e8364a2..c90f568fab15 100644 --- a/packages/auth/src/AuthProvider/ServerAuthProvider.tsx +++ b/packages/auth/src/AuthProvider/ServerAuthProvider.tsx @@ -1,8 +1,8 @@ import type { ReactNode } from 'react' import React from 'react' -import type { AuthProviderState } from './AuthProviderState' -import { defaultAuthProviderState } from './AuthProviderState' +import type { AuthProviderState } from './AuthProviderState.js' +import { defaultAuthProviderState } from './AuthProviderState.js' export type ServerAuthState = AuthProviderState & { cookieHeader?: string diff --git a/packages/auth/src/AuthProvider/useCurrentUser.ts b/packages/auth/src/AuthProvider/useCurrentUser.ts index bd385c9bc1cb..480528a9f33d 100644 --- a/packages/auth/src/AuthProvider/useCurrentUser.ts +++ b/packages/auth/src/AuthProvider/useCurrentUser.ts @@ -1,8 +1,8 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' -import { useToken } from './useToken' +import { useToken } from './useToken.js' export const useCurrentUser = (authImplementation: AuthImplementation) => { const getToken = useToken(authImplementation) diff --git a/packages/auth/src/AuthProvider/useForgotPassword.ts b/packages/auth/src/AuthProvider/useForgotPassword.ts index 7589648c735f..945e7a9c303c 100644 --- a/packages/auth/src/AuthProvider/useForgotPassword.ts +++ b/packages/auth/src/AuthProvider/useForgotPassword.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' export const useForgotPassword = < TUser, diff --git a/packages/auth/src/AuthProvider/useHasRole.ts b/packages/auth/src/AuthProvider/useHasRole.ts index fd324c40bf1c..0201baddb055 100644 --- a/packages/auth/src/AuthProvider/useHasRole.ts +++ b/packages/auth/src/AuthProvider/useHasRole.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react' -import type { CurrentUser } from '../AuthContext' +import type { CurrentUser } from '../AuthContext.js' export const useHasRole = (currentUser: CurrentUser | null) => { /** diff --git a/packages/auth/src/AuthProvider/useLogIn.ts b/packages/auth/src/AuthProvider/useLogIn.ts index 9e9515b6b0a0..80c556106533 100644 --- a/packages/auth/src/AuthProvider/useLogIn.ts +++ b/packages/auth/src/AuthProvider/useLogIn.ts @@ -1,11 +1,11 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' -import type { AuthProviderState } from './AuthProviderState' -import { defaultAuthProviderState } from './AuthProviderState' -import type { useCurrentUser } from './useCurrentUser' -import { useReauthenticate } from './useReauthenticate' +import type { AuthProviderState } from './AuthProviderState.js' +import { defaultAuthProviderState } from './AuthProviderState.js' +import type { useCurrentUser } from './useCurrentUser.js' +import { useReauthenticate } from './useReauthenticate.js' export const useLogIn = < TUser, diff --git a/packages/auth/src/AuthProvider/useLogOut.ts b/packages/auth/src/AuthProvider/useLogOut.ts index a5d0b942db23..e7306eb06676 100644 --- a/packages/auth/src/AuthProvider/useLogOut.ts +++ b/packages/auth/src/AuthProvider/useLogOut.ts @@ -1,8 +1,8 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' -import type { AuthProviderState } from './AuthProviderState' +import type { AuthProviderState } from './AuthProviderState.js' export const useLogOut = < TUser, diff --git a/packages/auth/src/AuthProvider/useReauthenticate.ts b/packages/auth/src/AuthProvider/useReauthenticate.ts index 11de939fa017..6837628e5e3b 100644 --- a/packages/auth/src/AuthProvider/useReauthenticate.ts +++ b/packages/auth/src/AuthProvider/useReauthenticate.ts @@ -1,10 +1,10 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' -import type { AuthProviderState } from './AuthProviderState' -import type { useCurrentUser } from './useCurrentUser' -import { useToken } from './useToken' +import type { AuthProviderState } from './AuthProviderState.js' +import type { useCurrentUser } from './useCurrentUser.js' +import { useToken } from './useToken.js' const notAuthenticatedState = { isAuthenticated: false, diff --git a/packages/auth/src/AuthProvider/useResetPassword.ts b/packages/auth/src/AuthProvider/useResetPassword.ts index 9ce8c4587f3c..162994e3294c 100644 --- a/packages/auth/src/AuthProvider/useResetPassword.ts +++ b/packages/auth/src/AuthProvider/useResetPassword.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' export const useResetPassword = < TUser, diff --git a/packages/auth/src/AuthProvider/useSignUp.ts b/packages/auth/src/AuthProvider/useSignUp.ts index 596cd8155f05..3fc97a8020a0 100644 --- a/packages/auth/src/AuthProvider/useSignUp.ts +++ b/packages/auth/src/AuthProvider/useSignUp.ts @@ -1,10 +1,10 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' -import type { AuthProviderState } from './AuthProviderState' -import type { useCurrentUser } from './useCurrentUser' -import { useReauthenticate } from './useReauthenticate' +import type { AuthProviderState } from './AuthProviderState.js' +import type { useCurrentUser } from './useCurrentUser.js' +import { useReauthenticate } from './useReauthenticate.js' export const useSignUp = < TUser, diff --git a/packages/auth/src/AuthProvider/useToken.ts b/packages/auth/src/AuthProvider/useToken.ts index 10ba69b51635..9e17e0cac997 100644 --- a/packages/auth/src/AuthProvider/useToken.ts +++ b/packages/auth/src/AuthProvider/useToken.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' export const useToken = (authImplementation: AuthImplementation) => { return useCallback(async () => { diff --git a/packages/auth/src/AuthProvider/useValidateResetToken.ts b/packages/auth/src/AuthProvider/useValidateResetToken.ts index f7ea795f3d86..eeafd5a3c9f6 100644 --- a/packages/auth/src/AuthProvider/useValidateResetToken.ts +++ b/packages/auth/src/AuthProvider/useValidateResetToken.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react' -import type { AuthImplementation } from '../AuthImplementation' +import type { AuthImplementation } from '../AuthImplementation.js' export const useValidateResetToken = < TUser, diff --git a/packages/auth/src/__tests__/AuthProvider.test.tsx b/packages/auth/src/__tests__/AuthProvider.test.tsx index 082f3032de06..444a3b2ec37a 100644 --- a/packages/auth/src/__tests__/AuthProvider.test.tsx +++ b/packages/auth/src/__tests__/AuthProvider.test.tsx @@ -32,8 +32,8 @@ globalThis.Headers = HeadersPolyfill globalThis.Request = RequestPolyfill globalThis.Response = ResponsePolyfill -import type { CustomTestAuthClient } from './fixtures/customTestAuth' -import { createCustomTestAuth } from './fixtures/customTestAuth' +import type { CustomTestAuthClient } from './fixtures/customTestAuth.js' +import { createCustomTestAuth } from './fixtures/customTestAuth.js' configure({ asyncUtilTimeout: 5_000, diff --git a/packages/auth/src/authFactory.ts b/packages/auth/src/authFactory.ts index 33c00aa5732d..ec909c729108 100644 --- a/packages/auth/src/authFactory.ts +++ b/packages/auth/src/authFactory.ts @@ -1,8 +1,8 @@ -import type { CurrentUser } from './AuthContext' -import { createAuthContext } from './AuthContext' -import type { AuthImplementation } from './AuthImplementation' -import { createAuthProvider } from './AuthProvider/AuthProvider' -import { createUseAuth } from './useAuth' +import type { CurrentUser } from './AuthContext.js' +import { createAuthContext } from './AuthContext.js' +import type { AuthImplementation } from './AuthImplementation.js' +import { createAuthProvider } from './AuthProvider/AuthProvider.js' +import { createUseAuth } from './useAuth.js' export function createAuthentication< TUser, diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts index 14a8cc83fbba..3f0f49c51925 100644 --- a/packages/auth/src/index.ts +++ b/packages/auth/src/index.ts @@ -1,7 +1,8 @@ -export { AuthContextInterface, CurrentUser } from './AuthContext' -export { useNoAuth, UseAuth } from './useAuth' -export { createAuthentication } from './authFactory' -export type { AuthImplementation } from './AuthImplementation' +export type { AuthContextInterface, CurrentUser } from './AuthContext.js' +export { useNoAuth } from './useAuth.js' +export type { UseAuth } from './useAuth.js' +export { createAuthentication } from './authFactory.js' +export type { AuthImplementation } from './AuthImplementation.js' -export * from './AuthProvider/AuthProviderState' -export * from './AuthProvider/ServerAuthProvider' +export * from './AuthProvider/AuthProviderState.js' +export * from './AuthProvider/ServerAuthProvider.js' diff --git a/packages/auth/src/useAuth.ts b/packages/auth/src/useAuth.ts index 301aa66877b8..80b74f92bdc7 100644 --- a/packages/auth/src/useAuth.ts +++ b/packages/auth/src/useAuth.ts @@ -1,6 +1,6 @@ import React from 'react' -import type { AuthContextInterface } from './AuthContext' +import type { AuthContextInterface } from './AuthContext.js' export function createUseAuth< TUser, diff --git a/packages/auth/tsconfig.build-esm.json b/packages/auth/tsconfig.build-esm.json new file mode 100644 index 000000000000..de5a45368b9e --- /dev/null +++ b/packages/auth/tsconfig.build-esm.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.compilerOption.json", + "compilerOptions": { + "isolatedModules": true, + "moduleResolution": "NodeNext", + "module": "NodeNext", + "rootDir": "src", + "outDir": "dist/esm", + }, + "include": ["src", "ambient.d.ts"], + "references": [ + { "path": "../framework-tools" } + ] +} diff --git a/packages/auth/tsconfig.build.json b/packages/auth/tsconfig.build.json index 9a2c0dd67621..6cb547bce6f0 100644 --- a/packages/auth/tsconfig.build.json +++ b/packages/auth/tsconfig.build.json @@ -1,8 +1,14 @@ { "extends": "../../tsconfig.compilerOption.json", "compilerOptions": { + "isolatedModules": true, + "moduleResolution": "NodeNext", + "module": "NodeNext", "rootDir": "src", "outDir": "dist", }, "include": ["src", "ambient.d.ts"], + "references": [ + { "path": "../framework-tools" } + ] } diff --git a/packages/auth/tsconfig.json b/packages/auth/tsconfig.json index fc87e25a7c7d..d435973639c6 100644 --- a/packages/auth/tsconfig.json +++ b/packages/auth/tsconfig.json @@ -1,6 +1,9 @@ { "extends": "../../tsconfig.compilerOption.json", "compilerOptions": { + "isolatedModules": true, + "moduleResolution": "NodeNext", + "module": "NodeNext", "outDir": "dist" }, "include": [ @@ -10,5 +13,8 @@ "./vitest.setup.ts", "__tests__" ], - "exclude": ["dist", "node_modules", "**/__mocks__", "**/__fixtures__"] + "exclude": ["dist", "node_modules", "**/__mocks__", "**/__fixtures__"], + "references": [ + { "path": "../framework-tools" } + ] } diff --git a/packages/testing/src/web/mockAuth.tsx b/packages/testing/src/web/mockAuth.tsx index 1624f98bc473..0d27ed7c6e42 100644 --- a/packages/testing/src/web/mockAuth.tsx +++ b/packages/testing/src/web/mockAuth.tsx @@ -2,7 +2,7 @@ import React from 'react' // Exporting everything here, but exports further down in this file will // override exports with the same name -export * from '@redwoodjs/auth/dist/index' +export * from '@redwoodjs/auth' import { mockedUserMeta } from './mockRequests' diff --git a/yarn.lock b/yarn.lock index 45c81383a972..2e87107a8bd7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7877,6 +7877,7 @@ __metadata: "@babel/cli": "npm:7.24.1" "@babel/core": "npm:^7.22.20" "@babel/runtime-corejs3": "npm:7.24.1" + "@redwoodjs/auth": "workspace:*" "@supabase/supabase-js": "npm:2.40.0" "@types/react": "npm:^18.2.55" core-js: "npm:3.36.1" @@ -7946,14 +7947,13 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth@workspace:packages/auth" dependencies: - "@babel/cli": "npm:7.24.1" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.24.1" + "@redwoodjs/framework-tools": "workspace:*" "@testing-library/jest-dom": "npm:6.4.2" "@testing-library/react": "npm:14.2.2" core-js: "npm:3.36.1" msw: "npm:1.3.3" react: "npm:18.3.0-canary-a870b2d54-20240314" + tsx: "npm:4.7.1" typescript: "npm:5.4.3" vitest: "npm:1.4.0" languageName: unknown From bc5781bcf7d7d47dc5c2e1b70fb84fa320793af0 Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Sun, 7 Apr 2024 18:06:43 +0200 Subject: [PATCH 07/14] chore(deps): Update vite to 5.2.8 (#10427) --- packages/forms/src/index.tsx | 4 +- packages/vite/package.json | 2 +- yarn.lock | 189 ++++++++++++++++++++++++++++++++--- 3 files changed, 180 insertions(+), 15 deletions(-) diff --git a/packages/forms/src/index.tsx b/packages/forms/src/index.tsx index aa0573e601ed..ddf2deae416d 100644 --- a/packages/forms/src/index.tsx +++ b/packages/forms/src/index.tsx @@ -1017,6 +1017,8 @@ export const { WeekField, } = InputComponents +export * from 'react-hook-form' + export { Form, ServerErrorsContext, @@ -1032,5 +1034,3 @@ export { } export type { ServerError, RWGqlError, ServerParseError } from './FormError' - -export * from 'react-hook-form' diff --git a/packages/vite/package.json b/packages/vite/package.json index c418f7fb9af0..f3837f137b92 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -83,7 +83,7 @@ "isbot": "3.8.0", "react": "18.3.0-canary-a870b2d54-20240314", "react-server-dom-webpack": "18.3.0-canary-a870b2d54-20240314", - "vite": "5.1.7", + "vite": "5.2.8", "vite-plugin-cjs-interop": "2.1.0", "yargs-parser": "21.1.1" }, diff --git a/yarn.lock b/yarn.lock index 2e87107a8bd7..66afa954cca4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8803,7 +8803,7 @@ __metadata: rollup: "npm:4.13.0" tsx: "npm:4.7.1" typescript: "npm:5.4.3" - vite: "npm:5.1.7" + vite: "npm:5.2.8" vite-plugin-cjs-interop: "npm:2.1.0" vitest: "npm:1.4.0" yargs-parser: "npm:21.1.1" @@ -8930,6 +8930,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.14.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-android-arm64@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-android-arm64@npm:4.13.0" @@ -8937,6 +8944,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-android-arm64@npm:4.14.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-arm64@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-darwin-arm64@npm:4.13.0" @@ -8944,6 +8958,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.14.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-darwin-x64@npm:4.13.0" @@ -8951,6 +8972,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-x64@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.14.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0" @@ -8958,6 +8986,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.14.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.13.0" @@ -8965,6 +9000,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-gnu@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.14.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-musl@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.13.0" @@ -8972,6 +9014,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.14.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.14.1" + conditions: os=linux & cpu=ppc64le & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-gnu@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.13.0" @@ -8979,6 +9035,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.14.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.14.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-gnu@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.13.0" @@ -8986,6 +9056,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-gnu@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.14.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-musl@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-x64-musl@npm:4.13.0" @@ -8993,6 +9070,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.14.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-win32-arm64-msvc@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.13.0" @@ -9000,6 +9084,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.14.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-ia32-msvc@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.13.0" @@ -9007,6 +9098,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.14.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-msvc@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.13.0" @@ -9014,6 +9112,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-msvc@npm:4.14.1": + version: 4.14.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.14.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@sdl-codegen/node@npm:0.0.13": version: 0.0.13 resolution: "@sdl-codegen/node@npm:0.0.13" @@ -17677,7 +17782,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:0.20.2": +"esbuild@npm:0.20.2, esbuild@npm:^0.20.1": version: 0.20.2 resolution: "esbuild@npm:0.20.2" dependencies: @@ -17834,7 +17939,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.19.3, esbuild@npm:~0.19.10": +"esbuild@npm:~0.19.10": version: 0.19.12 resolution: "esbuild@npm:0.19.12" dependencies: @@ -27941,7 +28046,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.2.14, postcss@npm:^8.4.24, postcss@npm:^8.4.33, postcss@npm:^8.4.35": +"postcss@npm:^8.2.14, postcss@npm:^8.4.24, postcss@npm:^8.4.33, postcss@npm:^8.4.38": version: 8.4.38 resolution: "postcss@npm:8.4.38" dependencies: @@ -29708,7 +29813,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:4.13.0, rollup@npm:^4.2.0": +"rollup@npm:4.13.0": version: 4.13.0 resolution: "rollup@npm:4.13.0" dependencies: @@ -29762,6 +29867,66 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.13.0": + version: 4.14.1 + resolution: "rollup@npm:4.14.1" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.14.1" + "@rollup/rollup-android-arm64": "npm:4.14.1" + "@rollup/rollup-darwin-arm64": "npm:4.14.1" + "@rollup/rollup-darwin-x64": "npm:4.14.1" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.14.1" + "@rollup/rollup-linux-arm64-gnu": "npm:4.14.1" + "@rollup/rollup-linux-arm64-musl": "npm:4.14.1" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.14.1" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.14.1" + "@rollup/rollup-linux-s390x-gnu": "npm:4.14.1" + "@rollup/rollup-linux-x64-gnu": "npm:4.14.1" + "@rollup/rollup-linux-x64-musl": "npm:4.14.1" + "@rollup/rollup-win32-arm64-msvc": "npm:4.14.1" + "@rollup/rollup-win32-ia32-msvc": "npm:4.14.1" + "@rollup/rollup-win32-x64-msvc": "npm:4.14.1" + "@types/estree": "npm:1.0.5" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/c9028c04537f7f16f9b5e4d75c84d2f0dc960d280fc4eca5960f0d67e786d993b8b707a63fc8b2e054b018fdb3a5a98d5eb7ed5674635c7612dd0b66696805fa + languageName: node + linkType: hard + "root-workspace-0b6124@workspace:.": version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." @@ -33239,14 +33404,14 @@ __metadata: languageName: node linkType: hard -"vite@npm:5.1.7, vite@npm:^5.0.0": - version: 5.1.7 - resolution: "vite@npm:5.1.7" +"vite@npm:5.2.8, vite@npm:^5.0.0": + version: 5.2.8 + resolution: "vite@npm:5.2.8" dependencies: - esbuild: "npm:^0.19.3" + esbuild: "npm:^0.20.1" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.35" - rollup: "npm:^4.2.0" + postcss: "npm:^8.4.38" + rollup: "npm:^4.13.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 less: "*" @@ -33275,7 +33440,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/f64e1d8bcb237f600790c303447b95f0972e7c5377c0e1c38c1e62ef4864df2bff00c83315994da6e2e64fb51166199403a740b685c5b69a4af648b9244fc69c + checksum: 10c0/b5717bb00c2570c08ff6d8ed917655e79184efcafa9dd62d52eea19c5d6dfc5a708ec3de9ebc670a7165fc5d401c2bdf1563bb39e2748d8e51e1593d286a9a13 languageName: node linkType: hard From 06d5ccd6e95b266824c2725dad245f6ee51e5a1e Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sun, 7 Apr 2024 10:08:15 -0700 Subject: [PATCH 08/14] chore(rsc): simplify `noExternals` config (#10220) Co-authored-by: Tobbe Lundberg --- packages/vite/src/rsc/rscBuildAnalyze.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/vite/src/rsc/rscBuildAnalyze.ts b/packages/vite/src/rsc/rscBuildAnalyze.ts index 4eadc467fe98..464b22ce9f15 100644 --- a/packages/vite/src/rsc/rscBuildAnalyze.ts +++ b/packages/vite/src/rsc/rscBuildAnalyze.ts @@ -53,9 +53,7 @@ export async function rscBuildAnalyze() { ), ], ssr: { - // We can ignore everything that starts with `node:` because it's not - // going to be RSCs - noExternal: /^(?!node:)/, + noExternal: true, // TODO (RSC): Figure out what the `external` list should be. Right // now it's just copied from waku, plus we added prisma external: ['react', 'minimatch', '@prisma/client'], From 7a2a13529bae1e1e5536aed1eb2fe31854a6024c Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Sun, 7 Apr 2024 19:36:30 +0200 Subject: [PATCH 09/14] chore(refactor): Split rwjs/forms up into several smaller logical units (#10428) --- packages/forms/src/CheckboxField.tsx | 63 ++ packages/forms/src/FieldError.tsx | 72 ++ packages/forms/src/FieldProps.ts | 31 + packages/forms/src/Form.tsx | 96 ++ packages/forms/src/InputComponents.tsx | 160 ++++ packages/forms/src/Label.tsx | 38 + packages/forms/src/SelectField.tsx | 56 ++ packages/forms/src/ServerErrorsContext.tsx | 10 + packages/forms/src/Submit.tsx | 17 + packages/forms/src/TextAreaField.tsx | 59 ++ packages/forms/src/coercion.ts | 266 ++++++ packages/forms/src/index.tsx | 984 +-------------------- packages/forms/src/useErrorStyles.ts | 56 ++ packages/forms/src/useRegister.ts | 87 ++ 14 files changed, 1028 insertions(+), 967 deletions(-) create mode 100644 packages/forms/src/CheckboxField.tsx create mode 100644 packages/forms/src/FieldError.tsx create mode 100644 packages/forms/src/FieldProps.ts create mode 100644 packages/forms/src/Form.tsx create mode 100644 packages/forms/src/InputComponents.tsx create mode 100644 packages/forms/src/Label.tsx create mode 100644 packages/forms/src/SelectField.tsx create mode 100644 packages/forms/src/ServerErrorsContext.tsx create mode 100644 packages/forms/src/Submit.tsx create mode 100644 packages/forms/src/TextAreaField.tsx create mode 100644 packages/forms/src/coercion.ts create mode 100644 packages/forms/src/useErrorStyles.ts create mode 100644 packages/forms/src/useRegister.ts diff --git a/packages/forms/src/CheckboxField.tsx b/packages/forms/src/CheckboxField.tsx new file mode 100644 index 000000000000..b987e281dbaf --- /dev/null +++ b/packages/forms/src/CheckboxField.tsx @@ -0,0 +1,63 @@ +import type { ForwardedRef } from 'react' +import React, { forwardRef } from 'react' + +import type { FieldProps } from './FieldProps' +import { useErrorStyles } from './useErrorStyles' +import { useRegister } from './useRegister' + +export interface CheckboxFieldProps + extends Omit, 'type' | 'emptyAs'>, + Omit, 'name' | 'type'> {} + +/** Renders an `` field */ +export const CheckboxField = forwardRef( + ( + { + name, + id, + // for useErrorStyles + errorClassName, + errorStyle, + className, + style, + // for useRegister + validation, + onBlur, + onChange, + ...rest + }: CheckboxFieldProps, + ref: ForwardedRef, + ) => { + const styles = useErrorStyles({ + name, + errorClassName, + errorStyle, + className, + style, + }) + + const type = 'checkbox' + + const useRegisterReturn = useRegister( + { + name, + validation, + onBlur, + onChange, + type, + }, + ref, + ) + + return ( + + ) + }, +) diff --git a/packages/forms/src/FieldError.tsx b/packages/forms/src/FieldError.tsx new file mode 100644 index 000000000000..43492f824f39 --- /dev/null +++ b/packages/forms/src/FieldError.tsx @@ -0,0 +1,72 @@ +import React from 'react' + +import { get, useFormContext } from 'react-hook-form' + +export interface FieldErrorProps + extends React.ComponentPropsWithoutRef<'span'> { + /** + * The name of the field the ``'s associated with. + */ + name: string +} + +const DEFAULT_MESSAGES = { + required: 'is required', + pattern: 'is not formatted correctly', + minLength: 'is too short', + maxLength: 'is too long', + min: 'is too low', + max: 'is too high', + validate: 'is not valid', +} + +/** + * Renders a `` with an error message if there's a validation error on the corresponding field. + * If no error message is provided, a default one is used based on the type of validation that caused the error. + * + * @example Displaying a validation error message with `` + * + * `` doesn't render (i.e. returns `null`) when there's no error on ``. + * + * ```jsx + * + * + * + * ``` + * + * @see {@link https://redwoodjs.com/docs/tutorial/chapter3/forms#fielderror} + * + * @privateRemarks + * + * This is basically a helper for a common pattern you see in `react-hook-form`: + * + * ```jsx + *
+ * + * {errors.firstName?.type === 'required' && "First name is required"} + * ``` + * + * @see {@link https://react-hook-form.com/get-started#Handleerrors} + */ +export const FieldError = ({ name, ...rest }: FieldErrorProps) => { + const { + formState: { errors }, + } = useFormContext() + + const validationError = get(errors, name) + + const errorMessage = + validationError && + (validationError.message || + `${name} ${ + DEFAULT_MESSAGES[validationError.type as keyof typeof DEFAULT_MESSAGES] + }`) + + return validationError ? {errorMessage} : null +} diff --git a/packages/forms/src/FieldProps.ts b/packages/forms/src/FieldProps.ts new file mode 100644 index 000000000000..38171b593a34 --- /dev/null +++ b/packages/forms/src/FieldProps.ts @@ -0,0 +1,31 @@ +import type { EmptyAsValue, RedwoodRegisterOptions } from './coercion' + +/** + * The main interface, just to have some sort of source of truth. + * + * @typeParam E - The type of element; we're only ever working with a few HTMLElements. + * + * `extends` constrains the generic while `=` provides a default. + * + * @see {@link https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-constraints} + * + * @internal + */ +export interface FieldProps< + Element extends + | HTMLTextAreaElement + | HTMLSelectElement + | HTMLInputElement = HTMLInputElement, +> { + name: string + id?: string + emptyAs?: EmptyAsValue + errorClassName?: string + errorStyle?: React.CSSProperties + className?: string + style?: React.CSSProperties + validation?: RedwoodRegisterOptions + type?: string + onBlur?: React.FocusEventHandler + onChange?: React.ChangeEventHandler +} diff --git a/packages/forms/src/Form.tsx b/packages/forms/src/Form.tsx new file mode 100644 index 000000000000..dff2fc3c801a --- /dev/null +++ b/packages/forms/src/Form.tsx @@ -0,0 +1,96 @@ +import React, { forwardRef } from 'react' +import type { ForwardedRef } from 'react' + +import { useForm, FormProvider } from 'react-hook-form' +import type { FieldValues, UseFormReturn, UseFormProps } from 'react-hook-form' + +import { ServerErrorsContext } from './ServerErrorsContext' + +export interface FormProps + extends Omit, 'onSubmit'> { + error?: any + /** + * The methods returned by `useForm`. + * This prop is only necessary if you've called `useForm` yourself to get + * access to one of its functions, like `reset`. + * + * @example + * + * ```typescript + * const formMethods = useForm() + * + * const onSubmit = (data: FormData) => { + * sendDataToServer(data) + * formMethods.reset() + * } + * + * return ( + * + * ) + * ``` + */ + formMethods?: UseFormReturn + /** + * Configures how React Hook Form performs validation, among other things. + * + * @example + * + * ```jsx + * + * ``` + * + * @see {@link https://react-hook-form.com/api/useform} + */ + config?: UseFormProps + onSubmit?: (value: TFieldValues, event?: React.BaseSyntheticEvent) => void +} + +/** + * Renders a `` with the required context. + */ +function FormInner( + { + config, + error: errorProps, + formMethods: propFormMethods, + onSubmit, + children, + ...rest + }: FormProps, + ref: ForwardedRef, +) { + const hookFormMethods = useForm(config) + const formMethods = propFormMethods || hookFormMethods + + return ( + + onSubmit?.(data, event), + )} + > + + {children} + + + ) +} + +// Sorry about the `as` type assertion (type cast) here. Normally I'd redeclare +// forwardRef to only return a plain function, allowing us to use TypeScript's +// Higher-order Function Type Inference. But that gives us problems with the +// ForwardRefExoticComponent type we use for our InputComponents. So instead +// of changing that type (because it's correct) I use a type assertion here. +// forwardRef is notoriously difficult to use with UI component libs. +// Chakra-UI also says: +// > To be honest, the forwardRef type is quite complex [...] I'd recommend +// > that you cast the type +// https://github.com/chakra-ui/chakra-ui/issues/4528#issuecomment-902566185 +export const Form = forwardRef(FormInner) as ( + props: FormProps & React.RefAttributes, +) => React.ReactElement | null diff --git a/packages/forms/src/InputComponents.tsx b/packages/forms/src/InputComponents.tsx new file mode 100644 index 000000000000..6d1efd289dc9 --- /dev/null +++ b/packages/forms/src/InputComponents.tsx @@ -0,0 +1,160 @@ +import type { ForwardedRef } from 'react' +import React, { forwardRef } from 'react' + +import pascalcase from 'pascalcase' + +import type { FieldProps } from './FieldProps' +import { useErrorStyles } from './useErrorStyles' +import { useRegister } from './useRegister' + +/** + * All the types we'll be generating named `` for (which is basically all of them). + * Note that `'checkbox'` isn't here because we handle it separately above. + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types} + */ +const INPUT_TYPES = [ + 'button', + 'color', + 'date', + 'datetime-local', + 'email', + 'file', + 'hidden', + 'image', + 'month', + 'number', + 'password', + 'radio', + 'range', + 'reset', + 'search', + 'submit', + 'tel', + 'text', + 'time', + 'url', + 'week', +] as const + +type InputType = (typeof INPUT_TYPES)[number] + +export interface InputFieldProps + extends Omit, 'type'>, + Omit, 'name' | 'type'> { + /** + * @privateRemarks + * + * With this typing, passing `'checkbox'` to ``'s type is an error, which, + * at face value, feels like it shouldn't be. + * + * Even though we provide a separate ``, maybe we should reconsider the typing here? + */ + type?: InputType +} + +/** + * Renders an `` field. + * + * @see {@link https://redwoodjs.com/docs/form#inputfields} + */ +export const InputField = forwardRef( + ( + { + name, + id, + emptyAs, + // for useErrorStyles + errorClassName, + errorStyle, + className, + style, + // for useRegister + validation, + onBlur, + onChange, + type, + ...rest + }: InputFieldProps, + ref: ForwardedRef, + ) => { + const styles = useErrorStyles({ + name, + errorClassName, + errorStyle, + className, + style, + }) + + const useRegisterReturn = useRegister( + { + name, + validation, + onBlur, + onChange, + type, + }, + ref, + emptyAs, + ) + + return ( + + ) + }, +) + +/** + * `React.ForwardRefExoticComponent` is `forwardRef`'s return type. + * You can hover over `` above to see the type inference at work. + */ +const InputComponents: Record< + string, + React.ForwardRefExoticComponent> +> = {} + +/** + * Create a component for each type in `INPUT_TYPES`. + * + * Rather than writing out each and every component definition, + * we use a bit of JS metaprogramming to create them all with the appropriate name. + * + * We end up with `InputComponents.TextField`, `InputComponents.TimeField`, etc. + * Export those and we're good to go! + */ +INPUT_TYPES.forEach((type) => { + InputComponents[`${pascalcase(type)}Field`] = forwardRef< + HTMLInputElement, + Omit + >((props, ref) => ) +}) + +export const { + ButtonField, + ColorField, + DateField, + DatetimeLocalField, + EmailField, + FileField, + HiddenField, + ImageField, + MonthField, + NumberField, + PasswordField, + RadioField, + RangeField, + ResetField, + SearchField, + SubmitField, + TelField, + TextField, + TimeField, + UrlField, + WeekField, +} = InputComponents diff --git a/packages/forms/src/Label.tsx b/packages/forms/src/Label.tsx new file mode 100644 index 000000000000..4eee9819495c --- /dev/null +++ b/packages/forms/src/Label.tsx @@ -0,0 +1,38 @@ +import React from 'react' + +import type { FieldProps } from './FieldProps' +import { useErrorStyles } from './useErrorStyles' + +export interface LabelProps + extends Pick, + React.ComponentPropsWithoutRef<'label'> { + name: string +} + +/** + * Renders a `