diff --git a/dataconnect/.firebaserc b/dataconnect/.firebaserc index 89a1108c..6def5060 100644 --- a/dataconnect/.firebaserc +++ b/dataconnect/.firebaserc @@ -1,12 +1,7 @@ { "projects": { - "default": "FIREBASE_PROJECT_ID_HERE" + "default": null }, "targets": {}, - "etags": {}, - "dataconnectEmulatorConfig": { - "postgres": { - "localConnectionString": "postgresql://user:mypassword@localhost:5432/dataconnect?sslmode=disable" - } - } + "etags": {} } diff --git a/dataconnect/README.md b/dataconnect/README.md index aeceda69..eec07d80 100644 --- a/dataconnect/README.md +++ b/dataconnect/README.md @@ -1,5 +1,5 @@ # Firebase Data Connect - + Try in IDX diff --git a/dataconnect/flutter-blank/.gitignore b/dataconnect/flutter-blank/.gitignore new file mode 100644 index 00000000..29a3a501 --- /dev/null +++ b/dataconnect/flutter-blank/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# 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 +.pub-cache/ +.pub/ +/build/ + +# 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/dataconnect/flutter-blank/.metadata b/dataconnect/flutter-blank/.metadata new file mode 100644 index 00000000..90eabcff --- /dev/null +++ b/dataconnect/flutter-blank/.metadata @@ -0,0 +1,45 @@ +# 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: "80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + - platform: android + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + - platform: ios + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + - platform: linux + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + - platform: macos + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + - platform: web + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + - platform: windows + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/dataconnect/flutter-blank/analysis_options.yaml b/dataconnect/flutter-blank/analysis_options.yaml new file mode 100644 index 00000000..0d290213 --- /dev/null +++ b/dataconnect/flutter-blank/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/dataconnect/flutter-blank/android/.gitignore b/dataconnect/flutter-blank/android/.gitignore new file mode 100644 index 00000000..55afd919 --- /dev/null +++ b/dataconnect/flutter-blank/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/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/dataconnect/flutter-blank/android/app/build.gradle b/dataconnect/flutter-blank/android/app/build.gradle new file mode 100644 index 00000000..309ddf75 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/build.gradle @@ -0,0 +1,63 @@ +plugins { + id "com.android.application" + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + +def localProperties = new Properties() +def localPropertiesFile = rootProject.file("local.properties") +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader("UTF-8") { reader -> + localProperties.load(reader) + } +} + +def flutterVersionCode = localProperties.getProperty("flutter.versionCode") +if (flutterVersionCode == null) { + flutterVersionCode = "1" +} + +def flutterVersionName = localProperties.getProperty("flutter.versionName") +if (flutterVersionName == null) { + flutterVersionName = "1.0" +} + + +android { + namespace = "com.example.blank" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8 + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.blank" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = 23 + targetSdk = 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 = "../.." +} diff --git a/dataconnect/flutter-blank/android/app/src/debug/AndroidManifest.xml b/dataconnect/flutter-blank/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..399f6981 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/dataconnect/flutter-blank/android/app/src/main/AndroidManifest.xml b/dataconnect/flutter-blank/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..b79e6209 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/dataconnect/flutter-blank/android/app/src/main/kotlin/com/example/blank/MainActivity.kt b/dataconnect/flutter-blank/android/app/src/main/kotlin/com/example/blank/MainActivity.kt new file mode 100644 index 00000000..06a2fff7 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/src/main/kotlin/com/example/blank/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.blank + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() diff --git a/dataconnect/flutter-blank/android/app/src/main/res/drawable-v21/launch_background.xml b/dataconnect/flutter-blank/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 00000000..f74085f3 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/dataconnect/flutter-blank/android/app/src/main/res/drawable/launch_background.xml b/dataconnect/flutter-blank/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/dataconnect/flutter-blank/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-blank/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/dataconnect/flutter-blank/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-blank/android/app/src/main/res/values-night/styles.xml b/dataconnect/flutter-blank/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 00000000..06952be7 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/dataconnect/flutter-blank/android/app/src/main/res/values/styles.xml b/dataconnect/flutter-blank/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..cb1ef880 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/dataconnect/flutter-blank/android/app/src/profile/AndroidManifest.xml b/dataconnect/flutter-blank/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..399f6981 --- /dev/null +++ b/dataconnect/flutter-blank/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/dataconnect/flutter-blank/android/build.gradle b/dataconnect/flutter-blank/android/build.gradle new file mode 100644 index 00000000..d2ffbffa --- /dev/null +++ b/dataconnect/flutter-blank/android/build.gradle @@ -0,0 +1,18 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = "../build" +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/dataconnect/flutter-blank/android/gradle.properties b/dataconnect/flutter-blank/android/gradle.properties new file mode 100644 index 00000000..25971708 --- /dev/null +++ b/dataconnect/flutter-blank/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/dataconnect/flutter-blank/android/gradle/wrapper/gradle-wrapper.properties b/dataconnect/flutter-blank/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..e1ca574e --- /dev/null +++ b/dataconnect/flutter-blank/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip diff --git a/dataconnect/flutter-blank/android/settings.gradle b/dataconnect/flutter-blank/android/settings.gradle new file mode 100644 index 00000000..536165d3 --- /dev/null +++ b/dataconnect/flutter-blank/android/settings.gradle @@ -0,0 +1,25 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.3.0" apply false + id "org.jetbrains.kotlin.android" version "1.7.10" apply false +} + +include ":app" diff --git a/dataconnect/nextjs-blank/dataconnect/connector/connector.yaml b/dataconnect/flutter-blank/dataconnect/connector/connector.yaml similarity index 76% rename from dataconnect/nextjs-blank/dataconnect/connector/connector.yaml rename to dataconnect/flutter-blank/dataconnect/connector/connector.yaml index 8cf696c4..f2dcf8ab 100644 --- a/dataconnect/nextjs-blank/dataconnect/connector/connector.yaml +++ b/dataconnect/flutter-blank/dataconnect/connector/connector.yaml @@ -10,11 +10,9 @@ generate: # kotlinSdk: # outputDir: # package: connectors.default - javascriptSdk: + dartSdk: # Create a custom package name for your generated SDK - package: "@blank/generated" + package: "blank_package" # Tells Data Connect where to store the generated SDK code, this should be in the same # directory as your app code - outputDir: "../../webapp/dataconnect-generated" - # This property tells Data Connect what directory to install the generated SDK to - packageJsonDir: "../../webapp" + outputDir: "../../lib/generated" diff --git a/dataconnect/nextjs-blank/dataconnect/connector/mutations.gql b/dataconnect/flutter-blank/dataconnect/connector/mutations.gql similarity index 100% rename from dataconnect/nextjs-blank/dataconnect/connector/mutations.gql rename to dataconnect/flutter-blank/dataconnect/connector/mutations.gql diff --git a/dataconnect/nextjs-blank/dataconnect/connector/queries.gql b/dataconnect/flutter-blank/dataconnect/connector/queries.gql similarity index 100% rename from dataconnect/nextjs-blank/dataconnect/connector/queries.gql rename to dataconnect/flutter-blank/dataconnect/connector/queries.gql diff --git a/dataconnect/nextjs-blank/dataconnect/dataconnect.yaml b/dataconnect/flutter-blank/dataconnect/dataconnect.yaml similarity index 100% rename from dataconnect/nextjs-blank/dataconnect/dataconnect.yaml rename to dataconnect/flutter-blank/dataconnect/dataconnect.yaml diff --git a/dataconnect/nextjs-blank/dataconnect/schema/schema.gql b/dataconnect/flutter-blank/dataconnect/schema/schema.gql similarity index 100% rename from dataconnect/nextjs-blank/dataconnect/schema/schema.gql rename to dataconnect/flutter-blank/dataconnect/schema/schema.gql diff --git a/dataconnect/flutter-blank/dev.nix b/dataconnect/flutter-blank/dev.nix new file mode 100644 index 00000000..064d6520 --- /dev/null +++ b/dataconnect/flutter-blank/dev.nix @@ -0,0 +1,73 @@ +# To learn more about how to use Nix to configure your environment +# see: https://developers.google.com/idx/guides/customize-idx-env +{ pkgs, ... }: { + processes = { + writeEnv = { + command = "echo \"HOST=$WEB_HOST\" > .env"; + }; + }; + + # Which nixpkgs channel to use. + channel = "stable-24.05"; # or "unstable" + + + # Use https://search.nixos.org/packages to find packages + packages = [ + pkgs.nodejs_20 + (pkgs.postgresql_15.withPackages (p: [ p.pgvector ])) + pkgs.nodePackages.pnpm + pkgs.jdk17 + pkgs.unzip + pkgs.caddy + ]; + + # Sets environment variables in the workspace + env = { + POSTGRESQL_CONN_STRING = "postgresql://user:mypassword@localhost:5432/dataconnect?sslmode=disable"; + PATH = ["/home/user/.pub-cache/bin" "/home/user/flutter/bin" "./.flutter-sdk/flutter/bin"]; + }; + idx = { + # Search for the extensions you want on https://open-vsx.org/ and use "publisher.id" + extensions = [ + "mtxr.sqltools" + "Dart-Code.flutter" + "Dart-Code.dart-code" + "mtxr.sqltools-driver-pg" + "GraphQL.vscode-graphql-syntax" + "GoogleCloudTools.firebase-dataconnect-vscode" + ]; + + workspace = { + # Runs when a workspace is first created with this `dev.nix` file + onCreate = { + installSdk = '' + chmod +x ./installDeps.sh + ./installDeps.sh + ''; + }; + onStart = { + startProxy = '' + caddy run + ''; + }; + + # To run something each time the workspace is (re)started, use the `onStart` hook + }; + # set up a proxy that routes requests from $PORT in IDX to 9003, and any FDC-like queries are automatically rerouted to FDC + # Enable previews and customize configuration + previews = { + enable = true; + previews = { + web = { + command = ["flutter" "run" "--machine" "-d" "web-server" "--web-hostname" "0.0.0.0" "--web-port" "9003"]; + manager = "flutter"; + }; + android = { + command = ["flutter" "run" "--machine" "-d" "android" "-d" "localhost:5555"]; + manager = "flutter"; + }; + }; + }; + }; + +} \ No newline at end of file diff --git a/dataconnect/nextjs-email-app/firebase.json b/dataconnect/flutter-blank/firebase.json similarity index 90% rename from dataconnect/nextjs-email-app/firebase.json rename to dataconnect/flutter-blank/firebase.json index 861a21dc..57c62dd9 100644 --- a/dataconnect/nextjs-email-app/firebase.json +++ b/dataconnect/flutter-blank/firebase.json @@ -4,7 +4,7 @@ }, "emulators": { "dataconnect": { - "port": 9399 + "port": 9400 }, "ui": { "enabled": false diff --git a/dataconnect/flutter-blank/lib/firebase_options.dart b/dataconnect/flutter-blank/lib/firebase_options.dart new file mode 100644 index 00000000..9c664017 --- /dev/null +++ b/dataconnect/flutter-blank/lib/firebase_options.dart @@ -0,0 +1,57 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: type=lint +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.iOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } +} diff --git a/dataconnect/flutter-blank/lib/main.dart b/dataconnect/flutter-blank/lib/main.dart new file mode 100644 index 00000000..419aa3cb --- /dev/null +++ b/dataconnect/flutter-blank/lib/main.dart @@ -0,0 +1,210 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; + +import 'firebase_options.dart'; +import 'error_handler.dart'; +import 'package:blank/generated/blank.dart'; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + int port = 443; + String hostName = Uri.base.host; + if (!kIsWeb) { + hostName = '10.0.2.2'; + port = 9403; + } + try { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + MovieConnectorConnector.instance.dataConnect + .useDataConnectEmulator(hostName, port, isSecure: true); + runApp(const MyApp()); + } catch (_) { + runApp(const ShowError()); + } +} + +class ShowError extends StatelessWidget { + const ShowError({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Error', + theme: ThemeData( + // This is the theme of your application. + // + // TRY THIS: Try running your application with "flutter run". You'll see + // the application has a purple toolbar. Then, without quitting the app, + // try changing the seedColor in the colorScheme below to Colors.green + // and then invoke "hot reload" (save your changes or press the "hot + // reload" button in a Flutter-supported IDE, or press "r" if you used + // the command line to start the app). + // + // Notice that the counter didn't reset back to zero; the application + // state is not lost during the reload. To reset the state, use hot + // restart instead. + // + // This works for code too, not just values: Most code changes can be + // tested with just a hot reload. + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const Text( + "Run flutterfire configure to continue and refresh the page."), + ); + } +} + +class ErrorContent extends StatelessWidget { + const ErrorContent({super.key}); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + // TRY THIS: Try changing the color here to a specific color (to + // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar + // change color while the other colors stay the same. + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + // + // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" + // action in the IDE, or press "p" in the console), to see the + // wireframe for each widget. + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Text( + "Open the Firebase Data Connect Extension and click 'Start Emulators' to get started."), + ), + ], + ), + ), + ); + } +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + // This is the theme of your application. + // + // TRY THIS: Try running your application with "flutter run". You'll see + // the application has a purple toolbar. Then, without quitting the app, + // try changing the seedColor in the colorScheme below to Colors.green + // and then invoke "hot reload" (save your changes or press the "hot + // reload" button in a Flutter-supported IDE, or press "r" if you used + // the command line to start the app). + // + // Notice that the counter didn't reset back to zero; the application + // state is not lost during the reload. To reset the state, use hot + // restart instead. + // + // This works for code too, not just values: Most code changes can be + // tested with just a hot reload. + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // TRY THIS: Try changing the color here to a specific color (to + // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar + // change color while the other colors stay the same. + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + // + // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" + // action in the IDE, or press "p" in the console), to see the + // wireframe for each widget. + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Text( + "Open the Firebase Data Connect Extension and click 'Start Emulators' to get started."), + ), + ], + ), + ), + ); + } +} diff --git a/dataconnect/flutter-blank/package.json b/dataconnect/flutter-blank/package.json new file mode 100644 index 00000000..12b361ac --- /dev/null +++ b/dataconnect/flutter-blank/package.json @@ -0,0 +1,10 @@ +{ + "name": "@firebase/dart-sample", + "scripts": { + "start:proxy": "node proxy-web/proxy.js" + }, + "devDependencies": { + "express": "^4.19.2", + "http-proxy-middleware": "^3.0.0" + } +} diff --git a/dataconnect/flutter-blank/pnpm-lock.yaml b/dataconnect/flutter-blank/pnpm-lock.yaml new file mode 100644 index 00000000..5eb3e376 --- /dev/null +++ b/dataconnect/flutter-blank/pnpm-lock.yaml @@ -0,0 +1,697 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + express: + specifier: ^4.19.2 + version: 4.21.0 + http-proxy-middleware: + specifier: ^3.0.0 + version: 3.0.2 + +packages: + + '@types/http-proxy@1.17.15': + resolution: {integrity: sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==} + + '@types/node@22.7.4': + resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + express@4.21.0: + resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==} + engines: {node: '>= 0.10.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-proxy-middleware@3.0.2: + resolution: {integrity: sha512-fBLFpmvDzlxdckwZRjM0wWtwDZ4KBtQ8NFqhrFKoEtK4myzuiumBuNTxD+F4cVbXfOZljIbrynmvByofDzT7Ag==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-to-regexp@0.1.10: + resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + +snapshots: + + '@types/http-proxy@1.17.15': + dependencies: + '@types/node': 22.7.4 + + '@types/node@22.7.4': + dependencies: + undici-types: 6.19.8 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + array-flatten@1.1.1: {} + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + bytes@3.1.2: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.6: {} + + cookie@0.6.0: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + depd@2.0.0: {} + + destroy@1.2.0: {} + + ee-first@1.1.1: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + escape-html@1.0.3: {} + + etag@1.8.1: {} + + eventemitter3@4.0.7: {} + + express@4.21.0: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.6.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.10 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + follow-redirects@1.15.9(debug@4.3.7): + optionalDependencies: + debug: 4.3.7 + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + function-bind@1.1.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-proxy-middleware@3.0.2: + dependencies: + '@types/http-proxy': 1.17.15 + debug: 4.3.7 + http-proxy: 1.18.1(debug@4.3.7) + is-glob: 4.0.3 + is-plain-object: 5.0.0 + micromatch: 4.0.8 + transitivePeerDependencies: + - supports-color + + http-proxy@1.18.1(debug@4.3.7): + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.9(debug@4.3.7) + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-plain-object@5.0.0: {} + + media-typer@0.3.0: {} + + merge-descriptors@1.0.3: {} + + methods@1.1.2: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + negotiator@0.6.3: {} + + object-inspect@1.13.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + parseurl@1.3.3: {} + + path-to-regexp@0.1.10: {} + + picomatch@2.3.1: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + requires-port@1.0.0: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + statuses@2.0.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + undici-types@6.19.8: {} + + unpipe@1.0.0: {} + + utils-merge@1.0.1: {} + + vary@1.1.2: {} diff --git a/dataconnect/flutter-blank/proxy-web/package-lock.json b/dataconnect/flutter-blank/proxy-web/package-lock.json new file mode 100644 index 00000000..75c8f2a2 --- /dev/null +++ b/dataconnect/flutter-blank/proxy-web/package-lock.json @@ -0,0 +1,1131 @@ +{ + "name": "proxy-web", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "express": "^4.19.2", + "http-proxy-middleware": "^3.0.0", + "nodemon": "^3.1.4" + } + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.0.tgz", + "integrity": "sha512-36AV1fIaI2cWRzHo+rbcxhe3M3jUDCNzc4D5zRl57sEWRAxdXYtw7FSQKYY6PDKssiAKjLYypbssHk+xs/kMXw==", + "dependencies": { + "@types/http-proxy": "^1.17.10", + "debug": "^4.3.4", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", + "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/dataconnect/flutter-blank/proxy-web/proxy.js b/dataconnect/flutter-blank/proxy-web/proxy.js new file mode 100644 index 00000000..4ec6a4db --- /dev/null +++ b/dataconnect/flutter-blank/proxy-web/proxy.js @@ -0,0 +1,30 @@ +const express = require("express"); +const { createProxyMiddleware } = require("http-proxy-middleware"); + +const EXT_PORT = 9002; +const FLUTTER_PORT = 9003; +const DATACONNECT_PORT = 9400; +const app = express(); + +app.use( + createProxyMiddleware({ + target: `http://localhost:${FLUTTER_PORT}`, + router: { + [`/v1beta`]: `http://localhost:${DATACONNECT_PORT}`, // API on 8081 should support /api/* paths + }, + }) +); + +app.listen(EXT_PORT, () => { + console.log(` + ====Firebase Data Connect Proxy Server======== + ====Please DO NOT CLOSE======================= + `); + console.log( + "Proxy Server Listening on: " + + EXT_PORT + ); + console.log(` + ============================================== + `); +}); \ No newline at end of file diff --git a/dataconnect/flutter-blank/pubspec.lock b/dataconnect/flutter-blank/pubspec.lock new file mode 100644 index 00000000..9196d529 --- /dev/null +++ b/dataconnect/flutter-blank/pubspec.lock @@ -0,0 +1,434 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2" + url: "https://pub.dev" + source: hosted + version: "1.3.44" + archive: + dependency: transitive + description: + name: archive + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d + url: "https://pub.dev" + source: hosted + version: "3.6.1" + args: + dependency: transitive + description: + name: args + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + url: "https://pub.dev" + source: hosted + version: "2.5.0" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + url: "https://pub.dev" + source: hosted + version: "3.0.5" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + firebase_app_check: + dependency: transitive + description: + name: firebase_app_check + sha256: b5b3c1df2698d6b6bd183f27fb10fbf61f9a0a564d8ccba3d87d0e0760a9ffea + url: "https://pub.dev" + source: hosted + version: "0.3.1+4" + firebase_app_check_platform_interface: + dependency: transitive + description: + name: firebase_app_check_platform_interface + sha256: "8dbb826d99c67512212331331461ee142e46645740f1c1209706ca2f72958e57" + url: "https://pub.dev" + source: hosted + version: "0.1.0+38" + firebase_app_check_web: + dependency: transitive + description: + name: firebase_app_check_web + sha256: d9cf8d7e7eb904399784ecdc21ac66119ff2a93181bd7a3f8ab43e8220ad0be8 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + firebase_auth: + dependency: transitive + description: + name: firebase_auth + sha256: d453acec0d958ba0e25d41a9901b32cb77d1535766903dea7a61b2788c304596 + url: "https://pub.dev" + source: hosted + version: "5.3.1" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "78966c2ef774f5bf2a8381a307222867e9ece3509110500f7a138c115926aa65" + url: "https://pub.dev" + source: hosted + version: "7.4.7" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: "77ad3b252badedd3f08dfa21a4c7fe244be96c6da3a4067f253b13ea5d32424c" + url: "https://pub.dev" + source: hosted + version: "5.13.2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96" + url: "https://pub.dev" + source: hosted + version: "3.6.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810 + url: "https://pub.dev" + source: hosted + version: "5.3.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5 + url: "https://pub.dev" + source: hosted + version: "2.18.1" + firebase_data_connect: + dependency: "direct main" + description: + name: firebase_data_connect + sha256: "0893243bf24fbb7ae82a53b751a85e8fa6c5096ddff380eccb0c1efa11029f5c" + url: "https://pub.dev" + source: hosted + version: "0.1.2+1" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_dotenv: + dependency: "direct main" + description: + name: flutter_dotenv + sha256: "9357883bdd153ab78cbf9ffa07656e336b8bbb2b5a3ca596b0b27e119f7c7d77" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + 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" + google_identity_services_web: + dependency: transitive + description: + name: google_identity_services_web + sha256: "5be191523702ba8d7a01ca97c17fca096822ccf246b0a9f11923a6ded06199b6" + url: "https://pub.dev" + source: hosted + version: "0.3.1+4" + googleapis_auth: + dependency: transitive + description: + name: googleapis_auth + sha256: befd71383a955535060acde8792e7efc11d2fccd03dd1d3ec434e85b68775938 + url: "https://pub.dev" + source: hosted + version: "1.6.0" + grpc: + dependency: transitive + description: + name: grpc + sha256: e93ee3bce45c134bf44e9728119102358c7cd69de7832d9a874e2e74eb8cab40 + url: "https://pub.dev" + source: hosted + version: "3.2.4" + http: + dependency: transitive + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" + http2: + dependency: transitive + description: + name: http2 + sha256: "9ced024a160b77aba8fb8674e38f70875e321d319e6f303ec18e87bd5a4b0c1d" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + intl: + dependency: transitive + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://pub.dev" + source: hosted + version: "10.0.5" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + lints: + dependency: transitive + description: + name: lints + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" + source: hosted + version: "1.15.0" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + protobuf: + dependency: transitive + description: + name: protobuf + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://pub.dev" + source: hosted + version: "0.7.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + url: "https://pub.dev" + source: hosted + version: "14.2.5" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" +sdks: + dart: ">=3.4.0 <4.0.0" + flutter: ">=3.22.0" diff --git a/dataconnect/flutter-blank/pubspec.yaml b/dataconnect/flutter-blank/pubspec.yaml new file mode 100644 index 00000000..3c610369 --- /dev/null +++ b/dataconnect/flutter-blank/pubspec.yaml @@ -0,0 +1,94 @@ +name: blank +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 is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 1.0.0+1 + +environment: + sdk: ^3.4.0 + +# Dependencies specify other packages that you*r 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. + cupertino_icons: ^1.0.8 + firebase_core: ^3.3.0 + firebase_data_connect: ^0.1.2 + flutter_dotenv: ^5.1.0 + +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. + flutter_lints: ^4.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 packages. +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: + - .env + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/to/asset-from-package + + # 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/to/font-from-package diff --git a/dataconnect/flutter-blank/startProxy.sh b/dataconnect/flutter-blank/startProxy.sh new file mode 100755 index 00000000..a41cc714 --- /dev/null +++ b/dataconnect/flutter-blank/startProxy.sh @@ -0,0 +1,7 @@ +#!/bin/bash +fail() { + echo "Unable to log in. Please re-run ./installDeps.sh to configure Flutter for your workstation." + exit 1 +} +pnpm install 2>&1 | tee install.txt +pnpm run start:proxy 2>&1 | tee start_proxy.txt diff --git a/dataconnect/flutter-blank/test/widget_test.dart b/dataconnect/flutter-blank/test/widget_test.dart new file mode 100644 index 00000000..c96ea8a4 --- /dev/null +++ b/dataconnect/flutter-blank/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 in the flutter_test package. 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:blank/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/dataconnect/flutter-blank/web/favicon.png b/dataconnect/flutter-blank/web/favicon.png new file mode 100644 index 00000000..8aaa46ac Binary files /dev/null and b/dataconnect/flutter-blank/web/favicon.png differ diff --git a/dataconnect/flutter-blank/web/icons/Icon-192.png b/dataconnect/flutter-blank/web/icons/Icon-192.png new file mode 100644 index 00000000..b749bfef Binary files /dev/null and b/dataconnect/flutter-blank/web/icons/Icon-192.png differ diff --git a/dataconnect/flutter-blank/web/icons/Icon-512.png b/dataconnect/flutter-blank/web/icons/Icon-512.png new file mode 100644 index 00000000..88cfd48d Binary files /dev/null and b/dataconnect/flutter-blank/web/icons/Icon-512.png differ diff --git a/dataconnect/flutter-blank/web/icons/Icon-maskable-192.png b/dataconnect/flutter-blank/web/icons/Icon-maskable-192.png new file mode 100644 index 00000000..eb9b4d76 Binary files /dev/null and b/dataconnect/flutter-blank/web/icons/Icon-maskable-192.png differ diff --git a/dataconnect/flutter-blank/web/icons/Icon-maskable-512.png b/dataconnect/flutter-blank/web/icons/Icon-maskable-512.png new file mode 100644 index 00000000..d69c5669 Binary files /dev/null and b/dataconnect/flutter-blank/web/icons/Icon-maskable-512.png differ diff --git a/dataconnect/flutter-blank/web/index.html b/dataconnect/flutter-blank/web/index.html new file mode 100644 index 00000000..c065fd27 --- /dev/null +++ b/dataconnect/flutter-blank/web/index.html @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + blank + + + + + + diff --git a/dataconnect/flutter-blank/web/manifest.json b/dataconnect/flutter-blank/web/manifest.json new file mode 100644 index 00000000..00e3a5bb --- /dev/null +++ b/dataconnect/flutter-blank/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "blank", + "short_name": "blank", + "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/dataconnect/flutter-movie/.firebase/.graphqlrc b/dataconnect/flutter-movie/.firebase/.graphqlrc new file mode 100644 index 00000000..51bf7fd7 --- /dev/null +++ b/dataconnect/flutter-movie/.firebase/.graphqlrc @@ -0,0 +1 @@ +{"schema":["../dataconnect/schema/**/*.gql","../dataconnect/.dataconnect/**/*.gql"],"document":["../dataconnect/connector/**/*.gql"]} \ No newline at end of file diff --git a/dataconnect/flutter-movie/.firebaserc b/dataconnect/flutter-movie/.firebaserc new file mode 100644 index 00000000..6b2c9934 --- /dev/null +++ b/dataconnect/flutter-movie/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": null + } +} diff --git a/dataconnect/flutter-movie/.gitignore b/dataconnect/flutter-movie/.gitignore new file mode 100644 index 00000000..5b1e3843 --- /dev/null +++ b/dataconnect/flutter-movie/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# 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 +.pub-cache/ +.pub/ +/build/ + +# 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 + +/lib/firebase_options.dart diff --git a/dataconnect/flutter-movie/.metadata b/dataconnect/flutter-movie/.metadata new file mode 100644 index 00000000..c2aa44bd --- /dev/null +++ b/dataconnect/flutter-movie/.metadata @@ -0,0 +1,45 @@ +# 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: "603104015dd692ea3403755b55d07813d5cf8965" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 603104015dd692ea3403755b55d07813d5cf8965 + base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + - platform: android + create_revision: 603104015dd692ea3403755b55d07813d5cf8965 + base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + - platform: ios + create_revision: 603104015dd692ea3403755b55d07813d5cf8965 + base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + - platform: linux + create_revision: 603104015dd692ea3403755b55d07813d5cf8965 + base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + - platform: macos + create_revision: 603104015dd692ea3403755b55d07813d5cf8965 + base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + - platform: web + create_revision: 603104015dd692ea3403755b55d07813d5cf8965 + base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + - platform: windows + create_revision: 603104015dd692ea3403755b55d07813d5cf8965 + base_revision: 603104015dd692ea3403755b55d07813d5cf8965 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/dataconnect/flutter-movie/.vscode/launch.json b/dataconnect/flutter-movie/.vscode/launch.json new file mode 100644 index 00000000..ff72c193 --- /dev/null +++ b/dataconnect/flutter-movie/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "dataconnect", + "request": "launch", + "type": "dart" + }, + { + "name": "dataconnect (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "dataconnect (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/dataconnect/flutter-movie/README.md b/dataconnect/flutter-movie/README.md new file mode 100644 index 00000000..94315621 --- /dev/null +++ b/dataconnect/flutter-movie/README.md @@ -0,0 +1,48 @@ +# Firebase Data Connect Quickstart + +## Introduction + +This quickstart is a movie review app to demonstrate the use of Firebase Data Connect with a Cloud SQL database. For more information about Firebase Data Connect visit [the docs](https://firebase.google.com/docs/data-connect/). + + +## Getting Started + +Follow these steps to get up and running with Firebase Data Connect. For more detailed instructions, check out the [official documentation](https://firebase.google.com/docs/data-connect/quickstart). + +### 1. Connect to your Firebase project + +1. If you haven't already, create a Firebase project. + 1. In the [Firebase console](https://console.firebase.google.com), click + **Add project**, then follow the on-screen instructions. +2. Enable Email/Password Sign-in method [here](https://console.firebase.google.com/project/_/authentication/providers). + +### 2. Cloning the repository + +1. Clone this repository to your local machine: + ```sh + git clone https://github.com/firebase/quickstart-flutter.git + ``` +2. Configure flutterfire +This will automatically download and set up firebase for your project: +```sh +flutterfire configure -y -a com.example.dataconnect +``` + + +### 3. Open in Visual Studio Code (VS Code) + +1. Click on the Firebase Data Connect icon on the VS Code sidebar to load the Extension. + a. Sign in with your Google Account if you haven't already. +2. Click on "Connect a Firebase project" and choose the project where you have set up Data Connect. +3. Click on "Start Emulators" - this should generate the Kotlin SDK for you and start the emulators. + +### 4. Populate the database +In VS Code, open the `quickstart-flutter/dataconnect/dataconnect/moviedata_insert.gql` file and click the + `Run (local)` button at the top of the file. + +If you’d like to confirm that the data was correctly inserted, +open `quickstart-flutter/dataconnect/movie-connector/queries.gql` and run the `ListMovies` query. + +### 5. Running the app + +Press the Run button in VS Code to run the sample app on your device. diff --git a/dataconnect/flutter-movie/analysis_options.yaml b/dataconnect/flutter-movie/analysis_options.yaml new file mode 100644 index 00000000..86cb8820 --- /dev/null +++ b/dataconnect/flutter-movie/analysis_options.yaml @@ -0,0 +1,31 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +analyzer: + exclude: + - lib/movies_connector/** +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/dataconnect/flutter-movie/android/.gitignore b/dataconnect/flutter-movie/android/.gitignore new file mode 100644 index 00000000..55afd919 --- /dev/null +++ b/dataconnect/flutter-movie/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/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/dataconnect/flutter-movie/android/app/build.gradle b/dataconnect/flutter-movie/android/app/build.gradle new file mode 100644 index 00000000..49cc888e --- /dev/null +++ b/dataconnect/flutter-movie/android/app/build.gradle @@ -0,0 +1,47 @@ +plugins { + id "com.android.application" + // START: FlutterFire Configuration + id 'com.google.gms.google-services' + // END: FlutterFire Configuration + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + +android { + namespace = "com.example.dataconnect" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8 + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.dataconnect" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = 23 + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + 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 = "../.." +} diff --git a/dataconnect/flutter-movie/android/app/google-services.json b/dataconnect/flutter-movie/android/app/google-services.json new file mode 100644 index 00000000..2a2315fd --- /dev/null +++ b/dataconnect/flutter-movie/android/app/google-services.json @@ -0,0 +1,28 @@ +{ + "project_info": { + "project_id": "mockproject-1234", + "project_number": "123456789000", + "name": "FirebaseQuickstarts", + "firebase_url": "https://mockproject-1234.firebaseio.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "123456789000", + "client_id": "android:com.example.dataconnect", + "client_type": 1, + "android_client_info": { + "package_name": "com.example.dataconnect", + "certificate_hash": [] + } + }, + "api_key": [ + { + "current_key": "AIzbSzCn1" + } + ] + } + ], + "client_info": [], + "ARTIFACT_VERSION": "1" + } \ No newline at end of file diff --git a/dataconnect/flutter-movie/android/app/src/debug/AndroidManifest.xml b/dataconnect/flutter-movie/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..399f6981 --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/dataconnect/flutter-movie/android/app/src/main/AndroidManifest.xml b/dataconnect/flutter-movie/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..136e48a8 --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/dataconnect/flutter-movie/android/app/src/main/kotlin/com/example/dataconnect/MainActivity.kt b/dataconnect/flutter-movie/android/app/src/main/kotlin/com/example/dataconnect/MainActivity.kt new file mode 100644 index 00000000..e3f53e16 --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/main/kotlin/com/example/dataconnect/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.dataconnect + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() diff --git a/dataconnect/flutter-movie/android/app/src/main/res/drawable-v21/launch_background.xml b/dataconnect/flutter-movie/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 00000000..f74085f3 --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/dataconnect/flutter-movie/android/app/src/main/res/drawable/launch_background.xml b/dataconnect/flutter-movie/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/dataconnect/flutter-movie/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-movie/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/dataconnect/flutter-movie/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/dataconnect/flutter-movie/android/app/src/main/res/values-night/styles.xml b/dataconnect/flutter-movie/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 00000000..06952be7 --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/dataconnect/flutter-movie/android/app/src/main/res/values/styles.xml b/dataconnect/flutter-movie/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..cb1ef880 --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/dataconnect/flutter-movie/android/app/src/main/res/xml/network_security_config.xml b/dataconnect/flutter-movie/android/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 00000000..17abf3ac --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,6 @@ + + + + 10.0.2.2 + + \ No newline at end of file diff --git a/dataconnect/flutter-movie/android/app/src/profile/AndroidManifest.xml b/dataconnect/flutter-movie/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..399f6981 --- /dev/null +++ b/dataconnect/flutter-movie/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/dataconnect/flutter-movie/android/build.gradle b/dataconnect/flutter-movie/android/build.gradle new file mode 100644 index 00000000..d2ffbffa --- /dev/null +++ b/dataconnect/flutter-movie/android/build.gradle @@ -0,0 +1,18 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = "../build" +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/dataconnect/flutter-movie/android/gradle.properties b/dataconnect/flutter-movie/android/gradle.properties new file mode 100644 index 00000000..25971708 --- /dev/null +++ b/dataconnect/flutter-movie/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/dataconnect/flutter-movie/android/gradle/wrapper/gradle-wrapper.properties b/dataconnect/flutter-movie/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..7bb2df6b --- /dev/null +++ b/dataconnect/flutter-movie/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip diff --git a/dataconnect/flutter-movie/android/settings.gradle b/dataconnect/flutter-movie/android/settings.gradle new file mode 100644 index 00000000..9759a220 --- /dev/null +++ b/dataconnect/flutter-movie/android/settings.gradle @@ -0,0 +1,28 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "8.1.0" apply false + // START: FlutterFire Configuration + id "com.google.gms.google-services" version "4.3.15" apply false + // END: FlutterFire Configuration + id "org.jetbrains.kotlin.android" version "1.8.22" apply false +} + +include ":app" diff --git a/dataconnect/flutter-movie/assets/open-in-new-tab.png b/dataconnect/flutter-movie/assets/open-in-new-tab.png new file mode 100644 index 00000000..b3ab4213 Binary files /dev/null and b/dataconnect/flutter-movie/assets/open-in-new-tab.png differ diff --git a/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/implicit.gql b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/implicit.gql new file mode 100644 index 00000000..c7944ef7 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/implicit.gql @@ -0,0 +1,40 @@ +extend type FavoriteMovie { + """ + ✨ Implicit foreign key field based on `FavoriteMovie`.`user`. It must match the value of `User`.`id`. See `@ref` for how to customize it. + """ + userId: String! @fdc_generated(from: "FavoriteMovie.user", purpose: IMPLICIT_REF_FIELD) + """ + ✨ Implicit foreign key field based on `FavoriteMovie`.`movie`. It must match the value of `Movie`.`id`. See `@ref` for how to customize it. + """ + movieId: UUID! @fdc_generated(from: "FavoriteMovie.movie", purpose: IMPLICIT_REF_FIELD) +} +extend type MovieActor { + """ + ✨ Implicit foreign key field based on `MovieActor`.`movie`. It must match the value of `Movie`.`id`. See `@ref` for how to customize it. + """ + movieId: UUID! @fdc_generated(from: "MovieActor.movie", purpose: IMPLICIT_REF_FIELD) + """ + ✨ Implicit foreign key field based on `MovieActor`.`actor`. It must match the value of `Actor`.`id`. See `@ref` for how to customize it. + """ + actorId: UUID! @fdc_generated(from: "MovieActor.actor", purpose: IMPLICIT_REF_FIELD) +} +extend type MovieMetadata { + """ + ✨ Implicit primary key field. It's a UUID column default to a generated new value. See `@table` for how to customize it. + """ + id: UUID! @default(expr: "uuidV4()") @fdc_generated(from: "MovieMetadata", purpose: IMPLICIT_KEY_FIELD) + """ + ✨ Implicit foreign key field based on `MovieMetadata`.`movie`. It must match the value of `Movie`.`id`. See `@ref` for how to customize it. + """ + movieId: UUID! @fdc_generated(from: "MovieMetadata.movie", purpose: IMPLICIT_REF_FIELD) +} +extend type Review { + """ + ✨ Implicit foreign key field based on `Review`.`movie`. It must match the value of `Movie`.`id`. See `@ref` for how to customize it. + """ + movieId: UUID! @fdc_generated(from: "Review.movie", purpose: IMPLICIT_REF_FIELD) + """ + ✨ Implicit foreign key field based on `Review`.`user`. It must match the value of `User`.`id`. See `@ref` for how to customize it. + """ + userId: String! @fdc_generated(from: "Review.user", purpose: IMPLICIT_REF_FIELD) +} diff --git a/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/input.gql b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/input.gql new file mode 100644 index 00000000..4ea8e393 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/input.gql @@ -0,0 +1,1152 @@ +""" +✨ `Actor_KeyOutput` returns the primary key fields of table type `Actor`. + +It has the same format as `Actor_Key`, but is only used as mutation return value. +""" +scalar Actor_KeyOutput +""" +✨ `FavoriteMovie_KeyOutput` returns the primary key fields of table type `FavoriteMovie`. + +It has the same format as `FavoriteMovie_Key`, but is only used as mutation return value. +""" +scalar FavoriteMovie_KeyOutput +""" +✨ `Movie_KeyOutput` returns the primary key fields of table type `Movie`. + +It has the same format as `Movie_Key`, but is only used as mutation return value. +""" +scalar Movie_KeyOutput +""" +✨ `MovieActor_KeyOutput` returns the primary key fields of table type `MovieActor`. + +It has the same format as `MovieActor_Key`, but is only used as mutation return value. +""" +scalar MovieActor_KeyOutput +""" +✨ `MovieMetadata_KeyOutput` returns the primary key fields of table type `MovieMetadata`. + +It has the same format as `MovieMetadata_Key`, but is only used as mutation return value. +""" +scalar MovieMetadata_KeyOutput +""" +✨ `Review_KeyOutput` returns the primary key fields of table type `Review`. + +It has the same format as `Review_Key`, but is only used as mutation return value. +""" +scalar Review_KeyOutput +""" +✨ `User_KeyOutput` returns the primary key fields of table type `User`. + +It has the same format as `User_Key`, but is only used as mutation return value. +""" +scalar User_KeyOutput +""" +✨ Generated data input type for table 'Actor'. It includes all necessary fields for creating or upserting rows into table. +""" +input Actor_Data { + """ + ✨ Generated from Field `Actor`.`id` of type `UUID!` + """ + id: UUID + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `Actor`.`id` of type `UUID!`) + """ + id_expr: UUID_Expr + """ + ✨ Generated from Field `Actor`.`imageUrl` of type `String!` + """ + imageUrl: String + """ + ✨ `_expr` server value variant of `imageUrl` (✨ Generated from Field `Actor`.`imageUrl` of type `String!`) + """ + imageUrl_expr: String_Expr + """ + ✨ Generated from Field `Actor`.`name` of type `String!` + """ + name: String + """ + ✨ `_expr` server value variant of `name` (✨ Generated from Field `Actor`.`name` of type `String!`) + """ + name_expr: String_Expr +} +""" +✨ Generated filter input type for table 'Actor'. This input allows filtering objects using various conditions. Use `_or`, `_and`, and `_not` to compose complex filters. +""" +input Actor_Filter { + """ + Apply multiple filter conditions using `AND` logic. + """ + _and: [Actor_Filter!] + """ + Negate the result of the provided filter condition. + """ + _not: Actor_Filter + """ + Apply multiple filter conditions using `OR` logic. + """ + _or: [Actor_Filter!] + """ + ✨ Generated from Field `Actor`.`id` of type `UUID!` + """ + id: UUID_Filter + """ + ✨ Generated from Field `Actor`.`imageUrl` of type `String!` + """ + imageUrl: String_Filter + """ + ✨ Generated from Field `Actor`.`name` of type `String!` + """ + name: String_Filter + """ + ✨ Generated from Field `Actor`.`movieActors_on_actor` of type `[MovieActor!]!` + """ + movieActors_on_actor: MovieActor_ListFilter + """ + ✨ Generated from Field `Actor`.`movies_via_MovieActor` of type `[Movie!]!` + """ + movies_via_MovieActor: Movie_ListFilter +} +""" +✨ Generated first-row input type for table 'Actor'. This input selects the first row matching the filter criteria, ordered according to the specified conditions. +""" +input Actor_FirstRow { + """ + Order the result by the specified fields. + """ + orderBy: [Actor_Order!] + """ + Filters rows based on the specified conditions. + """ + where: Actor_Filter +} +""" +✨ Generated key input type for table 'Actor'. It represents the primary key fields used to uniquely identify a row in the table. +""" +input Actor_Key { + """ + ✨ Generated from Field `Actor`.`id` of type `UUID!` + """ + id: UUID + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `Actor`.`id` of type `UUID!`) + """ + id_expr: UUID_Expr +} +""" +✨ Generated list filter input type for table 'Actor'. This input applies filtering logic based on the count or existence of related objects that matches certain criteria. +""" +input Actor_ListFilter { + """ + The desired number of objects that match the condition (defaults to at least one). + """ + count: Int_Filter = {gt:0} + """ + Condition of the related objects to filter for. + """ + exist: Actor_Filter +} +""" +✨ Generated order input type for table 'Actor'. This input defines the sorting order of rows in query results based on one or more fields. +""" +input Actor_Order { + """ + ✨ Generated from Field `Actor`.`id` of type `UUID!` + """ + id: OrderDirection + """ + ✨ Generated from Field `Actor`.`imageUrl` of type `String!` + """ + imageUrl: OrderDirection + """ + ✨ Generated from Field `Actor`.`name` of type `String!` + """ + name: OrderDirection +} +""" +✨ Generated data input type for table 'FavoriteMovie'. It includes all necessary fields for creating or upserting rows into table. +""" +input FavoriteMovie_Data { + """ + ✨ Generated from Field `FavoriteMovie`.`userId` of type `String!` + """ + userId: String + """ + ✨ `_expr` server value variant of `userId` (✨ Generated from Field `FavoriteMovie`.`userId` of type `String!`) + """ + userId_expr: String_Expr + """ + ✨ Generated from Field `FavoriteMovie`.`movieId` of type `UUID!` + """ + movieId: UUID + """ + ✨ `_expr` server value variant of `movieId` (✨ Generated from Field `FavoriteMovie`.`movieId` of type `UUID!`) + """ + movieId_expr: UUID_Expr + """ + ✨ Generated from Field `FavoriteMovie`.`movie` of type `Movie!` + """ + movie: Movie_Key + """ + ✨ Generated from Field `FavoriteMovie`.`user` of type `User!` + """ + user: User_Key +} +""" +✨ Generated filter input type for table 'FavoriteMovie'. This input allows filtering objects using various conditions. Use `_or`, `_and`, and `_not` to compose complex filters. +""" +input FavoriteMovie_Filter { + """ + Apply multiple filter conditions using `AND` logic. + """ + _and: [FavoriteMovie_Filter!] + """ + Negate the result of the provided filter condition. + """ + _not: FavoriteMovie_Filter + """ + Apply multiple filter conditions using `OR` logic. + """ + _or: [FavoriteMovie_Filter!] + """ + ✨ Generated from Field `FavoriteMovie`.`userId` of type `String!` + """ + userId: String_Filter + """ + ✨ Generated from Field `FavoriteMovie`.`movieId` of type `UUID!` + """ + movieId: UUID_Filter + """ + ✨ Generated from Field `FavoriteMovie`.`movie` of type `Movie!` + """ + movie: Movie_Filter + """ + ✨ Generated from Field `FavoriteMovie`.`user` of type `User!` + """ + user: User_Filter +} +""" +✨ Generated first-row input type for table 'FavoriteMovie'. This input selects the first row matching the filter criteria, ordered according to the specified conditions. +""" +input FavoriteMovie_FirstRow { + """ + Order the result by the specified fields. + """ + orderBy: [FavoriteMovie_Order!] + """ + Filters rows based on the specified conditions. + """ + where: FavoriteMovie_Filter +} +""" +✨ Generated key input type for table 'FavoriteMovie'. It represents the primary key fields used to uniquely identify a row in the table. +""" +input FavoriteMovie_Key { + """ + ✨ Generated from Field `FavoriteMovie`.`userId` of type `String!` + """ + userId: String + """ + ✨ `_expr` server value variant of `userId` (✨ Generated from Field `FavoriteMovie`.`userId` of type `String!`) + """ + userId_expr: String_Expr + """ + ✨ Generated from Field `FavoriteMovie`.`movieId` of type `UUID!` + """ + movieId: UUID + """ + ✨ `_expr` server value variant of `movieId` (✨ Generated from Field `FavoriteMovie`.`movieId` of type `UUID!`) + """ + movieId_expr: UUID_Expr +} +""" +✨ Generated list filter input type for table 'FavoriteMovie'. This input applies filtering logic based on the count or existence of related objects that matches certain criteria. +""" +input FavoriteMovie_ListFilter { + """ + The desired number of objects that match the condition (defaults to at least one). + """ + count: Int_Filter = {gt:0} + """ + Condition of the related objects to filter for. + """ + exist: FavoriteMovie_Filter +} +""" +✨ Generated order input type for table 'FavoriteMovie'. This input defines the sorting order of rows in query results based on one or more fields. +""" +input FavoriteMovie_Order { + """ + ✨ Generated from Field `FavoriteMovie`.`userId` of type `String!` + """ + userId: OrderDirection + """ + ✨ Generated from Field `FavoriteMovie`.`movieId` of type `UUID!` + """ + movieId: OrderDirection + """ + ✨ Generated from Field `FavoriteMovie`.`movie` of type `Movie!` + """ + movie: Movie_Order + """ + ✨ Generated from Field `FavoriteMovie`.`user` of type `User!` + """ + user: User_Order +} +""" +✨ Generated filter input type for table 'Genre'. This input allows filtering objects using various conditions. Use `_or`, `_and`, and `_not` to compose complex filters. +""" +input Genre_Filter { + """ + Apply multiple filter conditions using `AND` logic. + """ + _and: [Genre_Filter!] + """ + Negate the result of the provided filter condition. + """ + _not: Genre_Filter + """ + Apply multiple filter conditions using `OR` logic. + """ + _or: [Genre_Filter!] + """ + ✨ Generated from Field `Genre`.`genre` of type `String` + """ + genre: String_Filter +} +""" +✨ Generated first-row input type for table 'Genre'. This input selects the first row matching the filter criteria, ordered according to the specified conditions. +""" +input Genre_FirstRow { + """ + Order the result by the specified fields. + """ + orderBy: [Genre_Order!] + """ + Filters rows based on the specified conditions. + """ + where: Genre_Filter +} +""" +✨ Generated list filter input type for table 'Genre'. This input applies filtering logic based on the count or existence of related objects that matches certain criteria. +""" +input Genre_ListFilter { + """ + The desired number of objects that match the condition (defaults to at least one). + """ + count: Int_Filter = {gt:0} + """ + Condition of the related objects to filter for. + """ + exist: Genre_Filter +} +""" +✨ Generated order input type for table 'Genre'. This input defines the sorting order of rows in query results based on one or more fields. +""" +input Genre_Order { + """ + ✨ Generated from Field `Genre`.`genre` of type `String` + """ + genre: OrderDirection +} +""" +✨ Generated data input type for table 'Movie'. It includes all necessary fields for creating or upserting rows into table. +""" +input Movie_Data { + """ + ✨ Generated from Field `Movie`.`id` of type `UUID!` + """ + id: UUID + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `Movie`.`id` of type `UUID!`) + """ + id_expr: UUID_Expr + """ + ✨ Generated from Field `Movie`.`description` of type `String` + """ + description: String + """ + ✨ `_expr` server value variant of `description` (✨ Generated from Field `Movie`.`description` of type `String`) + """ + description_expr: String_Expr + """ + ✨ Generated from Field `Movie`.`genre` of type `String` + """ + genre: String + """ + ✨ `_expr` server value variant of `genre` (✨ Generated from Field `Movie`.`genre` of type `String`) + """ + genre_expr: String_Expr + """ + ✨ Generated from Field `Movie`.`imageUrl` of type `String!` + """ + imageUrl: String + """ + ✨ `_expr` server value variant of `imageUrl` (✨ Generated from Field `Movie`.`imageUrl` of type `String!`) + """ + imageUrl_expr: String_Expr + """ + ✨ Generated from Field `Movie`.`rating` of type `Float` + """ + rating: Float + """ + ✨ Generated from Field `Movie`.`releaseYear` of type `Int` + """ + releaseYear: Int + """ + ✨ Generated from Field `Movie`.`tags` of type `[String]` + """ + tags: [String!] + """ + ✨ Generated from Field `Movie`.`title` of type `String!` + """ + title: String + """ + ✨ `_expr` server value variant of `title` (✨ Generated from Field `Movie`.`title` of type `String!`) + """ + title_expr: String_Expr +} +""" +✨ Generated filter input type for table 'Movie'. This input allows filtering objects using various conditions. Use `_or`, `_and`, and `_not` to compose complex filters. +""" +input Movie_Filter { + """ + Apply multiple filter conditions using `AND` logic. + """ + _and: [Movie_Filter!] + """ + Negate the result of the provided filter condition. + """ + _not: Movie_Filter + """ + Apply multiple filter conditions using `OR` logic. + """ + _or: [Movie_Filter!] + """ + ✨ Generated from Field `Movie`.`id` of type `UUID!` + """ + id: UUID_Filter + """ + ✨ Generated from Field `Movie`.`description` of type `String` + """ + description: String_Filter + """ + ✨ Generated from Field `Movie`.`genre` of type `String` + """ + genre: String_Filter + """ + ✨ Generated from Field `Movie`.`imageUrl` of type `String!` + """ + imageUrl: String_Filter + """ + ✨ Generated from Field `Movie`.`rating` of type `Float` + """ + rating: Float_Filter + """ + ✨ Generated from Field `Movie`.`releaseYear` of type `Int` + """ + releaseYear: Int_Filter + """ + ✨ Generated from Field `Movie`.`tags` of type `[String]` + """ + tags: String_ListFilter + """ + ✨ Generated from Field `Movie`.`title` of type `String!` + """ + title: String_Filter + """ + ✨ Generated from Field `Movie`.`favorite_movies_on_movie` of type `[FavoriteMovie!]!` + """ + favorite_movies_on_movie: FavoriteMovie_ListFilter + """ + ✨ Generated from Field `Movie`.`movieActors_on_movie` of type `[MovieActor!]!` + """ + movieActors_on_movie: MovieActor_ListFilter + """ + ✨ Generated from Field `Movie`.`movieMetadatas_on_movie` of type `[MovieMetadata!]!` + """ + movieMetadatas_on_movie: MovieMetadata_ListFilter + """ + ✨ Generated from Field `Movie`.`reviews_on_movie` of type `[Review!]!` + """ + reviews_on_movie: Review_ListFilter + """ + ✨ Generated from Field `Movie`.`actors_via_MovieActor` of type `[Actor!]!` + """ + actors_via_MovieActor: Actor_ListFilter + """ + ✨ Generated from Field `Movie`.`users_via_FavoriteMovie` of type `[User!]!` + """ + users_via_FavoriteMovie: User_ListFilter + """ + ✨ Generated from Field `Movie`.`users_via_Review` of type `[User!]!` + """ + users_via_Review: User_ListFilter +} +""" +✨ Generated first-row input type for table 'Movie'. This input selects the first row matching the filter criteria, ordered according to the specified conditions. +""" +input Movie_FirstRow { + """ + Order the result by the specified fields. + """ + orderBy: [Movie_Order!] + """ + Filters rows based on the specified conditions. + """ + where: Movie_Filter +} +""" +✨ Generated key input type for table 'Movie'. It represents the primary key fields used to uniquely identify a row in the table. +""" +input Movie_Key { + """ + ✨ Generated from Field `Movie`.`id` of type `UUID!` + """ + id: UUID + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `Movie`.`id` of type `UUID!`) + """ + id_expr: UUID_Expr +} +""" +✨ Generated list filter input type for table 'Movie'. This input applies filtering logic based on the count or existence of related objects that matches certain criteria. +""" +input Movie_ListFilter { + """ + The desired number of objects that match the condition (defaults to at least one). + """ + count: Int_Filter = {gt:0} + """ + Condition of the related objects to filter for. + """ + exist: Movie_Filter +} +""" +✨ Generated order input type for table 'Movie'. This input defines the sorting order of rows in query results based on one or more fields. +""" +input Movie_Order { + """ + ✨ Generated from Field `Movie`.`id` of type `UUID!` + """ + id: OrderDirection + """ + ✨ Generated from Field `Movie`.`description` of type `String` + """ + description: OrderDirection + """ + ✨ Generated from Field `Movie`.`genre` of type `String` + """ + genre: OrderDirection + """ + ✨ Generated from Field `Movie`.`imageUrl` of type `String!` + """ + imageUrl: OrderDirection + """ + ✨ Generated from Field `Movie`.`rating` of type `Float` + """ + rating: OrderDirection + """ + ✨ Generated from Field `Movie`.`releaseYear` of type `Int` + """ + releaseYear: OrderDirection + """ + ✨ Generated from Field `Movie`.`title` of type `String!` + """ + title: OrderDirection +} +""" +✨ Generated data input type for table 'MovieActor'. It includes all necessary fields for creating or upserting rows into table. +""" +input MovieActor_Data { + """ + ✨ Generated from Field `MovieActor`.`movieId` of type `UUID!` + """ + movieId: UUID + """ + ✨ `_expr` server value variant of `movieId` (✨ Generated from Field `MovieActor`.`movieId` of type `UUID!`) + """ + movieId_expr: UUID_Expr + """ + ✨ Generated from Field `MovieActor`.`actorId` of type `UUID!` + """ + actorId: UUID + """ + ✨ `_expr` server value variant of `actorId` (✨ Generated from Field `MovieActor`.`actorId` of type `UUID!`) + """ + actorId_expr: UUID_Expr + """ + ✨ Generated from Field `MovieActor`.`actor` of type `Actor!` + """ + actor: Actor_Key + """ + ✨ Generated from Field `MovieActor`.`movie` of type `Movie!` + """ + movie: Movie_Key + """ + ✨ Generated from Field `MovieActor`.`role` of type `String!` + """ + role: String + """ + ✨ `_expr` server value variant of `role` (✨ Generated from Field `MovieActor`.`role` of type `String!`) + """ + role_expr: String_Expr +} +""" +✨ Generated filter input type for table 'MovieActor'. This input allows filtering objects using various conditions. Use `_or`, `_and`, and `_not` to compose complex filters. +""" +input MovieActor_Filter { + """ + Apply multiple filter conditions using `AND` logic. + """ + _and: [MovieActor_Filter!] + """ + Negate the result of the provided filter condition. + """ + _not: MovieActor_Filter + """ + Apply multiple filter conditions using `OR` logic. + """ + _or: [MovieActor_Filter!] + """ + ✨ Generated from Field `MovieActor`.`movieId` of type `UUID!` + """ + movieId: UUID_Filter + """ + ✨ Generated from Field `MovieActor`.`actorId` of type `UUID!` + """ + actorId: UUID_Filter + """ + ✨ Generated from Field `MovieActor`.`actor` of type `Actor!` + """ + actor: Actor_Filter + """ + ✨ Generated from Field `MovieActor`.`movie` of type `Movie!` + """ + movie: Movie_Filter + """ + ✨ Generated from Field `MovieActor`.`role` of type `String!` + """ + role: String_Filter +} +""" +✨ Generated first-row input type for table 'MovieActor'. This input selects the first row matching the filter criteria, ordered according to the specified conditions. +""" +input MovieActor_FirstRow { + """ + Order the result by the specified fields. + """ + orderBy: [MovieActor_Order!] + """ + Filters rows based on the specified conditions. + """ + where: MovieActor_Filter +} +""" +✨ Generated key input type for table 'MovieActor'. It represents the primary key fields used to uniquely identify a row in the table. +""" +input MovieActor_Key { + """ + ✨ Generated from Field `MovieActor`.`movieId` of type `UUID!` + """ + movieId: UUID + """ + ✨ `_expr` server value variant of `movieId` (✨ Generated from Field `MovieActor`.`movieId` of type `UUID!`) + """ + movieId_expr: UUID_Expr + """ + ✨ Generated from Field `MovieActor`.`actorId` of type `UUID!` + """ + actorId: UUID + """ + ✨ `_expr` server value variant of `actorId` (✨ Generated from Field `MovieActor`.`actorId` of type `UUID!`) + """ + actorId_expr: UUID_Expr +} +""" +✨ Generated list filter input type for table 'MovieActor'. This input applies filtering logic based on the count or existence of related objects that matches certain criteria. +""" +input MovieActor_ListFilter { + """ + The desired number of objects that match the condition (defaults to at least one). + """ + count: Int_Filter = {gt:0} + """ + Condition of the related objects to filter for. + """ + exist: MovieActor_Filter +} +""" +✨ Generated order input type for table 'MovieActor'. This input defines the sorting order of rows in query results based on one or more fields. +""" +input MovieActor_Order { + """ + ✨ Generated from Field `MovieActor`.`movieId` of type `UUID!` + """ + movieId: OrderDirection + """ + ✨ Generated from Field `MovieActor`.`actorId` of type `UUID!` + """ + actorId: OrderDirection + """ + ✨ Generated from Field `MovieActor`.`actor` of type `Actor!` + """ + actor: Actor_Order + """ + ✨ Generated from Field `MovieActor`.`movie` of type `Movie!` + """ + movie: Movie_Order + """ + ✨ Generated from Field `MovieActor`.`role` of type `String!` + """ + role: OrderDirection +} +""" +✨ Generated data input type for table 'MovieMetadata'. It includes all necessary fields for creating or upserting rows into table. +""" +input MovieMetadata_Data { + """ + ✨ Generated from Field `MovieMetadata`.`id` of type `UUID!` + """ + id: UUID + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `MovieMetadata`.`id` of type `UUID!`) + """ + id_expr: UUID_Expr + """ + ✨ Generated from Field `MovieMetadata`.`movieId` of type `UUID!` + """ + movieId: UUID + """ + ✨ `_expr` server value variant of `movieId` (✨ Generated from Field `MovieMetadata`.`movieId` of type `UUID!`) + """ + movieId_expr: UUID_Expr + """ + ✨ Generated from Field `MovieMetadata`.`movie` of type `Movie!` + """ + movie: Movie_Key + """ + ✨ Generated from Field `MovieMetadata`.`director` of type `String` + """ + director: String + """ + ✨ `_expr` server value variant of `director` (✨ Generated from Field `MovieMetadata`.`director` of type `String`) + """ + director_expr: String_Expr +} +""" +✨ Generated filter input type for table 'MovieMetadata'. This input allows filtering objects using various conditions. Use `_or`, `_and`, and `_not` to compose complex filters. +""" +input MovieMetadata_Filter { + """ + Apply multiple filter conditions using `AND` logic. + """ + _and: [MovieMetadata_Filter!] + """ + Negate the result of the provided filter condition. + """ + _not: MovieMetadata_Filter + """ + Apply multiple filter conditions using `OR` logic. + """ + _or: [MovieMetadata_Filter!] + """ + ✨ Generated from Field `MovieMetadata`.`id` of type `UUID!` + """ + id: UUID_Filter + """ + ✨ Generated from Field `MovieMetadata`.`movieId` of type `UUID!` + """ + movieId: UUID_Filter + """ + ✨ Generated from Field `MovieMetadata`.`movie` of type `Movie!` + """ + movie: Movie_Filter + """ + ✨ Generated from Field `MovieMetadata`.`director` of type `String` + """ + director: String_Filter +} +""" +✨ Generated first-row input type for table 'MovieMetadata'. This input selects the first row matching the filter criteria, ordered according to the specified conditions. +""" +input MovieMetadata_FirstRow { + """ + Order the result by the specified fields. + """ + orderBy: [MovieMetadata_Order!] + """ + Filters rows based on the specified conditions. + """ + where: MovieMetadata_Filter +} +""" +✨ Generated key input type for table 'MovieMetadata'. It represents the primary key fields used to uniquely identify a row in the table. +""" +input MovieMetadata_Key { + """ + ✨ Generated from Field `MovieMetadata`.`id` of type `UUID!` + """ + id: UUID + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `MovieMetadata`.`id` of type `UUID!`) + """ + id_expr: UUID_Expr +} +""" +✨ Generated list filter input type for table 'MovieMetadata'. This input applies filtering logic based on the count or existence of related objects that matches certain criteria. +""" +input MovieMetadata_ListFilter { + """ + The desired number of objects that match the condition (defaults to at least one). + """ + count: Int_Filter = {gt:0} + """ + Condition of the related objects to filter for. + """ + exist: MovieMetadata_Filter +} +""" +✨ Generated order input type for table 'MovieMetadata'. This input defines the sorting order of rows in query results based on one or more fields. +""" +input MovieMetadata_Order { + """ + ✨ Generated from Field `MovieMetadata`.`id` of type `UUID!` + """ + id: OrderDirection + """ + ✨ Generated from Field `MovieMetadata`.`movieId` of type `UUID!` + """ + movieId: OrderDirection + """ + ✨ Generated from Field `MovieMetadata`.`movie` of type `Movie!` + """ + movie: Movie_Order + """ + ✨ Generated from Field `MovieMetadata`.`director` of type `String` + """ + director: OrderDirection +} +""" +✨ Generated data input type for table 'Review'. It includes all necessary fields for creating or upserting rows into table. +""" +input Review_Data { + """ + ✨ Generated from Field `Review`.`movieId` of type `UUID!` + """ + movieId: UUID + """ + ✨ `_expr` server value variant of `movieId` (✨ Generated from Field `Review`.`movieId` of type `UUID!`) + """ + movieId_expr: UUID_Expr + """ + ✨ Generated from Field `Review`.`userId` of type `String!` + """ + userId: String + """ + ✨ `_expr` server value variant of `userId` (✨ Generated from Field `Review`.`userId` of type `String!`) + """ + userId_expr: String_Expr + """ + ✨ Generated from Field `Review`.`movie` of type `Movie!` + """ + movie: Movie_Key + """ + ✨ Generated from Field `Review`.`user` of type `User!` + """ + user: User_Key + """ + ✨ Generated from Field `Review`.`id` of type `UUID!` + """ + id: UUID + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `Review`.`id` of type `UUID!`) + """ + id_expr: UUID_Expr + """ + ✨ Generated from Field `Review`.`rating` of type `Int` + """ + rating: Int + """ + ✨ Generated from Field `Review`.`reviewDate` of type `Date!` + """ + reviewDate: Date + """ + ✨ `_date` server value variant of `reviewDate` (✨ Generated from Field `Review`.`reviewDate` of type `Date!`) + """ + reviewDate_date: Date_Relative + """ + ✨ `_expr` server value variant of `reviewDate` (✨ Generated from Field `Review`.`reviewDate` of type `Date!`) + """ + reviewDate_expr: Date_Expr + """ + ✨ Generated from Field `Review`.`reviewText` of type `String` + """ + reviewText: String + """ + ✨ `_expr` server value variant of `reviewText` (✨ Generated from Field `Review`.`reviewText` of type `String`) + """ + reviewText_expr: String_Expr +} +""" +✨ Generated filter input type for table 'Review'. This input allows filtering objects using various conditions. Use `_or`, `_and`, and `_not` to compose complex filters. +""" +input Review_Filter { + """ + Apply multiple filter conditions using `AND` logic. + """ + _and: [Review_Filter!] + """ + Negate the result of the provided filter condition. + """ + _not: Review_Filter + """ + Apply multiple filter conditions using `OR` logic. + """ + _or: [Review_Filter!] + """ + ✨ Generated from Field `Review`.`movieId` of type `UUID!` + """ + movieId: UUID_Filter + """ + ✨ Generated from Field `Review`.`userId` of type `String!` + """ + userId: String_Filter + """ + ✨ Generated from Field `Review`.`movie` of type `Movie!` + """ + movie: Movie_Filter + """ + ✨ Generated from Field `Review`.`user` of type `User!` + """ + user: User_Filter + """ + ✨ Generated from Field `Review`.`id` of type `UUID!` + """ + id: UUID_Filter + """ + ✨ Generated from Field `Review`.`rating` of type `Int` + """ + rating: Int_Filter + """ + ✨ Generated from Field `Review`.`reviewDate` of type `Date!` + """ + reviewDate: Date_Filter + """ + ✨ Generated from Field `Review`.`reviewText` of type `String` + """ + reviewText: String_Filter +} +""" +✨ Generated first-row input type for table 'Review'. This input selects the first row matching the filter criteria, ordered according to the specified conditions. +""" +input Review_FirstRow { + """ + Order the result by the specified fields. + """ + orderBy: [Review_Order!] + """ + Filters rows based on the specified conditions. + """ + where: Review_Filter +} +""" +✨ Generated key input type for table 'Review'. It represents the primary key fields used to uniquely identify a row in the table. +""" +input Review_Key { + """ + ✨ Generated from Field `Review`.`movieId` of type `UUID!` + """ + movieId: UUID + """ + ✨ `_expr` server value variant of `movieId` (✨ Generated from Field `Review`.`movieId` of type `UUID!`) + """ + movieId_expr: UUID_Expr + """ + ✨ Generated from Field `Review`.`userId` of type `String!` + """ + userId: String + """ + ✨ `_expr` server value variant of `userId` (✨ Generated from Field `Review`.`userId` of type `String!`) + """ + userId_expr: String_Expr +} +""" +✨ Generated list filter input type for table 'Review'. This input applies filtering logic based on the count or existence of related objects that matches certain criteria. +""" +input Review_ListFilter { + """ + The desired number of objects that match the condition (defaults to at least one). + """ + count: Int_Filter = {gt:0} + """ + Condition of the related objects to filter for. + """ + exist: Review_Filter +} +""" +✨ Generated order input type for table 'Review'. This input defines the sorting order of rows in query results based on one or more fields. +""" +input Review_Order { + """ + ✨ Generated from Field `Review`.`movieId` of type `UUID!` + """ + movieId: OrderDirection + """ + ✨ Generated from Field `Review`.`userId` of type `String!` + """ + userId: OrderDirection + """ + ✨ Generated from Field `Review`.`movie` of type `Movie!` + """ + movie: Movie_Order + """ + ✨ Generated from Field `Review`.`user` of type `User!` + """ + user: User_Order + """ + ✨ Generated from Field `Review`.`id` of type `UUID!` + """ + id: OrderDirection + """ + ✨ Generated from Field `Review`.`rating` of type `Int` + """ + rating: OrderDirection + """ + ✨ Generated from Field `Review`.`reviewDate` of type `Date!` + """ + reviewDate: OrderDirection + """ + ✨ Generated from Field `Review`.`reviewText` of type `String` + """ + reviewText: OrderDirection +} +""" +✨ Generated data input type for table 'User'. It includes all necessary fields for creating or upserting rows into table. +""" +input User_Data { + """ + ✨ Generated from Field `User`.`id` of type `String!` + """ + id: String + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `User`.`id` of type `String!`) + """ + id_expr: String_Expr + """ + ✨ Generated from Field `User`.`name` of type `String!` + """ + name: String + """ + ✨ `_expr` server value variant of `name` (✨ Generated from Field `User`.`name` of type `String!`) + """ + name_expr: String_Expr + """ + ✨ Generated from Field `User`.`username` of type `String!` + """ + username: String + """ + ✨ `_expr` server value variant of `username` (✨ Generated from Field `User`.`username` of type `String!`) + """ + username_expr: String_Expr +} +""" +✨ Generated filter input type for table 'User'. This input allows filtering objects using various conditions. Use `_or`, `_and`, and `_not` to compose complex filters. +""" +input User_Filter { + """ + Apply multiple filter conditions using `AND` logic. + """ + _and: [User_Filter!] + """ + Negate the result of the provided filter condition. + """ + _not: User_Filter + """ + Apply multiple filter conditions using `OR` logic. + """ + _or: [User_Filter!] + """ + ✨ Generated from Field `User`.`id` of type `String!` + """ + id: String_Filter + """ + ✨ Generated from Field `User`.`name` of type `String!` + """ + name: String_Filter + """ + ✨ Generated from Field `User`.`username` of type `String!` + """ + username: String_Filter + """ + ✨ Generated from Field `User`.`favorite_movies_on_user` of type `[FavoriteMovie!]!` + """ + favorite_movies_on_user: FavoriteMovie_ListFilter + """ + ✨ Generated from Field `User`.`reviews_on_user` of type `[Review!]!` + """ + reviews_on_user: Review_ListFilter + """ + ✨ Generated from Field `User`.`movies_via_FavoriteMovie` of type `[Movie!]!` + """ + movies_via_FavoriteMovie: Movie_ListFilter + """ + ✨ Generated from Field `User`.`movies_via_Review` of type `[Movie!]!` + """ + movies_via_Review: Movie_ListFilter +} +""" +✨ Generated first-row input type for table 'User'. This input selects the first row matching the filter criteria, ordered according to the specified conditions. +""" +input User_FirstRow { + """ + Order the result by the specified fields. + """ + orderBy: [User_Order!] + """ + Filters rows based on the specified conditions. + """ + where: User_Filter +} +""" +✨ Generated key input type for table 'User'. It represents the primary key fields used to uniquely identify a row in the table. +""" +input User_Key { + """ + ✨ Generated from Field `User`.`id` of type `String!` + """ + id: String + """ + ✨ `_expr` server value variant of `id` (✨ Generated from Field `User`.`id` of type `String!`) + """ + id_expr: String_Expr +} +""" +✨ Generated list filter input type for table 'User'. This input applies filtering logic based on the count or existence of related objects that matches certain criteria. +""" +input User_ListFilter { + """ + The desired number of objects that match the condition (defaults to at least one). + """ + count: Int_Filter = {gt:0} + """ + Condition of the related objects to filter for. + """ + exist: User_Filter +} +""" +✨ Generated order input type for table 'User'. This input defines the sorting order of rows in query results based on one or more fields. +""" +input User_Order { + """ + ✨ Generated from Field `User`.`id` of type `String!` + """ + id: OrderDirection + """ + ✨ Generated from Field `User`.`name` of type `String!` + """ + name: OrderDirection + """ + ✨ Generated from Field `User`.`username` of type `String!` + """ + username: OrderDirection +} diff --git a/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/mutation.gql b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/mutation.gql new file mode 100644 index 00000000..1dad2178 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/mutation.gql @@ -0,0 +1,766 @@ +extend type Mutation { + """ + ✨ Insert a single `Actor` into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + actor_insert( + """ + Data object to insert into the table. + """ + data: Actor_Data! + ): Actor_KeyOutput! @fdc_generated(from: "Actor", purpose: INSERT_SINGLE) + """ + ✨ Insert a single `FavoriteMovie` into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + favorite_movie_insert( + """ + Data object to insert into the table. + """ + data: FavoriteMovie_Data! + ): FavoriteMovie_KeyOutput! @fdc_generated(from: "FavoriteMovie", purpose: INSERT_SINGLE) + """ + ✨ Insert a single `Movie` into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + movie_insert( + """ + Data object to insert into the table. + """ + data: Movie_Data! + ): Movie_KeyOutput! @fdc_generated(from: "Movie", purpose: INSERT_SINGLE) + """ + ✨ Insert a single `MovieActor` into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + movieActor_insert( + """ + Data object to insert into the table. + """ + data: MovieActor_Data! + ): MovieActor_KeyOutput! @fdc_generated(from: "MovieActor", purpose: INSERT_SINGLE) + """ + ✨ Insert a single `MovieMetadata` into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + movieMetadata_insert( + """ + Data object to insert into the table. + """ + data: MovieMetadata_Data! + ): MovieMetadata_KeyOutput! @fdc_generated(from: "MovieMetadata", purpose: INSERT_SINGLE) + """ + ✨ Insert a single `Review` into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + review_insert( + """ + Data object to insert into the table. + """ + data: Review_Data! + ): Review_KeyOutput! @fdc_generated(from: "Review", purpose: INSERT_SINGLE) + """ + ✨ Insert a single `User` into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + user_insert( + """ + Data object to insert into the table. + """ + data: User_Data! + ): User_KeyOutput! @fdc_generated(from: "User", purpose: INSERT_SINGLE) + """ + ✨ Insert `Actor` objects into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + actor_insertMany( + """ + List of data objects to insert into the table. + """ + data: [Actor_Data!]! + ): [Actor_KeyOutput!]! @fdc_generated(from: "Actor", purpose: INSERT_MULTIPLE) + """ + ✨ Insert `FavoriteMovie` objects into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + favorite_movie_insertMany( + """ + List of data objects to insert into the table. + """ + data: [FavoriteMovie_Data!]! + ): [FavoriteMovie_KeyOutput!]! @fdc_generated(from: "FavoriteMovie", purpose: INSERT_MULTIPLE) + """ + ✨ Insert `Movie` objects into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + movie_insertMany( + """ + List of data objects to insert into the table. + """ + data: [Movie_Data!]! + ): [Movie_KeyOutput!]! @fdc_generated(from: "Movie", purpose: INSERT_MULTIPLE) + """ + ✨ Insert `MovieActor` objects into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + movieActor_insertMany( + """ + List of data objects to insert into the table. + """ + data: [MovieActor_Data!]! + ): [MovieActor_KeyOutput!]! @fdc_generated(from: "MovieActor", purpose: INSERT_MULTIPLE) + """ + ✨ Insert `MovieMetadata` objects into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + movieMetadata_insertMany( + """ + List of data objects to insert into the table. + """ + data: [MovieMetadata_Data!]! + ): [MovieMetadata_KeyOutput!]! @fdc_generated(from: "MovieMetadata", purpose: INSERT_MULTIPLE) + """ + ✨ Insert `Review` objects into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + review_insertMany( + """ + List of data objects to insert into the table. + """ + data: [Review_Data!]! + ): [Review_KeyOutput!]! @fdc_generated(from: "Review", purpose: INSERT_MULTIPLE) + """ + ✨ Insert `User` objects into the table. Columns not specified in `data` will receive defaults (e.g. `null`). + """ + user_insertMany( + """ + List of data objects to insert into the table. + """ + data: [User_Data!]! + ): [User_KeyOutput!]! @fdc_generated(from: "User", purpose: INSERT_MULTIPLE) + """ + ✨ Insert or update a single `Actor` into the table, based on the primary key. Returns the key of the newly inserted `Actor`. + """ + actor_upsert( + """ + Data object to insert or update if it already exists. + """ + data: Actor_Data! + ): Actor_KeyOutput! @fdc_generated(from: "Actor", purpose: UPSERT_SINGLE) + """ + ✨ Insert or update a single `FavoriteMovie` into the table, based on the primary key. Returns the key of the newly inserted `FavoriteMovie`. + """ + favorite_movie_upsert( + """ + Data object to insert or update if it already exists. + """ + data: FavoriteMovie_Data! + ): FavoriteMovie_KeyOutput! @fdc_generated(from: "FavoriteMovie", purpose: UPSERT_SINGLE) + """ + ✨ Insert or update a single `Movie` into the table, based on the primary key. Returns the key of the newly inserted `Movie`. + """ + movie_upsert( + """ + Data object to insert or update if it already exists. + """ + data: Movie_Data! + ): Movie_KeyOutput! @fdc_generated(from: "Movie", purpose: UPSERT_SINGLE) + """ + ✨ Insert or update a single `MovieActor` into the table, based on the primary key. Returns the key of the newly inserted `MovieActor`. + """ + movieActor_upsert( + """ + Data object to insert or update if it already exists. + """ + data: MovieActor_Data! + ): MovieActor_KeyOutput! @fdc_generated(from: "MovieActor", purpose: UPSERT_SINGLE) + """ + ✨ Insert or update a single `MovieMetadata` into the table, based on the primary key. Returns the key of the newly inserted `MovieMetadata`. + """ + movieMetadata_upsert( + """ + Data object to insert or update if it already exists. + """ + data: MovieMetadata_Data! + ): MovieMetadata_KeyOutput! @fdc_generated(from: "MovieMetadata", purpose: UPSERT_SINGLE) + """ + ✨ Insert or update a single `Review` into the table, based on the primary key. Returns the key of the newly inserted `Review`. + """ + review_upsert( + """ + Data object to insert or update if it already exists. + """ + data: Review_Data! + ): Review_KeyOutput! @fdc_generated(from: "Review", purpose: UPSERT_SINGLE) + """ + ✨ Insert or update a single `User` into the table, based on the primary key. Returns the key of the newly inserted `User`. + """ + user_upsert( + """ + Data object to insert or update if it already exists. + """ + data: User_Data! + ): User_KeyOutput! @fdc_generated(from: "User", purpose: UPSERT_SINGLE) + """ + ✨ Insert or update `Actor` objects into the table, based on the primary key. Returns the key of the newly inserted `Actor`. + """ + actor_upsertMany( + """ + List of data objects to insert or update if it already exists. + """ + data: [Actor_Data!]! + ): [Actor_KeyOutput!]! @fdc_generated(from: "Actor", purpose: UPSERT_MULTIPLE) + """ + ✨ Insert or update `FavoriteMovie` objects into the table, based on the primary key. Returns the key of the newly inserted `FavoriteMovie`. + """ + favorite_movie_upsertMany( + """ + List of data objects to insert or update if it already exists. + """ + data: [FavoriteMovie_Data!]! + ): [FavoriteMovie_KeyOutput!]! @fdc_generated(from: "FavoriteMovie", purpose: UPSERT_MULTIPLE) + """ + ✨ Insert or update `Movie` objects into the table, based on the primary key. Returns the key of the newly inserted `Movie`. + """ + movie_upsertMany( + """ + List of data objects to insert or update if it already exists. + """ + data: [Movie_Data!]! + ): [Movie_KeyOutput!]! @fdc_generated(from: "Movie", purpose: UPSERT_MULTIPLE) + """ + ✨ Insert or update `MovieActor` objects into the table, based on the primary key. Returns the key of the newly inserted `MovieActor`. + """ + movieActor_upsertMany( + """ + List of data objects to insert or update if it already exists. + """ + data: [MovieActor_Data!]! + ): [MovieActor_KeyOutput!]! @fdc_generated(from: "MovieActor", purpose: UPSERT_MULTIPLE) + """ + ✨ Insert or update `MovieMetadata` objects into the table, based on the primary key. Returns the key of the newly inserted `MovieMetadata`. + """ + movieMetadata_upsertMany( + """ + List of data objects to insert or update if it already exists. + """ + data: [MovieMetadata_Data!]! + ): [MovieMetadata_KeyOutput!]! @fdc_generated(from: "MovieMetadata", purpose: UPSERT_MULTIPLE) + """ + ✨ Insert or update `Review` objects into the table, based on the primary key. Returns the key of the newly inserted `Review`. + """ + review_upsertMany( + """ + List of data objects to insert or update if it already exists. + """ + data: [Review_Data!]! + ): [Review_KeyOutput!]! @fdc_generated(from: "Review", purpose: UPSERT_MULTIPLE) + """ + ✨ Insert or update `User` objects into the table, based on the primary key. Returns the key of the newly inserted `User`. + """ + user_upsertMany( + """ + List of data objects to insert or update if it already exists. + """ + data: [User_Data!]! + ): [User_KeyOutput!]! @fdc_generated(from: "User", purpose: UPSERT_MULTIPLE) + """ + ✨ Update a single `Actor` based on `id`, `key` or `first`, setting columns specified in `data`. Returns `null` if not found. + """ + actor_update( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: Actor_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Actor_FirstRow + + """ + Data object containing fields to be updated. + """ + data: Actor_Data! + ): Actor_KeyOutput @fdc_generated(from: "Actor", purpose: UPDATE_SINGLE) + """ + ✨ Update a single `FavoriteMovie` based on `id`, `key` or `first`, setting columns specified in `data`. Returns `null` if not found. + """ + favorite_movie_update( + """ + The key used to identify the object. + """ + key: FavoriteMovie_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: FavoriteMovie_FirstRow + + """ + Data object containing fields to be updated. + """ + data: FavoriteMovie_Data! + ): FavoriteMovie_KeyOutput @fdc_generated(from: "FavoriteMovie", purpose: UPDATE_SINGLE) + """ + ✨ Update a single `Movie` based on `id`, `key` or `first`, setting columns specified in `data`. Returns `null` if not found. + """ + movie_update( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: Movie_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Movie_FirstRow + + """ + Data object containing fields to be updated. + """ + data: Movie_Data! + ): Movie_KeyOutput @fdc_generated(from: "Movie", purpose: UPDATE_SINGLE) + """ + ✨ Update a single `MovieActor` based on `id`, `key` or `first`, setting columns specified in `data`. Returns `null` if not found. + """ + movieActor_update( + """ + The key used to identify the object. + """ + key: MovieActor_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: MovieActor_FirstRow + + """ + Data object containing fields to be updated. + """ + data: MovieActor_Data! + ): MovieActor_KeyOutput @fdc_generated(from: "MovieActor", purpose: UPDATE_SINGLE) + """ + ✨ Update a single `MovieMetadata` based on `id`, `key` or `first`, setting columns specified in `data`. Returns `null` if not found. + """ + movieMetadata_update( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: MovieMetadata_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: MovieMetadata_FirstRow + + """ + Data object containing fields to be updated. + """ + data: MovieMetadata_Data! + ): MovieMetadata_KeyOutput @fdc_generated(from: "MovieMetadata", purpose: UPDATE_SINGLE) + """ + ✨ Update a single `Review` based on `id`, `key` or `first`, setting columns specified in `data`. Returns `null` if not found. + """ + review_update( + """ + The key used to identify the object. + """ + key: Review_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Review_FirstRow + + """ + Data object containing fields to be updated. + """ + data: Review_Data! + ): Review_KeyOutput @fdc_generated(from: "Review", purpose: UPDATE_SINGLE) + """ + ✨ Update a single `User` based on `id`, `key` or `first`, setting columns specified in `data`. Returns `null` if not found. + """ + user_update( + """ + The unique ID of the object. + """ + id: String + + """ + ✨ `_expr` server value variant of `id` (The unique ID of the object.) + """ + id_expr: String_Expr + + """ + The key used to identify the object. + """ + key: User_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: User_FirstRow + + """ + Data object containing fields to be updated. + """ + data: User_Data! + ): User_KeyOutput @fdc_generated(from: "User", purpose: UPDATE_SINGLE) + """ + ✨ Update `Actor` objects matching `where` conditions (or `all`, if true) according to `data`. Returns the number of rows updated. + """ + actor_updateMany( + """ + Filter condition to specify which rows to update. + """ + where: Actor_Filter + + """ + Set to true to update all rows. + """ + all: Boolean = false + + """ + Data object containing fields to update. + """ + data: Actor_Data! + ): Int! @fdc_generated(from: "Actor", purpose: UPDATE_MULTIPLE) + """ + ✨ Update `FavoriteMovie` objects matching `where` conditions (or `all`, if true) according to `data`. Returns the number of rows updated. + """ + favorite_movie_updateMany( + """ + Filter condition to specify which rows to update. + """ + where: FavoriteMovie_Filter + + """ + Set to true to update all rows. + """ + all: Boolean = false + + """ + Data object containing fields to update. + """ + data: FavoriteMovie_Data! + ): Int! @fdc_generated(from: "FavoriteMovie", purpose: UPDATE_MULTIPLE) + """ + ✨ Update `Movie` objects matching `where` conditions (or `all`, if true) according to `data`. Returns the number of rows updated. + """ + movie_updateMany( + """ + Filter condition to specify which rows to update. + """ + where: Movie_Filter + + """ + Set to true to update all rows. + """ + all: Boolean = false + + """ + Data object containing fields to update. + """ + data: Movie_Data! + ): Int! @fdc_generated(from: "Movie", purpose: UPDATE_MULTIPLE) + """ + ✨ Update `MovieActor` objects matching `where` conditions (or `all`, if true) according to `data`. Returns the number of rows updated. + """ + movieActor_updateMany( + """ + Filter condition to specify which rows to update. + """ + where: MovieActor_Filter + + """ + Set to true to update all rows. + """ + all: Boolean = false + + """ + Data object containing fields to update. + """ + data: MovieActor_Data! + ): Int! @fdc_generated(from: "MovieActor", purpose: UPDATE_MULTIPLE) + """ + ✨ Update `MovieMetadata` objects matching `where` conditions (or `all`, if true) according to `data`. Returns the number of rows updated. + """ + movieMetadata_updateMany( + """ + Filter condition to specify which rows to update. + """ + where: MovieMetadata_Filter + + """ + Set to true to update all rows. + """ + all: Boolean = false + + """ + Data object containing fields to update. + """ + data: MovieMetadata_Data! + ): Int! @fdc_generated(from: "MovieMetadata", purpose: UPDATE_MULTIPLE) + """ + ✨ Update `Review` objects matching `where` conditions (or `all`, if true) according to `data`. Returns the number of rows updated. + """ + review_updateMany( + """ + Filter condition to specify which rows to update. + """ + where: Review_Filter + + """ + Set to true to update all rows. + """ + all: Boolean = false + + """ + Data object containing fields to update. + """ + data: Review_Data! + ): Int! @fdc_generated(from: "Review", purpose: UPDATE_MULTIPLE) + """ + ✨ Update `User` objects matching `where` conditions (or `all`, if true) according to `data`. Returns the number of rows updated. + """ + user_updateMany( + """ + Filter condition to specify which rows to update. + """ + where: User_Filter + + """ + Set to true to update all rows. + """ + all: Boolean = false + + """ + Data object containing fields to update. + """ + data: User_Data! + ): Int! @fdc_generated(from: "User", purpose: UPDATE_MULTIPLE) + """ + ✨ Delete a single `Actor` based on `id`, `key` or `first` and return its key (or `null` if not found). + """ + actor_delete( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: Actor_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Actor_FirstRow + ): Actor_KeyOutput @fdc_generated(from: "Actor", purpose: DELETE_SINGLE) + """ + ✨ Delete a single `FavoriteMovie` based on `id`, `key` or `first` and return its key (or `null` if not found). + """ + favorite_movie_delete( + """ + The key used to identify the object. + """ + key: FavoriteMovie_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: FavoriteMovie_FirstRow + ): FavoriteMovie_KeyOutput @fdc_generated(from: "FavoriteMovie", purpose: DELETE_SINGLE) + """ + ✨ Delete a single `Movie` based on `id`, `key` or `first` and return its key (or `null` if not found). + """ + movie_delete( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: Movie_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Movie_FirstRow + ): Movie_KeyOutput @fdc_generated(from: "Movie", purpose: DELETE_SINGLE) + """ + ✨ Delete a single `MovieActor` based on `id`, `key` or `first` and return its key (or `null` if not found). + """ + movieActor_delete( + """ + The key used to identify the object. + """ + key: MovieActor_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: MovieActor_FirstRow + ): MovieActor_KeyOutput @fdc_generated(from: "MovieActor", purpose: DELETE_SINGLE) + """ + ✨ Delete a single `MovieMetadata` based on `id`, `key` or `first` and return its key (or `null` if not found). + """ + movieMetadata_delete( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: MovieMetadata_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: MovieMetadata_FirstRow + ): MovieMetadata_KeyOutput @fdc_generated(from: "MovieMetadata", purpose: DELETE_SINGLE) + """ + ✨ Delete a single `Review` based on `id`, `key` or `first` and return its key (or `null` if not found). + """ + review_delete( + """ + The key used to identify the object. + """ + key: Review_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Review_FirstRow + ): Review_KeyOutput @fdc_generated(from: "Review", purpose: DELETE_SINGLE) + """ + ✨ Delete a single `User` based on `id`, `key` or `first` and return its key (or `null` if not found). + """ + user_delete( + """ + The unique ID of the object. + """ + id: String + + """ + ✨ `_expr` server value variant of `id` (The unique ID of the object.) + """ + id_expr: String_Expr + + """ + The key used to identify the object. + """ + key: User_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: User_FirstRow + ): User_KeyOutput @fdc_generated(from: "User", purpose: DELETE_SINGLE) + """ + ✨ Delete `Actor` objects matching `where` conditions (or `all`, if true). Returns the number of rows deleted. + """ + actor_deleteMany( + """ + Filter condition to specify which rows to delete. + """ + where: Actor_Filter + + """ + Set to true to delete all rows. + """ + all: Boolean = false + ): Int! @fdc_generated(from: "Actor", purpose: DELETE_MULTIPLE) + """ + ✨ Delete `FavoriteMovie` objects matching `where` conditions (or `all`, if true). Returns the number of rows deleted. + """ + favorite_movie_deleteMany( + """ + Filter condition to specify which rows to delete. + """ + where: FavoriteMovie_Filter + + """ + Set to true to delete all rows. + """ + all: Boolean = false + ): Int! @fdc_generated(from: "FavoriteMovie", purpose: DELETE_MULTIPLE) + """ + ✨ Delete `Movie` objects matching `where` conditions (or `all`, if true). Returns the number of rows deleted. + """ + movie_deleteMany( + """ + Filter condition to specify which rows to delete. + """ + where: Movie_Filter + + """ + Set to true to delete all rows. + """ + all: Boolean = false + ): Int! @fdc_generated(from: "Movie", purpose: DELETE_MULTIPLE) + """ + ✨ Delete `MovieActor` objects matching `where` conditions (or `all`, if true). Returns the number of rows deleted. + """ + movieActor_deleteMany( + """ + Filter condition to specify which rows to delete. + """ + where: MovieActor_Filter + + """ + Set to true to delete all rows. + """ + all: Boolean = false + ): Int! @fdc_generated(from: "MovieActor", purpose: DELETE_MULTIPLE) + """ + ✨ Delete `MovieMetadata` objects matching `where` conditions (or `all`, if true). Returns the number of rows deleted. + """ + movieMetadata_deleteMany( + """ + Filter condition to specify which rows to delete. + """ + where: MovieMetadata_Filter + + """ + Set to true to delete all rows. + """ + all: Boolean = false + ): Int! @fdc_generated(from: "MovieMetadata", purpose: DELETE_MULTIPLE) + """ + ✨ Delete `Review` objects matching `where` conditions (or `all`, if true). Returns the number of rows deleted. + """ + review_deleteMany( + """ + Filter condition to specify which rows to delete. + """ + where: Review_Filter + + """ + Set to true to delete all rows. + """ + all: Boolean = false + ): Int! @fdc_generated(from: "Review", purpose: DELETE_MULTIPLE) + """ + ✨ Delete `User` objects matching `where` conditions (or `all`, if true). Returns the number of rows deleted. + """ + user_deleteMany( + """ + Filter condition to specify which rows to delete. + """ + where: User_Filter + + """ + Set to true to delete all rows. + """ + all: Boolean = false + ): Int! @fdc_generated(from: "User", purpose: DELETE_MULTIPLE) +} diff --git a/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/query.gql b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/query.gql new file mode 100644 index 00000000..a2f3bc6f --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/query.gql @@ -0,0 +1,317 @@ +extend type Query { + """ + ✨ Look up a single `Actor` based on `id`, `key` or `first` and return selected fields (or `null` if not found). + """ + actor( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: Actor_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Actor_FirstRow + ): Actor @fdc_generated(from: "Actor", purpose: QUERY_SINGLE) + """ + ✨ Look up a single `FavoriteMovie` based on `id`, `key` or `first` and return selected fields (or `null` if not found). + """ + favorite_movie( + """ + The key used to identify the object. + """ + key: FavoriteMovie_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: FavoriteMovie_FirstRow + ): FavoriteMovie @fdc_generated(from: "FavoriteMovie", purpose: QUERY_SINGLE) + """ + ✨ Look up a single `Movie` based on `id`, `key` or `first` and return selected fields (or `null` if not found). + """ + movie( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: Movie_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Movie_FirstRow + ): Movie @fdc_generated(from: "Movie", purpose: QUERY_SINGLE) + """ + ✨ Look up a single `MovieActor` based on `id`, `key` or `first` and return selected fields (or `null` if not found). + """ + movieActor( + """ + The key used to identify the object. + """ + key: MovieActor_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: MovieActor_FirstRow + ): MovieActor @fdc_generated(from: "MovieActor", purpose: QUERY_SINGLE) + """ + ✨ Look up a single `MovieMetadata` based on `id`, `key` or `first` and return selected fields (or `null` if not found). + """ + movieMetadata( + """ + The unique ID of the object. + """ + id: UUID + + """ + The key used to identify the object. + """ + key: MovieMetadata_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: MovieMetadata_FirstRow + ): MovieMetadata @fdc_generated(from: "MovieMetadata", purpose: QUERY_SINGLE) + """ + ✨ Look up a single `Review` based on `id`, `key` or `first` and return selected fields (or `null` if not found). + """ + review( + """ + The key used to identify the object. + """ + key: Review_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: Review_FirstRow + ): Review @fdc_generated(from: "Review", purpose: QUERY_SINGLE) + """ + ✨ Look up a single `User` based on `id`, `key` or `first` and return selected fields (or `null` if not found). + """ + user( + """ + The unique ID of the object. + """ + id: String + + """ + ✨ `_expr` server value variant of `id` (The unique ID of the object.) + """ + id_expr: String_Expr + + """ + The key used to identify the object. + """ + key: User_Key + + """ + Fetch the first row based on the filters and ordering. + """ + first: User_FirstRow + ): User @fdc_generated(from: "User", purpose: QUERY_SINGLE) + """ + ✨ List `Actor` objects in the table, optionally filtered by `where` conditions. + """ + actors( + """ + Filter condition to narrow down the query results. + """ + where: Actor_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [Actor_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Actor!]! @fdc_generated(from: "Actor", purpose: QUERY_MULTIPLE) + """ + ✨ List `FavoriteMovie` objects in the table, optionally filtered by `where` conditions. + """ + favorite_movies( + """ + Filter condition to narrow down the query results. + """ + where: FavoriteMovie_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [FavoriteMovie_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [FavoriteMovie!]! @fdc_generated(from: "FavoriteMovie", purpose: QUERY_MULTIPLE) + """ + ✨ List `Genre` objects in the table, optionally filtered by `where` conditions. + """ + genres( + """ + Filter condition to narrow down the query results. + """ + where: Genre_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [Genre_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Genre!]! @fdc_generated(from: "Genre", purpose: QUERY_MULTIPLE) + """ + ✨ List `Movie` objects in the table, optionally filtered by `where` conditions. + """ + movies( + """ + Filter condition to narrow down the query results. + """ + where: Movie_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [Movie_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Movie!]! @fdc_generated(from: "Movie", purpose: QUERY_MULTIPLE) + """ + ✨ List `MovieActor` objects in the table, optionally filtered by `where` conditions. + """ + movieActors( + """ + Filter condition to narrow down the query results. + """ + where: MovieActor_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [MovieActor_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [MovieActor!]! @fdc_generated(from: "MovieActor", purpose: QUERY_MULTIPLE) + """ + ✨ List `MovieMetadata` objects in the table, optionally filtered by `where` conditions. + """ + movieMetadatas( + """ + Filter condition to narrow down the query results. + """ + where: MovieMetadata_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [MovieMetadata_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [MovieMetadata!]! @fdc_generated(from: "MovieMetadata", purpose: QUERY_MULTIPLE) + """ + ✨ List `Review` objects in the table, optionally filtered by `where` conditions. + """ + reviews( + """ + Filter condition to narrow down the query results. + """ + where: Review_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [Review_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Review!]! @fdc_generated(from: "Review", purpose: QUERY_MULTIPLE) + """ + ✨ List `User` objects in the table, optionally filtered by `where` conditions. + """ + users( + """ + Filter condition to narrow down the query results. + """ + where: User_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [User_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [User!]! @fdc_generated(from: "User", purpose: QUERY_MULTIPLE) +} diff --git a/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/relation.gql b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/relation.gql new file mode 100644 index 00000000..5b1d7799 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/main/relation.gql @@ -0,0 +1,318 @@ +extend type Actor { + """ + ✨ List `MovieActor` objects in a one-to-many relationship (where `MovieActor`.`actor` is this object). + """ + movieActors_on_actor( + """ + Filter condition to narrow down the query results. + """ + where: MovieActor_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [MovieActor_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [MovieActor!]! @fdc_generated(from: "MovieActor.actor", purpose: QUERY_MULTIPLE_ONE_TO_MANY) + """ + ✨ List `Movie` objects using `MovieActor` as the join table (a `MovieActor` object exists where its `actor` is this and its `movie` is that). + """ + movies_via_MovieActor( + """ + Filter condition to narrow down the query results. + """ + where: MovieActor_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [MovieActor_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Movie!]! @fdc_generated(from: "MovieActor", purpose: QUERY_MULTIPLE_MANY_TO_MANY) +} +extend type Movie { + """ + ✨ List `FavoriteMovie` objects in a one-to-many relationship (where `FavoriteMovie`.`movie` is this object). + """ + favorite_movies_on_movie( + """ + Filter condition to narrow down the query results. + """ + where: FavoriteMovie_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [FavoriteMovie_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [FavoriteMovie!]! @fdc_generated(from: "FavoriteMovie.movie", purpose: QUERY_MULTIPLE_ONE_TO_MANY) + """ + ✨ List `MovieActor` objects in a one-to-many relationship (where `MovieActor`.`movie` is this object). + """ + movieActors_on_movie( + """ + Filter condition to narrow down the query results. + """ + where: MovieActor_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [MovieActor_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [MovieActor!]! @fdc_generated(from: "MovieActor.movie", purpose: QUERY_MULTIPLE_ONE_TO_MANY) + """ + ✨ List `MovieMetadata` objects in a one-to-many relationship (where `MovieMetadata`.`movie` is this object). + """ + movieMetadatas_on_movie( + """ + Filter condition to narrow down the query results. + """ + where: MovieMetadata_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [MovieMetadata_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [MovieMetadata!]! @fdc_generated(from: "MovieMetadata.movie", purpose: QUERY_MULTIPLE_ONE_TO_MANY) + """ + ✨ List `Review` objects in a one-to-many relationship (where `Review`.`movie` is this object). + """ + reviews_on_movie( + """ + Filter condition to narrow down the query results. + """ + where: Review_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [Review_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Review!]! @fdc_generated(from: "Review.movie", purpose: QUERY_MULTIPLE_ONE_TO_MANY) + """ + ✨ List `Actor` objects using `MovieActor` as the join table (a `MovieActor` object exists where its `movie` is this and its `actor` is that). + """ + actors_via_MovieActor( + """ + Filter condition to narrow down the query results. + """ + where: MovieActor_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [MovieActor_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Actor!]! @fdc_generated(from: "MovieActor", purpose: QUERY_MULTIPLE_MANY_TO_MANY) + """ + ✨ List `User` objects using `FavoriteMovie` as the join table (a `FavoriteMovie` object exists where its `movie` is this and its `user` is that). + """ + users_via_FavoriteMovie( + """ + Filter condition to narrow down the query results. + """ + where: FavoriteMovie_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [FavoriteMovie_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [User!]! @fdc_generated(from: "FavoriteMovie", purpose: QUERY_MULTIPLE_MANY_TO_MANY) + """ + ✨ List `User` objects using `Review` as the join table (a `Review` object exists where its `movie` is this and its `user` is that). + """ + users_via_Review( + """ + Filter condition to narrow down the query results. + """ + where: Review_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [Review_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [User!]! @fdc_generated(from: "Review", purpose: QUERY_MULTIPLE_MANY_TO_MANY) +} +extend type User { + """ + ✨ List `FavoriteMovie` objects in a one-to-many relationship (where `FavoriteMovie`.`user` is this object). + """ + favorite_movies_on_user( + """ + Filter condition to narrow down the query results. + """ + where: FavoriteMovie_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [FavoriteMovie_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [FavoriteMovie!]! @fdc_generated(from: "FavoriteMovie.user", purpose: QUERY_MULTIPLE_ONE_TO_MANY) + """ + ✨ List `Review` objects in a one-to-many relationship (where `Review`.`user` is this object). + """ + reviews_on_user( + """ + Filter condition to narrow down the query results. + """ + where: Review_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [Review_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Review!]! @fdc_generated(from: "Review.user", purpose: QUERY_MULTIPLE_ONE_TO_MANY) + """ + ✨ List `Movie` objects using `FavoriteMovie` as the join table (a `FavoriteMovie` object exists where its `user` is this and its `movie` is that). + """ + movies_via_FavoriteMovie( + """ + Filter condition to narrow down the query results. + """ + where: FavoriteMovie_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [FavoriteMovie_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Movie!]! @fdc_generated(from: "FavoriteMovie", purpose: QUERY_MULTIPLE_MANY_TO_MANY) + """ + ✨ List `Movie` objects using `Review` as the join table (a `Review` object exists where its `user` is this and its `movie` is that). + """ + movies_via_Review( + """ + Filter condition to narrow down the query results. + """ + where: Review_Filter + + """ + Order the query results by specific fields. + """ + orderBy: [Review_Order!] + + """ + Number of rows to skip before starting to return the results. + """ + offset: Int + + """ + Maximum number of rows to return (defaults to 100 rows). + """ + limit: Int = 100 + ): [Movie!]! @fdc_generated(from: "Review", purpose: QUERY_MULTIPLE_MANY_TO_MANY) +} diff --git a/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/prelude.gql b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/prelude.gql new file mode 100644 index 00000000..7fac870c --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/.dataconnect/schema/prelude.gql @@ -0,0 +1,2026 @@ +"AccessLevel specifies coarse access policies for common situations." +enum AccessLevel { + """ + This operation is accessible to anyone, with or without authentication. + Equivalent to: `@auth(expr: "true")` + """ + PUBLIC + + """ + This operation can be executed only with a valid Firebase Auth ID token. + **Note:** This access level allows anonymous and unverified accounts, + which may present security and abuse risks. + Equivalent to: `@auth(expr: "auth.uid != nil")` + """ + USER_ANON + + """ + This operation is restricted to non-anonymous Firebase Auth accounts. + Equivalent to: `@auth(expr: "auth.uid != nil && auth.token.firebase.sign_in_provider != 'anonymous'")` + """ + USER + + """ + This operation is restricted to Firebase Auth accounts with verified email addresses. + Equivalent to: `@auth(expr: "auth.uid != nil && auth.token.email_verified")` + """ + USER_EMAIL_VERIFIED + + """ + This operation cannot be executed by anyone. The operation can only be performed + by using the Admin SDK from a privileged environment. + Equivalent to: `@auth(expr: "false")` + """ + NO_ACCESS +} + +""" +The `@auth` directive defines the authentication policy for a query or mutation. + +It must be added to any operation that you wish to be accessible from a client +application. If not specified, the operation defaults to `@auth(level: NO_ACCESS)`. + +Refer to [Data Connect Auth Guide](https://firebase.google.com/docs/data-connect/authorization-and-security) for the best practices. +""" +directive @auth( + """ + The minimal level of access required to perform this operation. + Exactly one of `level` and `expr` should be specified. + """ + level: AccessLevel @fdc_oneOf(required: true) + """ + A CEL expression that grants access to this operation if the expression + evaluates to `true`. + Exactly one of `level` and `expr` should be specified. + """ + expr: Boolean_Expr @fdc_oneOf(required: true) +) on QUERY | MUTATION + + +""" +Require that this mutation always run in a DB transaction. + +Mutations with `@transaction` are guaranteed to either fully succeed or fully +fail. If any of the fields within the transaction fails, the entire transaction +is rolled back. From a client standpoint, any failure behaves as if the entire +request had failed with a request error and execution had not begun. + +Mutations without `@transaction` would execute each root field one after +another in sequence. It surfaces any errors as partial [field errors](https://spec.graphql.org/October2021/#sec-Errors.Field-errors), +but not impacts the subsequent executions. + +The `@transaction` directive cannot be added to queries for now. +Currently, queries cannot fail partially, the response data is not guaranteed +to be a consistent snapshot. +""" +directive @transaction on MUTATION + +"Query filter criteria for `String` scalar fields." +input String_Filter { + "When true, match if field `IS NULL`. When false, match if field is `NOT NULL`." + isNull: Boolean + "Match if field is exactly equal to provided value." + eq: String @fdc_oneOf(group: "eq") + """ + Match if field is exactly equal to the result of the provided server value + expression. Currently only `auth.uid` is supported as an expression. + """ + eq_expr: String_Expr @fdc_oneOf(group: "eq") + "Match if field is not equal to provided value." + ne: String @fdc_oneOf(group: "ne") + """ + Match if field is not equal to the result of the provided server value + expression. Currently only `auth.uid` is supported as an expression. + """ + ne_expr: String_Expr @fdc_oneOf(group: "ne") + "Match if field value is among the provided list of values." + in: [String!] + "Match if field value is not among the provided list of values." + nin: [String!] + "Match if field value is greater than the provided value." + gt: String + "Match if field value is greater than or equal to the provided value." + ge: String + "Match if field value is less than the provided value." + lt: String + "Match if field value is less than or equal to the provided value." + le: String + """ + Match if field value contains the provided value as a substring. Equivalent + to `LIKE '%value%'` + """ + contains: String + """ + Match if field value starts with the provided value. Equivalent to + `LIKE 'value%'` + """ + startsWith: String + """ + Match if field value ends with the provided value. Equivalent to + `LIKE '%value'` + """ + endsWith: String + """ + Match if field value matches the provided pattern. See `String_Pattern` for + more details. + """ + pattern: String_Pattern +} + +""" +The pattern match condition on a string. Specify either like or regex. +https://www.postgresql.org/docs/current/functions-matching.html +""" +input String_Pattern { + "Match using the provided `LIKE` expression." + like: String + "Match using the provided POSIX regular expression." + regex: String + "When true, ignore case when matching." + ignoreCase: Boolean + "When true, invert the match result. Equivalent to `NOT LIKE` or `!~`." + invert: Boolean +} + +"Query filter criteris for `[String!]` scalar fields." +input String_ListFilter { + "Match if list field contains the provided value as a member." + includes: String + "Match if list field does not contain the provided value as a member." + excludes: String + "Match if list field contains all of the provided values as members." + includesAll: [String!] + "Match if list field does not contain any of the provided values as members." + excludesAll: [String!] +} + +"Query filter criteria for `UUID` scalar fields." +input UUID_Filter { + "When true, match if field `IS NULL`. When false, match if field is `NOT NULL`." + isNull: Boolean + "Match if field is exactly equal to provided value." + eq: UUID + "Match if field is not equal to provided value." + ne: UUID + "Match if field value is among the provided list of values." + in: [UUID!] + "Match if field value is not among the provided list of values." + nin: [UUID!] +} + +"Query filter criteris for `[UUID!]` scalar fields." +input UUID_ListFilter { + "Match if list field contains the provided value as a member." + includes: UUID + "Match if list field does not contain the provided value as a member." + excludes: UUID + "Match if list field contains all of the provided values as members." + includesAll: [UUID!] + "Match if list field does not contain any of the provided values as members." + excludesAll: [UUID!] +} + +"Query filter criteria for `Int` scalar fields." +input Int_Filter { + "When true, match if field `IS NULL`. When false, match if field is `NOT NULL`." + isNull: Boolean + "Match if field is exactly equal to provided value." + eq: Int + "Match if field is not equal to provided value." + ne: Int + "Match if field value is among the provided list of values." + in: [Int!] + "Match if field value is not among the provided list of values." + nin: [Int!] + "Match if field value is greater than the provided value." + gt: Int + "Match if field value is greater than or equal to the provided value." + ge: Int + "Match if field value is less than the provided value." + lt: Int + "Match if field value is less than or equal to the provided value." + le: Int +} + +"Query filter criteris for `[Int!]` scalar fields." +input Int_ListFilter { + "Match if list field contains the provided value as a member." + includes: Int + "Match if list field does not contain the provided value as a member." + excludes: Int + "Match if list field contains all of the provided values as members." + includesAll: [Int!] + "Match if list field does not contain any of the provided values as members." + excludesAll: [Int!] +} + +"Query filter criteria for `Int64` scalar fields." +input Int64_Filter { + "When true, match if field `IS NULL`. When false, match if field is `NOT NULL`." + isNull: Boolean + "Match if field is exactly equal to provided value." + eq: Int64 + "Match if field is not equal to provided value." + ne: Int64 + "Match if field value is among the provided list of values." + in: [Int64!] + "Match if field value is not among the provided list of values." + nin: [Int64!] + "Match if field value is greater than the provided value." + gt: Int64 + "Match if field value is greater than or equal to the provided value." + ge: Int64 + "Match if field value is less than the provided value." + lt: Int64 + "Match if field value is less than or equal to the provided value." + le: Int64 +} + +"Query filter criteria for `[Int64!]` scalar fields." +input Int64_ListFilter { + "Match if list field contains the provided value as a member." + includes: Int64 + "Match if list field does not contain the provided value as a member." + excludes: Int64 + "Match if list field contains all of the provided values as members." + includesAll: [Int64!] + "Match if list field does not contain any of the provided values as members." + excludesAll: [Int64!] +} + +"Query filter criteria for `Float` scalar fields." +input Float_Filter { + "When true, match if field `IS NULL`. When false, match if field is `NOT NULL`." + isNull: Boolean + "Match if field is exactly equal to provided value." + eq: Float + "Match if field is not equal to provided value." + ne: Float + "Match if field value is among the provided list of values." + in: [Float!] + "Match if field value is not among the provided list of values." + nin: [Float!] + "Match if field value is greater than the provided value." + gt: Float + "Match if field value is greater than or equal to the provided value." + ge: Float + "Match if field value is less than the provided value." + lt: Float + "Match if field value is less than or equal to the provided value." + le: Float +} + +"Query filter criteria for `[Float!]` scalar fields." +input Float_ListFilter { + "Match if list field contains the provided value as a member." + includes: Float + "Match if list field does not contain the provided value as a member." + excludes: Float + "Match if list field contains all of the provided values as members." + includesAll: [Float!] + "Match if list field does not contain any of the provided values as members." + excludesAll: [Float!] +} + +"Query filter criteria for `Boolean` scalar fields." +input Boolean_Filter { + "When true, match if field `IS NULL`. When false, match if field is `NOT NULL`." + isNull: Boolean + "Match if field is exactly equal to provided value." + eq: Boolean + "Match if field is not equal to provided value." + ne: Boolean + "Match if field value is among the provided list of values." + in: [Boolean!] + "Match if field value is not among the provided list of values." + nin: [Boolean!] +} + +"Query filter criteria for `[Boolean!]` scalar fields." +input Boolean_ListFilter { + "Match if list field contains the provided value as a member." + includes: Boolean + "Match if list field does not contain the provided value as a member." + excludes: Boolean + "Match if list field contains all of the provided values as members." + includesAll: [Boolean!] + "Match if list field does not contain any of the provided values as members." + excludesAll: [Boolean!] +} + +"Query filter criteria for `Any` scalar fields." +input Any_Filter { + "When true, match if field `IS NULL`. When false, match if field is `NOT NULL`." + isNull: Boolean + "Match if field is exactly equal to provided value." + eq: Any + "Match if field is not equal to provided value." + ne: Any + "Match if field value is among the provided list of values." + in: [Any!] + "Match if field value is not among the provided list of values." + nin: [Any!] +} + +"Query filter criteria for `[Any!]` scalar fields." +input Any_ListFilter { + "Match if list field contains the provided value as a member." + includes: Any + "Match if list field does not contain the provided value as a member." + excludes: Any + "Match if list field contains all of the provided values as members." + includesAll: [Any!] + "Match if list field does not contain any of the provided values as members." + excludesAll: [Any!] +} + +""" +(Internal) A string that uniquely identifies a type, field, and so on. + +The most common usage in FDC is `SomeType` or `SomeType.someField`. See the +linked page in the @specifiedBy directive for the GraphQL RFC with more details. +""" +scalar SchemaCoordinate + @specifiedBy(url: "https://github.com/graphql/graphql-wg/blob/6d02705dea034fb65ebc6799632adb7bd550d0aa/rfcs/SchemaCoordinates.md") + @fdc_forbiddenAsFieldType + @fdc_forbiddenAsVariableType + +"(Internal) The purpose of a generated type or field." +enum GeneratedPurpose { + # Implicit fields added to the table types as columns. + IMPLICIT_KEY_FIELD + IMPLICIT_REF_FIELD + + # Relational non-column fields extended to table types. + QUERY_MULTIPLE_ONE_TO_MANY + QUERY_MULTIPLE_MANY_TO_MANY + + # Top-level Query fields. + QUERY_SINGLE + QUERY_MULTIPLE + QUERY_MULTIPLE_BY_SIMILARITY + + # Top-level Mutation fields. + INSERT_SINGLE + INSERT_MULTIPLE + UPSERT_SINGLE + UPSERT_MULTIPLE + UPDATE_SINGLE + UPDATE_MULTIPLE + DELETE_SINGLE + DELETE_MULTIPLE +} + +"(Internal) Added to definitions generated by FDC." +directive @fdc_generated( + "The source type or field that causes this definition to be generated." + from: SchemaCoordinate! + "The reason why this definition is generated, such as the intended use case." + purpose: GeneratedPurpose! +) on + | SCALAR + | OBJECT + | FIELD_DEFINITION + | ARGUMENT_DEFINITION + | INTERFACE + | UNION + | ENUM + | ENUM_VALUE + | INPUT_OBJECT + | INPUT_FIELD_DEFINITION + +type _Service { + "Full Service Definition Language of the Frebase Data Connect Schema, including normalized schema, predefined and generated types." + sdl( + """ + Whether or not to omit Data Connect builtin GraphQL preludes. + They are static GraphQL publically available in the docsite. + """ + omitBuiltin: Boolean = false + """ + Whether or not to omit GQL description in the SDL. + We generate description to document generated schema. + It may bloat the size of SDL. + """ + omitDescription: Boolean = false + ): String! + "Orignal Schema Sources in the service." + schema: String! + "Generated documentation from the schema of the Firebase Data Connect Service." + docs: [_Doc!]! +} + +type _Doc { + "Name of the Doc Page." + page: String! + "The markdown content of the doc page." + markdown: String! +} + +"(Internal) Added to things that may be removed from FDC and will soon be no longer usable in schema or operations." +directive @fdc_deprecated(reason: String = "No longer supported") on + | SCHEMA + | SCALAR + | OBJECT + | FIELD_DEFINITION + | ARGUMENT_DEFINITION + | INTERFACE + | UNION + | ENUM + | ENUM_VALUE + | INPUT_OBJECT + | INPUT_FIELD_DEFINITION + +"(Internal) Added to scalars representing quoted CEL expressions." +directive @fdc_celExpression( + "The expected CEL type that the expression should evaluate to." + returnType: String +) on SCALAR + +"(Internal) Added to scalars representing quoted SQL expressions." +directive @fdc_sqlExpression( + "The expected SQL type that the expression should evaluate to." + dataType: String +) on SCALAR + +"(Internal) Added to types that may not be used as variables." +directive @fdc_forbiddenAsVariableType on SCALAR | OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT + +"(Internal) Added to types that may not be used as fields in schema." +directive @fdc_forbiddenAsFieldType on SCALAR | OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT + +"Provides a frequently used example for this type / field / argument." +directive @fdc_example( + "A GraphQL literal value (verbatim) whose type matches the target." + value: Any + "A human-readable text description of what `value` means in this context." + description: String +) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | INPUT_OBJECT | INPUT_FIELD_DEFINITION + +"(Internal) Marks this field / argument as conflicting with others in the same group." +directive @fdc_oneOf( + "The group name where fields / arguments conflict with each other." + group: String! = "" + "If true, exactly one field / argument in the group must be specified." + required: Boolean! = false +) repeatable on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION + +""" +`UUID` is a string of hexadecimal digits representing an RFC4122-compliant UUID. + +UUIDs are always output as 32 lowercase hexadecimal digits without delimiters or +curly braces. +Inputs in the following formats are also accepted (case insensitive): + +- `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` +- `urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` +- `{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}` + +In the PostgreSQL table, it's stored as [`uuid`](https://www.postgresql.org/docs/current/datatype-uuid.html). +""" +scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122") + +""" +`Int64` is a scalar that represents a 64-bit signed integer. + +In the PostgreSQL table, it's stored as [`bigint`](https://www.postgresql.org/docs/current/datatype-numeric.html). + +On the wire, it's encoded as string because 64-bit integer exceeds the range of JSON number. +""" +scalar Int64 + +""" +The `Any` scalar type accommodates any valid [JSON value](https://www.json.org/json-en.html) +(e.g., numbers, strings, booleans, arrays, objects). PostgreSQL efficiently +stores this data as jsonb, providing flexibility for schemas with evolving structures. + +Caution: JSON doesn't distinguish Int and Float. + +##### Example: + +#### Schema + +```graphql +type Movie @table { + name: String! + metadata: Any! +} +``` + +#### Mutation + +Insert a movie with name and metadata from JSON literal. + +```graphql +mutation InsertMovie { + movie_insert( + data: { + name: "The Dark Knight" + metadata: { + release_year: 2008 + genre: ["Action", "Adventure", "Superhero"] + cast: [ + { name: "Christopher Bale", age: 31 } + { name: "Heath Ledger", age: 28 } + ] + director: "Christopher Nolan" + } + } + ) +} +``` + +Insert a movie with name and metadata that's constructed from a few GQL variables. + +```graphql +mutation InsertMovie($name: String!, $releaseDate: Date!, $genre: [String], $cast: [Any], $director: String!, $boxOfficeInUSD: Int) { + movie_insert(data: { + name: $name, + release_date: $releaseDate, + genre: $genre, + cast: $cast, + director: $director, + box_office: $boxOfficeInUSD + }) +} +``` +**Note**: + + - A mix of non-null and nullable variables can be provided. + + - `Date!` can be passed into scalar `Any` as well! It's stored as string. + + - `$cast` is a nested array. `[Any]` can represent an array of arbitrary types, but it won't enforce the input shape. + +#### Query + +Since `metadata` field has scalar `Any` type, it would return the full JSON in the response. + +**Note**: You can't define selection set to scalar based on [GraphQL spec](https://spec.graphql.org/October2021/#sec-Field-Selections). + +```graphql +query GetAllMovies { + movies { + name + metadata + } +} +``` + +""" +scalar Any @specifiedBy(url: "https://www.json.org/json-en.html") + +""" +The `Void` scalar type represents the absence of any value. It is typically used +in operations where no value is expected in return. +""" +scalar Void + +""" +The `True` scalar type only accepts the boolean value `true`. + +An optional field/argument typed as `True` may either be set +to `true` or omitted (not provided at all). The values `false` or `null` are not +accepted. +""" +scalar True + @fdc_forbiddenAsFieldType + @fdc_forbiddenAsVariableType + @fdc_example(value: true, description: "The only allowed value.") + +""" +A Common Expression Language (CEL) expression that returns a boolean at runtime. + +This expression can reference the `auth` variable, which is null when Firebase +Auth is not used. When Firebase Auth is used, the following fields are available: + + - `auth.uid`: The current user ID. + - `auth.token`: A map containing all token fields (e.g., claims). + +""" +scalar Boolean_Expr + @specifiedBy(url: "https://github.com/google/cel-spec") + @fdc_celExpression(returnType: "bool") + @fdc_forbiddenAsVariableType + @fdc_forbiddenAsFieldType + @fdc_example(value: "auth != null", description: "Allow only if a Firebase Auth user is present.") + +""" +A Common Expression Language (CEL) expression that returns a string at runtime. + +**Limitation**: Currently, only a limited set of expressions are supported. +""" +scalar String_Expr + @specifiedBy(url: "https://github.com/google/cel-spec") + @fdc_celExpression(returnType: "string") + @fdc_forbiddenAsVariableType + @fdc_forbiddenAsFieldType + @fdc_example(value: "auth.uid", description: "The ID of the currently logged in user in Firebase Auth. (Errors if not logged in.)") + @fdc_example(value: "uuidV4()", description: "Generates a new random UUID (version 4) string, formatted as 32 lower-case hex digits without delimiters.") + +""" +A Common Expression Language (CEL) expression that returns a UUID string at runtime. + +**Limitation**: Currently, only a limited set of expressions are supported. +""" +scalar UUID_Expr + @specifiedBy(url: "https://github.com/google/cel-spec") + @fdc_celExpression(returnType: "string") + @fdc_forbiddenAsVariableType + @fdc_forbiddenAsFieldType + @fdc_example(value: "uuidV4()", description: "Generates a new random UUID (version 4) every time.") + +""" +A Common Expression Language (CEL) expression whose return type is unspecified. + +**Limitation**: Only a limited set of expressions are currently supported for each +type. +""" +scalar Any_Expr + @specifiedBy(url: "https://github.com/google/cel-spec") + @fdc_celExpression + @fdc_forbiddenAsVariableType + @fdc_forbiddenAsFieldType + @fdc_example(value: "auth.uid", description: "The ID of the currently logged in user in Firebase Auth. (Errors if not logged in.)") + @fdc_example(value: "uuidV4()", description: "Generates a new random UUID version 4 (formatted as 32 lower-case hex digits without delimiters if result type is String).") + @fdc_example(value: "request.time", description: "The timestamp when the request is received (with microseconds precision).") + +""" +A PostgreSQL value expression whose return type is unspecified. +""" +scalar Any_SQL + @specifiedBy(url: "https://www.postgresql.org/docs/current/sql-expressions.html") + @fdc_sqlExpression + @fdc_forbiddenAsVariableType + @fdc_forbiddenAsFieldType + +""" +Defines a relational database table. + +In this example, we defined one table with a field named `myField`. + +```graphql +type TableName @table { + myField: String +} +``` +Data Connect adds an implicit `id` primary key column. So the above schema is equivalent to: + +```graphql +type TableName @table(key: "id") { + id: String @default(expr: "uuidV4()") + myField: String +} +``` + +Data Connect generates the following SQL table and CRUD operations to use it. + +```sql +CREATE TABLE "public"."table_name" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "my_field" text NULL, + PRIMARY KEY ("id") +) +``` + + * You can lookup a row: `query ($id: UUID!) { tableName(id: $id) { myField } } ` + * You can find rows using: `query tableNames(limit: 20) { myField }` + * You can insert a row: `mutation { tableName_insert(data: {myField: "foo"}) }` + * You can update a row: `mutation ($id: UUID!) { tableName_update(id: $id, data: {myField: "bar"}) }` + * You can delete a row: `mutation ($id: UUID!) { tableName_delete(id: $id) }` + +##### Customizations + +- `@table(singular)` and `@table(plural)` can customize the singular and plural name. +- `@table(name)` can customize the Postgres table name. +- `@table(key)` can customize the primary key field name and type. + +For example, the `User` table often has a `uid` as its primary key. + +```graphql +type User @table(key: "uid") { + uid: String! + name: String +} +``` + + * You can securely lookup a row: `query { user(key: {uid_expr: "auth.uid"}) { name } } ` + * You can securely insert a row: `mutation { user_insert(data: {uid_expr: "auth.uid" name: "Fred"}) }` + * You can securely update a row: `mutation { user_update(key: {uid_expr: "auth.uid"}, data: {name: "New Name"}) }` + * You can securely delete a row: `mutation { user_delete(key: {uid_expr: "auth.uid"}) }` + +`@table` type can be configured further with: + + - Custom SQL data types for columns. See `@col`. + - Add SQL indexes. See `@index`. + - Add SQL unique constraints. See `@unique`. + - Add foreign key constraints to define relations. See `@ref`. + +""" +directive @table( + """ + Configures the SQL database table name. Defaults to snake_case like `table_name`. + """ + name: String + """ + Configures the singular name. Defaults to the camelCase like `tableName`. + """ + singular: String + """ + Configures the plural name. Defaults to infer based on English plural pattern like `tableNames`. + """ + plural: String + """ + Defines the primary key of the table. Defaults to a single field named `id`. + If not present already, Data Connect adds an implicit field `id: UUID! @default(expr: "uuidV4()")`. + """ + key: [String!] +) on OBJECT + +""" +Defines a relational database Raw SQLview. + +Data Connect generates GraphQL queries with WHERE and ORDER BY clauses. +However, not all SQL features has native GraphQL equivalent. + +You can write **an arbitrary SQL SELECT statement**. Data Connect +would map Graphql fields on `@view` type to columns in your SELECT statement. + +* Scalar GQL fields (camelCase) should match a SQL column (snake_case) + in the SQL SELECT statement. +* Reference GQL field can point to another `@table` type. Similar to foreign key + defined with `@ref` on a `@table` type, a `@view` type establishes a relation + when `@ref(fields)` match `@ref(references)` on the target table. + +In this example, you can use `@view(sql)` to define an aggregation view on existing +table. + +```graphql +type User @table { + name: String + score: Int +} +type UserAggregation @view(sql: ''' + SELECT + COUNT(*) as count, + SUM(score) as sum, + AVG(score) as average, + PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY score) AS median, + (SELECT id FROM "user" LIMIT 1) as example_id + FROM "user" +''') { + count: Int + sum: Int + average: Float + median: Float + example: User + exampleId: UUID +} +``` + +###### Example: Query Raw SQL View + +```graphql +query { + userAggregations { + count sum average median + exampleId example { id } + } +} +``` + +##### One-to-One View + +An one-to-one companion `@view` can be handy if you want to argument a `@table` +with additional implied content. + +```graphql +type Restaurant @table { + name: String! +} +type Review @table { + restaurant: Restaurant! + rating: Int! +} +type RestaurantStats @view(sql: ''' + SELECT + restaurant_id, + COUNT(*) AS review_count, + AVG(rating) AS average_rating + FROM review + GROUP BY restaurant_id +''') { + restaurant: Restaurant @unique + reviewCount: Int + averageRating: Float +} +``` + +In this example, `@unique` convey the assumption that each `Restaurant` should +have only one `RestaurantStats` object. + +###### Example: Query One-to-One View + +```graphql +query ListRestaurants { + restaurants { + name + stats: restaurantStats_on_restaurant { + reviewCount + averageRating + } + } +} +``` + +###### Example: Filter based on One-to-One View + +```graphql +query BestRestaurants($minAvgRating: Float, $minReviewCount: Int) { + restaurants(where: { + restaurantStats_on_restaurant: { + averageRating: {ge: $minAvgRating} + reviewCount: {ge: $minReviewCount} + } + }) { name } +} +``` + +##### Customizations + +- One of `@view(sql)` or `@view(name)` should be defined. + `@view(name)` can refer to a persisted SQL view in the Postgres schema. +- `@view(singular)` and `@view(plural)` can customize the singular and plural name. + +`@view` type can be configured further: + + - `@unique` lets you define one-to-one relation. + - `@col` lets you customize SQL column mapping. For example, `@col(name: "column_in_select")`. + +##### Limitations + +Raw SQL view doesn't have a primary key, so it doesn't support lookup. Other +`@table` or `@view` cannot have `@ref` to a view either. + +View cannot be mutated. You can perform CRUD operations on the underlying +table to alter its content. + +**Important: Data Connect doesn't parse and validate SQL** + +- If the SQL view is invalid or undefined, related requests may fail. +- If the SQL view return incompatible types. Firebase Data Connect may surface + errors. +- If a field doesn't have a corresponding column in the SQL SELECT statement, + it will always be `null`. +- There is no way to ensure VIEW to TABLE `@ref` constraint. +- All fields must be nullable in case they aren't found in the SELECT statement + or in the referenced table. + +**Important: You should always test `@view`!** + +""" +directive @view( + """ + The SQL view name. If neither `name` nor `sql` are provided, defaults to the + snake_case of the singular type name. + `name` and `sql` cannot be specified at the same time. + """ + name: String @fdc_oneOf + """ + SQL `SELECT` statement used as the basis for this type. + SQL SELECT columns should use snake_case. GraphQL fields should use camelCase. + `name` and `sql` cannot be specified at the same time. + """ + sql: String @fdc_oneOf + """ + Configures the singular name. Defaults to the camelCase like `viewName`. + """ + singular: String + """ + Configures the plural name. Defaults to infer based on English plural pattern like `viewNames`. + """ + plural: String +) on OBJECT + +""" +Customizes a field that represents a SQL database table column. + +Data Connect maps scalar Fields on `@table` type to a SQL column of +corresponding data type. + +- scalar `UUID` maps to [`uuid`](https://www.postgresql.org/docs/current/datatype-uuid.html). +- scalar `String` maps to [`text`](https://www.postgresql.org/docs/current/datatype-character.html). +- scalar `Int` maps to [`int`](https://www.postgresql.org/docs/current/datatype-numeric.html). +- scalar `Int64` maps to [`bigint`](https://www.postgresql.org/docs/current/datatype-numeric.html). +- scalar `Float` maps to [`double precision`](https://www.postgresql.org/docs/current/datatype-numeric.html). +- scalar `Boolean` maps to [`boolean`](https://www.postgresql.org/docs/current/datatype-boolean.html). +- scalar `Date` maps to [`date`](https://www.postgresql.org/docs/current/datatype-datetime.html). +- scalar `Timestamp` maps to [`timestamptz`](https://www.postgresql.org/docs/current/datatype-datetime.html). +- scalar `Any` maps to [`jsonb`](https://www.postgresql.org/docs/current/datatype-json.html). +- scalar `Vector` maps to [`pgvector`](https://github.com/pgvector/pgvector). + +Array scalar fields are mapped to [Postgres arrays](https://www.postgresql.org/docs/current/arrays.html). + +###### Example: Serial Primary Key + +For example, you can define auto-increment primary key. + +```graphql +type Post @table { + id: Int! @col(name: "post_id", dataType: "serial") +} +``` + +Data Connect converts it to the following SQL table schema. + +```sql +CREATE TABLE "public"."post" ( + "post_id" serial NOT NULL, + PRIMARY KEY ("id") +) +``` + +###### Example: Vector + +```graphql +type Post @table { + content: String! @col(name: "post_content") + contentEmbedding: Vector! @col(size:768) +} +``` + +""" +directive @col( + """ + The SQL database column name. Defaults to snake_case of the field name. + """ + name: String + """ + Configures the custom SQL data type. + + Each GraphQL type can map to multiple SQL data types. + Refer to [Postgres supported data types](https://www.postgresql.org/docs/current/datatype.html). + + Incompatible SQL data type will lead to undefined behavior. + """ + dataType: String + """ + Required on `Vector` columns. It specifies the length of the Vector. + `textembedding-gecko@003` model generates `Vector` of `@col(size:768)`. + """ + size: Int +) on FIELD_DEFINITION + + +""" +Defines a foreign key reference to another table. + +For example, we can define a many-to-one relation. + +```graphql +type ManyTable @table { + refField: OneTable! +} +type OneTable @table { + someField: String! +} +``` +Data Connect adds implicit foreign key column and relation query field. So the +above schema is equivalent to the following schema. + +```graphql +type ManyTable @table { + id: UUID! @default(expr: "uuidV4()") + refField: OneTable! @ref(fields: "refFieldId", references: "id") + refFieldId: UUID! +} +type OneTable @table { + id: UUID! @default(expr: "uuidV4()") + someField: UUID! + # Generated Fields: + # manyTables_on_refField: [ManyTable!]! +} +``` +Data Connect generates the necessary foreign key constraint. + +```graphql +CREATE TABLE "public"."many_table" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "ref_field_id" uuid NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "many_table_ref_field_id_fkey" FOREIGN KEY ("ref_field_id") REFERENCES "public"."one_table" ("id") ON DELETE CASCADE +) +``` + +###### Example: Traverse the Reference Field + +```graphql +query ($id: UUID!) { + manyTable(id: $id) { + refField { id } + } +} +``` + +###### Example: Reverse Traverse the Reference field + +```graphql +query ($id: UUID!) { + oneTable(id: $id) { + manyTables_on_refField { id } + } +} +``` + +##### Optional Many-to-One Relation + +An optional foreign key reference will be set to null if the referenced row is deleted. + +In this example, if a `User` is deleted, the `assignee` and `reporter` +references will be set to null. + +```graphql +type Bug @table { + title: String! + assignee: User + reproter: User +} + +type User @table { name: String! } +``` + +##### Required Many-to-One Relation + +A required foreign key reference will cascade delete if the referenced row is +deleted. + +In this example, if a `Post` is deleted, associated comments will also be +deleted. + +```graphql +type Comment @table { + post: Post! + content: String! +} + +type Post @table { title: String! } +``` + +##### Many To Many Relation + +You can define a many-to-many relation with a join table. + +```graphql +type Membership @table(key: ["group", "user"]) { + group: Group! + user: User! + role: String! @default(value: "member") +} + +type Group @table { name: String! } +type User @table { name: String! } +``` + +When Data Connect sees a table with two reference field as its primary key, it +knows this is a join table, so expands the many-to-many query field. + +```graphql +type Group @table { + name: String! + # Generated Fields: + # users_via_Membership: [User!]! + # memberships_on_group: [Membership!]! +} +type User @table { + name: String! + # Generated Fields: + # groups_via_Membership: [Group!]! + # memberships_on_user: [Membership!]! +} +``` + +###### Example: Traverse the Many-To-Many Relation + +```graphql +query ($id: UUID!) { + group(id: $id) { + users: users_via_Membership { + name + } + } +} +``` + +###### Example: Traverse to the Join Table + +```graphql +query ($id: UUID!) { + group(id: $id) { + memberships: memberships_on_group { + user { name } + role + } + } +} +``` + +##### One To One Relation + +You can even define a one-to-one relation with the help of `@unique` or `@table(key)`. + +```graphql +type User @table { + name: String +} +type Account @table { + user: User! @unique +} +# Alternatively, use primary key constraint. +# type Account @table(key: "user") { +# user: User! +# } +``` + +###### Example: Transerse the Reference Field + +```graphql +query ($id: UUID!) { + account(id: $id) { + user { id } + } +} +``` + +###### Example: Reverse Traverse the Reference field + +```graphql +query ($id: UUID!) { + user(id: $id) { + account_on_user { id } + } +} +``` + +##### Customizations + +- `@ref(constraintName)` can customize the SQL foreign key constraint name (`table_name_ref_field_fkey` above). +- `@ref(fields)` can customize the foreign key field names. +- `@ref(references)` can customize the constraint to reference other columns. + By default, `@ref(references)` is the primary key of the `@ref` table. + Other fields with `@unique` may also be referred in the foreign key constraint. + +""" +directive @ref( + "The SQL database foreign key constraint name. Defaults to snake_case `{table_name}_{field_name}_fkey`." + constraintName: String + """ + Foreign key fields. Defaults to `{tableName}{PrimaryIdName}`. + """ + fields: [String!] + "The fields that the foreign key references in the other table. Defaults to its primary key." + references: [String!] +) on FIELD_DEFINITION + +"Defines the orderBy direction in a query." +enum OrderDirection { +"Results are ordered in ascending order." + ASC +"Results are ordered in descending order." + DESC +} + +""" +Specifies the default value for a column field. + +For example: + +```graphql +type User @table(key: "uid") { + uid: String! @default(expr: "auth.uid") + number: Int! @col(dataType: "serial") + createdAt: Date! @default(expr: "request.time") + role: String! @default(value: "Member") + credit: Int! @default(value: 100) +} +``` + +The supported arguments vary based on the field type. +""" +directive @default( + "A constant value validated against the field's GraphQL type during compilation." + value: Any @fdc_oneOf(required: true) + "A CEL expression whose return value must match the field's data type." + expr: Any_Expr @fdc_oneOf(required: true) + """ + A raw SQL expression, whose SQL data type must match the underlying column. + + The value is any variable-free expression (in particular, cross-references to + other columns in the current table are not allowed). Subqueries are not allowed either. + See [PostgreSQL defaults](https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-PARMS-DEFAULT) + for more details. + """ + sql: Any_SQL @fdc_oneOf(required: true) +) on FIELD_DEFINITION + +""" +Defines a database index to optimize query performance. + +```graphql +type User @table @index(fields: ["name", "phoneNumber"], order: [ASC, DESC]) { + name: String @index + phoneNumber: Int64 @index + tags: [String] @index # GIN Index +} +``` + +##### Single Field Index + +You can put `@index` on a `@col` field to create a SQL index. + +`@index(order)` matters little for single field indexes, as they can be scanned +in both directions. + +##### Composite Index + +You can put `@index(fields: [...])` on `@table` type to define composite indexes. + +`@index(order: [...])` can customize the index order to satisfy particular +filter and order requirement. + +""" +directive @index( + """ + Configure the SQL database index id. + + If not overridden, Data Connect generates the index name: + - `{table_name}_{first_field}_{second_field}_aa_idx` + - `{table_name}_{field_name}_idx` + """ + name: String + """ + Only allowed and required when used on a `@table` type. + Specifies the fields to create the index on. + """ + fields: [String!] + """ + Only allowed for `BTREE` `@index` on `@table` type. + Specifies the order for each indexed column. Defaults to all `ASC`. + """ + order: [IndexFieldOrder!] + """ + Customize the index type. + + For most index, it defaults to `BTREE`. + For array fields, only allowed `IndexType` is `GIN`. + For `Vector` fields, defaults to `HNSW`, may configure to `IVFFLAT`. + """ + type: IndexType + """ + Only allowed when used on vector field. + Defines the vector similarity method. Defaults to `INNER_PRODUCT`. + """ + vector_method: VectorSimilarityMethod +) repeatable on FIELD_DEFINITION | OBJECT + +"Specifies the sorting order for database indexes." +enum IndexFieldOrder { + "Sorts the field in ascending order (from lowest to highest)." + ASC + "Sorts the field in descending order (from highest to lowest)." + DESC +} + +"Defines the type of index to be used in the database." +enum IndexType { + "A general-purpose index type commonly used for sorting and searching." + BTREE + "Generalized Inverted Index, optimized for indexing composite values such as arrays." + GIN + "Hierarchical Navigable Small World graph, used for nearest-neighbor searches on vector fields." + HNSW + "Inverted File Index, optimized for approximate nearest-neighbor searches in vector databases." + IVFFLAT +} + +""" +Defines unique constraints on `@table`. + +For example, + +```graphql +type User @table { + phoneNumber: Int64 @unique +} +type UserProfile @table { + user: User! @unique + address: String @unique +} +``` + +- `@unique` on a `@col` field adds a single-column unique constraint. +- `@unique` on a `@table` type adds a composite unique constraint. +- `@unique` on a `@ref` defines a one-to-one relation. It adds unique constraint + on `@ref(fields)`. + +`@unique` ensures those fields can uniquely identify a row, so other `@table` +type may define `@ref(references)` to refer to fields that has a unique constraint. + +""" +directive @unique( + """ + Configures the SQL database unique constraint name. + + If not overridden, Data Connect generates the unique constraint name: + - `table_name_first_field_second_field_uidx` + - `table_name_only_field_name_uidx` + """ + indexName: String + """ + Only allowed and required when used on OBJECT, + this specifies the fields to create a unique constraint on. + """ + fields: [String!] +) repeatable on FIELD_DEFINITION | OBJECT + +""" +Date is a string in the YYYY-MM-DD format representing a local-only date. + +See the description for Timestamp for range and limitations. + +As a FDC-specific extension, inputs that includes time portions (as specified by +the Timestamp scalar) are accepted but only the date portion is used. In other +words, only the part before "T" is used and the rest discarded. This effectively +truncates it to the local date in the specified time-zone. + +Outputs will always be in the canonical YYYY-MM-DD format. + +In the PostgreSQL table, it's stored as [`date`](https://www.postgresql.org/docs/current/datatype-datetime.html). +""" +scalar Date @specifiedBy(url: "https://scalars.graphql.org/andimarek/local-date.html") + +""" +Timestamp is a RFC 3339 string that represents an exact point in time. + +The serialization format follows https://scalars.graphql.org/andimarek/date-time +except the "Non-optional exact milliseconds" Section. As a FDC-specific +extension, inputs and outputs may contain 0, 3, 6, or 9 fractional digits. + +Specifically, output precision varies by server-side factors such as data source +support and clients must not rely on an exact number of digits. Clients may +truncate extra digits as fit, with the caveat that there may be information loss +if the truncated value is subsequently sent back to the server. + +FDC only supports year 1583 to 9999 (inclusive) and uses the ISO-8601 calendar +system for all date-time calculations. Notably, the expanded year representation +(+/-YYYYY) is rejected and Year 1582 and before may either be rejected or cause +undefined behavior. + +In the PostgreSQL table, it's stored as [`timestamptz`](https://www.postgresql.org/docs/current/datatype-datetime.html). +""" +scalar Timestamp @specifiedBy(url: "https://scalars.graphql.org/andimarek/date-time") + +""" +A Common Expression Language (CEL) expression that returns a Timestamp at runtime. + +Limitation: Right now, only a few expressions are supported. +""" +scalar Timestamp_Expr + @specifiedBy(url: "https://github.com/google/cel-spec") + @fdc_celExpression(returnType: "google.protobuf.Timestamp") + @fdc_forbiddenAsVariableType + @fdc_forbiddenAsFieldType + @fdc_example(value: "request.time", description: "The timestamp when the request is received (with microseconds precision).") + +""" +A Common Expression Language (CEL) expression that returns a Timestamp at runtime, +which is then truncated to UTC date only. The time-of-day parts are discarded. + +Limitation: Right now, only a few expressions are supported. +""" +scalar Date_Expr + @specifiedBy(url: "https://github.com/google/cel-spec") + @fdc_celExpression(returnType: "google.protobuf.Timestamp") + @fdc_forbiddenAsVariableType + @fdc_forbiddenAsFieldType + @fdc_example(value: "request.time", description: "The UTC date on which the request is received.") + +"Conditions on a `Date` value." +input Date_Filter { + "Match if the field `IS NULL`." + isNull: Boolean + "Match if the field is exactly equal to the provided value." + eq: Date @fdc_oneOf(group: "eq") + "Match if the field equals the provided CEL expression." + eq_expr: Date_Expr @fdc_oneOf(group: "eq") + "Match if the field equals the provided relative date." + eq_date: Date_Relative @fdc_oneOf(group: "eq") + "Match if the field is not equal to the provided value." + ne: Date @fdc_oneOf(group: "ne") + "Match if the field is not equal to the provided CEL expression." + ne_expr: Date_Expr @fdc_oneOf(group: "ne") + "Match if the field is not equal to the provided relative date." + ne_date: Date_Relative @fdc_oneOf(group: "ne") + "Match if the field value is among the provided list of values." + in: [Date!] + "Match if the field value is not among the provided list of values." + nin: [Date!] + "Match if the field value is greater than the provided value." + gt: Date @fdc_oneOf(group: "gt") + "Match if the field value is greater than the provided CEL expression." + gt_expr: Date_Expr @fdc_oneOf(group: "gt") + "Match if the field value is greater than the provided relative date." + gt_date: Date_Relative @fdc_oneOf(group: "gt") + "Match if the field value is greater than or equal to the provided value." + ge: Date @fdc_oneOf(group: "ge") + "Match if the field value is greater than or equal to the provided CEL expression." + ge_expr: Date_Expr @fdc_oneOf(group: "ge") + "Match if the field value is greater than or equal to the provided relative date." + ge_date: Date_Relative @fdc_oneOf(group: "ge") + "Match if the field value is less than the provided value." + lt: Date @fdc_oneOf(group: "lt") + "Match if the field value is less than the provided CEL expression." + lt_expr: Date_Expr @fdc_oneOf(group: "lt") + "Match if the field value is less than the provided relative date." + lt_date: Date_Relative @fdc_oneOf(group: "lt") + "Match if the field value is less than or equal to the provided value." + le: Date @fdc_oneOf(group: "le") + "Match if the field value is less than or equal to the provided CEL expression." + le_expr: Date_Expr @fdc_oneOf(group: "le") + "Match if the field value is less than or equal to the provided relative date." + le_date: Date_Relative @fdc_oneOf(group: "le") +} + +"Conditions on a`Date` list." +input Date_ListFilter { + "Match if the list contains the provided date." + includes: Date @fdc_oneOf(group: "includes") + "Match if the list contains the provided date CEL expression." + includes_expr: Date_Expr @fdc_oneOf(group: "includes") + "Match if the list contains the provided relative date." + includes_date: Date_Relative @fdc_oneOf(group: "includes") + "Match if the list does not contain the provided date." + excludes: Date @fdc_oneOf(group: "excludes") + "Match if the list does not contain the provided date CEL expression." + excludes_expr: Date_Expr @fdc_oneOf(group: "excludes") + "Match if the list does not contain the provided relative date." + excludes_date: Date_Relative @fdc_oneOf(group: "excludes") + "Match if the list contains all the provided dates." + includesAll: [Date!] + "Match if the list contains none of the provided dates." + excludesAll: [Date!] +} + +"Conditions on a `Timestamp` value." +input Timestamp_Filter { + "Match if the field `IS NULL`." + isNull: Boolean + "Match if the field is exactly equal to the provided value." + eq: Timestamp @fdc_oneOf(group: "eq") + "Match if the field equals the provided CEL expression." + eq_expr: Timestamp_Expr @fdc_oneOf(group: "eq") + "Match if the field equals the provided relative time." + eq_time: Timestamp_Relative @fdc_oneOf(group: "eq") + "Match if the field is not equal to the provided value." + ne: Timestamp @fdc_oneOf(group: "ne") + "Match if the field is not equal to the provided CEL expression." + ne_expr: Timestamp_Expr @fdc_oneOf(group: "ne") + "Match if the field is not equal to the provided relative time." + ne_time: Timestamp_Relative @fdc_oneOf(group: "ne") + "Match if the field value is among the provided list of values." + in: [Timestamp!] + "Match if the field value is not among the provided list of values." + nin: [Timestamp!] + "Match if the field value is greater than the provided value." + gt: Timestamp @fdc_oneOf(group: "gt") + "Match if the field value is greater than the provided CEL expression." + gt_expr: Timestamp_Expr @fdc_oneOf(group: "gt") + "Match if the field value is greater than the provided relative time." + gt_time: Timestamp_Relative @fdc_oneOf(group: "gt") + "Match if the field value is greater than or equal to the provided value." + ge: Timestamp @fdc_oneOf(group: "ge") + "Match if the field value is greater than or equal to the provided CEL expression." + ge_expr: Timestamp_Expr @fdc_oneOf(group: "ge") + "Match if the field value is greater than or equal to the provided relative time." + ge_time: Timestamp_Relative @fdc_oneOf(group: "ge") + "Match if the field value is less than the provided value." + lt: Timestamp @fdc_oneOf(group: "lt") + "Match if the field value is less than the provided CEL expression." + lt_expr: Timestamp_Expr @fdc_oneOf(group: "lt") + "Match if the field value is less than the provided relative time." + lt_time: Timestamp_Relative @fdc_oneOf(group: "lt") + "Match if the field value is less than or equal to the provided value." + le: Timestamp @fdc_oneOf(group: "le") + "Match if the field value is less than or equal to the provided CEL expression." + le_expr: Timestamp_Expr @fdc_oneOf(group: "le") + "Match if the field value is less than or equal to the provided relative time." + le_time: Timestamp_Relative @fdc_oneOf(group: "le") +} + +"Conditions on a `Timestamp` list." +input Timestamp_ListFilter { + "Match if the list contains the provided timestamp." + includes: Timestamp @fdc_oneOf(group: "includes") + "Match if the list contains the provided timestamp CEL expression." + includes_expr: Timestamp_Expr @fdc_oneOf(group: "includes") + "Match if the list contains the provided relative timestamp." + includes_time: Timestamp_Relative @fdc_oneOf(group: "includes") + "Match if the list does not contain the provided timestamp." + excludes: Timestamp @fdc_oneOf(group: "excludes") + "Match if the list does not contain the provided timestamp CEL expression." + excludes_expr: Timestamp_Expr @fdc_oneOf(group: "excludes") + "Match if the list does not contain the provided relative timestamp." + excludes_time: Timestamp_Relative @fdc_oneOf(group: "excludes") + "Match if the list contains all the provided timestamps." + includesAll: [Timestamp!] + "Match if the list contains none of the provided timestamps." + excludesAll: [Timestamp!] +} + +"Update input of a `Date` value." +input Date_Update { + "Set the field to the provided date." + set: Date @fdc_oneOf(group: "set") + "Set the field to the provided date CEL expression." + set_expr: Date_Expr @fdc_oneOf(group: "set") + "Set the field to the provided relative date." + set_date: Date_Relative @fdc_oneOf(group: "set") +} + +"Update input of a `Date` list value." +input Date_ListUpdate { + "Replace the current list with the provided list of `Date` values." + set: [Date!] + "Append the provided `Date` values to the existing list." + append: [Date!] + "Prepend the provided `Date` values to the existing list." + prepend: [Date!] + "Remove the date value at the specified index." + delete: Int + "The index of the list to perform updates." + i: Int + "Update the date value at the specified index." + update: Date +} + +"Update input of a `Timestamp` value." +input Timestamp_Update { + "Set the field to the provided timestamp." + set: Timestamp @fdc_oneOf(group: "set") + "Set the field to the provided timestamp CEL expression." + set_expr: Timestamp_Expr @fdc_oneOf(group: "set") + "Set the field to the provided relative timestamp." + set_time: Timestamp_Relative @fdc_oneOf(group: "set") +} + +"Update input of an `Timestamp` list value." +input Timestamp_ListUpdate { + "Replace the current list with the provided list of `Timestamp` values." + set: [Timestamp!] + "Append the provided `Timestamp` values to the existing list." + append: [Timestamp!] + "Prepend the provided `Timestamp` values to the existing list." + prepend: [Timestamp!] + "Remove the timestamp value at the specified index." + delete: Int + "The index of the list to perform updates." + i: Int + "Update the timestamp value at the specified index." + update: Timestamp +} + + +"A runtime-calculated `Timestamp` value relative to `now` or `at`." +input Timestamp_Relative @fdc_forbiddenAsVariableType @fdc_forbiddenAsFieldType { + "Match for the current time." + now: True @fdc_oneOf(group: "from", required: true) + "A specific timestamp for matching." + at: Timestamp @fdc_oneOf(group: "from", required: true) + "Add the provided duration to the base timestamp." + add: Timestamp_Duration + "Subtract the provided duration from the base timestamp." + sub: Timestamp_Duration + "Truncate the timestamp to the provided interval." + truncateTo: Timestamp_Interval +} + +input Timestamp_Duration @fdc_forbiddenAsVariableType @fdc_forbiddenAsFieldType { + "The number of milliseconds for the duration." + milliseconds: Int! = 0 + "The number of seconds for the duration." + seconds: Int! = 0 + "The number of minutes for the duration." + minutes: Int! = 0 + "The number of hours for the duration." + hours: Int! = 0 + "The number of days for the duration." + days: Int! = 0 + "The number of weeks for the duration." + weeks: Int! = 0 + "The number of months for the duration." + months: Int! = 0 + "The number of years for the duration." + years: Int! = 0 +} + +enum Timestamp_Interval @fdc_forbiddenAsFieldType { + "Represents a time interval of one second." + SECOND + "Represents a time interval of one minute." + MINUTE + "Represents a time interval of one hour." + HOUR + "Represents a time interval of one day." + DAY + "Represents a time interval of one week." + WEEK + "Represents a time interval of one month." + MONTH + "Represents a time interval of one year." + YEAR +} + +"A runtime-calculated Date value relative to `today` or `on`." +input Date_Relative @fdc_forbiddenAsVariableType @fdc_forbiddenAsFieldType { + "Match for today’s date." + today: True @fdc_oneOf(group: "from", required: true) + "A specific date for matching." + on: Date @fdc_oneOf(group: "from", required: true) + "Add the provided duration to the base date." + add: Date_Duration + "Subtract the provided duration from the base date." + sub: Date_Duration + "Truncate the date to the provided interval." + truncateTo: Date_Interval +} + +input Date_Duration @fdc_forbiddenAsVariableType @fdc_forbiddenAsFieldType { + "The number of days for the duration." + days: Int! = 0 + "The number of weeks for the duration." + weeks: Int! = 0 + "The number of months for the duration." + months: Int! = 0 + "The number of years for the duration." + years: Int! = 0 +} + +enum Date_Interval @fdc_forbiddenAsFieldType { + "Represents a time interval of one week." + WEEK + "Represents a time interval of one month." + MONTH + "Represents a time interval of one year." + YEAR +} + +"Update input of a `String` value." +input String_Update { + "Set the field to a provided value." + set: String @fdc_oneOf(group: "set") + "Set the field to a provided server value expression." + set_expr: String_Expr @fdc_oneOf(group: "set") +} + +"Update input of a `String` list value." +input String_ListUpdate { + "Set the list with the provided values." + set: [String!] + "Append the provided values to the existing list." + append: [String!] + "Prepend the provided values to the existing list." + prepend: [String!] +} + +"Update input of a `UUID` value." +input UUID_Update { + "Set the field to a provided UUID." + set: UUID @fdc_oneOf(group: "set") + "Set the field to a provided UUID expression." + set_expr: UUID_Expr @fdc_oneOf(group: "set") +} + +"Update input of an `ID` list value." +input UUID_ListUpdate { + "Set the list with the provided list of UUIDs." + set: [UUID!] + "Append the provided UUIDs to the existing list." + append: [UUID!] + "Prepend the provided UUIDs to the existing list." + prepend: [UUID!] +} + +"Update input of an `Int` value." +input Int_Update { + "Set the field to a provided value." + set: Int + "Increment the field by a provided value." + inc: Int + "Decrement the field by a provided value." + dec: Int +} + +"Update input of an `Int` list value." +input Int_ListUpdate { + "Set the list with the provided values." + set: [Int!] + "Append the provided list of values to the existing list." + append: [Int!] + "Prepend the provided list of values to the existing list." + prepend: [Int!] +} + +"Update input of an `Int64` value." +input Int64_Update { + "Set the field to a provided value." + set: Int64 + "Increment the field by a provided value." + inc: Int64 + "Decrement the field by a provided value." + dec: Int64 +} + +"Update input of an `Int64` list value." +input Int64_ListUpdate { + "Replace the list with the provided values." + set: [Int64!] + "Append the provided list of values to the existing list." + append: [Int64!] + "Prepend the provided list of values to the existing list." + prepend: [Int64!] +} + +"Update input of a `Float` value." +input Float_Update { + "Set the field to a provided value." + set: Float + "Increment the field by a provided value." + inc: Float + "Decrement the field by a provided value." + dec: Float +} + +"Update input of a `Float` list value." +input Float_ListUpdate { + "Set the list with the provided values." + set: [Float!] + "Append the provided list of values to the existing list." + append: [Float!] + "Prepend the provided list of values to the existing list." + prepend: [Float!] +} + +"Update input of a `Boolean` value." +input Boolean_Update { + "Set the field to a provided value." + set: Boolean +} + +"Update input of a `Boolean` list value." +input Boolean_ListUpdate { + "Set the list with the provided values." + set: [Boolean!] + "Append the provided list of values to the existing list." + append: [Boolean!] + "Prepend the provided list of values to the existing list." + prepend: [Boolean!] +} + +"Update input of an `Any` value." +input Any_Update { + "Set the field to a provided value." + set: Any +} + +"Update input of an `Any` list value." +input Any_ListUpdate { + "Set the list with the provided values." + set: [Any!] + "Append the provided list of values to the existing list." + append: [Any!] + "Prepend the provided list of values to the existing list." + prepend: [Any!] +} + +type Query { + """ + _service provides customized introspection on Firebase Data Connect Sevice. + """ + _service: _Service! +} + +""" +Vector is an array of single-precision floating-point numbers, serialized +as a JSON array. All elements must be finite (no NaN, Infinity or -Infinity). + +Example: [1.1, 2, 3.3] + +In the PostgreSQL table, it's stored as [`pgvector`](https://github.com/pgvector/pgvector). + +See `Vector_Embed` for how to generate text embeddings in query and mutations. +""" +scalar Vector + +""" +Defines the similarity function to use when comparing vectors in queries. + +Defaults to `INNER_PRODUCT`. + +View [all vector functions](https://github.com/pgvector/pgvector?tab=readme-ov-file#vector-functions). +""" +enum VectorSimilarityMethod { + "Measures the Euclidean (L2) distance between two vectors." + L2 + "Measures the cosine similarity between two vectors." + COSINE + "Measures the inner product(dot product) between two vectors." + INNER_PRODUCT +} + +"Conditions on a Vector value." +input Vector_Filter { + "Match if the field is exactly equal to the provided vector." + eq: Vector + "Match if the field is not equal to the provided vector." + ne: Vector + "Match if the field value is among the provided list of vectors." + in: [Vector!] + "Match if the field value is not among the provided list of vectors." + nin: [Vector!] + "Match if the field is `NULL`." + isNull: Boolean +} + +input Vector_ListFilter { + "Match if the list includes the supplied vector." + includes: Vector + "Match if the list does not include the supplied vector." + excludes: Vector + "Match if the list contains all the provided vectors." + includesAll: [Vector!] + "Match if the list contains none of the provided vectors." + excludesAll: [Vector!] +} + +"Update input of a Vector value." +input Vector_Update { + "Set the field to the provided vector value." + set: Vector @fdc_oneOf(group: "set") + "Set the field to the vector embedding result from a text input." + set_embed: Vector_Embed @fdc_oneOf(group: "set") +} + + +"Update input of a Vector list value." +input Vector_ListUpdate { + "Replace the current list with the provided list of Vector values." + set: [Vector] + "Append the provided Vector values to the existing list." + append: [Vector] + "Prepend the provided Vector values to the existing list." + prepend: [Vector] + "Delete the vector at the specified index." + delete: Int + "The index of the vector to be updated." + i: Int + "Update the vector at the specified index." + update: Vector +} + +""" +Create a vector embedding of text using the given model on Vertex AI. + +Cloud SQL for Postgresql natively integrates with [Vertex AI Text embeddings API](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text-embeddings-api) +to effectively generate text embeddings. + +If you uses [`Vector`](scalar.md#Vector) in your schema, Firebase Data Connect automatically installs +[`pgvector`](https://github.com/pgvector/pgvector) and [`google_ml_integration`](https://cloud.google.com/sql/docs/postgres/integrate-cloud-sql-with-vertex-ai) +Postgres extensions in your Cloud SQL database. + +Given a Post table with a `Vector` embedding field. + +```graphql +type Post @table { + content: String! + contentEmbedding: Vector @col(size:768) +} +``` + +NOTE: All natively supported `Vector_Embed_Model` generates vector of length `768`. + +###### Example: Insert embedding + +```graphql +mutation CreatePost($content: String!) { + post_insert(data: { + content: $content, + contentEmbedding_embed: {model: "textembedding-gecko@003", text: $content}, + }) +} +``` + +###### Example: Vector similarity Search + +```graphql +query SearchPost($query: String!) { + posts_contentEmbedding_similarity(compare_embed: {model: "textembedding-gecko@003", text: $query}) { + id + content + } +} +``` +""" +input Vector_Embed @fdc_forbiddenAsVariableType { + """ + The model to use for vector embedding. + Recommend the latest stable model: `textembedding-gecko@003`. + """ + model: Vector_Embed_Model! + "The text to generate the vector embedding from." + text: String! +} + +""" +The Vertex AI model version that is required in input `Vector_Embed`. + +It is recommended to use the latest stable model version: `textembedding-gecko@003`. + +View all supported [Vertex AI Text embeddings APIs](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text-embeddings-api). +""" +scalar Vector_Embed_Model + @specifiedBy(url: "https://cloud.google.com/vertex-ai/generative-ai/docs/learn/model-versioning") + @fdc_forbiddenAsVariableType + @fdc_forbiddenAsFieldType + @fdc_example(value: "textembedding-gecko@003", description: "A stable version of the textembedding-gecko model") + @fdc_example(value: "textembedding-gecko@001", description: "An older version of the textembedding-gecko model") + @fdc_example(value: "text-embedding-004", description: "Another text embedding model") + +""" +Redact a part of the response from the client. + +Redacted fields are still evaluated for side effects (including data changes and +`@check`) and the results are still available to later steps in CEL expressions +(via `response.fieldName`). +""" +directive @redact on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +""" +Ensure this field is present and is not null or `[]`, or abort the request / transaction. + +A CEL expression, `expr` is used to test the field value. It defaults to +rejecting null and `[]` but a custom expression can be provided instead. + +If the field occurs multiple times (i.e. directly or indirectly nested under a +list), `expr` will be executed once for each occurrence and `@check` succeeds if +all values succeed. `@check` fails when the field is not present at all (i.e. +all ancestor paths contain `null` or `[]`), unless `optional` is true. + +If a `@check` fails in a mutation, the top-level field containing it will be +replaced with a partial error, whose message can be customzied via the `message` +argument. Each subsequent top-level fields will return an aborted error (i.e. +not executed). To rollback previous steps, see `@transaction`. +""" +directive @check( + """ + The CEL expression to test the field value (or values if nested under a list). + + Within the CEL expression, a special value `this` evaluates to the field that + this directive is attached to. If this field occurs multiple times because + any ancestor is a list, each occurrence is tested with `this` bound to each + value. When the field itself is a list or object, `this` follows the same + structure (including all decendants selected in case of objects). + + For any given path, if an ancestor is `null` or `[]`, the field will not be + reached and the CEL evaluation will be skipped for that path. In other words, + evaluation only takes place when `this` is `null` or non-null, but never + undefined. (See also the `optional` argument.) + """ + expr: Boolean_Expr! = "!(this in [null, []])" + """ + The error message to return to the client if the check fails. + + Defaults to "permission denied" if not specified. + """ + message: String! = "permission denied" + """ + Whether the check should pass or fail (default) when the field is not present. + + A field will not be reached at a given path if its parent or any ancestor is + `[]` or `null`. When this happens to all paths, the field will not be present + anywhere in the response tree. In other words, `expr` is evaluated 0 times. + By default, @check will automatically fail in this case. Set this argument to + `true` to make it pass even if no tests are run (a.k.a. "vacuously true"). + """ + optional: Boolean = false +) repeatable on QUERY | MUTATION | FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT + +type Mutation { + """ + Run a query during the mutation and add fields into the response. + + Example: foo: query { users { id } } will add a field foo: {users: [{id: "..."}, …]} into the response JSON. + + Note: Data fetched this way can be handy for permission checks. See @check. + """ + query: Query +} + diff --git a/dataconnect/flutter-movie/dataconnect/connector/connector.yaml b/dataconnect/flutter-movie/dataconnect/connector/connector.yaml new file mode 100644 index 00000000..b1556370 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/connector/connector.yaml @@ -0,0 +1,5 @@ +connectorId: movies +generate: + dartSdk: + outputDir: ../../lib/movies_connector + package: movies_connector diff --git a/dataconnect/flutter-movie/dataconnect/connector/mutations.gql b/dataconnect/flutter-movie/dataconnect/connector/mutations.gql new file mode 100644 index 00000000..82a899a7 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/connector/mutations.gql @@ -0,0 +1,102 @@ +mutation UpsertUser($username: String!) @auth(level: USER) { + user_upsert( + data: { + id_expr: "auth.uid" + username: $username + } + ) +} + +# Add a movie to the user's favorites list +mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) { + favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId }) +} + +# Remove a movie from the user's favorites list +mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) { + favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId }) +} + +# Add a review for a movie +mutation AddReview($movieId: UUID!, $rating: Int!, $reviewText: String!) +@auth(level: USER) { + review_upsert( + data: { + userId_expr: "auth.uid" + movieId: $movieId + rating: $rating + reviewText: $reviewText + reviewDate_date: { today: true } + } + ) +} + +# Update a user's review for a movie +mutation UpdateReview($movieId: UUID!, $rating: Int!, $reviewText: String!) +@auth(level: USER) { + review_update( + key: { userId_expr: "auth.uid", movieId: $movieId } + data: { + userId_expr: "auth.uid" + movieId: $movieId + rating: $rating + reviewText: $reviewText + reviewDate_date: { today: true } + } + ) +} + +# Delete a user's review for a movie +mutation DeleteReview($movieId: UUID!) @auth(level: USER) { + review_delete(key: { userId_expr: "auth.uid", movieId: $movieId }) +} + +# The mutations below are unused by the application, but are useful examples for more complex cases + +# Create a movie based on user input +# mutation CreateMovie( +# $title: String! +# $releaseYear: Int! +# $genre: String! +# $rating: Float +# $description: String +# $imageUrl: String! +# $tags: [String!] = [] +# ) @auth(expr: "auth.token.isAdmin == true") { + +# } +# Update movie information based on the provided ID +# mutation UpdateMovie( +# $id: UUID! +# $title: String +# $releaseYear: Int +# $genre: String +# $rating: Float +# $description: String +# $imageUrl: String +# $tags: [String!] = [] +# ) @auth(level: USER_EMAIL_VERIFIED) { +# movie_update( +# id: $id +# data: { +# title: $title +# releaseYear: $releaseYear +# genre: $genre +# rating: $rating +# description: $description +# imageUrl: $imageUrl +# tags: $tags +# } +# ) +# } + +# Delete a movie by its ID +# mutation DeleteMovie($id: UUID!) @auth(level: USER_EMAIL_VERIFIED) { +# movie_delete(id: $id) +# } + +# Delete movies with a rating lower than the specified minimum rating +# mutation DeleteUnpopularMovies($minRating: Float!) @auth(level: USER_EMAIL_VERIFIED) { +# movie_deleteMany(where: { rating: { le: $minRating } }) +# } +# End of example mutations \ No newline at end of file diff --git a/dataconnect/flutter-movie/dataconnect/connector/queries.gql b/dataconnect/flutter-movie/dataconnect/connector/queries.gql new file mode 100644 index 00000000..f0904ba0 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/connector/queries.gql @@ -0,0 +1,357 @@ +# List subset of fields for movies +query ListMovies($orderByRating: OrderDirection, $orderByReleaseYear: OrderDirection, $limit: Int) @auth(level: PUBLIC) { + movies( + orderBy: [ + { rating: $orderByRating }, + { releaseYear: $orderByReleaseYear } + ] + limit: $limit + ) { + id + title + imageUrl + releaseYear + genre + rating + tags + description + } +} +query ListMoviesByGenre($genre: String!, $orderByRating: OrderDirection, $orderByReleaseYear: OrderDirection, $limit: Int) @auth(level: PUBLIC) { + movies(where: { + genre: { + eq: $genre + } + }, orderBy: [ + { rating: $orderByRating }, + { releaseYear: $orderByReleaseYear } + ] + limit: $limit) { + id + title + imageUrl + releaseYear + genre + rating + tags + description + } +} + +query ListGenres @auth(level: PUBLIC) { + genres { + genre + } +} + +# Get movie by id +query GetMovieById($id: UUID!) @auth(level: PUBLIC) { + movie(id: $id) { + id + title + imageUrl + releaseYear + genre + rating + description + tags + metadata: movieMetadatas_on_movie { + director + } + mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) { + id + name + imageUrl + } + supportingActors: actors_via_MovieActor( + where: { role: { eq: "supporting" } } + ) { + id + name + imageUrl + } + reviews: reviews_on_movie { + id + reviewText + reviewDate + rating + user { + id + username + } + } + } + } + +# Get actor by id +query GetActorById($id: UUID!) @auth(level: PUBLIC) { + actor(id: $id) { + id + name + imageUrl + mainActors: movies_via_MovieActor(where: { role: { eq: "main" } }) { + id + title + genre + tags + imageUrl + } + supportingActors: movies_via_MovieActor( + where: { role: { eq: "supporting" } } + ) { + id + title + genre + tags + imageUrl + } + } +} + + +# Get user by ID +query GetCurrentUser @auth(level: USER) { + user(key: { id_expr: "auth.uid" }) { + id + username + reviews: reviews_on_user { + id + rating + reviewDate + reviewText + movie { + id + title + } + } + favoriteMovies: favorite_movies_on_user { + movie { + id + title + genre + imageUrl + releaseYear + rating + description + tags + metadata: movieMetadatas_on_movie { + director + } + } + } + } +} + +query GetMovieInfoForUser($movieId: UUID!) @auth(level: USER) { + favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) { + movieId + } +} + + +# Search for movies, actors, and reviews +query SearchAll( + $input: String + $minYear: Int! + $maxYear: Int! + $minRating: Float! + $maxRating: Float! + $genre: String! +) @auth(level: PUBLIC) { + moviesMatchingTitle: movies( + where: { + _and: [ + { releaseYear: { ge: $minYear } } + { releaseYear: { le: $maxYear } } + { rating: { ge: $minRating } } + { rating: { le: $maxRating } } + { genre: { contains: $genre } } + { title: { contains: $input } } + ] + } + ) { + id + title + genre + rating + imageUrl + } + moviesMatchingDescription: movies( + where: { + _and: [ + { releaseYear: { ge: $minYear } } + { releaseYear: { le: $maxYear } } + { rating: { ge: $minRating } } + { rating: { le: $maxRating } } + { genre: { contains: $genre } } + { description: { contains: $input } } + ] + } + ) { + id + title + genre + rating + imageUrl + } + actorsMatchingName: actors(where: { name: { contains: $input } }) { + id + name + imageUrl + } + reviewsMatchingText: reviews(where: { reviewText: { contains: $input } }) { + id + rating + reviewText + reviewDate + movie { + id + title + } + user { + id + username + } + } +} + +# Search movie descriptions using L2 similarity with Vertex AI +# query SearchMovieDescriptionUsingL2Similarity($query: String!) +# @auth(level: PUBLIC) { +# movies_descriptionEmbedding_similarity( +# compare_embed: { model: "textembedding-gecko@003", text: $query } +# method: L2 +# within: 2 +# limit: 5 +# ) { +# id +# title +# description +# tags +# rating +# imageUrl +# } +# } + + + +# # The queries below are unused by the application, but are useful examples for more complex cases + +# List movies by partial title match +query ListMoviesByPartialTitle($input: String!) @auth(level: PUBLIC) { + movies(where: { title: { contains: $input } }) { + id + title + genre + rating + imageUrl + description + } +} + +# # List movies by tag +# query ListMoviesByTag($tag: String!) @auth(level: PUBLIC) { +# movies(where: { tags: { includes: $tag } }) { +# id +# title +# imageUrl +# genre +# rating +# } +# } + +# # List movies by release year range +# query MoviesByReleaseYear($min: Int, $max: Int) @auth(level: PUBLIC) { +# movies( +# where: { releaseYear: { le: $max, ge: $min } } +# orderBy: { releaseYear: ASC } +# ) { +# id +# rating +# title +# imageUrl +# } +# } + +# # List movies by rating and genre with OR filters +# query SearchMovieOr( +# $minRating: Float +# $maxRating: Float +# $genre: String +# $tag: String +# $input: String +# ) @auth(level: PUBLIC) { +# movies( +# where: { +# _or: [ +# { rating: { ge: $minRating } } +# { rating: { le: $maxRating } } +# { genre: { eq: $genre } } +# { tags: { includes: $tag } } +# { title: { contains: $input } } +# ] +# } +# ) { +# id +# rating +# title +# imageUrl +# } +# } + +# # List movies by rating and genre with AND filters +# query SearchMovieAnd( +# $minRating: Float +# $maxRating: Float +# $genre: String +# $tag: String +# $input: String +# ) @auth(level: PUBLIC) { +# movies( +# where: { +# _and: [ +# { rating: { ge: $minRating } } +# { rating: { le: $maxRating } } +# { genre: { eq: $genre } } +# { tags: { includes: $tag } } +# { title: { contains: $input } } +# ] +# } +# ) { +# id +# rating +# title +# imageUrl +# } +# } + +# # Get favorite actors by user ID +# query GetFavoriteActors @auth(level: USER) { +# user(key: {id_expr: "auth.uid"}) { +# favorite_actors_on_user { +# actor { +# id +# name +# imageUrl +# } +# } +# } +# } + +# # Get favorite movies by user ID +# query GetUserFavoriteMovies @auth(level: USER) { +# user(id_expr: "auth.uid") { +# favorite_movies_on_user { +# movie { +# id +# title +# genre +# imageUrl +# releaseYear +# rating +# description +# } +# } +# } +# } +# # end of example queries diff --git a/dataconnect/flutter-movie/dataconnect/dataconnect.yaml b/dataconnect/flutter-movie/dataconnect/dataconnect.yaml new file mode 100644 index 00000000..300d80b1 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/dataconnect.yaml @@ -0,0 +1,12 @@ +specVersion: "v1beta" +serviceId: "dataconnect" +location: "us-central1" +schema: + source: "./schema" + datasource: + postgresql: + database: "fdcdb" + cloudSql: + instanceId: "dataconnect-fdc" + # schemaValidation: "COMPATIBLE" +connectorDirs: ["./connector"] diff --git a/dataconnect/flutter-movie/dataconnect/moviedata_insert.gql b/dataconnect/flutter-movie/dataconnect/moviedata_insert.gql new file mode 100644 index 00000000..44cdfe00 --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/moviedata_insert.gql @@ -0,0 +1,701 @@ + # Copyright 2024 Google LLC + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + +mutation { + movie_insertMany( + data: [ + { + id: "550e8400-e29b-41d4-a716-446655440000" + title: "Quantum Paradox" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fquantum_paradox.jpeg?alt=media&token=4142e2a1-bf43-43b5-b7cf-6616be3fd4e3" + releaseYear: 2025 + genre: "sci-fi" + rating: 7.9 + description: "A group of scientists accidentally open a portal to a parallel universe, causing a rift in time. As the team races to close the portal, they encounter alternate versions of themselves, leading to shocking revelations." + tags: ["thriller", "adventure"] + } + { + id: "550e8400-e29b-41d4-a716-446655440001" + title: "The Lone Outlaw" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Flone_outlaw.jpeg?alt=media&token=15525ffc-208f-4b59-b506-ae8348e06e85" + releaseYear: 2023 + genre: "western" + rating: 8.2 + description: "In the lawless Wild West, a mysterious gunslinger with a hidden past takes on a corrupt sheriff and his band of outlaws to bring justice to a small town." + tags: ["action", "drama"] + } + { + id: "550e8400-e29b-41d4-a716-446655440002" + title: "Celestial Harmony" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fcelestial_harmony.jpeg?alt=media&token=f5fe1845-3fac-4f46-8511-f35f928b6d1d" + releaseYear: 2024 + genre: "romance" + rating: 7.5 + description: "Two astronauts, stationed on a remote space station, fall in love amidst the isolation of deep space. But when a mysterious signal disrupts their communication, they must find a way to reconnect and survive." + tags: ["romance", "sci-fi"] + } + { + id: "550e8400-e29b-41d4-a716-446655440003" + title: "Noir Mystique" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fnoir_mystique.jpeg?alt=media&token=3299adba-cb98-4302-8b23-aeb679a4f913" + releaseYear: 2022 + genre: "mystery" + rating: 8.0 + description: "A private detective gets caught up in a web of lies, deception, and betrayal while investigating the disappearance of a famous actress in 1940s Hollywood." + tags: ["crime", "thriller"] + } + { + id: "550e8400-e29b-41d4-a716-446655440004" + title: "The Forgotten Island" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fforgotten_island.jpeg?alt=media&token=a6b2d761-2018-48c3-91a1-632d199440d4" + releaseYear: 2025 + genre: "adventure" + rating: 7.6 + description: "An explorer leads an expedition to a remote island rumored to be home to mythical creatures. As the team ventures deeper into the island, they uncover secrets that change the course of history." + tags: ["adventure", "fantasy"] + } + { + id: "550e8400-e29b-41d4-a716-446655440005" + title: "Digital Nightmare" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fdigital_nightmare.jpeg?alt=media&token=335ec842-1ca4-4b09-abd1-e96d9f5c0c2f" + releaseYear: 2024 + genre: "horror" + rating: 6.9 + description: "A tech-savvy teenager discovers a cursed app that brings nightmares to life. As the horrors of the digital world cross into reality, she must find a way to break the curse before it's too late." + tags: ["horror", "thriller"] + } + { + id: "550e8400-e29b-41d4-a716-446655440006" + title: "Eclipse of Destiny" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Feclipse_destiny.jpeg?alt=media&token=346649b3-cb5c-4d7e-b0d4-6f02e3df5959" + releaseYear: 2026 + genre: "fantasy" + rating: 8.1 + description: "In a kingdom on the brink of war, a prophecy speaks of an eclipse that will grant power to the rightful ruler. As factions vie for control, a young warrior must decide where his true loyalty lies." + tags: ["fantasy", "adventure"] + } + { + id: "550e8400-e29b-41d4-a716-446655440007" + title: "Heart of Steel" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fheart_steel.jpeg?alt=media&token=17883d71-329b-415a-86f8-dd4d9e941d7f" + releaseYear: 2023 + genre: "sci-fi" + rating: 7.7 + description: "A brilliant scientist creates a robot with a human heart. As the robot struggles to understand emotions, it becomes entangled in a plot that could change the fate of humanity." + tags: ["sci-fi", "drama"] + } + { + id: "550e8400-e29b-41d4-a716-446655440008" + title: "Rise of the Crimson Empire" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Frise_crimson_empire.jpeg?alt=media&token=6faa73ad-7504-4146-8f3a-50b90f607f33" + releaseYear: 2025 + genre: "action" + rating: 8.4 + description: "A legendary warrior rises to challenge the tyrannical rule of a powerful empire. As rebellion brews, the warrior must unite different factions to lead an uprising." + tags: ["action", "adventure"] + } + { + id: "550e8400-e29b-41d4-a716-446655440009" + title: "Silent Waves" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fsilent_waves.jpeg?alt=media&token=bd626bf1-ec60-4e57-aa07-87ba14e35bb7" + releaseYear: 2024 + genre: "drama" + rating: 8.2 + description: "A talented pianist, who loses his hearing in a tragic accident, must rediscover his passion for music with the help of a young music teacher who believes in him." + tags: ["drama", "music"] + } + { + id: "550e8400-e29b-41d4-a716-446655440010" + title: "Echoes of the Past" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fecho_of_past.jpeg?alt=media&token=d866aa27-8534-4d72-8988-9da4a1b9e452" + releaseYear: 2023 + genre: "historical" + rating: 7.8 + description: "A historian stumbles upon an ancient artifact that reveals hidden truths about an empire long forgotten. As she deciphers the clues, a shadowy organization tries to stop her from unearthing the past." + tags: ["drama", "mystery"] + } + { + id: "550e8400-e29b-41d4-a716-446655440011" + title: "Beyond the Horizon" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fbeyond_horizon.jpeg?alt=media&token=9c054b8d-1a63-48f6-b161-fb28e3d15e55" + releaseYear: 2026 + genre: "sci-fi" + rating: 8.5 + description: "In the future, Earth's best pilots are sent on a mission to explore a mysterious planet beyond the solar system. What they find changes humanity's understanding of the universe forever." + tags: ["sci-fi", "adventure"] + } + { + id: "550e8400-e29b-41d4-a716-446655440012" + title: "Shadows and Lies" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fshadows_lies.jpeg?alt=media&token=01afb80d-caee-47f8-a00e-aea8b9e459a2" + releaseYear: 2022 + genre: "crime" + rating: 7.9 + description: "A young detective with a dark past investigates a series of mysterious murders in a city plagued by corruption. As she digs deeper, she realizes nothing is as it seems." + tags: ["crime", "thriller"] + } + { + id: "550e8400-e29b-41d4-a716-446655440013" + title: "The Last Symphony" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Flast_symphony.jpeg?alt=media&token=f9bf80cd-3d8e-4e24-8503-7feb11f4e397" + releaseYear: 2024 + genre: "drama" + rating: 8.0 + description: "An aging composer struggling with memory loss attempts to complete his final symphony. With the help of a young prodigy, he embarks on an emotional journey through his memories and legacy." + tags: ["drama", "music"] + } + { + id: "550e8400-e29b-41d4-a716-446655440014" + title: "Moonlit Crusade" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fmoonlit_crusade.jpeg?alt=media&token=1e2d46e2-6b76-4e20-b656-4b005b37d14b" + releaseYear: 2025 + genre: "fantasy" + rating: 8.3 + description: "A knight is chosen by an ancient order to embark on a quest under the light of the full moon. Facing mythical beasts and treacherous landscapes, he seeks a relic that could save his kingdom." + tags: ["fantasy", "adventure"] + } + { + id: "550e8400-e29b-41d4-a716-446655440015" + title: "Abyss of the Deep" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fabyss_deep.jpeg?alt=media&token=2417321d-2451-4ec0-9ed6-6297042170e6" + releaseYear: 2023 + genre: "horror" + rating: 7.2 + description: "When a group of marine biologists descends into the unexplored depths of the ocean, they encounter a terrifying and ancient force. Now, they must survive as the abyss comes alive." + tags: ["horror", "thriller"] + } + { + id: "550e8400-e29b-41d4-a716-446655440016" + title: "Phoenix Rising" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fpheonix_rising.jpeg?alt=media&token=7298b1fd-833c-471c-a55d-e8fc798b4ab2" + releaseYear: 2025 + genre: "action" + rating: 8.6 + description: "A special forces operative, presumed dead, returns to avenge his fallen comrades. With nothing to lose, he faces a powerful enemy in a relentless pursuit for justice." + tags: ["action", "thriller"] + } + { + id: "550e8400-e29b-41d4-a716-446655440017" + title: "The Infinite Knot" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Finfinite_knot.jpeg?alt=media&token=93d54d93-d933-4663-a6fe-26b707ef823e" + releaseYear: 2026 + genre: "romance" + rating: 7.4 + description: "Two souls destined to meet across multiple lifetimes struggle to find each other in a chaotic world. With each incarnation, they get closer, but time itself becomes their greatest obstacle." + tags: ["romance", "fantasy"] + } + { + id: "550e8400-e29b-41d4-a716-446655440018" + title: "Parallel Justice" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fparallel_justice.jpeg?alt=media&token=f975524a-6edf-4d3b-99e1-c99e62a50518" + releaseYear: 2024 + genre: "crime" + rating: 8.1 + description: "A lawyer who can see the outcomes of different timelines must choose between justice and personal gain. When a high-stakes case arises, he faces a moral dilemma that could alter his life forever." + tags: ["crime", "thriller"] + } + { + id: "550e8400-e29b-41d4-a716-446655440019" + title: "Veil of Illusion" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/movie%2Fveil_illusion.jpeg?alt=media&token=baa02cce-efe8-4c9f-bd9f-65233c6e1ca8" + releaseYear: 2022 + genre: "mystery" + rating: 7.8 + description: "A magician-turned-detective uses his skills in illusion to solve crimes. When a series of murders leaves the city in fear, he must reveal the truth hidden behind a veil of deceit." + tags: ["mystery", "crime"] + } + ] + ) + actor_insertMany( + data: [ + { + id: "123e4567-e89b-12d3-a456-426614174020" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Foliver_blackwood.jpeg?alt=media&token=79cdbc29-c2c6-4dc3-b87f-f6dc4f1a8208" + name: "Oliver Blackwood" + } + { + id: "123e4567-e89b-12d3-a456-426614174021" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Femma_westfield.jpeg?alt=media&token=2991c3c9-cfa8-4067-8b26-c5239b6894c4" + name: "Emma Westfield" + } + { + id: "123e4567-e89b-12d3-a456-426614174022" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fjack_stone.jpeg?alt=media&token=74a564aa-d840-4bdd-a8a6-c6b17bbde608" + name: "Jack Stone" + } + { + id: "123e4567-e89b-12d3-a456-426614174023" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fclara_woods.jpeg?alt=media&token=b4ff2a15-ef6d-4f20-86c9-07d67015fb29" + name: "Clara Woods" + } + { + id: "123e4567-e89b-12d3-a456-426614174024" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fnoah_frost.jpeg?alt=media&token=0d08179a-7778-405e-9501-feac43b77a99" + name: "Noah Frost" + } + { + id: "123e4567-e89b-12d3-a456-426614174025" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fisabelle_hart.jpeg?alt=media&token=d4fdf896-0f5b-4c32-91a4-7a541a95e77d" + name: "Isabella Hart" + } + { + id: "123e4567-e89b-12d3-a456-426614174026" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fliam_hale.jpeg?alt=media&token=08e8eeee-b8ef-4e7b-8f97-a1e0b59321cc" + name: "Liam Hale" + } + { + id: "123e4567-e89b-12d3-a456-426614174027" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fsophia_knight.jpeg?alt=media&token=7a79ef21-93e0-46f9-934c-6bbef7b5d430" + name: "Sophia Knight" + } + { + id: "123e4567-e89b-12d3-a456-426614174028" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Falex_clay.jpeg?alt=media&token=2a798cdb-f44f-48d5-91bc-9d26a758944e" + name: "Alexander Clay" + } + { + id: "123e4567-e89b-12d3-a456-426614174029" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Famelia_stone.jpeg?alt=media&token=34f21ba9-9e28-4708-9e55-f123634ab506" + name: "Amelia Stone" + } + { + id: "123e4567-e89b-12d3-a456-426614174030" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fethan_blake.jpeg?alt=media&token=41352170-a5cd-4088-b8fd-1c4ee0d52cad" + name: "Ethan Blake" + } + { + id: "123e4567-e89b-12d3-a456-426614174031" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fmia_gray.jpeg?alt=media&token=1ba1831a-3ada-485a-b5c9-2d018bf1862b" + name: "Mia Gray" + } + { + id: "123e4567-e89b-12d3-a456-426614174032" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Flucas_reed.jpeg?alt=media&token=c74f44f3-ae98-4208-8e67-18c2db65a5c1" + name: "Lucas Reed" + } + { + id: "123e4567-e89b-12d3-a456-426614174033" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fevelyn_harper.jpeg?alt=media&token=b138b308-9589-4dfe-8c50-a6d70f06dfb1" + name: "Evelyn Harper" + } + { + id: "123e4567-e89b-12d3-a456-426614174034" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Foscar_smith.jpeg?alt=media&token=d493da85-644d-4d45-a09d-ecb5416645e4" + name: "Oscar Smith" + } + { + id: "123e4567-e89b-12d3-a456-426614174035" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fava_winter.jpeg?alt=media&token=757e4b11-0372-401e-8fa0-61797e90312a" + name: "Ava Winter" + } + { + id: "123e4567-e89b-12d3-a456-426614174036" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fleo_hunt.jpeg?alt=media&token=2cb14738-b39b-47b1-87f9-b45f38245179" + name: "Leo Hunt" + } + { + id: "123e4567-e89b-12d3-a456-426614174037" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Flucy_walsh.jpeg?alt=media&token=016a216c-f329-4c10-bbe8-b31425f73c69" + name: "Lucy Walsh" + } + { + id: "123e4567-e89b-12d3-a456-426614174038" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Fmason_ford.jpeg?alt=media&token=55388be9-fdc8-483f-8352-c29755ed3574" + name: "Mason Ford" + } + { + id: "123e4567-e89b-12d3-a456-426614174039" + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-web-quickstart.appspot.com/o/actor%2Flily_moore.jpeg?alt=media&token=19538aa6-1baf-4033-8fd7-d2a62aa79f51" + name: "Lily Moore" + } + ] + ) + movieMetadata_insertMany( + data: [ + { + movieId: "550e8400-e29b-41d4-a716-446655440000" + director: "Henry Caldwell" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440001" + director: "Juliana Mason, Clark Avery" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440002" + director: "Diana Rivers" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440003" + director: "Liam Thatcher" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440004" + director: "Evelyn Hart" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440005" + director: "Grayson Brooks" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440006" + director: "Isabella Quinn" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440007" + director: "Vincent Hale" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440008" + director: "Amelia Sutton" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440009" + director: "Lucas Stone" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440010" + director: "Sophia Langford" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440011" + director: "Noah Bennett" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440012" + director: "Chloe Armstrong" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440013" + director: "Sebastian Crane" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440014" + director: "Isla Fitzgerald" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440015" + director: "Oliver Hayes" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440016" + director: "Mila Donovan" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440017" + director: "Carter Monroe, Elise Turner" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440018" + director: "Adrian Blake" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440019" + director: "Hazel Carter" + } + ] + ) +movieActor_insertMany( + data: [ + { + movieId: "550e8400-e29b-41d4-a716-446655440000" + actorId: "123e4567-e89b-12d3-a456-426614174020" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440000" + actorId: "123e4567-e89b-12d3-a456-426614174021" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440001" + actorId: "123e4567-e89b-12d3-a456-426614174021" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440001" + actorId: "123e4567-e89b-12d3-a456-426614174022" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440002" + actorId: "123e4567-e89b-12d3-a456-426614174022" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440002" + actorId: "123e4567-e89b-12d3-a456-426614174023" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440003" + actorId: "123e4567-e89b-12d3-a456-426614174023" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440003" + actorId: "123e4567-e89b-12d3-a456-426614174024" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440004" + actorId: "123e4567-e89b-12d3-a456-426614174024" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440004" + actorId: "123e4567-e89b-12d3-a456-426614174025" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440005" + actorId: "123e4567-e89b-12d3-a456-426614174025" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440005" + actorId: "123e4567-e89b-12d3-a456-426614174026" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440006" + actorId: "123e4567-e89b-12d3-a456-426614174026" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440006" + actorId: "123e4567-e89b-12d3-a456-426614174027" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440007" + actorId: "123e4567-e89b-12d3-a456-426614174027" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440007" + actorId: "123e4567-e89b-12d3-a456-426614174028" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440008" + actorId: "123e4567-e89b-12d3-a456-426614174028" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440008" + actorId: "123e4567-e89b-12d3-a456-426614174029" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440009" + actorId: "123e4567-e89b-12d3-a456-426614174029" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440009" + actorId: "123e4567-e89b-12d3-a456-426614174030" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440010" + actorId: "123e4567-e89b-12d3-a456-426614174030" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440010" + actorId: "123e4567-e89b-12d3-a456-426614174031" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440011" + actorId: "123e4567-e89b-12d3-a456-426614174031" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440011" + actorId: "123e4567-e89b-12d3-a456-426614174032" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440012" + actorId: "123e4567-e89b-12d3-a456-426614174032" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440012" + actorId: "123e4567-e89b-12d3-a456-426614174033" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440013" + actorId: "123e4567-e89b-12d3-a456-426614174033" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440013" + actorId: "123e4567-e89b-12d3-a456-426614174034" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440014" + actorId: "123e4567-e89b-12d3-a456-426614174034" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440014" + actorId: "123e4567-e89b-12d3-a456-426614174035" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440015" + actorId: "123e4567-e89b-12d3-a456-426614174035" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440015" + actorId: "123e4567-e89b-12d3-a456-426614174036" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440016" + actorId: "123e4567-e89b-12d3-a456-426614174036" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440016" + actorId: "123e4567-e89b-12d3-a456-426614174037" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440017" + actorId: "123e4567-e89b-12d3-a456-426614174037" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440017" + actorId: "123e4567-e89b-12d3-a456-426614174038" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440018" + actorId: "123e4567-e89b-12d3-a456-426614174038" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440018" + actorId: "123e4567-e89b-12d3-a456-426614174039" + role: "supporting" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440019" + actorId: "123e4567-e89b-12d3-a456-426614174039" + role: "main" + } + { + movieId: "550e8400-e29b-41d4-a716-446655440019" + actorId: "123e4567-e89b-12d3-a456-426614174020" + role: "supporting" + } + ] +) + user_insertMany( + data: [ + { id: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", username: "sherlock_h" } + { id: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", username: "hercule_p" } + { id: "TBedjwCX0Jf955Uuoxk6k74sY0l1", username: "jane_d" } + ] + ) + + review_insertMany( + data: [ + { + id: "345e4567-e89b-12d3-a456-426614174000" + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2" + movieId: "550e8400-e29b-41d4-a716-446655440000" + rating: 5 + reviewText: "An incredible movie with a mind-blowing plot!" + reviewDate_date: { today: true } + } + { + id: "345e4567-e89b-12d3-a456-426614174001" + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2" + movieId: "550e8400-e29b-41d4-a716-446655440001" + rating: 5 + reviewText: "A revolutionary film that changed cinema forever." + reviewDate_date: { today: true } + } + { + id: "345e4567-e89b-12d3-a456-426614174002" + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1" + movieId: "550e8400-e29b-41d4-a716-446655440002" + rating: 5 + reviewText: "A visually stunning and emotionally impactful movie." + reviewDate_date: { today: true } + } + { + id: "345e4567-e89b-12d3-a456-426614174003" + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2" + movieId: "550e8400-e29b-41d4-a716-446655440003" + rating: 4 + reviewText: "A fantastic superhero film with great performances." + reviewDate_date: { today: true } + } + { + id: "345e4567-e89b-12d3-a456-426614174004" + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2" + movieId: "550e8400-e29b-41d4-a716-446655440004" + rating: 5 + reviewText: "An amazing film that keeps you on the edge of your seat." + reviewDate_date: { today: true } + } + { + id: "345e4567-e89b-12d3-a456-426614174005" + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1" + movieId: "550e8400-e29b-41d4-a716-446655440005" + rating: 5 + reviewText: "An absolute classic with unforgettable dialogue." + reviewDate_date: { today: true } + } + ] + ) + + favorite_movie_insertMany( + data: [ + { + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2" + movieId: "550e8400-e29b-41d4-a716-446655440000" + } + { + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2" + movieId: "550e8400-e29b-41d4-a716-446655440001" + } + { + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1" + movieId: "550e8400-e29b-41d4-a716-446655440002" + } + { + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2" + movieId: "550e8400-e29b-41d4-a716-446655440003" + } + { + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2" + movieId: "550e8400-e29b-41d4-a716-446655440004" + } + { + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1" + movieId: "550e8400-e29b-41d4-a716-446655440005" + } + ] + ) +} diff --git a/dataconnect/flutter-movie/dataconnect/schema/schema.gql b/dataconnect/flutter-movie/dataconnect/schema/schema.gql new file mode 100644 index 00000000..1eecf54e --- /dev/null +++ b/dataconnect/flutter-movie/dataconnect/schema/schema.gql @@ -0,0 +1,95 @@ +# Movies +# TODO: Fill out Movie table +type Movie + # The below parameter values are generated by default with @table, and can be edited manually. + @table { + # implicitly calls @col to generates a column name. ex: @col(name: "movie_id") + id: UUID! @default(expr: "uuidV4()") + title: String! + imageUrl: String! + releaseYear: Int + genre: String + rating: Float + description: String + tags: [String] + # descriptionEmbedding: Vector @col(size:768) # Enables vector search +} + +# Movie Metadata +# Movie - MovieMetadata is a one-to-one relationship +# TODO: Fill out MovieMetadata table +type MovieMetadata + @table { + # @ref creates a field in the current table (MovieMetadata) + # It is a reference that holds the primary key of the referenced type + # In this case, @ref(fields: "movieId", references: "id") is implied + movie: Movie! @ref + # movieId: UUID <- this is created by the above @ref + director: String +} + +# Actors +# Suppose an actor can participate in multiple movies and movies can have multiple actors +# Movie - Actors (or vice versa) is a many to many relationship +# TODO: Fill out Actor table +type Actor @table { + id: UUID! + imageUrl: String! + name: String! @col(name: "name", dataType: "varchar(30)") +} + +# Users +# Suppose a user can leave reviews for movies +# user-reviews is a one to many relationship, movie-reviews is a one to many relationship, movie:user is a many to many relationship +# TODO: Fill out User table +type User + @table { + id: String! @col(name: "user_auth") + username: String! @col(name: "username", dataType: "varchar(50)") + # The following are generated from the @ref in the Review table + # reviews_on_user + # movies_via_Review +} + +# Reviews +# TODO: Fill out Review table +type Review @table(name: "Reviews", key: ["movie", "user"]) { + id: UUID! @default(expr: "uuidV4()") + user: User! + movie: Movie! + rating: Int + reviewText: String + reviewDate: Date! @default(expr: "request.time") +} + +# Join table for many-to-many relationship for movies and actors +# The 'key' param signifies the primary key(s) of this table +# In this case, the keys are [movieId, actorId], the generated fields of the reference types [movie, actor] +# TODO: Fill out MovieActor table +type MovieActor @table(key: ["movie", "actor"]) { + # @ref creates a field in the current table (MovieActor) that holds the primary key of the referenced type + # In this case, @ref(fields: "id") is implied + movie: Movie! + # movieId: UUID! <- this is created by the implied @ref, see: implicit.gql + + actor: Actor! + # actorId: UUID! <- this is created by the implied @ref, see: implicit.gql + + role: String! # "main" or "supporting" +} + +type Genre @view(sql: """ +SELECT DISTINCT genre from "movie" +""" +) { + genre: String +} + +# Join table for many-to-many relationship for users and favorite movies +# TODO: Fill out FavoriteMovie table +type FavoriteMovie + @table(name: "FavoriteMovies", singular: "favorite_movie", plural: "favorite_movies", key: ["user", "movie"]) { + # @ref is implicit + user: User! + movie: Movie! +} diff --git a/dataconnect/flutter-movie/firebase.json b/dataconnect/flutter-movie/firebase.json new file mode 100644 index 00000000..dd862209 --- /dev/null +++ b/dataconnect/flutter-movie/firebase.json @@ -0,0 +1,14 @@ +{ + "dataconnect": { + "source": "dataconnect" + }, + "emulators": { + "dataconnect": { + "port": 9403 + }, + "ui": { + "enabled": false + }, + "singleProjectMode": true + } +} diff --git a/dataconnect/flutter-movie/lib/actor_detail.dart b/dataconnect/flutter-movie/lib/actor_detail.dart new file mode 100644 index 00000000..a25a0556 --- /dev/null +++ b/dataconnect/flutter-movie/lib/actor_detail.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; + +import 'movie_state.dart'; +import 'widgets/list_movies.dart'; + +class ActorDetail extends StatelessWidget { + const ActorDetail({ + super.key, + required this.actorId, + }); + + final String actorId; + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: MovieState.getActorById(actorId), + builder: (context, snapshot) { + final actor = snapshot.data?.data.actor; + final loading = snapshot.connectionState == ConnectionState.waiting; + return Scaffold( + body: SafeArea( + child: () { + if (actor == null || loading) { + return const Center( + child: CircularProgressIndicator(), + ); + } + return Padding( + padding: const EdgeInsets.all(30), + child: SingleChildScrollView( + child: Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + actor.name, + style: const TextStyle(fontSize: 30), + )), + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: AspectRatio( + aspectRatio: + 9 / 16, // 9:16 aspect ratio for the image + child: Image.network( + actor.imageUrl, + fit: BoxFit.cover, + ), + ), + ), + ], + ), + ListMovies( + movies: MovieState.convertMainActorDetail( + actor.mainActors, + ), + title: "Main Roles", + ), + ListMovies( + movies: MovieState.convertSupportingActorDetail( + actor.supportingActors, + ), + title: "Supporting Roles", + ), + ], + ), + ), + ); + }(), + ), + ); + }, + ); + } +} diff --git a/dataconnect/flutter-movie/lib/destination.dart b/dataconnect/flutter-movie/lib/destination.dart new file mode 100644 index 00000000..25820bbe --- /dev/null +++ b/dataconnect/flutter-movie/lib/destination.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; + +class Route extends NavigationDestination { + Route({ + super.key, + required this.path, + required super.label, + required this.iconData, + }) : super(icon: Icon(iconData)); + final String path; + final IconData iconData; +} + +final homePath = Route( + path: '/home', + label: 'Home', + iconData: Icons.home, +); +final searchPath = Route( + path: '/search', + label: 'Search', + iconData: Icons.search, +); +final profilePath = Route( + path: '/profile', + label: 'Profile', + iconData: Icons.person, +); + +final paths = [homePath, searchPath, profilePath]; diff --git a/dataconnect/flutter-movie/lib/firebase_options.dart b/dataconnect/flutter-movie/lib/firebase_options.dart new file mode 100644 index 00000000..9c664017 --- /dev/null +++ b/dataconnect/flutter-movie/lib/firebase_options.dart @@ -0,0 +1,57 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: type=lint +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.iOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } +} diff --git a/dataconnect/flutter-movie/lib/login.dart b/dataconnect/flutter-movie/lib/login.dart new file mode 100644 index 00000000..91685bba --- /dev/null +++ b/dataconnect/flutter-movie/lib/login.dart @@ -0,0 +1,114 @@ +import 'package:dataconnect/movies_connector/movies.dart'; +import 'package:dataconnect/widgets/auth_dialog.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +class Login extends StatefulWidget { + const Login({super.key}); + + @override + State createState() => _LoginState(); +} + +class _LoginState extends State { + final _formKey = GlobalKey(); + final _username = TextEditingController(); + final _password = TextEditingController(); + + Future logIn() async { + final messenger = ScaffoldMessenger.of(context); + final navigator = GoRouter.of(context); + messenger.showSnackBar(const SnackBar(content: Text('Signing In'))); + try { + await FirebaseAuth.instance.signInWithEmailAndPassword( + email: _username.text, + password: _password.text, + ); + final isLoggedIn = + await MoviesConnector.instance.getCurrentUser().execute(); + if (isLoggedIn.data.user == null) { + await MoviesConnector.instance + .upsertUser(username: _username.text) + .execute(); + } + if (mounted) { + navigator.go('/home'); + } + } on FirebaseAuthException catch (e) { + if (mounted) { + String message = e.code.contains('configuration-not-found') + ? 'Email/Password authentication has not been enabled' + : e.message!; + bool shouldLaunch = e.code.contains('operation-not-allowed') || + e.code.contains('configuration-not-found'); + AuthDialog.showAuthDialog(context, message, shouldLaunch); + } + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(30), + child: Center( + child: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TextFormField( + decoration: const InputDecoration( + hintText: "Username", + border: OutlineInputBorder(), + ), + controller: _username, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter some text'; + } + return null; + }, + ), + const SizedBox(height: 30), + TextFormField( + obscureText: true, + autocorrect: false, + decoration: const InputDecoration( + hintText: "Password", + border: OutlineInputBorder(), + ), + controller: _password, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter a password'; + } + return null; + }, + ), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + logIn(); + } + }, + child: const Text('Sign In')), + const Text("Don't have an account?"), + ElevatedButton( + onPressed: () { + context.go('/signup'); + }, + child: const Text('Sign Up'), + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/dataconnect/flutter-movie/lib/main.dart b/dataconnect/flutter-movie/lib/main.dart new file mode 100644 index 00000000..3202f6e0 --- /dev/null +++ b/dataconnect/flutter-movie/lib/main.dart @@ -0,0 +1,184 @@ +import 'package:dataconnect/models/movie.dart'; +import 'package:dataconnect/movie_state.dart'; +import 'package:dataconnect/router.dart'; +import 'package:dataconnect/widgets/list_movies.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'firebase_options.dart'; +import 'package:flutter_web_plugins/url_strategy.dart'; +import 'util/auth.dart'; +import 'movies_connector/movies.dart'; + +bool isSetup = false; +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + usePathUrlStrategy(); + try { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + isSetup = true; + + await Auth.instance.init(); + int port = 443; + String hostName = Uri.base.host; + bool isSecure = true; + if (!kIsWeb) { + hostName = '10.0.2.2'; + port = 9403; + isSecure = false; + } + MoviesConnector.instance.dataConnect + .useDataConnectEmulator(hostName, port, isSecure: isSecure); + } catch (_) { + // The user hasn't run ./installDeps.sh yet + } + + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp.router( + theme: ThemeData.dark(), + routerConfig: router, + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key}); + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + List _topMovies = []; + List _latestMovies = []; + bool _showMessage = true; + + @override + void initState() { + super.initState(); + + if (isSetup) { + MovieState.getTopTenMovies().then((res) { + if (res.data.movies.isNotEmpty) { + if (mounted) { + setState(() { + _showMessage = false; + _topMovies = res.data.movies; + }); + } + } + }); + + MovieState.getTopTenMovies().then((res) { + setState(() { + _latestMovies = res.data.movies; + }); + }); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: SingleChildScrollView( + child: _showMessage || !isSetup + ? Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(30.0), + child: isSetup + ? Text( + 'Go to the Firebase Data Connect extension, and click start Emulators. ${_latestMovies.isEmpty ? 'Then open dataconnect/moviedata_insert.gql and the click "Run(local)".' : ''} Then, refresh the page.') + : const NumberedList(bullets: [ + 'Make sure you already have a Firebase Project', + 'In the sidebar, open The Firebase Data Connect Extension', + 'Sign into your google account associated with your firebase project', + 'Select your firebase project', + 'Open a new terminal (by clicking the + icon below) and Run "flutterfire configure -y -a com.example.dataconnect"', + 'Refresh this preview page' + ])) + ], + ) + : Column( + children: [ + ListMovies( + title: 'Top 10 Movies', + movies: _topMovies + .map( + (e) => Movie( + id: e.id, + title: e.title, + imageUrl: e.imageUrl, + description: e.description), + ) + .toList()), + ListMovies( + title: 'Latest Movies', + movies: _latestMovies + .map( + (e) => Movie( + id: e.id, + title: e.title, + imageUrl: e.imageUrl, + description: e.description), + ) + .toList()), + ], + ), + )), + ); + } +} + +class NumberedList extends StatelessWidget { + const NumberedList({super.key, required this.bullets}); + + final List bullets; + + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.centerLeft, + padding: const EdgeInsets.fromLTRB(16, 15, 16, 16), + child: Column( + children: bullets + .asMap() + .keys + .map((index) => Row(children: [ + Text( + "${index + 1}.", + style: const TextStyle( + fontSize: 16, height: 1.55, color: Colors.white), + ), + const SizedBox( + width: 5, + ), + Expanded( + child: Text( + bullets[index], + textAlign: TextAlign.left, + softWrap: true, + style: const TextStyle( + fontSize: 16, + color: Colors.white, + height: 1.55, + ), + ), + ) + ])) + .toList())); + } +} diff --git a/dataconnect/flutter-movie/lib/models/movie.dart b/dataconnect/flutter-movie/lib/models/movie.dart new file mode 100644 index 00000000..7b0ed506 --- /dev/null +++ b/dataconnect/flutter-movie/lib/models/movie.dart @@ -0,0 +1,11 @@ +class Movie { + Movie( + {required this.id, + required this.title, + required this.imageUrl, + this.description}); + String id; + String title; + String imageUrl; + String? description; +} diff --git a/dataconnect/flutter-movie/lib/movie_detail.dart b/dataconnect/flutter-movie/lib/movie_detail.dart new file mode 100644 index 00000000..0189843c --- /dev/null +++ b/dataconnect/flutter-movie/lib/movie_detail.dart @@ -0,0 +1,262 @@ +import 'dart:async'; + +import 'package:dataconnect/movie_state.dart'; +import 'package:dataconnect/movies_connector/movies.dart'; +import 'package:dataconnect/widgets/list_actors.dart'; +import 'package:dataconnect/widgets/login_guard.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +class MovieDetail extends StatefulWidget { + const MovieDetail({super.key, required this.id}); + + final String id; + + @override + State createState() => _MovieDetailState(); +} + +class _MovieDetailState extends State { + double _ratingValue = 0; + bool loading = true; + GetMovieByIdData? data; + bool _favorited = false; + + final _reviewTextController = TextEditingController(); + StreamSubscription? _movieByIdSub, _movieInfoSub; + + @override + void initState() { + super.initState(); + init(widget.id); + } + + @override + void dispose() { + _movieByIdSub?.cancel(); + _movieInfoSub?.cancel(); + super.dispose(); + } + + @override + void didUpdateWidget(covariant MovieDetail oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.id != widget.id) { + init(widget.id); + } + } + + Future init(String id) async { + _movieByIdSub?.cancel(); + _movieInfoSub?.cancel(); + _movieByIdSub = MovieState.subscribeToMovieById(widget.id).listen( + (value) { + if (mounted) { + setState(() { + loading = false; + data = value.data; + }); + } + }, + ); + _movieInfoSub = MovieState.subscribeToGetMovieInfo(widget.id).listen( + (value) { + if (mounted) { + setState(() { + _favorited = value.data.favorite_movie != null; + }); + } + }, + ); + } + + void _toggleFavorite() { + MovieState.toggleFavorite(widget.id, _favorited).then((_) { + if (mounted) { + setState(() { + _favorited = !_favorited; + }); + } + }); + } + + void _refreshData() { + MovieState.refreshMovieDetail(widget.id); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: () { + final movie = data?.movie; + if (movie == null) { + return const Center( + child: CircularProgressIndicator(), + ); + } + return Padding( + padding: const EdgeInsets.all(30), + child: SingleChildScrollView( + child: Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + movie.title, + style: const TextStyle(fontSize: 30), + )), + Row( + children: [ + Text(movie.releaseYear.toString()), + const SizedBox(width: 10), + Row( + children: [ + const Icon(Icons.star), + Text(movie.rating.toString()) + ], + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: AspectRatio( + aspectRatio: + 9 / 16, // 9:16 aspect ratio for the image + child: Image.network( + movie.imageUrl, + fit: BoxFit.cover, + ), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 0, 0), + child: Column(children: [ + Row( + children: movie.tags!.map((tag) { + return Chip( + label: Text( + tag, + overflow: TextOverflow.ellipsis, + )); + }).toList(), + ), + Text(movie.description!) + ]), + )) + ]), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LoginGuard( + builder: (context) => OutlinedButton.icon( + onPressed: () { + _toggleFavorite(); + }, + icon: Icon(_favorited + ? Icons.favorite + : Icons.favorite_border), + label: Text( + _favorited + ? 'Remove From Favorites' + : 'Add To Favorites', + ), + ), + ) + ], + ), + ListActors( + actors: data!.movie!.mainActors + .map((actor) => Actor( + imageUrl: actor.imageUrl, + name: actor.name, + id: actor.id)) + .toList(), + title: "Main Actors"), + ListActors( + actors: data!.movie!.supportingActors + .map((actor) => Actor( + imageUrl: actor.imageUrl, + name: actor.name, + id: actor.id)) + .toList(), + title: "Supporting Actors"), + Text("Rating: $_ratingValue"), + Slider( + value: _ratingValue, + max: 10, + divisions: 20, + label: _ratingValue.toString(), + onChanged: (double value) { + setState(() { + _ratingValue = value; + }); + }, + ), + LoginGuard( + builder: (context) => TextField( + decoration: const InputDecoration( + hintText: "Write your review", + border: OutlineInputBorder(), + ), + controller: _reviewTextController, + ), + message: "writing a review", + ), + LoginGuard( + builder: (context) => OutlinedButton.icon( + onPressed: () { + MoviesConnector.instance + .addReview( + movieId: widget.id, + rating: _ratingValue.toInt(), + reviewText: _reviewTextController.text) + .execute() + .then( + (_) { + _refreshData(); + _reviewTextController.clear(); + MovieState.triggerUpdateFavorite(); + }, + ); + }, + label: const Text('Submit Review'), + ), + ), + ...data!.movie!.reviews.map((review) { + return Card( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(review.user.username), + Row( + children: [ + Text(DateFormat.yMMMd() + .format(review.reviewDate)), + const SizedBox( + width: 10, + ), + Text("Rating ${review.rating}") + ], + ), + Text(review.reviewText!) + ], + )), + ); + }), + ], + ), + ), + ); + }(), + ), + ); + } +} diff --git a/dataconnect/flutter-movie/lib/movie_state.dart b/dataconnect/flutter-movie/lib/movie_state.dart new file mode 100644 index 00000000..85a5a6d1 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movie_state.dart @@ -0,0 +1,91 @@ +import 'package:dataconnect/movies_connector/movies.dart'; +import 'package:firebase_data_connect/firebase_data_connect.dart'; + +import 'models/movie.dart'; + +class MovieState { + static void triggerUpdateFavorite() { + MoviesConnector.instance.getCurrentUser().execute(); + } + + static Future> + getTopTenMovies() { + return MoviesConnector.instance + .listMovies() + .orderByRating(OrderDirection.DESC) + .limit(10) + .execute(); + } + + static Future> + getLatestMovies() { + return MoviesConnector.instance + .listMovies() + .orderByReleaseYear(OrderDirection.DESC) + .execute(); + } + + static searchByPartialTitle(String input) { + return MoviesConnector.instance + .listMoviesByPartialTitle(input: input) + .execute(); + } + + static Stream> + subscribeToMovieById(String id) { + return MoviesConnector.instance.getMovieById(id: id).ref().subscribe(); + } + + static void refreshMovieDetail(String id) { + MoviesConnector.instance.getMovieById(id: id).execute(); + MoviesConnector.instance.getMovieInfoForUser(movieId: id).execute(); + } + + static Stream< + QueryResult> + subscribeToGetMovieInfo(String id) { + return MoviesConnector.instance + .getMovieInfoForUser(movieId: id) + .ref() + .subscribe(); + } + + static Future> + getActorById(String actorId) { + return MoviesConnector.instance.getActorById(id: actorId).execute(); + } + + static List convertMainActorDetail( + List actors) { + return actors + .map( + (e) => Movie(imageUrl: e.imageUrl, id: e.id, title: e.title), + ) + .toList(); + } + + static List convertSupportingActorDetail( + List actors) { + return actors + .map( + (e) => Movie(imageUrl: e.imageUrl, id: e.id, title: e.title), + ) + .toList(); + } + + static Stream> + subscribeToCurrentUser() { + return MoviesConnector.instance.getCurrentUser().ref().subscribe(); + } + + static Future toggleFavorite(String id, bool favorited) async { + if (favorited) { + await MoviesConnector.instance + .deleteFavoritedMovie(movieId: id) + .execute(); + } else { + await MoviesConnector.instance.addFavoritedMovie(movieId: id).execute(); + } + triggerUpdateFavorite(); + } +} diff --git a/dataconnect/flutter-movie/lib/movies_connector/add_favorited_movie.dart b/dataconnect/flutter-movie/lib/movies_connector/add_favorited_movie.dart new file mode 100644 index 00000000..9f2a90b9 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/add_favorited_movie.dart @@ -0,0 +1,192 @@ +part of movies_connector; + +class AddFavoritedMovieVariablesBuilder { + String movieId; + + + FirebaseDataConnect _dataConnect; + + AddFavoritedMovieVariablesBuilder(this._dataConnect, {required String this.movieId,}); + Deserializer dataDeserializer = (dynamic json) => AddFavoritedMovieData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (AddFavoritedMovieVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + MutationRef ref() { + AddFavoritedMovieVariables vars=AddFavoritedMovieVariables(movieId: movieId,); + + return _dataConnect.mutation("AddFavoritedMovie", dataDeserializer, varsSerializer, vars); + } +} + + + class AddFavoritedMovieFavoriteMovieUpsert { + + String userId; + + + String movieId; + + + + + + + AddFavoritedMovieFavoriteMovieUpsert.fromJson(dynamic json): + userId = + + nativeFromJson(json['userId']) + + + + , + + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['userId'] = + + nativeToJson(userId) + +; + + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + AddFavoritedMovieFavoriteMovieUpsert({ + + required this.userId, + + required this.movieId, + + }); +} + + + + class AddFavoritedMovieData { + + AddFavoritedMovieFavoriteMovieUpsert favorite_movie_upsert; + + + + + + + AddFavoritedMovieData.fromJson(dynamic json): + favorite_movie_upsert = + + AddFavoritedMovieFavoriteMovieUpsert.fromJson(json['favorite_movie_upsert']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['favorite_movie_upsert'] = + + favorite_movie_upsert.toJson() + +; + + + return json; + } + + AddFavoritedMovieData({ + + required this.favorite_movie_upsert, + + }); +} + + + + class AddFavoritedMovieVariables { + + String movieId; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + AddFavoritedMovieVariables.fromJson(Map json): + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + AddFavoritedMovieVariables({ + + required this.movieId, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/add_review.dart b/dataconnect/flutter-movie/lib/movies_connector/add_review.dart new file mode 100644 index 00000000..bbf6f7af --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/add_review.dart @@ -0,0 +1,240 @@ +part of movies_connector; + +class AddReviewVariablesBuilder { + String movieId; +int rating; +String reviewText; + + + FirebaseDataConnect _dataConnect; + + AddReviewVariablesBuilder(this._dataConnect, {required String this.movieId,required int this.rating,required String this.reviewText,}); + Deserializer dataDeserializer = (dynamic json) => AddReviewData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (AddReviewVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + MutationRef ref() { + AddReviewVariables vars=AddReviewVariables(movieId: movieId,rating: rating,reviewText: reviewText,); + + return _dataConnect.mutation("AddReview", dataDeserializer, varsSerializer, vars); + } +} + + + class AddReviewReviewUpsert { + + String userId; + + + String movieId; + + + + + + + AddReviewReviewUpsert.fromJson(dynamic json): + userId = + + nativeFromJson(json['userId']) + + + + , + + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['userId'] = + + nativeToJson(userId) + +; + + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + AddReviewReviewUpsert({ + + required this.userId, + + required this.movieId, + + }); +} + + + + class AddReviewData { + + AddReviewReviewUpsert review_upsert; + + + + + + + AddReviewData.fromJson(dynamic json): + review_upsert = + + AddReviewReviewUpsert.fromJson(json['review_upsert']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['review_upsert'] = + + review_upsert.toJson() + +; + + + return json; + } + + AddReviewData({ + + required this.review_upsert, + + }); +} + + + + class AddReviewVariables { + + String movieId; + + + int rating; + + + String reviewText; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + AddReviewVariables.fromJson(Map json): + movieId = + + nativeFromJson(json['movieId']) + + + + , + + rating = + + nativeFromJson(json['rating']) + + + + , + + reviewText = + + nativeFromJson(json['reviewText']) + + + + + { + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + + json['rating'] = + + nativeToJson(rating) + +; + + + + json['reviewText'] = + + nativeToJson(reviewText) + +; + + + return json; + } + + AddReviewVariables({ + + required this.movieId, + + required this.rating, + + required this.reviewText, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/delete_favorited_movie.dart b/dataconnect/flutter-movie/lib/movies_connector/delete_favorited_movie.dart new file mode 100644 index 00000000..2071ee5d --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/delete_favorited_movie.dart @@ -0,0 +1,194 @@ +part of movies_connector; + +class DeleteFavoritedMovieVariablesBuilder { + String movieId; + + + FirebaseDataConnect _dataConnect; + + DeleteFavoritedMovieVariablesBuilder(this._dataConnect, {required String this.movieId,}); + Deserializer dataDeserializer = (dynamic json) => DeleteFavoritedMovieData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (DeleteFavoritedMovieVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + MutationRef ref() { + DeleteFavoritedMovieVariables vars=DeleteFavoritedMovieVariables(movieId: movieId,); + + return _dataConnect.mutation("DeleteFavoritedMovie", dataDeserializer, varsSerializer, vars); + } +} + + + class DeleteFavoritedMovieFavoriteMovieDelete { + + String userId; + + + String movieId; + + + + + + + DeleteFavoritedMovieFavoriteMovieDelete.fromJson(dynamic json): + userId = + + nativeFromJson(json['userId']) + + + + , + + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['userId'] = + + nativeToJson(userId) + +; + + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + DeleteFavoritedMovieFavoriteMovieDelete({ + + required this.userId, + + required this.movieId, + + }); +} + + + + class DeleteFavoritedMovieData { + + DeleteFavoritedMovieFavoriteMovieDelete? favorite_movie_delete; + + + + + + + DeleteFavoritedMovieData.fromJson(dynamic json): + favorite_movie_delete = json['favorite_movie_delete'] == null ? null : + + DeleteFavoritedMovieFavoriteMovieDelete.fromJson(json['favorite_movie_delete']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (favorite_movie_delete != null) { + json['favorite_movie_delete'] = + + favorite_movie_delete!.toJson() + +; + } + + + return json; + } + + DeleteFavoritedMovieData({ + + this.favorite_movie_delete, + + }); +} + + + + class DeleteFavoritedMovieVariables { + + String movieId; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + DeleteFavoritedMovieVariables.fromJson(Map json): + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + DeleteFavoritedMovieVariables({ + + required this.movieId, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/delete_review.dart b/dataconnect/flutter-movie/lib/movies_connector/delete_review.dart new file mode 100644 index 00000000..49fe10cd --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/delete_review.dart @@ -0,0 +1,194 @@ +part of movies_connector; + +class DeleteReviewVariablesBuilder { + String movieId; + + + FirebaseDataConnect _dataConnect; + + DeleteReviewVariablesBuilder(this._dataConnect, {required String this.movieId,}); + Deserializer dataDeserializer = (dynamic json) => DeleteReviewData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (DeleteReviewVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + MutationRef ref() { + DeleteReviewVariables vars=DeleteReviewVariables(movieId: movieId,); + + return _dataConnect.mutation("DeleteReview", dataDeserializer, varsSerializer, vars); + } +} + + + class DeleteReviewReviewDelete { + + String userId; + + + String movieId; + + + + + + + DeleteReviewReviewDelete.fromJson(dynamic json): + userId = + + nativeFromJson(json['userId']) + + + + , + + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['userId'] = + + nativeToJson(userId) + +; + + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + DeleteReviewReviewDelete({ + + required this.userId, + + required this.movieId, + + }); +} + + + + class DeleteReviewData { + + DeleteReviewReviewDelete? review_delete; + + + + + + + DeleteReviewData.fromJson(dynamic json): + review_delete = json['review_delete'] == null ? null : + + DeleteReviewReviewDelete.fromJson(json['review_delete']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (review_delete != null) { + json['review_delete'] = + + review_delete!.toJson() + +; + } + + + return json; + } + + DeleteReviewData({ + + this.review_delete, + + }); +} + + + + class DeleteReviewVariables { + + String movieId; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + DeleteReviewVariables.fromJson(Map json): + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + DeleteReviewVariables({ + + required this.movieId, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/get_actor_by_id.dart b/dataconnect/flutter-movie/lib/movies_connector/get_actor_by_id.dart new file mode 100644 index 00000000..5400fa07 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/get_actor_by_id.dart @@ -0,0 +1,573 @@ +part of movies_connector; + +class GetActorByIdVariablesBuilder { + String id; + + + FirebaseDataConnect _dataConnect; + + GetActorByIdVariablesBuilder(this._dataConnect, {required String this.id,}); + Deserializer dataDeserializer = (dynamic json) => GetActorByIdData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (GetActorByIdVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + GetActorByIdVariables vars=GetActorByIdVariables(id: id,); + + return _dataConnect.query("GetActorById", dataDeserializer, varsSerializer, vars); + } +} + + + class GetActorByIdActor { + + String id; + + + String name; + + + String imageUrl; + + + List mainActors; + + + List supportingActors; + + + + + + + GetActorByIdActor.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + name = + + nativeFromJson(json['name']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + , + + mainActors = + + + (json['mainActors'] as List) + .map((e) => GetActorByIdActorMainActors.fromJson(e)) + .toList() + + + + + , + + supportingActors = + + + (json['supportingActors'] as List) + .map((e) => GetActorByIdActorSupportingActors.fromJson(e)) + .toList() + + + + + + { + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['name'] = + + nativeToJson(name) + +; + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + + json['mainActors'] = + + + mainActors.map((e) => e.toJson()).toList() + + +; + + + + json['supportingActors'] = + + + supportingActors.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + GetActorByIdActor({ + + required this.id, + + required this.name, + + required this.imageUrl, + + required this.mainActors, + + required this.supportingActors, + + }); +} + + + + class GetActorByIdActorMainActors { + + String id; + + + String title; + + + String? genre; + + + List? tags; + + + String imageUrl; + + + + + + + GetActorByIdActorMainActors.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + tags = json['tags'] == null ? null : + + + (json['tags'] as List) + .map((e) => nativeFromJson(e)) + .toList() + + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + + { + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + if (tags != null) { + json['tags'] = + + + tags?.map((e) => nativeToJson(e)).toList() + + +; + } + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + return json; + } + + GetActorByIdActorMainActors({ + + required this.id, + + required this.title, + + this.genre, + + this.tags, + + required this.imageUrl, + + }); +} + + + + class GetActorByIdActorSupportingActors { + + String id; + + + String title; + + + String? genre; + + + List? tags; + + + String imageUrl; + + + + + + + GetActorByIdActorSupportingActors.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + tags = json['tags'] == null ? null : + + + (json['tags'] as List) + .map((e) => nativeFromJson(e)) + .toList() + + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + + { + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + if (tags != null) { + json['tags'] = + + + tags?.map((e) => nativeToJson(e)).toList() + + +; + } + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + return json; + } + + GetActorByIdActorSupportingActors({ + + required this.id, + + required this.title, + + this.genre, + + this.tags, + + required this.imageUrl, + + }); +} + + + + class GetActorByIdData { + + GetActorByIdActor? actor; + + + + + + + GetActorByIdData.fromJson(dynamic json): + actor = json['actor'] == null ? null : + + GetActorByIdActor.fromJson(json['actor']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (actor != null) { + json['actor'] = + + actor!.toJson() + +; + } + + + return json; + } + + GetActorByIdData({ + + this.actor, + + }); +} + + + + class GetActorByIdVariables { + + String id; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + GetActorByIdVariables.fromJson(Map json): + id = + + nativeFromJson(json['id']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + return json; + } + + GetActorByIdVariables({ + + required this.id, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/get_current_user.dart b/dataconnect/flutter-movie/lib/movies_connector/get_current_user.dart new file mode 100644 index 00000000..38a7e191 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/get_current_user.dart @@ -0,0 +1,763 @@ +part of movies_connector; + +class GetCurrentUserVariablesBuilder { + + + FirebaseDataConnect _dataConnect; + + GetCurrentUserVariablesBuilder(this._dataConnect, ); + Deserializer dataDeserializer = (dynamic json) => GetCurrentUserData.fromJson(jsonDecode(json)); + + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + + return _dataConnect.query("GetCurrentUser", dataDeserializer, emptySerializer, null); + } +} + + + class GetCurrentUserUser { + + String id; + + + String username; + + + List reviews; + + + List favoriteMovies; + + + + + + + GetCurrentUserUser.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + username = + + nativeFromJson(json['username']) + + + + , + + reviews = + + + (json['reviews'] as List) + .map((e) => GetCurrentUserUserReviews.fromJson(e)) + .toList() + + + + + , + + favoriteMovies = + + + (json['favoriteMovies'] as List) + .map((e) => GetCurrentUserUserFavoriteMovies.fromJson(e)) + .toList() + + + + + + { + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['username'] = + + nativeToJson(username) + +; + + + + json['reviews'] = + + + reviews.map((e) => e.toJson()).toList() + + +; + + + + json['favoriteMovies'] = + + + favoriteMovies.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + GetCurrentUserUser({ + + required this.id, + + required this.username, + + required this.reviews, + + required this.favoriteMovies, + + }); +} + + + + class GetCurrentUserUserReviews { + + String id; + + + int? rating; + + + DateTime reviewDate; + + + String? reviewText; + + + GetCurrentUserUserReviewsMovie movie; + + + + + + + GetCurrentUserUserReviews.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + reviewDate = + + nativeFromJson(json['reviewDate']) + + + + , + + reviewText = json['reviewText'] == null ? null : + + nativeFromJson(json['reviewText']) + + + + , + + movie = + + GetCurrentUserUserReviewsMovie.fromJson(json['movie']) + + + + + { + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + json['reviewDate'] = + + nativeToJson(reviewDate) + +; + + + + if (reviewText != null) { + json['reviewText'] = + + nativeToJson(reviewText) + +; + } + + + + json['movie'] = + + movie.toJson() + +; + + + return json; + } + + GetCurrentUserUserReviews({ + + required this.id, + + this.rating, + + required this.reviewDate, + + this.reviewText, + + required this.movie, + + }); +} + + + + class GetCurrentUserUserReviewsMovie { + + String id; + + + String title; + + + + + + + GetCurrentUserUserReviewsMovie.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + return json; + } + + GetCurrentUserUserReviewsMovie({ + + required this.id, + + required this.title, + + }); +} + + + + class GetCurrentUserUserFavoriteMovies { + + GetCurrentUserUserFavoriteMoviesMovie movie; + + + + + + + GetCurrentUserUserFavoriteMovies.fromJson(dynamic json): + movie = + + GetCurrentUserUserFavoriteMoviesMovie.fromJson(json['movie']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movie'] = + + movie.toJson() + +; + + + return json; + } + + GetCurrentUserUserFavoriteMovies({ + + required this.movie, + + }); +} + + + + class GetCurrentUserUserFavoriteMoviesMovie { + + String id; + + + String title; + + + String? genre; + + + String imageUrl; + + + int? releaseYear; + + + double? rating; + + + String? description; + + + List? tags; + + + List metadata; + + + + + + + GetCurrentUserUserFavoriteMoviesMovie.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + , + + releaseYear = json['releaseYear'] == null ? null : + + nativeFromJson(json['releaseYear']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + description = json['description'] == null ? null : + + nativeFromJson(json['description']) + + + + , + + tags = json['tags'] == null ? null : + + + (json['tags'] as List) + .map((e) => nativeFromJson(e)) + .toList() + + + + + , + + metadata = + + + (json['metadata'] as List) + .map((e) => GetCurrentUserUserFavoriteMoviesMovieMetadata.fromJson(e)) + .toList() + + + + + + { + + + + + + + + + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + + if (releaseYear != null) { + json['releaseYear'] = + + nativeToJson(releaseYear) + +; + } + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + if (description != null) { + json['description'] = + + nativeToJson(description) + +; + } + + + + if (tags != null) { + json['tags'] = + + + tags?.map((e) => nativeToJson(e)).toList() + + +; + } + + + + json['metadata'] = + + + metadata.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + GetCurrentUserUserFavoriteMoviesMovie({ + + required this.id, + + required this.title, + + this.genre, + + required this.imageUrl, + + this.releaseYear, + + this.rating, + + this.description, + + this.tags, + + required this.metadata, + + }); +} + + + + class GetCurrentUserUserFavoriteMoviesMovieMetadata { + + String? director; + + + + + + + GetCurrentUserUserFavoriteMoviesMovieMetadata.fromJson(dynamic json): + director = json['director'] == null ? null : + + nativeFromJson(json['director']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (director != null) { + json['director'] = + + nativeToJson(director) + +; + } + + + return json; + } + + GetCurrentUserUserFavoriteMoviesMovieMetadata({ + + this.director, + + }); +} + + + + class GetCurrentUserData { + + GetCurrentUserUser? user; + + + + + + + GetCurrentUserData.fromJson(dynamic json): + user = json['user'] == null ? null : + + GetCurrentUserUser.fromJson(json['user']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (user != null) { + json['user'] = + + user!.toJson() + +; + } + + + return json; + } + + GetCurrentUserData({ + + this.user, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/get_movie_by_id.dart b/dataconnect/flutter-movie/lib/movies_connector/get_movie_by_id.dart new file mode 100644 index 00000000..56cc681c --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/get_movie_by_id.dart @@ -0,0 +1,912 @@ +part of movies_connector; + +class GetMovieByIdVariablesBuilder { + String id; + + + FirebaseDataConnect _dataConnect; + + GetMovieByIdVariablesBuilder(this._dataConnect, {required String this.id,}); + Deserializer dataDeserializer = (dynamic json) => GetMovieByIdData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (GetMovieByIdVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + GetMovieByIdVariables vars=GetMovieByIdVariables(id: id,); + + return _dataConnect.query("GetMovieById", dataDeserializer, varsSerializer, vars); + } +} + + + class GetMovieByIdMovie { + + String id; + + + String title; + + + String imageUrl; + + + int? releaseYear; + + + String? genre; + + + double? rating; + + + String? description; + + + List? tags; + + + List metadata; + + + List mainActors; + + + List supportingActors; + + + List reviews; + + + + + + + GetMovieByIdMovie.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + , + + releaseYear = json['releaseYear'] == null ? null : + + nativeFromJson(json['releaseYear']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + description = json['description'] == null ? null : + + nativeFromJson(json['description']) + + + + , + + tags = json['tags'] == null ? null : + + + (json['tags'] as List) + .map((e) => nativeFromJson(e)) + .toList() + + + + + , + + metadata = + + + (json['metadata'] as List) + .map((e) => GetMovieByIdMovieMetadata.fromJson(e)) + .toList() + + + + + , + + mainActors = + + + (json['mainActors'] as List) + .map((e) => GetMovieByIdMovieMainActors.fromJson(e)) + .toList() + + + + + , + + supportingActors = + + + (json['supportingActors'] as List) + .map((e) => GetMovieByIdMovieSupportingActors.fromJson(e)) + .toList() + + + + + , + + reviews = + + + (json['reviews'] as List) + .map((e) => GetMovieByIdMovieReviews.fromJson(e)) + .toList() + + + + + + { + + + + + + + + + + + + + + + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + + if (releaseYear != null) { + json['releaseYear'] = + + nativeToJson(releaseYear) + +; + } + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + if (description != null) { + json['description'] = + + nativeToJson(description) + +; + } + + + + if (tags != null) { + json['tags'] = + + + tags?.map((e) => nativeToJson(e)).toList() + + +; + } + + + + json['metadata'] = + + + metadata.map((e) => e.toJson()).toList() + + +; + + + + json['mainActors'] = + + + mainActors.map((e) => e.toJson()).toList() + + +; + + + + json['supportingActors'] = + + + supportingActors.map((e) => e.toJson()).toList() + + +; + + + + json['reviews'] = + + + reviews.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + GetMovieByIdMovie({ + + required this.id, + + required this.title, + + required this.imageUrl, + + this.releaseYear, + + this.genre, + + this.rating, + + this.description, + + this.tags, + + required this.metadata, + + required this.mainActors, + + required this.supportingActors, + + required this.reviews, + + }); +} + + + + class GetMovieByIdMovieMetadata { + + String? director; + + + + + + + GetMovieByIdMovieMetadata.fromJson(dynamic json): + director = json['director'] == null ? null : + + nativeFromJson(json['director']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (director != null) { + json['director'] = + + nativeToJson(director) + +; + } + + + return json; + } + + GetMovieByIdMovieMetadata({ + + this.director, + + }); +} + + + + class GetMovieByIdMovieMainActors { + + String id; + + + String name; + + + String imageUrl; + + + + + + + GetMovieByIdMovieMainActors.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + name = + + nativeFromJson(json['name']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + + { + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['name'] = + + nativeToJson(name) + +; + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + return json; + } + + GetMovieByIdMovieMainActors({ + + required this.id, + + required this.name, + + required this.imageUrl, + + }); +} + + + + class GetMovieByIdMovieSupportingActors { + + String id; + + + String name; + + + String imageUrl; + + + + + + + GetMovieByIdMovieSupportingActors.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + name = + + nativeFromJson(json['name']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + + { + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['name'] = + + nativeToJson(name) + +; + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + return json; + } + + GetMovieByIdMovieSupportingActors({ + + required this.id, + + required this.name, + + required this.imageUrl, + + }); +} + + + + class GetMovieByIdMovieReviews { + + String id; + + + String? reviewText; + + + DateTime reviewDate; + + + int? rating; + + + GetMovieByIdMovieReviewsUser user; + + + + + + + GetMovieByIdMovieReviews.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + reviewText = json['reviewText'] == null ? null : + + nativeFromJson(json['reviewText']) + + + + , + + reviewDate = + + nativeFromJson(json['reviewDate']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + user = + + GetMovieByIdMovieReviewsUser.fromJson(json['user']) + + + + + { + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + if (reviewText != null) { + json['reviewText'] = + + nativeToJson(reviewText) + +; + } + + + + json['reviewDate'] = + + nativeToJson(reviewDate) + +; + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + json['user'] = + + user.toJson() + +; + + + return json; + } + + GetMovieByIdMovieReviews({ + + required this.id, + + this.reviewText, + + required this.reviewDate, + + this.rating, + + required this.user, + + }); +} + + + + class GetMovieByIdMovieReviewsUser { + + String id; + + + String username; + + + + + + + GetMovieByIdMovieReviewsUser.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + username = + + nativeFromJson(json['username']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['username'] = + + nativeToJson(username) + +; + + + return json; + } + + GetMovieByIdMovieReviewsUser({ + + required this.id, + + required this.username, + + }); +} + + + + class GetMovieByIdData { + + GetMovieByIdMovie? movie; + + + + + + + GetMovieByIdData.fromJson(dynamic json): + movie = json['movie'] == null ? null : + + GetMovieByIdMovie.fromJson(json['movie']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (movie != null) { + json['movie'] = + + movie!.toJson() + +; + } + + + return json; + } + + GetMovieByIdData({ + + this.movie, + + }); +} + + + + class GetMovieByIdVariables { + + String id; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + GetMovieByIdVariables.fromJson(Map json): + id = + + nativeFromJson(json['id']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + return json; + } + + GetMovieByIdVariables({ + + required this.id, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/get_movie_info_for_user.dart b/dataconnect/flutter-movie/lib/movies_connector/get_movie_info_for_user.dart new file mode 100644 index 00000000..753020d4 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/get_movie_info_for_user.dart @@ -0,0 +1,171 @@ +part of movies_connector; + +class GetMovieInfoForUserVariablesBuilder { + String movieId; + + + FirebaseDataConnect _dataConnect; + + GetMovieInfoForUserVariablesBuilder(this._dataConnect, {required String this.movieId,}); + Deserializer dataDeserializer = (dynamic json) => GetMovieInfoForUserData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (GetMovieInfoForUserVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + GetMovieInfoForUserVariables vars=GetMovieInfoForUserVariables(movieId: movieId,); + + return _dataConnect.query("GetMovieInfoForUser", dataDeserializer, varsSerializer, vars); + } +} + + + class GetMovieInfoForUserFavoriteMovie { + + String movieId; + + + + + + + GetMovieInfoForUserFavoriteMovie.fromJson(dynamic json): + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + GetMovieInfoForUserFavoriteMovie({ + + required this.movieId, + + }); +} + + + + class GetMovieInfoForUserData { + + GetMovieInfoForUserFavoriteMovie? favorite_movie; + + + + + + + GetMovieInfoForUserData.fromJson(dynamic json): + favorite_movie = json['favorite_movie'] == null ? null : + + GetMovieInfoForUserFavoriteMovie.fromJson(json['favorite_movie']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (favorite_movie != null) { + json['favorite_movie'] = + + favorite_movie!.toJson() + +; + } + + + return json; + } + + GetMovieInfoForUserData({ + + this.favorite_movie, + + }); +} + + + + class GetMovieInfoForUserVariables { + + String movieId; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + GetMovieInfoForUserVariables.fromJson(Map json): + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + GetMovieInfoForUserVariables({ + + required this.movieId, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/list_genres.dart b/dataconnect/flutter-movie/lib/movies_connector/list_genres.dart new file mode 100644 index 00000000..dd834671 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/list_genres.dart @@ -0,0 +1,126 @@ +part of movies_connector; + +class ListGenresVariablesBuilder { + + + FirebaseDataConnect _dataConnect; + + ListGenresVariablesBuilder(this._dataConnect, ); + Deserializer dataDeserializer = (dynamic json) => ListGenresData.fromJson(jsonDecode(json)); + + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + + return _dataConnect.query("ListGenres", dataDeserializer, emptySerializer, null); + } +} + + + class ListGenresGenres { + + String? genre; + + + + + + + ListGenresGenres.fromJson(dynamic json): + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + return json; + } + + ListGenresGenres({ + + this.genre, + + }); +} + + + + class ListGenresData { + + List genres; + + + + + + + ListGenresData.fromJson(dynamic json): + genres = + + + (json['genres'] as List) + .map((e) => ListGenresGenres.fromJson(e)) + .toList() + + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['genres'] = + + + genres.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + ListGenresData({ + + required this.genres, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/list_movies.dart b/dataconnect/flutter-movie/lib/movies_connector/list_movies.dart new file mode 100644 index 00000000..57399267 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/list_movies.dart @@ -0,0 +1,403 @@ +part of movies_connector; + +class ListMoviesVariablesBuilder { + Optional _orderByRating = Optional.optional(orderDirectionDeserializer, enumSerializer); +Optional _orderByReleaseYear = Optional.optional(orderDirectionDeserializer, enumSerializer); +Optional _limit = Optional.optional(nativeFromJson, nativeToJson); + + + FirebaseDataConnect _dataConnect; + ListMoviesVariablesBuilder orderByRating(OrderDirection? t) { +this._orderByRating.value = t; +return this; +} +ListMoviesVariablesBuilder orderByReleaseYear(OrderDirection? t) { +this._orderByReleaseYear.value = t; +return this; +} +ListMoviesVariablesBuilder limit(int? t) { +this._limit.value = t; +return this; +} + + ListMoviesVariablesBuilder(this._dataConnect, ); + Deserializer dataDeserializer = (dynamic json) => ListMoviesData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (ListMoviesVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + ListMoviesVariables vars=ListMoviesVariables(orderByRating: _orderByRating,orderByReleaseYear: _orderByReleaseYear,limit: _limit,); + + return _dataConnect.query("ListMovies", dataDeserializer, varsSerializer, vars); + } +} + + + class ListMoviesMovies { + + String id; + + + String title; + + + String imageUrl; + + + int? releaseYear; + + + String? genre; + + + double? rating; + + + List? tags; + + + String? description; + + + + + + + ListMoviesMovies.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + , + + releaseYear = json['releaseYear'] == null ? null : + + nativeFromJson(json['releaseYear']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + tags = json['tags'] == null ? null : + + + (json['tags'] as List) + .map((e) => nativeFromJson(e)) + .toList() + + + + + , + + description = json['description'] == null ? null : + + nativeFromJson(json['description']) + + + + + { + + + + + + + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + + if (releaseYear != null) { + json['releaseYear'] = + + nativeToJson(releaseYear) + +; + } + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + if (tags != null) { + json['tags'] = + + + tags?.map((e) => nativeToJson(e)).toList() + + +; + } + + + + if (description != null) { + json['description'] = + + nativeToJson(description) + +; + } + + + return json; + } + + ListMoviesMovies({ + + required this.id, + + required this.title, + + required this.imageUrl, + + this.releaseYear, + + this.genre, + + this.rating, + + this.tags, + + this.description, + + }); +} + + + + class ListMoviesData { + + List movies; + + + + + + + ListMoviesData.fromJson(dynamic json): + movies = + + + (json['movies'] as List) + .map((e) => ListMoviesMovies.fromJson(e)) + .toList() + + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movies'] = + + + movies.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + ListMoviesData({ + + required this.movies, + + }); +} + + + + class ListMoviesVariables { + + late OptionalorderByRating; + + + late OptionalorderByReleaseYear; + + + late Optionallimit; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + ListMoviesVariables.fromJson(Map json) { + + + orderByRating = Optional.optional(orderDirectionDeserializer, enumSerializer); + orderByRating.value = json['orderByRating'] == null ? null : + + OrderDirection.values.byName(json['orderByRating']) + +; + + + + orderByReleaseYear = Optional.optional(orderDirectionDeserializer, enumSerializer); + orderByReleaseYear.value = json['orderByReleaseYear'] == null ? null : + + OrderDirection.values.byName(json['orderByReleaseYear']) + +; + + + + limit = Optional.optional(nativeFromJson, nativeToJson); + limit.value = json['limit'] == null ? null : + + nativeFromJson(json['limit']) + +; + + + } + + + Map toJson() { + Map json = {}; + + + if(orderByRating.state == OptionalState.set) { + json['orderByRating'] = orderByRating.toJson(); + } + + + + if(orderByReleaseYear.state == OptionalState.set) { + json['orderByReleaseYear'] = orderByReleaseYear.toJson(); + } + + + + if(limit.state == OptionalState.set) { + json['limit'] = limit.toJson(); + } + + + return json; + } + + ListMoviesVariables({ + + required this.orderByRating, + + required this.orderByReleaseYear, + + required this.limit, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/list_movies_by_genre.dart b/dataconnect/flutter-movie/lib/movies_connector/list_movies_by_genre.dart new file mode 100644 index 00000000..a0bfb78d --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/list_movies_by_genre.dart @@ -0,0 +1,427 @@ +part of movies_connector; + +class ListMoviesByGenreVariablesBuilder { + String genre; +Optional _orderByRating = Optional.optional(orderDirectionDeserializer, enumSerializer); +Optional _orderByReleaseYear = Optional.optional(orderDirectionDeserializer, enumSerializer); +Optional _limit = Optional.optional(nativeFromJson, nativeToJson); + + + FirebaseDataConnect _dataConnect; + ListMoviesByGenreVariablesBuilder orderByRating(OrderDirection? t) { +this._orderByRating.value = t; +return this; +} +ListMoviesByGenreVariablesBuilder orderByReleaseYear(OrderDirection? t) { +this._orderByReleaseYear.value = t; +return this; +} +ListMoviesByGenreVariablesBuilder limit(int? t) { +this._limit.value = t; +return this; +} + + ListMoviesByGenreVariablesBuilder(this._dataConnect, {required String this.genre,}); + Deserializer dataDeserializer = (dynamic json) => ListMoviesByGenreData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (ListMoviesByGenreVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + ListMoviesByGenreVariables vars=ListMoviesByGenreVariables(genre: genre,orderByRating: _orderByRating,orderByReleaseYear: _orderByReleaseYear,limit: _limit,); + + return _dataConnect.query("ListMoviesByGenre", dataDeserializer, varsSerializer, vars); + } +} + + + class ListMoviesByGenreMovies { + + String id; + + + String title; + + + String imageUrl; + + + int? releaseYear; + + + String? genre; + + + double? rating; + + + List? tags; + + + String? description; + + + + + + + ListMoviesByGenreMovies.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + , + + releaseYear = json['releaseYear'] == null ? null : + + nativeFromJson(json['releaseYear']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + tags = json['tags'] == null ? null : + + + (json['tags'] as List) + .map((e) => nativeFromJson(e)) + .toList() + + + + + , + + description = json['description'] == null ? null : + + nativeFromJson(json['description']) + + + + + { + + + + + + + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + + if (releaseYear != null) { + json['releaseYear'] = + + nativeToJson(releaseYear) + +; + } + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + if (tags != null) { + json['tags'] = + + + tags?.map((e) => nativeToJson(e)).toList() + + +; + } + + + + if (description != null) { + json['description'] = + + nativeToJson(description) + +; + } + + + return json; + } + + ListMoviesByGenreMovies({ + + required this.id, + + required this.title, + + required this.imageUrl, + + this.releaseYear, + + this.genre, + + this.rating, + + this.tags, + + this.description, + + }); +} + + + + class ListMoviesByGenreData { + + List movies; + + + + + + + ListMoviesByGenreData.fromJson(dynamic json): + movies = + + + (json['movies'] as List) + .map((e) => ListMoviesByGenreMovies.fromJson(e)) + .toList() + + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movies'] = + + + movies.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + ListMoviesByGenreData({ + + required this.movies, + + }); +} + + + + class ListMoviesByGenreVariables { + + String genre; + + + late OptionalorderByRating; + + + late OptionalorderByReleaseYear; + + + late Optionallimit; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + ListMoviesByGenreVariables.fromJson(Map json): + genre = + + nativeFromJson(json['genre']) + + + + + { + + + + + orderByRating = Optional.optional(orderDirectionDeserializer, enumSerializer); + orderByRating.value = json['orderByRating'] == null ? null : + + OrderDirection.values.byName(json['orderByRating']) + +; + + + + orderByReleaseYear = Optional.optional(orderDirectionDeserializer, enumSerializer); + orderByReleaseYear.value = json['orderByReleaseYear'] == null ? null : + + OrderDirection.values.byName(json['orderByReleaseYear']) + +; + + + + limit = Optional.optional(nativeFromJson, nativeToJson); + limit.value = json['limit'] == null ? null : + + nativeFromJson(json['limit']) + +; + + + } + + + Map toJson() { + Map json = {}; + + + json['genre'] = + + nativeToJson(genre) + +; + + + + if(orderByRating.state == OptionalState.set) { + json['orderByRating'] = orderByRating.toJson(); + } + + + + if(orderByReleaseYear.state == OptionalState.set) { + json['orderByReleaseYear'] = orderByReleaseYear.toJson(); + } + + + + if(limit.state == OptionalState.set) { + json['limit'] = limit.toJson(); + } + + + return json; + } + + ListMoviesByGenreVariables({ + + required this.genre, + + required this.orderByRating, + + required this.orderByReleaseYear, + + required this.limit, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/list_movies_by_partial_title.dart b/dataconnect/flutter-movie/lib/movies_connector/list_movies_by_partial_title.dart new file mode 100644 index 00000000..41cf6b8d --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/list_movies_by_partial_title.dart @@ -0,0 +1,296 @@ +part of movies_connector; + +class ListMoviesByPartialTitleVariablesBuilder { + String input; + + + FirebaseDataConnect _dataConnect; + + ListMoviesByPartialTitleVariablesBuilder(this._dataConnect, {required String this.input,}); + Deserializer dataDeserializer = (dynamic json) => ListMoviesByPartialTitleData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (ListMoviesByPartialTitleVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + ListMoviesByPartialTitleVariables vars=ListMoviesByPartialTitleVariables(input: input,); + + return _dataConnect.query("ListMoviesByPartialTitle", dataDeserializer, varsSerializer, vars); + } +} + + + class ListMoviesByPartialTitleMovies { + + String id; + + + String title; + + + String? genre; + + + double? rating; + + + String imageUrl; + + + String? description; + + + + + + + ListMoviesByPartialTitleMovies.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + , + + description = json['description'] == null ? null : + + nativeFromJson(json['description']) + + + + + { + + + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + + if (description != null) { + json['description'] = + + nativeToJson(description) + +; + } + + + return json; + } + + ListMoviesByPartialTitleMovies({ + + required this.id, + + required this.title, + + this.genre, + + this.rating, + + required this.imageUrl, + + this.description, + + }); +} + + + + class ListMoviesByPartialTitleData { + + List movies; + + + + + + + ListMoviesByPartialTitleData.fromJson(dynamic json): + movies = + + + (json['movies'] as List) + .map((e) => ListMoviesByPartialTitleMovies.fromJson(e)) + .toList() + + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['movies'] = + + + movies.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + ListMoviesByPartialTitleData({ + + required this.movies, + + }); +} + + + + class ListMoviesByPartialTitleVariables { + + String input; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + ListMoviesByPartialTitleVariables.fromJson(Map json): + input = + + nativeFromJson(json['input']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['input'] = + + nativeToJson(input) + +; + + + return json; + } + + ListMoviesByPartialTitleVariables({ + + required this.input, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/movies.dart b/dataconnect/flutter-movie/lib/movies_connector/movies.dart new file mode 100644 index 00000000..acb06fdc --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/movies.dart @@ -0,0 +1,150 @@ +library movies_connector; +import 'package:firebase_data_connect/firebase_data_connect.dart'; +import 'dart:convert'; + +part 'upsert_user.dart'; + +part 'add_favorited_movie.dart'; + +part 'delete_favorited_movie.dart'; + +part 'add_review.dart'; + +part 'update_review.dart'; + +part 'delete_review.dart'; + +part 'list_movies.dart'; + +part 'list_movies_by_genre.dart'; + +part 'list_genres.dart'; + +part 'get_movie_by_id.dart'; + +part 'get_actor_by_id.dart'; + +part 'get_current_user.dart'; + +part 'get_movie_info_for_user.dart'; + +part 'search_all.dart'; + +part 'list_movies_by_partial_title.dart'; + + + + enum OrderDirection { + + ASC, + + DESC, + + } + OrderDirection orderDirectionDeserializer(dynamic data) { + return OrderDirection.values.byName(data); + } + + + +String enumSerializer(Enum e) { + return e.name; +} + + + +class MoviesConnector { + + + UpsertUserVariablesBuilder upsertUser ({required String username,}) { + return UpsertUserVariablesBuilder(dataConnect, username: username,); + } + + + AddFavoritedMovieVariablesBuilder addFavoritedMovie ({required String movieId,}) { + return AddFavoritedMovieVariablesBuilder(dataConnect, movieId: movieId,); + } + + + DeleteFavoritedMovieVariablesBuilder deleteFavoritedMovie ({required String movieId,}) { + return DeleteFavoritedMovieVariablesBuilder(dataConnect, movieId: movieId,); + } + + + AddReviewVariablesBuilder addReview ({required String movieId,required int rating,required String reviewText,}) { + return AddReviewVariablesBuilder(dataConnect, movieId: movieId,rating: rating,reviewText: reviewText,); + } + + + UpdateReviewVariablesBuilder updateReview ({required String movieId,required int rating,required String reviewText,}) { + return UpdateReviewVariablesBuilder(dataConnect, movieId: movieId,rating: rating,reviewText: reviewText,); + } + + + DeleteReviewVariablesBuilder deleteReview ({required String movieId,}) { + return DeleteReviewVariablesBuilder(dataConnect, movieId: movieId,); + } + + + ListMoviesVariablesBuilder listMovies () { + return ListMoviesVariablesBuilder(dataConnect, ); + } + + + ListMoviesByGenreVariablesBuilder listMoviesByGenre ({required String genre,}) { + return ListMoviesByGenreVariablesBuilder(dataConnect, genre: genre,); + } + + + ListGenresVariablesBuilder listGenres () { + return ListGenresVariablesBuilder(dataConnect, ); + } + + + GetMovieByIdVariablesBuilder getMovieById ({required String id,}) { + return GetMovieByIdVariablesBuilder(dataConnect, id: id,); + } + + + GetActorByIdVariablesBuilder getActorById ({required String id,}) { + return GetActorByIdVariablesBuilder(dataConnect, id: id,); + } + + + GetCurrentUserVariablesBuilder getCurrentUser () { + return GetCurrentUserVariablesBuilder(dataConnect, ); + } + + + GetMovieInfoForUserVariablesBuilder getMovieInfoForUser ({required String movieId,}) { + return GetMovieInfoForUserVariablesBuilder(dataConnect, movieId: movieId,); + } + + + SearchAllVariablesBuilder searchAll ({required int minYear,required int maxYear,required double minRating,required double maxRating,required String genre,}) { + return SearchAllVariablesBuilder(dataConnect, minYear: minYear,maxYear: maxYear,minRating: minRating,maxRating: maxRating,genre: genre,); + } + + + ListMoviesByPartialTitleVariablesBuilder listMoviesByPartialTitle ({required String input,}) { + return ListMoviesByPartialTitleVariablesBuilder(dataConnect, input: input,); + } + + + static ConnectorConfig connectorConfig = ConnectorConfig( + 'us-central1', + 'movies', + 'dataconnect', + ); + + MoviesConnector({required this.dataConnect}); + static MoviesConnector get instance { + return MoviesConnector( + dataConnect: FirebaseDataConnect.instanceFor( + connectorConfig: connectorConfig, + sdkType: CallerSDKType.generated)); + } + + FirebaseDataConnect dataConnect; +} + diff --git a/dataconnect/flutter-movie/lib/movies_connector/search_all.dart b/dataconnect/flutter-movie/lib/movies_connector/search_all.dart new file mode 100644 index 00000000..27803d0a --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/search_all.dart @@ -0,0 +1,1021 @@ +part of movies_connector; + +class SearchAllVariablesBuilder { + Optional _input = Optional.optional(nativeFromJson, nativeToJson); +int minYear; +int maxYear; +double minRating; +double maxRating; +String genre; + + + FirebaseDataConnect _dataConnect; + SearchAllVariablesBuilder input(String? t) { +this._input.value = t; +return this; +} + + SearchAllVariablesBuilder(this._dataConnect, {required int this.minYear,required int this.maxYear,required double this.minRating,required double this.maxRating,required String this.genre,}); + Deserializer dataDeserializer = (dynamic json) => SearchAllData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (SearchAllVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + QueryRef ref() { + SearchAllVariables vars=SearchAllVariables(input: _input,minYear: minYear,maxYear: maxYear,minRating: minRating,maxRating: maxRating,genre: genre,); + + return _dataConnect.query("SearchAll", dataDeserializer, varsSerializer, vars); + } +} + + + class SearchAllMoviesMatchingTitle { + + String id; + + + String title; + + + String? genre; + + + double? rating; + + + String imageUrl; + + + + + + + SearchAllMoviesMatchingTitle.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + + { + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + return json; + } + + SearchAllMoviesMatchingTitle({ + + required this.id, + + required this.title, + + this.genre, + + this.rating, + + required this.imageUrl, + + }); +} + + + + class SearchAllMoviesMatchingDescription { + + String id; + + + String title; + + + String? genre; + + + double? rating; + + + String imageUrl; + + + + + + + SearchAllMoviesMatchingDescription.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + , + + genre = json['genre'] == null ? null : + + nativeFromJson(json['genre']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + + { + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + + if (genre != null) { + json['genre'] = + + nativeToJson(genre) + +; + } + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + return json; + } + + SearchAllMoviesMatchingDescription({ + + required this.id, + + required this.title, + + this.genre, + + this.rating, + + required this.imageUrl, + + }); +} + + + + class SearchAllActorsMatchingName { + + String id; + + + String name; + + + String imageUrl; + + + + + + + SearchAllActorsMatchingName.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + name = + + nativeFromJson(json['name']) + + + + , + + imageUrl = + + nativeFromJson(json['imageUrl']) + + + + + { + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['name'] = + + nativeToJson(name) + +; + + + + json['imageUrl'] = + + nativeToJson(imageUrl) + +; + + + return json; + } + + SearchAllActorsMatchingName({ + + required this.id, + + required this.name, + + required this.imageUrl, + + }); +} + + + + class SearchAllReviewsMatchingText { + + String id; + + + int? rating; + + + String? reviewText; + + + DateTime reviewDate; + + + SearchAllReviewsMatchingTextMovie movie; + + + SearchAllReviewsMatchingTextUser user; + + + + + + + SearchAllReviewsMatchingText.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + rating = json['rating'] == null ? null : + + nativeFromJson(json['rating']) + + + + , + + reviewText = json['reviewText'] == null ? null : + + nativeFromJson(json['reviewText']) + + + + , + + reviewDate = + + nativeFromJson(json['reviewDate']) + + + + , + + movie = + + SearchAllReviewsMatchingTextMovie.fromJson(json['movie']) + + + + , + + user = + + SearchAllReviewsMatchingTextUser.fromJson(json['user']) + + + + + { + + + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + if (rating != null) { + json['rating'] = + + nativeToJson(rating) + +; + } + + + + if (reviewText != null) { + json['reviewText'] = + + nativeToJson(reviewText) + +; + } + + + + json['reviewDate'] = + + nativeToJson(reviewDate) + +; + + + + json['movie'] = + + movie.toJson() + +; + + + + json['user'] = + + user.toJson() + +; + + + return json; + } + + SearchAllReviewsMatchingText({ + + required this.id, + + this.rating, + + this.reviewText, + + required this.reviewDate, + + required this.movie, + + required this.user, + + }); +} + + + + class SearchAllReviewsMatchingTextMovie { + + String id; + + + String title; + + + + + + + SearchAllReviewsMatchingTextMovie.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + title = + + nativeFromJson(json['title']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['title'] = + + nativeToJson(title) + +; + + + return json; + } + + SearchAllReviewsMatchingTextMovie({ + + required this.id, + + required this.title, + + }); +} + + + + class SearchAllReviewsMatchingTextUser { + + String id; + + + String username; + + + + + + + SearchAllReviewsMatchingTextUser.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + , + + username = + + nativeFromJson(json['username']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + + json['username'] = + + nativeToJson(username) + +; + + + return json; + } + + SearchAllReviewsMatchingTextUser({ + + required this.id, + + required this.username, + + }); +} + + + + class SearchAllData { + + List moviesMatchingTitle; + + + List moviesMatchingDescription; + + + List actorsMatchingName; + + + List reviewsMatchingText; + + + + + + + SearchAllData.fromJson(dynamic json): + moviesMatchingTitle = + + + (json['moviesMatchingTitle'] as List) + .map((e) => SearchAllMoviesMatchingTitle.fromJson(e)) + .toList() + + + + + , + + moviesMatchingDescription = + + + (json['moviesMatchingDescription'] as List) + .map((e) => SearchAllMoviesMatchingDescription.fromJson(e)) + .toList() + + + + + , + + actorsMatchingName = + + + (json['actorsMatchingName'] as List) + .map((e) => SearchAllActorsMatchingName.fromJson(e)) + .toList() + + + + + , + + reviewsMatchingText = + + + (json['reviewsMatchingText'] as List) + .map((e) => SearchAllReviewsMatchingText.fromJson(e)) + .toList() + + + + + + { + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['moviesMatchingTitle'] = + + + moviesMatchingTitle.map((e) => e.toJson()).toList() + + +; + + + + json['moviesMatchingDescription'] = + + + moviesMatchingDescription.map((e) => e.toJson()).toList() + + +; + + + + json['actorsMatchingName'] = + + + actorsMatchingName.map((e) => e.toJson()).toList() + + +; + + + + json['reviewsMatchingText'] = + + + reviewsMatchingText.map((e) => e.toJson()).toList() + + +; + + + return json; + } + + SearchAllData({ + + required this.moviesMatchingTitle, + + required this.moviesMatchingDescription, + + required this.actorsMatchingName, + + required this.reviewsMatchingText, + + }); +} + + + + class SearchAllVariables { + + late Optionalinput; + + + int minYear; + + + int maxYear; + + + double minRating; + + + double maxRating; + + + String genre; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + SearchAllVariables.fromJson(Map json): + minYear = + + nativeFromJson(json['minYear']) + + + + , + + maxYear = + + nativeFromJson(json['maxYear']) + + + + , + + minRating = + + nativeFromJson(json['minRating']) + + + + , + + maxRating = + + nativeFromJson(json['maxRating']) + + + + , + + genre = + + nativeFromJson(json['genre']) + + + + + { + + + input = Optional.optional(nativeFromJson, nativeToJson); + input.value = json['input'] == null ? null : + + nativeFromJson(json['input']) + +; + + + + + + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + if(input.state == OptionalState.set) { + json['input'] = input.toJson(); + } + + + + json['minYear'] = + + nativeToJson(minYear) + +; + + + + json['maxYear'] = + + nativeToJson(maxYear) + +; + + + + json['minRating'] = + + nativeToJson(minRating) + +; + + + + json['maxRating'] = + + nativeToJson(maxRating) + +; + + + + json['genre'] = + + nativeToJson(genre) + +; + + + return json; + } + + SearchAllVariables({ + + required this.input, + + required this.minYear, + + required this.maxYear, + + required this.minRating, + + required this.maxRating, + + required this.genre, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/update_review.dart b/dataconnect/flutter-movie/lib/movies_connector/update_review.dart new file mode 100644 index 00000000..bbd614a2 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/update_review.dart @@ -0,0 +1,242 @@ +part of movies_connector; + +class UpdateReviewVariablesBuilder { + String movieId; +int rating; +String reviewText; + + + FirebaseDataConnect _dataConnect; + + UpdateReviewVariablesBuilder(this._dataConnect, {required String this.movieId,required int this.rating,required String this.reviewText,}); + Deserializer dataDeserializer = (dynamic json) => UpdateReviewData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (UpdateReviewVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + MutationRef ref() { + UpdateReviewVariables vars=UpdateReviewVariables(movieId: movieId,rating: rating,reviewText: reviewText,); + + return _dataConnect.mutation("UpdateReview", dataDeserializer, varsSerializer, vars); + } +} + + + class UpdateReviewReviewUpdate { + + String userId; + + + String movieId; + + + + + + + UpdateReviewReviewUpdate.fromJson(dynamic json): + userId = + + nativeFromJson(json['userId']) + + + + , + + movieId = + + nativeFromJson(json['movieId']) + + + + + { + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['userId'] = + + nativeToJson(userId) + +; + + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + return json; + } + + UpdateReviewReviewUpdate({ + + required this.userId, + + required this.movieId, + + }); +} + + + + class UpdateReviewData { + + UpdateReviewReviewUpdate? review_update; + + + + + + + UpdateReviewData.fromJson(dynamic json): + review_update = json['review_update'] == null ? null : + + UpdateReviewReviewUpdate.fromJson(json['review_update']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + if (review_update != null) { + json['review_update'] = + + review_update!.toJson() + +; + } + + + return json; + } + + UpdateReviewData({ + + this.review_update, + + }); +} + + + + class UpdateReviewVariables { + + String movieId; + + + int rating; + + + String reviewText; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + UpdateReviewVariables.fromJson(Map json): + movieId = + + nativeFromJson(json['movieId']) + + + + , + + rating = + + nativeFromJson(json['rating']) + + + + , + + reviewText = + + nativeFromJson(json['reviewText']) + + + + + { + + + + + + + + } + + + Map toJson() { + Map json = {}; + + + json['movieId'] = + + nativeToJson(movieId) + +; + + + + json['rating'] = + + nativeToJson(rating) + +; + + + + json['reviewText'] = + + nativeToJson(reviewText) + +; + + + return json; + } + + UpdateReviewVariables({ + + required this.movieId, + + required this.rating, + + required this.reviewText, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/movies_connector/upsert_user.dart b/dataconnect/flutter-movie/lib/movies_connector/upsert_user.dart new file mode 100644 index 00000000..16d90738 --- /dev/null +++ b/dataconnect/flutter-movie/lib/movies_connector/upsert_user.dart @@ -0,0 +1,169 @@ +part of movies_connector; + +class UpsertUserVariablesBuilder { + String username; + + + FirebaseDataConnect _dataConnect; + + UpsertUserVariablesBuilder(this._dataConnect, {required String this.username,}); + Deserializer dataDeserializer = (dynamic json) => UpsertUserData.fromJson(jsonDecode(json)); + Serializer varsSerializer = (UpsertUserVariables vars) => jsonEncode(vars.toJson()); + Future> execute() { + return this.ref().execute(); + } + MutationRef ref() { + UpsertUserVariables vars=UpsertUserVariables(username: username,); + + return _dataConnect.mutation("UpsertUser", dataDeserializer, varsSerializer, vars); + } +} + + + class UpsertUserUserUpsert { + + String id; + + + + + + + UpsertUserUserUpsert.fromJson(dynamic json): + id = + + nativeFromJson(json['id']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['id'] = + + nativeToJson(id) + +; + + + return json; + } + + UpsertUserUserUpsert({ + + required this.id, + + }); +} + + + + class UpsertUserData { + + UpsertUserUserUpsert user_upsert; + + + + + + + UpsertUserData.fromJson(dynamic json): + user_upsert = + + UpsertUserUserUpsert.fromJson(json['user_upsert']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['user_upsert'] = + + user_upsert.toJson() + +; + + + return json; + } + + UpsertUserData({ + + required this.user_upsert, + + }); +} + + + + class UpsertUserVariables { + + String username; + + + + + + @Deprecated('fromJson is deprecated for Variable classes as they are no longer required for deserialization.') + + + UpsertUserVariables.fromJson(Map json): + username = + + nativeFromJson(json['username']) + + + + + { + + + + } + + + Map toJson() { + Map json = {}; + + + json['username'] = + + nativeToJson(username) + +; + + + return json; + } + + UpsertUserVariables({ + + required this.username, + + }); +} + + + + + + + diff --git a/dataconnect/flutter-movie/lib/navigation_shell.dart b/dataconnect/flutter-movie/lib/navigation_shell.dart new file mode 100644 index 00000000..f73b02e8 --- /dev/null +++ b/dataconnect/flutter-movie/lib/navigation_shell.dart @@ -0,0 +1,34 @@ +import 'package:dataconnect/destination.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +class NavigationShell extends StatelessWidget { + const NavigationShell({required this.navigationShell, super.key}); + final StatefulNavigationShell navigationShell; + + void _goBranch(int index) { + navigationShell.goBranch( + index, + // A common pattern when using bottom navigation bars is to support + // navigating to the initial location when tapping the item that is + // already active. This example demonstrates how to support this behavior, + // using the initialLocation parameter of goBranch. + initialLocation: index == navigationShell.currentIndex, + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: navigationShell, + bottomNavigationBar: NavigationBar( + selectedIndex: navigationShell.currentIndex, + onDestinationSelected: _goBranch, + destinations: paths + .map((destination) => NavigationDestination( + icon: Icon(destination.iconData), label: destination.label)) + .toList(), + ), + ); + } +} diff --git a/dataconnect/flutter-movie/lib/profile.dart b/dataconnect/flutter-movie/lib/profile.dart new file mode 100644 index 00000000..9fe5c4a0 --- /dev/null +++ b/dataconnect/flutter-movie/lib/profile.dart @@ -0,0 +1,84 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +import 'movie_state.dart'; +import 'models/movie.dart'; +import 'movies_connector/movies.dart'; +import 'util/auth.dart'; +import 'widgets/list_movies.dart'; +import 'widgets/list_reviews.dart'; +import 'widgets/login_guard.dart'; + +class Profile extends StatelessWidget { + const Profile({super.key}); + + @override + Widget build(BuildContext context) { + return LoginGuard(builder: (context) { + return StreamBuilder( + stream: MovieState.subscribeToCurrentUser(), + builder: (context, snapshot) { + final res = snapshot.data; + if (res == null) { + return const Center( + child: CircularProgressIndicator(), + ); + } + final displayName = FirebaseAuth.instance.currentUser!.displayName; + final favoriteMovies = + res.data.user!.favoriteMovies.map((e) => e.movie).toList(); + final reviews = res.data.user!.reviews; + return RefreshIndicator( + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: Container( + padding: const EdgeInsets.all(30), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + children: [ + Text('Welcome back $displayName !'), + TextButton( + onPressed: () async { + FirebaseAuth.instance.signOut(); + context.go('/login'); + }, + child: const Text('Sign out')) + ], + ), + ListMovies( + title: "Favorite Movies", + movies: favoriteMovies + .map( + (e) => Movie( + id: e.id, + title: e.title, + imageUrl: e.imageUrl), + ) + .toList()), + ListReviews( + reviews: reviews + .map( + (e) => Review( + reviewText: e.reviewText!, + rating: e.rating!, + username: Auth.instance.currentUser!.email!, + date: e.reviewDate), + ) + .toList(), + title: "Reviews"), + ], + ), + ), + ), + onRefresh: () async { + await MoviesConnector.instance.getCurrentUser().execute(); + }, + ); + }); + }); + } +} diff --git a/dataconnect/flutter-movie/lib/router.dart b/dataconnect/flutter-movie/lib/router.dart new file mode 100644 index 00000000..a8bbea4c --- /dev/null +++ b/dataconnect/flutter-movie/lib/router.dart @@ -0,0 +1,81 @@ +import 'package:go_router/go_router.dart'; + +import 'login.dart'; +import 'destination.dart'; +import 'profile.dart'; +import 'search.dart'; +import 'actor_detail.dart'; +import 'main.dart'; +import 'movie_detail.dart'; +import 'navigation_shell.dart'; +import 'sign_up.dart'; +import 'util/auth.dart'; + +var router = GoRouter( + refreshListenable: Auth.instance, + initialLocation: homePath.path, + routes: [ + StatefulShellRoute.indexedStack( + builder: (context, state, navigationShell) { + return NavigationShell(navigationShell: navigationShell); + }, + branches: [ + StatefulShellBranch( + routes: [ + GoRoute(path: '/', redirect: (context, path) => homePath.path), + GoRoute( + path: homePath.path, + builder: (context, state) => const MyHomePage(), + ), + GoRoute( + path: '/movies/:movieId', + builder: (context, state) => + MovieDetail(id: state.pathParameters['movieId']!)), + GoRoute( + path: "/actors", + redirect: (context, state) => + '/actors/${state.pathParameters['actorId']}', + routes: [ + GoRoute( + path: ":actorId", + builder: (context, state) => ActorDetail( + actorId: state.pathParameters['actorId']!)) + ]) + ], + ), + StatefulShellBranch( + routes: [ + GoRoute( + path: "/search", + builder: (context, state) => const Search(), + ), + ], + ), + StatefulShellBranch( + routes: [ + GoRoute( + path: "/profile", + redirect: (context, state) async { + return Auth.instance.isLoggedIn ? null : '/login'; + }, + builder: (context, state) => const Profile()), + GoRoute( + path: "/login", + builder: (context, state) => const Login(), + redirect: (context, state) async { + return Auth.instance.isLoggedIn ? '/profile' : null; + }, + ), + GoRoute( + path: "/signup", + builder: (context, state) => const SignUp(), + redirect: (context, state) async { + return Auth.instance.isLoggedIn ? '/profile' : null; + }, + ) + ], + ) + ], + ) + ], +); diff --git a/dataconnect/flutter-movie/lib/search.dart b/dataconnect/flutter-movie/lib/search.dart new file mode 100644 index 00000000..fd796b98 --- /dev/null +++ b/dataconnect/flutter-movie/lib/search.dart @@ -0,0 +1,98 @@ +import 'package:dataconnect/models/movie.dart'; +import 'package:dataconnect/movie_state.dart'; +import 'package:dataconnect/movies_connector/movies.dart'; +import 'package:dataconnect/widgets/horizontal_movie.dart'; +import 'package:flutter/material.dart'; + +class Search extends StatefulWidget { + const Search({super.key}); + + @override + State createState() => _SearchState(); +} + +class SearchFormState { + String title = ''; +} + +class _SearchState extends State { + final _formKey = GlobalKey(); + String title = ''; + List _resultsMovieMatchingTitle = []; + + void _searchMovie() { + MovieState.searchByPartialTitle(title).then((value) { + setState(() { + _resultsMovieMatchingTitle = value.data.movies; + }); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: SingleChildScrollView( + child: Container( + margin: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Form( + key: _formKey, + child: Column( + children: [ + Row( + children: [ + Expanded( + flex: 6, + child: TextFormField( + initialValue: title, + decoration: const InputDecoration( + hintText: 'Title'), + validator: (value) => + value == null || value.isEmpty + ? 'Please enter some text' + : null, + onFieldSubmitted: (value) => + _searchMovie(), + onChanged: (value) { + setState(() { + title = value; + }); + }, + ), + ), + const SizedBox(width: 10), + Expanded( + flex: 1, + child: IconButton( + icon: const Icon(Icons.search), + onPressed: + _formKey.currentState?.validate() == + true + ? _searchMovie + : null, + ), + ), + ], + ), + ], + )), + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: _resultsMovieMatchingTitle.map( + (e) { + final Movie movie = Movie( + id: e.id, + title: e.title, + imageUrl: e.imageUrl, + description: e.description); + return HorizontalMovie(movie: movie); + }, + ).toList()), + ], + ))))); + } +} diff --git a/dataconnect/flutter-movie/lib/sign_up.dart b/dataconnect/flutter-movie/lib/sign_up.dart new file mode 100644 index 00000000..558c3171 --- /dev/null +++ b/dataconnect/flutter-movie/lib/sign_up.dart @@ -0,0 +1,124 @@ +import 'package:dataconnect/movies_connector/movies.dart'; +import 'package:dataconnect/widgets/auth_dialog.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +class SignUp extends StatefulWidget { + const SignUp({super.key}); + + @override + State createState() => _SignUpState(); +} + +class _SignUpState extends State { + final _formKey = GlobalKey(); + String _username = ''; + String _password = ''; + String _name = ''; + + signUp() async { + ScaffoldMessenger.of(context) + .showSnackBar(const SnackBar(content: Text('Signing Up'))); + try { + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: _username, password: _password); + await FirebaseAuth.instance.currentUser!.updateDisplayName(_name); + await MoviesConnector.instance.upsertUser(username: _username).execute(); + if (mounted) { + context.go('/home'); + } + } on FirebaseAuthException catch (e) { + if (mounted) { + String message = e.code.contains('configuration-not-found') + ? 'Email/Password authentication has not been enabled' + : e.message!; + bool shouldLaunch = e.code.contains('operation-not-allowed') || + e.code.contains('configuration-not-found'); + AuthDialog.showAuthDialog(context, message, shouldLaunch); + } + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(30), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Form( + key: _formKey, + child: Column( + children: [ + TextFormField( + decoration: const InputDecoration( + hintText: "Email", + border: OutlineInputBorder()), + onChanged: (value) { + setState(() { + _username = value; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter some text'; + } + return null; + }, + ), + const SizedBox(height: 30), + TextFormField( + enableSuggestions: false, + decoration: const InputDecoration( + hintText: "Name", border: OutlineInputBorder()), + onChanged: (value) { + setState(() { + _name = value; + }); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter a name'; + } + return null; + }, + ), + const SizedBox(height: 30), + TextFormField( + obscureText: true, + enableSuggestions: false, + autocorrect: false, + decoration: const InputDecoration( + hintText: "Password", + border: OutlineInputBorder()), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter some text'; + } + return null; + }, + onChanged: (value) { + setState(() { + _password = value; + }); + }, + ), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + signUp(); + } + }, + child: const Text('Submit')) + ], + )) + ], + ))), + ); + } +} diff --git a/dataconnect/flutter-movie/lib/util/auth.dart b/dataconnect/flutter-movie/lib/util/auth.dart new file mode 100644 index 00000000..2113b806 --- /dev/null +++ b/dataconnect/flutter-movie/lib/util/auth.dart @@ -0,0 +1,44 @@ +import 'dart:async'; + +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/foundation.dart'; + +typedef AuthState = ({User? user, String? token}); + +class Auth extends ValueNotifier { + bool get isLoggedIn => value.user != null && value.token != null; + User? get currentUser => value.user; + String? get token => value.token; + + StreamSubscription? _cleanup; + + Future init() async { + final user = FirebaseAuth.instance.currentUser; + final token = await user?.token; + value = (user: user, token: token); + _cleanup = FirebaseAuth.instance.authStateChanges().listen((user) async { + final token = await user?.token; + value = (user: user, token: token); + }); + } + + @override + void dispose() { + super.dispose(); + _cleanup?.cancel(); + } + + static Auth instance = Auth((user: null, token: null)); + + Auth(super.value); +} + +extension on User { + Future get token async { + try { + return await getIdToken(); + } catch (_) { + return null; + } + } +} diff --git a/dataconnect/flutter-movie/lib/widgets/auth_dialog.dart b/dataconnect/flutter-movie/lib/widgets/auth_dialog.dart new file mode 100644 index 00000000..b2088be0 --- /dev/null +++ b/dataconnect/flutter-movie/lib/widgets/auth_dialog.dart @@ -0,0 +1,41 @@ +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/material.dart'; +import 'package:url_launcher/link.dart'; + +class AuthDialog { + static final String link = + "https://console.firebase.google.com/project/${Firebase.app().options.projectId}/overview/authentication/providers"; + static showAuthDialog( + BuildContext context, String message, bool shouldLaunch) { + List content = [const SizedBox()]; + if (shouldLaunch) { + content = [ + Link( + uri: Uri.parse(link), + target: LinkTarget.blank, + builder: (context, followLink) { + return TextButton( + onPressed: followLink, + child: const Text( + 'Click here to go to the Firebase Console and enable Email/Password Auth.')); + }) + ]; + } + + return showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Login Error'), + content: Column(mainAxisSize: MainAxisSize.min, children: [ + Text('There was an error when logging in: $message'), + ...content + ]), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, 'OK'), + child: const Text('OK'), + ), + ], + )); + } +} diff --git a/dataconnect/flutter-movie/lib/widgets/display_movie.dart b/dataconnect/flutter-movie/lib/widgets/display_movie.dart new file mode 100644 index 00000000..b2ec257d --- /dev/null +++ b/dataconnect/flutter-movie/lib/widgets/display_movie.dart @@ -0,0 +1,44 @@ +import 'package:dataconnect/models/movie.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +class DisplayMovie extends StatelessWidget { + const DisplayMovie({super.key, required this.movie}); + final Movie movie; + @override + Widget build(BuildContext context) { + return Container( + width: 150, + padding: const EdgeInsets.all(4.0), + child: Card( + child: InkWell( + onTap: () { + context.push("/movies/${movie.id}"); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AspectRatio( + aspectRatio: 9 / 16, // 9:16 aspect ratio for the image + child: Image.network( + movie.imageUrl, + fit: BoxFit.cover, + ), + ), + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + movie.title, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + ], + ), + ), + ), + ); + ; + } +} diff --git a/dataconnect/flutter-movie/lib/widgets/horizontal_movie.dart b/dataconnect/flutter-movie/lib/widgets/horizontal_movie.dart new file mode 100644 index 00000000..5ab2f861 --- /dev/null +++ b/dataconnect/flutter-movie/lib/widgets/horizontal_movie.dart @@ -0,0 +1,34 @@ +import 'package:dataconnect/models/movie.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +class HorizontalMovie extends StatelessWidget { + const HorizontalMovie({super.key, required this.movie}); + final Movie movie; + + @override + Widget build(BuildContext context) { + return Card( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + leading: SizedBox( + width: 150, + child: Image.network(movie.imageUrl, fit: BoxFit.fitWidth)), + onTap: () { + context.push("/movies/${movie.id}"); + }, + title: Text( + movie.title, + overflow: TextOverflow.ellipsis, + ), + subtitle: movie.description != null + ? Text(movie.description!, overflow: TextOverflow.ellipsis) + : const Text(''), + ), + ], + ), + ); + } +} diff --git a/dataconnect/flutter-movie/lib/widgets/list_actors.dart b/dataconnect/flutter-movie/lib/widgets/list_actors.dart new file mode 100644 index 00000000..d258826f --- /dev/null +++ b/dataconnect/flutter-movie/lib/widgets/list_actors.dart @@ -0,0 +1,65 @@ +import 'package:dataconnect/widgets/list_title.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +class Actor { + Actor({ + required this.imageUrl, + required this.name, + required this.id, + }); + String imageUrl; + String name; + String id; +} + +class ListActors extends StatelessWidget { + const ListActors({ + super.key, + required this.actors, + required this.title, + }); + final List actors; + final String title; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 125, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTitle(title: title), + Expanded( + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + final actor = actors[index]; + return SizedBox( + width: 100, + child: InkWell( + onTap: () => context.push("/actors/${actor.id}"), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CircleAvatar( + radius: 30, + child: + ClipOval(child: Image.network(actor.imageUrl))), + Text( + actor.name, + overflow: TextOverflow.ellipsis, + ) + ], + ), + )); + }, + itemCount: actors.length, + )) + ], + ), + ); + } +} diff --git a/dataconnect/flutter-movie/lib/widgets/list_movies.dart b/dataconnect/flutter-movie/lib/widgets/list_movies.dart new file mode 100644 index 00000000..83efee58 --- /dev/null +++ b/dataconnect/flutter-movie/lib/widgets/list_movies.dart @@ -0,0 +1,54 @@ +import 'package:dataconnect/widgets/display_movie.dart'; +import 'package:dataconnect/widgets/list_title.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +import '/models/movie.dart'; + +class ListMovies extends StatelessWidget { + const ListMovies( + {super.key, + required this.movies, + this.title, + this.scrollDirection = Axis.horizontal}); + + final List movies; + final String? title; + final Axis scrollDirection; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + title != null + ? Padding( + padding: const EdgeInsets.all(8.0), + child: ListTitle(title: title!)) + : const SizedBox(), + movies.isEmpty + ? title != null + ? Padding( + padding: const EdgeInsets.all(10.0), + child: Text( + "No $title", + style: const TextStyle( + fontSize: 15, fontWeight: FontWeight.bold), + )) + : const SizedBox() + : SizedBox( + height: 300, // Adjust the height as needed + child: ListView.builder( + scrollDirection: scrollDirection, + itemCount: movies.length, + itemBuilder: (context, index) { + final movie = movies[index]; + return DisplayMovie(movie: movie); + }, + ), + ), + ], + ); + } +} diff --git a/dataconnect/flutter-movie/lib/widgets/list_reviews.dart b/dataconnect/flutter-movie/lib/widgets/list_reviews.dart new file mode 100644 index 00000000..9ae9d217 --- /dev/null +++ b/dataconnect/flutter-movie/lib/widgets/list_reviews.dart @@ -0,0 +1,77 @@ +import 'package:dataconnect/widgets/list_title.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +class Review { + Review({ + required this.reviewText, + required this.rating, + required this.username, + required this.date, + }); + String reviewText; + int rating; + String username; + DateTime date; +} + +class ListReviews extends StatelessWidget { + const ListReviews({ + super.key, + required this.reviews, + required this.title, + }); + final List reviews; + final String title; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), child: ListTitle(title: title)), + reviews.isEmpty + ? Padding( + padding: const EdgeInsets.all(10.0), + child: Text( + "No $title", + style: const TextStyle( + fontSize: 15, fontWeight: FontWeight.bold), + )) + : SizedBox( + height: 125, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + var rating = reviews[index]; + return Card( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(rating.username), + Row( + children: [ + Text(DateFormat.yMMMd().format(rating.date)), + const SizedBox( + width: 10, + ), + Text("Rating ${rating.rating}") + ], + ), + Text(rating.reviewText) + ], + )), + ); + }, + itemCount: reviews.length, + ), + ), + ], + ); + } +} diff --git a/dataconnect/flutter-movie/lib/widgets/list_title.dart b/dataconnect/flutter-movie/lib/widgets/list_title.dart new file mode 100644 index 00000000..489b4663 --- /dev/null +++ b/dataconnect/flutter-movie/lib/widgets/list_title.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class ListTitle extends StatelessWidget { + const ListTitle({super.key, required this.title}); + final String title; + @override + Widget build(BuildContext context) { + return Text( + title, + style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ); + } +} diff --git a/dataconnect/flutter-movie/lib/widgets/login_guard.dart b/dataconnect/flutter-movie/lib/widgets/login_guard.dart new file mode 100644 index 00000000..1e3f9d0d --- /dev/null +++ b/dataconnect/flutter-movie/lib/widgets/login_guard.dart @@ -0,0 +1,33 @@ +import 'package:dataconnect/util/auth.dart'; +import 'package:flutter/material.dart'; + +class LoginGuard extends StatelessWidget { + const LoginGuard({ + super.key, + required this.builder, + this.message, + }); + + final WidgetBuilder builder; + final String? message; + + @override + Widget build(BuildContext context) { + return ValueListenableBuilder( + valueListenable: Auth.instance, + builder: (context, state, _) { + final isLoggedIn = Auth.instance.isLoggedIn; + if (!isLoggedIn) { + if (message == null) { + return const SizedBox(); + } + return Text( + 'Please visit the profile page' + 'to log in before $message', + ); + } + return builder(context); + }, + ); + } +} diff --git a/dataconnect/flutter-movie/pubspec.lock b/dataconnect/flutter-movie/pubspec.lock new file mode 100644 index 00000000..72b70260 --- /dev/null +++ b/dataconnect/flutter-movie/pubspec.lock @@ -0,0 +1,506 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "71c01c1998c40b3af1944ad0a5f374b4e6fef7f3d2df487f3970dbeadaeb25a1" + url: "https://pub.dev" + source: hosted + version: "1.3.46" + archive: + dependency: transitive + description: + name: archive + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d + url: "https://pub.dev" + source: hosted + version: "3.6.1" + args: + dependency: transitive + description: + name: args + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + url: "https://pub.dev" + source: hosted + version: "2.6.0" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + firebase_app_check: + dependency: transitive + description: + name: firebase_app_check + sha256: "0b7e85c11fbdaada02d01f5cc5b5feffda4983d229806c30cadcc013c2fa3c1f" + url: "https://pub.dev" + source: hosted + version: "0.3.1+6" + firebase_app_check_platform_interface: + dependency: transitive + description: + name: firebase_app_check_platform_interface + sha256: "21ba031a28e62e12eddf8c39852607c3d04673fdfd75c3ed7f913e5802eb7d8e" + url: "https://pub.dev" + source: hosted + version: "0.1.0+40" + firebase_app_check_web: + dependency: transitive + description: + name: firebase_app_check_web + sha256: "36de135e9e0cc1554d3e3f73b437d3ff6be7132f2ef0a9999d0c6e414fa3d04b" + url: "https://pub.dev" + source: hosted + version: "0.2.0+2" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + sha256: "49c356bac95ed234805e3bb928a86d5b21a4d3745d77be53ecf2d61409ddb802" + url: "https://pub.dev" + source: hosted + version: "5.3.3" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "9bc336ce673ea90a9dbdb04f0e9a3e52a32321898dc869cdefe6cc0f0db369ed" + url: "https://pub.dev" + source: hosted + version: "7.4.9" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: "56dcce4293e2a2c648c33ab72c09e888bd0e64cbb1681a32575ec9dc9c2f67f3" + url: "https://pub.dev" + source: hosted + version: "5.13.4" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "2438a75ad803e818ad3bd5df49137ee619c46b6fc7101f4dbc23da07305ce553" + url: "https://pub.dev" + source: hosted + version: "3.8.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810 + url: "https://pub.dev" + source: hosted + version: "5.3.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5 + url: "https://pub.dev" + source: hosted + version: "2.18.1" + firebase_data_connect: + dependency: "direct main" + description: + name: firebase_data_connect + sha256: dfc62553159f203714e887babf76c21b21ca850d03f60a334b16e7ab03183ab6 + url: "https://pub.dev" + source: hosted + version: "0.1.2+4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: "844a216ee2aa29dd484fdc815f2d1bc1ca7d02182121b494e14c2ce79bb01bb7" + url: "https://pub.dev" + source: hosted + version: "14.5.0" + google_identity_services_web: + dependency: transitive + description: + name: google_identity_services_web + sha256: "5be191523702ba8d7a01ca97c17fca096822ccf246b0a9f11923a6ded06199b6" + url: "https://pub.dev" + source: hosted + version: "0.3.1+4" + googleapis_auth: + dependency: transitive + description: + name: googleapis_auth + sha256: befd71383a955535060acde8792e7efc11d2fccd03dd1d3ec434e85b68775938 + url: "https://pub.dev" + source: hosted + version: "1.6.0" + grpc: + dependency: transitive + description: + name: grpc + sha256: e93ee3bce45c134bf44e9728119102358c7cd69de7832d9a874e2e74eb8cab40 + url: "https://pub.dev" + source: hosted + version: "3.2.4" + http: + dependency: transitive + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" + http2: + dependency: transitive + description: + name: http2 + sha256: "9ced024a160b77aba8fb8674e38f70875e321d319e6f303ec18e87bd5a4b0c1d" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://pub.dev" + source: hosted + version: "10.0.5" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + lints: + dependency: transitive + description: + name: lints + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" + source: hosted + version: "1.15.0" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + protobuf: + dependency: transitive + description: + name: protobuf + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://pub.dev" + source: hosted + version: "0.7.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" + url: "https://pub.dev" + source: hosted + version: "6.3.1" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193" + url: "https://pub.dev" + source: hosted + version: "6.3.14" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e + url: "https://pub.dev" + source: hosted + version: "6.3.1" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" + url: "https://pub.dev" + source: hosted + version: "2.3.3" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4" + url: "https://pub.dev" + source: hosted + version: "3.1.3" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + url: "https://pub.dev" + source: hosted + version: "14.2.5" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" +sdks: + dart: ">=3.5.3 <4.0.0" + flutter: ">=3.24.0" diff --git a/dataconnect/flutter-movie/pubspec.yaml b/dataconnect/flutter-movie/pubspec.yaml new file mode 100644 index 00000000..f54ec762 --- /dev/null +++ b/dataconnect/flutter-movie/pubspec.yaml @@ -0,0 +1,97 @@ +name: dataconnect +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 is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 1.0.0+1 + +environment: + sdk: ^3.5.3 + +# 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 + flutter_web_plugins: + sdk: flutter + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.8 + firebase_data_connect: ^0.1.2+1 + firebase_core: ^3.6.0 + go_router: ^14.5.0 + intl: ^0.19.0 + firebase_auth: ^5.3.3 + url_launcher: ^6.3.1 + +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. + flutter_lints: ^4.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 packages. +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/open-in-new-tab.png + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/to/asset-from-package + + # 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/to/font-from-package diff --git a/dataconnect/flutter-movie/test/widget_test.dart b/dataconnect/flutter-movie/test/widget_test.dart new file mode 100644 index 00000000..a07002c0 --- /dev/null +++ b/dataconnect/flutter-movie/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 in the flutter_test package. 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:dataconnect/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/dataconnect/flutter-movie/web/favicon.png b/dataconnect/flutter-movie/web/favicon.png new file mode 100644 index 00000000..8aaa46ac Binary files /dev/null and b/dataconnect/flutter-movie/web/favicon.png differ diff --git a/dataconnect/flutter-movie/web/icons/Icon-192.png b/dataconnect/flutter-movie/web/icons/Icon-192.png new file mode 100644 index 00000000..b749bfef Binary files /dev/null and b/dataconnect/flutter-movie/web/icons/Icon-192.png differ diff --git a/dataconnect/flutter-movie/web/icons/Icon-512.png b/dataconnect/flutter-movie/web/icons/Icon-512.png new file mode 100644 index 00000000..88cfd48d Binary files /dev/null and b/dataconnect/flutter-movie/web/icons/Icon-512.png differ diff --git a/dataconnect/flutter-movie/web/icons/Icon-maskable-192.png b/dataconnect/flutter-movie/web/icons/Icon-maskable-192.png new file mode 100644 index 00000000..eb9b4d76 Binary files /dev/null and b/dataconnect/flutter-movie/web/icons/Icon-maskable-192.png differ diff --git a/dataconnect/flutter-movie/web/icons/Icon-maskable-512.png b/dataconnect/flutter-movie/web/icons/Icon-maskable-512.png new file mode 100644 index 00000000..d69c5669 Binary files /dev/null and b/dataconnect/flutter-movie/web/icons/Icon-maskable-512.png differ diff --git a/dataconnect/flutter-movie/web/index.html b/dataconnect/flutter-movie/web/index.html new file mode 100644 index 00000000..b923e444 --- /dev/null +++ b/dataconnect/flutter-movie/web/index.html @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + dataconnect + + + + + + diff --git a/dataconnect/flutter-movie/web/manifest.json b/dataconnect/flutter-movie/web/manifest.json new file mode 100644 index 00000000..5ed8c6ad --- /dev/null +++ b/dataconnect/flutter-movie/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "dataconnect", + "short_name": "dataconnect", + "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/dataconnect/flutter/Caddyfile b/dataconnect/flutter/Caddyfile new file mode 100644 index 00000000..10e4dd13 --- /dev/null +++ b/dataconnect/flutter/Caddyfile @@ -0,0 +1,7 @@ +:9002 { + reverse_proxy /v1beta* http://localhost:9403 + reverse_proxy /* http://localhost:9003 { + header_down Cross-Origin-Embedder-Policy unsafe-none + header_down cross-origin-opener-policy same-origin-allow-popups + } +} diff --git a/dataconnect/flutter/dev.nix b/dataconnect/flutter/dev.nix new file mode 100644 index 00000000..6eb8f36c --- /dev/null +++ b/dataconnect/flutter/dev.nix @@ -0,0 +1,79 @@ +# To learn more about how to use Nix to configure your environment +# see: https://developers.google.com/idx/guides/customize-idx-env +{ pkgs, ... }: { + processes = { + writeEnv = { + command = "echo \"HOST=$WEB_HOST\" > .env"; + }; + }; + + # Which nixpkgs channel to use. + channel = "stable-24.05"; # or "unstable" + +services.postgres = { + extensions = ["pgvector"]; + enable = true; +}; + + + # Use https://search.nixos.org/packages to find packages + packages = [ + pkgs.nodejs_20 + (pkgs.postgresql_15.withPackages (p: [ p.pgvector ])) + pkgs.nodePackages.pnpm + pkgs.jdk17 + pkgs.unzip + pkgs.caddy + ]; + + # Sets environment variables in the workspace + env = { + FIREBASE_DATACONNECT_POSTGRESQL_STRING = "postgresql://user:mypassword@localhost:5432/dataconnect?sslmode=disable"; + PATH = ["/home/user/.pub-cache/bin" "/home/user/flutter/bin" "./.flutter-sdk/flutter/bin"]; + }; + idx = { + # Search for the extensions you want on https://open-vsx.org/ and use "publisher.id" + extensions = [ + "mtxr.sqltools" + "Dart-Code.flutter" + "Dart-Code.dart-code" + "mtxr.sqltools-driver-pg" + "GraphQL.vscode-graphql-syntax" + "GoogleCloudTools.firebase-dataconnect-vscode" + ]; + + workspace = { + # Runs when a workspace is first created with this `dev.nix` file + onCreate = { + postgres = '' + psql --dbname=postgres -c "ALTER USER \"user\" PASSWORD 'mypassword';" + psql --dbname=postgres -c "CREATE DATABASE dataconnect;" + psql --dbname=dataconnect -c "CREATE EXTENSION vector;" + ''; + }; + onStart = { + startProxy = '' + caddy run + ''; + }; + + # To run something each time the workspace is (re)started, use the `onStart` hook + }; + # set up a proxy that routes requests from $PORT in IDX to 9003, and any FDC-like queries are automatically rerouted to FDC + # Enable previews and customize configuration + previews = { + enable = true; + previews = { + web = { + command = ["flutter" "run" "--machine" "-d" "web-server" "--web-hostname" "0.0.0.0" "--web-port" "9003"]; + manager = "flutter"; + }; + android = { + command = ["flutter" "run" "--machine" "-d" "android" "-d" "localhost:5555"]; + manager = "flutter"; + }; + }; + }; + }; + +} \ No newline at end of file diff --git a/dataconnect/flutter/error_handler.dart b/dataconnect/flutter/error_handler.dart new file mode 100644 index 00000000..a1d00df4 --- /dev/null +++ b/dataconnect/flutter/error_handler.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; + +class ErrorContent extends StatelessWidget { + const ErrorContent({super.key}); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + // TRY THIS: Try changing the color here to a specific color (to + // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar + // change color while the other colors stay the same. + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text("Error"), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + // + // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" + // action in the IDE, or press "p" in the console), to see the + // wireframe for each widget. + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Text("Try running ./installDeps.sh to set up flutterfire"), + ), + ], + ), + ), + ); + } +} + +class ShowError extends StatelessWidget { + const ShowError({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Error', + theme: ThemeData( + // This is the theme of your application. + // + // TRY THIS: Try running your application with "flutter run". You'll see + // the application has a purple toolbar. Then, without quitting the app, + // try changing the seedColor in the colorScheme below to Colors.green + // and then invoke "hot reload" (save your changes or press the "hot + // reload" button in a Flutter-supported IDE, or press "r" if you used + // the command line to start the app). + // + // Notice that the counter didn't reset back to zero; the application + // state is not lost during the reload. To reset the state, use hot + // restart instead. + // + // This works for code too, not just values: Most code changes can be + // tested with just a hot reload. + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const ErrorContent(), + ); + } +} diff --git a/dataconnect/flutter/installDeps.sh b/dataconnect/flutter/installDeps.sh new file mode 100755 index 00000000..fb3a9b36 --- /dev/null +++ b/dataconnect/flutter/installDeps.sh @@ -0,0 +1,29 @@ +#!/bin/bash +echo "Installing the latest firebase-tools..." +npm install -g firebase-tools +export PATH=~/.global_modules/bin:$PATH +while [ ! -f ./.firebaserc ] +do + echo "=============================================================================================================================================" + echo "Couldn't find .firebaserc file. Please open the Data Connect Extension and Connect a firebase project. Waiting 5s before checking again" + echo "=============================================================================================================================================" + sleep 5s # Waits 5 seconds. +done + +projectId=$(cat ./.firebaserc | grep -o '"default": "[^"]*' | grep -o '[^"]*$') +while [ -z "$projectId" ] || [ "$projectId" == "monospace-2" ] +do + echo "=========================================================================================================================================================" + echo "Couldn't find project ID in .firebaserc. Please open the Firebase Data Connect Extension and Connect a firebase project. Waiting 5s before checking again" + echo "=========================================================================================================================================================" + sleep 5s # Waits 5 seconds. + projectId=$(cat ./.firebaserc | grep -o '"default": "[^"]*' | grep -o '[^"]*$') +done +echo "Using ProjectID: $projectId" +dart pub global activate flutterfire_cli +export PATH=~/.global_modules/bin:$PATH +endName=$(ls android/app/src/main/kotlin/com/example) +rm lib/firebase_options.dart +flutterfire configure -y -a com.example.$endName +flutter pub get +firebase dataconnect:sdk:generate diff --git a/dataconnect/idx-template.json b/dataconnect/idx-template.json index 3cc7afc7..b089cd17 100644 --- a/dataconnect/idx-template.json +++ b/dataconnect/idx-template.json @@ -1,25 +1,33 @@ { "name": "Data Connect", "description": "Build a new web app using Data Connect", - "categories": ["Web app"], - "icon": "https://www.gstatic.com/monospace/231115/logo_react.svg", + "categories": ["Web app", "Flutter app", "Databases"], + "icon": "https://www.gstatic.com/monospace/240513/logo_firebase.svg", "publisher": "Google LLC", + "host": { + "virtualization": "true" + }, "params": [ { - "id": "projectId", - "name": "Firebase Project ID", - "description": "Find or create a project on firebase.google.com", - "type": "text", - "required": true + "id": "platform", + "description": "Build a new app using Data Connect", + "type": "enum", + "name": "Platform", + "required": true, + "options": { + "web": "Web", + "flutter": "Flutter" + } }, { - "id": "sample", - "description": "Build a new web app using Data Connect", + "id": "appType", + "description": "Build a new app using Data Connect", "type": "enum", + "name": "App Type", "required": true, "options": { - "nextjs-blank": "Next.js Blank", - "nextjs-email-app": "Next.js Email App" + "blank": "Empty App", + "quickstart": "Quickstart" } } ] diff --git a/dataconnect/idx-template.nix b/dataconnect/idx-template.nix index dd18e80c..137427ee 100644 --- a/dataconnect/idx-template.nix +++ b/dataconnect/idx-template.nix @@ -6,25 +6,45 @@ idx-template \ --output-dir /home/user/community-templates/template-test -a '{}' */ -{pkgs, sample ? "nextjs-email-app", projectId ? "FIREBASE_PROJECT_ID", ... }: { +{pkgs, platform ? "web", appType ? "blank", ... }: { packages = [ pkgs.nodejs_20 ]; - bootstrap = '' + bootstrap = let + platformPrefix = if platform == "web" then "nextjs" else "flutter"; + suffix = if platform == "web" && appType == "quickstart" then "movie-app" else if platform == "flutter" && appType == "quickstart" then "movie" else appType; + sample = "${platformPrefix}-${suffix}"; + in '' mkdir "$out" + chmod -R u+w "$out" mkdir "$out"/.idx - cp ${./dev.nix} "$out"/.idx/dev.nix + + ${ + if sample == "flutter-blank" || sample == "flutter-movie" then "cp -r ${./flutter}/dev.nix \"$out\"/.idx/dev.nix" + else "cp ${./.}/${sample}/dev.nix \"$out\"/.idx/dev.nix" + } + + ${ + if sample == "nextjs-movie-app" then "cp -r ${./nextjs-movie-app}/* \"$out\"" + else if sample == "nextjs-blank" then "cp -r ${./nextjs-blank}/* \"$out\"" + else if sample == "flutter-blank" then "cp -r ${./flutter-blank}/* \"$out\"" + else "cp -r ${./flutter-movie}/* \"$out\"" + } + chmod -R u+w "$out" + ${ + if sample == "flutter-blank" || sample == "flutter-movie" then "cp ${./flutter}/installDeps.sh \"$out\"/" else "" + } + ${ + if sample == "flutter-blank" || sample == "flutter-movie" then "cp ${./flutter}/Caddyfile \"$out\"/" else "" + } ${ - if sample == "nextjs-email-app" then "cp -r ${./nextjs-email-app}/* \"$out\"" - else "cp -r ${./nextjs-blank}/* \"$out\"" + if sample == "flutter-blank" || sample == "flutter-movie" then "cp ${./flutter}/error_handler.dart \"$out\"/lib/" else "" } cp ${./.firebaserc} "$out"/.firebaserc cp ${./.graphqlrc.yaml} "$out"/.graphqlrc.yaml mkdir "$out"/.vscode cp ${./.vscode/settings.json} "$out"/.vscode/settings.json chmod -R u+w "$out" - sed -i 's/FIREBASE_PROJECT_ID_HERE/${projectId}/g' "$out"/.firebaserc - sed -i 's/FIREBASE_PROJECT_ID_HERE/${projectId}/g' "$out"/webapp/src/data-connect/index.tsx ''; } diff --git a/dataconnect/mobile-blank/README.md b/dataconnect/mobile-blank/README.md new file mode 100644 index 00000000..092ac93d --- /dev/null +++ b/dataconnect/mobile-blank/README.md @@ -0,0 +1,12 @@ +# Empty Template + +1. Click on the Firebase Data Connect Extension and click `firebase init` to initialize your Firebase project. +2. Updating your schema, query and mutations. +3. Open the Firebase Data Connect Extension and click "Deploy to Production". +4. Open up "Files", and right click on your generated SDK, and click "Zip and Download" +5. Place the SDK on your local computer in the corresponding location of your app. +6. To set up your SDK, please follow the link below based on what platform you use: +* [Set up the web SDK](https://firebase.google.com/docs/data-connect/web-sdk) +* [Set up the Android SDK](https://firebase.google.com/docs/data-connect/android-sdk) +* [Set up the iOS SDK](https://firebase.google.com/docs/data-connect/ios-sdk) +* [Set up the Flutter SDK](https://firebase.google.com/docs/data-connect/flutter-sdk) diff --git a/dataconnect/mobile-blank/dev.nix b/dataconnect/mobile-blank/dev.nix new file mode 100644 index 00000000..7c9dc8c7 --- /dev/null +++ b/dataconnect/mobile-blank/dev.nix @@ -0,0 +1,22 @@ +{ pkgs, ... }: + { + channel = "stable-24.05"; + packages = [ + pkgs.nodejs_20 + ]; + + idx.extensions = [ + "mtxr.sqltools" + "mtxr.sqltools-driver-pg" + "GraphQL.vscode-graphql-syntax" + "GoogleCloudTools.firebase-dataconnect-vscode" + ]; + + idx = { + workspace = { + onCreate = { + update-firebase = "npm install -g firebase-tools"; + }; + }; + }; +} diff --git a/dataconnect/mobile-blank/idx-template.json b/dataconnect/mobile-blank/idx-template.json new file mode 100644 index 00000000..d48be529 --- /dev/null +++ b/dataconnect/mobile-blank/idx-template.json @@ -0,0 +1,10 @@ +{ + "name": "Data Connect", + "description": "Build a new web app using Data Connect", + "categories": ["Web app", "Flutter app", "Databases"], + "icon": "https://www.gstatic.com/monospace/240513/logo_firebase.svg", + "publisher": "Google LLC", + "host": { + "virtualization": "true" + } +} diff --git a/dataconnect/mobile-blank/idx-template.nix b/dataconnect/mobile-blank/idx-template.nix new file mode 100644 index 00000000..5e317502 --- /dev/null +++ b/dataconnect/mobile-blank/idx-template.nix @@ -0,0 +1,21 @@ +/* + +rm -rf ./test && \ +idx-template \ + /home/user/community-templates/dataconnect \ + --output-dir /home/user/community-templates/template-test -a '{}' + +*/ +{pkgs, platform ? "web", appType ? "blank", ... }: { + packages = [ + pkgs.nodejs_20 + ]; + + bootstrap = '' + mkdir "$out" + chmod -R u+w "$out" + mkdir "$out"/.idx + cp ${./dev.nix} "$out"/.idx/dev.nix + cp ${./README.md} "$out"/README.md + ''; +} diff --git a/dataconnect/dev.nix b/dataconnect/nextjs-blank/dev.nix similarity index 69% rename from dataconnect/dev.nix rename to dataconnect/nextjs-blank/dev.nix index 8b44f1dd..32299ce9 100644 --- a/dataconnect/dev.nix +++ b/dataconnect/nextjs-blank/dev.nix @@ -1,25 +1,19 @@ { pkgs, ... }: - let firebase-ext = pkgs.fetchurl { - url = - "https://firebasestorage.googleapis.com/v0/b/firemat-preview-drop/o/vsix%2Ffirebase-vscode-0.5.3.vsix?alt=media&token=f9ebbddf-b09f-4aae-b8c5-7ebe7ae95725"; - hash = "sha256-W30ofDjr611EKwZf3lAq+u+mf6Ao0Z1IMrVhoxZtCQo="; - name = "firebase.vsix"; - }; - in { + { channel = "stable-24.05"; packages = [ pkgs.nodejs_20 ]; env = { - POSTGRESQL_CONN_STRING = "postgresql://user:mypassword@localhost:5432/dataconnect?sslmode=disable"; + FIREBASE_DATACONNECT_POSTGRESQL_STRING = "postgresql://user:mypassword@localhost:5432/dataconnect?sslmode=disable"; }; idx.extensions = [ "mtxr.sqltools" "mtxr.sqltools-driver-pg" "GraphQL.vscode-graphql-syntax" - "${firebase-ext}" + "GoogleCloudTools.firebase-dataconnect-vscode" ]; services.postgres = { diff --git a/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/esm/index.esm.js b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/esm/index.esm.js new file mode 100644 index 00000000..be8b0581 --- /dev/null +++ b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/esm/index.esm.js @@ -0,0 +1,8 @@ +import { getDataConnect, validateArgs } from 'firebase/data-connect'; + +export const connectorConfig = { + connector: 'default', + service: 'local', + location: 'us-central1' +}; + diff --git a/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/esm/package.json b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/esm/package.json new file mode 100644 index 00000000..7c34deb5 --- /dev/null +++ b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/esm/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/index.cjs.js b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/index.cjs.js new file mode 100644 index 00000000..68a88f56 --- /dev/null +++ b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/index.cjs.js @@ -0,0 +1,9 @@ +const { getDataConnect, validateArgs } = require('firebase/data-connect'); + +const connectorConfig = { + connector: 'default', + service: 'local', + location: 'us-central1' +}; +exports.connectorConfig = connectorConfig; + diff --git a/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/index.d.ts b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/index.d.ts new file mode 100644 index 00000000..15eaf769 --- /dev/null +++ b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/index.d.ts @@ -0,0 +1,15 @@ +import { ConnectorConfig, DataConnect } from 'firebase/data-connect'; +export const connectorConfig: ConnectorConfig; + +export type TimestampString = string; + +export type UUIDString = string; + +export type Int64String = string; + +export type DateString = string; + + + + + diff --git a/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/package.json b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/package.json new file mode 100644 index 00000000..5e14e66b --- /dev/null +++ b/dataconnect/nextjs-blank/webapp/dataconnect-generated/js/default-connector/package.json @@ -0,0 +1,25 @@ +{ + "name": "@firebasegen/default-connector", + "version": "1.0.0", + "author": "Firebase (https://firebase.google.com/)", + "description": "Generated SDK For default", + "license": "Apache-2.0", + "engines": { + "node": " >=18.0" + }, + "typings": "index.d.ts", + "module": "esm/index.esm.js", + "main": "index.cjs.js", + "browser": "esm/index.esm.js", + "exports": { + ".": { + "types": "./index.d.ts", + "require": "./index.cjs.js", + "default": "./esm/index.esm.js" + }, + "./package.json": "./package.json" + }, + "peerDependencies": { + "firebase": "^10.14.0" + } +} \ No newline at end of file diff --git a/dataconnect/nextjs-blank/webapp/next.config.mjs b/dataconnect/nextjs-blank/webapp/next.config.mjs index fe898d84..d20cfc79 100644 --- a/dataconnect/nextjs-blank/webapp/next.config.mjs +++ b/dataconnect/nextjs-blank/webapp/next.config.mjs @@ -2,8 +2,8 @@ const nextConfig = { rewrites: async () => [ { - source: '/v1alpha/projects/:path*', - destination: 'http://127.0.0.1:9399/v1alpha/projects/:path*' + source: '/v1beta/projects/:path*', + destination: 'http://127.0.0.1:9399/v1beta/projects/:path*' }, ], }; diff --git a/dataconnect/nextjs-blank/webapp/package-lock.json b/dataconnect/nextjs-blank/webapp/package-lock.json index a4f1f035..ef759695 100644 --- a/dataconnect/nextjs-blank/webapp/package-lock.json +++ b/dataconnect/nextjs-blank/webapp/package-lock.json @@ -8,6 +8,9 @@ "name": "webapp", "version": "0.1.0", "dependencies": { + "@blank/generated": "file:dataconnect-generated", + "@firebasegen/default-connector": "file:dataconnect-generated/js/default-connector", + "firebase": "^10.14.0", "next": "14.2.5", "react": "^18", "react-dom": "^18" @@ -16,12 +19,22 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", - "firebase": "^10.14.0", "postcss": "^8", "tailwindcss": "^3.4.1", "typescript": "^5" } }, + "dataconnect-generated": { + "version": "1.0.0", + "license": "Apache-2.0", + "engines": { + "node": " >=18.0" + }, + "peerDependencies": { + "firebase": "^10.14.0" + } + }, + "dataconnect-generated/js/default-connector": {}, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -35,17 +48,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@blank/generated": { + "resolved": "dataconnect-generated", + "link": true + }, "node_modules/@firebase/analytics": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.7.tgz", - "integrity": "sha512-GE29uTT6y/Jv2EP0OjpTezeTQZ5FTCTaZXKrrdVGjb/t35AU4u/jiU+hUwUPpuK8fqhhiHkS/AawE3a3ZK/a9Q==", - "dev": true, - "license": "Apache-2.0", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.8.tgz", + "integrity": "sha512-CVnHcS4iRJPqtIDc411+UmFldk0ShSK3OB+D0bKD8Ck5Vro6dbK5+APZpkuWpbfdL359DIQUnAaMLE+zs/PVyA==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", + "@firebase/component": "0.6.9", + "@firebase/installations": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -53,16 +68,14 @@ } }, "node_modules/@firebase/analytics-compat": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.13.tgz", - "integrity": "sha512-aZ4wGfNDMsCxhKzDbK2g1aV0JKsdQ9FbeIsjpNJPzhahV0XYj+z36Y4RNLPpG/6hHU4gxnezxs+yn3HhHkNL8w==", - "dev": true, - "license": "Apache-2.0", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.14.tgz", + "integrity": "sha512-unRVY6SvRqfNFIAA/kwl4vK+lvQAL2HVcgu9zTrUtTyYDmtIt/lOuHJynBMYEgLnKm39YKBDhtqdapP2e++ASw==", "dependencies": { - "@firebase/analytics": "0.10.7", + "@firebase/analytics": "0.10.8", "@firebase/analytics-types": "0.8.2", - "@firebase/component": "0.6.8", - "@firebase/util": "1.9.7", + "@firebase/component": "0.6.9", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -72,34 +85,28 @@ "node_modules/@firebase/analytics-types": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.2.tgz", - "integrity": "sha512-EnzNNLh+9/sJsimsA/FGqzakmrAUKLeJvjRHlg8df1f97NLUlFidk9600y0ZgWOp3CAxn6Hjtk+08tixlUOWyw==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-EnzNNLh+9/sJsimsA/FGqzakmrAUKLeJvjRHlg8df1f97NLUlFidk9600y0ZgWOp3CAxn6Hjtk+08tixlUOWyw==" }, "node_modules/@firebase/app": { - "version": "0.10.10", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.10.tgz", - "integrity": "sha512-sDqkdeFdVn5uygQm5EuIKOQ6/wxTcX/qKfm0MR46AiwLRHGLCDUMrXBkc8GhkK3ca2d6mPUSfPmndggo43D6PQ==", - "dev": true, - "license": "Apache-2.0", + "version": "0.10.13", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.13.tgz", + "integrity": "sha512-OZiDAEK/lDB6xy/XzYAyJJkaDqmQ+BCtOEPLqFvxWKUz5JbBmej7IiiRHdtiIOD/twW7O5AxVsfaaGA/V1bNsA==", "dependencies": { - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "idb": "7.1.1", "tslib": "^2.1.0" } }, "node_modules/@firebase/app-check": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.7.tgz", - "integrity": "sha512-EkOeJcMKVR0zZ6z/jqcFTqHb/xq+TVIRIuBNGHdpcIuFU1czhSlegvqv2+nC+nFrkD8M6Xvd3tAlUOkdbMeS6A==", - "dev": true, - "license": "Apache-2.0", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.8.tgz", + "integrity": "sha512-O49RGF1xj7k6BuhxGpHmqOW5hqBIAEbt2q6POW0lIywx7emYtzPDeQI+ryQpC4zbKX646SoVZ711TN1DBLNSOQ==", "dependencies": { - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -107,17 +114,15 @@ } }, "node_modules/@firebase/app-check-compat": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.14.tgz", - "integrity": "sha512-kK3bPfojAfXE53W+20rxMqIxrloFswXG9vh4kEdYL6Wa2IB3sD5++2dPiK3yGxl8oQiqS8qL2wcKB5/xLpEVEg==", - "dev": true, - "license": "Apache-2.0", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.15.tgz", + "integrity": "sha512-zFIvIFFNqDXpOT2huorz9cwf56VT3oJYRFjSFYdSbGYEJYEaXjLJbfC79lx/zjx4Fh+yuN8pry3TtvwaevrGbg==", "dependencies": { - "@firebase/app-check": "0.8.7", + "@firebase/app-check": "0.8.8", "@firebase/app-check-types": "0.5.2", - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -127,48 +132,38 @@ "node_modules/@firebase/app-check-interop-types": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz", - "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "node_modules/@firebase/app-check-types": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.2.tgz", - "integrity": "sha512-FSOEzTzL5bLUbD2co3Zut46iyPWML6xc4x+78TeaXMSuJap5QObfb+rVvZJtla3asN4RwU7elaQaduP+HFizDA==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-FSOEzTzL5bLUbD2co3Zut46iyPWML6xc4x+78TeaXMSuJap5QObfb+rVvZJtla3asN4RwU7elaQaduP+HFizDA==" }, "node_modules/@firebase/app-compat": { - "version": "0.2.40", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.40.tgz", - "integrity": "sha512-2L5MW4MH2ya7Wvw0hzWy3ZWeB4SqC5gYXDAV5AS1lBTL4zL3k8dsqJmry/cFV00GgkCI01WJbcXvFMCXJvgyow==", - "dev": true, - "license": "Apache-2.0", + "version": "0.2.43", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.43.tgz", + "integrity": "sha512-HM96ZyIblXjAC7TzE8wIk2QhHlSvksYkQ4Ukh1GmEenzkucSNUmUX4QvoKrqeWsLEQ8hdcojABeCV8ybVyZmeg==", "dependencies": { - "@firebase/app": "0.10.10", - "@firebase/component": "0.6.8", + "@firebase/app": "0.10.13", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" } }, "node_modules/@firebase/app-types": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", - "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==" }, "node_modules/@firebase/auth": { - "version": "1.7.8", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.7.8.tgz", - "integrity": "sha512-1KJlDrTrEEFTIBj9MxjAWjQ4skecBD4bmoayQ0l14QDbNc1a8qGbi+MFSJkH7O6VnGE6bTMcWSw6RrQNecqKaw==", - "dev": true, - "license": "Apache-2.0", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.7.9.tgz", + "integrity": "sha512-yLD5095kVgDw965jepMyUrIgDklD6qH/BZNHeKOgvu7pchOKNjVM+zQoOVYJIKWMWOWBq8IRNVU6NXzBbozaJg==", "dependencies": { - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0", "undici": "6.19.7" }, @@ -183,16 +178,14 @@ } }, "node_modules/@firebase/auth-compat": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.13.tgz", - "integrity": "sha512-rV6TMxUU6wBBZ2ouDMtjJsJXeewtvYvVzslzt3/P7O/kxiWlreHT/2M/1guMiXKo3zk52XK3GqP0uM2bN7fEow==", - "dev": true, - "license": "Apache-2.0", + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.14.tgz", + "integrity": "sha512-2eczCSqBl1KUPJacZlFpQayvpilg3dxXLy9cSMTKtQMTQSmondUtPI47P3ikH3bQAXhzKLOE+qVxJ3/IRtu9pw==", "dependencies": { - "@firebase/auth": "1.7.8", + "@firebase/auth": "1.7.9", "@firebase/auth-types": "0.12.2", - "@firebase/component": "0.6.8", - "@firebase/util": "1.9.7", + "@firebase/component": "0.6.9", + "@firebase/util": "1.10.0", "tslib": "^2.1.0", "undici": "6.19.7" }, @@ -203,84 +196,85 @@ "node_modules/@firebase/auth-interop-types": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", - "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==" }, "node_modules/@firebase/auth-types": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", - "dev": true, - "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "node_modules/@firebase/component": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.8.tgz", - "integrity": "sha512-LcNvxGLLGjBwB0dJUsBGCej2fqAepWyBubs4jt1Tiuns7QLbXHuyObZ4aMeBjZjWx4m8g1LoVI9QFpSaq/k4/g==", - "dev": true, - "license": "Apache-2.0", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", + "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", + "dependencies": { + "@firebase/util": "1.10.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/data-connect": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.1.0.tgz", + "integrity": "sha512-vSe5s8dY13ilhLnfY0eYRmQsdTbH7PUFZtBbqU6JVX/j8Qp9A6G5gG6//ulbX9/1JFOF1IWNOne9c8S/DOCJaQ==", "dependencies": { - "@firebase/util": "1.9.7", + "@firebase/auth-interop-types": "0.2.3", + "@firebase/component": "0.6.9", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x" } }, "node_modules/@firebase/database": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.7.tgz", - "integrity": "sha512-wjXr5AO8RPxVVg7rRCYffT7FMtBjHRfJ9KMwi19MbOf0vBf0H9YqW3WCgcnLpXI6ehiUcU3z3qgPnnU0nK6SnA==", - "dev": true, - "license": "Apache-2.0", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.8.tgz", + "integrity": "sha512-dzXALZeBI1U5TXt6619cv0+tgEhJiwlUtQ55WNZY7vGAjv7Q1QioV969iYwt1AQQ0ovHnEW0YW9TiBfefLvErg==", "dependencies": { "@firebase/app-check-interop-types": "0.3.2", "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "node_modules/@firebase/database-compat": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.7.tgz", - "integrity": "sha512-R/3B+VVzEFN5YcHmfWns3eitA8fHLTL03io+FIoMcTYkajFnrBdS3A+g/KceN9omP7FYYYGTQWF9lvbEx6eMEg==", - "dev": true, - "license": "Apache-2.0", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.8.tgz", + "integrity": "sha512-OpeWZoPE3sGIRPBKYnW9wLad25RaWbGyk7fFQe4xnJQKRzlynWeFBSRRAoLE2Old01WXwskUiucNqUUVlFsceg==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/database": "1.0.7", - "@firebase/database-types": "1.0.4", + "@firebase/component": "0.6.9", + "@firebase/database": "1.0.8", + "@firebase/database-types": "1.0.5", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" } }, "node_modules/@firebase/database-types": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.4.tgz", - "integrity": "sha512-mz9ZzbH6euFXbcBo+enuJ36I5dR5w+enJHHjy9Y5ThCdKUseqfDjW3vCp1YxE9zygFCSjJJ/z1cQ+zodvUcwPQ==", - "dev": true, - "license": "Apache-2.0", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.5.tgz", + "integrity": "sha512-fTlqCNwFYyq/C6W7AJ5OCuq5CeZuBEsEwptnVxlNPkWCo5cTTyukzAHRSO/jaQcItz33FfYrrFk1SJofcu2AaQ==", "dependencies": { "@firebase/app-types": "0.9.2", - "@firebase/util": "1.9.7" + "@firebase/util": "1.10.0" } }, "node_modules/@firebase/firestore": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.1.tgz", - "integrity": "sha512-WliQNa8GVcH6EWkH0NAf+uAnxNiBuH+G8Buzr2ZS1NznOhJDK/q6Hsjv5TzNrijLTAdEfj/wk9VEv994KDSjxg==", - "dev": true, - "license": "Apache-2.0", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.3.tgz", + "integrity": "sha512-NwVU+JPZ/3bhvNSJMCSzfcBZZg8SUGyzZ2T0EW3/bkUeefCyzMISSt/TTIfEHc8cdyXGlMqfGe3/62u9s74UEg==", "dependencies": { - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "@firebase/webchannel-wrapper": "1.0.1", "@grpc/grpc-js": "~1.9.0", "@grpc/proto-loader": "^0.7.8", @@ -295,16 +289,14 @@ } }, "node_modules/@firebase/firestore-compat": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.36.tgz", - "integrity": "sha512-NtoIm7CT9f+SFB7cPMCtyCSxZReh/+SII5X4TQH394S3dwhru9HIfvEOKAMuAnXsSsLH72jXPUgdsEAUqg6Oug==", - "dev": true, - "license": "Apache-2.0", + "version": "0.3.38", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.38.tgz", + "integrity": "sha512-GoS0bIMMkjpLni6StSwRJarpu2+S5m346Na7gr9YZ/BZ/W3/8iHGNr9PxC+f0rNZXqS4fGRn88pICjrZEgbkqQ==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/firestore": "4.7.1", + "@firebase/component": "0.6.9", + "@firebase/firestore": "4.7.3", "@firebase/firestore-types": "3.0.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -315,25 +307,21 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.2.tgz", "integrity": "sha512-wp1A+t5rI2Qc/2q7r2ZpjUXkRVPtGMd6zCLsiWurjsQpqPgFin3AhNibKcIzoF2rnToNa/XYtyWXuifjOOwDgg==", - "dev": true, - "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "node_modules/@firebase/functions": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.7.tgz", - "integrity": "sha512-xaUsGI2kYrI8zJXgrNB7SrJKB8v1vJqR16YYi6g6dFTgBz4+VzWJFqqVU60BbdAWm6fXnUrg9gjlJQeqomT2Vg==", - "dev": true, - "license": "Apache-2.0", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.8.tgz", + "integrity": "sha512-Lo2rTPDn96naFIlSZKVd1yvRRqqqwiJk7cf9TZhUerwnPKgBzXy+aHE22ry+6EjCaQusUoNai6mU6p+G8QZT1g==", "dependencies": { "@firebase/app-check-interop-types": "0.3.2", "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/messaging-interop-types": "0.2.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0", "undici": "6.19.7" }, @@ -342,16 +330,14 @@ } }, "node_modules/@firebase/functions-compat": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.13.tgz", - "integrity": "sha512-qcZvJO2ed6PAD+18DanVztw7WyQVQK43HoRhxusHAwDFvK/xY+mcGpj+IpfdxTNMBGCOIxKFp4Xqk/c2nubBlQ==", - "dev": true, - "license": "Apache-2.0", + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.14.tgz", + "integrity": "sha512-dZ0PKOKQFnOlMfcim39XzaXonSuPPAVuzpqA4ONTIdyaJK/OnBaIEVs/+BH4faa1a2tLeR+Jy15PKqDRQoNIJw==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/functions": "0.11.7", + "@firebase/component": "0.6.9", + "@firebase/functions": "0.11.8", "@firebase/functions-types": "0.6.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -361,19 +347,15 @@ "node_modules/@firebase/functions-types": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.2.tgz", - "integrity": "sha512-0KiJ9lZ28nS2iJJvimpY4nNccV21rkQyor5Iheu/nq8aKXJqtJdeSlZDspjPSBBiHRzo7/GMUttegnsEITqR+w==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-0KiJ9lZ28nS2iJJvimpY4nNccV21rkQyor5Iheu/nq8aKXJqtJdeSlZDspjPSBBiHRzo7/GMUttegnsEITqR+w==" }, "node_modules/@firebase/installations": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.8.tgz", - "integrity": "sha512-57V374qdb2+wT5v7+ntpLXBjZkO6WRgmAUbVkRfFTM/4t980p0FesbqTAcOIiM8U866UeuuuF8lYH70D3jM/jQ==", - "dev": true, - "license": "Apache-2.0", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.9.tgz", + "integrity": "sha512-hlT7AwCiKghOX3XizLxXOsTFiFCQnp/oj86zp1UxwDGmyzsyoxtX+UIZyVyH/oBF5+XtblFG9KZzZQ/h+dpy+Q==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/util": "1.9.7", + "@firebase/component": "0.6.9", + "@firebase/util": "1.10.0", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -382,16 +364,14 @@ } }, "node_modules/@firebase/installations-compat": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.8.tgz", - "integrity": "sha512-pI2q8JFHB7yIq/szmhzGSWXtOvtzl6tCUmyykv5C8vvfOVJUH6mP4M4iwjbK8S1JotKd/K70+JWyYlxgQ0Kpyw==", - "dev": true, - "license": "Apache-2.0", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.9.tgz", + "integrity": "sha512-2lfdc6kPXR7WaL4FCQSQUhXcPbI7ol3wF+vkgtU25r77OxPf8F/VmswQ7sgIkBBWtymn5ZF20TIKtnOj9rjb6w==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", + "@firebase/component": "0.6.9", + "@firebase/installations": "0.6.9", "@firebase/installations-types": "0.5.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -402,8 +382,6 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.2.tgz", "integrity": "sha512-que84TqGRZJpJKHBlF2pkvc1YcXrtEDOVGiDjovP/a3s6W4nlbohGXEsBJo0JCeeg/UG9A+DEZVDUV9GpklUzA==", - "dev": true, - "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x" } @@ -412,23 +390,19 @@ "version": "0.4.2", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", - "dev": true, - "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@firebase/messaging": { - "version": "0.12.10", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.10.tgz", - "integrity": "sha512-fGbxJPKpl2DIKNJGhbk4mYPcM+qE2gl91r6xPoiol/mN88F5Ym6UeRdMVZah+pijh9WxM55alTYwXuW40r1Y2Q==", - "dev": true, - "license": "Apache-2.0", + "version": "0.12.12", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.12.tgz", + "integrity": "sha512-6q0pbzYBJhZEtUoQx7hnPhZvAbuMNuBXKQXOx2YlWhSrlv9N1m0ZzlNpBbu/ItTzrwNKTibdYzUyaaxdWLg+4w==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", + "@firebase/component": "0.6.9", + "@firebase/installations": "0.6.9", "@firebase/messaging-interop-types": "0.2.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -437,15 +411,13 @@ } }, "node_modules/@firebase/messaging-compat": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.10.tgz", - "integrity": "sha512-FXQm7rcowkDm8kFLduHV35IRYCRo+Ng0PIp/t1+EBuEbyplaKkGjZ932pE+owf/XR+G/60ku2QRBptRGLXZydg==", - "dev": true, - "license": "Apache-2.0", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.12.tgz", + "integrity": "sha512-pKsiUVZrbmRgdImYqhBNZlkKJbqjlPkVdQRZGRbkTyX4OSGKR0F/oJeCt1a8jEg5UnBp4fdVwSWSp4DuCovvEQ==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/messaging": "0.12.10", - "@firebase/util": "1.9.7", + "@firebase/component": "0.6.9", + "@firebase/messaging": "0.12.12", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -455,21 +427,17 @@ "node_modules/@firebase/messaging-interop-types": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.2.tgz", - "integrity": "sha512-l68HXbuD2PPzDUOFb3aG+nZj5KA3INcPwlocwLZOzPp9rFM9yeuI9YLl6DQfguTX5eAGxO0doTR+rDLDvQb5tA==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-l68HXbuD2PPzDUOFb3aG+nZj5KA3INcPwlocwLZOzPp9rFM9yeuI9YLl6DQfguTX5eAGxO0doTR+rDLDvQb5tA==" }, "node_modules/@firebase/performance": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.8.tgz", - "integrity": "sha512-F+alziiIZ6Yn8FG47mxwljq+4XkgkT2uJIFRlkyViUQRLzrogaUJW6u/+6ZrePXnouKlKIwzqos3PVJraPEcCA==", - "dev": true, - "license": "Apache-2.0", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.9.tgz", + "integrity": "sha512-PnVaak5sqfz5ivhua+HserxTJHtCar/7zM0flCX6NkzBNzJzyzlH4Hs94h2Il0LQB99roBqoE5QT1JqWqcLJHQ==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", + "@firebase/component": "0.6.9", + "@firebase/installations": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -477,17 +445,15 @@ } }, "node_modules/@firebase/performance-compat": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.8.tgz", - "integrity": "sha512-o7TFClRVJd3VIBoY7KZQqtCeW0PC6v9uBzM6Lfw3Nc9D7hM6OonqecYvh7NwJ6R14k+xM27frLS4BcCvFHKw2A==", - "dev": true, - "license": "Apache-2.0", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.9.tgz", + "integrity": "sha512-dNl95IUnpsu3fAfYBZDCVhXNkASE0uo4HYaEPd2/PKscfTvsgqFAOxfAXzBEDOnynDWiaGUnb5M1O00JQ+3FXA==", "dependencies": { - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/performance": "0.6.8", + "@firebase/performance": "0.6.9", "@firebase/performance-types": "0.2.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -497,21 +463,17 @@ "node_modules/@firebase/performance-types": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.2.tgz", - "integrity": "sha512-gVq0/lAClVH5STrIdKnHnCo2UcPLjJlDUoEB/tB4KM+hAeHUxWKnpT0nemUPvxZ5nbdY/pybeyMe8Cs29gEcHA==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-gVq0/lAClVH5STrIdKnHnCo2UcPLjJlDUoEB/tB4KM+hAeHUxWKnpT0nemUPvxZ5nbdY/pybeyMe8Cs29gEcHA==" }, "node_modules/@firebase/remote-config": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.8.tgz", - "integrity": "sha512-AMLqe6wfIRnjc6FkCWOSUjhc1fSTEf8o+cv1NolFvbiJ/tU+TqN4pI7pT+MIKQzNiq5fxLehkOx+xtAQBxPJKQ==", - "dev": true, - "license": "Apache-2.0", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.9.tgz", + "integrity": "sha512-EO1NLCWSPMHdDSRGwZ73kxEEcTopAxX1naqLJFNApp4hO8WfKfmEpmjxmP5TrrnypjIf2tUkYaKsfbEA7+AMmA==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", + "@firebase/component": "0.6.9", + "@firebase/installations": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -519,17 +481,15 @@ } }, "node_modules/@firebase/remote-config-compat": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.8.tgz", - "integrity": "sha512-UxSFOp6dzFj2AHB8Bq/BYtbq5iFyizKx4Rd6WxAdaKYM8cnPMeK+l2v+Oogtjae+AeyHRI+MfL2acsfVe5cd2A==", - "dev": true, - "license": "Apache-2.0", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.9.tgz", + "integrity": "sha512-AxzGpWfWFYejH2twxfdOJt5Cfh/ATHONegTd/a0p5flEzsD5JsxXgfkFToop+mypEL3gNwawxrxlZddmDoNxyA==", "dependencies": { - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/remote-config": "0.4.8", + "@firebase/remote-config": "0.4.9", "@firebase/remote-config-types": "0.3.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -539,19 +499,15 @@ "node_modules/@firebase/remote-config-types": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.2.tgz", - "integrity": "sha512-0BC4+Ud7y2aPTyhXJTMTFfrGGLqdYXrUB9sJVAB8NiqJswDTc4/2qrE/yfUbnQJhbSi6ZaTTBKyG3n1nplssaA==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-0BC4+Ud7y2aPTyhXJTMTFfrGGLqdYXrUB9sJVAB8NiqJswDTc4/2qrE/yfUbnQJhbSi6ZaTTBKyG3n1nplssaA==" }, "node_modules/@firebase/storage": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.1.tgz", - "integrity": "sha512-L6AJ5tWgHSi2g/gbc/2Pbm3qxmoEg9THmPIOpRsLwuz9LPeWbhyMQeGlqxWqtZGQO/z/LMjGYadNlupQj0HNfw==", - "dev": true, - "license": "Apache-2.0", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.2.tgz", + "integrity": "sha512-fxuJnHshbhVwuJ4FuISLu+/76Aby2sh+44ztjF2ppoe0TELIDxPW6/r1KGlWYt//AD0IodDYYA8ZTN89q8YqUw==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/util": "1.9.7", + "@firebase/component": "0.6.9", + "@firebase/util": "1.10.0", "tslib": "^2.1.0", "undici": "6.19.7" }, @@ -560,16 +516,14 @@ } }, "node_modules/@firebase/storage-compat": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.11.tgz", - "integrity": "sha512-EEa9jgm/aRVIGSD0ByYAsZ0tvEKfVwSp9uFoa/97BISGWGjSNPIWjenaDvpDZ7aL8OxaGIpwuk700aHy7/T0Ug==", - "dev": true, - "license": "Apache-2.0", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.12.tgz", + "integrity": "sha512-hA4VWKyGU5bWOll+uwzzhEMMYGu9PlKQc1w4DWxB3aIErWYzonrZjF0icqNQZbwKNIdh8SHjZlFeB2w6OSsjfg==", "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/storage": "0.13.1", + "@firebase/component": "0.6.9", + "@firebase/storage": "0.13.2", "@firebase/storage-types": "0.8.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "peerDependencies": { @@ -580,34 +534,28 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.2.tgz", "integrity": "sha512-0vWu99rdey0g53lA7IShoA2Lol1jfnPovzLDUBuon65K7uKG9G+L5uO05brD9pMw+l4HRFw23ah3GwTGpEav6g==", - "dev": true, - "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, "node_modules/@firebase/util": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.7.tgz", - "integrity": "sha512-fBVNH/8bRbYjqlbIhZ+lBtdAAS4WqZumx03K06/u7fJSpz1TGjEMm1ImvKD47w+xaFKIP2ori6z8BrbakRfjJA==", - "dev": true, - "license": "Apache-2.0", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", + "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/@firebase/vertexai-preview": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@firebase/vertexai-preview/-/vertexai-preview-0.0.3.tgz", - "integrity": "sha512-KVtUWLp+ScgiwkDKAvNkVucAyhLVQp6C6lhnVEuIg4mWhWcS3oerjAeVhZT4uNofKwWxRsOaB2Yec7DMTXlQPQ==", - "dev": true, - "license": "Apache-2.0", + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@firebase/vertexai-preview/-/vertexai-preview-0.0.4.tgz", + "integrity": "sha512-EBSqyu9eg8frQlVU9/HjKtHN7odqbh9MtAcVz3WwHj4gLCLOoN9F/o+oxlq3CxvFrd3CNTZwu6d2mZtVlEInng==", "dependencies": { "@firebase/app-check-interop-types": "0.3.2", - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "engines": { @@ -621,16 +569,16 @@ "node_modules/@firebase/webchannel-wrapper": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.1.tgz", - "integrity": "sha512-jmEnr/pk0yVkA7mIlHNnxCi+wWzOFUg0WyIotgkKAb2u1J7fAeDBcVNSTjTihbAYNusCLQdW5s9IJ5qwnEufcQ==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-jmEnr/pk0yVkA7mIlHNnxCi+wWzOFUg0WyIotgkKAb2u1J7fAeDBcVNSTjTihbAYNusCLQdW5s9IJ5qwnEufcQ==" + }, + "node_modules/@firebasegen/default-connector": { + "resolved": "dataconnect-generated/js/default-connector", + "link": true }, "node_modules/@grpc/grpc-js": { "version": "1.9.15", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", - "dev": true, - "license": "Apache-2.0", "dependencies": { "@grpc/proto-loader": "^0.7.8", "@types/node": ">=12.12.47" @@ -643,8 +591,6 @@ "version": "0.7.13", "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "dev": true, - "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", @@ -931,37 +877,27 @@ "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -970,37 +906,27 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "dev": true, - "license": "BSD-3-Clause" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@swc/counter": { "version": "0.1.3", @@ -1022,7 +948,6 @@ "version": "20.16.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -1242,8 +1167,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -1257,8 +1180,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -1267,8 +1188,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1282,16 +1201,12 @@ "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/cliui/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1305,8 +1220,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1318,8 +1231,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1336,7 +1247,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1349,7 +1259,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/commander": { @@ -1429,8 +1338,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -1479,8 +1386,6 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -1502,39 +1407,38 @@ } }, "node_modules/firebase": { - "version": "10.13.1", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-10.13.1.tgz", - "integrity": "sha512-L5BSkmvB2dzCUMpr8i/O8WMJC3Nqj5Ld8Wj/qnak+tz2Ga+JH6/FO93xArg9IGhktCrPXVODoWp6t9ybdgmXCA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@firebase/analytics": "0.10.7", - "@firebase/analytics-compat": "0.2.13", - "@firebase/app": "0.10.10", - "@firebase/app-check": "0.8.7", - "@firebase/app-check-compat": "0.3.14", - "@firebase/app-compat": "0.2.40", + "version": "10.14.1", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-10.14.1.tgz", + "integrity": "sha512-0KZxU+Ela9rUCULqFsUUOYYkjh7OM1EWdIfG6///MtXd0t2/uUIf0iNV5i0KariMhRQ5jve/OY985nrAXFaZeQ==", + "dependencies": { + "@firebase/analytics": "0.10.8", + "@firebase/analytics-compat": "0.2.14", + "@firebase/app": "0.10.13", + "@firebase/app-check": "0.8.8", + "@firebase/app-check-compat": "0.3.15", + "@firebase/app-compat": "0.2.43", "@firebase/app-types": "0.9.2", - "@firebase/auth": "1.7.8", - "@firebase/auth-compat": "0.5.13", - "@firebase/database": "1.0.7", - "@firebase/database-compat": "1.0.7", - "@firebase/firestore": "4.7.1", - "@firebase/firestore-compat": "0.3.36", - "@firebase/functions": "0.11.7", - "@firebase/functions-compat": "0.3.13", - "@firebase/installations": "0.6.8", - "@firebase/installations-compat": "0.2.8", - "@firebase/messaging": "0.12.10", - "@firebase/messaging-compat": "0.2.10", - "@firebase/performance": "0.6.8", - "@firebase/performance-compat": "0.2.8", - "@firebase/remote-config": "0.4.8", - "@firebase/remote-config-compat": "0.2.8", - "@firebase/storage": "0.13.1", - "@firebase/storage-compat": "0.3.11", - "@firebase/util": "1.9.7", - "@firebase/vertexai-preview": "0.0.3" + "@firebase/auth": "1.7.9", + "@firebase/auth-compat": "0.5.14", + "@firebase/data-connect": "0.1.0", + "@firebase/database": "1.0.8", + "@firebase/database-compat": "1.0.8", + "@firebase/firestore": "4.7.3", + "@firebase/firestore-compat": "0.3.38", + "@firebase/functions": "0.11.8", + "@firebase/functions-compat": "0.3.14", + "@firebase/installations": "0.6.9", + "@firebase/installations-compat": "0.2.9", + "@firebase/messaging": "0.12.12", + "@firebase/messaging-compat": "0.2.12", + "@firebase/performance": "0.6.9", + "@firebase/performance-compat": "0.2.9", + "@firebase/remote-config": "0.4.9", + "@firebase/remote-config-compat": "0.2.9", + "@firebase/storage": "0.13.2", + "@firebase/storage-compat": "0.3.12", + "@firebase/util": "1.10.0", + "@firebase/vertexai-preview": "0.0.4" } }, "node_modules/foreground-child": { @@ -1583,8 +1487,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -1645,16 +1547,12 @@ "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true, - "license": "MIT" + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, "node_modules/idb": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", - "dev": true, - "license": "ISC" + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -1699,7 +1597,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1787,16 +1684,12 @@ "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true, - "license": "MIT" + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "dev": true, - "license": "Apache-2.0" + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/loose-envify": { "version": "1.4.0", @@ -2252,9 +2145,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", - "dev": true, "hasInstallScript": true, - "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -2346,8 +2237,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2409,7 +2298,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -2423,8 +2311,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/scheduler": { "version": "0.23.2", @@ -2756,8 +2643,6 @@ "version": "6.19.7", "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz", "integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==", - "dev": true, - "license": "MIT", "engines": { "node": ">=18.17" } @@ -2766,7 +2651,6 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, "license": "MIT" }, "node_modules/util-deprecate": { @@ -2780,8 +2664,6 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -2795,8 +2677,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } @@ -2919,8 +2799,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", "engines": { "node": ">=10" } @@ -2942,8 +2820,6 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -2961,8 +2837,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", "engines": { "node": ">=12" } @@ -2971,8 +2845,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -2980,16 +2852,12 @@ "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3003,8 +2871,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, diff --git a/dataconnect/nextjs-blank/webapp/package.json b/dataconnect/nextjs-blank/webapp/package.json index 8b65d036..9cabc257 100644 --- a/dataconnect/nextjs-blank/webapp/package.json +++ b/dataconnect/nextjs-blank/webapp/package.json @@ -9,18 +9,18 @@ "lint": "next lint" }, "dependencies": { - "@blank/generated": "file:dataconnect-generated", - "firebase": "^10.14.0", + "@firebasegen/default-connector": "file:dataconnect-generated/js/default-connector", + "firebase": "^10.14.0", + "next": "14.2.5", "react": "^18", - "react-dom": "^18", - "next": "14.2.5" + "react-dom": "^18" }, "devDependencies": { - "typescript": "^5", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "postcss": "^8", - "tailwindcss": "^3.4.1" + "tailwindcss": "^3.4.1", + "typescript": "^5" } } diff --git a/dataconnect/nextjs-blank/webapp/src/data-connect/index.tsx b/dataconnect/nextjs-blank/webapp/src/data-connect/index.tsx index 2f47bf93..4cd79d84 100644 --- a/dataconnect/nextjs-blank/webapp/src/data-connect/index.tsx +++ b/dataconnect/nextjs-blank/webapp/src/data-connect/index.tsx @@ -1,6 +1,6 @@ import { initializeApp } from 'firebase/app'; import { getDataConnect, connectDataConnectEmulator } from 'firebase/data-connect' -import { connectorConfig } from '@blank/generated' +import { connectorConfig } from '@firebasegen/default-connector' export default (host: string = 'localhost') => { // Note: When connecting to a prod instance, please replace the empty config with your firebase config provided in the console. diff --git a/dataconnect/nextjs-email-app/.graphqlrc.yaml b/dataconnect/nextjs-email-app/.graphqlrc.yaml deleted file mode 100644 index 58e0eda2..00000000 --- a/dataconnect/nextjs-email-app/.graphqlrc.yaml +++ /dev/null @@ -1,9 +0,0 @@ -schema: - - ./dataconnect/schema/**/*.gql - - ./dataconnect/.dataconnect/**/*.gql -documents: - - ./dataconnect/connector/**/*.gql -extensions: - endpoints: - default: - url: http://127.0.0.1:8080/__/graphql \ No newline at end of file diff --git a/dataconnect/nextjs-email-app/dataconnect/EmailMeta_insert.gql b/dataconnect/nextjs-email-app/dataconnect/EmailMeta_insert.gql deleted file mode 100644 index a19846d7..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/EmailMeta_insert.gql +++ /dev/null @@ -1,117 +0,0 @@ -# -# Run the _insert files in this order: -# 1. User_insert.gql -# 2. Email_insert.gql -# 3. Recipient_insert.gql -# 4. EmailMeta_insert.gql -# -# This is one of many ways to run data seeds. You can create one large mutation or -# have separate smaller files like this. You can also use the generated SDK to seed data as well. -mutation { - demo: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "6c84fb90-12c4-11e1-840d-7b25c5ee775a", - labels: ["important", "work"], - read: false, - starred: false, - muted: false, - }) - launch_blog: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "e0b6e4f6-050c-4846-a3fe-6c6b056f5f63", - labels: ["important", "work"], - read: false, - starred: false, - muted: false, - }) - - sql_experiment_results: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "8eb6df3a-c56f-48bb-b610-a050e050fa65", - labels: ["important"], - read: true, - starred: false, - muted: false, - }) - - ai_model_suggestion: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "a016ef90-9096-4695-9606-66dd6da6166d", - labels: ["work", "follow-up"], - read: false, - starred: true, - muted: false, - }) - - bigquery_anomaly: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "a05069fa-b056-4a61-a561-96da06da96da", - labels: ["urgent", "billing"], - read: false, - starred: true, - muted: false, - }) - - new_dataset: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "6a69df9a-6619-46fa-9a90-90ad6df0a09a", - labels: ["data"], - read: true, - starred: false, - muted: false, - }) - - training_job_complete: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "d0fa6d06-0a05-46af-90ae-fafa6fa005fa", - labels: ["ML", "work"], - read: false, - starred: false, - muted: false, - }) - - feature_request: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "5aa59699-96ae-40af-5ab4-fa6ad0ad6060", - labels: ["tools", "follow-up"], - read: true, - starred: false, - muted: false, - }) - - conference_update: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "0aa6ef66-6fa6-4a16-afa9-a9ad6df9a9ae", - labels: ["work"], - read: false, - starred: true, - muted: false, - }) - - blog_post_draft: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "123abc0a-bc6d-40ae-b0ca-0aa590ab6c90", - labels: ["review"], - read: false, - starred: false, - muted: false, - }) - - internal_tool_bug: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "fa65ab6c-0aa6-45ca-b0fa-0a6d0ad0ae69", - labels: ["bug", "urgent"], - read: false, - starred: false, - muted: false, - }) - - dataset_access_request: emailMeta_insert(data: { - userUid: "user_tyler", - emailId: "4ab6ef69-aa16-4a66-96fa-9aef6ad0fa6d", - labels: ["access"], - read: true, - starred: false, - muted: false, - }) -} diff --git a/dataconnect/nextjs-email-app/dataconnect/Email_insert.gql b/dataconnect/nextjs-email-app/dataconnect/Email_insert.gql deleted file mode 100644 index d99070f7..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/Email_insert.gql +++ /dev/null @@ -1,115 +0,0 @@ -# -# Run the _insert files in this order: -# 1. User_insert.gql -# 2. Email_insert.gql -# 3. Recipient_insert.gql -# 4. EmailMeta_insert.gql -# -# This is one of many ways to run data seeds. You can create one large mutation or -# have separate smaller files like this. You can also use the generated SDK to seed data as well. -mutation { - demo: email_insert(data: { - id: "6c84fb90-12c4-11e1-840d-7b25c5ee775a", - subject: "Demo for FireSQL + Cloud SQL update" # String - date_date: { today: true } # Date - text: "Hey everyone! The demo is on track for the meeting on Monday. Oddly enough, we'll be showcasing an email client." - fromUid: "user_david" - }) - launch_blog: email_insert(data: { - id: "e0b6e4f6-050c-4846-a3fe-6c6b056f5f63", - subject: "RE: Launch Blog", - date_date: { today: true }, - text: "When do you want to start drafting the launch blog? I was thinking it should be focused around the AI capabilities with PGVector, queries, and the type-safe SDKs. Thoughts?" - fromUid: "user_bleigh" - }) - - # Record 1 - sql_experiment_results: email_insert(data: { - id: "8eb6df3a-c56f-48bb-b610-a050e050fa65", - subject: "SQL Optimization Experiment - Interesting Results", - date_date: { today: true }, - text: "Team, I tried tweaking the indexing on the 'user_actions' table, and query performance improved by 20%! Here's the breakdown: [Results]. Thoughts on scaling this change?", - fromUid: "user_tyler" - }) - - # Record 2 - ai_model_suggestion: email_insert(data: { - id: "a016ef90-9096-4695-9606-66dd6da6166d", - subject: "AI Model Idea: Query Intent Prediction", - date_date: { today: true }, - text: "Could we train a model to predict the *intent* of a SQL query? This could help with auto-suggesting optimizations or caching results. Thoughts?", - fromUid: "user_bleigh" - }) - - # Record 3 - bigquery_anomaly: email_insert(data: { - id: "a05069fa-b056-4a61-a561-96da06da96da", - subject: "Urgent: Anomaly Detected in Billing Data", - date_date: { today: true }, - text: "Our cost monitoring model flagged a spike in BigQuery usage. Investigating now, but wanted to raise awareness.", - fromUid: "user_jana" - }) - - # Record 4 - new_dataset: email_insert(data: { - id: "6a69df9a-6619-46fa-9a90-90ad6df0a09a", - subject: "Dataset Release: Customer Sentiment Analysis", - date_date: { today: true }, - text: "The new sentiment analysis dataset (NLP on customer reviews) is ready in BigQuery. Schema details: [Link]. Use cases?", - fromUid: "user_kj" - }) - - # Record 5 - training_job_complete: email_insert(data: { - id: "d0fa6d06-0a05-46af-90ae-fafa6fa005fa", - subject: "Recommendation Model Training Complete", - date_date: { today: true }, - text: "The updated product recommendation model has finished training. Accuracy metrics: [Results]. Should we deploy to the staging environment?", - fromUid: "user_gesly" - }) - - # Record 6 - feature_request: email_insert(data: { - id: "5aa59699-96ae-40af-5ab4-fa6ad0ad6060", - subject: "Feature Request: SQL Query Visualization Tool", - date_date: { today: true }, - text: "It'd be awesome to have a UI tool to visualize the execution plan of SQL queries. Could we add this to the internal tooling roadmap?", - fromUid: "user_kara" - }) - - # Record 7 - conference_update: email_insert(data: { - id: "0aa6ef66-6fa6-4a16-afa9-a9ad6df9a9ae", - subject: "Accepted to Present at DataCloud Conference!", - date_date: { today: true }, - text: "Great news – our talk proposal on hybrid SQL/AI systems was accepted. Let's start working on the slides!", - fromUid: "user_david" - }) - - # Record 8 - blog_post_draft: email_insert(data: { - id: "123abc0a-bc6d-40ae-b0ca-0aa590ab6c90", - subject: "Draft: Blog Post on Federated Learning with SQL", - date_date: { today: true }, - text: "Please review this draft blog post. Focus on whether it's technically accurate and approachable for developers.", - fromUid: "user_pankaj" - }) - - # Record 9 - internal_tool_bug: email_insert(data: { - id: "fa65ab6c-0aa6-45ca-b0fa-0a6d0ad0ae69", - subject: "Bug: User Permissions Dashboard Not Working", - date_date: { today: true }, - text: "Severity: Medium. The dashboard for managing database permissions is throwing errors. Steps to reproduce: [Steps].", - fromUid: "user_seba" - }) - - # Record 10 - dataset_access_request: email_insert(data: { - id: "4ab6ef69-aa16-4a66-96fa-9aef6ad0fa6d", - subject: "Data Access Request - Marketing Team", - date_date: { today: true }, - text: "The marketing team needs access to the 'web_analytics' dataset for a new campaign analysis. Please review and approve.", - fromUid: "user_jeanine" - }) -} diff --git a/dataconnect/nextjs-email-app/dataconnect/Recipient_insert.gql b/dataconnect/nextjs-email-app/dataconnect/Recipient_insert.gql deleted file mode 100644 index 2a5fbb4d..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/Recipient_insert.gql +++ /dev/null @@ -1,167 +0,0 @@ -# -# Run the _insert files in this order: -# 1. User_insert.gql -# 2. Email_insert.gql -# 3. Recipient_insert.gql -# 4. EmailMeta_insert.gql -# -# This is one of many ways to run data seeds. You can create one large mutation or -# have separate smaller files like this. You can also use the generated SDK to seed data as well. -mutation { - tyler: recipient_insert(data: { - emailId: "6c84fb90-12c4-11e1-840d-7b25c5ee775a" # EmailId - userUid: "user_tyler" # UserId - }) - bleigh: recipient_insert(data: { - emailId: "6c84fb90-12c4-11e1-840d-7b25c5ee775a" # EmailId - userUid: "user_bleigh" # UserId - }) - gesly: recipient_insert(data: { - emailId: "6c84fb90-12c4-11e1-840d-7b25c5ee775a" # EmailId - userUid: "user_gesly" # UserId - }) - puf: recipient_insert(data: { - emailId: "6c84fb90-12c4-11e1-840d-7b25c5ee775a" # EmailId - userUid: "user_puf" # UserId - }) - kara: recipient_insert(data: { - emailId: "6c84fb90-12c4-11e1-840d-7b25c5ee775a" # EmailId - userUid: "user_kara" # UserId - }) - blog_tyler: recipient_insert(data: { - emailId: "e0b6e4f6-050c-4846-a3fe-6c6b056f5f63", - userUid: "user_tyler" - }) - # Recipients for 'sql_experiment_results' email - sql_results_tyler: recipient_insert(data: { - emailId: "8eb6df3a-c56f-48bb-b610-a050e050fa65", - userUid: "user_tyler" - }) - sql_results_jana: recipient_insert(data: { - emailId: "8eb6df3a-c56f-48bb-b610-a050e050fa65", - userUid: "user_jana" - }) - - # Recipients for 'ai_model_suggestion' email - ai_model_tyler: recipient_insert(data: { - emailId: "a016ef90-9096-4695-9606-66dd6da6166d", - userUid: "user_tyler" - }) - ai_model_bleigh: recipient_insert(data: { - emailId: "a016ef90-9096-4695-9606-66dd6da6166d", - userUid: "user_bleigh" - }) - ai_model_pankaj: recipient_insert(data: { # Assuming Pankaj is interested in AI - emailId: "a016ef90-9096-4695-9606-66dd6da6166d", - userUid: "user_pankaj" - }) - - # Recipients for 'bigquery_anomaly' email - anomaly_tyler: recipient_insert(data: { - emailId: "a05069fa-b056-4a61-a561-96da06da96da", - userUid: "user_tyler" - }) - anomaly_jana: recipient_insert(data: { - emailId: "a05069fa-b056-4a61-a561-96da06da96da", - userUid: "user_jana" - }) - anomaly_seba: recipient_insert(data: { # Assuming Seba is on a related team - emailId: "a05069fa-b056-4a61-a561-96da06da96da", - userUid: "user_seba" - }) - - # ... Add recipients for other emails based on relevance... - # Recipients for 'new_dataset' email - dataset_tyler: recipient_insert(data: { - emailId: "6a69df9a-6619-46fa-9a90-90ad6df0a09a", - userUid: "user_tyler" - }) - dataset_kj: recipient_insert(data: { # Assuming KJ works with data - emailId: "6a69df9a-6619-46fa-9a90-90ad6df0a09a", - userUid: "user_kj" - }) - dataset_gesly: recipient_insert(data: { # Potentially interested in NLP - emailId: "6a69df9a-6619-46fa-9a90-90ad6df0a09a", - userUid: "user_gesly" - }) - - # Recipients for 'training_job_complete' email - training_tyler: recipient_insert(data: { - emailId: "d0fa6d06-0a05-46af-90ae-fafa6fa005fa", - userUid: "user_tyler" - }) - training_gesly: recipient_insert(data: { - emailId: "d0fa6d06-0a05-46af-90ae-fafa6fa005fa", - userUid: "user_gesly" - }) - training_pankaj: recipient_insert(data: { - emailId: "d0fa6d06-0a05-46af-90ae-fafa6fa005fa", - userUid: "user_pankaj" - }) - - # Recipients for 'feature_request' email - feature_tyler: recipient_insert(data: { - emailId: "5aa59699-96ae-40af-5ab4-fa6ad0ad6060", - userUid: "user_tyler" - }) - feature_kara: recipient_insert(data: { # Likely the owner of tooling - emailId: "5aa59699-96ae-40af-5ab4-fa6ad0ad6060", - userUid: "user_kara" - }) - feature_seba: recipient_insert(data: { # Might be impacted by the feature - emailId: "5aa59699-96ae-40af-5ab4-fa6ad0ad6060", - userUid: "user_seba" - }) - - # Recipients for 'conference_update' email - conference_tyler: recipient_insert(data: { - emailId: "0aa6ef66-6fa6-4a16-afa9-a9ad6df9a9ae", - userUid: "user_tyler" - }) - conference_david: recipient_insert(data: { # David submitted the proposal - emailId: "0aa6ef66-6fa6-4a16-afa9-a9ad6df9a9ae", - userUid: "user_david" - }) - - # Recipients for 'blog_post_draft' email - blog_draft_tyler: recipient_insert(data: { - emailId: "123abc0a-bc6d-40ae-b0ca-0aa590ab6c90", - userUid: "user_tyler" - }) - blog_draft_pankaj: recipient_insert(data: { # Pankaj authored the post - emailId: "123abc0a-bc6d-40ae-b0ca-0aa590ab6c90", - userUid: "user_pankaj" - }) - blog_draft_sujatha: recipient_insert(data: { # Assuming Sujatha is a tech editor - emailId: "123abc0a-bc6d-40ae-b0ca-0aa590ab6c90", - userUid: "user_sujatha" - }) - - # Recipients for 'internal_tool_bug' email - bug_tyler: recipient_insert(data: { - emailId: "fa65ab6c-0aa6-45ca-b0fa-0a6d0ad0ae69", - userUid: "user_tyler" - }) - bug_seba: recipient_insert(data: { # Seba reported the bug - emailId: "fa65ab6c-0aa6-45ca-b0fa-0a6d0ad0ae69", - userUid: "user_seba" - }) - bug_kara: recipient_insert(data: { # Kara likely owns the tool - emailId: "fa65ab6c-0aa6-45ca-b0fa-0a6d0ad0ae69", - userUid: "user_kara" - }) - - # Recipients for 'dataset_access_request' email - access_tyler: recipient_insert(data: { - emailId: "4ab6ef69-aa16-4a66-96fa-9aef6ad0fa6d", - userUid: "user_tyler" - }) - access_jeanine: recipient_insert(data: { # Jeanine requested access - emailId: "4ab6ef69-aa16-4a66-96fa-9aef6ad0fa6d", - userUid: "user_jeanine" - }) - access_jana: recipient_insert(data: { # Assuming Jana manages data access - emailId: "4ab6ef69-aa16-4a66-96fa-9aef6ad0fa6d", - userUid: "user_jana" - }) -} diff --git a/dataconnect/nextjs-email-app/dataconnect/User_insert.gql b/dataconnect/nextjs-email-app/dataconnect/User_insert.gql deleted file mode 100644 index 0beecc3d..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/User_insert.gql +++ /dev/null @@ -1,76 +0,0 @@ -# -# Run the _insert files in this order: -# 1. User_insert.gql -# 2. Email_insert.gql -# 3. Recipient_insert.gql -# 4. EmailMeta_insert.gql -# -# This is one of many ways to run data seeds. You can create one large mutation or -# have separate smaller files like this. You can also use the generated SDK to seed data as well. -mutation { - david: user_insert(data: { - uid: "user_david", - name: "David Smith", - address: "dsmith123@example.com" - }) - jeanine: user_insert(data: { - uid: "user_jeanine", - name: "Jeanine Johnson", - address: "jejohnson@example.com" - }) - tyler: user_insert(data: { - uid: "user_tyler", - name: "Tyler Williams", - address: "twilliams72@example.com" - }) - bleigh: user_insert(data: { - uid: "user_bleigh", - name: "Michael Brown", - address: "mbrown.work@example.com" - }) - kara: user_insert(data: { - uid: "user_kara", - name: "Kara Lee", - address: "karalee.info@example.com" - }) - jana: user_insert(data: { - uid: "user_jana", - name: "Jana Rodriguez", - address: "jrodriguez2023@example.com" - }) - seba: user_insert(data: { - uid: "user_seba", - name: "Seba Martin", - address: "smartin.dev@example.com" - }) - puf: user_insert(data: { - uid: "user_puf", - name: "Frank Miller", - address: "frank.miller@example.com" - }) - pankaj: user_insert(data: { - uid: "user_pankaj", - name: "Pankaj Davis", - address: "pdavis.work1@example.com" - }) - gesly: user_insert(data: { - uid: "user_gesly", - name: "Gesly Anderson", - address: "gesly.anderson20@example.com" - }) - kj: user_insert(data: { - uid: "user_kj", - name: "KJ Jackson", - address: "kylejackson@example.com" - }) - malcom: user_insert(data: { - uid: "user_malcom", - name: "Malcolm Thomas", - address: "malcolmthomas44@example.com" - }) - sujatha: user_insert(data: { - uid: "user_sujatha", - name: "Sujatha Garcia", - address: "sgarcia22@example.com" - }) -} \ No newline at end of file diff --git a/dataconnect/nextjs-email-app/dataconnect/connector/connector.yaml b/dataconnect/nextjs-email-app/dataconnect/connector/connector.yaml deleted file mode 100644 index 9446466d..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/connector/connector.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Required. The connector name of the Firebase Data Connect connector resource. -connectorId: email -# Required. Accepted values are either "PUBLIC" or "ADMIN" (only "PUBLIC" for gated private -# preview). If "ADMIN", the connector in this directory is an AdminConnector and its operations -# are gated by IAM. -authMode: PUBLIC -generate: - javascriptSdk: - # Create a custom package name for your generated SDK - package: "@email-app/email" - # Tells Data Connect where to store the generated SDK code, this should be in the same - # directory as your app code - outputDir: "../../webapp/email-generated" - # This property tells Data Connect what directory to install the generated SDK to - # packageJsonDir: "../../webapp" diff --git a/dataconnect/nextjs-email-app/dataconnect/connector/mutations.gql b/dataconnect/nextjs-email-app/dataconnect/connector/mutations.gql deleted file mode 100644 index 13d68137..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/connector/mutations.gql +++ /dev/null @@ -1,27 +0,0 @@ -mutation CreateUser($uid: String, $name: String, $address: String) @auth(level: NO_ACCESS) { - user_insert(data: { - uid: $uid, - name: $name, - address: $address - }) -} - -mutation CreateEmail($content: String, $subject: String, $fromUid: String) @auth(level: PUBLIC) { - email_insert(data: { - text: $content, - subject: $subject, - fromUid: $fromUid, - date_date: { today: true } - }) -} - -mutation CreateRecipient($emailId: UUID, $uid: String) @auth(level: PUBLIC) { - recipient_insert(data: { - emailId: $emailId, - userUid: $uid - }) -} - -mutation DeleteEmail($emailId: UUID, $uid: String) @auth(level: PUBLIC) { - recipient_delete(key: {emailId: $emailId, userUid: $uid}) -} diff --git a/dataconnect/nextjs-email-app/dataconnect/connector/queries.gql b/dataconnect/nextjs-email-app/dataconnect/connector/queries.gql deleted file mode 100644 index 06572ac2..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/connector/queries.gql +++ /dev/null @@ -1,64 +0,0 @@ -query ListUsers @auth(level: NO_ACCESS) { - users { uid, name, email: address } -} - -query GetUidByEmail($emails: [String!]) @auth(level: PUBLIC) { - users(where: { address: { in: $emails } }, limit: 4, orderBy: { name: ASC }) { - uid email: address - } -} - -query SearchEmail( - $query: String, - $uid: String -) @auth(level: PUBLIC) { - emails(where: { - text: { contains: $query }, - users_via_Recipient: { - exist: { uid: { eq: $uid } - }} - }) { - id subject date - content: text - sender: from { name email: address uid } - to: recipients_on_email { - user { name email: address uid } - } - } -} - -query ListInbox( - $uid: String -) @auth(level: PUBLIC) { - emails(where: { - users_via_Recipient: { - exist: { uid: { eq: $uid } - }} - }) { - id subject date - content: text - sender: from { name email: address uid } - to: recipients_on_email { - user { name email: address uid } - } - } -} - -query ListSent( - $uid: String -) @auth(level: PUBLIC) { - emails(where: { - fromUid: { eq: $uid } - }) { - id subject date - content: text - sender: from { name email: address uid } - to: recipients_on_email { - user { name email: address uid } - } - } -} - -query GetStats @auth(level: PUBLIC) { - emailStats { count } -} diff --git a/dataconnect/nextjs-email-app/dataconnect/dataconnect.yaml b/dataconnect/nextjs-email-app/dataconnect/dataconnect.yaml deleted file mode 100644 index 5b95a666..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/dataconnect.yaml +++ /dev/null @@ -1,11 +0,0 @@ -specVersion: "v1alpha" -serviceId: "local" -location: "us-central1" -schema: - source: "./schema" - datasource: - postgresql: - database: "dataconnect" - cloudSql: - instanceId: "my-instance" -connectorDirs: ["./connector"] \ No newline at end of file diff --git a/dataconnect/nextjs-email-app/dataconnect/schema/schema.gql b/dataconnect/nextjs-email-app/dataconnect/schema/schema.gql deleted file mode 100644 index afa3f241..00000000 --- a/dataconnect/nextjs-email-app/dataconnect/schema/schema.gql +++ /dev/null @@ -1,35 +0,0 @@ -type User @table(key: "uid") { - uid: String! - name: String! - address: String! -} - -type Email @table { - subject: String! - date: Date! - text: String! - from: User! -} - -type Recipient @table(key: ["email", "user"]) { - email: Email! - user: User! -} - -type EmailMeta @table(key: ["user", "email"]) { - user: User! - email: Email! - labels: [String] - read: Boolean! - starred: Boolean! - muted: Boolean! - snoozed: Date -} - -type EmailStat @view(sql: """ - SELECT - COUNT(*) AS count - FROM email - """) { - count: Int -} diff --git a/dataconnect/nextjs-email-app/webapp/.eslintrc.json b/dataconnect/nextjs-email-app/webapp/.eslintrc.json deleted file mode 100644 index bffb357a..00000000 --- a/dataconnect/nextjs-email-app/webapp/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "next/core-web-vitals" -} diff --git a/dataconnect/nextjs-email-app/webapp/.gitignore b/dataconnect/nextjs-email-app/webapp/.gitignore deleted file mode 100644 index fd3dbb57..00000000 --- a/dataconnect/nextjs-email-app/webapp/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts diff --git a/dataconnect/nextjs-email-app/webapp/README.md b/dataconnect/nextjs-email-app/webapp/README.md deleted file mode 100644 index c4033664..00000000 --- a/dataconnect/nextjs-email-app/webapp/README.md +++ /dev/null @@ -1,36 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/dataconnect/nextjs-email-app/webapp/next.config.mjs b/dataconnect/nextjs-email-app/webapp/next.config.mjs deleted file mode 100644 index fe898d84..00000000 --- a/dataconnect/nextjs-email-app/webapp/next.config.mjs +++ /dev/null @@ -1,11 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - rewrites: async () => [ - { - source: '/v1alpha/projects/:path*', - destination: 'http://127.0.0.1:9399/v1alpha/projects/:path*' - }, - ], -}; - -export default nextConfig; diff --git a/dataconnect/nextjs-email-app/webapp/package-lock.json b/dataconnect/nextjs-email-app/webapp/package-lock.json deleted file mode 100644 index 1e72a4ce..00000000 --- a/dataconnect/nextjs-email-app/webapp/package-lock.json +++ /dev/null @@ -1,6435 +0,0 @@ -{ - "name": "firebase-email-app", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "firebase-email-app", - "version": "0.1.0", - "dependencies": { - "@email-app/email": "file:email-generated", - "firebase": "^10.14.0", - "next": "14.1.3", - "react": "^18", - "react-dom": "^18" - }, - "devDependencies": { - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "autoprefixer": "^10.0.1", - "eslint": "^8", - "eslint-config-next": "14.1.3", - "postcss": "^8", - "postcss-import": "^16.1.0", - "postcss-nesting": "^12.1.0", - "tailwindcss": "^3.3.0", - "typescript": "^5" - } - }, - "email-generated": {}, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@csstools/selector-resolve-nested": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-1.1.0.tgz", - "integrity": "sha512-uWvSaeRcHyeNenKg8tp17EVDRkpflmdyvbE0DHo6D/GdBb6PDnCYYU6gRpXhtICMGMcahQmj2zGxwFM/WC8hCg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.13" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", - "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.13" - } - }, - "node_modules/@email-app/email": { - "resolved": "email-generated", - "link": true - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@firebase/analytics": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.7.tgz", - "integrity": "sha512-GE29uTT6y/Jv2EP0OjpTezeTQZ5FTCTaZXKrrdVGjb/t35AU4u/jiU+hUwUPpuK8fqhhiHkS/AawE3a3ZK/a9Q==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/analytics-compat": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.13.tgz", - "integrity": "sha512-aZ4wGfNDMsCxhKzDbK2g1aV0JKsdQ9FbeIsjpNJPzhahV0XYj+z36Y4RNLPpG/6hHU4gxnezxs+yn3HhHkNL8w==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/analytics": "0.10.7", - "@firebase/analytics-types": "0.8.2", - "@firebase/component": "0.6.8", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/analytics-types": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.2.tgz", - "integrity": "sha512-EnzNNLh+9/sJsimsA/FGqzakmrAUKLeJvjRHlg8df1f97NLUlFidk9600y0ZgWOp3CAxn6Hjtk+08tixlUOWyw==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app": { - "version": "0.10.10", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.10.tgz", - "integrity": "sha512-sDqkdeFdVn5uygQm5EuIKOQ6/wxTcX/qKfm0MR46AiwLRHGLCDUMrXBkc8GhkK3ca2d6mPUSfPmndggo43D6PQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "idb": "7.1.1", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/app-check": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.7.tgz", - "integrity": "sha512-EkOeJcMKVR0zZ6z/jqcFTqHb/xq+TVIRIuBNGHdpcIuFU1czhSlegvqv2+nC+nFrkD8M6Xvd3tAlUOkdbMeS6A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/app-check-compat": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.14.tgz", - "integrity": "sha512-kK3bPfojAfXE53W+20rxMqIxrloFswXG9vh4kEdYL6Wa2IB3sD5++2dPiK3yGxl8oQiqS8qL2wcKB5/xLpEVEg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check": "0.8.7", - "@firebase/app-check-types": "0.5.2", - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/app-check-interop-types": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz", - "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app-check-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.2.tgz", - "integrity": "sha512-FSOEzTzL5bLUbD2co3Zut46iyPWML6xc4x+78TeaXMSuJap5QObfb+rVvZJtla3asN4RwU7elaQaduP+HFizDA==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/app-compat": { - "version": "0.2.40", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.40.tgz", - "integrity": "sha512-2L5MW4MH2ya7Wvw0hzWy3ZWeB4SqC5gYXDAV5AS1lBTL4zL3k8dsqJmry/cFV00GgkCI01WJbcXvFMCXJvgyow==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app": "0.10.10", - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/app-types": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", - "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/auth": { - "version": "1.7.8", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.7.8.tgz", - "integrity": "sha512-1KJlDrTrEEFTIBj9MxjAWjQ4skecBD4bmoayQ0l14QDbNc1a8qGbi+MFSJkH7O6VnGE6bTMcWSw6RrQNecqKaw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0", - "undici": "6.19.7" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@react-native-async-storage/async-storage": "^1.18.1" - }, - "peerDependenciesMeta": { - "@react-native-async-storage/async-storage": { - "optional": true - } - } - }, - "node_modules/@firebase/auth-compat": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.13.tgz", - "integrity": "sha512-rV6TMxUU6wBBZ2ouDMtjJsJXeewtvYvVzslzt3/P7O/kxiWlreHT/2M/1guMiXKo3zk52XK3GqP0uM2bN7fEow==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/auth": "1.7.8", - "@firebase/auth-types": "0.12.2", - "@firebase/component": "0.6.8", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0", - "undici": "6.19.7" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/auth-interop-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", - "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/auth-types": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", - "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/component": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.8.tgz", - "integrity": "sha512-LcNvxGLLGjBwB0dJUsBGCej2fqAepWyBubs4jt1Tiuns7QLbXHuyObZ4aMeBjZjWx4m8g1LoVI9QFpSaq/k4/g==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.7.tgz", - "integrity": "sha512-wjXr5AO8RPxVVg7rRCYffT7FMtBjHRfJ9KMwi19MbOf0vBf0H9YqW3WCgcnLpXI6ehiUcU3z3qgPnnU0nK6SnA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database-compat": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.7.tgz", - "integrity": "sha512-R/3B+VVzEFN5YcHmfWns3eitA8fHLTL03io+FIoMcTYkajFnrBdS3A+g/KceN9omP7FYYYGTQWF9lvbEx6eMEg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/database": "1.0.7", - "@firebase/database-types": "1.0.4", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database-types": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.4.tgz", - "integrity": "sha512-mz9ZzbH6euFXbcBo+enuJ36I5dR5w+enJHHjy9Y5ThCdKUseqfDjW3vCp1YxE9zygFCSjJJ/z1cQ+zodvUcwPQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-types": "0.9.2", - "@firebase/util": "1.9.7" - } - }, - "node_modules/@firebase/firestore": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.1.tgz", - "integrity": "sha512-WliQNa8GVcH6EWkH0NAf+uAnxNiBuH+G8Buzr2ZS1NznOhJDK/q6Hsjv5TzNrijLTAdEfj/wk9VEv994KDSjxg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "@firebase/webchannel-wrapper": "1.0.1", - "@grpc/grpc-js": "~1.9.0", - "@grpc/proto-loader": "^0.7.8", - "tslib": "^2.1.0", - "undici": "6.19.7" - }, - "engines": { - "node": ">=10.10.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/firestore-compat": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.36.tgz", - "integrity": "sha512-NtoIm7CT9f+SFB7cPMCtyCSxZReh/+SII5X4TQH394S3dwhru9HIfvEOKAMuAnXsSsLH72jXPUgdsEAUqg6Oug==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/firestore": "4.7.1", - "@firebase/firestore-types": "3.0.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/firestore-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.2.tgz", - "integrity": "sha512-wp1A+t5rI2Qc/2q7r2ZpjUXkRVPtGMd6zCLsiWurjsQpqPgFin3AhNibKcIzoF2rnToNa/XYtyWXuifjOOwDgg==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/functions": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.7.tgz", - "integrity": "sha512-xaUsGI2kYrI8zJXgrNB7SrJKB8v1vJqR16YYi6g6dFTgBz4+VzWJFqqVU60BbdAWm6fXnUrg9gjlJQeqomT2Vg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.8", - "@firebase/messaging-interop-types": "0.2.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0", - "undici": "6.19.7" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/functions-compat": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.13.tgz", - "integrity": "sha512-qcZvJO2ed6PAD+18DanVztw7WyQVQK43HoRhxusHAwDFvK/xY+mcGpj+IpfdxTNMBGCOIxKFp4Xqk/c2nubBlQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/functions": "0.11.7", - "@firebase/functions-types": "0.6.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/functions-types": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.2.tgz", - "integrity": "sha512-0KiJ9lZ28nS2iJJvimpY4nNccV21rkQyor5Iheu/nq8aKXJqtJdeSlZDspjPSBBiHRzo7/GMUttegnsEITqR+w==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/installations": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.8.tgz", - "integrity": "sha512-57V374qdb2+wT5v7+ntpLXBjZkO6WRgmAUbVkRfFTM/4t980p0FesbqTAcOIiM8U866UeuuuF8lYH70D3jM/jQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/util": "1.9.7", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/installations-compat": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.8.tgz", - "integrity": "sha512-pI2q8JFHB7yIq/szmhzGSWXtOvtzl6tCUmyykv5C8vvfOVJUH6mP4M4iwjbK8S1JotKd/K70+JWyYlxgQ0Kpyw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", - "@firebase/installations-types": "0.5.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/installations-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.2.tgz", - "integrity": "sha512-que84TqGRZJpJKHBlF2pkvc1YcXrtEDOVGiDjovP/a3s6W4nlbohGXEsBJo0JCeeg/UG9A+DEZVDUV9GpklUzA==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x" - } - }, - "node_modules/@firebase/logger": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", - "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/messaging": { - "version": "0.12.10", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.10.tgz", - "integrity": "sha512-fGbxJPKpl2DIKNJGhbk4mYPcM+qE2gl91r6xPoiol/mN88F5Ym6UeRdMVZah+pijh9WxM55alTYwXuW40r1Y2Q==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", - "@firebase/messaging-interop-types": "0.2.2", - "@firebase/util": "1.9.7", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/messaging-compat": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.10.tgz", - "integrity": "sha512-FXQm7rcowkDm8kFLduHV35IRYCRo+Ng0PIp/t1+EBuEbyplaKkGjZ932pE+owf/XR+G/60ku2QRBptRGLXZydg==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/messaging": "0.12.10", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/messaging-interop-types": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.2.tgz", - "integrity": "sha512-l68HXbuD2PPzDUOFb3aG+nZj5KA3INcPwlocwLZOzPp9rFM9yeuI9YLl6DQfguTX5eAGxO0doTR+rDLDvQb5tA==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/performance": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.8.tgz", - "integrity": "sha512-F+alziiIZ6Yn8FG47mxwljq+4XkgkT2uJIFRlkyViUQRLzrogaUJW6u/+6ZrePXnouKlKIwzqos3PVJraPEcCA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/performance-compat": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.8.tgz", - "integrity": "sha512-o7TFClRVJd3VIBoY7KZQqtCeW0PC6v9uBzM6Lfw3Nc9D7hM6OonqecYvh7NwJ6R14k+xM27frLS4BcCvFHKw2A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/performance": "0.6.8", - "@firebase/performance-types": "0.2.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/performance-types": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.2.tgz", - "integrity": "sha512-gVq0/lAClVH5STrIdKnHnCo2UcPLjJlDUoEB/tB4KM+hAeHUxWKnpT0nemUPvxZ5nbdY/pybeyMe8Cs29gEcHA==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/remote-config": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.8.tgz", - "integrity": "sha512-AMLqe6wfIRnjc6FkCWOSUjhc1fSTEf8o+cv1NolFvbiJ/tU+TqN4pI7pT+MIKQzNiq5fxLehkOx+xtAQBxPJKQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/installations": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/remote-config-compat": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.8.tgz", - "integrity": "sha512-UxSFOp6dzFj2AHB8Bq/BYtbq5iFyizKx4Rd6WxAdaKYM8cnPMeK+l2v+Oogtjae+AeyHRI+MfL2acsfVe5cd2A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/remote-config": "0.4.8", - "@firebase/remote-config-types": "0.3.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/remote-config-types": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.2.tgz", - "integrity": "sha512-0BC4+Ud7y2aPTyhXJTMTFfrGGLqdYXrUB9sJVAB8NiqJswDTc4/2qrE/yfUbnQJhbSi6ZaTTBKyG3n1nplssaA==", - "license": "Apache-2.0" - }, - "node_modules/@firebase/storage": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.1.tgz", - "integrity": "sha512-L6AJ5tWgHSi2g/gbc/2Pbm3qxmoEg9THmPIOpRsLwuz9LPeWbhyMQeGlqxWqtZGQO/z/LMjGYadNlupQj0HNfw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0", - "undici": "6.19.7" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/storage-compat": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.11.tgz", - "integrity": "sha512-EEa9jgm/aRVIGSD0ByYAsZ0tvEKfVwSp9uFoa/97BISGWGjSNPIWjenaDvpDZ7aL8OxaGIpwuk700aHy7/T0Ug==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.8", - "@firebase/storage": "0.13.1", - "@firebase/storage-types": "0.8.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/storage-types": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.2.tgz", - "integrity": "sha512-0vWu99rdey0g53lA7IShoA2Lol1jfnPovzLDUBuon65K7uKG9G+L5uO05brD9pMw+l4HRFw23ah3GwTGpEav6g==", - "license": "Apache-2.0", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/util": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.7.tgz", - "integrity": "sha512-fBVNH/8bRbYjqlbIhZ+lBtdAAS4WqZumx03K06/u7fJSpz1TGjEMm1ImvKD47w+xaFKIP2ori6z8BrbakRfjJA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/vertexai-preview": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@firebase/vertexai-preview/-/vertexai-preview-0.0.3.tgz", - "integrity": "sha512-KVtUWLp+ScgiwkDKAvNkVucAyhLVQp6C6lhnVEuIg4mWhWcS3oerjAeVhZT4uNofKwWxRsOaB2Yec7DMTXlQPQ==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/component": "0.6.8", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@firebase/app-types": "0.x" - } - }, - "node_modules/@firebase/webchannel-wrapper": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.1.tgz", - "integrity": "sha512-jmEnr/pk0yVkA7mIlHNnxCi+wWzOFUg0WyIotgkKAb2u1J7fAeDBcVNSTjTihbAYNusCLQdW5s9IJ5qwnEufcQ==", - "license": "Apache-2.0" - }, - "node_modules/@grpc/grpc-js": { - "version": "1.9.15", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", - "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", - "license": "Apache-2.0", - "dependencies": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@next/env": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.3.tgz", - "integrity": "sha512-VhgXTvrgeBRxNPjyfBsDIMvgsKDxjlpw4IAUsHCX8Gjl1vtHUYRT3+xfQ/wwvLPDd/6kqfLqk9Pt4+7gysuCKQ==", - "license": "MIT" - }, - "node_modules/@next/eslint-plugin-next": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.3.tgz", - "integrity": "sha512-VCnZI2cy77Yaj3L7Uhs3+44ikMM1VD/fBMwvTBb3hIaTIuqa+DmG4dhUDq+MASu3yx97KhgsVJbsas0XuiKyww==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "10.3.10" - } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.3.tgz", - "integrity": "sha512-LALu0yIBPRiG9ANrD5ncB3pjpO0Gli9ZLhxdOu6ZUNf3x1r3ea1rd9Q+4xxUkGrUXLqKVK9/lDkpYIJaCJ6AHQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.3.tgz", - "integrity": "sha512-E/9WQeXxkqw2dfcn5UcjApFgUq73jqNKaE5bysDm58hEUdUGedVrnRhblhJM7HbCZNhtVl0j+6TXsK0PuzXTCg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.3.tgz", - "integrity": "sha512-USArX9B+3rZSXYLFvgy0NVWQgqh6LHWDmMt38O4lmiJNQcwazeI6xRvSsliDLKt+78KChVacNiwvOMbl6g6BBw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.3.tgz", - "integrity": "sha512-esk1RkRBLSIEp1qaQXv1+s6ZdYzuVCnDAZySpa62iFTMGTisCyNQmqyCTL9P+cLJ4N9FKCI3ojtSfsyPHJDQNw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.3.tgz", - "integrity": "sha512-8uOgRlYEYiKo0L8YGeS+3TudHVDWDjPVDUcST+z+dUzgBbTEwSSIaSgF/vkcC1T/iwl4QX9iuUyUdQEl0Kxalg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.3.tgz", - "integrity": "sha512-DX2zqz05ziElLoxskgHasaJBREC5Y9TJcbR2LYqu4r7naff25B4iXkfXWfcp69uD75/0URmmoSgT8JclJtrBoQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.3.tgz", - "integrity": "sha512-HjssFsCdsD4GHstXSQxsi2l70F/5FsRTRQp8xNgmQs15SxUfUJRvSI9qKny/jLkY3gLgiCR3+6A7wzzK0DBlfA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.3.tgz", - "integrity": "sha512-DRuxD5axfDM1/Ue4VahwSxl1O5rn61hX8/sF0HY8y0iCbpqdxw3rB3QasdHn/LJ6Wb2y5DoWzXcz3L1Cr+Thrw==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.3.tgz", - "integrity": "sha512-uC2DaDoWH7h1P/aJ4Fok3Xiw6P0Lo4ez7NbowW2VGNXw/Xv6tOuLUcxhBYZxsSUJtpeknCi8/fvnSpyCFp4Rcg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause" - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", - "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@swc/helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", - "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.16.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", - "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "18.3.7", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.7.tgz", - "integrity": "sha512-KUnDCJF5+AiZd8owLIeVHqmW9yM4sqmDVf2JRJiBMFkGvkoZ4/WyV2lL4zVsoinmRS/W3FeEdZLEWFRofnT2FQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", - "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", - "dev": true, - "license": "MPL-2.0", - "engines": { - "node": ">=4" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001660", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz", - "integrity": "sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, - "license": "MIT" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, - "license": "MIT" - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.25", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.25.tgz", - "integrity": "sha512-kMb204zvK3PsSlgvvwzI3wBIcAw15tRkYk+NQdsjdDtcQWTp2RABbMQ9rUBy8KNEOM+/E6ep+XC3AykiWZld4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-next": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.3.tgz", - "integrity": "sha512-sUCpWlGuHpEhI0pIT0UtdSLJk5Z8E2DYinPTwsBiWaSYQomchdl0i60pjynY48+oXvtyWMQ7oE+G3m49yrfacg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@next/eslint-plugin-next": "14.1.3", - "@rushstack/eslint-patch": "^1.3.3", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" - }, - "peerDependencies": { - "eslint": "^7.23.0 || ^8.0.0", - "typescript": ">=3.3.1" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz", - "integrity": "sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.3.5", - "enhanced-resolve": "^5.15.0", - "eslint-module-utils": "^2.8.1", - "fast-glob": "^3.3.2", - "get-tsconfig": "^4.7.5", - "is-bun-module": "^1.0.2", - "is-glob": "^4.0.3" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz", - "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", - "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.9.0", - "hasown": "^2.0.2", - "is-core-module": "^2.15.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.0", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", - "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "aria-query": "~5.1.3", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.10.0", - "axobject-query": "^4.1.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.19", - "hasown": "^2.0.2", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.0" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.36.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz", - "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.19", - "estraverse": "^5.3.0", - "hasown": "^2.0.2", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.8", - "object.fromentries": "^2.0.8", - "object.values": "^1.2.0", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11", - "string.prototype.repeat": "^1.0.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/firebase": { - "version": "10.13.1", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-10.13.1.tgz", - "integrity": "sha512-L5BSkmvB2dzCUMpr8i/O8WMJC3Nqj5Ld8Wj/qnak+tz2Ga+JH6/FO93xArg9IGhktCrPXVODoWp6t9ybdgmXCA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/analytics": "0.10.7", - "@firebase/analytics-compat": "0.2.13", - "@firebase/app": "0.10.10", - "@firebase/app-check": "0.8.7", - "@firebase/app-check-compat": "0.3.14", - "@firebase/app-compat": "0.2.40", - "@firebase/app-types": "0.9.2", - "@firebase/auth": "1.7.8", - "@firebase/auth-compat": "0.5.13", - "@firebase/database": "1.0.7", - "@firebase/database-compat": "1.0.7", - "@firebase/firestore": "4.7.1", - "@firebase/firestore-compat": "0.3.36", - "@firebase/functions": "0.11.7", - "@firebase/functions-compat": "0.3.13", - "@firebase/installations": "0.6.8", - "@firebase/installations-compat": "0.2.8", - "@firebase/messaging": "0.12.10", - "@firebase/messaging-compat": "0.2.10", - "@firebase/performance": "0.6.8", - "@firebase/performance-compat": "0.2.8", - "@firebase/remote-config": "0.4.8", - "@firebase/remote-config-compat": "0.2.8", - "@firebase/storage": "0.13.1", - "@firebase/storage-compat": "0.3.11", - "@firebase/util": "1.9.7", - "@firebase/vertexai-preview": "0.0.3" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", - "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "license": "MIT" - }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", - "license": "ISC" - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bun-module": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.2.1.tgz", - "integrity": "sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.6.3" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" - } - }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dev": true, - "license": "MIT", - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "license": "Apache-2.0" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/next": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.3.tgz", - "integrity": "sha512-oexgMV2MapI0UIWiXKkixF8J8ORxpy64OuJ/J9oVUmIthXOUCcuVEZX+dtpgq7wIfIqtBwQsKEDXejcjTsan9g==", - "license": "MIT", - "dependencies": { - "@next/env": "14.1.3", - "@swc/helpers": "0.5.2", - "busboy": "1.6.0", - "caniuse-lite": "^1.0.30001579", - "graceful-fs": "^4.2.11", - "postcss": "8.4.31", - "styled-jsx": "5.1.1" - }, - "bin": { - "next": "dist/bin/next" - }, - "engines": { - "node": ">=18.17.0" - }, - "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.3", - "@next/swc-darwin-x64": "14.1.3", - "@next/swc-linux-arm64-gnu": "14.1.3", - "@next/swc-linux-arm64-musl": "14.1.3", - "@next/swc-linux-x64-gnu": "14.1.3", - "@next/swc-linux-x64-musl": "14.1.3", - "@next/swc-win32-arm64-msvc": "14.1.3", - "@next/swc-win32-ia32-msvc": "14.1.3", - "@next/swc-win32-x64-msvc": "14.1.3" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-import": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-16.1.0.tgz", - "integrity": "sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-nesting": { - "version": "12.1.5", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-12.1.5.tgz", - "integrity": "sha512-N1NgI1PDCiAGWPTYrwqm8wpjv0bgDmkYHH72pNsqTCv9CObxjxftdYu6AKtGN+pnJa7FQjMm3v4sp8QJbFsYdQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-resolve-nested": "^1.1.0", - "@csstools/selector-specificity": "^3.1.1", - "postcss-selector-parser": "^6.1.0" - }, - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/protobufjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/string.prototype.includes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "regexp.prototype.flags": "^1.5.2", - "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.repeat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/styled-jsx": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", - "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", - "license": "MIT", - "dependencies": { - "client-only": "0.0.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tailwindcss": { - "version": "3.4.12", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.12.tgz", - "integrity": "sha512-Htf/gHj2+soPb9UayUNci/Ja3d8pTmu9ONTfh4QY8r3MATTZOzmv6UYWF7ZwikEIC8okpfqmGqrmDehua8mF8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz", - "integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==", - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", - "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", - "dev": true, - "license": "MIT", - "dependencies": { - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.0.5", - "is-finalizationregistry": "^1.0.2", - "is-generator-function": "^1.0.10", - "is-regex": "^1.1.4", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/dataconnect/nextjs-email-app/webapp/package.json b/dataconnect/nextjs-email-app/webapp/package.json deleted file mode 100644 index 8d26507f..00000000 --- a/dataconnect/nextjs-email-app/webapp/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "firebase-email-app", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@email-app/email": "file:email-generated", - "firebase": "^10.14.0", - "next": "14.1.3", - "react": "^18", - "react-dom": "^18" - }, - "devDependencies": { - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "autoprefixer": "^10.0.1", - "eslint": "^8", - "eslint-config-next": "14.1.3", - "postcss": "^8", - "postcss-import": "^16.1.0", - "postcss-nesting": "^12.1.0", - "tailwindcss": "^3.3.0", - "typescript": "^5" - } -} diff --git a/dataconnect/nextjs-email-app/webapp/postcss.config.js b/dataconnect/nextjs-email-app/webapp/postcss.config.js deleted file mode 100644 index fe09c11d..00000000 --- a/dataconnect/nextjs-email-app/webapp/postcss.config.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - plugins: { - "postcss-import": {}, - "tailwindcss/nesting": "postcss-nesting", - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/dataconnect/nextjs-email-app/webapp/public/close.svg b/dataconnect/nextjs-email-app/webapp/public/close.svg deleted file mode 100644 index 5a60c58e..00000000 --- a/dataconnect/nextjs-email-app/webapp/public/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/dataconnect/nextjs-email-app/webapp/public/extension.png b/dataconnect/nextjs-email-app/webapp/public/extension.png deleted file mode 100644 index 54f79a89..00000000 Binary files a/dataconnect/nextjs-email-app/webapp/public/extension.png and /dev/null differ diff --git a/dataconnect/nextjs-email-app/webapp/public/insert-scripts.png b/dataconnect/nextjs-email-app/webapp/public/insert-scripts.png deleted file mode 100644 index 9330faa4..00000000 Binary files a/dataconnect/nextjs-email-app/webapp/public/insert-scripts.png and /dev/null differ diff --git a/dataconnect/nextjs-email-app/webapp/public/mutation-testing.png b/dataconnect/nextjs-email-app/webapp/public/mutation-testing.png deleted file mode 100644 index 25de4f18..00000000 Binary files a/dataconnect/nextjs-email-app/webapp/public/mutation-testing.png and /dev/null differ diff --git a/dataconnect/nextjs-email-app/webapp/public/next.svg b/dataconnect/nextjs-email-app/webapp/public/next.svg deleted file mode 100644 index 5174b28c..00000000 --- a/dataconnect/nextjs-email-app/webapp/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/dataconnect/nextjs-email-app/webapp/public/psql.png b/dataconnect/nextjs-email-app/webapp/public/psql.png deleted file mode 100644 index 1bac92a7..00000000 Binary files a/dataconnect/nextjs-email-app/webapp/public/psql.png and /dev/null differ diff --git a/dataconnect/nextjs-email-app/webapp/public/send.svg b/dataconnect/nextjs-email-app/webapp/public/send.svg deleted file mode 100644 index 75e72995..00000000 --- a/dataconnect/nextjs-email-app/webapp/public/send.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/dataconnect/nextjs-email-app/webapp/src/app/ComposeModal.client.tsx b/dataconnect/nextjs-email-app/webapp/src/app/ComposeModal.client.tsx deleted file mode 100644 index 49ad7981..00000000 --- a/dataconnect/nextjs-email-app/webapp/src/app/ComposeModal.client.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import React, { useEffect, useRef, useState } from 'react'; -import Image from "next/image"; -import useOutsideClick from './hooks/useOutsideClick'; -import { createRecipient, createEmail, getUidByEmail } from "@email-app/email"; -import type { DataConnect } from 'firebase/data-connect'; - -interface Props { - isOpen: boolean; - onClose: () => void; - uid: string; - dc: DataConnect; -} - -const ComposeModal = ({isOpen, onClose, uid, dc}: Props) => { - const [renderModal, setRenderModal] = useState(isOpen); - const [openModal, setOpenModal] = useState(false); - const [animateUp, setAnimateUp] = useState(false); - const modalRef = useRef(null); - const formRef = useRef(null); - const modalPanelRef = useRef(null); - - useOutsideClick(modalPanelRef, onClose); - - useEffect(() => { - let animateTimeout: NodeJS.Timeout; - if (isOpen) { - // Add modal-open class (to animate) after modal is added to the DOM - setRenderModal(true); - animateTimeout = setTimeout(() => setOpenModal(true), 300); - } else { - setOpenModal(false); - // Animate modal out before removing from the DOM - const modal = modalRef.current; - if (modal) { - modal.addEventListener('transitionend', () => { - animateTimeout = setTimeout(() => { - setRenderModal(false); - setAnimateUp(false); - }, 300); - }, { once: true }); - } - } - return () => { - clearTimeout(animateTimeout); - }; - }, [isOpen]); - - const handleSubmit = async (event: React.FormEvent) => { - event.preventDefault(); - const formData = new FormData(formRef.current!); - // Support comma delimated email input or single emails - // ex: "david@example.com, another@example.com" - const to = formData.get('to')?.toString()!.trim() - .split(',').map(email => email.trim())! - const subject = formData.get('subject')?.toString() - const content = formData.get('body')?.toString() - - const emailResponse = await createEmail(dc, { - fromUid: uid, - subject, - content, - }) - - const emailId = emailResponse.data.email_insert.id; - /** - * Note: This needs to be controlled by a security policy which - * will be coming in an update soon. - */ - const uidResponse = await getUidByEmail(dc, { - emails: to - }) - - /** - * Note: This is a work around until we support batch inserts. This - * will eventually be handled in the API. - */ - const uidPromises = uidResponse.data.users.map((user: any) => { - return createRecipient(dc, { - emailId, - uid: user.uid - }) - }) - - await Promise.all(uidPromises); - - let submitTimeout: NodeJS.Timeout; - setTimeout(() => { - setAnimateUp(true); - onClose(); - }, 200); - return () => { - clearTimeout(submitTimeout); - }; - }; - - useEffect(() => { - const handleKeyDown = (event: KeyboardEvent) => { - if (event.key === 'Escape') { - onClose(); - } - }; - document.addEventListener('keydown', handleKeyDown); - return () => { - document.removeEventListener('keydown', handleKeyDown); - }; -}, [onClose]); - - if (!renderModal) { - return null; - } - - return ( -
- {/* modal backdrop */} -
- {/* modal panel */} -
- -

New Message

-
- - - -
- - -
-
-
-
- ) -} - -export default ComposeModal; \ No newline at end of file diff --git a/dataconnect/nextjs-email-app/webapp/src/app/Email.client.tsx b/dataconnect/nextjs-email-app/webapp/src/app/Email.client.tsx deleted file mode 100644 index 9842e50f..00000000 --- a/dataconnect/nextjs-email-app/webapp/src/app/Email.client.tsx +++ /dev/null @@ -1,102 +0,0 @@ -"use client"; // This is a client component 👈🏽 - -import Sidebar from "./Sidebar.client"; -import ComposeModal from "./ComposeModal.client"; -import { useEffect, useState, useCallback } from "react"; -import { ListInboxResponse, listInbox, deleteEmail } from '@email-app/email' -import dataConnect from "@/data-connect"; - -interface Props { - initialEmails: ListInboxResponse['emails']; - firstEmail: ListInboxResponse['emails'][0]; - uid: string; - host: string; -} - -export default function Email({initialEmails, uid, host, firstEmail}: Props) { - const [selectedEmail, setSelectedEmail] = useState(firstEmail); // Default to the first email - const [isComposeOpen, setIsComposeOpen] = useState(false); - const [emails, setEmails] = useState(initialEmails); - const dc = dataConnect(host); - - const triggerFetch = useCallback(() => { - async function run() { - try { - const res = await listInbox(dc, { uid }); - setEmails(res.data.emails); - } catch (e) { - console.error(e); - } - } - run(); - }, [dc, uid]); - - useEffect(() => { - triggerFetch(); - }, [isComposeOpen]); - - return ( - <> - {/* Sidebar */} - - - {/* Main pane */} -
- {/* Actions */} - -
- -
- {/* Email details */} -
-
- {/* Metadata */} -
- {/* Sender */} -
- {selectedEmail.sender.name} - - {selectedEmail.sender.email} - {" "} -
- - {/* Time */} - -
- - {/* Subject */} -

- {selectedEmail.subject} -

-
- -
- -
-
- - setIsComposeOpen(false)} - dc={dc} /> - - ); -} diff --git a/dataconnect/nextjs-email-app/webapp/src/app/ReplyForm.client.tsx b/dataconnect/nextjs-email-app/webapp/src/app/ReplyForm.client.tsx deleted file mode 100644 index bd3be942..00000000 --- a/dataconnect/nextjs-email-app/webapp/src/app/ReplyForm.client.tsx +++ /dev/null @@ -1,92 +0,0 @@ -"use client"; // This is a client component 👈🏽 - -import {SetStateAction, useState, useEffect} from "react"; -import Spinner from "./Spinner"; - -const ReplyForm = () => { - const [AIResponseLoading, setAIResponseLoading] = useState(false); - const [textAreaValue, setTextAreaValue] = useState(''); - - useEffect(() => { - // setTimeout here to simulate AI response time - const timer = setTimeout(() => { - setAIResponseLoading(false); - }, 3000); - - return () => clearTimeout(timer); - }, [AIResponseLoading]); - - - const handleTextAreaChange = (event: { target: { style: { height: string; }; scrollHeight: number; value: SetStateAction; }; }) => { - let textAreaHeight = event.target.scrollHeight >= 64 ? event.target.scrollHeight : 42; - event.target.style.height = `${textAreaHeight}px`; - setTextAreaValue(event.target.value); - }; - - const handleAIClick = (e: React.MouseEvent) => { - e.preventDefault(); - setAIResponseLoading(true); - } - - return ( -
- {/* Relpy Buttons Container */} -
- -
- {/* Reply with AI Button */} - - {/* Submit Button */} - -
-
- {/* */} -