-
Notifications
You must be signed in to change notification settings - Fork 433
feat(astro): Add CSR support #3911
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
wobsoriano
merged 95 commits into
main
from
rob/eco-17-explore-our-options-for-csr-only-support-in-astro
Aug 22, 2024
Merged
Changes from all commits
Commits
Show all changes
95 commits
Select commit
Hold shift + click to select a range
68d1181
chore(astro): Use shared data attribute builder for hotloading
wobsoriano 832d2dd
chore(astro): Use shared clerk-js hotload script
wobsoriano 982d455
chore(astro): Clean up type ignores
wobsoriano 22e7ceb
chore(astro): Fix merge conflicts
wobsoriano 98456b9
chore(astro): Fix incorrect file name
wobsoriano 062cb9b
chore(shared): Allow custom package version
wobsoriano ddbd13a
test(shared): Handle custom package versions for versionSelector
wobsoriano 470e945
chore(astro): Use shared clerk-js hotload script
wobsoriano dd0c8f4
chore(shared): Update internal package version property name
wobsoriano af076d3
chore(astro): Remove unused file
wobsoriano c78912f
chore(shared): Make options optional in loadClerkJsScript and throw i…
wobsoriano e0d683b
chore(shared,astro,react,nextjs): Use built-in error thrower when Cle…
wobsoriano 7a4911b
test(shared): Use clerk-js major version from package.json when testi…
wobsoriano d8b1ac6
chore(shared): Add nonce prop to to load script
wobsoriano 097035c
chore(shared): Remove extra folder
wobsoriano a3a29d9
feat(astro): Add CSR support to control components
wobsoriano b489b41
chore(astro): Use dynamic components
wobsoriano 5cdebf7
chore(astro): Type fix
wobsoriano bc64acd
chore(astro): formatting update
wobsoriano 6890da2
chore(astro): Simplify Protect slots
wobsoriano ad714b7
chore(astro): Add initial changeset
wobsoriano 19af4a7
test(astro): Add initial CSR e2e test
wobsoriano 604bec8
test(astro): Add astro-static to template map
wobsoriano e82f4a7
chore(astrp): Use hidden attribute for CSR component toggling
wobsoriano 63e2b24
test(astro): Clean up
wobsoriano 6f71f03
test(astro): More clean ups
wobsoriano 03a1e73
chore(astro): Add vite plugin for dynamic control components
wobsoriano 8be568b
chore(astro): Use hidden attribute for toggling visibility in Protect…
wobsoriano ce1b5fb
test(astro): Remove client props
wobsoriano 982d0d1
chore(astro): Add type for virtual module
wobsoriano f97124b
test(astro): Add SignedIn, SignedOut and Protect e2e tests
wobsoriano ae02d48
test(astro): Clean up static config
wobsoriano 7887e26
chore(astro): File location clean up
wobsoriano 095c199
chore(astro): Remove unused bundled folder
wobsoriano 5a41ab1
chore(astro): Update virtual module to include hybrid mode
wobsoriano 783f4db
chore(astro): Run formatter
wobsoriano 3d5943f
test(astro): Improve visibility tests
wobsoriano 5d91dd0
chore(astro): Add back adapter missing error message
wobsoriano 5e363d2
chore(astro): Run prettier format
wobsoriano 2928bf6
chore(astro): Revert hotload script build logic
wobsoriano 05f848f
chore(astro): Remove duplicate import
wobsoriano 026b7e4
chore(astro): Reuse ProtectProps and publish types file
wobsoriano ce97965
chore(astro): Fix incorrect variable name
wobsoriano ac7d460
chore(astro): pre-bundle client stores export
wobsoriano c99bc75
chore(astro): Update vite plugin to set hybrid component initial to s…
wobsoriano 466ba97
chore(astro): Update vite plugin to set hybrid component initial to s…
wobsoriano 29957bb
chore(astro): Remove duplicate env vars in vite
wobsoriano d4b02ff
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano 3dae9b2
chore(astro): Update changeset
wobsoriano c895c7b
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano 5624586
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano 0c8d0f3
chore(astro): Dynamically export control components
wobsoriano dd30100
chore(astro): Prettier formatting
wobsoriano 656272e
chore(astro): Fix protect csr fallback slot
wobsoriano 2f67e98
chore(astro): Working tests and separate custom element declarations
wobsoriano db2dfe6
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano edbe5ad
chore(astro): Add base element for CSR web components
wobsoriano aa3112c
chore(astro): Remove unnecessary optimized dep
wobsoriano dfb9826
chore(astro): Perform clean ups
wobsoriano 4b2e495
chore(astro): Slot clean up
wobsoriano b4ce8ff
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano ed6f7f1
chore(astro): Update changeset
wobsoriano f3f36fc
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano ccecf05
chore(astro): Fix incorrect output
wobsoriano 6582e64
chore(astro): Use authorization checker function from session object
wobsoriano 2dca843
fix(astro): Do not ignore astro files in tsconfig
wobsoriano 29e1190
chore(astro): Run prettier format
wobsoriano f182753
chore(astro): Add isStatic prop definition
wobsoriano 85e257a
chore(astro): Revert previous commit
wobsoriano 42a830b
chore(astro): type fixes
wobsoriano 0ee00ff
chore(astro): Put web component declarations inside CSR components
wobsoriano edad853
chore(astro): Fix flickering when rendering signed in and signed out …
wobsoriano 46a3426
chore(astro): Test type fix
wobsoriano 7985b29
chore(astro): Format tsconfig
wobsoriano a87bc9c
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano 93be93d
chore(astro): Remove unnecessary ts config
wobsoriano 009bfa3
chore(astro): Update test preset comment
wobsoriano 76aae65
test(astro): Use react component in static test
wobsoriano e57b449
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano 71c3070
chore(astro): Make sure hidden attributes are not overridable
wobsoriano e2f8279
chore(astro): Make sure hidden attributes are not overridable in prot…
wobsoriano ef87390
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano 24df6df
test(astro): Fix protect CSR tests
wobsoriano 0ae1248
chore(astro): Formatting fix
wobsoriano 506bce7
chore(astro): Remove unused util file
wobsoriano 17a4abb
chore(astro): Set initial resource values to undefined
wobsoriano a188cc8
chore(astro): Ignore ts files in components folder
wobsoriano db66adc
chore(astro): TS errors clean up
wobsoriano 0b65ac6
test(astro): Update static test to hybrid
wobsoriano 6e1beeb
chore(astro): Update eslint ignores
wobsoriano eb0647c
chore(astro): Simplify ignored files in tsconfig
wobsoriano fa723e4
chore(astro): Add JSDoc to vite plugin
wobsoriano 7f20b12
chore(astro): Add classes to control components wrappers
wobsoriano d21a98a
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano aadf639
test(astro): Rename hybrid test description
wobsoriano File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@clerk/astro": minor | ||
| --- | ||
|
|
||
| Add support for Astro `static` and `hybrid` outputs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # build output | ||
| dist/ | ||
|
|
||
| # generated types | ||
| .astro/ | ||
|
|
||
| # dependencies | ||
| node_modules/ | ||
|
|
||
| # logs | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| pnpm-debug.log* | ||
|
|
||
| # environment variables | ||
| .env | ||
| .env.production | ||
|
|
||
| # macOS-specific files | ||
| .DS_Store | ||
|
|
||
| # jetbrains setting folder | ||
| .idea/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { defineConfig } from 'astro/config'; | ||
| import clerk from '@clerk/astro'; | ||
| import react from '@astrojs/react'; | ||
|
|
||
| export default defineConfig({ | ||
| output: 'hybrid', | ||
| integrations: [clerk(), react()], | ||
| server: { | ||
| port: Number(process.env.PORT), | ||
| }, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "name": "astro-clerk-hybrid-playground", | ||
| "type": "module", | ||
| "version": "0.0.1", | ||
| "scripts": { | ||
| "dev": "astro dev", | ||
| "start": "astro dev --port $PORT", | ||
| "build": "astro check && astro build", | ||
| "preview": "astro preview --port $PORT", | ||
| "astro": "astro" | ||
| }, | ||
| "dependencies": { | ||
| "@astrojs/check": "^0.7.0", | ||
| "@astrojs/react": "^3.6.0", | ||
| "@astrojs/node": "^8.3.2", | ||
| "@types/react": "^18.3.3", | ||
| "@types/react-dom": "^18.3.0", | ||
| "astro": "^4.11.5", | ||
| "react": "^18.3.1", | ||
| "react-dom": "^18.3.1", | ||
| "typescript": "^5.5.3" | ||
| } | ||
| } |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions
24
integration/templates/astro-hybrid/src/layouts/Layout.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| --- | ||
| interface Props { | ||
| title: string; | ||
| } | ||
|
|
||
| const { title } = Astro.props; | ||
| --- | ||
|
|
||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="description" content="Astro description" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> | ||
| <meta name="generator" content={Astro.generator} /> | ||
| <title>{title}</title> | ||
| </head> | ||
| <body> | ||
| <main> | ||
| <slot /> | ||
| </main> | ||
| </body> | ||
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| import { clerkMiddleware } from '@clerk/astro/server'; | ||
|
|
||
| export const onRequest = clerkMiddleware(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| --- | ||
| import { UserButton, SignInButton, SignedIn, SignedOut } from "@clerk/astro/components"; | ||
| import { OrganizationSwitcher } from "@clerk/astro/react"; | ||
| import Layout from "../layouts/Layout.astro"; | ||
|
|
||
| export const prerender = true; | ||
| --- | ||
|
|
||
| <Layout title="Home"> | ||
| <SignedOut> | ||
| <h1>Signed out</h1> | ||
| <SignInButton mode="modal" fallbackRedirectUrl="/" /> | ||
| </SignedOut> | ||
| <SignedIn> | ||
| <h1>Signed in</h1> | ||
| <UserButton /> | ||
| <OrganizationSwitcher client:only="react" /> | ||
| </SignedIn> | ||
| </Layout> |
13 changes: 13 additions & 0 deletions
13
integration/templates/astro-hybrid/src/pages/only-admins.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| --- | ||
| import { Protect } from "@clerk/astro/components"; | ||
| import Layout from "../layouts/Layout.astro"; | ||
|
|
||
| export const prerender = true; | ||
| --- | ||
|
|
||
| <Layout title="Protected"> | ||
| <Protect role="admin"> | ||
| <h1>I'm an admin</h1> | ||
| <h1 slot="fallback">Not an admin</h1> | ||
| </Protect> | ||
| </Layout> |
13 changes: 13 additions & 0 deletions
13
integration/templates/astro-hybrid/src/pages/only-members.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| --- | ||
| import { Protect } from "@clerk/astro/components"; | ||
| import Layout from "../layouts/Layout.astro"; | ||
|
|
||
| export const prerender = false; | ||
| --- | ||
|
|
||
| <Layout title="Protected"> | ||
| <Protect role="basic_member" isStatic={false}> | ||
| <h1>I'm a member</h1> | ||
| <h1 slot="fallback">Not a member</h1> | ||
| </Protect> | ||
| </Layout> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| --- | ||
| import { UserButton, SignInButton, SignedIn, SignedOut } from "@clerk/astro/components"; | ||
| import { OrganizationSwitcher } from "@clerk/astro/react"; | ||
| import Layout from "../layouts/Layout.astro"; | ||
|
|
||
| export const prerender = false; | ||
| --- | ||
|
|
||
| <Layout title="Home"> | ||
| <SignedOut isStatic={false}> | ||
| <h1>Signed out</h1> | ||
| <SignInButton mode="modal" fallbackRedirectUrl="/" /> | ||
| </SignedOut> | ||
| <SignedIn isStatic={false}> | ||
| <h1>Signed in</h1> | ||
| <UserButton /> | ||
| <OrganizationSwitcher client:load /> | ||
| </SignedIn> | ||
| </Layout> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "extends": "astro/tsconfigs/strict", | ||
| "compilerOptions": { | ||
| "jsx": "react-jsx", | ||
| "jsxImportSource": "react" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| import { expect, test } from '@playwright/test'; | ||
|
|
||
| import type { FakeOrganization, FakeUser } from '../../testUtils'; | ||
| import { createTestUtils, testAgainstRunningApps } from '../../testUtils'; | ||
|
|
||
| testAgainstRunningApps({ withPattern: ['astro.static.withCustomRoles'] })( | ||
| 'basic flows for @astro hybrid output', | ||
| ({ app }) => { | ||
| test.describe.configure({ mode: 'serial' }); | ||
|
|
||
| let fakeAdmin: FakeUser; | ||
| let fakeOrganization: FakeOrganization; | ||
| let fakeAdmin2: FakeUser; | ||
| let fakeOrganization2: FakeOrganization; | ||
|
|
||
| test.beforeAll(async () => { | ||
| const m = createTestUtils({ app }); | ||
| fakeAdmin = m.services.users.createFakeUser(); | ||
| const admin = await m.services.users.createBapiUser(fakeAdmin); | ||
| fakeOrganization = await m.services.users.createFakeOrganization(admin.id); | ||
|
|
||
| fakeAdmin2 = m.services.users.createFakeUser(); | ||
| const admin2 = await m.services.users.createBapiUser(fakeAdmin2); | ||
| fakeOrganization2 = await m.services.users.createFakeOrganization(admin2.id); | ||
| }); | ||
|
|
||
| test.afterAll(async () => { | ||
| await fakeOrganization.delete(); | ||
| await fakeAdmin.deleteIfExists(); | ||
|
|
||
| await fakeOrganization2.delete(); | ||
| await fakeAdmin2.deleteIfExists(); | ||
| await app.teardown(); | ||
| }); | ||
|
|
||
| test('render SignedIn and SignedOut contents (prerendered)', async ({ page, context }) => { | ||
| const u = createTestUtils({ app, page, context }); | ||
| await u.page.goToAppHome(); | ||
|
|
||
| await u.page.waitForClerkJsLoaded(); | ||
|
|
||
| await u.po.expect.toBeSignedOut(); | ||
| await expect(u.page.getByText('Signed out')).toBeVisible(); | ||
| await expect(u.page.getByText('Signed in')).toBeHidden(); | ||
|
|
||
| await u.page.getByRole('button', { name: /Sign in/i }).click(); | ||
|
|
||
| await u.po.signIn.waitForMounted(); | ||
| await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password }); | ||
| await u.po.expect.toBeSignedIn(); | ||
|
|
||
| await expect(u.page.getByText('Signed out')).toBeHidden(); | ||
| await expect(u.page.getByText('Signed in')).toBeVisible(); | ||
| }); | ||
|
|
||
| test('render SignedIn and SignedOut contents (SSR)', async ({ page, context }) => { | ||
| const u = createTestUtils({ app, page, context }); | ||
| await u.page.goToRelative('/ssr'); | ||
|
|
||
| await u.page.waitForClerkJsLoaded(); | ||
|
|
||
| await u.po.expect.toBeSignedOut(); | ||
| await expect(u.page.getByText('Signed out')).toBeVisible(); | ||
| await expect(u.page.getByText('Signed in')).toBeHidden(); | ||
|
|
||
| await u.page.getByRole('button', { name: /Sign in/i }).click(); | ||
|
|
||
| await u.po.signIn.waitForMounted(); | ||
| await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password }); | ||
| await u.po.expect.toBeSignedIn(); | ||
|
|
||
| await expect(u.page.getByText('Signed out')).toBeHidden(); | ||
| await expect(u.page.getByText('Signed in')).toBeVisible(); | ||
| }); | ||
|
|
||
| test('render Protect contents for admin', async ({ page, context }) => { | ||
| const u = createTestUtils({ app, page, context }); | ||
| await u.page.goToAppHome(); | ||
|
|
||
| await u.page.waitForClerkJsLoaded(); | ||
|
|
||
| // Sign in | ||
| await u.page.getByRole('button', { name: /Sign in/i }).click(); | ||
| await u.po.signIn.waitForMounted(); | ||
| await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password }); | ||
| await u.po.expect.toBeSignedIn(); | ||
|
|
||
| // Select an organization | ||
| await u.po.organizationSwitcher.waitForMounted(); | ||
| await u.po.organizationSwitcher.waitForAnOrganizationToSelected(); | ||
|
|
||
| await u.page.goToRelative('/only-admins'); | ||
|
|
||
| await expect(u.page.getByText("I'm an admin")).toBeVisible(); | ||
| }); | ||
|
|
||
| test('render Protect fallback', async ({ page, context }) => { | ||
| const u = createTestUtils({ app, page, context }); | ||
| await u.page.goToAppHome(); | ||
|
|
||
| await u.page.waitForClerkJsLoaded(); | ||
|
|
||
| // Sign in | ||
| await u.page.getByRole('button', { name: /Sign in/i }).click(); | ||
| await u.po.signIn.waitForMounted(); | ||
| await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password }); | ||
| await u.po.expect.toBeSignedIn(); | ||
|
|
||
| await u.page.goToRelative('/only-members'); | ||
|
|
||
| await expect(u.page.getByText('Not a member')).toBeVisible(); | ||
| }); | ||
| }, | ||
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ astro-components/ | |
| components/ | ||
| !src/components/ | ||
| .output/ | ||
| /types.ts | ||
|
|
||
| .vscode/ | ||
| .idea/ | ||
|
|
||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.