From b330320958867ad31487415872b991b2bd67f295 Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Thu, 15 Aug 2024 14:15:41 +0200 Subject: [PATCH 01/52] fix(exec): Include nested scripts in --list (#11262) --- .changesets/11262.md | 4 ++ .../scripts/one/two/myNestedScript.ts | 3 ++ .../cli/src/commands/__tests__/exec.test.ts | 52 +++++++++++++++++++ packages/cli/src/commands/execHandler.js | 8 +-- packages/internal/src/files.ts | 2 +- .../rebuild-test-project-fixture.ts | 29 +++++++++-- 6 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 .changesets/11262.md create mode 100644 __fixtures__/test-project/scripts/one/two/myNestedScript.ts create mode 100644 packages/cli/src/commands/__tests__/exec.test.ts diff --git a/.changesets/11262.md b/.changesets/11262.md new file mode 100644 index 000000000000..70d00a9d4c0c --- /dev/null +++ b/.changesets/11262.md @@ -0,0 +1,4 @@ +- fix(exec): Include nested scripts in --list (#11262) by @Tobbe + +Now also nested scripts, like `scripts/nested/script.ts`, are included in the +output of `yarn rw exec --list` diff --git a/__fixtures__/test-project/scripts/one/two/myNestedScript.ts b/__fixtures__/test-project/scripts/one/two/myNestedScript.ts new file mode 100644 index 000000000000..d8e6c4138eed --- /dev/null +++ b/__fixtures__/test-project/scripts/one/two/myNestedScript.ts @@ -0,0 +1,3 @@ +export default async () => { + console.log('Hello from myNestedScript.ts') +} diff --git a/packages/cli/src/commands/__tests__/exec.test.ts b/packages/cli/src/commands/__tests__/exec.test.ts new file mode 100644 index 000000000000..8a7995bbf2ae --- /dev/null +++ b/packages/cli/src/commands/__tests__/exec.test.ts @@ -0,0 +1,52 @@ +import path from 'node:path' + +import '../../lib/mockTelemetry' + +import { vi, afterEach, beforeEach, describe, it, expect } from 'vitest' + +import { handler } from '../execHandler' + +vi.mock('envinfo', () => ({ default: { run: () => '' } })) +vi.mock('@redwoodjs/project-config', () => ({ + getPaths: () => ({ + scripts: path.join( + __dirname, + '../../../../../__fixtures__/test-project/scripts', + ), + }), + resolveFile: (path: string) => path, +})) + +const mockRedwoodToml = { + fileContents: '', +} + +// Before rw tests run, api/ and web/ `jest.config.js` is confirmed via existsSync() +vi.mock('node:fs', async () => ({ + default: { + readFileSync: () => { + return mockRedwoodToml.fileContents + }, + }, +})) + +beforeEach(() => { + vi.spyOn(console, 'log').mockImplementation(() => {}) +}) + +afterEach(() => { + vi.mocked(console).log.mockRestore() +}) + +describe('yarn rw exec --list', () => { + it('includes nested scripts', async () => { + await handler({ list: true }) + const scriptPath = path + .join('one', 'two', 'myNestedScript') + // Handle Windows path separators + .replaceAll('\\', '\\\\') + expect(vi.mocked(console).log).toHaveBeenCalledWith( + expect.stringMatching(new RegExp('\\b' + scriptPath + '\\b')), + ) + }) +}) diff --git a/packages/cli/src/commands/execHandler.js b/packages/cli/src/commands/execHandler.js index 1de907100a64..0da6ef42f8ca 100644 --- a/packages/cli/src/commands/execHandler.js +++ b/packages/cli/src/commands/execHandler.js @@ -18,9 +18,11 @@ import { generatePrismaClient } from '../lib/generatePrismaClient' const printAvailableScriptsToConsole = () => { console.log('Available scripts:') - findScripts().forEach((scriptPath) => { - const { name } = path.parse(scriptPath) - console.log(c.info(`- ${name}`)) + findScripts(getPaths().scripts).forEach((scriptPath) => { + const relativePath = path.relative(getPaths().scripts, scriptPath) + const { ext } = path.parse(relativePath) + const relativePathWithoutExt = relativePath.slice(0, -ext.length) + console.log(c.info(`- ${relativePathWithoutExt}`)) }) console.log() } diff --git a/packages/internal/src/files.ts b/packages/internal/src/files.ts index 1600a64d9cc8..e162855cc704 100644 --- a/packages/internal/src/files.ts +++ b/packages/internal/src/files.ts @@ -146,7 +146,7 @@ export const isCellFile = (p: string) => { } export const findScripts = (cwd: string = getPaths().scripts) => { - return fg.sync('*.{js,jsx,ts,tsx}', { + return fg.sync('./**/*.{js,jsx,ts,tsx}', { cwd, absolute: true, ignore: ['node_modules'], diff --git a/tasks/test-project/rebuild-test-project-fixture.ts b/tasks/test-project/rebuild-test-project-fixture.ts index b6600a27a123..581f20a1dddb 100755 --- a/tasks/test-project/rebuild-test-project-fixture.ts +++ b/tasks/test-project/rebuild-test-project-fixture.ts @@ -386,8 +386,29 @@ async function runCommand() { }, }) + await tuiTask({ + step: 9, + title: 'Add scripts', + task: () => { + const nestedPath = path.join( + OUTPUT_PROJECT_PATH, + 'scripts', + 'one', + 'two' + ) + + fs.mkdirSync(nestedPath, { recursive: true }) + fs.writeFileSync( + path.join(nestedPath, 'myNestedScript.ts'), + 'export default async () => {\n' + + " console.log('Hello from myNestedScript.ts')\n" + + '}\n\n' + ) + }, + }) + await tuiTask({ - step: 9, + step: 10, title: 'Running prisma migrate reset', task: () => { return exec( @@ -399,7 +420,7 @@ async function runCommand() { }) await tuiTask({ - step: 10, + step: 11, title: 'Lint --fix all the things', task: async () => { try { @@ -431,7 +452,7 @@ async function runCommand() { }) await tuiTask({ - step: 11, + step: 12, title: 'Replace and Cleanup Fixture', task: async () => { // @TODO: This only works on UNIX, we should use path.join everywhere @@ -469,7 +490,7 @@ async function runCommand() { }) await tuiTask({ - step: 12, + step: 13, title: 'All done!', task: () => { console.log('-'.repeat(30)) From b1d1ec8bd70492f527dbf496fc40e1779159a5e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:36:33 +0000 Subject: [PATCH 02/52] chore(deps): update dependency publint to v0.2.10 (#11266) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [publint](https://publint.dev) ([source](https://togithub.com/bluwy/publint/tree/HEAD/pkg)) | [`0.2.9` -> `0.2.10`](https://renovatebot.com/diffs/npm/publint/0.2.9/0.2.10) | [![age](https://developer.mend.io/api/mc/badges/age/npm/publint/0.2.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/publint/0.2.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/publint/0.2.9/0.2.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/publint/0.2.9/0.2.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
bluwy/publint (publint) ### [`v0.2.10`](https://togithub.com/bluwy/publint/releases/tag/v0.2.10) [Compare Source](https://togithub.com/bluwy/publint/compare/v0.2.9...v0.2.10) ##### Features - Adds a new rule that validates the `"repository"` field ([https://github.com/bluwy/publint/pull/106](https://togithub.com/bluwy/publint/pull/106)) - If `"repository"` is a string, it must be one of the supported shorthand strings from the docs. - If `"repository"` is an object with `"type": "git"`, the `"url"` must be a valid [git URL](https://git-scm.com/docs/git-clone#\_git_urls) and can be [parsed by npm](https://togithub.com/npm/hosted-git-info). - The `git://` protocol for GitHub repos should not be used due [security concerns](https://github.blog/security/application-security/improving-git-protocol-security-github/). - GitHub or GitLab links should be prefixed with `git+` and postfixed with `.git`. (This is also warned by npm when publishing a package). #### New Contributors - [@​Namchee](https://togithub.com/Namchee) made their first contribution in [https://github.com/bluwy/publint/pull/106](https://togithub.com/bluwy/publint/pull/106) **Full Changelog**: https://github.com/bluwy/publint/compare/v0.2.9...v0.2.10
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/create-redwood-rsc-app/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/create-redwood-rsc-app/yarn.lock b/packages/create-redwood-rsc-app/yarn.lock index 9585b9ac78b5..867f6fefd2be 100644 --- a/packages/create-redwood-rsc-app/yarn.lock +++ b/packages/create-redwood-rsc-app/yarn.lock @@ -3553,15 +3553,15 @@ __metadata: linkType: hard "publint@npm:^0.2.9": - version: 0.2.9 - resolution: "publint@npm:0.2.9" + version: 0.2.10 + resolution: "publint@npm:0.2.10" dependencies: npm-packlist: "npm:^5.1.3" picocolors: "npm:^1.0.1" sade: "npm:^1.8.1" bin: publint: lib/cli.js - checksum: 10c0/b414f40c2bc9372119346d5684eccb12bdf8066fc821301880d9dcdec0a5d852bbe926cb4583511f3e97736c53d1723e46e49285c9463bcb808cbfd979d5c2fc + checksum: 10c0/af1b82d0427e3e18a77157cfecf8dd84270540e8209215a434d571f93a3d0e4e0e56caf87efb7ed18b9518806469440d7ea003df0d15b82bf0500f14ff48aa64 languageName: node linkType: hard From 08ddc5d04acd959f5573708c3a1f3f8f5a64785b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:37:33 +0000 Subject: [PATCH 03/52] chore(deps): update dependency eslint-plugin-perfectionist to v3.2.0 (#11274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [eslint-plugin-perfectionist](https://perfectionist.dev) ([source](https://togithub.com/azat-io/eslint-plugin-perfectionist)) | [`3.1.3` -> `3.2.0`](https://renovatebot.com/diffs/npm/eslint-plugin-perfectionist/3.1.3/3.2.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/eslint-plugin-perfectionist/3.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/eslint-plugin-perfectionist/3.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/eslint-plugin-perfectionist/3.1.3/3.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/eslint-plugin-perfectionist/3.1.3/3.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
azat-io/eslint-plugin-perfectionist (eslint-plugin-perfectionist) ### [`v3.2.0`](https://togithub.com/azat-io/eslint-plugin-perfectionist/blob/HEAD/changelog.md#v320) [Compare Source](https://togithub.com/azat-io/eslint-plugin-perfectionist/compare/v3.1.3...v3.2.0) [compare changes](https://togithub.com/azat-io/eslint-plugin-perfectionist/compare/v3.1.3...v3.2.0) ##### 🚀 Features - Use dynamic group generation in sort-classes ([baa701d](https://togithub.com/azat-io/eslint-plugin-perfectionist/commit/baa701d)) - Support for sorting by enum value ([285a451](https://togithub.com/azat-io/eslint-plugin-perfectionist/commit/285a451)) - Improve group order error messages in sort-classes ([b02d626](https://togithub.com/azat-io/eslint-plugin-perfectionist/commit/b02d626)) - Allow specifying cross-rule settings ([8e15730](https://togithub.com/azat-io/eslint-plugin-perfectionist/commit/8e15730)) - Add property-function groups in sort-class rule ([41b92d3](https://togithub.com/azat-io/eslint-plugin-perfectionist/commit/41b92d3)) ##### ❤️ Contributors - Hugo ([@​hugop95](http://github.com/hugop95)) - Azat S. ([@​azat-io](http://github.com/azat-io))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/create-redwood-rsc-app/yarn.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/create-redwood-rsc-app/yarn.lock b/packages/create-redwood-rsc-app/yarn.lock index 867f6fefd2be..2a3824e88e95 100644 --- a/packages/create-redwood-rsc-app/yarn.lock +++ b/packages/create-redwood-rsc-app/yarn.lock @@ -963,7 +963,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.1.0, @typescript-eslint/types@npm:^8.0.1": +"@typescript-eslint/types@npm:8.1.0, @typescript-eslint/types@npm:^8.1.0": version: 8.1.0 resolution: "@typescript-eslint/types@npm:8.1.0" checksum: 10c0/ceade44455f45974e68956016c4d1c6626580732f7f9675e14ffa63db80b551752b0df596b20473dae9f0dc6ed966e17417dc2cf36e1a82b6ab0edc97c5eaa50 @@ -1022,7 +1022,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:^8.0.1": +"@typescript-eslint/utils@npm:^8.1.0": version: 8.1.0 resolution: "@typescript-eslint/utils@npm:8.1.0" dependencies: @@ -1880,11 +1880,11 @@ __metadata: linkType: hard "eslint-plugin-perfectionist@npm:^3.0.0": - version: 3.1.3 - resolution: "eslint-plugin-perfectionist@npm:3.1.3" + version: 3.2.0 + resolution: "eslint-plugin-perfectionist@npm:3.2.0" dependencies: - "@typescript-eslint/types": "npm:^8.0.1" - "@typescript-eslint/utils": "npm:^8.0.1" + "@typescript-eslint/types": "npm:^8.1.0" + "@typescript-eslint/utils": "npm:^8.1.0" minimatch: "npm:^10.0.1" natural-compare-lite: "npm:^1.4.0" peerDependencies: @@ -1902,7 +1902,7 @@ __metadata: optional: true vue-eslint-parser: optional: true - checksum: 10c0/0f98000145367c9f64e42fe3c682d178acc488b684eeb1c316b8a13e6cdc8516fdf4d8bb71133afe76bf2b5b92a1edbd6a80e8254a2bac23964eb9b8997b25b3 + checksum: 10c0/c0db9ae69417e129c3a29166418eecfe185283cde54b070fcc9733b0d5006739d0c829482cd28afc9a995bb753eea18524812a835843f3c91142734c54c5bdb6 languageName: node linkType: hard From aef187aeaa057a3d59c2d52ac52e2cb2f088c178 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:38:03 +0000 Subject: [PATCH 04/52] chore(deps): update dependency @eslint-community/eslint-plugin-eslint-comments to v4.4.0 (#11273) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@eslint-community/eslint-plugin-eslint-comments](https://togithub.com/eslint-community/eslint-plugin-eslint-comments) | [`4.3.0` -> `4.4.0`](https://renovatebot.com/diffs/npm/@eslint-community%2feslint-plugin-eslint-comments/4.3.0/4.4.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@eslint-community%2feslint-plugin-eslint-comments/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@eslint-community%2feslint-plugin-eslint-comments/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@eslint-community%2feslint-plugin-eslint-comments/4.3.0/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@eslint-community%2feslint-plugin-eslint-comments/4.3.0/4.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
eslint-community/eslint-plugin-eslint-comments (@​eslint-community/eslint-plugin-eslint-comments) ### [`v4.4.0`](https://togithub.com/eslint-community/eslint-plugin-eslint-comments/releases/tag/v4.4.0) [Compare Source](https://togithub.com/eslint-community/eslint-plugin-eslint-comments/compare/v4.3.0...v4.4.0) ##### Features - add `name` to flat config (for tooling) ([#​243](https://togithub.com/eslint-community/eslint-plugin-eslint-comments/issues/243)) ([c993b63](https://togithub.com/eslint-community/eslint-plugin-eslint-comments/commit/c993b638c7ce5938953f0c0c4a17f3644daadb65))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/create-redwood-rsc-app/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/create-redwood-rsc-app/yarn.lock b/packages/create-redwood-rsc-app/yarn.lock index 2a3824e88e95..2bc8ed0e1055 100644 --- a/packages/create-redwood-rsc-app/yarn.lock +++ b/packages/create-redwood-rsc-app/yarn.lock @@ -356,14 +356,14 @@ __metadata: linkType: hard "@eslint-community/eslint-plugin-eslint-comments@npm:^4.3.0": - version: 4.3.0 - resolution: "@eslint-community/eslint-plugin-eslint-comments@npm:4.3.0" + version: 4.4.0 + resolution: "@eslint-community/eslint-plugin-eslint-comments@npm:4.4.0" dependencies: escape-string-regexp: "npm:^4.0.0" ignore: "npm:^5.2.4" peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: 10c0/d468a44ae205659b48aa8a853b2f9c95622ba0a102984fc53621dce0cb00361e3395723947848cf3db3b4f25835e0db3c6725bdfce84d6b2944362c5025fc10e + checksum: 10c0/26ef5a2aea65ba9c7ee542f784af9cbc1627e167002fe6c908a36e7baed7d14df0af565d7d09745ce8a624c92bdcefbc5075007b61285e33e753879994c5cafc languageName: node linkType: hard From 818032751b1c6adcd1069ec14a62538b59b40cac Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:40:14 +0100 Subject: [PATCH 05/52] chore(lint): enable 'typescript-eslint/prefer-includes' (#11261) Enables the `@typescript-eslint/prefer-includes` rule and addresses and errors which result. --- .eslintrc.js | 1 - packages/api-server/src/plugins/lambdaLoader.ts | 2 +- .../src/commands/setup/monitoring/sentry/sentryHandler.ts | 6 +++--- packages/graphql-server/src/makeMergedSchema.ts | 5 +---- packages/internal/src/generate/watch.ts | 4 ++-- packages/router/src/util.ts | 2 +- packages/structure/src/util.ts | 2 +- packages/telemetry/src/sendTelemetry.ts | 2 +- 8 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 423923ee35b2..2055f4dcf0e9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -221,7 +221,6 @@ module.exports = { '@typescript-eslint/restrict-template-expressions': 'off', '@typescript-eslint/non-nullable-type-assertion-style': 'off', '@typescript-eslint/no-implied-eval': 'off', - '@typescript-eslint/prefer-includes': 'off', '@typescript-eslint/no-base-to-string': 'off', '@typescript-eslint/no-duplicate-type-constituents': 'off', '@typescript-eslint/unbound-method': 'off', diff --git a/packages/api-server/src/plugins/lambdaLoader.ts b/packages/api-server/src/plugins/lambdaLoader.ts index b51ead976176..d926ab6406a7 100644 --- a/packages/api-server/src/plugins/lambdaLoader.ts +++ b/packages/api-server/src/plugins/lambdaLoader.ts @@ -66,7 +66,7 @@ export const loadFunctionsFromDist = async ( ) // Place `GraphQL` serverless function at the start. - const i = serverFunctions.findIndex((x) => x.indexOf('graphql') !== -1) + const i = serverFunctions.findIndex((x) => x.includes('graphql')) if (i >= 0) { const graphQLFn = serverFunctions.splice(i, 1)[0] serverFunctions.unshift(graphQLFn) diff --git a/packages/cli/src/commands/setup/monitoring/sentry/sentryHandler.ts b/packages/cli/src/commands/setup/monitoring/sentry/sentryHandler.ts index e652b452f5ad..16a831e56fc0 100644 --- a/packages/cli/src/commands/setup/monitoring/sentry/sentryHandler.ts +++ b/packages/cli/src/commands/setup/monitoring/sentry/sentryHandler.ts @@ -70,7 +70,7 @@ export const handler = async ({ force }: Args) => { ) const pluginsIndex = contentLines.findLastIndex((line) => - /extraPlugins:/.test(line), + line.includes('extraPlugins:'), ) if (handlerIndex === -1 || pluginsIndex !== -1) { @@ -119,7 +119,7 @@ export const handler = async ({ force }: Args) => { ) const boundaryOpenIndex = contentLines.findLastIndex((line) => - //.test(line), + line.includes(''), ) contentLines.splice( boundaryOpenIndex, @@ -128,7 +128,7 @@ export const handler = async ({ force }: Args) => { ) const boundaryCloseIndex = contentLines.findLastIndex((line) => - /<\/FatalErrorBoundary>/.test(line), + line.includes(''), ) contentLines.splice(boundaryCloseIndex, 1, '') diff --git a/packages/graphql-server/src/makeMergedSchema.ts b/packages/graphql-server/src/makeMergedSchema.ts index c5a65462a0ff..abf5ba73d883 100644 --- a/packages/graphql-server/src/makeMergedSchema.ts +++ b/packages/graphql-server/src/makeMergedSchema.ts @@ -164,10 +164,7 @@ const resolveUnionType = (types: readonly GraphQLObjectType[]) => ({ // If the maxIntersection fields is not unique, we are unable to determine type if ( - fieldIntersections.indexOf( - maxIntersectionFields, - maxIntersectionIdx + 1, - ) !== -1 + fieldIntersections.includes(maxIntersectionFields, maxIntersectionIdx + 1) ) { throw Error( 'Unable to resolve correct type for union. Try adding unique fields to each type or __typename to each resolver', diff --git a/packages/internal/src/generate/watch.ts b/packages/internal/src/generate/watch.ts index 10a52f5b6b1f..09c526c3b3df 100644 --- a/packages/internal/src/generate/watch.ts +++ b/packages/internal/src/generate/watch.ts @@ -101,7 +101,7 @@ watcher chalk.dim.italic(Date.now() - start + ' ms'), ) - if (absPath.indexOf('Cell') !== -1 && isCellFile(absPath)) { + if (absPath.includes('Cell') && isCellFile(absPath)) { await generateTypeDefGraphQLWeb() await generateClientPreset() if (eventName === 'unlink') { @@ -114,7 +114,7 @@ watcher generateTypeDefRouterRoutes() routesWarningMessage = warningForDuplicateRoutes() finished('Routes') - } else if (absPath.indexOf('Page') !== -1 && isPageFile(absPath)) { + } else if (absPath.includes('Page') && isPageFile(absPath)) { generateTypeDefRouterPages() finished('Page') } else if (isDirectoryNamedModuleFile(absPath)) { diff --git a/packages/router/src/util.ts b/packages/router/src/util.ts index 93e0af181e41..49401af8d301 100644 --- a/packages/router/src/util.ts +++ b/packages/router/src/util.ts @@ -259,7 +259,7 @@ export function validatePath(path: string, routeName: string) { ) } - if (path.indexOf(' ') >= 0) { + if (path.includes(' ')) { throw new Error(`Route path for ${routeName} contains spaces: "${path}"`) } diff --git a/packages/structure/src/util.ts b/packages/structure/src/util.ts index 205a83bfcffa..689c4198ee77 100644 --- a/packages/structure/src/util.ts +++ b/packages/structure/src/util.ts @@ -5,7 +5,7 @@ export function validateRoutePath(path: string) { throw new Error(`Route path does not begin with a slash: "${path}"`) } - if (path.indexOf(' ') >= 0) { + if (path.includes(' ')) { throw new Error(`Route path contains spaces: "${path}"`) } diff --git a/packages/telemetry/src/sendTelemetry.ts b/packages/telemetry/src/sendTelemetry.ts index aa68b6576c2e..27909f28b83c 100644 --- a/packages/telemetry/src/sendTelemetry.ts +++ b/packages/telemetry/src/sendTelemetry.ts @@ -138,7 +138,7 @@ export const sanitizeArgv = ( if (sensitiveCommand.positions) { sensitiveCommand.positions.forEach((pos: number, index: number) => { // only redact if the text in the given position is not a --flag - if (args[pos] && !/--/.test(args[pos])) { + if (args[pos] && !args[pos].includes('--')) { args[pos] = sensitiveCommand.redactWith[index] } }) From 6865ecfd41efa9e237e34c49438a3ad22627902e Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:40:27 +0100 Subject: [PATCH 06/52] chore(lint): enable 'typescript-eslint/prefer-find' (#11259) Enables the `@typescript-eslint/prefer-find` rule and addresses any errors that resulted. --- .eslintrc.js | 1 - .../src/plugins/babel-plugin-redwood-routes-auto-loader.ts | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 2055f4dcf0e9..1abf4b674070 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -224,7 +224,6 @@ module.exports = { '@typescript-eslint/no-base-to-string': 'off', '@typescript-eslint/no-duplicate-type-constituents': 'off', '@typescript-eslint/unbound-method': 'off', - '@typescript-eslint/prefer-find': 'off', }, }, { diff --git a/packages/babel-config/src/plugins/babel-plugin-redwood-routes-auto-loader.ts b/packages/babel-config/src/plugins/babel-plugin-redwood-routes-auto-loader.ts index 6e60aa587d0c..7e51858f6d57 100644 --- a/packages/babel-config/src/plugins/babel-plugin-redwood-routes-auto-loader.ts +++ b/packages/babel-config/src/plugins/babel-plugin-redwood-routes-auto-loader.ts @@ -77,9 +77,12 @@ export default function ( importStatementPath(p.node.source?.value), ) - const defaultSpecifier = p.node.specifiers.filter((specifiers) => + const defaultSpecifier = p.node.specifiers.find((specifiers) => t.isImportDefaultSpecifier(specifiers), - )[0] + ) + if (!defaultSpecifier) { + return + } // Remove Page imports in prerender mode (see babel-preset) // The removed imports will be replaced further down in this file From cb810823b2996d994057a8785f2b4309ae0cbf4f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:41:57 +0000 Subject: [PATCH 07/52] fix(deps): update docusaurus monorepo to v3.5.2 (#11272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@docusaurus/core](https://togithub.com/facebook/docusaurus) ([source](https://togithub.com/facebook/docusaurus/tree/HEAD/packages/docusaurus)) | [`3.5.1` -> `3.5.2`](https://renovatebot.com/diffs/npm/@docusaurus%2fcore/3.5.1/3.5.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@docusaurus%2fcore/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@docusaurus%2fcore/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@docusaurus%2fcore/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@docusaurus%2fcore/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@docusaurus/module-type-aliases](https://togithub.com/facebook/docusaurus) ([source](https://togithub.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-module-type-aliases)) | [`3.5.1` -> `3.5.2`](https://renovatebot.com/diffs/npm/@docusaurus%2fmodule-type-aliases/3.5.1/3.5.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@docusaurus%2fmodule-type-aliases/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@docusaurus%2fmodule-type-aliases/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@docusaurus%2fmodule-type-aliases/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@docusaurus%2fmodule-type-aliases/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@docusaurus/plugin-content-docs](https://togithub.com/facebook/docusaurus) ([source](https://togithub.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-plugin-content-docs)) | [`3.5.1` -> `3.5.2`](https://renovatebot.com/diffs/npm/@docusaurus%2fplugin-content-docs/3.5.1/3.5.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@docusaurus%2fplugin-content-docs/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@docusaurus%2fplugin-content-docs/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@docusaurus%2fplugin-content-docs/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@docusaurus%2fplugin-content-docs/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@docusaurus/preset-classic](https://togithub.com/facebook/docusaurus) ([source](https://togithub.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-preset-classic)) | [`3.5.1` -> `3.5.2`](https://renovatebot.com/diffs/npm/@docusaurus%2fpreset-classic/3.5.1/3.5.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@docusaurus%2fpreset-classic/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@docusaurus%2fpreset-classic/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@docusaurus%2fpreset-classic/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@docusaurus%2fpreset-classic/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@docusaurus/theme-common](https://togithub.com/facebook/docusaurus) ([source](https://togithub.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-theme-common)) | [`3.5.1` -> `3.5.2`](https://renovatebot.com/diffs/npm/@docusaurus%2ftheme-common/3.5.1/3.5.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@docusaurus%2ftheme-common/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@docusaurus%2ftheme-common/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@docusaurus%2ftheme-common/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@docusaurus%2ftheme-common/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@docusaurus/tsconfig](https://togithub.com/facebook/docusaurus) ([source](https://togithub.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-tsconfig)) | [`3.5.1` -> `3.5.2`](https://renovatebot.com/diffs/npm/@docusaurus%2ftsconfig/3.5.1/3.5.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@docusaurus%2ftsconfig/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@docusaurus%2ftsconfig/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@docusaurus%2ftsconfig/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@docusaurus%2ftsconfig/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
facebook/docusaurus (@​docusaurus/core) ### [`v3.5.2`](https://togithub.com/facebook/docusaurus/compare/v3.5.1...eeec303dd773774ed5a023884800da0b061f6942) [Compare Source](https://togithub.com/facebook/docusaurus/compare/v3.5.1...v3.5.2)
facebook/docusaurus (@​docusaurus/module-type-aliases) ### [`v3.5.2`](https://togithub.com/facebook/docusaurus/compare/v3.5.1...eeec303dd773774ed5a023884800da0b061f6942) [Compare Source](https://togithub.com/facebook/docusaurus/compare/v3.5.1...v3.5.2)
facebook/docusaurus (@​docusaurus/plugin-content-docs) ### [`v3.5.2`](https://togithub.com/facebook/docusaurus/blob/HEAD/CHANGELOG.md#352-2024-08-13) [Compare Source](https://togithub.com/facebook/docusaurus/compare/v3.5.1...v3.5.2) ##### :bug: Bug Fix - `docusaurus-theme-common` - [#​10397](https://togithub.com/facebook/docusaurus/pull/10397) fix(theme-common): restore useContextualSearchFilters public API for retrocompatibility ([@​slorber](https://togithub.com/slorber)) - `docusaurus` - [#​10391](https://togithub.com/facebook/docusaurus/pull/10391) fix(core): always alias React/ReactDOM to site dependency so that importing MDX from anywhere works ([@​slorber](https://togithub.com/slorber)) - `create-docusaurus`, `docusaurus-plugin-content-blog` - [#​10392](https://togithub.com/facebook/docusaurus/pull/10392) fix(create-docusaurus): Improve init templates blog setup + fix warnings ([@​slorber](https://togithub.com/slorber)) - `docusaurus-theme-classic` - [#​10390](https://togithub.com/facebook/docusaurus/pull/10390) fix(theme): Adjust blog authors line height to show descenders in lowercase letters (`g`, `j`, `p`, `q`, and `y`) ([@​josh-wong](https://togithub.com/josh-wong)) ##### :nail_care: Polish - `docusaurus-theme-classic`, `docusaurus-theme-common`, `docusaurus-theme-translations` - [#​10394](https://togithub.com/facebook/docusaurus/pull/10394) fix(translations): change casing of some en labels ([@​cstangerup](https://togithub.com/cstangerup)) ##### :memo: Documentation - [#​10393](https://togithub.com/facebook/docusaurus/pull/10393) docs(showcase): remove sites not using Docusaurus anymore ([@​GatienBoquet](https://togithub.com/GatienBoquet)) ##### :robot: Dependencies - [#​10396](https://togithub.com/facebook/docusaurus/pull/10396) chore(deps): bump github/codeql-action from 3.25.13 to 3.26.0 ([@​dependabot\[bot\]](https://togithub.com/apps/dependabot)) ##### Committers: 4 - Christian Stangerup ([@​cstangerup](https://togithub.com/cstangerup)) - Gatien Boquet ([@​GatienBoquet](https://togithub.com/GatienBoquet)) - Josh Wong ([@​josh-wong](https://togithub.com/josh-wong)) - Sébastien Lorber ([@​slorber](https://togithub.com/slorber))
facebook/docusaurus (@​docusaurus/preset-classic) ### [`v3.5.2`](https://togithub.com/facebook/docusaurus/compare/v3.5.1...eeec303dd773774ed5a023884800da0b061f6942) [Compare Source](https://togithub.com/facebook/docusaurus/compare/v3.5.1...v3.5.2)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- docs/package.json | 12 +- docs/yarn.lock | 395 +++++++++++++++++++++++----------------------- 2 files changed, 204 insertions(+), 203 deletions(-) diff --git a/docs/package.json b/docs/package.json index 865a03008a5e..f700a56c22b6 100644 --- a/docs/package.json +++ b/docs/package.json @@ -24,10 +24,10 @@ ] }, "dependencies": { - "@docusaurus/core": "3.5.1", - "@docusaurus/plugin-content-docs": "3.5.1", - "@docusaurus/preset-classic": "3.5.1", - "@docusaurus/theme-common": "3.5.1", + "@docusaurus/core": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/preset-classic": "3.5.2", + "@docusaurus/theme-common": "3.5.2", "@mdx-js/react": "3.0.1", "clsx": "2.1.1", "prism-react-renderer": "2.3.1", @@ -36,8 +36,8 @@ "react-player": "2.16.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.5.1", - "@docusaurus/tsconfig": "3.5.1", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/tsconfig": "3.5.2", "typescript": "5.5.4" }, "packageManager": "yarn@4.4.0" diff --git a/docs/yarn.lock b/docs/yarn.lock index f4e982018bc7..3d66bbf59696 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -1729,9 +1729,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/core@npm:3.5.1" +"@docusaurus/core@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/core@npm:3.5.2" dependencies: "@babel/core": "npm:^7.23.3" "@babel/generator": "npm:^7.23.3" @@ -1743,12 +1743,12 @@ __metadata: "@babel/runtime": "npm:^7.22.6" "@babel/runtime-corejs3": "npm:^7.22.6" "@babel/traverse": "npm:^7.22.8" - "@docusaurus/cssnano-preset": "npm:3.5.1" - "@docusaurus/logger": "npm:3.5.1" - "@docusaurus/mdx-loader": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-common": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" + "@docusaurus/cssnano-preset": "npm:3.5.2" + "@docusaurus/logger": "npm:3.5.2" + "@docusaurus/mdx-loader": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-common": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" autoprefixer: "npm:^10.4.14" babel-loader: "npm:^9.1.3" babel-plugin-dynamic-import-node: "npm:^2.3.3" @@ -1802,43 +1802,44 @@ __metadata: webpack-merge: "npm:^5.9.0" webpackbar: "npm:^5.0.2" peerDependencies: + "@mdx-js/react": ^3.0.0 react: ^18.0.0 react-dom: ^18.0.0 bin: docusaurus: bin/docusaurus.mjs - checksum: 10c0/72544271f53de32cbf13a3aab8f1d1b34c0b262d16ce8c546c32ca9188d0a390db1a453f6d8345a1dc5f793e382151ed4ef03faefebd1c6631b8cb2299c6b83a + checksum: 10c0/0868fc7cfbc38e7d927d60e927abf883fe442fe723123a58425a5402905a48bfb57b4e59ff555944af54ad3be462380d43e0f737989f6f300f11df2ca29d0498 languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/cssnano-preset@npm:3.5.1" +"@docusaurus/cssnano-preset@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/cssnano-preset@npm:3.5.2" dependencies: cssnano-preset-advanced: "npm:^6.1.2" postcss: "npm:^8.4.38" postcss-sort-media-queries: "npm:^5.2.0" tslib: "npm:^2.6.0" - checksum: 10c0/8ddb02086d693a5f711dd9314f88192a68fba066fd29fc947f8bca9268de1d0405b47e85dc430c3cdf1100778f394f9c444fc47e786cc091effe9d7bbb58aade + checksum: 10c0/10fd97d66aa7973d86322ac205978edc18636e13dc1f5eb7e6fca5169c4203660bd958f2a483a2b1639d05c1878f5d0eb5f07676eee5d5aa3b71b417d35fa42a languageName: node linkType: hard -"@docusaurus/logger@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/logger@npm:3.5.1" +"@docusaurus/logger@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/logger@npm:3.5.2" dependencies: chalk: "npm:^4.1.2" tslib: "npm:^2.6.0" - checksum: 10c0/463965be9e1e814b48cb7a80f207d60c759d30f7ccc42df819ab133fbc9023a02aed282acf10a2b37a1ceeceb8cb1ef1d3693ca7727a42292ee487b42f682c2b + checksum: 10c0/5360228a980c024445483c88e14c2f2e69ca7b8386c0c39bd147307b0296277fdf06c27e43dba0e43d9ea6abee7b0269a4d6fe166e57ad5ffb2e093759ff6c03 languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/mdx-loader@npm:3.5.1" +"@docusaurus/mdx-loader@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/mdx-loader@npm:3.5.2" dependencies: - "@docusaurus/logger": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" + "@docusaurus/logger": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" "@mdx-js/mdx": "npm:^3.0.0" "@slorber/remark-comment": "npm:^1.0.0" escape-html: "npm:^1.0.3" @@ -1863,15 +1864,15 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/a5a0a29fde5dbd3d6137caa31c2dcaa95e833dcce1031c4bbe25c8d1018944b89183309619be5c9e8ee487708db076c8f3830e62b8a0ade93e59654386a4475c + checksum: 10c0/52f193578cd3f369c155a2a7a5db532dc482ecb460e3b32ca1111e0036ea8939bfaf4094860929510e639f9a00d1edbbedc797ccdef9eddc381bedaa255d5ab3 languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/module-type-aliases@npm:3.5.1" +"@docusaurus/module-type-aliases@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/module-type-aliases@npm:3.5.2" dependencies: - "@docusaurus/types": "npm:3.5.1" + "@docusaurus/types": "npm:3.5.2" "@types/history": "npm:^4.7.11" "@types/react": "npm:*" "@types/react-router-config": "npm:*" @@ -1881,22 +1882,22 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: 10c0/4ffac163da4887230759c273eddde0f34ddee65c1f26ef0ee53efca4aa98017481e94fa0d56b8240871bf11ca330401d128508adfc679526b18329db46c2a76b + checksum: 10c0/5174c8ad4a545b4ef8aa16bae6f6a2d501ab0d4ddd400cca83c55b6b35eac79b1d7cff52d6041da4f0f339a969d72be1f40e57d5ea73a50a61e0688505627e0c languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/plugin-content-blog@npm:3.5.1" - dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/logger": "npm:3.5.1" - "@docusaurus/mdx-loader": "npm:3.5.1" - "@docusaurus/theme-common": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-common": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" +"@docusaurus/plugin-content-blog@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-blog@npm:3.5.2" + dependencies: + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/logger": "npm:3.5.2" + "@docusaurus/mdx-loader": "npm:3.5.2" + "@docusaurus/theme-common": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-common": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" cheerio: "npm:1.0.0-rc.12" feed: "npm:^4.2.2" fs-extra: "npm:^11.1.1" @@ -1911,23 +1912,23 @@ __metadata: "@docusaurus/plugin-content-docs": "*" react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/580d1715f11a4835af4e3f1be50a55a357bcf50213fb72f97d98be4c73ac95d998fe7ced8f0a3ad86703c7913be313baa0edd3c756d0772822b11d3f8e226a2e + checksum: 10c0/0cdd4944e19c4ed02783be311dd735728a03282585517f48277358373cf46740b5659daa14bdaf58f80e0f949579a97110aa785a15333ad420154acc997471e6 languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/plugin-content-docs@npm:3.5.1" - dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/logger": "npm:3.5.1" - "@docusaurus/mdx-loader": "npm:3.5.1" - "@docusaurus/module-type-aliases": "npm:3.5.1" - "@docusaurus/theme-common": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-common": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" +"@docusaurus/plugin-content-docs@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-docs@npm:3.5.2" + dependencies: + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/logger": "npm:3.5.2" + "@docusaurus/mdx-loader": "npm:3.5.2" + "@docusaurus/module-type-aliases": "npm:3.5.2" + "@docusaurus/theme-common": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-common": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" "@types/react-router-config": "npm:^5.0.7" combine-promises: "npm:^1.1.0" fs-extra: "npm:^11.1.1" @@ -1939,152 +1940,152 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/c2e117c875c68d1a6d517195a024509c9ddc0051c89d0f13cce2707497c30ada8167e61b2702b19d36a5acc52beff9b1c7087110a0e746fee2af86ac000f686c + checksum: 10c0/fd245e323bd2735c9a65bbb50c8411db3bf8b562ad812ef92c4637554b1606aeaf2f2da95ea447a6fb158d96836677d7f95a6a006dae3c4730c231c5527fd7ce languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/plugin-content-pages@npm:3.5.1" +"@docusaurus/plugin-content-pages@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-pages@npm:3.5.2" dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/mdx-loader": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/mdx-loader": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" fs-extra: "npm:^11.1.1" tslib: "npm:^2.6.0" webpack: "npm:^5.88.1" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/8c4d8e6b47012885b20cf08de0799bea95b27ebaec15298b51eb76c153a2b5e1887d4ba0d3bc626748d97f2bed2e1ea6df56e7587387c18c40fbecec11c54a3a + checksum: 10c0/4ca00fad896976095a64f485c6b58da5426fb8301921b2d3099d3604f3a3485461543e373415b54ce743104ff67f54e4f6fb4364547fce3d8c88be57e1c87426 languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/plugin-debug@npm:3.5.1" +"@docusaurus/plugin-debug@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-debug@npm:3.5.2" dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" fs-extra: "npm:^11.1.1" react-json-view-lite: "npm:^1.2.0" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/1b1e142454a90d163e37c943a3d7ab8a1ab4395d715455f2fd5e9456ce61825750157800cb36851113c57e887e9794e4b383d42f10abc289d0554e5f6abef19a + checksum: 10c0/2d47f01154a026b9c9028df72fa87a633772c5079501a8e7c48ca48ba87fd1f4ec6e7e277c8123315cccbc43a9897e45e8a0b8b975cc337a74316eee03f7b320 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/plugin-google-analytics@npm:3.5.1" +"@docusaurus/plugin-google-analytics@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-analytics@npm:3.5.2" dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/e95428125a2678c694778e0e6bcb2e51fa67d74482e921438198e6d96ea4b55d4feefcad6aa36114808ce4518bd4f195abf202a548eb46dbaa7518a1e323ce80 + checksum: 10c0/19e2fbdb625a0345c7f5571ae39fae5803b32933f7f69ba481daf56b4640d68c899049a8c0a7a774e533723364361a7e56839e4fd279940717c5c35d66c226b5 languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/plugin-google-gtag@npm:3.5.1" +"@docusaurus/plugin-google-gtag@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-gtag@npm:3.5.2" dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" "@types/gtag.js": "npm:^0.0.12" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/0aae8ecea7b60e76deffa86d71a1a89109be4716c74b386a44e2a11fea93cb093ed56b8f549992cc9032156c319c511172d00af34a6d27a5fd67dd47797da79f + checksum: 10c0/ba502ae3e0b766b8eebafe89935365199cbc66f9d472950d3d95362619b1f78dddf8e45a73c7e9a1040be965b927ea5ce76037b3f7ee5443c25cab8e6e232934 languageName: node linkType: hard -"@docusaurus/plugin-google-tag-manager@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/plugin-google-tag-manager@npm:3.5.1" +"@docusaurus/plugin-google-tag-manager@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-tag-manager@npm:3.5.2" dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/515416d6638d770684e6ef0812fce580a791bcbc0a46dba9a1eb9ee1b1174e2567cf921270adac23a64bd6be47a87b0e9d8d600d1c17941a061fe2574322f7cd + checksum: 10c0/067eed163b41ac03e85b70ec677525479bae6f4b7137e837d81dd48d03ab8c246b52be3236283cbc4607039beddc618adcfe451f91b19e2d41d343cd0952bd73 languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/plugin-sitemap@npm:3.5.1" - dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/logger": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-common": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" +"@docusaurus/plugin-sitemap@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-sitemap@npm:3.5.2" + dependencies: + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/logger": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-common": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" fs-extra: "npm:^11.1.1" sitemap: "npm:^7.1.1" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/58a40cf4c61e1879470778b8e5d37903bedff65ec2bf046b5cd7e38fa402ae557760f6fb6a8d25d8ea24b8d8d153975471ee5585c1176b958be795558b16570e + checksum: 10c0/9490c3a11869fb50abe7d8d9c235d57b18247a2dbe59d2351a6a919f0a4cf5445879e019db049a5dd55cbbb1ce0e19d5f1342e368e593408652f48d19331f961 languageName: node linkType: hard -"@docusaurus/preset-classic@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/preset-classic@npm:3.5.1" - dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/plugin-content-blog": "npm:3.5.1" - "@docusaurus/plugin-content-docs": "npm:3.5.1" - "@docusaurus/plugin-content-pages": "npm:3.5.1" - "@docusaurus/plugin-debug": "npm:3.5.1" - "@docusaurus/plugin-google-analytics": "npm:3.5.1" - "@docusaurus/plugin-google-gtag": "npm:3.5.1" - "@docusaurus/plugin-google-tag-manager": "npm:3.5.1" - "@docusaurus/plugin-sitemap": "npm:3.5.1" - "@docusaurus/theme-classic": "npm:3.5.1" - "@docusaurus/theme-common": "npm:3.5.1" - "@docusaurus/theme-search-algolia": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" +"@docusaurus/preset-classic@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/preset-classic@npm:3.5.2" + dependencies: + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/plugin-content-blog": "npm:3.5.2" + "@docusaurus/plugin-content-docs": "npm:3.5.2" + "@docusaurus/plugin-content-pages": "npm:3.5.2" + "@docusaurus/plugin-debug": "npm:3.5.2" + "@docusaurus/plugin-google-analytics": "npm:3.5.2" + "@docusaurus/plugin-google-gtag": "npm:3.5.2" + "@docusaurus/plugin-google-tag-manager": "npm:3.5.2" + "@docusaurus/plugin-sitemap": "npm:3.5.2" + "@docusaurus/theme-classic": "npm:3.5.2" + "@docusaurus/theme-common": "npm:3.5.2" + "@docusaurus/theme-search-algolia": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/6a2b7d0c87bf7fff0c8003f3ac478f25894ecd02724c1d1d4a82a417a0dbd620f620e70d284fe13b31f21e39ed451a22f6fccbeae0367f60acb96c013f3801e5 - languageName: node - linkType: hard - -"@docusaurus/theme-classic@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/theme-classic@npm:3.5.1" - dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/mdx-loader": "npm:3.5.1" - "@docusaurus/module-type-aliases": "npm:3.5.1" - "@docusaurus/plugin-content-blog": "npm:3.5.1" - "@docusaurus/plugin-content-docs": "npm:3.5.1" - "@docusaurus/plugin-content-pages": "npm:3.5.1" - "@docusaurus/theme-common": "npm:3.5.1" - "@docusaurus/theme-translations": "npm:3.5.1" - "@docusaurus/types": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-common": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" + checksum: 10c0/ea15474b01399a7bf05d6fd8b0edbf2856ffc83baa0d726b6e90c365ffc93ed39a78ac3d5690750f43051387ff96a8b455927ffa712f4589f4e4b45a4490aaaa + languageName: node + linkType: hard + +"@docusaurus/theme-classic@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-classic@npm:3.5.2" + dependencies: + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/mdx-loader": "npm:3.5.2" + "@docusaurus/module-type-aliases": "npm:3.5.2" + "@docusaurus/plugin-content-blog": "npm:3.5.2" + "@docusaurus/plugin-content-docs": "npm:3.5.2" + "@docusaurus/plugin-content-pages": "npm:3.5.2" + "@docusaurus/theme-common": "npm:3.5.2" + "@docusaurus/theme-translations": "npm:3.5.2" + "@docusaurus/types": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-common": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" "@mdx-js/react": "npm:^3.0.0" clsx: "npm:^2.0.0" copy-text-to-clipboard: "npm:^3.2.0" @@ -2101,18 +2102,18 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/bef53f309e0aabc179c7b4d9bea276bb541e3148330fe51d3ac7777284fcd8248910745c6043b7a9b3537566da2381a9b1bf8260d4027633a83945acfacc11bd + checksum: 10c0/b0f1dd2a81b96d5522ce456de77e0edd539ea07406ff370b624d878a46af4b33f66892242bc177bf04a0026831fccd3621d722c174ebb8a05a8e6f6ed07d72c3 languageName: node linkType: hard -"@docusaurus/theme-common@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/theme-common@npm:3.5.1" +"@docusaurus/theme-common@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-common@npm:3.5.2" dependencies: - "@docusaurus/mdx-loader": "npm:3.5.1" - "@docusaurus/module-type-aliases": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-common": "npm:3.5.1" + "@docusaurus/mdx-loader": "npm:3.5.2" + "@docusaurus/module-type-aliases": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-common": "npm:3.5.2" "@types/history": "npm:^4.7.11" "@types/react": "npm:*" "@types/react-router-config": "npm:*" @@ -2125,22 +2126,22 @@ __metadata: "@docusaurus/plugin-content-docs": "*" react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/3dc262190b27e2df563133200a8ccfd42330fbc7ac1906a51ebb261d29e7033f17d1927178aa470e9ff8328b94dc8e0959784835ebcf18721eef0a3482e26b59 + checksum: 10c0/ae84a910b98c2b6706110e1580af96e5d87d5b29fe1f085d461932aa9608ee3df90e257d809ddcea5c5d848a160933d16052db1669dd062b5d13870834ac0394 languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/theme-search-algolia@npm:3.5.1" +"@docusaurus/theme-search-algolia@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-search-algolia@npm:3.5.2" dependencies: "@docsearch/react": "npm:^3.5.2" - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/logger": "npm:3.5.1" - "@docusaurus/plugin-content-docs": "npm:3.5.1" - "@docusaurus/theme-common": "npm:3.5.1" - "@docusaurus/theme-translations": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-validation": "npm:3.5.1" + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/logger": "npm:3.5.2" + "@docusaurus/plugin-content-docs": "npm:3.5.2" + "@docusaurus/theme-common": "npm:3.5.2" + "@docusaurus/theme-translations": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-validation": "npm:3.5.2" algoliasearch: "npm:^4.18.0" algoliasearch-helper: "npm:^3.13.3" clsx: "npm:^2.0.0" @@ -2152,30 +2153,30 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/e725afad1b6dc734335a7c3492db2d190912c5d2540c8cc2a1d19e12b5da580901729f45844c32034ad50597ed0dd6283bde5218a741b3e594e91795c54b535c + checksum: 10c0/c617528fc0574611e49eb355f99df47e77a295a3c87792f185ec53ce0e7a6b239f017e0d9f8b45d91c87f3c615e9008441978d6daf35debcbb1b48fc9d2d98ee languageName: node linkType: hard -"@docusaurus/theme-translations@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/theme-translations@npm:3.5.1" +"@docusaurus/theme-translations@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-translations@npm:3.5.2" dependencies: fs-extra: "npm:^11.1.1" tslib: "npm:^2.6.0" - checksum: 10c0/2d98004226cdf729aa77768bbec7c3500cd01666ab24036b77a35321fcd7e39610c1b208127e979387efca70d6cb61845aa75b59c68dbeac10cd721aeba472b0 + checksum: 10c0/aa427b55a6d642ff30d67d5b9b8bc9f16f92b8902b125d3d6499c59e7e4ece3549a8a8e9fc017ef1cc68d9b9d5426a35812f8bf829c049103607867d605adc7b languageName: node linkType: hard -"@docusaurus/tsconfig@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/tsconfig@npm:3.5.1" - checksum: 10c0/db21721dab74e410a1d435f207d5e2e7ea590eefc39e158ef539e91f9bfa10046fca0a0afb83d1ccd78d5a0281a82fc3c005461ca785f1d04298c882fdf40c3e +"@docusaurus/tsconfig@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/tsconfig@npm:3.5.2" + checksum: 10c0/1cde5cfadfc94605ba9a1ec8484bc58700bcff99944fa20c6f6d93599126914dc33f15c3464ee3279cf6becafcea86909d1d25a20f8f97e95c8ddf6b1122eac8 languageName: node linkType: hard -"@docusaurus/types@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/types@npm:3.5.1" +"@docusaurus/types@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/types@npm:3.5.2" dependencies: "@mdx-js/mdx": "npm:^3.0.0" "@types/history": "npm:^4.7.11" @@ -2189,13 +2190,13 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10c0/34c6816bea33125ffaf6986ce14d09b94af3dc9f41a92aa2bb25ef42bcdf6af0f182f3e35a11c43f106458d3caf93b184bacb982ec1c0eee85fcd4c9b68e0e10 + checksum: 10c0/a06607a8ed96871d9a2c1239e1d94e584acd5c638f7eb4071feb1f18221c25c9b78794b3f804884db201cfdfc67cecdf37a823efe854f435fb4f5a36b28237d4 languageName: node linkType: hard -"@docusaurus/utils-common@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/utils-common@npm:3.5.1" +"@docusaurus/utils-common@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils-common@npm:3.5.2" dependencies: tslib: "npm:^2.6.0" peerDependencies: @@ -2203,32 +2204,32 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 10c0/e4d5347351a33ead3d7f03b4f03a24b8f1be0c77c1ebe30d2bb6fc7afba882c72f61a52d4982e9769a59da7526ff0d5a79e9e709866e2d11b75c1af148b4fc3c + checksum: 10c0/17723bed0174d98895eff9666e9988757cb1b3562d90045db7a9a90294d686ca5472f5d7c171de7f306148ae24573ae7e959d31167a8dac8c1b4d7606459e056 languageName: node linkType: hard -"@docusaurus/utils-validation@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/utils-validation@npm:3.5.1" +"@docusaurus/utils-validation@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils-validation@npm:3.5.2" dependencies: - "@docusaurus/logger": "npm:3.5.1" - "@docusaurus/utils": "npm:3.5.1" - "@docusaurus/utils-common": "npm:3.5.1" + "@docusaurus/logger": "npm:3.5.2" + "@docusaurus/utils": "npm:3.5.2" + "@docusaurus/utils-common": "npm:3.5.2" fs-extra: "npm:^11.2.0" joi: "npm:^17.9.2" js-yaml: "npm:^4.1.0" lodash: "npm:^4.17.21" tslib: "npm:^2.6.0" - checksum: 10c0/84233e321c05f61c9527cd11b0b063bf73b01a069c0ad75e59ef0e5aee12ad7e5b15da1664d9edbceafa67b991c56927f2f024d281a081dbaec1b45018c61fd1 + checksum: 10c0/b179f7e68f9e3bfad7d03001ca9280e4122592a8995ea7ca31a8a59c5ce3b568af1177b06b41417c98bcd4cd30a7a054d0c06be8384b3f05be37bf239df96213 languageName: node linkType: hard -"@docusaurus/utils@npm:3.5.1": - version: 3.5.1 - resolution: "@docusaurus/utils@npm:3.5.1" +"@docusaurus/utils@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils@npm:3.5.2" dependencies: - "@docusaurus/logger": "npm:3.5.1" - "@docusaurus/utils-common": "npm:3.5.1" + "@docusaurus/logger": "npm:3.5.2" + "@docusaurus/utils-common": "npm:3.5.2" "@svgr/webpack": "npm:^8.1.0" escape-string-regexp: "npm:^4.0.0" file-loader: "npm:^6.2.0" @@ -2252,7 +2253,7 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 10c0/5476cfb5ec57e3dd754c39d1720de6edcb82f868cc5e18556fd2cbef1a9bdef7a018f58dd09a8ed6a3b2fe081630a12464e68c9e4ee71a3f348c29f20f5c1ad4 + checksum: 10c0/a4d2d530c16ffd93bb84f5bc221efb767cba5915cfabd36f83130ba008cbb03a4d79ec324bb1dd0ef2d25d1317692357ee55ec8df0e9e801022e37c633b80ca9 languageName: node linkType: hard @@ -4947,12 +4948,12 @@ __metadata: version: 0.0.0-use.local resolution: "docs@workspace:." dependencies: - "@docusaurus/core": "npm:3.5.1" - "@docusaurus/module-type-aliases": "npm:3.5.1" - "@docusaurus/plugin-content-docs": "npm:3.5.1" - "@docusaurus/preset-classic": "npm:3.5.1" - "@docusaurus/theme-common": "npm:3.5.1" - "@docusaurus/tsconfig": "npm:3.5.1" + "@docusaurus/core": "npm:3.5.2" + "@docusaurus/module-type-aliases": "npm:3.5.2" + "@docusaurus/plugin-content-docs": "npm:3.5.2" + "@docusaurus/preset-classic": "npm:3.5.2" + "@docusaurus/theme-common": "npm:3.5.2" + "@docusaurus/tsconfig": "npm:3.5.2" "@mdx-js/react": "npm:3.0.1" clsx: "npm:2.1.1" prism-react-renderer: "npm:2.3.1" From 3fbf1f683d5c31335e0e9edde0f832f8dc4cfb92 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:52:27 +0000 Subject: [PATCH 08/52] chore(deps): update chore (#11264) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [cypress](https://cypress.io) ([source](https://togithub.com/cypress-io/cypress)) | [`13.13.2` -> `13.13.3`](https://renovatebot.com/diffs/npm/cypress/13.13.2/13.13.3) | [![age](https://developer.mend.io/api/mc/badges/age/npm/cypress/13.13.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/cypress/13.13.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/cypress/13.13.2/13.13.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/cypress/13.13.2/13.13.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [nx](https://nx.dev) ([source](https://togithub.com/nrwl/nx/tree/HEAD/packages/nx)) | [`19.5.7` -> `19.6.0`](https://renovatebot.com/diffs/npm/nx/19.5.7/19.6.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/nx/19.6.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/nx/19.6.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/nx/19.5.7/19.6.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/nx/19.5.7/19.6.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
cypress-io/cypress (cypress) ### [`v13.13.3`](https://togithub.com/cypress-io/cypress/releases/tag/v13.13.3) [Compare Source](https://togithub.com/cypress-io/cypress/compare/v13.13.2...v13.13.3) Changelog: https://docs.cypress.io/guides/references/changelog#13-13-3
nrwl/nx (nx) ### [`v19.6.0`](https://togithub.com/nrwl/nx/compare/19.5.7...541079427324c05bc682f06b7b95eb68e721d8b4) [Compare Source](https://togithub.com/nrwl/nx/compare/19.5.7...19.6.0)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +- yarn.lock | 112 +++++++++++++++++++++++++-------------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index c5a91e7b9f14..2fac09ffa27c 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "concurrently": "8.2.2", "core-js": "3.38.0", "cross-env": "7.0.3", - "cypress": "13.13.2", + "cypress": "13.13.3", "cypress-fail-fast": "7.1.1", "cypress-wait-until": "3.0.2", "dependency-cruiser": "16.3.10", @@ -117,7 +117,7 @@ "ncp": "2.0.0", "nodemon": "3.1.4", "npm-packlist": "8.0.2", - "nx": "19.5.7", + "nx": "19.6.0", "ora": "8.0.1", "prettier": "3.3.3", "prettier-plugin-curly": "0.2.2", diff --git a/yarn.lock b/yarn.lock index 16fb7e0ab62a..d99a4ae7fd26 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5659,15 +5659,15 @@ __metadata: languageName: node linkType: hard -"@nrwl/tao@npm:19.5.7": - version: 19.5.7 - resolution: "@nrwl/tao@npm:19.5.7" +"@nrwl/tao@npm:19.6.0": + version: 19.6.0 + resolution: "@nrwl/tao@npm:19.6.0" dependencies: - nx: "npm:19.5.7" + nx: "npm:19.6.0" tslib: "npm:^2.3.0" bin: tao: index.js - checksum: 10c0/4a86e121688728cd78a41fbfada3248ae77e172bf2f7c63d06fecb9fb76972c13702beaf552d298130d8a2fdff17350b688ca62976ef11ee9169891d05329002 + checksum: 10c0/719b372bec775260f663126e616e1c30f069c2a6437b47a28aac020df5fb204a01ebbd58852e61f66af7a0aaa0ef06a9d4957cbc84c82544fbcc2b3e3c0a2737 languageName: node linkType: hard @@ -5690,72 +5690,72 @@ __metadata: languageName: node linkType: hard -"@nx/nx-darwin-arm64@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-darwin-arm64@npm:19.5.7" +"@nx/nx-darwin-arm64@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-darwin-arm64@npm:19.6.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@nx/nx-darwin-x64@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-darwin-x64@npm:19.5.7" +"@nx/nx-darwin-x64@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-darwin-x64@npm:19.6.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@nx/nx-freebsd-x64@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-freebsd-x64@npm:19.5.7" +"@nx/nx-freebsd-x64@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-freebsd-x64@npm:19.6.0" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@nx/nx-linux-arm-gnueabihf@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-linux-arm-gnueabihf@npm:19.5.7" +"@nx/nx-linux-arm-gnueabihf@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-linux-arm-gnueabihf@npm:19.6.0" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@nx/nx-linux-arm64-gnu@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-linux-arm64-gnu@npm:19.5.7" +"@nx/nx-linux-arm64-gnu@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-linux-arm64-gnu@npm:19.6.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@nx/nx-linux-arm64-musl@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-linux-arm64-musl@npm:19.5.7" +"@nx/nx-linux-arm64-musl@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-linux-arm64-musl@npm:19.6.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@nx/nx-linux-x64-gnu@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-linux-x64-gnu@npm:19.5.7" +"@nx/nx-linux-x64-gnu@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-linux-x64-gnu@npm:19.6.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@nx/nx-linux-x64-musl@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-linux-x64-musl@npm:19.5.7" +"@nx/nx-linux-x64-musl@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-linux-x64-musl@npm:19.6.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@nx/nx-win32-arm64-msvc@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-win32-arm64-msvc@npm:19.5.7" +"@nx/nx-win32-arm64-msvc@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-win32-arm64-msvc@npm:19.6.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@nx/nx-win32-x64-msvc@npm:19.5.7": - version: 19.5.7 - resolution: "@nx/nx-win32-x64-msvc@npm:19.5.7" +"@nx/nx-win32-x64-msvc@npm:19.6.0": + version: 19.6.0 + resolution: "@nx/nx-win32-x64-msvc@npm:19.6.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -14788,9 +14788,9 @@ __metadata: languageName: node linkType: hard -"cypress@npm:13.13.2": - version: 13.13.2 - resolution: "cypress@npm:13.13.2" +"cypress@npm:13.13.3": + version: 13.13.3 + resolution: "cypress@npm:13.13.3" dependencies: "@cypress/request": "npm:^3.0.1" "@cypress/xvfb": "npm:^1.2.4" @@ -14836,7 +14836,7 @@ __metadata: yauzl: "npm:^2.10.0" bin: cypress: bin/cypress - checksum: 10c0/7a38851aac96ff36414a2a4665312cc6778b9863913d5328685c4b13339aa3159506574d63d60d974ccc4a88b4d26db2b3a9c8c5a9921d351dc41ebdae446bae + checksum: 10c0/187fdbe0ca6eedd04a04828971847ef5f3d0e0c2bd74a25a761dd2cc0de1fb84f7e4c1bc4f88e46f753d87748b31eca3ddaae798275546fe1964c8453cbe4a63 languageName: node linkType: hard @@ -23694,22 +23694,22 @@ __metadata: languageName: node linkType: hard -"nx@npm:19.5.7, nx@npm:>=17.1.2 < 20": - version: 19.5.7 - resolution: "nx@npm:19.5.7" +"nx@npm:19.6.0, nx@npm:>=17.1.2 < 20": + version: 19.6.0 + resolution: "nx@npm:19.6.0" dependencies: "@napi-rs/wasm-runtime": "npm:0.2.4" - "@nrwl/tao": "npm:19.5.7" - "@nx/nx-darwin-arm64": "npm:19.5.7" - "@nx/nx-darwin-x64": "npm:19.5.7" - "@nx/nx-freebsd-x64": "npm:19.5.7" - "@nx/nx-linux-arm-gnueabihf": "npm:19.5.7" - "@nx/nx-linux-arm64-gnu": "npm:19.5.7" - "@nx/nx-linux-arm64-musl": "npm:19.5.7" - "@nx/nx-linux-x64-gnu": "npm:19.5.7" - "@nx/nx-linux-x64-musl": "npm:19.5.7" - "@nx/nx-win32-arm64-msvc": "npm:19.5.7" - "@nx/nx-win32-x64-msvc": "npm:19.5.7" + "@nrwl/tao": "npm:19.6.0" + "@nx/nx-darwin-arm64": "npm:19.6.0" + "@nx/nx-darwin-x64": "npm:19.6.0" + "@nx/nx-freebsd-x64": "npm:19.6.0" + "@nx/nx-linux-arm-gnueabihf": "npm:19.6.0" + "@nx/nx-linux-arm64-gnu": "npm:19.6.0" + "@nx/nx-linux-arm64-musl": "npm:19.6.0" + "@nx/nx-linux-x64-gnu": "npm:19.6.0" + "@nx/nx-linux-x64-musl": "npm:19.6.0" + "@nx/nx-win32-arm64-msvc": "npm:19.6.0" + "@nx/nx-win32-x64-msvc": "npm:19.6.0" "@yarnpkg/lockfile": "npm:^1.1.0" "@yarnpkg/parsers": "npm:3.0.0-rc.46" "@zkochan/js-yaml": "npm:0.0.7" @@ -23775,7 +23775,7 @@ __metadata: bin: nx: bin/nx.js nx-cloud: bin/nx-cloud.js - checksum: 10c0/4d805c63021ee7b23ff97911cf1ee76f381d15893e8efdbe0b082590a85e6958e8a192bf7e90a1f90224a04b4a0abf8dabf4221e94d1c7e32c937f438d3eb512 + checksum: 10c0/199191bd88877b6fb38b8699f0f195d0c84f8380eff7f675a12db60c1c4095fa4734114403a847eab1da0ca452f09ce9c88e17a05ded436aa8d30118dfd520f9 languageName: node linkType: hard @@ -26657,7 +26657,7 @@ __metadata: concurrently: "npm:8.2.2" core-js: "npm:3.38.0" cross-env: "npm:7.0.3" - cypress: "npm:13.13.2" + cypress: "npm:13.13.3" cypress-fail-fast: "npm:7.1.1" cypress-wait-until: "npm:3.0.2" dependency-cruiser: "npm:16.3.10" @@ -26679,7 +26679,7 @@ __metadata: ncp: "npm:2.0.0" nodemon: "npm:3.1.4" npm-packlist: "npm:8.0.2" - nx: "npm:19.5.7" + nx: "npm:19.6.0" ora: "npm:8.0.1" prettier: "npm:3.3.3" prettier-plugin-curly: "npm:0.2.2" From 06f723002934d931497ce92dd365a972d4e13cfb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:57:41 +0100 Subject: [PATCH 09/52] chore(deps): update dependency publint to v0.2.10 (#11265) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [publint](https://publint.dev) ([source](https://togithub.com/bluwy/publint/tree/HEAD/pkg)) | [`0.2.9` -> `0.2.10`](https://renovatebot.com/diffs/npm/publint/0.2.9/0.2.10) | [![age](https://developer.mend.io/api/mc/badges/age/npm/publint/0.2.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/publint/0.2.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/publint/0.2.9/0.2.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/publint/0.2.9/0.2.10?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
bluwy/publint (publint) ### [`v0.2.10`](https://togithub.com/bluwy/publint/releases/tag/v0.2.10) [Compare Source](https://togithub.com/bluwy/publint/compare/v0.2.9...v0.2.10) ##### Features - Adds a new rule that validates the `"repository"` field ([https://github.com/bluwy/publint/pull/106](https://togithub.com/bluwy/publint/pull/106)) - If `"repository"` is a string, it must be one of the supported shorthand strings from the docs. - If `"repository"` is an object with `"type": "git"`, the `"url"` must be a valid [git URL](https://git-scm.com/docs/git-clone#\_git_urls) and can be [parsed by npm](https://togithub.com/npm/hosted-git-info). - The `git://` protocol for GitHub repos should not be used due [security concerns](https://github.blog/security/application-security/improving-git-protocol-security-github/). - GitHub or GitLab links should be prefixed with `git+` and postfixed with `.git`. (This is also warned by npm when publishing a package). #### New Contributors - [@​Namchee](https://togithub.com/Namchee) made their first contribution in [https://github.com/bluwy/publint/pull/106](https://togithub.com/bluwy/publint/pull/106) **Full Changelog**: https://github.com/bluwy/publint/compare/v0.2.9...v0.2.10
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../dbAuth/middleware/package.json | 2 +- .../supabase/middleware/package.json | 2 +- packages/auth/package.json | 2 +- packages/project-config/package.json | 2 +- packages/router/package.json | 2 +- packages/vite/package.json | 2 +- packages/web/package.json | 2 +- yarn.lock | 22 +++++++++---------- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/auth-providers/dbAuth/middleware/package.json b/packages/auth-providers/dbAuth/middleware/package.json index a11ceb653696..16f2c9306541 100644 --- a/packages/auth-providers/dbAuth/middleware/package.json +++ b/packages/auth-providers/dbAuth/middleware/package.json @@ -47,7 +47,7 @@ "@redwoodjs/graphql-server": "workspace:*", "@types/aws-lambda": "8.10.143", "concurrently": "8.2.2", - "publint": "0.2.9", + "publint": "0.2.10", "ts-toolbelt": "9.6.0", "tsx": "4.17.0", "typescript": "5.5.4", diff --git a/packages/auth-providers/supabase/middleware/package.json b/packages/auth-providers/supabase/middleware/package.json index 11c269fbfaae..ecb5636e118c 100644 --- a/packages/auth-providers/supabase/middleware/package.json +++ b/packages/auth-providers/supabase/middleware/package.json @@ -50,7 +50,7 @@ "@redwoodjs/graphql-server": "workspace:*", "@types/aws-lambda": "8.10.143", "concurrently": "8.2.2", - "publint": "0.2.9", + "publint": "0.2.10", "ts-toolbelt": "9.6.0", "tsx": "4.17.0", "typescript": "5.5.4", diff --git a/packages/auth/package.json b/packages/auth/package.json index 36571201b603..47adba1abad0 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -97,7 +97,7 @@ "@testing-library/react": "14.3.1", "concurrently": "8.2.2", "msw": "1.3.3", - "publint": "0.2.9", + "publint": "0.2.10", "tsx": "4.17.0", "type-fest": "4.24.0", "typescript": "5.5.4", diff --git a/packages/project-config/package.json b/packages/project-config/package.json index 97e49b0c71f7..812803e37ab8 100644 --- a/packages/project-config/package.json +++ b/packages/project-config/package.json @@ -45,7 +45,7 @@ "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/framework-tools": "workspace:*", "concurrently": "8.2.2", - "publint": "0.2.9", + "publint": "0.2.10", "rimraf": "6.0.1", "tsx": "4.17.0", "typescript": "5.5.4", diff --git a/packages/router/package.json b/packages/router/package.json index a3735a879801..9822b215a496 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -104,7 +104,7 @@ "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "concurrently": "8.2.2", - "publint": "0.2.9", + "publint": "0.2.10", "react": "19.0.0-rc-8269d55d-20240802", "react-dom": "19.0.0-rc-8269d55d-20240802", "tstyche": "2.1.1", diff --git a/packages/vite/package.json b/packages/vite/package.json index 2f89a6b8cd1e..84586507aa25 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -108,7 +108,7 @@ "@types/yargs-parser": "21.0.3", "concurrently": "8.2.2", "glob": "11.0.0", - "publint": "0.2.9", + "publint": "0.2.10", "rollup": "4.20.0", "tsx": "4.17.0", "typescript": "5.5.4", diff --git a/packages/web/package.json b/packages/web/package.json index e87ca422a6b1..247bc2005c52 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -171,7 +171,7 @@ "@types/react-dom": "^18.2.19", "concurrently": "8.2.2", "nodemon": "3.1.4", - "publint": "0.2.9", + "publint": "0.2.10", "react": "19.0.0-rc-8269d55d-20240802", "react-dom": "19.0.0-rc-8269d55d-20240802", "tstyche": "2.1.1", diff --git a/yarn.lock b/yarn.lock index d99a4ae7fd26..d0d6ce46975c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7448,7 +7448,7 @@ __metadata: "@redwoodjs/web": "workspace:*" "@types/aws-lambda": "npm:8.10.143" concurrently: "npm:8.2.2" - publint: "npm:0.2.9" + publint: "npm:0.2.10" ts-toolbelt: "npm:9.6.0" tsx: "npm:4.17.0" typescript: "npm:5.5.4" @@ -7630,7 +7630,7 @@ __metadata: "@supabase/ssr": "npm:0.4.0" "@types/aws-lambda": "npm:8.10.143" concurrently: "npm:8.2.2" - publint: "npm:0.2.9" + publint: "npm:0.2.10" ts-toolbelt: "npm:9.6.0" tsx: "npm:4.17.0" typescript: "npm:5.5.4" @@ -7737,7 +7737,7 @@ __metadata: concurrently: "npm:8.2.2" core-js: "npm:3.38.0" msw: "npm:1.3.3" - publint: "npm:0.2.9" + publint: "npm:0.2.10" react: "npm:19.0.0-rc-8269d55d-20240802" tsx: "npm:4.17.0" type-fest: "npm:4.24.0" @@ -8385,7 +8385,7 @@ __metadata: concurrently: "npm:8.2.2" deepmerge: "npm:4.3.1" fast-glob: "npm:3.3.2" - publint: "npm:0.2.9" + publint: "npm:0.2.10" rimraf: "npm:6.0.1" smol-toml: "npm:1.3.0" string-env-interpolation: "npm:1.0.1" @@ -8458,7 +8458,7 @@ __metadata: "@types/react-dom": "npm:^18.2.19" concurrently: "npm:8.2.2" core-js: "npm:3.38.0" - publint: "npm:0.2.9" + publint: "npm:0.2.10" react: "npm:19.0.0-rc-8269d55d-20240802" react-dom: "npm:19.0.0-rc-8269d55d-20240802" tstyche: "npm:2.1.1" @@ -8639,7 +8639,7 @@ __metadata: glob: "npm:11.0.0" http-proxy-middleware: "npm:3.0.0" isbot: "npm:5.1.14" - publint: "npm:0.2.9" + publint: "npm:0.2.10" react: "npm:19.0.0-rc-8269d55d-20240802" react-server-dom-webpack: "npm:19.0.0-rc-8269d55d-20240802" rimraf: "npm:6.0.1" @@ -8709,7 +8709,7 @@ __metadata: graphql-sse: "npm:2.5.3" graphql-tag: "npm:2.12.6" nodemon: "npm:3.1.4" - publint: "npm:0.2.9" + publint: "npm:0.2.10" react: "npm:19.0.0-rc-8269d55d-20240802" react-dom: "npm:19.0.0-rc-8269d55d-20240802" react-helmet-async: "npm:2.0.5" @@ -25329,16 +25329,16 @@ __metadata: languageName: node linkType: hard -"publint@npm:0.2.9": - version: 0.2.9 - resolution: "publint@npm:0.2.9" +"publint@npm:0.2.10": + version: 0.2.10 + resolution: "publint@npm:0.2.10" dependencies: npm-packlist: "npm:^5.1.3" picocolors: "npm:^1.0.1" sade: "npm:^1.8.1" bin: publint: lib/cli.js - checksum: 10c0/b414f40c2bc9372119346d5684eccb12bdf8066fc821301880d9dcdec0a5d852bbe926cb4583511f3e97736c53d1723e46e49285c9463bcb808cbfd979d5c2fc + checksum: 10c0/af1b82d0427e3e18a77157cfecf8dd84270540e8209215a434d571f93a3d0e4e0e56caf87efb7ed18b9518806469440d7ea003df0d15b82bf0500f14ff48aa64 languageName: node linkType: hard From d8baa1c1e7d8125a97379e0594f0a5e105ecca87 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:57:57 +0100 Subject: [PATCH 10/52] chore(lint): enable '@typescript-eslint/only-throw-error' (#11260) Enables `@typescript-eslint/only-throw-error` rule and addresses the resulting errors. Also updates the eslint tsconfig to handle test files. --- .eslintrc.js | 1 - packages/auth/src/__tests__/AuthProvider.test.tsx | 2 +- .../src/plugins/__tests__/useRedwoodError.test.ts | 9 ++++++++- packages/prerender/src/errors.tsx | 10 ++++------ .../web/src/components/cell/createSuspendingCell.tsx | 5 ++++- tsconfig.eslint.json | 3 ++- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 1abf4b674070..aa76958f5b56 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -208,7 +208,6 @@ module.exports = { '@typescript-eslint/no-unnecessary-type-assertion': 'off', '@typescript-eslint/no-unsafe-enum-comparison': 'off', '@typescript-eslint/dot-notation': 'off', - '@typescript-eslint/only-throw-error': 'off', '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-unsafe-return': 'off', '@typescript-eslint/prefer-optional-chain': 'off', diff --git a/packages/auth/src/__tests__/AuthProvider.test.tsx b/packages/auth/src/__tests__/AuthProvider.test.tsx index d20ad977216a..06af8859f82c 100644 --- a/packages/auth/src/__tests__/AuthProvider.test.tsx +++ b/packages/auth/src/__tests__/AuthProvider.test.tsx @@ -649,7 +649,7 @@ describe('Custom auth provider', () => { test("getToken doesn't fail if client throws an error", async () => { mockedTestAuthClient.getToken.mockImplementation(() => { - throw 'Login Required' + throw new Error('Login Required') }) const auth = await getCustomTestAuth() diff --git a/packages/graphql-server/src/plugins/__tests__/useRedwoodError.test.ts b/packages/graphql-server/src/plugins/__tests__/useRedwoodError.test.ts index 09b7f1508ed0..56a0ddcb36b7 100644 --- a/packages/graphql-server/src/plugins/__tests__/useRedwoodError.test.ts +++ b/packages/graphql-server/src/plugins/__tests__/useRedwoodError.test.ts @@ -1,6 +1,10 @@ import type { APIGatewayProxyEvent, Context } from 'aws-lambda' import { CurrencyDefinition, CurrencyResolver } from 'graphql-scalars' +import type { + RedwoodError as RedwoodErrorType, + EmailValidationError as EmailValidationErrorType, +} from '@redwoodjs/api' import { createLogger } from '@redwoodjs/api/logger' import { createGraphQLHandler } from '../../functions/graphql' @@ -12,9 +16,12 @@ jest.mock('../../makeMergedSchema', () => { ForbiddenError, RedwoodGraphQLError, } = require('@redwoodjs/graphql-server/dist/errors') - const { EmailValidationError, RedwoodError } = require('@redwoodjs/api') const { CurrencyResolver } = require('graphql-scalars') + const { RedwoodError, EmailValidationError } = require('@redwoodjs/api') as { + RedwoodError: typeof RedwoodErrorType + EmailValidationError: typeof EmailValidationErrorType + } class WeatherError extends RedwoodError { constructor(message: string, extensions?: Record) { diff --git a/packages/prerender/src/errors.tsx b/packages/prerender/src/errors.tsx index ced9959e40e1..1c7830cb457b 100644 --- a/packages/prerender/src/errors.tsx +++ b/packages/prerender/src/errors.tsx @@ -1,12 +1,11 @@ import type { DocumentNode } from 'graphql' import { print } from 'graphql' -export class PrerenderGqlError { - message: string +export class PrerenderGqlError extends Error { stack: string constructor(message: string) { - this.message = 'GQL error: ' + message + super('GQL error: ' + message) // The stacktrace would just point to this file, which isn't helpful, // because that's not where the error is. So we're just putting the // message there as well @@ -14,12 +13,11 @@ export class PrerenderGqlError { } } -export class GqlHandlerImportError { - message: string +export class GqlHandlerImportError extends Error { stack: string constructor(message: string) { - this.message = 'Gql Handler Import Error: ' + message + super('Gql Handler Import Error: ' + message) // The stacktrace would just point to this file, which isn't helpful, // because that's not where the error is. So we're just putting the // message there as well diff --git a/packages/web/src/components/cell/createSuspendingCell.tsx b/packages/web/src/components/cell/createSuspendingCell.tsx index 7cd14a067c36..cc38242cdcae 100644 --- a/packages/web/src/components/cell/createSuspendingCell.tsx +++ b/packages/web/src/components/cell/createSuspendingCell.tsx @@ -107,7 +107,10 @@ export function createSuspendingCell< const FailureComponent = ({ error, resetErrorBoundary }: FallbackProps) => { if (!Failure) { // So that it bubbles up to the nearest error boundary - throw error + if (error) { + throw error + } + throw new Error('Unreachable code: FailureComponent without a Failure') } const queryResultWithErrorReset = { diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index ad9a7b7a4578..827907f39aa8 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -1,4 +1,5 @@ { "extends": "./tsconfig.compilerOption.json", - "exclude": ["dist", "node_modules", "**/__mocks__"] + "exclude": ["dist", "node_modules", "**/__mocks__"], + "include": ["**/*"] } From c17c5073c175ceb2a6191460fd05a057ee3cfad4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:11:05 +0000 Subject: [PATCH 11/52] fix(deps): update dependency @graphql-tools/utils to v10.5.3 (#11267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@graphql-tools/utils](https://togithub.com/ardatan/graphql-tools) ([source](https://togithub.com/ardatan/graphql-tools/tree/HEAD/packages/utils)) | [`10.5.2` -> `10.5.3`](https://renovatebot.com/diffs/npm/@graphql-tools%2futils/10.5.2/10.5.3) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@graphql-tools%2futils/10.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@graphql-tools%2futils/10.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@graphql-tools%2futils/10.5.2/10.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@graphql-tools%2futils/10.5.2/10.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
ardatan/graphql-tools (@​graphql-tools/utils) ### [`v10.5.3`](https://togithub.com/ardatan/graphql-tools/blob/HEAD/packages/utils/CHANGELOG.md#1053) [Compare Source](https://togithub.com/ardatan/graphql-tools/compare/@graphql-tools/utils@10.5.2...@graphql-tools/utils@10.5.3) ##### Patch Changes - [`2124d7d`](https://togithub.com/ardatan/graphql-tools/commit/2124d7de749b722e051fb591bcf9d514bc73fa50) Thanks [@​ardatan](https://togithub.com/ardatan)! - Allow invalid path in \`getDirectiveExtensions\`
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/graphql-server/package.json | 2 +- packages/realtime/package.json | 2 +- yarn.lock | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/graphql-server/package.json b/packages/graphql-server/package.json index 3884a59a27c6..0acdfb05a96e 100644 --- a/packages/graphql-server/package.json +++ b/packages/graphql-server/package.json @@ -31,7 +31,7 @@ "@escape.tech/graphql-armor": "3.0.1", "@graphql-tools/merge": "9.0.5", "@graphql-tools/schema": "10.0.5", - "@graphql-tools/utils": "10.5.2", + "@graphql-tools/utils": "10.5.3", "@graphql-yoga/plugin-persisted-operations": "3.6.3", "@opentelemetry/api": "1.8.0", "@redwoodjs/api": "workspace:*", diff --git a/packages/realtime/package.json b/packages/realtime/package.json index 7715bb37d4d0..5df5a5368a69 100644 --- a/packages/realtime/package.json +++ b/packages/realtime/package.json @@ -24,7 +24,7 @@ "dependencies": { "@envelop/live-query": "7.0.0", "@graphql-tools/schema": "10.0.5", - "@graphql-tools/utils": "10.5.2", + "@graphql-tools/utils": "10.5.3", "@graphql-yoga/plugin-defer-stream": "3.6.3", "@graphql-yoga/plugin-graphql-sse": "3.6.3", "@graphql-yoga/redis-event-target": "3.0.1", diff --git a/yarn.lock b/yarn.lock index d0d6ce46975c..45ad8b959fe2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4605,9 +4605,9 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/utils@npm:10.5.2, @graphql-tools/utils@npm:^10.0.0, @graphql-tools/utils@npm:^10.2.3, @graphql-tools/utils@npm:^10.3.2, @graphql-tools/utils@npm:^10.4.0": - version: 10.5.2 - resolution: "@graphql-tools/utils@npm:10.5.2" +"@graphql-tools/utils@npm:10.5.3, @graphql-tools/utils@npm:^10.0.0, @graphql-tools/utils@npm:^10.2.3, @graphql-tools/utils@npm:^10.3.2, @graphql-tools/utils@npm:^10.4.0": + version: 10.5.3 + resolution: "@graphql-tools/utils@npm:10.5.3" dependencies: "@graphql-typed-document-node/core": "npm:^3.1.1" cross-inspect: "npm:1.0.1" @@ -4615,7 +4615,7 @@ __metadata: tslib: "npm:^2.4.0" peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 10c0/4db90d543790ad31b4d9f7b59fd704f6185dc1a9ac71d62f158e6ab3cdf48749d45f590cac1453e76d667f154c9236e8b6eb6c318e9e0316206278cc14059e96 + checksum: 10c0/2129447411ff4086f4c1436d24493e3f08de63cab27847b50ff96c3a0cd21ef1e27ca605fd5520ba158f67c39bd6e0818266d062bf8799d795ee5201bf1a9100 languageName: node linkType: hard @@ -8160,7 +8160,7 @@ __metadata: "@escape.tech/graphql-armor": "npm:3.0.1" "@graphql-tools/merge": "npm:9.0.5" "@graphql-tools/schema": "npm:10.0.5" - "@graphql-tools/utils": "npm:10.5.2" + "@graphql-tools/utils": "npm:10.5.3" "@graphql-yoga/plugin-persisted-operations": "npm:3.6.3" "@opentelemetry/api": "npm:1.8.0" "@redwoodjs/api": "workspace:*" @@ -8404,7 +8404,7 @@ __metadata: "@envelop/testing": "npm:7.0.0" "@envelop/types": "npm:5.0.0" "@graphql-tools/schema": "npm:10.0.5" - "@graphql-tools/utils": "npm:10.5.2" + "@graphql-tools/utils": "npm:10.5.3" "@graphql-yoga/plugin-defer-stream": "npm:3.6.3" "@graphql-yoga/plugin-graphql-sse": "npm:3.6.3" "@graphql-yoga/redis-event-target": "npm:3.0.1" From c4c737c9481436ba606b8c6919e16e5df76f2c17 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:13:25 +0000 Subject: [PATCH 12/52] chore(deps): update dependency firebase to v10.13.0 (#11277) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [firebase](https://firebase.google.com/) ([source](https://togithub.com/firebase/firebase-js-sdk), [changelog](https://firebase.google.com/support/release-notes/js)) | [`10.12.5` -> `10.13.0`](https://renovatebot.com/diffs/npm/firebase/10.12.5/10.13.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/firebase/10.13.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/firebase/10.13.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/firebase/10.12.5/10.13.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/firebase/10.12.5/10.13.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
firebase/firebase-js-sdk (firebase) ### [`v10.13.0`](https://togithub.com/firebase/firebase-js-sdk/releases/tag/firebase%4010.13.0) [Compare Source](https://togithub.com/firebase/firebase-js-sdk/compare/firebase@10.12.5...firebase@10.13.0) For more detailed release notes, see [Firebase JavaScript SDK Release Notes](https://firebase.google.com/support/release-notes/js). ### What's Changed #### firebase@10.13.0 ##### Minor Changes - [`6b0ca77b2`](https://togithub.com/firebase/firebase-js-sdk/commit/6b0ca77b28315349b39cca1ec8a63f929df07a4c) [#​8410](https://togithub.com/firebase/firebase-js-sdk/pull/8410) (fixes [#​8303](https://togithub.com/firebase/firebase-js-sdk/issues/8303)) - Migrate from the Node to Web ReadableStream interface - [`e6b852562`](https://togithub.com/firebase/firebase-js-sdk/commit/e6b852562bfe57dd02ae59ee2dce9966b5498b01) [#​8215](https://togithub.com/firebase/firebase-js-sdk/pull/8215) - Add support for reading and writing Firestore vectors. ##### Patch Changes - Updated dependencies \[[`6b0ca77b2`](https://togithub.com/firebase/firebase-js-sdk/commit/6b0ca77b28315349b39cca1ec8a63f929df07a4c), [`6d6ce8100`](https://togithub.com/firebase/firebase-js-sdk/commit/6d6ce8100fd1443a40cd1ebd68ad980cab55fb10), [`2ddbd4e49`](https://togithub.com/firebase/firebase-js-sdk/commit/2ddbd4e4900e148648a1bc4cb82932e096a7009e), [`e6b852562`](https://togithub.com/firebase/firebase-js-sdk/commit/e6b852562bfe57dd02ae59ee2dce9966b5498b01), [`16015723b`](https://togithub.com/firebase/firebase-js-sdk/commit/16015723b1aee46eec4b79e044aeb9dd582370cc)]: - [@​firebase/storage](https://togithub.com/firebase/storage)[@​0](https://togithub.com/0).13.0 - [@​firebase/app](https://togithub.com/firebase/app)[@​0](https://togithub.com/0).10.9 - [@​firebase/auth](https://togithub.com/firebase/auth)[@​1](https://togithub.com/1).7.7 - [@​firebase/firestore](https://togithub.com/firebase/firestore)[@​4](https://togithub.com/4).7.0 - [@​firebase/app-compat](https://togithub.com/firebase/app-compat)[@​0](https://togithub.com/0).2.39 - [@​firebase/storage-compat](https://togithub.com/firebase/storage-compat)[@​0](https://togithub.com/0).3.10 - [@​firebase/auth-compat](https://togithub.com/firebase/auth-compat)[@​0](https://togithub.com/0).5.12 - [@​firebase/firestore-compat](https://togithub.com/firebase/firestore-compat)[@​0](https://togithub.com/0).3.35 #### [@​firebase/firestore](https://togithub.com/firebase/firestore)[@​4](https://togithub.com/4).7.0 ##### Minor Changes - [`e6b852562`](https://togithub.com/firebase/firebase-js-sdk/commit/e6b852562bfe57dd02ae59ee2dce9966b5498b01) [#​8215](https://togithub.com/firebase/firebase-js-sdk/pull/8215) - Add support for reading and writing Firestore vectors. #### [@​firebase/storage](https://togithub.com/firebase/storage)[@​0](https://togithub.com/0).13.0 ##### Minor Changes - [`6b0ca77b2`](https://togithub.com/firebase/firebase-js-sdk/commit/6b0ca77b28315349b39cca1ec8a63f929df07a4c) [#​8410](https://togithub.com/firebase/firebase-js-sdk/pull/8410) (fixes [#​8303](https://togithub.com/firebase/firebase-js-sdk/issues/8303)) - Migrate from the Node to Web ReadableStream interface #### [@​firebase/app](https://togithub.com/firebase/app)[@​0](https://togithub.com/0).10.9 ##### Patch Changes - [`6d6ce8100`](https://togithub.com/firebase/firebase-js-sdk/commit/6d6ce8100fd1443a40cd1ebd68ad980cab55fb10) [#​8425](https://togithub.com/firebase/firebase-js-sdk/pull/8425) (fixes [#​8407](https://togithub.com/firebase/firebase-js-sdk/issues/8407)) - Prevent heartbeats methods from throwing - warn instead. #### [@​firebase/app-compat](https://togithub.com/firebase/app-compat)[@​0](https://togithub.com/0).2.39 ##### Patch Changes - [`16015723b`](https://togithub.com/firebase/firebase-js-sdk/commit/16015723b1aee46eec4b79e044aeb9dd582370cc) [#​8414](https://togithub.com/firebase/firebase-js-sdk/pull/8414) (fixes [#​8409](https://togithub.com/firebase/firebase-js-sdk/issues/8409)) - Updated how app-compat checks the global scope. - Updated dependencies \[[`6d6ce8100`](https://togithub.com/firebase/firebase-js-sdk/commit/6d6ce8100fd1443a40cd1ebd68ad980cab55fb10)]: - [@​firebase/app](https://togithub.com/firebase/app)[@​0](https://togithub.com/0).10.9 #### [@​firebase/auth](https://togithub.com/firebase/auth)[@​1](https://togithub.com/1).7.7 ##### Patch Changes - [`2ddbd4e49`](https://togithub.com/firebase/firebase-js-sdk/commit/2ddbd4e4900e148648a1bc4cb82932e096a7009e) [#​8408](https://togithub.com/firebase/firebase-js-sdk/pull/8408) - Remove localStorage synchronization on storage events in Safari iframes. See [GitHub PR #​8408](https://togithub.com/firebase/firebase-js-sdk/pull/8408). #### [@​firebase/auth-compat](https://togithub.com/firebase/auth-compat)[@​0](https://togithub.com/0).5.12 ##### Patch Changes - Updated dependencies \[[`2ddbd4e49`](https://togithub.com/firebase/firebase-js-sdk/commit/2ddbd4e4900e148648a1bc4cb82932e096a7009e)]: - [@​firebase/auth](https://togithub.com/firebase/auth)[@​1](https://togithub.com/1).7.7 #### [@​firebase/firestore-compat](https://togithub.com/firebase/firestore-compat)[@​0](https://togithub.com/0).3.35 ##### Patch Changes - Updated dependencies \[[`e6b852562`](https://togithub.com/firebase/firebase-js-sdk/commit/e6b852562bfe57dd02ae59ee2dce9966b5498b01)]: - [@​firebase/firestore](https://togithub.com/firebase/firestore)[@​4](https://togithub.com/4).7.0 #### [@​firebase/storage-compat](https://togithub.com/firebase/storage-compat)[@​0](https://togithub.com/0).3.10 ##### Patch Changes - Updated dependencies \[[`6b0ca77b2`](https://togithub.com/firebase/firebase-js-sdk/commit/6b0ca77b28315349b39cca1ec8a63f929df07a4c)]: - [@​firebase/storage](https://togithub.com/firebase/storage)[@​0](https://togithub.com/0).13.0
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../auth-providers/firebase/web/package.json | 4 +- yarn.lock | 100 +++++++++--------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/packages/auth-providers/firebase/web/package.json b/packages/auth-providers/firebase/web/package.json index 7e419360f8da..5a8a67608feb 100644 --- a/packages/auth-providers/firebase/web/package.json +++ b/packages/auth-providers/firebase/web/package.json @@ -31,14 +31,14 @@ "@babel/cli": "7.24.8", "@babel/core": "^7.22.20", "@types/react": "^18.2.55", - "firebase": "10.12.5", + "firebase": "10.13.0", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "react": "19.0.0-rc-8269d55d-20240802", "typescript": "5.5.4" }, "peerDependencies": { - "firebase": "10.12.5" + "firebase": "10.13.0" }, "gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1" } diff --git a/yarn.lock b/yarn.lock index 45ad8b959fe2..c1c7dab5e6d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3274,16 +3274,16 @@ __metadata: languageName: node linkType: hard -"@firebase/app-compat@npm:0.2.38": - version: 0.2.38 - resolution: "@firebase/app-compat@npm:0.2.38" +"@firebase/app-compat@npm:0.2.39": + version: 0.2.39 + resolution: "@firebase/app-compat@npm:0.2.39" dependencies: - "@firebase/app": "npm:0.10.8" + "@firebase/app": "npm:0.10.9" "@firebase/component": "npm:0.6.8" "@firebase/logger": "npm:0.4.2" "@firebase/util": "npm:1.9.7" tslib: "npm:^2.1.0" - checksum: 10c0/cbd391576ffc6dce0102ac4373feee044e877897fefca44fd8dbbeb746710ef8cdcfdb3069fa668765a7e85c1240907e9ab4694af62004ae5ca09a67f714e4a8 + checksum: 10c0/2890eb447962c30fd4cf550d33dc5df17a50069e459c52f931dd97380e3ccb105f51aea8713f126f5a0396648dda8b0d3cecd491e7bd895092a949c762ab0d17 languageName: node linkType: hard @@ -3294,24 +3294,24 @@ __metadata: languageName: node linkType: hard -"@firebase/app@npm:0.10.8": - version: 0.10.8 - resolution: "@firebase/app@npm:0.10.8" +"@firebase/app@npm:0.10.9": + version: 0.10.9 + resolution: "@firebase/app@npm:0.10.9" dependencies: "@firebase/component": "npm:0.6.8" "@firebase/logger": "npm:0.4.2" "@firebase/util": "npm:1.9.7" idb: "npm:7.1.1" tslib: "npm:^2.1.0" - checksum: 10c0/55dddd7b06746d06ef4d83ea09597bbfdabc42532ae5189615793d9944f77eeb140e7d348ba1195ea7c3f0dc7eb1572baaed6a70baff1580c49b699beb3f06b3 + checksum: 10c0/2ddef3f5b70dca7e0fc014e8d5bddfef74a4adcb141aaf001d7e98d0209530dcf87dbb2d98c9168aa21329596140e59c09686e9717ce59823da49d765bc04a53 languageName: node linkType: hard -"@firebase/auth-compat@npm:0.5.11": - version: 0.5.11 - resolution: "@firebase/auth-compat@npm:0.5.11" +"@firebase/auth-compat@npm:0.5.12": + version: 0.5.12 + resolution: "@firebase/auth-compat@npm:0.5.12" dependencies: - "@firebase/auth": "npm:1.7.6" + "@firebase/auth": "npm:1.7.7" "@firebase/auth-types": "npm:0.12.2" "@firebase/component": "npm:0.6.8" "@firebase/util": "npm:1.9.7" @@ -3319,7 +3319,7 @@ __metadata: undici: "npm:5.28.4" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/34b990c387de1d4b06a10f102833b7295b7a785fecfb4662ce9ab3bee0c2f589550a7309958f23a6a043ddfe761db5ad592da8e20bfe04b9888f57c3801364f7 + checksum: 10c0/08f25b7412d9ebde1444b0ed2751f4888d427ceadac91d4e46672556b1313791a3b891f6ebeceb20c437829eafd6f6a02510a9022d7760e1c5b67b6457c65728 languageName: node linkType: hard @@ -3340,9 +3340,9 @@ __metadata: languageName: node linkType: hard -"@firebase/auth@npm:1.7.6": - version: 1.7.6 - resolution: "@firebase/auth@npm:1.7.6" +"@firebase/auth@npm:1.7.7": + version: 1.7.7 + resolution: "@firebase/auth@npm:1.7.7" dependencies: "@firebase/component": "npm:0.6.8" "@firebase/logger": "npm:0.4.2" @@ -3355,7 +3355,7 @@ __metadata: peerDependenciesMeta: "@react-native-async-storage/async-storage": optional: true - checksum: 10c0/0f8f0ceaefae72a9a78c94756213bde10d68d91ef6cbda62d6a6657b358e80ec76f42f6e7738ed7a66606b37c5d73bad45b7413224e4db1938d0715b644454f2 + checksum: 10c0/0095393e8626b8b840435648c27bf042fb64b0bb8e5d3f6d6f188efc11917a659778c346115b132575dd6f3c3c8912aa07fabc1a241cf74533ea6eb0d9ce7e8c languageName: node linkType: hard @@ -3408,18 +3408,18 @@ __metadata: languageName: node linkType: hard -"@firebase/firestore-compat@npm:0.3.34": - version: 0.3.34 - resolution: "@firebase/firestore-compat@npm:0.3.34" +"@firebase/firestore-compat@npm:0.3.35": + version: 0.3.35 + resolution: "@firebase/firestore-compat@npm:0.3.35" dependencies: "@firebase/component": "npm:0.6.8" - "@firebase/firestore": "npm:4.6.5" + "@firebase/firestore": "npm:4.7.0" "@firebase/firestore-types": "npm:3.0.2" "@firebase/util": "npm:1.9.7" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/95ccc568f11a9d0bd5284f660ab44a5aef1972d0b1be7c8ea01c6ff80120e2df554bf95b50a097c6613aeb23452925a04ba54647940c1f5b4d20bd5be26e5991 + checksum: 10c0/3806a079a3675f76ab8c3fd1eef8c4fe4efec603f5ac05a99147219143211cfcb789cab2136bcd54c5676da59f1d5401116e432bbd2b1800b2e2e87c4edd3c11 languageName: node linkType: hard @@ -3433,9 +3433,9 @@ __metadata: languageName: node linkType: hard -"@firebase/firestore@npm:4.6.5": - version: 4.6.5 - resolution: "@firebase/firestore@npm:4.6.5" +"@firebase/firestore@npm:4.7.0": + version: 4.7.0 + resolution: "@firebase/firestore@npm:4.7.0" dependencies: "@firebase/component": "npm:0.6.8" "@firebase/logger": "npm:0.4.2" @@ -3447,7 +3447,7 @@ __metadata: undici: "npm:5.28.4" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/eac1d2ab4e3b2a6a9348d7392a4da266354790625841cb23924a3dac8cb930e7b62f393e7d5dd05f2076c2e8cc9e5a1d77fffce86cf88d9c0d27857041a2afa6 + checksum: 10c0/874ecc9e3b2c62e2a89ff8e427637e316ce451ef19127d13d29b5d2a1ef5ebccafe991787f741a1a83a912616226b9086d8ecc6aa4bde7cf2dd43d38c103b8db languageName: node linkType: hard @@ -3650,18 +3650,18 @@ __metadata: languageName: node linkType: hard -"@firebase/storage-compat@npm:0.3.9": - version: 0.3.9 - resolution: "@firebase/storage-compat@npm:0.3.9" +"@firebase/storage-compat@npm:0.3.10": + version: 0.3.10 + resolution: "@firebase/storage-compat@npm:0.3.10" dependencies: "@firebase/component": "npm:0.6.8" - "@firebase/storage": "npm:0.12.6" + "@firebase/storage": "npm:0.13.0" "@firebase/storage-types": "npm:0.8.2" "@firebase/util": "npm:1.9.7" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/65a8ca66050cea4bd78d89753f6d3917c0bff01435c99c3ddbf0297087c081cb1260c019e947ed195062d2abf3c65205a20f374c257ef3495766bd6f7b488643 + checksum: 10c0/ebf5afdff27bc79a039bc8a5fa8de012a7af8de2e32f411e8056069112260371e974e9f8bcf9ba2ed352996200ce0fd7612d9e51800eaed3b9f969a48f7a37fb languageName: node linkType: hard @@ -3675,9 +3675,9 @@ __metadata: languageName: node linkType: hard -"@firebase/storage@npm:0.12.6": - version: 0.12.6 - resolution: "@firebase/storage@npm:0.12.6" +"@firebase/storage@npm:0.13.0": + version: 0.13.0 + resolution: "@firebase/storage@npm:0.13.0" dependencies: "@firebase/component": "npm:0.6.8" "@firebase/util": "npm:1.9.7" @@ -3685,7 +3685,7 @@ __metadata: undici: "npm:5.28.4" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/d46553887873f6e28dbb8c92ed13a37f3c0748d53437d3ba7c939a8d18bbdea80655fa680ae16d1a2955c1e048c31642e3e952fac2d90415514c06b1307490d2 + checksum: 10c0/56b554cc33b5689cb213bc1b5318b5dec8f536b94f2fb355b7c9f54b8ccf2df35bb353c3a69b737230b6c8362aa501b5808302b6e8e9cd93ad74ff8bd4aa8ae2 languageName: node linkType: hard @@ -7537,13 +7537,13 @@ __metadata: "@redwoodjs/auth": "workspace:*" "@types/react": "npm:^18.2.55" core-js: "npm:3.38.0" - firebase: "npm:10.12.5" + firebase: "npm:10.13.0" jest: "npm:29.7.0" jest-environment-jsdom: "npm:29.7.0" react: "npm:19.0.0-rc-8269d55d-20240802" typescript: "npm:5.5.4" peerDependencies: - firebase: 10.12.5 + firebase: 10.13.0 languageName: unknown linkType: soft @@ -17472,23 +17472,23 @@ __metadata: languageName: node linkType: hard -"firebase@npm:10.12.5": - version: 10.12.5 - resolution: "firebase@npm:10.12.5" +"firebase@npm:10.13.0": + version: 10.13.0 + resolution: "firebase@npm:10.13.0" dependencies: "@firebase/analytics": "npm:0.10.7" "@firebase/analytics-compat": "npm:0.2.13" - "@firebase/app": "npm:0.10.8" + "@firebase/app": "npm:0.10.9" "@firebase/app-check": "npm:0.8.7" "@firebase/app-check-compat": "npm:0.3.14" - "@firebase/app-compat": "npm:0.2.38" + "@firebase/app-compat": "npm:0.2.39" "@firebase/app-types": "npm:0.9.2" - "@firebase/auth": "npm:1.7.6" - "@firebase/auth-compat": "npm:0.5.11" + "@firebase/auth": "npm:1.7.7" + "@firebase/auth-compat": "npm:0.5.12" "@firebase/database": "npm:1.0.7" "@firebase/database-compat": "npm:1.0.7" - "@firebase/firestore": "npm:4.6.5" - "@firebase/firestore-compat": "npm:0.3.34" + "@firebase/firestore": "npm:4.7.0" + "@firebase/firestore-compat": "npm:0.3.35" "@firebase/functions": "npm:0.11.6" "@firebase/functions-compat": "npm:0.3.12" "@firebase/installations": "npm:0.6.8" @@ -17499,11 +17499,11 @@ __metadata: "@firebase/performance-compat": "npm:0.2.8" "@firebase/remote-config": "npm:0.4.8" "@firebase/remote-config-compat": "npm:0.2.8" - "@firebase/storage": "npm:0.12.6" - "@firebase/storage-compat": "npm:0.3.9" + "@firebase/storage": "npm:0.13.0" + "@firebase/storage-compat": "npm:0.3.10" "@firebase/util": "npm:1.9.7" "@firebase/vertexai-preview": "npm:0.0.3" - checksum: 10c0/eb2e978f1cbdac305c652c8fc26c9d662a1b032c5627bd2414b388b9dfad85fe56fe00cebb50b4d3d9701a6235ed343d85eb8f4556e332281435211b1f93ac06 + checksum: 10c0/d2c9272e8fc1c202976191c3746a96b7479c682334cd28b3591dcd8da83b8b955679c68d3a417a880d55727c5551599c243fd31d7ea1d84dd7c7e3be1c45922d languageName: node linkType: hard From bd2647431753bbe696b3de83189056481b242378 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:57:46 +0000 Subject: [PATCH 13/52] fix(deps): update dependency isbot to v5.1.16 (#11271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [isbot](https://isbot.js.org) ([source](https://togithub.com/omrilotan/isbot)) | [`5.1.14` -> `5.1.16`](https://renovatebot.com/diffs/npm/isbot/5.1.14/5.1.16) | [![age](https://developer.mend.io/api/mc/badges/age/npm/isbot/5.1.16?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/isbot/5.1.16?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/isbot/5.1.14/5.1.16?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/isbot/5.1.14/5.1.16?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
omrilotan/isbot (isbot) ### [`v5.1.16`](https://togithub.com/omrilotan/isbot/blob/HEAD/CHANGELOG.md#5116) [Compare Source](https://togithub.com/omrilotan/isbot/compare/v5.1.15...v5.1.16) - \[Pattern] Treat CCleaner broswer as an actual browser, not a bot ### [`v5.1.15`](https://togithub.com/omrilotan/isbot/blob/HEAD/CHANGELOG.md#5115) [Compare Source](https://togithub.com/omrilotan/isbot/compare/v5.1.14...v5.1.15) - \[Pattern] Pattern updates for better recognition
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/vite/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vite/package.json b/packages/vite/package.json index 84586507aa25..817882751f41 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -86,7 +86,7 @@ "find-my-way": "8.2.0", "fs-extra": "11.2.0", "http-proxy-middleware": "3.0.0", - "isbot": "5.1.14", + "isbot": "5.1.16", "react": "19.0.0-rc-8269d55d-20240802", "react-server-dom-webpack": "19.0.0-rc-8269d55d-20240802", "rimraf": "6.0.1", diff --git a/yarn.lock b/yarn.lock index c1c7dab5e6d2..35bfb393424f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8638,7 +8638,7 @@ __metadata: fs-extra: "npm:11.2.0" glob: "npm:11.0.0" http-proxy-middleware: "npm:3.0.0" - isbot: "npm:5.1.14" + isbot: "npm:5.1.16" publint: "npm:0.2.10" react: "npm:19.0.0-rc-8269d55d-20240802" react-server-dom-webpack: "npm:19.0.0-rc-8269d55d-20240802" @@ -19910,10 +19910,10 @@ __metadata: languageName: node linkType: hard -"isbot@npm:5.1.14": - version: 5.1.14 - resolution: "isbot@npm:5.1.14" - checksum: 10c0/a5ab10944aa1edff87f00c4af7162182751fe1cd200cb166fca73095fa5af9e19ef46dcfc27d9059cead28e13eb440098cda2b852e091594b4ea26172b2947fa +"isbot@npm:5.1.16": + version: 5.1.16 + resolution: "isbot@npm:5.1.16" + checksum: 10c0/363d8ebcc65393e3b23794cfae80763d2ee10f4300d35861d301286892765dc7b134cc050471646905c255d4de3e2133654f21fdb2cb84a1b11c281c84f41334 languageName: node linkType: hard From 1748a969b9e9821f8be73ef51ab74321b42bb04d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:00:11 +0100 Subject: [PATCH 14/52] fix(deps): update dependency @whatwg-node/server to v0.9.47 (#11270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@whatwg-node/server](https://togithub.com/ardatan/whatwg-node) ([source](https://togithub.com/ardatan/whatwg-node/tree/HEAD/packages/server)) | [`0.9.46` -> `0.9.47`](https://renovatebot.com/diffs/npm/@whatwg-node%2fserver/0.9.46/0.9.47) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@whatwg-node%2fserver/0.9.47?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@whatwg-node%2fserver/0.9.47?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@whatwg-node%2fserver/0.9.46/0.9.47?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@whatwg-node%2fserver/0.9.46/0.9.47?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
ardatan/whatwg-node (@​whatwg-node/server) ### [`v0.9.47`](https://togithub.com/ardatan/whatwg-node/blob/HEAD/packages/server/CHANGELOG.md#0947) [Compare Source](https://togithub.com/ardatan/whatwg-node/compare/@whatwg-node/server@0.9.46...@whatwg-node/server@0.9.47) ##### Patch Changes - [#​1566](https://togithub.com/ardatan/whatwg-node/pull/1566) [`de1e95a`](https://togithub.com/ardatan/whatwg-node/commit/de1e95a8eb107083e638aa8472089b96b33bbe4a) Thanks [@​ardatan](https://togithub.com/ardatan)! - Avoid constructing DecompressionStream to check supported encodings - Updated dependencies \[[`de1e95a`](https://togithub.com/ardatan/whatwg-node/commit/de1e95a8eb107083e638aa8472089b96b33bbe4a)]: - [@​whatwg-node/fetch](https://togithub.com/whatwg-node/fetch)[@​0](https://togithub.com/0).9.20
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/vite/package.json | 2 +- yarn.lock | 33 +++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/vite/package.json b/packages/vite/package.json index 817882751f41..90f3e6f165e8 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -73,7 +73,7 @@ "@swc/core": "1.7.10", "@vitejs/plugin-react": "4.3.1", "@whatwg-node/fetch": "0.9.19", - "@whatwg-node/server": "0.9.46", + "@whatwg-node/server": "0.9.47", "acorn-loose": "8.4.0", "buffer": "6.0.3", "busboy": "^1.6.0", diff --git a/yarn.lock b/yarn.lock index 35bfb393424f..15383db4ace1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8623,7 +8623,7 @@ __metadata: "@types/yargs-parser": "npm:21.0.3" "@vitejs/plugin-react": "npm:4.3.1" "@whatwg-node/fetch": "npm:0.9.19" - "@whatwg-node/server": "npm:0.9.46" + "@whatwg-node/server": "npm:0.9.47" acorn-loose: "npm:8.4.0" buffer: "npm:6.0.3" busboy: "npm:^1.6.0" @@ -11482,7 +11482,7 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/fetch@npm:0.9.19, @whatwg-node/fetch@npm:^0.9.18, @whatwg-node/fetch@npm:^0.9.19": +"@whatwg-node/fetch@npm:0.9.19": version: 0.9.19 resolution: "@whatwg-node/fetch@npm:0.9.19" dependencies: @@ -11505,6 +11505,16 @@ __metadata: languageName: node linkType: hard +"@whatwg-node/fetch@npm:^0.9.18, @whatwg-node/fetch@npm:^0.9.20": + version: 0.9.20 + resolution: "@whatwg-node/fetch@npm:0.9.20" + dependencies: + "@whatwg-node/node-fetch": "npm:^0.5.22" + urlpattern-polyfill: "npm:^10.0.0" + checksum: 10c0/b40521697543135783a22d8b3b96af17fb00f803e4cf55c60ea1e2bcf0c5d24906922db1c2c9c0f84be530d4f097560d67f58745c1f263c3c46ad7120aea67f5 + languageName: node + linkType: hard + "@whatwg-node/node-fetch@npm:^0.3.6": version: 0.3.6 resolution: "@whatwg-node/node-fetch@npm:0.3.6" @@ -11518,26 +11528,25 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/node-fetch@npm:^0.5.16": - version: 0.5.17 - resolution: "@whatwg-node/node-fetch@npm:0.5.17" +"@whatwg-node/node-fetch@npm:^0.5.16, @whatwg-node/node-fetch@npm:^0.5.22": + version: 0.5.22 + resolution: "@whatwg-node/node-fetch@npm:0.5.22" dependencies: "@kamilkisiela/fast-url-parser": "npm:^1.1.4" - "@whatwg-node/events": "npm:^0.1.0" busboy: "npm:^1.6.0" fast-querystring: "npm:^1.1.1" tslib: "npm:^2.6.3" - checksum: 10c0/43ce26409fc210e2cc8c99cf080e7cf95878642fefdaf4ce9368ec901ea8185c6bec30549087a8fc72b4d9d89299961666be13e795c0ec22659663ee912317d0 + checksum: 10c0/690365ebbfff726fc2f06ebe5410b5113d1f1a8360a5d6b34f1213f48e8eb3a5d39564e956e2cf787a71f2f9e7f30b40fb6ad3fc2ceae175e1de458e6b3eafc4 languageName: node linkType: hard -"@whatwg-node/server@npm:0.9.46, @whatwg-node/server@npm:^0.9.41": - version: 0.9.46 - resolution: "@whatwg-node/server@npm:0.9.46" +"@whatwg-node/server@npm:0.9.47, @whatwg-node/server@npm:^0.9.41": + version: 0.9.47 + resolution: "@whatwg-node/server@npm:0.9.47" dependencies: - "@whatwg-node/fetch": "npm:^0.9.19" + "@whatwg-node/fetch": "npm:^0.9.20" tslib: "npm:^2.6.3" - checksum: 10c0/af4eea053e4e0ba7283f9ef93cf17811633660bc04ed7bcd6f3ef63a375f03d7936f84bf3b657a46cd500f5fee4df4a3ed598d32ce66ffbcee86187f2eec6aab + checksum: 10c0/1ce717d5b3781f8b07cb12367bd334b7d6cdb0e446836d626d5c333e4fd55bceda081cb0fc7936fa3da4b35b5292d8cda66a172daa71b099345f2c285820222b languageName: node linkType: hard From 8dc98c764a312f1a10e5de385826d1c12e4882e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:00:31 +0100 Subject: [PATCH 15/52] fix(deps): update dependency vite to v5.4.1 (#11276) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [vite](https://vitejs.dev) ([source](https://togithub.com/vitejs/vite/tree/HEAD/packages/vite)) | [`5.4.0` -> `5.4.1`](https://renovatebot.com/diffs/npm/vite/5.4.0/5.4.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/vite/5.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vite/5.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vite/5.4.0/5.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vite/5.4.0/5.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
vitejs/vite (vite) ### [`v5.4.1`](https://togithub.com/vitejs/vite/blob/HEAD/packages/vite/CHANGELOG.md#small541-2024-08-15-small) - fix: `build.modulePreload.resolveDependencies` is optimizable ([#​16083](https://togithub.com/vitejs/vite/issues/16083)) ([e961b31](https://togithub.com/vitejs/vite/commit/e961b31493f8493277b46773156cc6e546b9c86b)), closes [#​16083](https://togithub.com/vitejs/vite/issues/16083) - fix: align CorsOptions.origin type with [@​types/cors](https://togithub.com/types/cors) ([#​17836](https://togithub.com/vitejs/vite/issues/17836)) ([1bda847](https://togithub.com/vitejs/vite/commit/1bda847329022d5279cfa2b51719dd19a161fd64)), closes [#​17836](https://togithub.com/vitejs/vite/issues/17836) - fix: typings for vite:preloadError ([#​17868](https://togithub.com/vitejs/vite/issues/17868)) ([6700594](https://togithub.com/vitejs/vite/commit/67005949999054ab3cd079890ed220bc359bcf62)), closes [#​17868](https://togithub.com/vitejs/vite/issues/17868) - fix(build): avoid re-define `__vite_import_meta_env__` ([#​17876](https://togithub.com/vitejs/vite/issues/17876)) ([e686d74](https://togithub.com/vitejs/vite/commit/e686d749d673c02ff4395971ac74340082da14e5)), closes [#​17876](https://togithub.com/vitejs/vite/issues/17876) - fix(deps): update all non-major dependencies ([#​17869](https://togithub.com/vitejs/vite/issues/17869)) ([d11711c](https://togithub.com/vitejs/vite/commit/d11711c7e4c082fd0400245bfdc766006fd38ac8)), closes [#​17869](https://togithub.com/vitejs/vite/issues/17869) - fix(lightningcss): search for assets with correct base path ([#​17856](https://togithub.com/vitejs/vite/issues/17856)) ([4e5ce3c](https://togithub.com/vitejs/vite/commit/4e5ce3c7a90966b1f942df35b8b3e8a550a4f031)), closes [#​17856](https://togithub.com/vitejs/vite/issues/17856) - fix(worker): handle self reference url worker in dependency for build ([#​17846](https://togithub.com/vitejs/vite/issues/17846)) ([391bb49](https://togithub.com/vitejs/vite/commit/391bb4917b55baf3fdb01c6fc3d782d6c51be6c8)), closes [#​17846](https://togithub.com/vitejs/vite/issues/17846) - chore: fix picocolors import for local dev ([#​17884](https://togithub.com/vitejs/vite/issues/17884)) ([9018255](https://togithub.com/vitejs/vite/commit/9018255c697a8c0888dce57aaa755d25bf66beba)), closes [#​17884](https://togithub.com/vitejs/vite/issues/17884) - refactor: remove `handleHotUpdate` from watch-package-data plugin ([#​17865](https://togithub.com/vitejs/vite/issues/17865)) ([e16bf1f](https://togithub.com/vitejs/vite/commit/e16bf1fb14b7a3a950de4d74fce31416746829b3)), closes [#​17865](https://togithub.com/vitejs/vite/issues/17865)
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/ogimage-gen/package.json | 2 +- packages/storybook/package.json | 2 +- packages/vite/package.json | 2 +- yarn.lock | 18 +++++++++--------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/ogimage-gen/package.json b/packages/ogimage-gen/package.json index b63913bf5bae..fe6b7cfb3dcf 100644 --- a/packages/ogimage-gen/package.json +++ b/packages/ogimage-gen/package.json @@ -53,7 +53,7 @@ "ts-toolbelt": "9.6.0", "tsx": "4.17.0", "typescript": "5.5.4", - "vite": "5.4.0", + "vite": "5.4.1", "vitest": "2.0.5" }, "gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1" diff --git a/packages/storybook/package.json b/packages/storybook/package.json index f76eb3994e67..ffcf32b2dcc9 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -62,7 +62,7 @@ "@types/node": "20.14.15", "tsx": "4.17.0", "typescript": "5.5.4", - "vite": "5.4.0" + "vite": "5.4.1" }, "peerDependencies": { "@redwoodjs/project-config": "workspace:*", diff --git a/packages/vite/package.json b/packages/vite/package.json index 90f3e6f165e8..4310d81ffa90 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -90,7 +90,7 @@ "react": "19.0.0-rc-8269d55d-20240802", "react-server-dom-webpack": "19.0.0-rc-8269d55d-20240802", "rimraf": "6.0.1", - "vite": "5.4.0", + "vite": "5.4.1", "vite-plugin-cjs-interop": "2.1.2", "vite-plugin-node-polyfills": "0.22.0", "ws": "8.18.0", diff --git a/yarn.lock b/yarn.lock index 15383db4ace1..65b73412fa3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8344,7 +8344,7 @@ __metadata: ts-toolbelt: "npm:9.6.0" tsx: "npm:4.17.0" typescript: "npm:5.5.4" - vite: "npm:5.4.0" + vite: "npm:5.4.1" vitest: "npm:2.0.5" languageName: unknown linkType: soft @@ -8646,7 +8646,7 @@ __metadata: rollup: "npm:4.20.0" tsx: "npm:4.17.0" typescript: "npm:5.5.4" - vite: "npm:5.4.0" + vite: "npm:5.4.1" vite-plugin-cjs-interop: "npm:2.1.2" vite-plugin-node-polyfills: "npm:0.22.0" vitest: "npm:2.0.5" @@ -24917,7 +24917,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.2.14, postcss@npm:^8.4.40": +"postcss@npm:^8.2.14, postcss@npm:^8.4.41": version: 8.4.41 resolution: "postcss@npm:8.4.41" dependencies: @@ -27623,7 +27623,7 @@ __metadata: tsx: "npm:4.17.0" typescript: "npm:5.5.4" unplugin-auto-import: "npm:0.18.2" - vite: "npm:5.4.0" + vite: "npm:5.4.1" peerDependencies: "@redwoodjs/project-config": "workspace:*" "@redwoodjs/router": "workspace:*" @@ -29664,13 +29664,13 @@ __metadata: languageName: node linkType: hard -"vite@npm:5.4.0, vite@npm:^5.0.0": - version: 5.4.0 - resolution: "vite@npm:5.4.0" +"vite@npm:5.4.1, vite@npm:^5.0.0": + version: 5.4.1 + resolution: "vite@npm:5.4.1" dependencies: esbuild: "npm:^0.21.3" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.40" + postcss: "npm:^8.4.41" rollup: "npm:^4.13.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 @@ -29703,7 +29703,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/122de7795e1c3c08cd0acc7d77296f908398266b424492be7310400107f37a3cf4c9506f2b4b16619e57299ca2859b8ca187aac5e25f8e66d84f9204a1d72d18 + checksum: 10c0/b9ea824f1a946aa494f756e6d9dd88869baa62ae5ba3071b32b6a20958fd622cb624c860bdd7daee201c83ca029feaf8bbe2d2a6e172a5d49308772f8899d86d languageName: node linkType: hard From 3bb9d47dab6c702f9b425b156fde36184ac4566f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:12:27 +0000 Subject: [PATCH 16/52] fix(deps): update dependency @swc/core to v1.7.11 (#11268) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@swc/core](https://swc.rs) ([source](https://togithub.com/swc-project/swc)) | [`1.7.10` -> `1.7.11`](https://renovatebot.com/diffs/npm/@swc%2fcore/1.7.10/1.7.11) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@swc%2fcore/1.7.11?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@swc%2fcore/1.7.11?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@swc%2fcore/1.7.10/1.7.11?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@swc%2fcore/1.7.10/1.7.11?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
swc-project/swc (@​swc/core) ### [`v1.7.11`](https://togithub.com/swc-project/swc/blob/HEAD/CHANGELOG.md#1711---2024-08-14) [Compare Source](https://togithub.com/swc-project/swc/compare/v1.7.10...v1.7.11) ##### Bug Fixes - **(es)** Improve sourcemap url error messages. ([#​9422](https://togithub.com/swc-project/swc/issues/9422)) ([230d1d9](https://togithub.com/swc-project/swc/commit/230d1d98b91bde2fa0de54e5fe06e899302e481c)) - **(visit)** Fix regression of AST paths ([#​9420](https://togithub.com/swc-project/swc/issues/9420)) ([9751518](https://togithub.com/swc-project/swc/commit/9751518a0aa1cbe07e2ad4db7a32b0c6cc342641)) ##### Features - **(es/typescript)** Add ` native_class_properties ` to skip reordering of class properties inits ([#​9421](https://togithub.com/swc-project/swc/issues/9421)) ([d2929d1](https://togithub.com/swc-project/swc/commit/d2929d1ce61a00360cc0596441041571a958da23)) - **(estree/compat)** Remove dependency on `rayon` ([#​9393](https://togithub.com/swc-project/swc/issues/9393)) ([34d1b27](https://togithub.com/swc-project/swc/commit/34d1b27251dab3f87dc3a39d245a3498b4c2b151)) - **(html/minifier)** Support using custom css minifier ([#​9425](https://togithub.com/swc-project/swc/issues/9425)) ([970cc81](https://togithub.com/swc-project/swc/commit/970cc81033b4a616643be6625bdf8da99614ba98)) ##### Miscellaneous Tasks - **(bindings/node)** Deprecate `parse` ([#​9419](https://togithub.com/swc-project/swc/issues/9419)) ([1bf467d](https://togithub.com/swc-project/swc/commit/1bf467d99fb72ebff42136e08d7f03d50872f64e)) - **(deps)** Update cargo (patch) ([#​9405](https://togithub.com/swc-project/swc/issues/9405)) ([baf4928](https://togithub.com/swc-project/swc/commit/baf4928ce2964e659af5ca77cd899427a8c29f60)) - **(es/preset-env)** Update core js compat data ([#​9407](https://togithub.com/swc-project/swc/issues/9407)) ([ce761cf](https://togithub.com/swc-project/swc/commit/ce761cf51571f70c9378b6b67759bac3af4f4f92)) - **(es/typescript)** Remove the workaround for wasm-bindgen ([#​9428](https://togithub.com/swc-project/swc/issues/9428)) ([55f7268](https://togithub.com/swc-project/swc/commit/55f72687f69eae131c6ce08d6a449afaa7357667))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/vite/package.json | 2 +- yarn.lock | 90 +++++++++++++++++++------------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/packages/vite/package.json b/packages/vite/package.json index 4310d81ffa90..66da130018c7 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -70,7 +70,7 @@ "@redwoodjs/project-config": "workspace:*", "@redwoodjs/server-store": "workspace:*", "@redwoodjs/web": "workspace:*", - "@swc/core": "1.7.10", + "@swc/core": "1.7.11", "@vitejs/plugin-react": "4.3.1", "@whatwg-node/fetch": "0.9.19", "@whatwg-node/server": "0.9.47", diff --git a/yarn.lock b/yarn.lock index 65b73412fa3a..ff7e709f6c50 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8613,7 +8613,7 @@ __metadata: "@redwoodjs/project-config": "workspace:*" "@redwoodjs/server-store": "workspace:*" "@redwoodjs/web": "workspace:*" - "@swc/core": "npm:1.7.10" + "@swc/core": "npm:1.7.11" "@types/busboy": "npm:^1" "@types/cookie": "npm:^0" "@types/express": "npm:4" @@ -9976,90 +9976,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-darwin-arm64@npm:1.7.10" +"@swc/core-darwin-arm64@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-darwin-arm64@npm:1.7.11" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-darwin-x64@npm:1.7.10" +"@swc/core-darwin-x64@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-darwin-x64@npm:1.7.11" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.10" +"@swc/core-linux-arm-gnueabihf@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.11" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-linux-arm64-gnu@npm:1.7.10" +"@swc/core-linux-arm64-gnu@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.11" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-linux-arm64-musl@npm:1.7.10" +"@swc/core-linux-arm64-musl@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.11" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-linux-x64-gnu@npm:1.7.10" +"@swc/core-linux-x64-gnu@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.11" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-linux-x64-musl@npm:1.7.10" +"@swc/core-linux-x64-musl@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-linux-x64-musl@npm:1.7.11" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-win32-arm64-msvc@npm:1.7.10" +"@swc/core-win32-arm64-msvc@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.11" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-win32-ia32-msvc@npm:1.7.10" +"@swc/core-win32-ia32-msvc@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.11" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core-win32-x64-msvc@npm:1.7.10" +"@swc/core-win32-x64-msvc@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.11" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@swc/core@npm:1.7.10": - version: 1.7.10 - resolution: "@swc/core@npm:1.7.10" +"@swc/core@npm:1.7.11": + version: 1.7.11 + resolution: "@swc/core@npm:1.7.11" dependencies: - "@swc/core-darwin-arm64": "npm:1.7.10" - "@swc/core-darwin-x64": "npm:1.7.10" - "@swc/core-linux-arm-gnueabihf": "npm:1.7.10" - "@swc/core-linux-arm64-gnu": "npm:1.7.10" - "@swc/core-linux-arm64-musl": "npm:1.7.10" - "@swc/core-linux-x64-gnu": "npm:1.7.10" - "@swc/core-linux-x64-musl": "npm:1.7.10" - "@swc/core-win32-arm64-msvc": "npm:1.7.10" - "@swc/core-win32-ia32-msvc": "npm:1.7.10" - "@swc/core-win32-x64-msvc": "npm:1.7.10" + "@swc/core-darwin-arm64": "npm:1.7.11" + "@swc/core-darwin-x64": "npm:1.7.11" + "@swc/core-linux-arm-gnueabihf": "npm:1.7.11" + "@swc/core-linux-arm64-gnu": "npm:1.7.11" + "@swc/core-linux-arm64-musl": "npm:1.7.11" + "@swc/core-linux-x64-gnu": "npm:1.7.11" + "@swc/core-linux-x64-musl": "npm:1.7.11" + "@swc/core-win32-arm64-msvc": "npm:1.7.11" + "@swc/core-win32-ia32-msvc": "npm:1.7.11" + "@swc/core-win32-x64-msvc": "npm:1.7.11" "@swc/counter": "npm:^0.1.3" "@swc/types": "npm:^0.1.12" peerDependencies: @@ -10088,7 +10088,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 10c0/c05ff9cf9d8a8a0961a7188d03bfcf6776b3f7e72798f72110a06d185ffe13b3a46138ddf0ff135dc07030aecfd689dd15d14e796b302cfaabd0ab8978831054 + checksum: 10c0/32d43694c4cb4baacab1d846a02e1ae9aa01b6291bde4bda90144b2bb5bed666d47dae2caca7e83a9953f15919093509e68973fb2f9f7c99334a6170a97a21ad languageName: node linkType: hard From bb0b311cff5298002fcbbc5835cf85a99c32a73d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:13:29 +0000 Subject: [PATCH 17/52] fix(deps): update babel monorepo (#11275) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@babel/plugin-transform-react-jsx](https://babel.dev/docs/en/next/babel-plugin-transform-react-jsx) ([source](https://togithub.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-react-jsx)) | [`7.24.7` -> `7.25.2`](https://renovatebot.com/diffs/npm/@babel%2fplugin-transform-react-jsx/7.24.7/7.25.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@babel%2fplugin-transform-react-jsx/7.25.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@babel%2fplugin-transform-react-jsx/7.25.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@babel%2fplugin-transform-react-jsx/7.24.7/7.25.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@babel%2fplugin-transform-react-jsx/7.24.7/7.25.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@babel/plugin-transform-typescript](https://babel.dev/docs/en/next/babel-plugin-transform-typescript) ([source](https://togithub.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-typescript)) | [`7.24.7` -> `7.25.2`](https://renovatebot.com/diffs/npm/@babel%2fplugin-transform-typescript/7.24.7/7.25.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@babel%2fplugin-transform-typescript/7.25.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@babel%2fplugin-transform-typescript/7.25.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@babel%2fplugin-transform-typescript/7.24.7/7.25.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@babel%2fplugin-transform-typescript/7.24.7/7.25.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | | [@babel/preset-env](https://babel.dev/docs/en/next/babel-preset-env) ([source](https://togithub.com/babel/babel/tree/HEAD/packages/babel-preset-env)) | [`7.24.7` -> `7.25.3`](https://renovatebot.com/diffs/npm/@babel%2fpreset-env/7.24.7/7.25.3) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@babel%2fpreset-env/7.25.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@babel%2fpreset-env/7.25.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@babel%2fpreset-env/7.24.7/7.25.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@babel%2fpreset-env/7.24.7/7.25.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
babel/babel (@​babel/plugin-transform-react-jsx) ### [`v7.25.2`](https://togithub.com/babel/babel/blob/HEAD/CHANGELOG.md#v7252-2024-07-30) [Compare Source](https://togithub.com/babel/babel/compare/v7.24.7...v7.25.2) ##### :bug: Bug Fix - `babel-core`, `babel-traverse` - [#​16695](https://togithub.com/babel/babel/pull/16695) Ensure that `requeueComputedKeyAndDecorators` is available ([@​nicolo-ribaudo](https://togithub.com/nicolo-ribaudo))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://togithub.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 252 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 130 insertions(+), 122 deletions(-) diff --git a/yarn.lock b/yarn.lock index ff7e709f6c50..4515ea79265f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -430,7 +430,7 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.24.7, @babel/compat-data@npm:^7.25.2": +"@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.2": version: 7.25.2 resolution: "@babel/compat-data@npm:7.25.2" checksum: 10c0/5bf1f14d6e5f0d37c19543e99209ff4a94bb97915e1ce01e5334a144aa08cd56b6e62ece8135dac77e126723d63d4d4b96fc603a12c43b88c28f4b5e070270c5 @@ -530,7 +530,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.24.7": +"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.24.7, @babel/helper-create-class-features-plugin@npm:^7.25.0": version: 7.25.0 resolution: "@babel/helper-create-class-features-plugin@npm:7.25.0" dependencies: @@ -547,7 +547,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.24.7": +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.24.7, @babel/helper-create-regexp-features-plugin@npm:^7.25.0": version: 7.25.2 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.2" dependencies: @@ -575,24 +575,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-environment-visitor@npm:7.24.7" - dependencies: - "@babel/types": "npm:^7.24.7" - checksum: 10c0/36ece78882b5960e2d26abf13cf15ff5689bf7c325b10a2895a74a499e712de0d305f8d78bb382dd3c05cfba7e47ec98fe28aab5674243e0625cd38438dd0b2d - languageName: node - linkType: hard - -"@babel/helper-hoist-variables@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-hoist-variables@npm:7.24.7" - dependencies: - "@babel/types": "npm:^7.24.7" - checksum: 10c0/19ee37563bbd1219f9d98991ad0e9abef77803ee5945fd85aa7aa62a67c69efca9a801696a1b58dda27f211e878b3327789e6fd2a6f6c725ccefe36774b5ce95 - languageName: node - linkType: hard - "@babel/helper-member-expression-to-functions@npm:^7.24.8": version: 7.24.8 resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" @@ -613,7 +595,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.24.7, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.25.2": +"@babel/helper-module-transforms@npm:^7.24.7, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.25.0, @babel/helper-module-transforms@npm:^7.25.2": version: 7.25.2 resolution: "@babel/helper-module-transforms@npm:7.25.2" dependencies: @@ -643,7 +625,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.24.7": +"@babel/helper-remap-async-to-generator@npm:^7.24.7, @babel/helper-remap-async-to-generator@npm:^7.25.0": version: 7.25.0 resolution: "@babel/helper-remap-async-to-generator@npm:7.25.0" dependencies: @@ -772,26 +754,37 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.24.7" +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.3": + version: 7.25.3 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.3" dependencies: - "@babel/helper-environment-visitor": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/traverse": "npm:^7.25.3" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/394c30e2b708ad385fa1219528e039066a1f1cb40f47986f283878848fd354c745e6397f588b4e5a046ee8d64bfdf4c208e4c3dfbdcfb2fd34315ec67c64e7af + checksum: 10c0/814b4d3f102e7556a5053d1acf57ef601cfcff39a2c81b8cdc6a5c842e3cb9838f5925d1466a5f1e6416e74c9c83586a3c07fbd7fb8610a396c2becdf9ae5790 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.24.7" +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.0" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.24.8" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/a36307428ecc1a01b00cf90812335eed1575d13f211ab24fe4d0c55c28a2fcbd4135f142efabc3b277b2a8e09ee05df594a1272353f061b63829495b5dcfdb96 + checksum: 10c0/9645a1f47b3750acadb1353c02e71cc712d072aafe5ce115ed3a886bc14c5d9200cfb0b5b5e60e813baa549b800cf798f8714019fd246c699053cf68c428e426 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/ed1ce1c90cac46c01825339fd0f2a96fa071b016fb819d8dfaf8e96300eae30e74870cb47e4dc80d4ce2fb287869f102878b4f3b35bc927fec8b1d0d76bcf612 languageName: node linkType: hard @@ -808,15 +801,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.24.7" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/traverse": "npm:^7.25.0" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/2b52a73e444f6adc73f927b623e53a4cf64397170dd1071268536df1b3db1e02131418c8dc91351af48837a6298212118f4a72d5407f8005cf9a732370a315b0 + checksum: 10c0/45988025537a9d4a27b610fd696a18fd9ba9336621a69b4fb40560eeb10c79657f85c92a37f30c7c8fb29c22970eea0b373315795a891f1a05549a6cfe5a6bfe languageName: node linkType: hard @@ -1134,17 +1127,17 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.24.7" +"@babel/plugin-transform-async-generator-functions@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-remap-async-to-generator": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-remap-async-to-generator": "npm:^7.25.0" "@babel/plugin-syntax-async-generators": "npm:^7.8.4" + "@babel/traverse": "npm:^7.25.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/6b5e33ae66dce0afce9b06d8dace6fa052528e60f7622aa6cfd3e71bd372ca5079d426e78336ca564bc0d5f37acbcda1b21f4fe656fcb642f1a93a697ab39742 + checksum: 10c0/5348c3a33d16e0d62f13482c6fa432185ba096d58880b08d42450f7db662d6b03e6149d495c8620897dcd3da35061068cbd6c09da7d0ec95743e55a788809e4e languageName: node linkType: hard @@ -1172,7 +1165,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.0.0, @babel/plugin-transform-block-scoping@npm:^7.24.7": +"@babel/plugin-transform-block-scoping@npm:^7.0.0, @babel/plugin-transform-block-scoping@npm:^7.25.0": version: 7.25.0 resolution: "@babel/plugin-transform-block-scoping@npm:7.25.0" dependencies: @@ -1208,7 +1201,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.0.0, @babel/plugin-transform-classes@npm:^7.24.7": +"@babel/plugin-transform-classes@npm:^7.0.0, @babel/plugin-transform-classes@npm:^7.25.0": version: 7.25.0 resolution: "@babel/plugin-transform-classes@npm:7.25.0" dependencies: @@ -1236,7 +1229,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.0.0, @babel/plugin-transform-destructuring@npm:^7.24.7": +"@babel/plugin-transform-destructuring@npm:^7.0.0, @babel/plugin-transform-destructuring@npm:^7.24.8": version: 7.24.8 resolution: "@babel/plugin-transform-destructuring@npm:7.24.8" dependencies: @@ -1270,6 +1263,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.0" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/1c9b57ddd9b33696e88911d0e7975e1573ebc46219c4b30eb1dc746cbb71aedfac6f6dab7fdfdec54dd58f31468bf6ab56b157661ea4ffe58f906d71f89544c8 + languageName: node + linkType: hard + "@babel/plugin-transform-dynamic-import@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.7" @@ -1330,7 +1335,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.0.0, @babel/plugin-transform-function-name@npm:^7.24.7": +"@babel/plugin-transform-function-name@npm:^7.0.0, @babel/plugin-transform-function-name@npm:^7.25.1": version: 7.25.1 resolution: "@babel/plugin-transform-function-name@npm:7.25.1" dependencies: @@ -1355,7 +1360,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.0.0, @babel/plugin-transform-literals@npm:^7.24.7": +"@babel/plugin-transform-literals@npm:^7.0.0, @babel/plugin-transform-literals@npm:^7.25.2": version: 7.25.2 resolution: "@babel/plugin-transform-literals@npm:7.25.2" dependencies: @@ -1401,7 +1406,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.0.0, @babel/plugin-transform-modules-commonjs@npm:^7.23.0, @babel/plugin-transform-modules-commonjs@npm:^7.24.7": +"@babel/plugin-transform-modules-commonjs@npm:^7.0.0, @babel/plugin-transform-modules-commonjs@npm:^7.23.0, @babel/plugin-transform-modules-commonjs@npm:^7.24.7, @babel/plugin-transform-modules-commonjs@npm:^7.24.8": version: 7.24.8 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" dependencies: @@ -1414,17 +1419,17 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.24.7" +"@babel/plugin-transform-modules-systemjs@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.0" dependencies: - "@babel/helper-hoist-variables": "npm:^7.24.7" - "@babel/helper-module-transforms": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-module-transforms": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.24.8" "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/traverse": "npm:^7.25.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e2a795e0a6baafe26f4a74010622212ddd873170742d673f450e0097f8d984f6e6a95eb8ce41b05071ee9790c4be088b33801aaab3f78ee202c567634e52a331 + checksum: 10c0/fca6198da71237e4bb1274b3b67a0c81d56013c9535361242b6bfa87d70a9597854aadb45d4d8203369be4a655e158be2a5d20af0040b1f8d1bfc47db3ad7b68 languageName: node linkType: hard @@ -1525,7 +1530,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.23.0, @babel/plugin-transform-optional-chaining@npm:^7.24.7": +"@babel/plugin-transform-optional-chaining@npm:^7.23.0, @babel/plugin-transform-optional-chaining@npm:^7.24.7, @babel/plugin-transform-optional-chaining@npm:^7.24.8": version: 7.24.8 resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.8" dependencies: @@ -1631,17 +1636,17 @@ __metadata: linkType: hard "@babel/plugin-transform-react-jsx@npm:^7.0.0, @babel/plugin-transform-react-jsx@npm:^7.22.15, @babel/plugin-transform-react-jsx@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-jsx@npm:7.24.7" + version: 7.25.2 + resolution: "@babel/plugin-transform-react-jsx@npm:7.25.2" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.24.7" "@babel/helper-module-imports": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.24.8" "@babel/plugin-syntax-jsx": "npm:^7.24.7" - "@babel/types": "npm:^7.24.7" + "@babel/types": "npm:^7.25.2" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5c46d2c1c06a30e6bde084839df9cc689bf9c9cb0292105d61c225ca731f64247990724caee7dfc7f817dc964c062e8319e7f05394209590c476b65d75373435 + checksum: 10c0/8c5b515f38118471197605e02bea54a8a4283010e3c55bad8cfb78de59ad63612b14d40baca63689afdc9d57b147aac4c7794fe5f7736c9e1ed6dd38784be624 languageName: node linkType: hard @@ -1741,28 +1746,29 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.7" +"@babel/plugin-transform-typeof-symbol@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.8" dependencies: - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.24.8" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5649e7260a138681e68b296ab5931e2b1f132f287d6b4131d49b24f9dc20d62902b7e9d63c4d2decd5683b41df35ef4b9b03f58c7f9f65e4c25a6d8bbf04e9e9 + checksum: 10c0/2f570a4fbbdc5fd85f48165a97452826560051e3b8efb48c3bb0a0a33ee8485633439e7b71bfe3ef705583a1df43f854f49125bd759abdedc195b2cf7e60012a languageName: node linkType: hard "@babel/plugin-transform-typescript@npm:^7.22.15, @babel/plugin-transform-typescript@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-typescript@npm:7.24.7" + version: 7.25.2 + resolution: "@babel/plugin-transform-typescript@npm:7.25.2" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.24.7" - "@babel/helper-create-class-features-plugin": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" + "@babel/helper-create-class-features-plugin": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" "@babel/plugin-syntax-typescript": "npm:^7.24.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/e8dacdc153a4c4599014b66eb01b94e3dc933d58d4f0cc3039c1a8f432e77b9df14f34a61964e014b975bf466f3fefd8c4768b3e887d3da1be9dc942799bdfdf + checksum: 10c0/b3c941da39ee7ecf72df1b78a01d4108160438245f2ab61befe182f51d17fd0034733c6d079b7efad81e03a66438aa3881a671cd68c5eb0fc775df86b88df996 languageName: node linkType: hard @@ -1814,17 +1820,18 @@ __metadata: linkType: hard "@babel/preset-env@npm:^7.22.20, @babel/preset-env@npm:^7.23.2": - version: 7.24.7 - resolution: "@babel/preset-env@npm:7.24.7" + version: 7.25.3 + resolution: "@babel/preset-env@npm:7.25.3" dependencies: - "@babel/compat-data": "npm:^7.24.7" - "@babel/helper-compilation-targets": "npm:^7.24.7" - "@babel/helper-plugin-utils": "npm:^7.24.7" - "@babel/helper-validator-option": "npm:^7.24.7" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.24.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.24.7" + "@babel/compat-data": "npm:^7.25.2" + "@babel/helper-compilation-targets": "npm:^7.25.2" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-validator-option": "npm:^7.24.8" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.3" + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.0" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.0" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.24.7" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.24.7" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.0" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators": "npm:^7.8.4" "@babel/plugin-syntax-class-properties": "npm:^7.12.13" @@ -1845,29 +1852,30 @@ __metadata: "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" "@babel/plugin-transform-arrow-functions": "npm:^7.24.7" - "@babel/plugin-transform-async-generator-functions": "npm:^7.24.7" + "@babel/plugin-transform-async-generator-functions": "npm:^7.25.0" "@babel/plugin-transform-async-to-generator": "npm:^7.24.7" "@babel/plugin-transform-block-scoped-functions": "npm:^7.24.7" - "@babel/plugin-transform-block-scoping": "npm:^7.24.7" + "@babel/plugin-transform-block-scoping": "npm:^7.25.0" "@babel/plugin-transform-class-properties": "npm:^7.24.7" "@babel/plugin-transform-class-static-block": "npm:^7.24.7" - "@babel/plugin-transform-classes": "npm:^7.24.7" + "@babel/plugin-transform-classes": "npm:^7.25.0" "@babel/plugin-transform-computed-properties": "npm:^7.24.7" - "@babel/plugin-transform-destructuring": "npm:^7.24.7" + "@babel/plugin-transform-destructuring": "npm:^7.24.8" "@babel/plugin-transform-dotall-regex": "npm:^7.24.7" "@babel/plugin-transform-duplicate-keys": "npm:^7.24.7" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.0" "@babel/plugin-transform-dynamic-import": "npm:^7.24.7" "@babel/plugin-transform-exponentiation-operator": "npm:^7.24.7" "@babel/plugin-transform-export-namespace-from": "npm:^7.24.7" "@babel/plugin-transform-for-of": "npm:^7.24.7" - "@babel/plugin-transform-function-name": "npm:^7.24.7" + "@babel/plugin-transform-function-name": "npm:^7.25.1" "@babel/plugin-transform-json-strings": "npm:^7.24.7" - "@babel/plugin-transform-literals": "npm:^7.24.7" + "@babel/plugin-transform-literals": "npm:^7.25.2" "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7" "@babel/plugin-transform-member-expression-literals": "npm:^7.24.7" "@babel/plugin-transform-modules-amd": "npm:^7.24.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.24.7" - "@babel/plugin-transform-modules-systemjs": "npm:^7.24.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" + "@babel/plugin-transform-modules-systemjs": "npm:^7.25.0" "@babel/plugin-transform-modules-umd": "npm:^7.24.7" "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7" "@babel/plugin-transform-new-target": "npm:^7.24.7" @@ -1876,7 +1884,7 @@ __metadata: "@babel/plugin-transform-object-rest-spread": "npm:^7.24.7" "@babel/plugin-transform-object-super": "npm:^7.24.7" "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7" - "@babel/plugin-transform-optional-chaining": "npm:^7.24.7" + "@babel/plugin-transform-optional-chaining": "npm:^7.24.8" "@babel/plugin-transform-parameters": "npm:^7.24.7" "@babel/plugin-transform-private-methods": "npm:^7.24.7" "@babel/plugin-transform-private-property-in-object": "npm:^7.24.7" @@ -1887,7 +1895,7 @@ __metadata: "@babel/plugin-transform-spread": "npm:^7.24.7" "@babel/plugin-transform-sticky-regex": "npm:^7.24.7" "@babel/plugin-transform-template-literals": "npm:^7.24.7" - "@babel/plugin-transform-typeof-symbol": "npm:^7.24.7" + "@babel/plugin-transform-typeof-symbol": "npm:^7.24.8" "@babel/plugin-transform-unicode-escapes": "npm:^7.24.7" "@babel/plugin-transform-unicode-property-regex": "npm:^7.24.7" "@babel/plugin-transform-unicode-regex": "npm:^7.24.7" @@ -1896,11 +1904,11 @@ __metadata: babel-plugin-polyfill-corejs2: "npm:^0.4.10" babel-plugin-polyfill-corejs3: "npm:^0.10.4" babel-plugin-polyfill-regenerator: "npm:^0.6.1" - core-js-compat: "npm:^3.31.0" + core-js-compat: "npm:^3.37.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/c6714346f3ccc1271eaa90051c75b8bb57b20ef57408ab68740e2f3552693ae0ee5a4bcce3a00211d40e4947af1f7b8ab422066b953f0095461937fb72d11274 + checksum: 10c0/9287dc2e296fe2aa3367d84c2a799db17c9d1e48bba86525f47c6f51f5ba2e2cce454f45f4ae2ef928f9077c0640b04556b55b94835675ceeca94a0c5133205e languageName: node linkType: hard @@ -2013,7 +2021,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.14.0, @babel/traverse@npm:^7.16.8, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.22.20, @babel/traverse@npm:^7.22.5, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.1, @babel/traverse@npm:^7.25.2": +"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.14.0, @babel/traverse@npm:^7.16.8, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.22.20, @babel/traverse@npm:^7.22.5, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.1, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.3": version: 7.25.3 resolution: "@babel/traverse@npm:7.25.3" dependencies: @@ -13160,17 +13168,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.23.0, browserslist@npm:^4.23.1": - version: 4.23.2 - resolution: "browserslist@npm:4.23.2" +"browserslist@npm:^4.23.1, browserslist@npm:^4.23.3": + version: 4.23.3 + resolution: "browserslist@npm:4.23.3" dependencies: - caniuse-lite: "npm:^1.0.30001640" - electron-to-chromium: "npm:^1.4.820" - node-releases: "npm:^2.0.14" + caniuse-lite: "npm:^1.0.30001646" + electron-to-chromium: "npm:^1.5.4" + node-releases: "npm:^2.0.18" update-browserslist-db: "npm:^1.1.0" bin: browserslist: cli.js - checksum: 10c0/0217d23c69ed61cdd2530c7019bf7c822cd74c51f8baab18dd62457fed3129f52499f8d3a6f809ae1fb7bb3050aa70caa9a529cc36c7478427966dbf429723a5 + checksum: 10c0/3063bfdf812815346447f4796c8f04601bf5d62003374305fd323c2a463e42776475bcc5309264e39bcf9a8605851e53560695991a623be988138b3ff8c66642 languageName: node linkType: hard @@ -13409,10 +13417,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001640": - version: 1.0.30001642 - resolution: "caniuse-lite@npm:1.0.30001642" - checksum: 10c0/7366878ecdd482392a741c66fd2b39816b70573d66f64b1f8e5916835faf7a15f116368290170f4d7c4e823ec78eea9b6c0f63bee763a511cc7990afa429d63b +"caniuse-lite@npm:^1.0.30001646": + version: 1.0.30001651 + resolution: "caniuse-lite@npm:1.0.30001651" + checksum: 10c0/7821278952a6dbd17358e5d08083d258f092e2a530f5bc1840657cb140fbbc5ec44293bc888258c44a18a9570cde149ed05819ac8320b9710cf22f699891e6ad languageName: node linkType: hard @@ -14428,12 +14436,12 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.36.1": - version: 3.37.1 - resolution: "core-js-compat@npm:3.37.1" +"core-js-compat@npm:^3.36.1, core-js-compat@npm:^3.37.1": + version: 3.38.0 + resolution: "core-js-compat@npm:3.38.0" dependencies: - browserslist: "npm:^4.23.0" - checksum: 10c0/4e2da9c900f2951a57947af7aeef4d16f2c75d7f7e966c0d0b62953f65225003ade5e84d3ae98847f65b24c109c606821d9dc925db8ca418fb761e7c81963c2a + browserslist: "npm:^4.23.3" + checksum: 10c0/9d653a448b8a491034358d2f052e63dda86f75fb65646e2d313a938212470ba1c2f5a83bf31cc583d6c87a9e8d7b0d49458447cab2ff36c4caa097ae381de336 languageName: node linkType: hard @@ -15727,10 +15735,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.820": - version: 1.4.830 - resolution: "electron-to-chromium@npm:1.4.830" - checksum: 10c0/1a77042c805c1db081e00c058bded0e564154e9357eb63e77278e8f21d99125a35d2ba66d5357fddecbb63cc8f8b40ef8654a1bc949e34eccd5d31d4b7affc18 +"electron-to-chromium@npm:^1.5.4": + version: 1.5.8 + resolution: "electron-to-chromium@npm:1.5.8" + checksum: 10c0/801de2afa0479ffa0cd0e36b7865241dcd3a66a92fca28457431d2dc2bd9c2d066ab07578b419426c504df196f078c63283ee47140c28039d224ec2631acbcee languageName: node linkType: hard @@ -23374,10 +23382,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.14": - version: 2.0.14 - resolution: "node-releases@npm:2.0.14" - checksum: 10c0/199fc93773ae70ec9969bc6d5ac5b2bbd6eb986ed1907d751f411fef3ede0e4bfdb45ceb43711f8078bea237b6036db8b1bf208f6ff2b70c7d615afd157f3ab9 +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: 10c0/786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27 languageName: node linkType: hard From fc47b2cf3dfa8507303dd436951b9a1e4509ccf9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:48:40 +0000 Subject: [PATCH 18/52] fix(deps): update dependency @whatwg-node/fetch to v0.9.20 (#11269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@whatwg-node/fetch](https://togithub.com/ardatan/whatwg-node) ([source](https://togithub.com/ardatan/whatwg-node/tree/HEAD/packages/fetch)) | [`0.9.19` -> `0.9.20`](https://renovatebot.com/diffs/npm/@whatwg-node%2ffetch/0.9.19/0.9.20) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@whatwg-node%2ffetch/0.9.20?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@whatwg-node%2ffetch/0.9.20?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@whatwg-node%2ffetch/0.9.19/0.9.20?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@whatwg-node%2ffetch/0.9.19/0.9.20?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
ardatan/whatwg-node (@​whatwg-node/fetch) ### [`v0.9.20`](https://togithub.com/ardatan/whatwg-node/blob/HEAD/packages/fetch/CHANGELOG.md#0920) [Compare Source](https://togithub.com/ardatan/whatwg-node/compare/@whatwg-node/fetch@0.9.19...@whatwg-node/fetch@0.9.20) ##### Patch Changes - [#​1566](https://togithub.com/ardatan/whatwg-node/pull/1566) [`de1e95a`](https://togithub.com/ardatan/whatwg-node/commit/de1e95a8eb107083e638aa8472089b96b33bbe4a) Thanks [@​ardatan](https://togithub.com/ardatan)! - Avoid constructing DecompressionStream to check supported encodings - Updated dependencies \[[`de1e95a`](https://togithub.com/ardatan/whatwg-node/commit/de1e95a8eb107083e638aa8472089b96b33bbe4a)]: - [@​whatwg-node/node-fetch](https://togithub.com/whatwg-node/node-fetch)[@​0](https://togithub.com/0).5.22
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/redwoodjs/redwood). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/api/package.json | 2 +- packages/codemods/package.json | 2 +- packages/graphql-server/package.json | 2 +- packages/prerender/package.json | 2 +- packages/telemetry/package.json | 2 +- packages/vite/package.json | 2 +- packages/web/package.json | 2 +- yarn.lock | 36 ++++++++++------------------ 8 files changed, 20 insertions(+), 30 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 010d2a7fa0fc..f984a71c2958 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -34,7 +34,7 @@ "dependencies": { "@babel/runtime-corejs3": "7.25.0", "@prisma/client": "5.18.0", - "@whatwg-node/fetch": "0.9.19", + "@whatwg-node/fetch": "0.9.20", "cookie": "0.6.0", "core-js": "3.38.0", "humanize-string": "2.1.0", diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 0ff20c028b15..33434cb0c239 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -33,7 +33,7 @@ "@svgr/core": "8.1.0", "@svgr/plugin-jsx": "8.1.0", "@vscode/ripgrep": "1.15.9", - "@whatwg-node/fetch": "0.9.19", + "@whatwg-node/fetch": "0.9.20", "cheerio": "1.0.0", "core-js": "3.38.0", "deepmerge": "4.3.1", diff --git a/packages/graphql-server/package.json b/packages/graphql-server/package.json index 0acdfb05a96e..ab633d5b9cd9 100644 --- a/packages/graphql-server/package.json +++ b/packages/graphql-server/package.json @@ -55,7 +55,7 @@ "@types/jsonwebtoken": "9.0.6", "@types/lodash": "4.17.7", "@types/uuid": "10.0.0", - "@whatwg-node/fetch": "0.9.19", + "@whatwg-node/fetch": "0.9.20", "jest": "29.7.0", "jsonwebtoken": "9.0.2", "tsx": "4.17.0", diff --git a/packages/prerender/package.json b/packages/prerender/package.json index f6945610e110..fd798f21f1d9 100644 --- a/packages/prerender/package.json +++ b/packages/prerender/package.json @@ -30,7 +30,7 @@ "@redwoodjs/router": "workspace:*", "@redwoodjs/structure": "workspace:*", "@redwoodjs/web": "workspace:*", - "@whatwg-node/fetch": "0.9.19", + "@whatwg-node/fetch": "0.9.20", "babel-plugin-ignore-html-and-css-imports": "0.1.0", "cheerio": "1.0.0", "core-js": "3.38.0", diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index befcc2be8ef6..b2536a72e252 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -23,7 +23,7 @@ "dependencies": { "@redwoodjs/project-config": "workspace:*", "@redwoodjs/structure": "workspace:*", - "@whatwg-node/fetch": "0.9.19", + "@whatwg-node/fetch": "0.9.20", "ci-info": "4.0.0", "envinfo": "7.13.0", "systeminformation": "5.23.4", diff --git a/packages/vite/package.json b/packages/vite/package.json index 66da130018c7..9b9567288489 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -72,7 +72,7 @@ "@redwoodjs/web": "workspace:*", "@swc/core": "1.7.11", "@vitejs/plugin-react": "4.3.1", - "@whatwg-node/fetch": "0.9.19", + "@whatwg-node/fetch": "0.9.20", "@whatwg-node/server": "0.9.47", "acorn-loose": "8.4.0", "buffer": "6.0.3", diff --git a/packages/web/package.json b/packages/web/package.json index 247bc2005c52..a3edfb78968b 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -145,7 +145,7 @@ "@babel/runtime-corejs3": "7.25.0", "@redwoodjs/auth": "workspace:*", "@redwoodjs/server-store": "workspace:*", - "@whatwg-node/fetch": "0.9.19", + "@whatwg-node/fetch": "0.9.20", "core-js": "3.38.0", "graphql": "16.9.0", "graphql-sse": "2.5.3", diff --git a/yarn.lock b/yarn.lock index 4515ea79265f..f9d2800f8bf4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7224,7 +7224,7 @@ __metadata: "@types/memjs": "npm:1" "@types/pascalcase": "npm:1.0.3" "@types/split2": "npm:4.2.3" - "@whatwg-node/fetch": "npm:0.9.19" + "@whatwg-node/fetch": "npm:0.9.20" cookie: "npm:0.6.0" core-js: "npm:3.38.0" humanize-string: "npm:2.1.0" @@ -7958,7 +7958,7 @@ __metadata: "@types/jscodeshift": "npm:0.11.11" "@types/yargs": "npm:17.0.33" "@vscode/ripgrep": "npm:1.15.9" - "@whatwg-node/fetch": "npm:0.9.19" + "@whatwg-node/fetch": "npm:0.9.20" cheerio: "npm:1.0.0" core-js: "npm:3.38.0" deepmerge: "npm:4.3.1" @@ -8179,7 +8179,7 @@ __metadata: "@types/jsonwebtoken": "npm:9.0.6" "@types/lodash": "npm:4.17.7" "@types/uuid": "npm:10.0.0" - "@whatwg-node/fetch": "npm:0.9.19" + "@whatwg-node/fetch": "npm:0.9.20" core-js: "npm:3.38.0" graphql: "npm:16.9.0" graphql-scalars: "npm:1.23.0" @@ -8369,7 +8369,7 @@ __metadata: "@redwoodjs/structure": "workspace:*" "@redwoodjs/web": "workspace:*" "@types/mime-types": "npm:2.1.4" - "@whatwg-node/fetch": "npm:0.9.19" + "@whatwg-node/fetch": "npm:0.9.20" babel-plugin-ignore-html-and-css-imports: "npm:0.1.0" babel-plugin-tester: "npm:11.0.4" cheerio: "npm:1.0.0" @@ -8543,7 +8543,7 @@ __metadata: "@types/envinfo": "npm:7.8.4" "@types/uuid": "npm:10.0.0" "@types/yargs": "npm:17.0.33" - "@whatwg-node/fetch": "npm:0.9.19" + "@whatwg-node/fetch": "npm:0.9.20" ci-info: "npm:4.0.0" envinfo: "npm:7.13.0" systeminformation: "npm:5.23.4" @@ -8630,7 +8630,7 @@ __metadata: "@types/ws": "npm:^8" "@types/yargs-parser": "npm:21.0.3" "@vitejs/plugin-react": "npm:4.3.1" - "@whatwg-node/fetch": "npm:0.9.19" + "@whatwg-node/fetch": "npm:0.9.20" "@whatwg-node/server": "npm:0.9.47" acorn-loose: "npm:8.4.0" buffer: "npm:6.0.3" @@ -8710,7 +8710,7 @@ __metadata: "@testing-library/react": "npm:14.3.1" "@types/react": "npm:^18.2.55" "@types/react-dom": "npm:^18.2.19" - "@whatwg-node/fetch": "npm:0.9.19" + "@whatwg-node/fetch": "npm:0.9.20" concurrently: "npm:8.2.2" core-js: "npm:3.38.0" graphql: "npm:16.9.0" @@ -11490,13 +11490,13 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/fetch@npm:0.9.19": - version: 0.9.19 - resolution: "@whatwg-node/fetch@npm:0.9.19" +"@whatwg-node/fetch@npm:0.9.20, @whatwg-node/fetch@npm:^0.9.18, @whatwg-node/fetch@npm:^0.9.20": + version: 0.9.20 + resolution: "@whatwg-node/fetch@npm:0.9.20" dependencies: - "@whatwg-node/node-fetch": "npm:^0.5.16" + "@whatwg-node/node-fetch": "npm:^0.5.22" urlpattern-polyfill: "npm:^10.0.0" - checksum: 10c0/df446e2348c1ac795f6dd241f5c4c89dc303bfcc44ab27fa85c959d40b542deb6335d19bf5ad8271a40c1d2be66987932bfe83a7fce11831a33dbd97c7d5711e + checksum: 10c0/b40521697543135783a22d8b3b96af17fb00f803e4cf55c60ea1e2bcf0c5d24906922db1c2c9c0f84be530d4f097560d67f58745c1f263c3c46ad7120aea67f5 languageName: node linkType: hard @@ -11513,16 +11513,6 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/fetch@npm:^0.9.18, @whatwg-node/fetch@npm:^0.9.20": - version: 0.9.20 - resolution: "@whatwg-node/fetch@npm:0.9.20" - dependencies: - "@whatwg-node/node-fetch": "npm:^0.5.22" - urlpattern-polyfill: "npm:^10.0.0" - checksum: 10c0/b40521697543135783a22d8b3b96af17fb00f803e4cf55c60ea1e2bcf0c5d24906922db1c2c9c0f84be530d4f097560d67f58745c1f263c3c46ad7120aea67f5 - languageName: node - linkType: hard - "@whatwg-node/node-fetch@npm:^0.3.6": version: 0.3.6 resolution: "@whatwg-node/node-fetch@npm:0.3.6" @@ -11536,7 +11526,7 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/node-fetch@npm:^0.5.16, @whatwg-node/node-fetch@npm:^0.5.22": +"@whatwg-node/node-fetch@npm:^0.5.22": version: 0.5.22 resolution: "@whatwg-node/node-fetch@npm:0.5.22" dependencies: From c32bc628dee94d83be2bae9861beced1a2db6e71 Mon Sep 17 00:00:00 2001 From: David Thyresson Date: Thu, 15 Aug 2024 13:00:08 -0400 Subject: [PATCH 19/52] fix(cli): Service generator supports relations (#11250) This PR address an issue when using `yarn rw g service` independently vs having ti be called by `yarn rw g sdl` or `yarn rw g scaffold`. When using `yarn rw g service`, the model's relations were not correctly determined. For the sdl generator, relations are determined and then passed as an argument to the service generator; however, if you run just the service generator, the relations were always []. Thus, for the test fixture model schema: ```prisma model User { id Int @id @default(autoincrement()) name String? email String @unique isAdmin Boolean @default(false) profiles UserProfile[] transactions Transaction[] } ``` A user has two relations: a UserProfile and transactions. Without the fix, the following is missing from the user service: ```ts export const User = { profiles: (_obj, { root }) => { return db.user.findUnique({ where: { id: root?.id } }).profiles() }, transactions: (_obj, { root }) => { return db.user.findUnique({ where: { id: root?.id } }).transactions() }, } ``` Fixing because when using experimental sdlCodegen, I write the SDL manually and then generate the service. I also will have a custom template for the sdlCogen pattern, but my template failed because it didn't get the the relations to properly build out the service according to my template. This is why this PR also bumps the sdl-codegen package. --- .changesets/11250.md | 7 ++ .../__snapshots__/service.test.js.snap | 71 ++++++++++++++++++- .../src/commands/generate/service/service.js | 8 ++- packages/internal/package.json | 2 +- yarn.lock | 10 +-- 5 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 .changesets/11250.md diff --git a/.changesets/11250.md b/.changesets/11250.md new file mode 100644 index 000000000000..ae78b6e9abad --- /dev/null +++ b/.changesets/11250.md @@ -0,0 +1,7 @@ +- fix(cli): Service generator supports relations (#11250) by @dthyresson + +This PR address an issue when using `yarn rw g service` independently vs having ti be called by `yarn rw g sdl` or `yarn rw g scaffold`. + +When using `yarn rw g service`, the model's relations were not correctly determined. For the sdl generator, relations are determined and then passed as an argument to the service generator; however, if you run just the service generator, the relations were always `[]`. + +This PR fixes that by adding a check to see if the relations are already passed in as an argument. If they are, it uses that; otherwise, it falls back to determining the relations itself. diff --git a/packages/cli/src/commands/generate/service/__tests__/__snapshots__/service.test.js.snap b/packages/cli/src/commands/generate/service/__tests__/__snapshots__/service.test.js.snap index 33c5bfeaa721..020ce533a67f 100644 --- a/packages/cli/src/commands/generate/service/__tests__/__snapshots__/service.test.js.snap +++ b/packages/cli/src/commands/generate/service/__tests__/__snapshots__/service.test.js.snap @@ -6,6 +6,18 @@ exports[`in javascript mode > creates a multi word service file 1`] = ` export const userProfiles = () => { return db.userProfile.findMany() } + +export const userProfile = ({ id }) => { + return db.userProfile.findUnique({ + where: { id }, + }) +} + +export const UserProfile = { + user: (_obj, { root }) => { + return db.userProfile.findUnique({ where: { id: root?.id } }).user() + }, +} " `; @@ -189,6 +201,15 @@ export const deleteUser = ({ id }) => { where: { id }, }) } + +export const User = { + profiles: (_obj, { root }) => { + return db.user.findUnique({ where: { id: root?.id } }).profiles() + }, + transactions: (_obj, { root }) => { + return db.user.findUnique({ where: { id: root?.id } }).transactions() + }, +} " `; @@ -223,6 +244,12 @@ export const deletePost = ({ id }) => { where: { id }, }) } + +export const Post = { + favorites: (_obj, { root }) => { + return db.post.findUnique({ where: { id: root?.id } }).favorites() + }, +} " `; @@ -353,13 +380,28 @@ describe('users', () => { `; exports[`in typescript mode > creates a multi word service file 1`] = ` -"import type { QueryResolvers } from 'types/graphql' +"import type { + QueryResolvers, + UserProfileRelationResolvers, +} from 'types/graphql' import { db } from 'src/lib/db' export const userProfiles: QueryResolvers['userProfiles'] = () => { return db.userProfile.findMany() } + +export const userProfile: QueryResolvers['userProfile'] = ({ id }) => { + return db.userProfile.findUnique({ + where: { id }, + }) +} + +export const UserProfile: UserProfileRelationResolvers = { + user: (_obj, { root }) => { + return db.userProfile.findUnique({ where: { id: root?.id } }).user() + }, +} " `; @@ -528,7 +570,11 @@ describe('scalarTypes', () => { `; exports[`in typescript mode > creates a single word service file 1`] = ` -"import type { QueryResolvers, MutationResolvers } from 'types/graphql' +"import type { + QueryResolvers, + MutationResolvers, + UserRelationResolvers, +} from 'types/graphql' import { db } from 'src/lib/db' @@ -560,11 +606,24 @@ export const deleteUser: MutationResolvers['deleteUser'] = ({ id }) => { where: { id }, }) } + +export const User: UserRelationResolvers = { + profiles: (_obj, { root }) => { + return db.user.findUnique({ where: { id: root?.id } }).profiles() + }, + transactions: (_obj, { root }) => { + return db.user.findUnique({ where: { id: root?.id } }).transactions() + }, +} " `; exports[`in typescript mode > creates a single word service file with CRUD actions 1`] = ` -"import type { QueryResolvers, MutationResolvers } from 'types/graphql' +"import type { + QueryResolvers, + MutationResolvers, + PostRelationResolvers, +} from 'types/graphql' import { db } from 'src/lib/db' @@ -596,6 +655,12 @@ export const deletePost: MutationResolvers['deletePost'] = ({ id }) => { where: { id }, }) } + +export const Post: PostRelationResolvers = { + favorites: (_obj, { root }) => { + return db.post.findUnique({ where: { id: root?.id } }).favorites() + }, +} " `; diff --git a/packages/cli/src/commands/generate/service/service.js b/packages/cli/src/commands/generate/service/service.js index 051c25da3764..e98f849b9420 100644 --- a/packages/cli/src/commands/generate/service/service.js +++ b/packages/cli/src/commands/generate/service/service.js @@ -4,7 +4,7 @@ import terminalLink from 'terminal-link' import { transformTSToJS } from '../../../lib' import { pluralize, singularize } from '../../../lib/rwPluralize' import { getSchema, verifyModelName } from '../../../lib/schemaHelpers' -import { yargsDefaults } from '../helpers' +import { yargsDefaults, relationsForModel } from '../helpers' import { createYargsForComponentGeneration, templateForComponentFile, @@ -304,6 +304,9 @@ export const files = async ({ const model = name const idName = await getIdName(model) const extension = 'ts' + + const modelRelations = relations || relationsForModel(await getSchema(model)) + const serviceFile = await templateForComponentFile({ name, componentName: componentName, @@ -311,7 +314,7 @@ export const files = async ({ apiPathSection: 'services', generator: 'service', templatePath: `service.${extension}.template`, - templateVars: { relations: relations || [], idName, ...rest }, + templateVars: { relations: modelRelations, idName, ...rest }, }) const testFile = await templateForComponentFile({ @@ -347,6 +350,7 @@ export const files = async ({ stringifiedScenario: await buildStringifiedScenario(model), prismaModel: model, idName, + relations: modelRelations, ...rest, }, }) diff --git a/packages/internal/package.json b/packages/internal/package.json index 710755a48566..21f7015e27f1 100644 --- a/packages/internal/package.json +++ b/packages/internal/package.json @@ -51,7 +51,7 @@ "@redwoodjs/graphql-server": "workspace:*", "@redwoodjs/project-config": "workspace:*", "@redwoodjs/router": "workspace:*", - "@sdl-codegen/node": "1.0.1", + "@sdl-codegen/node": "1.0.2", "chalk": "4.1.2", "core-js": "3.38.0", "deepmerge": "4.3.1", diff --git a/yarn.lock b/yarn.lock index f9d2800f8bf4..e432e137353e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8221,7 +8221,7 @@ __metadata: "@redwoodjs/graphql-server": "workspace:*" "@redwoodjs/project-config": "workspace:*" "@redwoodjs/router": "workspace:*" - "@sdl-codegen/node": "npm:1.0.1" + "@sdl-codegen/node": "npm:1.0.2" "@types/fs-extra": "npm:11.0.4" chalk: "npm:4.1.2" core-js: "npm:3.38.0" @@ -8912,9 +8912,9 @@ __metadata: languageName: node linkType: hard -"@sdl-codegen/node@npm:1.0.1": - version: 1.0.1 - resolution: "@sdl-codegen/node@npm:1.0.1" +"@sdl-codegen/node@npm:1.0.2": + version: 1.0.2 + resolution: "@sdl-codegen/node@npm:1.0.2" dependencies: "@mrleebo/prisma-ast": "npm:^0.12.0" ts-morph: "npm:^22.0.0" @@ -8925,7 +8925,7 @@ __metadata: peerDependenciesMeta: prettier: optional: true - checksum: 10c0/eb75031018b73b90d053a6647d3806414e3eeb5811159b0c0ea710cb5a8028f9cb36b57ab718dafbb63281828934020e3341bf598fd674de19b0756996ba0d11 + checksum: 10c0/60df05c9d1d4b483343a07521a0e1796367ac2de0332fa9bd7b93044fd4a8d8fe703ceac0c80714def50ec0b4e04ea5bd378c0214750bb0cde6ec56abcb06ac8 languageName: node linkType: hard From c75493e552ada924e15eaf006fceffdff8cecea6 Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Thu, 15 Aug 2024 20:21:26 +0200 Subject: [PATCH 20/52] feat(exec): Add --silent to silence all RW output (#11278) --- .changesets/11278.md | 8 ++++++++ packages/cli/src/commands/exec.js | 6 ++++++ packages/cli/src/commands/execHandler.js | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .changesets/11278.md diff --git a/.changesets/11278.md b/.changesets/11278.md new file mode 100644 index 000000000000..891d5b90c13d --- /dev/null +++ b/.changesets/11278.md @@ -0,0 +1,8 @@ +- feat(exec): Add --silent to silence all RW output (#11278) by @Tobbe + +Run with `--silent` (or `-s`) to not have the framework itself print anything to +your console. Only console logs you have yourself in the script, or any files +the script includes, will come through. + +If you're using Prisma you might want to tweak Prisma's logging (in +`api/lib/db.ts`) and turn off "info" logging, depending on your goals. diff --git a/packages/cli/src/commands/exec.js b/packages/cli/src/commands/exec.js index 47e6c4837437..3298991c3bd2 100644 --- a/packages/cli/src/commands/exec.js +++ b/packages/cli/src/commands/exec.js @@ -19,6 +19,12 @@ export const builder = (yargs) => { default: false, description: 'List available scripts', }) + .option('silent', { + alias: 's', + type: 'boolean', + default: false, + description: "Silence Redwood's output, leaving only the script output", + }) .strict(false) .epilogue( `Also see the ${terminalLink( diff --git a/packages/cli/src/commands/execHandler.js b/packages/cli/src/commands/execHandler.js index 0da6ef42f8ca..f0ae2a84f1d0 100644 --- a/packages/cli/src/commands/execHandler.js +++ b/packages/cli/src/commands/execHandler.js @@ -137,7 +137,7 @@ export const handler = async (args) => { const tasks = new Listr(scriptTasks, { rendererOptions: { collapseSubtasks: false }, - renderer: 'verbose', + renderer: args.silent ? 'silent' : 'verbose', }) // Prevent user project telemetry from within the script from being recorded From 936b410763b9a53f1e4d307297c38bee8c5e55bb Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:14:13 +0100 Subject: [PATCH 21/52] chore(lint): enable 'typescript-eslint/no-unsafe-enum-comparison' (#11281) Enables the `typescript-eslint/no-unsafe-enum-comparison` rule and addresses the points it raised. --- .eslintrc.js | 1 - .../babel-plugin-redwood-mock-cell-data.ts | 7 +++-- packages/cli/src/testLib/cells.ts | 8 +++--- packages/codemods/src/lib/cells.ts | 8 +++--- .../src/service-type-annotations.ts | 9 ++++--- .../src/unsupported-route-components.ts | 26 ++++++++++++------- .../src/directives/makeDirectives.ts | 4 +-- .../internal/src/generate/graphqlCodeGen.ts | 4 +-- packages/internal/src/gql.ts | 8 +++--- packages/structure/src/model/RWCell.ts | 4 +-- packages/structure/src/model/RWSDL.ts | 3 ++- packages/web/src/apollo/index.tsx | 6 +++-- packages/web/src/graphql.ts | 7 +++-- 13 files changed, 56 insertions(+), 39 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index aa76958f5b56..127d7959dbcf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -206,7 +206,6 @@ module.exports = { '@typescript-eslint/prefer-nullish-coalescing': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unnecessary-type-assertion': 'off', - '@typescript-eslint/no-unsafe-enum-comparison': 'off', '@typescript-eslint/dot-notation': 'off', '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-unsafe-return': 'off', diff --git a/packages/babel-config/src/plugins/babel-plugin-redwood-mock-cell-data.ts b/packages/babel-config/src/plugins/babel-plugin-redwood-mock-cell-data.ts index 04443082ae03..b6c7add5e967 100644 --- a/packages/babel-config/src/plugins/babel-plugin-redwood-mock-cell-data.ts +++ b/packages/babel-config/src/plugins/babel-plugin-redwood-mock-cell-data.ts @@ -7,7 +7,7 @@ import { parse as babelParse } from '@babel/parser' import type { ParserPlugin } from '@babel/parser' import traverse from '@babel/traverse' import fg from 'fast-glob' -import { parse as graphqlParse } from 'graphql' +import { parse as graphqlParse, Kind } from 'graphql' export default function ({ types: t }: { types: typeof types }): PluginObj { let nodesToRemove: any[] = [] @@ -248,7 +248,10 @@ export const getCellMetadata = (p: string) => { const document = graphqlParse(operation) for (const definition of document.definitions) { - if (definition.kind === 'OperationDefinition' && definition.name?.value) { + if ( + definition.kind === Kind.OPERATION_DEFINITION && + definition.name?.value + ) { operationName = definition.name.value } } diff --git a/packages/cli/src/testLib/cells.ts b/packages/cli/src/testLib/cells.ts index 577bd2e36e3b..d83e87d68238 100644 --- a/packages/cli/src/testLib/cells.ts +++ b/packages/cli/src/testLib/cells.ts @@ -13,7 +13,7 @@ import type { OperationDefinitionNode, OperationTypeNode, } from 'graphql' -import { parse, visit } from 'graphql' +import { Kind, parse, visit } from 'graphql' import { getPaths } from '@redwoodjs/project-config' @@ -239,13 +239,13 @@ const getFields = (field: FieldNode): any => { const lookAtFieldNode = (node: FieldNode | InlineFragmentNode): void => { node.selectionSet?.selections.forEach((subField) => { switch (subField.kind) { - case 'Field': + case Kind.FIELD: obj[field.name.value].push(getFields(subField as FieldNode)) break - case 'FragmentSpread': + case Kind.FRAGMENT_SPREAD: // TODO: Maybe this will also be needed, right now it's accounted for to not crash in the tests break - case 'InlineFragment': + case Kind.INLINE_FRAGMENT: lookAtFieldNode(subField) } }) diff --git a/packages/codemods/src/lib/cells.ts b/packages/codemods/src/lib/cells.ts index 577bd2e36e3b..d83e87d68238 100644 --- a/packages/codemods/src/lib/cells.ts +++ b/packages/codemods/src/lib/cells.ts @@ -13,7 +13,7 @@ import type { OperationDefinitionNode, OperationTypeNode, } from 'graphql' -import { parse, visit } from 'graphql' +import { Kind, parse, visit } from 'graphql' import { getPaths } from '@redwoodjs/project-config' @@ -239,13 +239,13 @@ const getFields = (field: FieldNode): any => { const lookAtFieldNode = (node: FieldNode | InlineFragmentNode): void => { node.selectionSet?.selections.forEach((subField) => { switch (subField.kind) { - case 'Field': + case Kind.FIELD: obj[field.name.value].push(getFields(subField as FieldNode)) break - case 'FragmentSpread': + case Kind.FRAGMENT_SPREAD: // TODO: Maybe this will also be needed, right now it's accounted for to not crash in the tests break - case 'InlineFragment': + case Kind.INLINE_FRAGMENT: lookAtFieldNode(subField) } }) diff --git a/packages/eslint-plugin/src/service-type-annotations.ts b/packages/eslint-plugin/src/service-type-annotations.ts index 563aebe22bd4..9ba5dccd7ebc 100644 --- a/packages/eslint-plugin/src/service-type-annotations.ts +++ b/packages/eslint-plugin/src/service-type-annotations.ts @@ -48,7 +48,10 @@ export const serviceTypeAnnotations = createRule({ node.declaration.declarations.forEach((vd) => { // VariableDeclarator means an `export const abcThing =` - if (vd.type === 'VariableDeclarator' && vd.id.type === 'Identifier') { + if ( + vd.type === AST_NODE_TYPES.VariableDeclarator && + vd.id.type === AST_NODE_TYPES.Identifier + ) { // Don't add types to functions that start with _ if (vd.id.name.startsWith('_')) { return @@ -65,7 +68,7 @@ export const serviceTypeAnnotations = createRule({ // Only run for lowercase arrow funcs ATM if ( isGlobalOrMutationResolver && - vd.init?.type !== 'ArrowFunctionExpression' + vd.init?.type !== AST_NODE_TYPES.ArrowFunctionExpression ) { return } @@ -117,7 +120,7 @@ export const serviceTypeAnnotations = createRule({ } const isCorrectType = - type.typeName?.type === 'Identifier' && + type.typeName?.type === AST_NODE_TYPES.Identifier && type.typeName?.name === typeName if (isCorrectType) { diff --git a/packages/eslint-plugin/src/unsupported-route-components.ts b/packages/eslint-plugin/src/unsupported-route-components.ts index d24e35ad8a34..09b5652438a6 100644 --- a/packages/eslint-plugin/src/unsupported-route-components.ts +++ b/packages/eslint-plugin/src/unsupported-route-components.ts @@ -1,5 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils' -import { ESLintUtils } from '@typescript-eslint/utils' +import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils' import type { RuleContext } from '@typescript-eslint/utils/ts-eslint' const createRule = ESLintUtils.RuleCreator.withoutDocs @@ -13,9 +13,9 @@ function checkNodes( nodesToCheck: TSESTree.JSXElement | TSESTree.JSXChild, context: RuleContext<'unexpected', []>, ) { - if (nodesToCheck.type === 'JSXElement') { + if (nodesToCheck.type === AST_NODE_TYPES.JSXElement) { const name = - nodesToCheck.openingElement.name.type === 'JSXIdentifier' + nodesToCheck.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier ? nodesToCheck.openingElement.name.name : null if (name && !isAllowedElement(name)) { @@ -51,15 +51,21 @@ export const unsupportedRouteComponents = createRule({ if (isRoutesRenderBlock(node.declarations[0])) { const routesDeclaration = node.declarations[0].init - if (routesDeclaration?.type === 'ArrowFunctionExpression') { - if (routesDeclaration.body.type === 'JSXElement') { + if ( + routesDeclaration?.type === AST_NODE_TYPES.ArrowFunctionExpression + ) { + if (routesDeclaration.body.type === AST_NODE_TYPES.JSXElement) { // Routes = () => ... checkNodes(routesDeclaration.body, context) - } else if (routesDeclaration.body.type === 'BlockStatement') { + } else if ( + routesDeclaration.body.type === AST_NODE_TYPES.BlockStatement + ) { // For when Routes = () => { return (...) } if ( - routesDeclaration.body.body[0].type === 'ReturnStatement' && - routesDeclaration.body.body[0].argument?.type === 'JSXElement' + routesDeclaration.body.body[0].type === + AST_NODE_TYPES.ReturnStatement && + routesDeclaration.body.body[0].argument?.type === + AST_NODE_TYPES.JSXElement ) { const routesReturnStatement = routesDeclaration.body.body[0].argument @@ -76,8 +82,8 @@ export const unsupportedRouteComponents = createRule({ function isRoutesRenderBlock(node?: TSESTree.VariableDeclarator) { return ( - node?.type === 'VariableDeclarator' && - node?.id.type === 'Identifier' && + node?.type === AST_NODE_TYPES.VariableDeclarator && + node?.id.type === AST_NODE_TYPES.Identifier && node?.id.name === 'Routes' ) } diff --git a/packages/graphql-server/src/directives/makeDirectives.ts b/packages/graphql-server/src/directives/makeDirectives.ts index 09e113540e61..e3b0f84f025a 100644 --- a/packages/graphql-server/src/directives/makeDirectives.ts +++ b/packages/graphql-server/src/directives/makeDirectives.ts @@ -1,4 +1,4 @@ -import type { DocumentNode } from 'graphql' +import { Kind, type DocumentNode } from 'graphql' import type { RedwoodDirective, @@ -49,7 +49,7 @@ export const makeDirectivesForPlugin = ( export const getDirectiveName = (schema: DocumentNode) => { const definition = schema.definitions.find( - (definition) => definition.kind === 'DirectiveDefinition', + (definition) => definition.kind === Kind.DIRECTIVE_DEFINITION, ) return definition?.name?.value diff --git a/packages/internal/src/generate/graphqlCodeGen.ts b/packages/internal/src/generate/graphqlCodeGen.ts index 08b383f0ea36..694be8675dcf 100644 --- a/packages/internal/src/generate/graphqlCodeGen.ts +++ b/packages/internal/src/generate/graphqlCodeGen.ts @@ -15,7 +15,7 @@ import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader' import { loadDocuments, loadSchemaSync } from '@graphql-tools/load' import type { LoadTypedefsOptions } from '@graphql-tools/load' import execa from 'execa' -import type { DocumentNode } from 'graphql' +import { Kind, type DocumentNode } from 'graphql' import { getPaths, getConfig } from '@redwoodjs/project-config' @@ -346,7 +346,7 @@ const printMappedModelsPlugin: CodegenPlugin = { // this way we can make sure relation types are not required const sdlTypesWhichAreMapped = Object.values(schema.getTypeMap()) .filter((type) => { - return type.astNode?.kind === 'ObjectTypeDefinition' + return type.astNode?.kind === Kind.OBJECT_TYPE_DEFINITION }) .filter((objectDefType) => { const modelName = objectDefType.astNode?.name.value diff --git a/packages/internal/src/gql.ts b/packages/internal/src/gql.ts index a6ad16477465..922903b2d803 100644 --- a/packages/internal/src/gql.ts +++ b/packages/internal/src/gql.ts @@ -7,7 +7,7 @@ import type { OperationDefinitionNode, OperationTypeNode, } from 'graphql' -import { parse, print, visit } from 'graphql' +import { Kind, parse, print, visit } from 'graphql' import { rootSchema } from '@redwoodjs/graphql-server' import { getPaths } from '@redwoodjs/project-config' @@ -61,13 +61,13 @@ const getFields = (field: FieldNode): any => { const lookAtFieldNode = (node: FieldNode | InlineFragmentNode): void => { node.selectionSet?.selections.forEach((subField) => { switch (subField.kind) { - case 'Field': + case Kind.FIELD: obj[field.name.value].push(getFields(subField as FieldNode)) break - case 'FragmentSpread': + case Kind.FRAGMENT_SPREAD: // TODO: Maybe this will also be needed, right now it's accounted for to not crash in the tests break - case 'InlineFragment': + case Kind.INLINE_FRAGMENT: lookAtFieldNode(subField) } }) diff --git a/packages/structure/src/model/RWCell.ts b/packages/structure/src/model/RWCell.ts index f2d457e6878c..854a1fd608d3 100644 --- a/packages/structure/src/model/RWCell.ts +++ b/packages/structure/src/model/RWCell.ts @@ -1,4 +1,4 @@ -import { parse as parseGraphQL } from 'graphql' +import { Kind, parse as parseGraphQL } from 'graphql' import * as tsm from 'ts-morph' import { DiagnosticSeverity } from 'vscode-languageserver-types' @@ -60,7 +60,7 @@ export class RWCell extends RWComponent { return undefined } for (const def of ast.definitions) { - if (def.kind == 'OperationDefinition') { + if (def.kind == Kind.OPERATION_DEFINITION) { return def?.name?.value } } diff --git a/packages/structure/src/model/RWSDL.ts b/packages/structure/src/model/RWSDL.ts index 5c24225171b0..d054c71dd026 100644 --- a/packages/structure/src/model/RWSDL.ts +++ b/packages/structure/src/model/RWSDL.ts @@ -1,5 +1,6 @@ import { basename } from 'path' +import { Kind } from 'graphql' import { parse as parseGraphQL } from 'graphql/language/parser' import * as tsm from 'ts-morph' @@ -59,7 +60,7 @@ export class RWSDL extends FileNode { } //? const ast = parseGraphQL(self.schemaString) for (const def of ast.definitions) { - if (def.kind === 'ObjectTypeDefinition') { + if (def.kind === Kind.OBJECT_TYPE_DEFINITION) { if (def.name.value === 'Query' || def.name.value === 'Mutation') { for (const field of def.fields ?? []) { yield new RWSDLField(def, field, self) diff --git a/packages/web/src/apollo/index.tsx b/packages/web/src/apollo/index.tsx index 05de0f56bcc4..42df19ffe12c 100644 --- a/packages/web/src/apollo/index.tsx +++ b/packages/web/src/apollo/index.tsx @@ -29,6 +29,7 @@ import { } from '@apollo/client/react/hooks/hooks.cjs' import { getMainDefinition } from '@apollo/client/utilities/utilities.cjs' import { fetch as crossFetch } from '@whatwg-node/fetch' +import { Kind, OperationTypeNode } from 'graphql' import { print } from 'graphql/language/printer.js' import type { UseAuth } from '@redwoodjs/auth' @@ -48,6 +49,7 @@ import { } from './fragmentRegistry.js' import * as SSELinkExports from './sseLink.js' import { useCache } from './useCache.js' + // Not sure why we need to import it this way for legacy builds to work const { SSELink } = SSELinkExports @@ -236,8 +238,8 @@ const ApolloProviderWithFetchConfig: React.FunctionComponent<{ const definition = getMainDefinition(query) return ( - definition.kind === 'OperationDefinition' && - definition.operation === 'subscription' + definition.kind === Kind.OPERATION_DEFINITION && + definition.operation === OperationTypeNode.SUBSCRIPTION ) }, new SSELink({ diff --git a/packages/web/src/graphql.ts b/packages/web/src/graphql.ts index baef34c3c177..43caa654f3ba 100644 --- a/packages/web/src/graphql.ts +++ b/packages/web/src/graphql.ts @@ -1,4 +1,4 @@ -import type { DocumentNode } from 'graphql' +import { Kind, type DocumentNode } from 'graphql' /** * Given a query like the one below this function will return @@ -23,7 +23,10 @@ import type { DocumentNode } from 'graphql' */ export function getOperationName(document: DocumentNode) { for (const definition of document.definitions) { - if (definition.kind === 'OperationDefinition' && definition.name?.value) { + if ( + definition.kind === Kind.OPERATION_DEFINITION && + definition.name?.value + ) { return definition.name.value } } From dcfcb932c4100a2f2a2aeb1664fab2fa81c385b7 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:19:51 +0100 Subject: [PATCH 22/52] chore(lint): enable 'typescript-eslint/no-duplicate-type-constituents' (#11283) Enabled `typescript-eslint/no-duplicate-type-constituents` and addresses points raised. --- .eslintrc.js | 1 - packages/api/src/auth/verifiers/common.ts | 1 - packages/forms/src/coercion.ts | 3 +-- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 127d7959dbcf..df2949f64802 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -220,7 +220,6 @@ module.exports = { '@typescript-eslint/non-nullable-type-assertion-style': 'off', '@typescript-eslint/no-implied-eval': 'off', '@typescript-eslint/no-base-to-string': 'off', - '@typescript-eslint/no-duplicate-type-constituents': 'off', '@typescript-eslint/unbound-method': 'off', }, }, diff --git a/packages/api/src/auth/verifiers/common.ts b/packages/api/src/auth/verifiers/common.ts index f2bfc42237e7..3691f42a5a56 100644 --- a/packages/api/src/auth/verifiers/common.ts +++ b/packages/api/src/auth/verifiers/common.ts @@ -33,7 +33,6 @@ export type SupportedVerifiers = | Sha256Verifier | Base64Sha1Verifier | Base64Sha256Verifier - | Sha1Verifier | TimestampSchemeVerifier | JwtVerifier diff --git a/packages/forms/src/coercion.ts b/packages/forms/src/coercion.ts index db6f6828389c..258d21e7f061 100644 --- a/packages/forms/src/coercion.ts +++ b/packages/forms/src/coercion.ts @@ -110,8 +110,7 @@ const SET_VALUE_AS_FUNCTIONS: Record< isValueEmpty(val) ? null : +val, emptyAsUndefined: (val: string): number | undefined => isValueEmpty(val) ? undefined : +val, - emptyAsNaN: (val: string): number | typeof NaN => - isValueEmpty(val) ? NaN : +val, + emptyAsNaN: (val: string): number => (isValueEmpty(val) ? NaN : +val), emptyAsString: (val: string): number | '' => isValueEmpty(val) ? '' : +val, emptyAsZero: (val: string): number => (isValueEmpty(val) ? 0 : +val), From 5ea976d9ac96ad71e09cccd860059708bd0e85b1 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:20:23 +0100 Subject: [PATCH 23/52] chore(lint): enable 'typescript-eslint/no-implied-eval' (#11282) Enables `typescript-eslint/no-implied-eval` and addresses points raised. --- .eslintrc.js | 1 - packages/internal/src/generate/templates.ts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index df2949f64802..cfa36f98cb0f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -218,7 +218,6 @@ module.exports = { '@typescript-eslint/prefer-regexp-exec': 'off', '@typescript-eslint/restrict-template-expressions': 'off', '@typescript-eslint/non-nullable-type-assertion-style': 'off', - '@typescript-eslint/no-implied-eval': 'off', '@typescript-eslint/no-base-to-string': 'off', '@typescript-eslint/unbound-method': 'off', }, diff --git a/packages/internal/src/generate/templates.ts b/packages/internal/src/generate/templates.ts index 5600a655d3cb..b5ec1038252b 100644 --- a/packages/internal/src/generate/templates.ts +++ b/packages/internal/src/generate/templates.ts @@ -23,6 +23,7 @@ export const writeTemplate = ( } const templatized = (template: string, vars = {}) => { + // eslint-disable-next-line @typescript-eslint/no-implied-eval const handler = new Function( 'vars', [ From bbf16c1a3c2eff5c3afae2b9093ade15afd4185f Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:21:11 +0100 Subject: [PATCH 24/52] chore(lint): enable 'typescript-eslint/prefer-string-starts-ends-with' (#11280) Enables the `typescript-eslint/prefer-string-starts-ends-with` rule and fixes issues that resulted. --- .eslintrc.js | 1 - packages/adapters/fastify/web/src/helpers.ts | 4 ++-- .../src/plugins/babel-plugin-redwood-src-alias.ts | 2 +- .../cli/src/commands/setup/monitoring/sentry/sentryHandler.ts | 2 +- packages/forms/src/coercion.ts | 2 +- packages/router/src/router.tsx | 2 +- packages/router/src/rsc/ServerRouter.tsx | 2 +- packages/router/src/util.ts | 4 ++-- packages/structure/src/x/URL.ts | 2 +- 9 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index cfa36f98cb0f..5821dc514ec8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -198,7 +198,6 @@ module.exports = { camelcase: 'off', // TODO(jgmw): Work through these and either keep disabled or fix and re-enable - '@typescript-eslint/prefer-string-starts-ends-with': 'off', '@typescript-eslint/await-thenable': 'off', '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-unsafe-assignment': 'off', diff --git a/packages/adapters/fastify/web/src/helpers.ts b/packages/adapters/fastify/web/src/helpers.ts index 699ea26d9cba..b43579dde332 100644 --- a/packages/adapters/fastify/web/src/helpers.ts +++ b/packages/adapters/fastify/web/src/helpers.ts @@ -1,7 +1,7 @@ /** Ensures that `path` starts and ends with a slash ('/') */ export function coerceRootPath(path: string) { - const prefix = path.charAt(0) !== '/' ? '/' : '' - const suffix = path.charAt(path.length - 1) !== '/' ? '/' : '' + const prefix = !path.startsWith('/') ? '/' : '' + const suffix = !path.endsWith('/') ? '/' : '' return `${prefix}${path}${suffix}` } diff --git a/packages/babel-config/src/plugins/babel-plugin-redwood-src-alias.ts b/packages/babel-config/src/plugins/babel-plugin-redwood-src-alias.ts index 5fe60706f12e..cf241f184820 100644 --- a/packages/babel-config/src/plugins/babel-plugin-redwood-src-alias.ts +++ b/packages/babel-config/src/plugins/babel-plugin-redwood-src-alias.ts @@ -34,7 +34,7 @@ export default function ( if (process.platform === 'win32') { newImport = newImport.replaceAll('\\', '/') } - if (newImport.indexOf('.') !== 0) { + if (!newImport.startsWith('.')) { newImport = './' + newImport } const newSource = t.stringLiteral(newImport) diff --git a/packages/cli/src/commands/setup/monitoring/sentry/sentryHandler.ts b/packages/cli/src/commands/setup/monitoring/sentry/sentryHandler.ts index 16a831e56fc0..9646f757f2ef 100644 --- a/packages/cli/src/commands/setup/monitoring/sentry/sentryHandler.ts +++ b/packages/cli/src/commands/setup/monitoring/sentry/sentryHandler.ts @@ -66,7 +66,7 @@ export const handler = async ({ force }: Args) => { .split('\n') const handlerIndex = contentLines.findLastIndex((line) => - /^export const handler = createGraphQLHandler\({/.test(line), + line.startsWith('export const handler = createGraphQLHandler({'), ) const pluginsIndex = contentLines.findLastIndex((line) => diff --git a/packages/forms/src/coercion.ts b/packages/forms/src/coercion.ts index 258d21e7f061..af1f5f3f251a 100644 --- a/packages/forms/src/coercion.ts +++ b/packages/forms/src/coercion.ts @@ -260,6 +260,6 @@ export const setCoercion = ( valueAs, // type emptyAs, // emptyAs validation.required !== undefined && validation.required !== false, // required - /Id$/.test(name || ''), // isId + (name || '').endsWith('Id'), // isId ) } diff --git a/packages/router/src/router.tsx b/packages/router/src/router.tsx index be1283d0fcc1..041cc2000731 100644 --- a/packages/router/src/router.tsx +++ b/packages/router/src/router.tsx @@ -139,7 +139,7 @@ const LocationAwareRouter: React.FC = ({ let redirectPath: string | undefined = undefined if (redirect) { - if (redirect[0] === '/') { + if (redirect.startsWith('/')) { redirectPath = replaceParams(redirect, allParams) } else { const redirectRouteObject = Object.values(pathRouteMap).find( diff --git a/packages/router/src/rsc/ServerRouter.tsx b/packages/router/src/rsc/ServerRouter.tsx index 4d3e622a7d6d..a483ac0efac5 100644 --- a/packages/router/src/rsc/ServerRouter.tsx +++ b/packages/router/src/rsc/ServerRouter.tsx @@ -93,7 +93,7 @@ export const Router: React.FC = ({ paramTypes, children }) => { let redirectPath: string | undefined = undefined if (redirect) { - if (redirect[0] === '/') { + if (redirect.startsWith('/')) { redirectPath = replaceParams(redirect, allParams) } else { const redirectRouteObject = Object.values(pathRouteMap).find( diff --git a/packages/router/src/util.ts b/packages/router/src/util.ts index 49401af8d301..131a7f05c858 100644 --- a/packages/router/src/util.ts +++ b/packages/router/src/util.ts @@ -38,7 +38,7 @@ export function paramsForRoute(route: string) { // Normalize the name let name = parts[0] - if (name.slice(-3) === '...') { + if (name.endsWith('...')) { // Globs have their ellipsis removed name = name.slice(0, -3) } @@ -47,7 +47,7 @@ export function paramsForRoute(route: string) { let type = parts[1] if (!type) { // Strings and Globs are implicit in the syntax - type = match.slice(-3) === '...' ? 'Glob' : 'String' + type = match.endsWith('...') ? 'Glob' : 'String' } return [name, type, `{${match}}`] diff --git a/packages/structure/src/x/URL.ts b/packages/structure/src/x/URL.ts index e73484c819e6..cca3ebfe13df 100644 --- a/packages/structure/src/x/URL.ts +++ b/packages/structure/src/x/URL.ts @@ -51,7 +51,7 @@ function fileUriToPath(uri: string, sep = path_sep): string { if ( typeof uri !== 'string' || uri.length <= 7 || - uri.substring(0, 7) !== FILE_SCHEME + !uri.startsWith(FILE_SCHEME) ) { throw new TypeError('must pass in a file:// URI to convert to a file path') } From 544e73c0adcc206ea95730b5c83be5b3396abacd Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:55:44 +0100 Subject: [PATCH 25/52] chore(lint): enable 'typescript-eslint/no-unnecessary-type-assertion' (#11284) Enables `typescript-eslint/no-unnecessary-type-assertion` and addresses points raised. --- .eslintrc.js | 1 - packages/api/src/cache/index.ts | 2 +- .../auth-providers/dbAuth/api/src/DbAuthHandler.ts | 6 ++---- .../firebase/web/src/__tests__/firebase.test.tsx | 2 +- .../web/src/__tests__/supertokens.test.tsx | 2 +- packages/babel-config/src/common.ts | 5 +---- .../src/plugins/babel-plugin-redwood-cell.ts | 2 +- ...babel-plugin-redwood-graphql-options-extract.ts | 2 +- .../plugins/babel-plugin-redwood-mock-cell-data.ts | 2 +- .../plugins/babel-plugin-redwood-otel-wrapping.ts | 4 ++-- packages/cli/src/testLib/cells.ts | 4 ++-- packages/codemods/src/lib/cells.ts | 4 ++-- packages/context/src/store.ts | 2 +- .../eslint-plugin/src/service-type-annotations.ts | 2 +- packages/graphql-server/src/globalContextStore.ts | 2 +- .../graphql-server/src/plugins/useRedwoodLogger.ts | 4 ++-- packages/internal/src/ast.ts | 2 +- packages/internal/src/gql.ts | 2 +- packages/prerender/src/babelPlugins/utils.ts | 4 ++-- packages/router/src/util.ts | 7 ++----- packages/structure/src/ide.ts | 2 +- packages/structure/src/model/RWRoute.ts | 14 +++++++------- .../src/model/util/advanced_path_parser.ts | 6 +++--- packages/structure/src/x/URL.ts | 2 +- packages/vite/src/devFeServer.ts | 2 +- packages/vite/src/rsc/rscBuildEntriesFile.ts | 4 ++-- packages/vite/src/rsc/rscStudioHandlers.ts | 2 +- packages/web/src/components/Metadata.tsx | 2 +- .../src/components/cell/createSuspendingCell.tsx | 2 +- packages/web/src/config.ts | 10 +++++----- 30 files changed, 49 insertions(+), 58 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 5821dc514ec8..e5895bea9f25 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -204,7 +204,6 @@ module.exports = { '@typescript-eslint/require-await': 'off', '@typescript-eslint/prefer-nullish-coalescing': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/no-unnecessary-type-assertion': 'off', '@typescript-eslint/dot-notation': 'off', '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-unsafe-return': 'off', diff --git a/packages/api/src/cache/index.ts b/packages/api/src/cache/index.ts index d18f2a550121..7ceef709c6a8 100644 --- a/packages/api/src/cache/index.ts +++ b/packages/api/src/cache/index.ts @@ -191,7 +191,7 @@ export const createCache = ( try { await Promise.race([ - (result = client.del(cacheKey as string)), + (result = client.del(cacheKey)), wait(timeout).then(() => { throw new CacheTimeoutError() }), diff --git a/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts b/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts index 4f9acc8dad2a..678c71ecec5f 100644 --- a/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts +++ b/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts @@ -705,11 +705,9 @@ export class DbAuthHandler< } // check if password is valid using signup criteria - ;(this.options.signup as SignupFlowOptions).passwordValidation?.( - password as string, - ) + ;(this.options.signup as SignupFlowOptions).passwordValidation?.(password) - let user = await this._findUserByToken(resetToken as string) + let user = await this._findUserByToken(resetToken) const [hashedPassword] = hashPassword(password, { salt: user.salt, }) diff --git a/packages/auth-providers/firebase/web/src/__tests__/firebase.test.tsx b/packages/auth-providers/firebase/web/src/__tests__/firebase.test.tsx index e3c2612cffa0..7bda99da7bf9 100644 --- a/packages/auth-providers/firebase/web/src/__tests__/firebase.test.tsx +++ b/packages/auth-providers/firebase/web/src/__tests__/firebase.test.tsx @@ -151,7 +151,7 @@ function getFirebaseAuth(customProviderHooks?: { ) => (rolesToCheck: string | string[]) => boolean }) { const { useAuth, AuthProvider } = createAuth( - firebaseMockClient as FirebaseClient, + firebaseMockClient, customProviderHooks, ) const { result } = renderHook(() => useAuth(), { diff --git a/packages/auth-providers/supertokens/web/src/__tests__/supertokens.test.tsx b/packages/auth-providers/supertokens/web/src/__tests__/supertokens.test.tsx index b7ae0f2362a1..556f0ed3ddf9 100644 --- a/packages/auth-providers/supertokens/web/src/__tests__/supertokens.test.tsx +++ b/packages/auth-providers/supertokens/web/src/__tests__/supertokens.test.tsx @@ -85,7 +85,7 @@ function getSuperTokensAuth(customProviderHooks?: { ) => (rolesToCheck: string | string[]) => boolean }) { const { useAuth, AuthProvider } = createAuth( - superTokensMockClient as SuperTokensAuth, + superTokensMockClient, customProviderHooks, ) const { result } = renderHook(() => useAuth(), { diff --git a/packages/babel-config/src/common.ts b/packages/babel-config/src/common.ts index 6faa74e8bec2..cbd71e4af11e 100644 --- a/packages/babel-config/src/common.ts +++ b/packages/babel-config/src/common.ts @@ -162,10 +162,7 @@ export const getPathsFromTypeScriptConfig = ( continue } const aliasKey = key.replace('/*', '') - const aliasValue = path.join( - absoluteBase, - (value as string)[0].replace('/*', ''), - ) + const aliasValue = path.join(absoluteBase, value[0].replace('/*', '')) pathsObj[aliasKey] = aliasValue } diff --git a/packages/babel-config/src/plugins/babel-plugin-redwood-cell.ts b/packages/babel-config/src/plugins/babel-plugin-redwood-cell.ts index 70e46493c0a2..0f30cc448a95 100644 --- a/packages/babel-config/src/plugins/babel-plugin-redwood-cell.ts +++ b/packages/babel-config/src/plugins/babel-plugin-redwood-cell.ts @@ -55,7 +55,7 @@ export default function ({ types: t }: { types: typeof types }): PluginObj { let name if (declaration.type === 'VariableDeclaration') { const id = declaration.declarations[0].id as types.Identifier - name = id.name as string + name = id.name } if (declaration.type === 'FunctionDeclaration') { name = declaration?.id?.name diff --git a/packages/babel-config/src/plugins/babel-plugin-redwood-graphql-options-extract.ts b/packages/babel-config/src/plugins/babel-plugin-redwood-graphql-options-extract.ts index e35b6ab77c1e..6b0c90bcbde4 100644 --- a/packages/babel-config/src/plugins/babel-plugin-redwood-graphql-options-extract.ts +++ b/packages/babel-config/src/plugins/babel-plugin-redwood-graphql-options-extract.ts @@ -2,7 +2,7 @@ import type { NodePath, PluginObj, PluginPass, types } from '@babel/core' // This extracts the options passed to the graphql function and stores them in an exported variable so they can be imported elsewhere. -const exportVariableName = '__rw_graphqlOptions' as const +const exportVariableName = '__rw_graphqlOptions' function optionsConstNode( t: typeof types, diff --git a/packages/babel-config/src/plugins/babel-plugin-redwood-mock-cell-data.ts b/packages/babel-config/src/plugins/babel-plugin-redwood-mock-cell-data.ts index b6c7add5e967..7b150ff5e009 100644 --- a/packages/babel-config/src/plugins/babel-plugin-redwood-mock-cell-data.ts +++ b/packages/babel-config/src/plugins/babel-plugin-redwood-mock-cell-data.ts @@ -212,7 +212,7 @@ export const getCellMetadata = (p: string) => { const id = declaration.declarations[0].id as types.Identifier namedExports.push({ - name: id.name as string, + name: id.name, type: 'variable', }) } else if (declaration.type === 'FunctionDeclaration') { diff --git a/packages/babel-config/src/plugins/babel-plugin-redwood-otel-wrapping.ts b/packages/babel-config/src/plugins/babel-plugin-redwood-otel-wrapping.ts index 9c307be27cc5..eb4c55825882 100644 --- a/packages/babel-config/src/plugins/babel-plugin-redwood-otel-wrapping.ts +++ b/packages/babel-config/src/plugins/babel-plugin-redwood-otel-wrapping.ts @@ -101,7 +101,7 @@ function wrapExportNamedDeclaration( if (param.type === 'ObjectPattern') { const objectProperties = param.properties.filter( (p) => p.type === 'ObjectProperty', - ) as types.ObjectProperty[] + ) originalFunctionArgumentsWithoutDefaults.push( t.objectExpression( objectProperties.map((p) => { @@ -122,7 +122,7 @@ function wrapExportNamedDeclaration( } else if (param.left.type === 'ObjectPattern') { const objectProperties = param.left.properties.filter( (p) => p.type === 'ObjectProperty', - ) as types.ObjectProperty[] + ) originalFunctionArgumentsWithoutDefaults.push( t.objectExpression( objectProperties.map((p) => { diff --git a/packages/cli/src/testLib/cells.ts b/packages/cli/src/testLib/cells.ts index d83e87d68238..39ecb963721b 100644 --- a/packages/cli/src/testLib/cells.ts +++ b/packages/cli/src/testLib/cells.ts @@ -113,7 +113,7 @@ export const getNamedExports = (ast: types.Node): NamedExports[] => { if (declaration.type === 'VariableDeclaration') { const id = declaration.declarations[0].id as types.Identifier namedExports.push({ - name: id.name as string, + name: id.name, type: 'variable', }) } else if (declaration.type === 'FunctionDeclaration') { @@ -240,7 +240,7 @@ const getFields = (field: FieldNode): any => { node.selectionSet?.selections.forEach((subField) => { switch (subField.kind) { case Kind.FIELD: - obj[field.name.value].push(getFields(subField as FieldNode)) + obj[field.name.value].push(getFields(subField)) break case Kind.FRAGMENT_SPREAD: // TODO: Maybe this will also be needed, right now it's accounted for to not crash in the tests diff --git a/packages/codemods/src/lib/cells.ts b/packages/codemods/src/lib/cells.ts index d83e87d68238..39ecb963721b 100644 --- a/packages/codemods/src/lib/cells.ts +++ b/packages/codemods/src/lib/cells.ts @@ -113,7 +113,7 @@ export const getNamedExports = (ast: types.Node): NamedExports[] => { if (declaration.type === 'VariableDeclaration') { const id = declaration.declarations[0].id as types.Identifier namedExports.push({ - name: id.name as string, + name: id.name, type: 'variable', }) } else if (declaration.type === 'FunctionDeclaration') { @@ -240,7 +240,7 @@ const getFields = (field: FieldNode): any => { node.selectionSet?.selections.forEach((subField) => { switch (subField.kind) { case Kind.FIELD: - obj[field.name.value].push(getFields(subField as FieldNode)) + obj[field.name.value].push(getFields(subField)) break case Kind.FRAGMENT_SPREAD: // TODO: Maybe this will also be needed, right now it's accounted for to not crash in the tests diff --git a/packages/context/src/store.ts b/packages/context/src/store.ts index 2d89a38ef340..934c1b5d5afb 100644 --- a/packages/context/src/store.ts +++ b/packages/context/src/store.ts @@ -13,5 +13,5 @@ export const getAsyncStoreInstance = () => { if (!CONTEXT_STORAGE) { CONTEXT_STORAGE = new AsyncLocalStorage>() } - return CONTEXT_STORAGE as AsyncLocalStorage> + return CONTEXT_STORAGE } diff --git a/packages/eslint-plugin/src/service-type-annotations.ts b/packages/eslint-plugin/src/service-type-annotations.ts index 9ba5dccd7ebc..ebdad06975a3 100644 --- a/packages/eslint-plugin/src/service-type-annotations.ts +++ b/packages/eslint-plugin/src/service-type-annotations.ts @@ -74,7 +74,7 @@ export const serviceTypeAnnotations = createRule({ } // Switch from the estree type to the typescript-eslint type - const tsID = vd.id as TSESTree.Identifier + const tsID = vd.id // If there's no type annotation, then we should add one if (!tsID.typeAnnotation) { diff --git a/packages/graphql-server/src/globalContextStore.ts b/packages/graphql-server/src/globalContextStore.ts index 445cc190cd37..5a4ed89e1bb2 100644 --- a/packages/graphql-server/src/globalContextStore.ts +++ b/packages/graphql-server/src/globalContextStore.ts @@ -13,5 +13,5 @@ export const getAsyncStoreInstance = () => { if (!CONTEXT_STORAGE) { CONTEXT_STORAGE = new AsyncLocalStorage>() } - return CONTEXT_STORAGE as AsyncLocalStorage> + return CONTEXT_STORAGE } diff --git a/packages/graphql-server/src/plugins/useRedwoodLogger.ts b/packages/graphql-server/src/plugins/useRedwoodLogger.ts index 5a4515bae928..0da21edc1311 100644 --- a/packages/graphql-server/src/plugins/useRedwoodLogger.ts +++ b/packages/graphql-server/src/plugins/useRedwoodLogger.ts @@ -219,7 +219,7 @@ export const useRedwoodLogger = ( }) }, onParse({ params }) { - const options = params.options as any + const options = params.options const envelopLogger = childLogger.child({ ...options, @@ -232,7 +232,7 @@ export const useRedwoodLogger = ( } }, onValidate({ params }) { - const options = params.options as any + const options = params.options const envelopLogger = childLogger.child({ ...options, diff --git a/packages/internal/src/ast.ts b/packages/internal/src/ast.ts index feb0c5b73553..4affeaa38b8f 100644 --- a/packages/internal/src/ast.ts +++ b/packages/internal/src/ast.ts @@ -79,7 +79,7 @@ export const getNamedExports = (ast: types.Node): NamedExports[] => { if (declaration.type === 'VariableDeclaration') { const id = declaration.declarations[0].id as types.Identifier namedExports.push({ - name: id.name as string, + name: id.name, type: 'variable', location: { line: id.loc?.start.line ?? 1, diff --git a/packages/internal/src/gql.ts b/packages/internal/src/gql.ts index 922903b2d803..647141767f62 100644 --- a/packages/internal/src/gql.ts +++ b/packages/internal/src/gql.ts @@ -62,7 +62,7 @@ const getFields = (field: FieldNode): any => { node.selectionSet?.selections.forEach((subField) => { switch (subField.kind) { case Kind.FIELD: - obj[field.name.value].push(getFields(subField as FieldNode)) + obj[field.name.value].push(getFields(subField)) break case Kind.FRAGMENT_SPREAD: // TODO: Maybe this will also be needed, right now it's accounted for to not crash in the tests diff --git a/packages/prerender/src/babelPlugins/utils.ts b/packages/prerender/src/babelPlugins/utils.ts index 21b868a71470..58f31f107166 100644 --- a/packages/prerender/src/babelPlugins/utils.ts +++ b/packages/prerender/src/babelPlugins/utils.ts @@ -8,8 +8,8 @@ import mime from 'mime-types' // Not sure if possible in actually running builds export function convertToDataUrl(assetPath: string) { try { - const base64AssetContents = fs.readFileSync(assetPath as string, 'base64') - const mimeType = mime.lookup(assetPath as string) + const base64AssetContents = fs.readFileSync(assetPath, 'base64') + const mimeType = mime.lookup(assetPath) return `data:${mimeType};base64,${base64AssetContents}` } catch { console.warn(`Could not read file ${assetPath} for conversion to data uri`) diff --git a/packages/router/src/util.ts b/packages/router/src/util.ts index 131a7f05c858..29974a0f90a0 100644 --- a/packages/router/src/util.ts +++ b/packages/router/src/util.ts @@ -83,8 +83,6 @@ const coreParamTypes: Record = { }, } -type SupportedRouterParamTypes = keyof typeof coreParamTypes - /** * Determine if the given route is a match for the given pathname. If so, * extract any named params and return them in an object. @@ -145,8 +143,7 @@ export function matchPath( const params = providedParams.reduce>( (acc, value, index) => { const [name, transformName] = routeParamsDefinition[index] - const typeInfo = - allParamTypes[transformName as SupportedRouterParamTypes] + const typeInfo = allParamTypes[transformName] let transformedValue: string | unknown = value if (typeof typeInfo?.parse === 'function') { @@ -192,7 +189,7 @@ export function getRouteRegexAndParams( // /recipe/{id} -> /recipe/([^/$1*]+) for (const [_name, type, match] of routeParams) { // `undefined` matcher if `type` is not supported - const matcher = allParamTypes[type as SupportedRouterParamTypes]?.match + const matcher = allParamTypes[type]?.match // Get the regex as a string, or default regexp if `match` is not specified const typeRegexp = matcher?.source || '[^/]+' diff --git a/packages/structure/src/ide.ts b/packages/structure/src/ide.ts index d4757b186c9d..d481a0fadd1c 100644 --- a/packages/structure/src/ide.ts +++ b/packages/structure/src/ide.ts @@ -265,7 +265,7 @@ export abstract class FileNode extends BaseNode { if (typeof this.text === 'undefined') { throw new Error('undefined file ' + this.filePath) } - return createTSMSourceFile_cached(this.filePath, this.text!) + return createTSMSourceFile_cached(this.filePath, this.text) } @lazy() get basenameNoExt() { return basenameNoExt(this.filePath) diff --git a/packages/structure/src/model/RWRoute.ts b/packages/structure/src/model/RWRoute.ts index 4cf1cc59c5f9..ca547ad9f234 100644 --- a/packages/structure/src/model/RWRoute.ts +++ b/packages/structure/src/model/RWRoute.ts @@ -67,7 +67,7 @@ export class RWRoute extends BaseNode { } if (tsm.Node.isJsxAttribute(a)) { const init = a.getInitializer() - if (tsm.Node.isStringLiteral(init!)) { + if (tsm.Node.isStringLiteral(init)) { return init.getLiteralValue() } } @@ -189,9 +189,9 @@ export class RWRoute extends BaseNode { } if (tsm.Node.isJsxAttribute(a)) { const init = a.getInitializer() - if (tsm.Node.isJsxExpression(init!)) { + if (tsm.Node.isJsxExpression(init)) { const expr = init.getExpression() - if (tsm.Node.isIdentifier(expr!)) { + if (tsm.Node.isIdentifier(expr)) { return expr } } @@ -236,7 +236,7 @@ export class RWRoute extends BaseNode { } if (tsm.Node.isJsxAttribute(a)) { const init = a.getInitializer() - if (tsm.Node.isStringLiteral(init!)) { + if (tsm.Node.isStringLiteral(init)) { return init } } @@ -269,7 +269,7 @@ export class RWRoute extends BaseNode { } if (this.isPrivate && this.isNotFound) { yield err( - this.jsxNode!, + this.jsxNode, "The 'Not Found' page cannot be within a or a tag", ) } @@ -369,7 +369,7 @@ export class RWRoute extends BaseNode { // If it is explicitly set to true // e.g. return tsm.Node.isTrueLiteral(init.getExpression()) - } else if (tsm.Node.isStringLiteral(init!)) { + } else if (tsm.Node.isStringLiteral(init)) { // If its using the incorrect string form, we're accepting it as true // e.g. const literalValue = init.getLiteralValue() @@ -387,7 +387,7 @@ export class RWRoute extends BaseNode { } if (tsm.Node.isJsxAttribute(a)) { const init = a.getInitializer() - if (tsm.Node.isStringLiteral(init!)) { + if (tsm.Node.isStringLiteral(init)) { return init.getLiteralValue() } } diff --git a/packages/structure/src/model/util/advanced_path_parser.ts b/packages/structure/src/model/util/advanced_path_parser.ts index 130e05428f06..25f38cda6601 100644 --- a/packages/structure/src/model/util/advanced_path_parser.ts +++ b/packages/structure/src/model/util/advanced_path_parser.ts @@ -8,14 +8,14 @@ export function advanced_path_parser(route: string) { const paramTypeRanges: [number, number][] = [] for (const param of route.matchAll(/\{([^}]+)\}/g)) { const [paramName, paramType] = param[1].split(':') - const index = param.index! + 1 + const index = param.index + 1 paramRanges.push([index, index + paramName.length]) if (paramType) { const typeIndex = index + paramName.length + 2 paramTypeRanges.push([typeIndex, typeIndex + paramType.length]) } } - const punctuationIndexes = [...route.matchAll(/[{}:]/g)].map((x) => x.index!) - const slashIndexes = [...route.matchAll(/[\/]/g)].map((x) => x.index!) + const punctuationIndexes = [...route.matchAll(/[{}:]/g)].map((x) => x.index) + const slashIndexes = [...route.matchAll(/[\/]/g)].map((x) => x.index) return { punctuationIndexes, slashIndexes, paramRanges, paramTypeRanges } } diff --git a/packages/structure/src/x/URL.ts b/packages/structure/src/x/URL.ts index cca3ebfe13df..70398b30e8e5 100644 --- a/packages/structure/src/x/URL.ts +++ b/packages/structure/src/x/URL.ts @@ -33,7 +33,7 @@ export function URL_toFile(uriOrFilePath: string, sep = path_sep): string { if (!isAbsolute(p)) { throw new Error('absolute path expected: ' + p) } - return p! + return p } const FILE_SCHEME = 'file://' diff --git a/packages/vite/src/devFeServer.ts b/packages/vite/src/devFeServer.ts index 4db8ce24184e..e309d343d647 100644 --- a/packages/vite/src/devFeServer.ts +++ b/packages/vite/src/devFeServer.ts @@ -145,7 +145,7 @@ async function createServer() { const routeHandler = await createReactStreamingHandler( { routes, - clientEntryPath: rwPaths.web.entryClient as string, + clientEntryPath: rwPaths.web.entryClient, getStylesheetLinks: (route) => { // In dev route is a RouteSpec, with additional properties return getCssLinks({ rwPaths, route: route as RouteSpec, vite }) diff --git a/packages/vite/src/rsc/rscBuildEntriesFile.ts b/packages/vite/src/rsc/rscBuildEntriesFile.ts index d45fa540f793..ca379fd8df12 100644 --- a/packages/vite/src/rsc/rscBuildEntriesFile.ts +++ b/packages/vite/src/rsc/rscBuildEntriesFile.ts @@ -40,7 +40,7 @@ export async function rscBuildEntriesMappings( serverBuildOutput.find( (item) => 'moduleIds' in item && - item.moduleIds.includes(clientEntryFiles[name] as string), + item.moduleIds.includes(clientEntryFiles[name]), )?.fileName if (entryFile) { @@ -68,7 +68,7 @@ export async function rscBuildEntriesMappings( serverBuildOutput.find( (item) => 'moduleIds' in item && - item.moduleIds.includes(clientEntryFiles[name] as string), + item.moduleIds.includes(clientEntryFiles[name]), )?.fileName if (entryFile) { diff --git a/packages/vite/src/rsc/rscStudioHandlers.ts b/packages/vite/src/rsc/rscStudioHandlers.ts index 7629d73304a6..aeff1a9657cc 100644 --- a/packages/vite/src/rsc/rscStudioHandlers.ts +++ b/packages/vite/src/rsc/rscStudioHandlers.ts @@ -47,7 +47,7 @@ const processRenderRscStream = async ( pipeable.on('end', () => { const resultBuffer = Buffer.concat(chunks) - const resultString = resultBuffer.toString('utf-8') as string + const resultString = resultBuffer.toString('utf-8') resolve(resultString) }) diff --git a/packages/web/src/components/Metadata.tsx b/packages/web/src/components/Metadata.tsx index f33c75f85279..5ca4862ad546 100644 --- a/packages/web/src/components/Metadata.tsx +++ b/packages/web/src/components/Metadata.tsx @@ -36,7 +36,7 @@ const propToMetaTag = ( // plain text const attributes = { [options['attr']]: parentKey, - content: parentValue as string, + content: parentValue, } return } diff --git a/packages/web/src/components/cell/createSuspendingCell.tsx b/packages/web/src/components/cell/createSuspendingCell.tsx index cc38242cdcae..b854c31bfd38 100644 --- a/packages/web/src/components/cell/createSuspendingCell.tsx +++ b/packages/web/src/components/cell/createSuspendingCell.tsx @@ -55,7 +55,7 @@ export function createSuspendingCell< function SuspendingSuccess(props: SuspendingSuccessProps) { const { queryRef, suspenseQueryResult, userProps } = props const { data, networkStatus } = useReadQuery(queryRef) - const afterQueryData = afterQuery(data as DataObject) + const afterQueryData = afterQuery(data) const queryResultWithNetworkStatus: SuspenseCellQueryResult = { ...suspenseQueryResult, diff --git a/packages/web/src/config.ts b/packages/web/src/config.ts index 59d21de33d80..4454eca72244 100644 --- a/packages/web/src/config.ts +++ b/packages/web/src/config.ts @@ -6,8 +6,8 @@ // console.log('config.ts', RWJS_ENV) // console.log('config.ts') -globalThis.RWJS_API_GRAPHQL_URL = RWJS_ENV.RWJS_API_GRAPHQL_URL as string -globalThis.RWJS_API_URL = RWJS_ENV.RWJS_API_URL as string -globalThis.__REDWOOD__APP_TITLE = RWJS_ENV.__REDWOOD__APP_TITLE as string -globalThis.RWJS_EXP_STREAMING_SSR = RWJS_ENV.RWJS_EXP_STREAMING_SSR as boolean -globalThis.RWJS_EXP_RSC = RWJS_ENV.RWJS_EXP_RSC as boolean +globalThis.RWJS_API_GRAPHQL_URL = RWJS_ENV.RWJS_API_GRAPHQL_URL +globalThis.RWJS_API_URL = RWJS_ENV.RWJS_API_URL +globalThis.__REDWOOD__APP_TITLE = RWJS_ENV.__REDWOOD__APP_TITLE +globalThis.RWJS_EXP_STREAMING_SSR = RWJS_ENV.RWJS_EXP_STREAMING_SSR +globalThis.RWJS_EXP_RSC = RWJS_ENV.RWJS_EXP_RSC From 593aa27fbf366e23cdb3a7516b0bcb7b8fd0fd2c Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:56:26 +0100 Subject: [PATCH 26/52] chore(lint): first refactoring towards enabling 'require-await' rule (#11279) We will look to enable the `typescript-eslint/require-await` rule in the future. Currently we have many issues flagged when we do. This is the first work to refactor to correct issues related to that rule. For now I'm focusing on tests so that we can be sure none of this is user facing. The changes here are mostly just removing unneeded `async` keywords. --- packages/api-server/src/__tests__/api.test.ts | 4 +- .../requestHandlers/awsLambdaFastify.test.ts | 54 ++++++++------ .../getAuthenticationContext.test.ts | 71 ++++++++----------- packages/api/src/logger/logger.test.ts | 2 +- packages/internal/src/__tests__/ast.test.ts | 2 +- .../internal/src/__tests__/resolverFn.test.ts | 2 +- .../validateSchemaForReservedNames.test.ts | 35 ++++----- .../ogimage-gen/src/OgImageMiddleware.test.ts | 2 +- .../__tests__/useRedwoodRealtime.test.ts | 2 +- .../src/model/__tests__/model.test.ts | 14 ++-- .../__tests__/process_env_diagnostics.test.ts | 2 +- .../structure/src/x/__tests__/URL.test.ts | 8 +-- .../structure/src/x/__tests__/prisma.test.ts | 2 +- .../vscode-languageserver-types-x.test.ts | 6 +- .../middleware/createMiddlewareRouter.test.ts | 2 +- packages/vite/src/middleware/register.test.ts | 2 +- .../__tests__/vite-plugin-rsc-analyze.test.ts | 6 +- .../vite-plugin-rsc-route-auto-loader.test.ts | 2 +- .../src/components/cell/createCell.test.tsx | 40 +++++------ .../cell/createSuspendingCell.test.tsx | 6 +- 20 files changed, 124 insertions(+), 140 deletions(-) diff --git a/packages/api-server/src/__tests__/api.test.ts b/packages/api-server/src/__tests__/api.test.ts index f21faf1c9640..89c5322dd193 100644 --- a/packages/api-server/src/__tests__/api.test.ts +++ b/packages/api-server/src/__tests__/api.test.ts @@ -41,7 +41,7 @@ afterAll(async () => { }) describe('redwoodFastifyAPI', () => { - it('configures the `@fastify/url-data` and `fastify-raw-body` plugins', async () => { + it('configures the `@fastify/url-data` and `fastify-raw-body` plugins', () => { const plugins = fastifyInstance.printPlugins() expect(plugins.includes('@fastify/url-data')).toEqual(true) @@ -62,7 +62,7 @@ describe('redwoodFastifyAPI', () => { // // We can use `printRoutes` with a method for debugging, but not without one. // See https://fastify.dev/docs/latest/Reference/Server#printroutes - it('builds a tree of routes for GET and POST', async () => { + it('builds a tree of routes for GET and POST', () => { expect(fastifyInstance.printRoutes({ method: 'GET' })) .toMatchInlineSnapshot(` "└── / diff --git a/packages/api-server/src/__tests__/requestHandlers/awsLambdaFastify.test.ts b/packages/api-server/src/__tests__/requestHandlers/awsLambdaFastify.test.ts index 92c869559260..1efd280d3b41 100644 --- a/packages/api-server/src/__tests__/requestHandlers/awsLambdaFastify.test.ts +++ b/packages/api-server/src/__tests__/requestHandlers/awsLambdaFastify.test.ts @@ -35,9 +35,11 @@ describe('Tests AWS Lambda to Fastify request transformation and handling', () = vi.spyOn(mockedReply, 'status') const handler: Handler = async () => { - return { - body: { foo: 'bar' }, - } + return new Promise((resolve) => { + resolve({ + body: { foo: 'bar' }, + }) + }) } await requestHandler(request, mockedReply, handler) @@ -51,10 +53,12 @@ describe('Tests AWS Lambda to Fastify request transformation and handling', () = vi.spyOn(mockedReply, 'status') const handler: Handler = async () => { - return { - body: 'this_is_a_test_of_base64Encoding', - isBase64Encoded: true, - } + return new Promise((resolve) => { + resolve({ + body: 'this_is_a_test_of_base64Encoding', + isBase64Encoded: true, + }) + }) } await requestHandler(request, mockedReply, handler) @@ -81,7 +85,9 @@ describe('Tests AWS Lambda to Fastify request transformation and handling', () = vi.spyOn(mockedReply, 'status') const handler = async () => { - throw new Error('error') + return new Promise((_resolve, reject) => { + reject(new Error('error')) + }) } await requestHandler(request, mockedReply, handler) @@ -106,13 +112,15 @@ describe('Tests AWS Lambda to Fastify request transformation and handling', () = vi.spyOn(mockedReply, 'header') const handler: Handler = async () => { - return { - body: { foo: 'bar' }, - headers: { - 'content-type': 'application/json', - authorization: 'Bearer token 123', - }, - } + return new Promise((resolve) => { + resolve({ + body: { foo: 'bar' }, + headers: { + 'content-type': 'application/json', + authorization: 'Bearer token 123', + }, + }) + }) } await requestHandler(headersRequest, mockedReply, handler) @@ -144,13 +152,15 @@ describe('Tests AWS Lambda to Fastify request transformation and handling', () = vi.spyOn(mockedReply, 'header') const handler: Handler = async () => { - return { - body: {}, - headers: {}, - multiValueHeaders: { - 'content-type': ['application/json', 'text/html'], - }, - } + return new Promise((resolve) => { + resolve({ + body: {}, + headers: {}, + multiValueHeaders: { + 'content-type': ['application/json', 'text/html'], + }, + }) + }) } await requestHandler(headersRequest, mockedReply, handler) diff --git a/packages/api/src/auth/__tests__/getAuthenticationContext.test.ts b/packages/api/src/auth/__tests__/getAuthenticationContext.test.ts index d4ac85b63375..4c1373651d78 100644 --- a/packages/api/src/auth/__tests__/getAuthenticationContext.test.ts +++ b/packages/api/src/auth/__tests__/getAuthenticationContext.test.ts @@ -1,6 +1,7 @@ import type { APIGatewayProxyEvent, Context } from 'aws-lambda' import { describe, it, expect } from 'vitest' +import type { Decoded } from '../index' import { getAuthenticationContext } from '../index' export const createMockedEvent = ( @@ -52,18 +53,20 @@ export const createMockedEvent = ( } describe('getAuthenticationContext with bearer tokens', () => { - it('Can take a single auth decoder for the given provider', async () => { - const authDecoderOne = async (_token: string, type: string) => { + const authDecoderOne = async (_token: string, type: string) => { + return new Promise((resolve) => { if (type !== 'one') { - return null + return resolve(null) } - return { + return resolve({ iss: 'one', sub: 'user-id', - } - } + }) + }) + } + it('Can take a single auth decoder for the given provider', async () => { const result = await getAuthenticationContext({ authDecoder: authDecoderOne, event: createMockedEvent({ @@ -89,17 +92,6 @@ describe('getAuthenticationContext with bearer tokens', () => { }) it('Can take a single auth decoder for some other provider', async () => { - const authDecoderOne = async (_token: string, type: string) => { - if (type !== 'one') { - return null - } - - return { - iss: 'one', - sub: 'user-id', - } - } - const result = await getAuthenticationContext({ authDecoder: authDecoderOne, event: createMockedEvent({ @@ -144,26 +136,17 @@ describe('getAuthenticationContext with bearer tokens', () => { }) it('Can take an array of auth decoders', async () => { - const authDecoderOne = async (_token: string, type: string) => { - if (type !== 'one') { - return null - } - - return { - iss: 'one', - sub: 'user-id', - } - } - const authDecoderTwo = async (_token: string, type: string) => { - if (type !== 'two') { - return null - } - - return { - iss: 'two', - sub: 'user-id', - } + return new Promise((resolve) => { + if (type !== 'two') { + return resolve(null) + } + + return resolve({ + iss: 'two', + sub: 'user-id', + }) + }) } const result = await getAuthenticationContext({ @@ -214,14 +197,16 @@ describe('getAuthenticationContext with bearer tokens', () => { describe('getAuthenticationContext with cookies', () => { const authDecoderOne = async (_token: string, type: string) => { - if (type !== 'one') { - return null - } + return new Promise((resolve) => { + if (type !== 'one') { + return resolve(null) + } - return { - iss: 'one', - sub: 'user-id', - } + return resolve({ + iss: 'one', + sub: 'user-id', + }) + }) } it('Can take a single auth decoder for the given provider', async () => { diff --git a/packages/api/src/logger/logger.test.ts b/packages/api/src/logger/logger.test.ts index dbc6025e8063..06b701f5076c 100644 --- a/packages/api/src/logger/logger.test.ts +++ b/packages/api/src/logger/logger.test.ts @@ -90,7 +90,7 @@ const setupLogger = ( describe('logger', () => { describe('creates a logger without options', () => { - test('it logs a trace message', async () => { + test('it logs a trace message', () => { const logger = createLogger({}) expect(logger).toBeDefined() diff --git a/packages/internal/src/__tests__/ast.test.ts b/packages/internal/src/__tests__/ast.test.ts index b68b255993d1..3daa8dd81a63 100644 --- a/packages/internal/src/__tests__/ast.test.ts +++ b/packages/internal/src/__tests__/ast.test.ts @@ -10,7 +10,7 @@ import { fileToAst, } from '../ast' -vi.mock('@redwoodjs/project-config', async () => { +vi.mock('@redwoodjs/project-config', () => { const baseFixturePath = path.join(__dirname, 'fixtures') return { getPaths: () => ({ diff --git a/packages/internal/src/__tests__/resolverFn.test.ts b/packages/internal/src/__tests__/resolverFn.test.ts index c6fcb3543310..5bc099e27629 100644 --- a/packages/internal/src/__tests__/resolverFn.test.ts +++ b/packages/internal/src/__tests__/resolverFn.test.ts @@ -72,7 +72,7 @@ describe('ResovlerFn types', () => { `) }) - it('ResolverFn uses non-optional function args in strict mode', async () => { + it('ResolverFn uses non-optional function args in strict mode', () => { // Prertend project is strict mode mockedTSConfigs = { api: { diff --git a/packages/internal/src/__tests__/validateSchemaForReservedNames.test.ts b/packages/internal/src/__tests__/validateSchemaForReservedNames.test.ts index 408d83577009..0197922d95fa 100644 --- a/packages/internal/src/__tests__/validateSchemaForReservedNames.test.ts +++ b/packages/internal/src/__tests__/validateSchemaForReservedNames.test.ts @@ -1,6 +1,5 @@ import path from 'path' -import type { DocumentNode } from 'graphql' import gql from 'graphql-tag' import { beforeAll, afterAll, describe, test, expect } from 'vitest' @@ -18,13 +17,9 @@ afterAll(() => { delete process.env.RWJS_CWD }) -const validateSdlFile = async (document: DocumentNode) => { - validateSchema(document) -} - describe('SDL with no reserved names used', () => { describe('SDL is valid', () => { - test('with proper type definition names', async () => { + test('with proper type definition names', () => { const document = gql` type Message { from: String @@ -46,9 +41,9 @@ describe('SDL with no reserved names used', () => { } ` - await expect(validateSdlFile(document)).resolves.not.toThrowError() + expect(() => validateSchema(document)).not.toThrowError() }) - test('with proper interface interface definition names', async () => { + test('with proper interface interface definition names', () => { const document = gql` interface Node { id: ID! @@ -64,9 +59,9 @@ describe('SDL with no reserved names used', () => { room(id: ID!): [Message!]! @skipAuth } ` - await expect(validateSdlFile(document)).resolves.not.toThrowError() + expect(() => validateSchema(document)).not.toThrowError() }) - test('with proper interface input type definition names', async () => { + test('with proper interface input type definition names', () => { const document = gql` type Message { from: String @@ -87,12 +82,12 @@ describe('SDL with no reserved names used', () => { sendMessage(input: SendMessageInput!): Message! @skipAuth } ` - await expect(validateSdlFile(document)).resolves.not.toThrowError() + expect(() => validateSchema(document)).not.toThrowError() }) }) describe('SDL is invalid', () => { - test('because uses a reserved name as a type', async () => { + test('because uses a reserved name as a type', () => { const document = gql` type Float { from: String @@ -113,13 +108,11 @@ describe('SDL with no reserved names used', () => { sendMessage(input: SendMessageInput!): Message! @skipAuth } ` - await expect( - validateSdlFile(document), - ).rejects.toThrowErrorMatchingSnapshot() + expect(() => validateSchema(document)).toThrowErrorMatchingSnapshot() }) }) - test('because uses a reserved name as an input', async () => { + test('because uses a reserved name as an input', () => { const document = gql` type Message { from: String @@ -140,12 +133,10 @@ describe('SDL with no reserved names used', () => { sendMessage(input: SendMessageInput!): Message! @skipAuth } ` - await expect( - validateSdlFile(document), - ).rejects.toThrowErrorMatchingSnapshot() + expect(() => validateSchema(document)).toThrowErrorMatchingSnapshot() }) - test('because uses a reserved name as an interface', async () => { + test('because uses a reserved name as an interface', () => { const document = gql` interface Float { id: ID! @@ -171,8 +162,6 @@ describe('SDL with no reserved names used', () => { sendMessage(input: SendMessageInput!): Message! @skipAuth } ` - await expect( - validateSdlFile(document), - ).rejects.toThrowErrorMatchingSnapshot() + expect(() => validateSchema(document)).toThrowErrorMatchingSnapshot() }) }) diff --git a/packages/ogimage-gen/src/OgImageMiddleware.test.ts b/packages/ogimage-gen/src/OgImageMiddleware.test.ts index 7d3106827578..6aa197a6be58 100644 --- a/packages/ogimage-gen/src/OgImageMiddleware.test.ts +++ b/packages/ogimage-gen/src/OgImageMiddleware.test.ts @@ -139,7 +139,7 @@ describe('OgImageMiddleware', () => { expect(result).toEqual(passthroughRes) }) - test('getOgComponentPath should return the correct OG image file path', async () => { + test('getOgComponentPath should return the correct OG image file path', () => { const commonRouteInfo = { name: 'contact', bundle: 'assets/ContactPage-DjZx8IRT.js', diff --git a/packages/realtime/src/graphql/plugins/__tests__/useRedwoodRealtime.test.ts b/packages/realtime/src/graphql/plugins/__tests__/useRedwoodRealtime.test.ts index 5933c14ab3ea..2325746a683d 100644 --- a/packages/realtime/src/graphql/plugins/__tests__/useRedwoodRealtime.test.ts +++ b/packages/realtime/src/graphql/plugins/__tests__/useRedwoodRealtime.test.ts @@ -35,7 +35,7 @@ describe('useRedwoodRealtime', () => { `) }) - it('should update schema with live directive', async () => { + it('should update schema with live directive', () => { const spiedPlugin = createSpiedPlugin() // the original schema should not have the live directive before the useRedwoodRealtime plugin is applied diff --git a/packages/structure/src/model/__tests__/model.test.ts b/packages/structure/src/model/__tests__/model.test.ts index 7b5376771df0..a08568e8e024 100644 --- a/packages/structure/src/model/__tests__/model.test.ts +++ b/packages/structure/src/model/__tests__/model.test.ts @@ -100,7 +100,7 @@ describe('Cells', () => { }) describe('Redwood Page detection', () => { - it('detects pages', async () => { + it('detects pages', () => { const projectRoot = getFixtureDir('example-todo-main') const project = new RWProject({ projectRoot, host: new DefaultHost() }) const routes = project.getRouter().routes @@ -122,7 +122,7 @@ describe('Redwood Page detection', () => { }) describe('Redwood Route detection', () => { - it('detects the page identifier for a route', async () => { + it('detects the page identifier for a route', () => { const projectRoot = getFixtureDir('example-todo-main') const project = new RWProject({ projectRoot, host: new DefaultHost() }) const routes = project.getRouter().routes @@ -132,7 +132,7 @@ describe('Redwood Route detection', () => { expect(pageIdentifiers.length).toBe(9) expect(pageIdentifiers).toMatchSnapshot() }) - it('detects routes with the prerender prop', async () => { + it('detects routes with the prerender prop', () => { const projectRoot = getFixtureDir('example-todo-main') const project = new RWProject({ projectRoot, host: new DefaultHost() }) const routes = project.getRouter().routes @@ -160,7 +160,7 @@ describe('Redwood Route detection', () => { path: '/private-page', }) }) - it('detects authenticated routes', async () => { + it('detects authenticated routes', () => { const projectRoot = getFixtureDir('example-todo-main') const project = new RWProject({ projectRoot, host: new DefaultHost() }) const routes = project.getRouter().routes @@ -177,7 +177,7 @@ describe('Redwood Route detection', () => { expect(authenticatedRoutes.length).toBe(3) }) - it('detects name and path for an authenticated route', async () => { + it('detects name and path for an authenticated route', () => { const projectRoot = getFixtureDir('example-todo-main') const project = new RWProject({ projectRoot, host: new DefaultHost() }) const routes = project.getRouter().routes @@ -198,7 +198,7 @@ describe('Redwood Route detection', () => { expect(authenticatedRoutes[1].roles).toContain('admin') }) - it('detects roles for an authenticated route when roles is a string of a single role', async () => { + it('detects roles for an authenticated route when roles is a string of a single role', () => { const projectRoot = getFixtureDir('example-todo-main') const project = new RWProject({ projectRoot, host: new DefaultHost() }) const routes = project.getRouter().routes @@ -219,7 +219,7 @@ describe('Redwood Route detection', () => { expect(authenticatedRoutes[1].roles).toContain('admin') }) - it('detects roles for an authenticated route when roles is an array of a roles', async () => { + it('detects roles for an authenticated route when roles is an array of a roles', () => { const projectRoot = getFixtureDir('example-todo-main') const project = new RWProject({ projectRoot, host: new DefaultHost() }) const routes = project.getRouter().routes diff --git a/packages/structure/src/model/util/__tests__/process_env_diagnostics.test.ts b/packages/structure/src/model/util/__tests__/process_env_diagnostics.test.ts index cf999a359f3e..9a4726854844 100644 --- a/packages/structure/src/model/util/__tests__/process_env_diagnostics.test.ts +++ b/packages/structure/src/model/util/__tests__/process_env_diagnostics.test.ts @@ -36,7 +36,7 @@ describe('process_env_findInFile', () => { expect(r.length).toEqual(0) }) - test('process_env_findAll', async () => { + test('process_env_findAll', () => { const pp = getFixtureDir('example-todo-main-with-errors') //const webRoot = join(pp, 'web') const apiRoot = join(pp, 'api') diff --git a/packages/structure/src/x/__tests__/URL.test.ts b/packages/structure/src/x/__tests__/URL.test.ts index 79eb8c90efcd..29c11a365592 100644 --- a/packages/structure/src/x/__tests__/URL.test.ts +++ b/packages/structure/src/x/__tests__/URL.test.ts @@ -5,23 +5,23 @@ import { describe, it, expect } from 'vitest' import { URL_file, URL_toFile } from '../URL' describe('URL_fromFile', () => { - it('works for windows style paths', async () => { + it('works for windows style paths', () => { expect(URL_file(`\\a\\b.c`)).toEqual('file:///a/b.c') expect(URL_file(`\\a\\b.c`)).toEqual('file:///a/b.c') expect(URL_file(`C:\\a`, `b.c`)).toEqual('file:///C:/a/b.c') }) - it('works for linux style paths', async () => { + it('works for linux style paths', () => { expect(URL_file(`/a/b.c`)).toEqual('file:///a/b.c') expect(URL_file(`/a`, 'b.c')).toEqual('file:///a/b.c') }) - it('works with file:// URLs', async () => { + it('works with file:// URLs', () => { expect(URL_file('file:///a/b.c')).toEqual('file:///a/b.c') expect(URL_file(`file:///a`, 'b.c')).toEqual('file:///a/b.c') }) }) describe('URL_toFile', () => { - it('works', async () => { + it('works', () => { const res = `${sep}a${sep}b.c` expect(URL_toFile(`/a/b.c`)).toEqual(res) expect(URL_toFile(`file:///a/b.c`)).toEqual(res) diff --git a/packages/structure/src/x/__tests__/prisma.test.ts b/packages/structure/src/x/__tests__/prisma.test.ts index 68818eb7366d..1bbfc7308610 100644 --- a/packages/structure/src/x/__tests__/prisma.test.ts +++ b/packages/structure/src/x/__tests__/prisma.test.ts @@ -4,7 +4,7 @@ import { Range } from 'vscode-languageserver' import { prisma_parseEnvExpressions } from '../prisma' describe('prisma_parseEnvExpressions', () => { - it('can find env() expressions in a prisma schema', async () => { + it('can find env() expressions in a prisma schema', () => { const [r] = Array.from(prisma_parseEnvExpressions(`env("foo") `)) const range = Range.create(0, 0, 0, 10) expect(r).toEqual({ range, key: 'foo' }) diff --git a/packages/structure/src/x/__tests__/vscode-languageserver-types-x.test.ts b/packages/structure/src/x/__tests__/vscode-languageserver-types-x.test.ts index 349fe80e2fcb..3c76d026fec6 100644 --- a/packages/structure/src/x/__tests__/vscode-languageserver-types-x.test.ts +++ b/packages/structure/src/x/__tests__/vscode-languageserver-types-x.test.ts @@ -14,7 +14,7 @@ import { } from '../vscode-languageserver-types' describe('Position_compare', () => { - it('', async () => { + it('', () => { x(0, 0, 0, 0, 'equal') x(0, 0, 0, 1, 'smaller') @@ -35,7 +35,7 @@ describe('Position_compare', () => { }) describe('Range_contains', () => { - it('', async () => { + it('', () => { const r = Range.create(0, 1, 0, 3) x(r, 0, 0, false) x(r, 0, 1, true) @@ -49,7 +49,7 @@ describe('Range_contains', () => { }) describe('ExtendedDiagnostic_format', () => { - it('can format diagnostics', async () => { + it('can format diagnostics', () => { const d: ExtendedDiagnostic = { uri: 'file:///path/to/app/b.ts', diagnostic: { diff --git a/packages/vite/src/middleware/createMiddlewareRouter.test.ts b/packages/vite/src/middleware/createMiddlewareRouter.test.ts index 610d90f03333..bfa4be12f141 100644 --- a/packages/vite/src/middleware/createMiddlewareRouter.test.ts +++ b/packages/vite/src/middleware/createMiddlewareRouter.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import { createMiddlewareRouter } from './register' -vi.mock('@redwoodjs/project-config', async () => { +vi.mock('@redwoodjs/project-config', () => { const mockWin32Paths = { web: { base: 'C:\\proj\\web', diff --git a/packages/vite/src/middleware/register.test.ts b/packages/vite/src/middleware/register.test.ts index e59a3a3e5836..7a35fc105734 100644 --- a/packages/vite/src/middleware/register.test.ts +++ b/packages/vite/src/middleware/register.test.ts @@ -22,7 +22,7 @@ class FakeClassMw implements MiddlewareClass { this.value = value } - async invoke(_req: MiddlewareRequest, res: MiddlewareResponse) { + invoke(_req: MiddlewareRequest, res: MiddlewareResponse) { res.body = 'MW initialized with ' + this.value res.headers.set('class-mw-value', this.value.toString()) return res diff --git a/packages/vite/src/plugins/__tests__/vite-plugin-rsc-analyze.test.ts b/packages/vite/src/plugins/__tests__/vite-plugin-rsc-analyze.test.ts index a0c87468443d..e1007c2b6a4d 100644 --- a/packages/vite/src/plugins/__tests__/vite-plugin-rsc-analyze.test.ts +++ b/packages/vite/src/plugins/__tests__/vite-plugin-rsc-analyze.test.ts @@ -59,7 +59,7 @@ describe('vite-plugin-rsc-analyze', () => { export default ServerDelayForm; ` - pluginTransform(code, 'test.tsx') + await pluginTransform(code, 'test.tsx') expect(foundFiles).toHaveLength(1) expect(foundFiles[0]).toEqual('test.tsx') @@ -94,7 +94,7 @@ describe('vite-plugin-rsc-analyze', () => { export default ServerDelayForm; ` - pluginTransform(code, 'test.tsx') + await pluginTransform(code, 'test.tsx') expect(foundFiles).toHaveLength(1) expect(foundFiles[0]).toEqual('test.tsx') @@ -130,7 +130,7 @@ describe('vite-plugin-rsc-analyze', () => { export default ServerDelayForm; ` - pluginTransform(code, 'test.tsx') + await pluginTransform(code, 'test.tsx') expect(foundFiles).toHaveLength(1) expect(foundFiles[0]).toEqual('test.tsx') diff --git a/packages/vite/src/plugins/__tests__/vite-plugin-rsc-route-auto-loader.test.ts b/packages/vite/src/plugins/__tests__/vite-plugin-rsc-route-auto-loader.test.ts index 40c7a0253f19..14fb0b7ebfcb 100644 --- a/packages/vite/src/plugins/__tests__/vite-plugin-rsc-route-auto-loader.test.ts +++ b/packages/vite/src/plugins/__tests__/vite-plugin-rsc-route-auto-loader.test.ts @@ -290,7 +290,7 @@ describe('rscRoutesAutoLoader', () => { `) }) - it('should throw for duplicate page import names', async () => { + it('should throw for duplicate page import names', () => { vi.mocked(processPagesDir).mockReturnValue(pagesWithDuplicate) const getOutput = async () => { diff --git a/packages/web/src/components/cell/createCell.test.tsx b/packages/web/src/components/cell/createCell.test.tsx index 64c9824fa9bf..9644b900bcc3 100644 --- a/packages/web/src/components/cell/createCell.test.tsx +++ b/packages/web/src/components/cell/createCell.test.tsx @@ -14,7 +14,7 @@ describe('createCell', () => { } }) - test('Renders a static Success component', async () => { + test('Renders a static Success component', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -31,7 +31,7 @@ describe('createCell', () => { screen.getByText(/^Great success!$/) }) - test('Renders Success with data', async () => { + test('Renders Success with data', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -59,7 +59,7 @@ describe('createCell', () => { screen.getByText(/^42$/) }) - test('Renders Success if any of the fields have data (i.e. not just the first)', async () => { + test('Renders Success if any of the fields have data (i.e. not just the first)', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { users { name } posts { title } }', @@ -111,7 +111,7 @@ describe('createCell', () => { screen.getByText(/kittens/) }) - test('Renders default Loading when there is no data', async () => { + test('Renders default Loading when there is no data', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -128,7 +128,7 @@ describe('createCell', () => { screen.getByText(/^Loading...$/) }) - test('Renders custom Loading when there is no data', async () => { + test('Renders custom Loading when there is no data', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -146,7 +146,7 @@ describe('createCell', () => { screen.getByText(/^Fetching answer...$/) }) - test('Renders Success even when `loading` is true if there is data', async () => { + test('Renders Success even when `loading` is true if there is data', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -164,7 +164,7 @@ describe('createCell', () => { screen.getByText(/^Great success!$/) }) - test('Renders Empty if available, and data field is null', async () => { + test('Renders Empty if available, and data field is null', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -182,7 +182,7 @@ describe('createCell', () => { screen.getByText(/^No one knows$/) }) - test('Renders Empty if available, and data field is an empty array', async () => { + test('Renders Empty if available, and data field is an empty array', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answers }', @@ -200,7 +200,7 @@ describe('createCell', () => { screen.getByText(/^No one knows$/) }) - test('Renders Success even if data is empty when no Empty is available', async () => { + test('Renders Success even if data is empty when no Empty is available', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -217,7 +217,7 @@ describe('createCell', () => { screen.getByText(/^Empty success$/) }) - test('Allows passing children to Success', async () => { + test('Allows passing children to Success', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -237,7 +237,7 @@ describe('createCell', () => { screen.getByText(/^🦆$/) }) - test('Cell props are passed to the query as variables', async () => { + test('Cell props are passed to the query as variables', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: `query Greet($name: String!) { @@ -261,7 +261,7 @@ describe('createCell', () => { screen.getByText(/^Hello Bob!$/) }) - test('Allows QUERY to be a function', async () => { + test('Allows QUERY to be a function', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: ({ variables }) => { @@ -295,7 +295,7 @@ describe('createCell', () => { screen.getByText(/^Call me Lara Croft$/) }) - test('Renders Failure when there is an error', async () => { + test('Renders Failure when there is an error', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -314,7 +314,7 @@ describe('createCell', () => { screen.getByText(/^Sad face :\($/) }) - test('Passes error to Failure component', async () => { + test('Passes error to Failure component', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -333,7 +333,7 @@ describe('createCell', () => { screen.getByText(/^{"msg":"System malfunction"}$/) }) - test('Passes error and errorCode to Failure component', async () => { + test('Passes error and errorCode to Failure component', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -359,7 +359,7 @@ describe('createCell', () => { screen.getByText(/^{"msg":"System malfunction"},code:SIMON_SAYS_NO$/) }) - test('Passes children to Failure', async () => { + test('Passes children to Failure', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -379,7 +379,7 @@ describe('createCell', () => { screen.getByText(/^Child$/) }) - test('Throws an error when there is an error if no Failure component exists', async () => { + test('Throws an error when there is an error if no Failure component exists', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -410,7 +410,7 @@ describe('createCell', () => { console.error = err }) - test('Allows overriding of default isDataEmpty', async () => { + test('Allows overriding of default isDataEmpty', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -433,7 +433,7 @@ describe('createCell', () => { screen.getByText(/^Got nothing$/) }) - test('Allows mixing isDataEmpty with custom logic', async () => { + test('Allows mixing isDataEmpty with custom logic', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -457,7 +457,7 @@ describe('createCell', () => { screen.getByText(/^Got nothing$/) }) - test('Allows overriding variables in beforeQuery', async () => { + test('Allows overriding variables in beforeQuery', () => { const TestCell = createCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: `query Greet($name: String!) { diff --git a/packages/web/src/components/cell/createSuspendingCell.test.tsx b/packages/web/src/components/cell/createSuspendingCell.test.tsx index f59b4f27f793..33fb6d25a4d0 100644 --- a/packages/web/src/components/cell/createSuspendingCell.test.tsx +++ b/packages/web/src/components/cell/createSuspendingCell.test.tsx @@ -37,7 +37,7 @@ describe('createSuspendingCell', () => { const mockedQueryHook = () => ({ data: {} }) - test('Renders a static Success component', async () => { + test('Renders a static Success component', () => { const TestCell = createSuspendingCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -55,7 +55,7 @@ describe('createSuspendingCell', () => { screen.getByText(/^Great success!$/) }) - test('Renders Success with data', async () => { + test('Renders Success with data', () => { const TestCell = createSuspendingCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { answer }', @@ -86,7 +86,7 @@ describe('createSuspendingCell', () => { screen.getByText(/^42$/) }) - test('Renders Success if any of the fields have data (i.e. not just the first)', async () => { + test('Renders Success if any of the fields have data (i.e. not just the first)', () => { const TestCell = createSuspendingCell({ // @ts-expect-error - Purposefully using a plain string here. QUERY: 'query TestQuery { users { name } posts { title } }', From 59a68892bd2c071ef1e75c0cfda627b511f608a2 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 03:10:15 +0100 Subject: [PATCH 27/52] chore(lint): enable 'typescript-eslint/prefer-optional-chain' (#11285) Enables `typescript-eslint/prefer-optional-chain` and addressed issues raised. --- .eslintrc.js | 1 - packages/api/src/auth/index.ts | 2 +- packages/api/src/cors.ts | 2 +- .../auth-providers/auth0/web/src/auth0.ts | 7 ++- .../dbAuth/api/src/DbAuthHandler.ts | 11 ++-- .../src/__tests__/setupDataMockDMMF.test.ts | 2 +- .../tsconfigForRouteHooks.ts | 2 +- packages/forms/src/FormError.tsx | 2 +- .../src/__tests__/makeMergedSchema.test.ts | 52 +++++++++---------- .../internal/src/generate/trustedDocuments.ts | 4 +- ...-plugin-redwood-prerender-media-imports.ts | 2 +- .../src/graphql/plugins/useRedwoodRealtime.ts | 2 +- packages/router/src/a11yUtils.ts | 3 +- packages/vite/src/devFeServer.ts | 2 +- .../vite/src/lib/registerFwGlobalsAndShims.ts | 4 +- packages/vite/src/middleware/register.test.ts | 2 +- .../react-server-dom-webpack/node-loader.ts | 2 +- .../web/src/components/DevFatalErrorPage.tsx | 4 +- 18 files changed, 46 insertions(+), 60 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index e5895bea9f25..141ab8799e24 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -207,7 +207,6 @@ module.exports = { '@typescript-eslint/dot-notation': 'off', '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-unsafe-return': 'off', - '@typescript-eslint/prefer-optional-chain': 'off', '@typescript-eslint/prefer-promise-reject-errors': 'off', '@typescript-eslint/no-redundant-type-constituents': 'off', '@typescript-eslint/restrict-plus-operands': 'off', diff --git a/packages/api/src/auth/index.ts b/packages/api/src/auth/index.ts index 8fa386f1bfe9..7cd9bc98ea40 100644 --- a/packages/api/src/auth/index.ts +++ b/packages/api/src/auth/index.ts @@ -131,7 +131,7 @@ export const getAuthenticationContext = async ({ // There can be cases, such as with Supabase where its auth client sets the cookie and Bearer token // but the project is not using cookie auth with an auth-provider cookie set // So, cookie/ssr auth needs both the token and the auth-provider in cookies - if (cookieHeader && cookieHeader.type) { + if (cookieHeader?.type) { token = cookieHeader.rawCookie type = cookieHeader.type schema = 'cookie' diff --git a/packages/api/src/cors.ts b/packages/api/src/cors.ts index 6ab493845367..45b5ab1b0e30 100644 --- a/packages/api/src/cors.ts +++ b/packages/api/src/cors.ts @@ -66,7 +66,7 @@ export function createCorsContext(cors: CorsConfig | undefined) { const eventHeaders = new Headers(request.headers as HeadersInit) const requestCorsHeaders = new Headers(corsHeaders) - if (cors && cors.origin) { + if (cors?.origin) { const requestOrigin = eventHeaders.get('origin') if (typeof cors.origin === 'string') { requestCorsHeaders.set('access-control-allow-origin', cors.origin) diff --git a/packages/auth-providers/auth0/web/src/auth0.ts b/packages/auth-providers/auth0/web/src/auth0.ts index 5735b9d8a02d..7b62719da9dd 100644 --- a/packages/auth-providers/auth0/web/src/auth0.ts +++ b/packages/auth-providers/auth0/web/src/auth0.ts @@ -35,10 +35,9 @@ function createAuthImplementation(auth0Client: Auth0Client) { global?.location?.search?.includes('state=') ) { const { appState } = await auth0Client.handleRedirectCallback() - const url = - appState && appState.targetUrl - ? appState.targetUrl - : window.location.pathname + const url = appState?.targetUrl + ? appState.targetUrl + : window.location.pathname global?.location?.assign(url) } }, diff --git a/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts b/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts index 678c71ecec5f..6ae12b18d5a4 100644 --- a/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts +++ b/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts @@ -665,10 +665,7 @@ export class DbAuthHandler< dbUser, ) - if ( - handlerUser == null || - handlerUser[this.options.authFields.id] == null - ) { + if (handlerUser?.[this.options.authFields.id] == null) { throw new DbAuthError.NoUserIdError() } @@ -813,7 +810,7 @@ export class DbAuthHandler< throw new DbAuthError.WebAuthnError('Missing Id in request') } - if (!webAuthnOptions || !webAuthnOptions.enabled) { + if (!webAuthnOptions?.enabled) { throw new DbAuthError.WebAuthnError('WebAuthn is not enabled') } @@ -899,7 +896,7 @@ export class DbAuthHandler< '@simplewebauthn/server' ) - if (this.options.webAuthn === undefined || !this.options.webAuthn.enabled) { + if (!this.options.webAuthn?.enabled) { throw new DbAuthError.WebAuthnError('WebAuthn is not enabled') } @@ -1013,7 +1010,7 @@ export class DbAuthHandler< '@simplewebauthn/server' ) - if (this.options.webAuthn === undefined || !this.options.webAuthn.enabled) { + if (!this.options.webAuthn?.enabled) { throw new DbAuthError.WebAuthnError('WebAuthn is not enabled') } diff --git a/packages/auth-providers/dbAuth/setup/src/__tests__/setupDataMockDMMF.test.ts b/packages/auth-providers/dbAuth/setup/src/__tests__/setupDataMockDMMF.test.ts index 79b88940df0a..84c06cce5faa 100644 --- a/packages/auth-providers/dbAuth/setup/src/__tests__/setupDataMockDMMF.test.ts +++ b/packages/auth-providers/dbAuth/setup/src/__tests__/setupDataMockDMMF.test.ts @@ -54,7 +54,7 @@ jest.mock('@redwoodjs/cli-helpers', () => { } for (const task of args.extraTasks) { - if (task && task.task) { + if (task?.task) { await task.task(ctx, undefined) } } diff --git a/packages/codemods/src/codemods/v2.3.x/tsconfigForRouteHooks/tsconfigForRouteHooks.ts b/packages/codemods/src/codemods/v2.3.x/tsconfigForRouteHooks/tsconfigForRouteHooks.ts index dafa47a5335a..a28cd2bf18f3 100644 --- a/packages/codemods/src/codemods/v2.3.x/tsconfigForRouteHooks/tsconfigForRouteHooks.ts +++ b/packages/codemods/src/codemods/v2.3.x/tsconfigForRouteHooks/tsconfigForRouteHooks.ts @@ -24,7 +24,7 @@ export default async function addApiAliasToTsConfig() { ts.sys.readFile(webConfigPath) as string, // If file exists, it has contents ) - if (webConfig && webConfig?.compilerOptions) { + if (webConfig?.compilerOptions) { const newPathAliases = { ...webConfig.compilerOptions.paths, '$api/*': ['../api/*'], diff --git a/packages/forms/src/FormError.tsx b/packages/forms/src/FormError.tsx index ef3e210d5f3a..2776f63b64ad 100644 --- a/packages/forms/src/FormError.tsx +++ b/packages/forms/src/FormError.tsx @@ -71,7 +71,7 @@ const FormError = ({ 'properties' ] as RwGqlErrorProperties - const propertyMessages = properties && properties['messages'] + const propertyMessages = properties?.['messages'] if (propertyMessages) { for (const e in propertyMessages) { diff --git a/packages/graphql-server/src/__tests__/makeMergedSchema.test.ts b/packages/graphql-server/src/__tests__/makeMergedSchema.test.ts index 66d40b124b0c..5dcdd5c9b16b 100644 --- a/packages/graphql-server/src/__tests__/makeMergedSchema.test.ts +++ b/packages/graphql-server/src/__tests__/makeMergedSchema.test.ts @@ -149,25 +149,23 @@ describe('makeMergedSchema', () => { it('Resolver functions are mapped correctly.', () => { expect( - queryFields.inResolver.resolve && - queryFields.inResolver.resolve( - null, - {}, - null, - {} as GraphQLResolveInfo, - ), + queryFields.inResolver.resolve?.( + null, + {}, + null, + {} as GraphQLResolveInfo, + ), ).toEqual("I'm defined in the resolver.") }) it('Resolver functions take preference over service functions.', () => { expect( - queryFields.inResolverAndServices.resolve && - queryFields.inResolverAndServices.resolve( - null, - {}, - null, - {} as GraphQLResolveInfo, - ), + queryFields.inResolverAndServices.resolve?.( + null, + {}, + null, + {} as GraphQLResolveInfo, + ), ).toEqual("I'm defined in the resolver.") }) @@ -190,25 +188,23 @@ describe('makeMergedSchema', () => { it('Resolver functions are mapped correctly', () => { expect( - myOwnTypeFields.inTypeResolverAndServices.resolve && - myOwnTypeFields.inTypeResolverAndServices.resolve( - null, - {}, - null, - {} as GraphQLResolveInfo, - ), + myOwnTypeFields.inTypeResolverAndServices.resolve?.( + null, + {}, + null, + {} as GraphQLResolveInfo, + ), ).toEqual("MyOwnType: I'm defined in the resolver.") }) it('Resolver functions take preference over service functions.', () => { expect( - myOwnTypeFields.inTypeResolver.resolve && - myOwnTypeFields.inTypeResolver.resolve( - null, - {}, - null, - {} as GraphQLResolveInfo, - ), + myOwnTypeFields.inTypeResolver.resolve?.( + null, + {}, + null, + {} as GraphQLResolveInfo, + ), ).toEqual("MyOwnType: I'm defined in the resolver.") }) diff --git a/packages/internal/src/generate/trustedDocuments.ts b/packages/internal/src/generate/trustedDocuments.ts index dfbdd58a6e17..6f47c6c07d03 100644 --- a/packages/internal/src/generate/trustedDocuments.ts +++ b/packages/internal/src/generate/trustedDocuments.ts @@ -17,7 +17,7 @@ export const trustedDocumentsStore = async (generatedFiles: any) => { const storeFile = output[0] - if (storeFile && storeFile.content) { + if (storeFile?.content) { const content = await format(`export const store = ${storeFile.content}`, { trailingComma: 'es5', bracketSpacing: true, @@ -51,7 +51,7 @@ export const replaceGqlTagWithTrustedDocumentGraphql = async ( const gqlFile = gqlFileOutput[0] - if (gqlFile && gqlFile.content) { + if (gqlFile?.content) { gqlFile.content += `\n export function gql(source: string | TemplateStringsArray) { if (typeof source === 'string') { diff --git a/packages/prerender/src/babelPlugins/babel-plugin-redwood-prerender-media-imports.ts b/packages/prerender/src/babelPlugins/babel-plugin-redwood-prerender-media-imports.ts index c8e06788f26c..fa4962898d9c 100644 --- a/packages/prerender/src/babelPlugins/babel-plugin-redwood-prerender-media-imports.ts +++ b/packages/prerender/src/babelPlugins/babel-plugin-redwood-prerender-media-imports.ts @@ -32,7 +32,7 @@ const defaultOptions = { type ViteManifest = Record function getVariableName(p: NodePath) { - if (p.node.specifiers?.[0] && p.node.specifiers[0].local) { + if (p.node.specifiers?.[0]?.local) { return p.node.specifiers[0].local.name } return null diff --git a/packages/realtime/src/graphql/plugins/useRedwoodRealtime.ts b/packages/realtime/src/graphql/plugins/useRedwoodRealtime.ts index 9924bd80ed60..27bdc1801e98 100644 --- a/packages/realtime/src/graphql/plugins/useRedwoodRealtime.ts +++ b/packages/realtime/src/graphql/plugins/useRedwoodRealtime.ts @@ -167,7 +167,7 @@ export const useRedwoodRealtime = (options: RedwoodRealtimeOptions): Plugin => { */ const wasLiveQueryAdded = Symbol.for('useRedwoodRealtime.wasLiveQueryAdded') - if (options.liveQueries && options.liveQueries.store) { + if (options.liveQueries?.store) { if (options.liveQueries.store === 'in-memory') { liveQueriesEnabled = true diff --git a/packages/router/src/a11yUtils.ts b/packages/router/src/a11yUtils.ts index 40113030555b..184ce1628435 100644 --- a/packages/router/src/a11yUtils.ts +++ b/packages/router/src/a11yUtils.ts @@ -34,8 +34,7 @@ export const getFocus = () => { )?.[0] if ( - !routeFocus || - !routeFocus.children.length || + !routeFocus?.children.length || (routeFocus.children[0] as HTMLElement).tabIndex < 0 ) { return null diff --git a/packages/vite/src/devFeServer.ts b/packages/vite/src/devFeServer.ts index e309d343d647..5ba891491215 100644 --- a/packages/vite/src/devFeServer.ts +++ b/packages/vite/src/devFeServer.ts @@ -194,7 +194,7 @@ function getCssLinks({ vite: ViteDevServer }) { const appAndRouteModules = componentsModules( - [rwPaths.web.app, route && route.filePath].filter(Boolean) as string[], + [rwPaths.web.app, route?.filePath].filter(Boolean) as string[], vite, ) diff --git a/packages/vite/src/lib/registerFwGlobalsAndShims.ts b/packages/vite/src/lib/registerFwGlobalsAndShims.ts index eec59c07d57b..86bbc60ed663 100644 --- a/packages/vite/src/lib/registerFwGlobalsAndShims.ts +++ b/packages/vite/src/lib/registerFwGlobalsAndShims.ts @@ -26,9 +26,7 @@ function registerFwGlobals() { rwConfig.web.apiGraphQLUrl ?? rwConfig.web.apiUrl + '/graphql', RWJS_API_URL: rwConfig.web.apiUrl, __REDWOOD__APP_TITLE: rwConfig.web.title || path.basename(rwPaths.base), - RWJS_EXP_STREAMING_SSR: - rwConfig.experimental.streamingSsr && - rwConfig.experimental.streamingSsr.enabled, + RWJS_EXP_STREAMING_SSR: rwConfig.experimental.streamingSsr?.enabled, RWJS_EXP_RSC: rwConfig.experimental?.rsc?.enabled, RWJS_EXP_SSR_GRAPHQL_ENDPOINT: (() => { const apiPath = diff --git a/packages/vite/src/middleware/register.test.ts b/packages/vite/src/middleware/register.test.ts index 7a35fc105734..8f6cf69350ba 100644 --- a/packages/vite/src/middleware/register.test.ts +++ b/packages/vite/src/middleware/register.test.ts @@ -95,7 +95,7 @@ describe('groupByRoutePatterns', () => { exampleRequest, new MiddlewareResponse(), ) - expect((firstOutput || {}).body).toBe('MW initialized with 1') + expect(firstOutput?.body).toBe('MW initialized with 1') const secondOutput = await output['/second-path'][0]?.( exampleRequest, diff --git a/packages/vite/src/react-server-dom-webpack/node-loader.ts b/packages/vite/src/react-server-dom-webpack/node-loader.ts index c3be42ca319e..8bd0671dc628 100644 --- a/packages/vite/src/react-server-dom-webpack/node-loader.ts +++ b/packages/vite/src/react-server-dom-webpack/node-loader.ts @@ -351,7 +351,7 @@ async function transformClientModule( ([_key, value]) => value === url, ) - if (!entryRecord || !entryRecord[0]) { + if (!entryRecord?.[0]) { throw new Error('Entry not found for ' + url) } diff --git a/packages/web/src/components/DevFatalErrorPage.tsx b/packages/web/src/components/DevFatalErrorPage.tsx index 4b7ef8ca57d7..9370cd9a4de5 100644 --- a/packages/web/src/components/DevFatalErrorPage.tsx +++ b/packages/web/src/components/DevFatalErrorPage.tsx @@ -57,9 +57,7 @@ export const DevFatalErrorPage = (props: { error?: ErrorWithRequestMeta }) => { const stack = new StackTracey(err).withSources() const typeName = String( - (err as any)['type'] || - (err.constructor && err.constructor.name) || - typeof err, + (err as any)['type'] || err.constructor?.name || typeof err, ) const msg = String(err && err.message) From 3eea78f6d2f5b77e081f9f49625686b702f743c1 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 03:14:57 +0100 Subject: [PATCH 28/52] chore(formatting): include .changesets dir in prettier config (#11286) As title. --- .changesets/10064.md | 3 +- .changesets/10179.md | 2 +- .changesets/10266.md | 3 +- .changesets/10342.md | 1 - .changesets/10344.md | 1 + .changesets/10395.md | 18 ++++++---- .changesets/10420.md | 6 +--- .changesets/10441.md | 6 ++-- .changesets/10444.md | 3 +- .changesets/10453.md | 4 +-- .changesets/10457.md | 38 ++++++++++---------- .changesets/10460.md | 11 +++--- .changesets/10464.md | 8 ++--- .changesets/10465.md | 8 ++--- .changesets/10469.md | 48 +++++++++++++------------ .changesets/10493.md | 3 +- .changesets/10498.md | 2 -- .changesets/10499.md | 14 ++++---- .changesets/10502.md | 2 +- .changesets/10520.md | 2 +- .changesets/10522.md | 2 +- .changesets/10538.md | 1 + .changesets/10542.md | 2 +- .changesets/10570.md | 2 +- .changesets/10585.md | 8 ++--- .changesets/10586.md | 4 +-- .changesets/10656.md | 5 +-- .changesets/10668.md | 4 ++- .changesets/10677.md | 1 + .changesets/10680.md | 8 ++--- .changesets/10697.md | 7 ++-- .changesets/10702.md | 2 +- .changesets/10768.md | 1 + .changesets/10817.md | 4 +-- .changesets/10825.md | 7 ++-- .changesets/10830.md | 2 +- .changesets/10833.md | 2 +- .changesets/10865.md | 2 +- .changesets/10867.md | 1 + .changesets/10869.md | 14 ++++---- .changesets/10888.md | 2 +- .changesets/10893.md | 2 +- .changesets/10900.md | 2 +- .changesets/10911.md | 58 +++++++++++++++---------------- .changesets/10961.md | 2 +- .changesets/11062.md | 2 +- .changesets/11072.md | 2 +- .changesets/11108.md | 10 ++---- .changesets/11109.md | 3 +- .changesets/11135.md | 2 +- .changesets/11170.md | 7 ++-- .changesets/11189.md | 1 + .changesets/young-spiders-ring.md | 2 +- .prettierignore | 1 - 54 files changed, 183 insertions(+), 175 deletions(-) diff --git a/.changesets/10064.md b/.changesets/10064.md index 785c49a2ec24..286624f3e066 100644 --- a/.changesets/10064.md +++ b/.changesets/10064.md @@ -1,7 +1,8 @@ - Add Storybook (Vite) framework package (#10064) by @arimendelow Adds: + - Storybook framework package for using Storybook with Vite. - CLI package (command: `yarn rw sbv`) for running Storybook using Vite. CLI package additionally creates Mock Service Worker, and, on first run, the project-side Storybook config files. -Current Storybook (Webpack) users will need to manually migrate any additional Storybook config (mocks, etc.). The primary user-facing difference between the old and new Storybook integrations is that the config used by the old one lives in the `@redwoodjs/testing` package, and the config used by this new one lives in the user's `web/.storybook` directory. \ No newline at end of file +Current Storybook (Webpack) users will need to manually migrate any additional Storybook config (mocks, etc.). The primary user-facing difference between the old and new Storybook integrations is that the config used by the old one lives in the `@redwoodjs/testing` package, and the config used by this new one lives in the user's `web/.storybook` directory. diff --git a/.changesets/10179.md b/.changesets/10179.md index 6cae15af6c5f..ffd8f9b7aaa7 100644 --- a/.changesets/10179.md +++ b/.changesets/10179.md @@ -5,7 +5,7 @@ This PR upgrades Redwood internally to Prettier v3. We believe this won't have a If you have Tailwind CSS configured, can upgrade `prettier-plugin-tailwindcss` to a version later than `0.4.1` if you make a few changes: - Change `prettier.config.js` to `prettier.config.mjs` (js -> mjs) -- `export default` instead of `module.exports` +- `export default` instead of `module.exports` - `await import('...')` any plugins instead of `require('...')` Here's an example of an updated `prettier.config.mjs` to work with `prettier-plugin-tailwindcss@^0.5.12`: diff --git a/.changesets/10266.md b/.changesets/10266.md index 1201549dc6bd..5556caf2e2f6 100644 --- a/.changesets/10266.md +++ b/.changesets/10266.md @@ -1,6 +1,5 @@ - chore(linting): Update versions and avoid `{}` (#10266) by @Josh-Walker-GM -This PR updates the versions of the `eslint` and the `@typescript-eslint` packages from v5 to v7. +This PR updates the versions of the `eslint` and the `@typescript-eslint` packages from v5 to v7. This is a major upgrade of the `@typescript-eslint` package and although we think it is unlikely to introduce a breaking change for you we would recommend that you read the associated documentation. The v6 upgrade can be found [here](https://typescript-eslint.io/blog/announcing-typescript-eslint-v6/) and the v7 one [here](https://typescript-eslint.io/blog/announcing-typescript-eslint-v7/). - diff --git a/.changesets/10342.md b/.changesets/10342.md index 9a2dffd923f2..5179cd5e797e 100644 --- a/.changesets/10342.md +++ b/.changesets/10342.md @@ -23,7 +23,6 @@ The `` above would get the following classes if it was the active link That same `` now only gets the `activeClassName` classes `active inline-block rounded-t-lg border-b-2 border-blue-600 p-4 text-blue-600 dark:border-blue-500 dark:text-blue-500` - ## Breaking If you were relying on the merging behavior you will now have to copy all classes from `className` and also include them in `activeClassName`. diff --git a/.changesets/10344.md b/.changesets/10344.md index bd41152c0142..277035ccfdb0 100644 --- a/.changesets/10344.md +++ b/.changesets/10344.md @@ -5,6 +5,7 @@ Add intellisense and color support for not only `className` (which is enabled by ## Manual Instructions If you already have TW set up and want to enable this, open `.vscode/settings.json` and add this: + ```json "tailwindCSS": { "classAttributes": ["class", "className", "activeClassName", "errorClassName"] diff --git a/.changesets/10395.md b/.changesets/10395.md index 4b0bbaf2ffd7..fbb0c98be5a3 100644 --- a/.changesets/10395.md +++ b/.changesets/10395.md @@ -1,22 +1,24 @@ - Middleware Routing & `registerMiddleware` (#10395) by @dac09 -Implements the new syntax of using Middleware after discussion. This sets us up for doing Auth better, but also for implementations like OG Image generation. +Implements the new syntax of using Middleware after discussion. This sets us up for doing Auth better, but also for implementations like OG Image generation. ```js export const registerMiddleware = async () => { - return [ - dbAuthMiddleware(), - [new OgMiddleware({ rootFilename: 'index' }), [ '/:route.:extension']] - ] + return [ + dbAuthMiddleware(), + [new OgMiddleware({ rootFilename: 'index' }), ['/:route.:extension']], + ] } ``` **Features** + - [x] Registering middleware with above syntax - [x] Chaining multiple middleware by passing array of middleware, or tuples - [x] Defining the route patterns to match in the find-my-way syntax ---- +--- + **What syntax are you using for the route patterns?** After discussion that Regexes are slow and unwieldy, I did some research and comparisons here: https://www.notion.so/redwoodjs/Middleware-Route-patterns-0f1c5587b4134073adfae896a782b5ea?pvs= @@ -24,11 +26,13 @@ This implementation uses https://github.com/delvedor/find-my-way - which is the **Important for understanding** Quoting from find-my-way docs: + > The nodes are matched in the following order: + static parametric node with static ending parametric(regex)/multi-parametric parametric wildcard -Which means, if you have a more specific one - example you have `[mw1, `*`]` and `[mw2, '/refresh_auth']` - then a request to /refresh_auth will ONLY trigger mw2. This is sort of counter intuitive, but them are the rules with fmw. +Which means, if you have a more specific one - example you have `[mw1, `\*`]` and `[mw2, '/refresh_auth']` - then a request to /refresh_auth will ONLY trigger mw2. This is sort of counter intuitive, but them are the rules with fmw. diff --git a/.changesets/10420.md b/.changesets/10420.md index 58c60cddc8c1..75481c745124 100644 --- a/.changesets/10420.md +++ b/.changesets/10420.md @@ -1,4 +1,4 @@ -- feat: [Auth] Common AuthProvider & use* changes for middleware auth #10420 by @dac09 and @dthyresson +- feat: [Auth] Common AuthProvider & use\* changes for middleware auth #10420 by @dac09 and @dthyresson * First step of supporting Auth using middleware * Ensure backwards compatibility with non-SSR auth @@ -6,7 +6,3 @@ ### Breaking Change Removes `skipFetchCurrentUser` which was used by the no longer existing nHost auth provider, but could potentially have been used by custom auth. - - - - diff --git a/.changesets/10441.md b/.changesets/10441.md index de04d1ae4272..66869280a58c 100644 --- a/.changesets/10441.md +++ b/.changesets/10441.md @@ -1,10 +1,10 @@ - feat(og-gen): Update implementation of useLocation | Update App template (#10441) by @dac09 -**Updated App.tsx template** -We modified the `App.tsx` template to accept possible children, and render them if present. This lets the og:image handler inject your component into the Document tree, without including the entire Router, but still style your og:image component using whatever you used to style the rest of your app (Tailwind, perhaps?) + **Updated App.tsx template** + We modified the `App.tsx` template to accept possible children, and render them if present. This lets the og:image handler inject your component into the Document tree, without including the entire Router, but still style your og:image component using whatever you used to style the rest of your app (Tailwind, perhaps?) **Updated useLocation implementation** We also modified the `useLocation()` hook to now return everything that the [URL API](https://developer.mozilla.org/en-US/docs/Web/API/URL) returns. Previously it only returned three attributes of the url (pathname, search, hash), now it returns everything available to a call to `new URL()` (origin, href, searchParams, etc.). The reason for this is now that we have SSR, we can get access to more details in the hook - in this case we needed origin -Both changes should be non-breaking! +Both changes should be non-breaking! diff --git a/.changesets/10444.md b/.changesets/10444.md index eb3f6aee2016..0e13368a17c0 100644 --- a/.changesets/10444.md +++ b/.changesets/10444.md @@ -1,4 +1,5 @@ - feat(server-auth): Part 1/3: dbAuth middleware support (web side changes) (#10444) by @dac09 -Adds ability to `createMiddlewareAuth` in dbAuth client which: + Adds ability to `createMiddlewareAuth` in dbAuth client which: + 1. Updates the dbAuth web client to speak to middleware instead of graphql 2. Implements fetching current user from middleware diff --git a/.changesets/10453.md b/.changesets/10453.md index 42f3da15e1cb..54ff985037dc 100644 --- a/.changesets/10453.md +++ b/.changesets/10453.md @@ -1,5 +1,5 @@ - feat: Remove `--performance` option from `yarn rw build` (#10453) by @Josh-Walker-GM -This change removes the `--performance` flag from the `yarn rw build` command. It will no longer be available to use and the CLI will no longer accept this flag being passed in. +This change removes the `--performance` flag from the `yarn rw build` command. It will no longer be available to use and the CLI will no longer accept this flag being passed in. -Additionally, the associated webpack config (`@redwoodjs/core/config/webpack.perf.js`) has been removed so it can no longer be imported if you were doing so. +Additionally, the associated webpack config (`@redwoodjs/core/config/webpack.perf.js`) has been removed so it can no longer be imported if you were doing so. diff --git a/.changesets/10457.md b/.changesets/10457.md index daa8f21d0e87..4cbf40a10c3a 100644 --- a/.changesets/10457.md +++ b/.changesets/10457.md @@ -1,28 +1,30 @@ -- feat(server-auth): dbAuth 3/3 - handle login, logout, signup, etc. requests if forwarded from middleware (#10457) by @dac09 +- feat(server-auth): dbAuth 3/3 - handle login, logout, signup, etc. requests if forwarded from middleware (#10457) by @dac09 -This PR updates the DbAuthHandler class to handle requests forwarded from middleware, so it can generate responses for login, logout, signup, etc. These are POST requests - it used to be to the `/auth` function, but now they will be captured by dbAuth middleware and forwarded onto DbAuthHandler. +This PR updates the DbAuthHandler class to handle requests forwarded from middleware, so it can generate responses for login, logout, signup, etc. These are POST requests - it used to be to the `/auth` function, but now they will be captured by dbAuth middleware and forwarded onto DbAuthHandler. **High level changes:** + - use the `Headers` class in each of the "method" responses. This allows us to set multi-value headers like Set-Cookie. A simple object would not. See type `AuthMethodOutput` -- extracts `buildResponse` into a testable function and adds test. For `Set-Cookie` headers we return an array of strings. +- extracts `buildResponse` into a testable function and adds test. For `Set-Cookie` headers we return an array of strings. In the middleware here's the code I had for the final conversion: -```ts - if (AUTHHANDLER_REQUEST) { - const output = await dbAuthHandler(req) - const finalHeaders = new Headers() - Object.entries(output.headers).forEach(([key, value]) => { - if (Array.isArray(value)) { - value.forEach((v) => finalHeaders.append(key, v)) - } else { - finalHeaders.append(key, value) - } - }) +```ts +if (AUTHHANDLER_REQUEST) { + const output = await dbAuthHandler(req) - return new MiddlewareResponse(output.body, { - headers: finalHeaders, - status: output.statusCode, - }) + const finalHeaders = new Headers() + Object.entries(output.headers).forEach(([key, value]) => { + if (Array.isArray(value)) { + value.forEach((v) => finalHeaders.append(key, v)) + } else { + finalHeaders.append(key, value) } + }) + + return new MiddlewareResponse(output.body, { + headers: finalHeaders, + status: output.statusCode, + }) +} ``` diff --git a/.changesets/10460.md b/.changesets/10460.md index 19bb349dd502..de8debaa45e3 100644 --- a/.changesets/10460.md +++ b/.changesets/10460.md @@ -1,8 +1,8 @@ - chore(dbauth-mw): Refactor web side dbAuth creation (#10460) by @dac09 -This PR changes how the webside auth is initialised, by removing the `createMiddlewareAuth` function, instead it just detects it internally. +This PR changes how the webside auth is initialised, by removing the `createMiddlewareAuth` function, instead it just detects it internally. -For dbAuth this is what it will looks like: +For dbAuth this is what it will looks like: ```js:web/src/auth.ts import { @@ -23,13 +23,16 @@ export const { AuthProvider, useAuth } = createAuth(dbAuthClient) For other auth providers we are going to export a similar looking function: ```js -import { createAuth, createSupabaseAuthClient } from '@redwoodjs/auth-supabase-web' +import { + createAuth, + createSupabaseAuthClient, +} from '@redwoodjs/auth-supabase-web' // This function is new, and just wraps creating supabase👇 const supabaseClient = createSupabaseAuthClient({ supabaseUrl: process.env.SUPABASE_URL || '', supabaseKey: process.env.SUPABASE_KEY || '', - middleware: true + middleware: true, }) export const { AuthProvider, useAuth } = createAuth(supabaseClient) diff --git a/.changesets/10464.md b/.changesets/10464.md index 5741c801f356..5e4985ea77a8 100644 --- a/.changesets/10464.md +++ b/.changesets/10464.md @@ -4,7 +4,7 @@ We were using both `index.ts` and `router.tsx` as barrel export files. We should This is a breaking change for anyone who does `import ... from '@redwoodjs/router/dist/router'` in their project. Which hopefully isn't very many. - - The quick fix is to find the original export and pull from there instead - - The real fix is to talk to us on the core team and see if we can provide an - official way of solving it instead of relying on internal implementation - details 🙂 +- The quick fix is to find the original export and pull from there instead +- The real fix is to talk to us on the core team and see if we can provide an + official way of solving it instead of relying on internal implementation + details 🙂 diff --git a/.changesets/10465.md b/.changesets/10465.md index 0c667c4d47dd..c5a10d3b5ba2 100644 --- a/.changesets/10465.md +++ b/.changesets/10465.md @@ -2,12 +2,12 @@ **1. Updates `getAuthenticationContext` to parse the cookie header and pass it to authDecoder.** -Note that the authentication context itself does not pull out the token from cookies, because with some providers (e.g. supabase) - we don't know the name of the cookie. This is left to the authDecoder implementation. +Note that the authentication context itself does not pull out the token from cookies, because with some providers (e.g. supabase) - we don't know the name of the cookie. This is left to the authDecoder implementation. -The return type from this function is actually just a deserialized cookie header i.e. +The return type from this function is actually just a deserialized cookie header i.e. `cookie: auth-provider=one; session=xx/yy/zz; somethingElse=bsbs` => `{ 'auth-provider': 'one', session: 'xx/yy/zz', somethingElse: 'bsbs'` -**2. Retains support for header/token based auth** +**2. Retains support for header/token based auth** See test on line 259 of `packages/api/src/auth/__tests__/getAuthenticationContext.test.ts`. If a the `authorization` and `auth-provider` headers are passed in the request (as we do for SPA based auth) - then cookies will take precedence. -The end result is that graphql requests will now work with middleware-based auth providers! +The end result is that graphql requests will now work with middleware-based auth providers! diff --git a/.changesets/10469.md b/.changesets/10469.md index 7b2c8a51ca2b..8bbb2e124e5d 100644 --- a/.changesets/10469.md +++ b/.changesets/10469.md @@ -1,45 +1,49 @@ -- feat(og-gen): Implement middleware and hooks (#10469) by @dac09 +- feat(og-gen): Implement middleware and hooks (#10469) by @dac09 -The OG Gen saga continues with @cannikin and @dac09 ⚔️ +The OG Gen saga continues with @cannikin and @dac09 ⚔️ This PR: + - adds OgImageMiddleware and Hooks to `@redwoodjs/og-gen`, complete with tests ⚠️ Template changes: + - updates entry.client template to pass in Routes to App - updates App to take children (i.e. Routes) This is so that we can pass the OG component to be rendered _with_ your App's CSS setup. - **How to use this?** 1. **Registering the middleware:** - ```ts - import OgImageMiddleware from '@redwoodjs/ogimage-gen/middleware' - export const registerMiddleware = () => { - const ogMw = new OgImageMiddleware({ - App, - Document, - }) + ```ts + import OgImageMiddleware from '@redwoodjs/ogimage-gen/middleware' - return [ogMw] - } - ``` + export const registerMiddleware = () => { + const ogMw = new OgImageMiddleware({ + App, + Document, + }) + + return [ogMw] + } + ``` 2. Configure your `vite.config.ts` - ```ts - import vitePluginOgImageGen from '@redwoodjs/ogimage-gen/plugin' - const viteConfig: UserConfig = { - // 👇 so it builds your OG components - plugins: [redwood(), vitePluginOgImageGen()], - } + ```ts + import vitePluginOgImageGen from '@redwoodjs/ogimage-gen/plugin' + + const viteConfig: UserConfig = { + // 👇 so it builds your OG components + plugins: [redwood(), vitePluginOgImageGen()], + } + + export default defineConfig(viteConfig) + ``` - export default defineConfig(viteConfig) - ``` 3. Add your OG Image component next to the page it's for -e.g. web/src/pages/AboutPage/AboutPage.png.tsx + e.g. web/src/pages/AboutPage/AboutPage.png.tsx 4. Use hooks on AboutPage to generate the ogURL diff --git a/.changesets/10493.md b/.changesets/10493.md index 461695b4b362..15861211dbae 100644 --- a/.changesets/10493.md +++ b/.changesets/10493.md @@ -10,10 +10,9 @@ const myCookie = mwRequest.cookies.get('myCookie') const actualValue = myCookie.value ``` -This is unwieldy, and feels unergonomic for the 98% of cases where `get` will be used to just see the value. +This is unwieldy, and feels unergonomic for the 98% of cases where `get` will be used to just see the value. **How do I still see the options of the cookie?** You can still access all the details of the cookie by doing `cookie.entries`. I don't really have a case for this yet, so let's not optimise for this case, but we know it's possible! - This is me just stabilizing the API for Middleware stuff, before we ship it out of experimental diff --git a/.changesets/10498.md b/.changesets/10498.md index 611d82c6371c..6543f393acda 100644 --- a/.changesets/10498.md +++ b/.changesets/10498.md @@ -6,5 +6,3 @@ This is because the dbauth-provider-web packages are still CJS only. When import **2. Updates the default auth provider state for middleware auth** Middleware auth default state is _almost_ the same as SPA default auth state. Except that loading is always false! Otherwise you can get stuck in a loading state forever. - - \ No newline at end of file diff --git a/.changesets/10499.md b/.changesets/10499.md index de951de649f5..f80f8fef394c 100644 --- a/.changesets/10499.md +++ b/.changesets/10499.md @@ -2,11 +2,9 @@ Implement Supabase Auth Middleware to authenticate server-side requests. -* Adds middleware to the Supabase auth-providers package. -* createSupabaseAuthMiddleware is responsible for authenticating Supabase requests -* It does so by checking if the request has a supabase auth-provider header, and then uses the authDecoder to verify the session cookie using the Supabase ServerAuthClient and returning a decoded access token -- or throwing an exception if the session cookie is invalid -* Once the middleware has the decoded JWT, it hands that to the provided getCurrentUser from he user's project to return the information about authenticated user -* Lastly, it sets serverAuthState with user and metadata info to know the request isAuthenticated -* If the session is invalid or the cookie tampered with such that the access token cannot be verified, serverAuthState is cleared as are the auth provider and Supabase cookies - - +- Adds middleware to the Supabase auth-providers package. +- createSupabaseAuthMiddleware is responsible for authenticating Supabase requests +- It does so by checking if the request has a supabase auth-provider header, and then uses the authDecoder to verify the session cookie using the Supabase ServerAuthClient and returning a decoded access token -- or throwing an exception if the session cookie is invalid +- Once the middleware has the decoded JWT, it hands that to the provided getCurrentUser from he user's project to return the information about authenticated user +- Lastly, it sets serverAuthState with user and metadata info to know the request isAuthenticated +- If the session is invalid or the cookie tampered with such that the access token cannot be verified, serverAuthState is cleared as are the auth provider and Supabase cookies diff --git a/.changesets/10502.md b/.changesets/10502.md index 51a50674f2b1..5d2452434ca6 100644 --- a/.changesets/10502.md +++ b/.changesets/10502.md @@ -1,2 +1,2 @@ - fix(dbauth-mw): Unset cookie instead of clearing (#10502) by @dac09 -Updates dbAuth middleware implementation to _unset_ the cookies, instead of clearing them. + Updates dbAuth middleware implementation to _unset_ the cookies, instead of clearing them. diff --git a/.changesets/10520.md b/.changesets/10520.md index f18c4c48d7c0..d926d379c501 100644 --- a/.changesets/10520.md +++ b/.changesets/10520.md @@ -1,3 +1,3 @@ - feat(eslint): Disable restricted $api imports for entryserver (#10520) by @dac09 -With the introduction of middleware, it's pretty common to import things from the $api side. This is a non-issue as entry.server.{jsx,tsx} is not part of the client bundle we generate. +With the introduction of middleware, it's pretty common to import things from the $api side. This is a non-issue as entry.server.{jsx,tsx} is not part of the client bundle we generate. diff --git a/.changesets/10522.md b/.changesets/10522.md index 915280d80667..84953f30fb31 100644 --- a/.changesets/10522.md +++ b/.changesets/10522.md @@ -5,7 +5,7 @@ In `web/src/auth.ts`: ``` -// 👇 notice where this is imported from! +// 👇 notice where this is imported from! import { createBrowserClient } from '@supabase/ssr' import { createAuth } from '@redwoodjs/auth-supabase-web' diff --git a/.changesets/10538.md b/.changesets/10538.md index 02f8016306de..1991248970db 100644 --- a/.changesets/10538.md +++ b/.changesets/10538.md @@ -1,6 +1,7 @@ - fix(serverauth): Export dbAuthMiddleware as default export to match supabase (#10538) by @dac09 An example: + ```js //before import { createDbAuthMiddleware } from '@redwoodjs/auth-dbauth-middleware' diff --git a/.changesets/10542.md b/.changesets/10542.md index 0d665cc2bc8b..229f41e551e3 100644 --- a/.changesets/10542.md +++ b/.changesets/10542.md @@ -1,4 +1,4 @@ -- Rename og component assets from *.png.jsx to just*.og.jsx (#10542) by @cannikin +- Rename og component assets from _.png.jsx to just_.og.jsx (#10542) by @cannikin We ran into a conflict where you could name your component file something like `AboutPage.png.jsx` (where the returned content-type would be image/png). But, when you invoke `useOgImage()` to actually create the URL for a `` tag, you could instead use a different extension, like `.jpg`. Which one should win? diff --git a/.changesets/10570.md b/.changesets/10570.md index 679568957b17..4226df248500 100644 --- a/.changesets/10570.md +++ b/.changesets/10570.md @@ -2,4 +2,4 @@ With an empty/null payload (which it is by default) the body should be empty, not the string `'null'` -This is a breaking change for anyone who was depending on the current "null" behavior in their api function tests. More specifically, if you're **NOT** passing `body` or `payload` to `mockHttpEvent({ ... })` or if you're trying to explicitly set `payload` to `null` you might have to update your tests. +This is a breaking change for anyone who was depending on the current "null" behavior in their api function tests. More specifically, if you're **NOT** passing `body` or `payload` to `mockHttpEvent({ ... })` or if you're trying to explicitly set `payload` to `null` you might have to update your tests. diff --git a/.changesets/10585.md b/.changesets/10585.md index 0bd8ded820ca..22640b7ba67e 100644 --- a/.changesets/10585.md +++ b/.changesets/10585.md @@ -4,12 +4,12 @@ First pass at implementing a per-request store that allows: - access to headers and cookies from requests in server components - access to serverAuthState from server components -- maps serverAuthState updated from middleware to the the per request store +- maps serverAuthState updated from middleware to the the per request store This PR also implements execution of middleware in the RSC handler. Note that this is done in a "good enough" way currently, because the RSC handler doesn't use Fetch requests (but everything else does) - + Important things to note: + - the store is initialised _again_ in the RSC worker, with the same values on each invocation of renderRsc - we have _not_ tested or tried in Dev because `rw dev` does not work in RSC yet -- we have _not_ tested behaviour on initial SSR - because this is not implemented yet in RSC - +- we have _not_ tested behaviour on initial SSR - because this is not implemented yet in RSC diff --git a/.changesets/10586.md b/.changesets/10586.md index 864ae5c1420e..c2317e8fd1f5 100644 --- a/.changesets/10586.md +++ b/.changesets/10586.md @@ -1,6 +1,6 @@ - feat(middleware): Add .shortCircuit to MiddlewareResponse (#10586) by @dac09 -Adds a helper to generate a intercept/short-circuit response, that will interrupt execution of _all_ middleware and react rendering, and immediately return the response. +Adds a helper to generate a intercept/short-circuit response, that will interrupt execution of _all_ middleware and react rendering, and immediately return the response. There's a few different ways you can use this, see examples below: @@ -24,7 +24,5 @@ const shortCircuitMw: Middleware = (req, res) => { headers: { shortCircuitDirect: 'yes' }, }) } - } ``` - diff --git a/.changesets/10656.md b/.changesets/10656.md index 8307e1eda502..89780e1a68cf 100644 --- a/.changesets/10656.md +++ b/.changesets/10656.md @@ -6,6 +6,7 @@ - Introduces new `clear()` function to remove auth state - just syntax sugar ## Example usage + ```tsx // In entry.server.tsx export const registerMiddleware = () => { @@ -15,9 +16,9 @@ export const registerMiddleware = () => { getCurrentUser, getRoles: (decoded) => { return decoded.currentUser.roles || [] - } + }, }) - + return [authMw] } ``` diff --git a/.changesets/10668.md b/.changesets/10668.md index 2c2b6830fb66..187acaad387f 100644 --- a/.changesets/10668.md +++ b/.changesets/10668.md @@ -1,10 +1,12 @@ - fix(dbAuthMw): Update and fix logic related to dbAuth "verbs" and decryptionErrors (#10668) by @dac09 This PR does the following: + - updates the dbauth mw to correctly handle the cookieName option (it should always have been optional) - throws an error when the `dbAuthSession` returns an empty decoded token so that it clears the authState -- we had a check for only "POST" requests to be passed to the dbAuthHandler. This was incorrect because some of the dbAuth "verbs" or actions - like `webAuthnRegOptions` - uses a GET request. +- we had a check for only "POST" requests to be passed to the dbAuthHandler. This was incorrect because some of the dbAuth "verbs" or actions - like `webAuthnRegOptions` - uses a GET request. As a result, the tests started showing failures, so I: + - added a mock for `dbAuthSession`, so we can check both happy path and unhappy paths for session decryption - updated the tests where relevant diff --git a/.changesets/10677.md b/.changesets/10677.md index 4113d125217d..a62f180d5450 100644 --- a/.changesets/10677.md +++ b/.changesets/10677.md @@ -1,6 +1,7 @@ - Adds `searchParams` option to `useOgImage()` hook for adding arbitrary query string vars to generated URL (#10677) by @cannikin This can be used like so: + ``` const { url } = useOgImage({ searchParams: { foo: 'bar' }) console.log(url) // => http://localhost:8910/photo.png?foo=bar diff --git a/.changesets/10680.md b/.changesets/10680.md index e1a54c0ea56f..34aad4ebc011 100644 --- a/.changesets/10680.md +++ b/.changesets/10680.md @@ -3,10 +3,10 @@ This PR adds the `page_identifier_str` of `pageIdentifier` to the Route Manifest. Known what page belongs to the route can be useful to : - -* ensure if rendering a page/component that it belongs to the route and its auth permissions -* for visualizing routes -* general completeness in the manifest with the Routes jsx in manifest form + +- ensure if rendering a page/component that it belongs to the route and its auth permissions +- for visualizing routes +- general completeness in the manifest with the Routes jsx in manifest form ## Example diff --git a/.changesets/10697.md b/.changesets/10697.md index 475e74ed509f..559b35e5c3c3 100644 --- a/.changesets/10697.md +++ b/.changesets/10697.md @@ -2,8 +2,8 @@ 1. Adds fullUrl property to serverStore 2. Adds two utility functions: -a) `getFullUrl` - to construct the absolute url from an express request -b) `getFullUrlFromFlightRequest` - this is used when we get a request to render RSCs in the rscRequestHandler. This one is different because the location we want is for the actual page, not of the request (which goes to to the RSC endpoint). + a) `getFullUrl` - to construct the absolute url from an express request + b) `getFullUrlFromFlightRequest` - this is used when we get a request to render RSCs in the rscRequestHandler. This one is different because the location we want is for the actual page, not of the request (which goes to to the RSC endpoint). 3. Adds `getLocation` function to retrieve the Location (URL object) from server store Short video demonstrating location coming through in two cases: @@ -13,6 +13,7 @@ b) Hard render https://s.tape.sh/4g7LFsYP **Usage example:** + ```tsx import { getLocation } from '@redwoodjs/vite/serverStore' @@ -21,4 +22,4 @@ const NavigationLayout = ({ children, rnd }: NavigationLayoutProps) => { console.log(`👉 \n ~ location:`, location) ``` -Longer term, we may want to change how the endpoint for flight requests so that the location doesn't have to be constructed specially. +Longer term, we may want to change how the endpoint for flight requests so that the location doesn't have to be constructed specially. diff --git a/.changesets/10702.md b/.changesets/10702.md index 908ec2de515c..e543463368b8 100644 --- a/.changesets/10702.md +++ b/.changesets/10702.md @@ -12,4 +12,4 @@ In production Docker, the server file was never run and therefore the plugin to Here api server, simply ran the GraphQL function as expected, but the plugin was never invoked so Realtime was never configured or added to the schema. -This happened because by default, production Docker launch the plain vanilla api server -- it didn't launch server file that uses `createServer` to setup a separate GraphQL server and also add in the realtime plugin. +This happened because by default, production Docker launch the plain vanilla api server -- it didn't launch server file that uses `createServer` to setup a separate GraphQL server and also add in the realtime plugin. diff --git a/.changesets/10768.md b/.changesets/10768.md index 30fe7ebd1b03..294985a45d0b 100644 --- a/.changesets/10768.md +++ b/.changesets/10768.md @@ -1,4 +1,5 @@ - Add Storybook Vite smoke tests (#10768) by @arimendelow Adds: + - Unit tests for storybook-vite CLI (based on those from the dataMigrate CLI) diff --git a/.changesets/10817.md b/.changesets/10817.md index 17d6b873a3c3..8617c77192c7 100644 --- a/.changesets/10817.md +++ b/.changesets/10817.md @@ -10,8 +10,8 @@ The plgin for persisted operations lets one define what can bypass trusted docs So, we can use that in the useTrustedDocuments plugin to just allow that specific request. -const REDWOOD__AUTH_GET_CURRENT_USER_QUERY = - '{"query":"query __REDWOOD__AUTH_GET_CURRENT_USER { redwood { currentUser } }"}' +const REDWOOD**AUTH_GET_CURRENT_USER_QUERY = +'{"query":"query **REDWOOD\_\_AUTH_GET_CURRENT_USER { redwood { currentUser } }"}' When using Redwood Auth, we want to allow the known, trusted redwood.currentUser query to be executed without a persisted operation. This is because the currentUser query is a special case that is used to get the current user from the auth provider. diff --git a/.changesets/10825.md b/.changesets/10825.md index 1b40b11bf61a..c5f527bf4c13 100644 --- a/.changesets/10825.md +++ b/.changesets/10825.md @@ -4,8 +4,7 @@ Fixes https://github.com/redwoodjs/redwood/issues/10807 If one used GraphQL fragments, when mocking the GraphQL query for use in Storybook, the `typename` for the data object must be included otherwise Apollo client cannot properly map the data. -This PR - -* adds the typename to the cell generator templates -* updates the testing and graphql mock and fragments documentation to show how properly defines mock data +This PR +- adds the typename to the cell generator templates +- updates the testing and graphql mock and fragments documentation to show how properly defines mock data diff --git a/.changesets/10830.md b/.changesets/10830.md index d667110d4ddf..906feae23a7b 100644 --- a/.changesets/10830.md +++ b/.changesets/10830.md @@ -1,3 +1,3 @@ - fix(cli): Add check for excessively long route (#10830) by @Josh-Walker-GM -This change adds an additional internal check to protect against route definitions which are preposterously long. +This change adds an additional internal check to protect against route definitions which are preposterously long. diff --git a/.changesets/10833.md b/.changesets/10833.md index 68a7d6449afe..08c80b8b931a 100644 --- a/.changesets/10833.md +++ b/.changesets/10833.md @@ -2,4 +2,4 @@ This change updates our firebase auth provider to use the v12 major version of the `firebase-admin` package. This will require you to update your own version of `firebase-admin` that is listed in your api side package json file. -We have noticed no breaking api changes in our limited testing. Please consult the `firebase-admin` upgrade guide if you experience problems after upgrading - especially if you have more extensive or complex use of the firebase suite of products. +We have noticed no breaking api changes in our limited testing. Please consult the `firebase-admin` upgrade guide if you experience problems after upgrading - especially if you have more extensive or complex use of the firebase suite of products. diff --git a/.changesets/10865.md b/.changesets/10865.md index 7f2848b9fd06..0dc3fba1dcaa 100644 --- a/.changesets/10865.md +++ b/.changesets/10865.md @@ -1,3 +1,3 @@ - feat(dbAuth): Prompt to generate dbAuth pages (#10865) by @Tobbe -When setting up dbAuth we'll now prompt if the user also wants to generate pages for login, signup, password reset etc. We only prompt if no existing pages exist. \ No newline at end of file +When setting up dbAuth we'll now prompt if the user also wants to generate pages for login, signup, password reset etc. We only prompt if no existing pages exist. diff --git a/.changesets/10867.md b/.changesets/10867.md index 09f6f86a07ad..6dcd0b7065fb 100644 --- a/.changesets/10867.md +++ b/.changesets/10867.md @@ -1,6 +1,7 @@ - breaking: remove webpack (#10867) by @Josh-Walker-GM This PR removes support for webpack. There are a number of breaking changes associated with removing a core component of previous versions. A list of such changes is: + 1. `prebuildWebFile` is function no longer exported from `@redwoodjs/babel-config` package 2. `@redwoodjs/cli-storybook` has been removed 3. `yarn rw build` no longer accepts the `--stats` flag diff --git a/.changesets/10869.md b/.changesets/10869.md index e87bb1dbb3f5..beac04684f9b 100644 --- a/.changesets/10869.md +++ b/.changesets/10869.md @@ -1,25 +1,25 @@ feat(prisma): Support multi file Prisma schemas (#10869) by @dthyresson -Prisma's `prismaSchemaFolder` [feature](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema) allows you to define multiple files in a schema subdirectory of your prisma directory. +Prisma's `prismaSchemaFolder` [feature](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema) allows you to define multiple files in a schema subdirectory of your prisma directory. This PR updates: -* Prisma utilities -* generators -* dbAuth setup -* documentation +- Prisma utilities +- generators +- dbAuth setup +- documentation to support single and multi file Prisma schemas. If you have enabled Prisma multi file schemas, you configure your project toml api `schemaPath` setting the directory where your schema.prisma can be found, for example: './api/db/schema' -When [organizing your Prisma Schema into multiple files](https://www.prisma.io/blog/organize-your-prisma-schema-with-multi-file-support), you will need [enable](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema) that feature in Prisma, move your `schema.prisma` file into a new directory such as `./api/db/schema` and then set `schemaPath` in the api toml config. +When [organizing your Prisma Schema into multiple files](https://www.prisma.io/blog/organize-your-prisma-schema-with-multi-file-support), you will need [enable](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema) that feature in Prisma, move your `schema.prisma` file into a new directory such as `./api/db/schema` and then set `schemaPath` in the api toml config. ::: For example: ```toml title="redwood.toml" [api] - port = 8911 + port = 8911 schemaPath = "./api/db/schema" ``` diff --git a/.changesets/10888.md b/.changesets/10888.md index 3369c04737f0..4a38e50a9410 100644 --- a/.changesets/10888.md +++ b/.changesets/10888.md @@ -1,3 +1,3 @@ - fix(prerender): Fold output to prevent crashing on large prerender counts (#10888) by @Josh-Walker-GM -This change alters the CLI output during prerendering to prevent crashes when prerendering a large number (>100,000) of routes. +This change alters the CLI output during prerendering to prevent crashes when prerendering a large number (>100,000) of routes. diff --git a/.changesets/10893.md b/.changesets/10893.md index ca4f270a6e2b..c83381b21236 100644 --- a/.changesets/10893.md +++ b/.changesets/10893.md @@ -2,7 +2,7 @@ fix(realtime/trusted-docs): Supports GraphQL subscriptions and trusted documents Fixes: https://github.com/redwoodjs/redwood/issues/10892 -This PR updates the SSELink to check if there is a trusted document hash in the request. If there is, then don't also include the query. +This PR updates the SSELink to check if there is a trusted document hash in the request. If there is, then don't also include the query. The persisted operations plugin checks if the params has a query. If it does then raises an error that only persisted operations are allowed. diff --git a/.changesets/10900.md b/.changesets/10900.md index 75831396d6ca..d2c810b34926 100644 --- a/.changesets/10900.md +++ b/.changesets/10900.md @@ -1,3 +1,3 @@ - feat(Storybook Vite): Add JS project support (#10900) by @arimendelow -This adds support to the SBV CLI for JS projects. \ No newline at end of file +This adds support to the SBV CLI for JS projects. diff --git a/.changesets/10911.md b/.changesets/10911.md index b1e68bee2c1c..b82c358dd9be 100644 --- a/.changesets/10911.md +++ b/.changesets/10911.md @@ -5,32 +5,32 @@ This change updates Redwood linting config and introduces some changes to the li Specifically: 1. `jsx-a11y/no-noninteractive-element-to-interactive-role` has it's default config updated. -3. `@typescript-eslint/explicit-function-return-type` used to be turned off, now it's no longer applied. -4. `@typescript-eslint/no-empty-interface` - used to be turned off, now it's no longer applied. -5. `@typescript-eslint/explicit-module-boundary-types` - used be turned off, now it's no longer applied. -6. `@typescript-eslint/ban-types` - used to be 'warn', now it's no longer applied. This has been replaces with a set of smaller more specific rules. -7. `no-empty-function` - used be turned off, now it's no longer applied. The ts-eslint flavour is still there and turned off still. -8. `camelcase` - used to be turned off, now it's 'warn'. -9. `@typescript-eslint/camelcase` - used to be turned off, now it's no longer applied. -10. `no-use-before-define` - used to be turned off, now it's no longer applied. -11. `@typescript-eslint/no-use-before-define` - used to be turned off, now it's no longer applied. -12. `@typescript-eslint/prefer-namespace-keyword` - used to be turned off, now it's 'error' -13. `unicode-bom` - used to be turned off, now it's no longer applied. -14. `@typescript-eslint/adjacent-overload-signatures` - used to be 'error', now it's no longer applied. -15. `@typescript-eslint/no-explicit-any` - used be 'warn', now 'error' -16. `@typescript-eslint/no-inferrable-types` - used to be 'error', now it's no longer applied. -17. `no-loss-of-precision` - used be 'off', now 'error' -18. `@typescript-eslint/no-loss-of-precision` - used be 'error', now it's no longer applied. -19. `@typescript-eslint/no-non-null-assertion` - used be 'warn', now it's no longer applied. -20. `valid-typeof` - used be either 'error' or 'off', now always 'error' -21. `no-unused-expressions` - used be always 'error', now either 'error' or 'off' -22. `@typescript-eslint/prefer-function-type` - newly added as 'off' -23. `@typescript-eslint/no-require-imports` - newly added as 'off' -24. `@typescript-eslint/no-empty-object-type` - newly added as 'off' -25. `unicorn/template-indent` - newly added as 'off' -26. `@typescript-eslint/no-duplicate-enum-values` - newly added as 'error' -27. `@typescript-eslint/no-unsafe-declaration-merging` - newly added as 'error' -28. `@typescript-eslint/no-unsafe-function-type` - newly added as 'error' -29. `@typescript-eslint/no-unused-expressions` - newly added as 'error' -30. `@typescript-eslint/no-wrapper-object-types` - newly added as 'error' -31. `no-new-native-nonconstructor` - newly added as 'off' +2. `@typescript-eslint/explicit-function-return-type` used to be turned off, now it's no longer applied. +3. `@typescript-eslint/no-empty-interface` - used to be turned off, now it's no longer applied. +4. `@typescript-eslint/explicit-module-boundary-types` - used be turned off, now it's no longer applied. +5. `@typescript-eslint/ban-types` - used to be 'warn', now it's no longer applied. This has been replaces with a set of smaller more specific rules. +6. `no-empty-function` - used be turned off, now it's no longer applied. The ts-eslint flavour is still there and turned off still. +7. `camelcase` - used to be turned off, now it's 'warn'. +8. `@typescript-eslint/camelcase` - used to be turned off, now it's no longer applied. +9. `no-use-before-define` - used to be turned off, now it's no longer applied. +10. `@typescript-eslint/no-use-before-define` - used to be turned off, now it's no longer applied. +11. `@typescript-eslint/prefer-namespace-keyword` - used to be turned off, now it's 'error' +12. `unicode-bom` - used to be turned off, now it's no longer applied. +13. `@typescript-eslint/adjacent-overload-signatures` - used to be 'error', now it's no longer applied. +14. `@typescript-eslint/no-explicit-any` - used be 'warn', now 'error' +15. `@typescript-eslint/no-inferrable-types` - used to be 'error', now it's no longer applied. +16. `no-loss-of-precision` - used be 'off', now 'error' +17. `@typescript-eslint/no-loss-of-precision` - used be 'error', now it's no longer applied. +18. `@typescript-eslint/no-non-null-assertion` - used be 'warn', now it's no longer applied. +19. `valid-typeof` - used be either 'error' or 'off', now always 'error' +20. `no-unused-expressions` - used be always 'error', now either 'error' or 'off' +21. `@typescript-eslint/prefer-function-type` - newly added as 'off' +22. `@typescript-eslint/no-require-imports` - newly added as 'off' +23. `@typescript-eslint/no-empty-object-type` - newly added as 'off' +24. `unicorn/template-indent` - newly added as 'off' +25. `@typescript-eslint/no-duplicate-enum-values` - newly added as 'error' +26. `@typescript-eslint/no-unsafe-declaration-merging` - newly added as 'error' +27. `@typescript-eslint/no-unsafe-function-type` - newly added as 'error' +28. `@typescript-eslint/no-unused-expressions` - newly added as 'error' +29. `@typescript-eslint/no-wrapper-object-types` - newly added as 'error' +30. `no-new-native-nonconstructor` - newly added as 'off' diff --git a/.changesets/10961.md b/.changesets/10961.md index 8cd365b8663c..ee75c7843a56 100644 --- a/.changesets/10961.md +++ b/.changesets/10961.md @@ -1,3 +1,3 @@ - fix(storybook): Fix import issues with storybook vite (#10961) by @Josh-Walker-GM -Fixes an issue with the `yarn rw storybook-vite` command where it would not start due to an import issue. +Fixes an issue with the `yarn rw storybook-vite` command where it would not start due to an import issue. diff --git a/.changesets/11062.md b/.changesets/11062.md index f8f9c2f818e3..a2e51acf7bf6 100644 --- a/.changesets/11062.md +++ b/.changesets/11062.md @@ -1,3 +1,3 @@ -- fix(router): Add check for excessively long path (#11062) by @Josh-Walker-GM +- fix(router): Add check for excessively long path (#11062) by @Josh-Walker-GM This change adds an additional internal check to protect against route paths which are excessively long. diff --git a/.changesets/11072.md b/.changesets/11072.md index e4b3635cf9e6..5c3a91845806 100644 --- a/.changesets/11072.md +++ b/.changesets/11072.md @@ -1,3 +1,3 @@ - feat(cli): Move docker setup out of experimental (#11072) by @Josh-Walker-GM -This change introduces `yarn rw setup docker`. This is a result of moving our docker setup command out of it's experimental phase. +This change introduces `yarn rw setup docker`. This is a result of moving our docker setup command out of it's experimental phase. diff --git a/.changesets/11108.md b/.changesets/11108.md index f98f93c7a310..8fe7cd0208af 100644 --- a/.changesets/11108.md +++ b/.changesets/11108.md @@ -1,16 +1,15 @@ -- feat(testing): Configure jest to ignore sidecar files in __tests__ folder (#11108) by @V1shvesh +- feat(testing): Configure jest to ignore sidecar files in **tests** folder (#11108) by @V1shvesh Solves for #10870 ### Description: + `./api` directory structure: image `./web` directory structure: image - - -Before: +Before: `yarn rw test api`: image @@ -18,12 +17,9 @@ Before: `yarn rw test web`: image - - After: `yarn rw test api`: image `yarn rw test web`: image - diff --git a/.changesets/11109.md b/.changesets/11109.md index 0a79d4a4c51b..860cf6226eb8 100644 --- a/.changesets/11109.md +++ b/.changesets/11109.md @@ -5,9 +5,10 @@ The more detail the better. E.g., is it a new feature? How do they use it? Code - fix: concurrent api builds (#11109) by @callingmedic911 A few users [reported](https://community.redwoodjs.com/t/redwood-v7-0-0-upgrade-guide/5713/90?u=callingmedic911) that the API server crashes with the error `EADDRINUSE` when switching between branches. This issue happens on the API side when: + 1. New files are added or existing files are removed. 2. Immediately after, an existing file is changed. This scenario is common when doing git operations like switching branches or using git stash, where these changes occur simultaneously. When this happens, step 1 triggers a full build (without esbuild's rebuild), and step 2, without canceling the build from step 1, triggers a separate `rebuild`. This results in concurrent builds and two instances of the API server trying to start. -This PR provides a quick fix for the issue. A follow-up PR will be created to refactor the process, aiming to avoid separate build processes altogether, ensure a cleaner separation between the build and the server, and improve overall readability. \ No newline at end of file +This PR provides a quick fix for the issue. A follow-up PR will be created to refactor the process, aiming to avoid separate build processes altogether, ensure a cleaner separation between the build and the server, and improve overall readability. diff --git a/.changesets/11135.md b/.changesets/11135.md index 932c7fa1fd0e..afb073672f46 100644 --- a/.changesets/11135.md +++ b/.changesets/11135.md @@ -1,6 +1,6 @@ - fix(cli-cache): Remove RW CLI cache on upgrade (#11135) by @dac09 -This change removes the redwood cli plugin cache in `.redwood/commandCache.json` on running `rw upgrade`. +This change removes the redwood cli plugin cache in `.redwood/commandCache.json` on running `rw upgrade`. This prevents the redwood CLI from using outdated versions of CLI plugins, and is particularly important when they same alias. diff --git a/.changesets/11170.md b/.changesets/11170.md index 4f4390a76c6e..3fd0e84e161e 100644 --- a/.changesets/11170.md +++ b/.changesets/11170.md @@ -1,9 +1,10 @@ - fix: Update default tsconfig options (target, module and moduleResolution) (#11170) by @Josh-Walker-GM This changes the default values of: - - target - - module - - moduleResolution + +- target +- module +- moduleResolution in the tsconfig files for both the API and web side. The benefit of this change is increased correctness for build time checking of the imports from packages which specify `exports` in their `package.json` files. diff --git a/.changesets/11189.md b/.changesets/11189.md index 8f823c814668..f5ee9ad36933 100644 --- a/.changesets/11189.md +++ b/.changesets/11189.md @@ -1,6 +1,7 @@ - fix(babel-plugins): Handle additional syntax when extracting graphql options (#11189) by @Josh-Walker-GM This fixes an issue with the automatic extraction of options from the `createGraphQLHandler` function when you were wrapping that function within a custom handler function. For example the following would have failed before this fix: + ```ts const graphQLHandler = createGraphQLHandler({ // ...options diff --git a/.changesets/young-spiders-ring.md b/.changesets/young-spiders-ring.md index 83912e0a90bb..4b9212d8ccee 100644 --- a/.changesets/young-spiders-ring.md +++ b/.changesets/young-spiders-ring.md @@ -2,4 +2,4 @@ fix: Fixes Unknown Fragment issues due to GraphQL Tag type mismatch in web (#10357) by @dthyresson - Users reported in #10322 an incompatibility with fragments and when using gql from global web. The TS errors were caused by the global web gql type not being compatible with the standard graphql-tag type. +Users reported in #10322 an incompatibility with fragments and when using gql from global web. The TS errors were caused by the global web gql type not being compatible with the standard graphql-tag type. diff --git a/.prettierignore b/.prettierignore index 27e9f9c57db3..c154d8af0520 100644 --- a/.prettierignore +++ b/.prettierignore @@ -24,5 +24,4 @@ packages/create-redwood-rsc-app # TODO(jgmw): Re-enable these in managable chunks tasks .github -.changesets packages/create-redwood-app/tests/e2e_prompts* From 7eb679fe47019a96418c7ce917e57dcfd56f5b40 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 03:42:28 +0100 Subject: [PATCH 29/52] chore(formatting): include .github dir in prettier (#11287) As title. --- .github/ISSUE_TEMPLATE/bug-report.yml | 10 +- .github/ISSUE_TEMPLATE/documentation.yml | 6 +- .github/ISSUE_TEMPLATE/rfc.yml | 6 +- .github/actions/actionsLib.mjs | 92 ++++++++++--------- .../check_changesets/check_changesets.mjs | 23 +++-- .../check_create_redwood_app.mjs | 18 ++-- .github/actions/detect-changes/README.md | 1 + .github/actions/detect-changes/cases/rsc.mjs | 6 +- .github/actions/detect-changes/cases/ssr.mjs | 2 +- .../require-milestone/requireMilestone.mjs | 26 +++--- .../actions/set-up-rsa-project/jsconfig.json | 2 +- .../setUpRsaProjectGitHub.mjs | 4 +- .../setUpRsaProjectLocally.mjs | 6 +- .../jsconfig.json | 2 +- .../setUpRscKitchenSinkProjectGitHub.mjs | 4 +- .../setUpRscKitchenSinkProjectLocally.mjs | 6 +- .../actions/set-up-rsc-project/jsconfig.json | 2 +- .../set-up-rsc-project/setUpRscProject.mjs | 21 +---- .../setUpRscProjectLocally.mjs | 4 +- .../actions/set-up-test-project/action.yaml | 2 +- .../set-up-test-project/setUpTestProject.mjs | 28 +++--- .github/actions/telemetry_check/check.mjs | 14 ++- .github/scripts/publish_canary.sh | 10 +- .github/workflows/check-changelog.yml | 11 ++- .github/workflows/ci.yml | 4 +- .github/workflows/codeql-analysis.yml | 58 ++++++------ .github/workflows/publish-canary.yml | 2 +- .../workflows/publish-release-candidate.yml | 2 +- .github/workflows/require-release-label.yml | 2 +- .prettierignore | 1 - 30 files changed, 192 insertions(+), 183 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 0e6a6d9f9260..85949ff4a22b 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,7 +1,7 @@ -name: "🐛 Bug report" -description: "Something not working the way it should be?" +name: '🐛 Bug report' +description: 'Something not working the way it should be?' -title: "[Bug?]: " +title: '[Bug?]: ' labels: bug/needs-info body: @@ -29,7 +29,7 @@ body: you're much more likely to get a timely response and fix from us if you fill it out. Issues without reproductions are much harder for us to debug. validations: - required: false + required: false - type: textarea attributes: @@ -52,7 +52,7 @@ body: npmPackages: @redwoodjs/core: 1.5.2 => 1.5.2 validations: - required: false + required: false - type: checkboxes attributes: diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml index 0f299a954c91..3d86c31deb4a 100644 --- a/.github/ISSUE_TEMPLATE/documentation.yml +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -1,7 +1,7 @@ -name: "📖 Documentation" -description: "A catch-all template for issues about documentation" +name: '📖 Documentation' +description: 'A catch-all template for issues about documentation' -title: "[Docs]: " +title: '[Docs]: ' labels: topic/docs body: diff --git a/.github/ISSUE_TEMPLATE/rfc.yml b/.github/ISSUE_TEMPLATE/rfc.yml index 2a081eb62884..69aa95c7e632 100644 --- a/.github/ISSUE_TEMPLATE/rfc.yml +++ b/.github/ISSUE_TEMPLATE/rfc.yml @@ -1,7 +1,7 @@ -name: "💬 RFC" -description: "For detailed proposals about new features or changes to existing ones" +name: '💬 RFC' +description: 'For detailed proposals about new features or changes to existing ones' -title: "[RFC]: " +title: '[RFC]: ' body: - type: markdown diff --git a/.github/actions/actionsLib.mjs b/.github/actions/actionsLib.mjs index 8f82656af54d..deacbe1ef610 100644 --- a/.github/actions/actionsLib.mjs +++ b/.github/actions/actionsLib.mjs @@ -12,24 +12,22 @@ import { hashFiles } from '@actions/glob' * @typedef {import('@actions/exec').ExecOptions} ExecOptions */ -export const REDWOOD_FRAMEWORK_PATH = fileURLToPath(new URL('../../', import.meta.url)) +export const REDWOOD_FRAMEWORK_PATH = fileURLToPath( + new URL('../../', import.meta.url), +) /** * @param {string} command * @param {ExecOptions} options */ function execWithEnv(command, { env = {}, ...rest } = {}) { - return getExecOutput( - command, - undefined, - { - env: { - ...process.env, - ...env - }, - ...rest - } - ) + return getExecOutput(command, undefined, { + env: { + ...process.env, + ...env, + }, + ...rest, + }) } /** @@ -51,52 +49,64 @@ export const execInFramework = createExecWithEnvInCwd(REDWOOD_FRAMEWORK_PATH) * @param {string} redwoodProjectCwd */ export function projectDeps(redwoodProjectCwd) { - return execInFramework('yarn project:deps', { env: { RWJS_CWD: redwoodProjectCwd } }) + return execInFramework('yarn project:deps', { + env: { RWJS_CWD: redwoodProjectCwd }, + }) } /** * @param {string} redwoodProjectCwd */ export function projectCopy(redwoodProjectCwd) { - return execInFramework('yarn project:copy', { env: { RWJS_CWD: redwoodProjectCwd } }) + return execInFramework('yarn project:copy', { + env: { RWJS_CWD: redwoodProjectCwd }, + }) } /** * @param {{ baseKeyPrefix: string, distKeyPrefix: string, canary: boolean }} options */ -export async function createCacheKeys({ baseKeyPrefix, distKeyPrefix, canary }) { +export async function createCacheKeys({ + baseKeyPrefix, + distKeyPrefix, + canary, +}) { const baseKey = [ baseKeyPrefix, process.env.RUNNER_OS, process.env.GITHUB_REF.replaceAll('/', '-'), - await hashFiles(path.join('__fixtures__', 'test-project')) + await hashFiles(path.join('__fixtures__', 'test-project')), ].join('-') - const dependenciesKey = [ - baseKey, - 'dependencies', - await hashFiles(['yarn.lock', '.yarnrc.yml'].join('\n')), - ].join('-') + (canary ? '-canary' : '') - - const distKey = [ - dependenciesKey, - distKeyPrefix, - 'dist', - await hashFiles([ - 'package.json', - 'babel.config.js', - 'tsconfig.json', - 'tsconfig.compilerOption.json', - 'nx.json', - 'lerna.json', - 'packages', - ].join('\n')) - ].join('-') + (canary ? '-canary' : '') + const dependenciesKey = + [ + baseKey, + 'dependencies', + await hashFiles(['yarn.lock', '.yarnrc.yml'].join('\n')), + ].join('-') + (canary ? '-canary' : '') + + const distKey = + [ + dependenciesKey, + distKeyPrefix, + 'dist', + await hashFiles( + [ + 'package.json', + 'babel.config.js', + 'tsconfig.json', + 'tsconfig.compilerOption.json', + 'nx.json', + 'lerna.json', + 'packages', + ].join('\n'), + ), + ].join('-') + (canary ? '-canary' : '') return { baseKey, dependenciesKey, - distKey + distKey, } } @@ -119,7 +129,7 @@ export async function setUpRscTestProject( testProjectPath, fixtureName, core, - execInProject + execInProject, ) { core.setOutput('test-project-path', testProjectPath) @@ -129,15 +139,15 @@ export async function setUpRscTestProject( const fixturePath = path.join( REDWOOD_FRAMEWORK_PATH, '__fixtures__', - fixtureName + fixtureName, ) const rwBinPath = path.join( REDWOOD_FRAMEWORK_PATH, - 'packages/cli/dist/index.js' + 'packages/cli/dist/index.js', ) const rwfwBinPath = path.join( REDWOOD_FRAMEWORK_PATH, - 'packages/cli/dist/rwfw.js' + 'packages/cli/dist/rwfw.js', ) console.log(`Creating project at ${testProjectPath}`) diff --git a/.github/actions/check_changesets/check_changesets.mjs b/.github/actions/check_changesets/check_changesets.mjs index 334b23bf9455..07c7418e1466 100644 --- a/.github/actions/check_changesets/check_changesets.mjs +++ b/.github/actions/check_changesets/check_changesets.mjs @@ -5,7 +5,9 @@ import github from '@actions/github' async function main() { // If the PR has the "changesets-ok" label, just pass. const { labels } = JSON.parse(getInput('labels')) - const hasChangesetsOkLabel = labels.some((label) => label.name === 'changesets-ok') + const hasChangesetsOkLabel = labels.some( + (label) => label.name === 'changesets-ok', + ) if (hasChangesetsOkLabel) { console.log('Skipping check because of the "changesets-ok" label') return @@ -21,17 +23,18 @@ async function main() { // Check if the PR adds a changeset. await exec('git fetch origin main', [], { silent: true }) - const { stdout } = await getExecOutput('git diff origin/main --name-only', [], { silent: true }) + const { stdout } = await getExecOutput( + 'git diff origin/main --name-only', + [], + { silent: true }, + ) const changedFiles = stdout.toString().trim().split('\n').filter(Boolean) - const addedChangeset = changedFiles.some((file) => file.startsWith('.changesets/')) + const addedChangeset = changedFiles.some((file) => + file.startsWith('.changesets/'), + ) if (addedChangeset) { // Empty space here (and in subsequent `console.log`s) for formatting in the action. - console.log( - [ - '', - "Added a changeset", - ].join('\n') - ) + console.log(['', 'Added a changeset'].join('\n')) return } @@ -46,7 +49,7 @@ async function main() { 'If this is a user-facing PR (a feature or a fix), it should probably have a changeset.', `Run \`yarn changesets ${pr.number}\` to create a changeset for this PR.`, "If it doesn't need one (it's a chore), you can add the 'changesets-ok' label.", - ].join('\n') + ].join('\n'), ) process.exitCode = 1 diff --git a/.github/actions/check_create_redwood_app/check_create_redwood_app.mjs b/.github/actions/check_create_redwood_app/check_create_redwood_app.mjs index 130121c41a2a..0fd39fff6d54 100644 --- a/.github/actions/check_create_redwood_app/check_create_redwood_app.mjs +++ b/.github/actions/check_create_redwood_app/check_create_redwood_app.mjs @@ -14,7 +14,7 @@ if (hasCRWA_OkLabel) { const { stdout } = await getExecOutput('git diff origin/main --name-only') const changedFiles = stdout.toString().trim().split('\n').filter(Boolean) const didRebuildJS_Template = changedFiles.some((file) => - file.startsWith('packages/create-redwood-app/templates/js') + file.startsWith('packages/create-redwood-app/templates/js'), ) if (didRebuildJS_Template) { @@ -24,17 +24,21 @@ if (hasCRWA_OkLabel) { // because git fetch origin main prints to stdout. '', "The create redwood app JS template's been rebuilt", - ].join('\n') + ].join('\n'), ) } else { // If it doesn't, does it need to be rebuilt? If not, no problem. Otherwise, throw. - const shouldRebuildJS_Template = changedFiles.some( - (file) => - file.startsWith('packages/create-redwood-app/templates/ts') + const shouldRebuildJS_Template = changedFiles.some((file) => + file.startsWith('packages/create-redwood-app/templates/ts'), ) if (!shouldRebuildJS_Template) { - console.log(['', "The create redwood app JS template doesn't need to be rebuilt"].join('\n')) + console.log( + [ + '', + "The create redwood app JS template doesn't need to be rebuilt", + ].join('\n'), + ) } else { console.log( [ @@ -46,7 +50,7 @@ if (hasCRWA_OkLabel) { ' cd packages/create-redwood-app', ' yarn ts-to-js', '', - ].join('\n') + ].join('\n'), ) process.exitCode = 1 diff --git a/.github/actions/detect-changes/README.md b/.github/actions/detect-changes/README.md index 234c211c6d76..3ec4d8aea297 100644 --- a/.github/actions/detect-changes/README.md +++ b/.github/actions/detect-changes/README.md @@ -1,6 +1,7 @@ You can run this script locally to debug/verify Make sure you have a GITHUB_TOKEN or REDWOOD_GITHUB_TOKEN env var set, and then run this command: + ``` GITHUB_REF=refs/pull/6919/merge GITHUB_BASE_REF=main node .github/actions/detect-changes/detectChanges.mjs ``` diff --git a/.github/actions/detect-changes/cases/rsc.mjs b/.github/actions/detect-changes/cases/rsc.mjs index 796f3e7f6eb8..15bf5c117877 100644 --- a/.github/actions/detect-changes/cases/rsc.mjs +++ b/.github/actions/detect-changes/cases/rsc.mjs @@ -4,7 +4,7 @@ * @param {string[]} changedFiles The list of files which git has listed as changed * @returns {boolean} True if there are changes, false if not */ -export function rscChanged(changedFiles){ +export function rscChanged(changedFiles) { for (const changedFile of changedFiles) { // As the RSC implementation changes, this list will need to be updated. // Also, I could be much more specific here, but then I'd also have to @@ -15,7 +15,9 @@ export function rscChanged(changedFiles){ changedFile.startsWith('tasks/smoke-tests/rsa/') || changedFile.startsWith('tasks/smoke-tests/basePlaywright.config.ts') || changedFile.startsWith('.github/actions/set-up-rsa-project/') || - changedFile.startsWith('.github/actions/set-up-rsc-kitchen-sink-project/') || + changedFile.startsWith( + '.github/actions/set-up-rsc-kitchen-sink-project/', + ) || changedFile.startsWith('.github/actions/set-up-rsc-project/') || changedFile.startsWith('packages/internal/') || changedFile.startsWith('packages/project-config/') || diff --git a/.github/actions/detect-changes/cases/ssr.mjs b/.github/actions/detect-changes/cases/ssr.mjs index c3d05e7296cb..8bc6506f4465 100644 --- a/.github/actions/detect-changes/cases/ssr.mjs +++ b/.github/actions/detect-changes/cases/ssr.mjs @@ -4,7 +4,7 @@ * @param {string[]} changedFiles The list of files which git has listed as changed * @returns {boolean} True if there are changes, false if not */ -export function ssrChanged(changedFiles){ +export function ssrChanged(changedFiles) { for (const changedFile of changedFiles) { if ( changedFile.startsWith('tasks/smoke-tests/streaming-ssr') || diff --git a/.github/actions/require-milestone/requireMilestone.mjs b/.github/actions/require-milestone/requireMilestone.mjs index 3c6b76b3dfe9..f1bcb6e4da60 100644 --- a/.github/actions/require-milestone/requireMilestone.mjs +++ b/.github/actions/require-milestone/requireMilestone.mjs @@ -9,9 +9,7 @@ function main() { const event = fs.readFileSync(process.env.GITHUB_EVENT_PATH, 'utf-8') const { - pull_request: { - milestone - } + pull_request: { milestone }, } = JSON.parse(event) if (milestone) { @@ -20,16 +18,18 @@ function main() { process.exitCode = 1 - console.error([ - "A pull request must have a milestone that indicates where it's supposed to be released:", - '', - "- next-release -- the PR should be released in the next minor (it's a feature)", - "- next-release-patch -- the PR should be released in the next patch (it's a bug fix or project-side chore)", - "- v7.0.0 -- the PR should be released in v7.0.0 (it's breaking or builds off a breaking PR)", - "- chore -- the PR is a framework-side chore (changes CI, tasks, etc.) and it isn't released, per se", - '', - `(If you're still not sure, go with "next-release".)` - ].join('\n')) + console.error( + [ + "A pull request must have a milestone that indicates where it's supposed to be released:", + '', + "- next-release -- the PR should be released in the next minor (it's a feature)", + "- next-release-patch -- the PR should be released in the next patch (it's a bug fix or project-side chore)", + "- v7.0.0 -- the PR should be released in v7.0.0 (it's breaking or builds off a breaking PR)", + "- chore -- the PR is a framework-side chore (changes CI, tasks, etc.) and it isn't released, per se", + '', + `(If you're still not sure, go with "next-release".)`, + ].join('\n'), + ) } main() diff --git a/.github/actions/set-up-rsa-project/jsconfig.json b/.github/actions/set-up-rsa-project/jsconfig.json index 8effcfaa09ef..dc34d6dedca3 100644 --- a/.github/actions/set-up-rsa-project/jsconfig.json +++ b/.github/actions/set-up-rsa-project/jsconfig.json @@ -7,5 +7,5 @@ "moduleResolution": "node", "skipLibCheck": false, "jsx": "react-jsx" - }, + } } diff --git a/.github/actions/set-up-rsa-project/setUpRsaProjectGitHub.mjs b/.github/actions/set-up-rsa-project/setUpRsaProjectGitHub.mjs index 497d82e4c9bf..7657af8f9b8d 100644 --- a/.github/actions/set-up-rsa-project/setUpRsaProjectGitHub.mjs +++ b/.github/actions/set-up-rsa-project/setUpRsaProjectGitHub.mjs @@ -10,7 +10,7 @@ import { createExecWithEnvInCwd, setUpRscTestProject } from '../actionsLib.mjs' const testProjectAndFixtureName = 'test-project-rsa' const testProjectPath = path.join( path.dirname(process.cwd()), - testProjectAndFixtureName + testProjectAndFixtureName, ) const execInProject = createExecWithEnvInCwd(testProjectPath) @@ -18,5 +18,5 @@ setUpRscTestProject( testProjectPath, testProjectAndFixtureName, core, - execInProject + execInProject, ) diff --git a/.github/actions/set-up-rsa-project/setUpRsaProjectLocally.mjs b/.github/actions/set-up-rsa-project/setUpRsaProjectLocally.mjs index 8e9baa044594..8a738887fb56 100644 --- a/.github/actions/set-up-rsa-project/setUpRsaProjectLocally.mjs +++ b/.github/actions/set-up-rsa-project/setUpRsaProjectLocally.mjs @@ -78,7 +78,7 @@ const testProjectPath = path.join( 'redwood', testProjectAndFixtureName, // ":" is problematic with paths - new Date().toISOString().split(':').join('-') + new Date().toISOString().split(':').join('-'), ) // Mock for @actions/core @@ -99,7 +99,7 @@ function execInProject(commandLine, options) { return exec( commandLine, undefined, - getExecaOptions(testProjectPath, options?.env) + getExecaOptions(testProjectPath, options?.env), ) } @@ -107,5 +107,5 @@ setUpRscTestProject( testProjectPath, testProjectAndFixtureName, core, - execInProject + execInProject, ) diff --git a/.github/actions/set-up-rsc-kitchen-sink-project/jsconfig.json b/.github/actions/set-up-rsc-kitchen-sink-project/jsconfig.json index 8effcfaa09ef..dc34d6dedca3 100644 --- a/.github/actions/set-up-rsc-kitchen-sink-project/jsconfig.json +++ b/.github/actions/set-up-rsc-kitchen-sink-project/jsconfig.json @@ -7,5 +7,5 @@ "moduleResolution": "node", "skipLibCheck": false, "jsx": "react-jsx" - }, + } } diff --git a/.github/actions/set-up-rsc-kitchen-sink-project/setUpRscKitchenSinkProjectGitHub.mjs b/.github/actions/set-up-rsc-kitchen-sink-project/setUpRscKitchenSinkProjectGitHub.mjs index 27490e9f6cf3..094e85023c98 100644 --- a/.github/actions/set-up-rsc-kitchen-sink-project/setUpRscKitchenSinkProjectGitHub.mjs +++ b/.github/actions/set-up-rsc-kitchen-sink-project/setUpRscKitchenSinkProjectGitHub.mjs @@ -10,7 +10,7 @@ import { createExecWithEnvInCwd, setUpRscTestProject } from '../actionsLib.mjs' const testProjectAndFixtureName = 'test-project-rsc-kitchen-sink' const testProjectPath = path.join( path.dirname(process.cwd()), - testProjectAndFixtureName + testProjectAndFixtureName, ) const execInProject = createExecWithEnvInCwd(testProjectPath) @@ -18,5 +18,5 @@ setUpRscTestProject( testProjectPath, testProjectAndFixtureName, core, - execInProject + execInProject, ) diff --git a/.github/actions/set-up-rsc-kitchen-sink-project/setUpRscKitchenSinkProjectLocally.mjs b/.github/actions/set-up-rsc-kitchen-sink-project/setUpRscKitchenSinkProjectLocally.mjs index 41a966452833..38128b8badfd 100644 --- a/.github/actions/set-up-rsc-kitchen-sink-project/setUpRscKitchenSinkProjectLocally.mjs +++ b/.github/actions/set-up-rsc-kitchen-sink-project/setUpRscKitchenSinkProjectLocally.mjs @@ -78,7 +78,7 @@ const testProjectPath = path.join( 'redwood', testProjectAndFixtureName, // ":" is problematic with paths - new Date().toISOString().split(':').join('-') + new Date().toISOString().split(':').join('-'), ) // Mock for @actions/core @@ -99,7 +99,7 @@ function execInProject(commandLine, options) { return exec( commandLine, undefined, - getExecaOptions(testProjectPath, options?.env) + getExecaOptions(testProjectPath, options?.env), ) } @@ -107,5 +107,5 @@ setUpRscTestProject( testProjectPath, testProjectAndFixtureName, core, - execInProject + execInProject, ) diff --git a/.github/actions/set-up-rsc-project/jsconfig.json b/.github/actions/set-up-rsc-project/jsconfig.json index 8effcfaa09ef..dc34d6dedca3 100644 --- a/.github/actions/set-up-rsc-project/jsconfig.json +++ b/.github/actions/set-up-rsc-project/jsconfig.json @@ -7,5 +7,5 @@ "moduleResolution": "node", "skipLibCheck": false, "jsx": "react-jsx" - }, + } } diff --git a/.github/actions/set-up-rsc-project/setUpRscProject.mjs b/.github/actions/set-up-rsc-project/setUpRscProject.mjs index 6c2ec2f7cc17..76c247a8b5d1 100644 --- a/.github/actions/set-up-rsc-project/setUpRscProject.mjs +++ b/.github/actions/set-up-rsc-project/setUpRscProject.mjs @@ -36,22 +36,13 @@ import { REDWOOD_FRAMEWORK_PATH } from '../actionsLib.mjs' * @param {ExecInProject} execInProject * @returns {Promise} */ -export async function main( - rscProjectPath, - core, - exec, - execInProject -) { +export async function main(rscProjectPath, core, exec, execInProject) { core.setOutput('rsc-project-path', rscProjectPath) console.log('rwPath', REDWOOD_FRAMEWORK_PATH) console.log('rscProjectPath', rscProjectPath) - await setUpRscProject( - rscProjectPath, - exec, - execInProject, - ) + await setUpRscProject(rscProjectPath, exec, execInProject) } /** @@ -60,14 +51,10 @@ export async function main( * @param {ExecInProject} execInProject * @returns {Promise} */ -async function setUpRscProject( - rscProjectPath, - exec, - execInProject, -) { +async function setUpRscProject(rscProjectPath, exec, execInProject) { const rwBinPath = path.join( REDWOOD_FRAMEWORK_PATH, - 'packages/cli/dist/index.js' + 'packages/cli/dist/index.js', ) console.log(`Creating project at ${rscProjectPath}`) diff --git a/.github/actions/set-up-rsc-project/setUpRscProjectLocally.mjs b/.github/actions/set-up-rsc-project/setUpRscProjectLocally.mjs index c5c57ab2b31f..0ad4881ca2ce 100644 --- a/.github/actions/set-up-rsc-project/setUpRscProjectLocally.mjs +++ b/.github/actions/set-up-rsc-project/setUpRscProjectLocally.mjs @@ -75,7 +75,7 @@ const rscProjectPath = path.join( os.tmpdir(), 'redwood-rsc-project', // ":" is problematic with paths - new Date().toISOString().split(':').join('-') + new Date().toISOString().split(':').join('-'), ) // Mock for @actions/core @@ -96,7 +96,7 @@ function execInProject(commandLine, options) { return exec( commandLine, undefined, - getExecaOptions(rscProjectPath, options?.env) + getExecaOptions(rscProjectPath, options?.env), ) } diff --git a/.github/actions/set-up-test-project/action.yaml b/.github/actions/set-up-test-project/action.yaml index 78afea244e22..7c3528987a56 100644 --- a/.github/actions/set-up-test-project/action.yaml +++ b/.github/actions/set-up-test-project/action.yaml @@ -8,7 +8,7 @@ runs: inputs: canary: description: Upgrade the project to canary? - default: "false" + default: 'false' outputs: test-project-path: diff --git a/.github/actions/set-up-test-project/setUpTestProject.mjs b/.github/actions/set-up-test-project/setUpTestProject.mjs index eb6cbb55e3a1..5075ed383d64 100644 --- a/.github/actions/set-up-test-project/setUpTestProject.mjs +++ b/.github/actions/set-up-test-project/setUpTestProject.mjs @@ -13,16 +13,13 @@ import { REDWOOD_FRAMEWORK_PATH, } from '../actionsLib.mjs' -const TEST_PROJECT_PATH = path.join( - path.dirname(process.cwd()), - 'test-project' -) +const TEST_PROJECT_PATH = path.join(path.dirname(process.cwd()), 'test-project') core.setOutput('test-project-path', TEST_PROJECT_PATH) const canary = core.getInput('canary') === 'true' console.log({ - canary + canary, }) console.log() @@ -32,7 +29,7 @@ console.log() */ async function main() { await setUpTestProject({ - canary: true + canary: true, }) } @@ -44,14 +41,16 @@ async function setUpTestProject({ canary }) { const TEST_PROJECT_FIXTURE_PATH = path.join( REDWOOD_FRAMEWORK_PATH, '__fixtures__', - 'test-project' + 'test-project', ) console.log(`Creating project at ${TEST_PROJECT_PATH}`) console.log() await fs.copy(TEST_PROJECT_FIXTURE_PATH, TEST_PROJECT_PATH) - await execInFramework('yarn project:tarsync --verbose', { env: { RWJS_CWD: TEST_PROJECT_PATH } }) + await execInFramework('yarn project:tarsync --verbose', { + env: { RWJS_CWD: TEST_PROJECT_PATH }, + }) if (canary) { console.log(`Upgrading project to canary`) @@ -69,20 +68,17 @@ const execInProject = createExecWithEnvInCwd(TEST_PROJECT_PATH) */ async function sharedTasks() { console.log('Generating dbAuth secret') - const { stdout } = await execInProject( - 'yarn rw g secret --raw', - { silent: true } - ) + const { stdout } = await execInProject('yarn rw g secret --raw', { + silent: true, + }) fs.appendFileSync( path.join(TEST_PROJECT_PATH, '.env'), - `SESSION_SECRET='${stdout}'` + `SESSION_SECRET='${stdout}'`, ) console.log() console.log('Running prisma migrate reset') - await execInProject( - 'yarn rw prisma migrate reset --force', - ) + await execInProject('yarn rw prisma migrate reset --force') } main() diff --git a/.github/actions/telemetry_check/check.mjs b/.github/actions/telemetry_check/check.mjs index 54e34c79b54a..4191dad81b49 100644 --- a/.github/actions/telemetry_check/check.mjs +++ b/.github/actions/telemetry_check/check.mjs @@ -6,7 +6,7 @@ import path from 'path' import { exec } from '@actions/exec' console.log( - `Telemetry is being redirected to ${process.env.REDWOOD_REDIRECT_TELEMETRY}` + `Telemetry is being redirected to ${process.env.REDWOOD_REDIRECT_TELEMETRY}`, ) // Setup fake telemetry server @@ -37,23 +37,21 @@ try { switch (mode) { case 'crwa': exitCode = await exec( - `yarn node ./packages/create-redwood-app/dist/create-redwood-app.js ../project-for-telemetry --typescript true --git false --no-yarn-install` + `yarn node ./packages/create-redwood-app/dist/create-redwood-app.js ../project-for-telemetry --typescript true --git false --no-yarn-install`, ) if (exitCode) { process.exit(1) } break case 'cli': - exitCode = await exec( - `yarn install`, null, { - cwd: path.join(process.cwd(), '../project-for-telemetry') - } - ) + exitCode = await exec(`yarn install`, null, { + cwd: path.join(process.cwd(), '../project-for-telemetry'), + }) if (exitCode) { process.exit(1) } exitCode = await exec( - `yarn --cwd ../project-for-telemetry node ../redwood/packages/cli/dist/index.js info` + `yarn --cwd ../project-for-telemetry node ../redwood/packages/cli/dist/index.js info`, ) if (exitCode) { process.exit(1) diff --git a/.github/scripts/publish_canary.sh b/.github/scripts/publish_canary.sh index 3ed23efcc4fd..321113d1d8fe 100755 --- a/.github/scripts/publish_canary.sh +++ b/.github/scripts/publish_canary.sh @@ -33,14 +33,14 @@ args+=( # final number that lerna will use when publishing the canary packages. echo 'n' \ | yarn lerna publish "${args[@]}" 2>&1 \ - > publish_output + > publish_output cat publish_output \ | grep '\-canary\.' \ | tail -n 1 \ | sed 's/.*=> //' \ | sed 's/\+.*//' \ | awk -F. '{ $NF = $NF + 1 } 1' OFS=. \ - > canary_version + > canary_version if [ ! -s canary_version ]; then echo "The canary_version file is empty or does not exist." @@ -82,8 +82,8 @@ ws="$(yarn workspaces list --json)" IFS=$'\n' for line in $ws; do location=$( - echo "$line" | - jq -r '.location' + echo "$line" \ + | jq -r '.location' ) relative_pkg_json_path="$location/package.json" @@ -101,7 +101,7 @@ for line in $ws; do printf "Processing:\t%s\n" "$relative_pkg_json_path" sed "s/workspace:\*/$(cat canary_version)/g" "$pkg_json_path" > tmpfile \ - && mv tmpfile "$pkg_json_path" + && mv tmpfile "$pkg_json_path" done # Commit the changes diff --git a/.github/workflows/check-changelog.yml b/.github/workflows/check-changelog.yml index d854c06298c5..af5be4a6b56d 100644 --- a/.github/workflows/check-changelog.yml +++ b/.github/workflows/check-changelog.yml @@ -2,7 +2,16 @@ name: 📝 Check changesets on: pull_request: - types: [opened, synchronize, reopened, labeled, unlabeled, milestoned, demilestoned] + types: + [ + opened, + synchronize, + reopened, + labeled, + unlabeled, + milestoned, + demilestoned, + ] # Cancel in-progress runs of this workflow. # See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-only-cancel-in-progress-jobs-or-runs-for-the-current-workflow. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 579637f5f3cd..9c8b5111a84e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,7 +166,7 @@ jobs: wait-on: 'http://[::1]:8910' working-directory: ./tasks/e2e spec: | - cypress/e2e/01-tutorial/*.cy.js + cypress/e2e/01-tutorial/*.cy.js - uses: actions/upload-artifact@v4 if: always() @@ -505,7 +505,7 @@ jobs: runs-on: ${{ matrix.os }} env: - REDWOOD_REDIRECT_TELEMETRY: "http://127.0.0.1:48619" # Random port + REDWOOD_REDIRECT_TELEMETRY: 'http://127.0.0.1:48619' # Random port steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2af57bf1c982..6f575dc9468e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,10 +13,10 @@ name: 🔒 CodeQL on: push: - branches: [ main ] + branches: [main] pull_request: # The branches below must be a subset of the branches above - branches: [ main ] + branches: [main] schedule: - cron: '42 5 * * 3' @@ -34,41 +34,41 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: ['javascript'] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/codeql-config.yml - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v3 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/publish-canary.yml b/.github/workflows/publish-canary.yml index e4d5d968e260..d0775673329a 100644 --- a/.github/workflows/publish-canary.yml +++ b/.github/workflows/publish-canary.yml @@ -62,7 +62,7 @@ jobs: - name: 💬 Message Slack uses: ./.github/actions/message_slack_publishing with: - title: "🦜 Canary Packages" + title: '🦜 Canary Packages' status: ${{ needs.publish-canary.result }} version: ${{ needs.publish-canary.outputs.version }} slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL_PACKAGE_PUBLISHING }} diff --git a/.github/workflows/publish-release-candidate.yml b/.github/workflows/publish-release-candidate.yml index 1b34beff9346..85d785fab0f8 100644 --- a/.github/workflows/publish-release-candidate.yml +++ b/.github/workflows/publish-release-candidate.yml @@ -107,7 +107,7 @@ jobs: - name: 💬 Message Slack uses: ./.github/actions/message_slack_publishing with: - title: "🏎 RC Packages" + title: '🏎 RC Packages' status: ${{ needs.publish-release-candidate.result }} version: ${{ needs.publish-release-candidate.outputs.version }} slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL_PACKAGE_PUBLISHING }} diff --git a/.github/workflows/require-release-label.yml b/.github/workflows/require-release-label.yml index 6986f5239ba4..73b1624e8b03 100644 --- a/.github/workflows/require-release-label.yml +++ b/.github/workflows/require-release-label.yml @@ -19,4 +19,4 @@ jobs: with: mode: exactly count: 1 - labels: "release:docs, release:chore, release:experimental-breaking, release:fix, release:feature, release:breaking, release:dependency" + labels: 'release:docs, release:chore, release:experimental-breaking, release:fix, release:feature, release:breaking, release:dependency' diff --git a/.prettierignore b/.prettierignore index c154d8af0520..9f181bf39930 100644 --- a/.prettierignore +++ b/.prettierignore @@ -23,5 +23,4 @@ packages/create-redwood-rsc-app # TODO(jgmw): Re-enable these in managable chunks tasks -.github packages/create-redwood-app/tests/e2e_prompts* From 79f6b9c21b4644402b4938143605ce52d5c1e024 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 04:00:59 +0100 Subject: [PATCH 30/52] chore(deps): bump elliptic from 6.5.5 to 6.5.7 (#11288) Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.5 to 6.5.7.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=elliptic&package-manager=npm_and_yarn&previous-version=6.5.5&new-version=6.5.7)](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> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e432e137353e..dad43c6f8b77 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15733,8 +15733,8 @@ __metadata: linkType: hard "elliptic@npm:^6.5.3, elliptic@npm:^6.5.5": - version: 6.5.5 - resolution: "elliptic@npm:6.5.5" + version: 6.5.7 + resolution: "elliptic@npm:6.5.7" dependencies: bn.js: "npm:^4.11.9" brorand: "npm:^1.1.0" @@ -15743,7 +15743,7 @@ __metadata: inherits: "npm:^2.0.4" minimalistic-assert: "npm:^1.0.1" minimalistic-crypto-utils: "npm:^1.0.1" - checksum: 10c0/3e591e93783a1b66f234ebf5bd3a8a9a8e063a75073a35a671e03e3b25253b6e33ac121f7efe9b8808890fffb17b40596cc19d01e6e8d1fa13b9a56ff65597c8 + checksum: 10c0/799959b6c54ea3564e8961f35abdf8c77e37617f3051614b05ab1fb6a04ddb65bd1caa75ed1bae375b15dda312a0f79fed26ebe76ecf05c5a7af244152a601b8 languageName: node linkType: hard From 264bbda39a76879286892928166d52d77e454038 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 04:22:02 +0100 Subject: [PATCH 31/52] chore(formatting): include tasks dir in prettier (#11289) As title. --- .prettierignore | 1 - .../test-project/web/src/Redwood.stories.mdx | 5 +- .../tasks/generateCodemod/generateCodemod.mjs | 16 +- tasks/all-contributors/.all-contributorsrc | 1 - tasks/all-contributors/README.md | 23 ++- tasks/all-contributors/archive/README.md | 35 ++++- .../archive/mergeContributors.js | 4 +- tasks/changesets/changesets.mts | 2 +- tasks/changesets/changesetsHelpers.mts | 8 +- tasks/downgradeToReact18.mts | 2 +- tasks/framework-tools/lib/project.mjs | 18 +-- tasks/framework-tools/lib/viteConfig.mjs | 10 +- tasks/framework-tools/tarsync.mjs | 26 ++-- tasks/generateDependencyGraph.mjs | 4 +- tasks/getPackagesVersionsForTag.mjs | 6 +- tasks/k6-test/README.md | 1 + tasks/k6-test/run-k6-tests.mts | 83 +++++++--- .../setups/context_magic_number/setup.mts | 23 ++- .../context_magic_number/templates/func.ts | 2 +- .../setups/scalable_graphql_schema/setup.mts | 49 ++---- tasks/k6-test/util/util.mts | 56 ++++--- tasks/linting-diff/lintingDiff.mts | 56 ++++--- tasks/nmHoisting/README.md | 42 +++--- tasks/nmHoisting/nmHoisting.mjs | 4 +- tasks/nmHoisting/nmHoistingVisualize.html | 85 ++++++----- tasks/nmHoisting/nmHoistingVisualize.js | 16 +- tasks/server-tests/bothServer.test.mts | 4 +- tasks/server-tests/bothServerAPI.test.mts | 5 +- tasks/server-tests/bothServerWeb.test.mts | 5 +- .../fixtures/redwood-app/api/server.config.js | 16 +- tasks/server-tests/vitest.config.mts | 6 +- tasks/server-tests/vitest.setup.mts | 40 +++-- .../smoke-tests/auth/tests/authChecks.spec.ts | 12 +- .../smoke-tests/auth/tests/rbacChecks.spec.ts | 14 +- .../fragments-dev/tests/fragments.spec.ts | 2 +- .../fragments-serve/tests/fragments.spec.ts | 2 +- tasks/smoke-tests/jsconfig.json | 4 +- .../prerender/tests/prerender.spec.ts | 20 +-- tasks/smoke-tests/rsa/tests/rsa.spec.ts | 2 +- tasks/smoke-tests/shared/common.ts | 20 +-- tasks/smoke-tests/shared/delayedPage.ts | 2 +- tasks/smoke-tests/smoke-tests.mjs | 48 +++--- .../tests/progressiveRendering.spec.ts | 8 +- .../tests/botRendering.spec.ts | 2 +- .../test-project/codemods/Redwood.stories.mdx | 5 +- tasks/test-project/codemods/authorCell.js | 4 +- tasks/test-project/codemods/blogLayout.js | 4 +- tasks/test-project/codemods/blogPost.js | 2 +- tasks/test-project/codemods/blogPostCell.js | 4 +- tasks/test-project/codemods/blogPostsCell.js | 4 +- tasks/test-project/codemods/contactsSdl.js | 2 +- tasks/test-project/codemods/delayedPage.js | 6 +- tasks/test-project/codemods/groceriesPage.ts | 24 +-- tasks/test-project/codemods/routes.js | 14 +- .../codemods/updateAuthorStories.js | 22 +-- .../test-project/codemods/updateAuthorTest.js | 16 +- .../codemods/updateBlogPostPageStories.js | 18 +-- .../codemods/updateWaterfallPageStories.js | 18 +-- tasks/test-project/codemods/usersSdl.js | 2 +- tasks/test-project/codemods/usersService.js | 36 ++--- .../codemods/waterfallBlogPostCell.js | 4 +- tasks/test-project/codemods/waterfallPage.js | 2 +- .../rebuild-fragments-test-project-fixture.ts | 40 ++--- .../rebuild-test-project-fixture.ts | 73 +++++---- .../test-project/set-up-trusted-documents.ts | 12 +- tasks/test-project/tasks.js | 142 +++++++++--------- .../test-project/templates/web/FruitInfo.tsx | 22 ++- .../templates/web/ProduceInfo.tsx | 14 +- .../test-project/templates/web/StallInfo.tsx | 14 +- .../templates/web/VegetableInfo.tsx | 22 ++- tasks/test-project/util.js | 6 +- tasks/tsconfig.json | 4 +- tasks/update-package-versions | 6 +- 73 files changed, 711 insertions(+), 621 deletions(-) diff --git a/.prettierignore b/.prettierignore index 9f181bf39930..d542685cc9d2 100644 --- a/.prettierignore +++ b/.prettierignore @@ -22,5 +22,4 @@ packages/create-redwood-rsc-app **/__tests__/fixtures # TODO(jgmw): Re-enable these in managable chunks -tasks packages/create-redwood-app/tests/e2e_prompts* diff --git a/__fixtures__/test-project/web/src/Redwood.stories.mdx b/__fixtures__/test-project/web/src/Redwood.stories.mdx index 4481bff2fdc9..d0ef9e47cfcb 100644 --- a/__fixtures__/test-project/web/src/Redwood.stories.mdx +++ b/__fixtures__/test-project/web/src/Redwood.stories.mdx @@ -3,7 +3,10 @@ import { Meta } from '@storybook/addon-docs'

- +

Redwood

diff --git a/packages/codemods/tasks/generateCodemod/generateCodemod.mjs b/packages/codemods/tasks/generateCodemod/generateCodemod.mjs index 32d5347ddc4f..faff6b6bd4ff 100644 --- a/packages/codemods/tasks/generateCodemod/generateCodemod.mjs +++ b/packages/codemods/tasks/generateCodemod/generateCodemod.mjs @@ -58,17 +58,17 @@ await generateCodemod(version, name, kind) async function generateCodemod(version, name, kind) { console.log( `Generating ${chalk.green(kind)} codemod ${chalk.green( - name - )} for ${chalk.green(version)}...` + name, + )} for ${chalk.green(version)}...`, ) // Make the destination. const dest = new URL( `../../src/codemods/${version}/${name}/`, - import.meta.url + import.meta.url, ) const [testFixturesDest, testsDest] = ['__testfixtures__/', '__tests__/'].map( - (dir) => new URL(dir, dest) + (dir) => new URL(dir, dest), ) for (const dir of [testFixturesDest, testsDest]) { fs.mkdirSync(dir, { recursive: true }) @@ -80,18 +80,18 @@ async function generateCodemod(version, name, kind) { // __testfixtures__ fse.copySync( url.fileURLToPath(new URL('__testfixtures__', src)), - url.fileURLToPath(testFixturesDest) + url.fileURLToPath(testFixturesDest), ) // __tests__ const codemodTestTs = template( - fs.readFileSync(new URL('__tests__/codemod.test.ts.template', src), 'utf8') + fs.readFileSync(new URL('__tests__/codemod.test.ts.template', src), 'utf8'), )({ name }) fs.writeFileSync(new URL(`${name}.test.ts`, testsDest), codemodTestTs) // codemod.ts const codemodTs = template( - fs.readFileSync(new URL('codemod.ts.template', src), 'utf8') + fs.readFileSync(new URL('codemod.ts.template', src), 'utf8'), )({ name }) fs.writeFileSync(new URL(`${name}.ts`, dest), codemodTs) @@ -99,7 +99,7 @@ async function generateCodemod(version, name, kind) { const { titleName, kebabName } = makeNameVariants(name) const codemodYargsTs = template( - fs.readFileSync(new URL('codemod.yargs.ts.template', src)) + fs.readFileSync(new URL('codemod.yargs.ts.template', src)), )({ titleName, kebabName, diff --git a/tasks/all-contributors/.all-contributorsrc b/tasks/all-contributors/.all-contributorsrc index a8fcbd6ed8f5..ccb1a6b2fe8c 100644 --- a/tasks/all-contributors/.all-contributorsrc +++ b/tasks/all-contributors/.all-contributorsrc @@ -3190,4 +3190,3 @@ } ] } - diff --git a/tasks/all-contributors/README.md b/tasks/all-contributors/README.md index b072f426aaf4..48d0720272bc 100644 --- a/tasks/all-contributors/README.md +++ b/tasks/all-contributors/README.md @@ -1,5 +1,7 @@ # All-Contributors + + - [All-Contributors](#all-contributors) - [Purpose and Vision](#purpose-and-vision) - [Lead](#lead) @@ -10,23 +12,28 @@ - [Contributing](#contributing) ## Purpose and Vision + Redwood has a vibrant community that we want to highlight as much as possible. Using the [All-contributors](https://allcontributors.org/) specifications and CLI, this project allows us to: + - track the Framework, create-redwood-app, and Redwoodjs.com repo contributors - display the aggregated list of contributors in the [Contributors section](https://github.com/redwoodjs/redwood/blob/main/README.md#contributors) of the root README.md ## Lead + [@thedavidprice](https://github.com/thedavidprice) ## Managing All-Contributors Data + In general, this is a three-part process: + 1. Update the three `.all-contributorsrc` file with new contributors 2. Update README.md#Contributors with changes - ->When adding contributors, use this "type" key for specific repos: ->- 💻 (code) == Framework +> When adding contributors, use this "type" key for specific repos: > ->The "type" is required and we used to differentiate for various repos. But we don't display it. +> - 💻 (code) == Framework +> +> The "type" is required and we used to differentiate for various repos. But we don't display it. ### Step 1: Check for new contributors and add to `*rc` files @@ -34,6 +41,7 @@ In general, this is a three-part process: > Do not add [bot] accounts to the files. > > Also, members of the Core Team are manually added to the relevant section of #contributors. To avoid duplication, do not add the following profiles to .all-contributorsrc: +> > - peterp > - thedavidprice > - mojombo @@ -57,12 +65,11 @@ In general, this is a three-part process: > - chrisvdm > - realStandal > - virtuoushub -> ==BOTS== +> ==BOTS== > - dependabot[bot] > - renovate[bot] > - codesee-architecture-diagrams[bot] - ```js cd tasks/all-contributors @@ -74,6 +81,7 @@ yarn all-contributors add --config .all-contributorsrc code ``` ### Step 2: Update the content in README.md#Contributors + ```bash yarn all-contributors generate --contributorsPerLine 5 --config .all-contributorsrc ``` @@ -81,9 +89,12 @@ yarn all-contributors generate --contributorsPerLine 5 --config .all-contributor Don't forget to commit and PR changes. ## Roadmap + - [ ] Create a script to handle Step 1 (check and add new contributors for each repo) ## Contributing + Help with this project is welcome and needed! No specific experience required. You'll want to be familiar with: + - All-contributors [config](https://allcontributors.org/docs/en/cli/configuration) and [CLI](https://allcontributors.org/docs/en/cli/usage) - [GH Actions (Node.js)](https://docs.github.com/en/actions/language-and-framework-guides/using-nodejs-with-github-actions) diff --git a/tasks/all-contributors/archive/README.md b/tasks/all-contributors/archive/README.md index 3e6917af81aa..d758e805ac99 100644 --- a/tasks/all-contributors/archive/README.md +++ b/tasks/all-contributors/archive/README.md @@ -1,5 +1,7 @@ # All-Contributors + + - [Purpose and Vision](#Purpose-and-Vision) - [Package Lead](#Package-Lead) - [Managing All-Contributors Data](#step-2-merge-contributors-into-main-file) @@ -7,15 +9,20 @@ - [Contributing](#Contributing) ## Purpose and Vision + Redwood has a vibrant community that we want to highlight as much as possible. Using the [All-contributors](https://allcontributors.org/) specifications and CLI, this project allows us to: + - track the Framework, create-redwood-app, and Redwoodjs.com repo contributors - display the aggregated list of contributors in the [Contributors section](https://github.com/redwoodjs/redwood/blob/main/README.md#contributors) of the root README.md ## Lead + [@thedavidprice](https://github.com/thedavidprice) ## Managing All-Contributors Data + In general, this is a three-part process: + 1. Update the three `*.all-contributorsrc` files with new contributors 2. Merge changes into the main `.all-contributorsrc` file 3. Update README.md#Contributors with changes @@ -25,25 +32,30 @@ In general, this is a three-part process: **Framework** `redwoodjs/redwood` project: _note: this file is also used for all aggregated contributors_ + - `.all-contributorsrc` **Website** `redwoodjs/redwoodjs.com` project: + - `.rwjs.com.all-contributorsrc` **Learn** `redwoodjs/learn.redwoodjs.com` project: + - `.learn.all-contributorsrc` // Archived **CRWA** `redwoodjs/create-redwood-app` project: + - `.crwa.all-contributorsrc` ->When adding contributors, use this "type" key for specific repos: ->- 💻 (code) == Framework ->- 📖 (doc) == Redwoodjs.com ->- 🔧 (tool) == Create-Redwood-App ->- ✅ (tutorial) == Learn.Redwoodjs.com +> When adding contributors, use this "type" key for specific repos: > ->The "type" is required. +> - 💻 (code) == Framework +> - 📖 (doc) == Redwoodjs.com +> - 🔧 (tool) == Create-Redwood-App +> - ✅ (tutorial) == Learn.Redwoodjs.com +> +> The "type" is required. ### Step 1: Check for new contributors and add to `*rc` files @@ -53,6 +65,7 @@ _note: this file is also used for all aggregated contributors_ > Do not add [bot] accounts to the files. > > Also, members of the Core Team are manually added to the #core-team section. To avoid duplication, do not add the following profiles to the files below: +> > - peterp > - thedavidprice > - mojombo @@ -76,12 +89,13 @@ _note: this file is also used for all aggregated contributors_ > - chrisvdm > - realStandal > - virtuoushub -> ==BOTS== +> ==BOTS== > - dependabot[bot] > - renovate[bot] > - codesee-architecture-diagrams[bot] #### Framework + ```js yarn all-contributors check --config .all-contributorsrc @@ -91,6 +105,7 @@ yarn all-contributors add --config .all-contributorsrc code ``` #### Redwoodjs.com + ```js yarn all-contributors check --config .rwjs.com.all-contributorsrc @@ -100,6 +115,7 @@ yarn all-contributors add --config .rwjs.com.all-contributorsrc do ``` #### Learn.Redwoodjs.com + ```js yarn all-contributors check --config .learn.all-contributorsrc @@ -109,6 +125,7 @@ yarn all-contributors add --config .learn.all-contributorsrc tutor ``` ### Step 2: Merge contributors into main file + This script will add contributors from Redwoodjs.com and CRWA repos into the Framework file (if they don't already exist). It will also update the "type" of contribution for existing contributors. ```bash @@ -116,6 +133,7 @@ node mergeContributors.js ``` ### Step 3: Update the content in README.md#Contributors + ```bash yarn all-contributors generate --contributorsPerLine 5 --config .all-contributorsrc ``` @@ -123,10 +141,13 @@ yarn all-contributors generate --contributorsPerLine 5 --config .all-contributor Don't forget to commit and PR changes. ## Roadmap + - [ ] Create a script to handle Step 1 (check and add new contributors for each repo) - [ ] Convert these scripts into a GH Action that runs daily ## Contributing + Help with this project is welcome and needed! No specific experience required. You'll want to be familiar with: + - All-contributors [config](https://allcontributors.org/docs/en/cli/configuration) and [CLI](https://allcontributors.org/docs/en/cli/usage) - [GH Actions (Node.js)](https://docs.github.com/en/actions/language-and-framework-guides/using-nodejs-with-github-actions) diff --git a/tasks/all-contributors/archive/mergeContributors.js b/tasks/all-contributors/archive/mergeContributors.js index 47aa26b9e84b..a1d0f0e05588 100644 --- a/tasks/all-contributors/archive/mergeContributors.js +++ b/tasks/all-contributors/archive/mergeContributors.js @@ -17,7 +17,7 @@ const contribFiles = [ async function main() { console.log( - 'Initial count of contributors: ' + mainContribFile.contributors.length + 'Initial count of contributors: ' + mainContribFile.contributors.length, ) for (file of contribFiles) { let currentFile = JSON.parse(fs.readFileSync(file)) @@ -42,7 +42,7 @@ async function main() { } } console.log( - 'Updated count of contributors: ' + mainContribFile.contributors.length + 'Updated count of contributors: ' + mainContribFile.contributors.length, ) await fs.writeFileSync(targetFile, JSON.stringify(mainContribFile, null, 2)) console.log(`Successfully updated "${targetFile}"`) diff --git a/tasks/changesets/changesets.mts b/tasks/changesets/changesets.mts index 83f8c1a7ced5..b47058b62f8b 100755 --- a/tasks/changesets/changesets.mts +++ b/tasks/changesets/changesets.mts @@ -23,7 +23,7 @@ async function main() { [ `📝 Created a changeset at ${chalk.magenta(changesetFilePath)}`, " Commit it when you're done and push your branch up to GitHub. Thank you! 🙏", - ].join('\n') + ].join('\n'), ) } diff --git a/tasks/changesets/changesetsHelpers.mts b/tasks/changesets/changesetsHelpers.mts index c0ac7aef8f0c..8fc5c39ece02 100644 --- a/tasks/changesets/changesetsHelpers.mts +++ b/tasks/changesets/changesetsHelpers.mts @@ -1,7 +1,8 @@ import { fileURLToPath } from 'node:url' import { humanId } from 'human-id' -import { $, argv, path, fs, ProcessPromise } from 'zx' +import type { ProcessPromise } from 'zx' +import { $, argv, path, fs } from 'zx' const ROOT_DIR_PATH = fileURLToPath(new URL('../../', import.meta.url)) const DIRNAME = path.dirname(fileURLToPath(new URL(import.meta.url))) @@ -64,10 +65,7 @@ export async function resolveArgv() { return { prNumber: pr?.number ?? undefined } } - if ( - typeof maybePrNumber === 'string' && - maybePrNumber.startsWith('#') - ) { + if (typeof maybePrNumber === 'string' && maybePrNumber.startsWith('#')) { return { prNumber: +maybePrNumber.replace('#', '') } } if (typeof maybePrNumber === 'number') { diff --git a/tasks/downgradeToReact18.mts b/tasks/downgradeToReact18.mts index 4de28998c87e..f4aef0bb7514 100644 --- a/tasks/downgradeToReact18.mts +++ b/tasks/downgradeToReact18.mts @@ -44,7 +44,7 @@ async function parsePackageJsonFiles(packageJsonFilePaths: string[]) { } async function downgradeReactVersion(packageJsonArray: PackageJson[]) { - const targetReactVersion = "18.3.1" + const targetReactVersion = '18.3.1' for (const packageJson of packageJsonArray) { if (packageJson.dependencies?.react?.startsWith('19.')) { packageJson.dependencies.react = targetReactVersion diff --git a/tasks/framework-tools/lib/project.mjs b/tasks/framework-tools/lib/project.mjs index 7ef9ba3ce4af..b80ddee06637 100644 --- a/tasks/framework-tools/lib/project.mjs +++ b/tasks/framework-tools/lib/project.mjs @@ -92,17 +92,17 @@ export function fixProjectBinaries(projectPath) { */ export function addDependenciesToPackageJson( packageJsonPath, - dependencies = getFrameworkDependencies() + dependencies = getFrameworkDependencies(), ) { const packageJsonLink = terminalLink( 'package.json', - 'file://' + packageJsonPath + 'file://' + packageJsonPath, ) const numberOfDependencies = Object.keys(dependencies).length const spinner = ora( - `Adding ${numberOfDependencies} framework dependencies to ${packageJsonLink}...` + `Adding ${numberOfDependencies} framework dependencies to ${packageJsonLink}...`, ).start() const packageJson = fs.readJSONSync(packageJsonPath) @@ -115,7 +115,7 @@ export function addDependenciesToPackageJson( fs.writeJSONSync(packageJsonPath, packageJson, { spaces: 2 }) spinner.succeed( - `Added ${numberOfDependencies} framework dependencies to ${packageJsonLink}` + `Added ${numberOfDependencies} framework dependencies to ${packageJsonLink}`, ) } @@ -134,8 +134,8 @@ export function installProjectPackages(projectPath) { spinner.warn( `Error running 'yarn install', check ${terminalLink( 'yarn-error.log', - 'file://' + path.join(projectPath, 'yarn-error.log') - )} for more information.` + 'file://' + path.join(projectPath, 'yarn-error.log'), + )} for more information.`, ) console.log('-'.repeat(80)) @@ -144,7 +144,7 @@ export function installProjectPackages(projectPath) { export async function copyFrameworkFilesToProject( projectPath, - packageJsonPaths = getFrameworkPackageJsonPaths() + packageJsonPaths = getFrameworkPackageJsonPaths(), ) { // Loop over every package, delete all existing files and copy over the new files const packagesFiles = await getFrameworkPackagesFiles(packageJsonPaths) @@ -155,7 +155,7 @@ export async function copyFrameworkFilesToProject( path.dirname(packagePath) return packageNamesToPaths }, - {} + {}, ) for (const [packageName, files] of Object.entries(packagesFiles)) { @@ -164,7 +164,7 @@ export async function copyFrameworkFilesToProject( console.log( terminalLink(packageName, 'file://' + packageDistPath), files.length, - 'files' + 'files', ) await rimraf(packageDistPath) diff --git a/tasks/framework-tools/lib/viteConfig.mjs b/tasks/framework-tools/lib/viteConfig.mjs index 4d6dd727c620..e686b49259f5 100644 --- a/tasks/framework-tools/lib/viteConfig.mjs +++ b/tasks/framework-tools/lib/viteConfig.mjs @@ -52,7 +52,7 @@ function modifyViteConfigToForceOptimize(code) { (prop) => babelTypes.isObjectProperty(prop) && babelTypes.isIdentifier(prop.key) && - prop.key.name === 'force' + prop.key.name === 'force', ) if (forceProp) { @@ -61,20 +61,20 @@ function modifyViteConfigToForceOptimize(code) { optimizeDepsProp.value.properties.push( babelTypes.objectProperty( babelTypes.identifier('force'), - babelTypes.booleanLiteral(true) - ) + babelTypes.booleanLiteral(true), + ), ) } } } else { const forceProp = babelTypes.objectProperty( babelTypes.identifier('force'), - babelTypes.booleanLiteral(true) + babelTypes.booleanLiteral(true), ) optimizeDepsProp = babelTypes.objectProperty( babelTypes.identifier('optimizeDeps'), - babelTypes.objectExpression([forceProp]) + babelTypes.objectExpression([forceProp]), ) properties.push(optimizeDepsProp) diff --git a/tasks/framework-tools/tarsync.mjs b/tasks/framework-tools/tarsync.mjs index 6eb3c9d49334..b8b4852cf4e6 100644 --- a/tasks/framework-tools/tarsync.mjs +++ b/tasks/framework-tools/tarsync.mjs @@ -80,7 +80,7 @@ async function parseArgs() { ' 2. the `RWJS_CWD` env var', '', chalk.gray(' RWJS_CWD=/path/to/redwood/project yarn project:tarsync'), - ].join('\n') + ].join('\n'), ) } @@ -111,7 +111,7 @@ async function getOptions() { const mockSpinner = { text: '', - succeed: () => { }, + succeed: () => {}, } function getProjectSpinner({ text }) { @@ -140,19 +140,23 @@ async function moveTarballs(projectPath) { tarballs.map((tarball) => fs.move(tarball, path.join(tarballDest, path.basename(tarball)), { overwrite: true, - }) - ) + }), + ), ) } async function getReactResolutions() { - const packageConfig = await fs.readJson(path.join(FRAMEWORK_PATH, 'packages/web/package.json')) + const packageConfig = await fs.readJson( + path.join(FRAMEWORK_PATH, 'packages/web/package.json'), + ) const react = packageConfig.peerDependencies.react const reactDom = packageConfig.peerDependencies['react-dom'] if (!react || !reactDom) { - throw new Error("Couldn't find react or react-dom in @redwoodjs/web's peerDependencies") + throw new Error( + "Couldn't find react or react-dom in @redwoodjs/web's peerDependencies", + ) } return { @@ -172,8 +176,9 @@ async function updateResolutions(projectPath) { return { ...resolutions, // Turn a Redwood package name like `@redwoodjs/project-config` into `redwoodjs-project-config.tgz`. - [name]: `./${TARBALL_DEST_DIRNAME}/${name.replace('@', '').replaceAll('/', '-') + '.tgz' - }`, + [name]: `./${TARBALL_DEST_DIRNAME}/${ + name.replace('@', '').replaceAll('/', '-') + '.tgz' + }`, } }, {}) @@ -187,12 +192,12 @@ async function updateResolutions(projectPath) { resolutions: { ...projectPackageJson.resolutions, ...resolutions, - ...(await getReactResolutions()) + ...(await getReactResolutions()), }, }, { spaces: 2, - } + }, ) } @@ -212,5 +217,4 @@ async function yarnInstall(projectPath) { spinner.succeed(`finished in ${(entry.duration / 1000).toFixed(2)} seconds`) }) - } diff --git a/tasks/generateDependencyGraph.mjs b/tasks/generateDependencyGraph.mjs index 4c486086ef4c..c37917b72323 100644 --- a/tasks/generateDependencyGraph.mjs +++ b/tasks/generateDependencyGraph.mjs @@ -82,8 +82,8 @@ async function main() { console.log( `Wrote ${chalk.magenta(base)} dependency graph to ${chalk.magenta( - outputPath - )}` + outputPath, + )}`, ) if (values.open) { diff --git a/tasks/getPackagesVersionsForTag.mjs b/tasks/getPackagesVersionsForTag.mjs index b764d9071a9d..2dfa0a1ad8d7 100644 --- a/tasks/getPackagesVersionsForTag.mjs +++ b/tasks/getPackagesVersionsForTag.mjs @@ -21,7 +21,7 @@ async function main() { 'If provided, will ONLY display packages where current version != expectedVersion', '', '', - ].join('\n') + ].join('\n'), ) return @@ -58,8 +58,8 @@ async function main() { `yarn npm info ${packageName}@${tag} --fields version --json`, { encoding: 'utf-8', - } - ) + }, + ), ) namesToVersions[packageName] = version diff --git a/tasks/k6-test/README.md b/tasks/k6-test/README.md index 81f30fc8e63b..62ccbf3893e0 100644 --- a/tasks/k6-test/README.md +++ b/tasks/k6-test/README.md @@ -1,6 +1,7 @@ # K6 Task ## Usage + ``` yarn test:k6 [project-directory] ``` diff --git a/tasks/k6-test/run-k6-tests.mts b/tasks/k6-test/run-k6-tests.mts index 0a177fae6654..18dc756ff576 100755 --- a/tasks/k6-test/run-k6-tests.mts +++ b/tasks/k6-test/run-k6-tests.mts @@ -3,19 +3,28 @@ import os from 'node:os' import path from 'node:path' -import url from "node:url" +import url from 'node:url' import chalk from 'chalk' -import execa, { ExecaChildProcess } from 'execa' +import type { ExecaChildProcess } from 'execa' +import execa from 'execa' import fg from 'fast-glob' import fs from 'fs-extra' import { hideBin } from 'yargs/helpers' import yargs from 'yargs/yargs' -import { buildRedwoodFramework, addFrameworkDepsToProject, cleanUp, copyFrameworkPackages, createRedwoodJSApp, initGit, runYarnInstall } from "./util/util.mjs" +import { + buildRedwoodFramework, + addFrameworkDepsToProject, + cleanUp, + copyFrameworkPackages, + createRedwoodJSApp, + initGit, + runYarnInstall, +} from './util/util.mjs' // useful consts -const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) // Parse input const args = yargs(hideBin(process.argv)) @@ -38,7 +47,7 @@ const REDWOOD_PROJECT_DIRECTORY = os.tmpdir(), 'redwood-k6-test', // ":" is problematic with paths - new Date().toISOString().split(':').join('-') + new Date().toISOString().split(':').join('-'), ) const SETUPS_DIR = path.join(__dirname, 'setups') @@ -50,7 +59,7 @@ const API_SERVER_COMMANDS = [ }, { cmd: `node ${path.resolve(REDWOOD_PROJECT_DIRECTORY, 'node_modules/@redwoodjs/api-server/dist/bin.js')} api`, - host: 'http://localhost:8911' + host: 'http://localhost:8911', }, ] let cleanUpExecuted = false @@ -173,9 +182,10 @@ async function main() { // import the setup const setupFile = path.join(SETUPS_DIR, setup, 'setup.mjs') const setupModule = await import(setupFile) - const runForTests = args.test.length === 0 ? - setupModule.validForTests : - args.test.filter((test) => setupModule.validForTests.includes(test)) + const runForTests = + args.test.length === 0 + ? setupModule.validForTests + : args.test.filter((test) => setupModule.validForTests.includes(test)) console.log(`\n${divider}\nPreparing setup: ${setup}\n${divider}`) @@ -213,20 +223,34 @@ async function main() { // Run for different server commands for (let j = 0; j < API_SERVER_COMMANDS.length; j++) { console.log(`\n${divider}`) - console.log(`Running test ${i * API_SERVER_COMMANDS.length + j + 1}/${runForTests.length * API_SERVER_COMMANDS.length}: ${runForTests[i]}`) + console.log( + `Running test ${i * API_SERVER_COMMANDS.length + j + 1}/${runForTests.length * API_SERVER_COMMANDS.length}: ${runForTests[i]}`, + ) console.log(chalk.dim(API_SERVER_COMMANDS[j].cmd)) console.log(`${divider}`) // Start the server - await startServer(API_SERVER_COMMANDS[j].cmd, setupModule.startupGracePeriod) + await startServer( + API_SERVER_COMMANDS[j].cmd, + setupModule.startupGracePeriod, + ) // Run k6 test let passed = false try { - await execa('k6', ['run', path.join(TESTS_DIR, `${runForTests[i]}.js`), '--env', `TEST_HOST=${API_SERVER_COMMANDS[j].host}`], { - cwd: REDWOOD_PROJECT_DIRECTORY, - stdio: 'inherit', - }) + await execa( + 'k6', + [ + 'run', + path.join(TESTS_DIR, `${runForTests[i]}.js`), + '--env', + `TEST_HOST=${API_SERVER_COMMANDS[j].host}`, + ], + { + cwd: REDWOOD_PROJECT_DIRECTORY, + stdio: 'inherit', + }, + ) passed = true } catch (_error) { // ignore @@ -234,12 +258,17 @@ async function main() { results[setup] ??= {} results[setup][runForTests[i]] ??= {} - results[setup][runForTests[i]][API_SERVER_COMMANDS[j].cmd] = fs.readJSONSync(path.join(REDWOOD_PROJECT_DIRECTORY, 'summary.json'), { - throws: false, - flag: 'r', - encoding: 'utf-8', - }) ?? {} - results[setup][runForTests[i]][API_SERVER_COMMANDS[j].cmd].passed = passed + results[setup][runForTests[i]][API_SERVER_COMMANDS[j].cmd] = + fs.readJSONSync( + path.join(REDWOOD_PROJECT_DIRECTORY, 'summary.json'), + { + throws: false, + flag: 'r', + encoding: 'utf-8', + }, + ) ?? {} + results[setup][runForTests[i]][API_SERVER_COMMANDS[j].cmd].passed = + passed // Stop the server await stopServer() @@ -258,9 +287,15 @@ async function main() { const bgPrefix = bgColor(' ') console.log(passed ? bgColor(' PASS ') : bgColor(' FAIL ')) console.log(`${bgPrefix} Test: ${test} [${serverCommand}]`) - console.log(`${bgPrefix} Requests: ${results[setup][test][serverCommand].metrics?.http_reqs.values.count}`) - console.log(`${bgPrefix} Duration (p90): ${results[setup][test][serverCommand].metrics?.http_req_duration.values['p(90)'].toFixed(3)}`) - console.log(`${bgPrefix} TTFB (p90): ${results[setup][test][serverCommand].metrics?.http_req_waiting.values['p(90)'].toFixed(3)}`) + console.log( + `${bgPrefix} Requests: ${results[setup][test][serverCommand].metrics?.http_reqs.values.count}`, + ) + console.log( + `${bgPrefix} Duration (p90): ${results[setup][test][serverCommand].metrics?.http_req_duration.values['p(90)'].toFixed(3)}`, + ) + console.log( + `${bgPrefix} TTFB (p90): ${results[setup][test][serverCommand].metrics?.http_req_waiting.values['p(90)'].toFixed(3)}`, + ) console.log() } } diff --git a/tasks/k6-test/setups/context_magic_number/setup.mts b/tasks/k6-test/setups/context_magic_number/setup.mts index 92e02a5f448f..d729fab41150 100644 --- a/tasks/k6-test/setups/context_magic_number/setup.mts +++ b/tasks/k6-test/setups/context_magic_number/setup.mts @@ -1,23 +1,20 @@ #!/usr/bin/env node /* eslint-env node, es6*/ -import path from "node:path" -import url from "node:url" +import path from 'node:path' +import url from 'node:url' -import fs from "fs-extra" +import fs from 'fs-extra' -const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) -export const validForTests = [ - "context_functions", - "context_graphql", -] +export const validForTests = ['context_functions', 'context_graphql'] export function setup({ projectPath }: { projectPath: string }) { // Copy over SDL fs.copyFileSync( path.join(__dirname, 'templates', 'benchmark.sdl.ts'), - path.join(projectPath, 'api', 'src', 'graphql', 'benchmark.sdl.ts') + path.join(projectPath, 'api', 'src', 'graphql', 'benchmark.sdl.ts'), ) // Copy over the service @@ -26,12 +23,12 @@ export function setup({ projectPath }: { projectPath: string }) { 'api', 'src', 'services', - 'benchmarks' + 'benchmarks', ) fs.mkdirSync(benchmarkServicePath) fs.copyFileSync( path.join(__dirname, 'templates', 'benchmarks.ts'), - path.join(benchmarkServicePath, 'benchmarks.ts') + path.join(benchmarkServicePath, 'benchmarks.ts'), ) // Copy over the function @@ -39,10 +36,10 @@ export function setup({ projectPath }: { projectPath: string }) { projectPath, 'api', 'src', - 'functions' + 'functions', ) fs.copyFileSync( path.join(__dirname, 'templates', 'func.ts'), - path.join(benchmarkFunctionPath, 'func.ts') + path.join(benchmarkFunctionPath, 'func.ts'), ) } diff --git a/tasks/k6-test/setups/context_magic_number/templates/func.ts b/tasks/k6-test/setups/context_magic_number/templates/func.ts index d97e08c8a114..af7f31fe6d1e 100644 --- a/tasks/k6-test/setups/context_magic_number/templates/func.ts +++ b/tasks/k6-test/setups/context_magic_number/templates/func.ts @@ -4,7 +4,7 @@ import { setContext } from '@redwoodjs/context' export const handler = async ( event: APIGatewayProxyEvent, - _context: Context + _context: Context, ) => { const magicNumber = event.queryStringParameters?.magicNumber ?? 0 diff --git a/tasks/k6-test/setups/scalable_graphql_schema/setup.mts b/tasks/k6-test/setups/scalable_graphql_schema/setup.mts index 97fed5955577..f47fb636472d 100644 --- a/tasks/k6-test/setups/scalable_graphql_schema/setup.mts +++ b/tasks/k6-test/setups/scalable_graphql_schema/setup.mts @@ -1,21 +1,18 @@ #!/usr/bin/env node /* eslint-env node, es6*/ -import path from "node:path" -import url from "node:url" +import path from 'node:path' +import url from 'node:url' -import fs from "fs-extra" +import fs from 'fs-extra' -const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) -export const validForTests = [ - "scalable_graphql_schema", -] +export const validForTests = ['scalable_graphql_schema'] export const startupGracePeriod = 8000 export function setup({ projectPath }: { projectPath: string }) { - const modelCount = 1024 const dataCount = 64 // TODO: Have generic field count @@ -25,26 +22,20 @@ export function setup({ projectPath }: { projectPath: string }) { path.join(__dirname, 'templates', 'definition.sdl.ts'), { encoding: 'utf-8', - } + }, ) const implementationTemplate = fs.readFileSync( path.join(__dirname, 'templates', 'implementation.ts'), { encoding: 'utf-8', - } + }, ) // Copy over SDL for a relation fs.copyFileSync( path.join(__dirname, 'templates', 'relation.sdl.ts'), - path.join( - projectPath, - 'api', - 'src', - 'graphql', - 'relation.sdl.ts' - ) + path.join(projectPath, 'api', 'src', 'graphql', 'relation.sdl.ts'), ) for (let i = 0; i < modelCount; i++) { @@ -53,7 +44,7 @@ export function setup({ projectPath }: { projectPath: string }) { const queryName = `t${i}` // Generate fake data - let data: any[] = [] + const data: any[] = [] for (let j = 0; j < dataCount; j++) { data.push({ id: j, @@ -72,14 +63,8 @@ export function setup({ projectPath }: { projectPath: string }) { .replace(/__TYPE_NAME__/g, typeName) .replace(/__QUERY_NAME__/g, queryName) fs.writeFileSync( - path.join( - projectPath, - 'api', - 'src', - 'graphql', - `${typeName}.sdl.ts` - ), - specificDefinition + path.join(projectPath, 'api', 'src', 'graphql', `${typeName}.sdl.ts`), + specificDefinition, ) const specificImplementation = implementationTemplate @@ -87,13 +72,7 @@ export function setup({ projectPath }: { projectPath: string }) { .replace(/__QUERY_NAME__/g, queryName) .replace(/__DATA__/g, JSON.stringify(data)) fs.mkdirSync( - path.join( - projectPath, - 'api', - 'src', - 'services', - `${typeName}` - ) + path.join(projectPath, 'api', 'src', 'services', `${typeName}`), ) fs.writeFileSync( path.join( @@ -102,9 +81,9 @@ export function setup({ projectPath }: { projectPath: string }) { 'src', 'services', `${typeName}`, - `${typeName}.ts` + `${typeName}.ts`, ), - specificImplementation + specificImplementation, ) } } diff --git a/tasks/k6-test/util/util.mts b/tasks/k6-test/util/util.mts index e76f4df0c485..c19be123615d 100644 --- a/tasks/k6-test/util/util.mts +++ b/tasks/k6-test/util/util.mts @@ -1,12 +1,18 @@ -import path from "node:path" +import path from 'node:path' -import fg from "fast-glob" -import fs from "fs-extra" -import execa from "execa" +import chalk from 'chalk' +import execa from 'execa' +import fg from 'fast-glob' +import fs from 'fs-extra' import { rimrafSync } from 'rimraf' -import chalk from "chalk" -export function buildRedwoodFramework({frameworkPath, verbose}: {frameworkPath: string, verbose: boolean}) { +export function buildRedwoodFramework({ + frameworkPath, + verbose, +}: { + frameworkPath: string + verbose: boolean +}) { try { const files = fg.sync('packages/**/dist', { onlyDirectories: true, @@ -19,8 +25,8 @@ export function buildRedwoodFramework({frameworkPath, verbose}: {frameworkPath: { cwd: frameworkPath, shell: true, - stdio: verbose ? 'inherit': 'ignore', - } + stdio: verbose ? 'inherit' : 'ignore', + }, ) } catch (e) { if (e.signal !== 'SIGINT') { @@ -31,7 +37,17 @@ export function buildRedwoodFramework({frameworkPath, verbose}: {frameworkPath: } } -export function createRedwoodJSApp({ frameworkPath, projectPath, typescript, verbose }: { frameworkPath: string, projectPath: string, typescript: boolean, verbose: boolean }) { +export function createRedwoodJSApp({ + frameworkPath, + projectPath, + typescript, + verbose, +}: { + frameworkPath: string + projectPath: string + typescript: boolean + verbose: boolean +}) { try { execa.sync( 'yarn node dist/create-redwood-app.js', @@ -47,7 +63,7 @@ export function createRedwoodJSApp({ frameworkPath, projectPath, typescript, ver env: { REDWOOD_CI: '1' }, shell: true, stdio: verbose ? 'inherit' : 'ignore', - } + }, ) // Add prisma resolutions @@ -56,7 +72,7 @@ export function createRedwoodJSApp({ frameworkPath, projectPath, typescript, ver const getVersionFrmRwPkg = (dep, pkg) => { return fs.readJSONSync( - path.join(frameworkPath, 'packages', pkg, 'package.json') + path.join(frameworkPath, 'packages', pkg, 'package.json'), ).dependencies[dep] } @@ -80,7 +96,7 @@ export function createRedwoodJSApp({ frameworkPath, projectPath, typescript, ver export function addFrameworkDepsToProject({ frameworkPath, projectPath, - verbose + verbose, }: { frameworkPath: string projectPath: string @@ -99,7 +115,7 @@ export function addFrameworkDepsToProject({ } catch (e) { if (e.signal !== 'SIGINT') { console.error( - 'Error: Could not add Redwood Framework dependencies to project' + 'Error: Could not add Redwood Framework dependencies to project', ) console.error(e) } @@ -110,7 +126,7 @@ export function addFrameworkDepsToProject({ export function copyFrameworkPackages({ frameworkPath, projectPath, - verbose + verbose, }: { frameworkPath: string projectPath: string @@ -137,7 +153,7 @@ export function copyFrameworkPackages({ export function runYarnInstall({ projectPath, - verbose + verbose, }: { projectPath: string verbose: boolean @@ -159,7 +175,7 @@ export function runYarnInstall({ export function initGit({ projectPath, - verbose + verbose, }: { projectPath: string verbose: boolean @@ -179,7 +195,7 @@ export function initGit({ } catch (e) { if (e.signal !== 'SIGINT') { console.error( - 'There was an error with the `git init` or `git commit` step:' + 'There was an error with the `git init` or `git commit` step:', ) console.error(e) } @@ -187,11 +203,7 @@ export function initGit({ } } -export function cleanUp({ - projectPath, -}: { - projectPath: string -}) { +export function cleanUp({ projectPath }: { projectPath: string }) { const divider = chalk.blue('~'.repeat(process.stdout.columns)) console.log(`\n${divider}`) console.log('Cleaning up files (may take a few seconds)...') diff --git a/tasks/linting-diff/lintingDiff.mts b/tasks/linting-diff/lintingDiff.mts index 18bd730ec9b2..e3dc6c7701dd 100644 --- a/tasks/linting-diff/lintingDiff.mts +++ b/tasks/linting-diff/lintingDiff.mts @@ -1,6 +1,7 @@ -import { $, glob, spinner, fs, path } from 'zx' import { cpus } from 'node:os' +import { $, glob, spinner, fs, path } from 'zx' + async function getConfigsForFiles(files: string[]) { const configs = new Map() @@ -11,7 +12,9 @@ async function getConfigsForFiles(files: string[]) { const batch = files.slice(i, i + batchSize) process.stdout.clearLine(0) process.stdout.cursorTo(0) - process.stdout.write(`Progress: ${Math.min(i + batchSize, files.length)}/${files.length}`) + process.stdout.write( + `Progress: ${Math.min(i + batchSize, files.length)}/${files.length}`, + ) const promises = batch.map(async (file) => { const { stdout } = await $`yarn eslint --print-config ${file}` configs.set(file, JSON.parse(stdout)) @@ -45,15 +48,15 @@ async function main() { } // Get the configs for the files - console.log("Analyzing existing configs...") + console.log('Analyzing existing configs...') const fileExistingConfig = await getConfigsForFiles(files) // Tarsync the framework to the project to apply any changes - console.log("Tarsyncing the framework to the project...") + console.log('Tarsyncing the framework to the project...') await spinner('yarn rwfw project:tarsync', () => $`yarn rwfw project:tarsync`) // Get the configs for the files again - console.log("Analyzing updated configs...") + console.log('Analyzing updated configs...') const fileUpdatedConfig = await getConfigsForFiles(files) // Compare the configs @@ -68,38 +71,55 @@ async function main() { // Check for differences in the more simplistic keys const simpleChecks = [ - "env", - "globals", - "parser", - "plugins", - "settings", - "ignorePatterns" + 'env', + 'globals', + 'parser', + 'plugins', + 'settings', + 'ignorePatterns', ] for (const key of simpleChecks) { - if (JSON.stringify(existingConfig[key]) !== JSON.stringify(updatedConfig[key])) { + if ( + JSON.stringify(existingConfig[key]) !== + JSON.stringify(updatedConfig[key]) + ) { logAndPrint(`${file} has a different ${key} config`) } } // Check the "rules" key for differences - const allRuleKeys = new Set([...Object.keys(existingConfig.rules), ...Object.keys(updatedConfig.rules)]) + const allRuleKeys = new Set([ + ...Object.keys(existingConfig.rules), + ...Object.keys(updatedConfig.rules), + ]) for (const key of allRuleKeys) { if (!existingConfig.rules[key]) { logAndPrint(`${file} has a new rule for ${key}`) } else if (!updatedConfig.rules[key]) { logAndPrint(`${file} has a removed rule for ${key}`) - } else if (JSON.stringify(existingConfig.rules[key]) !== JSON.stringify(updatedConfig.rules[key])) { + } else if ( + JSON.stringify(existingConfig.rules[key]) !== + JSON.stringify(updatedConfig.rules[key]) + ) { logAndPrint(`${file} has a different rule for ${key}`) } } } // Write the output to files for later analysis - console.log("Writing results to files...") + console.log('Writing results to files...') const __dirname = import.meta.dirname ?? '.' - await fs.writeJSON(path.join(__dirname, 'before.json'), Object.fromEntries(fileExistingConfig), { spaces: 2 }) - await fs.writeJSON(path.join(__dirname, 'after.json'), Object.fromEntries(fileUpdatedConfig), { spaces: 2 }) - await fs.writeFile(path.join(__dirname, 'log.txt'), logs.join("\n")) + await fs.writeJSON( + path.join(__dirname, 'before.json'), + Object.fromEntries(fileExistingConfig), + { spaces: 2 }, + ) + await fs.writeJSON( + path.join(__dirname, 'after.json'), + Object.fromEntries(fileUpdatedConfig), + { spaces: 2 }, + ) + await fs.writeFile(path.join(__dirname, 'log.txt'), logs.join('\n')) } await main() diff --git a/tasks/nmHoisting/README.md b/tasks/nmHoisting/README.md index dd6e6f89e690..8e259f1cc49c 100644 --- a/tasks/nmHoisting/README.md +++ b/tasks/nmHoisting/README.md @@ -23,37 +23,37 @@ version `v6.5.1`: ```json5 { - "hoistedNodeModules": { + hoistedNodeModules: { // ... - "@redwoodjs/internal": { - "source-map": "0.7.4" + '@redwoodjs/internal': { + 'source-map': '0.7.4', }, - "@redwoodjs/cli": { - "decamelize": "5.0.1" + '@redwoodjs/cli': { + decamelize: '5.0.1', }, - "@redwoodjs/testing": { - "@types/node": "18.18.9" + '@redwoodjs/testing': { + '@types/node': '18.18.9', }, - "@redwoodjs/api": { - "@whatwg-node/fetch": "0.9.14" + '@redwoodjs/api': { + '@whatwg-node/fetch': '0.9.14', }, - "@redwoodjs/telemetry": { - "@whatwg-node/fetch": "0.9.14" + '@redwoodjs/telemetry': { + '@whatwg-node/fetch': '0.9.14', }, - "@redwoodjs/prerender": { - "@whatwg-node/fetch": "0.9.14" + '@redwoodjs/prerender': { + '@whatwg-node/fetch': '0.9.14', }, - "@redwoodjs/structure": { - "lru-cache": "7.18.3" + '@redwoodjs/structure': { + 'lru-cache': '7.18.3', }, - "@redwoodjs/graphql-server": { - "@graphql-tools/utils": "10.0.11", - "@graphql-tools/utils/cjs": "null", - "@graphql-tools/schema": "10.0.2", - "@graphql-tools/schema/cjs": "null" + '@redwoodjs/graphql-server': { + '@graphql-tools/utils': '10.0.11', + '@graphql-tools/utils/cjs': 'null', + '@graphql-tools/schema': '10.0.2', + '@graphql-tools/schema/cjs': 'null', }, // ... - } + }, } ``` diff --git a/tasks/nmHoisting/nmHoisting.mjs b/tasks/nmHoisting/nmHoisting.mjs index 1252b7bbbc68..8ca2ec3c4921 100644 --- a/tasks/nmHoisting/nmHoisting.mjs +++ b/tasks/nmHoisting/nmHoisting.mjs @@ -67,7 +67,7 @@ function batchLines(lines) { .split('\n') const name = line.match( - /^\.\/node_modules\/(?.+)\/node_modules$/ + /^\.\/node_modules\/(?.+)\/node_modules$/, )[1] obj[name] = await batchDepLines(depLines) @@ -82,7 +82,7 @@ function batchDepLines(depLines) { const version = (await $`cat ${depLine} | jq -r .version`).stdout.trim() const name = depLine.match( - /[^\.]+\/node_modules\/(?.+)\/package.json$/ + /[^\.]+\/node_modules\/(?.+)\/package.json$/, )[1] obj[name] = version diff --git a/tasks/nmHoisting/nmHoistingVisualize.html b/tasks/nmHoisting/nmHoistingVisualize.html index ec6d4aa05904..ffc69ed505fa 100644 --- a/tasks/nmHoisting/nmHoistingVisualize.html +++ b/tasks/nmHoisting/nmHoistingVisualize.html @@ -1,47 +1,58 @@ - + - - - - nmHoisting - - - -
-
-
-

nmHoisting

-

This page visualizes the data collected by the nmHoisting task.

-
-
-
- - + + + + nmHoisting + + + +
+
+
+

nmHoisting

+

+ This page visualizes the data collected by the + nmHoisting task. +

-
- - +
+
+ + +
+
+ + +
-
-

Redwood packages with nested `node_modules`

- +

Redwood packages with nested `node_modules`

+ -

All packages with nested `node_modules`

- +

All packages with nested `node_modules`

+ -

Raw data

-

+    

Raw data

+

 
-  
-  
-  
-
+    
+    
+    
+  
 
diff --git a/tasks/nmHoisting/nmHoistingVisualize.js b/tasks/nmHoisting/nmHoistingVisualize.js
index 64c2a7634b77..fb5b23dd7f42 100644
--- a/tasks/nmHoisting/nmHoistingVisualize.js
+++ b/tasks/nmHoisting/nmHoistingVisualize.js
@@ -86,7 +86,7 @@ const analyseNoComparison = () => {
   // ```
   const node_modulesS = Object.entries(node_modules).sort(
     ([_depA, nestedDepsA], [_depB, nestedDepsB]) =>
-      Object.keys(nestedDepsB).length - Object.keys(nestedDepsA).length
+      Object.keys(nestedDepsB).length - Object.keys(nestedDepsA).length,
   )
 
   const barChart = {}
@@ -134,7 +134,7 @@ const analyseNoComparison = () => {
           },
         },
       },
-    })
+    }),
   )
 
   // ------------------------
@@ -152,7 +152,7 @@ const analyseNoComparison = () => {
 
   rwBarChart.rwTooltipFooter = ([tooltipItem]) => {
     return Object.entries(
-      node_modulesS.filter(([dep]) => isRWDep(dep))[tooltipItem.dataIndex][1]
+      node_modulesS.filter(([dep]) => isRWDep(dep))[tooltipItem.dataIndex][1],
     )
       .map(getTooltipString)
       .join('\n')
@@ -199,7 +199,7 @@ const analyseNoComparison = () => {
           },
         },
       },
-    })
+    }),
   )
 }
 
@@ -251,8 +251,8 @@ const analyseWithComparison = () => {
     .sort(
       (
         [_depA, { added: addedA, removed: removedA }],
-        [_depB, { added: addedB, removed: removedB }]
-      ) => addedB.length + removedB.length - (addedA.length + removedA.length)
+        [_depB, { added: addedB, removed: removedB }],
+      ) => addedB.length + removedB.length - (addedA.length + removedA.length),
     )
     .map(([dep]) => {
       return dep
@@ -333,7 +333,7 @@ const analyseWithComparison = () => {
           },
         },
       },
-    })
+    }),
   )
 
   const redwoodKeys = sortedKeys.filter(isRWDep)
@@ -415,7 +415,7 @@ const analyseWithComparison = () => {
           },
         },
       },
-    })
+    }),
   )
 }
 
diff --git a/tasks/server-tests/bothServer.test.mts b/tasks/server-tests/bothServer.test.mts
index 11c371f35d98..c50e21477d15 100644
--- a/tasks/server-tests/bothServer.test.mts
+++ b/tasks/server-tests/bothServer.test.mts
@@ -4,7 +4,7 @@ import { $ } from 'zx'
 import { rw, rwServer } from './vitest.setup.mjs'
 
 describe('rw serve', () => {
-  it("has help configured", async () => {
+  it('has help configured', async () => {
     const { stdout } = await $`yarn node ${rw} serve --help`
     expect(stdout).toMatchInlineSnapshot(`
       "rw serve [side]
@@ -100,7 +100,7 @@ describe('rw serve', () => {
 })
 
 describe('rwServer', () => {
-  it("has help configured", async () => {
+  it('has help configured', async () => {
     const { stdout } = await $`yarn node ${rwServer} --help`
     expect(stdout).toMatchInlineSnapshot(`
       "rw-server
diff --git a/tasks/server-tests/bothServerAPI.test.mts b/tasks/server-tests/bothServerAPI.test.mts
index 2fbeed393449..8775f25bd32b 100644
--- a/tasks/server-tests/bothServerAPI.test.mts
+++ b/tasks/server-tests/bothServerAPI.test.mts
@@ -3,10 +3,7 @@ import { $ } from 'zx'
 
 import { rw, rwServer, sleep, test, testContext } from './vitest.setup.mjs'
 
-describe.each([
-  [[rw, 'serve']],
-  [rwServer],
-])('serve both (%s)', (cmd) => {
+describe.each([[[rw, 'serve']], [rwServer]])('serve both (%s)', (cmd) => {
   describe('apiPort', () => {
     it("`--apiPort` changes the api server's port", async () => {
       const apiPort = 8920
diff --git a/tasks/server-tests/bothServerWeb.test.mts b/tasks/server-tests/bothServerWeb.test.mts
index b28e365e9324..1c75f5169a2f 100644
--- a/tasks/server-tests/bothServerWeb.test.mts
+++ b/tasks/server-tests/bothServerWeb.test.mts
@@ -3,10 +3,7 @@ import { $ } from 'zx'
 
 import { rw, rwServer, test, testContext } from './vitest.setup.mjs'
 
-describe.each([
-  [[rw, 'serve']],
-  [rwServer],
-])('serve both (%s)', (cmd) => {
+describe.each([[[rw, 'serve']], [rwServer]])('serve both (%s)', (cmd) => {
   describe('webPort', () => {
     it("`--webPort` changes the web server's port", async () => {
       const webPort = 8920
diff --git a/tasks/server-tests/fixtures/redwood-app/api/server.config.js b/tasks/server-tests/fixtures/redwood-app/api/server.config.js
index 2d56f961257d..5ab723c77508 100644
--- a/tasks/server-tests/fixtures/redwood-app/api/server.config.js
+++ b/tasks/server-tests/fixtures/redwood-app/api/server.config.js
@@ -34,16 +34,13 @@ const configureFastify = async (fastify, options) => {
   if (options.side === 'api') {
     fastify.log.trace({ custom: { options } }, 'Configuring api side')
 
-    fastify.get(
-      `/rest/v1/users/get/:userId`,
-      async function (request, reply) {
-        const { userId } = request.params
+    fastify.get(`/rest/v1/users/get/:userId`, async function (request, reply) {
+      const { userId } = request.params
 
-        return reply.send({
-          id: 1
-        })
-      }
-    )
+      return reply.send({
+        id: 1,
+      })
+    })
   }
 
   if (options.side === 'web') {
@@ -61,4 +58,3 @@ module.exports = {
   config,
   configureFastify,
 }
-
diff --git a/tasks/server-tests/vitest.config.mts b/tasks/server-tests/vitest.config.mts
index 6942e5145f36..c92ec79e2122 100644
--- a/tasks/server-tests/vitest.config.mts
+++ b/tasks/server-tests/vitest.config.mts
@@ -10,8 +10,8 @@ export default defineConfig({
     pool: 'threads',
     poolOptions: {
       threads: {
-        singleThread: true
-      }
-    }
+        singleThread: true,
+      },
+    },
   },
 })
diff --git a/tasks/server-tests/vitest.setup.mts b/tasks/server-tests/vitest.setup.mts
index 6ff030978221..1af3d7a2a962 100644
--- a/tasks/server-tests/vitest.setup.mts
+++ b/tasks/server-tests/vitest.setup.mts
@@ -16,32 +16,42 @@ export const testContext: TestContext = {
   // Casting here because `beforeAll` below sets this and this file runs before all tests.
   // Working around it being possibly undefined muddies the code in the tests.
   // Also can't just call `getConfig()` because RWJS_CWD hasn't been set yet
-  projectConfig: {} as ReturnType
+  projectConfig: {} as ReturnType,
 }
 
 const __dirname = fileURLToPath(new URL('./', import.meta.url))
 // @redwoodjs/cli (yarn rw)
 export const rw = path.resolve(__dirname, '../../packages/cli/dist/index.js')
 // @redwoodjs/api-server (yarn rw-server)
-export const rwServer = path.resolve(__dirname, '../../packages/api-server/dist/bin.js')
+export const rwServer = path.resolve(
+  __dirname,
+  '../../packages/api-server/dist/bin.js',
+)
 // @redwoodjs/web-server (yarn rw-web-server)
-export const rwWebServer = path.resolve(__dirname, '../../packages/web-server/dist/bin.js')
+export const rwWebServer = path.resolve(
+  __dirname,
+  '../../packages/web-server/dist/bin.js',
+)
 
 let original_RWJS_CWD
 beforeAll(() => {
   original_RWJS_CWD = process.env.RWJS_CWD
-  const FIXTURE_PATH = fileURLToPath(new URL('./fixtures/redwood-app', import.meta.url))
+  const FIXTURE_PATH = fileURLToPath(
+    new URL('./fixtures/redwood-app', import.meta.url),
+  )
   process.env.RWJS_CWD = FIXTURE_PATH
   testContext.projectConfig = getConfig()
 
   // When running `yarn vitest run` to run all the test suites, log the bin paths only once.
   if (!globalThis.loggedBinPaths) {
-    console.log([
-      'These tests use the following commands to run the server:',
-      `• RWJS_CWD=${process.env.RWJS_CWD} yarn node ${rw} serve`,
-      `• RWJS_CWD=${process.env.RWJS_CWD} yarn node ${rwServer}`,
-      `• RWJS_CWD=${process.env.RWJS_CWD} yarn node ${rwWebServer}`,
-    ].join('\n'))
+    console.log(
+      [
+        'These tests use the following commands to run the server:',
+        `• RWJS_CWD=${process.env.RWJS_CWD} yarn node ${rw} serve`,
+        `• RWJS_CWD=${process.env.RWJS_CWD} yarn node ${rwServer}`,
+        `• RWJS_CWD=${process.env.RWJS_CWD} yarn node ${rwWebServer}`,
+      ].join('\n'),
+    )
     globalThis.loggedBinPaths = true
   }
 })
@@ -64,7 +74,7 @@ afterEach(async () => {
 })
 
 export function sleep(time = 1_000) {
-  return new Promise(resolve => setTimeout(resolve, time));
+  return new Promise((resolve) => setTimeout(resolve, time))
 }
 
 interface TestOptions {
@@ -106,8 +116,8 @@ export async function test({
   expect(webBody).toEqual(
     fs.readFileSync(
       path.join(__dirname, './fixtures/redwood-app/web/dist/about.html'),
-      'utf-8'
-    )
+      'utf-8',
+    ),
   )
 
   apiHost ??= '::'
@@ -128,7 +138,9 @@ export async function test({
   expect(apiRes.status).toEqual(200)
   expect(apiBody).toEqual({ data: 'hello function' })
 
-  const apiProxyRes = await fetch(`http://${webHost}:${webPort}${testContext.projectConfig.web.apiUrl}/hello`)
+  const apiProxyRes = await fetch(
+    `http://${webHost}:${webPort}${testContext.projectConfig.web.apiUrl}/hello`,
+  )
   const apiProxyBody = await apiProxyRes.json()
 
   expect(apiProxyRes.status).toEqual(200)
diff --git a/tasks/smoke-tests/auth/tests/authChecks.spec.ts b/tasks/smoke-tests/auth/tests/authChecks.spec.ts
index 86b4c711eb88..2472db0427d2 100644
--- a/tasks/smoke-tests/auth/tests/authChecks.spec.ts
+++ b/tasks/smoke-tests/auth/tests/authChecks.spec.ts
@@ -21,7 +21,7 @@ test('useAuth hook, auth redirects checks', async ({ page }) => {
 
   // To check redirects to the login page
   await expect(page).toHaveURL(
-    `http://localhost:8910/login?redirectTo=/profile`
+    `http://localhost:8910/login?redirectTo=/profile`,
   )
 
   await loginAsTestUser({ page, ...testUser })
@@ -30,19 +30,19 @@ test('useAuth hook, auth redirects checks', async ({ page }) => {
 
   const usernameRow = await page.waitForSelector('*css=tr >> text=EMAIL')
   await expect(await usernameRow.innerHTML()).toBe(
-    'EMAILtestuser@bazinga.com'
+    'EMAILtestuser@bazinga.com',
   )
 
   const isAuthenticatedRow = await page.waitForSelector(
-    '*css=tr >> text=isAuthenticated'
+    '*css=tr >> text=isAuthenticated',
   )
   await expect(await isAuthenticatedRow.innerHTML()).toBe(
-    'isAuthenticatedtrue'
+    'isAuthenticatedtrue',
   )
 
   const isAdminRow = await page.waitForSelector('*css=tr >> text=Is Admin')
   await expect(await isAdminRow.innerHTML()).toBe(
-    'Is Adminfalse'
+    'Is Adminfalse',
   )
 
   await page.goto('/')
@@ -63,7 +63,7 @@ test('requireAuth graphql checks', async ({ page }) => {
   await expect(
     page
       .locator('.rw-form-error-title')
-      .locator("text=You don't have permission to do that")
+      .locator("text=You don't have permission to do that"),
   ).toBeTruthy()
 
   await page.goto('/')
diff --git a/tasks/smoke-tests/auth/tests/rbacChecks.spec.ts b/tasks/smoke-tests/auth/tests/rbacChecks.spec.ts
index 280c2ad4c820..3b0450d85523 100644
--- a/tasks/smoke-tests/auth/tests/rbacChecks.spec.ts
+++ b/tasks/smoke-tests/auth/tests/rbacChecks.spec.ts
@@ -68,17 +68,17 @@ test('RBAC: Should not be able to delete contact as non-admin user', async ({
   await expect(
     page
       .locator('.rw-scaffold')
-      .locator("text=You don't have permission to do that")
+      .locator("text=You don't have permission to do that"),
   ).toBeTruthy()
 
   // @NOTE we do this because the scaffold content is actually on the page,
   // This is the only way we validate if its actually showing visually
   await expect(
-    page.locator('.rw-scaffold').locator('text=Contact deleted')
+    page.locator('.rw-scaffold').locator('text=Contact deleted'),
   ).toBeHidden()
 
   await expect(
-    await page.locator('text=charlie@chimichanga.com').count()
+    await page.locator('text=charlie@chimichanga.com').count(),
   ).toBeGreaterThan(0)
 })
 
@@ -86,7 +86,7 @@ test('RBAC: Admin user should be able to delete contacts', async ({ page }) => {
   fs.writeFileSync(
     path.join(
       process.env.REDWOOD_TEST_PROJECT_PATH as string,
-      'scripts/makeAdmin.ts'
+      'scripts/makeAdmin.ts',
     ),
     `\
 import { db } from 'api/src/lib/db'
@@ -102,7 +102,7 @@ export default async ({ args }) => {
   })
 
   console.log(await db.user.findMany())
-}`
+}`,
   )
 
   console.log(`Giving ${adminEmail} ADMIN role....`)
@@ -134,11 +134,11 @@ export default async ({ args }) => {
   await page.locator('text=Delete').first().click()
 
   await expect(
-    page.locator('.rw-scaffold').locator('text=Contact deleted')
+    page.locator('.rw-scaffold').locator('text=Contact deleted'),
   ).toBeVisible()
 
   await expect(await page.locator('text=charlie@chimichanga.com').count()).toBe(
-    contactCountBefore - 1
+    contactCountBefore - 1,
   )
 })
 
diff --git a/tasks/smoke-tests/fragments-dev/tests/fragments.spec.ts b/tasks/smoke-tests/fragments-dev/tests/fragments.spec.ts
index 71eee331a19c..8710765d3974 100644
--- a/tasks/smoke-tests/fragments-dev/tests/fragments.spec.ts
+++ b/tasks/smoke-tests/fragments-dev/tests/fragments.spec.ts
@@ -12,6 +12,6 @@ test('Fragments', async ({ page }) => {
   const vegetableCard = page.locator('div', { has: lettuceChild })
   await expect(vegetableCard.getByText('Vegetable Name: Lettuce')).toBeVisible()
   await expect(
-    vegetableCard.getByText('Stall Name: Salad Veggies')
+    vegetableCard.getByText('Stall Name: Salad Veggies'),
   ).toBeVisible()
 })
diff --git a/tasks/smoke-tests/fragments-serve/tests/fragments.spec.ts b/tasks/smoke-tests/fragments-serve/tests/fragments.spec.ts
index 71eee331a19c..8710765d3974 100644
--- a/tasks/smoke-tests/fragments-serve/tests/fragments.spec.ts
+++ b/tasks/smoke-tests/fragments-serve/tests/fragments.spec.ts
@@ -12,6 +12,6 @@ test('Fragments', async ({ page }) => {
   const vegetableCard = page.locator('div', { has: lettuceChild })
   await expect(vegetableCard.getByText('Vegetable Name: Lettuce')).toBeVisible()
   await expect(
-    vegetableCard.getByText('Stall Name: Salad Veggies')
+    vegetableCard.getByText('Stall Name: Salad Veggies'),
   ).toBeVisible()
 })
diff --git a/tasks/smoke-tests/jsconfig.json b/tasks/smoke-tests/jsconfig.json
index c22c46daceeb..7cc9784f62de 100644
--- a/tasks/smoke-tests/jsconfig.json
+++ b/tasks/smoke-tests/jsconfig.json
@@ -5,6 +5,6 @@
     "target": "esnext",
     "module": "esnext",
     "moduleResolution": "node",
-    "skipLibCheck": false,
-  },
+    "skipLibCheck": false
+  }
 }
diff --git a/tasks/smoke-tests/prerender/tests/prerender.spec.ts b/tasks/smoke-tests/prerender/tests/prerender.spec.ts
index 81b9a4bd2a7b..3968468a4247 100644
--- a/tasks/smoke-tests/prerender/tests/prerender.spec.ts
+++ b/tasks/smoke-tests/prerender/tests/prerender.spec.ts
@@ -48,7 +48,7 @@ test('Check that rehydration works for page not wrapped in Set', async ({
   // Wait for page to have been rehydrated before getting page content.
   // We know the page has been rehydrated when it sends an auth request
   await page.waitForResponse((response) =>
-    response.url().includes('/.redwood/functions/auth')
+    response.url().includes('/.redwood/functions/auth'),
   )
 
   await page.locator('h1').first().waitFor()
@@ -89,7 +89,7 @@ test('Check that rehydration works for page with Cell in Set', async ({
   // before getting page content.
   // We know cells have started fetching data when we see graphql requests
   await page.waitForResponse((response) =>
-    response.url().includes('/.redwood/functions/graphql')
+    response.url().includes('/.redwood/functions/graphql'),
   )
 
   await page.locator('h2').first().waitFor()
@@ -137,7 +137,7 @@ test('Check that rehydration works for page with code split chunks', async ({
   // Wait for page to have been rehydrated before getting page content.
   // We know the page has been rehydrated when it sends an auth request
   await page.waitForResponse((response) =>
-    response.url().includes('/.redwood/functions/auth')
+    response.url().includes('/.redwood/functions/auth'),
   )
 
   await expect(page.getByLabel('Name')).toBeVisible()
@@ -190,11 +190,11 @@ test('Check that meta-tags are rendering the correct dynamic data', async () =>
   await pageWithoutJs.goto('/blog-post/1')
 
   const metaDescription = await pageWithoutJs.locator(
-    'meta[name="description"]'
+    'meta[name="description"]',
   )
 
   const ogDescription = await pageWithoutJs.locator(
-    'meta[property="og:description"]'
+    'meta[property="og:description"]',
   )
   await expect(metaDescription).toHaveAttribute('content', 'Description 1')
   await expect(ogDescription).toHaveAttribute('content', 'Description 1')
@@ -217,7 +217,7 @@ test('Check that you can navigate from home page to specific blog post', async (
 
   await pageWithoutJs.goto('/')
   const aboutMeAnchor = await pageWithoutJs.locator(
-    'a:has-text("A little more about me")'
+    'a:has-text("A little more about me")',
   )
 
   await aboutMeAnchor.click()
@@ -230,7 +230,7 @@ test('Check that you can navigate from home page to specific blog post', async (
   expect(mainContent).not.toMatch(/Welcome to the blog!/)
   expect(mainContent).not.toMatch(/What is the meaning of life\?/)
   expect(pageWithoutJs.url()).toMatch(
-    new RegExp(escapeRegExp(aboutMeAnchorHref))
+    new RegExp(escapeRegExp(aboutMeAnchorHref)),
   )
 
   pageWithoutJs.close()
@@ -247,7 +247,7 @@ test('Check that about is prerendered', async () => {
 
   const aboutPageContent = await pageWithoutJs.locator('main').innerText()
   expect(aboutPageContent).toBe(
-    'This site was created to demonstrate my mastery of Redwood: Look on my works, ye mighty, and despair!'
+    'This site was created to demonstrate my mastery of Redwood: Look on my works, ye mighty, and despair!',
   )
   pageWithoutJs.close()
 })
@@ -267,7 +267,7 @@ test('prerender with broken gql query', async () => {
     'web',
     'src',
     'components',
-    'BlogPostsCell'
+    'BlogPostsCell',
   )
 
   const cellPathJs = path.join(cellBasePath, 'BlogPostsCell.jsx')
@@ -284,7 +284,7 @@ test('prerender with broken gql query', async () => {
     })
   } catch (e) {
     expect(e.message).toMatch(
-      /GQL error: Cannot query field "timestamp" on type "Post"\./
+      /GQL error: Cannot query field "timestamp" on type "Post"\./,
     )
   }
 
diff --git a/tasks/smoke-tests/rsa/tests/rsa.spec.ts b/tasks/smoke-tests/rsa/tests/rsa.spec.ts
index decd1c0b0560..2af276e60af0 100644
--- a/tasks/smoke-tests/rsa/tests/rsa.spec.ts
+++ b/tasks/smoke-tests/rsa/tests/rsa.spec.ts
@@ -14,7 +14,7 @@ test('Submitting the form should return a response', async ({ page }) => {
 
   const submittedPageText = page.locator('#redwood-app > div')
   await expect(submittedPageText).toHaveText(
-    /The form has been submitted 1 times./
+    /The form has been submitted 1 times./,
   )
 
   // Expect an echo of our message back from the server
diff --git a/tasks/smoke-tests/shared/common.ts b/tasks/smoke-tests/shared/common.ts
index b60e75eac343..4631a2395e21 100644
--- a/tasks/smoke-tests/shared/common.ts
+++ b/tasks/smoke-tests/shared/common.ts
@@ -7,18 +7,18 @@ export async function smokeTest({ page }: PlaywrightTestArgs) {
   // Check that the blog posts load. We're deliberately not checking their titles because we edit them in other tests.
   await expect(
     page.getByText(
-      'Meh waistcoat succulents umami asymmetrical, hoodie post-ironic paleo chillwave '
-    )
+      'Meh waistcoat succulents umami asymmetrical, hoodie post-ironic paleo chillwave ',
+    ),
   ).toBeVisible()
   await expect(
     page.getByText(
-      'Raclette shoreditch before they sold out lyft. Ethical bicycle rights meh prism '
-    )
+      'Raclette shoreditch before they sold out lyft. Ethical bicycle rights meh prism ',
+    ),
   ).toBeVisible()
   await expect(
     page.getByText(
-      "I'm baby single- origin coffee kickstarter lo - fi paleo skateboard.Tumblr hasht"
-    )
+      "I'm baby single- origin coffee kickstarter lo - fi paleo skateboard.Tumblr hasht",
+    ),
   ).toBeVisible()
 
   // CSS checks. We saw this break when we switched bundlers, so while it's not comprehensive, it's at least something.
@@ -26,20 +26,20 @@ export async function smokeTest({ page }: PlaywrightTestArgs) {
   const bgBlue700 = 'rgb(29, 78, 216)'
   expect(page.locator('#redwood-app > header')).toHaveCSS(
     'background-color',
-    bgBlue700
+    bgBlue700,
   )
 
   const textBlue400 = 'rgb(96, 165, 250)'
   expect(await page.getByRole('link', { name: 'Redwood Blog' })).toHaveCSS(
     'color',
-    textBlue400
+    textBlue400,
   )
 
   // Check the about page.
   await page.getByRole('link', { name: 'About', exact: true }).click()
   expect(page.url()).toBe('http://localhost:8910/about')
   await page.getByText(
-    'This site was created to demonstrate my mastery of Redwood: Look on my works, ye'
+    'This site was created to demonstrate my mastery of Redwood: Look on my works, ye',
   )
 
   // Check the contact us page.
@@ -79,7 +79,7 @@ export const signUpTestUser = async ({
   await Promise.race([
     page.waitForURL('/'),
     expect(
-      page.getByText(`Username \`${email}\` already in use`)
+      page.getByText(`Username \`${email}\` already in use`),
     ).toBeVisible(),
   ])
 }
diff --git a/tasks/smoke-tests/shared/delayedPage.ts b/tasks/smoke-tests/shared/delayedPage.ts
index 4b52aaf7c85f..fca7c88e08d5 100644
--- a/tasks/smoke-tests/shared/delayedPage.ts
+++ b/tasks/smoke-tests/shared/delayedPage.ts
@@ -3,7 +3,7 @@ import { expect } from '@playwright/test'
 
 export async function checkDelayedPageRendering(
   page: Page,
-  { expectedDelay }: { expectedDelay: number }
+  { expectedDelay }: { expectedDelay: number },
 ) {
   const delayedLogStatements: { message: string; time: number }[] = []
 
diff --git a/tasks/smoke-tests/smoke-tests.mjs b/tasks/smoke-tests/smoke-tests.mjs
index 26a76622af3c..131e1cea642c 100644
--- a/tasks/smoke-tests/smoke-tests.mjs
+++ b/tasks/smoke-tests/smoke-tests.mjs
@@ -45,8 +45,8 @@ async function main() {
   for (const smokeTest of smokeTests) {
     console.log(
       `Running ${chalk.magenta(smokeTest)} smoke test against ${chalk.magenta(
-        testProjectPath
-      )}\n`
+        testProjectPath,
+      )}\n`,
     )
 
     await within(async () => {
@@ -83,7 +83,7 @@ async function parseArgs() {
   const options = {
     testProjectPath: {
       description: `Path to the test project. Defaults to the ${chalk.magenta(
-        'REDWOOD_TEST_PROJECT_PATH'
+        'REDWOOD_TEST_PROJECT_PATH',
       )} env var`,
       short: 'p',
       type: /** @type {const} */ ('string'),
@@ -132,7 +132,7 @@ async function parseArgs() {
           '',
           getHelp(options),
           '',
-        ].join('\n')
+        ].join('\n'),
       )
     }
 
@@ -154,13 +154,13 @@ async function parseArgs() {
         chalk.red('Error: No test project to run smoke tests against.'),
         '',
         `If you haven't generated a test project, do so first: ${chalk.green(
-          'yarn build:test-project --link '
+          'yarn build:test-project --link ',
         )}.`,
         `Then set the ${chalk.magenta(
-          'REDWOOD_TEST_PROJECT_PATH'
+          'REDWOOD_TEST_PROJECT_PATH',
         )} env var to the path of your test project.`,
         '',
-      ].join('\n')
+      ].join('\n'),
     )
   }
 
@@ -178,16 +178,16 @@ async function parseArgs() {
         chalk.red("Error: Test project doesn't exist."),
         '',
         `The test project path you specified (${chalk.magenta(
-          testProjectPath
+          testProjectPath,
         )}) doesn't exist.`,
         `Make sure you've generated a test project: ${chalk.green(
-          'yarn build:test-project --link '
+          'yarn build:test-project --link ',
         )}.`,
         `Then set the ${chalk.magenta(
-          'REDWOOD_TEST_PROJECT_PATH'
+          'REDWOOD_TEST_PROJECT_PATH',
         )} env var to the path of your test project.`,
         '',
-      ].join('\n')
+      ].join('\n'),
     )
   }
 
@@ -207,7 +207,7 @@ async function parseArgs() {
     .map((dirent) => dirent.name)
 
   const invalidSmokeTest = smokeTests.find(
-    (smokeTest) => !availableSmokeTests.includes(smokeTest)
+    (smokeTest) => !availableSmokeTests.includes(smokeTest),
   )
 
   // Error if the user passed an invalid smoke test.
@@ -223,7 +223,7 @@ async function parseArgs() {
         '',
         getHelp(options),
         '',
-      ].join('\n')
+      ].join('\n'),
     )
   }
 
@@ -234,8 +234,8 @@ async function parseArgs() {
   if (!isProjectSyncRunning) {
     console.warn(
       chalk.yellow(
-        'Warning: If you want to test against the framework, you must have `yarn rwfw project:sync` running in your test project.'
-      )
+        'Warning: If you want to test against the framework, you must have `yarn rwfw project:sync` running in your test project.',
+      ),
     )
   }
 
@@ -276,7 +276,7 @@ async function parseArgs() {
           process.exitCode = 1
           throw new Error()
         },
-      }
+      },
     )
 
     smokeTests = answer.smokeTests
@@ -289,7 +289,7 @@ async function parseArgs() {
 
   if (
     smokeTests.some((smokeTest) =>
-      ['prerender', 'serve'].includes(smokeTest)
+      ['prerender', 'serve'].includes(smokeTest),
     ) &&
     !isTestProjectBuilt
   ) {
@@ -297,13 +297,13 @@ async function parseArgs() {
     throw new Error(
       [
         chalk.red(
-          'Error: You must build the test project before running the prerender or serve smoke tests.'
+          'Error: You must build the test project before running the prerender or serve smoke tests.',
         ),
         '',
         chalk.green(`  cd ${testProjectPath}`),
         chalk.green(`  yarn rw build`),
         '',
-      ].join('\n')
+      ].join('\n'),
     )
   }
 
@@ -318,7 +318,7 @@ function getHelp(options) {
   // Find the length of the longest option and justify the text based on it.
   const longestOptionLength = Object.entries(options).reduce(
     (max, [name]) => Math.max(max, name.length),
-    0
+    0,
   )
 
   const justifiedOptions = Object.entries(options).map(([name, config]) => {
@@ -343,10 +343,10 @@ function getHelp(options) {
     chalk.green('  yarn smoke-tests [options] [smoke-test..]'),
     '',
     `Make sure you've got a test project. (You can make one via ${chalk.green(
-      'yarn build:test-project --link '
+      'yarn build:test-project --link ',
     )}.)`,
     `Then set the ${chalk.magenta(
-      'REDWOOD_TEST_PROJECT_PATH'
+      'REDWOOD_TEST_PROJECT_PATH',
     )} env var to the path of your test project.`,
     '',
     chalk.dim('  # Let this script prompt you for which smoke test to run'),
@@ -356,10 +356,10 @@ function getHelp(options) {
     chalk.cyan('  REDWOOD_TEST_PROJECT_PATH= yarn smoke-tests dev'),
     '',
     chalk.dim(
-      '  # Pass flags to `npx playwright test` (see `npx playwright test --help`)'
+      '  # Pass flags to `npx playwright test` (see `npx playwright test --help`)',
     ),
     chalk.cyan(
-      '  REDWOOD_TEST_PROJECT_PATH= yarn smoke-tests --playwrightOptions="--debug"'
+      '  REDWOOD_TEST_PROJECT_PATH= yarn smoke-tests --playwrightOptions="--debug"',
     ),
     '',
     chalk.bold('## Options'),
diff --git a/tasks/smoke-tests/streaming-ssr-dev/tests/progressiveRendering.spec.ts b/tasks/smoke-tests/streaming-ssr-dev/tests/progressiveRendering.spec.ts
index 0f630a02bae9..b657e531fae6 100644
--- a/tasks/smoke-tests/streaming-ssr-dev/tests/progressiveRendering.spec.ts
+++ b/tasks/smoke-tests/streaming-ssr-dev/tests/progressiveRendering.spec.ts
@@ -71,15 +71,15 @@ test('Check delayed page has content progressively rendered', async () => {
 
   // Check that its actually rendered on the page. Important when **not** progressively rendering
   await expect(
-    pageWithClientBlocked.locator('[data-test-id="delayed-text-1"]')
+    pageWithClientBlocked.locator('[data-test-id="delayed-text-1"]'),
   ).toHaveCount(1)
   await expect(
-    pageWithClientBlocked.locator('[data-test-id="delayed-text-2"]')
+    pageWithClientBlocked.locator('[data-test-id="delayed-text-2"]'),
   ).toHaveCount(1)
   await expect(
-    pageWithClientBlocked.locator('[data-test-id="delayed-text-3"]')
+    pageWithClientBlocked.locator('[data-test-id="delayed-text-3"]'),
   ).toHaveCount(1)
   await expect(
-    pageWithClientBlocked.locator('[data-test-id="delayed-text-4"]')
+    pageWithClientBlocked.locator('[data-test-id="delayed-text-4"]'),
   ).toHaveCount(1)
 })
diff --git a/tasks/smoke-tests/streaming-ssr-prod/tests/botRendering.spec.ts b/tasks/smoke-tests/streaming-ssr-prod/tests/botRendering.spec.ts
index 59619645f3bc..9ff3707793f7 100644
--- a/tasks/smoke-tests/streaming-ssr-prod/tests/botRendering.spec.ts
+++ b/tasks/smoke-tests/streaming-ssr-prod/tests/botRendering.spec.ts
@@ -40,7 +40,7 @@ test('Check delayed page is NOT progressively rendered', async ({
   const botPageNoBundle = await botContext.newPage()
 
   await botPageNoBundle.route('**/*.*.{js,tsx,ts,jsx}', (route) =>
-    route.abort()
+    route.abort(),
   )
 
   await checkDelayedPageRendering(botPageNoBundle, {
diff --git a/tasks/test-project/codemods/Redwood.stories.mdx b/tasks/test-project/codemods/Redwood.stories.mdx
index 4481bff2fdc9..d0ef9e47cfcb 100644
--- a/tasks/test-project/codemods/Redwood.stories.mdx
+++ b/tasks/test-project/codemods/Redwood.stories.mdx
@@ -3,7 +3,10 @@ import { Meta } from '@storybook/addon-docs'
 
 
 

- +

Redwood

diff --git a/tasks/test-project/codemods/authorCell.js b/tasks/test-project/codemods/authorCell.js index 6747d7015cc9..210a8c9d75c2 100644 --- a/tasks/test-project/codemods/authorCell.js +++ b/tasks/test-project/codemods/authorCell.js @@ -16,7 +16,7 @@ export default (file, api) => { const componentImport = j.importDeclaration( [j.importDefaultSpecifier(j.identifier('Author'))], - j.stringLiteral('src/components/Author') + j.stringLiteral('src/components/Author'), ) root.find(j.ExportNamedDeclaration).at(0).insertBefore(componentImport) @@ -32,7 +32,7 @@ export default (file, api) => { const { node } = nodePath node.init.quasi = j.templateLiteral( [j.templateElement({ raw: query, cooked: query }, true)], - [] + [], ) return node }) diff --git a/tasks/test-project/codemods/blogLayout.js b/tasks/test-project/codemods/blogLayout.js index 596cfb0fe5db..39c8fc0460d9 100644 --- a/tasks/test-project/codemods/blogLayout.js +++ b/tasks/test-project/codemods/blogLayout.js @@ -84,12 +84,12 @@ export default (file, api) => { j.importSpecifier(j.identifier('NavLink'), j.identifier('NavLink')), j.importSpecifier(j.identifier('routes'), j.identifier('routes')), ], - j.stringLiteral('@redwoodjs/router') + j.stringLiteral('@redwoodjs/router'), ) const authImport = j.importDeclaration( [j.importSpecifier(j.identifier('useAuth'), j.identifier('useAuth'))], - j.stringLiteral('src/auth') + j.stringLiteral('src/auth'), ) root.find(j.VariableDeclaration).insertBefore(routerImport) diff --git a/tasks/test-project/codemods/blogPost.js b/tasks/test-project/codemods/blogPost.js index 1e6a29bc75f1..be868b08915b 100644 --- a/tasks/test-project/codemods/blogPost.js +++ b/tasks/test-project/codemods/blogPost.js @@ -44,7 +44,7 @@ export default (file, api) => { j.importSpecifier(j.identifier('Link'), j.identifier('Link')), j.importSpecifier(j.identifier('routes'), j.identifier('routes')), ], - j.stringLiteral('@redwoodjs/router') + j.stringLiteral('@redwoodjs/router'), ) root.find(j.VariableDeclaration).insertBefore(routerImport) diff --git a/tasks/test-project/codemods/blogPostCell.js b/tasks/test-project/codemods/blogPostCell.js index b05bc6d8eb42..3345d7e2a7a1 100644 --- a/tasks/test-project/codemods/blogPostCell.js +++ b/tasks/test-project/codemods/blogPostCell.js @@ -20,7 +20,7 @@ export default (file, api) => { const componentImport = j.importDeclaration( [j.importDefaultSpecifier(j.identifier('BlogPost'))], - j.stringLiteral('src/components/BlogPost') + j.stringLiteral('src/components/BlogPost'), ) root.find(j.ExportNamedDeclaration).at(0).insertBefore(componentImport) @@ -36,7 +36,7 @@ export default (file, api) => { const { node } = nodePath node.init.quasi = j.templateLiteral( [j.templateElement({ raw: query, cooked: query }, true)], - [] + [], ) return node }) diff --git a/tasks/test-project/codemods/blogPostsCell.js b/tasks/test-project/codemods/blogPostsCell.js index d3d84a9eddb7..1efbe6624db0 100644 --- a/tasks/test-project/codemods/blogPostsCell.js +++ b/tasks/test-project/codemods/blogPostsCell.js @@ -22,7 +22,7 @@ export default (file, api) => { const importComponent = j.importDeclaration( [j.importDefaultSpecifier(j.identifier('BlogPost'))], - j.stringLiteral('src/components/BlogPost') + j.stringLiteral('src/components/BlogPost'), ) root.find(j.ExportNamedDeclaration).at(0).insertBefore(importComponent) @@ -38,7 +38,7 @@ export default (file, api) => { const { node } = nodePath node.init.quasi = j.templateLiteral( [j.templateElement({ raw: query, cooked: query }, true)], - [] + [], ) return node }) diff --git a/tasks/test-project/codemods/contactsSdl.js b/tasks/test-project/codemods/contactsSdl.js index a04e6d2f6380..9b1c30d257fc 100644 --- a/tasks/test-project/codemods/contactsSdl.js +++ b/tasks/test-project/codemods/contactsSdl.js @@ -20,7 +20,7 @@ export default (file, api) => { const schema = `${node.init.quasi.quasis[0].value.raw} ${mutation}` node.init.quasi = j.templateLiteral( [j.templateElement({ raw: schema, cooked: schema }, true)], - [] + [], ) return node }) diff --git a/tasks/test-project/codemods/delayedPage.js b/tasks/test-project/codemods/delayedPage.js index 96f3487a1452..e08b46981946 100644 --- a/tasks/test-project/codemods/delayedPage.js +++ b/tasks/test-project/codemods/delayedPage.js @@ -83,14 +83,14 @@ export default (file, api) => { const serverInjectImport = j.importDeclaration( [j.importSpecifier(j.identifier('useServerInsertedHTML'))], - j.stringLiteral('@redwoodjs/web') + j.stringLiteral('@redwoodjs/web'), ) const reactImports = j.importDeclaration( ['Suspense', 'useState', 'use', 'useRef'].map((importName) => - j.importSpecifier(j.identifier(importName)) + j.importSpecifier(j.identifier(importName)), ), - j.stringLiteral('react') + j.stringLiteral('react'), ) root diff --git a/tasks/test-project/codemods/groceriesPage.ts b/tasks/test-project/codemods/groceriesPage.ts index 802c2a930ca7..84d59cb14bc0 100644 --- a/tasks/test-project/codemods/groceriesPage.ts +++ b/tasks/test-project/codemods/groceriesPage.ts @@ -52,8 +52,8 @@ export default (file: FileInfo, api: API) => { j.importSpecifier(j.identifier('GetProduce')), ], j.stringLiteral('types/graphql'), - 'type' - ) + 'type', + ), ) // Replace @@ -90,15 +90,15 @@ export default (file: FileInfo, api: API) => { return [ j.importDeclaration( [j.importDefaultSpecifier(j.identifier('FruitInfo'))], - j.stringLiteral('src/components/FruitInfo') + j.stringLiteral('src/components/FruitInfo'), ), j.importDeclaration( [j.importDefaultSpecifier(j.identifier('ProduceInfo'))], - j.stringLiteral('src/components/ProduceInfo') + j.stringLiteral('src/components/ProduceInfo'), ), j.importDeclaration( [j.importDefaultSpecifier(j.identifier('VegetableInfo'))], - j.stringLiteral('src/components/VegetableInfo') + j.stringLiteral('src/components/VegetableInfo'), ), ] }) @@ -137,9 +137,9 @@ export default (file: FileInfo, api: API) => { j.identifier('gql'), j.templateLiteral( [j.templateElement({ raw: query, cooked: query }, true)], - [] - ) - ) + [], + ), + ), ), ]) }) @@ -183,12 +183,12 @@ export default (file: FileInfo, api: API) => { [ j.templateElement( { raw: produceQuery, cooked: produceQuery }, - true + true, ), ], - [] - ) - ) + [], + ), + ), ), ]) }) diff --git a/tasks/test-project/codemods/routes.js b/tasks/test-project/codemods/routes.js index 0133f4ec5d0e..fa49da362d4b 100644 --- a/tasks/test-project/codemods/routes.js +++ b/tasks/test-project/codemods/routes.js @@ -7,12 +7,12 @@ export default (file, api) => { const blogImport = j.importDeclaration( [j.importDefaultSpecifier(j.identifier('BlogLayout'))], - j.stringLiteral('src/layouts/BlogLayout') + j.stringLiteral('src/layouts/BlogLayout'), ) const homePageImport = j.importDeclaration( [j.importDefaultSpecifier(j.identifier('HomePage'))], - j.stringLiteral('src/pages/HomePage') + j.stringLiteral('src/pages/HomePage'), ) root @@ -42,11 +42,11 @@ export default (file, api) => { j.jsxOpeningElement(j.jsxIdentifier('Set'), [ j.jsxAttribute( j.jsxIdentifier('wrap'), - j.jsxExpressionContainer(j.identifier('BlogLayout')) + j.jsxExpressionContainer(j.identifier('BlogLayout')), ), ]), j.jsxClosingElement(j.jsxIdentifier('Set')), - [...node.children] + [...node.children], ), ] @@ -60,7 +60,7 @@ export default (file, api) => { j.filters.JSXElement.hasAttributes({ name: 'profile', path: '/profile', - }) + }), ) .at(0) .replaceWith((nodePath) => { @@ -70,11 +70,11 @@ export default (file, api) => { j.jsxOpeningElement(j.jsxIdentifier('Private'), [ j.jsxAttribute( j.jsxIdentifier('unauthenticated'), - j.literal('login') + j.literal('login'), ), ]), j.jsxClosingElement(j.jsxIdentifier('Private')), - [node] + [node], ) return privateSetWrapped diff --git a/tasks/test-project/codemods/updateAuthorStories.js b/tasks/test-project/codemods/updateAuthorStories.js index 96efd2db365c..cf32f1cf1d95 100644 --- a/tasks/test-project/codemods/updateAuthorStories.js +++ b/tasks/test-project/codemods/updateAuthorStories.js @@ -33,10 +33,10 @@ export default (file, api) => { j.property( 'init', j.identifier('email'), - j.literal('story.user@email.com') + j.literal('story.user@email.com'), ), j.property('init', j.identifier('fullName'), j.literal('Story User')), - ]) + ]), ), ]) @@ -47,7 +47,7 @@ export default (file, api) => { // } const primaryIdentifier = j.identifier('Primary') primaryIdentifier.typeAnnotation = j.tsTypeAnnotation( - j.tsTypeReference(j.identifier('Story'), null) + j.tsTypeReference(j.identifier('Story'), null), ) const primaryWithRender = j.exportNamedDeclaration( @@ -68,22 +68,22 @@ export default (file, api) => { [ j.jsxAttribute( j.jsxIdentifier('author'), - j.jsxExpressionContainer(j.identifier('author')) + j.jsxExpressionContainer(j.identifier('author')), ), ], - true + true, ), null, [], - true - ) + true, + ), ), - ]) - ) + ]), + ), ), - ]) + ]), ), - ]) + ]), ) if (exportStatement.length > 0) { diff --git a/tasks/test-project/codemods/updateAuthorTest.js b/tasks/test-project/codemods/updateAuthorTest.js index d2006fa6ec13..a1c79fd734fa 100644 --- a/tasks/test-project/codemods/updateAuthorTest.js +++ b/tasks/test-project/codemods/updateAuthorTest.js @@ -10,24 +10,28 @@ export default (file, api) => { j.variableDeclarator( j.identifier('author'), j.objectExpression([ - j.property('init', j.identifier('email'), j.literal('test.user@email.com')), + j.property( + 'init', + j.identifier('email'), + j.literal('test.user@email.com'), + ), j.property('init', j.identifier('fullName'), j.literal('Test User')), - ]) - ) + ]), + ), ]) root.find(j.ExpressionStatement).at(0).insertBefore(authorDeclaration) // Change `` to `` root - .find(j.JSXOpeningElement, { name: { name: 'Author' } } ) + .find(j.JSXOpeningElement, { name: { name: 'Author' } }) .replaceWith((nodePath) => { const { node } = nodePath node.attributes.push( j.jsxAttribute( j.jsxIdentifier('author'), - j.jsxExpressionContainer(j.identifier('author')) - ) + j.jsxExpressionContainer(j.identifier('author')), + ), ) return node diff --git a/tasks/test-project/codemods/updateBlogPostPageStories.js b/tasks/test-project/codemods/updateBlogPostPageStories.js index eada95b8d15f..d293ae119380 100644 --- a/tasks/test-project/codemods/updateBlogPostPageStories.js +++ b/tasks/test-project/codemods/updateBlogPostPageStories.js @@ -26,7 +26,7 @@ export default (file, api) => { const primaryIdentifier = j.identifier('Primary') // Add the `Story` type annotation primaryIdentifier.typeAnnotation = j.tsTypeAnnotation( - j.tsTypeReference(j.identifier('Story'), null) + j.tsTypeReference(j.identifier('Story'), null), ) // export const Primary: Story = { @@ -52,23 +52,23 @@ export default (file, api) => { [ j.jsxAttribute( j.jsxIdentifier('id'), - j.jsxExpressionContainer(j.numericLiteral(42)) + j.jsxExpressionContainer(j.numericLiteral(42)), ), j.jsxSpreadAttribute(j.identifier('args')), ], - true + true, ), null, [], - true - ) + true, + ), ), - ]) - ) + ]), + ), ), - ]) + ]), ), - ]) + ]), ) if (exportStatement.length > 0) { diff --git a/tasks/test-project/codemods/updateWaterfallPageStories.js b/tasks/test-project/codemods/updateWaterfallPageStories.js index 99b646980f80..97252516efd6 100644 --- a/tasks/test-project/codemods/updateWaterfallPageStories.js +++ b/tasks/test-project/codemods/updateWaterfallPageStories.js @@ -26,7 +26,7 @@ export default (file, api) => { const primaryIdentifier = j.identifier('Primary') // Add the `Story` type annotation primaryIdentifier.typeAnnotation = j.tsTypeAnnotation( - j.tsTypeReference(j.identifier('Story'), null) + j.tsTypeReference(j.identifier('Story'), null), ) // export const Primary: Story = { @@ -52,23 +52,23 @@ export default (file, api) => { [ j.jsxAttribute( j.jsxIdentifier('id'), - j.jsxExpressionContainer(j.numericLiteral(42)) + j.jsxExpressionContainer(j.numericLiteral(42)), ), j.jsxSpreadAttribute(j.identifier('args')), ], - true + true, ), null, [], - true - ) + true, + ), ), - ]) - ) + ]), + ), ), - ]) + ]), ), - ]) + ]), ) if (exportStatement.length > 0) { diff --git a/tasks/test-project/codemods/usersSdl.js b/tasks/test-project/codemods/usersSdl.js index 8761452ea4e5..5ea2532abb12 100644 --- a/tasks/test-project/codemods/usersSdl.js +++ b/tasks/test-project/codemods/usersSdl.js @@ -36,7 +36,7 @@ export default (file, api) => { node.init.quasi = j.templateLiteral( [j.templateElement({ raw: schema, cooked: schema }, true)], - [] + [], ) return node }) diff --git a/tasks/test-project/codemods/usersService.js b/tasks/test-project/codemods/usersService.js index 2b5cfb412028..b5f0f163a0da 100644 --- a/tasks/test-project/codemods/usersService.js +++ b/tasks/test-project/codemods/usersService.js @@ -14,21 +14,23 @@ export default (file, api) => { // const params = j.objectPattern([property]) - return root - .find(j.VariableDeclarator, { - id: { - type: 'Identifier', - name: 'users', - }, - }) - // .replaceWith((nodePath) => { - // const { node } = nodePath - // node.id.name = 'user' - // node.id.typeAnnotation.typeAnnotation.indexType.literal.value = 'user' - // node.init.params[0] = params - // node.init.body.body[0] = body - // return node - // }) - .remove() - .toSource() + return ( + root + .find(j.VariableDeclarator, { + id: { + type: 'Identifier', + name: 'users', + }, + }) + // .replaceWith((nodePath) => { + // const { node } = nodePath + // node.id.name = 'user' + // node.id.typeAnnotation.typeAnnotation.indexType.literal.value = 'user' + // node.init.params[0] = params + // node.init.body.body[0] = body + // return node + // }) + .remove() + .toSource() + ) } diff --git a/tasks/test-project/codemods/waterfallBlogPostCell.js b/tasks/test-project/codemods/waterfallBlogPostCell.js index 87e88fa70f5b..80e126f9d64d 100644 --- a/tasks/test-project/codemods/waterfallBlogPostCell.js +++ b/tasks/test-project/codemods/waterfallBlogPostCell.js @@ -40,7 +40,7 @@ export default (file, api) => { const componentImport = j.importDeclaration( [j.importDefaultSpecifier(j.identifier('AuthorCell'))], - j.stringLiteral('src/components/AuthorCell') + j.stringLiteral('src/components/AuthorCell'), ) root.find(j.ExportNamedDeclaration).at(0).insertBefore(componentImport) @@ -56,7 +56,7 @@ export default (file, api) => { const { node } = nodePath node.init.quasi = j.templateLiteral( [j.templateElement({ raw: query, cooked: query }, true)], - [] + [], ) return node }) diff --git a/tasks/test-project/codemods/waterfallPage.js b/tasks/test-project/codemods/waterfallPage.js index 1664ff9ce591..07281f0ca1b8 100644 --- a/tasks/test-project/codemods/waterfallPage.js +++ b/tasks/test-project/codemods/waterfallPage.js @@ -8,7 +8,7 @@ export default (file, api) => { const importComponent = j.importDeclaration( [j.importDefaultSpecifier(j.identifier('WaterfallBlogPostCell'))], - j.stringLiteral('src/components/WaterfallBlogPostCell') + j.stringLiteral('src/components/WaterfallBlogPostCell'), ) root.find(j.ImportDeclaration).at(-1).insertAfter(importComponent) diff --git a/tasks/test-project/rebuild-fragments-test-project-fixture.ts b/tasks/test-project/rebuild-fragments-test-project-fixture.ts index acd94ef453b2..939161fc32fc 100755 --- a/tasks/test-project/rebuild-fragments-test-project-fixture.ts +++ b/tasks/test-project/rebuild-fragments-test-project-fixture.ts @@ -56,7 +56,7 @@ const OUTPUT_PROJECT_PATH = resumePath os.tmpdir(), 'redwood-fragment-test-project', // ":" is problematic with paths - new Date().toISOString().split(':').join('-') + new Date().toISOString().split(':').join('-'), ) let startStep = resumeStep || '' @@ -66,7 +66,7 @@ if (!startStep) { try { const stepTxt = fs.readFileSync( path.join(OUTPUT_PROJECT_PATH, 'step.txt'), - 'utf-8' + 'utf-8', ) if (stepTxt) { @@ -137,12 +137,12 @@ async function tuiTask({ step, title, content, task, parent }: TuiTaskDef) { if (e instanceof ExecaError) { tui.displayError( 'Failed ' + title.toLowerCase().replace('...', ''), - 'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr + 'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr, ) } else { tui.displayError( 'Failed ' + title.toLowerCase().replace('...', ''), - e.message + e.message, ) } @@ -158,12 +158,12 @@ async function tuiTask({ step, title, content, task, parent }: TuiTaskDef) { if (e instanceof ExecaError) { tui.displayError( 'Failed ' + title.toLowerCase().replace('...', ''), - 'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr + 'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr, ) } else { tui.displayError( 'Failed ' + title.toLowerCase().replace('...', ''), - e.message + e.message, ) } @@ -218,8 +218,8 @@ if (resume) { console.error( chalk.red.bold( '\n`resume` option is not supported yet. ' + - 'Please use `resumePath` instead.\n' - ) + 'Please use `resumePath` instead.\n', + ), ) process.exit(1) @@ -230,8 +230,8 @@ if (resumePath && !fs.existsSync(path.join(resumePath, 'redwood.toml'))) { chalk.red.bold( ` No redwood.toml file found at the given path: ${resumePath} - ` - ) + `, + ), ) process.exit(1) } @@ -243,7 +243,7 @@ const createProject = () => { cmd, // We create a ts project and convert using ts-to-js at the end if typescript flag is false ['--no-yarn-install', '--typescript', '--overwrite', '--no-git'], - getExecaOptions(RW_FRAMEWORK_PATH) + getExecaOptions(RW_FRAMEWORK_PATH), ) return subprocess @@ -252,7 +252,7 @@ const createProject = () => { const copyProject = async () => { const fixturePath = path.join( RW_FRAMEWORK_PATH, - '__fixtures__/fragment-test-project' + '__fixtures__/fragment-test-project', ) // remove existing Fixture @@ -290,7 +290,7 @@ async function runCommand() { return exec( 'yarn build:clean && yarn build', [], - getExecaOptions(RW_FRAMEWORK_PATH) + getExecaOptions(RW_FRAMEWORK_PATH), ) }, }) @@ -303,7 +303,7 @@ async function runCommand() { return addFrameworkDepsToProject( RW_FRAMEWORK_PATH, OUTPUT_PROJECT_PATH, - 'pipe' // TODO: Remove this when everything is using @rwjs/tui + 'pipe', // TODO: Remove this when everything is using @rwjs/tui ) }, }) @@ -331,12 +331,12 @@ async function runCommand() { newRedwoodToml = newRedwoodToml.replace( /\port = 8910/, - 'port = "${WEB_DEV_PORT:8910}"' + 'port = "${WEB_DEV_PORT:8910}"', ) newRedwoodToml = newRedwoodToml.replace( /\port = 8911/, - 'port = "${API_DEV_PORT:8911}"' + 'port = "${API_DEV_PORT:8911}"', ) fs.writeFileSync(REDWOOD_TOML_PATH, newRedwoodToml) @@ -350,7 +350,7 @@ async function runCommand() { return copyFrameworkPackages( RW_FRAMEWORK_PATH, OUTPUT_PROJECT_PATH, - 'pipe' + 'pipe', ) }, }) @@ -396,7 +396,7 @@ async function runCommand() { return exec( 'yarn rw prisma migrate reset', ['--force'], - getExecaOptions(OUTPUT_PROJECT_PATH) + getExecaOptions(OUTPUT_PROJECT_PATH), ) }, }) @@ -467,9 +467,9 @@ async function runCommand() { fs.copyFileSync( path.join( __dirname, - '../../packages/create-redwood-app/templates/ts/package.json' + '../../packages/create-redwood-app/templates/ts/package.json', ), - path.join(OUTPUT_PROJECT_PATH, 'package.json') + path.join(OUTPUT_PROJECT_PATH, 'package.json'), ) // removes existing Fixture and replaces with newly built project, diff --git a/tasks/test-project/rebuild-test-project-fixture.ts b/tasks/test-project/rebuild-test-project-fixture.ts index 581f20a1dddb..b7e66f932ea8 100755 --- a/tasks/test-project/rebuild-test-project-fixture.ts +++ b/tasks/test-project/rebuild-test-project-fixture.ts @@ -56,7 +56,7 @@ const OUTPUT_PROJECT_PATH = resumePath os.tmpdir(), 'redwood-test-project', // ":" is problematic with paths - new Date().toISOString().split(':').join('-') + new Date().toISOString().split(':').join('-'), ) let startStep = resumeStep || '' @@ -66,7 +66,7 @@ if (!startStep) { try { const stepTxt = fs.readFileSync( path.join(OUTPUT_PROJECT_PATH, 'step.txt'), - 'utf-8' + 'utf-8', ) if (stepTxt) { @@ -137,12 +137,12 @@ async function tuiTask({ step, title, content, task, parent }: TuiTaskDef) { if (e instanceof ExecaError) { tui.displayError( 'Failed ' + title.toLowerCase().replace('...', ''), - 'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr + 'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr, ) } else { tui.displayError( 'Failed ' + title.toLowerCase().replace('...', ''), - e.message + e.message, ) } @@ -158,12 +158,12 @@ async function tuiTask({ step, title, content, task, parent }: TuiTaskDef) { if (e instanceof ExecaError) { tui.displayError( 'Failed ' + title.toLowerCase().replace('...', ''), - 'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr + 'stdout:\n' + e.stdout + '\n\n' + 'stderr:\n' + e.stderr, ) } else { tui.displayError( 'Failed ' + title.toLowerCase().replace('...', ''), - e.message + e.message, ) } @@ -218,8 +218,8 @@ if (resume) { console.error( chalk.red.bold( '\n`resume` option is not supported yet. ' + - 'Please use `resumePath` instead.\n' - ) + 'Please use `resumePath` instead.\n', + ), ) process.exit(1) @@ -230,8 +230,8 @@ if (resumePath && !fs.existsSync(path.join(resumePath, 'redwood.toml'))) { chalk.red.bold( ` No redwood.toml file found at the given path: ${resumePath} - ` - ) + `, + ), ) process.exit(1) } @@ -243,7 +243,7 @@ const createProject = () => { cmd, // We create a ts project and convert using ts-to-js at the end if typescript flag is false ['--no-yarn-install', '--typescript', '--overwrite', '--no-git'], - getExecaOptions(RW_FRAMEWORK_PATH) + getExecaOptions(RW_FRAMEWORK_PATH), ) return subprocess @@ -287,7 +287,7 @@ async function runCommand() { return exec( 'yarn build:clean && yarn build', [], - getExecaOptions(RW_FRAMEWORK_PATH) + getExecaOptions(RW_FRAMEWORK_PATH), ) }, }) @@ -300,7 +300,7 @@ async function runCommand() { return addFrameworkDepsToProject( RW_FRAMEWORK_PATH, OUTPUT_PROJECT_PATH, - 'pipe' // TODO: Remove this when everything is using @rwjs/tui + 'pipe', // TODO: Remove this when everything is using @rwjs/tui ) }, }) @@ -328,12 +328,12 @@ async function runCommand() { newRedwoodToml = newRedwoodToml.replace( /\port = 8910/, - 'port = "${WEB_DEV_PORT:8910}"' + 'port = "${WEB_DEV_PORT:8910}"', ) newRedwoodToml = newRedwoodToml.replace( /\port = 8911/, - 'port = "${API_DEV_PORT:8911}"' + 'port = "${API_DEV_PORT:8911}"', ) fs.writeFileSync(REDWOOD_TOML_PATH, newRedwoodToml) @@ -347,7 +347,7 @@ async function runCommand() { return copyFrameworkPackages( RW_FRAMEWORK_PATH, OUTPUT_PROJECT_PATH, - 'pipe' + 'pipe', ) }, }) @@ -386,26 +386,21 @@ async function runCommand() { }, }) - await tuiTask({ - step: 9, - title: 'Add scripts', - task: () => { - const nestedPath = path.join( - OUTPUT_PROJECT_PATH, - 'scripts', - 'one', - 'two' - ) - - fs.mkdirSync(nestedPath, { recursive: true }) - fs.writeFileSync( - path.join(nestedPath, 'myNestedScript.ts'), - 'export default async () => {\n' + - " console.log('Hello from myNestedScript.ts')\n" + - '}\n\n' - ) - }, - }) + await tuiTask({ + step: 9, + title: 'Add scripts', + task: () => { + const nestedPath = path.join(OUTPUT_PROJECT_PATH, 'scripts', 'one', 'two') + + fs.mkdirSync(nestedPath, { recursive: true }) + fs.writeFileSync( + path.join(nestedPath, 'myNestedScript.ts'), + 'export default async () => {\n' + + " console.log('Hello from myNestedScript.ts')\n" + + '}\n\n', + ) + }, + }) await tuiTask({ step: 10, @@ -414,7 +409,7 @@ async function runCommand() { return exec( 'yarn rw prisma migrate reset', ['--force'], - getExecaOptions(OUTPUT_PROJECT_PATH) + getExecaOptions(OUTPUT_PROJECT_PATH), ) }, }) @@ -478,9 +473,9 @@ async function runCommand() { fs.copyFileSync( path.join( __dirname, - '../../packages/create-redwood-app/templates/ts/package.json' + '../../packages/create-redwood-app/templates/ts/package.json', ), - path.join(OUTPUT_PROJECT_PATH, 'package.json') + path.join(OUTPUT_PROJECT_PATH, 'package.json'), ) // removes existing Fixture and replaces with newly built project, diff --git a/tasks/test-project/set-up-trusted-documents.ts b/tasks/test-project/set-up-trusted-documents.ts index 5dd89f9fe41c..437d0bfc9732 100644 --- a/tasks/test-project/set-up-trusted-documents.ts +++ b/tasks/test-project/set-up-trusted-documents.ts @@ -24,7 +24,7 @@ async function runCommand() { await exec( 'yarn rw setup graphql trusted-documents', [], - getExecaOptions(OUTPUT_PROJECT_PATH) + getExecaOptions(OUTPUT_PROJECT_PATH), ) const redwoodTomlPath = path.join(OUTPUT_PROJECT_PATH, 'redwood.toml') @@ -36,7 +36,7 @@ async function runCommand() { if (!redwoodTomlContent.includes('trustedDocuments = true')) { console.error( - 'Failed to set up trusted-documents in fragments test-project' + 'Failed to set up trusted-documents in fragments test-project', ) console.error('trustedDocuments = true not set in redwood.toml') console.error() @@ -50,14 +50,14 @@ async function runCommand() { const graphqlHandlerPath = path.join( OUTPUT_PROJECT_PATH, - 'api/src/functions/graphql.ts' + 'api/src/functions/graphql.ts', ) const graphqlHandlerContent = fs.readFileSync(graphqlHandlerPath, 'utf-8') const storeImport = "import { store } from 'src/lib/trustedDocumentsStore'" if (!graphqlHandlerContent.includes(storeImport)) { console.error( - 'Failed to set up trusted-documents in fragments test-project' + 'Failed to set up trusted-documents in fragments test-project', ) console.error('`store` is not imported in the graphql handler') console.error() @@ -67,10 +67,10 @@ async function runCommand() { if (!graphqlHandlerContent.includes('trustedDocuments: {')) { console.error( - 'Failed to set up trusted-documents in fragments test-project' + 'Failed to set up trusted-documents in fragments test-project', ) console.error( - 'The trustedDocuments store is not used in the graphql handler' + 'The trustedDocuments store is not used in the graphql handler', ) console.error() console.error('Please run this command locally to make sure it works') diff --git a/tasks/test-project/tasks.js b/tasks/test-project/tasks.js index c4fa42ef9b3e..77c995ed7529 100644 --- a/tasks/test-project/tasks.js +++ b/tasks/test-project/tasks.js @@ -33,7 +33,7 @@ const createBuilder = (cmd) => { await execa( cmd, Array.isArray(positionals) ? positionals : [positionals], - getExecaOptions(OUTPUT_PATH) + getExecaOptions(OUTPUT_PATH), ) } } @@ -52,7 +52,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { return applyCodemod( 'homePage.js', - fullPath('web/src/pages/HomePage/HomePage') + fullPath('web/src/pages/HomePage/HomePage'), ) }, }, @@ -63,7 +63,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { return applyCodemod( 'aboutPage.js', - fullPath('web/src/pages/AboutPage/AboutPage') + fullPath('web/src/pages/AboutPage/AboutPage'), ) }, }, @@ -74,7 +74,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { return applyCodemod( 'contactUsPage.js', - fullPath('web/src/pages/ContactUsPage/ContactUsPage') + fullPath('web/src/pages/ContactUsPage/ContactUsPage'), ) }, }, @@ -85,7 +85,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { return applyCodemod( 'blogPostPage.js', - fullPath('web/src/pages/BlogPostPage/BlogPostPage') + fullPath('web/src/pages/BlogPostPage/BlogPostPage'), ) }, }, @@ -120,12 +120,12 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { fs.writeFileSync( fullPath('web/src/pages/ProfilePage/ProfilePage.test'), - testFileContent + testFileContent, ) return applyCodemod( 'profilePage.js', - fullPath('web/src/pages/ProfilePage/ProfilePage') + fullPath('web/src/pages/ProfilePage/ProfilePage'), ) }, }, @@ -133,12 +133,12 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { title: 'Creating MDX Storybook stories', task: () => { const redwoodMdxStoryContent = fs.readFileSync( - `${path.resolve(__dirname, 'codemods', 'Redwood.stories.mdx')}` + `${path.resolve(__dirname, 'codemods', 'Redwood.stories.mdx')}`, ) fs.writeFileSync( fullPath('web/src/Redwood.stories.mdx', { addExtension: false }), - redwoodMdxStoryContent + redwoodMdxStoryContent, ) return @@ -151,7 +151,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { await applyCodemod( 'waterfallPage.js', - fullPath('web/src/pages/WaterfallPage/WaterfallPage') + fullPath('web/src/pages/WaterfallPage/WaterfallPage'), ) }, }, @@ -165,7 +165,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { return applyCodemod( 'blogLayout.js', - fullPath('web/src/layouts/BlogLayout/BlogLayout') + fullPath('web/src/layouts/BlogLayout/BlogLayout'), ) } @@ -176,24 +176,24 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { await applyCodemod( 'blogPost.js', - fullPath('web/src/components/BlogPost/BlogPost') + fullPath('web/src/components/BlogPost/BlogPost'), ) await createComponent('author') await applyCodemod( 'author.js', - fullPath('web/src/components/Author/Author') + fullPath('web/src/components/Author/Author'), ) await applyCodemod( 'updateAuthorStories.js', - fullPath('web/src/components/Author/Author.stories') + fullPath('web/src/components/Author/Author.stories'), ) await applyCodemod( 'updateAuthorTest.js', - fullPath('web/src/components/Author/Author.test') + fullPath('web/src/components/Author/Author.test'), ) } @@ -204,28 +204,30 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { await applyCodemod( 'blogPostsCell.js', - fullPath('web/src/components/BlogPostsCell/BlogPostsCell') + fullPath('web/src/components/BlogPostsCell/BlogPostsCell'), ) await createCell('blogPost') await applyCodemod( 'blogPostCell.js', - fullPath('web/src/components/BlogPostCell/BlogPostCell') + fullPath('web/src/components/BlogPostCell/BlogPostCell'), ) await createCell('author') await applyCodemod( 'authorCell.js', - fullPath('web/src/components/AuthorCell/AuthorCell') + fullPath('web/src/components/AuthorCell/AuthorCell'), ) await createCell('waterfallBlogPost') return applyCodemod( 'waterfallBlogPostCell.js', - fullPath('web/src/components/WaterfallBlogPostCell/WaterfallBlogPostCell') + fullPath( + 'web/src/components/WaterfallBlogPostCell/WaterfallBlogPostCell', + ), ) } @@ -234,21 +236,21 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { 'updateBlogPostMocks.js', fullPath('web/src/components/BlogPostCell/BlogPostCell.mock.ts', { addExtension: false, - }) + }), ) await applyCodemod( 'updateBlogPostMocks.js', fullPath('web/src/components/BlogPostsCell/BlogPostsCell.mock.ts', { addExtension: false, - }) + }), ) await applyCodemod( 'updateAuthorCellMock.js', fullPath('web/src/components/AuthorCell/AuthorCell.mock.ts', { addExtension: false, - }) + }), ) return applyCodemod( @@ -257,8 +259,8 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { 'web/src/components/WaterfallBlogPostCell/WaterfallBlogPostCell.mock.ts', { addExtension: false, - } - ) + }, + ), ) } @@ -298,7 +300,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { execa( 'yarn workspace web add -D postcss postcss-loader tailwindcss autoprefixer prettier-plugin-tailwindcss@^0.5.12', [], - getExecaOptions(outputPath) + getExecaOptions(outputPath), ), enabled: () => linkWithLatestFwBuild, }, @@ -316,9 +318,9 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { return execa( 'yarn rw setup ui tailwindcss', ['--force', linkWithLatestFwBuild && '--no-install'].filter( - Boolean + Boolean, ), - getExecaOptions(outputPath) + getExecaOptions(outputPath), ) }, }, @@ -326,7 +328,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) { { exitOnError: true, renderer: verbose && 'verbose', - } + }, ) } @@ -354,7 +356,7 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { outputPath, 'node_modules', '@redwoodjs', - 'auth-dbauth-setup' + 'auth-dbauth-setup', ) // At an earlier step we run `yarn rwfw project:copy` which gives us @@ -368,7 +370,7 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { await execa( 'yarn rw setup auth dbAuth --force --no-webauthn', [], - getExecaOptions(outputPath) + getExecaOptions(outputPath), ) // Restore postinstall script @@ -386,7 +388,7 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { await execa( 'yarn rw g dbAuth --no-webauthn --username-label=username --password-label=password', [], - execaOptions + execaOptions, ) // update directive in contacts.sdl.ts @@ -395,11 +397,11 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { const resultsContactsSdl = contentContactsSdl .replace( 'createContact(input: CreateContactInput!): Contact! @requireAuth', - `createContact(input: CreateContactInput!): Contact @skipAuth` + `createContact(input: CreateContactInput!): Contact @skipAuth`, ) .replace( 'deleteContact(id: Int!): Contact! @requireAuth', - 'deleteContact(id: Int!): Contact! @requireAuth(roles:["ADMIN"])' + 'deleteContact(id: Int!): Contact! @requireAuth(roles:["ADMIN"])', ) // make deleting contacts admin only fs.writeFileSync(pathContactsSdl, resultsContactsSdl) @@ -409,7 +411,7 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { const resultsPostsSdl = contentPostsSdl.replace( /posts: \[Post!\]! @requireAuth([^}]*)@requireAuth/, `posts: [Post!]! @skipAuth - post(id: Int!): Post @skipAuth` + post(id: Int!): Post @skipAuth`, ) // make posts accessible to all fs.writeFileSync(pathPostsSdl, resultsPostsSdl) @@ -421,11 +423,11 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { const newLibAuthContent = libAuthContent .replace( 'select: { id: true }', - 'select: { id: true, roles: true, email: true}' + 'select: { id: true, roles: true, email: true}', ) .replace( 'const currentUserRoles = context.currentUser?.roles', - 'const currentUserRoles = context.currentUser?.roles as string | string[]' + 'const currentUserRoles = context.currentUser?.roles as string | string[]', ) fs.writeFileSync(libAuthPath, newLibAuthContent) @@ -436,7 +438,7 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { /const mockExecution([^}]*){} }\)/, `const mockExecution = mockRedwoodDirective(requireAuth, { context: { currentUser: { id: 1, roles: 'ADMIN', email: 'b@zinga.com' } }, - })` + })`, ) fs.writeFileSync(pathRequireAuth, resultsRequireAuth) @@ -444,7 +446,7 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { const pathSignupPageTs = `${OUTPUT_PATH}/web/src/pages/SignupPage/SignupPage.tsx` const contentSignupPageTs = fs.readFileSync(pathSignupPageTs, 'utf-8') const usernameFields = contentSignupPageTs.match( - /\s*/ + /\s*/, )[0] const fullNameFields = usernameFields .replace(/\s*ref=\{usernameRef}/, '') @@ -455,12 +457,12 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { .replace( '', '\n' + - fullNameFields + fullNameFields, ) // include full-name in the data we pass to `signUp()` .replace( 'password: data.password', - "password: data.password, 'full-name': data['full-name']" + "password: data.password, 'full-name': data['full-name']", ) fs.writeFileSync(pathSignupPageTs, newContentSignupPageTs) @@ -473,7 +475,7 @@ async function apiTasks(outputPath, { verbose, linkWithLatestFwBuild }) { .replace('userAttributes: _userAttributes', 'userAttributes') .replace( '// name: userAttributes.name', - "fullName: userAttributes['full-name']" + "fullName: userAttributes['full-name']", ) fs.writeFileSync(pathAuthTs, resultsAuthTs) @@ -518,7 +520,7 @@ export default DoublePage` fs.writeFileSync( fullPath('web/src/pages/DoublePage/DoublePage'), - doublePageContent + doublePageContent, ) }, }, @@ -529,31 +531,31 @@ export default DoublePage` const contentRoutes = fs.readFileSync(pathRoutes).toString() const resultsRoutesAbout = contentRoutes.replace( /name="about"/, - `name="about" prerender` + `name="about" prerender`, ) const resultsRoutesHome = resultsRoutesAbout.replace( /name="home"/, - `name="home" prerender` + `name="home" prerender`, ) const resultsRoutesBlogPost = resultsRoutesHome.replace( /name="blogPost"/, - `name="blogPost" prerender` + `name="blogPost" prerender`, ) const resultsRoutesNotFound = resultsRoutesBlogPost.replace( /page={NotFoundPage}/, - `page={NotFoundPage} prerender` + `page={NotFoundPage} prerender`, ) const resultsRoutesWaterfall = resultsRoutesNotFound.replace( /page={WaterfallPage}/, - `page={WaterfallPage} prerender` + `page={WaterfallPage} prerender`, ) const resultsRoutesDouble = resultsRoutesWaterfall.replace( 'name="double"', - 'name="double" prerender' + 'name="double" prerender', ) const resultsRoutesNewContact = resultsRoutesDouble.replace( 'name="newContact"', - 'name="newContact" prerender' + 'name="newContact" prerender', ) fs.writeFileSync(pathRoutes, resultsRoutesNewContact) @@ -593,7 +595,7 @@ export default DoublePage` return execa( `yarn rw prisma migrate dev --name create_post_user`, [], - getExecaOptions(outputPath) + getExecaOptions(outputPath), ) }, }, @@ -605,7 +607,7 @@ export default DoublePage` // Replace the random numbers in the scenario with consistent values await applyCodemod( 'scenarioValueSuffix.js', - fullPath('api/src/services/posts/posts.scenarios') + fullPath('api/src/services/posts/posts.scenarios'), ) await execa(`yarn rwfw project:copy`, [], getExecaOptions(outputPath)) @@ -616,7 +618,7 @@ export default DoublePage` task: async () => { await applyCodemod( 'seed.js', - fullPath('scripts/seed.ts', { addExtension: false }) + fullPath('scripts/seed.ts', { addExtension: false }), ) }, }, @@ -630,7 +632,7 @@ export default DoublePage` await execa( `yarn rw prisma migrate dev --name create_contact`, [], - getExecaOptions(outputPath) + getExecaOptions(outputPath), ) await generateScaffold('contacts') @@ -644,7 +646,7 @@ export default DoublePage` OUTPUT_PATH, 'api', 'db', - 'migrations' + 'migrations', ) // Migration folders are folders which start with 14 digits because they have a yyyymmddhhmmss const migrationFolders = fs @@ -671,8 +673,8 @@ export default DoublePage` path.join(migrationsFolderPath, name), path.join( migrationsFolderPath, - `${datetimeInCorrectFormat}${name.substring(14)}` - ) + `${datetimeInCorrectFormat}${name.substring(14)}`, + ), ) datetime.setDate(datetime.getDate() + 1) }) @@ -691,18 +693,18 @@ export default DoublePage` await applyCodemod( 'usersSdl.js', - fullPath('api/src/graphql/users.sdl') + fullPath('api/src/graphql/users.sdl'), ) await applyCodemod( 'usersService.js', - fullPath('api/src/services/users/users') + fullPath('api/src/services/users/users'), ) // Replace the random numbers in the scenario with consistent values await applyCodemod( 'scenarioValueSuffix.js', - fullPath('api/src/services/users/users.scenarios') + fullPath('api/src/services/users/users.scenarios'), ) const test = `import { user } from './users' @@ -727,7 +729,7 @@ export default DoublePage` // Copy contact.scenarios.ts, because scenario tests look for the same filename fs.copyFileSync( fullPath('api/src/services/contacts/contacts.scenarios'), - fullPath('api/src/services/contacts/describeContacts.scenarios') + fullPath('api/src/services/contacts/describeContacts.scenarios'), ) // Create describeContacts.test.ts @@ -735,12 +737,12 @@ export default DoublePage` __dirname, 'templates', 'api', - 'contacts.describeScenario.test.ts.template' + 'contacts.describeScenario.test.ts.template', ) fs.copyFileSync( describeScenarioFixture, - fullPath('api/src/services/contacts/describeContacts.test') + fullPath('api/src/services/contacts/describeContacts.test'), ) }, }, @@ -757,7 +759,7 @@ export default DoublePage` exitOnError: true, renderer: verbose && 'verbose', renderOptions: { collapseSubtasks: false }, - } + }, ) } @@ -777,7 +779,7 @@ async function streamingTasks(outputPath, { verbose }) { await applyCodemod( 'delayedPage.js', - fullPath('web/src/pages/DelayedPage/DelayedPage') + fullPath('web/src/pages/DelayedPage/DelayedPage'), ) }, }, @@ -785,7 +787,7 @@ async function streamingTasks(outputPath, { verbose }) { title: 'Enable streaming-ssr experiment', task: async () => { const setupExperiment = createBuilder( - 'yarn rw experimental setup-streaming-ssr' + 'yarn rw experimental setup-streaming-ssr', ) await setupExperiment('--force') }, @@ -828,7 +830,7 @@ async function fragmentsTasks(outputPath, { verbose }) { return exec( 'yarn rw prisma migrate dev --name create_produce_stall', [], - getExecaOptions(outputPath) + getExecaOptions(outputPath), ) }, }, @@ -837,7 +839,7 @@ async function fragmentsTasks(outputPath, { verbose }) { task: async () => { await applyCodemod( 'seedFragments.ts', - fullPath('scripts/seed.ts', { addExtension: false }) + fullPath('scripts/seed.ts', { addExtension: false }), ) await exec('yarn rw prisma db seed', [], getExecaOptions(outputPath)) @@ -853,7 +855,7 @@ async function fragmentsTasks(outputPath, { verbose }) { await applyCodemod( 'producesSdl.ts', - fullPath('api/src/graphql/produces.sdl') + fullPath('api/src/graphql/produces.sdl'), ) }, }, @@ -865,7 +867,7 @@ async function fragmentsTasks(outputPath, { verbose }) { OUTPUT_PATH, 'web', 'src', - 'components' + 'components', ) for (const fileName of [ @@ -905,7 +907,7 @@ async function fragmentsTasks(outputPath, { verbose }) { await applyCodemod( 'groceriesPage.ts', - fullPath('web/src/pages/GroceriesPage/GroceriesPage') + fullPath('web/src/pages/GroceriesPage/GroceriesPage'), ) }, }, diff --git a/tasks/test-project/templates/web/FruitInfo.tsx b/tasks/test-project/templates/web/FruitInfo.tsx index 95015ee57764..67a03889a5cc 100644 --- a/tasks/test-project/templates/web/FruitInfo.tsx +++ b/tasks/test-project/templates/web/FruitInfo.tsx @@ -5,19 +5,17 @@ import { registerFragment } from '@redwoodjs/web/apollo' import Card from 'src/components/Card' import StallInfo from 'src/components/StallInfo' -const { useRegisteredFragment } = registerFragment( - gql` - fragment Fruit_info on Fruit { - id - name - isSeedless - ripenessIndicators - stall { - ...Stall_info - } +const { useRegisteredFragment } = registerFragment(gql` + fragment Fruit_info on Fruit { + id + name + isSeedless + ripenessIndicators + stall { + ...Stall_info } - ` -) + } +`) const FruitInfo = ({ id }: { id: string }) => { const { data: fruit, complete } = useRegisteredFragment(id) diff --git a/tasks/test-project/templates/web/ProduceInfo.tsx b/tasks/test-project/templates/web/ProduceInfo.tsx index f06a68ad5e9d..39e06a874703 100644 --- a/tasks/test-project/templates/web/ProduceInfo.tsx +++ b/tasks/test-project/templates/web/ProduceInfo.tsx @@ -4,14 +4,12 @@ import { registerFragment } from '@redwoodjs/web/apollo' import Card from 'src/components/Card' -const { useRegisteredFragment } = registerFragment( - gql` - fragment Produce_info on Produce { - id - name - } - ` -) +const { useRegisteredFragment } = registerFragment(gql` + fragment Produce_info on Produce { + id + name + } +`) const ProduceInfo = ({ id }: { id: string }) => { const { data, complete } = useRegisteredFragment(id) diff --git a/tasks/test-project/templates/web/StallInfo.tsx b/tasks/test-project/templates/web/StallInfo.tsx index 24b2fbb58d35..4178b6ea93af 100644 --- a/tasks/test-project/templates/web/StallInfo.tsx +++ b/tasks/test-project/templates/web/StallInfo.tsx @@ -2,14 +2,12 @@ import type { Stall } from 'types/graphql' import { registerFragment } from '@redwoodjs/web/apollo' -const { useRegisteredFragment } = registerFragment( - gql` - fragment Stall_info on Stall { - id - name - } - ` -) +const { useRegisteredFragment } = registerFragment(gql` + fragment Stall_info on Stall { + id + name + } +`) const StallInfo = ({ id }: { id: string }) => { const { data, complete } = useRegisteredFragment(id) diff --git a/tasks/test-project/templates/web/VegetableInfo.tsx b/tasks/test-project/templates/web/VegetableInfo.tsx index 96f6208b19e9..6954d3fe5f5b 100644 --- a/tasks/test-project/templates/web/VegetableInfo.tsx +++ b/tasks/test-project/templates/web/VegetableInfo.tsx @@ -5,19 +5,17 @@ import { registerFragment } from '@redwoodjs/web/apollo' import Card from 'src/components/Card' import StallInfo from 'src/components/StallInfo' -const { useRegisteredFragment } = registerFragment( - gql` - fragment Vegetable_info on Vegetable { - id - name - vegetableFamily - isPickled - stall { - ...Stall_info - } +const { useRegisteredFragment } = registerFragment(gql` + fragment Vegetable_info on Vegetable { + id + name + vegetableFamily + isPickled + stall { + ...Stall_info } - ` -) + } +`) const VegetableInfo = ({ id }: { id: string }) => { const { data: vegetable, complete } = useRegisteredFragment(id) diff --git a/tasks/test-project/util.js b/tasks/test-project/util.js index a4dd2c105a8e..78d577c25c3e 100644 --- a/tasks/test-project/util.js +++ b/tasks/test-project/util.js @@ -36,7 +36,7 @@ const getExecaOptions = (cwd) => ({ const updatePkgJsonScripts = ({ projectPath, scripts }) => { const projectPackageJsonPath = path.join(projectPath, 'package.json') const projectPackageJson = JSON.parse( - fs.readFileSync(projectPackageJsonPath, 'utf-8') + fs.readFileSync(projectPackageJsonPath, 'utf-8'), ) projectPackageJson.scripts = { ...projectPackageJson.scripts, @@ -44,7 +44,7 @@ const updatePkgJsonScripts = ({ projectPath, scripts }) => { } fs.writeFileSync( projectPackageJsonPath, - JSON.stringify(projectPackageJson, undefined, 2) + JSON.stringify(projectPackageJson, undefined, 2), ) } @@ -66,7 +66,7 @@ async function confirmNoFixtureNoLink(copyFromFixtureOption, linkOption) { onCancel: () => { process.exit(1) }, - } + }, ) return checkNoLink } diff --git a/tasks/tsconfig.json b/tasks/tsconfig.json index dcfb6070d4d2..8598869e8c39 100644 --- a/tasks/tsconfig.json +++ b/tasks/tsconfig.json @@ -2,6 +2,6 @@ "extends": "../tsconfig.compilerOption.json", "compilerOptions": { "moduleResolution": "NodeNext", - "module": "NodeNext", - }, + "module": "NodeNext" + } } diff --git a/tasks/update-package-versions b/tasks/update-package-versions index 3ea10c4f183c..e7a2beaa650c 100755 --- a/tasks/update-package-versions +++ b/tasks/update-package-versions @@ -11,7 +11,7 @@ async function run() { if (!version) { console.error( - 'You have to provide a version.\nUsage ./update-package-versions ' + 'You have to provide a version.\nUsage ./update-package-versions ', ) process.exitCode = 1 return @@ -40,7 +40,7 @@ async function run() { console.log('Updating CRWA template...') const tsTemplatePath = path.join( cwd, - 'packages/create-redwood-app/templates/ts' + 'packages/create-redwood-app/templates/ts', ) updateRWJSPkgsVersion(tsTemplatePath, version) updateRWJSPkgsVersion(path.join(tsTemplatePath, 'api'), version) @@ -49,7 +49,7 @@ async function run() { const jsTemplatePath = path.join( cwd, - 'packages/create-redwood-app/templates/js' + 'packages/create-redwood-app/templates/js', ) updateRWJSPkgsVersion(jsTemplatePath, version) updateRWJSPkgsVersion(path.join(jsTemplatePath, 'api'), version) From cb6a323f901aa0883e785b92f363932c1a5645ae Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 05:51:41 +0100 Subject: [PATCH 32/52] chore(yarn): update to use js config for constraints (#11290) We currently use a prolog file to define the constraints yarn applies when you run `yarn constraints` (which is run with `yarn check`). You can see [here](https://yarnpkg.com/features/constraints) that yarn states this format should be considered deprecated. Instead a `yarn.config.cjs` file is recommended. This change switches our current prolog one to this new js one. I added rules to enforce some consistent and correctly specified fields are present on our package.json files. We can add to this in the future should we wish to. --- .github/workflows/ci.yml | 2 +- constraints.pro | 27 ------ package.json | 1 + yarn.config.cjs | 181 +++++++++++++++++++++++++++++++++++++++ yarn.lock | 10 +++ 5 files changed, 193 insertions(+), 28 deletions(-) delete mode 100644 constraints.pro create mode 100644 yarn.config.cjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c8b5111a84e..c66b3505a0ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: uses: ./.github/actions/set-up-job with: set-up-yarn-cache: false - yarn-install-directory: ./tasks/check + yarn-install-directory: . build: false - name: ✅ Check constraints, dependencies, and package.json's diff --git a/constraints.pro b/constraints.pro deleted file mode 100644 index 463749739678..000000000000 --- a/constraints.pro +++ /dev/null @@ -1,27 +0,0 @@ -% Yarn Constraints https://yarnpkg.com/features/constraints -% check with "yarn constraints" (fix w/ "yarn constraints --fix") -% reference for other constraints: https://github.com/babel/babel/blob/main/constraints.pro - -% Enforces that a dependency doesn't appear in both `dependencies` and `devDependencies` -gen_enforced_dependency(WorkspaceCwd, DependencyIdent, null, 'devDependencies') :- - workspace_has_dependency(WorkspaceCwd, DependencyIdent, _, 'devDependencies'), - workspace_has_dependency(WorkspaceCwd, DependencyIdent, _, 'dependencies'). - -% Prevent two workspaces from depending on conflicting versions of a same dependency -gen_enforced_dependency(WorkspaceCwd, DependencyIdent, DependencyRange2, DependencyType) :- - workspace_has_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType), - workspace_has_dependency(OtherWorkspaceCwd, DependencyIdent, DependencyRange2, DependencyType2), - DependencyRange \= DependencyRange2. - -% Enforce that all workspaces building with Babel depend on '@babel/runtime-corejs3' and 'core-js'. -gen_enforced_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, 'dependencies') :- - member(DependencyIdent, [ - '@babel/runtime-corejs3', - 'core-js' - ]), - % Exclude the root workspace - WorkspaceCwd \= '.', - % Only target workspaces with a build:js script - workspace_field(WorkspaceCwd, 'scripts.build:js', _), - % Get the range from the root workspace - workspace_has_dependency('.', DependencyIdent, DependencyRange, _). diff --git a/package.json b/package.json index 2fac09ffa27c..b92811a7c404 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "@types/prompts": "2.4.9", "@typescript-eslint/eslint-plugin": "8.1.0", "@typescript-eslint/parser": "8.1.0", + "@yarnpkg/types": "4.0.0", "all-contributors-cli": "6.26.1", "babel-jest": "^29.7.0", "babel-plugin-auto-import": "1.1.0", diff --git a/yarn.config.cjs b/yarn.config.cjs new file mode 100644 index 000000000000..7b550da914bc --- /dev/null +++ b/yarn.config.cjs @@ -0,0 +1,181 @@ +/* eslint-env node */ +// @ts-check + +/** + * @typedef {import('@yarnpkg/types').Yarn.Constraints.Context} Context + * @typedef {import('@yarnpkg/types').Yarn.Constraints.Workspace} Workspace + */ + +/** @type {import('@yarnpkg/types')} */ +const { defineConfig } = require(`@yarnpkg/types`) + +/** + * This rule will enforce that a workspace MUST depend on the same version of a + * dependency as the one used by the other workspaces. + * + * @param {Context} context + */ +function enforceConsistentDependenciesAcrossTheProject({ Yarn }) { + for (const dependency of Yarn.dependencies()) { + if (dependency.type === `peerDependencies`) { + continue + } + + for (const otherDependency of Yarn.dependencies({ + ident: dependency.ident, + })) { + if (otherDependency.type === `peerDependencies`) { + continue + } + + if ( + (dependency.type === `devDependencies` || + otherDependency.type === `devDependencies`) && + Yarn.workspace({ ident: otherDependency.ident }) + ) { + continue + } + + dependency.update(otherDependency.range) + } + } +} + +/** + * This rule will enforce that a workspace MUST depend on the same version of a + * dependency as the one used by the other workspaces. + * + * @param {Context} context + */ +function enforceWorkspaceDependenciesWhenPossible({ Yarn }) { + for (const dependency of Yarn.dependencies()) { + if (!Yarn.workspace({ ident: dependency.ident })) { + continue + } + + dependency.update(`workspace:*`) + } +} + +/** + * This rule will enforce that a dependency doesn't appear in both `dependencies` + * and `devDependencies`. + * + * @param {Context} context + */ +function enforceNotProdAndDevDependencies({ Yarn }) { + for (const workspace of Yarn.workspaces()) { + const dependencies = Yarn.dependencies({ workspace, type: 'dependencies' }) + const devDependencies = Yarn.dependencies({ + workspace, + type: 'devDependencies', + }) + for (const dependency of dependencies) { + if ( + devDependencies.find( + (devDependency) => devDependency.ident === dependency.ident, + ) + ) { + dependency.error( + `The dependency '${dependency.ident}' should not appear in both dependencies and devDependencies`, + ) + } + } + } +} + +/** + * This rule will enforce that any package built with babel (identified by the + * presence of a 'build:js' script in its `package.json`) must depend on the + * '@babel/runtime-corejs3' and 'core-js' packages. + * + * @param {Context} context + */ +function enforceBabelDependencies({ Yarn }) { + for (const workspace of Yarn.workspaces()) { + const packageJson = workspace.manifest + if (!packageJson.scripts?.[`build:js`]) { + continue + } + + const dependencies = Yarn.dependencies({ + workspace, + type: 'dependencies', + }) + const requiredDependencies = [`@babel/runtime-corejs3`, `core-js`] + for (const dependency of requiredDependencies) { + if (!dependencies.find((dep) => dep.ident === dependency)) { + workspace.error( + `The package '${workspace.cwd}' must depend on '${dependency}' to build with babel`, + ) + } + } + } +} + +/** + * This rule will enforce that the specified fields are present in the + * `package.json` of all workspaces. + * + * @param {Context} context + * @param {string[]} fields + */ +function enforceFieldsOnAllWorkspaces({ Yarn }, fields) { + for (const workspace of Yarn.workspaces()) { + // Skip the root workspace + if (workspace.cwd === '.') { + continue + } + + for (const field of fields) { + if (!workspace.manifest[field]) { + workspace.error( + `The field '${field}' is required in the package.json of '${workspace.cwd}'`, + ) + } + } + } +} + +/** + * This rule will enforce that the specified fields are present in the + * `package.json` of all workspaces and that they have the expected value. + * + * @param {Context} context + * @param {Record any) | string>} fields + */ +function enforceFieldsWithValuesOnAllWorkspaces({ Yarn }, fields) { + for (const workspace of Yarn.workspaces()) { + // Skip the root workspace + if (workspace.cwd === '.') { + continue + } + + for (const [field, value] of Object.entries(fields)) { + workspace.set( + field, + typeof value === `function` ? value(workspace) : value, + ) + } + } +} + +module.exports = defineConfig({ + constraints: async (ctx) => { + enforceConsistentDependenciesAcrossTheProject(ctx) + enforceWorkspaceDependenciesWhenPossible(ctx) + enforceNotProdAndDevDependencies(ctx) + enforceBabelDependencies(ctx) + enforceFieldsOnAllWorkspaces(ctx, [ + 'name', + 'version', + // 'description', // TODO(jgmw): Add description to all packages and uncomment this line + ]) + enforceFieldsWithValuesOnAllWorkspaces(ctx, { + license: 'MIT', + ['repository.type']: 'git', + ['repository.url']: 'git+https://github.com/redwoodjs/redwood.git', + ['repository.directory']: (workspace) => workspace.cwd, + }) + }, +}) diff --git a/yarn.lock b/yarn.lock index dad43c6f8b77..a77c81799160 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11648,6 +11648,15 @@ __metadata: languageName: node linkType: hard +"@yarnpkg/types@npm:4.0.0": + version: 4.0.0 + resolution: "@yarnpkg/types@npm:4.0.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/41f67a4aa5c414c1e228f51453451fa15e0dd70c5cf2b1ae1ca142a3f018f25e4a37e60372cd0f5970c755e1804a2e31e208bff427add1cf13f899b0b9adc1e0 + languageName: node + linkType: hard + "@zkochan/js-yaml@npm:0.0.7": version: 0.0.7 resolution: "@zkochan/js-yaml@npm:0.0.7" @@ -26656,6 +26665,7 @@ __metadata: "@types/prompts": "npm:2.4.9" "@typescript-eslint/eslint-plugin": "npm:8.1.0" "@typescript-eslint/parser": "npm:8.1.0" + "@yarnpkg/types": "npm:4.0.0" all-contributors-cli: "npm:6.26.1" babel-jest: "npm:^29.7.0" babel-plugin-auto-import: "npm:1.1.0" From 49ddfd4047b9081489c3394020877c5c0b3b7496 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 17:12:41 +0100 Subject: [PATCH 33/52] chore: delete crowdin config file (#11291) I don't really have any context around this file. I wasn't with the project when it was last touched. It hasn't been updated in years and the content inside it looks outdated. I would suggest we just delete file and if we need to look into our translation setup again then we can do so. No point in an old file laying around if it's not providing value. --- crowdin.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 crowdin.yml diff --git a/crowdin.yml b/crowdin.yml deleted file mode 100644 index 6cbb752d4ee3..000000000000 --- a/crowdin.yml +++ /dev/null @@ -1,5 +0,0 @@ -files: - - source: /learn.redwoodjs.com/docs/tutorial - translation: /learn.redwoodjs.com/i18n/%two_letters_code%/tutorial/%original_file_name% - - source: /learn.redwoodjs.com/docs/tutorial2 - translation: /learn.redwoodjs.com/i18n/%two_letters_code%/tutorial2/%original_file_name% From 1f328ef4820a7554f81b88ebd680459b4d2327ae Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 17:53:27 +0100 Subject: [PATCH 34/52] chore(check): Refactor 'yarn check' away from being a standalone node script (#11292) The `yarn check` script was implemented as a standalone node program that executed a couple of other yarn commands in series. To simplify we can just run the two commands in the shell and avoid maintaining a whole node program just to do the same thing. --- .github/workflows/ci.yml | 2 +- package.json | 2 +- tasks/check/action.yml | 5 - tasks/check/check.mjs | 29 ---- tasks/check/package.json | 10 -- tasks/check/yarn.lock | 352 --------------------------------------- 6 files changed, 2 insertions(+), 398 deletions(-) delete mode 100644 tasks/check/action.yml delete mode 100644 tasks/check/check.mjs delete mode 100644 tasks/check/package.json delete mode 100644 tasks/check/yarn.lock diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c66b3505a0ea..266936d63bae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: build: false - name: ✅ Check constraints, dependencies, and package.json's - uses: ./tasks/check + run: yarn check check-skip: needs: detect-changes diff --git a/package.json b/package.json index b92811a7c404..17f654b6d17e 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "build:test-project": "node ./tasks/test-project/test-project", "build:watch": "lerna run build:watch --parallel; tsc --build", "changesets": "tsx ./tasks/changesets/changesets.mts", - "check": "node ./tasks/check/check.mjs", + "check": "cross-env yarn constraints && yarn dedupe --check", "check:package": "nx run-many -t check:package --output-style static", "clean:prisma": "rimraf node_modules/.prisma/client && node node_modules/@prisma/client/scripts/postinstall.js", "e2e": "node ./tasks/run-e2e", diff --git a/tasks/check/action.yml b/tasks/check/action.yml deleted file mode 100644 index 913458202a20..000000000000 --- a/tasks/check/action.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: 'Check' -description: "Check constraints, dependencies, and package.json's" -runs: - using: node20 - main: 'check.mjs' diff --git a/tasks/check/check.mjs b/tasks/check/check.mjs deleted file mode 100644 index edf76826bb40..000000000000 --- a/tasks/check/check.mjs +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-env es6, node */ -import core from '@actions/core' -import { exec } from '@actions/exec' - -const checks = [ - { - command: 'yarn constraints', - fix: 'You can fix this by running "yarn constraints --fix"', - }, - { - command: 'yarn dedupe --check', - fix: 'You can fix this by running "yarn dedupe"', - }, - // { - // command: - // 'yarn workspaces foreach --all --parallel run sort-package-json --check', - // fix: 'You can fix this by running "yarn workspaces foreach --parallel dlx sort-package-json"', - // }, -] - -for (const { command, fix } of checks) { - try { - await exec(command) - console.log(`"${command}" passed`) - } catch (_e) { - core.setFailed(`"${command}" failed`) - console.log(fix) - } -} diff --git a/tasks/check/package.json b/tasks/check/package.json deleted file mode 100644 index 16948c9c9ec8..000000000000 --- a/tasks/check/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "check", - "private": true, - "dependencies": { - "@actions/core": "1.10.1", - "@actions/exec": "1.1.1", - "sort-package-json": "2.10.0" - }, - "packageManager": "yarn@4.4.0" -} diff --git a/tasks/check/yarn.lock b/tasks/check/yarn.lock deleted file mode 100644 index a7af630cb5d9..000000000000 --- a/tasks/check/yarn.lock +++ /dev/null @@ -1,352 +0,0 @@ -# This file is generated by running "yarn install" inside your project. -# Manual changes might be lost - proceed with caution! - -__metadata: - version: 8 - cacheKey: 10c0 - -"@actions/core@npm:1.10.1": - version: 1.10.1 - resolution: "@actions/core@npm:1.10.1" - dependencies: - "@actions/http-client": "npm:^2.0.1" - uuid: "npm:^8.3.2" - checksum: 10c0/7a61446697a23dcad3545cf0634dedbdedf20ae9a0ee6ee977554589a15deb4a93593ee48a41258933d58ce0778f446b0d2c162b60750956fb75e0b9560fb832 - languageName: node - linkType: hard - -"@actions/exec@npm:1.1.1": - version: 1.1.1 - resolution: "@actions/exec@npm:1.1.1" - dependencies: - "@actions/io": "npm:^1.0.1" - checksum: 10c0/4a09f6bdbe50ce68b5cf8a7254d176230d6a74bccf6ecc3857feee209a8c950ba9adec87cc5ecceb04110182d1c17117234e45557d72fde6229b7fd3a395322a - languageName: node - linkType: hard - -"@actions/http-client@npm:^2.0.1": - version: 2.0.1 - resolution: "@actions/http-client@npm:2.0.1" - dependencies: - tunnel: "npm:^0.0.6" - checksum: 10c0/b58987ba2f53d7988f612ede7ff834573a3360c21f8fdea9fea92f26ada0fd0efafb22aa7d83f49c18965a5b765775d5253e2edb8d9476d924c4b304ef726b67 - languageName: node - linkType: hard - -"@actions/io@npm:^1.0.1": - version: 1.1.2 - resolution: "@actions/io@npm:1.1.2" - checksum: 10c0/61c871bbee1cf58f57917d9bb2cf6bb7ea4dc40de3f65c7fb4ec619ceff57fc98f56be9cca2d476b09e7a96e1cba0d88cd125c4f690d384b9483935186f256c1 - languageName: node - linkType: hard - -"@nodelib/fs.scandir@npm:2.1.5": - version: 2.1.5 - resolution: "@nodelib/fs.scandir@npm:2.1.5" - dependencies: - "@nodelib/fs.stat": "npm:2.0.5" - run-parallel: "npm:^1.1.9" - checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb - languageName: node - linkType: hard - -"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": - version: 2.0.5 - resolution: "@nodelib/fs.stat@npm:2.0.5" - checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d - languageName: node - linkType: hard - -"@nodelib/fs.walk@npm:^1.2.3": - version: 1.2.8 - resolution: "@nodelib/fs.walk@npm:1.2.8" - dependencies: - "@nodelib/fs.scandir": "npm:2.1.5" - fastq: "npm:^1.6.0" - checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 - languageName: node - linkType: hard - -"braces@npm:^3.0.2": - version: 3.0.3 - resolution: "braces@npm:3.0.3" - dependencies: - fill-range: "npm:^7.1.1" - checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 - languageName: node - linkType: hard - -"check@workspace:.": - version: 0.0.0-use.local - resolution: "check@workspace:." - dependencies: - "@actions/core": "npm:1.10.1" - "@actions/exec": "npm:1.1.1" - sort-package-json: "npm:2.10.0" - languageName: unknown - linkType: soft - -"detect-indent@npm:^7.0.1": - version: 7.0.1 - resolution: "detect-indent@npm:7.0.1" - checksum: 10c0/47b6e3e3dda603c386e73b129f3e84844ae59bc2615f5072becf3cc02eab400bed5a4e6379c49d0b18cf630e80c2b07e87e0038b777addbc6ef793ad77dd05bc - languageName: node - linkType: hard - -"detect-newline@npm:^4.0.0": - version: 4.0.0 - resolution: "detect-newline@npm:4.0.0" - checksum: 10c0/87dcff7a9ec25d1f4b356c068c3f05eb68bf6c2cbc4461da013df317ec184bbc96a2383bfaab9f963882ab988336bdadd5ce71b9cec55dde02d8ef84cef99250 - languageName: node - linkType: hard - -"dir-glob@npm:^3.0.1": - version: 3.0.1 - resolution: "dir-glob@npm:3.0.1" - dependencies: - path-type: "npm:^4.0.0" - checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c - languageName: node - linkType: hard - -"fast-glob@npm:^3.3.0": - version: 3.3.0 - resolution: "fast-glob@npm:3.3.0" - dependencies: - "@nodelib/fs.stat": "npm:^2.0.2" - "@nodelib/fs.walk": "npm:^1.2.3" - glob-parent: "npm:^5.1.2" - merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.4" - checksum: 10c0/4700063a2d7c9aae178f575648580bee1fc3f02ab3f358236d77811f52332bc10a398e75c6d5ecde61216996f3308247b37d70e2ee605a0748abe147f01b8f64 - languageName: node - linkType: hard - -"fastq@npm:^1.6.0": - version: 1.13.0 - resolution: "fastq@npm:1.13.0" - dependencies: - reusify: "npm:^1.0.4" - checksum: 10c0/76c7b5dafb93c7e74359a3e6de834ce7a7c2e3a3184050ed4cb652661de55cf8d4895178d8d3ccd23069395056c7bb15450660d38fb382ca88c142b22694d7c9 - languageName: node - linkType: hard - -"fill-range@npm:^7.1.1": - version: 7.1.1 - resolution: "fill-range@npm:7.1.1" - dependencies: - to-regex-range: "npm:^5.0.1" - checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 - languageName: node - linkType: hard - -"get-stdin@npm:^9.0.0": - version: 9.0.0 - resolution: "get-stdin@npm:9.0.0" - checksum: 10c0/7ef2edc0c81a0644ca9f051aad8a96ae9373d901485abafaabe59fd347a1c378689d8a3d8825fb3067415d1d09dfcaa43cb9b9516ecac6b74b3138b65a8ccc6b - languageName: node - linkType: hard - -"git-hooks-list@npm:^3.0.0": - version: 3.1.0 - resolution: "git-hooks-list@npm:3.1.0" - checksum: 10c0/f1b93dd11b80b2a687b99a8bb553c0d07f344532d475b3ac2a5ff044d40fa71567ddcfa5cb39fae0b4e43a670a33f02f71ec3b24b7263233f3a3df89deddfb5a - languageName: node - linkType: hard - -"glob-parent@npm:^5.1.2": - version: 5.1.2 - resolution: "glob-parent@npm:5.1.2" - dependencies: - is-glob: "npm:^4.0.1" - checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee - languageName: node - linkType: hard - -"globby@npm:^13.1.2": - version: 13.2.2 - resolution: "globby@npm:13.2.2" - dependencies: - dir-glob: "npm:^3.0.1" - fast-glob: "npm:^3.3.0" - ignore: "npm:^5.2.4" - merge2: "npm:^1.4.1" - slash: "npm:^4.0.0" - checksum: 10c0/a8d7cc7cbe5e1b2d0f81d467bbc5bc2eac35f74eaded3a6c85fc26d7acc8e6de22d396159db8a2fc340b8a342e74cac58de8f4aee74146d3d146921a76062664 - languageName: node - linkType: hard - -"ignore@npm:^5.2.4": - version: 5.2.4 - resolution: "ignore@npm:5.2.4" - checksum: 10c0/7c7cd90edd9fea6e037f9b9da4b01bf0a86b198ce78345f9bbd983929d68ff14830be31111edc5d70c264921f4962404d75b7262b4d9cc3bc12381eccbd03096 - languageName: node - linkType: hard - -"is-extglob@npm:^2.1.1": - version: 2.1.1 - resolution: "is-extglob@npm:2.1.1" - checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 - languageName: node - linkType: hard - -"is-glob@npm:^4.0.1": - version: 4.0.3 - resolution: "is-glob@npm:4.0.3" - dependencies: - is-extglob: "npm:^2.1.1" - checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a - languageName: node - linkType: hard - -"is-number@npm:^7.0.0": - version: 7.0.0 - resolution: "is-number@npm:7.0.0" - checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 - languageName: node - linkType: hard - -"is-plain-obj@npm:^4.1.0": - version: 4.1.0 - resolution: "is-plain-obj@npm:4.1.0" - checksum: 10c0/32130d651d71d9564dc88ba7e6fda0e91a1010a3694648e9f4f47bb6080438140696d3e3e15c741411d712e47ac9edc1a8a9de1fe76f3487b0d90be06ac9975e - languageName: node - linkType: hard - -"lru-cache@npm:^6.0.0": - version: 6.0.0 - resolution: "lru-cache@npm:6.0.0" - dependencies: - yallist: "npm:^4.0.0" - checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 - languageName: node - linkType: hard - -"merge2@npm:^1.3.0, merge2@npm:^1.4.1": - version: 1.4.1 - resolution: "merge2@npm:1.4.1" - checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb - languageName: node - linkType: hard - -"micromatch@npm:^4.0.4": - version: 4.0.5 - resolution: "micromatch@npm:4.0.5" - dependencies: - braces: "npm:^3.0.2" - picomatch: "npm:^2.3.1" - checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff - languageName: node - linkType: hard - -"path-type@npm:^4.0.0": - version: 4.0.0 - resolution: "path-type@npm:4.0.0" - checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c - languageName: node - linkType: hard - -"picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be - languageName: node - linkType: hard - -"queue-microtask@npm:^1.2.2": - version: 1.2.3 - resolution: "queue-microtask@npm:1.2.3" - checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 - languageName: node - linkType: hard - -"reusify@npm:^1.0.4": - version: 1.0.4 - resolution: "reusify@npm:1.0.4" - checksum: 10c0/c19ef26e4e188f408922c46f7ff480d38e8dfc55d448310dfb518736b23ed2c4f547fb64a6ed5bdba92cd7e7ddc889d36ff78f794816d5e71498d645ef476107 - languageName: node - linkType: hard - -"run-parallel@npm:^1.1.9": - version: 1.2.0 - resolution: "run-parallel@npm:1.2.0" - dependencies: - queue-microtask: "npm:^1.2.2" - checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 - languageName: node - linkType: hard - -"semver@npm:^7.6.0": - version: 7.6.0 - resolution: "semver@npm:7.6.0" - dependencies: - lru-cache: "npm:^6.0.0" - bin: - semver: bin/semver.js - checksum: 10c0/fbfe717094ace0aa8d6332d7ef5ce727259815bd8d8815700853f4faf23aacbd7192522f0dc5af6df52ef4fa85a355ebd2f5d39f554bd028200d6cf481ab9b53 - languageName: node - linkType: hard - -"slash@npm:^4.0.0": - version: 4.0.0 - resolution: "slash@npm:4.0.0" - checksum: 10c0/b522ca75d80d107fd30d29df0549a7b2537c83c4c4ecd12cd7d4ea6c8aaca2ab17ada002e7a1d78a9d736a0261509f26ea5b489082ee443a3a810586ef8eff18 - languageName: node - linkType: hard - -"sort-object-keys@npm:^1.1.3": - version: 1.1.3 - resolution: "sort-object-keys@npm:1.1.3" - checksum: 10c0/3bf62398658d3ff4bbca0db4ed8f42f98abc41433859f63d02fb0ab953fbe5526be240ec7e5d85aa50fcab6c937f3fa7015abf1ecdeb3045a2281c53953886bf - languageName: node - linkType: hard - -"sort-package-json@npm:2.10.0": - version: 2.10.0 - resolution: "sort-package-json@npm:2.10.0" - dependencies: - detect-indent: "npm:^7.0.1" - detect-newline: "npm:^4.0.0" - get-stdin: "npm:^9.0.0" - git-hooks-list: "npm:^3.0.0" - globby: "npm:^13.1.2" - is-plain-obj: "npm:^4.1.0" - semver: "npm:^7.6.0" - sort-object-keys: "npm:^1.1.3" - bin: - sort-package-json: cli.js - checksum: 10c0/f3325c402cd63fa42947e3861fde0ed26c742bb1db9011d4a4111f2a27427ec778ce8223af5c5dd8fcdb1cf49a1ff55d7e5323fb187d29811cd99e503a80fe26 - languageName: node - linkType: hard - -"to-regex-range@npm:^5.0.1": - version: 5.0.1 - resolution: "to-regex-range@npm:5.0.1" - dependencies: - is-number: "npm:^7.0.0" - checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 - languageName: node - linkType: hard - -"tunnel@npm:^0.0.6": - version: 0.0.6 - resolution: "tunnel@npm:0.0.6" - checksum: 10c0/e27e7e896f2426c1c747325b5f54efebc1a004647d853fad892b46d64e37591ccd0b97439470795e5262b5c0748d22beb4489a04a0a448029636670bfd801b75 - languageName: node - linkType: hard - -"uuid@npm:^8.3.2": - version: 8.3.2 - resolution: "uuid@npm:8.3.2" - bin: - uuid: dist/bin/uuid - checksum: 10c0/bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54 - languageName: node - linkType: hard - -"yallist@npm:^4.0.0": - version: 4.0.0 - resolution: "yallist@npm:4.0.0" - checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a - languageName: node - linkType: hard From b774874f6b3c43dc3092efed0f36ca5d6392fc03 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 18:30:58 +0100 Subject: [PATCH 35/52] chore(docs): update prettier config and format docs content (#11293) As title. I switched back to js vs json prettier configs so we can extend one from another. --- .prettierignore | 5 +- .prettierrc.json | 12 - docs/README.md | 3 +- docs/docs/app-configuration-redwood-toml.md | 42 ++- docs/docs/assets-and-files.md | 16 +- docs/docs/auth/azure.md | 9 +- docs/docs/auth/clerk.md | 4 +- docs/docs/auth/custom.md | 18 +- docs/docs/auth/dbauth.md | 36 +- docs/docs/auth/firebase.md | 14 +- docs/docs/auth/supabase.md | 55 +-- docs/docs/auth/supertokens.md | 2 +- docs/docs/authentication.md | 5 - docs/docs/builds.md | 9 +- docs/docs/cells.md | 17 +- docs/docs/cli-commands.md | 198 +++++------ docs/docs/connection-pooling.md | 19 +- docs/docs/contributing-overview.md | 55 +-- docs/docs/contributing-walkthrough.md | 56 ++- docs/docs/cors.md | 22 +- docs/docs/create-redwood-app.md | 23 +- docs/docs/data-migrations.md | 33 +- docs/docs/database-seeds.md | 38 +- docs/docs/deploy/baremetal.md | 86 ++--- docs/docs/deploy/coherence.md | 1 + docs/docs/deploy/edgio.md | 19 +- docs/docs/deploy/flightcontrol.md | 10 +- docs/docs/deploy/introduction.md | 3 +- docs/docs/deploy/netlify.md | 1 - docs/docs/deploy/render.md | 1 + docs/docs/deploy/serverless.md | 20 +- docs/docs/deploy/vercel.md | 8 +- docs/docs/directives.md | 34 +- docs/docs/docker.md | 66 ++-- docs/docs/environment-variables.md | 4 +- docs/docs/forms.md | 61 ++-- docs/docs/graphql.md | 194 +++++----- docs/docs/graphql/caching.md | 10 +- docs/docs/graphql/fragments.md | 63 ++-- docs/docs/graphql/mocking-graphql-requests.md | 29 +- docs/docs/graphql/trusted-documents.md | 64 +++- docs/docs/how-to/background-worker.md | 3 +- .../build-dashboards-fast-with-tremor.md | 83 +++-- docs/docs/how-to/custom-function.md | 2 +- docs/docs/how-to/dbauth-passwordless.md | 81 +++-- docs/docs/how-to/disable-api-database.md | 1 + docs/docs/how-to/file-uploads.md | 4 +- .../how-to/mocking-graphql-in-storybook.md | 30 +- docs/docs/how-to/oauth.md | 22 +- docs/docs/how-to/pagination.md | 3 +- docs/docs/how-to/role-based-access-control.md | 28 +- docs/docs/how-to/self-hosting-redwood.md | 1 + docs/docs/how-to/sending-emails.md | 2 +- docs/docs/how-to/supabase-auth.md | 3 +- docs/docs/how-to/test-in-github-actions.md | 22 +- docs/docs/how-to/using-a-third-party-api.md | 34 +- docs/docs/how-to/using-gitpod.md | 8 +- docs/docs/how-to/using-nvm.md | 7 +- docs/docs/how-to/using-yarn.md | 1 + docs/docs/how-to/windows-development-setup.md | 7 +- docs/docs/intro-to-servers.md | 44 +-- docs/docs/local-postgres-setup.md | 39 +- docs/docs/logger.md | 12 +- docs/docs/mailer.md | 35 +- docs/docs/monitoring/sentry.md | 6 +- docs/docs/prerender.md | 23 +- .../project-configuration-dev-test-build.mdx | 22 +- docs/docs/quick-start.md | 4 +- docs/docs/realtime.md | 66 ++-- docs/docs/redwoodrecord.md | 39 +- docs/docs/router.md | 15 +- docs/docs/schema-relations.md | 20 +- docs/docs/security.md | 41 ++- docs/docs/serverless-functions.md | 161 +++++---- docs/docs/services.md | 334 ++++++++++-------- docs/docs/storybook.md | 13 +- docs/docs/studio.md | 27 +- docs/docs/testing.md | 236 +++++++------ docs/docs/tutorial/afterword.md | 1 - .../docs/tutorial/chapter0/what-is-redwood.md | 62 ++-- docs/docs/tutorial/chapter1/file-structure.md | 3 + docs/docs/tutorial/chapter1/first-page.md | 15 +- docs/docs/tutorial/chapter1/installation.md | 3 +- docs/docs/tutorial/chapter2/cells.md | 12 +- .../docs/tutorial/chapter2/getting-dynamic.md | 4 +- docs/docs/tutorial/chapter2/routing-params.md | 9 +- docs/docs/tutorial/chapter3/forms.md | 40 +-- docs/docs/tutorial/chapter3/saving-data.md | 48 ++- docs/docs/tutorial/chapter4/authentication.md | 45 +-- docs/docs/tutorial/chapter4/deployment.md | 9 +- docs/docs/tutorial/chapter5/first-story.md | 1 - docs/docs/tutorial/chapter5/first-test.md | 27 +- docs/docs/tutorial/chapter5/storybook.md | 14 +- docs/docs/tutorial/chapter5/testing.md | 4 +- docs/docs/tutorial/chapter6/comment-form.md | 22 +- .../docs/tutorial/chapter6/comments-schema.md | 83 ++--- .../tutorial/chapter6/multiple-comments.md | 31 +- .../docs/tutorial/chapter6/the-redwood-way.md | 4 +- .../tutorial/chapter7/api-side-currentuser.md | 53 ++- docs/docs/tutorial/chapter7/rbac.md | 35 +- docs/docs/tutorial/intermission.md | 2 +- docs/docs/typescript/generated-types.md | 13 +- docs/docs/typescript/introduction.md | 4 +- docs/docs/typescript/strict-mode.md | 16 +- docs/docs/typescript/utility-types.md | 62 ++-- docs/docs/vite-configuration.md | 16 +- docs/docs/webhooks.md | 5 +- docs/prettier.config.js | 4 - docs/prettier.config.mjs | 12 + docs/src/css/custom.css | 14 +- docs/tsconfig.json | 2 +- docs/versions.json | 10 +- prettier.config.mjs | 17 + 113 files changed, 1919 insertions(+), 1627 deletions(-) delete mode 100644 .prettierrc.json delete mode 100644 docs/prettier.config.js create mode 100644 docs/prettier.config.mjs create mode 100644 prettier.config.mjs diff --git a/.prettierignore b/.prettierignore index d542685cc9d2..2a65829322f1 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,8 +4,9 @@ # Ignore fixture projects __fixtures__ -# Ignore the docs (docusaurus) project -docs/ +# Ignore the certain files in /docs +/docs/versioned_docs +/docs/versioned_sidebars # Ignore the .nx directory /.nx diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index ef04338a6774..000000000000 --- a/.prettierrc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/prettierrc", - "bracketSpacing": true, - "tabWidth": 2, - "semi": false, - "singleQuote": true, - "plugins": [ - "prettier-plugin-curly", - "prettier-plugin-sh", - "prettier-plugin-packagejson" - ] -} diff --git a/docs/README.md b/docs/README.md index 7f694bc3c9f8..8c47a8c4e6bc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,7 +20,7 @@ After running `yarn start`, you should be able to see your changes in the local #### Internal linking -For links to other docs inside the `tutorials` directory you need to use *relative* links. +For links to other docs inside the `tutorials` directory you need to use _relative_ links. ``` In [previous section](./first-page) we.... @@ -35,6 +35,7 @@ Fork the repo, make your changes and open a PR on GitHub. That will build and la Double check that your changes look good! ### Updating Doc Images + To update any images in the doc, first upload your screenshot into a comment textbox in your PR. Once it's uploaded, you can open the image in a new tab and use the github url as a image link in your docs. ## Contributors diff --git a/docs/docs/app-configuration-redwood-toml.md b/docs/docs/app-configuration-redwood-toml.md index 214a17d0c481..afb3abbdd613 100644 --- a/docs/docs/app-configuration-redwood-toml.md +++ b/docs/docs/app-configuration-redwood-toml.md @@ -28,17 +28,17 @@ For certain options, instead of having to configure build tools directly, there' ## [web] -| Key | Description | Default | -| :---------------------------- | :--------------------------------------------------------- | :---------------------- | -| `title` | Title of your Redwood app | `'Redwood App'` | -| `port` | Port for the web server to listen at | `8910` | -| `apiUrl` | URL to your api server. This can be a relative URL in which case it acts like a proxy, or a fully-qualified URL | `'/.redwood/functions'` | -| `includeEnvironmentVariables` | Environment variables made available to the web side during dev and build | `[]` | -| `host` | Hostname for the web server to listen at | Defaults to `'0.0.0.0'` in production and `'::'` in development | -| `apiGraphQLUrl` | URL to your GraphQL function | `'${apiUrl}/graphql'` | -| `apiDbAuthUrl` | URL to your dbAuth function | `'${apiUrl}/auth'` | -| `sourceMap` | Enable source maps for production builds | `false` | -| `a11y` | Enable storybook `addon-a11y` and `eslint-plugin-jsx-a11y` | `true` | +| Key | Description | Default | +| :---------------------------- | :-------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------- | +| `title` | Title of your Redwood app | `'Redwood App'` | +| `port` | Port for the web server to listen at | `8910` | +| `apiUrl` | URL to your api server. This can be a relative URL in which case it acts like a proxy, or a fully-qualified URL | `'/.redwood/functions'` | +| `includeEnvironmentVariables` | Environment variables made available to the web side during dev and build | `[]` | +| `host` | Hostname for the web server to listen at | Defaults to `'0.0.0.0'` in production and `'::'` in development | +| `apiGraphQLUrl` | URL to your GraphQL function | `'${apiUrl}/graphql'` | +| `apiDbAuthUrl` | URL to your dbAuth function | `'${apiUrl}/auth'` | +| `sourceMap` | Enable source maps for production builds | `false` | +| `a11y` | Enable storybook `addon-a11y` and `eslint-plugin-jsx-a11y` | `true` | ### Customizing the GraphQL Endpoint @@ -105,22 +105,20 @@ Don't make secrets available to your web side. Everything in `includeEnvironment ## [api] -| Key | Description | Default | -| :------------- | :---------------------------------- | :------------------------- | -| `port` | Port for the api server to listen at | `8911` | -| `host` | Hostname for the api server to listen at | Defaults to `'0.0.0.0'` in production and `'::'` in development | -| `schemaPath` | The location of your Prisma schema. If you have [enabled Prisma multi file schemas](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema), then its value is the directory where your `schema.prisma` can be found, for example: `'./api/db/schema'` | Defaults to `'./api/db/schema.prisma'` | -| `debugPort` | Port for the debugger to listen at | `18911` | - +| Key | Description | Default | +| :----------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------- | +| `port` | Port for the api server to listen at | `8911` | +| `host` | Hostname for the api server to listen at | Defaults to `'0.0.0.0'` in production and `'::'` in development | +| `schemaPath` | The location of your Prisma schema. If you have [enabled Prisma multi file schemas](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema), then its value is the directory where your `schema.prisma` can be found, for example: `'./api/db/schema'` | Defaults to `'./api/db/schema.prisma'` | +| `debugPort` | Port for the debugger to listen at | `18911` | Additional server configuration can be done using [Server File](docker.md#using-the-server-file) - ### Multi File Schema -Prisma's `prismaSchemaFolder` [feature](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema) allows you to define multiple files in a schema subdirectory of your prisma directory. +Prisma's `prismaSchemaFolder` [feature](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema) allows you to define multiple files in a schema subdirectory of your prisma directory. -:::note Important +:::note Important If you wish to [organize your Prisma Schema into multiple files](https://www.prisma.io/blog/organize-your-prisma-schema-with-multi-file-support), you will need [enable](https://www.prisma.io/docs/orm/prisma-schema/overview/location#multi-file-prisma-schema) that feature in Prisma, move your `schema.prisma` file into a new directory such as `./api/db/schema` and then set `schemaPath` in the api toml config. ::: @@ -128,7 +126,7 @@ For example: ```toml title="redwood.toml" [api] - port = 8911 + port = 8911 schemaPath = "./api/db/schema" ``` diff --git a/docs/docs/assets-and-files.md b/docs/docs/assets-and-files.md index 785f92861ef5..2cdcf544242c 100644 --- a/docs/docs/assets-and-files.md +++ b/docs/docs/assets-and-files.md @@ -144,8 +144,8 @@ export const CarIcon = (props: SVGProps) => { If you needed to convert a whole library of SVGs into stylable (or animatable!) components, one easy way would be to use the [SVGR cli](https://react-svgr.com/docs/cli/) - ## Custom fonts + There are many different ways to peel this potato – it's all a search away – but if you're using the CSS `@font-face` rule, we have a quick tip for you: 1. Place your fonts in the public folder, so it gets carried across @@ -154,15 +154,15 @@ There are many different ways to peel this potato – it's all a search away – ```shell web/ ├── src - ├── App.tsx - ├── entry.client.tsx - ├── index.css - ├── ... +├── App.tsx +├── entry.client.tsx +├── index.css +├── ... ├── public -│ ├── favicon.png -│ ├── fonts +│ ├── favicon.png +│ ├── fonts // highlight-next-line -│ │ └── RedwoodNeue.woff2 +│ │ └── RedwoodNeue.woff2 ``` ```css diff --git a/docs/docs/auth/azure.md b/docs/docs/auth/azure.md index cf46c4d44f88..61477529fcb6 100644 --- a/docs/docs/auth/azure.md +++ b/docs/docs/auth/azure.md @@ -94,9 +94,7 @@ const HomePage = () => { {/* MetaTags, h1, paragraphs, etc. */}

{JSON.stringify({ isAuthenticated })}

- + ) } @@ -155,7 +153,7 @@ AZURE_ACTIVE_DIRECTORY_KNOWN_AUTHORITY=https://rwauthtestb2c.b2clogin.com ``` And don't forget to add `AZURE_ACTIVE_DIRECTORY_KNOWN_AUTHORITY` to the `includeEnvironmentVariables` array in `redwood.toml`. -(`AZURE_ACTIVE_DIRECTORY_JWT_ISSUER` is only used on the API side. But more importantly, it's sensitive—do *not* include it in the web side.) +(`AZURE_ACTIVE_DIRECTORY_JWT_ISSUER` is only used on the API side. But more importantly, it's sensitive—do _not_ include it in the web side.) #### Update `activeDirectoryClient` instance @@ -170,7 +168,7 @@ const azureActiveDirectoryClient = new PublicClientApplication({ postLogoutRedirectUri: process.env.AZURE_ACTIVE_DIRECTORY_LOGOUT_REDIRECT_URI, // highlight-next-line - knownAuthorities: [process.env.AZURE_ACTIVE_DIRECTORY_KNOWN_AUTHORITY] + knownAuthorities: [process.env.AZURE_ACTIVE_DIRECTORY_KNOWN_AUTHORITY], }, }) ``` @@ -178,5 +176,6 @@ const azureActiveDirectoryClient = new PublicClientApplication({ Now you can call the `logIn` and `logOut` functions from `useAuth()`, and everything should just work. Here's a few more links to relevant documentation for reference: + - [Overview of tokens in Azure Active Directory B2C](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview) - [Working with MSAL.js and Azure AD B2C](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/working-with-b2c.md) diff --git a/docs/docs/auth/clerk.md b/docs/docs/auth/clerk.md index 06266d0b4774..ec0f98555c50 100644 --- a/docs/docs/auth/clerk.md +++ b/docs/docs/auth/clerk.md @@ -13,7 +13,6 @@ See the [migration guide](https://github.com/redwoodjs/redwood/releases/tag/v5.3 ::: - To get started, run the setup command: ```text @@ -83,7 +82,6 @@ const HomePage = () => { Clicking sign up should open a sign-up box and after you sign up, you should see `{"isAuthenticated":true}` on the page. - ## Customizing the session token There's not a lot to the default session token. @@ -105,7 +103,7 @@ export const getCurrentUser = async ( // ... } -```` +``` ## Avoiding feature duplication diff --git a/docs/docs/auth/custom.md b/docs/docs/auth/custom.md index 65b5b801ab11..a694585d5ddf 100644 --- a/docs/docs/auth/custom.md +++ b/docs/docs/auth/custom.md @@ -71,7 +71,7 @@ We'll take all the work you have to do reading docs for granted here and cut to import { NhostClient } from '@nhost/nhost-js' const client = new NhostClient({ - backendUrl: '...' + backendUrl: '...', }) ``` @@ -105,7 +105,7 @@ import { NhostClient } from '@nhost/nhost-js' // ... const client = new NhostClient({ - backendUrl: process.env.NHOST_BACKEND_URL + backendUrl: process.env.NHOST_BACKEND_URL, }) ``` @@ -283,10 +283,16 @@ const HomePage = () => { {/* MetaTags, h1, paragraphs, etc. */}

{JSON.stringify({ isAuthenticated })}

- + ) } diff --git a/docs/docs/auth/dbauth.md b/docs/docs/auth/dbauth.md index 7bb395831159..b4207909941c 100644 --- a/docs/docs/auth/dbauth.md +++ b/docs/docs/auth/dbauth.md @@ -121,7 +121,7 @@ Almost all config for dbAuth lives in `api/src/functions/auth.js` in the object ### allowedUserFields ```javascript -allowedUserFields: ["id", "email"] +allowedUserFields: ['id', 'email'] ``` Most of the auth handlers accept a `user` argument that you can reference in the body of the function. These handlers also sometimes return that `user` object. As a security measure, `allowedUserFields` defines the only properties that will be available in that object so that sensitive data isn't accidentally leaked by these handlers to the client. @@ -223,13 +223,16 @@ If the password is valid, return `true`. Otherwise, throw the `PasswordValidatio ```javascript signup: { passwordValidation: (password) => { - if (password.length < 8) { - throw new PasswordValidationError('Password must be at least 8 characters') + throw new PasswordValidationError( + 'Password must be at least 8 characters' + ) } if (!password.match(/[A-Z]/)) { - throw new PasswordValidationError('Password must contain at least one capital letter') + throw new PasswordValidationError( + 'Password must contain at least one capital letter' + ) } return true @@ -299,13 +302,13 @@ login: { By default no setting is required. This is because each db has its own rules for enabling this feature. To enable please see the table below and pick the correct 'userMatchString' for your db of choice. -| DB | Default | usernameMatchString | notes | -|---|---|---|---| -| Postgres | 'default' | 'insensitive' | | -| MySQL | 'case-insensitive' | N/A | turned on by default so no setting required | -| MongoDB | 'default' | 'insensitive' | -| SQLite | N/A | N/A | [Not Supported] Insensitive checks can only be defined at a per column level | -| Microsoft SQL Server | 'case-insensitive' | N/A | turned on by default so no setting required | +| DB | Default | usernameMatchString | notes | +| -------------------- | ------------------ | ------------------- | ---------------------------------------------------------------------------- | +| Postgres | 'default' | 'insensitive' | | +| MySQL | 'case-insensitive' | N/A | turned on by default so no setting required | +| MongoDB | 'default' | 'insensitive' | +| SQLite | N/A | N/A | [Not Supported] Insensitive checks can only be defined at a per column level | +| Microsoft SQL Server | 'case-insensitive' | N/A | turned on by default so no setting required | ### Cookie config @@ -440,13 +443,13 @@ In both cases, actual scanning and matching of devices is handled by the operati WebAuthn is supported in the following browsers (as of July 2022): -| OS | Browser | Authenticator | -| ------- | ------- | ------------- | -| macOS | Firefox | Yubikey Security Key NFC (USB), Yubikey 5Ci, SoloKey | +| OS | Browser | Authenticator | +| ------- | ------- | -------------------------------------------------------------- | +| macOS | Firefox | Yubikey Security Key NFC (USB), Yubikey 5Ci, SoloKey | | macOS | Chrome | Touch ID, Yubikey Security Key NFC (USB), Yubikey 5Ci, SoloKey | | iOS | All | Face ID, Touch ID, Yubikey Security Key NFC (NFC), Yubikey 5Ci | -| Android | Chrome | Fingerprint Scanner, caBLE | -| Android | Firefox | Screen PIN | +| Android | Chrome | Fingerprint Scanner, caBLE | +| Android | Firefox | Screen PIN | ### Configuration @@ -528,7 +531,6 @@ import { db } from 'src/lib/db' import { DbAuthHandler } from '@redwoodjs/api' export const handler = async (event, context) => { - // assorted handler config here... const authHandler = new DbAuthHandler(event, context, { diff --git a/docs/docs/auth/firebase.md b/docs/docs/auth/firebase.md index dc4b3a5d95aa..6fa20136e3e4 100644 --- a/docs/docs/auth/firebase.md +++ b/docs/docs/auth/firebase.md @@ -59,10 +59,16 @@ const HomePage = () => { {/* MetaTags, h1, paragraphs, etc. */}

{JSON.stringify({ isAuthenticated })}

- + ) } diff --git a/docs/docs/auth/supabase.md b/docs/docs/auth/supabase.md index 5b4e19903f77..d9274e799773 100644 --- a/docs/docs/auth/supabase.md +++ b/docs/docs/auth/supabase.md @@ -1,6 +1,7 @@ --- sidebar_label: Supabase --- + # Supabase Authentication To get started, run the setup command: @@ -53,7 +54,6 @@ After you sign up, head to your inbox: there should be a confirmation email from Click the link, then head back to your app. Once you refresh the page, you should see `{"isAuthenticated":true}` on the page. - Let's make sure: if this is a brand new project, generate a home page. There we'll try to sign up by destructuring `signUp` from the `useAuth` hook (import that from `'src/auth'`). We'll also destructure and display `isAuthenticated` to see if it worked: @@ -69,10 +69,16 @@ const HomePage = () => { {/* MetaTags, h1, paragraphs, etc. */}

{JSON.stringify({ isAuthenticated })}

- + ) } @@ -126,14 +132,14 @@ Creates a new user with additional user metadata. const { signUp } = useAuth() await signUp({ -email: 'example@email.com', + email: 'example@email.com', password: 'example-password', options: { data: { first_name: 'John', age: 27, - } - } + }, + }, }) ``` @@ -145,11 +151,11 @@ Creates a new user with a redirect URL. const { signUp } = useAuth() await signUp({ -email: 'example@email.com', + email: 'example@email.com', password: 'example-password', options: { - emailRedirectTo: 'https://example.com/welcome' - } + emailRedirectTo: 'https://example.com/welcome', + }, }) ``` @@ -157,7 +163,7 @@ email: 'example@email.com', Log in an existing user with an email and password or phone and password. -* Requires either an email and password or a phone number and password. +- Requires either an email and password or a phone number and password. ```ts const { logIn } = useAuth() @@ -173,9 +179,9 @@ await logIn({ Log in a user using magiclink or a one-time password (OTP). -* Requires either an email or phone number. +- Requires either an email or phone number. -* This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number. +- This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number. ```ts const { logIn } = useAuth() @@ -184,8 +190,8 @@ await logIn({ authMethod: 'otp', email: 'example@email.com', options: { - emailRedirectTo: 'https://example.com/welcome' - } + emailRedirectTo: 'https://example.com/welcome', + }, }) ``` @@ -193,9 +199,9 @@ await logIn({ Log in an existing user via a third-party provider. -* This method is used for signing in using a third-party provider. +- This method is used for signing in using a third-party provider. -* Supabase supports many different [third-party providers](https://supabase.com/docs/guides/auth#providers). +- Supabase supports many different [third-party providers](https://supabase.com/docs/guides/auth#providers). ```ts const { logIn } = useAuth() @@ -270,10 +276,9 @@ logOut() Log in a user given a User supplied OTP received via mobile. -* The verifyOtp method takes in different verification types. If a phone number is used, the type can either be sms or phone_change. If an email address is used, the type can be one of the following: signup, magiclink, recovery, invite or email_change. - -* The verification type used should be determined based on the corresponding auth method called before verifyOtp to sign up / sign-in a user. +- The verifyOtp method takes in different verification types. If a phone number is used, the type can either be sms or phone_change. If an email address is used, the type can be one of the following: signup, magiclink, recovery, invite or email_change. +- The verification type used should be determined based on the corresponding auth method called before verifyOtp to sign up / sign-in a user. The RedwoodJS auth provider doesn't expose the `veriftyOtp` method from the Supabase SDK directly. @@ -285,7 +290,7 @@ So, in order to use the `verifyOtp` method, you would: const { client } = useAuth() useEffect(() => { - const { data, error } = await client.verifyOtp({ phone, token, type: 'sms'}) + const { data, error } = await client.verifyOtp({ phone, token, type: 'sms' }) }, [client]) ``` @@ -317,13 +322,15 @@ useEffect(() => { Receive a notification every time an auth event happens. -* Types of auth events: `SIGNED_IN`, `SIGNED_OUT`, `TOKEN_REFRESHED`, `USER_UPDATED`, `PASSWORD_RECOVERY` +- Types of auth events: `SIGNED_IN`, `SIGNED_OUT`, `TOKEN_REFRESHED`, `USER_UPDATED`, `PASSWORD_RECOVERY` ```ts const { client } = useAuth() useEffect(() => { - const { data: { subscription } } = client.onAuthStateChange((event, session) => { + const { + data: { subscription }, + } = client.onAuthStateChange((event, session) => { console.log(event, session) }) diff --git a/docs/docs/auth/supertokens.md b/docs/docs/auth/supertokens.md index 8b0b6b97ca8a..ecdc200726c6 100644 --- a/docs/docs/auth/supertokens.md +++ b/docs/docs/auth/supertokens.md @@ -51,6 +51,7 @@ SUPERTOKENS_API_KEY=your-api-key # The value can be omitted when self-hosting Su ``` ## Social login setup + The following environment variables have to be set up (depending on the social login options): ```bash @@ -79,7 +80,6 @@ includeEnvironmentVariables = [ ] ``` - # Page setup Let's make sure: if this is a brand new project, generate a home page. diff --git a/docs/docs/authentication.md b/docs/docs/authentication.md index b680c802a934..7c3d96e5ab1e 100644 --- a/docs/docs/authentication.md +++ b/docs/docs/authentication.md @@ -128,7 +128,6 @@ const Routes = () => { - // highlight-next-line @@ -150,16 +149,13 @@ const Routes = () => { - - // highlight-next-line - // highlight-next-line @@ -187,7 +183,6 @@ export const handler = createGraphQLHandler({ getCurrentUser, // ... }) - ``` If you're using one of Redwood's official integrations, `authDecoder` comes from the corresponding integration package (in auth0's case, `@redwoodjs/auth-auth0-api`): diff --git a/docs/docs/builds.md b/docs/docs/builds.md index 7303f1872814..b5cc87de5f0f 100644 --- a/docs/docs/builds.md +++ b/docs/docs/builds.md @@ -1,6 +1,7 @@ --- description: What happens when you build your app --- + # Builds > ⚠ **Work in Progress** ⚠️ @@ -11,7 +12,6 @@ description: What happens when you build your app > You can edit this doc [here](https://github.com/redwoodjs/redwoodjs.com/blob/main/docs/builds.md). > If you have any questions, just ask for help! We're active on the [forums](https://community.redwoodjs.com/c/contributing/9) and on [discord](https://discord.com/channels/679514959968993311/747258086569541703). - ## API The api side of Redwood is transpiled by Babel into the `./api/dist` folder. @@ -28,9 +28,10 @@ yarn zip-it-and-ship-it dist/functions/ zipballs/ Each lambda function in `./api/dist/functions` is parsed by zip-it-and-ship-it resulting in a zip file per lambda function that contains all the dependencies required for that lambda function. ->Note: The `@netlify/zip-it-and-ship-it` package needs to be installed as a dev dependency in `api/`. Use the command `yarn workspace api add -D @netlify/zip-it-and-ship-it`. ->- You can learn more about the package [here](https://www.npmjs.com/package/@netlify/zip-it-and-ship-it). ->- For more information on AWS Serverless Deploy see these [docs](/docs/deploy/serverless). +> Note: The `@netlify/zip-it-and-ship-it` package needs to be installed as a dev dependency in `api/`. Use the command `yarn workspace api add -D @netlify/zip-it-and-ship-it`. +> +> - You can learn more about the package [here](https://www.npmjs.com/package/@netlify/zip-it-and-ship-it). +> - For more information on AWS Serverless Deploy see these [docs](/docs/deploy/serverless). ## Web diff --git a/docs/docs/cells.md b/docs/docs/cells.md index 0a7377cd6b54..addfa2d6b2ac 100644 --- a/docs/docs/cells.md +++ b/docs/docs/cells.md @@ -1,6 +1,7 @@ --- description: Declarative data fetching with Cells --- + # Cells Cells are a declarative approach to data fetching and one of Redwood's signature modes of abstraction. @@ -43,7 +44,7 @@ yarn rw generate cell equipment --list ## Cells in-depth -Cells exports five constants: `QUERY`, `Loading` , `Empty` , `Failure` and `Success`. The root query in `QUERY` is the same as `` so that, if you're generating a cell based on a model in your `schema.prisma`, you can get something out of the database right away. But there's a good chance you won't generate your Cell this way, so if you need to, make sure to change the root query. See the [Cells](tutorial/chapter2/cells.md#our-first-cell) section of the Tutorial for a great example of this. +Cells exports five constants: `QUERY`, `Loading` , `Empty` , `Failure` and `Success`. The root query in `QUERY` is the same as `` so that, if you're generating a cell based on a model in your `schema.prisma`, you can get something out of the database right away. But there's a good chance you won't generate your Cell this way, so if you need to, make sure to change the root query. See the [Cells](tutorial/chapter2/cells.md#our-first-cell) section of the Tutorial for a great example of this. ## Usage @@ -114,7 +115,7 @@ export default HomePage ```jsx {2-3} export const QUERY = gql` - query($numberToShow: Int!) { + query ($numberToShow: Int!) { posts(numberToShow: $numberToShow) { id title @@ -135,8 +136,8 @@ By default, `beforeQuery` gives any props passed from the parent component to `Q export const beforeQuery = (props) => { return { variables: props, - fetchPolicy: 'cache-and-network' - } + fetchPolicy: 'cache-and-network', + } } ``` @@ -156,8 +157,8 @@ export const beforeQuery = () => { const { currentUser } = useAuth() return { - variables: { userId: currentUser.id } - } + variables: { userId: currentUser.id }, + } } ``` @@ -224,6 +225,7 @@ But, like `Loading`, Storybook is probably a better place to develop this. In production, failed cells won't break your app, they'll just be empty divs... --> In this example, we use the `errorCode` to conditionally render the error heading title, and we also use it for our translation string. + ```jsx export const Failure = ({ error, errorCode }: CellFailureProps) => { const { t } = useTranslation() @@ -282,7 +284,7 @@ client = useApolloClient() client.query({ query: gql` ... - ` + `, }) ``` @@ -347,6 +349,7 @@ And now let's say that Babel isn't going to come along and assemble our exports. We'd probably do something like this: + ```jsx const QUERY = gql` query { diff --git a/docs/docs/cli-commands.md b/docs/docs/cli-commands.md index f09be28f7a42..35afdca162ad 100644 --- a/docs/docs/cli-commands.md +++ b/docs/docs/cli-commands.md @@ -71,10 +71,10 @@ yarn redwood build [side..] We use Babel to transpile the api side into `./api/dist` and Vite to package the web side into `./web/dist`. -| Arguments & Options | Description | -| :------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `side` | Which side(s) to build. Choices are `api` and `web`. Defaults to `api` and `web` | -| `--verbose, -v` | Print more information while building | +| Arguments & Options | Description | +| :------------------ | :------------------------------------------------------------------------------- | +| `side` | Which side(s) to build. Choices are `api` and `web`. Defaults to `api` and `web` | +| `--verbose, -v` | Print more information while building | #### Usage @@ -88,9 +88,9 @@ Running `yarn redwood build` without any arguments generates the Prisma client a ~/redwood-app$ yarn redwood build yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood build - ✔ Generating the Prisma client... - ✔ Building "api"... - ✔ Building "web"... +✔ Generating the Prisma client... +✔ Building "api"... +✔ Building "web"... Done in 17.37s. ``` @@ -192,10 +192,10 @@ yarn redwood dev [side..] `yarn redwood dev api` starts the Redwood dev server and `yarn redwood dev web` starts the Vite dev server with Redwood's config. -| Argument | Description | -| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `side` | Which dev server(s) to start. Choices are `api` and `web`. Defaults to `api` and `web` | -| `--forward, --fwd` | String of one or more Vite Dev Server config options. See example usage below | +| Argument | Description | +| :----------------- | :------------------------------------------------------------------------------------- | +| `side` | Which dev server(s) to start. Choices are `api` and `web`. Defaults to `api` and `web` | +| `--forward, --fwd` | String of one or more Vite Dev Server config options. See example usage below | #### Usage @@ -208,10 +208,10 @@ $ /redwood-app/node_modules/.bin/redwood dev api $ /redwood-app/node_modules/.bin/dev-server 15:04:51 api | Listening on http://localhost:8911 15:04:51 api | Watching /home/dominic/projects/redwood/redwood-app/api -15:04:51 api | -15:04:51 api | Now serving -15:04:51 api | -15:04:51 api | ► http://localhost:8911/graphql/ +15:04:51 api \ + | 15:04:51 api | Now serving +15:04:51 api \ + | 15:04:51 api | ► http://localhost:8911/graphql/ ``` Using `--forward` (alias `--fwd`), you can pass one or more Vite Dev Server [config options](https://vitejs.dev/guide/cli#vite). The following will run the dev server, set the port to `1234`, and disable automatic browser opening. @@ -268,7 +268,6 @@ yarn redwood deploy serverless | `--pack-only` | Only package the build for deployment | | `--first-run` | Use this flag the first time you deploy. The first deploy wizard will walk you through configuring your web side to connect to the api side | - ### deploy netlify Build command for Netlify deploy @@ -284,6 +283,7 @@ yarn redwood deploy netlify | `--data-migrate, --dm` | Migrate the data in your database [default: "true"] | #### Example + The following command will build, apply Prisma DB migrations, and skip data migrations. ``` @@ -316,6 +316,7 @@ yarn redwood deploy render | `--serve` | Run server for api in production [default: "true"] | #### Example + The following command will build the Web side for static-site CDN deployment. ``` @@ -343,6 +344,7 @@ yarn redwood deploy vercel | `--data-migrate, --dm` | Migrate the data in your database [default: "true"] | #### Example + The following command will build, apply Prisma DB migrations, and skip data migrations. ``` @@ -402,6 +404,7 @@ See [this how to](how-to/background-worker.md) for an example of using exec to r Set up and run experimental features. Some caveats: + - these features do not follow SemVer (may be breaking changes in minor and patch releases) - these features may be deprecated or removed (anytime) - your feedback is wanted and necessary! @@ -411,6 +414,7 @@ For more information, including details about specific features, see this Redwoo **Available Experimental Features** View all that can be _set up_: + ``` yarn redwood experimental --help ``` @@ -491,9 +495,9 @@ Generating a user cell: ~/redwood-app$ yarn redwood generate cell user yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood g cell user - ✔ Generating cell files... - ✔ Writing `./web/src/components/UserCell/UserCell.test.js`... - ✔ Writing `./web/src/components/UserCell/UserCell.js`... +✔ Generating cell files... +✔ Writing $(./web/src/components/UserCell/UserCell.test.js)... +✔ Writing $(./web/src/components/UserCell/UserCell.js)... Done in 1.00s. ``` @@ -552,9 +556,9 @@ Generating a user component: ~/redwood-app$ yarn redwood generate component user yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood g component user - ✔ Generating component files... - ✔ Writing `./web/src/components/User/User.test.js`... - ✔ Writing `./web/src/components/User/User.js`... +✔ Generating component files... +✔ Writing $(./web/src/components/User/User.test.js)... +✔ Writing $(./web/src/components/User/User.js)... Done in 1.02s. ``` @@ -660,8 +664,8 @@ Generating a `myDirective` directive using the interactive command: yarn rw g directive myDirective ? What type of directive would you like to generate? › - Use arrow-keys. Return to submit. -❯ Validator - Implement a validation: throw an error if criteria not met to stop execution - Transformer - Modify values of fields or query responses +❯ Validator - Implement a validation: throw an error if criteria not met to stop execution +Transformer - Modify values of fields or query responses ``` ### generate function @@ -699,8 +703,8 @@ Generating a user function: ~/redwood-app$ yarn redwood generate function user yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood g function user - ✔ Generating function files... - ✔ Writing `./api/src/functions/user.js`... +✔ Generating function files... +✔ Writing $(./api/src/functions/user.js)... Done in 16.04s. ``` @@ -769,9 +773,9 @@ Generating a user layout: ~/redwood-app$ yarn redwood generate layout user yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood g layout user - ✔ Generating layout files... - ✔ Writing `./web/src/layouts/UserLayout/UserLayout.test.js`... - ✔ Writing `./web/src/layouts/UserLayout/UserLayout.js`... +✔ Generating layout files... +✔ Writing $(./web/src/layouts/UserLayout/UserLayout.test.js)... +✔ Writing $(./web/src/layouts/UserLayout/UserLayout.js)... Done in 1.00s. ``` @@ -809,14 +813,14 @@ See the [RedwoodRecord docs](redwoodrecord.md). ~/redwood-app$ yarn redwood generate model User yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood g model User - ✔ Generating model file... - ✔ Successfully wrote file `./api/src/models/User.js` - ✔ Parsing datamodel, generating api/src/models/index.js... +✔ Generating model file... +✔ Successfully wrote file $(./api/src/models/User.js) +✔ Parsing datamodel, generating api/src/models/index.js... - Wrote /Users/rob/Sites/redwoodjs/redwood_record/.redwood/datamodel.json - Wrote /Users/rob/Sites/redwoodjs/redwood_record/api/src/models/index.js +Wrote /Users/rob/Sites/redwoodjs/redwood_record/.redwood/datamodel.json +Wrote /Users/rob/Sites/redwoodjs/redwood_record/api/src/models/index.js -✨ Done in 3.74s. +✨ Done in 3.74s. ``` Generating a model automatically runs `yarn rw record init` as well. @@ -826,7 +830,7 @@ Generating a model automatically runs `yarn rw record init` as well. Generates a page component and updates the routes. ```bash -yarn redwood generate page [path] +yarn redwood generate page < name > [path] ``` `path` can include a route parameter which will be passed to the generated @@ -944,6 +948,7 @@ const Routes = () => { ) } ``` + ### generate realtime Generate a boilerplate subscription or live query used with RedwoodJS Realtime. @@ -952,12 +957,11 @@ Generate a boilerplate subscription or live query used with RedwoodJS Realtime. yarn redwood generate realtime ``` -| Arguments & Options | Description | -| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | Name of the realtime event to setup.post` | -| `-t, --type` | Choices: `liveQuery`, `subscription`. Optional. If not provided, you will be prompted to select. -| `--force, -f` | Overwrite existing files - +| Arguments & Options | Description | +| ------------------- | ------------------------------------------------------------------------------------------------ | +| `name` | Name of the realtime event to setup.post` | +| `-t, --type` | Choices: `liveQuery`, `subscription`. Optional. If not provided, you will be prompted to select. | +| `--force, -f` | Overwrite existing files | #### Usage @@ -970,9 +974,9 @@ Generate a live query. ```bash ~/redwood-app$ yarn rw g realtime NewLiveQuery ? What type of realtime event would you like to create? › - Use arrow-keys. Return to submit. -❯ Live Query - Create a Live Query to watch for changes in data - Subscription +❯ Live Query +Create a Live Query to watch for changes in data +Subscription ✔ What type of realtime event would you like to create? › Live Query ✔ Checking for realtime environment prerequisites ... @@ -985,8 +989,8 @@ Generate a subscription. ```bash ~/redwood-app$ yarn rw g realtime NewSub ? What type of realtime event would you like to create? › - Use arrow-keys. Return to submit. - Live Query -❯ Subscription - Create a Subscription to watch for events +Live Query +❯ Subscription - Create a Subscription to watch for events ✔ What type of realtime event would you like to create? › Subscription ✔ Checking for realtime environment prerequisites ... @@ -994,7 +998,6 @@ Generate a subscription. ✔ Generating types ... ``` - ### generate scaffold Generate Pages, SDL, and Services files based on a given DB schema Model. Also accepts ``. @@ -1223,9 +1226,9 @@ yarn redwood g sdl --force --no-tests ~/redwood-app$ yarn redwood generate sdl user --force --no-tests yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood g sdl user - ✔ Generating SDL files... - ✔ Writing `./api/src/graphql/users.sdl.js`... - ✔ Writing `./api/src/services/users/users.js`... +✔ Generating SDL files... +✔ Writing $(./api/src/graphql/users.sdl.js)... +✔ Writing $(./api/src/services/users/users.js)... Done in 1.04s. ``` @@ -1243,11 +1246,11 @@ Generating a user sdl: ~/redwood-app$ yarn redwood generate sdl user yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood g sdl user - ✔ Generating SDL files... - ✔ Writing `./api/src/graphql/users.sdl.js`... - ✔ Writing `./api/src/services/users/users.scenarios.js`... - ✔ Writing `./api/src/services/users/users.test.js`... - ✔ Writing `./api/src/services/users/users.js`... +✔ Generating SDL files... +✔ Writing $(./api/src/graphql/users.sdl.js)... +✔ Writing $(./api/src/services/users/users.scenarios.js)... +✔ Writing $(./api/src/services/users/users.test.js)... +✔ Writing $(./api/src/services/users/users.js)... Done in 1.04s. ``` @@ -1387,7 +1390,6 @@ Services are where Redwood puts its business logic. They can be used by your Gra | `--tests` | Generate test and scenario files [default: true] | | `--rollback` | Rollback changes if an error occurs [default: true] | - **Destroying** ``` @@ -1402,10 +1404,10 @@ Generating a user service: ~/redwood-app$ yarn redwood generate service user yarn run v1.22.4 $ /redwood-app/node_modules/.bin/redwood g service user - ✔ Generating service files... - ✔ Writing `./api/src/services/users/users.scenarios.js`... - ✔ Writing `./api/src/services/users/users.test.js`... - ✔ Writing `./api/src/services/users/users.js`... +✔ Generating service files... +✔ Writing $(./api/src/services/users/users.scenarios.js)... +✔ Writing $(./api/src/services/users/users.test.js)... +✔ Writing $(./api/src/services/users/users.js)... Done in 1.02s. ``` @@ -1839,9 +1841,9 @@ Copying the cell generator templates: ~/redwood-app$ yarn rw setup generator cell yarn run v1.22.4 $ /redwood-app/node_modules/.bin/rw setup generator cell - ✔ Copying generator templates... - ✔ Wrote templates to /web/generators/cell -✨ Done in 2.33s. +✔ Copying generator templates... +✔ Wrote templates to /web/generators/cell +✨ Done in 2.33s. ``` ### setup deploy (config) @@ -1852,11 +1854,11 @@ Set up a deployment configuration. yarn redwood setup deploy ``` -| Arguments & Options | Description | -| :------------------ | :---------------------------------------------------------------------------------------------------- | -| `provider` | Deploy provider to configure. Choices are `baremetal`, `coherence`, `edgio`, `flightcontrol`, `netlify`, `render`, `vercel`, or `aws-serverless [deprecated]`, | -| `--database, -d` | Database deployment for Render only [choices: "none", "postgresql", "sqlite"] [default: "postgresql"] | -| `--force, -f` | Overwrite existing configuration [default: false] | +| Arguments & Options | Description | +| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `provider` | Deploy provider to configure. Choices are `baremetal`, `coherence`, `edgio`, `flightcontrol`, `netlify`, `render`, `vercel`, or `aws-serverless [deprecated]`, | +| `--database, -d` | Database deployment for Render only [choices: "none", "postgresql", "sqlite"] [default: "postgresql"] | +| `--force, -f` | Overwrite existing configuration [default: false] | #### setup deploy netlify @@ -1902,10 +1904,10 @@ This command adds the necessary packages and files to get started using the Redw yarn redwood setup mailer ``` -| Arguments & Options | Description | -| :---------------------- | :----------------------------- | -| `--force, -f` | Overwrite existing files | -| `--skip-examples` | Do not include example content, such as a React email template | +| Arguments & Options | Description | +| :------------------ | :------------------------------------------------------------- | +| `--force, -f` | Overwrite existing files | +| `--skip-examples` | Do not include example content, such as a React email template | ### setup package @@ -1917,18 +1919,20 @@ This command behaves similarly to `yarn dlx` but will attempt to confirm compati yarn redwood setup package ``` -| Arguments & Options | Description | -| :------------------ | :----------------------- | +| Arguments & Options | Description | +| :------------------ | :------------------------- | | `--force, -f` | Forgo compatibility checks | #### Usage Run the made up `@redwoodjs/setup-example` package: + ```bash ~/redwood-app$ yarn rw setup package @redwoodjs/setup-example ``` Run the same package but using a particular npm tag and avoiding any compatibility checks: + ```bash ~/redwood-app$ yarn rw setup package @redwoodjs/setup-example@beta --force ``` @@ -1977,7 +1981,6 @@ Run `yarn rw setup graphql fragments` This command creates the necessary configuration to start using [GraphQL Trusted Documents](./graphql/trusted-documents.md). - ``` yarn redwood setup graphql trusted-documents ``` @@ -1995,7 +1998,6 @@ Run `yarn rw setup graphql trusted-documents` ✔ Configuring the GraphQL Handler to use a Trusted Documents store ... ``` - If you have not setup the RedwoodJS server file, it will be setup: ```bash @@ -2004,7 +2006,6 @@ If you have not setup the RedwoodJS server file, it will be setup: ✔ Adding required api packages... ``` - ### setup realtime This command creates the necessary files, installs the required packages, and provides examples to setup RedwoodJS Realtime from GraphQL live queries and subscriptions. See the Realtime docs for more information. @@ -2013,10 +2014,10 @@ This command creates the necessary files, installs the required packages, and pr yarn redwood setup realtime ``` -| Arguments & Options | Description | -| :------------------ | :----------------------- | -| `-e, --includeExamples, --examples` | Include examples of how to implement liveQueries and subscriptions. Default: true. | -| `--force, -f` | Forgo compatibility checks | +| Arguments & Options | Description | +| :---------------------------------- | :--------------------------------------------------------------------------------- | +| `-e, --includeExamples, --examples` | Include examples of how to implement liveQueries and subscriptions. Default: true. | +| `--force, -f` | Forgo compatibility checks | :::note @@ -2041,7 +2042,6 @@ Run `yarn rw setup realtime` ✔ Generating types ... ``` - If you have not setup the RedwoodJS server file, it will be setup: ```bash @@ -2062,8 +2062,6 @@ yarn redwood setup tsconfig | :------------------ | :----------------------- | | `--force, -f` | Overwrite existing files | - - ### setup ui Set up a UI design or style library. Right now the choices are [TailwindCSS](https://tailwindcss.com/), [Chakra UI](https://chakra-ui.com/), and [Mantine UI](https://ui.mantine.dev/). @@ -2072,10 +2070,10 @@ Set up a UI design or style library. Right now the choices are [TailwindCSS](htt yarn rw setup ui ``` -| Arguments & Options | Description | -| :------------------ | :-------------------------------------------------------------------------------------- | +| Arguments & Options | Description | +| :------------------ | :-------------------------------------------------------------------------- | | `library` | Library to configure. Choices are `chakra-ui`, `tailwindcss`, and `mantine` | -| `--force, -f` | Overwrite existing configuration | +| `--force, -f` | Overwrite existing configuration | ## storybook @@ -2105,15 +2103,15 @@ Run Jest tests for api and web. yarn redwood test [side..] ``` -| Arguments & Options | Description | -| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `sides or filter` | Which side(s) to test, and/or a regular expression to match against your test files to filter by | -| `--help` | Show help | -| `--version` | Show version number | -| `--watch` | Run tests related to changed files based on hg/git (uncommitted files). Specify the name or path to a file to focus on a specific set of tests [default: true] | -| `--watchAll` | Run all tests | -| `--collectCoverage` | Show test coverage summary and output info to `coverage` directory in project root. See this directory for an .html coverage report | -| `--clearCache` | Delete the Jest cache directory and exit without running tests | +| Arguments & Options | Description | +| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `sides or filter` | Which side(s) to test, and/or a regular expression to match against your test files to filter by | +| `--help` | Show help | +| `--version` | Show version number | +| `--watch` | Run tests related to changed files based on hg/git (uncommitted files). Specify the name or path to a file to focus on a specific set of tests [default: true] | +| `--watchAll` | Run all tests | +| `--collectCoverage` | Show test coverage summary and output info to `coverage` directory in project root. See this directory for an .html coverage report | +| `--clearCache` | Delete the Jest cache directory and exit without running tests | | `--db-push` | Syncs the test database with your Prisma schema without requiring a migration. It creates a test database if it doesn't already exist [default: true]. This flag is ignored if your project doesn't have an `api` side. [👉 More details](#prisma-db-push). | > **Note** all other flags are passed onto the jest cli. So for example if you wanted to update your snapshots you can pass the `-u` flag @@ -2215,9 +2213,9 @@ Besides upgrading to a new stable release, you can use this command to upgrade t A canary release is published to npm every time a PR is merged to the `main` branch, and when we're getting close to a new release, we publish release candidates. -| Option | Description | -| :-------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--dry-run, -d` | Check for outdated packages without upgrading | +| Option | Description | +| :-------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--dry-run, -d` | Check for outdated packages without upgrading | | `--tag, -t` | Choices are "rc", "canary", "latest", "next", "experimental", or a specific version (e.g. "0.19.3"). WARNING: Unstable releases in the case of "canary", "rc", "next", and "experimental". And "canary" releases include breaking changes often requiring codemods if upgrading a project. | #### Example diff --git a/docs/docs/connection-pooling.md b/docs/docs/connection-pooling.md index 750c012b3076..7f28eaed7c81 100644 --- a/docs/docs/connection-pooling.md +++ b/docs/docs/connection-pooling.md @@ -16,9 +16,9 @@ Production Redwood apps should enable connection pooling in order to properly sc ## Prisma Data Proxy -The [Prisma Data Proxy](https://www.prisma.io/docs/data-platform/data-proxy) provides database connection management and pooling for Redwood apps using Prisma. It supports MySQL and Postgres databases in either the U.S. or EU regions. +The [Prisma Data Proxy](https://www.prisma.io/docs/data-platform/data-proxy) provides database connection management and pooling for Redwood apps using Prisma. It supports MySQL and Postgres databases in either the U.S. or EU regions. -To set up a Prisma Data Proxy, sign up for the [Prisma Data Platform](https://www.prisma.io/data-platform) for free. In your onboarding workflow, plug in the connection URL for your database and choose your region. This will generate a connection string for your app. Then follow the instructions in [Prisma's documentation](https://www.prisma.io/docs/concepts/data-platform/data-proxy). +To set up a Prisma Data Proxy, sign up for the [Prisma Data Platform](https://www.prisma.io/data-platform) for free. In your onboarding workflow, plug in the connection URL for your database and choose your region. This will generate a connection string for your app. Then follow the instructions in [Prisma's documentation](https://www.prisma.io/docs/concepts/data-platform/data-proxy). > Note that the example uses npm. Rather than using npm, you can access the Prisma CLI using `yarn redwood prisma` inside a Redwood app. @@ -26,7 +26,6 @@ To set up a Prisma Data Proxy, sign up for the [Prisma Data Platform](https://ww PgBouncer holds a connection pool to the database and proxies incoming client connections by sitting between Prisma Client and the database. This reduces the number of processes a database has to handle at any given time. PgBouncer passes on a limited number of connections to the database and queues additional connections for delivery when space becomes available. - To use Prisma Client with PgBouncer from a serverless function, add the `?pgbouncer=true` flag to the PostgreSQL connection URL: ``` @@ -57,12 +56,13 @@ postgresql://postgres:mydb.supabase.co:6543/postgres?sslmode=require&pgbouncer=t ``` ## Heroku + For Postgres, see [Postgres Connection Pooling](https://devcenter.heroku.com/articles/postgres-connection-pooling). Heroku does not officially support MySQL. - ## Digital Ocean + For Postgres, see [How to Manage Connection Pools](https://www.digitalocean.com/docs/databases/postgresql/how-to/manage-connection-pools) To run migrations through a connection pool, you're required to append connection parameters to your `DATABASE_URL`. Prisma needs to know to use pgbouncer (which is part of Digital Ocean's connection pool). If omitted, you may receive the following error: @@ -77,7 +77,9 @@ To resolve this, use the following structure in your `DATABASE_URL`: ``` :25061/defaultdb?connection_limit=3&sslmode=require&pgbouncer=true&connect_timeout=10&pool_timeout=30 ``` + Here's a couple more things to be aware of: + - When using a Digital Ocean connection pool, you'll have multiple ports available. Typically the direct connection (without connection pooling) is on port `25060` and the connection through pgbouncer is served through port `25061`. Make sure you connect to your connection pool on port `25061` - Adjust the `connection_limit`. Clusters provide 25 connections per 1 GB of RAM. Three connections per cluster are reserved for maintenance, and all remaining connections can be allocated to connection pools - Both `pgbouncer=true` and `pool_timeout=30` are required to deploy successfully through your connection pool @@ -85,20 +87,21 @@ Here's a couple more things to be aware of: Connection Pooling for MySQL is not yet supported. ## AWS + Use [Amazon RDS Proxy](https://aws.amazon.com/rds/proxy) for MySQL or PostgreSQL. From the [AWS Docs](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html#rds-proxy.limitations): ->Your RDS Proxy must be in the same VPC as the database. The proxy can't be publicly accessible. -Because of this limitation, with out-of-the-box configuration, you can only use RDS Proxy if you're deploying your Lambda Functions to the same AWS account. Alternatively, you can use RDS directly, but you might require larger instances to handle your production traffic and the number of concurrent connections. +> Your RDS Proxy must be in the same VPC as the database. The proxy can't be publicly accessible. +Because of this limitation, with out-of-the-box configuration, you can only use RDS Proxy if you're deploying your Lambda Functions to the same AWS account. Alternatively, you can use RDS directly, but you might require larger instances to handle your production traffic and the number of concurrent connections. ## Why Connection Pooling? Relational databases have a maximum number of concurrent client connections. -* Postgres allows 100 by default -* MySQL allows 151 by default +- Postgres allows 100 by default +- MySQL allows 151 by default In a traditional server environment, you would need a large amount of traffic (and therefore web servers) to exhaust these connections, since each web server instance typically leverages a single connection. diff --git a/docs/docs/contributing-overview.md b/docs/docs/contributing-overview.md index 623d70ae02a3..873757c25733 100644 --- a/docs/docs/contributing-overview.md +++ b/docs/docs/contributing-overview.md @@ -26,13 +26,15 @@ _Before interacting with the Redwood community, please read and understand our [ > 3. 🪜 [Step-by-step Walkthrough](contributing-walkthrough.md) (including Video Recording) > 4. 📈 [Current Project Status](https://github.com/orgs/redwoodjs/projects/11) > 5. 🤔 What should I work on? -> - [Good First Issue](https://redwoodjs.com/good-first-issue) -> - [Discovery Process and Open Issues](#what-should-i-work-on) +> - [Good First Issue](https://redwoodjs.com/good-first-issue) +> - [Discovery Process and Open Issues](#what-should-i-work-on) ## The Characteristics of a Contributor + More than committing code, contributing is about human collaboration and relationship. Our community mantra is **“By helping each other be successful with Redwood, we make the Redwood project successful.”** We have a specific vision for the effect this project and community will have on you — it should give you superpowers to build+create, progress in skills, and help advance your career. So who do you need to become to achieve this? Specifically, what characteristics, skills, and capabilities will you need to cultivate through practice? Here are our suggestions: + - Empathy - Gratitude - Generosity @@ -42,6 +44,7 @@ All of these are applicable in relation to both others and yourself. The goal of And you thought all this was just about opening a PR 🤣 Yes, it’s a super rewarding experience. But that’s just the beginning! ## What should I work on? + Even if you know the mechanics, it’s hard to get started without a starting place. Our best advice is this — dive into the Redwood Tutorial, read the docs, and build your own experiment with Redwood. Along the way, you’ll find typos, out-of-date (or missing) documentation, code that could work better, or even opportunities for improving and adding features. You’ll be engaging in the Forums and Chat and developing a feel for priorities and needs. This way, you’ll naturally follow your own interests and sooner than later intersect “things you’re interested in” + “ways to help improve Redwood”. There are other more direct ways to get started as well, which are outlined below. @@ -51,11 +54,13 @@ There are other more direct ways to get started as well, which are outlined belo The Redwood Core Team is working publicly — progress is updated daily on the [Release Project Board](https://github.com/orgs/redwoodjs/projects/11). Eventually, all this leads you back to Redwood’s GitHub Issues page. Here you’ll find open items that need help, which are organized by labels. There are four labels helpful for contributing: + 1. [Good First Issue](https://github.com/redwoodjs/redwood/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22): these items are more likely to be an accessible entry point to the Framework. It’s less about skill level and more about focused scope. 2. [Help Wanted](https://github.com/redwoodjs/redwood/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22): these items especially need contribution help from the community. 3. [Bugs 🐛](https://github.com/redwoodjs/redwood/issues?q=is%3Aissue+is%3Aopen+label%3Abug%2Fconfirmed): last but not least, we always need help with bugs. Some are technically less challenging than others. Sometimes the best way you can help is to attempt to reproduce the bug and confirm whether or not it’s still an issue. ### Create a New Issue + Anyone can create a new Issue. If you’re not sure that your feature or idea is something to work on, start the discussion with an Issue. Describe the idea and problem + solution as clearly as possible, including examples or pseudo code if applicable. It’s also very helpful to `@` mention a maintainer or Core Team member that shares the area of interest. Just know that there’s a lot of Issues that shuffle every day. If no one replies, it’s just because people are busy. Reach out in the Forums, Chat, or comment in the Issue. We intend to reply to every Issue that’s opened. If yours doesn’t have a reply, then give us a nudge! @@ -73,26 +78,27 @@ For details on contributing to a specific package, see the package's README (lin What you want to do not on the roadmap? Well, still go for it! We love spikes and proof-of-concepts. And if you have a question, just ask! ### RedwoodJS Framework Packages -|Package|Description| -|:-|:-| -|[`@redwoodjs/api-server`](https://github.com/redwoodjs/redwood/blob/main/packages/api-server/README.md)|Run a Redwood app using Fastify server (alternative to serverless API)| -|[`@redwoodjs/api`](https://github.com/redwoodjs/redwood/blob/main/packages/api/README.md)|Infrastructure components for your applications UI including logging, webhooks, authentication decoders and parsers, as well as tools to test custom serverless functions and webhooks| -|[`@redwoodjs/auth`](https://github.com/redwoodjs/redwood/blob/main/packages/auth/README.md#contributing)|A lightweight wrapper around popular SPA authentication libraries| -|[`@redwoodjs/cli`](https://github.com/redwoodjs/redwood/blob/main/packages/cli/README.md)|All the commands for Redwood's built-in CLI| -|[`@redwoodjs/codemods`](https://github.com/redwoodjs/redwood/blob/main/packages/codemods/README.md)|Codemods that automate upgrading a Redwood project| -|[`@redwoodjs/core`](https://github.com/redwoodjs/redwood/blob/main/packages/core/README.md)|Defines babel plugins and config files| -|[`@redwoodjs/create-redwood-app`](https://github.com/redwoodjs/redwood/blob/main/packages/create-redwood-app/README.md)|Enables `yarn create redwood-app`—downloads the latest release of Redwood and extracts it into the supplied directory| -|[`@redwoodjs/eslint-config`](https://github.com/redwoodjs/redwood/blob/main/packages/eslint-config/README.md)|Defines Redwood's eslint config| -|[`@redwoodjs/forms`](https://github.com/redwoodjs/redwood/blob/main/packages/forms/README.md)|Provides Form helpers| -|[`@redwoodjs/graphql-server`](https://github.com/redwoodjs/redwood/blob/main/packages/graphql-server/README.md)|Exposes functions to build the GraphQL API, provides services with `context`, and a set of envelop plugins to supercharge your GraphQL API with logging, authentication, error handling, directives and more| -|[`@redwoodjs/internal`](https://github.com/redwoodjs/redwood/blob/main/packages/internal/README.md)|Provides tooling to parse Redwood configs and get a project's paths| -|[`@redwoodjs/prerender`](https://github.com/redwoodjs/redwood/blob/main/packages/prerender/README.md)|Defines functionality for prerendering static content| -|[`@redwoodjs/record`](https://github.com/redwoodjs/redwood/blob/main/packages/record/README.md)|ORM built on top of Prisma. It may be extended in the future to wrap other database access packages| -|[`@redwoodjs/router`](https://github.com/redwoodjs/redwood/blob/main/packages/router/README.md)|The built-in router for Redwood| -|[`@redwoodjs/structure`](https://github.com/redwoodjs/redwood/blob/main/packages/structure/README.md)|Provides a way to build, validate and inspect an object graph that represents a complete Redwood project| -|[`@redwoodjs/telemetry`](https://github.com/redwoodjs/redwood/blob/main/packages/telemetry/README.md)|Provides functionality for anonymous data collection| -|[`@redwoodjs/testing`](https://github.com/redwoodjs/redwood/blob/main/packages/testing/README.md)|Provides helpful defaults when testing a Redwood project's web side| -|[`@redwoodjs/web`](https://github.com/redwoodjs/redwood/blob/main/packages/web/README.md)|Configures a Redwood's app web side: wraps the Apollo Client in `RedwoodApolloProvider`; defines the Cell HOC| + +| Package | Description | +| :---------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`@redwoodjs/api-server`](https://github.com/redwoodjs/redwood/blob/main/packages/api-server/README.md) | Run a Redwood app using Fastify server (alternative to serverless API) | +| [`@redwoodjs/api`](https://github.com/redwoodjs/redwood/blob/main/packages/api/README.md) | Infrastructure components for your applications UI including logging, webhooks, authentication decoders and parsers, as well as tools to test custom serverless functions and webhooks | +| [`@redwoodjs/auth`](https://github.com/redwoodjs/redwood/blob/main/packages/auth/README.md#contributing) | A lightweight wrapper around popular SPA authentication libraries | +| [`@redwoodjs/cli`](https://github.com/redwoodjs/redwood/blob/main/packages/cli/README.md) | All the commands for Redwood's built-in CLI | +| [`@redwoodjs/codemods`](https://github.com/redwoodjs/redwood/blob/main/packages/codemods/README.md) | Codemods that automate upgrading a Redwood project | +| [`@redwoodjs/core`](https://github.com/redwoodjs/redwood/blob/main/packages/core/README.md) | Defines babel plugins and config files | +| [`@redwoodjs/create-redwood-app`](https://github.com/redwoodjs/redwood/blob/main/packages/create-redwood-app/README.md) | Enables `yarn create redwood-app`—downloads the latest release of Redwood and extracts it into the supplied directory | +| [`@redwoodjs/eslint-config`](https://github.com/redwoodjs/redwood/blob/main/packages/eslint-config/README.md) | Defines Redwood's eslint config | +| [`@redwoodjs/forms`](https://github.com/redwoodjs/redwood/blob/main/packages/forms/README.md) | Provides Form helpers | +| [`@redwoodjs/graphql-server`](https://github.com/redwoodjs/redwood/blob/main/packages/graphql-server/README.md) | Exposes functions to build the GraphQL API, provides services with `context`, and a set of envelop plugins to supercharge your GraphQL API with logging, authentication, error handling, directives and more | +| [`@redwoodjs/internal`](https://github.com/redwoodjs/redwood/blob/main/packages/internal/README.md) | Provides tooling to parse Redwood configs and get a project's paths | +| [`@redwoodjs/prerender`](https://github.com/redwoodjs/redwood/blob/main/packages/prerender/README.md) | Defines functionality for prerendering static content | +| [`@redwoodjs/record`](https://github.com/redwoodjs/redwood/blob/main/packages/record/README.md) | ORM built on top of Prisma. It may be extended in the future to wrap other database access packages | +| [`@redwoodjs/router`](https://github.com/redwoodjs/redwood/blob/main/packages/router/README.md) | The built-in router for Redwood | +| [`@redwoodjs/structure`](https://github.com/redwoodjs/redwood/blob/main/packages/structure/README.md) | Provides a way to build, validate and inspect an object graph that represents a complete Redwood project | +| [`@redwoodjs/telemetry`](https://github.com/redwoodjs/redwood/blob/main/packages/telemetry/README.md) | Provides functionality for anonymous data collection | +| [`@redwoodjs/testing`](https://github.com/redwoodjs/redwood/blob/main/packages/testing/README.md) | Provides helpful defaults when testing a Redwood project's web side | +| [`@redwoodjs/web`](https://github.com/redwoodjs/redwood/blob/main/packages/web/README.md) | Configures a Redwood's app web side: wraps the Apollo Client in `RedwoodApolloProvider`; defines the Cell HOC | ## Contributing Docs @@ -146,12 +152,15 @@ These docs are in the Framework repo, redwoodjs/redwood, and explain how to cont In general, they should consist of more straightforward explanations, are allowed to be technically heavy, and should be written for a more experienced audience. But as a best practice for collaborative projects, they should still provide a Vision + Roadmap and identify the project-point person(s) (or lead(s)). ## What makes for a good Pull Request? + In general, we don’t have a formal structure for PRs. Our goal is to make it as efficient as possible for anyone to open a PR. But there are some good practices, which are flexible. Just keep in mind that after opening a PR there’s more to do before getting to the finish line: + 1. Reviews from other contributors and maintainers 2. Update code and, after maintainer approval, merge-in changes to the `main` branch 3. Once PR is merged, it will be released and added to the next version Release Notes with a link for anyone to look at the PR and understand it. Some tips and advice: + - **Connect the dots and leave a breadcrumb**: link to related Issues, Forum discussions, etc. Help others follow the trail leading up to this PR. - **A Helpful Description**: What does the code in the PR do and what problem does it solve? How can someone use the code? Code sample, Screenshot, Quick Video… Any or all of this is so so good. - **Draft or Work in Progress**: You don’t have to finish the code to open a PR. Once you have a start, open it up! Most often the best way to move an Issue forward is to see the code in action. Also, often this helps identify ways forward before you spend a lot of time polishing. @@ -162,7 +171,9 @@ Some tips and advice: The best thing you can do is look through existing PRs, which will give you a feel for how things work and what you think is helpful. ### Example PR + If you’re looking for an example of “what makes a good PR”, look no further than this one by Kim-Adeline: + - [Convert component generator to TS #632](https://github.com/redwoodjs/redwood/pull/632) Not every PR needs this much information. But it’s definitely helpful when it does! diff --git a/docs/docs/contributing-walkthrough.md b/docs/docs/contributing-walkthrough.md index 89560c3907db..5747b425e799 100644 --- a/docs/docs/contributing-walkthrough.md +++ b/docs/docs/contributing-walkthrough.md @@ -14,11 +14,11 @@ description: Watch a video of the contributing process > 3. 🪜 **Step-by-step Walkthrough** (👈 you are here) > 4. 📈 [Current Project Status: v1 Release Board](https://github.com/orgs/redwoodjs/projects/6) > 5. 🤔 What should I work on? -> - ["Help Wanted" v1 Triage Board](https://redwoodjs.com/good-first-issue) -> - [Discovery Process and Open Issues](contributing-overview.md#what-should-i-work-on) - +> - ["Help Wanted" v1 Triage Board](https://redwoodjs.com/good-first-issue) +> - [Discovery Process and Open Issues](contributing-overview.md#what-should-i-work-on) ## Video Recording of Complete Contributing Process + The following recording is from a Contributing Workshop, following through the exact steps outlined below. The Workshop includes additional topics along with Q&A discussion. ## Prologue: Getting Started with Redwood and GitHub (and git) + These are the foundations for contributing, which you should be familiar with before starting the walkthrough. [**The Redwood Tutorial**](tutorial/foreword.md) @@ -42,6 +43,7 @@ The best (and most fun) way to learn Redwood and the underlying tools and techno - And browse through [How To's](how-to/index) ### GitHub (and Git) + Diving into Git and the GitHub workflow can feel intimidating if you haven’t experienced it before. The good news is there’s a lot of great material to help you learn and be committing in no time! - [Introduction to GitHub](https://lab.github.com/githubtraining/introduction-to-github) (overview of concepts and workflow) @@ -51,7 +53,9 @@ Diving into Git and the GitHub workflow can feel intimidating if you haven’t e ## The Full Workflow: From Local Development to a New PR ### Definitions + #### Redwood “Project” + We refer to the codebase of a Redwood application as a Project. This is what you install when you run `yarn create redwood-app `. It’s the thing you are building with Redwood. Lastly, you’ll find the template used to create a new project (when you run create redwood-app) here in GitHub: [redwoodjs/redwood/packages/create-redwood-app/template/](https://github.com/redwoodjs/redwood/tree/main/packages/create-redwood-app/template) @@ -59,9 +63,11 @@ Lastly, you’ll find the template used to create a new project (when you run cr We refer to this as the **CRWA Template or Project Template**. #### Redwood “Framework” + The Framework is the codebase containing all the packages (and other code) that is published on NPMjs.com as `@redwoodjs/`. The Framework repository on GitHub is here: [https://github.com/redwoodjs/redwood](https://github.com/redwoodjs/redwood) ### Development tools + These are the tools used and recommended by the Core Team. **VS Code** @@ -80,6 +86,7 @@ There’s nothing wrong with Terminal (on Mac) and plain zsh or bash. (If you’ Unfortunately, there are a lot of “gotchas” when it comes to working with Javascript-based frameworks on Windows. We do our best to point out (and resolve) issues, but our priority focus is on developing a Redwood app vs contributing to the Framework. (If you’re interested, there’s a lengthy Forum conversation about this with many suggestions.) All that said, we highly recommend using one of the following setups to maximize your workflow: + 1. Use [Git for Windows and Git Bash](how-to/windows-development-setup.md) (included in installation) 2. Use [WSL following this setup guide on the Forums](https://community.redwoodjs.com/t/windows-subsystem-for-linux-setup/2439) @@ -93,17 +100,21 @@ But don’t skip out reading the following steps in “Local Development Setup But when you’re ready, learn how to use it in the section at the end [“GitPod: Browser-based Development”](#gitpod-browser-based-development). ### Local Development Setup + #### Step 1: Redwood Framework + 1. **Fork the [Redwood Framework](https://github.com/redwoodjs/redwood)** into a personal repo 2. Using GitHub Desktop, **open the Framework Codebase** in a VS Code workspace 3. Commands to “**start fresh**” when working on the Framework - - `yarn install`: This installs the package dependencies in /node_modules using Yarn package manager. This command is the same as just typing `yarn`. Also, if you ever switch branches and want to make sure the install dependencies are correct, you can run `yarn install --force` (shorthand `yarn -f`). - - `git clean -fxd`: *You’ll only need to do this if you’ve already been developing and want to “start over” and reset your codebase*. This command will permanently delete everything that is .gitignored, e.g. /node_modules and /dist directories with package builds. When switching between branches, this command makes sure nothing is carried over that you don’t want. (Warning: it will delete .env files in a Redwood Project. To avoid this, you can use `git clean -fxd -e .env`.) + - `yarn install`: This installs the package dependencies in /node_modules using Yarn package manager. This command is the same as just typing `yarn`. Also, if you ever switch branches and want to make sure the install dependencies are correct, you can run `yarn install --force` (shorthand `yarn -f`). + - `git clean -fxd`: _You’ll only need to do this if you’ve already been developing and want to “start over” and reset your codebase_. This command will permanently delete everything that is .gitignored, e.g. /node_modules and /dist directories with package builds. When switching between branches, this command makes sure nothing is carried over that you don’t want. (Warning: it will delete .env files in a Redwood Project. To avoid this, you can use `git clean -fxd -e .env`.) 4. **Create a new branch** from the `main` branch -First make sure you’ve pulled all changes from the remote origin (GitHub repo) into your local branch. (If you just cloned from your fork, you should be up to date.) Then create a new branch. The nomenclature used by David Price is `-description-with-hyphens`, e.g. `dsp-add-eslint-config-redwood-toml`. It's simple to use VS Code or GitHub Desktop to manage branches. You can also do this via the CLI git checkout command. + First make sure you’ve pulled all changes from the remote origin (GitHub repo) into your local branch. (If you just cloned from your fork, you should be up to date.) Then create a new branch. The nomenclature used by David Price is `-description-with-hyphens`, e.g. `dsp-add-eslint-config-redwood-toml`. It's simple to use VS Code or GitHub Desktop to manage branches. You can also do this via the CLI git checkout command. #### Step 2: Test Project + There are several options for creating a local Redwood Project to use during development. Anytime you are developing against a test project, there are some specific gotchas to keep in mind: + - New projects always use the latest stable version of the Redwood packages, which will not be up to date with the latest Framework code in the `main` branch. - To use the packages corresponding with the latest code in the Framework `main` branch, you can use the canary version published to NPM. All you need to do to install the canary versions is run `yarn rw upgrade --tag canary` in your Project - Using a cloned project or repo? Just know there are likely breaking changes in `main` that haven’t been applied. You can examine merged PRs with the “breaking” label for more info. @@ -112,44 +123,49 @@ There are several options for creating a local Redwood Project to use during dev With those details out of the way, now is the time to choose an option below that meets your needs based on functionality and codebase version. **Build a Functional Test Project [Recommended]** + 1. 👉 **Use the build script to create a test project**: From the Framework root directory, run `yarn build:test-project `. This command installs a new project using the Template codebase from your current Framework branch, it then adds Tutorial features, and finally it initializes the DB (with seed data!). It should work 90% of the time and is the recommended starting place. We also use this out-of-the-box with Gitpod. **Other Options to create a project** 2. **Install a fresh project using the local Framework template code:** Sometimes you need to create a project that uses the Template codebase in your local branch of the Framework, e.g. your changes include modifications to the CRWA Template and need to be tested. Running the command above is exactly the same as `yarn create redwood- app …`, only it runs the command from your local Framework package using the local Template codebase. Note: this is the same command used at the start of the `yarn build:test-project` command. + ``` yarn babel-node packages/create-redwood-app/src/create-redwood-app.js ``` 3. **Clone the Redwood Tutorial App repo:** This is the codebase to use when starting the Redwood Tutorial Part 2. It is updated to the latest version and has the Blog features. This is often something we use for local development. Note: be sure to upgrade to canary and look out for breaking changes coming with the next release. - 4. **Install a fresh project**: `yarn create redwood-app ` If you just need a fresh installation 1) using the latest version template codebase and 2) without any features, then just install a new Redwood project. Note: this can have the same issues regarding the need to upgrade to canary and addressing breaking changes (see Notes from items 2 and 3 above). > Note: All the options above currently set the language to JavaScript. If you would like to work with TypeScript, you can add the option `--typescript` to either of the commands that run the create-redwood-app installation. #### Step 3: Link the local Framework with the local test Project + Once you work on the Framework code, you’ll most often want to run the code in a Redwood app for testing. However, the Redwood Project you created for testing is currently using the latest version (or canary) packages of Redwood published on NPMjs.com, e.g. [@redwoodjs/core](https://www.npmjs.com/package/@redwoodjs/core) So we’ll use the Redwood Framework (rwfw) command to connect our local Framework and test Projects, which allows the Project to run on the code for Packages we are currently developing. Run this command from the CLI in your test Project: + ``` RWFW_PATH= yarn rwfw project:sync ``` For Example: + ``` cd redwood-project RWFW_PATH=~/redwood yarn rwfw project:sync ``` -RWFW_PATH is the path to your local copy of the Redwood Framework. _Once provided to rwfw, it'll remember it and you shouldn't have to provide it again unless you move it._ +RWFW*PATH is the path to your local copy of the Redwood Framework. \_Once provided to rwfw, it'll remember it and you shouldn't have to provide it again unless you move it.* > **Heads up for Windows Devs** > Depending on your dev setup, Windows might balk at you setting the env var RWFW_PATH at the beginning of the command like this. If so, try prepending with `cross-env`, e.g. `yarn cross-env RWFW_PATH=~/redwood yarn rwfw` ... Or you can add the env var and value directly to your shell before running the command. As project:sync starts up, it'll start logging to the console. In order, it: + 1. cleans and builds the framework 2. copies the framework's dependencies to your project 3. runs yarn install in your project @@ -161,11 +177,13 @@ Step two is the only explicit change you'll see to your project. You'll see that All done? You’re ready to kill the link process with “ctrl + c”. You’ll need to confirm your root package.json no longer has the added dependencies. And, if you want to reset your test-project, you should run `yarn install --force`. #### Step 4: Framework Package(s) Local Testing + Within your Framework directory, use the following tools and commands to test your code: + 1. **Build the packages**: `yarn build` - - to delete all previous build directories: yarn build:clean + - to delete all previous build directories: yarn build:clean 2. **Syntax and Formatting**: `yarn lint` - - to fix errors or warnings: `yarn lint:fix` + - to fix errors or warnings: `yarn lint:fix` 3. **Run unit tests for each package**: `yarn test` 4. **Run through the Cypress E2E integration tests**: `yarn e2e` 5. **Check Yarn resolutions and package.json format**: `yarn check` @@ -173,14 +191,17 @@ Within your Framework directory, use the following tools and commands to test yo All of these checks are included in Redwood’s GitHub PR Continuous Integration (CI) automation. However, it’s good practice to understand what they do by using them locally. The E2E tests aren’t something we use every time anymore (because it takes a while), but you should learn how to use it because it comes in handy when your code is failing tests on GitHub and you need to diagnose. > **Heads up for Windows Devs** -> The Cypress E2E does *not* work on Windows. Two options are available if needed: +> The Cypress E2E does _not_ work on Windows. Two options are available if needed: +> > 1. Use Gitpod (see related section for info) > 2. When you create a PR, just ask for help from a maintainer #### Step 5: Open a PR 🚀 + You’ve made it to the fun part! It’s time to use the code you’re working on to create a new PR into the Redwood Framework `main` branch. We use GitHub Desktop to walk through the process of: + - Committing my changes to my development branch - Publishing (pushing) my branch and changes to my GitHub repo fork of the Redwood Framework - Opening a PR requesting to merge my forked-repo branch into the Redwood Framework `main` branch @@ -200,7 +221,7 @@ You have successfully submitted your PR! **Note:** Make sure you check the box that allows project maintainers to update your branch. This option is found on the "Open a pull request" form below the description textbox. Checking this option helps move a PR forward more quickly, as branches always need to be updated from `main` before we can merge. **When is my code “ready” to open a PR?** -Most of the action, communication, and decisions happen within a PR. A common mistake new contributors make is *waiting* until their code is “perfect” before opening a PR. Assuming your PR has some code changes, it’s great practice to open a [Draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/) (setting during the PR creation), which you can use to start discussion and ask questions. PRs are closed all the time without being merged, often because they are replaced by another PR resulting from decisions and discussion. It’s part of the process. More importantly, it means collaboration is happening! +Most of the action, communication, and decisions happen within a PR. A common mistake new contributors make is _waiting_ until their code is “perfect” before opening a PR. Assuming your PR has some code changes, it’s great practice to open a [Draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/) (setting during the PR creation), which you can use to start discussion and ask questions. PRs are closed all the time without being merged, often because they are replaced by another PR resulting from decisions and discussion. It’s part of the process. More importantly, it means collaboration is happening! What isn’t a fun experience is spending a whole bunch of time on code that ends up not being the correct direction or is unnecessary/redundant to something that already exists. This is a part of the learning process. But it’s another reason to open a draft PR sooner than later to get confirmation and questions out of the way before investing time into refining and details. @@ -209,7 +230,9 @@ When in doubt, just try first and ask for help and direction! Refer to the [What makes for a good Pull Request?](contributing-overview.md#what-makes-for-a-good-pull-request) section in [Contributing Overview](contributing-overview.md)for general good practices when opening PR. ### Gitpod: Browser-based Development + [Gitpod](http://gitpod.io) has recently been integrated with Redwood to JustWork™ with any branch or PR. When a virtual Gitpod workspace is initialized, it automatically: + 1. Checks-out the code from your branch or PR 2. Run Yarn installation 3. Creates the functional Test Project via `yarn build:test-project` @@ -222,6 +245,7 @@ Refer to the [What makes for a good Pull Request?](contributing-overview.md#what **Demo of Gitpod** David briefly walks-through an automatically prebuilt Gitpod workspace here: + - [Gitpod + RedwoodJS 3-minute Walkthrough](https://youtu.be/_kMuTW3x--s) Make sure you watch until the end where David shows how to set up your integration with GitHub and VS Code sync. 🤩 @@ -229,12 +253,12 @@ Make sure you watch until the end where David shows how to set up your integrati **Start a Gitpod Workspace** There are two ways to get started with Gitpod + Redwood. -*Option 1: Open a PR* +_Option 1: Open a PR_ Every PR will trigger a Gitpod prebuild using the PR branch. Just look for Gitpod in the list of checks at the bottom of the PR — click the “Details” link and away you’ll go! PR Checks -*Option 2: Use the link from your project or branch* +_Option 2: Use the link from your project or branch_ You can initialize a workspace using this URL pattern: @@ -243,9 +267,9 @@ https://gitpod.io/# ``` For example, this link will start a workspace using the RedwoodJS main branch: + - https://gitpod.io/#https://github.com/redwoodjs/redwood And this link will start a workspace for a PR #3434: -- https://gitpod.io/#https://github.com/redwoodjs/redwood/pull/3434 - +- https://gitpod.io/#https://github.com/redwoodjs/redwood/pull/3434 diff --git a/docs/docs/cors.md b/docs/docs/cors.md index 5325cedc2ba0..3781aeb19fe2 100644 --- a/docs/docs/cors.md +++ b/docs/docs/cors.md @@ -19,7 +19,7 @@ This will become obvious when you point your browser to your site and see none o Dealing with CORS can complicate your app and make it harder to deploy to new hosts, run in different environments, etc. Is there a way to avoid CORS altogether? -Yes! If you can add a proxy between your web and api sides, all requests will *appear* to be going to and from the same domain (the web side, even though behind the scenes they are forwarded somewhere else). This functionality is included automatically with hosts like [Netlify](https://docs.netlify.com/routing/redirects/rewrites-proxies/#proxy-to-another-service) or [Vercel](https://vercel.com/docs/cli#project-configuration/rewrites). With a host like [Render](https://render-web.onrender.com/docs/deploy-redwood#deployment) you can enable a proxy with a simple config option. Most providers should provide this functionality through a combination of provider-specific config and/or web server configuration. +Yes! If you can add a proxy between your web and api sides, all requests will _appear_ to be going to and from the same domain (the web side, even though behind the scenes they are forwarded somewhere else). This functionality is included automatically with hosts like [Netlify](https://docs.netlify.com/routing/redirects/rewrites-proxies/#proxy-to-another-service) or [Vercel](https://vercel.com/docs/cli#project-configuration/rewrites). With a host like [Render](https://render-web.onrender.com/docs/deploy-redwood#deployment) you can enable a proxy with a simple config option. Most providers should provide this functionality through a combination of provider-specific config and/or web server configuration. ## GraphQL Config @@ -40,7 +40,7 @@ export const handler = createGraphQLHandler({ }) ``` -Note that the `origin` needs to be a complete URL including the scheme (`https`). This is the domain that requests are allowed to come *from*. In this example we assume the web side is served from `https://www.example.com`. If you have multiple servers that should be allowed to access the api, you can pass an array of them instead: +Note that the `origin` needs to be a complete URL including the scheme (`https`). This is the domain that requests are allowed to come _from_. In this example we assume the web side is served from `https://www.example.com`. If you have multiple servers that should be allowed to access the api, you can pass an array of them instead: ```jsx cors: { @@ -56,11 +56,11 @@ The following config only applies if you're using [dbAuth](authentication.md#sel You'll need to configure several things: -* Add CORS config for GraphQL -* Add CORS config for the auth function -* Cookie config for the auth function -* Allow sending of credentials in GraphQL XHR requests -* Allow sending of credentials in auth function requests +- Add CORS config for GraphQL +- Add CORS config for the auth function +- Cookie config for the auth function +- Allow sending of credentials in GraphQL XHR requests +- Allow sending of credentials in auth function requests Here's how you configure each of these: @@ -84,7 +84,7 @@ export const handler = createGraphQLHandler({ }) ``` -`origin` is the domain(s) that requests come *from* (the web side). +`origin` is the domain(s) that requests come _from_ (the web side). ### Auth CORS Config @@ -119,7 +119,7 @@ const authHandler = new DbAuthHandler(event, context, { }) ``` -Just like the GraphQL config, `origin` is the domain(s) that requests come *from* (the web side). +Just like the GraphQL config, `origin` is the domain(s) that requests come _from_ (the web side). ### Cookie Config @@ -209,7 +209,7 @@ Forwarding http://fb6d701c44b5.ngrok.io -> http://localhost:8911 Forwarding https://fb6d701c44b5.ngrok.io -> http://localhost:8911 ``` -Note the two different domains. Copy the `https` domain from the api side because we'll need it in a moment. Even if the Redwood dev server isn't running you can leave these tunnels running, and when the dev server *does* start, they'll just start on those domains again. +Note the two different domains. Copy the `https` domain from the api side because we'll need it in a moment. Even if the Redwood dev server isn't running you can leave these tunnels running, and when the dev server _does_ start, they'll just start on those domains again. ### `redwood.toml` Config @@ -255,7 +255,7 @@ Where you get this domain from will depend on how you expose your app to the out You'll need to apply an option when starting the dev server to tell it to accept requests from any host, not just `localhost`: ```bash -> yarn rw dev --fwd="--allowed-hosts all" +rw > yarn dev --fwd="--allowed-hosts all" ``` ### Wrapping Up diff --git a/docs/docs/create-redwood-app.md b/docs/docs/create-redwood-app.md index 61e2d15b5dfe..1d4fe329bde7 100644 --- a/docs/docs/create-redwood-app.md +++ b/docs/docs/create-redwood-app.md @@ -12,6 +12,7 @@ yarn create redwood-app ``` ## Set up for success + Redwood requires that you're running Node version 20 or higher. If you're running Node version 21.0.0 or higher, you can still use Create Redwood App, but it may make your project incompatible with some deploy targets, such as AWS Lambdas. @@ -35,11 +36,13 @@ To upgrade your version of yarn, [you can refer to the yarn documentation](https ## What you can expect ### Select your preferred language + Options: TypeScript (default) or JavaScript If you choose JavaScript, you can always [add TypeScript later](/docs/typescript/introduction#converting-a-javascript-project-to-typescript). ### Do you want to initialize a git repo? + Options: yes (default) or no If you mark "yes", then it will ask you to **Enter a commit message**. The default message is "Initial commit." @@ -56,6 +59,7 @@ git commit -m "Initial commit" If you're new to git, here's a recommended playlist on YouTube: [git for Beginners](https://www.youtube.com/playlist?list=PLrz61zkUHJJFmfTgOVL1mBw_NZcgGe882) ### Do you want to run `yarn install`? + Options: yes (default) or no _NOTE: This prompt will only display if you're running yarn, version 1._ @@ -83,21 +87,20 @@ yarn rw dev - You can visit the Redwood GraphQL Playground at `http://localhost:8911/graphql`. ## Flags + You can by pass these prompts by using the following flags: -| Flag | Alias | What it does | -| :--- | :--- | :--- | -| `--yarn-install` | | Run `yarn install` | -| `--typescript` | `ts` | Set TypeScript as the preferred language (pass `--no-typescript` to use JavaScript) | -| `--overwrite` | | Overwrites the existing directory, if it has the same name | -| `--git-init` | `git` | Initializes a git repository | -| `--commit-message "Initial commit"` | `m` | Specifies the initial git commit message | -| `--yes` | `y` | Automatically select all defaults | +| Flag | Alias | What it does | +| :---------------------------------- | :---- | :---------------------------------------------------------------------------------- | +| `--yarn-install` | | Run `yarn install` | +| `--typescript` | `ts` | Set TypeScript as the preferred language (pass `--no-typescript` to use JavaScript) | +| `--overwrite` | | Overwrites the existing directory, if it has the same name | +| `--git-init` | `git` | Initializes a git repository | +| `--commit-message "Initial commit"` | `m` | Specifies the initial git commit message | +| `--yes` | `y` | Automatically select all defaults | For example, here's the project with all flags enabled: ```terminal yarn create redwood-app --typescript --git-init --commit-message "Initial commit" --yarn-install ``` - - diff --git a/docs/docs/data-migrations.md b/docs/docs/data-migrations.md index 3f7d32d389fd..4f7e85e03e94 100644 --- a/docs/docs/data-migrations.md +++ b/docs/docs/data-migrations.md @@ -8,12 +8,12 @@ description: Track changes to database content There are two kinds of changes you can make to your database: -* Changes to structure -* Changes to content +- Changes to structure +- Changes to content -In Redwood, [Prisma Migrate](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-migrate) takes care of codifying changes to your database *structure* in code by creating a snapshot of changes to your database that can be reliably repeated to end up in some known state. +In Redwood, [Prisma Migrate](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-migrate) takes care of codifying changes to your database _structure_ in code by creating a snapshot of changes to your database that can be reliably repeated to end up in some known state. -To track changes to your database *content*, Redwood includes a feature we call **Data Migration**. As your app evolves and you move data around, you need a way to consistently declare how that data should move. +To track changes to your database _content_, Redwood includes a feature we call **Data Migration**. As your app evolves and you move data around, you need a way to consistently declare how that data should move. Imagine a `User` model that contains several columns for user preferences. Over time, you may end up with more and more preferences to the point that you have more preference-related columns in the table than you do data unique to the user! This is a common occurrence as applications grow. You decide that the app should have a new model, `Preference`, to keep track of them all (and `Preference` will have a foreign key `userId` to reference it back to its `User`). You'll use Prisma Migrate to create the new `Preference` model, but how do you copy the preference data to the new table? Data migrations to the rescue! @@ -22,9 +22,11 @@ Imagine a `User` model that contains several columns for user preferences. Over Just like Prisma, we will store which data migrations have run in the database itself. We'll create a new database table `DataMigration` to keep track of which ones have run already. Rather than create this model by hand, Redwood includes a CLI tool to add the model to `schema.prisma` and create the DB migration that adds the table to the database: + ``` yarn rw data-migrate install ``` + You'll see a new directory created at `api/db/dataMigrations` which will store our individual migration tasks. Take a look at `schema.prisma` to see the new model definition: @@ -39,21 +41,27 @@ model RW_DataMigration { ``` The install script also ran `yarn rw prisma migrate dev --create-only` automatically so you have a DB migration ready to go. You just need to run the `prisma migrate dev` command to apply it: + ``` yarn rw prisma migrate dev ``` + ## Creating a New Data Migration Data migrations are just plain Typescript or Javascript files which export a single anonymous function that is given a single argument—an instance of `PrismaClient` called `db` that you can use to access your database. The files have a simple naming convention: + ``` {version}-{name}.js ``` + Where `version` is a timestamp, like `20200721123456` (an ISO8601 datetime without any special characters or zone identifier), and `name` is a param-case human readable name for the migration, like `copy-preferences`. To create a data migration we have a generator: + ``` yarn rw generate dataMigration copyPreferences ``` + This will create `api/db/dataMigrations/20200721123456-copy-preferences.js`: ```jsx title="api/db/dataMigrations/20200721123456-copy-preferences.js" @@ -84,8 +92,8 @@ export default async ({ db }) => { newsletter: user.newsletter, frequency: user.frequency, theme: user.theme, - user: { connect: { id: user.id } } - } + user: { connect: { id: user.id } }, + }, }) }) } @@ -100,23 +108,25 @@ This loops through each existing `User` and creates a new `Preference` record co > > When going to production, you would need to run this as two separate deploys to ensure no data is lost. > -> The reason is that all DB migrations are run and *then* all data migrations. So if you had two DB migrations (one to create `Preference` and one to drop the unneeded columns from `User`) they would both run before the Data Migration, so the columns containing the preferences are gone before the data migration gets a chance to copy them over! +> The reason is that all DB migrations are run and _then_ all data migrations. So if you had two DB migrations (one to create `Preference` and one to drop the unneeded columns from `User`) they would both run before the Data Migration, so the columns containing the preferences are gone before the data migration gets a chance to copy them over! > > **Remember**: Any destructive action on the database (removing a table or column especially) needs to be a two step process to avoid data loss. ## Running a Data Migration When you're ready, you can execute your data migration with `data-migrate`'s `up` command: + ``` yarn rw data-migrate up ``` + This goes through each file in `api/db/dataMigrations`, compares it against the list of migrations that have already run according to the `DataMigration` table in the database, and executes any that aren't present in that table, sorted oldest to newest based on the timestamp in the filename. Any logging statements (like `console.info()`) you include in your data migration script will be output to the console as the script is running. If the script encounters an error, the process will abort, skipping any following data migrations. -> The example data migration above didn't include this for brevity, but you should always run your data migration [inside a transaction](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/transactions#bulk-operations-experimental) so that if any errors occur during execution the database will not be left in an inconsistent state where only *some* of your changes were performed. +> The example data migration above didn't include this for brevity, but you should always run your data migration [inside a transaction](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/transactions#bulk-operations-experimental) so that if any errors occur during execution the database will not be left in an inconsistent state where only _some_ of your changes were performed. ## Long-term Maintainability @@ -137,8 +147,8 @@ export default async ({ db }) => { newsletter: user.newsletter, frequency: user.frequency, theme: user.theme, - user: { connect: { id: user.id } } - } + user: { connect: { id: user.id } }, + }, }) }) } @@ -148,11 +158,14 @@ export default async ({ db }) => { ## Lifecycle Summary Run once: + ``` yarn rw data-migrate install yarn rw prisma migrate dev ``` + Run every time you need a new data migration: + ``` yarn rw generate dataMigration migrationName yarn rw data-migrate up diff --git a/docs/docs/database-seeds.md b/docs/docs/database-seeds.md index 65ffe013993a..e8cdc1917ce5 100644 --- a/docs/docs/database-seeds.md +++ b/docs/docs/database-seeds.md @@ -7,15 +7,15 @@ a new environment. Seed data are things like: -* An admin user so that you can log in to your new instance -* A list of categories that can be assigned to a Product -* Lists of roles and permissions +- An admin user so that you can log in to your new instance +- A list of categories that can be assigned to a Product +- Lists of roles and permissions Seed data is not meant for: -* Sample data to be used in development -* Data to run tests against -* Randomized data +- Sample data to be used in development +- Data to run tests against +- Randomized data ## Best Practices @@ -31,7 +31,7 @@ already exists, and if so just update it, if not then create it. But, this technique requires a separate SQL statement for each member of your data array and is less performant than `createMany()`. -You could also do a check if *any* data exists in the database first, and if +You could also do a check if _any_ data exists in the database first, and if not, create the records with `createMany()`. However, this means that any existing seed data that may have been modified will remain, and would not be updated to match what you expect in your seed. @@ -46,7 +46,7 @@ Seeds are automatically run the first time you migrate your database: yarn rw prisma migrate dev ``` -They are run *every* time you reset your database: +They are run _every_ time you reset your database: ```bash yarn rw prisma migrate reset @@ -148,14 +148,14 @@ export default async () => { { name: 'Fiction', bisacCode: 'FIC000000' }, { name: 'Nature', bisacCode: 'NAT000000' }, { name: 'Travel', bisacCode: 'TRV000000' }, - { name: 'World History', bisacCode: 'HIS037000' } + { name: 'World History', bisacCode: 'HIS037000' }, ] for (const item of data) { - await db.category.upsert({ + await db.category.upsert({ where: { name: item.name }, update: { code: item.code }, - create: { name: item.name, code: item.code } + create: { name: item.name, code: item.code }, }) } } catch (error) { @@ -167,7 +167,7 @@ export default async () => { You can now execute this seed as many times as you want and you'll end up with that exact list in the database each time. And, any additional categories you've created in the meantime will remain. Remember: seeds are meant to be the -*minimum* amount of data you need for your app to run, not necessarily *all* the +_minimum_ amount of data you need for your app to run, not necessarily _all_ the data that will ever be present in those tables. # Seeding users for dbAuth @@ -182,27 +182,27 @@ import { hashPassword } from '@redwoodjs/auth-dbauth-api' export default async () => { const users = [ { name: 'John', email: 'john@example.com', password: 'secret1' }, - { name: 'Jane', email: 'jane@example.com', password: 'secret2' } + { name: 'Jane', email: 'jane@example.com', password: 'secret2' }, ] for (const user of users) { const [hashedPassword, salt] = hashPassword(user.password) await db.user.upsert({ - where: { - email: user.email + where: { + email: user.email, }, - create: { + create: { name: user.name, email: user.email, hashedPassword, - salt + salt, }, update: { name: user.name, hashedPassword, - salt - } + salt, + }, }) } } diff --git a/docs/docs/deploy/baremetal.md b/docs/docs/deploy/baremetal.md index aec882f28381..ba99355f6fa3 100644 --- a/docs/docs/deploy/baremetal.md +++ b/docs/docs/deploy/baremetal.md @@ -48,8 +48,9 @@ The Baremetal deploy runs several commands in sequence. These can be customized, ### First Run Lifecycle If the `--first-run` flag is specified then step 6 above will execute the following commands instead: - - `pm2 start [service]` - starts the serving process(es) - - `pm2 save` - saves the running services to the deploy users config file for future startup. See [Starting on Reboot](#starting-on-reboot) for further information + +- `pm2 start [service]` - starts the serving process(es) +- `pm2 save` - saves the running services to the deploy users config file for future startup. See [Starting on Reboot](#starting-on-reboot) for further information ## Directory Structure @@ -155,29 +156,29 @@ This lists a single server, in the `production` environment, providing the hostn #### Config Options -* `host` - hostname to the server -* `port` - [optional] ssh port for server connection, defaults to 22 -* `username` - the user to login as -* `password` - [optional] if you are using password authentication, include that here -* `privateKey` - [optional] if you connect with a private key, include the content of the key here, as a buffer: `privateKey: Buffer.from('...')`. Use this *or* `privateKeyPath`, not both. -* `privateKeyPath` - [optional] if you connect with a private key, include the path to the key here: `privateKeyPath: path.join('path','to','key.pem')` Use this *or* `privateKey`, not both. -* `passphrase` - [optional] if your private key contains a passphrase, enter it here -* `agentForward` - [optional] if you have [agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding) enabled, set this to `true` and your own credentials will be used for further SSH connections from the server (like when connecting to GitHub) -* `sides` - An array of sides that will be built on this server -* `packageManagerCommand` - The package manager bin to call, defaults to `yarn` but could be updated to be prefixed with another command first, for example: `doppler run -- yarn` -* `monitorCommand` - The monitor bin to call, defaults to `pm2` but could be updated to be prefixed with another command first, for example: `doppler run -- pm2` -* `path` - The absolute path to the root of the application on the server -* `migrate` - [optional] Whether or not to run migration processes on this server, defaults to `true` -* `processNames` - An array of service names from `ecosystem.config.js` which will be (re)started on a successful deploy -* `repo` - The path to the git repo to clone -* `branch` - [optional] The branch to deploy (defaults to `main`) -* `keepReleases` - [optional] The number of previous releases to keep on the server, including the one currently being served (defaults to 5) +- `host` - hostname to the server +- `port` - [optional] ssh port for server connection, defaults to 22 +- `username` - the user to login as +- `password` - [optional] if you are using password authentication, include that here +- `privateKey` - [optional] if you connect with a private key, include the content of the key here, as a buffer: `privateKey: Buffer.from('...')`. Use this _or_ `privateKeyPath`, not both. +- `privateKeyPath` - [optional] if you connect with a private key, include the path to the key here: `privateKeyPath: path.join('path','to','key.pem')` Use this _or_ `privateKey`, not both. +- `passphrase` - [optional] if your private key contains a passphrase, enter it here +- `agentForward` - [optional] if you have [agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding) enabled, set this to `true` and your own credentials will be used for further SSH connections from the server (like when connecting to GitHub) +- `sides` - An array of sides that will be built on this server +- `packageManagerCommand` - The package manager bin to call, defaults to `yarn` but could be updated to be prefixed with another command first, for example: `doppler run -- yarn` +- `monitorCommand` - The monitor bin to call, defaults to `pm2` but could be updated to be prefixed with another command first, for example: `doppler run -- pm2` +- `path` - The absolute path to the root of the application on the server +- `migrate` - [optional] Whether or not to run migration processes on this server, defaults to `true` +- `processNames` - An array of service names from `ecosystem.config.js` which will be (re)started on a successful deploy +- `repo` - The path to the git repo to clone +- `branch` - [optional] The branch to deploy (defaults to `main`) +- `keepReleases` - [optional] The number of previous releases to keep on the server, including the one currently being served (defaults to 5) The easiest connection method is generally to include your own public key in the server's `~/.ssh/authorized_keys` mannually or by running `ssh-copy-id user@server.com` from your local machine, [enable agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding), and then set `agentForward = true` in `deploy.toml`. This will allow you to use your own credentials when pulling code from GitHub (required for private repos). Otherwise you can create a [deploy key](https://docs.github.com/en/developers/overview/managing-deploy-keys) and keep it on the server. #### Using Environment Variables in `deploy.toml` -Similarly to `redwood.toml`, `deploy.toml` supports interpolation of environment variables. For more details on how to use the environment variable interpolation see [Using Environment Variables in redwood.toml](/docs/app-configuration-redwood-toml#using-environment-variables-in-redwoodtoml) +Similarly to `redwood.toml`, `deploy.toml` supports interpolation of environment variables. For more details on how to use the environment variable interpolation see [Using Environment Variables in redwood.toml](/docs/app-configuration-redwood-toml#using-environment-variables-in-redwoodtoml) #### Multiple Servers @@ -278,7 +279,7 @@ You'll want to create an `.env` file in this directory containing any environmen The deployment process uses a '[non-interactive](https://tldp.org/LDP/abs/html/intandnonint.html)' SSH session to run commands on the remote server. A non-interactive session will often load a minimal amount of settings for better compatibility and speed. In some versions of Linux `.bashrc` by default does not load (by design) from a non-interactive session. This can lead to `yarn` (or other commands) not being found by the deployment script, even though they are in your path, because additional ENV vars are set in `~/.bashrc` which provide things like NPM paths and setup. -A quick fix on some distros is to edit the deployment user's `~/.bashrc` file and comment out the lines that *stop* non-interactive processing. +A quick fix on some distros is to edit the deployment user's `~/.bashrc` file and comment out the lines that _stop_ non-interactive processing. ```diff title="~/.bashrc" # If not running interactively, don't do anything @@ -322,9 +323,9 @@ If it worked, hooray! You're deployed to BAREMETAL. If not, read on... On the server you should see a new directory inside the `path` you defined in `deploy.toml`. It should be a timestamp of the deploy, like: ```bash -drwxrwxr-x 7 ubuntu ubuntu 4096 Apr 22 23:00 ./ -drwxr-xr-x 7 ubuntu ubuntu 4096 Apr 22 22:46 ../ --rw-rw-r-- 1 ubuntu ubuntu 1167 Apr 22 20:49 .env +drwxrwxr-x 7 ubuntu ubuntu 4096 Apr 22 23:00 ./ +drwxr-xr-x 7 ubuntu ubuntu 4096 Apr 22 22:46 ../ +-rw-rw-r-- 1 ubuntu ubuntu 1167 Apr 22 20:49 .env drwxrwxr-x 10 ubuntu ubuntu 4096 Apr 22 21:43 20220422214218/ ``` @@ -408,7 +409,7 @@ Note that if you have more than one process running, like we do here, requesting ## Starting Processes on Server Restart -The `pm2` service requires some system "hooks" to be installed so it can boot up using your system's service manager. Otherwise, your PM2 services will need to be manually started again on a server restart. These steps only need to be run the first time you install PM2. +The `pm2` service requires some system "hooks" to be installed so it can boot up using your system's service manager. Otherwise, your PM2 services will need to be manually started again on a server restart. These steps only need to be run the first time you install PM2. SSH into your server and then run: @@ -416,11 +417,11 @@ SSH into your server and then run: pm2 startup ``` -You will see some output similar to the output below. We care about the output after "copy/paste the following command:" You'll need to do just that: copy the command starting with `sudo` and then paste and execute it. *Note* this command uses `sudo` so you'll need the root password to the machine in order for it to complete successfully. +You will see some output similar to the output below. We care about the output after "copy/paste the following command:" You'll need to do just that: copy the command starting with `sudo` and then paste and execute it. _Note_ this command uses `sudo` so you'll need the root password to the machine in order for it to complete successfully. :::warning -The below text is *example* output, yours will be different, don't copy and paste ours! +The below text is _example_ output, yours will be different, don't copy and paste ours! ::: @@ -463,22 +464,22 @@ Baremetal supports running your own custom commands before or after the regular You can define your before/after commands in three different places: -* Globally - runs for any environment -* Environment specific - runs for only a single environment -* Server specific - runs for only a single server in a single environment +- Globally - runs for any environment +- Environment specific - runs for only a single environment +- Server specific - runs for only a single server in a single environment :::warning Custom commands are run in the new **deploy** directory, not the root of your application directory. During a deploy the `current` symlink will point to the previous directory while your code is executed in the new one, before the `current` symlink location is updated. ```bash -drwxrwxr-x 5 ubuntu ubuntu 4096 May 10 18:20 ./ -drwxr-xr-x 7 ubuntu ubuntu 4096 Apr 27 17:43 ../ -drwxrwxr-x 2 ubuntu ubuntu 4096 May 9 22:59 20220503211428/ -drwxrwxr-x 2 ubuntu ubuntu 4096 May 9 22:59 20220503211429/ -drwxrwxr-x 10 ubuntu ubuntu 4096 May 10 18:18 20220510181730/ <-- commands are run in here -lrwxrwxrwx 1 ubuntu ubuntu 14 May 10 18:19 current -> 20220503211429/ --rw-rw-r-- 1 ubuntu ubuntu 1167 Apr 22 20:49 .env +drwxrwxr-x 5 ubuntu ubuntu 4096 May 10 18:20 ./ +drwxr-xr-x 7 ubuntu ubuntu 4096 Apr 27 17:43 ../ +drwxrwxr-x 2 ubuntu ubuntu 4096 May 9 22:59 20220503211428/ +drwxrwxr-x 2 ubuntu ubuntu 4096 May 9 22:59 20220503211429/ +drwxrwxr-x 10 ubuntu ubuntu 4096 May 10 18:18 20220510181730/ commands are run in here < -- +lrwxrwxrwx 1 ubuntu ubuntu 14 May 10 18:19 current - > 20220503211429/ +-rw-rw-r-- 1 ubuntu ubuntu 1167 Apr 22 20:49 .env ``` ::: @@ -536,7 +537,6 @@ host = 'server.com' You can include commands in any/all of the three configurations (global, env and server) and they will all be stacked up and run in that order: `global -> environment -> server`. For example: - ```toml [[production.servers]] host = 'server.com' @@ -571,7 +571,7 @@ You can even rollback multiple deploys, up to the total number you still have de yarn rw deploy baremetal production --rollback 3 ``` -Note that this will *not* rollback your database—if you had a release that changed the database, that updated database will still be in effect, but with the previous version of the web and api sides. Trying to undo database migrations is a very difficult proposition and isn't even possible in many cases. +Note that this will _not_ rollback your database—if you had a release that changed the database, that updated database will still be in effect, but with the previous version of the web and api sides. Trying to undo database migrations is a very difficult proposition and isn't even possible in many cases. Make sure to thoroughly test releases that change the database before doing it for real! @@ -583,7 +583,7 @@ If you find that you have a particular complex deploy, one that may involve inco yarn rw deploy baremetal production --maintenance up ``` -It does this by replacing `web/dist/200.html` with `web/src/maintenance.html`. This means any new web requests, at any URL, will show the maintenance page. This process also stops any services listed in the `processNames` option of `deploy.toml`—this is important for the api server as it will otherwise keep serving requests to users currently running the app, even though no *new* users can get the Javascript packages required to start a new session in their browser. +It does this by replacing `web/dist/200.html` with `web/src/maintenance.html`. This means any new web requests, at any URL, will show the maintenance page. This process also stops any services listed in the `processNames` option of `deploy.toml`—this is important for the api server as it will otherwise keep serving requests to users currently running the app, even though no _new_ users can get the Javascript packages required to start a new session in their browser. You can remove the maintenance page with: @@ -613,7 +613,7 @@ The default configuration, which requires the least amount of manual configurati ### Redwood Serves Web and Api Sides, Bind to Port 80 -This is almost as easy as the default configuration, you just need to tell Redwood to bind to port 80. However, most *nix distributions will not allow a process to bind to ports lower than 1024 without root/sudo permissions. There is a command you can run to allow access to a specific binary (`node` in this case) to bind to one of those ports anyway. +This is almost as easy as the default configuration, you just need to tell Redwood to bind to port 80. However, most \*nix distributions will not allow a process to bind to ports lower than 1024 without root/sudo permissions. There is a command you can run to allow access to a specific binary (`node` in this case) to bind to one of those ports anyway. #### Tell Redwood to Bind to Port 80 @@ -729,8 +729,8 @@ module.exports = { exec_mode: 'cluster', wait_ready: true, listen_timeout: 10000, - } - ] + }, + ], } ``` diff --git a/docs/docs/deploy/coherence.md b/docs/docs/deploy/coherence.md index a2b9ec845d2a..ccd5bdc00088 100644 --- a/docs/docs/deploy/coherence.md +++ b/docs/docs/deploy/coherence.md @@ -34,6 +34,7 @@ yarn rw setup deploy coherence The command will inspect your Prisma config to determine if you're using a supported database (at the moment, only `postgres` or `mysql` are supported on Coherence). Then follow the [Coherence Redwood deploy docs](https://docs.withcoherence.com/docs/configuration/frameworks#redwood-js) for more information, including if you want to set up: + - a redis server - database migration/seeding/snapshot loading - cron jobs or async workers diff --git a/docs/docs/deploy/edgio.md b/docs/docs/deploy/edgio.md index 66df9c717529..fd115935b85b 100644 --- a/docs/docs/deploy/edgio.md +++ b/docs/docs/deploy/edgio.md @@ -1,13 +1,14 @@ # Deploy to Edgio ->⚠️ **Deprecated** +> ⚠️ **Deprecated** > ->As of Redwood v7, we are deprecating this deploy setup as an "officially" supported provider. This means: ->- For projects already using this deploy provider, there will be NO change at this time ->- Both the associated `setup` and `deploy` commands will remain in the framework as is; when setup is run, there will be a “deprecation” message ->- We will no longer run CI/CD on the Edgio deployments, which means we are no longer guaranteeing this deploy works with each new version +> As of Redwood v7, we are deprecating this deploy setup as an "officially" supported provider. This means: > ->If you have concerns or questions about our decision to deprecate this deploy provider please reach out to us on our [community forum](https://community.redwoodjs.com). +> - For projects already using this deploy provider, there will be NO change at this time +> - Both the associated `setup` and `deploy` commands will remain in the framework as is; when setup is run, there will be a “deprecation” message +> - We will no longer run CI/CD on the Edgio deployments, which means we are no longer guaranteeing this deploy works with each new version +> +> If you have concerns or questions about our decision to deprecate this deploy provider please reach out to us on our [community forum](https://community.redwoodjs.com). [Edgio](https://edg.io) extends the capabilities of a traditional CDN by not only hosting your static content, but also providing server-side rendering for progressive web applications as well as caching both your APIs and HTML at the network edge to provide your users with the fastest browsing experience. @@ -18,8 +19,8 @@ In order to deploy your RedwoodJS project to Edgio, the project must first be in 1. In your project, run the command `yarn rw setup deploy edgio`. 2. Verify the changes to your project, commit and push to your repository. 3. Deploy your project to Edgio - 1. If this is your first time deploying to Edgio, the interactive CLI will prompt to authenticate using your browser. You can start the deploy by running `yarn rw deploy edgio`. - 2. If you are deploying from a **non-interactive** environment, you will need to create an account on [Edgio Developer Console](https://app.layer0.co) first and setup a [deploy token](https://docs.edg.io/guides/deploy_apps#deploy-from-ci). Once the deploy token is created, save it as a secret to your environment. You can start the deploy by running `yarn rw deploy edgio --token=XXX`. -4. Follow the link in the output to view your site live once deployment has completed! +4. If this is your first time deploying to Edgio, the interactive CLI will prompt to authenticate using your browser. You can start the deploy by running `yarn rw deploy edgio`. +5. If you are deploying from a **non-interactive** environment, you will need to create an account on [Edgio Developer Console](https://app.layer0.co) first and setup a [deploy token](https://docs.edg.io/guides/deploy_apps#deploy-from-ci). Once the deploy token is created, save it as a secret to your environment. You can start the deploy by running `yarn rw deploy edgio --token=XXX`. +6. Follow the link in the output to view your site live once deployment has completed! For more information on deploying to Edgio, check out the [documentation](https://docs.edg.io). diff --git a/docs/docs/deploy/flightcontrol.md b/docs/docs/deploy/flightcontrol.md index ffcb0409c42e..9d1c544703a3 100644 --- a/docs/docs/deploy/flightcontrol.md +++ b/docs/docs/deploy/flightcontrol.md @@ -13,11 +13,11 @@ description: How to deploy a Redwood app to AWS via Flightcontrol 3. Commit the changes and push to github. 4. If you don't have an account, sign up at [app.flightcontrol.dev/signup](https://app.flightcontrol.dev/signup?ref=redwood). 5. Create a new project from the onboarding screen or project list. - 1. Connect your Github account and select your repo. - 2. Click "Create Project" and complete any required steps like linking your AWS account. - 3. Configuration Type should autoselect as `flightcontrol.json`. - 4. NOTE: `flightcontrol.json` is now the source of truth for your Project and its Environments. + 1. Connect your Github account and select your repo. + 2. Click "Create Project" and complete any required steps like linking your AWS account. + 3. Configuration Type should autoselect as `flightcontrol.json`. + 4. NOTE: `flightcontrol.json` is now the source of truth for your Project and its Environments. 6. Add your env vars in Flightcontrol for your Environment. 7. If using dbAuth, add the session secret key env variable in the Flightcontrol dashboard. -If you have *any* problems or questions, Flightcontrol is very responsive in [their support Discord](https://discord.gg/yY8rSPrD6q). +If you have _any_ problems or questions, Flightcontrol is very responsive in [their support Discord](https://discord.gg/yY8rSPrD6q). diff --git a/docs/docs/deploy/introduction.md b/docs/docs/deploy/introduction.md index 1cbb38e0fcd7..49eba8f4a87d 100644 --- a/docs/docs/deploy/introduction.md +++ b/docs/docs/deploy/introduction.md @@ -12,6 +12,7 @@ Redwood is designed for both serverless and traditional infrastructure deploymen 4. the hosting provider deploys the built Web static assets to a CDN and the API code to a serverless backend (e.g. AWS Lambdas) Currently, these are the officially supported deploy targets: + - Baremetal (physical server that you have SSH access to) - [Coherence](https://www.withcoherence.com/) - [Flightcontrol.dev](https://www.flightcontrol.dev?ref=redwood) @@ -22,13 +23,13 @@ Currently, these are the officially supported deploy targets: - [Vercel.com](https://vercel.com) Redwood has a CLI generator that adds the code and configuration required by the specified provider (see the [CLI Doc](cli-commands.md#deploy-config) for more information): + ```shell yarn rw setup deploy ``` There are examples of deploying Redwood on other providers such as Google Cloud and direct to AWS. You can find more information by searching the [GitHub Issues](https://github.com/redwoodjs/redwood/issues) and [Forums](https://community.redwoodjs.com). - ## General Deployment Setup Deploying Redwood requires setup for the following four categories. diff --git a/docs/docs/deploy/netlify.md b/docs/docs/deploy/netlify.md index ad62b9b5d8f5..3f779f1b6ab4 100644 --- a/docs/docs/deploy/netlify.md +++ b/docs/docs/deploy/netlify.md @@ -18,7 +18,6 @@ While you may be tempted to use the [Netlify CLI](https://cli.netlify.com) comma The main reason for this is that these Netlify CLI commands simply build and deploy -- they build your project locally and then push the dist folder. That means that when building a RedwoodJS project, the [Prisma client is generated with binaries matching the operating system at build time](https://cli.netlify.com/commands/link) -- and not the [OS compatible](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#binarytargets-options) with running functions on Netlify. Your Prisma client engine may be `darwin` for OSX or `windows` for Windows, but it needs to be `debian-openssl-1.1.x` or `rhel-openssl-1.1.x`. If the client is incompatible, your functions will fail. - Therefore, **please follow the [Tutorial Deployment section](tutorial/chapter4/deployment.md)** to sync your GitHub (or other compatible source control service) repository with Netlify andalllow their build and deploy system to manage deployments. ::: diff --git a/docs/docs/deploy/render.md b/docs/docs/deploy/render.md index 705ec3dec80f..46ae652e35e8 100644 --- a/docs/docs/deploy/render.md +++ b/docs/docs/deploy/render.md @@ -9,6 +9,7 @@ Render is a unified cloud to build and run all your apps and websites with free ## Render tl;dr Deploy If you simply want to experience the Render deployment process, including a Postgres or SQLite database, you can do the following: + 1. create a new redwood project: `yarn create redwood-app ./render-deploy` 2. after your "render-deploy" project installation is complete, init git, commit, and add it as a new repo to GitHub or GitLab 3. run the command `yarn rw setup deploy render`, use the flag `--database` to select from `postgresql`, `sqlite` or `none` to proceed without a database [default : `postgresql`] diff --git a/docs/docs/deploy/serverless.md b/docs/docs/deploy/serverless.md index d854ff791f7c..ed9a1d108ca4 100644 --- a/docs/docs/deploy/serverless.md +++ b/docs/docs/deploy/serverless.md @@ -4,16 +4,17 @@ description: Deploy to AWS with Serverless Framework # Deploy to AWS with Serverless Framework ->⚠️ **Deprecated** ->As of Redwood v5, we are deprecating this deploy setup as an "officially" supported provider. This means: ->- For projects already using this deploy provider, there will be NO change at this time ->- Both the associated `setup` and `deploy` commands will remain in the framework as is; when setup is run, there will be a “deprecation” message ->- We will no longer run CI/CD on the Serverless-AWS deployments, which means we are no longer guaranteeing this deploy works with each new version ->- We are exploring better options to deploy directly to AWS Lambdas; the current deploy commands will not be removed until we find a replacement +> ⚠️ **Deprecated** +> As of Redwood v5, we are deprecating this deploy setup as an "officially" supported provider. This means: > ->For more details (e.g. why?) and current status, see the Forum post ["Deprecating support for Serverless Framework Deployments to AWS Lambdas"](https://community.redwoodjs.com/t/deprecating-support-for-serverless-framework-deployments-to-aws-lambdas/4755/10) +> - For projects already using this deploy provider, there will be NO change at this time +> - Both the associated `setup` and `deploy` commands will remain in the framework as is; when setup is run, there will be a “deprecation” message +> - We will no longer run CI/CD on the Serverless-AWS deployments, which means we are no longer guaranteeing this deploy works with each new version +> - We are exploring better options to deploy directly to AWS Lambdas; the current deploy commands will not be removed until we find a replacement +> +> For more details (e.g. why?) and current status, see the Forum post ["Deprecating support for Serverless Framework Deployments to AWS Lambdas"](https://community.redwoodjs.com/t/deprecating-support-for-serverless-framework-deployments-to-aws-lambdas/4755/10) ->The following instructions assume you have read the [General Deployment Setup](./introduction.md#general-deployment-setup) section above. +> The following instructions assume you have read the [General Deployment Setup](./introduction.md#general-deployment-setup) section above. Yes, the name is confusing, but Serverless provides a very interesting option—deploy to your own cloud service account and skip the middleman entirely! By default, Serverless just orchestrates starting up services in your cloud provider of choice and pushing your code up to them. Any bill you receive is from your hosting provider (although many offer a generous free tier). You can optionally use the [Serverless Dashboard](https://www.serverless.com/dashboard/) to monitor your deploys and setup CI/CD to automatically deploy when pushing to your repo of choice. If you don't setup CI/CD you actually deploy from your development machine (or another designated machine you've setup to do the deployment). @@ -64,7 +65,6 @@ Once that command completes you should see a message including the URL of your s From now on you can simply run `yarn rw deploy serverless` when you're ready to deploy (which will also be much faster). - :::info Remember, if you add or generate new serverless functions (or endpoints), you'll need to update the configuration in your serverless.yml in `./api/serverless.yml`. @@ -88,7 +88,7 @@ There are even more places you can get environment variables from, check out Ser To integrate your site into the Serverless Dashboard, there are two ways: -1. Run `yarn serverless login` and a browser *should* open asking you to allow permission. However, in our experience, this command will fail nearly 50% of the time complaining about an invalid URL. If it *does* work you can then run `yarn serverless` in both the `api` and `web` directories to link to them an existing app in the Dashboard, or you'll be prompted to create a new one. Future deploys will now be monitored on the Dashboard. +1. Run `yarn serverless login` and a browser _should_ open asking you to allow permission. However, in our experience, this command will fail nearly 50% of the time complaining about an invalid URL. If it _does_ work you can then run `yarn serverless` in both the `api` and `web` directories to link to them an existing app in the Dashboard, or you'll be prompted to create a new one. Future deploys will now be monitored on the Dashboard. 2. You can manually add the `org` and `app` lines in `api/serverless.yml` and `web/serverless.yml`. You'll see example ones commented out near the top of the file. ## Environments Besides Production diff --git a/docs/docs/deploy/vercel.md b/docs/docs/deploy/vercel.md index 5720c2225b5c..060627e4c224 100644 --- a/docs/docs/deploy/vercel.md +++ b/docs/docs/deploy/vercel.md @@ -4,11 +4,12 @@ description: Deploy serverless in an instant with Vercel # Deploy to Vercel ->The following instructions assume you have read the [General Deployment Setup](./introduction.md#general-deployment-setup) section above. +> The following instructions assume you have read the [General Deployment Setup](./introduction.md#general-deployment-setup) section above. ## Vercel tl;dr Deploy If you simply want to experience the Vercel deployment process without a database and/or adding custom code, you can do the following: + 1. create a new redwood project: `yarn create redwood-app ./vercel-deploy` 2. after your "vercel-deploy" project installation is complete, init git, commit, and add it as a new repo to GitHub, BitBucket, or GitLab 3. run the command `yarn rw setup deploy vercel` and commit and push changes @@ -29,6 +30,7 @@ Complete the following two steps. Then save, commit, and push your changes. ### Step 1. Serverless Functions Path Run the following CLI Command: + ```shell yarn rw setup deploy vercel ``` @@ -50,6 +52,7 @@ yarn rw deploy vercel --prisma=false --data-migrate=false ::: ### Vercel Initial Setup and Configuration + Either [login](https://vercel.com/login) to your Vercel account and select "Import Project" or use the Vercel [quick start](https://vercel.com/#get-started). Then select the "Continue" button within the "From Git Repository" section: @@ -60,6 +63,7 @@ Next, select the provider where your repo is hosted: GitHub, GitLab, or Bitbucke You'll then need to provide permissions for Vercel to access the repo on your hosting provider. ### Import and Deploy your Project + Vercel will recognize your repo as a Redwood project and take care of most configuration heavy lifting. You should see the following options and, most importantly, the "Framework Preset" showing RedwoodJS. @@ -121,13 +125,13 @@ export const handler = async (event: APIGatewayEvent, _context: Context) => { }), } } - ``` :::tip important Since Redwood has it's own handling of the api directory, the Vercel flavored api directory is disabled. Therefore you don't use the "functions" config in `vercel.json` with Redwood. Also, be sure to use Node version 20.x or greater or set the `runtime` in the function config: + ```ts export const config = { runtime: 'nodejs20.x', diff --git a/docs/docs/directives.md b/docs/docs/directives.md index c4b9e97f403a..d9c0d1d50119 100644 --- a/docs/docs/directives.md +++ b/docs/docs/directives.md @@ -251,14 +251,14 @@ As noted in the [GraphQL spec](https://graphql.org/learn/queries/#directives): Here's a helpful guide for deciding when you should use one of Redwood's Validator or Transformer directives: -| | Use | Directive | Custom? | Type | -| --- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------ | -| ✅ | Check if the request is authenticated? | `@requireAuth` | Built-in | Validator | -| ✅ | Check if the user belongs to a role? | `@requireAuth(roles: ["AUTHOR"])` | Built-in | Validator | -| ✅ | Only allow admins to see emails, but others get a masked value like "###@######.###" | `@maskedEmail(roles: ["ADMIN"])` | Custom | Transformer | -| 🙅 | Know if the logged in user can edit the record, and/or values | N/A - Instead do this check in your service | +| | Use | Directive | Custom? | Type | +| --- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------ | +| ✅ | Check if the request is authenticated? | `@requireAuth` | Built-in | Validator | +| ✅ | Check if the user belongs to a role? | `@requireAuth(roles: ["AUTHOR"])` | Built-in | Validator | +| ✅ | Only allow admins to see emails, but others get a masked value like "###@######.###" | `@maskedEmail(roles: ["ADMIN"])` | Custom | Transformer | +| 🙅 | Know if the logged in user can edit the record, and/or values | N/A - Instead do this check in your service | | 🙅 | Is my input a valid email address format? | N/A - Instead do this check in your service using [Service Validations](services.md#service-validations) or consider [GraphQL Scalars](https://www.graphql-scalars.dev) | -| 🙅 | I want to remove a field from the response for data filtering; for example, do not include the title of the post | `@skip(if: true )` or `@include(if: false)` | Instead use [core directives](https://graphql.org/learn/queries/#directives) on the GraphQL client query, not the SDL | Core GraphQL | +| 🙅 | I want to remove a field from the response for data filtering; for example, do not include the title of the post | `@skip(if: true )` or `@include(if: false)` | Instead use [core directives](https://graphql.org/learn/queries/#directives) on the GraphQL client query, not the SDL | Core GraphQL | ## Combining, Chaining and Cascading Directives @@ -412,11 +412,11 @@ When your app builds and your server starts up, Redwood checks that **all** quer If not, then your build will fail: ```bash - ✖ Verifying graphql schema... - Building API... - Cleaning Web... - Building Web... - Prerendering Web... +✖ Verifying graphql schema... +Building API... +Cleaning Web... +Building Web... +Prerendering Web... You must specify one of @requireAuth, @skipAuth or a custom directive for - contacts Query - posts Query @@ -490,8 +490,8 @@ you'll be presented with a choice of creating a Validator or a Transformer direc yarn redwood generate directive myDirective ? What type of directive would you like to generate? › - Use arrow-keys. Return to submit. -❯ Validator - Implement a validation: throw an error if criteria not met to stop execution - Transformer - Modify values of fields or query responses +❯ Validator - Implement a validation: throw an error if criteria not met to stop execution +Transformer - Modify values of fields or query responses ``` > **Note:** You can pass the `--type` flag with either `validator` or `transformer` to create the desired directive type. @@ -586,7 +586,9 @@ describe('isSubscriber directive', () => { it('has a isSubscriber throws an error if validation does not pass', () => { const mockExecution = mockRedwoodDirective(isSubscriber, {}) - expect(mockExecution).toThrowError('Implementation missing for isSubscriber') + expect(mockExecution).toThrowError( + 'Implementation missing for isSubscriber' + ) }) }) ``` @@ -675,7 +677,6 @@ describe('maskedEmail directive', () => { If your Transformer Directive is asynchronous, you can use `resolves` to handle the result. - ```ts import maskedEmail from './maskedEmail' @@ -689,4 +690,5 @@ describe('maskedEmail directive', () => { }) }) ``` + ::: diff --git a/docs/docs/docker.md b/docs/docs/docker.md index 70a534e8703e..f2d013a56b93 100644 --- a/docs/docs/docker.md +++ b/docs/docs/docker.md @@ -15,6 +15,7 @@ yarn rw setup docker ``` The setup commands does several things: + - writes four files: `Dockerfile`, `.dockerignore`, `docker-compose.dev.yml`, and `docker-compose.prod.yml` - adds the `@redwoodjs/api-server` and `@redwoodjs/web-server` packages to the api and web sides respectively - edits the `browser.open` setting in the `redwood.toml` (right now, if it's set to `true`, it'll break the dev server when running the `docker-compose.dev.yml`) @@ -52,7 +53,7 @@ root@...:/home/node/app# yarn rw prisma migrate dev The docker setup command assumes that you are using Postgres as your database provider and sets up a local Postgres database for you. You may have to switch from SQLite to Postgres if you have not done so and want to continue with the default setup. ::: -:::important +:::important If you are using a [Server File](#using-the-server-file) then you should [change the command](#command) that runs the `api_serve` service. ::: @@ -131,7 +132,7 @@ COPY --chown=node:node yarn.lock . Here we copy the minimum set of files that the `yarn install` step needs. The order isn't completely arbitrary—it tries to maximize [Docker's layer caching](https://docs.docker.com/build/cache/). -We expect `yarn.lock` to change more than the `package.json`s and the `package.json`s to change more than `.yarnrc.yml`. +We expect `yarn.lock` to change more than the `package.json`s and the `package.json`s to change more than `.yarnrc.yml`. That said, it's hard to argue that these files couldn't be arranged differently, or that the `COPY` instructions couldn't be combined. The important thing is that they're all here, before the `yarn install` step: @@ -275,19 +276,16 @@ ENV NODE_ENV=production CMD [ "node_modules/.bin/rw-server", "api" ] ``` -:::important +:::important If you are using a [Server File](#using-the-server-file) then you must change the command that runs the `api_serve` service to `./api/dist/server.js` as shown above. Not updating the command will not completely configure the GraphQL Server and not setup [Redwood Realtime](./realtime.md), if you are using that. ::: - Note that the Redwood CLI isn't available anymore because it is a dev dependency. To access the server bin, we have to find its path in `node_modules`. Though this is somewhat discouraged in modern yarn, since we're using the `node-modules` node linker, it's in `node_modules/.bin`. - - ### The `web_build` stage This `web_build` builds the web side: @@ -370,7 +368,7 @@ Lastly, note that we use the shell form of `CMD` here for its variable expansion The `console` stage is an optional stage for debugging: -```Dockerfile +````Dockerfile FROM base as console # To add more packages: @@ -387,7 +385,7 @@ FROM base as console COPY --chown=node:node api api COPY --chown=node:node web web COPY --chown=node:node scripts scripts -``` +```` The console stage completes the base stage by copying in the rest of your Redwood app. But then it pretty much leaves you to your own devices. @@ -529,13 +527,11 @@ yarn node api/dist/server.js You can't run the server file directly with Node.js; it has to be built first: - ``` yarn rw build api ``` -The api serve stage in the Dockerfile pulls from the api build stage, so things are already in the right order there. Similarly, for `yarn rw dev`, the dev server will build and reload the server file for you. - +The api serve stage in the Dockerfile pulls from the api build stage, so things are already in the right order there. Similarly, for `yarn rw dev`, the dev server will build and reload the server file for you. ### Command @@ -548,7 +544,7 @@ That means you will swap the `CMD` instruction in the api server stage: + CMD [ "api/dist/server.js" ] ``` -:::important +:::important If you are using a [Server File](#using-the-server-file) then you must change the command that runs the `api_serve` service to `./api/dist/server.js` as shown above. Not updating the command will not completely configure the GraphQL Server and not setup [Redwood Realtime](./realtime.md), if you are using that. @@ -559,6 +555,7 @@ Not updating the command will not completely configure the GraphQL Server and no There are three ways you may wish to configure the server. #### Underlying Fastify server + First, you can configure how the underlying Fastify server is instantiated via the`fastifyServerOptions` passed to the `createServer` function: ```ts title="api/src/server.ts" @@ -567,7 +564,7 @@ const server = await createServer({ // highlight-start fastifyServerOptions: { // ... - } + }, // highlight-end }) ``` @@ -575,6 +572,7 @@ const server = await createServer({ For the complete list of options, see [Fastify's documentation](https://fastify.dev/docs/latest/Reference/Server/#factory). #### Configure the redwood API plugin + Second, you may want to alter the behavior of redwood's API plugin itself. To do this we provide a `configureApiServer(server)` option where you can do anything you wish to the fastify instance before the API plugin is registered. Two examples are given below. ##### Example: Compressing Payloads and Rate Limiting @@ -601,14 +599,13 @@ const server = await createServer({ threshold: 1024, encodings: ['deflate', 'gzip'], }) - + await server.register(import('@fastify/rate-limit'), { max: 100, timeWindow: '5 minutes', }) - } + }, }) - ``` ##### Example: File Uploads @@ -625,7 +622,7 @@ If you try to POST file content to the api server such as images or PDFs, you ma ``` This's because Fastify [only supports `application/json` and `text/plain` content types natively](https://www.fastify.io/docs/latest/Reference/ContentTypeParser/). -While Redwood configures the api server to also accept `application/x-www-form-urlencoded` and `multipart/form-data`, if you want to support other content or MIME types (likes images or PDFs), you'll need to configure them here in the server file. +While Redwood configures the api server to also accept `application/x-www-form-urlencoded` and `multipart/form-data`, if you want to support other content or MIME types (likes images or PDFs), you'll need to configure them here in the server file. You can use Fastify's `addContentTypeParser` function to allow uploads of the content types your application needs. For example, to support image file uploads you'd tell Fastify to allow `/^image\/.*/` content types: @@ -633,13 +630,13 @@ For example, to support image file uploads you'd tell Fastify to allow `/^image\ ```ts title="api/src/server.ts" const server = await createServer({ logger, - configureApiServer(server){ + configureApiServer(server) { server.addContentTypeParser(/^image\/.*/, (_req, payload, done) => { payload.on('end', () => { done() }) }) - } + }, }) ``` @@ -648,6 +645,7 @@ The regular expression (`/^image\/.*/`) above allows all image content or MIME t Now, when you POST those content types to a function served by the api server, you can access the file content on `event.body`. #### Additional Fastify plugins + Finally, you can register additional Fastify plugins on the server instance: ```ts title="api/src/server.ts" @@ -657,11 +655,11 @@ const server = await createServer({ // highlight-next-line server.register(myFastifyPlugin) -``` +``` :::note Fastify encapsulation -Fastify is built around the concept of [encapsulation](https://fastify.dev/docs/latest/Reference/Encapsulation/). It is important to note that redwood's API plugin cannot be mutated after it is registered, see [here](https://fastify.dev/docs/latest/Reference/Plugins/#asyncawait). This is why you must use the `configureApiServer` option to do as shown above. +Fastify is built around the concept of [encapsulation](https://fastify.dev/docs/latest/Reference/Encapsulation/). It is important to note that redwood's API plugin cannot be mutated after it is registered, see [here](https://fastify.dev/docs/latest/Reference/Plugins/#asyncawait). This is why you must use the `configureApiServer` option to do as shown above. ::: @@ -678,25 +676,25 @@ It takes the same arguments as `listen`, except for host and port. It computes t 1. `--apiHost` or `--apiPort` flags: - ``` - yarn node api/dist/server.js --apiHost 0.0.0.0 --apiPort 8913 - ``` +``` +yarn node api/dist/server.js --apiHost 0.0.0.0 --apiPort 8913 +``` 2. `REDWOOD_API_HOST` or `REDWOOD_API_PORT` env vars: - ``` - export REDWOOD_API_HOST='0.0.0.0' - export REDWOOD_API_PORT='8913' - yarn node api/dist/server.js - ``` +``` +export REDWOOD_API_HOST='0.0.0.0' +export REDWOOD_API_PORT='8913' +yarn node api/dist/server.js +``` 3. `[api].host` and `[api].port` in `redwood.toml`: - ```toml title="redwood.toml" - [api] - host = '0.0.0.0' - port = 8913 - ``` +```toml title="redwood.toml" +[api] + host = '0.0.0.0' + port = 8913 +``` If you'd rather not have `createServer` parsing `process.argv`, you can disable it via `parseArgv`: diff --git a/docs/docs/environment-variables.md b/docs/docs/environment-variables.md index 537d7d259930..1e6534bbdc60 100644 --- a/docs/docs/environment-variables.md +++ b/docs/docs/environment-variables.md @@ -22,6 +22,7 @@ Redwood also configures Vite, so that all references to `process.env` vars on th ## Web ### Including environment variables + > **Heads Up:** for Web to access environment variables in production, you _must_ configure one of the options below. > > Redwood recommends **Option 1: `redwood.toml`** as it is the most robust. @@ -47,13 +48,12 @@ By adding environment variables to this array, they'll be available to Web in pr Note: if someone inspects your site's source, _they could see your `REDWOOD_ENV_SECRET_API_KEY` in plain text._ This is a limitation of delivering static JS and HTML to the browser. -#### Option 2: Prefixing with REDWOOD\_ENV\_ +#### Option 2: Prefixing with REDWOOD_ENV\_ In `.env`, if you prefix your environment variables with `REDWOOD_ENV_`, they'll be available via `process.env.REDWOOD_ENV_MY_VAR_NAME`, and will be dynamically replaced at build-time. Like the option above, these are also removed and replaced with the _actual value_ during build in order to be available in production. - ### Accessing API URLs Redwood automatically makes your API URL configurations from the web section of your `redwood.toml` available globally. diff --git a/docs/docs/forms.md b/docs/docs/forms.md index db7b39ce2657..22575b27c69e 100644 --- a/docs/docs/forms.md +++ b/docs/docs/forms.md @@ -26,7 +26,7 @@ import { `@redwoodjs/forms` exports the following components: | Component | Description | -|:------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------| +| :---------------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | | `
` | Surrounds all components, providing form and error contexts | | `` | Displays error messages from the server. Typically placed at the top of your form | | `
)) - ``` +``` Note that if you're copy-pasting this example, it uses [Tailwind CSS](https://tailwindcss.com), so you'll have to set that up first. See the [setup ui](./cli-commands.md#setup-ui) CLI command to add it to your project. diff --git a/docs/docs/schema-relations.md b/docs/docs/schema-relations.md index 0d0b3add404b..c5e28261c00d 100644 --- a/docs/docs/schema-relations.md +++ b/docs/docs/schema-relations.md @@ -45,7 +45,7 @@ These relationships can be [implicit](https://www.prisma.io/docs/concepts/compon CRUD (Create, Retrieve, Update, Delete) actions in Redwood currently require a single, unique field in order to retrieve, update or delete a record. This field must be denoted with Prisma's [`@id`](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#id) attribute, marking it as the tables's primary key. This field is guaranteed to be unique and so can be used to find a specific record. -Prisma's implicit many-to-many relationships create a table _without_ a single field marked with the `@id` attribute. Instead, it uses a similar attribute: [`@@id`](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#id-1) to define a *multi-field ID*. This multi-field ID will become the tables's primary key. The diagram above shows the result of letting Prisma create an implicit relationship. +Prisma's implicit many-to-many relationships create a table _without_ a single field marked with the `@id` attribute. Instead, it uses a similar attribute: [`@@id`](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#id-1) to define a _multi-field ID_. This multi-field ID will become the tables's primary key. The diagram above shows the result of letting Prisma create an implicit relationship. Since there's no single `@id` field in implicit many-to-many relationships, you can't use the SDL generator with the `--crud` flag. Likewise, you can't use the scaffold generator, which uses the SDL generator (with `--crud`) behind the scenes. @@ -131,11 +131,11 @@ yarn rw g sdl Book Here's how the output from the command starts: ```bash - ✔ Generating SDL files... - ✔ Successfully wrote file `./api/src/graphql/books.sdl.js` - ✔ Successfully wrote file `./api/src/services/books/books.scenarios.js` - ✔ Successfully wrote file `./api/src/services/books/books.test.js` - ✔ Successfully wrote file `./api/src/services/books/books.js` +✔ Generating SDL files... +✔ Successfully wrote file $(./api/src/graphql/books.sdl.js) +✔ Successfully wrote file $(./api/src/services/books/books.scenarios.js) +✔ Successfully wrote file $(./api/src/services/books/books.test.js) +✔ Successfully wrote file $(./api/src/services/books/books.js) ``` Looks like it's working so far. The SDL and service files generated! @@ -213,10 +213,10 @@ yarn rw g sdl Shelf --force --no-tests [Self-relations](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations#one-to-many-self-relations) are useful for modeling parent-child relationships where the parent and child are the "same type of thing". For example, in a business, everyone is an employee with a role and possibly someone to directly report to: -* President—no direct report (for the purposes of this example) -* Director—reports to the President -* Manager—reports to a Director -* Employee—reports to a Manager, but has no direct reports +- President—no direct report (for the purposes of this example) +- Director—reports to the President +- Manager—reports to a Director +- Employee—reports to a Manager, but has no direct reports Let's use a self-relation to model this in our Prisma schema: diff --git a/docs/docs/security.md b/docs/docs/security.md index 1493da1f2d10..d77502550439 100644 --- a/docs/docs/security.md +++ b/docs/docs/security.md @@ -6,12 +6,12 @@ description: Build and deploy secure applications RedwoodJS wants you to be able build and deploy secure applications and takes the topic of security seriously. -* [RedwoodJS Security](https://github.com/redwoodjs/redwood/security) on GitHub -* [CodeQL code scanning](https://github.com/features/security) -* [Authentication](authentication.md) -* [Webhook signature verification](webhooks.md) -* [Ways to keep your serverless functions secure](serverless-functions.md#security-considerations) -* [Environment variables for secure keys and tokens](environment-variables.md) +- [RedwoodJS Security](https://github.com/redwoodjs/redwood/security) on GitHub +- [CodeQL code scanning](https://github.com/features/security) +- [Authentication](authentication.md) +- [Webhook signature verification](webhooks.md) +- [Ways to keep your serverless functions secure](serverless-functions.md#security-considerations) +- [Environment variables for secure keys and tokens](environment-variables.md) > ⚠️ **Security is Your Responsibility** > While Redwood offers the tools, practices, and information to keep your application secure, it remains your responsibility to put these in place. Proper password, token, and key protection using disciplined communication, password management systems, and environment management services like [Doppler](https://www.doppler.com) are strongly encouraged. @@ -25,15 +25,15 @@ RedwoodJS wants you to be able build and deploy secure applications and takes th `@redwoodjs/auth` is a lightweight wrapper around popular SPA authentication libraries. We currently support [the following authentication providers](authentication.md) as well as a self-hosted solution ([dbAuth](auth/dbauth.md)): -* Netlify Identity Widget -* Auth0 -* Azure Active Directory -* Netlify GoTrue-JS -* Magic Links - Magic.js -* Firebase's GoogleAuthProvider -* Ethereum -* Supabase -* Nhost +- Netlify Identity Widget +- Auth0 +- Azure Active Directory +- Netlify GoTrue-JS +- Magic Links - Magic.js +- Firebase's GoogleAuthProvider +- Ethereum +- Supabase +- Nhost For example implementations, please see [Authentication](https://github.com/redwoodjs/redwood/tree/main/packages/auth) and the use of the `getCurrentUser` and `requireAuth` helpers. @@ -46,12 +46,15 @@ GraphQL is a fundamental part of Redwood. For details on how Redwood uses GraphQ ### Malicious Document Requests The RedwoodJS GraphQL handler sets [reasonable defaults](graphql.md#security) to prevent abusive queries that attackers often use to exploit systems. + ### Disable Introspection and Playground Because both introspection and the playground share possibly sensitive information about your data model, your data, your queries and mutations, best practices for deploying a GraphQL Server call to [disable these in production](graphql.md#introspection-and-playground-disabled-in-production), by default RedwoodJS **only enables introspection and the playground when running in development**. :::note + + For more information on how to enable introspection in production, please see the [GraphQL Docs](graphql.md#introspection-and-playground-disabled-in-production). ::: @@ -69,9 +72,9 @@ They are a form of messaging or automation and allows web applications to commun Since each of these webhooks will call a function endpoint in your RedwoodJS api, you need to ensure that these run **only when they should**. That means you need to: -* Verify it comes from the place you expect -* Trust the party -* Know the payload sent in the hook hasn't been tampered with -* Ensure that the hook isn't reprocessed or replayed +- Verify it comes from the place you expect +- Trust the party +- Know the payload sent in the hook hasn't been tampered with +- Ensure that the hook isn't reprocessed or replayed For details on how to keep your incoming webhooks secure and how to sign your outgoing webhooks, please see [Webhooks](webhooks.md). diff --git a/docs/docs/serverless-functions.md b/docs/docs/serverless-functions.md index c0c53fc8a846..a5753b376d81 100644 --- a/docs/docs/serverless-functions.md +++ b/docs/docs/serverless-functions.md @@ -6,7 +6,6 @@ description: Create, develop, and run serverless functions - :::info You can think of serverless functions as API Endpoints, and in the future we'll update the terminology used. @@ -79,10 +78,10 @@ api/src ├── functions │   ├── graphql.ts │   └── helloWorld -│   ├── helloWorld.scenarios.ts -│   ├── helloWorld.test.ts -│   └── helloWorld.ts # <-- imports hellWorldLib -│   └── helloWorldLib.ts # <-- exports can be used in the helloWorld +│   ├── helloWorld.scenarios.ts +│   ├── helloWorld.test.ts +│   └── helloWorld.ts # <-- imports hellWorldLib +│   └── helloWorldLib.ts # <-- exports can be used in the helloWorld ``` ## Developing locally @@ -104,7 +103,7 @@ To help you mock the `event` and `context` information, we've provided several a | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `mockHttpEvent` | Use this to mock out the http request `event` that is received by your function in unit tests. Here you can set `headers`, `httpMethod`, `queryStringParameters` as well as the `body` and if the body `isBase64Encoded`. The `event` contains information from the invoker as JSON-formatted string whose structure will vary. See [Working with AWS Lambda proxy integrations for HTTP APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html) for the payload format. | | `mockContext` | Use this function to mock the http `context`. Your function handler receives a context object with properties that provide information about the invocation, function, and execution environment. See [AWS Lambda context object in Node.js](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-context.html) for what context properties you can mock. | -| `mockSignedWebhook` | Use this function to mock a signed webhook. This is a specialized `mockHttpEvent` mock that also signs the payload and adds a signature header needed to verify that the webhook is trustworthy. See [How to Receive and Verify an Incoming Webhook](webhooks.md#how-to-receive-and-verify-an-incoming-webhook) to learn more about signing and verifying webhooks. | +| `mockSignedWebhook` | Use this function to mock a signed webhook. This is a specialized `mockHttpEvent` mock that also signs the payload and adds a signature header needed to verify that the webhook is trustworthy. See [How to Receive and Verify an Incoming Webhook](webhooks.md#how-to-receive-and-verify-an-incoming-webhook) to learn more about signing and verifying webhooks. | ### How to Test Serverless Functions @@ -124,7 +123,8 @@ We'll use the querystring to pass the `dividend` and `divisor` to the function h ```bash // request -http://localhost:8911/divide?dividend=10&divisor=2 +http://localhost:8911/divide?dividend=10 & +divisor=2 ``` If the function can successfully divide the two numbers, the function returns a body payload back in the response with a [HTTP 200 Success](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200) status: @@ -197,10 +197,10 @@ To test a serverless function, you'll work with the test script associated with ```bash api ├── src -│ ├── functions -│ │ ├── divide -│ │ │ ├── divide.ts -│ │ │ ├── divide.test.ts +│ ├── functions +│ │ ├── divide +│ │ │ ├── divide.ts +│ │ │ ├── divide.test.ts ``` The setup steps are to: @@ -317,11 +317,11 @@ First, let's create a fixture for the `divide` function alongside your function ```bash api ├── src -│ ├── functions -│ │ ├── divide -│ │ │ ├── divide.ts -│ │ │ ├── divide.test.ts -│ │ │ ├── divide.fixtures.ts // <-- your fixture +│ ├── functions +│ │ ├── divide +│ │ │ ├── divide.ts +│ │ │ ├── divide.test.ts +│ │ │ ├── divide.fixtures.ts // your fixture < -- ``` Let's define a fixture for a new test case: when the function is invoked, but it is missing a divisor: @@ -414,12 +414,11 @@ yarn rw generate function updateOrderStatus ```bash api ├── src -│ ├── functions -│ │ ├── updateOrderStatus -│ │ │ ├── updateOrderStatus.ts -│ │ │ ├── updateOrderStatus.scenarios.ts -│ │ │ ├── updateOrderStatus.test.ts - +│ ├── functions +│ │ ├── updateOrderStatus +│ │ │ ├── updateOrderStatus.ts +│ │ │ ├── updateOrderStatus.scenarios.ts +│ │ │ ├── updateOrderStatus.test.ts ``` The `updateOrderStatus` webhook will expect: @@ -435,7 +434,11 @@ The `updateOrderStatus` webhook will expect: ```tsx import type { APIGatewayEvent } from 'aws-lambda' -import { verifyEvent, VerifyOptions, WebhookVerificationError } from '@redwoodjs/api/webhooks' +import { + verifyEvent, + VerifyOptions, + WebhookVerificationError, +} from '@redwoodjs/api/webhooks' import { db } from 'src/lib/db' export const handler = async (event: APIGatewayEvent) => { @@ -475,7 +478,9 @@ export const handler = async (event: APIGatewayEvent) => { // updated the order with the new status // using the trackingNumber provided const order = await db.order.update({ - where: { trackingNumber_status: { trackingNumber, status: currentOrderStatus } }, + where: { + trackingNumber_status: { trackingNumber, status: currentOrderStatus }, + }, data: { status: status }, }) @@ -589,21 +594,27 @@ For brevity we didn't test that the order's status wasn't changed, but that coul ::: ```jsx -scenario('with an invalid signature header, the webhook is unauthorized', async (scenario) => { - const order = scenario.order.placed - - const payload = { trackingNumber: order.trackingNumber, status: 'DELIVERED' } - const event = mockSignedWebhook({ - payload, - signatureType: 'sha256Verifier', - signatureHeader: 'X-Webhook-Signature-Invalid', - secret: 'MY-VOICE-IS-MY-PASSPORT-VERIFY-ME', - }) +scenario( + 'with an invalid signature header, the webhook is unauthorized', + async (scenario) => { + const order = scenario.order.placed + + const payload = { + trackingNumber: order.trackingNumber, + status: 'DELIVERED', + } + const event = mockSignedWebhook({ + payload, + signatureType: 'sha256Verifier', + signatureHeader: 'X-Webhook-Signature-Invalid', + secret: 'MY-VOICE-IS-MY-PASSPORT-VERIFY-ME', + }) - const result = await handler(event) + const result = await handler(event) - expect(result.statusCode).toBe(401) -}) + expect(result.statusCode).toBe(401) + } +) ``` Next, we test what happens if the event payload is signed, but with a different secret than it expects; that is it was signed using the wrong secret (`MY-NAME-IS-WERNER-BRANDES-VERIFY-ME` and not `MY-VOICE-IS-MY-PASSPORT-VERIFY-ME`). @@ -611,44 +622,53 @@ Next, we test what happens if the event payload is signed, but with a different Again, we expect as 401 Unauthorized response. ```jsx -scenario('with the wrong webhook secret the webhook is unauthorized', async (scenario) => { - const order = scenario.order.placed - - const payload = { trackingNumber: order.trackingNumber, status: 'DELIVERED' } - const event = mockSignedWebhook({ - payload, - signatureType: 'sha256Verifier', - signatureHeader: 'X-Webhook-Signature', - secret: 'MY-NAME-IS-WERNER-BRANDES-VERIFY-ME', - }) +scenario( + 'with the wrong webhook secret the webhook is unauthorized', + async (scenario) => { + const order = scenario.order.placed + + const payload = { + trackingNumber: order.trackingNumber, + status: 'DELIVERED', + } + const event = mockSignedWebhook({ + payload, + signatureType: 'sha256Verifier', + signatureHeader: 'X-Webhook-Signature', + secret: 'MY-NAME-IS-WERNER-BRANDES-VERIFY-ME', + }) - const result = await handler(event) + const result = await handler(event) - expect(result.statusCode).toBe(401) -}) + expect(result.statusCode).toBe(401) + } +) ``` Next, what happens if the order cannot be found? We'll try a tracking number that doesn't exist (that is we did not create it in our scenario order data): ```jsx -scenario('when the tracking number cannot be found, returns an error', async (scenario) => { - const order = scenario.order.placed - - const payload = { trackingNumber: '1Z-DOES-NOT-EXIST', status: 'DELIVERED' } - const event = mockSignedWebhook({ - payload, - signatureType: 'sha256Verifier', - signatureHeader: 'X-Webhook-Signature', - secret: 'MY-VOICE-IS-MY-PASSPORT-VERIFY-ME', - }) +scenario( + 'when the tracking number cannot be found, returns an error', + async (scenario) => { + const order = scenario.order.placed + + const payload = { trackingNumber: '1Z-DOES-NOT-EXIST', status: 'DELIVERED' } + const event = mockSignedWebhook({ + payload, + signatureType: 'sha256Verifier', + signatureHeader: 'X-Webhook-Signature', + secret: 'MY-VOICE-IS-MY-PASSPORT-VERIFY-ME', + }) - const result = await handler(event) + const result = await handler(event) - const body = JSON.parse(result.body) + const body = JSON.parse(result.body) - expect(result.statusCode).toBe(500) - expect(body).toHaveProperty('error') -}) + expect(result.statusCode).toBe(500) + expect(body).toHaveProperty('error') + } +) ``` Last, we want to test a business rule that says you cannot update an order to be delivered if it already is delivered @@ -735,7 +755,7 @@ Serverless functions can use the same user-authentication strategy used by Graph :::tip - If you need to protect an endpoint via authentication that isn't user-based, you should consider using [Webhooks](webhooks.md) with a signed payload and verifier. +If you need to protect an endpoint via authentication that isn't user-based, you should consider using [Webhooks](webhooks.md) with a signed payload and verifier. ::: @@ -778,7 +798,7 @@ const myHandler = async (event: APIGatewayEvent, context: Context) => { data: 'myHandler function', }), } - // highlight-start + // highlight-start } else { logger.error('Access to myHandler was denied') @@ -824,7 +844,6 @@ auth-provider: supabase Content-Type: application/json ``` - ### Other security considerations In addition to securing your serverless functions, you may consider logging, rate limiting and whitelisting as ways to protect your functions from abuse or misuse. @@ -863,7 +882,11 @@ Because the `event` passed to the function handler contains the request's IP add ```jsx const ipAddress = ({ event }) => { - return event?.headers?.['client-ip'] || event?.requestContext?.identity?.sourceIp || 'localhost' + return ( + event?.headers?.['client-ip'] || + event?.requestContext?.identity?.sourceIp || + 'localhost' + ) } ``` diff --git a/docs/docs/services.md b/docs/docs/services.md index 52bb916f0a8a..0b6c49ef88e0 100644 --- a/docs/docs/services.md +++ b/docs/docs/services.md @@ -47,21 +47,34 @@ Finally, Services can also be called from [serverless functions](serverless-func Redwood includes a feature we call Service Validations. These simplify an extremely common task: making sure that incoming data is formatted properly before continuing. These validations are meant to be included at the start of your Service function and will throw an error if conditions are not met: ```jsx -import { validate, validateWith, validateWithSync, validateUniqueness } from '@redwoodjs/api' +import { + validate, + validateWith, + validateWithSync, + validateUniqueness, +} from '@redwoodjs/api' export const createUser = async ({ input }) => { validate(input.firstName, 'First name', { presence: true, - exclusion: { in: ['Admin', 'Owner'], message: 'That name is reserved, sorry!' }, - length: { min: 2, max: 255 } + exclusion: { + in: ['Admin', 'Owner'], + message: 'That name is reserved, sorry!', + }, + length: { min: 2, max: 255 }, }) validateWithSync(() => { - if (input.role === 'Manager' && !context.currentUser.roles.includes('admin')) { + if ( + input.role === 'Manager' && + !context.currentUser.roles.includes('admin') + ) { throw 'Only Admins can create new Managers' } }) await validateWith(async () => { - const inviteCount = await db.invites.count({ where: { userId: currentUser.id } }) + const inviteCount = await db.invites.count({ + where: { userId: currentUser.id }, + }) if (inviteCount >= 10) { throw 'You have already invited your max of 10 users' } @@ -75,7 +88,7 @@ export const createUser = async ({ input }) => { > **What's the difference between Service Validations and Validator Directives?** > -> [Validator Directives](directives.md#validators) were added to Redwood in v0.37 and provide a way to validate whether data going through GraphQL is allowed based on the user that's currently requesting it (the user that is logged in). These directives control *access* to data, while Service Validators operate on a different level, outside of GraphQL, and make sure data is formatted properly before, most commonly, putting it into a database. +> [Validator Directives](directives.md#validators) were added to Redwood in v0.37 and provide a way to validate whether data going through GraphQL is allowed based on the user that's currently requesting it (the user that is logged in). These directives control _access_ to data, while Service Validators operate on a different level, outside of GraphQL, and make sure data is formatted properly before, most commonly, putting it into a database. > > You could use these in combination to, for example, prevent a client from accessing the email addresses of any users that aren't themselves (Validator Directives) while also verifying that when creating a user, an email address is present, formatted correctly, and unique (Service Validations). @@ -151,7 +164,7 @@ Please provide a valid email address #### Multiple Validations -You can provide multiple validations in the last argument object, some with custom messages and some without. If you include only *some* custom messages, make sure to use the 3-argument version as the ones without custom messages will need a variable name to include their messages: +You can provide multiple validations in the last argument object, some with custom messages and some without. If you include only _some_ custom messages, make sure to use the 3-argument version as the ones without custom messages will need a variable name to include their messages: ```jsx validate(input.name, 'Name', { @@ -191,25 +204,25 @@ Opposite of the [presence](#presence) validator. ```jsx validate(input.value, 'Value', { - absence: true + absence: true, }) ``` ##### Options -* `allowEmptyString` will count an empty string as being absent (that is, `null`, `undefined` and `""` will pass this validation) +- `allowEmptyString` will count an empty string as being absent (that is, `null`, `undefined` and `""` will pass this validation) ```jsx validate(input.honeypot, 'Honeypot', { - absence: { allowEmptyString: true } + absence: { allowEmptyString: true }, }) ``` -* `message`: a message to be shown if the validation fails +- `message`: a message to be shown if the validation fails ```jsx validate(input.value, { - absence: { message: 'Value must be absent' } + absence: { message: 'Value must be absent' }, }) ``` @@ -219,25 +232,25 @@ Requires that the passed value be `true`, or within an array of allowed values t ```jsx validate(input.terms, 'Terms of Service', { - acceptance: true + acceptance: true, }) ``` ##### Options -* `in`: an array of values that, if any match, will pass the validation +- `in`: an array of values that, if any match, will pass the validation ```jsx validate(input.terms, 'Terms of Service', { - acceptance: { in: [true, 'true', 1, '1'] } + acceptance: { in: [true, 'true', 1, '1'] }, }) ``` -* `message`: a custom message if validation fails +- `message`: a custom message if validation fails ```jsx validate(input.terms, { - acceptance: { message: 'Please accept the Terms of Service' } + acceptance: { message: 'Please accept the Terms of Service' }, }) ``` @@ -245,23 +258,23 @@ validate(input.terms, { Requires that the value be formatted like an email address by comparing against a regular expression. The regex is extremely lax: `/^[^@\s]+@[^.\s]+\.[^\s]+$/` This says that the value: -* Must start with one or more characters that aren't a whitespace or literal `@` -* Followed by a `@` -* Followed by one or more characters that aren't a whitespace or literal `.` -* Followed by a `.` -* Ending with one or more characters that aren't whitespace +- Must start with one or more characters that aren't a whitespace or literal `@` +- Followed by a `@` +- Followed by one or more characters that aren't a whitespace or literal `.` +- Followed by a `.` +- Ending with one or more characters that aren't whitespace Since the [official email regex](http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html) is around 6,300 characters long, we though this one was good enough. If you have a different, preferred email validation regular expression, use the [format](#format) validation. ```jsx validate(input.email, 'Email', { - email: true + email: true, }) ``` ##### Options -* `message`: a custom message if validation fails +- `message`: a custom message if validation fails ```jsx validate(input.email, { @@ -271,33 +284,33 @@ validate(input.email, { #### Exclusion -Requires that the given value *not* equal to any in a list of given values. Opposite of the [inclusion](#inclusion) validation. +Requires that the given value _not_ equal to any in a list of given values. Opposite of the [inclusion](#inclusion) validation. ```jsx validate(input.name, 'Name', { - exclusion: ['Admin', 'Owner'] + exclusion: ['Admin', 'Owner'], }) ``` ##### Options -* `in`: the list of values that cannot be used -* `caseSensitive`: toggles case sensitivity; default: `true` +- `in`: the list of values that cannot be used +- `caseSensitive`: toggles case sensitivity; default: `true` ```jsx validate(input.name, 'Name', { - exclusion: { in: ['Admin', 'Owner'] } + exclusion: { in: ['Admin', 'Owner'] }, }) ``` -* `message`: a custom error message if validation fails +- `message`: a custom error message if validation fails ```jsx validate(input.name, { exclusion: { in: ['Admin', 'Owner'], - message: 'That name is reserved, try another' - } + message: 'That name is reserved, try another', + }, }) ``` @@ -307,61 +320,60 @@ Requires that the value match a given regular expression. ```jsx validate(input.usPhone, 'US Phone Number', { - format: /^[0-9-]{10,12}$/ + format: /^[0-9-]{10,12}$/, }) ``` ##### Options -* `pattern`: the regular expression to use +- `pattern`: the regular expression to use ```jsx validate(input.usPhone, 'US Phone Number', { - format: { pattern: /^[0-9-]{10,12}$/ } + format: { pattern: /^[0-9-]{10,12}$/ }, }) ``` -* `message`: a custom error message if validation fails - +- `message`: a custom error message if validation fails ```jsx validate(input.usPhone, { format: { pattern: /^[0-9-]{10,12}$/, - message: 'Can only contain numbers and dashes' - } + message: 'Can only contain numbers and dashes', + }, }) ``` #### Inclusion -Requires that the given value *is* equal to one in a list of given values. Opposite of the [exclusion](#exclusion) validation. +Requires that the given value _is_ equal to one in a list of given values. Opposite of the [exclusion](#exclusion) validation. ```jsx validate(input.role, 'Role', { - inclusion: ['Guest', 'Member', 'Manager'] + inclusion: ['Guest', 'Member', 'Manager'], }) ``` ##### Options -* `in`: the list of values that can be used -* `caseSensitive`: toggles case sensitivity; default: `true` +- `in`: the list of values that can be used +- `caseSensitive`: toggles case sensitivity; default: `true` ```jsx validate(input.role, 'Role', { - inclusion: { in: ['Guest', 'Member', 'Manager'] } + inclusion: { in: ['Guest', 'Member', 'Manager'] }, }) ``` -* `message`: a custom error message if validation fails +- `message`: a custom error message if validation fails ```jsx validate(input.role, 'Role', { inclusion: { - in: ['Guest', 'Member', 'Manager'] , - message: 'Please select a proper role' - } + in: ['Guest', 'Member', 'Manager'], + message: 'Please select a proper role', + }, }) ``` @@ -371,49 +383,53 @@ Requires that the value meet one or more of a number of string length validation ```jsx validate(input.answer, 'Answer', { - length: { min: 6, max: 200 } + length: { min: 6, max: 200 }, }) ``` ##### Options -* `min`: must be at least this number of characters long +- `min`: must be at least this number of characters long ```jsx validate(input.name, 'Name', { - length: { min: 2 } + length: { min: 2 }, }) ``` -* `max`: must be no more than this number of characters long +- `max`: must be no more than this number of characters long ```jsx validate(input.company, 'Company', { - length: { max: 255 } + length: { max: 255 }, }) ``` -* `equal`: must be exactly this number of characters long +- `equal`: must be exactly this number of characters long ```jsx validate(input.pin, 'PIN', { - length: { equal: 4 } + length: { equal: 4 }, }) ``` -* `between`: convenience syntax for defining min and max as an array +- `between`: convenience syntax for defining min and max as an array ```jsx validate(input.title, 'Title', { - length: { between: [2, 255] } + length: { between: [2, 255] }, }) ``` -* `message`: a custom message if validation fails. Can use length options as string interpolations in the message itself, including `name` which is the name of the field provided in the second argument +- `message`: a custom message if validation fails. Can use length options as string interpolations in the message itself, including `name` which is the name of the field provided in the second argument ```jsx validate(input.title, 'Title', { - length: { min: 2, max: 255, message: '${name} must be between ${min} and ${max} characters' } + length: { + min: 2, + max: 255, + message: '${name} must be between ${min} and ${max} characters', + }, }) ``` @@ -425,105 +441,108 @@ The awesomely-named Numericality Validation requires that the value passed meet ```jsx validate(input.year, 'Year', { - numericality: { greaterThan: 1900, lessThanOrEqual: 2021 } + numericality: { greaterThan: 1900, lessThanOrEqual: 2021 }, }) ``` ##### Options -* `integer`: the number must be an integer +- `integer`: the number must be an integer ```jsx validate(input.age, 'Age', { - numericality: { integer: true } + numericality: { integer: true }, }) ``` -* `lessThan`: the number must be less than the given value +- `lessThan`: the number must be less than the given value ```jsx validate(input.temp, 'Temperature', { - numericality: { lessThan: 100 } + numericality: { lessThan: 100 }, }) ``` -* `lessThanOrEqual`: the number must be less than or equal to the given value +- `lessThanOrEqual`: the number must be less than or equal to the given value ```jsx validate(input.temp, 'Temperature', { - numericality: { lessThanOrEqual: 100 } + numericality: { lessThanOrEqual: 100 }, }) ``` -* `greaterThan`: the number must be greater than the given value +- `greaterThan`: the number must be greater than the given value ```jsx validate(input.temp, 'Temperature', { - numericality: { greaterThan: 32 } + numericality: { greaterThan: 32 }, }) ``` -* `greaterThanOrEqual`: the number must be greater than or equal to the given number +- `greaterThanOrEqual`: the number must be greater than or equal to the given number ```jsx validate(input.temp, 'Temperature', { - numericality: { greaterThanOrEqual: 32 } + numericality: { greaterThanOrEqual: 32 }, }) ``` -* `equal`: the number must be equal to the given number +- `equal`: the number must be equal to the given number ```jsx validate(input.guess, 'Guess', { - numericality: { equal: 6 } + numericality: { equal: 6 }, }) ``` -* `otherThan`: the number must not be equal to the given number +- `otherThan`: the number must not be equal to the given number ```jsx validate(input.floor, 'Floor', { - numericality: { otherThan: 13 } + numericality: { otherThan: 13 }, }) ``` -* `even`: the number must be even +- `even`: the number must be even ```jsx validate(input.skip, 'Skip', { - numericality: { even: true } + numericality: { even: true }, }) ``` -* `odd`: the number must be odd +- `odd`: the number must be odd ```jsx validate(input.zenGarden, 'Zen Garden', { - numericality: { odd: true } + numericality: { odd: true }, }) ``` -* `positive`: the number must be positive (greater than 0) +- `positive`: the number must be positive (greater than 0) ```jsx validate(input.balance, 'Balance', { - numericality: { positive: true } + numericality: { positive: true }, }) ``` -* `negative`: the number must be negative (less than 0) +- `negative`: the number must be negative (less than 0) ```jsx validate(input.debt, 'Debt', { - numericality: { negative: true } + numericality: { negative: true }, }) ``` -* `message`: a custom message if validation fails. Some options can be used in string interpolation: `lessThan`, `lessThanOrEqual`, `greaterThan`, `greaterThanOrEqual`, `equal`, and `otherThan` +- `message`: a custom message if validation fails. Some options can be used in string interpolation: `lessThan`, `lessThanOrEqual`, `greaterThan`, `greaterThanOrEqual`, `equal`, and `otherThan` ```jsx validate(input.floor, 'Floor', { - numericality: { otherThan: 13, message: 'You cannot go to floor ${otherThan}' } + numericality: { + otherThan: 13, + message: 'You cannot go to floor ${otherThan}', + }, }) ``` @@ -536,50 +555,50 @@ Opposite of the [absence](#absence) validator. ```jsx validate(input.value, 'Value', { - presence: true + presence: true, }) ``` ##### Options -* `allowNull`: whether or not to allow `null` to be considered present (default is `false`) +- `allowNull`: whether or not to allow `null` to be considered present (default is `false`) ```jsx validate(input.value, 'Value', { - presence: { allowNull: true } + presence: { allowNull: true }, }) // `null` passes // `undefined` fails // "" passes ``` -* `allowUndefined`: whether or not to allow `undefined` to be considered present (default is `false`) +- `allowUndefined`: whether or not to allow `undefined` to be considered present (default is `false`) ```jsx validate(input.value, 'Value', { - presence: { allowUndefined: true } + presence: { allowUndefined: true }, }) // `null` fails // `undefined` passes // "" passes ``` -* `allowEmptyString`: whether or not to allow an empty string `""` to be considered present (default is `true`) +- `allowEmptyString`: whether or not to allow an empty string `""` to be considered present (default is `true`) ```jsx validate(input.value, 'Value', { - presence: { allowEmptyString: false } + presence: { allowEmptyString: false }, }) // `null` fails // `undefined` fails // "" fails ``` -* `message`: a message to be shown if the validation fails +- `message`: a message to be shown if the validation fails ```jsx validate(input.lastName, { - presence: { allowEmptyString: false, message: "Can't leave last name empty" } + presence: { allowEmptyString: false, message: "Can't leave last name empty" }, }) ``` @@ -595,14 +614,14 @@ validate(input.value, 'Value', { if (isInvalid) { throw new Error('Value is invalid') } - } - } + }, + }, }) ``` ##### Options -* `message`: a custom error message if validation fails +- `message`: a custom error message if validation fails ```jsx validate(input.value, 'Value', { @@ -612,10 +631,11 @@ validate(input.value, 'Value', { throw new Error('Value is invalid') } }, - message: 'Please specify a different value' - } + message: 'Please specify a different value', + }, }) ``` + ### validateWithSync() `validateWithSync()` is simply given a function to execute. This function should throw with a message if there is a problem, otherwise do nothing. @@ -644,8 +664,8 @@ The same behavior as `validateWithSync()` but works with Promises. Remember to ` ```jsx await validateWith(async () => { - if (await db.products.count() >= 100) { - throw "There can only be a maximum of 100 products in your store" + if ((await db.products.count()) >= 100) { + throw 'There can only be a maximum of 100 products in your store' } }) ``` @@ -703,7 +723,8 @@ You can provide a custom message if the validation failed with the optional thir ```jsx const createUser = (input) => { - return validateUniqueness('user', + return validateUniqueness( + 'user', { email: input.email }, { message: 'Your email is already in use' }, (db) => db.user.create({ data: input }) @@ -712,14 +733,13 @@ const createUser = (input) => { ``` You can provide the PrismaClient to be used for the transaction and callback. + ```jsx import { db } from 'src/lib/db' const createUser = (input) => { - return validateUniqueness('user', - { email: input.email }, - { db }, - (db) => db.user.create({ data: input }) + return validateUniqueness('user', { email: input.email }, { db }, (db) => + db.user.create({ data: input }) ) } ``` @@ -749,12 +769,16 @@ Sometimes we may only want to check uniqueness against a subset of records, say ```jsx const createPost = (input) => { - return validateUniqueness('post', { - title: input.title, - $scope: { userId: context.currentUser.id } - }, (db) => { - return db.user.create({ data: input }) - }) + return validateUniqueness( + 'post', + { + title: input.title, + $scope: { userId: context.currentUser.id }, + }, + (db) => { + return db.user.create({ data: input }) + } + ) } ``` @@ -795,7 +819,12 @@ export const updatePost = async ({ id, input }) => { where: { id }, }) // highlight-next-line - await cacheClient.MSET(`post-${id}`, JSON.stringify(post), `blogpost-${id}`, JSON.stringify(post)) + await cacheClient.MSET( + `post-${id}`, + JSON.stringify(post), + `blogpost-${id}`, + JSON.stringify(post) + ) return post } @@ -827,10 +856,10 @@ Okay, let's use the product's database ID as the key: `41443`. It's definitely g What if we add a "type" into the cache key, so we know what type of thing we're caching: `product-41442`. Now we're getting somewhere. Users will have a cache key `user-41442` and the two won't clash. But what happens if you change some data about that product, like the description? Remember that we can only get an existing key/value, or create a key/value in the cache, we can't update an existing key. How we can encapsulate the "knowledge" that a product's data has changed into the cache key? -One solution would be to put all of the data that we care about changing into the key, like: `product-41442-${description}`. The problem here is that keys can only be so long (in Memcached it's 250 bytes). Another option could be to hash the entire product object and use that as the key (this can encompass the `product` part of the key as well as the ID itself, since *any* data in the object being different will result in a new hash): +One solution would be to put all of the data that we care about changing into the key, like: `product-41442-${description}`. The problem here is that keys can only be so long (in Memcached it's 250 bytes). Another option could be to hash the entire product object and use that as the key (this can encompass the `product` part of the key as well as the ID itself, since _any_ data in the object being different will result in a new hash): ```js -import { md5 } from "blueimp-md5" +import { md5 } from 'blueimp-md5' cache(md5(JSON.stringify(product)), () => { // ... @@ -850,9 +879,10 @@ cache(product, () => { // ... }) ``` + ::: -One drawback to this key is in potentially responding to *too many* data changes, even ones we don't care about caching. Imagine that a product has a `views` field that tracks how many times it has been viewed in the browser. This number will be changing all the time, but if we don't display that count to the user then we're constantly re-creating the cache for the product even though no data the user will see is changing. There's no way to tell Prisma "set the `updatedAt` when the record changes, but not if the `views` column changes." This cache key is too variable. One solution would be to move the `views` column to another table with a `productId` pointing back to this record. Now the `product` is back to just containing data we care about caching. +One drawback to this key is in potentially responding to _too many_ data changes, even ones we don't care about caching. Imagine that a product has a `views` field that tracks how many times it has been viewed in the browser. This number will be changing all the time, but if we don't display that count to the user then we're constantly re-creating the cache for the product even though no data the user will see is changing. There's no way to tell Prisma "set the `updatedAt` when the record changes, but not if the `views` column changes." This cache key is too variable. One solution would be to move the `views` column to another table with a `productId` pointing back to this record. Now the `product` is back to just containing data we care about caching. What if you want to expire a cache regardless of whether the data itself has changed? Maybe you make a UI change where you now show a product's SKU on the page where you didn't before. You weren't previously selecting the `sku` field out of the database, and so it hasn't been cached. But now that you're showing it you'll need to add it the list of fields to return from the service. One solution would be forcibly update all of the `updatedAt` fields in the database. But a) Prisma won't easily let you do this since it think it controls that column, and b) every product is going to appear to have been edited at the same time, when in fact nothing changed—you just needed to bust the cache. @@ -864,16 +894,16 @@ And this key is our final form: a unique, but flexible key that allows us to exp One more case: what if the underlying `Product` model itself changes, adding a new field, for example? Each product will now have new data, but no changes will occur to `updatedAt` as a result of adding this column. There are a couple things you could do here: -* Increment the version on the key, if you have one: `v1` => `v2` -* "Touch" all of the Product records in a script, forcing them to have their `updatedAt` timestamp changed -* Incorporate a hash of all the keys of a `product` into the cache key +- Increment the version on the key, if you have one: `v1` => `v2` +- "Touch" all of the Product records in a script, forcing them to have their `updatedAt` timestamp changed +- Incorporate a hash of all the keys of a `product` into the cache key How does that last one work? We get a list of all the keys and then apply a hashing algorithm like MD5 to get a string that's unique based on that list of database columns. Then if one is ever added or removed, the hash will change, which will change the key, which will bust the cache: ```javascript const product = db.product.findUnique({ where: { id } }) const columns = Object.keys(product) // ['id', 'name', 'sku', ...] -const hash = md5(columns.join(',')) // "e4d7f1b4ed2e42d15898f4b27b019da4" +const hash = md5(columns.join(',')) // "e4d7f1b4ed2e42d15898f4b27b019da4" cache(`v1-product-${hash}-${id}-${updatedAt}`, () => { // ... @@ -889,16 +919,20 @@ Note that this has the side effect of having to select at least one record from You can skirt these issues about what data is changing and what to include or not include in the key by just setting an expiration time on this cache entry. You may decide that if a change is made to a product, it's okay if users don't see the change for, say, an hour. In this case just set the expiration time to 3600 seconds and it will automatically be re-built, whether something changed in the record or not: ```js -cache(`product-${id}`, () => { - // ... -}, { expires: 3600 }) +cache( + `product-${id}`, + () => { + // ... + }, + { expires: 3600 } +) ``` -This leads to your product cache being rebuilt every hour, even though you haven't made any changes that are of consequence to the user. But that may be we worth the tradeoff versus rebuilding the cache when *no* useful data has changed (like the `views` column being updated). +This leads to your product cache being rebuilt every hour, even though you haven't made any changes that are of consequence to the user. But that may be we worth the tradeoff versus rebuilding the cache when _no_ useful data has changed (like the `views` column being updated). #### Global Cache Key Prefix -Just like the `v1` we added to the `product` cache key above, you can globally prefix a string to *all* of your cache keys: +Just like the `v1` we added to the `product` cache key above, you can globally prefix a string to _all_ of your cache keys: ```js title="api/src/lib/cache.js" export const { cache, cacheFindMany } = createCache(client, { @@ -911,7 +945,7 @@ export const { cache, cacheFindMany } = createCache(client, { This would turn a key like `posts-123` into `alpha-posts-123` before giving it to the cache client. If you prefixed with `v1` in the individual cache key, you'd now have `alpha-v1-posts-123`. -This gives you a nuclear option to invalidate all cache keys globally in your app. Let's say you launched a new redesign, or other visual change to your site where you may be showing more or less data from your GraphQL queries. If your data was purely based on the DB data (like `id` and `updatedAt`) there would be no way to refresh all of these keys without changing each and every cache key manually in every service, or by manually updating *all* `updatedAt` timestamps in the database. This gives you a fallback to refreshing all data at once. +This gives you a nuclear option to invalidate all cache keys globally in your app. Let's say you launched a new redesign, or other visual change to your site where you may be showing more or less data from your GraphQL queries. If your data was purely based on the DB data (like `id` and `updatedAt`) there would be no way to refresh all of these keys without changing each and every cache key manually in every service, or by manually updating _all_ `updatedAt` timestamps in the database. This gives you a fallback to refreshing all data at once. #### Caching User-specific Data @@ -923,9 +957,9 @@ cache(`recommended-${context.currentUser.id}`, () => { }) ``` -If every page the user visits has a different list of recommended products for every page (meaning that the full computation will need to run at least once, before it's cached) then creating this cache may not be worth it: how often does the user revisit the same product page more than once? Conversely, if you show the *same* recommended products on every page then this cache would definitely improve the user's experience. +If every page the user visits has a different list of recommended products for every page (meaning that the full computation will need to run at least once, before it's cached) then creating this cache may not be worth it: how often does the user revisit the same product page more than once? Conversely, if you show the _same_ recommended products on every page then this cache would definitely improve the user's experience. -The *key* to writing a good key (!) is to think carefully about the circumstances in which the key needs to expire, and include those bits of information into the key string/array. Adding caching can lead to weird bugs you don't expect, but in these cases the root cause will usually be the cache key not containing enough bits of information to expire it correctly. When in doubt, restart the app with the cache server (memcached or redis) disabled and see if the same behavior is still present. If not, the cache key is the culprit! +The _key_ to writing a good key (!) is to think carefully about the circumstances in which the key needs to expire, and include those bits of information into the key string/array. Adding caching can lead to weird bugs you don't expect, but in these cases the root cause will usually be the cache key not containing enough bits of information to expire it correctly. When in doubt, restart the app with the cache server (memcached or redis) disabled and see if the same behavior is still present. If not, the cache key is the culprit! ### Setup @@ -981,7 +1015,7 @@ The second usage of the logger argument: ```js export const { cache, cacheFindMany } = createCache(client, { logger, - timeout: 500 + timeout: 500, }) ``` @@ -991,10 +1025,10 @@ is passing it to Redwood's own service cache code, so that it can log cache hits There are several options you can pass to the `createCache()` call: -* `logger`: an instance of the Redwood logger. Defaults to `null`, but if you want any feedback about what the cache is doing, make sure to set this! -* `timeout`: how long to wait for the cache server to respond during a get/set before giving up and just executing the function containing what you want to cache and returning the result directly. Defaults to `500` milliseconds. -* `prefix`: a global cache key prefix. Defaults to `null`. -* `fields`: an object that maps the model field names for the `id` and `updatedAt` fields if your database has another name for them. For example: `fields: { id: 'post_id', updatedAt: 'updated_at' }`. Even if only one of your names is different, you need to provide both properties to this option. Defaults to `{ id: 'id', updatedAt: 'updatedAt' }` +- `logger`: an instance of the Redwood logger. Defaults to `null`, but if you want any feedback about what the cache is doing, make sure to set this! +- `timeout`: how long to wait for the cache server to respond during a get/set before giving up and just executing the function containing what you want to cache and returning the result directly. Defaults to `500` milliseconds. +- `prefix`: a global cache key prefix. Defaults to `null`. +- `fields`: an object that maps the model field names for the `id` and `updatedAt` fields if your database has another name for them. For example: `fields: { id: 'post_id', updatedAt: 'updated_at' }`. Even if only one of your names is different, you need to provide both properties to this option. Defaults to `{ id: 'id', updatedAt: 'updatedAt' }` ### `cache()` @@ -1010,9 +1044,13 @@ const post = ({ id }) => { // cache for 1 hour const post = ({ id }) => { - return cache(`posts`, () => { - return db.post.findMany() - }, { expires: 3600 }) + return cache( + `posts`, + () => { + return db.post.findMany() + }, + { expires: 3600 } + ) } ``` @@ -1028,7 +1066,7 @@ const post = ({ id }) => { // or const post = ({ id }) => { - return cache(['posts', id, updatedAt.getTime()], () => { + return cache(['posts', id, updatedAt.getTime()], () => { return db.post.findMany() }) } @@ -1042,7 +1080,7 @@ const post = ({ id }) => { ### `cacheFindMany()` -Use this function if you want to cache the results of a `findMany()` call from Prisma, but only until one or more of the records in the set is updated. This is sort of a best of both worlds cache scenario where you can cache as much data as possible, but also expire and re-cache as soon as any piece of it changes, without going through every record manually to see if it's changed: whenever *any* record changes the cache will be discarded. +Use this function if you want to cache the results of a `findMany()` call from Prisma, but only until one or more of the records in the set is updated. This is sort of a best of both worlds cache scenario where you can cache as much data as possible, but also expire and re-cache as soon as any piece of it changes, without going through every record manually to see if it's changed: whenever _any_ record changes the cache will be discarded. This function will always execute a `findFirst()` query to get the latest record that's changed, then use its `id` and `updatedAt` timestamp as the cache key for the full query. This means you'll always incur the overhead of a single DB call, but not the bigger `findMany()` unless something has changed. Note you still need to include a cache key prefix: @@ -1057,7 +1095,7 @@ The above is the simplest usage example. If you need to pass a `where`, or any o ```js const post = ({ id }) => { return cacheFindMany(`users`, db.user, { - conditions: { where: { roles: 'admin' } } + conditions: { where: { roles: 'admin' } }, }) } ``` @@ -1080,12 +1118,10 @@ If you also want to pass an `expires` option, do it in the same object as `condi ```js const post = ({ id }) => { - return cacheFindMany( - `users`, db.user, { - conditions: { where: { roles: 'admin' } }, - expires: 86400 - } - ) + return cacheFindMany(`users`, db.user, { + conditions: { where: { roles: 'admin' } }, + expires: 86400, + }) } ``` @@ -1122,15 +1158,15 @@ Scenarios like this are what people are talking about when they say that caching ::: - ### Testing what you cache + We wouldn't just give you all of these caching APIs and not show you how to test it right? You'll find all the details in the [Caching section in the testing doc](testing.md#testing-caching). ### Creating Your Own Client If Memcached or Redis don't serve your needs, you can create your own client adapter. In the Redwood codebase take a look at `packages/api/src/cache/clients` as a reference for writing your own. The interface is extremely simple: -* Extend from the `BaseClient` class. -* A constructor that takes whatever arguments you want, passing them through to the client's initialization code. -* A `get()` function that accepts a `key` argument and returns the data from the cache if found, otherwise `null`. Note that in the Memcached and Redis clients the value returned is first run through `JSON.parse()` but if your cache client supports native JS objects then you wouldn't need to do this. -* A `set()` function that accepts a string `key`, the `value` to be cached, and an optional `options` object containing at least an `expires` key. Note that `value` can be a real JavaScript objects at this point, but in Memcached and Redis the value is run through `JSON.stringify()` before being sent to the client library. You may or may not need to do the same thing, depending on what your cache client supports. +- Extend from the `BaseClient` class. +- A constructor that takes whatever arguments you want, passing them through to the client's initialization code. +- A `get()` function that accepts a `key` argument and returns the data from the cache if found, otherwise `null`. Note that in the Memcached and Redis clients the value returned is first run through `JSON.parse()` but if your cache client supports native JS objects then you wouldn't need to do this. +- A `set()` function that accepts a string `key`, the `value` to be cached, and an optional `options` object containing at least an `expires` key. Note that `value` can be a real JavaScript objects at this point, but in Memcached and Redis the value is run through `JSON.stringify()` before being sent to the client library. You may or may not need to do the same thing, depending on what your cache client supports. diff --git a/docs/docs/storybook.md b/docs/docs/storybook.md index 4a8c4274148b..280fe5382c54 100644 --- a/docs/docs/storybook.md +++ b/docs/docs/storybook.md @@ -28,12 +28,13 @@ yarn rw storybook ``` If this is your first time running Storybook: - - The Redwood CLI will install Storybook, the framework package, and all related dependencies. - - The Redwood CLI will create the following config files for you: - - `web/.storybook/main.ts` - - This is the primary [Storybook configuration file](https://storybook.js.org/docs/configure). Note that it references our framework package, [`storybook-framework-redwoodjs-vite`](https://www.npmjs.com/package/storybook-framework-redwoodjs-vite). - - `web/.storybook/preview-body.html` - - This is required to change the `id` of the root div to `redwood-app`, which is what the entry file used by Vite requires. + +- The Redwood CLI will install Storybook, the framework package, and all related dependencies. +- The Redwood CLI will create the following config files for you: + - `web/.storybook/main.ts` + - This is the primary [Storybook configuration file](https://storybook.js.org/docs/configure). Note that it references our framework package, [`storybook-framework-redwoodjs-vite`](https://www.npmjs.com/package/storybook-framework-redwoodjs-vite). + - `web/.storybook/preview-body.html` + - This is required to change the `id` of the root div to `redwood-app`, which is what the entry file used by Vite requires. Once Storybook is all set up, it'll spin up on localhost port `7910` and open your browser. diff --git a/docs/docs/studio.md b/docs/docs/studio.md index c3d23de026be..0b4d5d39686d 100644 --- a/docs/docs/studio.md +++ b/docs/docs/studio.md @@ -16,37 +16,42 @@ While [logging](https://redwoodjs.com/docs/logger) can show you some of these st We hope Studio helps solve this problem with an observability tool that combines: -* Tracing with OpenTelemetry (service and GraphQL) +- Tracing with OpenTelemetry (service and GraphQL) -* SQL statement logging +- SQL statement logging -* general metrics (how many invocations) +- general metrics (how many invocations) -* GraphiQL playground with impersonated authentication +- GraphiQL playground with impersonated authentication With Studio, it is easier to: -* identify slow running SQL statements without reviewing captured log files +- identify slow running SQL statements without reviewing captured log files -* identify and improve N+1 queries by comparing before and after traces +- identify and improve N+1 queries by comparing before and after traces -* impersonate the user authentication headers in GraphiQL +- impersonate the user authentication headers in GraphiQL Redwood Studio is a command line tool which offers a web UI aimed at providing insights into your application via OpenTelemetry ingestion and other development conveniences like auth-impersonation within GraphiQL. ### Demo +
### Setup + There is no setup needed to begin using the studio; simply execute the following command to start the studio at `localhost:4318`: + ```bash yarn rw studio ``` + The first time you run this command it will likely install the studio package which may take a small amount of time. #### OpenTelemetry + If you want studio to pick up telemetry from you app automatically please ensure you've setup opentelemetry. A guide on this can be found [here](https://community.redwoodjs.com/t/opentelemetry-support-experimental/4772) ### Features @@ -103,20 +108,22 @@ Requires a `SUPABASE_JWT_SECRET` environment variable for JWT signing. All settings for Studio are located in `redwood.toml`, which you can find at the root of your Redwood project. -* `[studio.graphiql.authImpersonation].*` – Used to gain access to GraphQL +- `[studio.graphiql.authImpersonation].*` – Used to gain access to GraphQL endpoints that require authentication. See section above on auth impersonation for more details. -* `[studio].basePort` – Studio's web front-end will run on this port (default: +- `[studio].basePort` – Studio's web front-end will run on this port (default: 4318). It is also used to calculate the port for the mailer integration and other things. Please choose a port that is not already in use, and that has a few more free ports available next to it. -### Database File +### Database File + Studio stores the ingested telemetry to `studio/prisma.db` within the `.redwood` folder. You should not need to touch this file other than if you wish to delete it to erase any existing telemetry data. ## Availability + Along the release of Redwood v7, Studio has been rewritten and is available as a stable version. Just run `yarn rw studio` to start it! Prior to RW v7 Studio was available as an experimental feature. If you're still not using the stable diff --git a/docs/docs/testing.md b/docs/docs/testing.md index 7cbe86c4b07e..2b0302d5bcec 100644 --- a/docs/docs/testing.md +++ b/docs/docs/testing.md @@ -4,7 +4,7 @@ description: A comprehensive reference for testing your app # Testing -Testing. For some it's an essential part of their development workflow. For others it's something they know they *should* do, but for whatever reason it hasn't struck their fancy yet. For others still it's something they ignore completely, hoping the whole concept will go away. But tests are here to stay, and maybe Redwood can change some opinions about testing being awesome and fun. +Testing. For some it's an essential part of their development workflow. For others it's something they know they _should_ do, but for whatever reason it hasn't struck their fancy yet. For others still it's something they ignore completely, hoping the whole concept will go away. But tests are here to stay, and maybe Redwood can change some opinions about testing being awesome and fun. ## Introduction to Testing @@ -12,7 +12,7 @@ If you're already familiar with the ins and outs of testing and just want to kno ## Building a Test Runner -The idea of testing is pretty simple: for each "unit" of code you write, you write additional code that exercises that unit and makes sure it works as expected. What's a "unit" of code? That's for you to decide: it could be an entire class, a single function, or even a single line! In general, the smaller the unit, the better. Your tests will stay fast and focused on just one thing, which makes them easy to update when you refactor. The important thing is that you start *somewhere* and codify your code's functionality in a repeatable, verifiable way. +The idea of testing is pretty simple: for each "unit" of code you write, you write additional code that exercises that unit and makes sure it works as expected. What's a "unit" of code? That's for you to decide: it could be an entire class, a single function, or even a single line! In general, the smaller the unit, the better. Your tests will stay fast and focused on just one thing, which makes them easy to update when you refactor. The important thing is that you start _somewhere_ and codify your code's functionality in a repeatable, verifiable way. Let's say we write a function that adds two numbers together: @@ -36,7 +36,7 @@ if (add(1, 1) === 2) { } ``` -Pretty simple, right? The secret is that this simple check *is the basis of all testing*. Yes, that's it. So no matter how convoluted and theoretical the discussions on testing get, just remember that at the end of the day you're testing whether a condition is true or false. +Pretty simple, right? The secret is that this simple check _is the basis of all testing_. Yes, that's it. So no matter how convoluted and theoretical the discussions on testing get, just remember that at the end of the day you're testing whether a condition is true or false. ### Running a Test @@ -52,23 +52,23 @@ You should see "pass" written to the output. To verify that our test is working Let's get to some terminology: -* The entire code block that checks the functionality of `add()` is what's considered a single **test** -* The specific check that `add(1, 1) === 2` is known as an **assertion** -* The `add()` function itself is the **subject** of the test, or the code that is **under test** -* The value you expect to get (in our example, that's the number `2`) is sometimes called the **expected value** -* The value you actually get (whatever the output of `add(1, 1)` is) is sometimes called the **actual** or **received value** -* The file that contains the test is a **test file** -* Multiple test files, all run together, is known as a **test suite** -* You'll generally run your test files and suites with another piece of software. In Redwood that's Jest, and it's known as a **test runner** -* The amount of code you have that is exercised by tests is referred to as **coverage** and is usually reported as a percentage. If every single line of code is touched as a result of running your test suite then you have 100% coverage! +- The entire code block that checks the functionality of `add()` is what's considered a single **test** +- The specific check that `add(1, 1) === 2` is known as an **assertion** +- The `add()` function itself is the **subject** of the test, or the code that is **under test** +- The value you expect to get (in our example, that's the number `2`) is sometimes called the **expected value** +- The value you actually get (whatever the output of `add(1, 1)` is) is sometimes called the **actual** or **received value** +- The file that contains the test is a **test file** +- Multiple test files, all run together, is known as a **test suite** +- You'll generally run your test files and suites with another piece of software. In Redwood that's Jest, and it's known as a **test runner** +- The amount of code you have that is exercised by tests is referred to as **coverage** and is usually reported as a percentage. If every single line of code is touched as a result of running your test suite then you have 100% coverage! This is the basic idea behind all the tests you'll write: when you add code, you'll add another piece of code that uses the first and verifies that the result is what you expect. -Tests can also help drive new development. For example, what happens to our `add()` function if you leave out one of the arguments? We can drive these changes by writing a test of what we *want* to happen, and then modify the code that's being tested (the subject) to make it satisfy the assertion(s). +Tests can also help drive new development. For example, what happens to our `add()` function if you leave out one of the arguments? We can drive these changes by writing a test of what we _want_ to happen, and then modify the code that's being tested (the subject) to make it satisfy the assertion(s). ### Expecting Errors -So, what does happen if we leave off an argument when calling `add()`? Well, what do we *want* to happen? We'll answer that question by writing a test for what we expect. For this example let's have it throw an error. We'll write the test first that expects the error: +So, what does happen if we leave off an argument when calling `add()`? Well, what do we _want_ to happen? We'll answer that question by writing a test for what we expect. For this example let's have it throw an error. We'll write the test first that expects the error: ```jsx try { @@ -82,17 +82,17 @@ try { } ``` -This is interesting because we actually *expect* an error to be thrown, but we don't want that error to stop the test suite in it's tracks—we want the error to be raised, we just want to make sure it's exactly what we expect it to be! So we'll surround the code that's going to error in a try/catch block and inspect the error message. If it's what we want, then the test actually passes. +This is interesting because we actually _expect_ an error to be thrown, but we don't want that error to stop the test suite in it's tracks—we want the error to be raised, we just want to make sure it's exactly what we expect it to be! So we'll surround the code that's going to error in a try/catch block and inspect the error message. If it's what we want, then the test actually passes. -> Remember: we're testing for what we *want* to happen. Usually you think of errors as being "bad" but in this case we *want* the code to throw an error, so if it does, that's actually good! Raising an error passes the test, not raising the error (or raising the wrong error) is a failure. +> Remember: we're testing for what we _want_ to happen. Usually you think of errors as being "bad" but in this case we _want_ the code to throw an error, so if it does, that's actually good! Raising an error passes the test, not raising the error (or raising the wrong error) is a failure. Run this test and what happens? (If you previously made a change to `add()` to see the test fail, change it back now): -Where did *that* come from? Well, our subject `add()` didn't raise any errors (Javascript doesn't care about the number of arguments passed to a function) and so it tried to add `1` to `undefined`, and that's Not A Number. We didn't think about that! Testing is already helping us catch edge cases. +Where did _that_ come from? Well, our subject `add()` didn't raise any errors (Javascript doesn't care about the number of arguments passed to a function) and so it tried to add `1` to `undefined`, and that's Not A Number. We didn't think about that! Testing is already helping us catch edge cases. -To respond properly to this case we'll make one slight modification: add another "fail" log message if the code somehow gets past the call to `add(1)` *without* throwing an error: +To respond properly to this case we'll make one slight modification: add another "fail" log message if the code somehow gets past the call to `add(1)` _without_ throwing an error: ```jsx {3,8} try { @@ -158,9 +158,9 @@ Are you convinced? Let's keep going and see what Redwood brings to the table. Redwood relies on several packages to do the heavy lifting, but many are wrapped in Redwood's own functionality which makes them even better suited to their individual jobs: -* [Jest](https://jestjs.io/) -* [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) -* [Mock Service Worker](https://mswjs.io/) or **msw** for short. +- [Jest](https://jestjs.io/) +- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) +- [Mock Service Worker](https://mswjs.io/) or **msw** for short. Redwood Generators get your test suite bootstrapped. Redwood also includes [Storybook](https://storybook.js.org/), which isn't technically a test suite, but can help in other ways. @@ -182,7 +182,7 @@ Among other things, Mock Service Worker (msw) lets you simulate the response fro Storybook itself doesn't appear to be related to testing at all—it's for building and styling components in isolation from your main application—but it can serve as a sanity check for an overlooked part of testing: the user interface. Your tests will only be as good as you write them, and testing things like the alignment of text on the page, the inclusion of images, or animation can be very difficult without investing huge amounts of time and effort. These tests are also very brittle since, depending on how they're written, they can break without any code changes at all! Imagine an integration with a CMS that allows a marketing person to make text/style changes. These changes will probably not be covered by your test suite, but could make your site unusable depending on how bad they are. -Storybook can provide a quick way to inspect all visual aspects of your site without the tried-and-true method of having a QA person log in and exercise every possible function. Unfortunately, checking those UI elements is not something that Storybook can automate for you, and so can't be part of a continuous integration system. But it makes it *possible* to do so, even if it currently requires a human touch. +Storybook can provide a quick way to inspect all visual aspects of your site without the tried-and-true method of having a QA person log in and exercise every possible function. Unfortunately, checking those UI elements is not something that Storybook can automate for you, and so can't be part of a continuous integration system. But it makes it _possible_ to do so, even if it currently requires a human touch. ### Redwood Generators @@ -206,7 +206,6 @@ yarn rw test --no-watch This one is handy before committing some changes to be sure you didn't inadvertently break something you didn't expect, or before a deploy to production. - ### Filtering what tests to run You can run only the web- or api-side test suites by including the side as another argument to the command: @@ -227,6 +226,7 @@ If you need to be more specific, you can combine side filters, with other filter ```bash yarn rw test api Comment ``` + which will only run test specs matching "Comment" in the API side ## Testing Components @@ -273,6 +273,7 @@ render(
, { ) }) ``` + ::: ### Mocking useLocation @@ -307,11 +308,11 @@ The `allParams` argument accepts an object that will provide parameters as you e ### Queries -In most cases you will want to exclude the design elements and structure of your components from your test. Then you're free to redesign the component all you want without also having to make the same changes to your test suite. Let's look at some of the functions that React Testing Library provides (they call them "[queries](https://testing-library.com/docs/queries/about/)") that let you check for *parts* of the rendered component, rather than a full string match. +In most cases you will want to exclude the design elements and structure of your components from your test. Then you're free to redesign the component all you want without also having to make the same changes to your test suite. Let's look at some of the functions that React Testing Library provides (they call them "[queries](https://testing-library.com/docs/queries/about/)") that let you check for _parts_ of the rendered component, rather than a full string match. #### getByText() -In our **<Article>** component it seems like we really just want to test that the title of the product is rendered. *How* and *what it looks like* aren't really a concern for this test. Let's update the test to just check for the presence of the title itself: +In our **<Article>** component it seems like we really just want to test that the title of the product is rendered. _How_ and _what it looks like_ aren't really a concern for this test. Let's update the test to just check for the presence of the title itself: ```jsx {3,7-9} title="web/src/components/Article/Article.test.js" import { render, screen } from '@redwoodjs/testing/web' @@ -333,7 +334,7 @@ So, the above test in plain English says "if there is any DOM node containing th #### queryByText() -Why not use `getByText()` for everything? Because it will raise an error if the text is *not* found in the document. That means if you want to explicitly test that some text is *not* present, you can't—you'll always get an error. +Why not use `getByText()` for everything? Because it will raise an error if the text is _not_ found in the document. That means if you want to explicitly test that some text is _not_ present, you can't—you'll always get an error. Consider an update to our **<Article>** component: @@ -355,7 +356,7 @@ const Article = ({ article, summary }) => { export default Article ``` -If we're only displaying the summary of an article then we'll only show the first 100 characters with an ellipsis on the end ("...") and include a link to "Read more" to see the full article. A reasonable test for this component would be that when the `summary` prop is `true` then the "Read more" text should be present. If `summary` is `false` then it should *not* be present. That's where `queryByText()` comes in (relevant test lines are highlighted): +If we're only displaying the summary of an article then we'll only show the first 100 characters with an ellipsis on the end ("...") and include a link to "Read more" to see the full article. A reasonable test for this component would be that when the `summary` prop is `true` then the "Read more" text should be present. If `summary` is `false` then it should _not_ be present. That's where `queryByText()` comes in (relevant test lines are highlighted): ```jsx {22} title="web/src/components/Article/Article.test.js" import { render, screen } from '@redwoodjs/testing/web' @@ -388,7 +389,7 @@ describe('Article', () => { `getByRole()` allows you to look up elements by their "role", which is an ARIA element that assists in accessibility features. Many HTML elements have a [default role](https://www.w3.org/TR/html-aria/#docconformance) (including `
)} @@ -529,7 +521,7 @@ What happened here? Notice towards the end of the error message: `Field "postId" We manually mocked the GraphQL response in the story, and our mock always returns a correct response, regardless of the input! -There's always a tradeoff when creating mock data—it greatly simplifies testing by not having to rely on the entire GraphQL stack, but that means if you want it to be as accurate as the real thing you basically need to *re-write the real thing in your mock*. In this case, leaving out the `postId` was a one-time fix so it's probably not worth going through the work of creating a story/mock/test that simulates what would happen if we left it off. +There's always a tradeoff when creating mock data—it greatly simplifies testing by not having to rely on the entire GraphQL stack, but that means if you want it to be as accurate as the real thing you basically need to _re-write the real thing in your mock_. In this case, leaving out the `postId` was a one-time fix so it's probably not worth going through the work of creating a story/mock/test that simulates what would happen if we left it off. But, if `CommentForm` ended up being a component that was re-used throughout your application, or the code itself will go through a lot of churn because other developers will constantly be making changes to it, it might be worth investing the time to make sure the interface (the props passed to it and the expected return) are exactly what you want them to be. @@ -1126,7 +1118,7 @@ So it looks like we're just about done here! Try going back to the homepage and All posts have the same comments! **WHAT HAVE WE DONE??** -Remember our foreshadowing callout a few pages back, wondering if our `comments()` service which only returns *all* comments could come back to bite us? It finally has: when we get the comments for a post we're not actually getting them for only that post. We're ignoring the `postId` completely and just returning *all* comments in the database! Turns out the old axiom is true: computers only do exactly what you tell them to do. +Remember our foreshadowing callout a few pages back, wondering if our `comments()` service which only returns _all_ comments could come back to bite us? It finally has: when we get the comments for a post we're not actually getting them for only that post. We're ignoring the `postId` completely and just returning _all_ comments in the database! Turns out the old axiom is true: computers only do exactly what you tell them to do. Let's fix it! @@ -1304,7 +1296,7 @@ scenario('returns all comments', async (scenario: StandardScenario) => { -When the test suite runs everything will still pass. JavaScript won't care if you're passing an argument all of a sudden (although if you were using Typescript you will actually get an error at this point!). In TDD you generally want to get your test to fail before adding code to the thing you're testing which will then cause the test to pass. What's something in this test that will be different once we're only returning *some* comments? How about the number of comments expected to be returned? +When the test suite runs everything will still pass. JavaScript won't care if you're passing an argument all of a sudden (although if you were using Typescript you will actually get an error at this point!). In TDD you generally want to get your test to fail before adding code to the thing you're testing which will then cause the test to pass. What's something in this test that will be different once we're only returning _some_ comments? How about the number of comments expected to be returned? Let's take a look at the scenario we're using (remember, it's `standard()` by default): @@ -1434,7 +1426,7 @@ describe('comments', () => { -So we're first getting the result from the services, all the comments for a given `postId`. Then we pull the *actual* post from the database and include its comments. Then we expect that the number of comments returned from the service is the same as the number of comments actually attached to the post in the database. Now the test fails and you can see why in the output: +So we're first getting the result from the services, all the comments for a given `postId`. Then we pull the _actual_ post from the database and include its comments. Then we expect that the number of comments returned from the service is the same as the number of comments actually attached to the post in the database. Now the test fails and you can see why in the output: ```bash FAIL api api/src/services/comments/comments.test.js diff --git a/docs/docs/tutorial/chapter6/comments-schema.md b/docs/docs/tutorial/chapter6/comments-schema.md index 243488167736..3a6dac8139fe 100644 --- a/docs/docs/tutorial/chapter6/comments-schema.md +++ b/docs/docs/tutorial/chapter6/comments-schema.md @@ -66,8 +66,8 @@ model Comment { Most of these lines look very similar to what we've already seen, but this is the first instance of a [relation](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-schema/relations) between two models. `Comment` gets two entries to denote this relationship: -* `post` which has a type of `Post` and a special `@relation` keyword that tells Prisma how to connect a `Comment` to a `Post`. In this case the field `postId` references the field `id` in `Post` -* `postId` is just a regular `Int` column which contains the `id` of the `Post` that this comment is referencing +- `post` which has a type of `Post` and a special `@relation` keyword that tells Prisma how to connect a `Comment` to a `Post`. In this case the field `postId` references the field `id` in `Post` +- `postId` is just a regular `Int` column which contains the `id` of the `Post` that this comment is referencing This gives us a classic database model: @@ -86,13 +86,13 @@ This gives us a classic database model: Note that there is no real database column named `post` in `Comment`—this is special syntax for Prisma to know how to connect the models together and for you to reference that connection. When you query for a `Comment` using Prisma you can get access to the attached `Post` using that name: ```javascript -db.comment.findUnique({ where: { id: 1 }}).post() +db.comment.findUnique({ where: { id: 1 } }).post() ``` Prisma also added a convenience `comments` field to `Post` which gives us the same capability in reverse: ```javascript -db.post.findUnique({ where: { id: 1 }}).comments() +db.post.findUnique({ where: { id: 1 } }).comments() ``` ### Running the Migration @@ -107,7 +107,7 @@ When prompted, give this one a name something like "create comment". :::tip -You'll need to restart the test suite runner at this point if it's still running. You can do a Ctrl-C or just press `q`. Redwood creates a second, test database for you to run your tests against (it is at `.redwood/test.db` by default). The database migrations are run against that test database whenever the test suite is *started*, not while it's running, so you'll need to restart it to test against the new database structure. +You'll need to restart the test suite runner at this point if it's still running. You can do a Ctrl-C or just press `q`. Redwood creates a second, test database for you to run your tests against (it is at `.redwood/test.db` by default). The database migrations are run against that test database whenever the test suite is _started_, not while it's running, so you'll need to restart it to test against the new database structure. ::: @@ -330,7 +330,7 @@ query CommentsQuery { :::info -Have you noticed that something may be amiss? The `comments()` function returns *all* comments, and all comments only. Could this come back to bite us? +Have you noticed that something may be amiss? The `comments()` function returns _all_ comments, and all comments only. Could this come back to bite us? Hmmm... @@ -557,7 +557,7 @@ What is this `scenario()` function? That's made available by Redwood that mostly Yes, all things being equal it would be great to not have these tests depend on a piece of software outside of our control. -However, the difference here is that in a service almost all of the logic you write will depend on moving data in and out of a database and it's much simpler to just let that code run and *really* access the database, rather than trying to mock and intercept each and every possible call that Prisma could make. +However, the difference here is that in a service almost all of the logic you write will depend on moving data in and out of a database and it's much simpler to just let that code run and _really_ access the database, rather than trying to mock and intercept each and every possible call that Prisma could make. Not to mention that Prisma itself is currently under development and implementations could change at any time. Trying to keep pace with those changes and constantly keep mocks in sync would be a nightmare! @@ -630,11 +630,11 @@ The exported scenario here is named "standard." Remember when we worked on compo The nested structure of a scenario is defined like this: -* **comment**: the name of the model this data is for - * **one, two**: a friendly name given to the scenario data which you can reference in your tests - * **data**: contains the actual data that will be put in the database - * **name, body, post**: fields that correspond to the schema. In this case a **Comment** requires that it be related to a **Post**, so the scenario has a `post` key and values as well (using Prisma's [nested create syntax](https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#nested-writes)) - * **select, include**: optionally, to customize the object to `select` or `include` related fields [using Prisma's syntax](https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#create-a-related-record) +- **comment**: the name of the model this data is for + - **one, two**: a friendly name given to the scenario data which you can reference in your tests + - **data**: contains the actual data that will be put in the database + - **name, body, post**: fields that correspond to the schema. In this case a **Comment** requires that it be related to a **Post**, so the scenario has a `post` key and values as well (using Prisma's [nested create syntax](https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#nested-writes)) + - **select, include**: optionally, to customize the object to `select` or `include` related fields [using Prisma's syntax](https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#create-a-related-record) When you receive the `scenario` argument in your test, the `data` key gets unwrapped so that you can reference fields like `scenario.comment.one.name`. @@ -660,10 +660,10 @@ export const standard = defineScenario({ post: { create: { title: 'Redwood Leaves', - body: 'The quick brown fox jumped over the lazy dog.' - } - } - } + body: 'The quick brown fox jumped over the lazy dog.', + }, + }, + }, }, john: { data: { @@ -672,13 +672,13 @@ export const standard = defineScenario({ post: { create: { title: 'Root Systems', - body: 'The five boxing wizards jump quickly.' - } - } - } - } + body: 'The five boxing wizards jump quickly.', + }, + }, + }, + }, // highlight-end - } + }, }) ``` @@ -698,10 +698,10 @@ export const standard = defineScenario({ post: { create: { title: 'Redwood Leaves', - body: 'The quick brown fox jumped over the lazy dog.' - } - } - } + body: 'The quick brown fox jumped over the lazy dog.', + }, + }, + }, }, john: { data: { @@ -711,12 +711,12 @@ export const standard = defineScenario({ create: { title: 'Root Systems', body: 'The five boxing wizards jump quickly.', - } - } - } - } + }, + }, + }, + }, // highlight-end - } + }, }) ``` @@ -746,9 +746,9 @@ export const postOnly = defineScenario({ data: { title: 'Bark', body: "A tree's bark is worse than its bite", - } - } - } + }, + }, + }, }) // highlight-end ``` @@ -770,9 +770,9 @@ export const postOnly = defineScenario({ data: { title: 'Bark', body: "A tree's bark is worse than its bite", - } - } - } + }, + }, + }, }) // highlight-end @@ -893,12 +893,13 @@ interface CreateCommentArgs { input: Prisma.CommentCreateInput | Prisma.CommentUncheckedCreateInput } ``` + in case we wanted to allow both ways – which Prisma generally allows, however [it doesn't allow to pick and mix](https://stackoverflow.com/a/69169106/1246547) within the same input. ::: -We'll test that all the fields we give to the `createComment()` function are actually created in the database, and for good measure just make sure that `createdAt` is set to a non-null value. We could test that the actual timestamp is correct, but that involves freezing the JavaScript Date object so that no matter how long the test takes, you can still compare the value to `new Date` which is right *now*, down to the millisecond. While possible, it's beyond the scope of our easy, breezy tutorial since it gets [very gnarly](https://codewithhugo.com/mocking-the-current-date-in-jest-tests/)! +We'll test that all the fields we give to the `createComment()` function are actually created in the database, and for good measure just make sure that `createdAt` is set to a non-null value. We could test that the actual timestamp is correct, but that involves freezing the JavaScript Date object so that no matter how long the test takes, you can still compare the value to `new Date` which is right _now_, down to the millisecond. While possible, it's beyond the scope of our easy, breezy tutorial since it gets [very gnarly](https://codewithhugo.com/mocking-the-current-date-in-jest-tests/)! :::info What's up with the names for scenario data? `posts.bark`? Really? @@ -924,9 +925,9 @@ Maybe a [mnemonic](https://www.mnemonicgenerator.com/?words=M%20W%20S%20A) would **M**ocks : **W**eb :: **S**cenarios : **A**PI: -* Mysterious Weasels Scratched Armor -* Minesweepers Wrecked Subliminal Attorneys -* Martian Warriors Squeezed Apricots +- Mysterious Weasels Scratched Armor +- Minesweepers Wrecked Subliminal Attorneys +- Martian Warriors Squeezed Apricots Maybe not... diff --git a/docs/docs/tutorial/chapter6/multiple-comments.md b/docs/docs/tutorial/chapter6/multiple-comments.md index 0ac48bf9578f..84f7b87e7376 100644 --- a/docs/docs/tutorial/chapter6/multiple-comments.md +++ b/docs/docs/tutorial/chapter6/multiple-comments.md @@ -2,11 +2,11 @@ Our amazing blog posts will obviously garner a huge and passionate fanbase and we will very rarely have only a single comment. Let's work on displaying a list of comments. -Let's think about where our comments are being displayed. Probably not on the homepage, since that only shows a summary of each post. A user would need to go to the full page to show the comments for that blog post. But that page is only fetching the data for the single blog post itself, nothing else. We'll need to get the comments and since we'll be fetching *and* displaying them, that sounds like a job for a Cell. +Let's think about where our comments are being displayed. Probably not on the homepage, since that only shows a summary of each post. A user would need to go to the full page to show the comments for that blog post. But that page is only fetching the data for the single blog post itself, nothing else. We'll need to get the comments and since we'll be fetching _and_ displaying them, that sounds like a job for a Cell. :::info Couldn't the query for the blog post page also fetch the comments? -Yes, it could! But the idea behind Cells is to make components even more [composable](https://en.wikipedia.org/wiki/Composability) by having them be responsible for their own data fetching *and* display. If we rely on a blog post to fetch the comments then the new Comments component we're about to create now requires something *else* to fetch the comments and pass them in. If we re-use the Comments component somewhere, now we're fetching comments in two different places. +Yes, it could! But the idea behind Cells is to make components even more [composable](https://en.wikipedia.org/wiki/Composability) by having them be responsible for their own data fetching _and_ display. If we rely on a blog post to fetch the comments then the new Comments component we're about to create now requires something _else_ to fetch the comments and pass them in. If we re-use the Comments component somewhere, now we're fetching comments in two different places. **But what about the Comment component we just made, why doesn't that fetch its own data?** @@ -14,7 +14,7 @@ There aren't any instances I (the author) could think of where we would ever wan **Then why make a standalone Comment component at all? Why not just do all the display in the CommentsCell?** -We're trying to start in small chunks to make the tutorial more digestible for a new audience so we're starting simple and getting more complex as we go. But it also just feels *nice* to build up a UI from these smaller chunks that are easier to reason about and keep separate in your head. +We're trying to start in small chunks to make the tutorial more digestible for a new audience so we're starting simple and getting more complex as we go. But it also just feels _nice_ to build up a UI from these smaller chunks that are easier to reason about and keep separate in your head. **But what about—** @@ -112,13 +112,13 @@ export const Failure = ({ error }: CellFailureProps) => ( export const Success = ({ comments }: CellSuccessProps) => { return ( - // highlight-start + // highlight-start <> {comments.map((comment) => ( ))} - // highlight-end + // highlight-end ) } ``` @@ -221,7 +221,7 @@ export const Success = ({ comments }) => { {comments.map((comment) => ( ))} - // highlight-next-line + // highlight-next-line
) } @@ -232,7 +232,7 @@ export const Success = ({ comments }) => { :::tip -`space-y-8` is a handy Tailwind class that puts a space *between* elements, but not above or below the entire stack (which is what would happen if you gave each `` its own top/bottom margin). +`space-y-8` is a handy Tailwind class that puts a space _between_ elements, but not above or below the entire stack (which is what would happen if you gave each `` its own top/bottom margin). ::: @@ -312,7 +312,7 @@ export default Article -If we are *not* showing the summary, then we'll show the comments. Take a look at the **Full** and **Summary** stories in Storybook and you should see comments on one and not on the other. +If we are _not_ showing the summary, then we'll show the comments. Take a look at the **Full** and **Summary** stories in Storybook and you should see comments on one and not on the other. :::info Shouldn't the `CommentsCell` cause an actual GraphQL request? How does this work? @@ -399,10 +399,10 @@ We added a component, `CommentsCell`, and edited another, `Article`, so what do The actual `Comment` component does most of the work so there's no need to test all of that functionality again in `CommentsCell`: our `Comment` tests cover that just fine. What things does `CommentsCell` do that make it unique? -* Has a loading message -* Has an error message -* Has a failure message -* When it renders successfully, it outputs as many comments as were returned by the `QUERY` (*what* is rendered we'll leave to the `Comment` tests) +- Has a loading message +- Has an error message +- Has a failure message +- When it renders successfully, it outputs as many comments as were returned by the `QUERY` (_what_ is rendered we'll leave to the `Comment` tests) The default `CommentsCell.test.{jsx,tsx}` actually tests every state for us, albeit at an absolute minimum level—it makes sure no errors are thrown: @@ -568,17 +568,16 @@ describe('CommentsCell', () => { // highlight-end }) }) - ``` -We're looping through each `comment` from the mock, the same mock used by Storybook, so that even if we add more later, we're covered. You may find yourself writing a test and saying "just test that there are two total comments," which will work today, but months from now when you add more comments to the mock to try some different iterations in Storybook, that test will start failing. Avoid hardcoding data like this, especially [magic numbers](https://en.wikipedia.org/wiki/Magic_number_(programming)), into your test when you can derive it from your mocked data! +We're looping through each `comment` from the mock, the same mock used by Storybook, so that even if we add more later, we're covered. You may find yourself writing a test and saying "just test that there are two total comments," which will work today, but months from now when you add more comments to the mock to try some different iterations in Storybook, that test will start failing. Avoid hardcoding data like this, especially [magic numbers](), into your test when you can derive it from your mocked data! #### Testing Article -The functionality we added to `Article` says to show the comments for the post if we are *not* showing the summary. We've got a test for both the "full" and "summary" renders already. Generally you want a test to be testing "one thing," like whether the body of the article is present, and another test for whether the comments are displaying. If you find that you're using "and" in your test description (like "renders a blog post and its comments") that's a good sign that it should probably be split into two separate tests. +The functionality we added to `Article` says to show the comments for the post if we are _not_ showing the summary. We've got a test for both the "full" and "summary" renders already. Generally you want a test to be testing "one thing," like whether the body of the article is present, and another test for whether the comments are displaying. If you find that you're using "and" in your test description (like "renders a blog post and its comments") that's a good sign that it should probably be split into two separate tests. Let's add two additional tests for our new functionality: @@ -715,7 +714,7 @@ We're introducing a new test function here, `waitFor()`, which will wait for thi :::info -The summary version of `Article` does *not* render the `CommentsCell`, but we should still wait. Why? If we did mistakenly start including `CommentsCell`, but didn't wait for the render, we would get a falsely passing test—indeed the text isn't on the page but that's because it's still showing the `Loading` component! If we had waited we would have seen the actual comment body get rendered, and the test would (correctly) fail. +The summary version of `Article` does _not_ render the `CommentsCell`, but we should still wait. Why? If we did mistakenly start including `CommentsCell`, but didn't wait for the render, we would get a falsely passing test—indeed the text isn't on the page but that's because it's still showing the `Loading` component! If we had waited we would have seen the actual comment body get rendered, and the test would (correctly) fail. ::: diff --git a/docs/docs/tutorial/chapter6/the-redwood-way.md b/docs/docs/tutorial/chapter6/the-redwood-way.md index 316154c266d1..d0ec7c88f7f9 100644 --- a/docs/docs/tutorial/chapter6/the-redwood-way.md +++ b/docs/docs/tutorial/chapter6/the-redwood-way.md @@ -9,7 +9,7 @@ There are two main features we need to build: 1. Comment form and creation 2. Comment retrieval and display -Which order we build them in is up to us. To ease into things, let's start with the fetching and displaying comments first and then we'll move on to more complex work of adding a form and service to create a new comment. Of course, this is Redwood, so even forms and services aren't *that* complex! +Which order we build them in is up to us. To ease into things, let's start with the fetching and displaying comments first and then we'll move on to more complex work of adding a form and service to create a new comment. Of course, this is Redwood, so even forms and services aren't _that_ complex! ### Storybook @@ -124,7 +124,7 @@ export const generated = () => { comment={{ name: 'Rob Cameron', body: 'This is the first comment!', - createdAt: '2020-01-01T12:34:56Z' + createdAt: '2020-01-01T12:34:56Z', }} /> ) diff --git a/docs/docs/tutorial/chapter7/api-side-currentuser.md b/docs/docs/tutorial/chapter7/api-side-currentuser.md index bce5ffaa2efd..f781421ec8ff 100644 --- a/docs/docs/tutorial/chapter7/api-side-currentuser.md +++ b/docs/docs/tutorial/chapter7/api-side-currentuser.md @@ -144,7 +144,7 @@ Now run `yarn rw prisma migrate reset` and and...you'll get a different error. B ::: -We've got an error here because running a database `reset` doesn't also apply pending migrations. So we're trying to set a `userId` where one doesn't exist in the database (it does exist in Prisma generated client libs though, so it thinks that there *should* be one, even if it doesn't exist in the database yet). +We've got an error here because running a database `reset` doesn't also apply pending migrations. So we're trying to set a `userId` where one doesn't exist in the database (it does exist in Prisma generated client libs though, so it thinks that there _should_ be one, even if it doesn't exist in the database yet). It may feel like we're stuck, but note that the database did reset successfully, it's just the seed that failed. So now let's migrate the database to add the new `userId` to `Post`, and then re-run the seed to populate the database, naming it something like "add userId to post": @@ -200,7 +200,7 @@ To enable this we'll need to make two modifications on the api side: :::info What about the mutations? -We did *not* add `user` or `userId` to the `CreatePostInput` or `UpdatePostInput` types. Although we want to set a user on each newly created post, we don't want just anyone to do that via a GraphQL call! You could easily create or edit a post and assign it to someone else by just modifying the GraphQL payload. We'll save assigning the user to just the service, so it can't be manipulated by the outside world. +We did _not_ add `user` or `userId` to the `CreatePostInput` or `UpdatePostInput` types. Although we want to set a user on each newly created post, we don't want just anyone to do that via a GraphQL call! You could easily create or edit a post and assign it to someone else by just modifying the GraphQL payload. We'll save assigning the user to just the service, so it can't be manipulated by the outside world. ::: @@ -270,8 +270,7 @@ We could also write this resolver as follows: ```javascript export const Post = { - user: (_obj, { root }) => - db.user.findFirst({ where: { id: root.userId } }), + user: (_obj, { root }) => db.user.findFirst({ where: { id: root.userId } }), } ``` @@ -279,7 +278,7 @@ Note that if you keep the relation resolver above, but also included a `user` pr :::info Prisma and the N+1 Problem -If you have any experience with database design and retrieval you may have noticed this method presents a less than ideal solution: for every post that's found, you need to perform an *additional* query just to get the user data associated with that `post`, also known as the [N+1 problem](https://medium.com/the-marcy-lab-school/what-is-the-n-1-problem-in-graphql-dd4921cb3c1a). This is just due to the nature of GraphQL queries: each resolver function really only knows about its own parent object, nothing about potential children. +If you have any experience with database design and retrieval you may have noticed this method presents a less than ideal solution: for every post that's found, you need to perform an _additional_ query just to get the user data associated with that `post`, also known as the [N+1 problem](https://medium.com/the-marcy-lab-school/what-is-the-n-1-problem-in-graphql-dd4921cb3c1a). This is just due to the nature of GraphQL queries: each resolver function really only knows about its own parent object, nothing about potential children. There have been several attempts to work around this issue. A simple one that includes no extra dependencies is to remove this field resolver and simply include `user` data along with any `post` you retrieve from the database: @@ -288,8 +287,8 @@ export const post = ({ id }) => { return db.post.findUnique({ where: { id }, include: { - user: true - } + user: true, + }, }) } ``` @@ -395,13 +394,13 @@ Depending on whether you started from the Redwood Tutorial repo or not, you may ## Accessing `currentUser` on the API side -There's a magical variable named `context` that's available within any of your service functions. It contains the context in which the service function is being called. One property available on this context is the user that's logged in (*if* someone is logged in). It's the same `currentUser` that is available on the web side: +There's a magical variable named `context` that's available within any of your service functions. It contains the context in which the service function is being called. One property available on this context is the user that's logged in (_if_ someone is logged in). It's the same `currentUser` that is available on the web side: ```javascript title="api/src/service/posts/posts.js" export const createPost = ({ input }) => { return db.post.create({ // highlight-next-line - data: { ...input, userId: context.currentUser.id } + data: { ...input, userId: context.currentUser.id }, }) } ``` @@ -465,7 +464,7 @@ export const Post = { :::info Prisma's `findUnique()` vs. `findFirst()` -Note that we switched from `findUnique()` to `findFirst()` here. Prisma's `findUnique()` requires that any attributes in the `where` clause have unique indexes, which `id` does, but `userId` does not. So we need to switch to the `findFirst()` function which allows you to put whatever you want in the `where`, which may return more than one record, but Prisma will only return the first of that set. In this case we know there'll always only be one, because we're selecting by `id` *in addition* to `userId`. +Note that we switched from `findUnique()` to `findFirst()` here. Prisma's `findUnique()` requires that any attributes in the `where` clause have unique indexes, which `id` does, but `userId` does not. So we need to switch to the `findFirst()` function which allows you to put whatever you want in the `where`, which may return more than one record, but Prisma will only return the first of that set. In this case we know there'll always only be one, because we're selecting by `id` _in addition_ to `userId`. ::: @@ -473,7 +472,7 @@ These changes make sure that a user can only see a list of their own posts, or t What about `updatePost` and `deletePost`? They aren't limited to just the `currentUser`, which would let anyone update or delete a post if they made a manual GraphQL call! That's not good. We'll deal with those [a little later](#update-and-delete). -But there's a problem with the updates we just made: doesn't the homepage also use the `posts` service to display all the articles for the homepage? This code update would limit the homepage to only showing a logged in user's own posts and no one else! And what happens if someone who is *not* logged in goes to the homepage? ERROR. +But there's a problem with the updates we just made: doesn't the homepage also use the `posts` service to display all the articles for the homepage? This code update would limit the homepage to only showing a logged in user's own posts and no one else! And what happens if someone who is _not_ logged in goes to the homepage? ERROR. How can we return one list of posts in the admin, and a different list of posts for the homepage? @@ -481,7 +480,7 @@ How can we return one list of posts in the admin, and a different list of posts We could go down the road of adding variables in the GraphQL queries, along with checks in the existing `posts` service, that return a different list of posts whether you're on the homepage or in the admin. But this complexity adds a lot of surface area to test and some fragility if someone goes in there in the future—they have to be very careful not to add a new condition or negate an existing one and accidentally expose your admin functionality to exploits. -What if we created *new* GraphQL queries for the admin views of posts? They would have automatic security checks thanks to `@requireAdmin`, no custom code required. These new queries will be used in the admin posts pages, and the original, simple `posts` service will be used for the homepage and article detail page. +What if we created _new_ GraphQL queries for the admin views of posts? They would have automatic security checks thanks to `@requireAdmin`, no custom code required. These new queries will be used in the admin posts pages, and the original, simple `posts` service will be used for the homepage and article detail page. There are several steps we'll need to complete: @@ -512,7 +511,8 @@ export const schema = gql` type Mutation { createPost(input: CreatePostInput!): Post! @requireAuth(roles: ["admin"]) - updatePost(id: Int!, input: UpdatePostInput!): Post! @requireAuth(roles: ["admin"]) + updatePost(id: Int!, input: UpdatePostInput!): Post! + @requireAuth(roles: ["admin"]) deletePost(id: Int!): Post! @requireAuth(roles: ["admin"]) } ` @@ -757,25 +757,24 @@ export const deletePost = async ({ id }) => { where: { id }, }) } - ``` ## Wrapping Up Whew! Let's try several different scenarios (this is the kind of thing that the QA team lives for), making sure everything is working as expected: -* A logged out user *should* see all posts on the homepage -* A logged out user *should* be able to see the detail for a single post -* A logged out user *should not* be able to go to /admin/posts -* A logged out user *should not* see moderation controls next to comments -* A logged in admin user *should* see all articles on the homepage (not just their own) -* A logged in admin user *should* be able to go to /admin/posts -* A logged in admin user *should* be able to create a new post -* A logged in admin user *should not* be able to see anyone else's posts in /admin/posts -* A logged in admin user *should not* see moderation controls next to comments (unless you modified that behavior at the end of the last page) -* A logged in moderator user *should* see moderation controls next to comments -* A logged in moderator user *should not* be able to access /admin/posts - -In fact, you could write some new tests to make sure this functionality doesn't mistakenly change in the future. The quickest would probably be to create `adminPosts.scenarios.js` and `adminPosts.test.js` files to go with the new service and verify that you are only returned the posts owned by a given user. You can [mock currentUser](/docs/testing#mockcurrentuser-on-the-api-side) to simulate someone being logged in or not, with different roles. You could add tests for the Cells we modified above, but the data they get is dependent on what's returned from the service, so as long as you have the service itself covered you should be okay. The 100% coverage folks would argue otherwise, but while they're still busy writing tests we're out cruising in our new yacht thanks to all the revenue from our newly launched (with *reasonable* test coverage) features! +- A logged out user _should_ see all posts on the homepage +- A logged out user _should_ be able to see the detail for a single post +- A logged out user _should not_ be able to go to /admin/posts +- A logged out user _should not_ see moderation controls next to comments +- A logged in admin user _should_ see all articles on the homepage (not just their own) +- A logged in admin user _should_ be able to go to /admin/posts +- A logged in admin user _should_ be able to create a new post +- A logged in admin user _should not_ be able to see anyone else's posts in /admin/posts +- A logged in admin user _should not_ see moderation controls next to comments (unless you modified that behavior at the end of the last page) +- A logged in moderator user _should_ see moderation controls next to comments +- A logged in moderator user _should not_ be able to access /admin/posts + +In fact, you could write some new tests to make sure this functionality doesn't mistakenly change in the future. The quickest would probably be to create `adminPosts.scenarios.js` and `adminPosts.test.js` files to go with the new service and verify that you are only returned the posts owned by a given user. You can [mock currentUser](/docs/testing#mockcurrentuser-on-the-api-side) to simulate someone being logged in or not, with different roles. You could add tests for the Cells we modified above, but the data they get is dependent on what's returned from the service, so as long as you have the service itself covered you should be okay. The 100% coverage folks would argue otherwise, but while they're still busy writing tests we're out cruising in our new yacht thanks to all the revenue from our newly launched (with _reasonable_ test coverage) features! Did it work? Great! Did something go wrong? Can someone see too much, or too little? Double check that all of your GraphQL queries are updated and you've saved changes in all the opened files. diff --git a/docs/docs/tutorial/chapter7/rbac.md b/docs/docs/tutorial/chapter7/rbac.md index 26c2d36809c6..43abde2472af 100644 --- a/docs/docs/tutorial/chapter7/rbac.md +++ b/docs/docs/tutorial/chapter7/rbac.md @@ -1,6 +1,6 @@ # Role-Based Access Control (RBAC) -Imagine a few weeks in the future of our blog when every post hits the front page of the New York Times and we're getting hundreds of comments a day. We can't be expected to come up with quality content each day *and* moderate the endless stream of (mostly well-meaning) comments! We're going to need help. Let's hire a comment moderator to remove obvious spam and any comments that don't heap praise on our writing ability. You know, to help make the internet a better place. +Imagine a few weeks in the future of our blog when every post hits the front page of the New York Times and we're getting hundreds of comments a day. We can't be expected to come up with quality content each day _and_ moderate the endless stream of (mostly well-meaning) comments! We're going to need help. Let's hire a comment moderator to remove obvious spam and any comments that don't heap praise on our writing ability. You know, to help make the internet a better place. We already have a login system for our blog, but right now it's all-or-nothing: you either get access to create blog posts, or you don't. In this case our comment moderator(s) will need logins so that we know who they are, but we're not going to let them create new blog posts. We need some kind of role that we can give to our two kinds of users so we can distinguish them from one another. @@ -26,7 +26,6 @@ model User { Next we'll (try) to migrate the database: - ```bash yarn rw prisma migrate dev ``` @@ -117,7 +116,7 @@ export const hasRole = (roles: AllowedRoles): boolean => { return currentUserRoles?.some((allowedRole) => roles === allowedRole) } } - ``` +``` This is because we now know that the type of `currentUser.roles` is a `string` based on the type being returned from Prisma. So you can safely remove the block of code where it's checking if roles is an array: @@ -183,9 +182,19 @@ The easiest way to prevent access to an entire URL is via the Router. The ` - + - + @@ -246,12 +255,12 @@ Let's create a new user that will represent the comment moderator. Since this is :::tip The Plus Trick -The Plus Trick is a very handy feature of the email standard known as a "boxname", the idea being that you may have other incoming boxes besides one just named "Inbox" and by adding `+something` to your email address you can specify which box the mail should be sorted into. They don't appear to be in common use these days, but they are ridiculously helpful for us developers when we're constantly needing new email addresses for testing: it gives us an infinite number of *valid* email addresses—they all come to your regular inbox! +The Plus Trick is a very handy feature of the email standard known as a "boxname", the idea being that you may have other incoming boxes besides one just named "Inbox" and by adding `+something` to your email address you can specify which box the mail should be sorted into. They don't appear to be in common use these days, but they are ridiculously helpful for us developers when we're constantly needing new email addresses for testing: it gives us an infinite number of _valid_ email addresses—they all come to your regular inbox! Just append +something to your email address before the @: -* `jane.doe+testing@example.com` will go to `jane.doe@example.com` -* `dom+20210909@example.com` will go to `dom@example.com` +- `jane.doe+testing@example.com` will go to `jane.doe@example.com` +- `dom+20210909@example.com` will go to `dom@example.com` Note that not all providers support this plus-based syntax, but the major ones (Gmail, Yahoo, Microsoft, Apple) do. If you find that you're not receiving emails at your own domain, you may want to create a free account at one of these providers just to use for testing. @@ -266,13 +275,17 @@ If you disabled the new user signup as suggested at the end of the first part of ```javascript const CryptoJS = require('crypto-js') const salt = CryptoJS.lib.WordArray.random(128 / 8).toString() -const hashedPassword = CryptoJS.PBKDF2('password', salt, { keySize: 256 / 32 }).toString() -db.user.create({ data: { email: 'moderator@moderator.com', hashedPassword, salt } }) +const hashedPassword = CryptoJS.PBKDF2('password', salt, { + keySize: 256 / 32, +}).toString() +db.user.create({ + data: { email: 'moderator@moderator.com', hashedPassword, salt }, +}) ``` ::: -Now if you log out as the admin and log in as the moderator you should *not* have access to the posts admin. +Now if you log out as the admin and log in as the moderator you should _not_ have access to the posts admin. ### Restrict Access in a Component diff --git a/docs/docs/tutorial/intermission.md b/docs/docs/tutorial/intermission.md index 793730157af2..9fe7cdc2b74d 100644 --- a/docs/docs/tutorial/intermission.md +++ b/docs/docs/tutorial/intermission.md @@ -22,7 +22,7 @@ yarn rw setup ui tailwindcss However, none of the screenshots that follow will come anywhere close to what you're seeing in your browser (except for those isolated components you build in Storybook) so you may want to just start with the [example repo](https://github.com/redwoodjs/redwood-tutorial). You'll also be missing out on a good starting test suite that we've added! -If you're *still* set on continuing with your own repo, and you deployed to a service like Netlify, you would have changed the database provider in `schema.prisma` to `postgresql`. If that's the case then make sure your local development environment has changed over as well. Check out the [Local Postgres Setup](../local-postgres-setup.md) for assistance. If you stick with the [example repo](https://github.com/redwoodjs/redwood-tutorial) instead, you can go ahead with good ol' SQLite (what we were using locally to build everything in the first half). +If you're _still_ set on continuing with your own repo, and you deployed to a service like Netlify, you would have changed the database provider in `schema.prisma` to `postgresql`. If that's the case then make sure your local development environment has changed over as well. Check out the [Local Postgres Setup](../local-postgres-setup.md) for assistance. If you stick with the [example repo](https://github.com/redwoodjs/redwood-tutorial) instead, you can go ahead with good ol' SQLite (what we were using locally to build everything in the first half). Once you're ready, start up the dev server: diff --git a/docs/docs/typescript/generated-types.md b/docs/docs/typescript/generated-types.md index 644cc7b39bd4..f49463c5f2bb 100644 --- a/docs/docs/typescript/generated-types.md +++ b/docs/docs/typescript/generated-types.md @@ -38,13 +38,13 @@ For example, if you specify the return type on `getCurrentUser` as... ```ts title="api/src/lib/auth.ts" interface MyCurrentUser { - id: string, - roles: string[], - email: string, + id: string + roles: string[] + email: string projectId: number } -const getCurrentUser = ({decoded}): MyCurrentUser => { +const getCurrentUser = ({ decoded }): MyCurrentUser => { //.. } ``` @@ -77,7 +77,10 @@ Redwood generates types for both the data returned from the query and the query' These generated types will use the query's name—in this case, `FindBlogPostQuery`—so you can import them like this: ```ts title="web/src/components/BlogPostCell.tsx" -import type { FindBlogPostQuery, FindBlogPostQueryVariables } from 'types/graphql' +import type { + FindBlogPostQuery, + FindBlogPostQueryVariables, +} from 'types/graphql' ``` `FindBlogPostQuery` is the type of the data returned from the query (`{ title: string, body: string }`) and `FindBlogPostQueryVariables` is the type of the query's variables (`{ id: number }`). diff --git a/docs/docs/typescript/introduction.md b/docs/docs/typescript/introduction.md index eb881419fac1..7cfe1732f8ae 100644 --- a/docs/docs/typescript/introduction.md +++ b/docs/docs/typescript/introduction.md @@ -115,7 +115,7 @@ Add you custom `@adminUI` alias to your `tsconfig.json` file: You might have noticed the `"../.redwood/types/mirror/web/src/components/modules/admin/common/ui/*"` path. I'm glad you did! -When you build your project redwood will create a set of directories or a virtual directory called`.redwood`, [read more about this typescript feature here](https://www.typescriptlang.org/docs/handbook/module-resolution.html#virtual-directories-with-rootdirs). This directory contains types for te Cells, so there is no need for us to specify an index file. +When you build your project redwood will create a set of directories or a virtual directory called`.redwood`, [read more about this typescript feature here](https://www.typescriptlang.org/docs/handbook/module-resolution.html#virtual-directories-with-rootdirs). This directory contains types for te Cells, so there is no need for us to specify an index file. When you combine those two paths `.src/...` and `./.redwood/...` under an alias you can have shorter and cleaner import paths: @@ -130,5 +130,5 @@ import { CustomModal } from '@adminUI/CustomModal' #### Some benefits of using alias paths are 1. **Improved code readability**, by abstracting complex directory hierarchies, and having meaningful names for your imports. -1. **Code maintainability**, aliases allow you to decouple your code from the file structure and more easily move files around, as they are not tied to the longer path. +1. **Code maintainability**, aliases allow you to decouple your code from the file structure and more easily move files around, as they are not tied to the longer path. 1. **Reduce boilerplate**, no more `../../src/components/modules/admin/common/ui/` 😮‍💨 diff --git a/docs/docs/typescript/strict-mode.md b/docs/docs/typescript/strict-mode.md index 221d7e6fe98b..e83cd4ab3a11 100644 --- a/docs/docs/typescript/strict-mode.md +++ b/docs/docs/typescript/strict-mode.md @@ -18,7 +18,7 @@ Enable strict mode by setting `strict` to true in `web/tsconfig.json` and `api/t "noEmit": true, "allowJs": true, // highlight-next-line - "strict": true, + "strict": true // ... } // ... @@ -49,9 +49,9 @@ For most cases however, you probably want to convert nulls to undefined - one wa ```ts title="api/src/services/users.ts" // highlight-next-line -import { removeNulls } from "@redwoodjs/api" +import { removeNulls } from '@redwoodjs/api' -export const updateUser: MutationResolvers["updateUser"] = ({ id, input }) => { +export const updateUser: MutationResolvers['updateUser'] = ({ id, input }) => { return db.user.update({ // highlight-next-line data: removeNulls(input), @@ -108,7 +108,6 @@ export const Post: PostRelationResolvers = { } ``` - :::tip An optimization tip If the relation truly is required, it may make more sense to include `author` in your `post` Service's Prisma query and modify the `Post.author` resolver accordingly: @@ -167,7 +166,7 @@ If your `getCurrentUser` doesn't return `roles`, and you don't use this function #### B. Roles on current user is a string -Alternatively, if you define the roles as a string, you can remove the code that does checks against Arrays +Alternatively, if you define the roles as a string, you can remove the code that does checks against Arrays ```diff title="api/src/lib/auth.ts" export const hasRole = (roles: AllowedRoles): boolean => { @@ -236,6 +235,7 @@ export const hasRole = (roles: AllowedRoles): boolean => { return false } ``` + ### `getCurrentUser` in `api/src/lib/auth.ts` @@ -250,15 +250,15 @@ import type { AuthContextPayload } from '@redwoodjs/api' // Example 1: typing directly export const getCurrentUser: CurrentUserFunc = async ( - decoded: { id: string, name: string }, - { token, type }: { token: string, type: string }, + decoded: { id: string; name: string }, + { token, type }: { token: string; type: string } ) => { // ... } // Example 2: Using AuthContextPayload export const getCurrentUser: CurrentUserFunc = async ( - decoded: { id: string, name: string }, + decoded: { id: string; name: string }, { token, type }: AuthContextPayload[1], { event, context }: AuthContextPayload[2] ) => { diff --git a/docs/docs/typescript/utility-types.md b/docs/docs/typescript/utility-types.md index a01895f1adfd..a12ccab4a86f 100644 --- a/docs/docs/typescript/utility-types.md +++ b/docs/docs/typescript/utility-types.md @@ -17,14 +17,17 @@ This is used to type the props of your Cell's `Success` component. It takes two arguments as generics: | Generic | Description | -|:-------------|:-----------------------------------------------------------------------------------------| +| :----------- | :--------------------------------------------------------------------------------------- | | `TData` | The type of data you're expecting to receive (usually the type generated from the query) | | `TVariables` | An optional second parameter for the type of the query's variables | Not only does `CellSuccessProps` type the data returned from the query, but it also types the variables and methods returned by Apollo Client's `useQuery` hook! ```ts title="web/src/components/BlogPostCell.tsx" -import type { FindBlogPostQuery, FindBlogPostQueryVariables } from 'types/graphql' +import type { + FindBlogPostQuery, + FindBlogPostQueryVariables, +} from 'types/graphql' // highlight-next-line import type { CellSuccessProps } from '@redwoodjs/web' @@ -32,12 +35,15 @@ import type { CellSuccessProps } from '@redwoodjs/web' // ... // highlight-next-line -type SuccessProps = CellSuccessProps +type SuccessProps = CellSuccessProps< + FindBlogPostQuery, + FindBlogPostQueryVariables +> export const Success = ({ blogPost, // From the query. This is typed of course - queryResult // 👈 From Apollo Client. This is typed too! -// highlight-next-line + queryResult, // 👈 From Apollo Client. This is typed too! + // highlight-next-line }: SuccessProps) => { // ... } @@ -96,7 +102,7 @@ defineScenario ``` | Generic | Description | -|:-------------------|:------------------------------------------------------------------------------------------------------| +| :----------------- | :---------------------------------------------------------------------------------------------------- | | `PrismaCreateType` | (Optional) the type imported from Prisma's create operation that goes into the "data" key | | `TName` | (Optional) the name or names of the models in your scenario | | `TKeys` | (Optional) the key(s) in your scenario. These are really only useful while you write out the scenario | @@ -129,10 +135,10 @@ defineScenario This utility type makes it easy for you to access data created by your scenarios in your tests. It takes three generic parameters: -| Generic | Description | -|:--------|:---------------------------------------------------------------------------------| -| `TData` | The Prisma model that'll be returned | -| `TName` | (Optional) the name of the model. ("post" in the example below) | +| Generic | Description | +| :------ | :------------------------------------------------------------------------------ | +| `TData` | The Prisma model that'll be returned | +| `TName` | (Optional) the name of the model. ("post" in the example below) | | `TKeys` | (optional) the key(s) used to define the scenario. ("one" in the example below) | We know this is a lot of generics, but that's so you get to choose how specific you want to be with the types! @@ -157,7 +163,7 @@ You can of course just define the type in the test file instead of importing it. ## DbAuth -When you setup dbAuth, the generated files in `api/src/lib/auth.ts` and `api/src/functions/auth.ts` have all the types you need. Let's break down some of the utility types. +When you setup dbAuth, the generated files in `api/src/lib/auth.ts` and `api/src/functions/auth.ts` have all the types you need. Let's break down some of the utility types. ### `DbAuthSession` @@ -200,21 +206,19 @@ export const handler = async ( context: Context ) => { // Pass in the generic to the type here 👇 - const forgotPasswordOptions: DbAuthHandlerOptions['forgotPassword'] = { - - // ... - - // Now in the handler function, `user` will be typed - handler: (user) => { - return user - }, + const forgotPasswordOptions: DbAuthHandlerOptions['forgotPassword'] = + { + // ... - // ... + // Now in the handler function, `user` will be typed + handler: (user) => { + return user + }, - } + // ... + } // ... - } ``` @@ -222,8 +226,8 @@ Note that in strict mode, you'll likely see errors where the handlers expect "tr ## Directives - ### `ValidatorDirectiveFunc` + When you generate a [validator directive](directives.md#validators) you will see your `validate` function typed already with `ValidatorDirectiveFunc` ```ts @@ -258,10 +262,11 @@ const validate: RequireAuthValidate = ({ directiveArgs }) => { ``` | Generic | Description | -|:-----------------|:----------------------------------------------------------| +| :--------------- | :-------------------------------------------------------- | | `TDirectiveArgs` | The type of arguments passed to your directive in the SDL | ### `TransformerDirectiveFunc` + When you generate a [transformer directive](directives.md#transformers) you will see your `transform` function typed with `TransformDirectiveFunc`. ```ts @@ -275,12 +280,13 @@ This type takes two generics - the type of the field you are transforming, and t So for example, let's say you have a transformer directive `@maskedEmail(permittedRoles: ['ADMIN'])` that you apply to `String` fields. You would pass in the following types ```ts -type MaskedEmailTransform = TransformerDirectiveFunc +type MaskedEmailTransform = TransformerDirectiveFunc< + string, + { permittedRoles?: string[] } +> ``` | Generic | Description | -|:-----------------|:-------------------------------------------------------------------------------| +| :--------------- | :----------------------------------------------------------------------------- | | `TField` | This will type `resolvedValue` i.e. the type of the field you are transforming | | `TDirectiveArgs` | The type of arguments passed to your directive in the SDL | - - diff --git a/docs/docs/vite-configuration.md b/docs/docs/vite-configuration.md index ce9df4b866f2..d0bd0c125e1b 100644 --- a/docs/docs/vite-configuration.md +++ b/docs/docs/vite-configuration.md @@ -12,27 +12,25 @@ So it's worth repeating that you don't have to do any of this, because we config Regardless, there'll probably come a time when you have to configure Vite. All the Vite configuration for your web side sits in `web/vite.config.{js,ts}`, and can be configured the same as any other Vite project. Let's take a peek! ```js -import dns from 'dns'; -import { defineConfig } from 'vite'; -import redwood from '@redwoodjs/vite'; +import dns from 'dns' +import { defineConfig } from 'vite' +import redwood from '@redwoodjs/vite' -dns.setDefaultResultOrder('verbatim'); +dns.setDefaultResultOrder('verbatim') const viteConfig = { plugins: [ // 👇 this is the RedwoodJS Vite plugin, that houses all the default configuration - redwood() + redwood(), // ... add any custom Vite plugins you would like here ], // You can override built in configuration like server, optimizeDeps, etc. here -}; -export default defineConfig(viteConfig); - +} +export default defineConfig(viteConfig) ``` Checkout Vite's docs on [configuration](https://vitejs.dev/config/) - ### Sass and Tailwind CSS Redwood is already configured to use Sass, if the packages are there: diff --git a/docs/docs/webhooks.md b/docs/docs/webhooks.md index a185c7ebc4fa..c0c256a4b257 100644 --- a/docs/docs/webhooks.md +++ b/docs/docs/webhooks.md @@ -215,6 +215,7 @@ This is a variation on the SHA256 HMAC verification that works with binary buffe Svix (and by extension, Clerk) gives you a secret token that it uses to create a hash signature with each payload. This hash signature is included with the headers of each request as `svix-signature`. > Some production environments, like Vercel, might base64 encode the request body string. In that case, the body must be conditionally parsed. +> > ```js > export const handler = async (event: APIGatewayEvent) => { > const body = event.isBase64Encoded @@ -658,7 +659,9 @@ export const handler = async (event) => { }), } } else { - webhookLogger.warn(`Unsupported Orbit Event Type: ${orbitInfo.orbitEventType}`) + webhookLogger.warn( + `Unsupported Orbit Event Type: ${orbitInfo.orbitEventType}` + ) return { headers: { 'Content-Type': 'application/json', diff --git a/docs/prettier.config.js b/docs/prettier.config.js deleted file mode 100644 index 92ac286bf6bf..000000000000 --- a/docs/prettier.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - ...require('../prettier.config'), - trailingComma: 'es5', -} diff --git a/docs/prettier.config.mjs b/docs/prettier.config.mjs new file mode 100644 index 000000000000..310ad10a937a --- /dev/null +++ b/docs/prettier.config.mjs @@ -0,0 +1,12 @@ +import rootConfig from '../prettier.config.mjs' + +/** + * @see https://prettier.io/docs/en/configuration.html + * @type {import("prettier").Config} + */ +const config = { + ...rootConfig, + trailingComma: 'es5', +} + +export default config diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 33582ace94f0..5b3ea966d974 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -83,7 +83,7 @@ So far just lighten links a little for a11y. */ -[data-theme="dark"] { +[data-theme='dark'] { --ifm-link-color: var(--teal); } @@ -94,9 +94,9 @@ Correct the color on hover and increase the font weight. */ -.theme-doc-breadcrumbs{ +.theme-doc-breadcrumbs { --ifm-link-hover-color: var(--red); - font-weight: var(--ifm-font-weight-semibold) + font-weight: var(--ifm-font-weight-semibold); } /* @@ -150,11 +150,11 @@ blockquote { padding: 2rem; } -[data-theme="light"] blockquote code { +[data-theme='light'] blockquote code { --ifm-code-background: hsl(14deg 70% 84%); } -[data-theme="dark"] blockquote { +[data-theme='dark'] blockquote { background-color: hsl(210deg 3% 15%); } @@ -254,11 +254,11 @@ blockquote { Hide dark mode things on light mode and vice versa. ------------------------ */ -[data-theme="light"] [data-mode="dark"] { +[data-theme='light'] [data-mode='dark'] { display: none; } -[data-theme="dark"] [data-mode="light"] { +[data-theme='dark'] [data-mode='light'] { display: none; } diff --git a/docs/tsconfig.json b/docs/tsconfig.json index cbd6fdb37d18..a6ba1bd9dd5d 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -1,4 +1,4 @@ { // This file is not used in compilation. It is here just for a nice editor experience. - "extends": "@docusaurus/tsconfig", + "extends": "@docusaurus/tsconfig" } diff --git a/docs/versions.json b/docs/versions.json index 0b2ac7975068..8416f1a461fe 100644 --- a/docs/versions.json +++ b/docs/versions.json @@ -1,9 +1 @@ -[ - "7.0", - "6.x", - "5.x", - "4.x", - "3.x", - "2.x", - "1.x" -] +["7.0", "6.x", "5.x", "4.x", "3.x", "2.x", "1.x"] diff --git a/prettier.config.mjs b/prettier.config.mjs new file mode 100644 index 000000000000..f492b287fba0 --- /dev/null +++ b/prettier.config.mjs @@ -0,0 +1,17 @@ +/** + * @see https://prettier.io/docs/en/configuration.html + * @type {import("prettier").Config} + */ +const config = { + bracketSpacing: true, + tabWidth: 2, + semi: false, + singleQuote: true, + plugins: [ + 'prettier-plugin-curly', + 'prettier-plugin-sh', + 'prettier-plugin-packagejson', + ], +} + +export default config From eb68499e741df13e0d076564b06960a598c87a21 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Fri, 16 Aug 2024 23:28:59 +0100 Subject: [PATCH 36/52] chore(lint): fix prettier configs and ignores (#11295) So tests started to fail because babel plugin tester uses prettier to format test output. It looks like it didn't play well with a `.mjs` config file. --- .prettierignore | 5 ++++- docs/{prettier.config.mjs => prettier.config.js} | 7 +++++-- prettier.config.mjs => prettier.config.js | 5 ++++- 3 files changed, 13 insertions(+), 4 deletions(-) rename docs/{prettier.config.mjs => prettier.config.js} (59%) rename prettier.config.mjs => prettier.config.js (83%) diff --git a/.prettierignore b/.prettierignore index 2a65829322f1..1710316a30fe 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,9 +2,11 @@ **/dist # Ignore fixture projects -__fixtures__ +/__fixtures__ # Ignore the certain files in /docs +/docs/.docusaurus +/docs/build /docs/versioned_docs /docs/versioned_sidebars @@ -21,6 +23,7 @@ packages/create-redwood-rsc-app # Ignore test fixtures **/__testfixtures__ **/__tests__/fixtures +**/__tests__/__fixtures__ # TODO(jgmw): Re-enable these in managable chunks packages/create-redwood-app/tests/e2e_prompts* diff --git a/docs/prettier.config.mjs b/docs/prettier.config.js similarity index 59% rename from docs/prettier.config.mjs rename to docs/prettier.config.js index 310ad10a937a..3678af226708 100644 --- a/docs/prettier.config.mjs +++ b/docs/prettier.config.js @@ -1,4 +1,7 @@ -import rootConfig from '../prettier.config.mjs' +/* eslint-env node */ +// @ts-check + +const rootConfig = require('../prettier.config') /** * @see https://prettier.io/docs/en/configuration.html @@ -9,4 +12,4 @@ const config = { trailingComma: 'es5', } -export default config +module.exports = config diff --git a/prettier.config.mjs b/prettier.config.js similarity index 83% rename from prettier.config.mjs rename to prettier.config.js index f492b287fba0..956faa5471a0 100644 --- a/prettier.config.mjs +++ b/prettier.config.js @@ -1,3 +1,6 @@ +/* eslint-env node */ +// @ts-check + /** * @see https://prettier.io/docs/en/configuration.html * @type {import("prettier").Config} @@ -14,4 +17,4 @@ const config = { ], } -export default config +module.exports = config From fd56d16472f6bde70028ba303c5409452af1088c Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sat, 17 Aug 2024 00:19:12 +0100 Subject: [PATCH 37/52] feat(context): Build and publish package as dual esm/cjs (#11294) Followed the general pattern we've established around our approach to dual publishing. I only wrote one additional package.json file in the dist because it felt a little redundant to repeat the one we have at the root. We've spoke before about perhaps not wanting to ship two sets of type definitions - one for cjs and one for esm. I know that they're essentially the same and for a package like this it almost doubles the published size. For now let's just ship types for both. In the future we'll stop publishing cjs anyway. Since I was just following our established pattern I'm going to go ahead and merge this in. If we discover something we'd rather change we can always revert or follow up. --- packages/context/build.mts | 24 ++++++++++++-- packages/context/package.json | 33 +++++++++++++++++-- packages/context/src/context.ts | 2 +- .../context/src/global.api-auto-imports.ts | 2 +- packages/context/src/index.ts | 6 ++-- packages/context/src/store.ts | 2 +- packages/context/tsconfig.cjs.json | 9 +++++ packages/context/tsconfig.json | 6 ++-- yarn.lock | 3 ++ 9 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 packages/context/tsconfig.cjs.json diff --git a/packages/context/build.mts b/packages/context/build.mts index 16175a6725c0..95a1a301b8ea 100644 --- a/packages/context/build.mts +++ b/packages/context/build.mts @@ -1,3 +1,23 @@ -import { build } from '@redwoodjs/framework-tools' +import { writeFileSync } from 'node:fs' -await build() +import { build, defaultBuildOptions } from '@redwoodjs/framework-tools' + +// ESM build +await build({ + buildOptions: { + ...defaultBuildOptions, + format: 'esm', + }, +}) + +// CJS build +await build({ + buildOptions: { + ...defaultBuildOptions, + outdir: 'dist/cjs', + }, +}) + +// Place a package.json file with `type: commonjs` in the 'dist/cjs' folder so that +// all files are considered CommonJS modules. +writeFileSync('dist/cjs/package.json', JSON.stringify({ type: 'commonjs' })) diff --git a/packages/context/package.json b/packages/context/package.json index 698298126c94..5e487d1b6d12 100644 --- a/packages/context/package.json +++ b/packages/context/package.json @@ -7,7 +7,31 @@ "directory": "packages/context" }, "license": "MIT", - "main": "./dist/index.js", + "type": "module", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "default": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./dist/store": { + "import": { + "types": "./dist/store.d.ts", + "default": "./dist/store.js" + }, + "default": { + "types": "./dist/cjs/store.d.ts", + "default": "./dist/cjs/store.js" + } + } + }, + "main": "./dist/cjs/index.js", + "module": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" @@ -15,12 +39,17 @@ "scripts": { "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-context.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json ./tsconfig.cjs.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build" }, "devDependencies": { + "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/framework-tools": "workspace:*", + "concurrently": "8.2.2", + "publint": "0.2.10", "tsx": "4.17.0", "typescript": "5.5.4" }, diff --git a/packages/context/src/context.ts b/packages/context/src/context.ts index 85a0fb266261..87a07dc272b7 100644 --- a/packages/context/src/context.ts +++ b/packages/context/src/context.ts @@ -1,4 +1,4 @@ -import { getAsyncStoreInstance } from './store' +import { getAsyncStoreInstance } from './store.js' // eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface GlobalContext extends Record {} diff --git a/packages/context/src/global.api-auto-imports.ts b/packages/context/src/global.api-auto-imports.ts index cb7507a22fa9..415db112fea5 100644 --- a/packages/context/src/global.api-auto-imports.ts +++ b/packages/context/src/global.api-auto-imports.ts @@ -1,4 +1,4 @@ -import type { GlobalContext } from './context' +import type { GlobalContext } from './context.js' declare global { const context: GlobalContext diff --git a/packages/context/src/index.ts b/packages/context/src/index.ts index 1f8bd9fe5a85..88ef88991e6d 100644 --- a/packages/context/src/index.ts +++ b/packages/context/src/index.ts @@ -1,5 +1,5 @@ -export * from './context' +export * from './context.js' // Note: store is not exported here to discourage direct usage. -import './global.api-auto-imports' -export * from './global.api-auto-imports' +import './global.api-auto-imports.js' +export * from './global.api-auto-imports.js' diff --git a/packages/context/src/store.ts b/packages/context/src/store.ts index 934c1b5d5afb..9b472e1eb497 100644 --- a/packages/context/src/store.ts +++ b/packages/context/src/store.ts @@ -1,6 +1,6 @@ import { AsyncLocalStorage } from 'async_hooks' -import type { GlobalContext } from './context' +import type { GlobalContext } from './context.js' let CONTEXT_STORAGE: AsyncLocalStorage> diff --git a/packages/context/tsconfig.cjs.json b/packages/context/tsconfig.cjs.json new file mode 100644 index 000000000000..213c73d75e6b --- /dev/null +++ b/packages/context/tsconfig.cjs.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist/cjs", + "module": "CommonJS", + "moduleResolution": "Node10", + "tsBuildInfoFile": "./tsconfig.cjs.tsbuildinfo" + } +} diff --git a/packages/context/tsconfig.json b/packages/context/tsconfig.json index 10dc5ae9f731..db264235028b 100644 --- a/packages/context/tsconfig.json +++ b/packages/context/tsconfig.json @@ -2,8 +2,10 @@ "extends": "../../tsconfig.compilerOption.json", "compilerOptions": { "rootDir": "src", - "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"] } diff --git a/yarn.lock b/yarn.lock index a77c81799160..80af0845f642 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7983,7 +7983,10 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/context@workspace:packages/context" dependencies: + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/framework-tools": "workspace:*" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" tsx: "npm:4.17.0" typescript: "npm:5.5.4" languageName: unknown From b86898af57fae7897aa9d344f1e445fdc0bc59e5 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sat, 17 Aug 2024 02:43:42 +0100 Subject: [PATCH 38/52] chore(lint): tidy up the prettier ignore (#11297) As title. --- .prettierignore | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.prettierignore b/.prettierignore index 1710316a30fe..e915df037993 100644 --- a/.prettierignore +++ b/.prettierignore @@ -14,16 +14,14 @@ /.nx # Ignore create-redwood-app (we don't want to mismatch between framework and project) -packages/create-redwood-app +/packages/create-redwood-app/templates +/packages/create-redwood-app/tests/**/*.sh # Ignore create-redwood-rsc-app (it has it's own config) -packages/create-redwood-rsc-app +/packages/create-redwood-rsc-app # TODO(jgmw): Is this too broad? # Ignore test fixtures **/__testfixtures__ **/__tests__/fixtures **/__tests__/__fixtures__ - -# TODO(jgmw): Re-enable these in managable chunks -packages/create-redwood-app/tests/e2e_prompts* From 289cb6249ad8972807b203225c46d98b7edafd36 Mon Sep 17 00:00:00 2001 From: Silas Smith Date: Sat, 17 Aug 2024 14:19:31 -0700 Subject: [PATCH 39/52] Detect/resolve ambiguous script names (#9848) Co-authored-by: Tobbe Lundberg --- .changesets/9848.md | 3 + .../cli/src/commands/__tests__/exec.test.ts | 38 ++++++++- packages/cli/src/commands/execHandler.js | 82 ++++++++++++++++--- 3 files changed, 107 insertions(+), 16 deletions(-) create mode 100644 .changesets/9848.md diff --git a/.changesets/9848.md b/.changesets/9848.md new file mode 100644 index 000000000000..03ce8329ef77 --- /dev/null +++ b/.changesets/9848.md @@ -0,0 +1,3 @@ +- Detect/resolve ambiguous script names (#9848) by @codersmith + +Detects and resolves ambiguous script name combinations like `[foo.js, foo.ts]` or `[foo.ts, foo.json]` when running `yarn rw exec foo`. diff --git a/packages/cli/src/commands/__tests__/exec.test.ts b/packages/cli/src/commands/__tests__/exec.test.ts index 8a7995bbf2ae..212075565545 100644 --- a/packages/cli/src/commands/__tests__/exec.test.ts +++ b/packages/cli/src/commands/__tests__/exec.test.ts @@ -9,13 +9,23 @@ import { handler } from '../execHandler' vi.mock('envinfo', () => ({ default: { run: () => '' } })) vi.mock('@redwoodjs/project-config', () => ({ getPaths: () => ({ - scripts: path.join( - __dirname, - '../../../../../__fixtures__/test-project/scripts', - ), + scripts: path.join('redwood-app', 'scripts'), }), resolveFile: (path: string) => path, })) +vi.mock('@redwoodjs/internal/dist/files', () => ({ + findScripts: () => { + const scriptsPath = path.join('redwood-app', 'scripts') + + return [ + path.join(scriptsPath, 'one', 'two', 'myNestedScript.ts'), + path.join(scriptsPath, 'conflicting.js'), + path.join(scriptsPath, 'conflicting.ts'), + path.join(scriptsPath, 'normalScript.ts'), + path.join(scriptsPath, 'secondNormalScript.ts'), + ] + }, +})) const mockRedwoodToml = { fileContents: '', @@ -49,4 +59,24 @@ describe('yarn rw exec --list', () => { expect.stringMatching(new RegExp('\\b' + scriptPath + '\\b')), ) }) + + it("does not include the file extension if there's no ambiguity", async () => { + await handler({ list: true }) + expect(vi.mocked(console).log).toHaveBeenCalledWith( + expect.stringMatching(new RegExp('\\bnormalScript\\b')), + ) + expect(vi.mocked(console).log).toHaveBeenCalledWith( + expect.stringMatching(new RegExp('\\bsecondNormalScript\\b')), + ) + }) + + it('includes the file extension if there could be ambiguity', async () => { + await handler({ list: true }) + expect(vi.mocked(console).log).toHaveBeenCalledWith( + expect.stringMatching(new RegExp('\\bconflicting.js\\b')), + ) + expect(vi.mocked(console).log).toHaveBeenCalledWith( + expect.stringMatching(new RegExp('\\bconflicting.ts\\b')), + ) + }) }) diff --git a/packages/cli/src/commands/execHandler.js b/packages/cli/src/commands/execHandler.js index f0ae2a84f1d0..dab0cf670a07 100644 --- a/packages/cli/src/commands/execHandler.js +++ b/packages/cli/src/commands/execHandler.js @@ -1,4 +1,5 @@ -import path from 'path' +import fs from 'node:fs' +import path from 'node:path' import { context } from '@opentelemetry/api' import { suppressTracing } from '@opentelemetry/core' @@ -17,12 +18,30 @@ import { runScriptFunction } from '../lib/exec' import { generatePrismaClient } from '../lib/generatePrismaClient' const printAvailableScriptsToConsole = () => { - console.log('Available scripts:') - findScripts(getPaths().scripts).forEach((scriptPath) => { + // Loop through all scripts and get their relative path + // Also group scripts with the same name but different extensions + const scripts = findScripts(getPaths().scripts).reduce((acc, scriptPath) => { const relativePath = path.relative(getPaths().scripts, scriptPath) - const { ext } = path.parse(relativePath) - const relativePathWithoutExt = relativePath.slice(0, -ext.length) - console.log(c.info(`- ${relativePathWithoutExt}`)) + const ext = path.parse(relativePath).ext + const pathNoExt = relativePath.slice(0, -ext.length) + + acc[pathNoExt] ||= [] + acc[pathNoExt].push(relativePath) + + return acc + }, {}) + + console.log('Available scripts:') + Object.entries(scripts).forEach(([name, paths]) => { + // If a script name exists with multiple extensions, print them all, + // including the extension + if (paths.length > 1) { + paths.forEach((scriptPath) => { + console.log(c.info(`- ${scriptPath}`)) + }) + } else { + console.log(c.info(`- ${name}`)) + } }) console.log() } @@ -40,8 +59,6 @@ export const handler = async (args) => { return } - const scriptPath = path.join(getPaths().scripts, name) - const { overrides: _overrides, plugins: webPlugins, @@ -101,11 +118,11 @@ export const handler = async (args) => { ], }) - try { - require.resolve(scriptPath) - } catch { + const scriptPath = resolveScriptPath(name) + + if (!scriptPath) { console.error( - c.error(`\nNo script called ${c.underline(name)} in ./scripts folder.\n`), + c.error(`\nNo script called \`${name}\` in the ./scripts folder.\n`), ) printAvailableScriptsToConsole() @@ -145,3 +162,44 @@ export const handler = async (args) => { await tasks.run() }) } + +function resolveScriptPath(name) { + const scriptPath = path.join(getPaths().scripts, name) + + // If scriptPath already has an extension, and it's a valid path, return it + // as it is + if (fs.existsSync(scriptPath)) { + return scriptPath + } + + // These extensions match the ones in internal/src/files.ts::findScripts() + const extensions = ['.js', '.jsx', '.ts', '.tsx'] + const matches = [] + + for (const extension of extensions) { + const p = scriptPath + extension + + if (fs.existsSync(p)) { + matches.push(p) + } + } + + if (matches.length === 1) { + return matches[0] + } else if (matches.length > 1) { + console.error( + c.error( + `\nMultiple scripts found for \`${name}\`. Please specify the ` + + 'extension.', + ), + ) + + matches.forEach((match) => { + console.log(c.info(`- ${path.relative(getPaths().scripts, match)}`)) + }) + + process.exit(1) + } + + return null +} From 7d2ec50f6840cf0f68c638d20bc72c4ea79616cc Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Sat, 17 Aug 2024 23:53:31 +0200 Subject: [PATCH 40/52] chore(exec test): Clean up (#11302) --- .../cli/src/commands/__tests__/exec.test.ts | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/cli/src/commands/__tests__/exec.test.ts b/packages/cli/src/commands/__tests__/exec.test.ts index 212075565545..9e11c134cef1 100644 --- a/packages/cli/src/commands/__tests__/exec.test.ts +++ b/packages/cli/src/commands/__tests__/exec.test.ts @@ -1,18 +1,17 @@ import path from 'node:path' -import '../../lib/mockTelemetry' - import { vi, afterEach, beforeEach, describe, it, expect } from 'vitest' +import '../../lib/mockTelemetry' import { handler } from '../execHandler' -vi.mock('envinfo', () => ({ default: { run: () => '' } })) vi.mock('@redwoodjs/project-config', () => ({ getPaths: () => ({ scripts: path.join('redwood-app', 'scripts'), }), resolveFile: (path: string) => path, })) + vi.mock('@redwoodjs/internal/dist/files', () => ({ findScripts: () => { const scriptsPath = path.join('redwood-app', 'scripts') @@ -27,19 +26,6 @@ vi.mock('@redwoodjs/internal/dist/files', () => ({ }, })) -const mockRedwoodToml = { - fileContents: '', -} - -// Before rw tests run, api/ and web/ `jest.config.js` is confirmed via existsSync() -vi.mock('node:fs', async () => ({ - default: { - readFileSync: () => { - return mockRedwoodToml.fileContents - }, - }, -})) - beforeEach(() => { vi.spyOn(console, 'log').mockImplementation(() => {}) }) From 5aa02dd20708f1b0485fc849302348b550e0479f Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sun, 18 Aug 2024 01:08:53 +0100 Subject: [PATCH 41/52] chore(build): build core with esbuild (#11298) Just looking to switch from using babel to using esbuild. --- packages/core/.babelrc.js | 1 - packages/core/build.mts | 10 ++++++++++ packages/core/package.json | 12 +++++++----- packages/core/src/bins/cross-env.ts | 3 ++- packages/core/src/bins/eslint.ts | 3 ++- packages/core/src/bins/jest.ts | 3 ++- packages/core/src/bins/nodemon.ts | 3 ++- packages/core/src/bins/redwood.ts | 3 ++- packages/core/src/bins/rw-api-server-watch.ts | 3 ++- packages/core/src/bins/rw-dev-fe.ts | 3 ++- packages/core/src/bins/rw-gen-watch.ts | 3 ++- packages/core/src/bins/rw-gen.ts | 3 ++- packages/core/src/bins/rw-log-formatter.ts | 3 ++- packages/core/src/bins/rw-serve-api.ts | 3 ++- packages/core/src/bins/rw-serve-fe.ts | 3 ++- packages/core/src/bins/rw-server.ts | 3 ++- packages/core/src/bins/rw-web-server.ts | 3 ++- packages/core/src/bins/rwfw.ts | 3 ++- yarn.lock | 5 +++-- 19 files changed, 50 insertions(+), 23 deletions(-) delete mode 100644 packages/core/.babelrc.js create mode 100644 packages/core/build.mts diff --git a/packages/core/.babelrc.js b/packages/core/.babelrc.js deleted file mode 100644 index 3b2c815712d9..000000000000 --- a/packages/core/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../babel.config.js' } diff --git a/packages/core/build.mts b/packages/core/build.mts new file mode 100644 index 000000000000..05b2602f8d6d --- /dev/null +++ b/packages/core/build.mts @@ -0,0 +1,10 @@ +import { build, defaultBuildOptions } from '@redwoodjs/framework-tools' + +// ESM build +await build({ + buildOptions: { + ...defaultBuildOptions, + format: 'esm', + outdir: 'dist/bins', + }, +}) diff --git a/packages/core/package.json b/packages/core/package.json index 20c838bc7301..3ca0b51acf43 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -8,6 +8,7 @@ "directory": "packages/core" }, "license": "MIT", + "type": "module", "bin": { "cross-env": "./dist/bins/cross-env.js", "eslint": "./dist/bins/eslint.js", @@ -29,14 +30,13 @@ "dist" ], "scripts": { - "build": "yarn build:js", - "build:js": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\"", + "build": "tsx ./build.mts", "build:pack": "yarn pack -o redwoodjs-core.tgz", + "check:package": "yarn publint", "prepublishOnly": "NODE_ENV=production yarn build" }, "dependencies": { "@babel/cli": "7.24.8", - "@babel/runtime-corejs3": "7.25.0", "@redwoodjs/cli": "workspace:*", "@redwoodjs/eslint-config": "workspace:*", "@redwoodjs/internal": "workspace:*", @@ -44,7 +44,6 @@ "@redwoodjs/testing": "workspace:*", "@redwoodjs/web-server": "workspace:*", "babel-loader": "^9.1.3", - "core-js": "3.38.0", "graphql-tag": "2.12.6", "lodash": "4.17.21", "mini-css-extract-plugin": "2.9.0", @@ -57,7 +56,10 @@ "url-loader": "4.1.1" }, "devDependencies": { - "@types/lodash": "4.17.7" + "@redwoodjs/framework-tools": "workspace:*", + "@types/lodash": "4.17.7", + "publint": "0.2.10", + "tsx": "4.17.0" }, "gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1" } diff --git a/packages/core/src/bins/cross-env.ts b/packages/core/src/bins/cross-env.ts index 7b9c151ce72b..f7c82c956575 100644 --- a/packages/core/src/bins/cross-env.ts +++ b/packages/core/src/bins/cross-env.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromCrossEnv = createRequire( require.resolve('cross-env/package.json'), ) diff --git a/packages/core/src/bins/eslint.ts b/packages/core/src/bins/eslint.ts index a4904d38e678..0c147901ccdf 100644 --- a/packages/core/src/bins/eslint.ts +++ b/packages/core/src/bins/eslint.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromESLint = createRequire(require.resolve('eslint/package.json')) const bins = requireFromESLint('./package.json')['bin'] diff --git a/packages/core/src/bins/jest.ts b/packages/core/src/bins/jest.ts index 7269056f094a..ceaac11fb337 100644 --- a/packages/core/src/bins/jest.ts +++ b/packages/core/src/bins/jest.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromJest = createRequire(require.resolve('jest/package.json')) const bin = requireFromJest('./package.json')['bin'] diff --git a/packages/core/src/bins/nodemon.ts b/packages/core/src/bins/nodemon.ts index 6b6543e29bf3..f754664b5767 100644 --- a/packages/core/src/bins/nodemon.ts +++ b/packages/core/src/bins/nodemon.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromNodemon = createRequire( require.resolve('nodemon/package.json'), ) diff --git a/packages/core/src/bins/redwood.ts b/packages/core/src/bins/redwood.ts index f5fc8a995c02..84d3bcbd1e47 100644 --- a/packages/core/src/bins/redwood.ts +++ b/packages/core/src/bins/redwood.ts @@ -17,13 +17,14 @@ * - https://yarnpkg.com/advanced/rulebook#packages-should-only-ever-require-what-they-formally-list-in-their-dependencies * - https://yarnpkg.com/advanced/rulebook#modules-shouldnt-hardcode-node_modules-paths-to-access-other-modules */ -import { createRequire } from 'module' +import { createRequire } from 'node:module' // You can think about the argument we're passing to `createRequire` as being kinda like setting the `cwd`: // // > It's using the path/URL to resolve relative paths (e.g.: createRequire('/foo/bar')('./baz') may load /foo/baz/index.js) // // See https://github.com/nodejs/node/issues/40567#issuecomment-949825461. +const require = createRequire(import.meta.url) const requireFromCli = createRequire( require.resolve('@redwoodjs/cli/package.json'), ) diff --git a/packages/core/src/bins/rw-api-server-watch.ts b/packages/core/src/bins/rw-api-server-watch.ts index 6a42ab7ecd22..1e23bbc56f27 100644 --- a/packages/core/src/bins/rw-api-server-watch.ts +++ b/packages/core/src/bins/rw-api-server-watch.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromApiServer = createRequire( require.resolve('@redwoodjs/api-server/package.json'), ) diff --git a/packages/core/src/bins/rw-dev-fe.ts b/packages/core/src/bins/rw-dev-fe.ts index ecd5fd1b9138..947ad547277f 100644 --- a/packages/core/src/bins/rw-dev-fe.ts +++ b/packages/core/src/bins/rw-dev-fe.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromRwVite = createRequire( require.resolve('@redwoodjs/vite/package.json'), ) diff --git a/packages/core/src/bins/rw-gen-watch.ts b/packages/core/src/bins/rw-gen-watch.ts index 26ea5dcdb58d..b8b90d86aeb6 100644 --- a/packages/core/src/bins/rw-gen-watch.ts +++ b/packages/core/src/bins/rw-gen-watch.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromInternal = createRequire( require.resolve('@redwoodjs/internal/package.json'), ) diff --git a/packages/core/src/bins/rw-gen.ts b/packages/core/src/bins/rw-gen.ts index 35dc82d752be..a22e8ccc389b 100644 --- a/packages/core/src/bins/rw-gen.ts +++ b/packages/core/src/bins/rw-gen.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromInternal = createRequire( require.resolve('@redwoodjs/internal/package.json'), ) diff --git a/packages/core/src/bins/rw-log-formatter.ts b/packages/core/src/bins/rw-log-formatter.ts index df9917a8db3e..a4021baa6afd 100644 --- a/packages/core/src/bins/rw-log-formatter.ts +++ b/packages/core/src/bins/rw-log-formatter.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromApiServer = createRequire( require.resolve('@redwoodjs/api-server/package.json'), ) diff --git a/packages/core/src/bins/rw-serve-api.ts b/packages/core/src/bins/rw-serve-api.ts index 43a2de0478c5..dfb47d9c79c1 100644 --- a/packages/core/src/bins/rw-serve-api.ts +++ b/packages/core/src/bins/rw-serve-api.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromApiServer = createRequire( require.resolve('@redwoodjs/api-server/package.json'), ) diff --git a/packages/core/src/bins/rw-serve-fe.ts b/packages/core/src/bins/rw-serve-fe.ts index bc9497e49fea..30dda5fe24e1 100644 --- a/packages/core/src/bins/rw-serve-fe.ts +++ b/packages/core/src/bins/rw-serve-fe.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromRwVite = createRequire( require.resolve('@redwoodjs/vite/package.json'), ) diff --git a/packages/core/src/bins/rw-server.ts b/packages/core/src/bins/rw-server.ts index 6de88f63bb14..0ea4296ef6ba 100644 --- a/packages/core/src/bins/rw-server.ts +++ b/packages/core/src/bins/rw-server.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromApiServer = createRequire( require.resolve('@redwoodjs/api-server/package.json'), ) diff --git a/packages/core/src/bins/rw-web-server.ts b/packages/core/src/bins/rw-web-server.ts index 4e85da8a0936..0ad370457265 100644 --- a/packages/core/src/bins/rw-web-server.ts +++ b/packages/core/src/bins/rw-web-server.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromWebServer = createRequire( require.resolve('@redwoodjs/web-server/package.json'), ) diff --git a/packages/core/src/bins/rwfw.ts b/packages/core/src/bins/rwfw.ts index 5d09e6d133ef..2d708787c918 100644 --- a/packages/core/src/bins/rwfw.ts +++ b/packages/core/src/bins/rwfw.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node -import { createRequire } from 'module' +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) const requireFromCli = createRequire( require.resolve('@redwoodjs/cli/package.json'), ) diff --git a/yarn.lock b/yarn.lock index 80af0845f642..efd1a6b3691b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8012,24 +8012,25 @@ __metadata: resolution: "@redwoodjs/core@workspace:packages/core" dependencies: "@babel/cli": "npm:7.24.8" - "@babel/runtime-corejs3": "npm:7.25.0" "@redwoodjs/cli": "workspace:*" "@redwoodjs/eslint-config": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@redwoodjs/internal": "workspace:*" "@redwoodjs/project-config": "workspace:*" "@redwoodjs/testing": "workspace:*" "@redwoodjs/web-server": "workspace:*" "@types/lodash": "npm:4.17.7" babel-loader: "npm:^9.1.3" - core-js: "npm:3.38.0" graphql-tag: "npm:2.12.6" lodash: "npm:4.17.21" mini-css-extract-plugin: "npm:2.9.0" nodemon: "npm:3.1.4" null-loader: "npm:4.0.1" + publint: "npm:0.2.10" react-refresh: "npm:0.14.0" resolve-url-loader: "npm:5.0.0" rimraf: "npm:6.0.1" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" url-loader: "npm:4.1.1" bin: From 9fb2d6b74e1a3a55b76afc2fe04230463e22ff47 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sun, 18 Aug 2024 01:29:41 +0100 Subject: [PATCH 42/52] chore(deps): Remove webpack related dependencies (#11299) Looks like these are some webpack specific dependencies we don't need anymore. --- packages/core/package.json | 7 +- yarn.lock | 264 +++---------------------------------- 2 files changed, 16 insertions(+), 255 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 3ca0b51acf43..b3c378ca5e40 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -43,17 +43,12 @@ "@redwoodjs/project-config": "workspace:*", "@redwoodjs/testing": "workspace:*", "@redwoodjs/web-server": "workspace:*", - "babel-loader": "^9.1.3", "graphql-tag": "2.12.6", "lodash": "4.17.21", - "mini-css-extract-plugin": "2.9.0", "nodemon": "3.1.4", - "null-loader": "4.0.1", "react-refresh": "0.14.0", - "resolve-url-loader": "5.0.0", "rimraf": "6.0.1", - "typescript": "5.5.4", - "url-loader": "4.1.1" + "typescript": "5.5.4" }, "devDependencies": { "@redwoodjs/framework-tools": "workspace:*", diff --git a/yarn.lock b/yarn.lock index efd1a6b3691b..32dec80ebcd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8020,19 +8020,14 @@ __metadata: "@redwoodjs/testing": "workspace:*" "@redwoodjs/web-server": "workspace:*" "@types/lodash": "npm:4.17.7" - babel-loader: "npm:^9.1.3" graphql-tag: "npm:2.12.6" lodash: "npm:4.17.21" - mini-css-extract-plugin: "npm:2.9.0" nodemon: "npm:3.1.4" - null-loader: "npm:4.0.1" publint: "npm:0.2.10" react-refresh: "npm:0.14.0" - resolve-url-loader: "npm:5.0.0" rimraf: "npm:6.0.1" tsx: "npm:4.17.0" typescript: "npm:5.5.4" - url-loader: "npm:4.1.1" bin: cross-env: ./dist/bins/cross-env.js eslint: ./dist/bins/eslint.js @@ -10726,7 +10721,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db @@ -11830,16 +11825,6 @@ __metadata: languageName: node linkType: hard -"adjust-sourcemap-loader@npm:^4.0.0": - version: 4.0.0 - resolution: "adjust-sourcemap-loader@npm:4.0.0" - dependencies: - loader-utils: "npm:^2.0.0" - regex-parser: "npm:^2.2.11" - checksum: 10c0/6a6e5bb8b670e4e1238c708f6163e92aa2ad0308fe5913de73c89e4cbf41738ee0bcc5552b94d0b7bf8be435ee49b78c6de8a6db7badd80762051e843c8aa14f - languageName: node - linkType: hard - "agent-base@npm:5": version: 5.1.1 resolution: "agent-base@npm:5.1.1" @@ -11900,27 +11885,7 @@ __metadata: languageName: node linkType: hard -"ajv-keywords@npm:^3.5.2": - version: 3.5.2 - resolution: "ajv-keywords@npm:3.5.2" - peerDependencies: - ajv: ^6.9.1 - checksum: 10c0/0c57a47cbd656e8cdfd99d7c2264de5868918ffa207c8d7a72a7f63379d4333254b2ba03d69e3c035e996a3fd3eb6d5725d7a1597cca10694296e32510546360 - languageName: node - linkType: hard - -"ajv-keywords@npm:^5.1.0": - version: 5.1.0 - resolution: "ajv-keywords@npm:5.1.0" - dependencies: - fast-deep-equal: "npm:^3.1.3" - peerDependencies: - ajv: ^8.8.2 - checksum: 10c0/18bec51f0171b83123ba1d8883c126e60c6f420cef885250898bf77a8d3e65e3bfb9e8564f497e30bdbe762a83e0d144a36931328616a973ee669dc74d4a9590 - languageName: node - linkType: hard - -"ajv@npm:8.17.1, ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.9.0": +"ajv@npm:8.17.1, ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0": version: 8.17.1 resolution: "ajv@npm:8.17.1" dependencies: @@ -11932,7 +11897,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.4, ajv@npm:^6.12.5, ajv@npm:^6.12.6": +"ajv@npm:^6.12.4, ajv@npm:^6.12.6": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -12641,19 +12606,6 @@ __metadata: languageName: node linkType: hard -"babel-loader@npm:^9.1.3": - version: 9.1.3 - resolution: "babel-loader@npm:9.1.3" - dependencies: - find-cache-dir: "npm:^4.0.0" - schema-utils: "npm:^4.0.0" - peerDependencies: - "@babel/core": ^7.12.0 - webpack: ">=5" - checksum: 10c0/e3fc3c9e02bd908b37e8e8cd4f3d7280cf6ac45e33fc203aedbb615135a0fecc33bf92573b71a166a827af029d302c0b060354985cd91d510320bd70a2f949eb - languageName: node - linkType: hard - "babel-plugin-auto-import@npm:1.1.0": version: 1.1.0 resolution: "babel-plugin-auto-import@npm:1.1.0" @@ -12913,13 +12865,6 @@ __metadata: languageName: node linkType: hard -"big.js@npm:^5.2.2": - version: 5.2.2 - resolution: "big.js@npm:5.2.2" - checksum: 10c0/230520f1ff920b2d2ce3e372d77a33faa4fa60d802fe01ca4ffbc321ee06023fe9a741ac02793ee778040a16b7e497f7d60c504d1c402b8fdab6f03bb785a25f - languageName: node - linkType: hard - "bignumber.js@npm:^9.0.0": version: 9.1.1 resolution: "bignumber.js@npm:9.1.1" @@ -14097,13 +14042,6 @@ __metadata: languageName: node linkType: hard -"common-path-prefix@npm:^3.0.0": - version: 3.0.0 - resolution: "common-path-prefix@npm:3.0.0" - checksum: 10c0/c4a74294e1b1570f4a8ab435285d185a03976c323caa16359053e749db4fde44e3e6586c29cd051100335e11895767cbbd27ea389108e327d62f38daf4548fdb - languageName: node - linkType: hard - "common-tags@npm:1.8.2, common-tags@npm:^1.8.0": version: 1.8.2 resolution: "common-tags@npm:1.8.2" @@ -14388,7 +14326,7 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0": +"convert-source-map@npm:^1.6.0": version: 1.9.0 resolution: "convert-source-map@npm:1.9.0" checksum: 10c0/281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b @@ -15795,13 +15733,6 @@ __metadata: languageName: node linkType: hard -"emojis-list@npm:^3.0.0": - version: 3.0.0 - resolution: "emojis-list@npm:3.0.0" - checksum: 10c0/7dc4394b7b910444910ad64b812392159a21e1a7ecc637c775a440227dcb4f80eff7fe61f4453a7d7603fa23d23d30cc93fe9e4b5ed985b88d6441cd4a35117b - languageName: node - linkType: hard - "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -17399,16 +17330,6 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:^4.0.0": - version: 4.0.0 - resolution: "find-cache-dir@npm:4.0.0" - dependencies: - common-path-prefix: "npm:^3.0.0" - pkg-dir: "npm:^7.0.0" - checksum: 10c0/0faa7956974726c8769671de696d24c643ca1e5b8f7a2401283caa9e07a5da093293e0a0f4bd18c920ec981d2ef945c7f5b946cde268dfc9077d833ad0293cff - languageName: node - linkType: hard - "find-my-way@npm:8.2.0, find-my-way@npm:^8.0.0": version: 8.2.0 resolution: "find-my-way@npm:8.2.0" @@ -17458,16 +17379,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^6.3.0": - version: 6.3.0 - resolution: "find-up@npm:6.3.0" - dependencies: - locate-path: "npm:^7.1.0" - path-exists: "npm:^5.0.0" - checksum: 10c0/07e0314362d316b2b13f7f11ea4692d5191e718ca3f7264110127520f3347996349bf9e16805abae3e196805814bc66ef4bff2b8904dc4a6476085fc9b0eba07 - languageName: node - linkType: hard - "firebase-admin@npm:12.3.1": version: 12.3.1 resolution: "firebase-admin@npm:12.3.1" @@ -20969,7 +20880,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:2.2.3, json5@npm:^2.1.2, json5@npm:^2.2.2, json5@npm:^2.2.3": +"json5@npm:2.2.3, json5@npm:^2.2.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -21528,17 +21439,6 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^2.0.0": - version: 2.0.4 - resolution: "loader-utils@npm:2.0.4" - dependencies: - big.js: "npm:^5.2.2" - emojis-list: "npm:^3.0.0" - json5: "npm:^2.1.2" - checksum: 10c0/d5654a77f9d339ec2a03d88221a5a695f337bf71eb8dea031b3223420bb818964ba8ed0069145c19b095f6c8b8fd386e602a3fc7ca987042bd8bb1dcc90d7100 - languageName: node - linkType: hard - "local-pkg@npm:^0.5.0": version: 0.5.0 resolution: "local-pkg@npm:0.5.0" @@ -21587,15 +21487,6 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^7.1.0": - version: 7.2.0 - resolution: "locate-path@npm:7.2.0" - dependencies: - p-locate: "npm:^6.0.0" - checksum: 10c0/139e8a7fe11cfbd7f20db03923cacfa5db9e14fa14887ea121345597472b4a63c1a42a8a5187defeeff6acf98fd568da7382aa39682d38f0af27433953a97751 - languageName: node - linkType: hard - "lodash-decorators@npm:6.0.1": version: 6.0.1 resolution: "lodash-decorators@npm:6.0.1" @@ -22304,7 +22195,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:2.1.35, mime-types@npm:^2.1.12, mime-types@npm:^2.1.25, mime-types@npm:^2.1.27, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:2.1.35, mime-types@npm:^2.1.12, mime-types@npm:^2.1.25, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -22375,18 +22266,6 @@ __metadata: languageName: node linkType: hard -"mini-css-extract-plugin@npm:2.9.0": - version: 2.9.0 - resolution: "mini-css-extract-plugin@npm:2.9.0" - dependencies: - schema-utils: "npm:^4.0.0" - tapable: "npm:^2.2.1" - peerDependencies: - webpack: ^5.0.0 - checksum: 10c0/46e20747ea250420db8a82801b9779299ce3cd5ec4d6dd75e00904c39cc80f0f01decaa534b8cb9658d7d3b656b919cb2cc84b1ba7e2394d2d6548578a5c2901 - languageName: node - linkType: hard - "minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": version: 1.0.1 resolution: "minimalistic-assert@npm:1.0.1" @@ -23688,18 +23567,6 @@ __metadata: languageName: node linkType: hard -"null-loader@npm:4.0.1": - version: 4.0.1 - resolution: "null-loader@npm:4.0.1" - dependencies: - loader-utils: "npm:^2.0.0" - schema-utils: "npm:^3.0.0" - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: 10c0/fe9a74a928c9ddc1eab7be0e4322516439562d6efd6feeb0f7c61777d4b79a6a8e5a6bc8133deb59408f3f423bdf84c154a88168154a583154e9e33d544b4d42 - languageName: node - linkType: hard - "nullthrows@npm:^1.1.1": version: 1.1.1 resolution: "nullthrows@npm:1.1.1" @@ -24121,15 +23988,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^4.0.0": - version: 4.0.0 - resolution: "p-limit@npm:4.0.0" - dependencies: - yocto-queue: "npm:^1.0.0" - checksum: 10c0/a56af34a77f8df2ff61ddfb29431044557fcbcb7642d5a3233143ebba805fc7306ac1d448de724352861cb99de934bc9ab74f0d16fe6a5460bdbdf938de875ad - languageName: node - linkType: hard - "p-locate@npm:^2.0.0": version: 2.0.0 resolution: "p-locate@npm:2.0.0" @@ -24166,15 +24024,6 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^6.0.0": - version: 6.0.0 - resolution: "p-locate@npm:6.0.0" - dependencies: - p-limit: "npm:^4.0.0" - checksum: 10c0/d72fa2f41adce59c198270aa4d3c832536c87a1806e0f69dffb7c1a7ca998fb053915ca833d90f166a8c082d3859eabfed95f01698a3214c20df6bb8de046312 - languageName: node - linkType: hard - "p-map-series@npm:2.1.0": version: 2.1.0 resolution: "p-map-series@npm:2.1.0" @@ -24541,13 +24390,6 @@ __metadata: languageName: node linkType: hard -"path-exists@npm:^5.0.0": - version: 5.0.0 - resolution: "path-exists@npm:5.0.0" - checksum: 10c0/b170f3060b31604cde93eefdb7392b89d832dfbc1bed717c9718cbe0f230c1669b7e75f87e19901da2250b84d092989a0f9e44d2ef41deb09aa3ad28e691a40a - languageName: node - linkType: hard - "path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -24831,15 +24673,6 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^7.0.0": - version: 7.0.0 - resolution: "pkg-dir@npm:7.0.0" - dependencies: - find-up: "npm:^6.3.0" - checksum: 10c0/1afb23d2efb1ec9d8b2c4a0c37bf146822ad2774f074cb05b853be5dca1b40815c5960dd126df30ab8908349262a266f31b771e877235870a3b8fd313beebec5 - languageName: node - linkType: hard - "pkg-types@npm:^1.0.3, pkg-types@npm:^1.1.1, pkg-types@npm:^1.1.3": version: 1.1.3 resolution: "pkg-types@npm:1.1.3" @@ -24928,7 +24761,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.2.14, postcss@npm:^8.4.41": +"postcss@npm:^8.4.41": version: 8.4.41 resolution: "postcss@npm:8.4.41" dependencies: @@ -26089,13 +25922,6 @@ __metadata: languageName: node linkType: hard -"regex-parser@npm:^2.2.11": - version: 2.2.11 - resolution: "regex-parser@npm:2.2.11" - checksum: 10c0/6572acbd46b5444215a73cf164f3c6fdbd73b8a2cde6a31a97307e514d20f5cbb8609f9e4994a7744207f2d1bf9e6fca4bbc0c9854f2b3da77ae0063efdc3f98 - languageName: node - linkType: hard - "regexp-to-ast@npm:0.5.0": version: 0.5.0 resolution: "regexp-to-ast@npm:0.5.0" @@ -26335,19 +26161,6 @@ __metadata: languageName: node linkType: hard -"resolve-url-loader@npm:5.0.0": - version: 5.0.0 - resolution: "resolve-url-loader@npm:5.0.0" - dependencies: - adjust-sourcemap-loader: "npm:^4.0.0" - convert-source-map: "npm:^1.7.0" - loader-utils: "npm:^2.0.0" - postcss: "npm:^8.2.14" - source-map: "npm:0.6.1" - checksum: 10c0/53eef3620332f2fc35a4deffaa4395064b2ffd1bc28be380faa3f1e99c2fb7bbf0f705700b4539387d5b6c39586df54a92cd5d031606f19de4bf9e0ff1b6a522 - languageName: node - linkType: hard - "resolve.exports@npm:^2.0.0": version: 2.0.2 resolution: "resolve.exports@npm:2.0.2" @@ -26866,29 +26679,6 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.0.0": - version: 3.3.0 - resolution: "schema-utils@npm:3.3.0" - dependencies: - "@types/json-schema": "npm:^7.0.8" - ajv: "npm:^6.12.5" - ajv-keywords: "npm:^3.5.2" - checksum: 10c0/fafdbde91ad8aa1316bc543d4b61e65ea86970aebbfb750bfb6d8a6c287a23e415e0e926c2498696b242f63af1aab8e585252637fabe811fd37b604351da6500 - languageName: node - linkType: hard - -"schema-utils@npm:^4.0.0": - version: 4.2.0 - resolution: "schema-utils@npm:4.2.0" - dependencies: - "@types/json-schema": "npm:^7.0.9" - ajv: "npm:^8.9.0" - ajv-formats: "npm:^2.1.1" - ajv-keywords: "npm:^5.1.0" - checksum: 10c0/8dab7e7800316387fd8569870b4b668cfcecf95ac551e369ea799bbcbfb63fb0365366d4b59f64822c9f7904d8c5afcfaf5a6124a4b08783e558cd25f299a6b4 - languageName: node - linkType: hard - "scuid@npm:^1.1.0": version: 1.1.0 resolution: "scuid@npm:1.1.0" @@ -27404,13 +27194,6 @@ __metadata: languageName: node linkType: hard -"source-map@npm:0.6.1, source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1": - version: 0.6.1 - resolution: "source-map@npm:0.6.1" - checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 - languageName: node - linkType: hard - "source-map@npm:0.7.4": version: 0.7.4 resolution: "source-map@npm:0.7.4" @@ -27418,6 +27201,13 @@ __metadata: languageName: node linkType: hard +"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 + languageName: node + linkType: hard + "space-separated-tokens@npm:^1.0.0": version: 1.1.5 resolution: "space-separated-tokens@npm:1.1.5" @@ -28148,7 +27938,7 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.2.0, tapable@npm:^2.2.1": +"tapable@npm:^2.2.0": version: 2.2.1 resolution: "tapable@npm:2.2.1" checksum: 10c0/bc40e6efe1e554d075469cedaba69a30eeb373552aaf41caeaaa45bf56ffacc2674261b106245bd566b35d8f3329b52d838e851ee0a852120acae26e622925c9 @@ -29385,23 +29175,6 @@ __metadata: languageName: node linkType: hard -"url-loader@npm:4.1.1": - version: 4.1.1 - resolution: "url-loader@npm:4.1.1" - dependencies: - loader-utils: "npm:^2.0.0" - mime-types: "npm:^2.1.27" - schema-utils: "npm:^3.0.0" - peerDependencies: - file-loader: "*" - webpack: ^4.0.0 || ^5.0.0 - peerDependenciesMeta: - file-loader: - optional: true - checksum: 10c0/71b6300e02ce26c70625eae1a2297c0737635038c62691bb3007ac33e85c0130efc74bfb444baf5c6b3bad5953491159d31d66498967d1417865d0c7e7cd1a64 - languageName: node - linkType: hard - "url-parse-lax@npm:^3.0.0": version: 3.0.0 resolution: "url-parse-lax@npm:3.0.0" @@ -30505,13 +30278,6 @@ __metadata: languageName: node linkType: hard -"yocto-queue@npm:^1.0.0": - version: 1.0.0 - resolution: "yocto-queue@npm:1.0.0" - checksum: 10c0/856117aa15cf5103d2a2fb173f0ab4acb12b4b4d0ed3ab249fdbbf612e55d1cadfd27a6110940e24746fb0a78cf640b522cc8bca76f30a3b00b66e90cf82abe0 - languageName: node - linkType: hard - "yoga-layout-prebuilt@npm:1.10.0": version: 1.10.0 resolution: "yoga-layout-prebuilt@npm:1.10.0" From 78b897a4b689e9cf1f336113b1fbf18bf6dd871d Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sun, 18 Aug 2024 01:56:27 +0100 Subject: [PATCH 43/52] fix(auth-providers): Move away from babel for building 'setup' packages (#11303) This switches from babel to esbuild for building the 'api' auth provider packages. Continuing the work of #11301 but this time for the setup packages. I have not included the dbAuth package deliberately and will follow up with a separate update to that package. I had to make a small change to the `@redwoodjs/cli-helpers` package. This was because tsc was not happy that I was statically importing from a package marked `type: module` from a package marked as `type: commonjs` because it would result in requiring an es module. It was not understanding that the cli-helpers package was dual cjs/esm and that it will be totally fine to either import or require from it. The solution (it appears) is to be specific in the exports field of the package.json. Those edits here made tsc happy to generate types and didn't throw the error. I didn't update the styling of the tsconfig when I changed the cli-helpers package. We should refactor that standalone. I'm really not at all thrilled about my recent changes which use the `moduleResolution: node` because that isn't what we should be using but tsc errors out based on your `module` and `moduleResolution` setting which has been a pain. This for now is okay and we can revisit once we encounter the issue of using two different module resolution algorithms depending on cjs vs esm. --- .../auth-providers/auth0/setup/.babelrc.js | 1 - packages/auth-providers/auth0/setup/build.mts | 8 +++ .../auth-providers/auth0/setup/package.json | 33 ++++++--- .../auth-providers/auth0/setup/tsconfig.json | 5 +- .../azureActiveDirectory/setup/.babelrc.js | 1 - .../azureActiveDirectory/setup/build.mts | 8 +++ .../azureActiveDirectory/setup/package.json | 33 ++++++--- .../azureActiveDirectory/setup/tsconfig.json | 5 +- .../auth-providers/clerk/setup/.babelrc.js | 1 - packages/auth-providers/clerk/setup/build.mts | 8 +++ .../auth-providers/clerk/setup/package.json | 33 ++++++--- .../auth-providers/clerk/setup/tsconfig.json | 5 +- .../auth-providers/custom/setup/.babelrc.js | 1 - .../auth-providers/custom/setup/build.mts | 8 +++ .../auth-providers/custom/setup/package.json | 33 ++++++--- .../auth-providers/custom/setup/tsconfig.json | 5 +- .../auth-providers/firebase/setup/.babelrc.js | 1 - .../auth-providers/firebase/setup/build.mts | 8 +++ .../firebase/setup/package.json | 33 ++++++--- .../firebase/setup/tsconfig.json | 5 +- .../auth-providers/netlify/setup/.babelrc.js | 1 - .../auth-providers/netlify/setup/build.mts | 8 +++ .../auth-providers/netlify/setup/package.json | 33 ++++++--- .../netlify/setup/tsconfig.json | 5 +- .../auth-providers/supabase/setup/.babelrc.js | 1 - .../auth-providers/supabase/setup/build.mts | 8 +++ .../supabase/setup/package.json | 33 ++++++--- .../supabase/setup/tsconfig.json | 5 +- .../supertokens/setup/.babelrc.js | 1 - .../supertokens/setup/build.mts | 8 +++ .../supertokens/setup/package.json | 33 ++++++--- .../supertokens/setup/tsconfig.json | 5 +- packages/cli-helpers/package.json | 35 ++++++--- packages/cli-helpers/tsconfig.build.cjs.json | 9 +++ packages/framework-tools/src/buildDefaults.ts | 44 ++++++++++++ yarn.lock | 72 ++++++++++--------- 36 files changed, 414 insertions(+), 122 deletions(-) delete mode 100644 packages/auth-providers/auth0/setup/.babelrc.js create mode 100644 packages/auth-providers/auth0/setup/build.mts delete mode 100644 packages/auth-providers/azureActiveDirectory/setup/.babelrc.js create mode 100644 packages/auth-providers/azureActiveDirectory/setup/build.mts delete mode 100644 packages/auth-providers/clerk/setup/.babelrc.js create mode 100644 packages/auth-providers/clerk/setup/build.mts delete mode 100644 packages/auth-providers/custom/setup/.babelrc.js create mode 100644 packages/auth-providers/custom/setup/build.mts delete mode 100644 packages/auth-providers/firebase/setup/.babelrc.js create mode 100644 packages/auth-providers/firebase/setup/build.mts delete mode 100644 packages/auth-providers/netlify/setup/.babelrc.js create mode 100644 packages/auth-providers/netlify/setup/build.mts delete mode 100644 packages/auth-providers/supabase/setup/.babelrc.js create mode 100644 packages/auth-providers/supabase/setup/build.mts delete mode 100644 packages/auth-providers/supertokens/setup/.babelrc.js create mode 100644 packages/auth-providers/supertokens/setup/build.mts create mode 100644 packages/cli-helpers/tsconfig.build.cjs.json diff --git a/packages/auth-providers/auth0/setup/.babelrc.js b/packages/auth-providers/auth0/setup/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/auth0/setup/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/auth0/setup/build.mts b/packages/auth-providers/auth0/setup/build.mts new file mode 100644 index 000000000000..b35ee44f5def --- /dev/null +++ b/packages/auth-providers/auth0/setup/build.mts @@ -0,0 +1,8 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() + +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['templates/**/*.template'], +}) diff --git a/packages/auth-providers/auth0/setup/package.json b/packages/auth-providers/auth0/setup/package.json index 55e82b1c7ab5..39e405be8728 100644 --- a/packages/auth-providers/auth0/setup/package.json +++ b/packages/auth-providers/auth0/setup/package.json @@ -7,30 +7,47 @@ "directory": "packages/auth-providers/auth0/setup" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/setup": { + "types": "./dist/setup.d.ts", + "default": "./dist/setup.js" + }, + "./dist/setupHandler": { + "types": "./dist/setupHandler.d.ts", + "default": "./dist/setupHandler.js" + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-auth0-setup.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@redwoodjs/cli-helpers": "workspace:*", - "core-js": "3.38.0" + "@redwoodjs/cli-helpers": "workspace:*" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/yargs": "17.0.33", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/auth0/setup/tsconfig.json b/packages/auth-providers/auth0/setup/tsconfig.json index 31fd2566f42e..7a7ec0d32fa2 100644 --- a/packages/auth-providers/auth0/setup/tsconfig.json +++ b/packages/auth-providers/auth0/setup/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../cli-helpers" }] diff --git a/packages/auth-providers/azureActiveDirectory/setup/.babelrc.js b/packages/auth-providers/azureActiveDirectory/setup/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/azureActiveDirectory/setup/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/azureActiveDirectory/setup/build.mts b/packages/auth-providers/azureActiveDirectory/setup/build.mts new file mode 100644 index 000000000000..b35ee44f5def --- /dev/null +++ b/packages/auth-providers/azureActiveDirectory/setup/build.mts @@ -0,0 +1,8 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() + +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['templates/**/*.template'], +}) diff --git a/packages/auth-providers/azureActiveDirectory/setup/package.json b/packages/auth-providers/azureActiveDirectory/setup/package.json index 1025e75c504e..0bc7183d7dc2 100644 --- a/packages/auth-providers/azureActiveDirectory/setup/package.json +++ b/packages/auth-providers/azureActiveDirectory/setup/package.json @@ -7,30 +7,47 @@ "directory": "packages/auth-providers/azureActiveDirectory/setup" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/setup": { + "types": "./dist/setup.d.ts", + "default": "./dist/setup.js" + }, + "./dist/setupHandler": { + "types": "./dist/setupHandler.d.ts", + "default": "./dist/setupHandler.js" + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-azure-active-directory-setup.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@redwoodjs/cli-helpers": "workspace:*", - "core-js": "3.38.0" + "@redwoodjs/cli-helpers": "workspace:*" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/yargs": "17.0.33", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/azureActiveDirectory/setup/tsconfig.json b/packages/auth-providers/azureActiveDirectory/setup/tsconfig.json index 31fd2566f42e..7a7ec0d32fa2 100644 --- a/packages/auth-providers/azureActiveDirectory/setup/tsconfig.json +++ b/packages/auth-providers/azureActiveDirectory/setup/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../cli-helpers" }] diff --git a/packages/auth-providers/clerk/setup/.babelrc.js b/packages/auth-providers/clerk/setup/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/clerk/setup/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/clerk/setup/build.mts b/packages/auth-providers/clerk/setup/build.mts new file mode 100644 index 000000000000..b35ee44f5def --- /dev/null +++ b/packages/auth-providers/clerk/setup/build.mts @@ -0,0 +1,8 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() + +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['templates/**/*.template'], +}) diff --git a/packages/auth-providers/clerk/setup/package.json b/packages/auth-providers/clerk/setup/package.json index 4db7c443a806..d568a43f86db 100644 --- a/packages/auth-providers/clerk/setup/package.json +++ b/packages/auth-providers/clerk/setup/package.json @@ -7,28 +7,45 @@ "directory": "packages/auth-providers/clerk/setup" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/setup": { + "types": "./dist/setup.d.ts", + "default": "./dist/setup.js" + }, + "./dist/setupHandler": { + "types": "./dist/setupHandler.d.ts", + "default": "./dist/setupHandler.js" + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-clerk-setup.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@redwoodjs/cli-helpers": "workspace:*", - "core-js": "3.38.0" + "@redwoodjs/cli-helpers": "workspace:*" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/yargs": "17.0.33", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4" }, "gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1" diff --git a/packages/auth-providers/clerk/setup/tsconfig.json b/packages/auth-providers/clerk/setup/tsconfig.json index 31fd2566f42e..7a7ec0d32fa2 100644 --- a/packages/auth-providers/clerk/setup/tsconfig.json +++ b/packages/auth-providers/clerk/setup/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../cli-helpers" }] diff --git a/packages/auth-providers/custom/setup/.babelrc.js b/packages/auth-providers/custom/setup/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/custom/setup/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/custom/setup/build.mts b/packages/auth-providers/custom/setup/build.mts new file mode 100644 index 000000000000..b35ee44f5def --- /dev/null +++ b/packages/auth-providers/custom/setup/build.mts @@ -0,0 +1,8 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() + +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['templates/**/*.template'], +}) diff --git a/packages/auth-providers/custom/setup/package.json b/packages/auth-providers/custom/setup/package.json index c0c8f397cb37..cb4cfdce6a65 100644 --- a/packages/auth-providers/custom/setup/package.json +++ b/packages/auth-providers/custom/setup/package.json @@ -7,30 +7,47 @@ "directory": "packages/auth-providers/custom/setup" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/setup": { + "types": "./dist/setup.d.ts", + "default": "./dist/setup.js" + }, + "./dist/setupHandler": { + "types": "./dist/setupHandler.d.ts", + "default": "./dist/setupHandler.js" + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-custom-setup.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@redwoodjs/cli-helpers": "workspace:*", - "core-js": "3.38.0" + "@redwoodjs/cli-helpers": "workspace:*" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/yargs": "17.0.33", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/custom/setup/tsconfig.json b/packages/auth-providers/custom/setup/tsconfig.json index 31fd2566f42e..7a7ec0d32fa2 100644 --- a/packages/auth-providers/custom/setup/tsconfig.json +++ b/packages/auth-providers/custom/setup/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../cli-helpers" }] diff --git a/packages/auth-providers/firebase/setup/.babelrc.js b/packages/auth-providers/firebase/setup/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/firebase/setup/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/firebase/setup/build.mts b/packages/auth-providers/firebase/setup/build.mts new file mode 100644 index 000000000000..b35ee44f5def --- /dev/null +++ b/packages/auth-providers/firebase/setup/build.mts @@ -0,0 +1,8 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() + +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['templates/**/*.template'], +}) diff --git a/packages/auth-providers/firebase/setup/package.json b/packages/auth-providers/firebase/setup/package.json index 3ffce06c2f4e..99e6d6117628 100644 --- a/packages/auth-providers/firebase/setup/package.json +++ b/packages/auth-providers/firebase/setup/package.json @@ -7,30 +7,47 @@ "directory": "packages/auth-providers/firebase/setup" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/setup": { + "types": "./dist/setup.d.ts", + "default": "./dist/setup.js" + }, + "./dist/setupHandler": { + "types": "./dist/setupHandler.d.ts", + "default": "./dist/setupHandler.js" + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-firebase-setup.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@redwoodjs/cli-helpers": "workspace:*", - "core-js": "3.38.0" + "@redwoodjs/cli-helpers": "workspace:*" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/yargs": "17.0.33", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/firebase/setup/tsconfig.json b/packages/auth-providers/firebase/setup/tsconfig.json index 31fd2566f42e..7a7ec0d32fa2 100644 --- a/packages/auth-providers/firebase/setup/tsconfig.json +++ b/packages/auth-providers/firebase/setup/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../cli-helpers" }] diff --git a/packages/auth-providers/netlify/setup/.babelrc.js b/packages/auth-providers/netlify/setup/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/netlify/setup/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/netlify/setup/build.mts b/packages/auth-providers/netlify/setup/build.mts new file mode 100644 index 000000000000..b35ee44f5def --- /dev/null +++ b/packages/auth-providers/netlify/setup/build.mts @@ -0,0 +1,8 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() + +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['templates/**/*.template'], +}) diff --git a/packages/auth-providers/netlify/setup/package.json b/packages/auth-providers/netlify/setup/package.json index 0f7dffb27062..3e1b27366483 100644 --- a/packages/auth-providers/netlify/setup/package.json +++ b/packages/auth-providers/netlify/setup/package.json @@ -7,30 +7,47 @@ "directory": "packages/auth-providers/netlify/setup" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/setup": { + "types": "./dist/setup.d.ts", + "default": "./dist/setup.js" + }, + "./dist/setupHandler": { + "types": "./dist/setupHandler.d.ts", + "default": "./dist/setupHandler.js" + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-netlify-setup.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@redwoodjs/cli-helpers": "workspace:*", - "core-js": "3.38.0" + "@redwoodjs/cli-helpers": "workspace:*" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/yargs": "17.0.33", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/netlify/setup/tsconfig.json b/packages/auth-providers/netlify/setup/tsconfig.json index 31fd2566f42e..7a7ec0d32fa2 100644 --- a/packages/auth-providers/netlify/setup/tsconfig.json +++ b/packages/auth-providers/netlify/setup/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../cli-helpers" }] diff --git a/packages/auth-providers/supabase/setup/.babelrc.js b/packages/auth-providers/supabase/setup/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/supabase/setup/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/supabase/setup/build.mts b/packages/auth-providers/supabase/setup/build.mts new file mode 100644 index 000000000000..b35ee44f5def --- /dev/null +++ b/packages/auth-providers/supabase/setup/build.mts @@ -0,0 +1,8 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() + +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['templates/**/*.template'], +}) diff --git a/packages/auth-providers/supabase/setup/package.json b/packages/auth-providers/supabase/setup/package.json index 8c3334654b3f..8374370226fb 100644 --- a/packages/auth-providers/supabase/setup/package.json +++ b/packages/auth-providers/supabase/setup/package.json @@ -7,28 +7,45 @@ "directory": "packages/auth-providers/supabase/setup" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/setup": { + "types": "./dist/setup.d.ts", + "default": "./dist/setup.js" + }, + "./dist/setupHandler": { + "types": "./dist/setupHandler.d.ts", + "default": "./dist/setupHandler.js" + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-supabase-setup.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@redwoodjs/cli-helpers": "workspace:*", - "core-js": "3.38.0" + "@redwoodjs/cli-helpers": "workspace:*" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/yargs": "17.0.33", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4" }, "gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1" diff --git a/packages/auth-providers/supabase/setup/tsconfig.json b/packages/auth-providers/supabase/setup/tsconfig.json index 31fd2566f42e..7a7ec0d32fa2 100644 --- a/packages/auth-providers/supabase/setup/tsconfig.json +++ b/packages/auth-providers/supabase/setup/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../cli-helpers" }] diff --git a/packages/auth-providers/supertokens/setup/.babelrc.js b/packages/auth-providers/supertokens/setup/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/supertokens/setup/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/supertokens/setup/build.mts b/packages/auth-providers/supertokens/setup/build.mts new file mode 100644 index 000000000000..b35ee44f5def --- /dev/null +++ b/packages/auth-providers/supertokens/setup/build.mts @@ -0,0 +1,8 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() + +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['templates/**/*.template'], +}) diff --git a/packages/auth-providers/supertokens/setup/package.json b/packages/auth-providers/supertokens/setup/package.json index b327fe20cb9c..c79730e601ea 100644 --- a/packages/auth-providers/supertokens/setup/package.json +++ b/packages/auth-providers/supertokens/setup/package.json @@ -7,31 +7,48 @@ "directory": "packages/auth-providers/supertokens/setup" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./dist/setup": { + "types": "./dist/setup.d.ts", + "default": "./dist/setup.js" + }, + "./dist/setupHandler": { + "types": "./dist/setupHandler.d.ts", + "default": "./dist/setupHandler.js" + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-supertokens-setup.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@redwoodjs/cli-helpers": "workspace:*", - "core-js": "3.38.0" + "@redwoodjs/cli-helpers": "workspace:*" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/yargs": "17.0.33", + "concurrently": "8.2.2", "memfs": "4.11.1", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/supertokens/setup/tsconfig.json b/packages/auth-providers/supertokens/setup/tsconfig.json index 31fd2566f42e..7a7ec0d32fa2 100644 --- a/packages/auth-providers/supertokens/setup/tsconfig.json +++ b/packages/auth-providers/supertokens/setup/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../cli-helpers" }] diff --git a/packages/cli-helpers/package.json b/packages/cli-helpers/package.json index dde157b48432..974fbf958b4d 100644 --- a/packages/cli-helpers/package.json +++ b/packages/cli-helpers/package.json @@ -10,19 +10,34 @@ "type": "module", "exports": { ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "default": "./dist/cjs/index.js" + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "default": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } }, "./loadEnvFiles": { - "types": "./dist/lib/loadEnvFiles.d.ts", - "import": "./dist/lib/loadEnvFiles.js", - "default": "./dist/cjs/lib/loadEnvFiles.js" + "import": { + "types": "./dist/lib/loadEnvFiles.d.ts", + "default": "./dist/lib/loadEnvFiles.js" + }, + "default": { + "types": "./dist/cjs/lib/loadEnvFiles.d.ts", + "default": "./dist/cjs/lib/loadEnvFiles.js" + } }, "./dist/lib/loadEnvFiles.js": { - "types": "./dist/lib/loadEnvFiles.d.ts", - "import": "./dist/lib/loadEnvFiles.js", - "default": "./dist/cjs/lib/loadEnvFiles.js" + "import": { + "types": "./dist/lib/loadEnvFiles.d.ts", + "default": "./dist/lib/loadEnvFiles.js" + }, + "default": { + "types": "./dist/cjs/lib/loadEnvFiles.d.ts", + "default": "./dist/cjs/lib/loadEnvFiles.js" + } } }, "types": "./dist/index.d.ts", @@ -32,7 +47,7 @@ "scripts": { "build": "tsx ./build.ts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-cli-helpers.tgz", - "build:types": "tsc --build --verbose tsconfig.build.json", + "build:types": "tsc --build --verbose ./tsconfig.build.json ./tsconfig.build.cjs.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", diff --git a/packages/cli-helpers/tsconfig.build.cjs.json b/packages/cli-helpers/tsconfig.build.cjs.json new file mode 100644 index 000000000000..40b7e3f22c42 --- /dev/null +++ b/packages/cli-helpers/tsconfig.build.cjs.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.build.json", + "compilerOptions": { + "outDir": "dist/cjs", + "module": "CommonJS", + "moduleResolution": "Node10", + "tsBuildInfoFile": "./tsconfig.cjs.tsbuildinfo" + } +} diff --git a/packages/framework-tools/src/buildDefaults.ts b/packages/framework-tools/src/buildDefaults.ts index 17de5d4fb8da..a908448e8307 100644 --- a/packages/framework-tools/src/buildDefaults.ts +++ b/packages/framework-tools/src/buildDefaults.ts @@ -1,4 +1,5 @@ import path from 'node:path' +import { fileURLToPath } from 'node:url' import * as esbuild from 'esbuild' import type { BuildOptions as ESBuildOptions } from 'esbuild' @@ -83,3 +84,46 @@ export async function build({ ) } } + +interface CopyAssetsOptions { + buildFileUrl: string + patterns: string[] + ignore?: string[] +} + +export async function copyAssets({ + buildFileUrl, + patterns, + ignore, +}: CopyAssetsOptions) { + const rootDirPath = path.dirname(fileURLToPath(buildFileUrl)) + const srcDirPath = path.join(rootDirPath, 'src') + const distDirPath = path.join(rootDirPath, 'dist') + + let pathnames = await fg(patterns, { + absolute: true, + cwd: srcDirPath, + ignore: ignore ?? defaultIgnorePatterns, + }) + + // For Windows. + pathnames = pathnames.map((p) => path.normalize(p)) + + for (const pathname of pathnames) { + const distPathname = pathname.replace(srcDirPath, distDirPath) + + try { + await fs.mkdirp(path.dirname(distPathname)) + await fs.copyFile(pathname, distPathname) + console.log( + `Copied asset into dist: ${path.relative(distDirPath, distPathname)}`, + ) + } catch (error) { + console.error( + `Couldn't copy ${pathname} to ${distPathname}. ` + + `(Replaced ${srcDirPath} with ${distDirPath} to get the dist pathname.)`, + ) + throw error + } + } +} diff --git a/yarn.lock b/yarn.lock index 32dec80ebcd6..149a70b4eed0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7275,12 +7275,13 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-auth0-setup@workspace:packages/auth-providers/auth0/setup" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/cli-helpers": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/yargs": "npm:17.0.33" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7327,12 +7328,13 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-azure-active-directory-setup@workspace:packages/auth-providers/azureActiveDirectory/setup" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/cli-helpers": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/yargs": "npm:17.0.33" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7378,12 +7380,13 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-clerk-setup@workspace:packages/auth-providers/clerk/setup" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/cli-helpers": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/yargs": "npm:17.0.33" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" languageName: unknown linkType: soft @@ -7412,12 +7415,13 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-custom-setup@workspace:packages/auth-providers/custom/setup" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/cli-helpers": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/yargs": "npm:17.0.33" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7524,12 +7528,13 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-firebase-setup@workspace:packages/auth-providers/firebase/setup" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/cli-helpers": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/yargs": "npm:17.0.33" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7576,12 +7581,13 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-netlify-setup@workspace:packages/auth-providers/netlify/setup" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/cli-helpers": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/yargs": "npm:17.0.33" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7650,12 +7656,13 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-supabase-setup@workspace:packages/auth-providers/supabase/setup" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/cli-helpers": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/yargs": "npm:17.0.33" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" languageName: unknown linkType: soft @@ -7703,13 +7710,14 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-supertokens-setup@workspace:packages/auth-providers/supertokens/setup" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/cli-helpers": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/yargs": "npm:17.0.33" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" memfs: "npm:4.11.1" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown From ddfb0805708adc1bc024bb23106f59138a376723 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sun, 18 Aug 2024 02:18:26 +0100 Subject: [PATCH 44/52] fix(auth-providers): Move away from babel for building 'api' packages (#11301) This switches from babel to esbuild for building the 'api' auth provider packages. I added `exports` to the package.json. I added all existing files to the exports field. I updated the tsconfig files to use `Node16` module and module resolution. I explicitly set the tsbuildinfo file too. My thinking is that we can be explicit to start with. Once we have all our packages over to esbuild and know the lay of the land then we can deduplicate/refactor our configs. This is a chore but does effect what gets shipped so I'll label it as fix and mark it as next-release. --- packages/auth-providers/auth0/api/.babelrc.js | 1 - packages/auth-providers/auth0/api/build.mts | 3 + .../auth-providers/auth0/api/package.json | 31 ++++++-- .../auth-providers/auth0/api/tsconfig.json | 5 +- .../azureActiveDirectory/api/.babelrc.js | 1 - .../azureActiveDirectory/api/build.mts | 3 + .../azureActiveDirectory/api/package.json | 31 ++++++-- .../azureActiveDirectory/api/tsconfig.json | 5 +- packages/auth-providers/clerk/api/.babelrc.js | 1 - packages/auth-providers/clerk/api/build.mts | 3 + .../auth-providers/clerk/api/package.json | 33 ++++++--- .../auth-providers/clerk/api/tsconfig.json | 5 +- .../auth-providers/dbAuth/api/.babelrc.js | 1 - packages/auth-providers/dbAuth/api/build.mts | 3 + .../auth-providers/dbAuth/api/package.json | 49 +++++++++++-- .../auth-providers/dbAuth/api/tsconfig.json | 5 +- .../auth-providers/firebase/api/.babelrc.js | 1 - .../auth-providers/firebase/api/build.mts | 3 + .../auth-providers/firebase/api/package.json | 31 ++++++-- .../auth-providers/firebase/api/tsconfig.json | 5 +- .../auth-providers/netlify/api/.babelrc.js | 1 - packages/auth-providers/netlify/api/build.mts | 3 + .../auth-providers/netlify/api/package.json | 31 ++++++-- .../auth-providers/netlify/api/tsconfig.json | 5 +- .../auth-providers/supabase/api/.babelrc.js | 1 - .../auth-providers/supabase/api/build.mts | 3 + .../auth-providers/supabase/api/package.json | 31 ++++++-- .../auth-providers/supabase/api/tsconfig.json | 5 +- .../supertokens/api/.babelrc.js | 1 - .../auth-providers/supertokens/api/build.mts | 3 + .../supertokens/api/package.json | 31 ++++++-- .../supertokens/api/tsconfig.json | 5 +- yarn.lock | 72 ++++++++++--------- 33 files changed, 307 insertions(+), 105 deletions(-) delete mode 100644 packages/auth-providers/auth0/api/.babelrc.js create mode 100644 packages/auth-providers/auth0/api/build.mts delete mode 100644 packages/auth-providers/azureActiveDirectory/api/.babelrc.js create mode 100644 packages/auth-providers/azureActiveDirectory/api/build.mts delete mode 100644 packages/auth-providers/clerk/api/.babelrc.js create mode 100644 packages/auth-providers/clerk/api/build.mts delete mode 100644 packages/auth-providers/dbAuth/api/.babelrc.js create mode 100644 packages/auth-providers/dbAuth/api/build.mts delete mode 100644 packages/auth-providers/firebase/api/.babelrc.js create mode 100644 packages/auth-providers/firebase/api/build.mts delete mode 100644 packages/auth-providers/netlify/api/.babelrc.js create mode 100644 packages/auth-providers/netlify/api/build.mts delete mode 100644 packages/auth-providers/supabase/api/.babelrc.js create mode 100644 packages/auth-providers/supabase/api/build.mts delete mode 100644 packages/auth-providers/supertokens/api/.babelrc.js create mode 100644 packages/auth-providers/supertokens/api/build.mts diff --git a/packages/auth-providers/auth0/api/.babelrc.js b/packages/auth-providers/auth0/api/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/auth0/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/auth0/api/build.mts b/packages/auth-providers/auth0/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/auth-providers/auth0/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/auth-providers/auth0/api/package.json b/packages/auth-providers/auth0/api/package.json index 5d6f1bbb8ede..10cbd6251643 100644 --- a/packages/auth-providers/auth0/api/package.json +++ b/packages/auth-providers/auth0/api/package.json @@ -7,32 +7,49 @@ "directory": "packages/auth-providers/auth0/api" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "default": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "./dist/decoder": { + "default": { + "types": "./dist/decoder.d.ts", + "default": "./dist/decoder.js" + } + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-auth0-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "core-js": "3.38.0", "jsonwebtoken": "9.0.2", "jwks-rsa": "3.1.0" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/api": "workspace:*", + "@redwoodjs/framework-tools": "workspace:*", "@types/jsonwebtoken": "9.0.6", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/auth0/api/tsconfig.json b/packages/auth-providers/auth0/api/tsconfig.json index 6b8ec4efb25c..5f48476e8ec5 100644 --- a/packages/auth-providers/auth0/api/tsconfig.json +++ b/packages/auth-providers/auth0/api/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../api" }] diff --git a/packages/auth-providers/azureActiveDirectory/api/.babelrc.js b/packages/auth-providers/azureActiveDirectory/api/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/azureActiveDirectory/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/azureActiveDirectory/api/build.mts b/packages/auth-providers/azureActiveDirectory/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/auth-providers/azureActiveDirectory/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/auth-providers/azureActiveDirectory/api/package.json b/packages/auth-providers/azureActiveDirectory/api/package.json index 9f236bf572e4..76302388d6fe 100644 --- a/packages/auth-providers/azureActiveDirectory/api/package.json +++ b/packages/auth-providers/azureActiveDirectory/api/package.json @@ -7,33 +7,50 @@ "directory": "packages/auth-providers/azureActiveDirectory/api" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "default": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "./dist/decoder": { + "default": { + "types": "./dist/decoder.d.ts", + "default": "./dist/decoder.js" + } + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-azure-active-directory-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "core-js": "3.38.0", "jsonwebtoken": "9.0.2", "jwks-rsa": "3.1.0" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/api": "workspace:*", + "@redwoodjs/framework-tools": "workspace:*", "@types/aws-lambda": "8.10.143", "@types/jsonwebtoken": "9.0.6", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/azureActiveDirectory/api/tsconfig.json b/packages/auth-providers/azureActiveDirectory/api/tsconfig.json index 6b8ec4efb25c..5f48476e8ec5 100644 --- a/packages/auth-providers/azureActiveDirectory/api/tsconfig.json +++ b/packages/auth-providers/azureActiveDirectory/api/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../api" }] diff --git a/packages/auth-providers/clerk/api/.babelrc.js b/packages/auth-providers/clerk/api/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/clerk/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/clerk/api/build.mts b/packages/auth-providers/clerk/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/auth-providers/clerk/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/auth-providers/clerk/api/package.json b/packages/auth-providers/clerk/api/package.json index e77bbf75e210..200b743d2245 100644 --- a/packages/auth-providers/clerk/api/package.json +++ b/packages/auth-providers/clerk/api/package.json @@ -7,31 +7,48 @@ "directory": "packages/auth-providers/clerk/api" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "default": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "./dist/decoder": { + "default": { + "types": "./dist/decoder.d.ts", + "default": "./dist/decoder.js" + } + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-clerk-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "@clerk/clerk-sdk-node": "4.13.21", - "core-js": "3.38.0" + "@clerk/clerk-sdk-node": "4.13.21" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/api": "workspace:*", + "@redwoodjs/framework-tools": "workspace:*", "@types/aws-lambda": "8.10.143", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/clerk/api/tsconfig.json b/packages/auth-providers/clerk/api/tsconfig.json index 6b8ec4efb25c..5f48476e8ec5 100644 --- a/packages/auth-providers/clerk/api/tsconfig.json +++ b/packages/auth-providers/clerk/api/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../api" }] diff --git a/packages/auth-providers/dbAuth/api/.babelrc.js b/packages/auth-providers/dbAuth/api/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/dbAuth/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/dbAuth/api/build.mts b/packages/auth-providers/dbAuth/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/auth-providers/dbAuth/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/auth-providers/dbAuth/api/package.json b/packages/auth-providers/dbAuth/api/package.json index 9b221d731c91..fceceea517b3 100644 --- a/packages/auth-providers/dbAuth/api/package.json +++ b/packages/auth-providers/dbAuth/api/package.json @@ -7,36 +7,71 @@ "directory": "packages/auth-providers/dbAuth/api" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "default": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "./dist/decoder": { + "default": { + "types": "./dist/decoder.d.ts", + "default": "./dist/decoder.js" + } + }, + "./dist/errors": { + "default": { + "types": "./dist/errors.d.ts", + "default": "./dist/errors.js" + } + }, + "./dist/shared": { + "default": { + "types": "./dist/shared.d.ts", + "default": "./dist/shared.js" + } + }, + "./dist/DbAuthHandler": { + "default": { + "types": "./dist/DbAuthHandler.d.ts", + "default": "./dist/DbAuthHandler.js" + } + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-dbauth-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", "@redwoodjs/project-config": "workspace:*", "base64url": "3.0.1", - "core-js": "3.38.0", "md5": "2.3.0", "uuid": "10.0.0" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/api": "workspace:*", + "@redwoodjs/framework-tools": "workspace:*", "@simplewebauthn/server": "7.4.0", "@types/md5": "2.3.5", "@types/uuid": "10.0.0", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/dbAuth/api/tsconfig.json b/packages/auth-providers/dbAuth/api/tsconfig.json index 9cf53b22c9c0..f01d25beaf87 100644 --- a/packages/auth-providers/dbAuth/api/tsconfig.json +++ b/packages/auth-providers/dbAuth/api/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [ diff --git a/packages/auth-providers/firebase/api/.babelrc.js b/packages/auth-providers/firebase/api/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/firebase/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/firebase/api/build.mts b/packages/auth-providers/firebase/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/auth-providers/firebase/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/auth-providers/firebase/api/package.json b/packages/auth-providers/firebase/api/package.json index e904c9bc9e89..f0247dbb837e 100644 --- a/packages/auth-providers/firebase/api/package.json +++ b/packages/auth-providers/firebase/api/package.json @@ -7,31 +7,48 @@ "directory": "packages/auth-providers/firebase/api" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "default": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "./dist/decoder": { + "default": { + "types": "./dist/decoder.d.ts", + "default": "./dist/decoder.js" + } + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-firebase-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "core-js": "3.38.0", "firebase-admin": "12.3.1" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/api": "workspace:*", + "@redwoodjs/framework-tools": "workspace:*", "@types/aws-lambda": "8.10.143", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/firebase/api/tsconfig.json b/packages/auth-providers/firebase/api/tsconfig.json index 6b8ec4efb25c..5f48476e8ec5 100644 --- a/packages/auth-providers/firebase/api/tsconfig.json +++ b/packages/auth-providers/firebase/api/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../api" }] diff --git a/packages/auth-providers/netlify/api/.babelrc.js b/packages/auth-providers/netlify/api/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/netlify/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/netlify/api/build.mts b/packages/auth-providers/netlify/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/auth-providers/netlify/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/auth-providers/netlify/api/package.json b/packages/auth-providers/netlify/api/package.json index 693903bf910d..9d56dbb8e14b 100644 --- a/packages/auth-providers/netlify/api/package.json +++ b/packages/auth-providers/netlify/api/package.json @@ -7,32 +7,49 @@ "directory": "packages/auth-providers/netlify/api" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "default": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "./dist/decoder": { + "default": { + "types": "./dist/decoder.d.ts", + "default": "./dist/decoder.js" + } + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-netlify-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "core-js": "3.38.0", "jsonwebtoken": "9.0.2" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/api": "workspace:*", + "@redwoodjs/framework-tools": "workspace:*", "@types/aws-lambda": "8.10.143", "@types/jsonwebtoken": "9.0.6", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/netlify/api/tsconfig.json b/packages/auth-providers/netlify/api/tsconfig.json index 6b8ec4efb25c..5f48476e8ec5 100644 --- a/packages/auth-providers/netlify/api/tsconfig.json +++ b/packages/auth-providers/netlify/api/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../api" }] diff --git a/packages/auth-providers/supabase/api/.babelrc.js b/packages/auth-providers/supabase/api/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/supabase/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/supabase/api/build.mts b/packages/auth-providers/supabase/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/auth-providers/supabase/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/auth-providers/supabase/api/package.json b/packages/auth-providers/supabase/api/package.json index ba5b8a375800..309e0d0e9b2f 100644 --- a/packages/auth-providers/supabase/api/package.json +++ b/packages/auth-providers/supabase/api/package.json @@ -7,33 +7,50 @@ "directory": "packages/auth-providers/supabase/api" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "default": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "./dist/decoder": { + "default": { + "types": "./dist/decoder.d.ts", + "default": "./dist/decoder.js" + } + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-supabase-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", "@redwoodjs/api": "workspace:*", "@supabase/ssr": "0.4.0", - "core-js": "3.38.0", "jsonwebtoken": "9.0.2" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/aws-lambda": "8.10.143", "@types/jsonwebtoken": "9.0.6", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/supabase/api/tsconfig.json b/packages/auth-providers/supabase/api/tsconfig.json index 6b8ec4efb25c..5f48476e8ec5 100644 --- a/packages/auth-providers/supabase/api/tsconfig.json +++ b/packages/auth-providers/supabase/api/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../api" }] diff --git a/packages/auth-providers/supertokens/api/.babelrc.js b/packages/auth-providers/supertokens/api/.babelrc.js deleted file mode 100644 index 4312886a07e5..000000000000 --- a/packages/auth-providers/supertokens/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../../../babel.config.js' } diff --git a/packages/auth-providers/supertokens/api/build.mts b/packages/auth-providers/supertokens/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/auth-providers/supertokens/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/auth-providers/supertokens/api/package.json b/packages/auth-providers/supertokens/api/package.json index dced3a306d58..95329899edad 100644 --- a/packages/auth-providers/supertokens/api/package.json +++ b/packages/auth-providers/supertokens/api/package.json @@ -7,32 +7,49 @@ "directory": "packages/auth-providers/supertokens/api" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "default": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "./dist/decoder": { + "default": { + "types": "./dist/decoder.d.ts", + "default": "./dist/decoder.js" + } + } + }, "main": "./dist/index.js", "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\" --copy-files --no-copy-ignored", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-auth-supertokens-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", - "core-js": "3.38.0", "jsonwebtoken": "9.0.2", "jwks-rsa": "3.1.0" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/api": "workspace:*", + "@redwoodjs/framework-tools": "workspace:*", "@types/jsonwebtoken": "9.0.6", + "concurrently": "8.2.2", + "publint": "0.2.10", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/auth-providers/supertokens/api/tsconfig.json b/packages/auth-providers/supertokens/api/tsconfig.json index 6b8ec4efb25c..5f48476e8ec5 100644 --- a/packages/auth-providers/supertokens/api/tsconfig.json +++ b/packages/auth-providers/supertokens/api/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "strict": true, "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src"], "references": [{ "path": "../../../api" }] diff --git a/yarn.lock b/yarn.lock index 149a70b4eed0..2c7089a52f68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7258,14 +7258,15 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-auth0-api@workspace:packages/auth-providers/auth0/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/api": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/jsonwebtoken": "npm:9.0.6" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" jsonwebtoken: "npm:9.0.2" jwks-rsa: "npm:3.1.0" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7310,15 +7311,16 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-azure-active-directory-api@workspace:packages/auth-providers/azureActiveDirectory/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/api": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/aws-lambda": "npm:8.10.143" "@types/jsonwebtoken": "npm:9.0.6" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" jsonwebtoken: "npm:9.0.2" jwks-rsa: "npm:3.1.0" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7364,13 +7366,14 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-clerk-api@workspace:packages/auth-providers/clerk/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@clerk/clerk-sdk-node": "npm:4.13.21" "@redwoodjs/api": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/aws-lambda": "npm:8.10.143" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7431,17 +7434,18 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-dbauth-api@workspace:packages/auth-providers/dbAuth/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/api": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@redwoodjs/project-config": "workspace:*" "@simplewebauthn/server": "npm:7.4.0" "@types/md5": "npm:2.3.5" "@types/uuid": "npm:10.0.0" base64url: "npm:3.0.1" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" md5: "npm:2.3.0" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" uuid: "npm:10.0.0" vitest: "npm:2.0.5" @@ -7512,13 +7516,14 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-firebase-api@workspace:packages/auth-providers/firebase/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/api": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/aws-lambda": "npm:8.10.143" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" firebase-admin: "npm:12.3.1" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7564,14 +7569,15 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-netlify-api@workspace:packages/auth-providers/netlify/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/api": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/aws-lambda": "npm:8.10.143" "@types/jsonwebtoken": "npm:9.0.6" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" jsonwebtoken: "npm:9.0.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7616,15 +7622,16 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-supabase-api@workspace:packages/auth-providers/supabase/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/api": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@supabase/ssr": "npm:0.4.0" "@types/aws-lambda": "npm:8.10.143" "@types/jsonwebtoken": "npm:9.0.6" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" jsonwebtoken: "npm:9.0.2" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" languageName: unknown @@ -7691,14 +7698,15 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/auth-supertokens-api@workspace:packages/auth-providers/supertokens/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@redwoodjs/api": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@types/jsonwebtoken": "npm:9.0.6" - core-js: "npm:3.38.0" + concurrently: "npm:8.2.2" jsonwebtoken: "npm:9.0.2" jwks-rsa: "npm:3.1.0" + publint: "npm:0.2.10" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" peerDependencies: From ab6633abf20af81558d805b4acbc2b62fef885ff Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sun, 18 Aug 2024 03:40:27 +0100 Subject: [PATCH 45/52] fix(internal): Move away from babel for building package (#11304) This switches to esbuild over babel. I added exports entries for every use I could find in the framework. Internal isn't designed to be used externally so people should not have considered reaching into dist as stable anyway. I decided to mark this as breaking since it ultimately is. --- packages/internal/.babelrc.js | 1 - packages/internal/build.mts | 7 +++++ packages/internal/package.json | 56 ++++++++++++++++++++++++++++++--- packages/internal/tsconfig.json | 5 ++- yarn.lock | 5 ++- 5 files changed, 67 insertions(+), 7 deletions(-) delete mode 100644 packages/internal/.babelrc.js create mode 100644 packages/internal/build.mts diff --git a/packages/internal/.babelrc.js b/packages/internal/.babelrc.js deleted file mode 100644 index 3b2c815712d9..000000000000 --- a/packages/internal/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../babel.config.js' } diff --git a/packages/internal/build.mts b/packages/internal/build.mts new file mode 100644 index 000000000000..ecc19f75a3c8 --- /dev/null +++ b/packages/internal/build.mts @@ -0,0 +1,7 @@ +import { build, copyAssets } from '@redwoodjs/framework-tools' + +await build() +await copyAssets({ + buildFileUrl: import.meta.url, + patterns: ['generate/templates/**/*.template'], +}) diff --git a/packages/internal/package.json b/packages/internal/package.json index 21f7015e27f1..eaedd313d24a 100644 --- a/packages/internal/package.json +++ b/packages/internal/package.json @@ -7,6 +7,50 @@ "directory": "packages/internal" }, "license": "MIT", + "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./package.json": "./package.json", + "./dist/dev": { + "types": "./dist/dev.d.ts", + "default": "./dist/dev.js" + }, + "./dist/files": { + "types": "./dist/files.d.ts", + "default": "./dist/files.js" + }, + "./dist/files.js": { + "types": "./dist/files.d.ts", + "default": "./dist/files.js" + }, + "./dist/gql": { + "types": "./dist/gql.d.ts", + "default": "./dist/gql.js" + }, + "./dist/routes.js": { + "types": "./dist/routes.d.ts", + "default": "./dist/routes.js" + }, + "./dist/ts2js": { + "types": "./dist/ts2js.d.ts", + "default": "./dist/ts2js.js" + }, + "./dist/validateSchema": { + "types": "./dist/validateSchema.d.ts", + "default": "./dist/validateSchema.js" + }, + "./dist/build/api": { + "types": "./dist/build/api.d.ts", + "default": "./dist/build/api.js" + }, + "./dist/generate/generate": { + "types": "./dist/generate/generate.d.ts", + "default": "./dist/generate/generate.js" + } + }, "main": "dist/index.js", "types": "dist/index.d.ts", "bin": { @@ -17,12 +61,13 @@ "dist" ], "scripts": { - "build": "yarn build:js && yarn build:types", + "build": "tsx ./build.mts && yarn build:types", "build:clean-dist": "rimraf 'dist/**/*/__tests__' --glob", - "build:js": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\" --copy-files --no-copy-ignored && yarn build:clean-dist", "build:pack": "yarn pack -o redwoodjs-internal.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "fix:permissions": "chmod +x dist/generate/generate.js dist/generate/watch.js", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", @@ -70,9 +115,12 @@ "typescript": "5.5.4" }, "devDependencies": { - "@babel/cli": "7.24.8", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/fs-extra": "11.0.4", + "concurrently": "8.2.2", "graphql-tag": "2.12.6", + "publint": "0.2.10", "tsx": "4.17.0", "vitest": "2.0.5" }, diff --git a/packages/internal/tsconfig.json b/packages/internal/tsconfig.json index cbc1a3ef398c..e0ba04a6a84f 100644 --- a/packages/internal/tsconfig.json +++ b/packages/internal/tsconfig.json @@ -2,7 +2,10 @@ "extends": "../../tsconfig.compilerOption.json", "compilerOptions": { "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src/**/*", "./ambient.d.ts"], "references": [ diff --git a/yarn.lock b/yarn.lock index 2c7089a52f68..a085359a165d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8213,7 +8213,7 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/internal@workspace:packages/internal" dependencies: - "@babel/cli": "npm:7.24.8" + "@arethetypeswrong/cli": "npm:0.15.4" "@babel/core": "npm:^7.22.20" "@babel/parser": "npm:^7.22.16" "@babel/plugin-transform-react-jsx": "npm:^7.22.15" @@ -8233,12 +8233,14 @@ __metadata: "@graphql-codegen/typescript-resolvers": "npm:3.2.1" "@graphql-tools/documents": "npm:1.0.1" "@redwoodjs/babel-config": "workspace:*" + "@redwoodjs/framework-tools": "workspace:*" "@redwoodjs/graphql-server": "workspace:*" "@redwoodjs/project-config": "workspace:*" "@redwoodjs/router": "workspace:*" "@sdl-codegen/node": "npm:1.0.2" "@types/fs-extra": "npm:11.0.4" chalk: "npm:4.1.2" + concurrently: "npm:8.2.2" core-js: "npm:3.38.0" deepmerge: "npm:4.3.1" esbuild: "npm:0.23.0" @@ -8248,6 +8250,7 @@ __metadata: graphql-tag: "npm:2.12.6" kill-port: "npm:1.6.1" prettier: "npm:3.3.3" + publint: "npm:0.2.10" rimraf: "npm:6.0.1" source-map: "npm:0.7.4" string-env-interpolation: "npm:1.0.1" From c72c31780a84fa81b9e639ef77cfee680a4f442f Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sun, 18 Aug 2024 03:59:13 +0100 Subject: [PATCH 46/52] fix(api): Move away from babel for building package (#11305) Build the api package with esbuild instead of babel. I will follow up with a separate specific PR to introduce the exports field and remove the need for the files redirection thing that had to be done previously. --- packages/api/.babelrc.js | 1 - packages/api/build.mts | 3 +++ packages/api/package.json | 17 ++++++++++------- packages/api/tsconfig.json | 5 ++++- yarn.lock | 9 +++++---- 5 files changed, 22 insertions(+), 13 deletions(-) delete mode 100644 packages/api/.babelrc.js create mode 100644 packages/api/build.mts diff --git a/packages/api/.babelrc.js b/packages/api/.babelrc.js deleted file mode 100644 index 3b2c815712d9..000000000000 --- a/packages/api/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../babel.config.js' } diff --git a/packages/api/build.mts b/packages/api/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/api/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/api/package.json b/packages/api/package.json index f984a71c2958..1a6c91f9e9e2 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -7,6 +7,7 @@ "directory": "packages/api" }, "license": "MIT", + "type": "commonjs", "main": "./dist/index.js", "types": "./dist/index.d.ts", "bin": { @@ -22,21 +23,20 @@ "webhooks" ], "scripts": { - "build": "yarn build:js && yarn build:types", - "build:js": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\"", + "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-api.tgz", - "build:types": "tsc --build --verbose", + "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"", + "check:attw": "yarn attw -P", + "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", "test:watch": "vitest watch" }, "dependencies": { - "@babel/runtime-corejs3": "7.25.0", "@prisma/client": "5.18.0", "@whatwg-node/fetch": "0.9.20", "cookie": "0.6.0", - "core-js": "3.38.0", "humanize-string": "2.1.0", "jsonwebtoken": "9.0.2", "pascalcase": "1.0.0", @@ -44,17 +44,20 @@ "title-case": "3.0.3" }, "devDependencies": { - "@babel/cli": "7.24.8", - "@babel/core": "^7.22.20", + "@arethetypeswrong/cli": "0.15.4", + "@redwoodjs/framework-tools": "workspace:*", "@types/aws-lambda": "8.10.143", "@types/jsonwebtoken": "9.0.6", "@types/memjs": "1", "@types/pascalcase": "1.0.3", "@types/split2": "4.2.3", + "concurrently": "8.2.2", "memjs": "1.3.2", + "publint": "0.2.10", "redis": "4.7.0", "split2": "4.2.0", "ts-toolbelt": "9.6.0", + "tsx": "4.17.0", "typescript": "5.5.4", "vitest": "2.0.5" }, diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index 808b868a6dca..801c836e11b7 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -2,7 +2,10 @@ "extends": "../../tsconfig.compilerOption.json", "compilerOptions": { "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" }, "include": ["src/**/*"] } diff --git a/yarn.lock b/yarn.lock index a085359a165d..95119284b8d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7215,27 +7215,28 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/api@workspace:packages/api" dependencies: - "@babel/cli": "npm:7.24.8" - "@babel/core": "npm:^7.22.20" - "@babel/runtime-corejs3": "npm:7.25.0" + "@arethetypeswrong/cli": "npm:0.15.4" "@prisma/client": "npm:5.18.0" + "@redwoodjs/framework-tools": "workspace:*" "@types/aws-lambda": "npm:8.10.143" "@types/jsonwebtoken": "npm:9.0.6" "@types/memjs": "npm:1" "@types/pascalcase": "npm:1.0.3" "@types/split2": "npm:4.2.3" "@whatwg-node/fetch": "npm:0.9.20" + concurrently: "npm:8.2.2" cookie: "npm:0.6.0" - core-js: "npm:3.38.0" humanize-string: "npm:2.1.0" jsonwebtoken: "npm:9.0.2" memjs: "npm:1.3.2" pascalcase: "npm:1.0.0" pino: "npm:9.3.2" + publint: "npm:0.2.10" redis: "npm:4.7.0" split2: "npm:4.2.0" title-case: "npm:3.0.3" ts-toolbelt: "npm:9.6.0" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" peerDependencies: From ee4fb18360751b78ce82aa5d8e130fe00798b7d3 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sun, 18 Aug 2024 04:23:27 +0100 Subject: [PATCH 47/52] fix(codemods): Move away from babel for building package (#11306) Switch from babel to esbuild for building the codemods package. I consider this package a little more fragile than most of ours simply because it contains code which was written a long time ago. I haven't removed any dependencies or introduce the exports field here. Can follow up with that when/if needed. --- packages/codemods/.babelrc.js | 1 - packages/codemods/build.mts | 3 +++ packages/codemods/package.json | 8 ++++++-- packages/codemods/tsconfig.json | 4 +++- yarn.lock | 3 +++ 5 files changed, 15 insertions(+), 4 deletions(-) delete mode 100644 packages/codemods/.babelrc.js create mode 100644 packages/codemods/build.mts diff --git a/packages/codemods/.babelrc.js b/packages/codemods/.babelrc.js deleted file mode 100644 index 3b2c815712d9..000000000000 --- a/packages/codemods/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: '../../babel.config.js' } diff --git a/packages/codemods/build.mts b/packages/codemods/build.mts new file mode 100644 index 000000000000..16175a6725c0 --- /dev/null +++ b/packages/codemods/build.mts @@ -0,0 +1,3 @@ +import { build } from '@redwoodjs/framework-tools' + +await build() diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 33434cb0c239..8208a6138a67 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -8,15 +8,16 @@ "directory": "packages/codemods" }, "license": "MIT", + "type": "commonjs", "bin": "./dist/codemods.js", "files": [ "dist" ], "scripts": { - "build": "yarn build:js", - "build:js": "babel src -d dist --extensions \".js,.ts\" --ignore \"src/**/__tests__/**\" --ignore \"src/**/__testfixtures__/**\"", + "build": "tsx ./build.mts", "build:pack": "yarn pack -o redwoodjs-codemods.tgz", "build:watch": "nodemon --watch src --ignore dist --exec \"yarn build\"", + "check:package": "yarn publint", "generate:codemod": "yarn node ./tasks/generateCodemod/generateCodemod.mjs", "prepublishOnly": "yarn build", "test": "vitest run", @@ -48,12 +49,15 @@ "yargs": "17.7.2" }, "devDependencies": { + "@redwoodjs/framework-tools": "workspace:*", "@types/babel__core": "7.20.5", "@types/fs-extra": "11.0.4", "@types/jscodeshift": "0.11.11", "@types/yargs": "17.0.33", "fs-extra": "11.2.0", + "publint": "0.2.10", "tempy": "1.0.1", + "tsx": "4.17.0", "vitest": "2.0.5" }, "gitHead": "3905ed045508b861b495f8d5630d76c7a157d8f1" diff --git a/packages/codemods/tsconfig.json b/packages/codemods/tsconfig.json index 43e8728515c0..fbb47936232b 100644 --- a/packages/codemods/tsconfig.json +++ b/packages/codemods/tsconfig.json @@ -3,7 +3,9 @@ "compilerOptions": { "rootDir": "src", "emitDeclarationOnly": false, - "noEmit": true + "noEmit": true, + "module": "Node16", + "moduleResolution": "Node16" }, "include": ["src", "./testUtils.d.ts"], "exclude": ["**/__testfixtures__"] diff --git a/yarn.lock b/yarn.lock index 95119284b8d4..0c371ec171ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7967,6 +7967,7 @@ __metadata: "@babel/plugin-transform-typescript": "npm:^7.22.15" "@babel/runtime-corejs3": "npm:7.25.0" "@babel/traverse": "npm:^7.22.20" + "@redwoodjs/framework-tools": "workspace:*" "@redwoodjs/project-config": "workspace:*" "@svgr/core": "npm:8.1.0" "@svgr/plugin-jsx": "npm:8.1.0" @@ -7986,8 +7987,10 @@ __metadata: jscodeshift: "npm:17.0.0" pascalcase: "npm:1.0.0" prettier: "npm:3.3.3" + publint: "npm:0.2.10" tasuku: "npm:2.0.1" tempy: "npm:1.0.1" + tsx: "npm:4.17.0" typescript: "npm:5.5.4" vitest: "npm:2.0.5" yargs: "npm:17.7.2" From 7a0251684cd4291f8bab7e4609ab1ffd35038be5 Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Sun, 18 Aug 2024 18:19:32 +0200 Subject: [PATCH 48/52] chore(README): Move Kris from Maintainer to Alumni (#11308) --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 295271c7656d..082bc32428bd 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,6 @@ _A gigantic "Thank YOU!" to everyone below who has contributed to one or more Re
David Thyresson

maintainer
Daniel Choudhury

maintainer -
Kris Coulson

maintainer
Keith T Elliot

community
Barrett Burnworth

community @@ -214,6 +213,9 @@ _A gigantic "Thank YOU!" to everyone below who has contributed to one or more Re
Kim-Adeline Miguel


Dominic Saadi

+ +
Kris Coulson

+ From 4b54e040584958f7aa2135a852e09622ef8ac5ee Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Sun, 18 Aug 2024 18:28:12 +0200 Subject: [PATCH 49/52] chore(README): Fix formatting. One row (#11309) --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 082bc32428bd..c6dcb40e4ad9 100644 --- a/README.md +++ b/README.md @@ -169,11 +169,9 @@ _A gigantic "Thank YOU!" to everyone below who has contributed to one or more Re - + - -

David Thyresson

maintainer

Daniel Choudhury

maintainer

Daniel Choudhury

maintainer

Keith T Elliot

community

Barrett Burnworth

community

Josh Walker

maintainer
From 1083ab4bc0ce2ec726d2af9d79d63b1bdc7ec5b5 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Sun, 18 Aug 2024 18:59:16 +0100 Subject: [PATCH 50/52] chore(readme): Add my middle initials (#11310) As title. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c6dcb40e4ad9..9071e2d02fd6 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ _A gigantic "Thank YOU!" to everyone below who has contributed to one or more Re
Daniel Choudhury

maintainer
Keith T Elliot

community
Barrett Burnworth

community -
Josh Walker

maintainer +
Josh GM Walker

maintainer From fb8acb3b3efd629541f85d1ca3d6a1f8acb06bad Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Mon, 19 Aug 2024 00:35:18 +0100 Subject: [PATCH 51/52] refactor(api): Add conditional exports to package.json (#11307) This removes the need to have the top level files which then proxy to a file in dist by using the exports field of the package.json. In adding the exports field this PR becomes a breaking change. I did not see any usage within the framework repo of this package which isn't covered by the exports I have added here. In doing this PR I run into the same issue @Tobbe experienced. I wanted to run ATTW against the package but accept that node10 resolution won't work. There's currently no built in way to do this with that tool itself. Tobbe created a nice little script to handle this logic. What I do here is copy that script into the framework tools package in a way that can hopefully be used more easily by other packages as we go forward. --- .changesets/11307.md | 3 + packages/api-server/src/plugins/graphql.ts | 5 +- packages/api/cache/index.js | 2 - packages/api/cache/package.json | 4 -- packages/api/logger/index.js | 2 - packages/api/logger/package.json | 4 -- packages/api/package.json | 27 +++++++-- packages/api/webhooks/index.js | 2 - packages/api/webhooks/package.json | 4 -- packages/framework-tools/package.json | 7 ++- packages/framework-tools/src/attw.ts | 55 +++++++++++++++++++ .../src/bins/rw-fwtools-attw.ts | 21 +++++++ packages/graphql-server/tsconfig.json | 4 +- packages/mailer/core/tsconfig.json | 4 +- packages/testing/tsconfig.json | 4 +- yarn.lock | 5 +- 16 files changed, 121 insertions(+), 32 deletions(-) create mode 100644 .changesets/11307.md delete mode 100644 packages/api/cache/index.js delete mode 100644 packages/api/cache/package.json delete mode 100644 packages/api/logger/index.js delete mode 100644 packages/api/logger/package.json delete mode 100644 packages/api/webhooks/index.js delete mode 100644 packages/api/webhooks/package.json create mode 100644 packages/framework-tools/src/attw.ts create mode 100644 packages/framework-tools/src/bins/rw-fwtools-attw.ts diff --git a/.changesets/11307.md b/.changesets/11307.md new file mode 100644 index 000000000000..c45f540bd004 --- /dev/null +++ b/.changesets/11307.md @@ -0,0 +1,3 @@ +- refactor(api): Add conditional exports to package.json (#11307) by @Josh-Walker-GM + +This change restricts the available imports from this package. You can no longer freely import from within the dist like `@redwoodjs/api/dist/...`. If you were doing so please consult the `@redwoodjs/api` `package.json` file to see what exports are now available. diff --git a/packages/api-server/src/plugins/graphql.ts b/packages/api-server/src/plugins/graphql.ts index f5c1c0b871f8..cc07e8f33c4e 100644 --- a/packages/api-server/src/plugins/graphql.ts +++ b/packages/api-server/src/plugins/graphql.ts @@ -7,7 +7,6 @@ import type { FastifyRequest, } from 'fastify' import fastifyRawBody from 'fastify-raw-body' -import type { Plugin } from 'graphql-yoga' import type { GlobalContext } from '@redwoodjs/context' import { getAsyncStoreInstance } from '@redwoodjs/context/dist/store' @@ -68,8 +67,8 @@ export async function redwoodFastifyGraphQLServer( if (graphqlOptions?.realtime) { const { useRedwoodRealtime } = await import('@redwoodjs/realtime') - const originalExtraPlugins: Plugin[] = - graphqlOptions.extraPlugins ?? [] + const originalExtraPlugins = graphqlOptions.extraPlugins ?? [] + // @ts-expect-error TODO(jgmw): Fix this type issue introduced after switching to Node16 module resolution originalExtraPlugins.push(useRedwoodRealtime(graphqlOptions.realtime)) graphqlOptions.extraPlugins = originalExtraPlugins diff --git a/packages/api/cache/index.js b/packages/api/cache/index.js deleted file mode 100644 index 201b6305f692..000000000000 --- a/packages/api/cache/index.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-env es6, commonjs */ -module.exports = require('../dist/cache/index') diff --git a/packages/api/cache/package.json b/packages/api/cache/package.json deleted file mode 100644 index 5e13515fce56..000000000000 --- a/packages/api/cache/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "./index.js", - "types": "../dist/cache/index.d.ts" -} diff --git a/packages/api/logger/index.js b/packages/api/logger/index.js deleted file mode 100644 index c610a7a72fd0..000000000000 --- a/packages/api/logger/index.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-env es6, commonjs */ -module.exports = require('../dist/logger') diff --git a/packages/api/logger/package.json b/packages/api/logger/package.json deleted file mode 100644 index 6b6f21bb9d38..000000000000 --- a/packages/api/logger/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "./index.js", - "types": "../dist/logger/index.d.ts" -} diff --git a/packages/api/package.json b/packages/api/package.json index 1a6c91f9e9e2..4b35c22bad45 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -8,6 +8,25 @@ }, "license": "MIT", "type": "commonjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./package.json": "./package.json", + "./cache": { + "types": "./dist/cache/index.d.ts", + "default": "./dist/cache/index.js" + }, + "./logger": { + "types": "./dist/logger/index.d.ts", + "default": "./dist/logger/index.js" + }, + "./webhooks": { + "types": "./dist/webhooks/index.d.ts", + "default": "./dist/webhooks/index.js" + } + }, "main": "./dist/index.js", "types": "./dist/index.d.ts", "bin": { @@ -17,17 +36,14 @@ "tsc": "./dist/bins/tsc.js" }, "files": [ - "dist", - "cache", - "logger", - "webhooks" + "dist" ], "scripts": { "build": "tsx ./build.mts && yarn build:types", "build:pack": "yarn pack -o redwoodjs-api.tgz", "build:types": "tsc --build --verbose ./tsconfig.json", "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"", - "check:attw": "yarn attw -P", + "check:attw": "yarn rw-fwtools-attw", "check:package": "concurrently npm:check:attw yarn:publint", "prepublishOnly": "NODE_ENV=production yarn build", "test": "vitest run", @@ -44,7 +60,6 @@ "title-case": "3.0.3" }, "devDependencies": { - "@arethetypeswrong/cli": "0.15.4", "@redwoodjs/framework-tools": "workspace:*", "@types/aws-lambda": "8.10.143", "@types/jsonwebtoken": "9.0.6", diff --git a/packages/api/webhooks/index.js b/packages/api/webhooks/index.js deleted file mode 100644 index d6e24ae91429..000000000000 --- a/packages/api/webhooks/index.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-env es6, commonjs */ -module.exports = require('../dist/webhooks') diff --git a/packages/api/webhooks/package.json b/packages/api/webhooks/package.json deleted file mode 100644 index d709b28e4f09..000000000000 --- a/packages/api/webhooks/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "./index.js", - "types": "../dist/webhooks/index.d.ts" -} diff --git a/packages/framework-tools/package.json b/packages/framework-tools/package.json index 43d1153b84db..27298a95f392 100644 --- a/packages/framework-tools/package.json +++ b/packages/framework-tools/package.json @@ -20,6 +20,9 @@ } }, "types": "./dist/buildDefaults.d.ts", + "bin": { + "rw-fwtools-attw": "./dist/bins/rw-fwtools-attw.js" + }, "files": [ "dist" ], @@ -28,9 +31,11 @@ "build:types": "tsc --build --verbose" }, "dependencies": { + "@arethetypeswrong/cli": "0.15.4", "esbuild": "0.23.0", "fast-glob": "3.3.2", - "fs-extra": "11.2.0" + "fs-extra": "11.2.0", + "zx": "8.1.4" }, "devDependencies": { "@types/fs-extra": "11.0.4", diff --git a/packages/framework-tools/src/attw.ts b/packages/framework-tools/src/attw.ts new file mode 100644 index 000000000000..5eeaa653626e --- /dev/null +++ b/packages/framework-tools/src/attw.ts @@ -0,0 +1,55 @@ +import { spawnSync } from 'node:child_process' +import fs from 'node:fs' +import { createRequire } from 'node:module' +import path from 'node:path' + +interface Problem { + kind: string + entrypoint?: string + resolutionKind?: string +} + +export async function attw(): Promise { + // We can't rely on directly running the attw binary because it's not + // a direct dependency of the package that will ultimately use this. + // Instead, we have to do a little work to find the attw binary and run it. + const require = createRequire(import.meta.url) + const pathToAttw = require.resolve('@arethetypeswrong/cli/package.json') + const attwPackageJson = require(pathToAttw) + const relativeBinPath = attwPackageJson.bin.attw + const attwBinPath = path.normalize( + path.resolve(path.dirname(pathToAttw), relativeBinPath), + ) + + // Run attw via it's CLI and save the output to a file + const outputFileName = '.attw.json' + const outputFile = fs.openSync(outputFileName, 'w') + try { + spawnSync('node', [attwBinPath, '-P', '-f', 'json'], { + encoding: 'utf8', + stdio: ['ignore', outputFile, outputFile], + }) + } catch { + // We don't care about non-zero exit codes + } + fs.closeSync(outputFile) + + // Read the resulting JSON file + const content = fs.readFileSync(outputFileName, { + encoding: 'utf8', + }) + fs.unlinkSync(outputFileName) + const json = JSON.parse(content) + + // If no errors were found then return early + if (!json.analysis.problems || json.analysis.problems.length === 0) { + return [] + } + + // We don't care about node10 errors + const problems: Problem[] = json.analysis.problems.filter( + (problem: Problem) => problem.resolutionKind !== 'node10', + ) + + return problems +} diff --git a/packages/framework-tools/src/bins/rw-fwtools-attw.ts b/packages/framework-tools/src/bins/rw-fwtools-attw.ts new file mode 100644 index 000000000000..9f175a40e09b --- /dev/null +++ b/packages/framework-tools/src/bins/rw-fwtools-attw.ts @@ -0,0 +1,21 @@ +import process from 'node:process' + +import { attw } from '../attw.js' + +async function main() { + console.log(`Running attw against: ${process.cwd()}`) + + const problems = await attw() + if (problems.length > 0) { + console.error('Problems found:') + for (const problem of problems) { + console.error(problem) + } + process.exit(1) + } + + console.log('No problems found') + process.exit(0) +} + +main() diff --git a/packages/graphql-server/tsconfig.json b/packages/graphql-server/tsconfig.json index 12df66c46d7f..7b52929279dd 100644 --- a/packages/graphql-server/tsconfig.json +++ b/packages/graphql-server/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../../tsconfig.compilerOption.json", "compilerOptions": { "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16" }, "include": ["ambient.d.ts", "src/**/*"], "references": [{ "path": "../api" }, { "path": "../context" }] diff --git a/packages/mailer/core/tsconfig.json b/packages/mailer/core/tsconfig.json index 25d66097e358..78b8466e39ef 100644 --- a/packages/mailer/core/tsconfig.json +++ b/packages/mailer/core/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../../../tsconfig.compilerOption.json", "compilerOptions": { "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16" }, "include": ["src"] } diff --git a/packages/testing/tsconfig.json b/packages/testing/tsconfig.json index 62e956c6a726..af522a459f92 100644 --- a/packages/testing/tsconfig.json +++ b/packages/testing/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../../tsconfig.compilerOption.json", "compilerOptions": { "rootDir": "src", - "outDir": "dist" + "outDir": "dist", + "module": "Node16", + "moduleResolution": "Node16" }, "include": ["src"], "references": [ diff --git a/yarn.lock b/yarn.lock index 0c371ec171ef..8d3fae51989c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7215,7 +7215,6 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/api@workspace:packages/api" dependencies: - "@arethetypeswrong/cli": "npm:0.15.4" "@prisma/client": "npm:5.18.0" "@redwoodjs/framework-tools": "workspace:*" "@types/aws-lambda": "npm:8.10.143" @@ -8161,12 +8160,16 @@ __metadata: version: 0.0.0-use.local resolution: "@redwoodjs/framework-tools@workspace:packages/framework-tools" dependencies: + "@arethetypeswrong/cli": "npm:0.15.4" "@types/fs-extra": "npm:11.0.4" esbuild: "npm:0.23.0" fast-glob: "npm:3.3.2" fs-extra: "npm:11.2.0" tsx: "npm:4.17.0" typescript: "npm:5.5.4" + zx: "npm:8.1.4" + bin: + rw-fwtools-attw: ./dist/bins/rw-fwtools-attw.js languageName: unknown linkType: soft From 5d2f09095a4bbd75c42a116bfce69a052aa72b47 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Mon, 19 Aug 2024 03:39:15 +0100 Subject: [PATCH 52/52] linting: enable 'typescript-eslint/await-thenable' rule (#11311) Enables the `typescript-eslint/await-thenable` rule and addresses any of the issues that arisen. --- .eslintrc.js | 1 - packages/api-server/src/bothCLIConfigHandler.ts | 2 +- packages/auth-providers/dbAuth/web/src/webAuthn.ts | 2 +- packages/auth-providers/netlify/web/src/netlify.ts | 2 +- packages/auth-providers/supabase/api/src/decoder.ts | 2 +- packages/cli/src/testUtils/matchFolderTransform.ts | 2 +- .../ogimage-gen/src/vite-plugin-ogimage-gen.test.ts | 4 ++-- .../router/src/__tests__/routeScrollReset.test.tsx | 12 ++++++------ packages/vite/src/devFeServer.ts | 2 +- packages/vite/src/rsc/rscRequestHandler.ts | 2 +- packages/vite/src/rsc/rscStudioHandlers.ts | 2 +- packages/web/src/server/MiddlewareResponse.test.ts | 4 ++-- 12 files changed, 18 insertions(+), 19 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 141ab8799e24..a7094e6c548f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -198,7 +198,6 @@ module.exports = { camelcase: 'off', // TODO(jgmw): Work through these and either keep disabled or fix and re-enable - '@typescript-eslint/await-thenable': 'off', '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/require-await': 'off', diff --git a/packages/api-server/src/bothCLIConfigHandler.ts b/packages/api-server/src/bothCLIConfigHandler.ts index 7447c46b2f91..0beafc6ca0a1 100644 --- a/packages/api-server/src/bothCLIConfigHandler.ts +++ b/packages/api-server/src/bothCLIConfigHandler.ts @@ -33,7 +33,7 @@ export async function handler(options: BothParsedOptions) { }, }) - const apiFastify = await await createApiServer({ + const apiFastify = await createApiServer({ apiRootPath: options.apiRootPath, }) diff --git a/packages/auth-providers/dbAuth/web/src/webAuthn.ts b/packages/auth-providers/dbAuth/web/src/webAuthn.ts index 29feb8bd5d68..060b2085c788 100644 --- a/packages/auth-providers/dbAuth/web/src/webAuthn.ts +++ b/packages/auth-providers/dbAuth/web/src/webAuthn.ts @@ -50,7 +50,7 @@ export default class WebAuthnClient { async isSupported() { const { browserSupportsWebAuthn } = await import('@simplewebauthn/browser') - return await browserSupportsWebAuthn() + return browserSupportsWebAuthn() } isEnabled() { diff --git a/packages/auth-providers/netlify/web/src/netlify.ts b/packages/auth-providers/netlify/web/src/netlify.ts index 32d5f1d7c634..91fbeb0275c5 100644 --- a/packages/auth-providers/netlify/web/src/netlify.ts +++ b/packages/auth-providers/netlify/web/src/netlify.ts @@ -73,7 +73,7 @@ function createAuthImplementation(netlifyIdentity: NetlifyIdentity) { // The client refresh function only actually refreshes token // when it's been expired. Don't panic await netlifyIdentity.refresh() - const user = await netlifyIdentity.currentUser() + const user = netlifyIdentity.currentUser() return user?.token?.access_token || null } catch { return null diff --git a/packages/auth-providers/supabase/api/src/decoder.ts b/packages/auth-providers/supabase/api/src/decoder.ts index e4acedd5d200..8188922d3cf7 100644 --- a/packages/auth-providers/supabase/api/src/decoder.ts +++ b/packages/auth-providers/supabase/api/src/decoder.ts @@ -57,7 +57,7 @@ const getSupabaseAccessTokenFromCookie = async ( if (!error) { const { session } = data if (session) { - return await session.access_token + return session.access_token } throw new Error('No Supabase session found') } else { diff --git a/packages/cli/src/testUtils/matchFolderTransform.ts b/packages/cli/src/testUtils/matchFolderTransform.ts index 4cdcc50fa135..6bc42dffe33e 100644 --- a/packages/cli/src/testUtils/matchFolderTransform.ts +++ b/packages/cli/src/testUtils/matchFolderTransform.ts @@ -123,7 +123,7 @@ export const matchFolderTransform: MatchFolderTransformFunction = async ( const actualPath = path.join(tempDir, transformedFile) const expectedPath = path.join(fixtureOutputDir, transformedFile) - await expect(actualPath).toMatchFileContents(expectedPath, { + expect(actualPath).toMatchFileContents(expectedPath, { removeWhitespace, }) } diff --git a/packages/ogimage-gen/src/vite-plugin-ogimage-gen.test.ts b/packages/ogimage-gen/src/vite-plugin-ogimage-gen.test.ts index 15ed7a90a7f0..07e6e8ef7e15 100644 --- a/packages/ogimage-gen/src/vite-plugin-ogimage-gen.test.ts +++ b/packages/ogimage-gen/src/vite-plugin-ogimage-gen.test.ts @@ -41,7 +41,7 @@ describe('vitePluginOgGen', () => { test('should generate rollup inputs for all OG components', async () => { // Type cast so TS doesn't complain calling config below // because config can be of many types! - const plugin = (await vitePluginOgGen()) as { + const plugin = vitePluginOgGen() as { config: (config: any, env: ConfigEnv) => any } @@ -87,7 +87,7 @@ describe('vitePluginOgGen', () => { config: expect.any(Function), } - const plugin = await vitePluginOgGen() + const plugin = vitePluginOgGen() expect(plugin).toEqual(expectedPlugin) }) diff --git a/packages/router/src/__tests__/routeScrollReset.test.tsx b/packages/router/src/__tests__/routeScrollReset.test.tsx index e553c9284617..723a9251b2ae 100644 --- a/packages/router/src/__tests__/routeScrollReset.test.tsx +++ b/packages/router/src/__tests__/routeScrollReset.test.tsx @@ -24,7 +24,7 @@ describe('Router scroll reset', () => { render() // Make sure we're starting on the home route - await screen.getByText('Page 1') + screen.getByText('Page 1') }) afterEach(async () => { @@ -41,7 +41,7 @@ describe('Router scroll reset', () => { ), ) - await screen.getByText('Page 2') + screen.getByText('Page 2') expect(globalThis.scrollTo).toHaveBeenCalledTimes(1) }) @@ -56,7 +56,7 @@ describe('Router scroll reset', () => { ), ) - await screen.getByText('Page 2') + screen.getByText('Page 2') expect(globalThis.scrollTo).toHaveBeenCalledTimes(1) }) @@ -72,20 +72,20 @@ describe('Router scroll reset', () => { ), ) - await screen.getByText('Page 1') + screen.getByText('Page 1') expect(globalThis.scrollTo).toHaveBeenCalledTimes(1) }) it('does NOT reset on hash change', async () => { - await screen.getByText('Page 1') + screen.getByText('Page 1') act(() => // Stay on page 1, but change the hash navigate(`#route=66`, { replace: true }), ) - await screen.getByText('Page 1') + screen.getByText('Page 1') expect(globalThis.scrollTo).not.toHaveBeenCalled() }) diff --git a/packages/vite/src/devFeServer.ts b/packages/vite/src/devFeServer.ts index 5ba891491215..930b72588c7a 100644 --- a/packages/vite/src/devFeServer.ts +++ b/packages/vite/src/devFeServer.ts @@ -163,7 +163,7 @@ async function createServer() { const port = getConfig().web.port console.log(`Started server on http://localhost:${port}`) - return await app.listen(port) + return app.listen(port) } let devApp = createServer() diff --git a/packages/vite/src/rsc/rscRequestHandler.ts b/packages/vite/src/rsc/rscRequestHandler.ts index 750dedfb8d26..e749cd9f671c 100644 --- a/packages/vite/src/rsc/rscRequestHandler.ts +++ b/packages/vite/src/rsc/rscRequestHandler.ts @@ -195,7 +195,7 @@ export function createRscRequestHandler( // In the component, getting location would otherwise be at the rw-rsc URL const fullUrl = getFullUrlForFlightRequest(req, props) - const pipeable = await renderRsc({ + const pipeable = renderRsc({ rscId, props, rsfId, diff --git a/packages/vite/src/rsc/rscStudioHandlers.ts b/packages/vite/src/rsc/rscStudioHandlers.ts index aeff1a9657cc..0615a3c2a75b 100644 --- a/packages/vite/src/rsc/rscStudioHandlers.ts +++ b/packages/vite/src/rsc/rscStudioHandlers.ts @@ -141,7 +141,7 @@ export const sendRscFlightToStudio = async (input: StudioRenderInput) => { // becomes http://localhost:8910/about?foo=bar const fullUrl = getFullUrlForFlightRequest(req, props) - const pipeable = await renderRsc({ + const pipeable = renderRsc({ rscId, props, rsfId, diff --git a/packages/web/src/server/MiddlewareResponse.test.ts b/packages/web/src/server/MiddlewareResponse.test.ts index 67f14ddcfcf1..5dbedab41baa 100644 --- a/packages/web/src/server/MiddlewareResponse.test.ts +++ b/packages/web/src/server/MiddlewareResponse.test.ts @@ -4,7 +4,7 @@ import { describe, expect, test } from 'vitest' import { MiddlewareResponse, MiddlewareShortCircuit, -} from './MiddlewareResponse' +} from './MiddlewareResponse.js' describe('MiddlewareResponse', () => { test('constructor', () => { @@ -119,7 +119,7 @@ describe('MiddlewareResponse', () => { ).toStrictEqual('Nope') expect( - await shortCircuitError.mwResponse.toResponse().statusText, + shortCircuitError.mwResponse.toResponse().statusText, ).toStrictEqual('Hold your horses!') }