-
Notifications
You must be signed in to change notification settings - Fork 70
[Package] PowerSync Nuxt Module #797
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
Merged
Changes from all commits
Commits
Show all changes
62 commits
Select commit
Hold shift + click to select a range
db1ecce
feat: added nuxt module
khawarizmus e5c95ac
feat: add Nuxt Supabase Todo List demo with environment configuration…
khawarizmus 3521b82
feat: prepare NuxtPowerSyncDatabase to support default sync client im…
khawarizmus c58db3c
feat: add environment configuration template and sync rules for Nuxt …
khawarizmus 5771c58
feat: add README and update seed.sql for Nuxt Supabase Todo List demo
khawarizmus 07a9c27
docs: update README with secure password note and correct PowerSync d…
khawarizmus 7c52649
feat: add powersync-icon.svg asset and update references in AppHeader…
khawarizmus a67886d
chore: update package.json to include @supabase/supabase-js in depend…
khawarizmus d67a0fe
chore: remove vite-plugin-top-level-await from dependencies and updat…
khawarizmus 6e3e768
fix: update login button text to use consistent capitalization and re…
khawarizmus e5219b9
docs: clean up README by removing outdated comments and updating comp…
khawarizmus d2bd1c3
docs: add Nuxt Module to Docosorus
khawarizmus e3b04e5
chore: update pnpm-lock.yaml to reflect dependency version upgrades a…
khawarizmus 5883058
refactor: remove the need to add diagnostics schema manually
khawarizmus 2bda6eb
docs: update README to reflect removal of top-level await plugin and …
khawarizmus 49060a0
refactor: standardize table names to lowercase in SQL queries and upd…
khawarizmus 510a96f
feat: added multitab support
khawarizmus 6363f30
chore: add reset:repo script to clean node_modules and pnpm lock file…
khawarizmus 35490f8
chore: update author name in package.json from JOURNEYAPPS to POWERSYNC
khawarizmus 30062cc
Merge branch 'main' into nuxt
khawarizmus dd7181c
chore: lay the ground for demo Isolation
khawarizmus 754581d
fix: removed vue deps from demo project to allow pnpm to resolve a si…
khawarizmus fb28c97
feat: made Kysely integration in Nuxt module optional
khawarizmus 4d5ff6c
feat: added local development guide with supabase
khawarizmus a65a509
refactor: clean up and reorganize Vue components in the todolist demo…
khawarizmus 18b4319
refactor: replace watch with watchEffect for user navigation in confi…
khawarizmus 9c2fe9e
feat: add LoadingSpinner component and integrate it into powersync-in…
khawarizmus 4d57259
fix: fixed flickering cause by icon size change when status change
khawarizmus 30702fa
feat: define BucketRow and TableRow types for improved type safety in…
khawarizmus 939eb89
test: implement unit tests for nuxt package
khawarizmus 02a3a1a
fix: fixed nuxt package docs generation
khawarizmus f304989
fix: typed the return type of usePowerSyncInspectorDiagnostics compos…
khawarizmus 8e3e6f0
build: add prebuild:prod script to streamline production build proces…
khawarizmus 597666a
chore: Isolated nuxt-supabase-todolist demo and remove it from workspace
khawarizmus ee63d71
Merge branch 'main' into nuxt
khawarizmus 68bb624
chore: update package dependencies versions in nuxt demo
khawarizmus b1d2fe1
fix: fixed type issues in docs build and added missing dependencies
khawarizmus 5931a86
chore: update nuxt package version to 0.0.0-dev-20260128023420
khawarizmus fccf045
chore: add missing deps for nuxt packages tests
khawarizmus e195ba3
docs: updated docs to reflect latest changes and update nuxt-supabase…
khawarizmus 9444525
feat: initial release of PowerSync Nuxt module with Devtools integrat…
khawarizmus 20e76e2
chore: update package dependencies in nuxt-supabase-todolist demo and…
khawarizmus 5222eab
refactor: standardize code formatting across Nuxt components and modules
khawarizmus 3f9091d
chore: remove consola dependency and fix logs output
khawarizmus 03ab009
Merge branch 'main' into nuxt
khawarizmus 11d20b4
test: fix useDiagnosticsLogger tests for log storage and formatting
khawarizmus 211b720
chore: update pnpm-lock.yaml
khawarizmus 66d0cc3
refactor: simplify SyncStatusTab component by using dynamic metric se…
khawarizmus 718264a
chore: renamed README and removed a new line
khawarizmus bf35d98
Merge branch 'main' into nuxt
khawarizmus 6c6b42c
chore: update package versions in pnpm-lock.yaml
khawarizmus 97d3d95
Fixed whitespace abnormality.
Chriztiaan 284e971
Merge branch 'nuxt' of github.com:powersync-ja/powersync-js into nuxt
Chriztiaan 7bfaf84
chore: update PowerSync configuration in .env.template
khawarizmus 4a94a73
refactor: fix signup screen
khawarizmus fc22825
chore: update PS_PORT in .env.template from 6000 to 6060
khawarizmus 2361061
Merge branch 'main' into nuxt
khawarizmus 4ec9a50
chore: update package versions in pnpm-lock.yaml
khawarizmus 7114666
docs: enhance README with environment setup instructions and notes fo…
khawarizmus 0e27c2b
chore: add pnpm overrides for fast-xml-parser version
khawarizmus 0dc6381
chore: add allowlist for CLI-only dev tooling in audit-ci.jsonc
khawarizmus de6845d
chore: update fast-xml-parser version and clean up audit-ci.jsonc
khawarizmus 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 @@ | ||
| --- | ||
| '@powersync/nuxt': patch | ||
| --- | ||
|
|
||
| Initial release of the PowerSync Nuxt module. Provides Nuxt Devtools integration, built-in diagnostics and data inspection, and composables. Supports Nuxt 4. |
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,15 @@ | ||
| # Self-hosted Environment Configuration | ||
| # Copy this template: `cp .env.template .env` | ||
| # Edit .env and enter your Supabase and PowerSync project details. | ||
|
|
||
| NUXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321 | ||
| NUXT_PUBLIC_SUPABASE_ANON_KEY=<replace-with-your-anon-key-or-copy-publishable-key-from-supabase-start> | ||
| # PowerSync Configuration | ||
| NUXT_PUBLIC_POWERSYNC_URL=http://localhost:6060 | ||
|
|
||
| # Self-hosted PowerSync Configuration | ||
| PS_POSTGRESQL_URI=postgresql://postgres:postgres@supabase_db_nuxt-supabase-todolist:5432/postgres | ||
| # PS_SUPABASE_JWT_SECRET=super-secret-jwt-token-with-at-least-32-characters-long # Uncomment this if you want to use legacy Supabase JWT secret for auth | ||
| PS_JWKS_URI=http://kong:8000/auth/v1/.well-known/jwks.json | ||
| PS_API_TOKEN=anything-super-secrete-token | ||
| PS_PORT=6060 |
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 @@ | ||
| imports.autoImport=true |
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,142 @@ | ||
| # PowerSync + Supabase Nuxt Demo: Todo List | ||
|
|
||
| This is a demo application showcasing PowerSync integration with Nuxt 4 and Supabase. It demonstrates real-time data synchronization for a simple todo list application using PowerSync's official Nuxt module. | ||
|
|
||
| ## Setup Instructions | ||
|
|
||
| Note that this setup guide has minor deviations from the [Supabase + PowerSync integration guide](https://docs.powersync.com/integration-guides/supabase-+-powersync). Below we refer to sections in this guide where relevant. | ||
|
|
||
| ### 1. Install dependencies | ||
|
|
||
| In the repo root directory, use [pnpm](https://pnpm.io/installation) to install dependencies: | ||
|
|
||
| ```bash | ||
| pnpm install | ||
| pnpm build:packages | ||
| ``` | ||
|
|
||
| ### Quick Start: Local Development | ||
|
|
||
| This demo can be started with local PowerSync and Supabase services. | ||
|
|
||
| 1. Install the [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) | ||
|
|
||
| 2. Copy the environment template: | ||
|
|
||
| ```bash | ||
| cp .env.template .env | ||
| ``` | ||
|
|
||
| 3. Start Supabase: | ||
|
|
||
| ```bash | ||
| supabase start | ||
| ``` | ||
|
|
||
| 4. Copy the values from the `supabase start` output into `.env`. Local Supabase uses JWKS for auth, so this demo configures PowerSync with `jwks_uri` and `audience: authenticated`: | ||
| - `NUXT_PUBLIC_SUPABASE_ANON_KEY`: Use the **Publishable** key value | ||
| - `PS_JWKS_URI`: Use `http://kong:8000/auth/v1/.well-known/jwks.json` when PowerSync runs in Docker on the Supabase network (default in step 5). This points PowerSync at local Supabase's JWKS so it can verify tokens. If Kong is not reachable from the container (e.g. custom network), try `http://host.docker.internal:54321/auth/v1/.well-known/jwks.json` on Docker Desktop for Mac/Windows. | ||
|
|
||
| > [!NOTE] | ||
| > `NUXT_PUBLIC_SUPABASE_ANON_KEY`: Use the Publishable key value (requires Supabase CLI v2.45.5+) | ||
|
|
||
| 5. Start PowerSync: | ||
|
|
||
| ```bash | ||
| docker run \ | ||
| -p 6060:6060 \ | ||
| -e POWERSYNC_CONFIG_B64=$(base64 -i ./powersync.yaml) \ | ||
| -e POWERSYNC_SYNC_RULES_B64=$(base64 -i ./sync-rules.yaml) \ | ||
| --env-file ./.env \ | ||
| --network supabase_network_nuxt-supabase-todolist \ | ||
| --name powersync-nuxt journeyapps/powersync-service:latest | ||
| ``` | ||
|
|
||
| 6. Run the demo: | ||
| ```bash | ||
| pnpm dev | ||
| ``` | ||
|
|
||
| Open [http://localhost:3000](http://localhost:3000) to use the app. | ||
|
|
||
| ### 2. Create project on Supabase and set up Postgres | ||
|
|
||
| This demo app uses Supabase as its Postgres database and backend: | ||
|
|
||
| 1. [Create a new project on the Supabase dashboard](https://supabase.com/dashboard/projects). | ||
| 2. Go to the Supabase SQL Editor for your new project and execute the SQL statements in [`db/seed.sql`](db/seed.sql) to create the database schema, PowerSync replication role, and publication needed for PowerSync. | ||
|
|
||
| **Note:** Before executing the SQL, make sure to update the `powersync_role` password in `db/seed.sql` (currently set to `'postgres_12345'`) to a secure password of your choice. | ||
|
|
||
| **Important:** When connecting PowerSync to your Supabase database, you'll use the `powersync_role` credentials instead of the default Supabase connection string. This role has the necessary replication privileges and bypasses Row Level Security (RLS). | ||
|
|
||
| ### 3. Auth setup | ||
|
|
||
| This app uses Supabase's email/password authentication. | ||
|
|
||
| 1. Go to "Authentication" -> "Providers" in your Supabase dashboard | ||
| 2. Ensure "Email" provider is enabled | ||
| 3. You can disable email confirmation for development by going to "Authentication" -> "Email Auth" and disabling "Confirm email" | ||
|
|
||
| You'll need to create a user account when you first access the application. | ||
|
|
||
| ### 4. Set up PowerSync | ||
|
|
||
| You can use either PowerSync Cloud or self-host PowerSync: | ||
|
|
||
| - **PowerSync Cloud**: [Create a new project on the PowerSync dashboard](https://dashboard.powersync.com) and connect it to your Supabase database using the `powersync_role` credentials created in step 2. | ||
| - **Self-hosting**: Follow the [self-hosting guide](https://docs.powersync.com/self-hosting/getting-started) to deploy your own PowerSync instance. | ||
|
|
||
| The sync rules for this demo are provided in [`sync-rules.yaml`](sync-rules.yaml) in this directory. | ||
|
|
||
| ### 5. Set up local environment variables | ||
|
|
||
| Create a `.env` file in this directory with the following variables: | ||
|
|
||
| ```bash | ||
| NUXT_PUBLIC_SUPABASE_URL=your_supabase_url | ||
| NUXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key | ||
| NUXT_PUBLIC_POWERSYNC_URL=your_powersync_instance_url | ||
| ``` | ||
|
|
||
| Replace the values with your actual credentials: | ||
|
|
||
| - Get `NUXT_PUBLIC_SUPABASE_URL` and `NUXT_PUBLIC_SUPABASE_ANON_KEY` from your Supabase project settings under "Project Settings" -> "API" | ||
| - Get `NUXT_PUBLIC_POWERSYNC_URL` from your PowerSync instance (Cloud dashboard or your self-hosted instance URL) | ||
|
|
||
| ### 6. Run the demo app | ||
|
|
||
| In this directory, run the following to start the development server: | ||
|
|
||
| ```bash | ||
| pnpm dev | ||
| ``` | ||
|
|
||
| Open [http://localhost:3000](http://localhost:3000) with your browser to try out the demo. | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ``` | ||
| ├── powersync/ | ||
| │ ├── AppSchema.ts # PowerSync schema definition | ||
| │ └── SuperbaseConnector.ts # Supabase connector implementation | ||
| ├── plugins/ | ||
| │ └── powersync.client.ts # PowerSync plugin setup | ||
| ├── pages/ | ||
| │ ├── index.vue # Main todo list page | ||
| │ ├── login.vue # Login page | ||
| │ └── confirm.vue # Auth confirmation page | ||
| ├── components/ | ||
| │ └── AppHeader.vue # Header component | ||
| ├── db/ | ||
| │ └── seed.sql # Database setup SQL | ||
| ├── powersync.yaml # PowerSync server configuration | ||
| ├── sync-rules.yaml # PowerSync sync rules | ||
| └── nuxt.config.ts # Nuxt configuration | ||
| ``` | ||
|
|
||
| ## Learn More | ||
|
khawarizmus marked this conversation as resolved.
|
||
|
|
||
| - [PowerSync Documentation](https://docs.powersync.com/) | ||
| - [Supabase Documentation](https://supabase.com/docs) | ||
| - [Nuxt Documentation](https://nuxt.com/) | ||
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,20 @@ | ||
| export default defineAppConfig({ | ||
| ui: { | ||
| colors: { | ||
| primary: 'indigo', | ||
| neutral: 'stone', | ||
| }, | ||
| input: { | ||
| variants: { | ||
| variant: { | ||
| subtle: 'ring-default bg-elevated/50', | ||
| }, | ||
| }, | ||
| }, | ||
| header: { | ||
| slots: { | ||
| root: 'border-none', | ||
| }, | ||
| }, | ||
| }, | ||
| }) |
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,58 @@ | ||
| <template> | ||
|
Chriztiaan marked this conversation as resolved.
|
||
| <UApp> | ||
| <NuxtLayout> | ||
| <NuxtPage /> | ||
| </NuxtLayout> | ||
| </UApp> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| useHead({ | ||
| meta: [{ name: 'viewport', content: 'width=device-width, initial-scale=1' }], | ||
| link: [{ rel: 'icon', href: '/favicon.ico' }], | ||
| htmlAttrs: { | ||
| lang: 'en', | ||
| }, | ||
| }) | ||
|
|
||
| const title = 'PowerSync Playground' | ||
| const description | ||
| = 'Demo of a simple todo list app using PowerSync and Supabase.' | ||
|
|
||
| useSeoMeta({ | ||
| title, | ||
| ogTitle: title, | ||
| description, | ||
| ogDescription: description, | ||
| }) | ||
|
|
||
| const appIsReady = ref(false) | ||
|
|
||
| provide('appIsReady', readonly(appIsReady)) | ||
|
|
||
| const powerSync = usePowerSync() | ||
| const syncStatus = usePowerSyncStatus() | ||
|
|
||
| const user = useSupabaseUser() | ||
| const { logger: powerSyncLogger } = useDiagnosticsLogger() | ||
|
|
||
| watch(user, () => { | ||
| if (user) { | ||
| if (syncStatus.value.hasSynced) { | ||
| powerSyncLogger.log('User is logged in and has synced...', { user: user, syncStatus: syncStatus.value }) | ||
| appIsReady.value = true | ||
| } | ||
| else { | ||
| powerSyncLogger.log('User is logged waiting for first sync...', { user: user, syncStatus: syncStatus.value }) | ||
| powerSync.value.waitForFirstSync().then(() => { | ||
| appIsReady.value = true | ||
| }) | ||
| } | ||
| } | ||
| else { | ||
| powerSyncLogger.log('User is not logged in disconnecting...', { user: user, syncStatus: syncStatus.value }) | ||
| powerSync.value.disconnect() | ||
| appIsReady.value = true | ||
| } | ||
| }, { immediate: true }) | ||
| </script> | ||
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,8 @@ | ||
| @import "tailwindcss"; | ||
| @import "@nuxt/ui"; | ||
|
|
||
| :root { | ||
| --ui-header-height: 40px; | ||
|
|
||
| --ui-container: 100%; | ||
| } |
14 changes: 14 additions & 0 deletions
14
demos/nuxt-supabase-todolist/assets/img/powersync-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,30 @@ | ||
| <template> | ||
| <UHeader :toggle="false"> | ||
| <template #left> | ||
| <UButton variant="link" @click="navigateTo('/')"> | ||
| <img src="~/assets/img/powersync-icon.svg" alt="Powersync" class="size-10 inline-flex"> | ||
| </UButton> | ||
| </template> | ||
|
|
||
| <template #right> | ||
| <UColorModeButton variant="link" /> | ||
|
|
||
| <UButton v-if="user" variant="link" class="cursor-pointer" color="neutral" @click="logout"> | ||
| Logout | ||
| </UButton> | ||
| </template> | ||
| </UHeader> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| const client = useSupabaseClient() | ||
| const user = useSupabaseUser() | ||
| const powerSync = usePowerSync() | ||
|
|
||
| const logout = async () => { | ||
| await powerSync.value.disconnectAndClear() | ||
|
|
||
| await client.auth.signOut() | ||
| navigateTo('/login') | ||
| } | ||
| </script> |
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,28 @@ | ||
| -- Past this into your Superbase SQL Editor | ||
|
|
||
| -- TODO change this if changing the DB connection name | ||
| -- connect postgres; | ||
| -- Create tables | ||
|
|
||
| CREATE TABLE IF NOT EXISTS public.tasks( | ||
| id uuid NOT NULL DEFAULT gen_random_uuid(), | ||
| created_at timestamp with time zone NOT NULL DEFAULT now(), | ||
| completed_at timestamp with time zone NULL, | ||
| description text NOT NULL, | ||
| completed boolean NOT NULL DEFAULT FALSE, | ||
| user_id uuid NOT NULL, | ||
| CONSTRAINT tasks_pkey PRIMARY KEY (id) | ||
| ); | ||
|
|
||
| -- Create a role/user with replication privileges for PowerSync | ||
| CREATE ROLE powersync_role WITH REPLICATION BYPASSRLS LOGIN PASSWORD 'postgres_12345'; | ||
| -- Set up permissions for the newly created role | ||
| -- Read-only (SELECT) access is required | ||
| GRANT SELECT ON ALL TABLES IN SCHEMA public TO powersync_role; | ||
|
|
||
| -- Optionally, grant SELECT on all future tables (to cater for schema additions) | ||
| ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO powersync_role; | ||
|
|
||
|
|
||
| -- Create publication for PowerSync tables | ||
| CREATE PUBLICATION powersync FOR ALL TABLES; |
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,9 @@ | ||
| // @ts-check | ||
| import withNuxt from './.nuxt/eslint.config.mjs' | ||
|
|
||
| export default withNuxt({ | ||
| rules: { | ||
| '@typescript-eslint/no-explicit-any': 'off', | ||
| 'nuxt/nuxt-config-keys-order': 'off', | ||
| }, | ||
| }) |
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,9 @@ | ||
| <template> | ||
| <div> | ||
| <AppHeader /> | ||
|
|
||
| <UMain> | ||
| <slot /> | ||
| </UMain> | ||
| </div> | ||
| </template> |
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.