diff --git a/apps/www/data/Community.tsx b/apps/www/data/Community.tsx index 618092900c6..1da7c6df686 100644 --- a/apps/www/data/Community.tsx +++ b/apps/www/data/Community.tsx @@ -30,7 +30,7 @@ const data: CommunityItem[] = [ }, { title: 'GitHub', - stat: '32,000+', + stat: '34,000+', statLabel: 'GitHub stars', img: 'github.png', invertImgDarkMode: true, @@ -42,7 +42,7 @@ const data: CommunityItem[] = [ }, { title: 'Twitter', - stat: '30,000+', + stat: '32,000+', statLabel: 'Followers', img: 'twitter.png', detail: () => ( @@ -54,7 +54,7 @@ const data: CommunityItem[] = [ { title: 'Discord', stat: '6,000+', - statLabel: 'SuperTroopers', + statLabel: 'SupaTroopers', img: 'discord.png', detail: () => (
diff --git a/apps/www/data/Press.ts b/apps/www/data/Press.ts index 43f1e2aeb27..598c3e712d6 100644 --- a/apps/www/data/Press.ts +++ b/apps/www/data/Press.ts @@ -14,39 +14,63 @@ const data: PressItem[] = [ }, { type: 'article', - href: 'https://techcrunch.com/2021/09/09/supabase-raises-30m-for-its-open-source-insta-backend', - title: 'Open source backend-as-a-service startup Supabase raises $30M', - publisher: 'TechCrunch', + href: 'https://www.prnewswire.com/news-releases/supabase-announces-80-million-series-b-led-by-felicis-301544453.html', + title: 'Supabase Announces $80 Million Series B Led by Felicis', + publisher: 'PR Newswire', }, { type: 'article', - href: 'https://techcrunch.com/2020/12/15/supabase-raises-6m-for-its-open-source-firebase-alternative', - title: 'Supabase raises $6M for its open-source Firebase alternative', - publisher: 'TechCrunch', + href: 'https://medium.com/lightspeedindia/our-investment-in-supabase-2f443ff55aad', + title: 'Our investment in Supabase', + publisher: 'Medium', }, { type: 'podcast', - href: 'https://softwareengineeringdaily.com/2020/10/15/supabase-open-source-firebase-with-paul-copplestone', - title: 'Software Engineering Daily', - publisher: 'Software Engineering Daily', + href: 'https://podcasts.apple.com/us/podcast/73-elixir-at-supabase-with-paul-copplestone/id1516100616?i=1000542087899', + title: 'Elixir at Supabase with Paul Copplestone', + publisher: 'Thinking Elixir Podcast', + }, + { + type: 'podcast', + href: 'https://podcasts.apple.com/us/podcast/73-elixir-at-supabase-with-paul-copplestone/id1516100616?i=1000542087899', + title: 'Ant Wilson on Supabase ', + publisher: 'Software Engineering Radio', + }, + { + type: 'podcast', + href: 'https://podcasts.apple.com/us/podcast/78-logflare-with-chase-granberry/id1516100616?i=1000545628124', + title: 'Logflare with Chase Granberry', + publisher: 'Thinking Elixir Podcast', + }, + { + type: 'podcast', + href: 'https://stackoverflow.blog/2022/05/17/open-source-is-winning-over-developers-and-investors-ep-442/', + title: 'Open-source is winning over developers and investors', + publisher: 'Stackoverflow', + }, + { + type: 'podcast', + href: 'https://changelog.com/podcast/476', + title: 'Supabase is all in on Postgres', + publisher: 'changelog', }, { type: 'podcast', href: 'https://fsjam.org/episodes/episode-33-supabase-with-paul-copplestone', - title: 'FS Jam', + title: 'Supabase with Paul Copplestone', publisher: 'FS Jam', }, { type: 'podcast', - href: 'https://www.heavybit.com/library/podcasts/jamstack-radio/ep-71-open-source-firebase-alternative-with-paul-copplestone-of-supabase', - title: 'Jamstack Radio', - publisher: 'Heavybit', + href: 'https://www.heavybit.com/library/podcasts/jamstack-radio/ep-71-open-source-firebase-alternative-with-paul-copplestone-of-supabase/', + title: 'Open Source Firebase Alternative with Paul Copplestone of Supabase', + publisher: 'Jamstack', }, { type: 'podcast', href: 'https://podrocket.logrocket.com/9', - title: 'PodRocket', - publisher: 'LogRocket', + title: 'Supabase with Paul Copplestone', + publisher: 'Podrocket', }, ] diff --git a/apps/www/pages/company.tsx b/apps/www/pages/company.tsx index 7563952bb65..ff673e8de4e 100644 --- a/apps/www/pages/company.tsx +++ b/apps/www/pages/company.tsx @@ -15,6 +15,7 @@ import InvestorData from 'data/Investors' import TeamData from 'data/Team' import Image from 'next/image' +import Link from 'next/link' import { Button, @@ -313,30 +314,38 @@ const Press = () => {
{PressData.filter((x) => x.type == 'article').map((x) => ( - - - -
-

{x.type.toUpperCase()}

-

{x.title}

-
-
-
-
+ + + + +
+

{x.type.toUpperCase()}

+

+ {x.title} +

+
+
+
+
+ ))}
{PressData.filter((x) => x.type == 'podcast').map((x) => ( - - - -
-

{x.type.toUpperCase()}

-

{x.title}

-
-
-
-
+ + + + +
+

{x.type.toUpperCase()}

+

+ {x.title} +

+
+
+
+
+ ))}
diff --git a/apps/www/styles/index.css b/apps/www/styles/index.css index 13b6b8b6e55..163baf6c97c 100644 --- a/apps/www/styles/index.css +++ b/apps/www/styles/index.css @@ -242,3 +242,10 @@ table { position: relative !important; height: unset !important; } + +.line-clamp { + display: -webkit-box; + margin: 0 auto; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} diff --git a/examples/todo-list/flutter-todo-list/.gitignore b/examples/todo-list/flutter-todo-list/.gitignore new file mode 100644 index 00000000000..0fa6b675c0a --- /dev/null +++ b/examples/todo-list/flutter-todo-list/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/examples/todo-list/flutter-todo-list/.metadata b/examples/todo-list/flutter-todo-list/.metadata new file mode 100644 index 00000000000..5a023280af4 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 7e9793dee1b85a243edd0e06cb1658e98b077561 + channel: stable + +project_type: app diff --git a/examples/todo-list/flutter-todo-list/README.md b/examples/todo-list/flutter-todo-list/README.md new file mode 100644 index 00000000000..117838af68f --- /dev/null +++ b/examples/todo-list/flutter-todo-list/README.md @@ -0,0 +1,64 @@ +# Flutter Todo example using Supabase + +## Build from scratch + +### 1. Create new project + +Sign up to Supabase - [https://app.supabase.com](https://app.supabase.com) and create a new project. Wait for your database to start. + +### 2. Run "Todo List" Quickstart + +Once your database has started, run the "Todo List" quickstart. Inside of your project, enter the `SQL editor` tab and scroll down until you see `TODO LIST: Build a basic todo list with Row Level Security`. + +### 3. Get the URL and Key + +Go to the Project Settings (the cog icon), open the API tab, and find your API URL and `anon` key, you'll need these in the next step. + +The `anon` key is your client-side API key. It allows "anonymous access" to your database, until the user has logged in. Once they have logged in, the keys will switch to the user's own login token. This enables row level security for your data. Read more about this [below](#postgres-row-level-security). + +![image](https://user-images.githubusercontent.com/10214025/88916245-528c2680-d298-11ea-8a71-708f93e1ce4f.png) + +**_NOTE_**: The `service_role` key has full access to your data, bypassing any security policies. These keys have to be kept secret and are meant to be used in server environments and never on a client or browser. + +## Supabase details + +### Postgres Row level security + +This project uses very high-level Authorization using Postgres' Role Level Security. +When you start a Postgres database on Supabase, we populate it with an `auth` schema, and some helper functions. +When a user logs in, they are issued a JWT with the role `authenticated` and their UUID. +We can use these details to provide fine-grained control over what each user can and cannot do. + +This is a trimmed-down schema, with the policies: + +```sql +create table todos ( + id bigint generated by default as identity primary key, + user_id uuid references auth.users not null, + task text check (char_length(task) > 3), + is_complete boolean default false, + inserted_at timestamp with time zone default timezone('utc'::text, now()) not null +); + +alter table todos enable row level security; + +create policy "Individuals can create todos." on todos for + insert with check (auth.uid() = user_id); + +create policy "Individuals can view their own todos. " on todos for + select using (auth.uid() = user_id); + +create policy "Individuals can update their own todos." on todos for + update using (auth.uid() = user_id); + +create policy "Individuals can delete their own todos." on todos for + delete using (auth.uid() = user_id); +``` + +## Authors + +- [Aniket Singh](https://github.com/Anikets08) +- [Tyler Shukert](https://github.com/dshukertjr) +- [Supabase](https://supabase.com) + +Supabase is open source. We'd love for you to follow along and get involved at https://github.com/supabase/supabase diff --git a/examples/todo-list/flutter-todo-list/analysis_options.yaml b/examples/todo-list/flutter-todo-list/analysis_options.yaml new file mode 100644 index 00000000000..dd058571417 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/analysis_options.yaml @@ -0,0 +1,6 @@ +include: package:lints/recommended.yaml + +linter: + rules: + prefer_single_quotes: true + require_trailing_commas: true \ No newline at end of file diff --git a/examples/todo-list/flutter-todo-list/android/.gitignore b/examples/todo-list/flutter-todo-list/android/.gitignore new file mode 100644 index 00000000000..6f568019d3c --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/examples/todo-list/flutter-todo-list/android/app/build.gradle b/examples/todo-list/flutter-todo-list/android/app/build.gradle new file mode 100644 index 00000000000..7e58ab90520 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/build.gradle @@ -0,0 +1,68 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion flutter.compileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.todosupabase" + minSdkVersion flutter.minSdkVersion + targetSdkVersion flutter.targetSdkVersion + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/examples/todo-list/flutter-todo-list/android/app/src/debug/AndroidManifest.xml b/examples/todo-list/flutter-todo-list/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000000..2b76131d6bb --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/AndroidManifest.xml b/examples/todo-list/flutter-todo-list/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..d36513d9e95 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/kotlin/com/example/todosupabase/MainActivity.kt b/examples/todo-list/flutter-todo-list/android/app/src/main/kotlin/com/example/todosupabase/MainActivity.kt new file mode 100644 index 00000000000..a97a4a1bbe3 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/src/main/kotlin/com/example/todosupabase/MainActivity.kt @@ -0,0 +1,6 @@ +package com.example.todosupabase + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/drawable-v21/launch_background.xml b/examples/todo-list/flutter-todo-list/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 00000000000..f74085f3f6a --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/drawable/launch_background.xml b/examples/todo-list/flutter-todo-list/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000000..304732f8842 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000000..db77bb4b7b0 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000000..17987b79bb8 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000000..09d4391482b Binary files /dev/null and b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000000..d5f1c8d34e7 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000000..4d6372eebdb Binary files /dev/null and b/examples/todo-list/flutter-todo-list/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/values-night/styles.xml b/examples/todo-list/flutter-todo-list/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 00000000000..3db14bb5391 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/android/app/src/main/res/values/styles.xml b/examples/todo-list/flutter-todo-list/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000000..d460d1e9215 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/android/app/src/profile/AndroidManifest.xml b/examples/todo-list/flutter-todo-list/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000000..2b76131d6bb --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/examples/todo-list/flutter-todo-list/android/build.gradle b/examples/todo-list/flutter-todo-list/android/build.gradle new file mode 100644 index 00000000000..4256f917362 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.6.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.1.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/examples/todo-list/flutter-todo-list/android/gradle.properties b/examples/todo-list/flutter-todo-list/android/gradle.properties new file mode 100644 index 00000000000..94adc3a3f97 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/examples/todo-list/flutter-todo-list/android/gradle/wrapper/gradle-wrapper.properties b/examples/todo-list/flutter-todo-list/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..bc6a58afdda --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/examples/todo-list/flutter-todo-list/android/settings.gradle b/examples/todo-list/flutter-todo-list/android/settings.gradle new file mode 100644 index 00000000000..44e62bcf06a --- /dev/null +++ b/examples/todo-list/flutter-todo-list/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/examples/todo-list/flutter-todo-list/assets/supabase-logo.png b/examples/todo-list/flutter-todo-list/assets/supabase-logo.png new file mode 100644 index 00000000000..70e14586dbe Binary files /dev/null and b/examples/todo-list/flutter-todo-list/assets/supabase-logo.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/.gitignore b/examples/todo-list/flutter-todo-list/ios/.gitignore new file mode 100644 index 00000000000..7a7f9873ad7 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/examples/todo-list/flutter-todo-list/ios/Flutter/AppFrameworkInfo.plist b/examples/todo-list/flutter-todo-list/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000000..8d4492f977a --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 9.0 + + diff --git a/examples/todo-list/flutter-todo-list/ios/Flutter/Debug.xcconfig b/examples/todo-list/flutter-todo-list/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000000..ec97fc6f302 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/examples/todo-list/flutter-todo-list/ios/Flutter/Release.xcconfig b/examples/todo-list/flutter-todo-list/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000000..c4855bfe200 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/examples/todo-list/flutter-todo-list/ios/Podfile b/examples/todo-list/flutter-todo-list/ios/Podfile new file mode 100644 index 00000000000..1e8c3c90a55 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.pbxproj b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..c699b229cca --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,481 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.todosupabase; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.todosupabase; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.todosupabase; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..919434a6254 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000..18d981003d6 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000000..f9b0d7c5ea1 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000000..c87d15a3352 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/contents.xcworkspacedata b/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..1d526a16ed0 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000..18d981003d6 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000000..f9b0d7c5ea1 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/AppDelegate.swift b/examples/todo-list/flutter-todo-list/ios/Runner/AppDelegate.swift new file mode 100644 index 00000000000..70693e4a8c1 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000..d36b1fab2d9 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000000..dc9ada4725e Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000000..28c6bf03016 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000000..2ccbfd967d9 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000000..f091b6b0bca Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000000..4cde12118dd Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000000..d0ef06e7edb Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000000..dcdc2306c28 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000000..2ccbfd967d9 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000000..c8f9ed8f5ce Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000000..a6d6b8609df Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000000..a6d6b8609df Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000000..75b2d164a5a Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000000..c4df70d39da Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000000..6a84f41e14e Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000000..d0e1f585360 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000000..0bedcf2fd46 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000000..9da19eacad3 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000000..9da19eacad3 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000000..9da19eacad3 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000000..89c2725b70f --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Base.lproj/LaunchScreen.storyboard b/examples/todo-list/flutter-todo-list/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000000..f2e259c7c93 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Base.lproj/Main.storyboard b/examples/todo-list/flutter-todo-list/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000000..f3c28516fb3 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Info.plist b/examples/todo-list/flutter-todo-list/ios/Runner/Info.plist new file mode 100644 index 00000000000..b2265502bea --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Todosupabase + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + todosupabase + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/examples/todo-list/flutter-todo-list/ios/Runner/Runner-Bridging-Header.h b/examples/todo-list/flutter-todo-list/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 00000000000..308a2a560b4 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/examples/todo-list/flutter-todo-list/lib/constant.dart b/examples/todo-list/flutter-todo-list/lib/constant.dart new file mode 100644 index 00000000000..70abe48f080 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/lib/constant.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; + +const smallGap = SizedBox(height: 20); +const largeGap = SizedBox(height: 40); +final client = Supabase.instance.client; +final appTheme = ThemeData.dark().copyWith( + scaffoldBackgroundColor: Colors.black, + appBarTheme: const AppBarTheme( + backgroundColor: Colors.transparent, + elevation: 0, + ), + outlinedButtonTheme: OutlinedButtonThemeData( + style: OutlinedButton.styleFrom( + primary: Colors.white, + side: const BorderSide(color: Colors.white, width: 2), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + padding: const EdgeInsets.all(16), + ), + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + primary: Colors.white, + onPrimary: Colors.black, + textStyle: const TextStyle( + fontWeight: FontWeight.bold, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + padding: const EdgeInsets.all(16), + ), + ), + inputDecorationTheme: InputDecorationTheme( + labelStyle: const TextStyle(color: Colors.white), + focusColor: Colors.green, + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide( + color: Colors.white, + width: 2, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide( + color: Colors.green, + width: 2, + ), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + textTheme: const TextTheme( + bodyText1: TextStyle(color: Colors.white), + bodyText2: TextStyle(color: Colors.white), + ), +); + +extension ShowSnackBar on BuildContext { + /// Extention method to easily display error snack bar. + void showErrorSnackbar(String text) { + ScaffoldMessenger.of(this).showSnackBar( + SnackBar( + content: Text( + text, + style: const TextStyle(color: Color(0xFFFFFFFF)), + ), + backgroundColor: Colors.red, + ), + ); + } +} diff --git a/examples/todo-list/flutter-todo-list/lib/main.dart b/examples/todo-list/flutter-todo-list/lib/main.dart new file mode 100644 index 00000000000..ff4dcd5b46d --- /dev/null +++ b/examples/todo-list/flutter-todo-list/lib/main.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:supabase_flutter/supabase_flutter.dart'; +import 'package:todosupabase/constant.dart'; +import 'package:todosupabase/screens/signup.dart'; +import 'package:todosupabase/screens/signin.dart'; +import 'package:todosupabase/screens/todo.dart'; + +void main() async { + await Supabase.initialize( + url: 'YOUR_SUPABASE_URL', + anonKey: 'YOUR_SUPABASE_KEY', + ); + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: appTheme, + initialRoute: client.auth.currentSession != null ? '/todo' : '/', + routes: { + '/': (context) => const MyHomePage(), + '/signup': (context) => const SignUpPage(), + '/signin': (context) => const SignInPage(), + '/todo': (context) => const TodoPage(), + }, + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({Key? key}) : super(key: key); + + @override + State createState() => MyHomePageState(); +} + +class MyHomePageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 300), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Image.asset( + 'assets/supabase-logo.png', + height: 40, + ), + largeGap, + OutlinedButton( + child: const Text('Sign In'), + onPressed: () { + Navigator.pushNamed(context, '/signin'); + }, + ), + smallGap, + OutlinedButton( + child: const Text('Sign Up'), + onPressed: () { + Navigator.pushNamed(context, '/signup'); + }, + ) + ], + ), + ), + ), + ); + } +} diff --git a/examples/todo-list/flutter-todo-list/lib/screens/signin.dart b/examples/todo-list/flutter-todo-list/lib/screens/signin.dart new file mode 100644 index 00000000000..db64dc4eab5 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/lib/screens/signin.dart @@ -0,0 +1,91 @@ +import 'package:flutter/material.dart'; +import 'package:todosupabase/constant.dart'; + +class SignInPage extends StatefulWidget { + const SignInPage({Key? key}) : super(key: key); + + @override + State createState() => _SignInPageState(); +} + +class _SignInPageState extends State { + final TextEditingController _emailController = TextEditingController(); + final TextEditingController _passwordController = TextEditingController(); + bool loading = false; + Future loginUser({ + required String email, + required String password, + }) async { + final res = await client.auth.signIn(email: email, password: password); + final user = res.data?.user; + return user?.id; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + body: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 300), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Image.asset( + 'assets/supabase-logo.png', + height: 40, + ), + largeGap, + TextFormField( + controller: _emailController, + decoration: const InputDecoration(label: Text('Email')), + keyboardType: TextInputType.emailAddress, + ), + smallGap, + TextFormField( + controller: _passwordController, + decoration: const InputDecoration(label: Text('Password')), + obscureText: true, + ), + smallGap, + loading + ? Container( + height: 50, + width: 50, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(50), + ), + child: const Center( + child: CircularProgressIndicator(), + ), + ) + : ElevatedButton( + child: const Text('Sign In'), + onPressed: () async { + setState(() { + loading = true; + }); + var value = await loginUser( + email: _emailController.text, + password: _passwordController.text, + ); + setState(() { + loading = false; + }); + if (value != null) { + Navigator.pushReplacementNamed(context, '/todo'); + } else { + context + .showErrorSnackbar('Invalid Email or Password'); + } + }, + ) + ], + ), + ), + ), + ); + } +} diff --git a/examples/todo-list/flutter-todo-list/lib/screens/signup.dart b/examples/todo-list/flutter-todo-list/lib/screens/signup.dart new file mode 100644 index 00000000000..0ff98c454e4 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/lib/screens/signup.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; +import 'package:todosupabase/constant.dart'; + +class SignUpPage extends StatefulWidget { + const SignUpPage({Key? key}) : super(key: key); + + @override + State createState() => _SignUpPageState(); +} + +class _SignUpPageState extends State { + final TextEditingController _emailController = TextEditingController(); + final TextEditingController _passwordController = TextEditingController(); + final TextEditingController _nameController = TextEditingController(); + + Future createAccount({ + required String email, + required String password, + }) async { + final res = await client.auth.signUp(email, password); + final error = res.error; + if (error == null) { + return true; + } else { + return false; + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + body: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 300), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Image.asset( + 'assets/supabase-logo.png', + height: 40, + ), + largeGap, + TextFormField( + controller: _nameController, + decoration: const InputDecoration( + label: Text('Username'), + ), + ), + smallGap, + TextFormField( + controller: _emailController, + decoration: const InputDecoration( + label: Text('Email'), + ), + keyboardType: TextInputType.emailAddress, + ), + smallGap, + TextFormField( + controller: _passwordController, + decoration: const InputDecoration( + label: Text('Password'), + ), + obscureText: true, + ), + smallGap, + ElevatedButton( + child: const Text('Sign Up'), + onPressed: () async { + final value = await createAccount( + email: _emailController.text, + password: _passwordController.text, + ); + if (value == true) { + Navigator.pushReplacementNamed(context, '/signin'); + } + }, + ) + ], + ), + ), + ), + ); + } +} diff --git a/examples/todo-list/flutter-todo-list/lib/screens/todo.dart b/examples/todo-list/flutter-todo-list/lib/screens/todo.dart new file mode 100644 index 00000000000..7c88411a7d8 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/lib/screens/todo.dart @@ -0,0 +1,296 @@ +import 'package:flutter/material.dart'; +import 'package:todosupabase/constant.dart'; + +class TodoPage extends StatefulWidget { + const TodoPage({Key? key}) : super(key: key); + + @override + State createState() => _TodoPageState(); +} + +class _TodoPageState extends State { + bool loading = true; + List todos = []; + final TextEditingController _taskEditingController = TextEditingController(); + Future logOut(BuildContext context) async { + await client.auth.signOut(); + } + + // GETR THE TODOS + Future> getTodo() async { + final res = await client + .from('todos') + .select('*') + .eq('user_id', client.auth.currentUser!.id) + .order('id') + .execute(); + final data = res.data; + return data; + } + + // ADD A Todo IN THE DB + Future addTodo({ + required String task, + }) async { + final res = await client.from('todos').insert({ + 'user_id': client.auth.currentUser!.id, + 'task': task, + }).execute(); + final data = res.data; + return data; + } + + // DELETE A Todo IN THE DB + Future deleteTodo({required String id}) async { + try { + await client.from('todos').delete().eq('id', id).execute(); + } catch (e) { + print(e); + } + } + + // toggle a Todo IN THE DB + Future taskDone({ + required String id, + required bool value, + }) async { + final res = await client + .from('todos') + .update({'done': value}) + .eq('id', id) + .execute(); + final data = res.data; + return data; + } + + // Edit a Todo IN THE DB + Future editTask({ + required String id, + required String task, + }) async { + final res = await client + .from('todos') + .update({'task': task}) + .eq('id', id) + .execute(); + final data = res.data; + return data; + } + + Future initFunc() async { + List value = await getTodo(); + for (var element in value) { + todos.add(element); + } + setState(() { + loading = false; + }); + } + + @override + void initState() { + initFunc(); + super.initState(); + } + + @override + void dispose() { + super.dispose(); + _taskEditingController.dispose(); + } + + Future displayTextInputDialog({ + required BuildContext context, + void Function()? onTap, + required TextEditingController taskCtrl, + }) async { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text('Add a todo'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: taskCtrl, + decoration: + const InputDecoration(hintText: 'Add title of todo'), + ), + smallGap, + MaterialButton( + onPressed: onTap, + child: const Text( + 'Add Task', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + color: const Color(0xff33b27b), + ) + ], + ), + ); + }, + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.black, + automaticallyImplyLeading: false, + title: Text('Supabase Todo'), + actions: [ + IconButton( + icon: const Icon(Icons.exit_to_app), + onPressed: () async { + await logOut(context); + Navigator.pop(context, '/'); + }, + ), + ], + ), + body: loading + ? const Center(child: CircularProgressIndicator()) + : ConstrainedBox( + constraints: const BoxConstraints(), + child: todos.isEmpty + ? const Center( + child: Text('No Task, add new task'), + ) + : ListView.builder( + itemCount: todos.length, + itemBuilder: (context, index) { + return ListTile( + //Long Press to edit + onLongPress: () { + displayTextInputDialog( + context: context, + taskCtrl: _taskEditingController, + onTap: () async { + await editTask( + id: todos[index]['id'].toString(), + task: _taskEditingController.text, + ); + Navigator.pop(context); + setState(() { + loading = true; + }); + List value = await getTodo(); + todos.clear(); + for (var element in value) { + todos.add(element); + } + setState(() { + loading = false; + }); + }, + ); + }, + title: Text( + todos[index]['task'], + style: const TextStyle(color: Colors.white), + ), + + leading: GestureDetector( + onTap: () async { + setState(() { + loading = true; + }); + await deleteTodo( + id: todos[index]['id'].toString(), + ); + List value = await getTodo(); + todos.clear(); + for (var element in value) { + todos.add(element); + } + setState(() { + loading = false; + }); + }, + child: const Icon( + Icons.delete, + color: Colors.white, + ), + ), + trailing: GestureDetector( + onTap: () async { + setState(() { + loading = true; + }); + await taskDone( + id: todos[index]['id'].toString(), + value: !todos[index]['done'], + ); + List value = await getTodo(); + todos.clear(); + for (var element in value) { + todos.add(element); + } + setState(() { + loading = false; + }); + }, + child: Container( + height: 25, + width: 25, + decoration: BoxDecoration( + border: Border.all( + color: const Color(0xff33b27b), + width: 2, + ), + color: todos[index]['done'] + ? const Color(0xff33b27b) + : Colors.transparent, + borderRadius: BorderRadius.circular(5), + ), + child: todos[index]['done'] + ? const Center( + child: Icon( + Icons.done, + size: 15, + color: Colors.white, + ), + ) + : const SizedBox(), + ), + ), + ); + }, + ), + ), + floatingActionButton: FloatingActionButton( + backgroundColor: const Color(0xff33b27b), + child: const Icon(Icons.add), + onPressed: () { + displayTextInputDialog( + context: context, + taskCtrl: _taskEditingController, + onTap: () async { + await addTodo( + task: _taskEditingController.text, + ); + Navigator.pop(context); + setState(() { + loading = true; + }); + + List value = await getTodo(); + todos.clear(); + for (var element in value) { + todos.add(element); + } + setState(() { + loading = false; + }); + }, + ); + }, + ), + ); + } +} diff --git a/examples/todo-list/flutter-todo-list/pubspec.lock b/examples/todo-list/flutter-todo-list/pubspec.lock new file mode 100644 index 00000000000..0e79993e7c3 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/pubspec.lock @@ -0,0 +1,488 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.8.2" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_svg: + dependency: "direct main" + description: + name: flutter_svg + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + functions_client: + dependency: transitive + description: + name: functions_client + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1-dev.5" + gotrue: + dependency: transitive + description: + name: gotrue + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.2" + hive: + dependency: transitive + description: + name: hive + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" + hive_flutter: + dependency: transitive + description: + name: hive_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + jwt_decode: + dependency: transitive + description: + name: jwt_decode + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.1" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + path_drawing: + dependency: transitive + description: + name: path_drawing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.10" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.14" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.7" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + postgrest: + dependency: transitive + description: + name: postgrest + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.10+1" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + realtime_client: + dependency: transitive + description: + name: realtime_client + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.15" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + storage_client: + dependency: transitive + description: + name: storage_client + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.6+2" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + supabase: + dependency: transitive + description: + name: supabase + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" + supabase_flutter: + dependency: "direct main" + description: + name: supabase_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.1+1" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.8" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + uni_links: + dependency: transitive + description: + name: uni_links + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.1" + uni_links_platform_interface: + dependency: transitive + description: + name: uni_links_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + uni_links_web: + dependency: transitive + description: + name: uni_links_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" + universal_io: + dependency: transitive + description: + name: universal_io + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + url_launcher: + dependency: transitive + description: + name: url_launcher + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.17" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.17" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.5.2" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+1" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "5.3.1" +sdks: + dart: ">=2.16.1 <3.0.0" + flutter: ">=2.10.0" diff --git a/examples/todo-list/flutter-todo-list/pubspec.yaml b/examples/todo-list/flutter-todo-list/pubspec.yaml new file mode 100644 index 00000000000..3d4df48cc8d --- /dev/null +++ b/examples/todo-list/flutter-todo-list/pubspec.yaml @@ -0,0 +1,87 @@ +name: todosupabase +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: "none" # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.16.1 <3.0.0" + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + supabase_flutter: ^0.3.1+1 + flutter_svg: ^1.0.3 + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + lints: ^2.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/ + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/examples/todo-list/flutter-todo-list/test/widget_test.dart b/examples/todo-list/flutter-todo-list/test/widget_test.dart new file mode 100644 index 00000000000..d2e1174ab0d --- /dev/null +++ b/examples/todo-list/flutter-todo-list/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:todosupabase/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/examples/todo-list/flutter-todo-list/web/favicon.png b/examples/todo-list/flutter-todo-list/web/favicon.png new file mode 100644 index 00000000000..8aaa46ac1ae Binary files /dev/null and b/examples/todo-list/flutter-todo-list/web/favicon.png differ diff --git a/examples/todo-list/flutter-todo-list/web/icons/Icon-192.png b/examples/todo-list/flutter-todo-list/web/icons/Icon-192.png new file mode 100644 index 00000000000..b749bfef074 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/web/icons/Icon-192.png differ diff --git a/examples/todo-list/flutter-todo-list/web/icons/Icon-512.png b/examples/todo-list/flutter-todo-list/web/icons/Icon-512.png new file mode 100644 index 00000000000..88cfd48dff1 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/web/icons/Icon-512.png differ diff --git a/examples/todo-list/flutter-todo-list/web/icons/Icon-maskable-192.png b/examples/todo-list/flutter-todo-list/web/icons/Icon-maskable-192.png new file mode 100644 index 00000000000..eb9b4d76e52 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/web/icons/Icon-maskable-192.png differ diff --git a/examples/todo-list/flutter-todo-list/web/icons/Icon-maskable-512.png b/examples/todo-list/flutter-todo-list/web/icons/Icon-maskable-512.png new file mode 100644 index 00000000000..d69c56691fb Binary files /dev/null and b/examples/todo-list/flutter-todo-list/web/icons/Icon-maskable-512.png differ diff --git a/examples/todo-list/flutter-todo-list/web/index.html b/examples/todo-list/flutter-todo-list/web/index.html new file mode 100644 index 00000000000..2f674a9a5df --- /dev/null +++ b/examples/todo-list/flutter-todo-list/web/index.html @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + todosupabase + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/web/manifest.json b/examples/todo-list/flutter-todo-list/web/manifest.json new file mode 100644 index 00000000000..101869135b0 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "todosupabase", + "short_name": "todosupabase", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/examples/todo-list/flutter-todo-list/windows/.gitignore b/examples/todo-list/flutter-todo-list/windows/.gitignore new file mode 100644 index 00000000000..d492d0d98c8 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/examples/todo-list/flutter-todo-list/windows/CMakeLists.txt b/examples/todo-list/flutter-todo-list/windows/CMakeLists.txt new file mode 100644 index 00000000000..b327d83ddfa --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/CMakeLists.txt @@ -0,0 +1,95 @@ +cmake_minimum_required(VERSION 3.14) +project(todosupabase LANGUAGES CXX) + +set(BINARY_NAME "todosupabase") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() + +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/examples/todo-list/flutter-todo-list/windows/flutter/CMakeLists.txt b/examples/todo-list/flutter-todo-list/windows/flutter/CMakeLists.txt new file mode 100644 index 00000000000..b2e4bd8d658 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/flutter/CMakeLists.txt @@ -0,0 +1,103 @@ +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugin_registrant.cc b/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 00000000000..4f7884874da --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,14 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include + +void RegisterPlugins(flutter::PluginRegistry* registry) { + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); +} diff --git a/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugin_registrant.h b/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 00000000000..dc139d85a93 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugins.cmake b/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugins.cmake new file mode 100644 index 00000000000..411af46dd72 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/flutter/generated_plugins.cmake @@ -0,0 +1,16 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + url_launcher_windows +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) diff --git a/examples/todo-list/flutter-todo-list/windows/runner/CMakeLists.txt b/examples/todo-list/flutter-todo-list/windows/runner/CMakeLists.txt new file mode 100644 index 00000000000..de2d8916b72 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) +apply_standard_settings(${BINARY_NAME}) +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/examples/todo-list/flutter-todo-list/windows/runner/Runner.rc b/examples/todo-list/flutter-todo-list/windows/runner/Runner.rc new file mode 100644 index 00000000000..d5d06e6d49f --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#ifdef FLUTTER_BUILD_NUMBER +#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#else +#define VERSION_AS_NUMBER 1,0,0 +#endif + +#ifdef FLUTTER_BUILD_NAME +#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "todosupabase" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "todosupabase" "\0" + VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "todosupabase.exe" "\0" + VALUE "ProductName", "todosupabase" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/examples/todo-list/flutter-todo-list/windows/runner/flutter_window.cpp b/examples/todo-list/flutter-todo-list/windows/runner/flutter_window.cpp new file mode 100644 index 00000000000..b43b9095ea3 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/flutter_window.cpp @@ -0,0 +1,61 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/examples/todo-list/flutter-todo-list/windows/runner/flutter_window.h b/examples/todo-list/flutter-todo-list/windows/runner/flutter_window.h new file mode 100644 index 00000000000..6da0652f05f --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/examples/todo-list/flutter-todo-list/windows/runner/main.cpp b/examples/todo-list/flutter-todo-list/windows/runner/main.cpp new file mode 100644 index 00000000000..530c79c58e5 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"todosupabase", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/examples/todo-list/flutter-todo-list/windows/runner/resource.h b/examples/todo-list/flutter-todo-list/windows/runner/resource.h new file mode 100644 index 00000000000..66a65d1e4a7 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/examples/todo-list/flutter-todo-list/windows/runner/resources/app_icon.ico b/examples/todo-list/flutter-todo-list/windows/runner/resources/app_icon.ico new file mode 100644 index 00000000000..c04e20caf63 Binary files /dev/null and b/examples/todo-list/flutter-todo-list/windows/runner/resources/app_icon.ico differ diff --git a/examples/todo-list/flutter-todo-list/windows/runner/runner.exe.manifest b/examples/todo-list/flutter-todo-list/windows/runner/runner.exe.manifest new file mode 100644 index 00000000000..c977c4a4258 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/examples/todo-list/flutter-todo-list/windows/runner/utils.cpp b/examples/todo-list/flutter-todo-list/windows/runner/utils.cpp new file mode 100644 index 00000000000..d19bdbbcc32 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/utils.cpp @@ -0,0 +1,64 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr); + if (target_length == 0) { + return std::string(); + } + std::string utf8_string; + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, utf8_string.data(), + target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/examples/todo-list/flutter-todo-list/windows/runner/utils.h b/examples/todo-list/flutter-todo-list/windows/runner/utils.h new file mode 100644 index 00000000000..3879d547557 --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/examples/todo-list/flutter-todo-list/windows/runner/win32_window.cpp b/examples/todo-list/flutter-todo-list/windows/runner/win32_window.cpp new file mode 100644 index 00000000000..c10f08dc7da --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/win32_window.cpp @@ -0,0 +1,245 @@ +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} diff --git a/examples/todo-list/flutter-todo-list/windows/runner/win32_window.h b/examples/todo-list/flutter-todo-list/windows/runner/win32_window.h new file mode 100644 index 00000000000..17ba431125b --- /dev/null +++ b/examples/todo-list/flutter-todo-list/windows/runner/win32_window.h @@ -0,0 +1,98 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/studio/components/grid/SupabaseGrid.tsx b/studio/components/grid/SupabaseGrid.tsx index 4f192d036d5..6a09b66a572 100644 --- a/studio/components/grid/SupabaseGrid.tsx +++ b/studio/components/grid/SupabaseGrid.tsx @@ -1,40 +1,33 @@ -import React from 'react'; -import { createPortal } from 'react-dom'; -import { useMonaco } from '@monaco-editor/react'; -import { DndProvider } from 'react-dnd'; -import { HTML5Backend } from 'react-dnd-html5-backend'; -import { Dictionary, SupabaseGridProps, SupabaseGridRef } from './types'; -import { DataGridHandle } from '@supabase/react-data-grid'; -import { RowContextMenu } from './components/menu'; -import { StoreProvider, useDispatch, useTrackedState } from './store'; -import { fetchCount, fetchPage, refreshPageDebounced } from './utils'; -import { REFRESH_PAGE_IMMEDIATELY, TOTAL_ROWS_RESET } from './constants'; -import { Grid } from './components/grid'; -import { Shortcuts } from './components/common'; -import Header from './components/header'; -import Footer from './components/footer'; -import { - cleanupProps, - initTable, - saveStorageDebounced, -} from './SupabaseGrid.utils'; +import { useEffect, useState, useRef, forwardRef, useImperativeHandle } from 'react' +import { createPortal } from 'react-dom' +import { useMonaco } from '@monaco-editor/react' +import { DndProvider } from 'react-dnd' +import { HTML5Backend } from 'react-dnd-html5-backend' +import { Dictionary, SupabaseGridProps, SupabaseGridRef } from './types' +import { DataGridHandle } from '@supabase/react-data-grid' +import { RowContextMenu } from './components/menu' +import { StoreProvider, useDispatch, useTrackedState } from './store' +import { fetchCount, fetchPage, refreshPageDebounced } from './utils' +import { REFRESH_PAGE_IMMEDIATELY, TOTAL_ROWS_RESET } from './constants' +import { Grid } from './components/grid' +import { Shortcuts } from './components/common' +import Header from './components/header' +import Footer from './components/footer' +import { cleanupProps, initTable, saveStorageDebounced } from './SupabaseGrid.utils' /** * Supabase Grid. * * React component to render database table. */ -export const SupabaseGrid = React.forwardRef< - SupabaseGridRef, - SupabaseGridProps ->((props, ref) => { - const monaco = useMonaco(); - const _props = cleanupProps(props); - const { theme } = _props; +export const SupabaseGrid = forwardRef((props, ref) => { + const monaco = useMonaco() + const _props = cleanupProps(props) + const { theme } = _props - React.useEffect(() => { + useEffect(() => { if (monaco) { - const darkTheme = theme && theme === 'dark' ? true : false; + const darkTheme = theme && theme === 'dark' ? true : false monaco.editor.defineTheme('supabase', { base: 'vs-dark', // can also be vs-dark or hc-black @@ -47,9 +40,9 @@ export const SupabaseGrid = React.forwardRef< colors: { 'editor.background': darkTheme ? '#1f1f1f' : '#30313f', }, - }); + }) } - }, [monaco]); + }, [monaco]) return ( @@ -57,103 +50,101 @@ export const SupabaseGrid = React.forwardRef< - ); -}); + ) +}) -const SupabaseGridLayout = React.forwardRef( - (props, ref) => { - const { editable, storageRef, gridProps, headerActions } = props; - const dispatch = useDispatch(); - const state = useTrackedState(); - const gridRef = React.useRef(null); - const [mounted, setMount] = React.useState(false); +const SupabaseGridLayout = forwardRef((props, ref) => { + const { editable, storageRef, gridProps, headerActions } = props + const dispatch = useDispatch() + const state = useTrackedState() + const gridRef = useRef(null) + const [mounted, setMount] = useState(false) - React.useImperativeHandle(ref, () => ({ - rowAdded(row: Dictionary) { - dispatch({ - type: 'ADD_NEW_ROW', - payload: row, - }); - }, - rowEdited(row: Dictionary, idx: number) { - dispatch({ - type: 'EDIT_ROW', - payload: { row, idx }, - }); - }, - })); + useImperativeHandle(ref, () => ({ + rowAdded(row: Dictionary) { + dispatch({ + type: 'ADD_NEW_ROW', + payload: row, + }) + }, + rowEdited(row: Dictionary, idx: number) { + dispatch({ + type: 'EDIT_ROW', + payload: { row, idx }, + }) + }, + })) - React.useEffect(() => { - if (!mounted) setMount(true); - }, []); + useEffect(() => { + if (!mounted) setMount(true) + }, []) - React.useEffect(() => { - if (state.isInitialComplete && storageRef && state.table) { - saveStorageDebounced(state, storageRef); - } - }, [ - state.table, - state.isInitialComplete, - state.gridColumns, - state.sorts, - state.filters, - storageRef, - ]); + useEffect(() => { + if (state.isInitialComplete && storageRef && state.table) { + saveStorageDebounced(state, storageRef) + } + }, [ + state.table, + state.isInitialComplete, + state.gridColumns, + state.sorts, + state.filters, + storageRef, + ]) - React.useEffect(() => { - if (state.refreshPageFlag == REFRESH_PAGE_IMMEDIATELY) { - fetchPage(state, dispatch); - } else if (state.refreshPageFlag != 0) { - refreshPageDebounced(state, dispatch); - } - }, [state.refreshPageFlag]); + useEffect(() => { + if (state.refreshPageFlag == REFRESH_PAGE_IMMEDIATELY) { + fetchPage(state, dispatch) + } else if (state.refreshPageFlag != 0) { + refreshPageDebounced(state, dispatch) + } + }, [state.refreshPageFlag]) - React.useEffect(() => { - if (state.totalRows === TOTAL_ROWS_RESET) { - fetchCount(state, dispatch); - } - }, [state.totalRows]); + useEffect(() => { + if (state.totalRows === TOTAL_ROWS_RESET) { + fetchCount(state, dispatch) + } + }, [state.totalRows]) - React.useEffect(() => { - if (!state.metaService) { - dispatch({ - type: 'INIT_CLIENT', - payload: { onSqlQuery: props.onSqlQuery }, - }); - dispatch({ - type: 'INIT_CALLBACK', - payload: { ...props }, - }); - } - }, [state.metaService]); + useEffect(() => { + if (!state.metaService) { + dispatch({ + type: 'INIT_CLIENT', + payload: { onSqlQuery: props.onSqlQuery }, + }) + dispatch({ + type: 'INIT_CALLBACK', + payload: { ...props }, + }) + } + }, [state.metaService]) - React.useEffect(() => { - if (!state.metaService) return; + useEffect(() => { + if (!state.metaService) return - if ( - !state.table || - (typeof props.table == 'string' && - state.table!.name != props.table && - state.table!.schema != props.schema) || - (typeof props.table != 'string' && - JSON.stringify(props.table) !== JSON.stringify(state.table)) - ) { - initTable(props, state, dispatch); - } - }, [state.metaService, state.table, props.table, props.schema]); + if ( + !state.table || + (typeof props.table == 'string' && + state.table!.name != props.table && + state.table!.schema != props.schema) || + (typeof props.table != 'string' && + JSON.stringify(props.table) !== JSON.stringify(state.table)) + ) { + initTable(props, state, dispatch) + } + }, [state.metaService, state.table, props.table, props.schema]) - return ( -
-
- -
- - {mounted && createPortal(, document.body)} -
- ); - } -); + return ( +
+
+ +
+ + {mounted && createPortal(, document.body)} +
+ ) +}) diff --git a/studio/components/grid/components/common/ConfirmAlert.tsx b/studio/components/grid/components/common/ConfirmAlert.tsx index d1e0dd7f03a..294e3916cc0 100644 --- a/studio/components/grid/components/common/ConfirmAlert.tsx +++ b/studio/components/grid/components/common/ConfirmAlert.tsx @@ -1,14 +1,14 @@ -import * as React from 'react'; -import { Button, Modal } from '@supabase/ui'; -import { render, unmountComponentAtNode } from 'react-dom'; +import * as React from 'react' +import { Button, Modal } from '@supabase/ui' +import { render, unmountComponentAtNode } from 'react-dom' type ConfirmModalProps = { - title: string; - message: string; - onConfirm?: () => void; - onAsyncConfirm?: () => Promise; - variant?: 'danger' | 'warning' | 'success' | undefined; -}; + title: string + message: string + onConfirm?: () => void + onAsyncConfirm?: () => Promise + variant?: 'danger' | 'warning' | 'success' | undefined +} const ConfirmModal: React.FC = ({ title, message, @@ -16,26 +16,26 @@ const ConfirmModal: React.FC = ({ onAsyncConfirm, variant = 'danger', }) => { - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = React.useState(false) function onCancelClick() { - if (!loading) onClose(); + if (!loading) onClose() } async function onConfirmClick() { if (onAsyncConfirm) { - setLoading(true); - await onAsyncConfirm(); + setLoading(true) + await onAsyncConfirm() - onClose(); + onClose() } else if (onConfirm) { - onConfirm(); - onClose(); + onConfirm() + onClose() } } function onClose() { - removeElement(); + removeElement() } return ( @@ -55,11 +55,7 @@ const ConfirmModal: React.FC = ({ - @@ -67,32 +63,32 @@ const ConfirmModal: React.FC = ({ } > -

{message}

+

{message}

- ); -}; + ) +} function removeElement() { - const target = document.getElementById('supabase-ui-confirm-alert'); + const target = document.getElementById('supabase-ui-confirm-alert') if (target) { - unmountComponentAtNode(target); - target?.parentNode?.removeChild(target); + unmountComponentAtNode(target) + target?.parentNode?.removeChild(target) } } function createElement(props: ConfirmModalProps) { - let divTarget = document.getElementById('supabase-ui-confirm-alert'); + let divTarget = document.getElementById('supabase-ui-confirm-alert') if (divTarget) { - render(, divTarget); + render(, divTarget) } else { - divTarget = document.createElement('div'); - divTarget.id = 'supabase-ui-confirm-alert'; - document.body.appendChild(divTarget); - render(, divTarget); + divTarget = document.createElement('div') + divTarget.id = 'supabase-ui-confirm-alert' + document.body.appendChild(divTarget) + render(, divTarget) } } export function showConfirmAlert(props: ConfirmModalProps) { - createElement(props); + createElement(props) } diff --git a/studio/components/grid/components/footer/pagination/Pagination.tsx b/studio/components/grid/components/footer/pagination/Pagination.tsx index 4e9a317db08..1c3ef9f5847 100644 --- a/studio/components/grid/components/footer/pagination/Pagination.tsx +++ b/studio/components/grid/components/footer/pagination/Pagination.tsx @@ -1,83 +1,120 @@ -import * as React from 'react'; -import AwesomeDebouncePromise from 'awesome-debounce-promise'; -import { - Button, - InputNumber, - Typography, - IconArrowRight, - IconArrowLeft, -} from '@supabase/ui'; -import { DropdownControl } from '../../common'; -import { useDispatch, useTrackedState } from '../../../store'; +import { FC, useState, useEffect } from 'react' +import AwesomeDebouncePromise from 'awesome-debounce-promise' +import { Button, InputNumber, IconArrowRight, IconArrowLeft, IconLoader } from '@supabase/ui' +import { DropdownControl, showConfirmAlert } from '../../common' +import { useDispatch, useTrackedState } from '../../../store' const updatePage = (payload: number, dispatch: (value: unknown) => void) => { dispatch({ type: 'SET_PAGE', payload: payload, - }); -}; -const updatePageDebounced = AwesomeDebouncePromise(updatePage, 550); + }) +} +const updatePageDebounced = AwesomeDebouncePromise(updatePage, 550) const rowsPerPageOptions = [ { value: 100, label: '100 rows' }, { value: 500, label: '500 rows' }, { value: 1000, label: '1000 rows' }, -]; +] -type PaginationProps = {}; +type PaginationProps = {} -const Pagination: React.FC = () => { - const state = useTrackedState(); - const dispatch = useDispatch(); - const [page, setPage] = React.useState(state.page); - const maxPages = Math.ceil(state.totalRows / state.rowsPerPage); - const totalPages = state.totalRows > 0 ? maxPages : 1; +const Pagination: FC = () => { + const state = useTrackedState() + const dispatch = useDispatch() + const [page, setPage] = useState(state.page) + const maxPages = Math.ceil(state.totalRows / state.rowsPerPage) + const totalPages = state.totalRows > 0 ? maxPages : 1 - React.useEffect(() => { - if (state.page != page) setPage(state.page); - }, [state.page, page]); + useEffect(() => { + if (state.page != page) setPage(state.page) + }, [state.page, page]) - function onPreviousPage() { + // [Joshen] Oddly without this, state.selectedRows will be stale + useEffect(() => {}, [state.selectedRows]) + + // [Joshen] Note: I've made pagination buttons disabled while rows are being fetched for now + // at least until we can send an abort signal to cancel requests if users are mashing the + // pagination buttons to find the data they want + + const onPreviousPage = () => { if (state.page > 1) { - const previousPage = state.page - 1; - setPage(previousPage); - dispatch({ type: 'SET_PAGE', payload: previousPage }); + if (state.selectedRows.size >= 1) { + showConfirmAlert({ + title: 'Confirm moving to previous page', + message: 'The currently selected lines will be deselected, do you want to proceed?', + onConfirm: () => { + goToPreviousPage() + dispatch({ + type: 'SELECTED_ROWS_CHANGE', + payload: { selectedRows: new Set() }, + }) + }, + }) + } else { + goToPreviousPage() + } } } - function onNextPage() { + const onNextPage = () => { if (state.page < maxPages) { - const nextPage = state.page + 1; - setPage(nextPage); - dispatch({ type: 'SET_PAGE', payload: nextPage }); + if (state.selectedRows.size >= 1) { + showConfirmAlert({ + title: 'Confirm moving to next page', + message: 'The currently selected lines will be deselected, do you want to proceed?', + onConfirm: () => { + goToNextPage() + dispatch({ + type: 'SELECTED_ROWS_CHANGE', + payload: { selectedRows: new Set() }, + }) + }, + }) + } else { + goToNextPage() + } } } + const goToPreviousPage = () => { + const previousPage = state.page - 1 + setPage(previousPage) + dispatch({ type: 'SET_PAGE', payload: previousPage }) + } + + const goToNextPage = () => { + const nextPage = state.page + 1 + setPage(nextPage) + dispatch({ type: 'SET_PAGE', payload: nextPage }) + } + function onPageChange(event: React.ChangeEvent) { - const value = event.target.value; - const pageNum = Number(value); - setPage(pageNum); - updatePageDebounced(pageNum, dispatch); + const value = event.target.value + const pageNum = Number(value) + setPage(pageNum) + updatePageDebounced(pageNum, dispatch) } function onRowsPerPageChange(value: string | number) { - dispatch({ type: 'SET_ROWS_PER_PAGE', payload: value }); + dispatch({ type: 'SET_ROWS_PER_PAGE', payload: value }) } return (
{state.totalRows < 0 ? ( - ... loading total records +

Loading records...

) : ( <> - - {`${state.totalRows.toLocaleString()} records`} - +

{`${state.totalRows.toLocaleString()} records`}

+ {state.isLoading && } )}
- ); -}; -export default Pagination; + ) +} +export default Pagination diff --git a/studio/components/grid/components/grid/Grid.tsx b/studio/components/grid/components/grid/Grid.tsx index 43f2757aa2b..471ee85f128 100644 --- a/studio/components/grid/components/grid/Grid.tsx +++ b/studio/components/grid/components/grid/Grid.tsx @@ -1,54 +1,51 @@ -import * as React from 'react'; -import { memo } from 'react-tracked'; -import DataGrid, { - DataGridHandle, - RowsChangeData, -} from '@supabase/react-data-grid'; -import { IconLoader } from '@supabase/ui'; -import { GridProps, SupaRow } from '../../types'; -import { useDispatch, useTrackedState } from '../../store'; -import RowRenderer from './RowRenderer'; -import AwesomeDebouncePromise from 'awesome-debounce-promise'; +import { forwardRef } from 'react' +import { memo } from 'react-tracked' +import DataGrid, { DataGridHandle, RowsChangeData } from '@supabase/react-data-grid' +import { IconLoader } from '@supabase/ui' +import { GridProps, SupaRow } from '../../types' +import { useDispatch, useTrackedState } from '../../store' +import RowRenderer from './RowRenderer' +import AwesomeDebouncePromise from 'awesome-debounce-promise' function rowKeyGetter(row: SupaRow) { - return row.idx; + return row.idx +} + +interface IGrid extends GridProps { + rows: any[] } export const Grid = memo( - React.forwardRef( + forwardRef( ( - { width, height, containerClass, gridClass, rowClass }, + { width, height, containerClass, gridClass, rowClass, rows }, ref: React.Ref | undefined ) => { - const dispatch = useDispatch(); - const state = useTrackedState(); + const dispatch = useDispatch() + const state = useTrackedState() + // workaround to force state tracking on state.gridColumns - const columnHeaders = state.gridColumns.map( - (x) => `${x.key}_${x.frozen}` - ); - const { gridColumns, rows, onError: onErrorFunc } = state; + const columnHeaders = state.gridColumns.map((x) => `${x.key}_${x.frozen}`) + const { gridColumns, onError: onErrorFunc } = state function onColumnResize(index: number, width: number) { - updateColumnResizeDebounced(index, width, dispatch); + updateColumnResizeDebounced(index, width, dispatch) } - function onRowsChange( - rows: SupaRow[], - data: RowsChangeData - ) { - const rowData = rows[data.indexes[0]]; - const originRowData = state.rows.find((x) => x.idx == rowData.idx); - const changedColumn = Object.keys(rowData).find((name) => rowData[name] !== originRowData![name]); + async function onRowsChange(rows: SupaRow[], data: RowsChangeData) { + const rowData = rows[data.indexes[0]] + const originRowData = state.rows.find((x) => x.idx == rowData.idx) + const changedColumn = Object.keys(rowData).find( + (name) => rowData[name] !== originRowData![name] + ) if (changedColumn) { - const { error } = state.rowService!.update(rowData, changedColumn); - if (error) { - if (onErrorFunc) onErrorFunc(error); - } else { + const { error } = state.rowService!.update(rowData, changedColumn, (payload) => { dispatch({ - type: 'SET_ROWS', - payload: { rows }, - }); - } + type: 'EDIT_ROW', + payload, + }) + }) + if (error && onErrorFunc) onErrorFunc(error) } } @@ -56,14 +53,14 @@ export const Grid = memo( dispatch({ type: 'SELECTED_ROWS_CHANGE', payload: { selectedRows }, - }); + }) } function onSelectedCellChange(position: { idx: number; rowIdx: number }) { dispatch({ type: 'SELECTED_CELL_CHANGE', payload: { position }, - }); + }) } if (!columnHeaders || columnHeaders.length == 0) { @@ -73,14 +70,15 @@ export const Grid = memo( style={{ width: width || '100%', height: height || '50vh' }} >
-
+
-
Loading...
+
Loading...
- ); + ) } + return (
- ); + ) } ) -); +) -const updateColumnResize = ( - index: number, - width: number, - dispatch: (value: unknown) => void -) => { +const updateColumnResize = (index: number, width: number, dispatch: (value: unknown) => void) => { dispatch({ type: 'UPDATE_COLUMN_SIZE', payload: { index, width: Math.round(width) }, - }); -}; -const updateColumnResizeDebounced = AwesomeDebouncePromise( - updateColumnResize, - 500 -); + }) +} +const updateColumnResizeDebounced = AwesomeDebouncePromise(updateColumnResize, 500) diff --git a/studio/components/grid/services/row/SqlRowService.ts b/studio/components/grid/services/row/SqlRowService.ts index 057d56ad3d0..9605133ef2f 100644 --- a/studio/components/grid/services/row/SqlRowService.ts +++ b/studio/components/grid/services/row/SqlRowService.ts @@ -1,144 +1,140 @@ -import { IRowService } from '.'; -import { Filter, ServiceError, Sort, SupaRow, SupaTable } from '../../types'; -import { ERROR_PRIMARY_KEY_NOTFOUND, SupabaseGridQueue } from '../../constants'; -import Query from '../../query'; -import { isNumericalColumn } from '../../utils'; +import { IRowService } from '.' +import { Filter, ServiceError, Sort, SupaRow, SupaTable } from '../../types' +import { ERROR_PRIMARY_KEY_NOTFOUND, SupabaseGridQueue } from '../../constants' +import Query from '../../query' +import { isNumericalColumn } from '../../utils' +import { useDispatch } from 'components/grid/store' export class SqlRowService implements IRowService { - protected query = new Query(); + protected query = new Query() + protected dispatch = useDispatch() constructor( protected table: SupaTable, - protected onSqlQuery: ( - query: string - ) => Promise<{ data?: any; error?: any }>, + protected onSqlQuery: (query: string) => Promise<{ data?: any; error?: any }>, protected onError: (error: any) => void ) {} async count(filters: Filter[]) { - let queryChains = this.query - .from(this.table.name, this.table.schema ?? undefined) - .count(); + let queryChains = this.query.from(this.table.name, this.table.schema ?? undefined).count() filters .filter((x) => x.value && x.value != '') .forEach((x) => { - const value = this.formatFilterValue(x); - queryChains = queryChains.filter(x.column, x.operator, value); - }); + const value = this.formatFilterValue(x) + queryChains = queryChains.filter(x.column, x.operator, value) + }) - const query = queryChains.toSql(); - const { data, error } = await this.onSqlQuery(query); + const query = queryChains.toSql() + const { data, error } = await this.onSqlQuery(query) if (error) { - return { error }; + return { error } } else { if (data?.length == 1) { - return { data: data[0].count }; + return { data: data[0].count } } else { - return { error: { message: 'fetch rows count failed' } }; + return { error: { message: 'fetch rows count failed' } } } } } async create(row: SupaRow) { - console.log('create: ', row); - return { error: { message: 'not implemented' } }; + console.log('create: ', row) + return { error: { message: 'not implemented' } } } delete(rows: SupaRow[]) { - const { primaryKeys, error } = this.getPrimaryKeys(); - if (error) return { error }; + const { primaryKeys, error } = this.getPrimaryKeys() + if (error) return { error } - let queryChains = this.query - .from(this.table.name, this.table.schema ?? undefined) - .delete(); + let queryChains = this.query.from(this.table.name, this.table.schema ?? undefined).delete() primaryKeys!.forEach((key) => { - const primaryKeyValues = rows.map((x) => x[key]); - queryChains = queryChains.filter(key, 'in', primaryKeyValues); - }); + const primaryKeyValues = rows.map((x) => x[key]) + queryChains = queryChains.filter(key, 'in', primaryKeyValues) + }) - const query = queryChains.toSql(); + const query = queryChains.toSql() SupabaseGridQueue.add(async () => { - const { error } = await this.onSqlQuery(query); - if (error) throw error; + const { error } = await this.onSqlQuery(query) + if (error) throw error }).catch((error) => { - this.onError(error); - }); + this.onError(error) + }) - return {}; + return {} } - async fetchPage( - page: number, - rowsPerPage: number, - filters: Filter[], - sorts: Sort[] - ) { - const pageFromZero = page > 0 ? page - 1 : page; - const from = pageFromZero * rowsPerPage; - const to = (pageFromZero + 1) * rowsPerPage - 1; - let queryChains = this.query - .from(this.table.name, this.table.schema ?? undefined) - .select(); + async fetchPage(page: number, rowsPerPage: number, filters: Filter[], sorts: Sort[]) { + const pageFromZero = page > 0 ? page - 1 : page + const from = pageFromZero * rowsPerPage + const to = (pageFromZero + 1) * rowsPerPage - 1 + let queryChains = this.query.from(this.table.name, this.table.schema ?? undefined).select() filters .filter((x) => x.value && x.value != '') .forEach((x) => { - const value = this.formatFilterValue(x); - queryChains = queryChains.filter(x.column, x.operator, value); - }); + const value = this.formatFilterValue(x) + queryChains = queryChains.filter(x.column, x.operator, value) + }) sorts.forEach((x) => { - queryChains = queryChains.order(x.column, x.ascending, x.nullsFirst); - }); + queryChains = queryChains.order(x.column, x.ascending, x.nullsFirst) + }) - const query = queryChains.range(from, to).toSql(); - const { data, error } = await this.onSqlQuery(query); + const query = queryChains.range(from, to).toSql() + const { data, error } = await this.onSqlQuery(query) if (error) { - this.onError(error); - return { data: { rows: [] } }; + this.onError(error) + return { data: { rows: [] } } } else { const rows = data?.map((x: any, index: number) => { - return { idx: index, ...x } as SupaRow; - }); - return { data: { rows } }; + return { idx: index, ...x } as SupaRow + }) + return { data: { rows } } } } - update(row: SupaRow, changedColumn?: string) { - const { primaryKeys, error } = this.getPrimaryKeys(); + update(row: SupaRow, changedColumn?: string, onRowUpdate?: (value: any) => void) { + const { primaryKeys, error } = this.getPrimaryKeys() if (error) { - return { error }; + return { error } } - const { idx, ...value } = row; - const matchValues: any = {}; + const { idx, ...value } = row + const matchValues: any = {} primaryKeys!.forEach((key) => { - matchValues[key] = row[key]; + matchValues[key] = row[key] // fix: https://github.com/supabase/grid/issues/94 // remove primary key from updated value object - delete value[key]; - }); + delete value[key] + }) const query = this.query .from(this.table.name, this.table.schema ?? undefined) - .update(changedColumn ? { - [changedColumn]: value[changedColumn] - }: value) + .update( + changedColumn + ? { + [changedColumn]: value[changedColumn], + } + : value, + { returning: true } + ) .match(matchValues) - .toSql(); - SupabaseGridQueue.add(async () => { - const { error } = await this.onSqlQuery(query); - if (error) throw error; - }).catch((error) => { - this.onError(error); - }); + .toSql() - return {}; + SupabaseGridQueue.add(async () => { + const { data, error } = await this.onSqlQuery(query) + if (error) throw error + if (onRowUpdate) onRowUpdate({ row: data[0], idx }) + }).catch((error) => { + this.onError(error) + }) + + return {} } getPrimaryKeys(): { primaryKeys?: string[]; error?: ServiceError } { - const pkColumns = this.table.columns.filter((x) => x.isPrimaryKey); + const pkColumns = this.table.columns.filter((x) => x.isPrimaryKey) if (!pkColumns || pkColumns.length == 0) { - return { error: { message: ERROR_PRIMARY_KEY_NOTFOUND } }; + return { error: { message: ERROR_PRIMARY_KEY_NOTFOUND } } } - return { primaryKeys: pkColumns.map((x) => x.name) }; + return { primaryKeys: pkColumns.map((x) => x.name) } } /** @@ -146,12 +142,12 @@ export class SqlRowService implements IRowService { * which validate input value base on the column type */ formatFilterValue(filter: Filter) { - const column = this.table.columns.find((x) => x.name == filter.column); + const column = this.table.columns.find((x) => x.name == filter.column) if (column && isNumericalColumn(column.format)) { - const numberValue = Number(filter.value); - if (Number.isNaN(numberValue)) return filter.value; - else return Number(filter.value); + const numberValue = Number(filter.value) + if (Number.isNaN(numberValue)) return filter.value + else return Number(filter.value) } - return filter.value; + return filter.value } } diff --git a/studio/components/grid/services/row/index.tsx b/studio/components/grid/services/row/index.tsx index 36bbb934ff3..666f4f1a728 100644 --- a/studio/components/grid/services/row/index.tsx +++ b/studio/components/grid/services/row/index.tsx @@ -1,11 +1,9 @@ -import { Filter, ServiceError, Sort, SupaRow } from '../../types'; +import { Filter, ServiceError, Sort, SupaRow } from '../../types' export interface IRowService { - count: ( - filters: Filter[] - ) => Promise<{ data?: number; error?: ServiceError }>; + count: (filters: Filter[]) => Promise<{ data?: number; error?: ServiceError }> - create: (row: SupaRow) => Promise<{ data?: SupaRow; error?: ServiceError }>; + create: (row: SupaRow) => Promise<{ data?: SupaRow; error?: ServiceError }> fetchPage: ( page: number, @@ -13,9 +11,9 @@ export interface IRowService { filters: Filter[], sorts: Sort[] ) => Promise<{ - data?: { rows: SupaRow[] }; - error?: ServiceError; - }>; + data?: { rows: SupaRow[] } + error?: ServiceError + }> /** * TODO: should return a promise. @@ -25,9 +23,13 @@ export interface IRowService { * Right now, we remove rows immediately, so it's confused when delete operation fails * and rows are already removed from the grid */ - delete: (rows: SupaRow[]) => { error?: ServiceError }; + delete: (rows: SupaRow[]) => { error?: ServiceError } - update: (row: SupaRow, changedColumn?: string) => { error?: ServiceError }; + update: ( + row: SupaRow, + changedColumn?: string, + onRowUpdate?: (value: any) => void + ) => { row?: SupaRow; error?: ServiceError } } -export * from './SqlRowService'; +export * from './SqlRowService' diff --git a/studio/components/grid/store/reducers/row.ts b/studio/components/grid/store/reducers/row.ts index 569aa5a5815..a3de4a47f9f 100644 --- a/studio/components/grid/store/reducers/row.ts +++ b/studio/components/grid/store/reducers/row.ts @@ -1,54 +1,53 @@ -import update from 'immutability-helper'; -import { - REFRESH_PAGE_IMMEDIATELY, - TOTAL_ROWS_INITIAL, - TOTAL_ROWS_RESET, -} from '../../constants'; -import { Dictionary, SupaRow } from '../../types'; -import { INIT_ACTIONTYPE } from './base'; +import update from 'immutability-helper' +import { REFRESH_PAGE_IMMEDIATELY, TOTAL_ROWS_INITIAL, TOTAL_ROWS_RESET } from '../../constants' +import { Dictionary, SupaRow } from '../../types' +import { INIT_ACTIONTYPE } from './base' export interface RowInitialState { - rows: SupaRow[]; - selectedRows: ReadonlySet; - selectedCellPosition: { idx: number; rowIdx: number } | null; - page: number; - rowsPerPage: number; - totalRows: number; + isLoading: boolean + rows: SupaRow[] + selectedRows: ReadonlySet + selectedCellPosition: { idx: number; rowIdx: number } | null + page: number + rowsPerPage: number + totalRows: number } export const rowInitialState: RowInitialState = { + isLoading: false, rows: [], selectedRows: new Set(), selectedCellPosition: null, page: 1, rowsPerPage: 100, totalRows: TOTAL_ROWS_INITIAL, -}; +} type ROW_ACTIONTYPE = | INIT_ACTIONTYPE | { - type: 'SELECTED_CELL_CHANGE'; - payload: { position: { idx: number; rowIdx: number } }; + type: 'SELECTED_CELL_CHANGE' + payload: { position: { idx: number; rowIdx: number } } } | { - type: 'SELECTED_ROWS_CHANGE'; - payload: { selectedRows: ReadonlySet }; + type: 'SELECTED_ROWS_CHANGE' + payload: { selectedRows: ReadonlySet } } | { type: 'SET_PAGE'; payload: number } | { type: 'SET_ROWS_PER_PAGE'; payload: number } | { - type: 'SET_ROWS'; - payload: { rows: SupaRow[] }; + type: 'SET_ROWS' + payload: { rows: SupaRow[] } } | { - type: 'SET_ROWS_COUNT'; - payload: number; + type: 'SET_ROWS_COUNT' + payload: number } | { type: 'ADD_ROWS'; payload: SupaRow[] } | { type: 'ADD_NEW_ROW'; payload: Dictionary } | { type: 'EDIT_ROW'; payload: { row: Dictionary; idx: number } } - | { type: 'REMOVE_ROWS'; payload: { rowIdxs: number[] } }; + | { type: 'REMOVE_ROWS'; payload: { rowIdxs: number[] } } + | { type: 'SET_IS_LOADING'; payload: { isLoading: boolean } } const RowReducer = (state: RowInitialState, action: ROW_ACTIONTYPE) => { switch (action.type) { @@ -59,26 +58,26 @@ const RowReducer = (state: RowInitialState, action: ROW_ACTIONTYPE) => { selectedCellPosition: null, selectedRows: new Set(), totalRows: TOTAL_ROWS_RESET, - }; + } } case 'SELECTED_CELL_CHANGE': { return { ...state, selectedCellPosition: action.payload.position, - }; + } } case 'SELECTED_ROWS_CHANGE': { return { ...state, selectedRows: action.payload.selectedRows, - }; + } } case 'SET_PAGE': { return { ...state, page: action.payload, refreshPageFlag: REFRESH_PAGE_IMMEDIATELY, - }; + } } case 'SET_ROWS_PER_PAGE': { return { @@ -86,58 +85,64 @@ const RowReducer = (state: RowInitialState, action: ROW_ACTIONTYPE) => { page: 1, rowsPerPage: action.payload, refreshPageFlag: REFRESH_PAGE_IMMEDIATELY, - }; + } } case 'SET_ROWS': { return { ...state, rows: action.payload.rows, refreshPageFlag: 0, - }; + } } case 'SET_ROWS_COUNT': { return { ...state, totalRows: action.payload, - }; + } } case 'ADD_ROWS': { - const totalRows = state.totalRows + action.payload.length; + const totalRows = state.totalRows + action.payload.length return { ...state, rows: update(state.rows, { $push: action.payload }), totalRows: totalRows, - }; + } } case 'ADD_NEW_ROW': { - const supaRow = { ...action.payload, idx: state.rows.length }; - const totalRows = state.totalRows + 1; + const supaRow = { ...action.payload, idx: state.rows.length } + const totalRows = state.totalRows + 1 return { ...state, rows: update(state.rows, { $push: [supaRow] }), totalRows: totalRows, - }; + } } case 'EDIT_ROW': { - const supaRow = { ...action.payload.row, idx: action.payload.idx }; + const supaRow = { ...action.payload.row, idx: action.payload.idx } return { ...state, rows: update(state.rows, { [action.payload.idx]: { $set: supaRow }, }), - }; + } } case 'REMOVE_ROWS': { - const totalRows = state.totalRows - action.payload.rowIdxs.length; + const totalRows = state.totalRows - action.payload.rowIdxs.length return { ...state, rows: state.rows.filter((x) => !action.payload.rowIdxs.includes(x.idx)), totalRows: totalRows, - }; + } + } + case 'SET_IS_LOADING': { + return { + ...state, + isLoading: action.payload.isLoading, + } } default: - return state; + return state } -}; +} -export default RowReducer; +export default RowReducer diff --git a/studio/components/grid/utils/row.ts b/studio/components/grid/utils/row.ts index 718fa4b1d77..b0c45f8f270 100644 --- a/studio/components/grid/utils/row.ts +++ b/studio/components/grid/utils/row.ts @@ -1,40 +1,36 @@ -import AwesomeDebouncePromise from 'awesome-debounce-promise'; -import { InitialStateType } from '../store/reducers'; +import AwesomeDebouncePromise from 'awesome-debounce-promise' +import { InitialStateType } from '../store/reducers' -export async function fetchCount( - state: InitialStateType, - dispatch: (value: unknown) => void -) { - if (!state.rowService) return; - const { data, error } = await state.rowService.count(state.filters); +export async function fetchCount(state: InitialStateType, dispatch: (value: unknown) => void) { + if (!state.rowService) return + const { data, error } = await state.rowService.count(state.filters) if (error) { // TODO: handle fetch rows count error } else { dispatch({ type: 'SET_ROWS_COUNT', payload: data ?? 0, - }); + }) } } -export async function fetchPage( - state: InitialStateType, - dispatch: (value: unknown) => void -) { - if (!state.rowService) return; +export async function fetchPage(state: InitialStateType, dispatch: (value: unknown) => void) { + if (!state.rowService) return + dispatch({ type: 'SET_IS_LOADING', payload: { isLoading: true } }) const { data, error } = await state.rowService.fetchPage( state.page, state.rowsPerPage, state.filters, state.sorts - ); + ) if (error) { // TODO: handle fetch rows data error } else { dispatch({ type: 'SET_ROWS', payload: { rows: data?.rows ?? [] }, - }); + }) } + dispatch({ type: 'SET_IS_LOADING', payload: { isLoading: false } }) } -export const refreshPageDebounced = AwesomeDebouncePromise(fetchPage, 500); +export const refreshPageDebounced = AwesomeDebouncePromise(fetchPage, 500) diff --git a/studio/components/interfaces/Authentication/Policies/PolicyEditorModal/index.tsx b/studio/components/interfaces/Authentication/Policies/PolicyEditorModal/index.tsx index 1f63042e15c..5503d234ac4 100644 --- a/studio/components/interfaces/Authentication/Policies/PolicyEditorModal/index.tsx +++ b/studio/components/interfaces/Authentication/Policies/PolicyEditorModal/index.tsx @@ -120,18 +120,21 @@ const PolicyEditorModal: FC = ({ return ui.setNotification({ category: 'error', message: 'You will need to allow at one operation in your policy', + duration: 4000, }) } if (['SELECT', 'DELETE'].includes(command) && !definition) { return ui.setNotification({ category: 'error', message: 'Did you forget to provide a USING expression for your policy?', + duration: 4000, }) } if (command === 'INSERT' && !check) { return ui.setNotification({ category: 'error', message: 'Did you forget to provide a WITH CHECK expression for your policy?', + duration: 4000, }) } if (command === 'UPDATE' && !definition && !check) { @@ -139,6 +142,7 @@ const PolicyEditorModal: FC = ({ category: 'error', message: 'You will need to provide either a USING, or WITH CHECK expression, or both for your policy', + duration: 4000, }) } const policySQLStatement = createSQLPolicy(policyFormFields, selectedPolicyToEdit) diff --git a/studio/components/interfaces/Database/Publications/PublicationsTableItem.tsx b/studio/components/interfaces/Database/Publications/PublicationsTableItem.tsx index 63074d6b764..2fa4a01b8eb 100644 --- a/studio/components/interfaces/Database/Publications/PublicationsTableItem.tsx +++ b/studio/components/interfaces/Database/Publications/PublicationsTableItem.tsx @@ -54,11 +54,11 @@ const PublicationsTableItem: FC = ({ table, selectedPublication }) => { {table.name} {table.schema} - + {table.comment} -
+
{enabledForAllTables ? ( // @ts-ignore = ({ table, selectedPublication }) => { size="tiny" align="right" disabled={loading} - className="m-0 p-0 ml-2 mt-1 -mb-1" + className="m-0 ml-2 mt-1 -mb-1 p-0" checked={checked} onChange={() => toggleReplicationForTable(table, publication)} /> diff --git a/studio/components/interfaces/Home/Home.constants.ts b/studio/components/interfaces/Home/Home.constants.ts index d19e89231bb..68c22b13343 100644 --- a/studio/components/interfaces/Home/Home.constants.ts +++ b/studio/components/interfaces/Home/Home.constants.ts @@ -55,7 +55,7 @@ export const EXAMPLE_PROJECTS = [ }, { framework: 'React', - title: 'React.js realtime chat app', + title: 'React realtime chat app', description: 'Example app of real-time chat using supabase realtime api', url: 'https://github.com/shwosner/realtime-chat-supabase-react', }, @@ -73,7 +73,7 @@ export const EXAMPLE_PROJECTS = [ }, { framework: 'NextJS', - title: 'NextJS todo list app', + title: 'Next.js todo list app', description: 'NextJS todo list example', url: 'https://github.com/supabase/supabase/tree/master/examples/todo-list/nextjs-todo-list', }, diff --git a/studio/components/interfaces/Settings/Logs/Logs.constants.ts b/studio/components/interfaces/Settings/Logs/Logs.constants.ts index ddd889a38b8..af7cd0d5afb 100644 --- a/studio/components/interfaces/Settings/Logs/Logs.constants.ts +++ b/studio/components/interfaces/Settings/Logs/Logs.constants.ts @@ -21,7 +21,8 @@ export const TEMPLATES: LogTemplate[] = [ description: 'Count of commits made by users on the database', mode: 'custom', searchString: `select - p.user_name, count(*) as count + p.user_name, + count(*) as count from postgres_logs left join unnest(metadata) as m on true left join unnest(m.parsed) as p on true @@ -29,14 +30,16 @@ where regexp_contains(event_message, 'COMMIT') group by p.user_name - `, + `, for: ['database'], }, { label: 'Metadata IP', description: 'List all IP addresses that used the Supabase API', mode: 'custom', - searchString: `select timestamp, h.x_real_ip + searchString: `select + cast(timestamp as datetime) as timestamp, + h.x_real_ip from edge_logs left join unnest(metadata) as m on true left join unnest(m.request) as r on true @@ -50,7 +53,8 @@ where h.x_real_ip is not null description: 'List all ISO 3166-1 alpha-2 country codes that used the Supabase API', mode: 'custom', searchString: `select - cf.country, count(*) as count + cf.country, + count(*) as count from edge_logs left join unnest(metadata) as m on true left join unnest(m.request) as r on true @@ -67,7 +71,7 @@ order by mode: 'custom', description: 'List all Supabase API requests that are slow', searchString: `select - timestamp, + cast(timestamp as datetime) as timestamp, event_message, r.origin_time from edge_logs @@ -85,8 +89,8 @@ limit 100 label: '500 Request Codes', description: 'List all Supabase API requests that responded witha 5XX status code', mode: 'custom', - searchString: `SELECT - timestamp, + searchString: `select + cast(timestamp as datetime) as timestamp, event_message, r.status_code from edge_logs @@ -104,7 +108,7 @@ limit 100 label: 'Top Paths', description: 'List the most requested Supabase API paths', mode: 'custom', - searchString: `SELECT + searchString: `select r.path as path, r.search as params, count(timestamp) as c @@ -124,8 +128,8 @@ limit 100 label: 'REST Requests', description: 'List all PostgREST requests', mode: 'custom', - searchString: `SELECT - timestamp, + searchString: `select + cast(timestamp as datetime) as timestamp, event_message from edge_logs cross join unnest(metadata) as m @@ -142,14 +146,13 @@ limit 100 label: 'Errors', description: 'List all Postgres error messages with ERROR, FATAL, or PANIC severity', mode: 'custom', - searchString: `SELECT - t.timestamp, + searchString: `select + cast(t.timestamp as datetime) as timestamp, p.error_severity, event_message -from - postgres_logs as t - cross join unnest(metadata) as m - cross join unnest(m.parsed) as p +from postgres_logs as t + cross join unnest(metadata) as m + cross join unnest(m.parsed) as p where p.error_severity in ('ERROR', 'FATAL', 'PANIC') order by @@ -165,10 +168,9 @@ limit 100 count(t.timestamp) as count, p.user_name, p.error_severity -from - postgres_logs as t - cross join unnest(metadata) as m - cross join unnest(m.parsed) as p +from postgres_logs as t + cross join unnest(metadata) as m + cross join unnest(m.parsed) as p where p.error_severity in ('ERROR', 'FATAL', 'PANIC') group by diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/JsonEditor/JsonEditor.tsx b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/JsonEditor/JsonEditor.tsx index 2298bc6cddb..67ce557846c 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/JsonEditor/JsonEditor.tsx +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/JsonEditor/JsonEditor.tsx @@ -33,8 +33,8 @@ const JsonEdit: FC = ({ column, jsonString, visible, closePanel, } catch (error: any) { const message = error.message ? `Error: ${error.message}` - : 'Hmm, invalid JSON seems to have an invalid structure.' - ui.setNotification({ category: 'error', message }) + : 'JSON seems to have an invalid structure.' + ui.setNotification({ category: 'error', message, duration: 4000 }) } finally { resolve() } diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.tsx b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.tsx index 40dc8b0ac7e..02d985c796d 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.tsx +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.tsx @@ -82,6 +82,7 @@ const RowEditor: FC = ({ ui.setNotification({ category: 'error', message: `Please enter a value in the ${row.name} field first`, + duration: 4000, }) } const foreignKey = row.foreignKey @@ -108,6 +109,7 @@ const RowEditor: FC = ({ return ui.setNotification({ category: 'error', message: `Unable to find the corresponding row in ${foreignKey.target_table_schema}.${foreignKey.target_table_name} where ${foreignKey.target_column_name} equals ${row.value}`, + duration: 4000, }) } setReferenceRow({ loading: false, foreignKey, row: res[0] }) diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.utils.ts b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.utils.ts index 81826dcbf9b..fb93bd3f0e6 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.utils.ts +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/RowEditor.utils.ts @@ -283,8 +283,6 @@ export const generateRowObjectFromFields = ( rowObject[field.name] = tryParseJson(value) } } - } else if (NUMERICAL_TYPES.includes(field.format) && value) { - rowObject[field.name] = Number(value) } else if (field.format === 'bool' && value) { rowObject[field.name] = value === 'true' } else if (DATETIME_TYPES.includes(field.format)) { diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx b/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx index eff9bad6c29..e1403753d2d 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx @@ -148,13 +148,15 @@ const SidePanelEditor: FC = ({ tableId?: number importContent?: ImportContent isRLSEnabled: boolean + isRealtimeEnabled: boolean isDuplicateRows: boolean }, resolve: any ) => { let toastId let saveTableError = false - const { tableId, importContent, isRLSEnabled, isDuplicateRows } = configuration + const { tableId, importContent, isRLSEnabled, isRealtimeEnabled, isDuplicateRows } = + configuration try { if (isDuplicating) { @@ -165,6 +167,7 @@ const SidePanelEditor: FC = ({ }) const table: any = await meta.duplicateTable(payload, { isRLSEnabled, + isRealtimeEnabled, isDuplicateRows, duplicateTable, }) @@ -179,7 +182,14 @@ const SidePanelEditor: FC = ({ category: 'loading', message: `Creating new table: ${payload.name}...`, }) - const table = await meta.createTable(toastId, payload, isRLSEnabled, columns, importContent) + const table = await meta.createTable( + toastId, + payload, + columns, + isRLSEnabled, + isRealtimeEnabled, + importContent + ) ui.setNotification({ id: toastId, category: 'success', @@ -195,7 +205,8 @@ const SidePanelEditor: FC = ({ toastId, selectedTableToEdit, payload, - columns + columns, + isRealtimeEnabled ) if (hasError) { ui.setNotification({ @@ -258,8 +269,6 @@ const SidePanelEditor: FC = ({ )} = ({ error: errors, category: 'error', message: `Some issues have been detected on ${errors.length} rows. More details below the content preview.`, + duration: 4000, }) } setErrors(errors) @@ -98,6 +99,7 @@ const SpreadsheetImport: FC = ({ error: errors, category: 'error', message: `Some issues have been detected on ${errors.length} rows. More details below the content preview.`, + duration: 4000, }) } setErrors(errors) @@ -160,7 +162,7 @@ const SpreadsheetImport: FC = ({
{spreadsheetData.headers.length > 0 && ( -
+
Content Preview @@ -188,7 +190,7 @@ const SpreadsheetImport: FC = ({
onSelectExpandError(key)} /> diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/SpreadsheetImport/SpreadsheetImport.utils.ts b/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/SpreadsheetImport/SpreadsheetImport.utils.ts index 4ba1a2c91b3..ed3dca9ffcd 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/SpreadsheetImport/SpreadsheetImport.utils.ts +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/SpreadsheetImport/SpreadsheetImport.utils.ts @@ -122,9 +122,10 @@ export const inferColumnType = (column: string, rows: object[]) => { // Infer boolean type if (includes(['true', 'false'], columnData.toString().toLowerCase())) { - const isAllBoolean = columnDataAcrossRows.every((item: any) => - includes(['true', 'false'], item.toString().toLowerCase()) - ) + const isAllBoolean = columnDataAcrossRows.every((item: any) => { + if (item === null) return true + else return includes(['true', 'false'], item.toString().toLowerCase()) + }) if (isAllBoolean) { return 'boolean' } diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.tsx b/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.tsx index 6fcba4fe396..d03c3478f9b 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.tsx +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.tsx @@ -20,8 +20,6 @@ import { interface Props { table?: PostgresTable - tables: PostgresTable[] - enumTypes: PostgresType[] selectedSchema: string isDuplicating: boolean visible: boolean @@ -34,6 +32,7 @@ interface Props { tableId?: number importContent?: ImportContent isRLSEnabled: boolean + isRealtimeEnabled: boolean isDuplicateRows: boolean }, resolve: any @@ -43,8 +42,6 @@ interface Props { const TableEditor: FC = ({ table, - tables = [], - enumTypes = [] as PostgresType[], selectedSchema, isDuplicating, visible = false, @@ -52,9 +49,23 @@ const TableEditor: FC = ({ saveChanges = () => {}, updateEditorDirty = () => {}, }) => { - const { ui } = useStore() + const { ui, meta } = useStore() const isNewRecord = isUndefined(table) + const tables = meta.tables.list() + const enumTypes = meta.types.list( + (type: PostgresType) => !meta.excludedSchemas.includes(type.schema) + ) + + const publications = meta.publications.list() + const realtimePublication = publications.find( + (publication) => publication.name === 'supabase_realtime' + ) + const realtimeEnabledTables = realtimePublication?.tables ?? [] + const isRealtimeEnabled = isNewRecord + ? false + : realtimeEnabledTables.some((t: any) => t.id === table?.id) + const [errors, setErrors] = useState({}) const [tableFields, setTableFields] = useState() const [isDuplicateRows, setIsDuplicateRows] = useState(false) @@ -70,7 +81,11 @@ const TableEditor: FC = ({ const tableFields = generateTableField() setTableFields(tableFields) } else { - const tableFields = generateTableFieldFromPostgresTable(table!, isDuplicating) + const tableFields = generateTableFieldFromPostgresTable( + table!, + isDuplicating, + isRealtimeEnabled + ) setTableFields(tableFields) } } @@ -99,7 +114,7 @@ const TableEditor: FC = ({ if (tableFields) { const errors: any = validateFields(tableFields) if (errors.columns) { - ui.setNotification({ category: 'error', message: errors.columns }) + ui.setNotification({ category: 'error', message: errors.columns, duration: 4000 }) } setErrors(errors) @@ -122,6 +137,7 @@ const TableEditor: FC = ({ tableId: table?.id, importContent, isRLSEnabled: tableFields.isRLSEnabled, + isRealtimeEnabled: tableFields.isRealtimeEnabled, isDuplicateRows: isDuplicateRows, } @@ -187,8 +203,16 @@ const TableEditor: FC = ({
} description="Restrict access to your table by enabling RLS and writing Postgres policies" - checked={tableFields?.isRLSEnabled} - onChange={() => onUpdateField({ isRLSEnabled: !tableFields?.isRLSEnabled })} + checked={tableFields.isRLSEnabled} + onChange={() => onUpdateField({ isRLSEnabled: !tableFields.isRLSEnabled })} + size="medium" + /> + onUpdateField({ isRealtimeEnabled: !tableFields.isRealtimeEnabled })} size="medium" />
diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.types.ts b/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.types.ts index 4e7d4ecdc64..da2fc543765 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.types.ts +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.types.ts @@ -7,6 +7,7 @@ export interface TableField { comment?: string columns: ColumnField[] isRLSEnabled: boolean + isRealtimeEnabled: boolean } export interface ImportContent { diff --git a/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.utils.ts b/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.utils.ts index 2e02f1ff191..b17c714db37 100644 --- a/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.utils.ts +++ b/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.utils.ts @@ -30,12 +30,14 @@ export const generateTableField = (): TableField => { comment: '', columns: DEFAULT_COLUMNS, isRLSEnabled: false, + isRealtimeEnabled: false, } } export const generateTableFieldFromPostgresTable = ( table: PostgresTable, - isDuplicating = false + isDuplicating = false, + isRealtimeEnabled = false ): TableField => { return { id: table.id, @@ -46,6 +48,7 @@ export const generateTableFieldFromPostgresTable = ( return generateColumnFieldFromPostgresColumn(column, table) }), isRLSEnabled: table.rls_enabled, + isRealtimeEnabled, } } diff --git a/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx b/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx index 7a73bb73d18..1ab3f658cdd 100644 --- a/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx +++ b/studio/components/layouts/TableEditorLayout/TableEditorLayout.tsx @@ -37,6 +37,7 @@ const TableEditorLayout: FC = ({ meta.schemas.load() meta.tables.load() meta.types.load() + meta.publications.load() } }, [ui.selectedProject]) diff --git a/studio/components/to-be-cleaned/SqlEditor/TabWelcome.js b/studio/components/to-be-cleaned/SqlEditor/TabWelcome.js index dbdf030e296..2d36ad2ec4b 100644 --- a/studio/components/to-be-cleaned/SqlEditor/TabWelcome.js +++ b/studio/components/to-be-cleaned/SqlEditor/TabWelcome.js @@ -62,7 +62,7 @@ const TabWelcome = observer(() => { description={x.description} sql={x.sql} onClick={(sql, title) => { - handleNewQuery(sql, title) + handleNewQuery({ sql, name: title }) Telemetry.sendEvent('quickstart', 'quickstart_clicked', x.title) }} /> diff --git a/studio/hooks/misc/useStore.tsx b/studio/hooks/misc/useStore.tsx index 15f553cb98b..b267cb010a4 100644 --- a/studio/hooks/misc/useStore.tsx +++ b/studio/hooks/misc/useStore.tsx @@ -58,7 +58,7 @@ export const StoreProvider: FC = ({ children, rootStore }) => { return toast.success(message, { id, duration: toastDuration }) case 'error': console.error('Error:', { error, message }) - return toast.error(message, { id, duration: toastDuration }) + return toast.error(message, { id, duration: duration || Infinity }) case 'loading': if (progress) { return toast.loading( diff --git a/studio/pages/join/index.tsx b/studio/pages/join/index.tsx index c16000f9778..dd0c93426ab 100644 --- a/studio/pages/join/index.tsx +++ b/studio/pages/join/index.tsx @@ -1,28 +1,30 @@ -import React from 'react' -import { useStore, withAuth } from 'hooks' -import { Button, IconAlertCircle, Typography } from '@supabase/ui' -import { useState } from 'react' -import { useRouter } from 'next/router' import Link from 'next/link' +import { useState, useEffect } from 'react' +import { useRouter } from 'next/router' +import { Button, IconCheckSquare } from '@supabase/ui' + +import { useProfile, useStore } from 'hooks' +import { auth } from 'lib/gotrue' import { API_URL } from 'lib/constants' import { get, post, delete_ } from 'lib/common/fetch' -import { useEffect } from 'react' -interface TokenInfoI { - organization_name: string | undefined - token_does_not_exist: boolean - email_match: boolean - authorized_user: boolean - expired_token: boolean - invite_id: number +interface ITokenInfo { + organization_name?: string | undefined + token_does_not_exist?: boolean + email_match?: boolean + authorized_user?: boolean + expired_token?: boolean + invite_id?: number } -type TokenInfo = TokenInfoI | undefined +type TokenInfo = ITokenInfo | undefined -const User = () => { +const JoinOrganizationPage = () => { const router = useRouter() const { slug, token } = router.query - const { ui } = useStore() + const { ui, app } = useStore() + const { profile } = useProfile() + const [isSubmitting, setIsSubmitting] = useState(false) const [tokenValidationInfo, setTokenValidationInfo] = useState(undefined) const [tokenInfoLoaded, setTokenInfoLoaded] = useState(false) @@ -35,21 +37,27 @@ const User = () => { invite_id, } = tokenValidationInfo || {} + const loginRedirectLink = `/?next=${encodeURIComponent(`/join?token=${token}&slug=${slug}`)}` + useEffect(() => { - async function fetchTokenInfo() { - try { - const response = await get(`${API_URL}/organizations/${slug}/members/join?token=${token}`) - setTokenValidationInfo(response) + const fetchTokenInfo = async () => { + await ui.load() + + const response = await get(`${API_URL}/organizations/${slug}/members/join?token=${token}`) + if (response.error && response.error.code === 401) { + setTokenValidationInfo({ + authorized_user: false, + }) + } else { setTokenInfoLoaded(true) - } catch (error) { - console.error(error) + setTokenValidationInfo(response) } } - if (router.query.token && !tokenInfoLoaded) { + if (token && !tokenInfoLoaded) { fetchTokenInfo() } - }, [router.query]) + }, [token]) async function handleJoinOrganization() { setIsSubmitting(true) @@ -62,7 +70,7 @@ const User = () => { setIsSubmitting(false) } else { setIsSubmitting(false) - // app.organizations.load() + app.organizations.load() router.push('/') } } @@ -85,106 +93,150 @@ const User = () => { } } + const isError = + !!(tokenInfoLoaded && token_does_not_exist) || + (tokenInfoLoaded && !email_match) || + (tokenInfoLoaded && expired_token) + + const ErrorMessage = () => { + const message = token_does_not_exist ? ( + <> +

The invite token is invalid.

+

+ Try copying and pasting the link from the invite email, or ask the organization owner to + invite you again. +

+ + ) : !email_match ? ( + <> +

+ Your email address {profile?.primary_email} does not match the email address this + invitation was sent to. +

+

+ To accept this invitation, you will need to{' '} + { + await auth.signOut() + router.reload() + }} + > + sign out + {' '} + and then sign in or create a new account using the same email address used in the + invitation. +

+ + ) : expired_token ? ( + <> +

The invite token has expired.

+

Please request a new one from the organization member.

+ + ) : ( + '' + ) + + return ( +
+ {message} +
+ ) + } + return ( -
+
+ + + Supabase + +
-
- - - Supabase - {/*

Supabase

*/} -
- -

- Join {organization_name && email_match ? organization_name : 'a new organization'} -

- +
{!token_does_not_exist ? ( -

- You have been invited to join{' '} - {organization_name && email_match - ? `${organization_name}'s organization` - : 'a new organization'}{' '} - at Supabase. -

+ <> +

You have been invited to join

+ {organization_name ? ( + <> +

+ {organization_name ? `${organization_name}` : 'an organization'}{' '} +

+

an organization on Supabase

+ + ) : ( + <> +

an organization

+ + )} + ) : ( -
+
)}
-
-
+
+
{authorized_user && !expired_token && email_match && tokenInfoLoaded && ( -
+
+ - -
)} - {tokenInfoLoaded && ( -
- {(tokenInfoLoaded && token_does_not_exist) || - (tokenInfoLoaded && !email_match) || - (tokenInfoLoaded && expired_token && ( - - ))} + {tokenInfoLoaded && } - {tokenInfoLoaded && token_does_not_exist - ? 'The invite token is invalid. Try copying and pasting the link from the invite email, or ask the organization owner to invite you again.' - : tokenInfoLoaded && !email_match - ? 'The email address does not match. Are you signed in with right GitHub account?' - : tokenInfoLoaded && expired_token - ? 'The invite token has expired. Please request a new one from the organization owner.' - : ''} -
- )} - {authorized_user && !expired_token && email_match && tokenInfoLoaded && ( -
- - - -
- )} {!authorized_user && ( -
- - - +
+

+ You will need to sign in to accept this invitation +

+
+ + + + + + +
)}
@@ -194,4 +246,4 @@ const User = () => { ) } -export default User +export default JoinOrganizationPage diff --git a/studio/pages/org/[slug]/join.tsx b/studio/pages/org/[slug]/join.tsx deleted file mode 100644 index 3efcf2f8b8a..00000000000 --- a/studio/pages/org/[slug]/join.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import React from 'react' -import { useStore, withAuth } from 'hooks' -import { Button, IconAlertCircle, Typography } from '@supabase/ui' -import { useState } from 'react' -import { useRouter } from 'next/router' -import Link from 'next/link' -import { API_URL } from 'lib/constants' -import { get, post, delete_ } from 'lib/common/fetch' -import { useEffect } from 'react' - -interface TokenInfo { - organization_name: string | undefined - token_does_not_exist: boolean - email_match: boolean - authorized_user: boolean - expired_token: boolean - invite_id: number -} - -const User = () => { - const router = useRouter() - const { slug, token } = router.query - const { app, ui } = useStore() - const [isSubmitting, setIsSubmitting] = useState(false) - const [tokenValidationInfo, setTokenValidationInfo] = useState() - const [tokenInfoLoaded, setTokenInfoLoaded] = useState(false) - const { - token_does_not_exist, - email_match, - authorized_user, - expired_token, - organization_name, - invite_id, - } = tokenValidationInfo || {} - - useEffect(() => { - let cancel = false - - async function fetchTokenInfo() { - const response = await get(`${API_URL}/organizations/${slug}/members/join?token=${token}`, {}) - if (!cancel) { - setTokenValidationInfo(response) - setTokenInfoLoaded(true) - } - } - - if (router.query.token) { - fetchTokenInfo() - } - - return () => { - cancel = true - } - }, []) - - async function handleJoinOrganization() { - setIsSubmitting(true) - const response = await post(`${API_URL}/organizations/${slug}/members/join?token=${token}`, {}) - if (response.error) { - ui.setNotification({ - category: 'error', - message: `Failed to join organization: ${response.error.message}`, - }) - setIsSubmitting(false) - } else { - setIsSubmitting(false) - app.organizations.load() - router.push('/') - } - } - - async function handleDeclineJoinOrganization() { - setIsSubmitting(true) - const response = await delete_( - `${API_URL}/organizations/${slug}/members/invite?invited_id=${invite_id}`, - {} - ) - if (response.error) { - ui.setNotification({ - category: 'error', - message: `Failed to decline invitation: ${response.error.message}`, - }) - setIsSubmitting(false) - } else { - setIsSubmitting(false) - router.push('/') - } - } - - return ( -
-
-
- - - Supabase - - Supabase - - - - -

- Join {organization_name && email_match ? organization_name : 'a new organization'} -

- - {!token_does_not_exist ? ( -

- You have been invited to join{' '} - {organization_name && email_match - ? `${organization_name}'s organization` - : 'a new organization'}{' '} - at Supabase. -

- ) : ( -
- )} -
- - {authorized_user && !expired_token && email_match && tokenInfoLoaded && ( -
- - - -
- )} - - {tokenInfoLoaded && ( -
- {token_does_not_exist || - !email_match || - (expired_token && )} - - {token_does_not_exist - ? 'The invite token is invalid. Try copying and pasting the link from the invite email, or ask the organization owner to invite you again.' - : !email_match - ? 'The email address does not match. Are you signed in with right GitHub account?' - : expired_token - ? 'The invite token has expired. Please request a new one from the organization owner.' - : ''} -
- )} -
-
- ) -} - -export default withAuth(User) diff --git a/studio/pages/project/[ref]/index.tsx b/studio/pages/project/[ref]/index.tsx index eba3af89bf4..f71f809245d 100644 --- a/studio/pages/project/[ref]/index.tsx +++ b/studio/pages/project/[ref]/index.tsx @@ -38,7 +38,7 @@ const Home: NextPageWithLayout = () => { Example projects
- {EXAMPLE_PROJECTS.map((project) => ( + {EXAMPLE_PROJECTS.sort((a, b) => a.title.localeCompare(b.title)).map((project) => ( ))}
diff --git a/studio/pages/project/[ref]/settings/api.tsx b/studio/pages/project/[ref]/settings/api.tsx index a85c3bdf07e..7af9d5ed759 100644 --- a/studio/pages/project/[ref]/settings/api.tsx +++ b/studio/pages/project/[ref]/settings/api.tsx @@ -353,7 +353,7 @@ const ServiceList: FC = ({ projectRef }) => { variant="warning" title="This will invalidate all existing API keys!" > - Your project will also be restarted during this process, which will terminate + Generating a new JWT secret will invalidate all of your API keys, including your service_role and anon keys. Your project will also be restarted during this process, which will terminate any existing connections. )} diff --git a/studio/stores/pgmeta/MetaStore.ts b/studio/stores/pgmeta/MetaStore.ts index 874bfa65ada..986680b48dc 100644 --- a/studio/stores/pgmeta/MetaStore.ts +++ b/studio/stores/pgmeta/MetaStore.ts @@ -93,16 +93,28 @@ export interface IMetaStore { ) => any duplicateTable: ( payload: any, - metadata: { duplicateTable: PostgresTable; isRLSEnabled: boolean; isDuplicateRows: boolean } + metadata: { + duplicateTable: PostgresTable + isRLSEnabled: boolean + isRealtimeEnabled: boolean + isDuplicateRows: boolean + } ) => void createTable: ( toastId: string, payload: any, - isRLSEnabled: boolean, columns: ColumnField[], + isRLSEnabled: boolean, + isRealtimeEnabled: boolean, importContent?: ImportContent ) => any - updateTable: (toastId: string, table: PostgresTable, payload: any, columns: ColumnField[]) => any + updateTable: ( + toastId: string, + table: PostgresTable, + payload: any, + columns: ColumnField[], + isRealtimeEnabled: boolean + ) => any } export default class MetaStore implements IMetaStore { rootStore: IRootStore @@ -297,9 +309,15 @@ export default class MetaStore implements IMetaStore { async duplicateTable( payload: any, - metadata: { duplicateTable: PostgresTable; isRLSEnabled: boolean; isDuplicateRows: boolean } + metadata: { + duplicateTable: PostgresTable + isRLSEnabled: boolean + isRealtimeEnabled: boolean + isDuplicateRows: boolean + } ) { - const sourceTableName = metadata.duplicateTable.name + const { duplicateTable, isRLSEnabled, isRealtimeEnabled, isDuplicateRows } = metadata + const sourceTableName = duplicateTable.name const duplicatedTableName = payload.name // The following query will copy the structure of the table along with indexes, constraints and @@ -310,7 +328,7 @@ export default class MetaStore implements IMetaStore { if (table.error) throw table.error // Duplicate foreign key constraints over - const relationships = metadata.duplicateTable.relationships + const relationships = duplicateTable.relationships if (relationships.length > 0) { // @ts-ignore, but might need to investigate, sounds bad: // Type instantiation is excessively deep and possibly infinite @@ -324,14 +342,15 @@ export default class MetaStore implements IMetaStore { } // Duplicate rows if needed - if (metadata.isDuplicateRows) { + if (isDuplicateRows) { const rows = await this.rootStore.meta.query( `INSERT INTO "${duplicatedTableName}" SELECT * FROM ${sourceTableName};` ) if (rows.error) throw rows.error // Insert into does not copy over auto increment sequences, so we manually do it next if any - const columns = metadata.duplicateTable.columns + const columns = duplicateTable.columns + // @ts-ignore const identityColumns = columns.filter((column) => column.identity_generation !== null) identityColumns.map(async (column) => { const identity = await this.rootStore.meta.query( @@ -345,21 +364,37 @@ export default class MetaStore implements IMetaStore { const tables = this.tables.list() const duplicatedTable = find(tables, { name: duplicatedTableName }) - if (metadata.isRLSEnabled) { + if (isRLSEnabled) { const updateTable: any = await this.tables.update(duplicatedTable!.id, { - rls_enabled: metadata.isRLSEnabled, + rls_enabled: isRLSEnabled, }) if (updateTable.error) throw updateTable.error } + if (isRealtimeEnabled) { + const publications = this.publications.list() + const realtimePublication = publications.find( + (publication) => publication.name === 'supabase_realtime' + ) + + const id = realtimePublication?.id + const realtimeTables = [`${duplicateTable.schema}.${duplicatedTableName}`].concat( + realtimePublication.tables.map((t: any) => `${t.schema}.${t.name}`) + ) + let payload = { id, tables: realtimeTables } + const { error: publicationsUpdateError } = await this.publications.update(id, payload) + if (publicationsUpdateError) throw publicationsUpdateError + } + return duplicatedTable } async createTable( toastId: string, payload: any, - isRLSEnabled: boolean, columns: ColumnField[] = [], + isRLSEnabled: boolean, + isRealtimeEnabled: boolean, importContent?: ImportContent ) { // Create the table first @@ -379,6 +414,22 @@ export default class MetaStore implements IMetaStore { if (updatedTable.error) throw updatedTable.error } + // Toggle Realtime if configured to be + if (isRealtimeEnabled) { + const publications = this.publications.list() + const realtimePublication = publications.find( + (publication) => publication.name === 'supabase_realtime' + ) + + const id = realtimePublication?.id + const realtimeTables = [`${table.schema}.${table.name}`].concat( + realtimePublication.tables.map((t: any) => `${t.schema}.${t.name}`) + ) + let payload = { id, tables: realtimeTables } + const { error: publicationsUpdateError } = await this.publications.update(id, payload) + if (publicationsUpdateError) throw publicationsUpdateError + } + // Then insert the columns - we don't do Promise.all as we want to keep the integrity // of the column order during creation. Note that we add primary key constraints separately // via the query endpoint to support composite primary keys as pg-meta does not support that OOB @@ -483,11 +534,18 @@ export default class MetaStore implements IMetaStore { } } - async updateTable(toastId: string, table: PostgresTable, payload: any, columns: ColumnField[]) { + async updateTable( + toastId: string, + table: PostgresTable, + payload: any, + columns: ColumnField[], + isRealtimeEnabled: boolean + ) { // Prepare a check to see if primary keys to the tables were updated or not const primaryKeyColumns = columns .filter((column) => column.isPrimaryKey) .map((column) => `"${column.name}"`) + // @ts-ignore const existingPrimaryKeyColumns = table.primary_keys.map( (pk: PostgresPrimaryKey) => `"${pk.name}"` ) @@ -512,6 +570,7 @@ export default class MetaStore implements IMetaStore { const columnIds = columns.map((column) => column.id) // Delete any removed columns + // @ts-ignore const columnsToRemove = originalColumns.filter((column) => !columnIds.includes(column.id)) for (const column of columnsToRemove) { this.rootStore.ui.setNotification({ @@ -583,6 +642,30 @@ export default class MetaStore implements IMetaStore { if (primaryKeys.error) throw primaryKeys.error } + // Update realtime configuration + const publications = this.publications.list() + const realtimePublication = publications.find( + (publication) => publication.name === 'supabase_realtime' + ) + + const id = realtimePublication?.id + const realtimeEnabled = realtimePublication.tables.some((x: any) => x.id == table.id) + if (realtimeEnabled && !isRealtimeEnabled) { + // Toggle realtime off + const realtimeTables = realtimePublication.tables + .filter((x: any) => x.id != table.id) + .map((x: any) => `${x.schema}.${x.name}`) + let payload = { id, tables: realtimeTables } + await this.publications.update(id, payload) + } else if (!realtimeEnabled && isRealtimeEnabled) { + // Toggle realtime on + const realtimeTables = [`${table.schema}.${table.name}`].concat( + realtimePublication.tables.map((t: any) => `${t.schema}.${t.name}`) + ) + let payload = { id, tables: realtimeTables } + await this.publications.update(id, payload) + } + return { table: await this.tables.loadById(table.id), hasError } } diff --git a/studio/styles/ui.scss b/studio/styles/ui.scss index 5db599ca008..edd4643abf4 100644 --- a/studio/styles/ui.scss +++ b/studio/styles/ui.scss @@ -113,6 +113,10 @@ border-spacing: 0; } +.table-container table span { + @apply truncate; +} + .table-container thead th { @apply text-scale-900 font-normal text-sm; @apply bg-table-header-light dark:bg-table-header-dark; diff --git a/studio/tests/components/Editor/SpreadsheetImport.utils.test.js b/studio/tests/components/Editor/SpreadsheetImport.utils.test.js index a9d49688477..11ebfbe75c9 100644 --- a/studio/tests/components/Editor/SpreadsheetImport.utils.test.js +++ b/studio/tests/components/Editor/SpreadsheetImport.utils.test.js @@ -35,6 +35,15 @@ describe('SpreadsheedImport.utils: inferColumnType', () => { const type2 = inferColumnType('isRetired', mockData2) expect(type2).toBe('boolean') }) + test('should infer boolean type for a supposed boolean column if one of the rows has a null value', () => { + const mockData3 = [ + { name: 'bob', height: '161.72', isRetired: 'false' }, + { name: 'bob', height: '161.72', isRetired: 'true' }, + { name: 'bob', height: '161.72', isRetired: null }, + ] + const type3 = inferColumnType('isRetired', mockData3) + expect(type3).toBe('boolean') + }) test('should infer objects as jsonb types correctly', () => { const mockData = [{ name: 'bob', metadata: '{}' }] const type = inferColumnType('metadata', mockData) diff --git a/web/.gitignore b/web/.gitignore index daf4804dfa6..bd4efd55fd9 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -5,4 +5,7 @@ docs/client docs/gotrue/client docs/postgrest/client docs/realtime/client -docs/reference \ No newline at end of file + +docs/reference/**/* +!docs/reference/tools/ +!docs/reference/tools/**/* \ No newline at end of file diff --git a/web/docs/guides/api.mdx b/web/docs/guides/api.mdx index edebca59f58..8883bb38142 100644 --- a/web/docs/guides/api.mdx +++ b/web/docs/guides/api.mdx @@ -358,10 +358,10 @@ const handleInserts = (payload) => { console.log('Change received!', payload) } -// Listen to unserts +// Listen to inserts const { data: todos, error } = await supabase .from('todos') - .on('INSERT', handleUpdates) + .on('INSERT', handleInserts) .subscribe() ``` diff --git a/web/docs/guides/integrations/prisma.mdx b/web/docs/guides/integrations/prisma.mdx index 635e3bb9124..09411d99dfe 100644 --- a/web/docs/guides/integrations/prisma.mdx +++ b/web/docs/guides/integrations/prisma.mdx @@ -23,7 +23,7 @@ To make sure that everything works correctly, let’s try the connection string If you already have one, all you need to do is set the `DATABASE_URL` to the connection string (including the password) in your `.env` file, and you’re good to go. -In case you don’t have a Prisma project or this is your first time working with Prisma, you’re going to use with the repo from the [quickstart](https://www.prisma.io/docs/getting-started/quickstart) guide. +In case you don’t have a Prisma project or this is your first time working with Prisma, you’re going to use the repo from the [quickstart](https://www.prisma.io/docs/getting-started/quickstart) guide. ### Cloning the starter project @@ -140,10 +140,10 @@ alter type "Incompatible" rename to compatible; ## Connection pooling with Supabase -If you’re working in a serverless environment (for example Node.js functions hosted on AWS Lambda, Vercel or Netlify Functions), you need to set up [connection pooling](https://www.prisma.io/docs/guides/performance-and-optimization/connection-management#serverless-environments-faas) using a tool like [PgBouncer](https://www.pgbouncer.org/). That’s because every function invocation may result in a [new connection to the database](https://www.prisma.io/docs/guides/performance-and-optimization/connection-management#the-serverless-challenge). Supabase [support connection management using PgBouncer](https://supabase.io/blog/2021/04/02/supabase-pgbouncer#what-is-connection-pooling) and are enabled by default. +If you’re working in a serverless environment (for example Node.js functions hosted on AWS Lambda, Vercel or Netlify Functions), you need to set up [connection pooling](https://www.prisma.io/docs/guides/performance-and-optimization/connection-management#serverless-environments-faas) using a tool like [PgBouncer](https://www.pgbouncer.org/). That’s because every function invocation may result in a [new connection to the database](https://www.prisma.io/docs/guides/performance-and-optimization/connection-management#the-serverless-challenge). Supabase [supports connection management using PgBouncer](https://supabase.io/blog/2021/04/02/supabase-pgbouncer#what-is-connection-pooling) and are enabled by default. Go to the **Database** page from the sidebar in the Supabase dashboard and navigate to **connection pool** settings ![Connection pool settings](/img/guides/integrations/prisma/w0oowg8vq435ob5c3gf0.png) -When running migrations you need to use the non pooled connection URL (like the one we used in **step 4**). However, when deploying your app, you’ll use the pooled connection URL and add the `?pgbouncer=true` flag to the PostgreSQL connection URL. To minimize the number of concurrent connections, setting the `connection_limit` to `1` is also recommended. So The URL might look as follows: +When running migrations you need to use the non pooled connection URL (like the one we used in **step 4**). However, when deploying your app, you’ll use the pooled connection URL and add the `?pgbouncer=true` flag to the PostgreSQL connection URL. To minimize the number of concurrent connections, setting the `connection_limit` to `1` is also recommended. So the URL might look as follows: ```env # prisma/.env diff --git a/web/docs/guides/local-development.mdx b/web/docs/guides/local-development.mdx index fc95160cf38..114c5f8cfcf 100644 --- a/web/docs/guides/local-development.mdx +++ b/web/docs/guides/local-development.mdx @@ -244,11 +244,11 @@ supabase functions deploy ## Limitations -The local development environment is not as feature-complete as the Plaform. Here are some of the differences: +The local development environment is not as feature-complete as the Platform. Here are some of the differences: - The Storage interface is coming soon. - The Functions interface is coming soon. -- Logs are not supported though the interface (however you can accesss them via the docker containers). +- Logs are not supported through the interface (however you can accesss them via the docker containers). - You cannot update your project settings via the Dashboard - this can be done using the CLI instead. ## Next steps diff --git a/web/docs/reference.mdx b/web/docs/reference.mdx index 89b1c3fd836..b7e54ee6877 100644 --- a/web/docs/reference.mdx +++ b/web/docs/reference.mdx @@ -34,6 +34,34 @@ The Supabase Reference Docs provide technical descriptions of the products and h
+## Tools + +The Supabase Reference Docs provide technical descriptions of the products and how to use them. + +
+
+ {/* Examples - coming soon */} +
+ +
+

Auth

+

Auth reference.

+
+ +
+ {/* CLI */} +
+ +
+

Connection Pool

+

PgBouncer reference docs.

+
+ +
+ {/* */} +
+
+ ## Client Libraries
diff --git a/web/docs/reference/tools/auth.mdx b/web/docs/reference/tools/auth.mdx new file mode 100644 index 00000000000..c1c3ed60198 --- /dev/null +++ b/web/docs/reference/tools/auth.mdx @@ -0,0 +1,255 @@ +--- +id: reference-auth +title: Auth Server +description: An SWT based API for managing users and issuing SWT tokens +--- + +GoTrue is a small open-source API written in golang, that can act as a self-standing +API service for handling user registration and authentication for JAM projects. + +It's based on OAuth2 and JWT and will handle user signup, authentication and custom +user data. + +If you're using gotrue on the Supabase platform, some of these options are not exposed on the dashboard as they are set internally. +If you're self-hosting gotrue on your own infrastructure, you will need to maintain these configuration options in an `.env` file. Most of these configuration options need to be prefixed with `GOTRUE_` if self-hosting. + +## Configuration + +The following list provides an overview of the configuration set in gotrue. + +### Security + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `SITE_URL` | `string` | **Required**. The base URL your site is located at. Currently used in combination with other settings to construct URLs used in emails. Any URI that shares a host with `SITE_URL` is a permitted value for `redirect_to` params (see `/authorize` etc.). | +| `URI_ALLOW_LIST` | `string` | A comma separated list of URIs (e.g. `"https://foo.example.com,https://*.foo.example.com"`) which are permitted as valid `redirect_to` destinations. Defaults to [ ].

Supports wildcard matching through globbing. (e.g. `https://*.foo.example.com` will allow `https://a.foo.example.com` and `https://b.foo.example.com` to be accepted.)

Globbing is also supported on subdomains. (e.g. `https://foo.example.com/*` will allow `https://foo.example.com/page1` and `https://foo.example.com/page2` to be accepted.)
For more common glob patterns, check out the [following link](https://pkg.go.dev/github.com/gobwas/glob#Compile).| +| `OPERATOR_TOKEN` | `string` | The shared secret with an operator for this microservice. Used to verify requests have been proxied through the operator and the payload values can be trusted. | +| `DISABLE_SIGNUP` | `bool` | When signup is disabled the only way to create new users is through invites. Defaults to `false`, all signups enabled. | +| `EXTERNAL_EMAIL_ENABLED` | `bool` | Use this to disable email signups (users can still use external oauth providers to sign up / sign in) | +| `EXTERNAL_PHONE_ENABLED` | `bool` | Use this to disable phone signups (users can still use external oauth providers to sign up / sign in) | +| `RATE_LIMIT_TOKEN_REFRESH` | `string` | Rate limit the number of requests sent to `/token` | +| `RATE_LIMIT_EMAIL_SENT` | `string` | Rate limit the number of emails sent per hr on the following endpoints: `/signup`, `/invite`, `/magiclink`, `/recover`, `/otp`, & `/user`. | +| `PASSWORD_MIN_LENGTH` | `int` | Minimum password length, defaults to 6. | + +These options control additional security settings available in gotrue. If self-hosting, they need to be prefixed with `GOTRUE_SECURITY_` . + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `REFRESH_TOKEN_ROTATION_ENABLED` | `bool` | If refresh token rotation is enabled, gotrue will automatically detect malicious attempts to reuse a revoked refresh token. When a malicious attempt is detected, gotrue immediately revokes all tokens that descended from the offending token. | +| `REFRESH_TOKEN_REUSE_INTERVAL` | `string` | This setting is only applicable if `REFRESH_TOKEN_ROTATION_ENABLED` is enabled. The reuse interval for a refresh token allows for exchanging the refresh token multiple times during the interval to support concurrency or offline issues.
During the reuse interval, gotrue will not consider using a revoked token as a malicious attempt and will simply return the child refresh token.
Only the previous revoked token can be reused. Using an old refresh token way before the current valid refresh token will trigger the reuse detection. | +| `CAPTCHA_ENABLED` | `string` | Enables the captcha middleware. | +| `CAPTCHA_PROVIDER` | `string` | The only captcha provider option supported is: `hcaptcha`. | +| `CAPTCHA_SECRET` | `string` | The captcha secret token. Retrieve this from your captcha account. | +| `CAPTCHA_TIMEOUT` | `string` | The http timeout on the captcha request. | +| `UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION` | `bool` | When enabled, this requires a user to reauthenticate before being able to update their password. | + +### API + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `API_HOST` | `string` | Hostname to listen on. | +| `PORT` | `number` | Port number to listen on. Defaults to `8081`. | +| `REQUEST_ID_HEADER` | `string` | If you wish to inherit a request ID from the incoming request, specify the name in this value. | + + +### Database + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `DB_DRIVER` | `string` | **Required**. Chooses what dialect of database you want. Must be `postgres`. | +| `DATABASE_URL` | `string` | **Required**. Connection string for the database. | +| `DB_MAX_POOL_SIZE` | `int` | Sets the maximum number of open connections to the database. Defaults to 0 which is equivalent to an "unlimited" number of connections. | +| `DB_NAMESPACE` | `string` | Specifies the schema in which the tables are to be created in. | + +### JSON Web Tokens (JWT) + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `JWT_SECRET` | `string` | **Required**. The secret used to sign JWT tokens with. | +| `JWT_EXP` | `number` | How long tokens are valid for in seconds. Defaults to 3600 (1 hour). | +| `JWT_AUD` | `string` | The default JWT audience. Use audiences to group users. Defaults to `authenticated`. | +| `JWT_ADMIN_GROUP_NAME` | `string` | The name of the admin group (if enabled). Defaults to `admin`. | +| `JWT_DEFAULT_GROUP_NAME` | `string` | The default group to assign all new users to. | + +### External Authentication Providers + +We support `apple`, `azure`, `bitbucket`, `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin`, `notion`, `spotify`, `slack`, `twitch`, `twitter` and `workos` for external authentication. + +Use the names as the keys underneath `external` to configure each separately. + +No external providers are required, but you must provide the required values if you choose to enable any. + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `EXTERNAL_X_ENABLED` | `bool` | Whether this external provider is enabled or not | +| `EXTERNAL_X_CLIENT_ID` | `string` | **Required**. The OAuth2 Client ID registered with the external provider. | +| `EXTERNAL_X_SECRET` | `string` | **Required**. The OAuth2 Client Secret provided by the external provider when you registered. | +| `EXTERNAL_X_REDIRECT_URI` | `string` | **Required**. Also known as the callback url, this is the URI an OAuth2 provider will redirect to with the `code` and `state` values. | +| `EXTERNAL_X_URL` | `string` | The base URL used for constructing the URLs to request authorization and access tokens. Used by `gitlab` and `keycloak`. For `gitlab` it defaults to `https://gitlab.com`. For `keycloak` you need to set this to your realm url, (e.g. `https://keycloak.example.com/auth/realms/myrealm`) | + +#### Apple OAuth + +To try out sign-in with Apple locally, you will need to do the following: + +1. Run gotrue over https via ngrok or another proxy. +2. Generate the crt and key file. See [here](https://www.freecodecamp.org/news/how-to-get-https-working-on-your-local-development-environment-in-5-minutes-7af615770eec/) for more information. +3. Generate the `GOTRUE_EXTERNAL_APPLE_SECRET` by following this [post](https://medium.com/identity-beyond-borders/how-to-configure-sign-in-with-apple-77c61e336003)! + +### SMTP Configuration + +Sending email is not required, but highly recommended for password recovery. If `mailer_autoconfirm` is enabled, no emails will be sent out for `signup`, `recovery`, `invite`. Emails will only be sent out for `magiclink`. + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `SMTP_ADMIN_EMAIL` | `string` | **Required**. The `From` email address for all emails sent. | +| `SMTP_HOST` | `string` | **Required**. The mail server hostname to send emails through. | +| `SMTP_PORT` | `string` | **Required**. The port number to connect to the mail server on. | +| `SMTP_USER` | `string` | **Required**. If the mail server requires authentication, the username to use. | +| `SMTP_PASS` | `string` | **Required**. If the mail server requires authentication, the password to use. | +| `SMTP_MAX_FREQUENCY` | `string` | Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email. The value is the number of seconds. Defaults to 60 seconds. | +| `SMTP_SENDER_NAME` | `string` | Sets the name of the sender. Defaults to the `SMTP_ADMIN_EMAIL` if not used. | + +### Email + +These options control the emails sent from gotrue. + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `MAILER_AUTOCONFIRM` | `bool` | If you do not require email confirmation, you may set this to `true`. Defaults to `false`. | +| `MAILER_OTP_EXP` | `string` | Controls the duration an email link or otp is valid for. Defaults to 24 hrs. | +| `MAILER_URLPATHS_INVITE` | `string` | URL path to use in the user invite email. Defaults to `/`. | +| `MAILER_URLPATHS_CONFIRMATION` | `string` | URL path to use in the signup confirmation email. Defaults to `/`. | +| `MAILER_URLPATHS_RECOVERY` | `string` | URL path to use in the password reset email. Defaults to `/`. | +| `MAILER_URLPATHS_EMAIL_CHANGE` | `string` | URL path to use in the email change confirmation email. Defaults to `/`. | +| `MAILER_SUBJECTS_INVITE` | `string` | Email subject to use for user invite. Defaults to `You have been invited`. | +| `MAILER_SUBJECTS_CONFIRMATION` | `string` | Email subject to use for signup confirmation. Defaults to `Confirm Your Signup`. | +| `MAILER_SUBJECTS_RECOVERY` | `string` | Email subject to use for password reset. Defaults to `Reset Your Password`. | +| `MAILER_SUBJECTS_MAGIC_LINK` | `string` | Email subject to use for magic link email. Defaults to `Your Magic Link`. | +| `MAILER_SUBJECTS_EMAIL_CHANGE` | `string` | Email subject to use for email change confirmation. Defaults to `Confirm Email Change`. | + +### Email Templates +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `MAILER_TEMPLATES_INVITE` | `string` | URL path to an email template to use when inviting a user. `SiteURL`, `Email`, and `ConfirmationURL` variables are available. | + +Default Content (if template is unavailable): + +```html +

You have been invited

+

+ You have been invited to create a user on {{ .SiteURL }}. Follow this link to accept the invite: +

+

Accept the invite

+``` + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `MAILER_TEMPLATES_CONFIRMATION` | `string` | URL path to an email template to use when confirming a signup. `SiteURL`, `Email`, and `ConfirmationURL` variables are available. | + +Default Content (if template is unavailable): + +```html +

Confirm your signup

+ +

Follow this link to confirm your user:

+

Confirm your mail

+``` + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `MAILER_TEMPLATES_RECOVERY` | `string` | URL path to an email template to use when resetting a password. `SiteURL`, `Email`, and `ConfirmationURL` variables are available. | + +Default Content (if template is unavailable): + +```html +

Reset Password

+ +

Follow this link to reset the password for your user:

+

Reset Password

+``` + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `MAILER_TEMPLATES_MAGIC_LINK` | `string` | URL path to an email template to use when sending magic link. `SiteURL`, `Email`, and `ConfirmationURL` variables are available. | + +Default Content (if template is unavailable): + +```html +

Magic Link

+ +

Follow this link to login:

+

Log In

+``` + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `MAILER_TEMPLATES_EMAIL_CHANGE` | `string` | URL path to an email template to use when confirming the change of an email address. `SiteURL`, `Email`, `NewEmail` and `ConfirmationURL` variables are available. | + +Default Content (if template is unavailable): + +```html +

Confirm Change of Email

+ +

Follow this link to confirm the update of your email from {{ .Email }} to {{ .NewEmail }}:

+

Change Email

+``` + +### Phone Auth + +These options control the sms-es sent from gotrue. + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `SMS_AUTOCONFIRM` | `bool` | If you do not require phone confirmation, you may set this to `true`. Defaults to `false`. | +| `SMS_MAX_FREQUENCY` | `number` | Controls the minimum amount of time that must pass before sending another sms otp. The value is the number of seconds. Defaults to 60 (1 minute)). | +| `SMS_OTP_EXP` | `number` | Controls the duration an sms otp is valid for. | +| `SMS_OTP_LENGTH` | `number` | Controls the number of digits of the sms otp sent. Valid otp lengths are between [6 - 10] digits | +| `SMS_PROVIDER` | `string` | Available options are: `twilio`, `messagebird`, `textlocal`, and `vonage` | + +If you're using twilio, you can obtain your credentials from the [twilio dashboard](https://www.twilio.com/docs/usage/requests-to-twilio#credentials): + +You can find the `SMS_TWILIO_ACCOUNT_SID` and `SMS_TWILIO_AUTH_TOKEN` in the account info page of the twilio console dashboard. + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `SMS_TWILIO_ACCOUNT_SID` | `string` | Your twilio account string identifier (SID). | +| `SMS_TWILIO_AUTH_TOKEN` | `string` | Your twilio auth token. | +| `SMS_TWILIO_MESSAGE_SERVICE_SID` | `string` | Your twilio sender mobile number | + + +If you're using messagebird, you can obtain your credentials from the [messagebird dashboard](https://dashboard.messagebird.com/en/developers/access): + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `SMS_MESSAGEBIRD_ACCESS_KEY` | `string` | Your messagebird access key. | +| `SMS_MESSAGEBIRD_ORIGINATOR` | `string` | Your messagebird sender phone number with + or company name. | + +### Logging + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `LOG_LEVEL` | `string` | Controls what log levels are output. Choose from `panic`, `fatal`, `error`, `warn`, `info`, or `debug`. Defaults to `info`. | +| `LOG_FILE` | `string` | If you wish logs to be written to a file, set `log_file` to a valid file path. | + +### Opentracing + +Currently, only the Datadog tracer is supported. + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `TRACING_ENABLED` | `bool` | Whether tracing is enabled or not. Defaults to `false`. | +| `TRACING_HOST` | `string` | The tracing destination. (e.g. `GOTRUE_TRACING_HOST=127.0.0.1`) | +| `TRACING_PORT` | `int` | The port for the tracing host. | +| `TRACING_TAGS` | `string` | A comma separated list of key:value pairs. These key value pairs will be added as tags to all opentracing spans. (e.g. `GOTRUE_TRACING_TAGS="tag1:value1,tag2:value2"`) | +| `SERVICE_NAME` | `string` | The name to use for the service. | + +### Webhooks + +| Parameter | Type | Description | +| :-------- | :------- | :------------------------- | +| `WEBHOOK_URL` | `string` | Url of the webhook receiver endpoint. This will be called when events like `validate`, `signup` or `login` occur. | +| `WEBHOOK_SECRET` | `string` | Shared secret to authorize webhook requests. This secret signs the [JSON Web Signature](https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41) of the request. You _should_ use this to verify the integrity of the request. Otherwise others can feed your webhook receiver with fake data. | +| `WEBHOOK_RETRIES` | `number` | How often GoTrue should try a failed hook. | +| `WEBHOOK_TIMEOUT_SEC` | `number` | Time between retries (in seconds). | +| `WEBHOOK_EVENTS` | `list` | Which events should trigger a webhook. You can provide a comma separated list. For example to listen to all events, provide the values `validate,signup,login`. | + diff --git a/web/package-lock.json b/web/package-lock.json index 0fc3e698ae1..0d029015f2a 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -206,17 +206,17 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz", + "integrity": "sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", - "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz", + "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", @@ -224,10 +224,10 @@ "@babel/helper-compilation-targets": "^7.18.2", "@babel/helper-module-transforms": "^7.18.0", "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.0", + "@babel/parser": "^7.18.5", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2", + "@babel/traverse": "^7.18.5", + "@babel/types": "^7.18.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -668,9 +668,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", + "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1389,9 +1389,9 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.4.tgz", - "integrity": "sha512-lH2UaQaHVOAeYrUUuZ8i38o76J/FnO8vu21OE+tD1MyP9lxdZoSfz+pDbWkq46GogUrdrMz3tiz/FYGB+bVThg==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.5.tgz", + "integrity": "sha512-SEewrhPpcqMF1V7DhnEbhVJLrC+nnYfe1E0piZMZXBpxi9WvZqWGwpsk7JYP7wPWeqaBh4gyKlBhHJu3uz5g4Q==", "dependencies": { "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-module-transforms": "^7.18.0", @@ -1437,9 +1437,9 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.17.12.tgz", - "integrity": "sha512-CaOtzk2fDYisbjAD4Sd1MTKGVIpRtx9bWLyj24Y/k6p4s4gQ3CqDGJauFJxt8M/LEx003d0i3klVqnN73qvK3w==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.5.tgz", + "integrity": "sha512-TuRL5uGW4KXU6OsRj+mLp9BM7pO8e7SGNTEokQRRxHFkXYMFiy2jlKSZPFtI/mKORDzciH+hneskcSOp0gU8hg==", "dependencies": { "@babel/helper-plugin-utils": "^7.17.12" }, @@ -1598,9 +1598,9 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.2.tgz", - "integrity": "sha512-mr1ufuRMfS52ttq+1G1PD8OJNqgcTFjq3hwn8SZ5n1x1pBhi0E36rYMdTK0TsKtApJ4lDEdfXJwtGobQMHSMPg==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.5.tgz", + "integrity": "sha512-Q17hHxXr2fplrE+5BSC1j1Fo5cOA8YeP8XW3/1paI8MzF/faZGh0MaH1KC4jLAvqLPamQWHB5/B7KqSLY1kuHA==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/helper-plugin-utils": "^7.17.12", @@ -1923,9 +1923,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", - "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", + "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", "dependencies": { "@babel/code-frame": "^7.16.7", "@babel/generator": "^7.18.2", @@ -1933,8 +1933,8 @@ "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.2", + "@babel/parser": "^7.18.5", + "@babel/types": "^7.18.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2108,6 +2108,9 @@ "dependencies": { "@types/react": "*", "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": "*" } }, "node_modules/@docusaurus/cssnano-preset": { @@ -2671,7 +2674,6 @@ "node_modules/@kiwicopple/prism-react-renderer": { "version": "1.0.2", "resolved": "git+ssh://git@github.com/kiwicopple/prism-react-renderer.git#4a09100a587bce2d94d7ac8ed3564a61c6e70781", - "integrity": "sha512-QluokmJkMoHOwahIBN34hTG5n03kFyJ0REDq4mkf0o05JUC61ikXQsPNXtynASqoZRW7A+bKVNT65kCtUfgZlQ==", "license": "MIT", "dependencies": { "prismjs": "^1.22.0" @@ -2767,7 +2769,7 @@ "node_modules/@mdx-js/mdx/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "engines": { "node": ">=0.10.0" } @@ -2868,9 +2870,9 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", - "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.1.0.tgz", + "integrity": "sha512-kQzJh3ZUv3lDpi6M+uekMRHULvf9DlWoI1XgKN6nPeGDzkSgtkhVq1MMz3bFKQ6H6GbdC3ZqG/a6VzKhIx0VeA==" }, "node_modules/@octokit/request": { "version": "5.6.3", @@ -2896,11 +2898,11 @@ } }, "node_modules/@octokit/types": { - "version": "6.34.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", - "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "version": "6.35.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.35.0.tgz", + "integrity": "sha512-DhLfdUuv3H37u6jBDfkwamypx3HflHg29b26nbA6iVFYkAlZ5cMEtu/9pQoihGnQE5M7jJFnNo25Rr1UwQNF8Q==", "dependencies": { - "@octokit/openapi-types": "^11.2.0" + "@octokit/openapi-types": "^12.1.0" } }, "node_modules/@polka/url": { @@ -3208,27 +3210,27 @@ } }, "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "node_modules/@types/body-parser": { @@ -3266,9 +3268,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", - "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", + "version": "8.4.3", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.3.tgz", + "integrity": "sha512-YP1S7YJRMPs+7KZKDb9G63n8YejIwW9BALq7a5j2+H4yl6iOv9CB29edho+cuFRrvmJbbaH2yiVChKLJVysDGw==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -3300,9 +3302,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "version": "4.17.29", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", + "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -3354,9 +3356,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "node_modules/@types/node": { - "version": "14.18.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.20.tgz", - "integrity": "sha512-Q8KKwm9YqEmUBRsqJ2GWJDtXltBDxTdC4m5vTdXBolu2PeQh8LX+f6BTwU+OuXPu37fLxoN6gidqBmnky36FXA==" + "version": "14.18.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.21.tgz", + "integrity": "sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -3384,9 +3386,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/react": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.45.tgz", - "integrity": "sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg==", + "version": "17.0.46", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.46.tgz", + "integrity": "sha512-zNAJVEO9dBEQLPa/OuedGfx92/UlD+1rNxSv2qVWUQZ+orEtLUWFgZ08xfyI9TAZLnmWzZDtssAsgtbXT7Ew0g==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3778,9 +3780,9 @@ } }, "node_modules/algoliasearch-helper": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.8.2.tgz", - "integrity": "sha512-AXxiF0zT9oYwl8ZBgU/eRXvfYhz7cBA5YrLPlw9inZHdaYF0QEya/f1Zp1mPYMXc1v6VkHwBq4pk6/vayBLICg==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.8.3.tgz", + "integrity": "sha512-J0H08fQoyhZ2qLi7Uy8EvUeN/NJ4Trtt7NWB8mF1CGLuYpdXPyjZu9+Uoya2eayxQ20RP+QGF9Om/LddPv49vw==", "dependencies": { "@algolia/events": "^4.0.1" }, @@ -3860,9 +3862,9 @@ } }, "node_modules/arg": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.1.tgz", - "integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "node_modules/argparse": { "version": "1.0.10", @@ -3888,7 +3890,7 @@ "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "node_modules/at-least-node": { "version": "1.0.0", @@ -4076,12 +4078,12 @@ "node_modules/base16": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", - "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=" + "integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==" }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, "node_modules/before-after-hook": { "version": "2.2.2", @@ -4160,20 +4162,20 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/bonjour-service": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.12.tgz", - "integrity": "sha512-pMmguXYCu63Ug37DluMKEHdxc+aaIf/ay4YbF8Gxtba+9d3u+rmEWy61VK3Z3hp8Rskok3BunHYnG0dUHAsblw==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.13.tgz", + "integrity": "sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA==", "dependencies": { "array-flatten": "^2.1.2", "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.4" + "multicast-dns": "^7.2.5" } }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/boxen": { "version": "6.2.1", @@ -4217,9 +4219,9 @@ } }, "node_modules/browserslist": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", - "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "version": "4.20.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", + "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", "funding": [ { "type": "opencollective", @@ -4231,10 +4233,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001332", - "electron-to-chromium": "^1.4.118", + "caniuse-lite": "^1.0.30001349", + "electron-to-chromium": "^1.4.147", "escalade": "^3.1.1", - "node-releases": "^2.0.3", + "node-releases": "^2.0.5", "picocolors": "^1.0.0" }, "bin": { @@ -4364,9 +4366,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001346", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001346.tgz", - "integrity": "sha512-q6ibZUO2t88QCIPayP/euuDREq+aMAxFE5S70PkrLh0iTDj/zEhgvJRKC2+CvXY6EWc6oQwUR48lL5vCW6jiXQ==", + "version": "1.0.30001355", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001355.tgz", + "integrity": "sha512-Sd6pjJHF27LzCB7pT7qs+kuX2ndurzCzkpJl6Qct7LPSZ9jn0bkOA8mdgMgmqnQAWLVOOGjLpc+66V57eLtb1g==", "funding": [ { "type": "opencollective", @@ -4594,7 +4596,7 @@ "node_modules/clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", "dependencies": { "mimic-response": "^1.0.0" } @@ -4638,9 +4640,9 @@ "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==" }, "node_modules/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "node_modules/combine-promises": { "version": "1.1.0", @@ -4670,7 +4672,7 @@ "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "node_modules/compressible": { "version": "2.0.18", @@ -4719,12 +4721,12 @@ "node_modules/compression/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/configstore": { "version": "5.0.1", @@ -4790,7 +4792,7 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/copy-text-to-clipboard": { "version": "3.0.1", @@ -4864,9 +4866,9 @@ } }, "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.1.tgz", - "integrity": "sha512-XMzoDZbGZ37tufiv7g0N4F/zp3zkwdFtVbV3EHsVl1KQr4RPLfNoT068/97RPshz2J5xYNEjLKKBKaGHifBd3Q==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", "dependencies": { "dir-glob": "^3.0.1", "fast-glob": "^3.2.11", @@ -4916,9 +4918,9 @@ } }, "node_modules/core-js": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz", - "integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.1.tgz", + "integrity": "sha512-wfMYHWi1WQjpgZNC9kAlN4ut04TM9fUTdi7CqIoTVM7yaiOUQTklOzfb+oWH3r9edQcT3F887swuVmxrV+CC8w==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -4926,11 +4928,11 @@ } }, "node_modules/core-js-compat": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.8.tgz", - "integrity": "sha512-pQnwg4xtuvc2Bs/5zYQPaEYYSuTxsF7LBWF0SvnVhthZo/Qe+rJpcEekrdNK5DWwDJ0gv0oI9NNX5Mppdy0ctg==", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.1.tgz", + "integrity": "sha512-KeYrEc8t6FJsKYB2qnDwRHWaC0cJNaqlHfCpMe5q3j/W1nje3moib/txNklddLPCtGb+etcBIyJ8zuMa/LN5/A==", "dependencies": { - "browserslist": "^4.20.3", + "browserslist": "^4.20.4", "semver": "7.0.0" }, "funding": { @@ -4947,9 +4949,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.8.tgz", - "integrity": "sha512-bOxbZIy9S5n4OVH63XaLVXZ49QKicjowDx/UELyJ68vxfCRpYsbyh/WNZNfEfAk+ekA8vSjt+gCDpvh672bc3w==", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.1.tgz", + "integrity": "sha512-3qNgf6TqI3U1uhuSYRzJZGfFd4T+YlbyVPl+jgRiKjdZopvG4keZQwWZDAWpu1UH9nCgTpUzIV3GFawC7cJsqg==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5012,9 +5014,9 @@ } }, "node_modules/css-declaration-sorter": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz", - "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz", + "integrity": "sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og==", "engines": { "node": "^10 || ^12 || >=14" }, @@ -5136,7 +5138,7 @@ "node_modules/css-modules-require-hook": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/css-modules-require-hook/-/css-modules-require-hook-4.2.3.tgz", - "integrity": "sha1-Z5LKQSsV4j5vm+agfc739Xf/kE0=", + "integrity": "sha512-y3eGHAqmDl8JQdr1LYTwBkMxy7CSHCMy9YwpSjDqtGqCCEy9lKq/x/nmHVs+G7C1+xXmyIXjRu0q/MMn8w01mg==", "dev": true, "dependencies": { "debug": "^2.2.0", @@ -5194,7 +5196,7 @@ "node_modules/css-modules-require-hook/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/css-modules-require-hook/node_modules/debug": { @@ -5209,7 +5211,7 @@ "node_modules/css-modules-require-hook/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -5218,7 +5220,7 @@ "node_modules/css-modules-require-hook/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -5227,7 +5229,7 @@ "node_modules/css-modules-require-hook/node_modules/icss-utils": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-3.0.1.tgz", - "integrity": "sha1-7nDTroysOMa+XtkehRsn7tNDrQ8=", + "integrity": "sha512-ANhVLoEfe0KoC9+z4yiTaXOneB49K6JIXdS+yAgH0NERELpdIT7kkj2XxUPuHafeHnn8umXnECSpsfk1RTaUew==", "dev": true, "dependencies": { "postcss": "^6.0.2" @@ -5236,7 +5238,7 @@ "node_modules/css-modules-require-hook/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "node_modules/css-modules-require-hook/node_modules/postcss": { @@ -5381,11 +5383,11 @@ } }, "node_modules/cssnano": { - "version": "5.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.10.tgz", - "integrity": "sha512-ACpnRgDg4m6CZD/+8SgnLcGCgy6DDGdkMbOawwdvVxNietTNLe/MtWcenp6qT0PRt5wzhGl6/cjMWCdhKXC9QA==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.11.tgz", + "integrity": "sha512-2nx+O6LvewPo5EBtYrKc8762mMkZRk9cMGIOP4UlkmxHm7ObxH+zvsJJ+qLwPkUc4/yumL/qJkavYi9NlodWIQ==", "dependencies": { - "cssnano-preset-default": "^5.2.10", + "cssnano-preset-default": "^5.2.11", "lilconfig": "^2.0.3", "yaml": "^1.10.2" }, @@ -5401,12 +5403,12 @@ } }, "node_modules/cssnano-preset-advanced": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.6.tgz", - "integrity": "sha512-OZHsytu16eStRVrIY3wmPQqhJMaI0+O3raU4JHoKV3uuQYEeQek/FJVUIvYXD55hWR6OjCMyKYNRDw+k3/xgUw==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.7.tgz", + "integrity": "sha512-VNOdTMRA60KhaURZhnkTGeluHQBHWDMwY7TIDu1Qydf88X6k8xZbV2I+Wlm8JRaj2oi18xvoIOAW17JneoZzEg==", "dependencies": { "autoprefixer": "^10.3.7", - "cssnano-preset-default": "^5.2.10", + "cssnano-preset-default": "^5.2.11", "postcss-discard-unused": "^5.1.0", "postcss-merge-idents": "^5.1.1", "postcss-reduce-idents": "^5.2.0", @@ -5420,9 +5422,9 @@ } }, "node_modules/cssnano-preset-default": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.10.tgz", - "integrity": "sha512-H8TJRhTjBKVOPltp9vr9El9I+IfYsOMhmXdK0LwdvwJcxYX9oWkY7ctacWusgPWAgQq1vt/WO8v+uqpfLnM7QA==", + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.11.tgz", + "integrity": "sha512-4PadR1NtuaIK8MvLNuY7MznK4WJteldGlzCiMaaTiOUP+apeiIvUDIXykzUOoqgOOUAHrU64ncdD90NfZR3LSQ==", "dependencies": { "css-declaration-sorter": "^6.2.2", "cssnano-utils": "^3.1.0", @@ -5448,7 +5450,7 @@ "postcss-normalize-unicode": "^5.1.0", "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.1", + "postcss-ordered-values": "^5.1.2", "postcss-reduce-initial": "^5.1.0", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", @@ -6196,7 +6198,7 @@ "node_modules/decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "dependencies": { "mimic-response": "^1.0.0" }, @@ -6370,7 +6372,7 @@ "node_modules/detect-port-alt/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/detect-port/node_modules/debug": { "version": "2.6.9", @@ -6383,7 +6385,7 @@ "node_modules/detect-port/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/diff": { "version": "4.0.2", @@ -6408,12 +6410,12 @@ "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" }, "node_modules/dns-packet": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz", - "integrity": "sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", + "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -6566,7 +6568,7 @@ "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "integrity": "sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==" }, "node_modules/eastasianwidth": { "version": "0.2.0", @@ -6576,12 +6578,12 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.144", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.144.tgz", - "integrity": "sha512-R3RV3rU1xWwFJlSClVWDvARaOk6VUO/FubHLodIASDB3Mc2dzuWvNdfOgH9bwHUTqT79u92qw60NWfwUdzAqdg==" + "version": "1.4.158", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz", + "integrity": "sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -6608,7 +6610,7 @@ "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } @@ -6676,7 +6678,7 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -6762,7 +6764,7 @@ "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } @@ -6828,7 +6830,7 @@ "node_modules/exenv": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", - "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" }, "node_modules/express": { "version": "4.18.1", @@ -6940,7 +6942,7 @@ "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { "is-extendable": "^0.1.0" }, @@ -6976,7 +6978,7 @@ "node_modules/fast-url-parser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", "dependencies": { "punycode": "^1.3.2" } @@ -7303,7 +7305,7 @@ "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } @@ -7329,7 +7331,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", @@ -7352,7 +7354,7 @@ "node_modules/generic-names": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-1.0.3.tgz", - "integrity": "sha1-LXhqEhruUIh2eWk56OO/+DbCCRc=", + "integrity": "sha512-b6OHfQuKasIKM9b6YPkX+KUj/TLBTx3B/1aT1T5F12FEuEqyFMdr59OMS53aoaSw8eVtapdqieX6lbg5opaOhA==", "dev": true, "dependencies": { "loader-utils": "^0.2.16" @@ -7370,7 +7372,7 @@ "node_modules/generic-names/node_modules/emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", "dev": true, "engines": { "node": ">= 0.10" @@ -7379,7 +7381,7 @@ "node_modules/generic-names/node_modules/json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -7388,7 +7390,7 @@ "node_modules/generic-names/node_modules/loader-utils": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "integrity": "sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==", "dev": true, "dependencies": { "big.js": "^3.1.3", @@ -7406,13 +7408,13 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7472,7 +7474,7 @@ "node_modules/glob-to-regexp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", "dev": true }, "node_modules/global-dirs": { @@ -7809,7 +7811,7 @@ "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -7956,7 +7958,7 @@ "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" }, "node_modules/http-errors": { "version": "2.0.0", @@ -8047,7 +8049,7 @@ "node_modules/icss-replace-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", "dev": true }, "node_modules/icss-utils": { @@ -8084,9 +8086,9 @@ } }, "node_modules/immer": { - "version": "9.0.14", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz", - "integrity": "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw==", + "version": "9.0.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", + "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -8110,7 +8112,7 @@ "node_modules/import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", "engines": { "node": ">=4" } @@ -8118,7 +8120,7 @@ "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "engines": { "node": ">=0.8.19" } @@ -8142,7 +8144,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -8220,7 +8222,7 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -8303,7 +8305,7 @@ "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "engines": { "node": ">=0.10.0" } @@ -8311,7 +8313,7 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } @@ -8381,7 +8383,7 @@ "node_modules/is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", "engines": { "node": ">=0.10.0" } @@ -8421,7 +8423,7 @@ "node_modules/is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "engines": { "node": ">=0.10.0" } @@ -8448,7 +8450,7 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "node_modules/is-whitespace-character": { "version": "1.0.4", @@ -8492,12 +8494,12 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -8572,7 +8574,7 @@ "node_modules/json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -8607,9 +8609,9 @@ } }, "node_modules/jsrsasign": { - "version": "10.5.23", - "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.5.23.tgz", - "integrity": "sha512-e3hy//LH8EbRhzqyHJuf3pbehxYcnUZgGUjQKKTukWJ1M5uQTZBgFvItRK5ik8pixpYDAKY6xj527cEa1NQGPg==", + "version": "10.5.24", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.5.24.tgz", + "integrity": "sha512-0i/UHRgJZifp/YmoXHyNQXUY4eKWiSd7YxuD7oKEw9mlqgr51hg9lZQw2nlEDvwHDh7pyj6ZjYlxldlW27xb/Q==", "funding": { "url": "https://github.com/kjur/jsrsasign#donations" } @@ -8723,27 +8725,27 @@ "node_modules/lodash.curry": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", - "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA=" + "integrity": "sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==" }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.flow": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", - "integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=" + "integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==" }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, "node_modules/loglevel": { "version": "1.8.0", @@ -8892,12 +8894,12 @@ "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } @@ -8916,7 +8918,7 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/merge-stream": { "version": "2.0.0", @@ -8950,7 +8952,7 @@ "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } @@ -9027,9 +9029,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", - "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", + "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", "dependencies": { "schema-utils": "^4.0.0" }, @@ -9132,9 +9134,9 @@ "integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ==" }, "node_modules/mrmime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", - "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", "engines": { "node": ">=10" } @@ -9240,7 +9242,7 @@ "node_modules/normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "engines": { "node": ">=0.10.0" } @@ -9270,7 +9272,7 @@ "node_modules/nprogress": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E=" + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" }, "node_modules/nth-check": { "version": "2.1.1", @@ -9286,7 +9288,7 @@ "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } @@ -9351,7 +9353,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } @@ -10157,9 +10159,9 @@ } }, "node_modules/postcss-ordered-values": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.1.tgz", - "integrity": "sha512-7lxgXF0NaoMIgyihL/2boNAEZKiW0+HkMhdKMTD93CjW8TdCy2hSdj8lsAo+uwm7EDG16Da2Jdmtqpedl0cMfw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.2.tgz", + "integrity": "sha512-wr2avRbW4HS2XE2ZCqpfp4N/tDC6GZKZ+SVP8UBTOVS8QWrc4TD8MYrebJrvVVlGPKszmiSCzue43NDiVtgDmg==", "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" @@ -10530,7 +10532,7 @@ "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "engines": { "node": ">=0.10.0" } @@ -10550,7 +10552,7 @@ "node_modules/react-base16-styling": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.6.0.tgz", - "integrity": "sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=", + "integrity": "sha512-yvh/7CArceR/jNATXOKDlvTnPKPmGZz7zsenQ3jUwLzHkNUR0CvY3yGYJbWJ/nnxsL8Sgmt5cO3/SILVuPO6TQ==", "dependencies": { "base16": "^1.0.0", "lodash.curry": "^4.0.1", @@ -10864,7 +10866,7 @@ "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dependencies": { "resolve": "^1.1.6" }, @@ -10940,11 +10942,11 @@ } }, "node_modules/registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", + "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", "dependencies": { - "rc": "^1.2.8" + "rc": "1.2.8" }, "engines": { "node": ">=6.0.0" @@ -11038,7 +11040,7 @@ "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", "engines": { "node": ">= 0.10" } @@ -11177,7 +11179,7 @@ "node_modules/remark-mdx/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "engines": { "node": ">=0.10.0" } @@ -11317,7 +11319,7 @@ "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "engines": { "node": ">=0.10" } @@ -11333,7 +11335,7 @@ "node_modules/require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "engines": { "node": "*" } @@ -11341,7 +11343,7 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { "version": "1.22.0", @@ -11375,7 +11377,7 @@ "node_modules/responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", "dependencies": { "lowercase-keys": "^1.0.0" } @@ -11517,7 +11519,7 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "node_modules/rxjs": { "version": "7.5.5", @@ -11583,7 +11585,7 @@ "node_modules/seekout": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/seekout/-/seekout-1.0.2.tgz", - "integrity": "sha1-CbqfG9W0b7sTRxjrGaaDgsuxuck=", + "integrity": "sha512-eB4fRqHZCE8gmwFOVHC9tHzLkZJ2Y12qJvAJQox8kWjGObA++tgVeXHACsDCPajfNGnDaK2Juv+WzNlMuO43wQ==", "dev": true, "engines": { "node": ">=0.12" @@ -11592,7 +11594,7 @@ "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" }, "node_modules/selfsigned": { "version": "2.0.1", @@ -11729,7 +11731,7 @@ "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -11762,7 +11764,7 @@ "node_modules/serve-index/node_modules/http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -11776,12 +11778,12 @@ "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", @@ -11791,7 +11793,7 @@ "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "engines": { "node": ">= 0.6" } @@ -11813,7 +11815,7 @@ "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -11931,9 +11933,9 @@ } }, "node_modules/sitemap/node_modules/@types/node": { - "version": "17.0.38", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.38.tgz", - "integrity": "sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g==" + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" }, "node_modules/slash": { "version": "3.0.0", @@ -12026,7 +12028,7 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/stable": { "version": "0.1.8", @@ -12150,7 +12152,7 @@ "node_modules/strip-bom-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", "engines": { "node": ">=0.10.0" } @@ -12329,9 +12331,9 @@ } }, "node_modules/terser": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.0.tgz", - "integrity": "sha512-JC6qfIEkPBd9j1SMO3Pfn+A6w2kQV54tv+ABQLgZr7dA3k/DL/OBoYSWxzVpZev3J+bUHXfr55L8Mox7AaNo6g==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.1.tgz", + "integrity": "sha512-+ahUAE+iheqBTDxXhTisdA8hgvbEG1hHOQ9xmNjeUJSoi6DU/gMrKNcfZjHkyY6Alnuyc+ikYJaxxfHkT3+WuQ==", "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -12403,7 +12405,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/thunky": { "version": "1.1.0", @@ -12423,7 +12425,7 @@ "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "engines": { "node": ">=4" } @@ -12466,12 +12468,12 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==" }, "node_modules/trim-trailing-lines": { "version": "1.1.4", @@ -12492,9 +12494,9 @@ } }, "node_modules/ts-node": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.0.tgz", - "integrity": "sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==", + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", + "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -12546,9 +12548,9 @@ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/type-fest": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.0.tgz", - "integrity": "sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.1.tgz", + "integrity": "sha512-hXYyrPFwETT2swFLHeoKtJrvSF/ftG/sA15/8nGaLuaDGfVAaq8DYFpu4yOyV4tzp082WqnTEoMsm3flKMI2FQ==", "engines": { "node": ">=12.20" }, @@ -12596,9 +12598,9 @@ } }, "node_modules/typescript": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", - "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", + "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -12896,7 +12898,7 @@ "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } @@ -13097,7 +13099,7 @@ "node_modules/url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "dependencies": { "prepend-http": "^2.0.0" }, @@ -13145,12 +13147,12 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "node_modules/utility-types": { "version": "3.10.0", @@ -13163,7 +13165,7 @@ "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } @@ -13190,7 +13192,7 @@ "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } @@ -13295,7 +13297,7 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { "version": "5.73.0", @@ -13472,14 +13474,15 @@ } }, "node_modules/webpack-dev-server": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.1.tgz", - "integrity": "sha512-CTMfu2UMdR/4OOZVHRpdy84pNopOuigVIsRbGX3LVDMWNP8EUgC5mUBMErbwBlHTEX99ejZJpVqrir6EXAEajA==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz", + "integrity": "sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q==", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", "@types/express": "^4.17.13", "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", "@types/ws": "^8.5.1", "ansi-html-community": "^0.0.8", @@ -13570,9 +13573,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", - "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", + "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", "engines": { "node": ">=10.0.0" }, @@ -13691,7 +13694,7 @@ "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -13785,7 +13788,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -14055,14 +14058,14 @@ } }, "@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==" + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz", + "integrity": "sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==" }, "@babel/core": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", - "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz", + "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==", "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", @@ -14070,10 +14073,10 @@ "@babel/helper-compilation-targets": "^7.18.2", "@babel/helper-module-transforms": "^7.18.0", "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.0", + "@babel/parser": "^7.18.5", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2", + "@babel/traverse": "^7.18.5", + "@babel/types": "^7.18.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -14403,9 +14406,9 @@ } }, "@babel/parser": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==" + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", + "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.17.12", @@ -14851,9 +14854,9 @@ } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.4.tgz", - "integrity": "sha512-lH2UaQaHVOAeYrUUuZ8i38o76J/FnO8vu21OE+tD1MyP9lxdZoSfz+pDbWkq46GogUrdrMz3tiz/FYGB+bVThg==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.5.tgz", + "integrity": "sha512-SEewrhPpcqMF1V7DhnEbhVJLrC+nnYfe1E0piZMZXBpxi9WvZqWGwpsk7JYP7wPWeqaBh4gyKlBhHJu3uz5g4Q==", "requires": { "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-module-transforms": "^7.18.0", @@ -14881,9 +14884,9 @@ } }, "@babel/plugin-transform-new-target": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.17.12.tgz", - "integrity": "sha512-CaOtzk2fDYisbjAD4Sd1MTKGVIpRtx9bWLyj24Y/k6p4s4gQ3CqDGJauFJxt8M/LEx003d0i3klVqnN73qvK3w==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.5.tgz", + "integrity": "sha512-TuRL5uGW4KXU6OsRj+mLp9BM7pO8e7SGNTEokQRRxHFkXYMFiy2jlKSZPFtI/mKORDzciH+hneskcSOp0gU8hg==", "requires": { "@babel/helper-plugin-utils": "^7.17.12" } @@ -14976,9 +14979,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.2.tgz", - "integrity": "sha512-mr1ufuRMfS52ttq+1G1PD8OJNqgcTFjq3hwn8SZ5n1x1pBhi0E36rYMdTK0TsKtApJ4lDEdfXJwtGobQMHSMPg==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.5.tgz", + "integrity": "sha512-Q17hHxXr2fplrE+5BSC1j1Fo5cOA8YeP8XW3/1paI8MzF/faZGh0MaH1KC4jLAvqLPamQWHB5/B7KqSLY1kuHA==", "requires": { "@babel/helper-module-imports": "^7.16.7", "@babel/helper-plugin-utils": "^7.17.12", @@ -15215,9 +15218,9 @@ } }, "@babel/traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", - "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", + "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", "requires": { "@babel/code-frame": "^7.16.7", "@babel/generator": "^7.18.2", @@ -15225,8 +15228,8 @@ "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.2", + "@babel/parser": "^7.18.5", + "@babel/types": "^7.18.4", "debug": "^4.1.0", "globals": "^11.1.0" } @@ -15811,7 +15814,6 @@ }, "@kiwicopple/prism-react-renderer": { "version": "git+ssh://git@github.com/kiwicopple/prism-react-renderer.git#4a09100a587bce2d94d7ac8ed3564a61c6e70781", - "integrity": "sha512-QluokmJkMoHOwahIBN34hTG5n03kFyJ0REDq4mkf0o05JUC61ikXQsPNXtynASqoZRW7A+bKVNT65kCtUfgZlQ==", "from": "@kiwicopple/prism-react-renderer@https://github.com/kiwicopple/prism-react-renderer.git", "requires": { "prismjs": "^1.22.0" @@ -15887,7 +15889,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" } } }, @@ -15968,9 +15970,9 @@ } }, "@octokit/openapi-types": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", - "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.1.0.tgz", + "integrity": "sha512-kQzJh3ZUv3lDpi6M+uekMRHULvf9DlWoI1XgKN6nPeGDzkSgtkhVq1MMz3bFKQ6H6GbdC3ZqG/a6VzKhIx0VeA==" }, "@octokit/request": { "version": "5.6.3", @@ -15996,11 +15998,11 @@ } }, "@octokit/types": { - "version": "6.34.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", - "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "version": "6.35.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.35.0.tgz", + "integrity": "sha512-DhLfdUuv3H37u6jBDfkwamypx3HflHg29b26nbA6iVFYkAlZ5cMEtu/9pQoihGnQE5M7jJFnNo25Rr1UwQNF8Q==", "requires": { - "@octokit/openapi-types": "^11.2.0" + "@octokit/openapi-types": "^12.1.0" } }, "@polka/url": { @@ -16173,27 +16175,27 @@ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" }, "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "@types/body-parser": { @@ -16231,9 +16233,9 @@ } }, "@types/eslint": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", - "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", + "version": "8.4.3", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.3.tgz", + "integrity": "sha512-YP1S7YJRMPs+7KZKDb9G63n8YejIwW9BALq7a5j2+H4yl6iOv9CB29edho+cuFRrvmJbbaH2yiVChKLJVysDGw==", "requires": { "@types/estree": "*", "@types/json-schema": "*" @@ -16265,9 +16267,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "version": "4.17.29", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", + "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -16319,9 +16321,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "@types/node": { - "version": "14.18.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.20.tgz", - "integrity": "sha512-Q8KKwm9YqEmUBRsqJ2GWJDtXltBDxTdC4m5vTdXBolu2PeQh8LX+f6BTwU+OuXPu37fLxoN6gidqBmnky36FXA==" + "version": "14.18.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.21.tgz", + "integrity": "sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q==" }, "@types/parse-json": { "version": "4.0.0", @@ -16349,9 +16351,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/react": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.45.tgz", - "integrity": "sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg==", + "version": "17.0.46", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.46.tgz", + "integrity": "sha512-zNAJVEO9dBEQLPa/OuedGfx92/UlD+1rNxSv2qVWUQZ+orEtLUWFgZ08xfyI9TAZLnmWzZDtssAsgtbXT7Ew0g==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -16703,9 +16705,9 @@ } }, "algoliasearch-helper": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.8.2.tgz", - "integrity": "sha512-AXxiF0zT9oYwl8ZBgU/eRXvfYhz7cBA5YrLPlw9inZHdaYF0QEya/f1Zp1mPYMXc1v6VkHwBq4pk6/vayBLICg==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.8.3.tgz", + "integrity": "sha512-J0H08fQoyhZ2qLi7Uy8EvUeN/NJ4Trtt7NWB8mF1CGLuYpdXPyjZu9+Uoya2eayxQ20RP+QGF9Om/LddPv49vw==", "requires": { "@algolia/events": "^4.0.1" } @@ -16763,9 +16765,9 @@ } }, "arg": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.1.tgz", - "integrity": "sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "argparse": { "version": "1.0.10", @@ -16788,7 +16790,7 @@ "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "at-least-node": { "version": "1.0.0", @@ -16923,12 +16925,12 @@ "base16": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", - "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=" + "integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==" }, "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, "before-after-hook": { "version": "2.2.2", @@ -16993,20 +16995,20 @@ } }, "bonjour-service": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.12.tgz", - "integrity": "sha512-pMmguXYCu63Ug37DluMKEHdxc+aaIf/ay4YbF8Gxtba+9d3u+rmEWy61VK3Z3hp8Rskok3BunHYnG0dUHAsblw==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.13.tgz", + "integrity": "sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA==", "requires": { "array-flatten": "^2.1.2", "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.4" + "multicast-dns": "^7.2.5" } }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "boxen": { "version": "6.2.1", @@ -17041,14 +17043,14 @@ } }, "browserslist": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", - "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "version": "4.20.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", + "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", "requires": { - "caniuse-lite": "^1.0.30001332", - "electron-to-chromium": "^1.4.118", + "caniuse-lite": "^1.0.30001349", + "electron-to-chromium": "^1.4.147", "escalade": "^3.1.1", - "node-releases": "^2.0.3", + "node-releases": "^2.0.5", "picocolors": "^1.0.0" } }, @@ -17141,9 +17143,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001346", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001346.tgz", - "integrity": "sha512-q6ibZUO2t88QCIPayP/euuDREq+aMAxFE5S70PkrLh0iTDj/zEhgvJRKC2+CvXY6EWc6oQwUR48lL5vCW6jiXQ==" + "version": "1.0.30001355", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001355.tgz", + "integrity": "sha512-Sd6pjJHF27LzCB7pT7qs+kuX2ndurzCzkpJl6Qct7LPSZ9jn0bkOA8mdgMgmqnQAWLVOOGjLpc+66V57eLtb1g==" }, "ccount": { "version": "1.1.0", @@ -17294,7 +17296,7 @@ "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", "requires": { "mimic-response": "^1.0.0" } @@ -17328,9 +17330,9 @@ "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==" }, "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "combine-promises": { "version": "1.1.0", @@ -17350,7 +17352,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "compressible": { "version": "2.0.18", @@ -17392,14 +17394,14 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "configstore": { "version": "5.0.1", @@ -17450,7 +17452,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "copy-text-to-clipboard": { "version": "3.0.1", @@ -17498,9 +17500,9 @@ } }, "globby": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.1.tgz", - "integrity": "sha512-XMzoDZbGZ37tufiv7g0N4F/zp3zkwdFtVbV3EHsVl1KQr4RPLfNoT068/97RPshz2J5xYNEjLKKBKaGHifBd3Q==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", "requires": { "dir-glob": "^3.0.1", "fast-glob": "^3.2.11", @@ -17533,16 +17535,16 @@ } }, "core-js": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz", - "integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==" + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.1.tgz", + "integrity": "sha512-wfMYHWi1WQjpgZNC9kAlN4ut04TM9fUTdi7CqIoTVM7yaiOUQTklOzfb+oWH3r9edQcT3F887swuVmxrV+CC8w==" }, "core-js-compat": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.8.tgz", - "integrity": "sha512-pQnwg4xtuvc2Bs/5zYQPaEYYSuTxsF7LBWF0SvnVhthZo/Qe+rJpcEekrdNK5DWwDJ0gv0oI9NNX5Mppdy0ctg==", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.1.tgz", + "integrity": "sha512-KeYrEc8t6FJsKYB2qnDwRHWaC0cJNaqlHfCpMe5q3j/W1nje3moib/txNklddLPCtGb+etcBIyJ8zuMa/LN5/A==", "requires": { - "browserslist": "^4.20.3", + "browserslist": "^4.20.4", "semver": "7.0.0" }, "dependencies": { @@ -17554,9 +17556,9 @@ } }, "core-js-pure": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.8.tgz", - "integrity": "sha512-bOxbZIy9S5n4OVH63XaLVXZ49QKicjowDx/UELyJ68vxfCRpYsbyh/WNZNfEfAk+ekA8vSjt+gCDpvh672bc3w==" + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.1.tgz", + "integrity": "sha512-3qNgf6TqI3U1uhuSYRzJZGfFd4T+YlbyVPl+jgRiKjdZopvG4keZQwWZDAWpu1UH9nCgTpUzIV3GFawC7cJsqg==" }, "core-util-is": { "version": "1.0.3", @@ -17605,9 +17607,9 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" }, "css-declaration-sorter": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz", - "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz", + "integrity": "sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og==", "requires": {} }, "css-loader": { @@ -17678,7 +17680,7 @@ "css-modules-require-hook": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/css-modules-require-hook/-/css-modules-require-hook-4.2.3.tgz", - "integrity": "sha1-Z5LKQSsV4j5vm+agfc739Xf/kE0=", + "integrity": "sha512-y3eGHAqmDl8JQdr1LYTwBkMxy7CSHCMy9YwpSjDqtGqCCEy9lKq/x/nmHVs+G7C1+xXmyIXjRu0q/MMn8w01mg==", "dev": true, "requires": { "debug": "^2.2.0", @@ -17727,7 +17729,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "debug": { @@ -17742,19 +17744,19 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "icss-utils": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-3.0.1.tgz", - "integrity": "sha1-7nDTroysOMa+XtkehRsn7tNDrQ8=", + "integrity": "sha512-ANhVLoEfe0KoC9+z4yiTaXOneB49K6JIXdS+yAgH0NERELpdIT7kkj2XxUPuHafeHnn8umXnECSpsfk1RTaUew==", "dev": true, "requires": { "postcss": "^6.0.2" @@ -17763,7 +17765,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "postcss": { @@ -17880,22 +17882,22 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, "cssnano": { - "version": "5.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.10.tgz", - "integrity": "sha512-ACpnRgDg4m6CZD/+8SgnLcGCgy6DDGdkMbOawwdvVxNietTNLe/MtWcenp6qT0PRt5wzhGl6/cjMWCdhKXC9QA==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.11.tgz", + "integrity": "sha512-2nx+O6LvewPo5EBtYrKc8762mMkZRk9cMGIOP4UlkmxHm7ObxH+zvsJJ+qLwPkUc4/yumL/qJkavYi9NlodWIQ==", "requires": { - "cssnano-preset-default": "^5.2.10", + "cssnano-preset-default": "^5.2.11", "lilconfig": "^2.0.3", "yaml": "^1.10.2" } }, "cssnano-preset-advanced": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.6.tgz", - "integrity": "sha512-OZHsytu16eStRVrIY3wmPQqhJMaI0+O3raU4JHoKV3uuQYEeQek/FJVUIvYXD55hWR6OjCMyKYNRDw+k3/xgUw==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.7.tgz", + "integrity": "sha512-VNOdTMRA60KhaURZhnkTGeluHQBHWDMwY7TIDu1Qydf88X6k8xZbV2I+Wlm8JRaj2oi18xvoIOAW17JneoZzEg==", "requires": { "autoprefixer": "^10.3.7", - "cssnano-preset-default": "^5.2.10", + "cssnano-preset-default": "^5.2.11", "postcss-discard-unused": "^5.1.0", "postcss-merge-idents": "^5.1.1", "postcss-reduce-idents": "^5.2.0", @@ -17903,9 +17905,9 @@ } }, "cssnano-preset-default": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.10.tgz", - "integrity": "sha512-H8TJRhTjBKVOPltp9vr9El9I+IfYsOMhmXdK0LwdvwJcxYX9oWkY7ctacWusgPWAgQq1vt/WO8v+uqpfLnM7QA==", + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.11.tgz", + "integrity": "sha512-4PadR1NtuaIK8MvLNuY7MznK4WJteldGlzCiMaaTiOUP+apeiIvUDIXykzUOoqgOOUAHrU64ncdD90NfZR3LSQ==", "requires": { "css-declaration-sorter": "^6.2.2", "cssnano-utils": "^3.1.0", @@ -17931,7 +17933,7 @@ "postcss-normalize-unicode": "^5.1.0", "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.1", + "postcss-ordered-values": "^5.1.2", "postcss-reduce-initial": "^5.1.0", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", @@ -18537,7 +18539,7 @@ "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "requires": { "mimic-response": "^1.0.0" } @@ -18650,7 +18652,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -18674,7 +18676,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -18695,12 +18697,12 @@ "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" }, "dns-packet": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz", - "integrity": "sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", + "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", "requires": { "@leichtgewicht/ip-codec": "^2.0.1" } @@ -18812,7 +18814,7 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "integrity": "sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==" }, "eastasianwidth": { "version": "0.2.0", @@ -18822,12 +18824,12 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.144", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.144.tgz", - "integrity": "sha512-R3RV3rU1xWwFJlSClVWDvARaOk6VUO/FubHLodIASDB3Mc2dzuWvNdfOgH9bwHUTqT79u92qw60NWfwUdzAqdg==" + "version": "1.4.158", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz", + "integrity": "sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ==" }, "emoji-regex": { "version": "9.2.2", @@ -18847,7 +18849,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", @@ -18897,7 +18899,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "4.0.0", @@ -18951,7 +18953,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "eval": { "version": "0.1.8", @@ -18998,7 +19000,7 @@ "exenv": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", - "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" }, "express": { "version": "4.18.1", @@ -19089,7 +19091,7 @@ "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "requires": { "is-extendable": "^0.1.0" } @@ -19119,7 +19121,7 @@ "fast-url-parser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", "requires": { "punycode": "^1.3.2" } @@ -19350,7 +19352,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "fs-extra": { "version": "10.1.0", @@ -19370,7 +19372,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -19386,7 +19388,7 @@ "generic-names": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-1.0.3.tgz", - "integrity": "sha1-LXhqEhruUIh2eWk56OO/+DbCCRc=", + "integrity": "sha512-b6OHfQuKasIKM9b6YPkX+KUj/TLBTx3B/1aT1T5F12FEuEqyFMdr59OMS53aoaSw8eVtapdqieX6lbg5opaOhA==", "dev": true, "requires": { "loader-utils": "^0.2.16" @@ -19401,19 +19403,19 @@ "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", "dev": true }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", "dev": true }, "loader-utils": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "integrity": "sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==", "dev": true, "requires": { "big.js": "^3.1.3", @@ -19430,13 +19432,13 @@ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, "get-own-enumerable-property-symbols": { @@ -19481,7 +19483,7 @@ "glob-to-regexp": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", "dev": true }, "global-dirs": { @@ -19740,7 +19742,7 @@ "hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "requires": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -19851,7 +19853,7 @@ "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" }, "http-errors": { "version": "2.0.0", @@ -19915,7 +19917,7 @@ "icss-replace-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", "dev": true }, "icss-utils": { @@ -19938,9 +19940,9 @@ } }, "immer": { - "version": "9.0.14", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz", - "integrity": "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw==" + "version": "9.0.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", + "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==" }, "import-fresh": { "version": "3.3.0", @@ -19954,12 +19956,12 @@ "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==" }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" }, "indent-string": { "version": "4.0.0", @@ -19974,7 +19976,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -20035,7 +20037,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-binary-path": { "version": "2.1.0", @@ -20079,12 +20081,12 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -20126,7 +20128,7 @@ "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" }, "is-path-cwd": { "version": "2.2.0", @@ -20151,7 +20153,7 @@ "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" }, "is-root": { "version": "2.1.0", @@ -20166,7 +20168,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "is-whitespace-character": { "version": "1.0.4", @@ -20199,12 +20201,12 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "jest-worker": { "version": "27.5.1", @@ -20260,7 +20262,7 @@ "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -20287,9 +20289,9 @@ } }, "jsrsasign": { - "version": "10.5.23", - "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.5.23.tgz", - "integrity": "sha512-e3hy//LH8EbRhzqyHJuf3pbehxYcnUZgGUjQKKTukWJ1M5uQTZBgFvItRK5ik8pixpYDAKY6xj527cEa1NQGPg==" + "version": "10.5.24", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.5.24.tgz", + "integrity": "sha512-0i/UHRgJZifp/YmoXHyNQXUY4eKWiSd7YxuD7oKEw9mlqgr51hg9lZQw2nlEDvwHDh7pyj6ZjYlxldlW27xb/Q==" }, "keyv": { "version": "3.1.0", @@ -20373,27 +20375,27 @@ "lodash.curry": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", - "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA=" + "integrity": "sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==" }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "lodash.flow": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", - "integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=" + "integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==" }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, "loglevel": { "version": "1.8.0", @@ -20499,12 +20501,12 @@ "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memfs": { "version": "3.4.4", @@ -20517,7 +20519,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge-stream": { "version": "2.0.0", @@ -20548,7 +20550,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromatch": { "version": "4.0.5", @@ -20597,9 +20599,9 @@ } }, "mini-css-extract-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", - "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", + "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", "requires": { "schema-utils": "^4.0.0" }, @@ -20674,9 +20676,9 @@ "integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ==" }, "mrmime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", - "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==" }, "ms": { "version": "2.1.2", @@ -20750,7 +20752,7 @@ "normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" }, "normalize-url": { "version": "6.1.0", @@ -20768,7 +20770,7 @@ "nprogress": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E=" + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" }, "nth-check": { "version": "2.1.1", @@ -20781,7 +20783,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.12.2", @@ -20825,7 +20827,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -21345,9 +21347,9 @@ } }, "postcss-ordered-values": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.1.tgz", - "integrity": "sha512-7lxgXF0NaoMIgyihL/2boNAEZKiW0+HkMhdKMTD93CjW8TdCy2hSdj8lsAo+uwm7EDG16Da2Jdmtqpedl0cMfw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.2.tgz", + "integrity": "sha512-wr2avRbW4HS2XE2ZCqpfp4N/tDC6GZKZ+SVP8UBTOVS8QWrc4TD8MYrebJrvVVlGPKszmiSCzue43NDiVtgDmg==", "requires": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" @@ -21610,7 +21612,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" } } }, @@ -21626,7 +21628,7 @@ "react-base16-styling": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.6.0.tgz", - "integrity": "sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=", + "integrity": "sha512-yvh/7CArceR/jNATXOKDlvTnPKPmGZz7zsenQ3jUwLzHkNUR0CvY3yGYJbWJ/nnxsL8Sgmt5cO3/SILVuPO6TQ==", "requires": { "base16": "^1.0.0", "lodash.curry": "^4.0.1", @@ -21864,7 +21866,7 @@ "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "requires": { "resolve": "^1.1.6" } @@ -21927,11 +21929,11 @@ } }, "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", + "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", "requires": { - "rc": "^1.2.8" + "rc": "1.2.8" } }, "registry-url": { @@ -22005,7 +22007,7 @@ "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" }, "remark-admonitions": { "version": "1.2.1", @@ -22115,7 +22117,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" } } }, @@ -22223,7 +22225,7 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" }, "require-from-string": { "version": "2.0.2", @@ -22233,12 +22235,12 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=" + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==" }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "resolve": { "version": "1.22.0", @@ -22263,7 +22265,7 @@ "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", "requires": { "lowercase-keys": "^1.0.0" } @@ -22353,7 +22355,7 @@ "rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "rxjs": { "version": "7.5.5", @@ -22409,13 +22411,13 @@ "seekout": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/seekout/-/seekout-1.0.2.tgz", - "integrity": "sha1-CbqfG9W0b7sTRxjrGaaDgsuxuck=", + "integrity": "sha512-eB4fRqHZCE8gmwFOVHC9tHzLkZJ2Y12qJvAJQox8kWjGObA++tgVeXHACsDCPajfNGnDaK2Juv+WzNlMuO43wQ==", "dev": true }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" }, "selfsigned": { "version": "2.0.1", @@ -22536,7 +22538,7 @@ "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "requires": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -22563,7 +22565,7 @@ "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "requires": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -22574,12 +22576,12 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "setprototypeof": { "version": "1.1.0", @@ -22589,7 +22591,7 @@ "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" } } }, @@ -22607,7 +22609,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "setprototypeof": { "version": "1.2.0", @@ -22697,9 +22699,9 @@ }, "dependencies": { "@types/node": { - "version": "17.0.38", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.38.tgz", - "integrity": "sha512-5jY9RhV7c0Z4Jy09G+NIDTsCZ5G0L5n+Z+p+Y7t5VJHM30bgwzSjVtlcBxqAj+6L/swIlvtOSzr8rBk/aNyV2g==" + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" } } }, @@ -22775,7 +22777,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "stable": { "version": "0.1.8", @@ -22858,7 +22860,7 @@ "strip-bom-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=" + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==" }, "strip-final-newline": { "version": "2.0.0", @@ -22982,9 +22984,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "terser": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.0.tgz", - "integrity": "sha512-JC6qfIEkPBd9j1SMO3Pfn+A6w2kQV54tv+ABQLgZr7dA3k/DL/OBoYSWxzVpZev3J+bUHXfr55L8Mox7AaNo6g==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.1.tgz", + "integrity": "sha512-+ahUAE+iheqBTDxXhTisdA8hgvbEG1hHOQ9xmNjeUJSoi6DU/gMrKNcfZjHkyY6Alnuyc+ikYJaxxfHkT3+WuQ==", "requires": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -23026,7 +23028,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "thunky": { "version": "1.1.0", @@ -23046,7 +23048,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "to-readable-stream": { "version": "1.0.0", @@ -23074,12 +23076,12 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==" }, "trim-trailing-lines": { "version": "1.1.4", @@ -23092,9 +23094,9 @@ "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" }, "ts-node": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.0.tgz", - "integrity": "sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==", + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", + "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", @@ -23126,9 +23128,9 @@ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "type-fest": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.0.tgz", - "integrity": "sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==" + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.1.tgz", + "integrity": "sha512-hXYyrPFwETT2swFLHeoKtJrvSF/ftG/sA15/8nGaLuaDGfVAaq8DYFpu4yOyV4tzp082WqnTEoMsm3flKMI2FQ==" }, "type-is": { "version": "1.6.18", @@ -23163,9 +23165,9 @@ } }, "typescript": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", - "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==" + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", + "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==" }, "typesense": { "version": "1.3.0", @@ -23370,7 +23372,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "update-notifier": { "version": "5.1.0", @@ -23506,7 +23508,7 @@ "url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "requires": { "prepend-http": "^2.0.0" } @@ -23534,12 +23536,12 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "utility-types": { "version": "3.10.0", @@ -23549,7 +23551,7 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "8.3.2", @@ -23570,7 +23572,7 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "vfile": { "version": "4.2.1", @@ -23651,7 +23653,7 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "webpack": { "version": "5.73.0", @@ -23805,14 +23807,15 @@ } }, "webpack-dev-server": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.1.tgz", - "integrity": "sha512-CTMfu2UMdR/4OOZVHRpdy84pNopOuigVIsRbGX3LVDMWNP8EUgC5mUBMErbwBlHTEX99ejZJpVqrir6EXAEajA==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz", + "integrity": "sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q==", "requires": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", "@types/express": "^4.17.13", "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", "@types/ws": "^8.5.1", "ansi-html-community": "^0.0.8", @@ -23875,9 +23878,9 @@ } }, "ws": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", - "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", + "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", "requires": {} } } @@ -23925,7 +23928,7 @@ "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -23985,7 +23988,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "3.0.3", diff --git a/web/package.json b/web/package.json index c884e546384..0be0daeb3b1 100644 --- a/web/package.json +++ b/web/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "serve": "npm run start", - "start": "docusaurus start --port 3005", + "start": "docusaurus start --port 3006", "build": "npm run gen:all && docusaurus build", "swizzle": "docusaurus swizzle", "traction": "node traction.js", diff --git a/web/sidebars.js b/web/sidebars.js index d5e260d46eb..ffadeda625e 100755 --- a/web/sidebars.js +++ b/web/sidebars.js @@ -36,6 +36,12 @@ module.exports = { collapsed: false, items: supabaseCli.docs, }, + { + type: 'category', + label: 'Tools', + collapsed: false, + items: ['reference/tools/reference-auth'], + }, ], docs: [ { @@ -185,7 +191,13 @@ module.exports = { type: 'category', label: 'Platform', collapsed: false, - items: ['guides/platform/logs', 'guides/platform/metrics', 'going-into-prod', 'guides/platform/performance', 'guides/platform/permissions'], + items: [ + 'guides/platform/logs', + 'guides/platform/metrics', + 'going-into-prod', + 'guides/platform/performance', + 'guides/platform/permissions' + ], }, { type: 'category',