From a74df05f027c089c693a3dafab25bc29a5a68f35 Mon Sep 17 00:00:00 2001 From: Yiming Date: Fri, 15 Dec 2023 08:29:10 +0800 Subject: [PATCH 01/11] chore: update readme (#896) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 56d1c16dd..be3242a65 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ The following diagram gives a high-level architecture overview of ZenStack. ### Todo SaaS App -Check out the [Collaborative Todo App](https://zenstack-todo.vercel.app/) for a running example. You can find different implementations below: +Check out the [Multi-tenant Todo App](https://zenstack-todo.vercel.app/) for a running example. You can find different implementations below: - [Next.js 13 + NextAuth + SWR](https://github.com/zenstackhq/sample-todo-nextjs) - [Next.js 13 + NextAuth + TanStack Query](https://github.com/zenstackhq/sample-todo-nextjs-tanstack) From c79be9eb7f6b602bc84214bded2b927935b6273a Mon Sep 17 00:00:00 2001 From: Yiming Date: Mon, 25 Dec 2023 08:55:21 +0800 Subject: [PATCH 02/11] feat: JetBrains plugin for ZModel (#904) --- .github/workflows/build-test.yml | 14 ++ packages/ide/jetbrains/.gitignore | 18 ++ packages/ide/jetbrains/.idea/.gitignore | 8 + packages/ide/jetbrains/.idea/.name | 1 + packages/ide/jetbrains/.idea/gradle.xml | 15 ++ packages/ide/jetbrains/.idea/kotlinc.xml | 6 + packages/ide/jetbrains/.idea/misc.xml | 8 + packages/ide/jetbrains/.idea/vcs.xml | 6 + packages/ide/jetbrains/build.gradle.kts | 68 +++++ packages/ide/jetbrains/gradle.properties | 6 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 60756 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + packages/ide/jetbrains/gradlew | 234 ++++++++++++++++++ packages/ide/jetbrains/gradlew.bat | 89 +++++++ packages/ide/jetbrains/package.json | 17 ++ packages/ide/jetbrains/settings.gradle.kts | 8 + .../dev/zenstack/lang/ZModelFileType.kt | 14 ++ .../kotlin/dev/zenstack/lang/ZModelIcons.kt | 8 + .../dev/zenstack/lang/ZModelLanguage.kt | 7 + .../lsp/ZenStackLspServerDescriptor.kt | 62 +++++ .../lsp/ZenStackLspServerSupportProvider.kt | 20 ++ .../src/main/resources/META-INF/plugin.xml | 57 +++++ .../main/resources/META-INF/pluginIcon.svg | 15 ++ .../resources/META-INF/pluginIcon_dark.svg | 15 ++ .../src/main/resources/icons/zmodel.png | Bin 0 -> 366 bytes .../src/main/resources/icons/zmodel_dark.png | Bin 0 -> 371 bytes .../main/textMate/zmodel.tmbundle/info.plist | 16 ++ packages/language/package.json | 37 +-- packages/language/script/generate-plist.ts | 12 + packages/language/syntaxes/zmodel.tmLanguage | 113 +++++++++ packages/schema/.vscodeignore | 3 + packages/schema/build/bundle.js | 14 +- packages/schema/build/env-plugin.js | 60 ----- packages/schema/package.json | 8 +- packages/schema/src/res/prism-zmodel.js | 20 -- packages/schema/syntaxes/zmodel.json | 55 ---- .../schema/syntaxes/zmodel.tmLanguage.json | 69 ------ packages/server/package.json | 2 +- pnpm-lock.yaml | 24 ++ pnpm-workspace.yaml | 1 + 40 files changed, 896 insertions(+), 239 deletions(-) create mode 100644 packages/ide/jetbrains/.gitignore create mode 100644 packages/ide/jetbrains/.idea/.gitignore create mode 100644 packages/ide/jetbrains/.idea/.name create mode 100644 packages/ide/jetbrains/.idea/gradle.xml create mode 100644 packages/ide/jetbrains/.idea/kotlinc.xml create mode 100644 packages/ide/jetbrains/.idea/misc.xml create mode 100644 packages/ide/jetbrains/.idea/vcs.xml create mode 100644 packages/ide/jetbrains/build.gradle.kts create mode 100644 packages/ide/jetbrains/gradle.properties create mode 100644 packages/ide/jetbrains/gradle/wrapper/gradle-wrapper.jar create mode 100644 packages/ide/jetbrains/gradle/wrapper/gradle-wrapper.properties create mode 100755 packages/ide/jetbrains/gradlew create mode 100644 packages/ide/jetbrains/gradlew.bat create mode 100644 packages/ide/jetbrains/package.json create mode 100644 packages/ide/jetbrains/settings.gradle.kts create mode 100644 packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelFileType.kt create mode 100644 packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelIcons.kt create mode 100644 packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelLanguage.kt create mode 100644 packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerDescriptor.kt create mode 100644 packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerSupportProvider.kt create mode 100644 packages/ide/jetbrains/src/main/resources/META-INF/plugin.xml create mode 100644 packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon.svg create mode 100644 packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon_dark.svg create mode 100644 packages/ide/jetbrains/src/main/resources/icons/zmodel.png create mode 100644 packages/ide/jetbrains/src/main/resources/icons/zmodel_dark.png create mode 100644 packages/ide/jetbrains/src/main/textMate/zmodel.tmbundle/info.plist create mode 100644 packages/language/script/generate-plist.ts create mode 100644 packages/language/syntaxes/zmodel.tmLanguage delete mode 100644 packages/schema/build/env-plugin.js delete mode 100644 packages/schema/src/res/prism-zmodel.js delete mode 100644 packages/schema/syntaxes/zmodel.json delete mode 100644 packages/schema/syntaxes/zmodel.tmLanguage.json diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 4857fda3f..b6388804b 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -72,6 +72,20 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Gradle Wrapper Validation + uses: gradle/wrapper-validation-action@v1.1.0 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: zulu + java-version: 17 + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + with: + gradle-home-cache-cleanup: true + - name: Build run: DEFAULT_NPM_TAG=latest pnpm run build diff --git a/packages/ide/jetbrains/.gitignore b/packages/ide/jetbrains/.gitignore new file mode 100644 index 000000000..80b28c077 --- /dev/null +++ b/packages/ide/jetbrains/.gitignore @@ -0,0 +1,18 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ +.sign diff --git a/packages/ide/jetbrains/.idea/.gitignore b/packages/ide/jetbrains/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/packages/ide/jetbrains/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/packages/ide/jetbrains/.idea/.name b/packages/ide/jetbrains/.idea/.name new file mode 100644 index 000000000..8aa065d41 --- /dev/null +++ b/packages/ide/jetbrains/.idea/.name @@ -0,0 +1 @@ +zenstack \ No newline at end of file diff --git a/packages/ide/jetbrains/.idea/gradle.xml b/packages/ide/jetbrains/.idea/gradle.xml new file mode 100644 index 000000000..f9163b40e --- /dev/null +++ b/packages/ide/jetbrains/.idea/gradle.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/packages/ide/jetbrains/.idea/kotlinc.xml b/packages/ide/jetbrains/.idea/kotlinc.xml new file mode 100644 index 000000000..ae3f30ae1 --- /dev/null +++ b/packages/ide/jetbrains/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/packages/ide/jetbrains/.idea/misc.xml b/packages/ide/jetbrains/.idea/misc.xml new file mode 100644 index 000000000..68bf986ec --- /dev/null +++ b/packages/ide/jetbrains/.idea/misc.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/packages/ide/jetbrains/.idea/vcs.xml b/packages/ide/jetbrains/.idea/vcs.xml new file mode 100644 index 000000000..b2bdec2d7 --- /dev/null +++ b/packages/ide/jetbrains/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packages/ide/jetbrains/build.gradle.kts b/packages/ide/jetbrains/build.gradle.kts new file mode 100644 index 000000000..fa0e3ed31 --- /dev/null +++ b/packages/ide/jetbrains/build.gradle.kts @@ -0,0 +1,68 @@ +plugins { + id("java") + id("org.jetbrains.kotlin.jvm") version "1.9.21" + id("org.jetbrains.intellij") version "1.16.1" +} + +group = "dev.zenstack" +version = "0.5.0" + +repositories { + mavenCentral() +} + +// Configure Gradle IntelliJ Plugin +// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html +intellij { + version.set("2023.3.2") + type.set("IU") // Target IDE Platform + + plugins.set(listOf("JavaScript", "org.jetbrains.plugins.textmate")) +} + +tasks { + // Set the JVM compatibility versions + withType { + sourceCompatibility = "17" + targetCompatibility = "17" + } + withType { + kotlinOptions.jvmTarget = "17" + } + + prepareSandbox { + doLast { + copy { + from("${project.projectDir}/../../schema/bundle/language-server/main.js") + into("${destinationDir.path}/zenstack/language-server/") + } + copy { + from("${project.projectDir}/../../schema/src/res/stdlib.zmodel") + into("${destinationDir.path}/zenstack/res/") + } + copy { + from("${project.projectDir}/src/main/textMate/zmodel.tmbundle") + into("${destinationDir.path}/zenstack/res/zmodel.tmbundle") + } + copy { + from("${project.projectDir}/../../language/syntaxes/zmodel.tmLanguage") + into("${destinationDir.path}/zenstack/res/zmodel.tmbundle/Syntaxes/") + } + } + } + + patchPluginXml { + sinceBuild.set("231") + untilBuild.set("241.*") + } + + signPlugin { + certificateChain.set(System.getenv("CERTIFICATE_CHAIN")) + privateKey.set(System.getenv("PRIVATE_KEY")) + password.set(System.getenv("PRIVATE_KEY_PASSWORD")) + } + + publishPlugin { + token.set(System.getenv("PUBLISH_TOKEN")) + } +} diff --git a/packages/ide/jetbrains/gradle.properties b/packages/ide/jetbrains/gradle.properties new file mode 100644 index 000000000..e1c1990f8 --- /dev/null +++ b/packages/ide/jetbrains/gradle.properties @@ -0,0 +1,6 @@ +# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib +kotlin.stdlib.default.dependency=false +# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html +org.gradle.configuration-cache=false +# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html +org.gradle.caching=true diff --git a/packages/ide/jetbrains/gradle/wrapper/gradle-wrapper.jar b/packages/ide/jetbrains/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..249e5832f090a2944b7473328c07c9755baa3196 GIT binary patch literal 60756 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/packages/ide/jetbrains/gradlew.bat b/packages/ide/jetbrains/gradlew.bat new file mode 100644 index 000000000..ac1b06f93 --- /dev/null +++ b/packages/ide/jetbrains/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/ide/jetbrains/package.json b/packages/ide/jetbrains/package.json new file mode 100644 index 000000000..a7414f0bf --- /dev/null +++ b/packages/ide/jetbrains/package.json @@ -0,0 +1,17 @@ +{ + "name": "jetbrains", + "version": "1.5.0", + "displayName": "ZenStack JetBrains IDE Plugin", + "description": "ZenStack JetBrains IDE plugin", + "homepage": "https://zenstack.dev", + "private": true, + "scripts": { + "build": "./gradlew buildPlugin" + }, + "author": "ZenStack Team", + "license": "MIT", + "devDependencies": { + "zenstack": "workspace:*", + "@zenstackhq/language": "workspace:*" + } +} diff --git a/packages/ide/jetbrains/settings.gradle.kts b/packages/ide/jetbrains/settings.gradle.kts new file mode 100644 index 000000000..e0ac2ff8b --- /dev/null +++ b/packages/ide/jetbrains/settings.gradle.kts @@ -0,0 +1,8 @@ +pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + } +} + +rootProject.name = "zenstack" \ No newline at end of file diff --git a/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelFileType.kt b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelFileType.kt new file mode 100644 index 000000000..b0c4ada21 --- /dev/null +++ b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelFileType.kt @@ -0,0 +1,14 @@ +package dev.zenstack.lang + +import com.intellij.openapi.fileTypes.LanguageFileType +import javax.swing.Icon + +object ZModelFileType : LanguageFileType(ZModelLanguage) { + override fun getName(): String = "ZModel" + + override fun getDescription(): String = "ZModel Language" + + override fun getDefaultExtension(): String = "zmodel" + + override fun getIcon(): Icon = ZModelIcons.ZModel +} \ No newline at end of file diff --git a/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelIcons.kt b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelIcons.kt new file mode 100644 index 000000000..f168410d6 --- /dev/null +++ b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelIcons.kt @@ -0,0 +1,8 @@ +package dev.zenstack.lang + +import com.intellij.openapi.util.IconLoader; + +object ZModelIcons { + @JvmField + val ZModel = IconLoader.getIcon("/icons/zmodel.png", javaClass) +} diff --git a/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelLanguage.kt b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelLanguage.kt new file mode 100644 index 000000000..cfc60749f --- /dev/null +++ b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelLanguage.kt @@ -0,0 +1,7 @@ +package dev.zenstack.lang + +import com.intellij.lang.Language + +object ZModelLanguage : Language("ZModel") { + override fun getDisplayName(): String = "ZModel" +} diff --git a/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerDescriptor.kt b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerDescriptor.kt new file mode 100644 index 000000000..3d1219574 --- /dev/null +++ b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerDescriptor.kt @@ -0,0 +1,62 @@ +package dev.zenstack.lsp + +import com.intellij.codeInsight.completion.CompletionParameters +import com.intellij.execution.ExecutionException +import com.intellij.execution.configurations.GeneralCommandLine +import com.intellij.javascript.nodejs.interpreter.NodeCommandLineConfigurator +import com.intellij.javascript.nodejs.interpreter.NodeJsInterpreterManager +import com.intellij.javascript.nodejs.interpreter.local.NodeJsLocalInterpreter +import com.intellij.javascript.nodejs.interpreter.wsl.WslNodeInterpreter +import com.intellij.lang.javascript.service.JSLanguageServiceUtil +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.platform.lsp.api.ProjectWideLspServerDescriptor +import com.intellij.platform.lsp.api.customization.LspCompletionSupport +import com.intellij.platform.lsp.api.customization.LspFormattingSupport +import org.jetbrains.plugins.textmate.configuration.TextMateUserBundlesSettings +import org.jetbrains.plugins.textmate.TextMateService; +import dev.zenstack.lang.ZModelFileType + +class ZenStackLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor(project, "ZenStack") { + + override fun isSupportedFile(file: VirtualFile) = file.fileType == ZModelFileType + + override fun createCommandLine(): GeneralCommandLine { + + // install TextMate bundle + val textMateBundle = JSLanguageServiceUtil.getPluginDirectory(javaClass, "res/zmodel.tmbundle") + TextMateUserBundlesSettings.instance?.addBundle(textMateBundle.path, "zmodel") + val textMateService = TextMateService.getInstance(); + textMateService.reloadEnabledBundles() + + // start language server + val interpreter = NodeJsInterpreterManager.getInstance(project).interpreter + if (interpreter !is NodeJsLocalInterpreter && interpreter !is WslNodeInterpreter) { + throw ExecutionException("Interpreter not configured") + } + + val lsp = JSLanguageServiceUtil.getPluginDirectory(javaClass, "language-server/main.js") + if (lsp == null || !lsp.exists()) { + // broken plugin installation? + throw ExecutionException("Language server not found") + } + + return GeneralCommandLine().apply { + withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.CONSOLE) + withCharset(Charsets.UTF_8) + addParameter(lsp.path) + addParameter("--stdio") + + NodeCommandLineConfigurator.find(interpreter) + .configure(this, NodeCommandLineConfigurator.defaultOptions(project)) + } + } + + override val lspGoToDefinitionSupport = true + + override val lspHoverSupport = true + + override val lspFormattingSupport = object : LspFormattingSupport() { + override fun shouldFormatThisFileExclusivelyByServer(file: VirtualFile, ideCanFormatThisFileItself: Boolean, serverExplicitlyWantsToFormatThisFile: Boolean) = file.fileType == ZModelFileType + } +} diff --git a/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerSupportProvider.kt b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerSupportProvider.kt new file mode 100644 index 000000000..6fb6d79db --- /dev/null +++ b/packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerSupportProvider.kt @@ -0,0 +1,20 @@ +package dev.zenstack.lsp + +import com.intellij.javascript.nodejs.interpreter.NodeJsInterpreterManager +import com.intellij.javascript.nodejs.interpreter.local.NodeJsLocalInterpreter +import com.intellij.javascript.nodejs.interpreter.wsl.WslNodeInterpreter +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.platform.lsp.api.LspServerSupportProvider +import dev.zenstack.lang.ZModelFileType + +class ZenStackLspServerSupportProvider : LspServerSupportProvider { + override fun fileOpened(project: Project, file: VirtualFile, serverStarter: LspServerSupportProvider.LspServerStarter) { + if (file.fileType != ZModelFileType) return + + val node = NodeJsInterpreterManager.getInstance(project).interpreter + if (node !is NodeJsLocalInterpreter && node !is WslNodeInterpreter) return + + serverStarter.ensureServerStarted(ZenStackLspServerDescriptor(project)) + } +} \ No newline at end of file diff --git a/packages/ide/jetbrains/src/main/resources/META-INF/plugin.xml b/packages/ide/jetbrains/src/main/resources/META-INF/plugin.xml new file mode 100644 index 000000000..3ee6bf887 --- /dev/null +++ b/packages/ide/jetbrains/src/main/resources/META-INF/plugin.xml @@ -0,0 +1,57 @@ + + + + dev.zenstack.zenstack + + + ZenStack Language Tools + + + ZenStack + + + ZenStack is a toolkit that simplifies the development of a web app's backend. This plugin provides code editing experiences for its ZModel schema language. + +

Features

+ +
    +
  • Syntax highlighting
  • +
  • Go to definition
  • +
  • Code completion
  • +
+ ]]> + + + com.intellij.modules.ultimate + JavaScript + org.jetbrains.plugins.textmate + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon.svg b/packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon.svg new file mode 100644 index 000000000..c70b27f19 --- /dev/null +++ b/packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon.svg @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon_dark.svg b/packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon_dark.svg new file mode 100644 index 000000000..6f52be69d --- /dev/null +++ b/packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon_dark.svg @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/packages/ide/jetbrains/src/main/resources/icons/zmodel.png b/packages/ide/jetbrains/src/main/resources/icons/zmodel.png new file mode 100644 index 0000000000000000000000000000000000000000..dab4013a337c55a79bee3026861bdf627768b87a GIT binary patch literal 366 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}et=Jit9yZufQYD=loU6=04FaW zkPRfI<>Yho^2DX2g~h~0#3gtH1ck)JIeB^I6qSTT#pIQgB&214DsAl@cm;)kQlb)) zf}&y^JiI_IP!~{ESX?3|F3#N2ik+K>jfV@KqgZ)Pz$sP@WtsE3N8%&qzgVWP+RYxj;-||UhLiRW?0_0NJzX3_BrfOnpA>6W z;BieA=>q&45Il-!rI^YyJ=vYX$XcvP+zQ2yj~#_ENcO-FNeq68*oFrE%5 z^Ro!ozGzc$?{uc#imM$)ZstFJtJx^t`h5I8OC9Ts{c%!7Ku0lny85}Sb4q9e0CP2Q AXaE2J literal 0 HcmV?d00001 diff --git a/packages/ide/jetbrains/src/main/resources/icons/zmodel_dark.png b/packages/ide/jetbrains/src/main/resources/icons/zmodel_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..7b4b2b226db72c0e8efadbc824ed7d41d8631ba5 GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}X@F0Nt9yaZ%coD@zkc=Z)ypRj z?!S5Q{NdfZ&mKMc`tieoeS1H>d-wL`i_h=hy?*f=sOHnVx8Fa1x_{^PizknPjKc>G z{P^-2sNmz6z^?q-)cqr1XyId5tAOttgTv2UtVem=g#aO}gk za-fzrPZ!4!iOaeEH-(xNctoDCF&^ZK+xq(x~Co|qVCyv6)VuxgIGn_17lXmEy*F88x^|BZ&l)&G95Gv~5SoWR-h4d@~U MPgg&ebxsLQ0R6Sf3;+NC literal 0 HcmV?d00001 diff --git a/packages/ide/jetbrains/src/main/textMate/zmodel.tmbundle/info.plist b/packages/ide/jetbrains/src/main/textMate/zmodel.tmbundle/info.plist new file mode 100644 index 000000000..9abe98fab --- /dev/null +++ b/packages/ide/jetbrains/src/main/textMate/zmodel.tmbundle/info.plist @@ -0,0 +1,16 @@ + + + + + contactEmailRot13 + contact@zenstack.dev + contactName + ZenStack Team + description + ZModel Language + name + zmodel + uuid + 0EA94AB2-A210-4A58-9A25-CFFF59AC430B + + diff --git a/packages/language/package.json b/packages/language/package.json index fff1840c2..0977be59c 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -6,10 +6,10 @@ "homepage": "https://zenstack.dev", "scripts": { "clean": "rimraf dist", - "generate": "langium generate", + "generate": "langium generate && npx ts-node script/generate-plist.ts", "watch": "concurrently \"langium generate --watch\" \"tsc --watch\"", "lint": "eslint src --ext ts", - "build": "pnpm lint --max-warnings=0 && pnpm clean && pnpm generate && tsc && copyfiles -F ./README.md ./LICENSE ./package.json dist && pnpm pack dist --pack-destination '../../../.build'", + "build": "pnpm lint --max-warnings=0 && pnpm clean && pnpm generate && tsc && copyfiles -F ./README.md ./LICENSE ./package.json 'syntaxes/**/*' dist && pnpm pack dist --pack-destination '../../../.build'", "prepublishOnly": "pnpm build" }, "publishConfig": { @@ -19,24 +19,27 @@ "author": "ZenStack Team", "license": "MIT", "devDependencies": { - "langium-cli": "1.2.0" + "langium-cli": "1.2.0", + "plist2": "^1.1.3" }, "dependencies": { - "langium": "1.2.0" + "langium": "1.2.0" }, "contributes": { - "languages": [ - { - "id": "zmodel", - "extensions": [".zmodel"] - } - ], - "grammars": [ - { - "language": "zmodel", - "scopeName": "source.zmodel", - "path": "./syntaxes/zmodel.tmLanguage.json" - } - ] + "languages": [ + { + "id": "zmodel", + "extensions": [ + ".zmodel" + ] + } + ], + "grammars": [ + { + "language": "zmodel", + "scopeName": "source.zmodel", + "path": "./syntaxes/zmodel.tmLanguage.json" + } + ] } } diff --git a/packages/language/script/generate-plist.ts b/packages/language/script/generate-plist.ts new file mode 100644 index 000000000..f987f71ed --- /dev/null +++ b/packages/language/script/generate-plist.ts @@ -0,0 +1,12 @@ +// convert textmate grammar from json to plist with fixes + +import { json2plist } from 'plist2'; +import fs from 'fs'; +import path from 'path'; + +const src = fs.readFileSync(path.resolve(__dirname, '../syntaxes/zmodel.tmLanguage.json'), 'utf-8'); +const json = JSON.parse(src); +json['fileTypes'] = ['zmodel']; + +const plist = json2plist(JSON.stringify(json)); +fs.writeFileSync(path.resolve(__dirname, '../syntaxes/zmodel.tmLanguage'), plist, 'utf-8'); diff --git a/packages/language/syntaxes/zmodel.tmLanguage b/packages/language/syntaxes/zmodel.tmLanguage new file mode 100644 index 000000000..bacb471c3 --- /dev/null +++ b/packages/language/syntaxes/zmodel.tmLanguage @@ -0,0 +1,113 @@ + + + + + name + zmodel + scopeName + source.zmodel + fileTypes + + zmodel + + patterns + + + include + #comments + + + name + keyword.control.zmodel + match + \b(Any|Asc|BigInt|Boolean|Bytes|ContextType|DateTime|Decimal|Desc|FieldReference|Float|Int|Json|Null|Object|String|TransitiveFieldReference|Unsupported|abstract|attribute|datasource|enum|extends|false|function|generator|import|in|model|plugin|sort|true|view)\b + + + name + string.quoted.double.zmodel + begin + " + end + " + patterns + + + include + #string-character-escape + + + + + name + string.quoted.single.zmodel + begin + ' + end + ' + patterns + + + include + #string-character-escape + + + + + repository + + comments + + patterns + + + name + comment.block.zmodel + begin + /\* + beginCaptures + + 0 + + name + punctuation.definition.comment.zmodel + + + end + \*/ + endCaptures + + 0 + + name + punctuation.definition.comment.zmodel + + + + + begin + // + beginCaptures + + 1 + + name + punctuation.whitespace.comment.leading.zmodel + + + end + (?=$) + name + comment.line.zmodel + + + + string-character-escape + + name + constant.character.escape.zmodel + match + \\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|u\{[0-9A-Fa-f]+\}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$) + + + + \ No newline at end of file diff --git a/packages/schema/.vscodeignore b/packages/schema/.vscodeignore index ed687f91e..9551337ea 100644 --- a/packages/schema/.vscodeignore +++ b/packages/schema/.vscodeignore @@ -1,3 +1,4 @@ +.env .vscode/** .vscode-test/** .gitignore @@ -8,3 +9,5 @@ bin build jest.config.ts tsconfig.json +dist +README-global.md diff --git a/packages/schema/build/bundle.js b/packages/schema/build/bundle.js index 9adab015b..537588c3e 100644 --- a/packages/schema/build/bundle.js +++ b/packages/schema/build/bundle.js @@ -23,19 +23,7 @@ require('esbuild') }) .then(() => { fs.cpSync('./src/res', 'bundle/res', { force: true, recursive: true }); - fs.cpSync('./asset', 'bundle/asset', { - force: true, - recursive: true, - }); - fs.cpSync('./README.md', 'bundle/README.md', { - force: true, - }); - fs.cpSync('../../LICENSE', 'bundle/LICENSE', { - force: true, - }); - fs.cpSync('./package.json', 'bundle/package.json', { - force: true, - }); + fs.cpSync('../language/syntaxes', 'bundle/syntaxes', { force: true, recursive: true }); }) .then(() => console.log(success)) .catch((err) => { diff --git a/packages/schema/build/env-plugin.js b/packages/schema/build/env-plugin.js deleted file mode 100644 index 99e212616..000000000 --- a/packages/schema/build/env-plugin.js +++ /dev/null @@ -1,60 +0,0 @@ -// from: https://github.com/rw3iss/esbuild-envfile-plugin - -const path = require('path'); -const fs = require('fs'); - -const ENV = process.env.NODE_ENV || 'development'; - -module.exports = { - name: 'env', - - setup(build) { - function _findEnvFile(dir) { - if (!fs.existsSync(dir)) return undefined; - - const candidates = [`${dir}/.env.${ENV}.local`, `${dir}/.env.${ENV}`, `${dir}/.env.local`, `${dir}/.env`]; - - for (const candidate of candidates) { - if (fs.existsSync(candidate)) { - console.log('Using env from:', candidate); - return candidate; - } - } - - const next = path.resolve(dir, '../'); - if (next === dir) { - // at root now, exit - return undefined; - } else { - return _findEnvFile(next); - } - } - - build.onResolve({ filter: /^env$/ }, async (args) => { - const envPath = _findEnvFile(args.resolveDir); - return { - path: args.path, - namespace: 'env-ns', - pluginData: { - ...args.pluginData, - envPath, - }, - }; - }); - - build.onLoad({ filter: /.*/, namespace: 'env-ns' }, async (args) => { - // read in .env file contents and combine with regular .env: - let config = {}; - if (args.pluginData && args.pluginData.envPath) { - let data = await fs.promises.readFile(args.pluginData.envPath, 'utf8'); - const buf = Buffer.from(data); - config = require('dotenv').parse(buf); - } - - return { - contents: JSON.stringify({ ...config, ...process.env }), - loader: 'json', - }; - }); - }, -}; diff --git a/packages/schema/package.json b/packages/schema/package.json index a27e44032..961558b63 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -53,7 +53,7 @@ { "language": "zmodel", "scopeName": "source.zmodel", - "path": "./syntaxes/zmodel.tmLanguage.json" + "path": "./bundle/syntaxes/zmodel.tmLanguage.json" } ] }, @@ -67,10 +67,10 @@ "scripts": { "vscode:publish": "vsce publish --no-dependencies", "vscode:prepublish": "pnpm bundle", - "vscode:package": "vsce package --no-dependencies", - "clean": "rimraf bundle dist", + "vscode:package": "pnpm bundle && vsce package --no-dependencies", + "clean": "rimraf dist", "build": "pnpm clean && pnpm lint --max-warnings=0 && tsc && copyfiles -F \"bin/*\" dist && copyfiles ./README-global.md ./LICENSE ./package.json dist && renamer --replace \"README.md\" dist/README-global.md && copyfiles -u 1 \"src/res/*\" dist && node build/post-build.js && pnpm pack dist --pack-destination '../../../.build'", - "bundle": "pnpm clean && pnpm lint --max-warnings=0 && node build/bundle.js --minify", + "bundle": "rimraf bundle && pnpm lint --max-warnings=0 && node build/bundle.js --minify", "watch": "tsc --watch", "lint": "eslint src tests --ext ts", "test": "ZENSTACK_TEST=1 jest", diff --git a/packages/schema/src/res/prism-zmodel.js b/packages/schema/src/res/prism-zmodel.js deleted file mode 100644 index 2d9082332..000000000 --- a/packages/schema/src/res/prism-zmodel.js +++ /dev/null @@ -1,20 +0,0 @@ -// based on: https://github.com/prisma/docs/blob/c72eb087fcf57f3c00d153f86c549ef28b3d0f44/src/components/customMdx/prism/prism-prisma.js - -(function (Prism) { - Prism.languages.zmodel = Prism.languages.extend('clike', { - keyword: /\b(?:datasource|enum|generator|model|attribute|function|null|this)\b/, - 'type-class-name': /(\b()\s+)[\w.\\]+/, - }); - - Prism.languages.javascript['class-name'][0].pattern = /(\b(?:model|datasource|enum|generator)\s+)[\w.\\]+/; - - Prism.languages.insertBefore('zmodel', 'function', { - annotation: { - pattern: /(^|[^.])@+\w+/, - lookbehind: true, - alias: 'punctuation', - }, - }); - - Prism.languages.json5 = Prism.languages.js; -})(Prism); diff --git a/packages/schema/syntaxes/zmodel.json b/packages/schema/syntaxes/zmodel.json deleted file mode 100644 index 6d84ad7b6..000000000 --- a/packages/schema/syntaxes/zmodel.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "zmodel", - "scopeName": "source.zmodel", - "fileTypes": [".zmodel"], - "patterns": [ - { - "include": "#comments" - }, - { - "name": "keyword.control.zmodel", - "match": "\\b(Boolean|datasource|enum|model|String)\\b" - }, - { - "name": "string.quoted.double.zmodel", - "begin": "\"", - "end": "\"" - }, - { - "name": "string.quoted.single.zmodel", - "begin": "'", - "end": "'" - } - ], - "repository": { - "comments": { - "patterns": [ - { - "name": "comment.block.zmodel", - "begin": "/\\*", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.zmodel" - } - }, - "end": "\\*/", - "endCaptures": { - "0": { - "name": "punctuation.definition.comment.zmodel" - } - } - }, - { - "begin": "//", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.comment.leading.zmodel" - } - }, - "end": "(?=$)", - "name": "comment.line.zmodel" - } - ] - } - } -} diff --git a/packages/schema/syntaxes/zmodel.tmLanguage.json b/packages/schema/syntaxes/zmodel.tmLanguage.json deleted file mode 100644 index fb5bf9c7e..000000000 --- a/packages/schema/syntaxes/zmodel.tmLanguage.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "zmodel", - "scopeName": "source.zmodel", - "fileTypes": [".zmodel"], - "patterns": [ - { - "include": "#comments" - }, - { - "name": "keyword.storage.zmodel", - "match": "\\b(Any|Asc|BigInt|Boolean|Bytes|ContextType|DateTime|Decimal|Desc|FieldReference|Float|Int|Json|Null|Object|String|TransitiveFieldReference|Unsupported|abstract|attribute|datasource|enum|extends|false|function|generator|import|in|model|plugin|sort|true|view)\\b" - }, - { - "name": "string.quoted.double.zmodel", - "begin": "\"", - "end": "\"", - "patterns": [ - { - "include": "#string-character-escape" - } - ] - }, - { - "name": "string.quoted.single.zmodel", - "begin": "'", - "end": "'", - "patterns": [ - { - "include": "#string-character-escape" - } - ] - } - ], - "repository": { - "comments": { - "patterns": [ - { - "name": "comment.block.zmodel", - "begin": "/\\*", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.zmodel" - } - }, - "end": "\\*/", - "endCaptures": { - "0": { - "name": "punctuation.definition.comment.zmodel" - } - } - }, - { - "begin": "//", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.comment.leading.zmodel" - } - }, - "end": "(?=$)", - "name": "comment.line.zmodel" - } - ] - }, - "string-character-escape": { - "name": "constant.character.escape.zmodel", - "match": "\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|u\\{[0-9A-Fa-f]+\\}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)" - } - } -} diff --git a/packages/server/package.json b/packages/server/package.json index 2d02ee7e5..f31242954 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -23,7 +23,7 @@ "sveltekit", "nuxtjs" ], - "author": "", + "author": "ZenStack Team", "license": "MIT", "dependencies": { "@zenstackhq/runtime": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f209cbdac..de0f8a35f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,6 +57,15 @@ importers: specifier: ^5.3.2 version: 5.3.2 + packages/ide/jetbrains: + devDependencies: + '@zenstackhq/language': + specifier: workspace:* + version: link:../../language/dist + zenstack: + specifier: workspace:* + version: link:../../schema/dist + packages/language: dependencies: langium: @@ -66,6 +75,9 @@ importers: langium-cli: specifier: 1.2.0 version: 1.2.0 + plist2: + specifier: ^1.1.3 + version: 1.1.3 publishDirectory: dist packages/plugins/openapi: @@ -11117,6 +11129,13 @@ packages: queue-lit: 1.5.0 dev: true + /plist2@1.1.3: + resolution: {integrity: sha512-AOpoCuUdedSJYeeU2Be6UAIMZqFWno0fD43NNT64is8k5Fi2HyEylK4UAOZBmafeImnCO1FYc+u8cwwEExVztA==} + hasBin: true + dependencies: + yaml: 1.10.2 + dev: true + /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -14449,6 +14468,11 @@ packages: /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + /yaml@2.2.1: resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} engines: {node: '>= 14'} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 928f8bfc9..198ac1918 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,4 +1,5 @@ packages: - 'packages/*' - 'packages/plugins/*' + - 'packages/ide/*' - 'tests/*' From dd80a64ef0a3bba889075fdab077a674f4d56889 Mon Sep 17 00:00:00 2001 From: Yiming Date: Mon, 25 Dec 2023 08:59:52 +0800 Subject: [PATCH 03/11] chore: bump version 1.6.0 (#905) --- package.json | 2 +- packages/ide/jetbrains/package.json | 2 +- packages/language/package.json | 2 +- packages/plugins/openapi/package.json | 2 +- packages/plugins/swr/package.json | 2 +- packages/plugins/tanstack-query/package.json | 2 +- packages/plugins/trpc/package.json | 2 +- packages/runtime/package.json | 2 +- packages/schema/package.json | 2 +- packages/sdk/package.json | 2 +- packages/server/package.json | 2 +- packages/testtools/package.json | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index dbedaf9dd..19cac9cd5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "1.5.0", + "version": "1.6.0", "description": "", "scripts": { "build": "pnpm -r build", diff --git a/packages/ide/jetbrains/package.json b/packages/ide/jetbrains/package.json index a7414f0bf..7914671a7 100644 --- a/packages/ide/jetbrains/package.json +++ b/packages/ide/jetbrains/package.json @@ -1,6 +1,6 @@ { "name": "jetbrains", - "version": "1.5.0", + "version": "1.6.0", "displayName": "ZenStack JetBrains IDE Plugin", "description": "ZenStack JetBrains IDE plugin", "homepage": "https://zenstack.dev", diff --git a/packages/language/package.json b/packages/language/package.json index 0977be59c..784000a45 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/language", - "version": "1.5.0", + "version": "1.6.0", "displayName": "ZenStack modeling language compiler", "description": "ZenStack modeling language compiler", "homepage": "https://zenstack.dev", diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json index 00267ae73..9dcadfab2 100644 --- a/packages/plugins/openapi/package.json +++ b/packages/plugins/openapi/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/openapi", "displayName": "ZenStack Plugin and Runtime for OpenAPI", - "version": "1.5.0", + "version": "1.6.0", "description": "ZenStack plugin and runtime supporting OpenAPI", "main": "index.js", "repository": { diff --git a/packages/plugins/swr/package.json b/packages/plugins/swr/package.json index d38a7dcd7..ec41734bd 100644 --- a/packages/plugins/swr/package.json +++ b/packages/plugins/swr/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/swr", "displayName": "ZenStack plugin for generating SWR hooks", - "version": "1.5.0", + "version": "1.6.0", "description": "ZenStack plugin for generating SWR hooks", "main": "index.js", "repository": { diff --git a/packages/plugins/tanstack-query/package.json b/packages/plugins/tanstack-query/package.json index d50a39ee5..9ea0be9e9 100644 --- a/packages/plugins/tanstack-query/package.json +++ b/packages/plugins/tanstack-query/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/tanstack-query", "displayName": "ZenStack plugin for generating tanstack-query hooks", - "version": "1.5.0", + "version": "1.6.0", "description": "ZenStack plugin for generating tanstack-query hooks", "main": "index.js", "exports": { diff --git a/packages/plugins/trpc/package.json b/packages/plugins/trpc/package.json index 846febecd..5c4bb8be6 100644 --- a/packages/plugins/trpc/package.json +++ b/packages/plugins/trpc/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/trpc", "displayName": "ZenStack plugin for tRPC", - "version": "1.5.0", + "version": "1.6.0", "description": "ZenStack plugin for tRPC", "main": "index.js", "repository": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index a56f6b115..754357790 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "1.5.0", + "version": "1.6.0", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", diff --git a/packages/schema/package.json b/packages/schema/package.json index 961558b63..bc60658dd 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "Build scalable web apps with minimum code by defining authorization and validation rules inside the data schema that closer to the database", - "version": "1.5.0", + "version": "1.6.0", "author": { "name": "ZenStack Team" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 5c0fcd83e..844c60889 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "1.5.0", + "version": "1.6.0", "description": "ZenStack plugin development SDK", "main": "index.js", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index f31242954..de0f6cc44 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "1.5.0", + "version": "1.6.0", "displayName": "ZenStack Server-side Adapters", "description": "ZenStack server-side adapters", "homepage": "https://zenstack.dev", diff --git a/packages/testtools/package.json b/packages/testtools/package.json index 3919fe14e..52f6309b4 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "1.5.0", + "version": "1.6.0", "description": "ZenStack Test Tools", "main": "index.js", "private": true, From 0e422adf1a7f274b850eeba09ef1781b13ce9f1b Mon Sep 17 00:00:00 2001 From: Yiming Date: Mon, 25 Dec 2023 15:42:42 +0800 Subject: [PATCH 04/11] fix: properly handle nullable fields in openapi generator (#906) --- packages/plugins/openapi/package.json | 3 + .../plugins/openapi/src/generator-base.ts | 40 + .../plugins/openapi/src/rest-generator.ts | 90 +- packages/plugins/openapi/src/rpc-generator.ts | 64 +- .../tests/baseline/rest-3.0.0.baseline.yaml | 2599 ++++++++ ...baseline.yaml => rest-3.1.0.baseline.yaml} | 793 ++- .../rest-type-coverage-3.0.0.baseline.yaml | 803 +++ ...=> rest-type-coverage-3.1.0.baseline.yaml} | 8 +- ....baseline.yaml => rpc-3.0.0.baseline.yaml} | 1975 +++++- .../tests/baseline/rpc-3.1.0.baseline.yaml | 5477 +++++++++++++++++ ... => rpc-type-coverage-3.0.0.baseline.yaml} | 186 +- .../rpc-type-coverage-3.1.0.baseline.yaml | 2815 +++++++++ .../openapi/tests/openapi-restful.test.ts | 135 +- .../plugins/openapi/tests/openapi-rpc.test.ts | 135 +- packages/plugins/swr/tests/swr.test.ts | 3 +- .../tanstack-query/tests/plugin.test.ts | 13 +- packages/plugins/trpc/tests/trpc.test.ts | 20 +- pnpm-lock.yaml | 17 +- 18 files changed, 14726 insertions(+), 450 deletions(-) create mode 100644 packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml rename packages/plugins/openapi/tests/baseline/{rest.baseline.yaml => rest-3.1.0.baseline.yaml} (71%) create mode 100644 packages/plugins/openapi/tests/baseline/rest-type-coverage-3.0.0.baseline.yaml rename packages/plugins/openapi/tests/baseline/{rest-type-coverage.baseline.yaml => rest-type-coverage-3.1.0.baseline.yaml} (100%) rename packages/plugins/openapi/tests/baseline/{rpc.baseline.yaml => rpc-3.0.0.baseline.yaml} (67%) create mode 100644 packages/plugins/openapi/tests/baseline/rpc-3.1.0.baseline.yaml rename packages/plugins/openapi/tests/baseline/{rpc-type-coverage.baseline.yaml => rpc-type-coverage-3.0.0.baseline.yaml} (94%) create mode 100644 packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.1.0.baseline.yaml diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json index 9dcadfab2..f576acc09 100644 --- a/packages/plugins/openapi/package.json +++ b/packages/plugins/openapi/package.json @@ -32,7 +32,9 @@ "change-case": "^4.1.2", "lower-case-first": "^2.0.2", "openapi-types": "^12.1.0", + "semver": "^7.3.8", "tiny-invariant": "^1.3.1", + "ts-pattern": "^4.3.0", "upper-case-first": "^2.0.2", "yaml": "^2.2.1", "zod": "^3.22.4", @@ -41,6 +43,7 @@ "devDependencies": { "@readme/openapi-parser": "^2.4.0", "@types/pluralize": "^0.0.29", + "@types/semver": "^7.3.13", "@types/tmp": "^0.2.3", "@zenstackhq/testtools": "workspace:*", "pluralize": "^8.0.0", diff --git a/packages/plugins/openapi/src/generator-base.ts b/packages/plugins/openapi/src/generator-base.ts index 5f3e5d933..d00c081fc 100644 --- a/packages/plugins/openapi/src/generator-base.ts +++ b/packages/plugins/openapi/src/generator-base.ts @@ -4,8 +4,11 @@ import { Model } from '@zenstackhq/sdk/ast'; import type { OpenAPIV3_1 as OAPI } from 'openapi-types'; import { fromZodError } from 'zod-validation-error'; import { SecuritySchemesSchema } from './schema'; +import semver from 'semver'; export abstract class OpenAPIGeneratorBase { + protected readonly DEFAULT_SPEC_VERSION = '3.1.0'; + constructor(protected model: Model, protected options: PluginOptions, protected dmmf: DMMF.Document) {} abstract generate(): string[]; @@ -25,6 +28,43 @@ export abstract class OpenAPIGeneratorBase { } } + protected wrapNullable( + schema: OAPI.ReferenceObject | OAPI.SchemaObject, + isNullable: boolean + ): OAPI.ReferenceObject | OAPI.SchemaObject { + if (!isNullable) { + return schema; + } + + const specVersion = this.getOption('specVersion', this.DEFAULT_SPEC_VERSION); + + // https://stackoverflow.com/questions/48111459/how-to-define-a-property-that-can-be-string-or-null-in-openapi-swagger + // https://stackoverflow.com/questions/40920441/how-to-specify-a-property-can-be-null-or-a-reference-with-swagger + if (semver.gte(specVersion, '3.1.0')) { + // OAPI 3.1.0 and above has native 'null' type + if ((schema as OAPI.BaseSchemaObject).oneOf) { + // merge into existing 'oneOf' + return { oneOf: [...(schema as OAPI.BaseSchemaObject).oneOf!, { type: 'null' }] }; + } else { + // wrap into a 'oneOf' + return { oneOf: [{ type: 'null' }, schema] }; + } + } else { + if ((schema as OAPI.ReferenceObject).$ref) { + // nullable $ref needs to be represented as: { allOf: [{ $ref: ... }], nullable: true } + return { + allOf: [schema], + nullable: true, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + } else { + // nullable scalar: { type: ..., nullable: true } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return { ...schema, nullable: true } as any; + } + } + } + protected array(itemType: OAPI.SchemaObject | OAPI.ReferenceObject) { return { type: 'array', items: itemType } as const; } diff --git a/packages/plugins/openapi/src/rest-generator.ts b/packages/plugins/openapi/src/rest-generator.ts index 70b2dd18a..9dceeec3e 100644 --- a/packages/plugins/openapi/src/rest-generator.ts +++ b/packages/plugins/openapi/src/rest-generator.ts @@ -12,12 +12,13 @@ import { resolvePath, } from '@zenstackhq/sdk'; import { DataModel, DataModelField, DataModelFieldType, Enum, isDataModel, isEnum } from '@zenstackhq/sdk/ast'; -import * as fs from 'fs'; +import fs from 'fs'; import { lowerCaseFirst } from 'lower-case-first'; import type { OpenAPIV3_1 as OAPI } from 'openapi-types'; -import * as path from 'path'; +import path from 'path'; import pluralize from 'pluralize'; import invariant from 'tiny-invariant'; +import { P, match } from 'ts-pattern'; import YAML from 'yaml'; import { name } from '.'; import { OpenAPIGeneratorBase } from './generator-base'; @@ -49,7 +50,7 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { } const openapi: OAPI.Document = { - openapi: this.getOption('specVersion', '3.1.0'), + openapi: this.getOption('specVersion', this.DEFAULT_SPEC_VERSION), info: { title: this.getOption('title', 'ZenStack Generated API'), version: this.getOption('version', '1.0.0'), @@ -483,9 +484,8 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { schema = this.fieldTypeToOpenAPISchema(field.type); } } - if (array) { - schema = { type: 'array', items: schema }; - } + + schema = this.wrapArray(schema, array); return { name: name === 'id' ? 'filter[id]' : `filter[${field.name}${name}]`, @@ -576,10 +576,10 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { description: 'Pagination information', required: ['first', 'last', 'prev', 'next'], properties: { - first: this.nullable({ type: 'string', description: 'Link to the first page' }), - last: this.nullable({ type: 'string', description: 'Link to the last page' }), - prev: this.nullable({ type: 'string', description: 'Link to the previous page' }), - next: this.nullable({ type: 'string', description: 'Link to the next page' }), + first: this.wrapNullable({ type: 'string', description: 'Link to the first page' }, true), + last: this.wrapNullable({ type: 'string', description: 'Link to the last page' }, true), + prev: this.wrapNullable({ type: 'string', description: 'Link to the previous page' }, true), + next: this.wrapNullable({ type: 'string', description: 'Link to the next page' }, true), }, }, _errors: { @@ -634,7 +634,7 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { type: 'object', description: 'A to-one relationship', properties: { - data: this.nullable(this.ref('_resourceIdentifier')), + data: this.wrapNullable(this.ref('_resourceIdentifier'), true), }, }, _toOneRelationshipWithLinks: { @@ -643,7 +643,7 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { description: 'A to-one relationship with links', properties: { links: this.ref('_relationLinks'), - data: this.nullable(this.ref('_resourceIdentifier')), + data: this.wrapNullable(this.ref('_resourceIdentifier'), true), }, }, _toManyRelationship: { @@ -680,13 +680,16 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { }, _toOneRelationshipRequest: { description: 'Input for manipulating a to-one relationship', - ...this.nullable({ - type: 'object', - required: ['data'], - properties: { - data: this.ref('_resourceIdentifier'), + ...this.wrapNullable( + { + type: 'object', + required: ['data'], + properties: { + data: this.ref('_resourceIdentifier'), + }, }, - }), + true + ), }, _toManyRelationshipResponse: { description: 'Response for a to-many relationship', @@ -841,7 +844,7 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { const fields = model.fields.filter((f) => !isIdField(f)); const attributes: Record = {}; - const relationships: Record = {}; + const relationships: Record = {}; const required: string[] = []; @@ -853,7 +856,7 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { } else { relType = field.type.array ? '_toManyRelationshipWithLinks' : '_toOneRelationshipWithLinks'; } - relationships[field.name] = this.ref(relType); + relationships[field.name] = this.wrapNullable(this.ref(relType), field.type.optional); } else { attributes[field.name] = this.generateField(field); if ( @@ -911,48 +914,33 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase { } private generateField(field: DataModelField) { - return this.wrapArray(this.fieldTypeToOpenAPISchema(field.type), field.type.array); - } - - private get specVersion() { - return this.getOption('specVersion', '3.0.0'); + return this.wrapArray( + this.wrapNullable(this.fieldTypeToOpenAPISchema(field.type), field.type.optional), + field.type.array + ); } private fieldTypeToOpenAPISchema(type: DataModelFieldType): OAPI.ReferenceObject | OAPI.SchemaObject { - switch (type.type) { - case 'String': - return { type: 'string' }; - case 'Int': - case 'BigInt': - return { type: 'integer' }; - case 'Float': - return { type: 'number' }; - case 'Decimal': - return this.oneOf({ type: 'number' }, { type: 'string' }); - case 'Boolean': - return { type: 'boolean' }; - case 'DateTime': - return { type: 'string', format: 'date-time' }; - case 'Bytes': - return { type: 'string', format: 'byte', description: 'Base64 encoded byte array' }; - case 'Json': - return {}; - default: { + return match(type.type) + .with('String', () => ({ type: 'string' })) + .with(P.union('Int', 'BigInt'), () => ({ type: 'integer' })) + .with('Float', () => ({ type: 'number' })) + .with('Decimal', () => this.oneOf({ type: 'number' }, { type: 'string' })) + .with('Boolean', () => ({ type: 'boolean' })) + .with('DateTime', () => ({ type: 'string', format: 'date-time' })) + .with('Bytes', () => ({ type: 'string', format: 'byte', description: 'Base64 encoded byte array' })) + .with('Json', () => ({})) + .otherwise((t) => { const fieldDecl = type.reference?.ref; - invariant(fieldDecl); + invariant(fieldDecl, `Type ${t} is not a model reference`); return this.ref(fieldDecl?.name); - } - } + }); } private ref(type: string) { return { $ref: `#/components/schemas/${type}` }; } - private nullable(schema: OAPI.SchemaObject | OAPI.ReferenceObject) { - return this.specVersion === '3.0.0' ? { ...schema, nullable: true } : this.oneOf(schema, { type: 'null' }); - } - private parameter(type: string) { return { $ref: `#/components/parameters/${type}` }; } diff --git a/packages/plugins/openapi/src/rpc-generator.ts b/packages/plugins/openapi/src/rpc-generator.ts index 207dd66bf..13bb91272 100644 --- a/packages/plugins/openapi/src/rpc-generator.ts +++ b/packages/plugins/openapi/src/rpc-generator.ts @@ -16,6 +16,7 @@ import { lowerCaseFirst } from 'lower-case-first'; import type { OpenAPIV3_1 as OAPI } from 'openapi-types'; import * as path from 'path'; import invariant from 'tiny-invariant'; +import { match, P } from 'ts-pattern'; import { upperCaseFirst } from 'upper-case-first'; import YAML from 'yaml'; import { name } from '.'; @@ -62,7 +63,7 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { this.pruneComponents(paths, components); const openapi: OAPI.Document = { - openapi: this.getOption('specVersion', '3.1.0'), + openapi: this.getOption('specVersion', this.DEFAULT_SPEC_VERSION), info: { title: this.getOption('title', 'ZenStack Generated API'), version: this.getOption('version', '1.0.0'), @@ -710,14 +711,14 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { return result; } - private generateField(def: { kind: DMMF.FieldKind; type: string; isList: boolean }) { + private generateField(def: { kind: DMMF.FieldKind; type: string; isList: boolean; isRequired: boolean }) { switch (def.kind) { case 'scalar': - return this.wrapArray(this.prismaTypeToOpenAPIType(def.type), def.isList); + return this.wrapArray(this.prismaTypeToOpenAPIType(def.type, !def.isRequired), def.isList); case 'enum': case 'object': - return this.wrapArray(this.ref(def.type, false), def.isList); + return this.wrapArray(this.wrapNullable(this.ref(def.type, false), !def.isRequired), def.isList); default: throw new PluginError(this.options.name, `Unsupported field kind: ${def.kind}`); @@ -735,9 +736,18 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { f.location !== 'fieldRefTypes' ) .map((f) => { - return this.wrapArray(this.prismaTypeToOpenAPIType(f.type), f.isList); + return this.wrapArray(this.prismaTypeToOpenAPIType(f.type, false), f.isList); }); - properties[field.name] = options.length > 1 ? { oneOf: options } : options[0]; + + let prop = options.length > 1 ? { oneOf: options } : options[0]; + + // if types include 'Null', make it nullable + prop = this.wrapNullable( + prop, + field.inputTypes.some((f) => f.type === 'Null') + ); + + properties[field.name] = prop; } const result: OAPI.SchemaObject = { type: 'object', properties }; @@ -752,11 +762,12 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { switch (field.outputType.location) { case 'scalar': case 'enumTypes': - outputType = this.prismaTypeToOpenAPIType(field.outputType.type); + outputType = this.prismaTypeToOpenAPIType(field.outputType.type, !!field.isNullable); break; case 'outputObjectTypes': outputType = this.prismaTypeToOpenAPIType( - typeof field.outputType.type === 'string' ? field.outputType.type : field.outputType.type.name + typeof field.outputType.type === 'string' ? field.outputType.type : field.outputType.type.name, + !!field.isNullable ); break; } @@ -786,30 +797,19 @@ export class RPCOpenAPIGenerator extends OpenAPIGeneratorBase { } } - private prismaTypeToOpenAPIType(type: DMMF.ArgType): OAPI.ReferenceObject | OAPI.SchemaObject { - switch (type) { - case 'String': - return { type: 'string' }; - case 'Int': - case 'BigInt': - return { type: 'integer' }; - case 'Float': - return { type: 'number' }; - case 'Decimal': - return this.oneOf({ type: 'string' }, { type: 'number' }); - case 'Boolean': - case 'True': - return { type: 'boolean' }; - case 'DateTime': - return { type: 'string', format: 'date-time' }; - case 'Bytes': - return { type: 'string', format: 'byte' }; - case 'JSON': - case 'Json': - return {}; - default: - return this.ref(type.toString(), false); - } + private prismaTypeToOpenAPIType(type: DMMF.ArgType, nullable: boolean): OAPI.ReferenceObject | OAPI.SchemaObject { + const result = match(type) + .with('String', () => ({ type: 'string' })) + .with(P.union('Int', 'BigInt'), () => ({ type: 'integer' })) + .with('Float', () => ({ type: 'number' })) + .with('Decimal', () => this.oneOf({ type: 'string' }, { type: 'number' })) + .with(P.union('Boolean', 'True'), () => ({ type: 'boolean' })) + .with('DateTime', () => ({ type: 'string', format: 'date-time' })) + .with('Bytes', () => ({ type: 'string', format: 'byte' })) + .with(P.union('JSON', 'Json'), () => ({})) + .otherwise((type) => this.ref(type.toString(), false)); + + return this.wrapNullable(result, nullable); } private ref(type: string, rooted = true, description?: string): OAPI.ReferenceObject { diff --git a/packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml new file mode 100644 index 000000000..2bdc154a5 --- /dev/null +++ b/packages/plugins/openapi/tests/baseline/rest-3.0.0.baseline.yaml @@ -0,0 +1,2599 @@ +openapi: 3.0.0 +info: + title: ZenStack Generated API + version: 1.0.0 +tags: + - name: user + description: User operations + - name: profile + description: Profile operations + - name: post_Item + description: Post-related operations +paths: + /user: + get: + operationId: list-User + description: List "User" resources + tags: + - user + parameters: + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[id] + required: false + description: Id filter + in: query + style: form + explode: false + schema: + type: string + - name: filter[createdAt] + required: false + description: Equality filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$lt] + required: false + description: Less-than filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$lte] + required: false + description: Less-than or equal filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$gt] + required: false + description: Greater-than filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$gte] + required: false + description: Greater-than or equal filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt] + required: false + description: Equality filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$lt] + required: false + description: Less-than filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$lte] + required: false + description: Less-than or equal filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$gt] + required: false + description: Greater-than filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$gte] + required: false + description: Greater-than or equal filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[email] + required: false + description: Equality filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$contains] + required: false + description: String contains filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$icontains] + required: false + description: String case-insensitive contains filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$search] + required: false + description: String full-text search filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$startsWith] + required: false + description: String startsWith filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$endsWith] + required: false + description: String endsWith filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[role] + required: false + description: Equality filter for "role" + in: query + style: form + explode: false + schema: + $ref: '#/components/schemas/role' + - name: filter[posts] + required: false + description: Equality filter for "posts" + in: query + style: form + explode: false + schema: + type: array + items: + type: string + - name: filter[profile] + required: false + description: Equality filter for "profile" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserListResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + post: + operationId: create-User + description: Create a "User" resource + tags: + - user + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserCreateRequest' + responses: + '201': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/user/{id}': + get: + operationId: fetch-User + description: Fetch a "User" resource + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-User-put + description: Update a "User" resource + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-User-patch + description: Update a "User" resource + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + delete: + operationId: delete-User + description: Delete a "User" resource + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/user/{id}/posts': + get: + operationId: fetch-User-related-posts + description: Fetch the related "posts" resource for "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[id] + required: false + description: Id filter + in: query + style: form + explode: false + schema: + type: string + - name: filter[createdAt] + required: false + description: Equality filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$lt] + required: false + description: Less-than filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$lte] + required: false + description: Less-than or equal filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$gt] + required: false + description: Greater-than filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$gte] + required: false + description: Greater-than or equal filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt] + required: false + description: Equality filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$lt] + required: false + description: Less-than filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$lte] + required: false + description: Less-than or equal filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$gt] + required: false + description: Greater-than filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$gte] + required: false + description: Greater-than or equal filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[email] + required: false + description: Equality filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$contains] + required: false + description: String contains filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$icontains] + required: false + description: String case-insensitive contains filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$search] + required: false + description: String full-text search filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$startsWith] + required: false + description: String startsWith filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$endsWith] + required: false + description: String endsWith filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[role] + required: false + description: Equality filter for "role" + in: query + style: form + explode: false + schema: + $ref: '#/components/schemas/role' + - name: filter[posts] + required: false + description: Equality filter for "posts" + in: query + style: form + explode: false + schema: + type: array + items: + type: string + - name: filter[profile] + required: false + description: Equality filter for "profile" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemListResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/user/{id}/relationships/posts': + get: + operationId: fetch-User-relationship-posts + description: Fetch the "posts" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[id] + required: false + description: Id filter + in: query + style: form + explode: false + schema: + type: string + - name: filter[createdAt] + required: false + description: Equality filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$lt] + required: false + description: Less-than filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$lte] + required: false + description: Less-than or equal filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$gt] + required: false + description: Greater-than filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$gte] + required: false + description: Greater-than or equal filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt] + required: false + description: Equality filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$lt] + required: false + description: Less-than filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$lte] + required: false + description: Less-than or equal filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$gt] + required: false + description: Greater-than filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$gte] + required: false + description: Greater-than or equal filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[email] + required: false + description: Equality filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$contains] + required: false + description: String contains filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$icontains] + required: false + description: String case-insensitive contains filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$search] + required: false + description: String full-text search filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$startsWith] + required: false + description: String startsWith filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[email$endsWith] + required: false + description: String endsWith filter for "email" + in: query + style: form + explode: false + schema: + type: string + - name: filter[role] + required: false + description: Equality filter for "role" + in: query + style: form + explode: false + schema: + $ref: '#/components/schemas/role' + - name: filter[posts] + required: false + description: Equality filter for "posts" + in: query + style: form + explode: false + schema: + type: array + items: + type: string + - name: filter[profile] + required: false + description: Equality filter for "profile" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-User-relationship-posts-put + description: Update "posts" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-User-relationship-posts-patch + description: Update "posts" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + post: + operationId: create-User-relationship-posts + description: Create new "posts" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/user/{id}/profile': + get: + operationId: fetch-User-related-profile + description: Fetch the related "profile" resource for "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/user/{id}/relationships/profile': + get: + operationId: fetch-User-relationship-profile + description: Fetch the "profile" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-User-relationship-profile-put + description: Update "profile" relationship for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-User-relationship-profile-patch + description: Update "profile" relationship for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /profile: + get: + operationId: list-Profile + description: List "Profile" resources + tags: + - profile + parameters: + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[id] + required: false + description: Id filter + in: query + style: form + explode: false + schema: + type: string + - name: filter[image] + required: false + description: Equality filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$contains] + required: false + description: String contains filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$icontains] + required: false + description: String case-insensitive contains filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$search] + required: false + description: String full-text search filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$startsWith] + required: false + description: String startsWith filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$endsWith] + required: false + description: String endsWith filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[user] + required: false + description: Equality filter for "user" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileListResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + post: + operationId: create-Profile + description: Create a "Profile" resource + tags: + - profile + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileCreateRequest' + responses: + '201': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/profile/{id}': + get: + operationId: fetch-Profile + description: Fetch a "Profile" resource + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-Profile-put + description: Update a "Profile" resource + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-Profile-patch + description: Update a "Profile" resource + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + delete: + operationId: delete-Profile + description: Delete a "Profile" resource + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/profile/{id}/user': + get: + operationId: fetch-Profile-related-user + description: Fetch the related "user" resource for "Profile" + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/profile/{id}/relationships/user': + get: + operationId: fetch-Profile-relationship-user + description: Fetch the "user" relationships for a "Profile" + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-Profile-relationship-user-put + description: Update "user" relationship for a "Profile" + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-Profile-relationship-user-patch + description: Update "user" relationship for a "Profile" + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /post_Item: + get: + operationId: list-post_Item + description: List "post_Item" resources + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[id] + required: false + description: Id filter + in: query + style: form + explode: false + schema: + type: string + - name: filter[createdAt] + required: false + description: Equality filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$lt] + required: false + description: Less-than filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$lte] + required: false + description: Less-than or equal filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$gt] + required: false + description: Greater-than filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[createdAt$gte] + required: false + description: Greater-than or equal filter for "createdAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt] + required: false + description: Equality filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$lt] + required: false + description: Less-than filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$lte] + required: false + description: Less-than or equal filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$gt] + required: false + description: Greater-than filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[updatedAt$gte] + required: false + description: Greater-than or equal filter for "updatedAt" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[title] + required: false + description: Equality filter for "title" + in: query + style: form + explode: false + schema: + type: string + - name: filter[title$contains] + required: false + description: String contains filter for "title" + in: query + style: form + explode: false + schema: + type: string + - name: filter[title$icontains] + required: false + description: String case-insensitive contains filter for "title" + in: query + style: form + explode: false + schema: + type: string + - name: filter[title$search] + required: false + description: String full-text search filter for "title" + in: query + style: form + explode: false + schema: + type: string + - name: filter[title$startsWith] + required: false + description: String startsWith filter for "title" + in: query + style: form + explode: false + schema: + type: string + - name: filter[title$endsWith] + required: false + description: String endsWith filter for "title" + in: query + style: form + explode: false + schema: + type: string + - name: filter[author] + required: false + description: Equality filter for "author" + in: query + style: form + explode: false + schema: + type: string + - name: filter[published] + required: false + description: Equality filter for "published" + in: query + style: form + explode: false + schema: + type: boolean + - name: filter[viewCount] + required: false + description: Equality filter for "viewCount" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[viewCount$lt] + required: false + description: Less-than filter for "viewCount" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[viewCount$lte] + required: false + description: Less-than or equal filter for "viewCount" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[viewCount$gt] + required: false + description: Greater-than filter for "viewCount" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[viewCount$gte] + required: false + description: Greater-than or equal filter for "viewCount" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[notes] + required: false + description: Equality filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$contains] + required: false + description: String contains filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$icontains] + required: false + description: String case-insensitive contains filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$search] + required: false + description: String full-text search filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$startsWith] + required: false + description: String startsWith filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$endsWith] + required: false + description: String endsWith filter for "notes" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemListResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + post: + operationId: create-post_Item + description: Create a "post_Item" resource + tags: + - post_Item + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemCreateRequest' + responses: + '201': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/post_Item/{id}': + get: + operationId: fetch-post_Item + description: Fetch a "post_Item" resource + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-post_Item-put + description: Update a "post_Item" resource + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-post_Item-patch + description: Update a "post_Item" resource + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/post_ItemResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + delete: + operationId: delete-post_Item + description: Delete a "post_Item" resource + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/post_Item/{id}/author': + get: + operationId: fetch-post_Item-related-author + description: Fetch the related "author" resource for "post_Item" + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/post_Item/{id}/relationships/author': + get: + operationId: fetch-post_Item-relationship-author + description: Fetch the "author" relationships for a "post_Item" + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-post_Item-relationship-author-put + description: Update "author" relationship for a "post_Item" + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-post_Item-relationship-author-patch + description: Update "author" relationship for a "post_Item" + tags: + - post_Item + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' +components: + schemas: + _jsonapi: + type: object + description: An object describing the server’s implementation + required: + - version + properties: + version: + type: string + _meta: + type: object + description: Meta information about the request or response + properties: + serialization: + description: Superjson serialization metadata + additionalProperties: true + _resourceIdentifier: + type: object + description: Identifier for a resource + required: + - type + - id + properties: + type: + type: string + description: Resource type + id: + type: string + description: Resource id + _resource: + allOf: + - $ref: '#/components/schemas/_resourceIdentifier' + - type: object + description: A resource with attributes and relationships + properties: + attributes: + type: object + description: Resource attributes + relationships: + type: object + description: Resource relationships + _links: + type: object + required: + - self + description: Links related to the resource + properties: + self: + type: string + description: Link for refetching the curent results + _pagination: + type: object + description: Pagination information + required: + - first + - last + - prev + - next + properties: + first: + type: string + description: Link to the first page + nullable: true + last: + type: string + description: Link to the last page + nullable: true + prev: + type: string + description: Link to the previous page + nullable: true + next: + type: string + description: Link to the next page + nullable: true + _errors: + type: array + description: An array of error objects + items: + type: object + required: + - status + - code + properties: + status: + type: string + description: HTTP status + code: + type: string + description: Error code + prismaCode: + type: string + description: Prisma error code if the error is thrown by Prisma + title: + type: string + description: Error title + detail: + type: string + description: Error detail + reason: + type: string + description: Detailed error reason + zodErrors: + type: object + additionalProperties: true + description: Zod validation errors if the error is due to data validation + failure + _errorResponse: + type: object + required: + - errors + description: An error response + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + errors: + $ref: '#/components/schemas/_errors' + _relationLinks: + type: object + required: + - self + - related + description: Links related to a relationship + properties: + self: + type: string + description: Link for fetching this relationship + related: + type: string + description: Link for fetching the resource represented by this relationship + _toOneRelationship: + type: object + description: A to-one relationship + properties: + data: + allOf: + - $ref: '#/components/schemas/_resourceIdentifier' + nullable: true + _toOneRelationshipWithLinks: + type: object + required: + - links + - data + description: A to-one relationship with links + properties: + links: + $ref: '#/components/schemas/_relationLinks' + data: + allOf: + - $ref: '#/components/schemas/_resourceIdentifier' + nullable: true + _toManyRelationship: + type: object + required: + - data + description: A to-many relationship + properties: + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _toManyRelationshipWithLinks: + type: object + required: + - links + - data + description: A to-many relationship with links + properties: + links: + $ref: '#/components/schemas/_pagedRelationLinks' + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _pagedRelationLinks: + description: Relationship links with pagination information + allOf: + - $ref: '#/components/schemas/_pagination' + - $ref: '#/components/schemas/_relationLinks' + _toManyRelationshipRequest: + type: object + required: + - data + description: Input for manipulating a to-many relationship + properties: + data: + type: array + items: + $ref: '#/components/schemas/_resourceIdentifier' + _toOneRelationshipRequest: + description: Input for manipulating a to-one relationship + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/_resourceIdentifier' + nullable: true + _toManyRelationshipResponse: + description: Response for a to-many relationship + allOf: + - $ref: '#/components/schemas/_toManyRelationshipWithLinks' + - type: object + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + _toOneRelationshipResponse: + description: Response for a to-one relationship + allOf: + - $ref: '#/components/schemas/_toOneRelationshipWithLinks' + - type: object + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + role: + type: string + description: The "role" Enum + enum: + - USER + - ADMIN + User: + type: object + description: The "User" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/role' + relationships: + type: object + properties: + posts: + $ref: '#/components/schemas/_toManyRelationshipWithLinks' + profile: + allOf: + - $ref: '#/components/schemas/_toOneRelationshipWithLinks' + nullable: true + UserCreateRequest: + type: object + description: Input for creating a "User" + required: + - data + properties: + data: + type: object + description: The "User" model + required: + - type + - attributes + properties: + type: + type: string + attributes: + type: object + required: + - updatedAt + - email + properties: + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/role' + relationships: + type: object + properties: + posts: + $ref: '#/components/schemas/_toManyRelationship' + profile: + allOf: + - $ref: '#/components/schemas/_toOneRelationship' + nullable: true + meta: + $ref: '#/components/schemas/_meta' + UserUpdateRequest: + type: object + description: Input for updating a "User" + required: + - data + properties: + data: + type: object + description: The "User" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/role' + relationships: + type: object + properties: + posts: + $ref: '#/components/schemas/_toManyRelationship' + profile: + allOf: + - $ref: '#/components/schemas/_toOneRelationship' + nullable: true + meta: + $ref: '#/components/schemas/_meta' + UserResponse: + type: object + description: Response for a "User" + required: + - data + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + allOf: + - $ref: '#/components/schemas/User' + - type: object + properties: + relationships: + type: object + properties: &a1 + posts: + $ref: '#/components/schemas/_toManyRelationship' + profile: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + $ref: '#/components/schemas/_links' + UserListResponse: + type: object + description: Response for a list of "User" + required: + - data + - links + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + type: array + items: + allOf: + - $ref: '#/components/schemas/User' + - type: object + properties: + relationships: + type: object + properties: *a1 + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + allOf: + - $ref: '#/components/schemas/_links' + - $ref: '#/components/schemas/_pagination' + Profile: + type: object + description: The "Profile" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + image: + type: string + nullable: true + userId: + type: string + relationships: + type: object + properties: + user: + $ref: '#/components/schemas/_toOneRelationshipWithLinks' + ProfileCreateRequest: + type: object + description: Input for creating a "Profile" + required: + - data + properties: + data: + type: object + description: The "Profile" model + required: + - type + - attributes + properties: + type: + type: string + attributes: + type: object + required: + - userId + properties: + image: + type: string + nullable: true + userId: + type: string + relationships: + type: object + properties: + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + ProfileUpdateRequest: + type: object + description: Input for updating a "Profile" + required: + - data + properties: + data: + type: object + description: The "Profile" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + image: + type: string + nullable: true + userId: + type: string + relationships: + type: object + properties: + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + ProfileResponse: + type: object + description: Response for a "Profile" + required: + - data + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + allOf: + - $ref: '#/components/schemas/Profile' + - type: object + properties: + relationships: + type: object + properties: &a2 + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + $ref: '#/components/schemas/_links' + ProfileListResponse: + type: object + description: Response for a list of "Profile" + required: + - data + - links + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + type: array + items: + allOf: + - $ref: '#/components/schemas/Profile' + - type: object + properties: + relationships: + type: object + properties: *a2 + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + allOf: + - $ref: '#/components/schemas/_links' + - $ref: '#/components/schemas/_pagination' + post_Item: + type: object + description: The "post_Item" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + authorId: + type: string + nullable: true + published: + type: boolean + viewCount: + type: integer + notes: + type: string + nullable: true + relationships: + type: object + properties: + author: + allOf: + - $ref: '#/components/schemas/_toOneRelationshipWithLinks' + nullable: true + post_ItemCreateRequest: + type: object + description: Input for creating a "post_Item" + required: + - data + properties: + data: + type: object + description: The "post_Item" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + required: + - updatedAt + - title + properties: + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + authorId: + type: string + nullable: true + published: + type: boolean + viewCount: + type: integer + notes: + type: string + nullable: true + relationships: + type: object + properties: + author: + allOf: + - $ref: '#/components/schemas/_toOneRelationship' + nullable: true + meta: + $ref: '#/components/schemas/_meta' + post_ItemUpdateRequest: + type: object + description: Input for updating a "post_Item" + required: + - data + properties: + data: + type: object + description: The "post_Item" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + authorId: + type: string + nullable: true + published: + type: boolean + viewCount: + type: integer + notes: + type: string + nullable: true + relationships: + type: object + properties: + author: + allOf: + - $ref: '#/components/schemas/_toOneRelationship' + nullable: true + meta: + $ref: '#/components/schemas/_meta' + post_ItemResponse: + type: object + description: Response for a "post_Item" + required: + - data + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + allOf: + - $ref: '#/components/schemas/post_Item' + - type: object + properties: + relationships: + type: object + properties: &a3 + author: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + $ref: '#/components/schemas/_links' + post_ItemListResponse: + type: object + description: Response for a list of "post_Item" + required: + - data + - links + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + type: array + items: + allOf: + - $ref: '#/components/schemas/post_Item' + - type: object + properties: + relationships: + type: object + properties: *a3 + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + allOf: + - $ref: '#/components/schemas/_links' + - $ref: '#/components/schemas/_pagination' + parameters: + id: + name: id + in: path + description: The resource id + required: true + schema: + type: string + include: + name: include + in: query + description: Relationships to include + required: false + style: form + schema: + type: string + sort: + name: sort + in: query + description: Fields to sort by + required: false + style: form + schema: + type: string + page-offset: + name: page[offset] + in: query + description: Offset for pagination + required: false + style: form + schema: + type: integer + page-limit: + name: page[limit] + in: query + description: Limit for pagination + required: false + style: form + schema: + type: integer diff --git a/packages/plugins/openapi/tests/baseline/rest.baseline.yaml b/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml similarity index 71% rename from packages/plugins/openapi/tests/baseline/rest.baseline.yaml rename to packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml index 3421150c9..ea85b4aa3 100644 --- a/packages/plugins/openapi/tests/baseline/rest.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml @@ -5,6 +5,8 @@ info: tags: - name: user description: User operations + - name: profile + description: Profile operations - name: post_Item description: Post-related operations paths: @@ -183,6 +185,14 @@ paths: type: array items: type: string + - name: filter[profile] + required: false + description: Equality filter for "profile" + in: query + style: form + explode: false + schema: + type: string responses: '200': description: Successful operation @@ -507,6 +517,14 @@ paths: type: array items: type: string + - name: filter[profile] + required: false + description: Equality filter for "profile" + in: query + style: form + explode: false + schema: + type: string responses: '200': description: Successful operation @@ -701,13 +719,432 @@ paths: type: array items: type: string + - name: filter[profile] + required: false + description: Equality filter for "profile" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-User-relationship-posts-put + description: Update "posts" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-User-relationship-posts-patch + description: Update "posts" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + post: + operationId: create-User-relationship-posts + description: Create new "posts" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toManyRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/user/{id}/profile': + get: + operationId: fetch-User-related-profile + description: Fetch the related "profile" resource for "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/user/{id}/relationships/profile': + get: + operationId: fetch-User-relationship-profile + description: Fetch the "profile" relationships for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-User-relationship-profile-put + description: Update "profile" relationship for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-User-relationship-profile-patch + description: Update "profile" relationship for a "User" + tags: + - user + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + /profile: + get: + operationId: list-Profile + description: List "Profile" resources + tags: + - profile + parameters: + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[id] + required: false + description: Id filter + in: query + style: form + explode: false + schema: + type: string + - name: filter[image] + required: false + description: Equality filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$contains] + required: false + description: String contains filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$icontains] + required: false + description: String case-insensitive contains filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$search] + required: false + description: String full-text search filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$startsWith] + required: false + description: String startsWith filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[image$endsWith] + required: false + description: String endsWith filter for "image" + in: query + style: form + explode: false + schema: + type: string + - name: filter[user] + required: false + description: Equality filter for "user" + in: query + style: form + explode: false + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileListResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + post: + operationId: create-Profile + description: Create a "Profile" resource + tags: + - profile + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileCreateRequest' + responses: + '201': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/profile/{id}': + get: + operationId: fetch-Profile + description: Fetch a "Profile" resource + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-Profile-put + description: Update a "Profile" resource + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + patch: + operationId: update-Profile-patch + description: Update a "Profile" resource + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/ProfileUpdateRequest' responses: '200': description: Successful operation content: application/vnd.api+json: schema: - $ref: '#/components/schemas/_toManyRelationshipResponse' + $ref: '#/components/schemas/ProfileResponse' '403': description: Request is forbidden content: @@ -720,25 +1157,44 @@ paths: application/vnd.api+json: schema: $ref: '#/components/schemas/_errorResponse' - put: - operationId: update-User-relationship-posts-put - description: Update "posts" relationships for a "User" + delete: + operationId: delete-Profile + description: Delete a "Profile" resource tags: - - user + - profile parameters: - $ref: '#/components/parameters/id' - requestBody: - content: - application/vnd.api+json: - schema: - $ref: '#/components/schemas/_toManyRelationshipRequest' responses: '200': description: Successful operation + '403': + description: Request is forbidden content: application/vnd.api+json: schema: - $ref: '#/components/schemas/_toManyRelationshipResponse' + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '/profile/{id}/user': + get: + operationId: fetch-Profile-related-user + description: Fetch the related "user" resource for "Profile" + tags: + - profile + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/UserResponse' '403': description: Request is forbidden content: @@ -751,25 +1207,52 @@ paths: application/vnd.api+json: schema: $ref: '#/components/schemas/_errorResponse' - patch: - operationId: update-User-relationship-posts-patch - description: Update "posts" relationships for a "User" + '/profile/{id}/relationships/user': + get: + operationId: fetch-Profile-relationship-user + description: Fetch the "user" relationships for a "Profile" tags: - - user + - profile + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_toOneRelationshipResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + put: + operationId: update-Profile-relationship-user-put + description: Update "user" relationship for a "Profile" + tags: + - profile parameters: - $ref: '#/components/parameters/id' requestBody: content: application/vnd.api+json: schema: - $ref: '#/components/schemas/_toManyRelationshipRequest' + $ref: '#/components/schemas/_toOneRelationshipRequest' responses: '200': description: Successful operation content: application/vnd.api+json: schema: - $ref: '#/components/schemas/_toManyRelationshipResponse' + $ref: '#/components/schemas/_toOneRelationshipResponse' '403': description: Request is forbidden content: @@ -782,25 +1265,25 @@ paths: application/vnd.api+json: schema: $ref: '#/components/schemas/_errorResponse' - post: - operationId: create-User-relationship-posts - description: Create new "posts" relationships for a "User" + patch: + operationId: update-Profile-relationship-user-patch + description: Update "user" relationship for a "Profile" tags: - - user + - profile parameters: - $ref: '#/components/parameters/id' requestBody: content: application/vnd.api+json: schema: - $ref: '#/components/schemas/_toManyRelationshipRequest' + $ref: '#/components/schemas/_toOneRelationshipRequest' responses: '200': description: Successful operation content: application/vnd.api+json: schema: - $ref: '#/components/schemas/_toManyRelationshipResponse' + $ref: '#/components/schemas/_toOneRelationshipResponse' '403': description: Request is forbidden content: @@ -1026,6 +1509,54 @@ paths: explode: false schema: type: integer + - name: filter[notes] + required: false + description: Equality filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$contains] + required: false + description: String contains filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$icontains] + required: false + description: String case-insensitive contains filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$search] + required: false + description: String full-text search filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$startsWith] + required: false + description: String startsWith filter for "notes" + in: query + style: form + explode: false + schema: + type: string + - name: filter[notes$endsWith] + required: false + description: String endsWith filter for "notes" + in: query + style: form + explode: false + schema: + type: string responses: '200': description: Successful operation @@ -1353,24 +1884,24 @@ components: properties: first: oneOf: + - type: 'null' - type: string description: Link to the first page - - type: 'null' last: oneOf: + - type: 'null' - type: string description: Link to the last page - - type: 'null' prev: oneOf: + - type: 'null' - type: string description: Link to the previous page - - type: 'null' next: oneOf: + - type: 'null' - type: string description: Link to the next page - - type: 'null' _errors: type: array description: An array of error objects @@ -1432,8 +1963,8 @@ components: properties: data: oneOf: - - $ref: '#/components/schemas/_resourceIdentifier' - type: 'null' + - $ref: '#/components/schemas/_resourceIdentifier' _toOneRelationshipWithLinks: type: object required: @@ -1445,8 +1976,8 @@ components: $ref: '#/components/schemas/_relationLinks' data: oneOf: - - $ref: '#/components/schemas/_resourceIdentifier' - type: 'null' + - $ref: '#/components/schemas/_resourceIdentifier' _toManyRelationship: type: object required: @@ -1488,13 +2019,13 @@ components: _toOneRelationshipRequest: description: Input for manipulating a to-one relationship oneOf: + - type: 'null' - type: object required: - data properties: data: $ref: '#/components/schemas/_resourceIdentifier' - - type: 'null' _toManyRelationshipResponse: description: Response for a to-many relationship allOf: @@ -1547,6 +2078,10 @@ components: properties: posts: $ref: '#/components/schemas/_toManyRelationshipWithLinks' + profile: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/_toOneRelationshipWithLinks' UserCreateRequest: type: object description: Input for creating a "User" @@ -1583,6 +2118,10 @@ components: properties: posts: $ref: '#/components/schemas/_toManyRelationship' + profile: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/_toOneRelationship' meta: $ref: '#/components/schemas/_meta' UserUpdateRequest: @@ -1621,6 +2160,10 @@ components: properties: posts: $ref: '#/components/schemas/_toManyRelationship' + profile: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/_toOneRelationship' meta: $ref: '#/components/schemas/_meta' UserResponse: @@ -1641,6 +2184,8 @@ components: properties: &a1 posts: $ref: '#/components/schemas/_toManyRelationship' + profile: + $ref: '#/components/schemas/_toOneRelationship' meta: $ref: '#/components/schemas/_meta' included: @@ -1678,6 +2223,154 @@ components: allOf: - $ref: '#/components/schemas/_links' - $ref: '#/components/schemas/_pagination' + Profile: + type: object + description: The "Profile" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + image: + oneOf: + - type: 'null' + - type: string + userId: + type: string + relationships: + type: object + properties: + user: + $ref: '#/components/schemas/_toOneRelationshipWithLinks' + ProfileCreateRequest: + type: object + description: Input for creating a "Profile" + required: + - data + properties: + data: + type: object + description: The "Profile" model + required: + - type + - attributes + properties: + type: + type: string + attributes: + type: object + required: + - userId + properties: + image: + oneOf: + - type: 'null' + - type: string + userId: + type: string + relationships: + type: object + properties: + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + ProfileUpdateRequest: + type: object + description: Input for updating a "Profile" + required: + - data + properties: + data: + type: object + description: The "Profile" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + image: + oneOf: + - type: 'null' + - type: string + userId: + type: string + relationships: + type: object + properties: + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + ProfileResponse: + type: object + description: Response for a "Profile" + required: + - data + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + allOf: + - $ref: '#/components/schemas/Profile' + - type: object + properties: + relationships: + type: object + properties: &a2 + user: + $ref: '#/components/schemas/_toOneRelationship' + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + $ref: '#/components/schemas/_links' + ProfileListResponse: + type: object + description: Response for a list of "Profile" + required: + - data + - links + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + type: array + items: + allOf: + - $ref: '#/components/schemas/Profile' + - type: object + properties: + relationships: + type: object + properties: *a2 + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + allOf: + - $ref: '#/components/schemas/_links' + - $ref: '#/components/schemas/_pagination' post_Item: type: object description: The "post_Item" model @@ -1702,16 +2395,24 @@ components: title: type: string authorId: - type: string + oneOf: + - type: 'null' + - type: string published: type: boolean viewCount: type: integer + notes: + oneOf: + - type: 'null' + - type: string relationships: type: object properties: author: - $ref: '#/components/schemas/_toOneRelationshipWithLinks' + oneOf: + - type: 'null' + - $ref: '#/components/schemas/_toOneRelationshipWithLinks' post_ItemCreateRequest: type: object description: Input for creating a "post_Item" @@ -1745,16 +2446,24 @@ components: title: type: string authorId: - type: string + oneOf: + - type: 'null' + - type: string published: type: boolean viewCount: type: integer + notes: + oneOf: + - type: 'null' + - type: string relationships: type: object properties: author: - $ref: '#/components/schemas/_toOneRelationship' + oneOf: + - type: 'null' + - $ref: '#/components/schemas/_toOneRelationship' meta: $ref: '#/components/schemas/_meta' post_ItemUpdateRequest: @@ -1787,16 +2496,24 @@ components: title: type: string authorId: - type: string + oneOf: + - type: 'null' + - type: string published: type: boolean viewCount: type: integer + notes: + oneOf: + - type: 'null' + - type: string relationships: type: object properties: author: - $ref: '#/components/schemas/_toOneRelationship' + oneOf: + - type: 'null' + - $ref: '#/components/schemas/_toOneRelationship' meta: $ref: '#/components/schemas/_meta' post_ItemResponse: @@ -1814,7 +2531,7 @@ components: properties: relationships: type: object - properties: &a2 + properties: &a3 author: $ref: '#/components/schemas/_toOneRelationship' meta: @@ -1843,7 +2560,7 @@ components: properties: relationships: type: object - properties: *a2 + properties: *a3 meta: $ref: '#/components/schemas/_meta' included: diff --git a/packages/plugins/openapi/tests/baseline/rest-type-coverage-3.0.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rest-type-coverage-3.0.0.baseline.yaml new file mode 100644 index 000000000..a20233b24 --- /dev/null +++ b/packages/plugins/openapi/tests/baseline/rest-type-coverage-3.0.0.baseline.yaml @@ -0,0 +1,803 @@ +openapi: 3.0.0 +info: + title: ZenStack Generated API + version: 1.0.0 +tags: + - name: foo + description: Foo operations +paths: + /foo: + get: + operationId: list-Foo + description: List "Foo" resources + tags: + - foo + parameters: + - $ref: '#/components/parameters/include' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/page-offset' + - $ref: '#/components/parameters/page-limit' + - name: filter[id] + required: false + description: Id filter + in: query + style: form + explode: false + schema: + type: string + - name: filter[string] + required: false + description: Equality filter for "string" + in: query + style: form + explode: false + schema: + type: string + - name: filter[string$contains] + required: false + description: String contains filter for "string" + in: query + style: form + explode: false + schema: + type: string + - name: filter[string$icontains] + required: false + description: String case-insensitive contains filter for "string" + in: query + style: form + explode: false + schema: + type: string + - name: filter[string$search] + required: false + description: String full-text search filter for "string" + in: query + style: form + explode: false + schema: + type: string + - name: filter[string$startsWith] + required: false + description: String startsWith filter for "string" + in: query + style: form + explode: false + schema: + type: string + - name: filter[string$endsWith] + required: false + description: String endsWith filter for "string" + in: query + style: form + explode: false + schema: + type: string + - name: filter[int] + required: false + description: Equality filter for "int" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[int$lt] + required: false + description: Less-than filter for "int" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[int$lte] + required: false + description: Less-than or equal filter for "int" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[int$gt] + required: false + description: Greater-than filter for "int" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[int$gte] + required: false + description: Greater-than or equal filter for "int" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[bigInt] + required: false + description: Equality filter for "bigInt" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[bigInt$lt] + required: false + description: Less-than filter for "bigInt" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[bigInt$lte] + required: false + description: Less-than or equal filter for "bigInt" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[bigInt$gt] + required: false + description: Greater-than filter for "bigInt" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[bigInt$gte] + required: false + description: Greater-than or equal filter for "bigInt" + in: query + style: form + explode: false + schema: + type: integer + - name: filter[date] + required: false + description: Equality filter for "date" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[date$lt] + required: false + description: Less-than filter for "date" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[date$lte] + required: false + description: Less-than or equal filter for "date" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[date$gt] + required: false + description: Greater-than filter for "date" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[date$gte] + required: false + description: Greater-than or equal filter for "date" + in: query + style: form + explode: false + schema: + type: string + format: date-time + - name: filter[float] + required: false + description: Equality filter for "float" + in: query + style: form + explode: false + schema: + type: number + - name: filter[float$lt] + required: false + description: Less-than filter for "float" + in: query + style: form + explode: false + schema: + type: number + - name: filter[float$lte] + required: false + description: Less-than or equal filter for "float" + in: query + style: form + explode: false + schema: + type: number + - name: filter[float$gt] + required: false + description: Greater-than filter for "float" + in: query + style: form + explode: false + schema: + type: number + - name: filter[float$gte] + required: false + description: Greater-than or equal filter for "float" + in: query + style: form + explode: false + schema: + type: number + - name: filter[decimal] + required: false + description: Equality filter for "decimal" + in: query + style: form + explode: false + schema: + oneOf: + - type: number + - type: string + - name: filter[decimal$lt] + required: false + description: Less-than filter for "decimal" + in: query + style: form + explode: false + schema: + oneOf: + - type: number + - type: string + - name: filter[decimal$lte] + required: false + description: Less-than or equal filter for "decimal" + in: query + style: form + explode: false + schema: + oneOf: + - type: number + - type: string + - name: filter[decimal$gt] + required: false + description: Greater-than filter for "decimal" + in: query + style: form + explode: false + schema: + oneOf: + - type: number + - type: string + - name: filter[decimal$gte] + required: false + description: Greater-than or equal filter for "decimal" + in: query + style: form + explode: false + schema: + oneOf: + - type: number + - type: string + - name: filter[boolean] + required: false + description: Equality filter for "boolean" + in: query + style: form + explode: false + schema: + type: boolean + - name: filter[bytes] + required: false + description: Equality filter for "bytes" + in: query + style: form + explode: false + schema: + type: string + format: byte + description: Base64 encoded byte array + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/FooListResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + security: [] + post: + operationId: create-Foo + description: Create a "Foo" resource + tags: + - foo + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/FooCreateRequest' + responses: + '201': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/FooResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + security: [] + '/foo/{id}': + get: + operationId: fetch-Foo + description: Fetch a "Foo" resource + tags: + - foo + parameters: + - $ref: '#/components/parameters/id' + - $ref: '#/components/parameters/include' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/FooResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + security: [] + put: + operationId: update-Foo-put + description: Update a "Foo" resource + tags: + - foo + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/FooUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/FooResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + security: [] + patch: + operationId: update-Foo-patch + description: Update a "Foo" resource + tags: + - foo + parameters: + - $ref: '#/components/parameters/id' + requestBody: + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/FooUpdateRequest' + responses: + '200': + description: Successful operation + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/FooResponse' + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + security: [] + delete: + operationId: delete-Foo + description: Delete a "Foo" resource + tags: + - foo + parameters: + - $ref: '#/components/parameters/id' + responses: + '200': + description: Successful operation + '403': + description: Request is forbidden + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + '404': + description: Resource is not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/_errorResponse' + security: [] +components: + schemas: + _jsonapi: + type: object + description: An object describing the server’s implementation + required: + - version + properties: + version: + type: string + _meta: + type: object + description: Meta information about the request or response + properties: + serialization: + description: Superjson serialization metadata + additionalProperties: true + _resourceIdentifier: + type: object + description: Identifier for a resource + required: + - type + - id + properties: + type: + type: string + description: Resource type + id: + type: string + description: Resource id + _resource: + allOf: + - $ref: '#/components/schemas/_resourceIdentifier' + - type: object + description: A resource with attributes and relationships + properties: + attributes: + type: object + description: Resource attributes + relationships: + type: object + description: Resource relationships + _links: + type: object + required: + - self + description: Links related to the resource + properties: + self: + type: string + description: Link for refetching the curent results + _pagination: + type: object + description: Pagination information + required: + - first + - last + - prev + - next + properties: + first: + type: string + description: Link to the first page + nullable: true + last: + type: string + description: Link to the last page + nullable: true + prev: + type: string + description: Link to the previous page + nullable: true + next: + type: string + description: Link to the next page + nullable: true + _errors: + type: array + description: An array of error objects + items: + type: object + required: + - status + - code + properties: + status: + type: string + description: HTTP status + code: + type: string + description: Error code + prismaCode: + type: string + description: Prisma error code if the error is thrown by Prisma + title: + type: string + description: Error title + detail: + type: string + description: Error detail + reason: + type: string + description: Detailed error reason + zodErrors: + type: object + additionalProperties: true + description: Zod validation errors if the error is due to data validation + failure + _errorResponse: + type: object + required: + - errors + description: An error response + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + errors: + $ref: '#/components/schemas/_errors' + Foo: + type: object + description: The "Foo" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + string: + type: string + int: + type: integer + bigInt: + type: integer + date: + type: string + format: date-time + float: + type: number + decimal: + oneOf: + - type: number + - type: string + boolean: + type: boolean + bytes: + type: string + format: byte + description: Base64 encoded byte array + FooCreateRequest: + type: object + description: Input for creating a "Foo" + required: + - data + properties: + data: + type: object + description: The "Foo" model + required: + - type + - attributes + properties: + type: + type: string + attributes: + type: object + required: + - string + - int + - bigInt + - date + - float + - decimal + - boolean + - bytes + properties: + string: + type: string + int: + type: integer + bigInt: + type: integer + date: + type: string + format: date-time + float: + type: number + decimal: + oneOf: + - type: number + - type: string + boolean: + type: boolean + bytes: + type: string + format: byte + description: Base64 encoded byte array + meta: + $ref: '#/components/schemas/_meta' + FooUpdateRequest: + type: object + description: Input for updating a "Foo" + required: + - data + properties: + data: + type: object + description: The "Foo" model + required: + - id + - type + - attributes + properties: + id: + type: string + type: + type: string + attributes: + type: object + properties: + string: + type: string + int: + type: integer + bigInt: + type: integer + date: + type: string + format: date-time + float: + type: number + decimal: + oneOf: + - type: number + - type: string + boolean: + type: boolean + bytes: + type: string + format: byte + description: Base64 encoded byte array + meta: + $ref: '#/components/schemas/_meta' + FooResponse: + type: object + description: Response for a "Foo" + required: + - data + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + allOf: + - $ref: '#/components/schemas/Foo' + - type: object + properties: + relationships: + type: object + properties: &a1 {} + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + $ref: '#/components/schemas/_links' + FooListResponse: + type: object + description: Response for a list of "Foo" + required: + - data + - links + properties: + jsonapi: + $ref: '#/components/schemas/_jsonapi' + data: + type: array + items: + allOf: + - $ref: '#/components/schemas/Foo' + - type: object + properties: + relationships: + type: object + properties: *a1 + meta: + $ref: '#/components/schemas/_meta' + included: + type: array + items: + $ref: '#/components/schemas/_resource' + links: + allOf: + - $ref: '#/components/schemas/_links' + - $ref: '#/components/schemas/_pagination' + parameters: + id: + name: id + in: path + description: The resource id + required: true + schema: + type: string + include: + name: include + in: query + description: Relationships to include + required: false + style: form + schema: + type: string + sort: + name: sort + in: query + description: Fields to sort by + required: false + style: form + schema: + type: string + page-offset: + name: page[offset] + in: query + description: Offset for pagination + required: false + style: form + schema: + type: integer + page-limit: + name: page[limit] + in: query + description: Limit for pagination + required: false + style: form + schema: + type: integer diff --git a/packages/plugins/openapi/tests/baseline/rest-type-coverage.baseline.yaml b/packages/plugins/openapi/tests/baseline/rest-type-coverage-3.1.0.baseline.yaml similarity index 100% rename from packages/plugins/openapi/tests/baseline/rest-type-coverage.baseline.yaml rename to packages/plugins/openapi/tests/baseline/rest-type-coverage-3.1.0.baseline.yaml index c37e16697..30b1dc4f6 100644 --- a/packages/plugins/openapi/tests/baseline/rest-type-coverage.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rest-type-coverage-3.1.0.baseline.yaml @@ -522,24 +522,24 @@ components: properties: first: oneOf: + - type: 'null' - type: string description: Link to the first page - - type: 'null' last: oneOf: + - type: 'null' - type: string description: Link to the last page - - type: 'null' prev: oneOf: + - type: 'null' - type: string description: Link to the previous page - - type: 'null' next: oneOf: + - type: 'null' - type: string description: Link to the next page - - type: 'null' _errors: type: array description: An array of error objects diff --git a/packages/plugins/openapi/tests/baseline/rpc.baseline.yaml b/packages/plugins/openapi/tests/baseline/rpc-3.0.0.baseline.yaml similarity index 67% rename from packages/plugins/openapi/tests/baseline/rpc.baseline.yaml rename to packages/plugins/openapi/tests/baseline/rpc-3.0.0.baseline.yaml index 94d1445ce..0f936771e 100644 --- a/packages/plugins/openapi/tests/baseline/rpc.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rpc-3.0.0.baseline.yaml @@ -1,10 +1,12 @@ -openapi: 3.1.0 +openapi: 3.0.0 info: title: ZenStack Generated API version: 1.0.0 tags: - name: user description: User operations + - name: profile + description: Profile operations - name: post_Item description: Post-related operations components: @@ -22,6 +24,12 @@ components: - updatedAt - email - role + ProfileScalarFieldEnum: + type: string + enum: + - id + - image + - userId Post_ItemScalarFieldEnum: type: string enum: @@ -32,6 +40,7 @@ components: - authorId - published - viewCount + - notes SortOrder: type: string enum: @@ -66,12 +75,32 @@ components: type: array items: $ref: '#/components/schemas/Post_Item' + profile: + allOf: + - $ref: '#/components/schemas/Profile' + nullable: true required: - id - createdAt - updatedAt - email - role + Profile: + type: object + properties: + id: + type: string + image: + type: string + nullable: true + user: + $ref: '#/components/schemas/User' + userId: + type: string + required: + - id + - user + - userId Post_Item: type: object properties: @@ -86,13 +115,19 @@ components: title: type: string author: - $ref: '#/components/schemas/User' + allOf: + - $ref: '#/components/schemas/User' + nullable: true authorId: type: string + nullable: true published: type: boolean viewCount: type: integer + notes: + type: string + nullable: true required: - id - createdAt @@ -143,6 +178,11 @@ components: - $ref: '#/components/schemas/Role' posts: $ref: '#/components/schemas/Post_ItemListRelationFilter' + profile: + oneOf: + - $ref: '#/components/schemas/ProfileRelationFilter' + - $ref: '#/components/schemas/ProfileWhereInput' + nullable: true UserOrderByWithRelationInput: type: object properties: @@ -158,6 +198,8 @@ components: $ref: '#/components/schemas/SortOrder' posts: $ref: '#/components/schemas/Post_ItemOrderByRelationAggregateInput' + profile: + $ref: '#/components/schemas/ProfileOrderByWithRelationInput' UserWhereUniqueInput: type: object properties: @@ -206,6 +248,94 @@ components: oneOf: - $ref: '#/components/schemas/EnumroleWithAggregatesFilter' - $ref: '#/components/schemas/Role' + ProfileWhereInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/ProfileWhereInput' + - type: array + items: + $ref: '#/components/schemas/ProfileWhereInput' + OR: + type: array + items: + $ref: '#/components/schemas/ProfileWhereInput' + NOT: + oneOf: + - $ref: '#/components/schemas/ProfileWhereInput' + - type: array + items: + $ref: '#/components/schemas/ProfileWhereInput' + id: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + image: + oneOf: + - $ref: '#/components/schemas/StringNullableFilter' + - type: string + nullable: true + userId: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + user: + oneOf: + - $ref: '#/components/schemas/UserRelationFilter' + - $ref: '#/components/schemas/UserWhereInput' + ProfileOrderByWithRelationInput: + type: object + properties: + id: + $ref: '#/components/schemas/SortOrder' + image: + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' + userId: + $ref: '#/components/schemas/SortOrder' + user: + $ref: '#/components/schemas/UserOrderByWithRelationInput' + ProfileWhereUniqueInput: + type: object + properties: + id: + type: string + userId: + type: string + ProfileScalarWhereWithAggregatesInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + OR: + type: array + items: + $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + NOT: + oneOf: + - $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + id: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + image: + oneOf: + - $ref: '#/components/schemas/StringNullableWithAggregatesFilter' + - type: string + nullable: true + userId: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string Post_ItemWhereInput: type: object properties: @@ -247,6 +377,7 @@ components: oneOf: - $ref: '#/components/schemas/StringNullableFilter' - type: string + nullable: true published: oneOf: - $ref: '#/components/schemas/BoolFilter' @@ -255,10 +386,16 @@ components: oneOf: - $ref: '#/components/schemas/IntFilter' - type: integer + notes: + oneOf: + - $ref: '#/components/schemas/StringNullableFilter' + - type: string + nullable: true author: oneOf: - $ref: '#/components/schemas/UserRelationFilter' - $ref: '#/components/schemas/UserWhereInput' + nullable: true Post_ItemOrderByWithRelationInput: type: object properties: @@ -278,6 +415,10 @@ components: $ref: '#/components/schemas/SortOrder' viewCount: $ref: '#/components/schemas/SortOrder' + notes: + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' author: $ref: '#/components/schemas/UserOrderByWithRelationInput' Post_ItemWhereUniqueInput: @@ -326,6 +467,7 @@ components: oneOf: - $ref: '#/components/schemas/StringNullableWithAggregatesFilter' - type: string + nullable: true published: oneOf: - $ref: '#/components/schemas/BoolWithAggregatesFilter' @@ -334,6 +476,11 @@ components: oneOf: - $ref: '#/components/schemas/IntWithAggregatesFilter' - type: integer + notes: + oneOf: + - $ref: '#/components/schemas/StringNullableWithAggregatesFilter' + - type: string + nullable: true UserCreateInput: type: object properties: @@ -351,6 +498,8 @@ components: $ref: '#/components/schemas/Role' posts: $ref: '#/components/schemas/Post_ItemCreateNestedManyWithoutAuthorInput' + profile: + $ref: '#/components/schemas/ProfileCreateNestedOneWithoutUserInput' required: - email UserUpdateInput: @@ -380,6 +529,8 @@ components: - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' posts: $ref: '#/components/schemas/Post_ItemUpdateManyWithoutAuthorNestedInput' + profile: + $ref: '#/components/schemas/ProfileUpdateOneWithoutUserNestedInput' UserCreateManyInput: type: object properties: @@ -422,6 +573,56 @@ components: oneOf: - $ref: '#/components/schemas/Role' - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + ProfileCreateInput: + type: object + properties: + id: + type: string + image: + type: string + nullable: true + user: + $ref: '#/components/schemas/UserCreateNestedOneWithoutProfileInput' + required: + - user + ProfileUpdateInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + image: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true + user: + $ref: '#/components/schemas/UserUpdateOneRequiredWithoutProfileNestedInput' + ProfileCreateManyInput: + type: object + properties: + id: + type: string + image: + type: string + nullable: true + userId: + type: string + required: + - userId + ProfileUpdateManyMutationInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + image: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true Post_ItemCreateInput: type: object properties: @@ -439,6 +640,9 @@ components: type: boolean viewCount: type: integer + notes: + type: string + nullable: true author: $ref: '#/components/schemas/UserCreateNestedOneWithoutPostsInput' required: @@ -473,6 +677,11 @@ components: oneOf: - type: integer - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true author: $ref: '#/components/schemas/UserUpdateOneWithoutPostsNestedInput' Post_ItemCreateManyInput: @@ -490,10 +699,14 @@ components: type: string authorId: type: string + nullable: true published: type: boolean viewCount: type: integer + notes: + type: string + nullable: true required: - id - title @@ -526,6 +739,11 @@ components: oneOf: - type: integer - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true StringFilter: type: object properties: @@ -632,6 +850,17 @@ components: $ref: '#/components/schemas/Post_ItemWhereInput' none: $ref: '#/components/schemas/Post_ItemWhereInput' + ProfileRelationFilter: + type: object + properties: + is: + allOf: + - $ref: '#/components/schemas/ProfileWhereInput' + nullable: true + isNot: + allOf: + - $ref: '#/components/schemas/ProfileWhereInput' + nullable: true Post_ItemOrderByRelationAggregateInput: type: object properties: @@ -757,18 +986,21 @@ components: properties: equals: type: string + nullable: true in: oneOf: - type: array items: type: string - type: string + nullable: true notIn: oneOf: - type: array items: type: string - type: string + nullable: true lt: type: string lte: @@ -789,51 +1021,18 @@ components: oneOf: - type: string - $ref: '#/components/schemas/NestedStringNullableFilter' - BoolFilter: - type: object - properties: - equals: - type: boolean - not: - oneOf: - - type: boolean - - $ref: '#/components/schemas/NestedBoolFilter' - IntFilter: - type: object - properties: - equals: - type: integer - in: - oneOf: - - type: array - items: - type: integer - - type: integer - notIn: - oneOf: - - type: array - items: - type: integer - - type: integer - lt: - type: integer - lte: - type: integer - gt: - type: integer - gte: - type: integer - not: - oneOf: - - type: integer - - $ref: '#/components/schemas/NestedIntFilter' + nullable: true UserRelationFilter: type: object properties: is: - $ref: '#/components/schemas/UserWhereInput' + allOf: + - $ref: '#/components/schemas/UserWhereInput' + nullable: true isNot: - $ref: '#/components/schemas/UserWhereInput' + allOf: + - $ref: '#/components/schemas/UserWhereInput' + nullable: true SortOrderInput: type: object properties: @@ -848,18 +1047,21 @@ components: properties: equals: type: string + nullable: true in: oneOf: - type: array items: type: string - type: string + nullable: true notIn: oneOf: - type: array items: type: string - type: string + nullable: true lt: type: string lte: @@ -880,12 +1082,51 @@ components: oneOf: - type: string - $ref: '#/components/schemas/NestedStringNullableWithAggregatesFilter' + nullable: true _count: $ref: '#/components/schemas/NestedIntNullableFilter' _min: $ref: '#/components/schemas/NestedStringNullableFilter' _max: $ref: '#/components/schemas/NestedStringNullableFilter' + BoolFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolFilter' + IntFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntFilter' BoolWithAggregatesFilter: type: object properties: @@ -967,6 +1208,55 @@ components: - type: array items: $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + ProfileCreateNestedOneWithoutUserInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + connectOrCreate: + $ref: '#/components/schemas/ProfileCreateOrConnectWithoutUserInput' + connect: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + Post_ItemUncheckedCreateNestedManyWithoutAuthorInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + connectOrCreate: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + createMany: + $ref: '#/components/schemas/Post_ItemCreateManyAuthorInputEnvelope' + connect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + ProfileUncheckedCreateNestedOneWithoutUserInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + connectOrCreate: + $ref: '#/components/schemas/ProfileCreateOrConnectWithoutUserInput' + connect: + $ref: '#/components/schemas/ProfileWhereUniqueInput' StringFieldUpdateOperationsInput: type: object properties: @@ -1052,17 +1342,162 @@ components: - type: array items: $ref: '#/components/schemas/Post_ItemScalarWhereInput' - UserCreateNestedOneWithoutPostsInput: + ProfileUpdateOneWithoutUserNestedInput: type: object properties: create: oneOf: - - $ref: '#/components/schemas/UserCreateWithoutPostsInput' - - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' connectOrCreate: - $ref: '#/components/schemas/UserCreateOrConnectWithoutPostsInput' + $ref: '#/components/schemas/ProfileCreateOrConnectWithoutUserInput' + upsert: + $ref: '#/components/schemas/ProfileUpsertWithoutUserInput' + disconnect: + type: boolean + delete: + type: boolean connect: - $ref: '#/components/schemas/UserWhereUniqueInput' + $ref: '#/components/schemas/ProfileWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/ProfileUpdateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedUpdateWithoutUserInput' + Post_ItemUncheckedUpdateManyWithoutAuthorNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + connectOrCreate: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + upsert: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpsertWithWhereUniqueWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpsertWithWhereUniqueWithoutAuthorInput' + createMany: + $ref: '#/components/schemas/Post_ItemCreateManyAuthorInputEnvelope' + set: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + disconnect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + delete: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + connect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateWithWhereUniqueWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpdateWithWhereUniqueWithoutAuthorInput' + updateMany: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateManyWithWhereWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpdateManyWithWhereWithoutAuthorInput' + deleteMany: + oneOf: + - $ref: '#/components/schemas/Post_ItemScalarWhereInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereInput' + ProfileUncheckedUpdateOneWithoutUserNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + connectOrCreate: + $ref: '#/components/schemas/ProfileCreateOrConnectWithoutUserInput' + upsert: + $ref: '#/components/schemas/ProfileUpsertWithoutUserInput' + disconnect: + type: boolean + delete: + type: boolean + connect: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/ProfileUpdateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedUpdateWithoutUserInput' + UserCreateNestedOneWithoutProfileInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutProfileInput' + connectOrCreate: + $ref: '#/components/schemas/UserCreateOrConnectWithoutProfileInput' + connect: + $ref: '#/components/schemas/UserWhereUniqueInput' + NullableStringFieldUpdateOperationsInput: + type: object + properties: + set: + type: string + nullable: true + UserUpdateOneRequiredWithoutProfileNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutProfileInput' + connectOrCreate: + $ref: '#/components/schemas/UserCreateOrConnectWithoutProfileInput' + upsert: + $ref: '#/components/schemas/UserUpsertWithoutProfileInput' + connect: + $ref: '#/components/schemas/UserWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/UserUpdateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedUpdateWithoutProfileInput' + UserCreateNestedOneWithoutPostsInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + connectOrCreate: + $ref: '#/components/schemas/UserCreateOrConnectWithoutPostsInput' + connect: + $ref: '#/components/schemas/UserWhereUniqueInput' BoolFieldUpdateOperationsInput: type: object properties: @@ -1344,18 +1779,21 @@ components: properties: equals: type: string + nullable: true in: oneOf: - type: array items: type: string - type: string + nullable: true notIn: oneOf: - type: array items: type: string - type: string + nullable: true lt: type: string lte: @@ -1374,32 +1812,27 @@ components: oneOf: - type: string - $ref: '#/components/schemas/NestedStringNullableFilter' - NestedBoolFilter: - type: object - properties: - equals: - type: boolean - not: - oneOf: - - type: boolean - - $ref: '#/components/schemas/NestedBoolFilter' + nullable: true NestedStringNullableWithAggregatesFilter: type: object properties: equals: type: string + nullable: true in: oneOf: - type: array items: type: string - type: string + nullable: true notIn: oneOf: - type: array items: type: string - type: string + nullable: true lt: type: string lte: @@ -1418,6 +1851,7 @@ components: oneOf: - type: string - $ref: '#/components/schemas/NestedStringNullableWithAggregatesFilter' + nullable: true _count: $ref: '#/components/schemas/NestedIntNullableFilter' _min: @@ -1429,18 +1863,21 @@ components: properties: equals: type: integer + nullable: true in: oneOf: - type: array items: type: integer - type: integer + nullable: true notIn: oneOf: - type: array items: type: integer - type: integer + nullable: true lt: type: integer lte: @@ -1453,6 +1890,16 @@ components: oneOf: - type: integer - $ref: '#/components/schemas/NestedIntNullableFilter' + nullable: true + NestedBoolFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolFilter' NestedBoolWithAggregatesFilter: type: object properties: @@ -1553,6 +2000,9 @@ components: type: boolean viewCount: type: integer + notes: + type: string + nullable: true required: - id - title @@ -1573,6 +2023,9 @@ components: type: boolean viewCount: type: integer + notes: + type: string + nullable: true required: - id - title @@ -1601,6 +2054,34 @@ components: type: boolean required: - data + ProfileCreateWithoutUserInput: + type: object + properties: + id: + type: string + image: + type: string + nullable: true + ProfileUncheckedCreateWithoutUserInput: + type: object + properties: + id: + type: string + image: + type: string + nullable: true + ProfileCreateOrConnectWithoutUserInput: + type: object + properties: + where: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + required: + - where + - create Post_ItemUpsertWithWhereUniqueWithoutAuthorInput: type: object properties: @@ -1683,6 +2164,7 @@ components: oneOf: - $ref: '#/components/schemas/StringNullableFilter' - type: string + nullable: true published: oneOf: - $ref: '#/components/schemas/BoolFilter' @@ -1691,7 +2173,50 @@ components: oneOf: - $ref: '#/components/schemas/IntFilter' - type: integer - UserCreateWithoutPostsInput: + notes: + oneOf: + - $ref: '#/components/schemas/StringNullableFilter' + - type: string + nullable: true + ProfileUpsertWithoutUserInput: + type: object + properties: + update: + oneOf: + - $ref: '#/components/schemas/ProfileUpdateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedUpdateWithoutUserInput' + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + required: + - update + - create + ProfileUpdateWithoutUserInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + image: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true + ProfileUncheckedUpdateWithoutUserInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + image: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true + UserCreateWithoutProfileInput: type: object properties: id: @@ -1706,9 +2231,11 @@ components: type: string role: $ref: '#/components/schemas/Role' + posts: + $ref: '#/components/schemas/Post_ItemCreateNestedManyWithoutAuthorInput' required: - email - UserUncheckedCreateWithoutPostsInput: + UserUncheckedCreateWithoutProfileInput: type: object properties: id: @@ -1723,35 +2250,38 @@ components: type: string role: $ref: '#/components/schemas/Role' + posts: + $ref: "#/components/schemas/Post_ItemUncheckedCreateNestedManyWithoutAuthorInpu\ + t" required: - email - UserCreateOrConnectWithoutPostsInput: + UserCreateOrConnectWithoutProfileInput: type: object properties: where: $ref: '#/components/schemas/UserWhereUniqueInput' create: oneOf: - - $ref: '#/components/schemas/UserCreateWithoutPostsInput' - - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserCreateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutProfileInput' required: - where - create - UserUpsertWithoutPostsInput: + UserUpsertWithoutProfileInput: type: object properties: update: oneOf: - - $ref: '#/components/schemas/UserUpdateWithoutPostsInput' - - $ref: '#/components/schemas/UserUncheckedUpdateWithoutPostsInput' + - $ref: '#/components/schemas/UserUpdateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedUpdateWithoutProfileInput' create: oneOf: - - $ref: '#/components/schemas/UserCreateWithoutPostsInput' - - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserCreateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutProfileInput' required: - update - create - UserUpdateWithoutPostsInput: + UserUpdateWithoutProfileInput: type: object properties: id: @@ -1776,7 +2306,9 @@ components: oneOf: - $ref: '#/components/schemas/Role' - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' - UserUncheckedUpdateWithoutPostsInput: + posts: + $ref: '#/components/schemas/Post_ItemUpdateManyWithoutAuthorNestedInput' + UserUncheckedUpdateWithoutProfileInput: type: object properties: id: @@ -1801,7 +2333,10 @@ components: oneOf: - $ref: '#/components/schemas/Role' - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' - Post_ItemCreateManyAuthorInput: + posts: + $ref: "#/components/schemas/Post_ItemUncheckedUpdateManyWithoutAuthorNestedInpu\ + t" + UserCreateWithoutPostsInput: type: object properties: id: @@ -1812,51 +2347,177 @@ components: updatedAt: type: string format: date-time - title: + email: type: string - published: - type: boolean - viewCount: - type: integer + role: + $ref: '#/components/schemas/Role' + profile: + $ref: '#/components/schemas/ProfileCreateNestedOneWithoutUserInput' required: - - id - - title - Post_ItemUpdateWithoutAuthorInput: + - email + UserUncheckedCreateWithoutPostsInput: type: object properties: id: - oneOf: - - type: string - - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + type: string createdAt: - oneOf: - - type: string - format: date-time - - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + type: string + format: date-time updatedAt: - oneOf: - - type: string - format: date-time - - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' - title: - oneOf: - - type: string - - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' - published: - oneOf: - - type: boolean - - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' - viewCount: - oneOf: - - type: integer - - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' - Post_ItemUncheckedUpdateWithoutAuthorInput: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + profile: + $ref: '#/components/schemas/ProfileUncheckedCreateNestedOneWithoutUserInput' + required: + - email + UserCreateOrConnectWithoutPostsInput: type: object properties: - id: + where: + $ref: '#/components/schemas/UserWhereUniqueInput' + create: oneOf: - - type: string - - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + - $ref: '#/components/schemas/UserCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + required: + - where + - create + UserUpsertWithoutPostsInput: + type: object + properties: + update: + oneOf: + - $ref: '#/components/schemas/UserUpdateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedUpdateWithoutPostsInput' + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + required: + - update + - create + UserUpdateWithoutPostsInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + email: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + role: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + profile: + $ref: '#/components/schemas/ProfileUpdateOneWithoutUserNestedInput' + UserUncheckedUpdateWithoutPostsInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + email: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + role: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + profile: + $ref: '#/components/schemas/ProfileUncheckedUpdateOneWithoutUserNestedInput' + Post_ItemCreateManyAuthorInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + published: + type: boolean + viewCount: + type: integer + notes: + type: string + nullable: true + required: + - id + - title + Post_ItemUpdateWithoutAuthorInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + title: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + published: + oneOf: + - type: boolean + - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' + viewCount: + oneOf: + - type: integer + - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true + Post_ItemUncheckedUpdateWithoutAuthorInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' createdAt: oneOf: - type: string @@ -1879,6 +2540,11 @@ components: oneOf: - type: integer - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true Post_ItemUncheckedUpdateManyWithoutPostsInput: type: object properties: @@ -1908,6 +2574,11 @@ components: oneOf: - type: integer - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + nullable: true UserArgs: type: object properties: @@ -1915,6 +2586,13 @@ components: $ref: '#/components/schemas/UserSelect' include: $ref: '#/components/schemas/UserInclude' + ProfileArgs: + type: object + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' UserInclude: type: object properties: @@ -1922,10 +2600,21 @@ components: oneOf: - type: boolean - $ref: '#/components/schemas/Post_ItemFindManyArgs' + profile: + oneOf: + - type: boolean + - $ref: '#/components/schemas/ProfileArgs' _count: oneOf: - type: boolean - $ref: '#/components/schemas/UserCountOutputTypeArgs' + ProfileInclude: + type: object + properties: + user: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserArgs' Post_ItemInclude: type: object properties: @@ -1960,10 +2649,27 @@ components: oneOf: - type: boolean - $ref: '#/components/schemas/Post_ItemFindManyArgs' + profile: + oneOf: + - type: boolean + - $ref: '#/components/schemas/ProfileArgs' _count: oneOf: - type: boolean - $ref: '#/components/schemas/UserCountOutputTypeArgs' + ProfileSelect: + type: object + properties: + id: + type: boolean + image: + type: boolean + user: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserArgs' + userId: + type: boolean Post_ItemSelect: type: object properties: @@ -1985,6 +2691,8 @@ components: type: boolean viewCount: type: boolean + notes: + type: boolean UserCountAggregateInput: type: object properties: @@ -2026,15 +2734,50 @@ components: type: boolean role: type: boolean + ProfileCountAggregateInput: + type: object + properties: + id: + type: boolean + image: + type: boolean + userId: + type: boolean + _all: + type: boolean + ProfileMinAggregateInput: + type: object + properties: + id: + type: boolean + image: + type: boolean + userId: + type: boolean + ProfileMaxAggregateInput: + type: object + properties: + id: + type: boolean + image: + type: boolean + userId: + type: boolean AggregateUser: type: object properties: _count: - $ref: '#/components/schemas/UserCountAggregateOutputType' + allOf: + - $ref: '#/components/schemas/UserCountAggregateOutputType' + nullable: true _min: - $ref: '#/components/schemas/UserMinAggregateOutputType' + allOf: + - $ref: '#/components/schemas/UserMinAggregateOutputType' + nullable: true _max: - $ref: '#/components/schemas/UserMaxAggregateOutputType' + allOf: + - $ref: '#/components/schemas/UserMaxAggregateOutputType' + nullable: true UserGroupByOutputType: type: object properties: @@ -2051,30 +2794,86 @@ components: role: $ref: '#/components/schemas/Role' _count: - $ref: '#/components/schemas/UserCountAggregateOutputType' + allOf: + - $ref: '#/components/schemas/UserCountAggregateOutputType' + nullable: true _min: - $ref: '#/components/schemas/UserMinAggregateOutputType' + allOf: + - $ref: '#/components/schemas/UserMinAggregateOutputType' + nullable: true _max: - $ref: '#/components/schemas/UserMaxAggregateOutputType' + allOf: + - $ref: '#/components/schemas/UserMaxAggregateOutputType' + nullable: true required: - id - createdAt - updatedAt - email - role + AggregateProfile: + type: object + properties: + _count: + allOf: + - $ref: '#/components/schemas/ProfileCountAggregateOutputType' + nullable: true + _min: + allOf: + - $ref: '#/components/schemas/ProfileMinAggregateOutputType' + nullable: true + _max: + allOf: + - $ref: '#/components/schemas/ProfileMaxAggregateOutputType' + nullable: true + ProfileGroupByOutputType: + type: object + properties: + id: + type: string + image: + type: string + nullable: true + userId: + type: string + _count: + allOf: + - $ref: '#/components/schemas/ProfileCountAggregateOutputType' + nullable: true + _min: + allOf: + - $ref: '#/components/schemas/ProfileMinAggregateOutputType' + nullable: true + _max: + allOf: + - $ref: '#/components/schemas/ProfileMaxAggregateOutputType' + nullable: true + required: + - id + - userId AggregatePost_Item: type: object properties: _count: - $ref: '#/components/schemas/Post_ItemCountAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemCountAggregateOutputType' + nullable: true _avg: - $ref: '#/components/schemas/Post_ItemAvgAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemAvgAggregateOutputType' + nullable: true _sum: - $ref: '#/components/schemas/Post_ItemSumAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemSumAggregateOutputType' + nullable: true _min: - $ref: '#/components/schemas/Post_ItemMinAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemMinAggregateOutputType' + nullable: true _max: - $ref: '#/components/schemas/Post_ItemMaxAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemMaxAggregateOutputType' + nullable: true Post_ItemGroupByOutputType: type: object properties: @@ -2090,20 +2889,34 @@ components: type: string authorId: type: string + nullable: true published: type: boolean viewCount: type: integer + notes: + type: string + nullable: true _count: - $ref: '#/components/schemas/Post_ItemCountAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemCountAggregateOutputType' + nullable: true _avg: - $ref: '#/components/schemas/Post_ItemAvgAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemAvgAggregateOutputType' + nullable: true _sum: - $ref: '#/components/schemas/Post_ItemSumAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemSumAggregateOutputType' + nullable: true _min: - $ref: '#/components/schemas/Post_ItemMinAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemMinAggregateOutputType' + nullable: true _max: - $ref: '#/components/schemas/Post_ItemMaxAggregateOutputType' + allOf: + - $ref: '#/components/schemas/Post_ItemMaxAggregateOutputType' + nullable: true required: - id - createdAt @@ -2138,31 +2951,83 @@ components: properties: id: type: string + nullable: true createdAt: type: string format: date-time + nullable: true updatedAt: type: string format: date-time + nullable: true email: type: string + nullable: true role: - $ref: '#/components/schemas/Role' + allOf: + - $ref: '#/components/schemas/Role' + nullable: true UserMaxAggregateOutputType: type: object properties: id: type: string + nullable: true createdAt: type: string format: date-time + nullable: true updatedAt: type: string format: date-time + nullable: true email: type: string + nullable: true role: - $ref: '#/components/schemas/Role' + allOf: + - $ref: '#/components/schemas/Role' + nullable: true + ProfileCountAggregateOutputType: + type: object + properties: + id: + type: integer + image: + type: integer + userId: + type: integer + _all: + type: integer + required: + - id + - image + - userId + - _all + ProfileMinAggregateOutputType: + type: object + properties: + id: + type: string + nullable: true + image: + type: string + nullable: true + userId: + type: string + nullable: true + ProfileMaxAggregateOutputType: + type: object + properties: + id: + type: string + nullable: true + image: + type: string + nullable: true + userId: + type: string + nullable: true Post_ItemCountAggregateOutputType: type: object properties: @@ -2180,6 +3045,8 @@ components: type: integer viewCount: type: integer + notes: + type: integer _all: type: integer required: @@ -2190,55 +3057,78 @@ components: - authorId - published - viewCount + - notes - _all Post_ItemAvgAggregateOutputType: type: object properties: viewCount: type: number + nullable: true Post_ItemSumAggregateOutputType: type: object properties: viewCount: type: integer + nullable: true Post_ItemMinAggregateOutputType: type: object properties: id: type: string + nullable: true createdAt: type: string format: date-time + nullable: true updatedAt: type: string format: date-time + nullable: true title: type: string + nullable: true authorId: type: string + nullable: true published: type: boolean + nullable: true viewCount: type: integer + nullable: true + notes: + type: string + nullable: true Post_ItemMaxAggregateOutputType: type: object properties: id: type: string + nullable: true createdAt: type: string format: date-time + nullable: true updatedAt: type: string format: date-time + nullable: true title: type: string + nullable: true authorId: type: string + nullable: true published: type: boolean + nullable: true viewCount: type: integer + nullable: true + notes: + type: string + nullable: true _Meta: type: object properties: @@ -2465,91 +3355,91 @@ components: $ref: '#/components/schemas/UserMaxAggregateInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemCreateArgs: + ProfileCreateArgs: type: object required: - data properties: select: - $ref: '#/components/schemas/Post_ItemSelect' + $ref: '#/components/schemas/ProfileSelect' include: - $ref: '#/components/schemas/Post_ItemInclude' + $ref: '#/components/schemas/ProfileInclude' data: - $ref: '#/components/schemas/Post_ItemCreateInput' + $ref: '#/components/schemas/ProfileCreateInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemCreateManyArgs: + ProfileCreateManyArgs: type: object required: - data properties: data: - $ref: '#/components/schemas/Post_ItemCreateManyInput' + $ref: '#/components/schemas/ProfileCreateManyInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemFindUniqueArgs: + ProfileFindUniqueArgs: type: object required: - where properties: select: - $ref: '#/components/schemas/Post_ItemSelect' + $ref: '#/components/schemas/ProfileSelect' include: - $ref: '#/components/schemas/Post_ItemInclude' + $ref: '#/components/schemas/ProfileInclude' where: - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + $ref: '#/components/schemas/ProfileWhereUniqueInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemFindFirstArgs: + ProfileFindFirstArgs: type: object properties: select: - $ref: '#/components/schemas/Post_ItemSelect' + $ref: '#/components/schemas/ProfileSelect' include: - $ref: '#/components/schemas/Post_ItemInclude' + $ref: '#/components/schemas/ProfileInclude' where: - $ref: '#/components/schemas/Post_ItemWhereInput' + $ref: '#/components/schemas/ProfileWhereInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemFindManyArgs: + ProfileFindManyArgs: type: object properties: select: - $ref: '#/components/schemas/Post_ItemSelect' + $ref: '#/components/schemas/ProfileSelect' include: - $ref: '#/components/schemas/Post_ItemInclude' + $ref: '#/components/schemas/ProfileInclude' where: - $ref: '#/components/schemas/Post_ItemWhereInput' + $ref: '#/components/schemas/ProfileWhereInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemUpdateArgs: + ProfileUpdateArgs: type: object required: - where - data properties: select: - $ref: '#/components/schemas/Post_ItemSelect' + $ref: '#/components/schemas/ProfileSelect' include: - $ref: '#/components/schemas/Post_ItemInclude' + $ref: '#/components/schemas/ProfileInclude' where: - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + $ref: '#/components/schemas/ProfileWhereUniqueInput' data: - $ref: '#/components/schemas/Post_ItemUpdateInput' + $ref: '#/components/schemas/ProfileUpdateInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemUpdateManyArgs: + ProfileUpdateManyArgs: type: object required: - data properties: where: - $ref: '#/components/schemas/Post_ItemWhereInput' + $ref: '#/components/schemas/ProfileWhereInput' data: - $ref: '#/components/schemas/Post_ItemUpdateManyMutationInput' + $ref: '#/components/schemas/ProfileUpdateManyMutationInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemUpsertArgs: + ProfileUpsertArgs: type: object required: - create @@ -2557,24 +3447,204 @@ components: - where properties: select: - $ref: '#/components/schemas/Post_ItemSelect' + $ref: '#/components/schemas/ProfileSelect' include: - $ref: '#/components/schemas/Post_ItemInclude' + $ref: '#/components/schemas/ProfileInclude' where: - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + $ref: '#/components/schemas/ProfileWhereUniqueInput' create: - $ref: '#/components/schemas/Post_ItemCreateInput' + $ref: '#/components/schemas/ProfileCreateInput' update: - $ref: '#/components/schemas/Post_ItemUpdateInput' + $ref: '#/components/schemas/ProfileUpdateInput' meta: $ref: '#/components/schemas/_Meta' - Post_ItemDeleteUniqueArgs: + ProfileDeleteUniqueArgs: type: object required: - where properties: select: - $ref: '#/components/schemas/Post_ItemSelect' + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + where: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileDeleteManyArgs: + type: object + properties: + where: + $ref: '#/components/schemas/ProfileWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileCountArgs: + type: object + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + where: + $ref: '#/components/schemas/ProfileWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileAggregateArgs: + type: object + properties: + where: + $ref: '#/components/schemas/ProfileWhereInput' + orderBy: + $ref: '#/components/schemas/ProfileOrderByWithRelationInput' + cursor: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + take: + type: integer + skip: + type: integer + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/ProfileCountAggregateInput' + _min: + $ref: '#/components/schemas/ProfileMinAggregateInput' + _max: + $ref: '#/components/schemas/ProfileMaxAggregateInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileGroupByArgs: + type: object + properties: + where: + $ref: '#/components/schemas/ProfileWhereInput' + orderBy: + $ref: '#/components/schemas/ProfileOrderByWithRelationInput' + by: + $ref: '#/components/schemas/ProfileScalarFieldEnum' + having: + $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + take: + type: integer + skip: + type: integer + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/ProfileCountAggregateInput' + _min: + $ref: '#/components/schemas/ProfileMinAggregateInput' + _max: + $ref: '#/components/schemas/ProfileMaxAggregateInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemCreateArgs: + type: object + required: + - data + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + data: + $ref: '#/components/schemas/Post_ItemCreateInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemCreateManyArgs: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Post_ItemCreateManyInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemFindUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemFindFirstArgs: + type: object + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemFindManyArgs: + type: object + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemUpdateArgs: + type: object + required: + - where + - data + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + data: + $ref: '#/components/schemas/Post_ItemUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemUpdateManyArgs: + type: object + required: + - data + properties: + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + data: + $ref: '#/components/schemas/Post_ItemUpdateManyMutationInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemUpsertArgs: + type: object + required: + - create + - update + - where + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + create: + $ref: '#/components/schemas/Post_ItemCreateInput' + update: + $ref: '#/components/schemas/Post_ItemUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemDeleteUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' include: $ref: '#/components/schemas/Post_ItemInclude' where: @@ -3216,6 +4286,599 @@ paths: content: application/json: schema: {} + /profile/create: + post: + operationId: createProfile + description: Create a new Profile + tags: + - profile + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileCreateArgs' + /profile/createMany: + post: + operationId: createManyProfile + description: Create several Profile + tags: + - profile + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileCreateManyArgs' + /profile/findUnique: + get: + operationId: findUniqueProfile + description: Find one unique Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileFindUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/findFirst: + get: + operationId: findFirstProfile + description: Find the first Profile matching the given condition + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileFindFirstArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/findMany: + get: + operationId: findManyProfile + description: Find a list of Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileFindManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/update: + patch: + operationId: updateProfile + description: Update a Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpdateArgs' + /profile/updateMany: + patch: + operationId: updateManyProfile + description: Update Profiles matching the given condition + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpdateManyArgs' + /profile/upsert: + post: + operationId: upsertProfile + description: Upsert a Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpsertArgs' + /profile/delete: + delete: + operationId: deleteProfile + description: Delete one unique Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileDeleteUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/deleteMany: + delete: + operationId: deleteManyProfile + description: Delete Profiles matching the given condition + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileDeleteManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/count: + get: + operationId: countProfile + description: Find a list of Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + oneOf: + - type: integer + - $ref: '#/components/schemas/ProfileCountAggregateOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileCountArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/aggregate: + get: + operationId: aggregateProfile + description: Aggregate Profiles + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/AggregateProfile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileAggregateArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/groupBy: + get: + operationId: groupByProfile + description: Group Profiles by fields + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/ProfileGroupByOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileGroupByArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} /post_Item/create: post: operationId: createPost_Item diff --git a/packages/plugins/openapi/tests/baseline/rpc-3.1.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rpc-3.1.0.baseline.yaml new file mode 100644 index 000000000..d842234ab --- /dev/null +++ b/packages/plugins/openapi/tests/baseline/rpc-3.1.0.baseline.yaml @@ -0,0 +1,5477 @@ +openapi: 3.1.0 +info: + title: ZenStack Generated API + version: 1.0.0 +tags: + - name: user + description: User operations + - name: profile + description: Profile operations + - name: post_Item + description: Post-related operations +components: + schemas: + Role: + type: string + enum: + - USER + - ADMIN + UserScalarFieldEnum: + type: string + enum: + - id + - createdAt + - updatedAt + - email + - role + ProfileScalarFieldEnum: + type: string + enum: + - id + - image + - userId + Post_ItemScalarFieldEnum: + type: string + enum: + - id + - createdAt + - updatedAt + - title + - authorId + - published + - viewCount + - notes + SortOrder: + type: string + enum: + - asc + - desc + QueryMode: + type: string + enum: + - default + - insensitive + NullsOrder: + type: string + enum: + - first + - last + User: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + posts: + type: array + items: + $ref: '#/components/schemas/Post_Item' + profile: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Profile' + required: + - id + - createdAt + - updatedAt + - email + - role + Profile: + type: object + properties: + id: + type: string + image: + oneOf: + - type: 'null' + - type: string + user: + $ref: '#/components/schemas/User' + userId: + type: string + required: + - id + - user + - userId + Post_Item: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + author: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/User' + authorId: + oneOf: + - type: 'null' + - type: string + published: + type: boolean + viewCount: + type: integer + notes: + oneOf: + - type: 'null' + - type: string + required: + - id + - createdAt + - updatedAt + - title + - published + - viewCount + UserWhereInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/UserWhereInput' + - type: array + items: + $ref: '#/components/schemas/UserWhereInput' + OR: + type: array + items: + $ref: '#/components/schemas/UserWhereInput' + NOT: + oneOf: + - $ref: '#/components/schemas/UserWhereInput' + - type: array + items: + $ref: '#/components/schemas/UserWhereInput' + id: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + createdAt: + oneOf: + - $ref: '#/components/schemas/DateTimeFilter' + - type: string + format: date-time + updatedAt: + oneOf: + - $ref: '#/components/schemas/DateTimeFilter' + - type: string + format: date-time + email: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + role: + oneOf: + - $ref: '#/components/schemas/EnumroleFilter' + - $ref: '#/components/schemas/Role' + posts: + $ref: '#/components/schemas/Post_ItemListRelationFilter' + profile: + oneOf: + - $ref: '#/components/schemas/ProfileRelationFilter' + - $ref: '#/components/schemas/ProfileWhereInput' + - type: 'null' + UserOrderByWithRelationInput: + type: object + properties: + id: + $ref: '#/components/schemas/SortOrder' + createdAt: + $ref: '#/components/schemas/SortOrder' + updatedAt: + $ref: '#/components/schemas/SortOrder' + email: + $ref: '#/components/schemas/SortOrder' + role: + $ref: '#/components/schemas/SortOrder' + posts: + $ref: '#/components/schemas/Post_ItemOrderByRelationAggregateInput' + profile: + $ref: '#/components/schemas/ProfileOrderByWithRelationInput' + UserWhereUniqueInput: + type: object + properties: + id: + type: string + email: + type: string + UserScalarWhereWithAggregatesInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/UserScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/UserScalarWhereWithAggregatesInput' + OR: + type: array + items: + $ref: '#/components/schemas/UserScalarWhereWithAggregatesInput' + NOT: + oneOf: + - $ref: '#/components/schemas/UserScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/UserScalarWhereWithAggregatesInput' + id: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + createdAt: + oneOf: + - $ref: '#/components/schemas/DateTimeWithAggregatesFilter' + - type: string + format: date-time + updatedAt: + oneOf: + - $ref: '#/components/schemas/DateTimeWithAggregatesFilter' + - type: string + format: date-time + email: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + role: + oneOf: + - $ref: '#/components/schemas/EnumroleWithAggregatesFilter' + - $ref: '#/components/schemas/Role' + ProfileWhereInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/ProfileWhereInput' + - type: array + items: + $ref: '#/components/schemas/ProfileWhereInput' + OR: + type: array + items: + $ref: '#/components/schemas/ProfileWhereInput' + NOT: + oneOf: + - $ref: '#/components/schemas/ProfileWhereInput' + - type: array + items: + $ref: '#/components/schemas/ProfileWhereInput' + id: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + image: + oneOf: + - $ref: '#/components/schemas/StringNullableFilter' + - type: string + - type: 'null' + userId: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + user: + oneOf: + - $ref: '#/components/schemas/UserRelationFilter' + - $ref: '#/components/schemas/UserWhereInput' + ProfileOrderByWithRelationInput: + type: object + properties: + id: + $ref: '#/components/schemas/SortOrder' + image: + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' + userId: + $ref: '#/components/schemas/SortOrder' + user: + $ref: '#/components/schemas/UserOrderByWithRelationInput' + ProfileWhereUniqueInput: + type: object + properties: + id: + type: string + userId: + type: string + ProfileScalarWhereWithAggregatesInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + OR: + type: array + items: + $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + NOT: + oneOf: + - $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + id: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + image: + oneOf: + - $ref: '#/components/schemas/StringNullableWithAggregatesFilter' + - type: string + - type: 'null' + userId: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + Post_ItemWhereInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereInput' + OR: + type: array + items: + $ref: '#/components/schemas/Post_ItemWhereInput' + NOT: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereInput' + id: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + createdAt: + oneOf: + - $ref: '#/components/schemas/DateTimeFilter' + - type: string + format: date-time + updatedAt: + oneOf: + - $ref: '#/components/schemas/DateTimeFilter' + - type: string + format: date-time + title: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + authorId: + oneOf: + - $ref: '#/components/schemas/StringNullableFilter' + - type: string + - type: 'null' + published: + oneOf: + - $ref: '#/components/schemas/BoolFilter' + - type: boolean + viewCount: + oneOf: + - $ref: '#/components/schemas/IntFilter' + - type: integer + notes: + oneOf: + - $ref: '#/components/schemas/StringNullableFilter' + - type: string + - type: 'null' + author: + oneOf: + - $ref: '#/components/schemas/UserRelationFilter' + - $ref: '#/components/schemas/UserWhereInput' + - type: 'null' + Post_ItemOrderByWithRelationInput: + type: object + properties: + id: + $ref: '#/components/schemas/SortOrder' + createdAt: + $ref: '#/components/schemas/SortOrder' + updatedAt: + $ref: '#/components/schemas/SortOrder' + title: + $ref: '#/components/schemas/SortOrder' + authorId: + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' + published: + $ref: '#/components/schemas/SortOrder' + viewCount: + $ref: '#/components/schemas/SortOrder' + notes: + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' + author: + $ref: '#/components/schemas/UserOrderByWithRelationInput' + Post_ItemWhereUniqueInput: + type: object + properties: + id: + type: string + Post_ItemScalarWhereWithAggregatesInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/Post_ItemScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereWithAggregatesInput' + OR: + type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereWithAggregatesInput' + NOT: + oneOf: + - $ref: '#/components/schemas/Post_ItemScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereWithAggregatesInput' + id: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + createdAt: + oneOf: + - $ref: '#/components/schemas/DateTimeWithAggregatesFilter' + - type: string + format: date-time + updatedAt: + oneOf: + - $ref: '#/components/schemas/DateTimeWithAggregatesFilter' + - type: string + format: date-time + title: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + authorId: + oneOf: + - $ref: '#/components/schemas/StringNullableWithAggregatesFilter' + - type: string + - type: 'null' + published: + oneOf: + - $ref: '#/components/schemas/BoolWithAggregatesFilter' + - type: boolean + viewCount: + oneOf: + - $ref: '#/components/schemas/IntWithAggregatesFilter' + - type: integer + notes: + oneOf: + - $ref: '#/components/schemas/StringNullableWithAggregatesFilter' + - type: string + - type: 'null' + UserCreateInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + posts: + $ref: '#/components/schemas/Post_ItemCreateNestedManyWithoutAuthorInput' + profile: + $ref: '#/components/schemas/ProfileCreateNestedOneWithoutUserInput' + required: + - email + UserUpdateInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + email: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + role: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + posts: + $ref: '#/components/schemas/Post_ItemUpdateManyWithoutAuthorNestedInput' + profile: + $ref: '#/components/schemas/ProfileUpdateOneWithoutUserNestedInput' + UserCreateManyInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + required: + - email + UserUpdateManyMutationInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + email: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + role: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + ProfileCreateInput: + type: object + properties: + id: + type: string + image: + oneOf: + - type: 'null' + - type: string + user: + $ref: '#/components/schemas/UserCreateNestedOneWithoutProfileInput' + required: + - user + ProfileUpdateInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + image: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + user: + $ref: '#/components/schemas/UserUpdateOneRequiredWithoutProfileNestedInput' + ProfileCreateManyInput: + type: object + properties: + id: + type: string + image: + oneOf: + - type: 'null' + - type: string + userId: + type: string + required: + - userId + ProfileUpdateManyMutationInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + image: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + Post_ItemCreateInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + published: + type: boolean + viewCount: + type: integer + notes: + oneOf: + - type: 'null' + - type: string + author: + $ref: '#/components/schemas/UserCreateNestedOneWithoutPostsInput' + required: + - id + - title + Post_ItemUpdateInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + title: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + published: + oneOf: + - type: boolean + - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' + viewCount: + oneOf: + - type: integer + - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + author: + $ref: '#/components/schemas/UserUpdateOneWithoutPostsNestedInput' + Post_ItemCreateManyInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + authorId: + oneOf: + - type: 'null' + - type: string + published: + type: boolean + viewCount: + type: integer + notes: + oneOf: + - type: 'null' + - type: string + required: + - id + - title + Post_ItemUpdateManyMutationInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + title: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + published: + oneOf: + - type: boolean + - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' + viewCount: + oneOf: + - type: integer + - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + StringFilter: + type: object + properties: + equals: + type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + notIn: + oneOf: + - type: array + items: + type: string + - type: string + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringFilter' + DateTimeFilter: + type: object + properties: + equals: + type: string + format: date-time + in: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + notIn: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + lt: + type: string + format: date-time + lte: + type: string + format: date-time + gt: + type: string + format: date-time + gte: + type: string + format: date-time + not: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/NestedDateTimeFilter' + EnumroleFilter: + type: object + properties: + equals: + $ref: '#/components/schemas/Role' + in: + oneOf: + - type: array + items: + $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/Role' + notIn: + oneOf: + - type: array + items: + $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/Role' + not: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/NestedEnumroleFilter' + Post_ItemListRelationFilter: + type: object + properties: + every: + $ref: '#/components/schemas/Post_ItemWhereInput' + some: + $ref: '#/components/schemas/Post_ItemWhereInput' + none: + $ref: '#/components/schemas/Post_ItemWhereInput' + ProfileRelationFilter: + type: object + properties: + is: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/ProfileWhereInput' + isNot: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/ProfileWhereInput' + Post_ItemOrderByRelationAggregateInput: + type: object + properties: + _count: + $ref: '#/components/schemas/SortOrder' + StringWithAggregatesFilter: + type: object + properties: + equals: + type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + notIn: + oneOf: + - type: array + items: + type: string + - type: string + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedStringFilter' + _max: + $ref: '#/components/schemas/NestedStringFilter' + DateTimeWithAggregatesFilter: + type: object + properties: + equals: + type: string + format: date-time + in: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + notIn: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + lt: + type: string + format: date-time + lte: + type: string + format: date-time + gt: + type: string + format: date-time + gte: + type: string + format: date-time + not: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/NestedDateTimeWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedDateTimeFilter' + _max: + $ref: '#/components/schemas/NestedDateTimeFilter' + EnumroleWithAggregatesFilter: + type: object + properties: + equals: + $ref: '#/components/schemas/Role' + in: + oneOf: + - type: array + items: + $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/Role' + notIn: + oneOf: + - type: array + items: + $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/Role' + not: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/NestedEnumroleWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedEnumroleFilter' + _max: + $ref: '#/components/schemas/NestedEnumroleFilter' + StringNullableFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: string + - type: string + - type: 'null' + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringNullableFilter' + - type: 'null' + UserRelationFilter: + type: object + properties: + is: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/UserWhereInput' + isNot: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/UserWhereInput' + SortOrderInput: + type: object + properties: + sort: + $ref: '#/components/schemas/SortOrder' + nulls: + $ref: '#/components/schemas/NullsOrder' + required: + - sort + StringNullableWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: string + - type: string + - type: 'null' + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringNullableWithAggregatesFilter' + - type: 'null' + _count: + $ref: '#/components/schemas/NestedIntNullableFilter' + _min: + $ref: '#/components/schemas/NestedStringNullableFilter' + _max: + $ref: '#/components/schemas/NestedStringNullableFilter' + BoolFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolFilter' + IntFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntFilter' + BoolWithAggregatesFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedBoolFilter' + _max: + $ref: '#/components/schemas/NestedBoolFilter' + IntWithAggregatesFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedFloatFilter' + _sum: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedIntFilter' + _max: + $ref: '#/components/schemas/NestedIntFilter' + Post_ItemCreateNestedManyWithoutAuthorInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + connectOrCreate: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + createMany: + $ref: '#/components/schemas/Post_ItemCreateManyAuthorInputEnvelope' + connect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + ProfileCreateNestedOneWithoutUserInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + connectOrCreate: + $ref: '#/components/schemas/ProfileCreateOrConnectWithoutUserInput' + connect: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + Post_ItemUncheckedCreateNestedManyWithoutAuthorInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + connectOrCreate: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + createMany: + $ref: '#/components/schemas/Post_ItemCreateManyAuthorInputEnvelope' + connect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + ProfileUncheckedCreateNestedOneWithoutUserInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + connectOrCreate: + $ref: '#/components/schemas/ProfileCreateOrConnectWithoutUserInput' + connect: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + StringFieldUpdateOperationsInput: + type: object + properties: + set: + type: string + DateTimeFieldUpdateOperationsInput: + type: object + properties: + set: + type: string + format: date-time + EnumroleFieldUpdateOperationsInput: + type: object + properties: + set: + $ref: '#/components/schemas/Role' + Post_ItemUpdateManyWithoutAuthorNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + connectOrCreate: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + upsert: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpsertWithWhereUniqueWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpsertWithWhereUniqueWithoutAuthorInput' + createMany: + $ref: '#/components/schemas/Post_ItemCreateManyAuthorInputEnvelope' + set: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + disconnect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + delete: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + connect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateWithWhereUniqueWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpdateWithWhereUniqueWithoutAuthorInput' + updateMany: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateManyWithWhereWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpdateManyWithWhereWithoutAuthorInput' + deleteMany: + oneOf: + - $ref: '#/components/schemas/Post_ItemScalarWhereInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereInput' + ProfileUpdateOneWithoutUserNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + connectOrCreate: + $ref: '#/components/schemas/ProfileCreateOrConnectWithoutUserInput' + upsert: + $ref: '#/components/schemas/ProfileUpsertWithoutUserInput' + disconnect: + type: boolean + delete: + type: boolean + connect: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/ProfileUpdateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedUpdateWithoutUserInput' + Post_ItemUncheckedUpdateManyWithoutAuthorNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + connectOrCreate: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateOrConnectWithoutAuthorInput' + upsert: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpsertWithWhereUniqueWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpsertWithWhereUniqueWithoutAuthorInput' + createMany: + $ref: '#/components/schemas/Post_ItemCreateManyAuthorInputEnvelope' + set: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + disconnect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + delete: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + connect: + oneOf: + - $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateWithWhereUniqueWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpdateWithWhereUniqueWithoutAuthorInput' + updateMany: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateManyWithWhereWithoutAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemUpdateManyWithWhereWithoutAuthorInput' + deleteMany: + oneOf: + - $ref: '#/components/schemas/Post_ItemScalarWhereInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereInput' + ProfileUncheckedUpdateOneWithoutUserNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + connectOrCreate: + $ref: '#/components/schemas/ProfileCreateOrConnectWithoutUserInput' + upsert: + $ref: '#/components/schemas/ProfileUpsertWithoutUserInput' + disconnect: + type: boolean + delete: + type: boolean + connect: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/ProfileUpdateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedUpdateWithoutUserInput' + UserCreateNestedOneWithoutProfileInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutProfileInput' + connectOrCreate: + $ref: '#/components/schemas/UserCreateOrConnectWithoutProfileInput' + connect: + $ref: '#/components/schemas/UserWhereUniqueInput' + NullableStringFieldUpdateOperationsInput: + type: object + properties: + set: + oneOf: + - type: 'null' + - type: string + UserUpdateOneRequiredWithoutProfileNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutProfileInput' + connectOrCreate: + $ref: '#/components/schemas/UserCreateOrConnectWithoutProfileInput' + upsert: + $ref: '#/components/schemas/UserUpsertWithoutProfileInput' + connect: + $ref: '#/components/schemas/UserWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/UserUpdateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedUpdateWithoutProfileInput' + UserCreateNestedOneWithoutPostsInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + connectOrCreate: + $ref: '#/components/schemas/UserCreateOrConnectWithoutPostsInput' + connect: + $ref: '#/components/schemas/UserWhereUniqueInput' + BoolFieldUpdateOperationsInput: + type: object + properties: + set: + type: boolean + IntFieldUpdateOperationsInput: + type: object + properties: + set: + type: integer + increment: + type: integer + decrement: + type: integer + multiply: + type: integer + divide: + type: integer + UserUpdateOneWithoutPostsNestedInput: + type: object + properties: + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + connectOrCreate: + $ref: '#/components/schemas/UserCreateOrConnectWithoutPostsInput' + upsert: + $ref: '#/components/schemas/UserUpsertWithoutPostsInput' + disconnect: + type: boolean + delete: + type: boolean + connect: + $ref: '#/components/schemas/UserWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/UserUpdateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedUpdateWithoutPostsInput' + NestedStringFilter: + type: object + properties: + equals: + type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + notIn: + oneOf: + - type: array + items: + type: string + - type: string + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringFilter' + NestedDateTimeFilter: + type: object + properties: + equals: + type: string + format: date-time + in: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + notIn: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + lt: + type: string + format: date-time + lte: + type: string + format: date-time + gt: + type: string + format: date-time + gte: + type: string + format: date-time + not: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/NestedDateTimeFilter' + NestedEnumroleFilter: + type: object + properties: + equals: + $ref: '#/components/schemas/Role' + in: + oneOf: + - type: array + items: + $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/Role' + notIn: + oneOf: + - type: array + items: + $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/Role' + not: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/NestedEnumroleFilter' + NestedStringWithAggregatesFilter: + type: object + properties: + equals: + type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + notIn: + oneOf: + - type: array + items: + type: string + - type: string + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedStringFilter' + _max: + $ref: '#/components/schemas/NestedStringFilter' + NestedIntFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntFilter' + NestedDateTimeWithAggregatesFilter: + type: object + properties: + equals: + type: string + format: date-time + in: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + notIn: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + lt: + type: string + format: date-time + lte: + type: string + format: date-time + gt: + type: string + format: date-time + gte: + type: string + format: date-time + not: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/NestedDateTimeWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedDateTimeFilter' + _max: + $ref: '#/components/schemas/NestedDateTimeFilter' + NestedEnumroleWithAggregatesFilter: + type: object + properties: + equals: + $ref: '#/components/schemas/Role' + in: + oneOf: + - type: array + items: + $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/Role' + notIn: + oneOf: + - type: array + items: + $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/Role' + not: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/NestedEnumroleWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedEnumroleFilter' + _max: + $ref: '#/components/schemas/NestedEnumroleFilter' + NestedStringNullableFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: string + - type: string + - type: 'null' + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringNullableFilter' + - type: 'null' + NestedStringNullableWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: string + - type: string + - type: 'null' + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringNullableWithAggregatesFilter' + - type: 'null' + _count: + $ref: '#/components/schemas/NestedIntNullableFilter' + _min: + $ref: '#/components/schemas/NestedStringNullableFilter' + _max: + $ref: '#/components/schemas/NestedStringNullableFilter' + NestedIntNullableFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + - type: 'null' + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntNullableFilter' + - type: 'null' + NestedBoolFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolFilter' + NestedBoolWithAggregatesFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedBoolFilter' + _max: + $ref: '#/components/schemas/NestedBoolFilter' + NestedIntWithAggregatesFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedFloatFilter' + _sum: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedIntFilter' + _max: + $ref: '#/components/schemas/NestedIntFilter' + NestedFloatFilter: + type: object + properties: + equals: + type: number + in: + oneOf: + - type: array + items: + type: number + - type: number + notIn: + oneOf: + - type: array + items: + type: number + - type: number + lt: + type: number + lte: + type: number + gt: + type: number + gte: + type: number + not: + oneOf: + - type: number + - $ref: '#/components/schemas/NestedFloatFilter' + Post_ItemCreateWithoutAuthorInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + published: + type: boolean + viewCount: + type: integer + notes: + oneOf: + - type: 'null' + - type: string + required: + - id + - title + Post_ItemUncheckedCreateWithoutAuthorInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + published: + type: boolean + viewCount: + type: integer + notes: + oneOf: + - type: 'null' + - type: string + required: + - id + - title + Post_ItemCreateOrConnectWithoutAuthorInput: + type: object + properties: + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + create: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + required: + - where + - create + Post_ItemCreateManyAuthorInputEnvelope: + type: object + properties: + data: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateManyAuthorInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemCreateManyAuthorInput' + skipDuplicates: + type: boolean + required: + - data + ProfileCreateWithoutUserInput: + type: object + properties: + id: + type: string + image: + oneOf: + - type: 'null' + - type: string + ProfileUncheckedCreateWithoutUserInput: + type: object + properties: + id: + type: string + image: + oneOf: + - type: 'null' + - type: string + ProfileCreateOrConnectWithoutUserInput: + type: object + properties: + where: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + required: + - where + - create + Post_ItemUpsertWithWhereUniqueWithoutAuthorInput: + type: object + properties: + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + update: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedUpdateWithoutAuthorInput' + create: + oneOf: + - $ref: '#/components/schemas/Post_ItemCreateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedCreateWithoutAuthorInput' + required: + - where + - update + - create + Post_ItemUpdateWithWhereUniqueWithoutAuthorInput: + type: object + properties: + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + data: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateWithoutAuthorInput' + - $ref: '#/components/schemas/Post_ItemUncheckedUpdateWithoutAuthorInput' + required: + - where + - data + Post_ItemUpdateManyWithWhereWithoutAuthorInput: + type: object + properties: + where: + $ref: '#/components/schemas/Post_ItemScalarWhereInput' + data: + oneOf: + - $ref: '#/components/schemas/Post_ItemUpdateManyMutationInput' + - $ref: '#/components/schemas/Post_ItemUncheckedUpdateManyWithoutPostsInput' + required: + - where + - data + Post_ItemScalarWhereInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/Post_ItemScalarWhereInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereInput' + OR: + type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereInput' + NOT: + oneOf: + - $ref: '#/components/schemas/Post_ItemScalarWhereInput' + - type: array + items: + $ref: '#/components/schemas/Post_ItemScalarWhereInput' + id: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + createdAt: + oneOf: + - $ref: '#/components/schemas/DateTimeFilter' + - type: string + format: date-time + updatedAt: + oneOf: + - $ref: '#/components/schemas/DateTimeFilter' + - type: string + format: date-time + title: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + authorId: + oneOf: + - $ref: '#/components/schemas/StringNullableFilter' + - type: string + - type: 'null' + published: + oneOf: + - $ref: '#/components/schemas/BoolFilter' + - type: boolean + viewCount: + oneOf: + - $ref: '#/components/schemas/IntFilter' + - type: integer + notes: + oneOf: + - $ref: '#/components/schemas/StringNullableFilter' + - type: string + - type: 'null' + ProfileUpsertWithoutUserInput: + type: object + properties: + update: + oneOf: + - $ref: '#/components/schemas/ProfileUpdateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedUpdateWithoutUserInput' + create: + oneOf: + - $ref: '#/components/schemas/ProfileCreateWithoutUserInput' + - $ref: '#/components/schemas/ProfileUncheckedCreateWithoutUserInput' + required: + - update + - create + ProfileUpdateWithoutUserInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + image: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + ProfileUncheckedUpdateWithoutUserInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + image: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + UserCreateWithoutProfileInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + posts: + $ref: '#/components/schemas/Post_ItemCreateNestedManyWithoutAuthorInput' + required: + - email + UserUncheckedCreateWithoutProfileInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + posts: + $ref: "#/components/schemas/Post_ItemUncheckedCreateNestedManyWithoutAuthorInpu\ + t" + required: + - email + UserCreateOrConnectWithoutProfileInput: + type: object + properties: + where: + $ref: '#/components/schemas/UserWhereUniqueInput' + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutProfileInput' + required: + - where + - create + UserUpsertWithoutProfileInput: + type: object + properties: + update: + oneOf: + - $ref: '#/components/schemas/UserUpdateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedUpdateWithoutProfileInput' + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutProfileInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutProfileInput' + required: + - update + - create + UserUpdateWithoutProfileInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + email: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + role: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + posts: + $ref: '#/components/schemas/Post_ItemUpdateManyWithoutAuthorNestedInput' + UserUncheckedUpdateWithoutProfileInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + email: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + role: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + posts: + $ref: "#/components/schemas/Post_ItemUncheckedUpdateManyWithoutAuthorNestedInpu\ + t" + UserCreateWithoutPostsInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + profile: + $ref: '#/components/schemas/ProfileCreateNestedOneWithoutUserInput' + required: + - email + UserUncheckedCreateWithoutPostsInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + profile: + $ref: '#/components/schemas/ProfileUncheckedCreateNestedOneWithoutUserInput' + required: + - email + UserCreateOrConnectWithoutPostsInput: + type: object + properties: + where: + $ref: '#/components/schemas/UserWhereUniqueInput' + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + required: + - where + - create + UserUpsertWithoutPostsInput: + type: object + properties: + update: + oneOf: + - $ref: '#/components/schemas/UserUpdateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedUpdateWithoutPostsInput' + create: + oneOf: + - $ref: '#/components/schemas/UserCreateWithoutPostsInput' + - $ref: '#/components/schemas/UserUncheckedCreateWithoutPostsInput' + required: + - update + - create + UserUpdateWithoutPostsInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + email: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + role: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + profile: + $ref: '#/components/schemas/ProfileUpdateOneWithoutUserNestedInput' + UserUncheckedUpdateWithoutPostsInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + email: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + role: + oneOf: + - $ref: '#/components/schemas/Role' + - $ref: '#/components/schemas/EnumroleFieldUpdateOperationsInput' + profile: + $ref: '#/components/schemas/ProfileUncheckedUpdateOneWithoutUserNestedInput' + Post_ItemCreateManyAuthorInput: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + published: + type: boolean + viewCount: + type: integer + notes: + oneOf: + - type: 'null' + - type: string + required: + - id + - title + Post_ItemUpdateWithoutAuthorInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + title: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + published: + oneOf: + - type: boolean + - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' + viewCount: + oneOf: + - type: integer + - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + Post_ItemUncheckedUpdateWithoutAuthorInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + title: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + published: + oneOf: + - type: boolean + - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' + viewCount: + oneOf: + - type: integer + - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + Post_ItemUncheckedUpdateManyWithoutPostsInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + createdAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + updatedAt: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + title: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + published: + oneOf: + - type: boolean + - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' + viewCount: + oneOf: + - type: integer + - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + notes: + oneOf: + - type: string + - $ref: '#/components/schemas/NullableStringFieldUpdateOperationsInput' + - type: 'null' + UserArgs: + type: object + properties: + select: + $ref: '#/components/schemas/UserSelect' + include: + $ref: '#/components/schemas/UserInclude' + ProfileArgs: + type: object + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + UserInclude: + type: object + properties: + posts: + oneOf: + - type: boolean + - $ref: '#/components/schemas/Post_ItemFindManyArgs' + profile: + oneOf: + - type: boolean + - $ref: '#/components/schemas/ProfileArgs' + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserCountOutputTypeArgs' + ProfileInclude: + type: object + properties: + user: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserArgs' + Post_ItemInclude: + type: object + properties: + author: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserArgs' + UserCountOutputTypeSelect: + type: object + properties: + posts: + type: boolean + UserCountOutputTypeArgs: + type: object + properties: + select: + $ref: '#/components/schemas/UserCountOutputTypeSelect' + UserSelect: + type: object + properties: + id: + type: boolean + createdAt: + type: boolean + updatedAt: + type: boolean + email: + type: boolean + role: + type: boolean + posts: + oneOf: + - type: boolean + - $ref: '#/components/schemas/Post_ItemFindManyArgs' + profile: + oneOf: + - type: boolean + - $ref: '#/components/schemas/ProfileArgs' + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserCountOutputTypeArgs' + ProfileSelect: + type: object + properties: + id: + type: boolean + image: + type: boolean + user: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserArgs' + userId: + type: boolean + Post_ItemSelect: + type: object + properties: + id: + type: boolean + createdAt: + type: boolean + updatedAt: + type: boolean + title: + type: boolean + author: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserArgs' + authorId: + type: boolean + published: + type: boolean + viewCount: + type: boolean + notes: + type: boolean + UserCountAggregateInput: + type: object + properties: + id: + type: boolean + createdAt: + type: boolean + updatedAt: + type: boolean + email: + type: boolean + role: + type: boolean + _all: + type: boolean + UserMinAggregateInput: + type: object + properties: + id: + type: boolean + createdAt: + type: boolean + updatedAt: + type: boolean + email: + type: boolean + role: + type: boolean + UserMaxAggregateInput: + type: object + properties: + id: + type: boolean + createdAt: + type: boolean + updatedAt: + type: boolean + email: + type: boolean + role: + type: boolean + ProfileCountAggregateInput: + type: object + properties: + id: + type: boolean + image: + type: boolean + userId: + type: boolean + _all: + type: boolean + ProfileMinAggregateInput: + type: object + properties: + id: + type: boolean + image: + type: boolean + userId: + type: boolean + ProfileMaxAggregateInput: + type: object + properties: + id: + type: boolean + image: + type: boolean + userId: + type: boolean + AggregateUser: + type: object + properties: + _count: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/UserCountAggregateOutputType' + _min: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/UserMinAggregateOutputType' + _max: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/UserMaxAggregateOutputType' + UserGroupByOutputType: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + email: + type: string + role: + $ref: '#/components/schemas/Role' + _count: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/UserCountAggregateOutputType' + _min: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/UserMinAggregateOutputType' + _max: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/UserMaxAggregateOutputType' + required: + - id + - createdAt + - updatedAt + - email + - role + AggregateProfile: + type: object + properties: + _count: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/ProfileCountAggregateOutputType' + _min: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/ProfileMinAggregateOutputType' + _max: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/ProfileMaxAggregateOutputType' + ProfileGroupByOutputType: + type: object + properties: + id: + type: string + image: + oneOf: + - type: 'null' + - type: string + userId: + type: string + _count: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/ProfileCountAggregateOutputType' + _min: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/ProfileMinAggregateOutputType' + _max: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/ProfileMaxAggregateOutputType' + required: + - id + - userId + AggregatePost_Item: + type: object + properties: + _count: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemCountAggregateOutputType' + _avg: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemAvgAggregateOutputType' + _sum: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemSumAggregateOutputType' + _min: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemMinAggregateOutputType' + _max: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemMaxAggregateOutputType' + Post_ItemGroupByOutputType: + type: object + properties: + id: + type: string + createdAt: + type: string + format: date-time + updatedAt: + type: string + format: date-time + title: + type: string + authorId: + oneOf: + - type: 'null' + - type: string + published: + type: boolean + viewCount: + type: integer + notes: + oneOf: + - type: 'null' + - type: string + _count: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemCountAggregateOutputType' + _avg: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemAvgAggregateOutputType' + _sum: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemSumAggregateOutputType' + _min: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemMinAggregateOutputType' + _max: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Post_ItemMaxAggregateOutputType' + required: + - id + - createdAt + - updatedAt + - title + - published + - viewCount + UserCountAggregateOutputType: + type: object + properties: + id: + type: integer + createdAt: + type: integer + updatedAt: + type: integer + email: + type: integer + role: + type: integer + _all: + type: integer + required: + - id + - createdAt + - updatedAt + - email + - role + - _all + UserMinAggregateOutputType: + type: object + properties: + id: + oneOf: + - type: 'null' + - type: string + createdAt: + oneOf: + - type: 'null' + - type: string + format: date-time + updatedAt: + oneOf: + - type: 'null' + - type: string + format: date-time + email: + oneOf: + - type: 'null' + - type: string + role: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Role' + UserMaxAggregateOutputType: + type: object + properties: + id: + oneOf: + - type: 'null' + - type: string + createdAt: + oneOf: + - type: 'null' + - type: string + format: date-time + updatedAt: + oneOf: + - type: 'null' + - type: string + format: date-time + email: + oneOf: + - type: 'null' + - type: string + role: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/Role' + ProfileCountAggregateOutputType: + type: object + properties: + id: + type: integer + image: + type: integer + userId: + type: integer + _all: + type: integer + required: + - id + - image + - userId + - _all + ProfileMinAggregateOutputType: + type: object + properties: + id: + oneOf: + - type: 'null' + - type: string + image: + oneOf: + - type: 'null' + - type: string + userId: + oneOf: + - type: 'null' + - type: string + ProfileMaxAggregateOutputType: + type: object + properties: + id: + oneOf: + - type: 'null' + - type: string + image: + oneOf: + - type: 'null' + - type: string + userId: + oneOf: + - type: 'null' + - type: string + Post_ItemCountAggregateOutputType: + type: object + properties: + id: + type: integer + createdAt: + type: integer + updatedAt: + type: integer + title: + type: integer + authorId: + type: integer + published: + type: integer + viewCount: + type: integer + notes: + type: integer + _all: + type: integer + required: + - id + - createdAt + - updatedAt + - title + - authorId + - published + - viewCount + - notes + - _all + Post_ItemAvgAggregateOutputType: + type: object + properties: + viewCount: + oneOf: + - type: 'null' + - type: number + Post_ItemSumAggregateOutputType: + type: object + properties: + viewCount: + oneOf: + - type: 'null' + - type: integer + Post_ItemMinAggregateOutputType: + type: object + properties: + id: + oneOf: + - type: 'null' + - type: string + createdAt: + oneOf: + - type: 'null' + - type: string + format: date-time + updatedAt: + oneOf: + - type: 'null' + - type: string + format: date-time + title: + oneOf: + - type: 'null' + - type: string + authorId: + oneOf: + - type: 'null' + - type: string + published: + oneOf: + - type: 'null' + - type: boolean + viewCount: + oneOf: + - type: 'null' + - type: integer + notes: + oneOf: + - type: 'null' + - type: string + Post_ItemMaxAggregateOutputType: + type: object + properties: + id: + oneOf: + - type: 'null' + - type: string + createdAt: + oneOf: + - type: 'null' + - type: string + format: date-time + updatedAt: + oneOf: + - type: 'null' + - type: string + format: date-time + title: + oneOf: + - type: 'null' + - type: string + authorId: + oneOf: + - type: 'null' + - type: string + published: + oneOf: + - type: 'null' + - type: boolean + viewCount: + oneOf: + - type: 'null' + - type: integer + notes: + oneOf: + - type: 'null' + - type: string + _Meta: + type: object + properties: + meta: + type: object + description: Meta information about the request or response + properties: + serialization: + description: Serialization metadata + additionalProperties: true + _Error: + type: object + required: + - error + properties: + error: + type: object + required: + - message + properties: + prisma: + type: boolean + description: Indicates if the error occurred during a Prisma call + rejectedByPolicy: + type: boolean + description: Indicates if the error was due to rejection by a policy + code: + type: string + description: Prisma error code. Only available when "prisma" field is true. + message: + type: string + description: Error message + reason: + type: string + description: Detailed error reason + zodErrors: + type: object + additionalProperties: true + description: Zod validation errors if the error is due to data validation + failure + additionalProperties: true + BatchPayload: + type: object + properties: + count: + type: integer + UserCreateArgs: + type: object + required: + - data + properties: + select: + $ref: '#/components/schemas/UserSelect' + include: + $ref: '#/components/schemas/UserInclude' + data: + $ref: '#/components/schemas/UserCreateInput' + meta: + $ref: '#/components/schemas/_Meta' + UserCreateManyArgs: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/UserCreateManyInput' + meta: + $ref: '#/components/schemas/_Meta' + UserFindUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/UserSelect' + include: + $ref: '#/components/schemas/UserInclude' + where: + $ref: '#/components/schemas/UserWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + UserFindFirstArgs: + type: object + properties: + select: + $ref: '#/components/schemas/UserSelect' + include: + $ref: '#/components/schemas/UserInclude' + where: + $ref: '#/components/schemas/UserWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + UserFindManyArgs: + type: object + properties: + select: + $ref: '#/components/schemas/UserSelect' + include: + $ref: '#/components/schemas/UserInclude' + where: + $ref: '#/components/schemas/UserWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + UserUpdateArgs: + type: object + required: + - where + - data + properties: + select: + $ref: '#/components/schemas/UserSelect' + include: + $ref: '#/components/schemas/UserInclude' + where: + $ref: '#/components/schemas/UserWhereUniqueInput' + data: + $ref: '#/components/schemas/UserUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + UserUpdateManyArgs: + type: object + required: + - data + properties: + where: + $ref: '#/components/schemas/UserWhereInput' + data: + $ref: '#/components/schemas/UserUpdateManyMutationInput' + meta: + $ref: '#/components/schemas/_Meta' + UserUpsertArgs: + type: object + required: + - create + - update + - where + properties: + select: + $ref: '#/components/schemas/UserSelect' + include: + $ref: '#/components/schemas/UserInclude' + where: + $ref: '#/components/schemas/UserWhereUniqueInput' + create: + $ref: '#/components/schemas/UserCreateInput' + update: + $ref: '#/components/schemas/UserUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + UserDeleteUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/UserSelect' + include: + $ref: '#/components/schemas/UserInclude' + where: + $ref: '#/components/schemas/UserWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + UserDeleteManyArgs: + type: object + properties: + where: + $ref: '#/components/schemas/UserWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + UserCountArgs: + type: object + properties: + select: + $ref: '#/components/schemas/UserSelect' + where: + $ref: '#/components/schemas/UserWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + UserAggregateArgs: + type: object + properties: + where: + $ref: '#/components/schemas/UserWhereInput' + orderBy: + $ref: '#/components/schemas/UserOrderByWithRelationInput' + cursor: + $ref: '#/components/schemas/UserWhereUniqueInput' + take: + type: integer + skip: + type: integer + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserCountAggregateInput' + _min: + $ref: '#/components/schemas/UserMinAggregateInput' + _max: + $ref: '#/components/schemas/UserMaxAggregateInput' + meta: + $ref: '#/components/schemas/_Meta' + UserGroupByArgs: + type: object + properties: + where: + $ref: '#/components/schemas/UserWhereInput' + orderBy: + $ref: '#/components/schemas/UserOrderByWithRelationInput' + by: + $ref: '#/components/schemas/UserScalarFieldEnum' + having: + $ref: '#/components/schemas/UserScalarWhereWithAggregatesInput' + take: + type: integer + skip: + type: integer + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/UserCountAggregateInput' + _min: + $ref: '#/components/schemas/UserMinAggregateInput' + _max: + $ref: '#/components/schemas/UserMaxAggregateInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileCreateArgs: + type: object + required: + - data + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + data: + $ref: '#/components/schemas/ProfileCreateInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileCreateManyArgs: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/ProfileCreateManyInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileFindUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + where: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileFindFirstArgs: + type: object + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + where: + $ref: '#/components/schemas/ProfileWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileFindManyArgs: + type: object + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + where: + $ref: '#/components/schemas/ProfileWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileUpdateArgs: + type: object + required: + - where + - data + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + where: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + data: + $ref: '#/components/schemas/ProfileUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileUpdateManyArgs: + type: object + required: + - data + properties: + where: + $ref: '#/components/schemas/ProfileWhereInput' + data: + $ref: '#/components/schemas/ProfileUpdateManyMutationInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileUpsertArgs: + type: object + required: + - create + - update + - where + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + where: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + create: + $ref: '#/components/schemas/ProfileCreateInput' + update: + $ref: '#/components/schemas/ProfileUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileDeleteUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + include: + $ref: '#/components/schemas/ProfileInclude' + where: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileDeleteManyArgs: + type: object + properties: + where: + $ref: '#/components/schemas/ProfileWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileCountArgs: + type: object + properties: + select: + $ref: '#/components/schemas/ProfileSelect' + where: + $ref: '#/components/schemas/ProfileWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileAggregateArgs: + type: object + properties: + where: + $ref: '#/components/schemas/ProfileWhereInput' + orderBy: + $ref: '#/components/schemas/ProfileOrderByWithRelationInput' + cursor: + $ref: '#/components/schemas/ProfileWhereUniqueInput' + take: + type: integer + skip: + type: integer + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/ProfileCountAggregateInput' + _min: + $ref: '#/components/schemas/ProfileMinAggregateInput' + _max: + $ref: '#/components/schemas/ProfileMaxAggregateInput' + meta: + $ref: '#/components/schemas/_Meta' + ProfileGroupByArgs: + type: object + properties: + where: + $ref: '#/components/schemas/ProfileWhereInput' + orderBy: + $ref: '#/components/schemas/ProfileOrderByWithRelationInput' + by: + $ref: '#/components/schemas/ProfileScalarFieldEnum' + having: + $ref: '#/components/schemas/ProfileScalarWhereWithAggregatesInput' + take: + type: integer + skip: + type: integer + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/ProfileCountAggregateInput' + _min: + $ref: '#/components/schemas/ProfileMinAggregateInput' + _max: + $ref: '#/components/schemas/ProfileMaxAggregateInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemCreateArgs: + type: object + required: + - data + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + data: + $ref: '#/components/schemas/Post_ItemCreateInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemCreateManyArgs: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Post_ItemCreateManyInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemFindUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemFindFirstArgs: + type: object + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemFindManyArgs: + type: object + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemUpdateArgs: + type: object + required: + - where + - data + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + data: + $ref: '#/components/schemas/Post_ItemUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemUpdateManyArgs: + type: object + required: + - data + properties: + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + data: + $ref: '#/components/schemas/Post_ItemUpdateManyMutationInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemUpsertArgs: + type: object + required: + - create + - update + - where + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + create: + $ref: '#/components/schemas/Post_ItemCreateInput' + update: + $ref: '#/components/schemas/Post_ItemUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemDeleteUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + include: + $ref: '#/components/schemas/Post_ItemInclude' + where: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemDeleteManyArgs: + type: object + properties: + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemCountArgs: + type: object + properties: + select: + $ref: '#/components/schemas/Post_ItemSelect' + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemAggregateArgs: + type: object + properties: + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + orderBy: + $ref: '#/components/schemas/Post_ItemOrderByWithRelationInput' + cursor: + $ref: '#/components/schemas/Post_ItemWhereUniqueInput' + take: + type: integer + skip: + type: integer + meta: + $ref: '#/components/schemas/_Meta' + Post_ItemGroupByArgs: + type: object + properties: + where: + $ref: '#/components/schemas/Post_ItemWhereInput' + orderBy: + $ref: '#/components/schemas/Post_ItemOrderByWithRelationInput' + by: + $ref: '#/components/schemas/Post_ItemScalarFieldEnum' + having: + $ref: '#/components/schemas/Post_ItemScalarWhereWithAggregatesInput' + take: + type: integer + skip: + type: integer + meta: + $ref: '#/components/schemas/_Meta' +paths: + /user/create: + post: + operationId: createUser + description: Create a new User + tags: + - user + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/User' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserCreateArgs' + /user/createMany: + post: + operationId: createManyUser + description: Create several User + tags: + - user + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserCreateManyArgs' + /user/findUnique: + get: + operationId: findUniqueUser + description: Find one unique User + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/User' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/UserFindUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /user/findFirst: + get: + operationId: findFirstUser + description: Find the first User matching the given condition + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/User' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/UserFindFirstArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /user/findMany: + get: + operationId: findManyUser + description: Find users matching the given conditions + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/User' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/UserFindManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /user/update: + patch: + operationId: updateUser + description: Update a User + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/User' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserUpdateArgs' + /user/updateMany: + patch: + operationId: updateManyUser + description: Update Users matching the given condition + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserUpdateManyArgs' + /user/upsert: + post: + operationId: upsertUser + description: Upsert a User + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/User' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserUpsertArgs' + /user/dodelete: + put: + operationId: deleteUser + description: Delete a unique user + tags: + - delete + - user + summary: Delete a user yeah yeah + deprecated: true + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/User' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserDeleteUniqueArgs' + /user/deleteMany: + delete: + operationId: deleteManyUser + description: Delete Users matching the given condition + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/UserDeleteManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /user/count: + get: + operationId: countUser + description: Find a list of User + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + oneOf: + - type: integer + - $ref: '#/components/schemas/UserCountAggregateOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/UserCountArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /user/aggregate: + get: + operationId: aggregateUser + description: Aggregate Users + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/AggregateUser' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/UserAggregateArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /user/groupBy: + get: + operationId: groupByUser + description: Group Users by fields + tags: + - user + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/UserGroupByOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/UserGroupByArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/create: + post: + operationId: createProfile + description: Create a new Profile + tags: + - profile + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileCreateArgs' + /profile/createMany: + post: + operationId: createManyProfile + description: Create several Profile + tags: + - profile + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileCreateManyArgs' + /profile/findUnique: + get: + operationId: findUniqueProfile + description: Find one unique Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileFindUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/findFirst: + get: + operationId: findFirstProfile + description: Find the first Profile matching the given condition + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileFindFirstArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/findMany: + get: + operationId: findManyProfile + description: Find a list of Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileFindManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/update: + patch: + operationId: updateProfile + description: Update a Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpdateArgs' + /profile/updateMany: + patch: + operationId: updateManyProfile + description: Update Profiles matching the given condition + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpdateManyArgs' + /profile/upsert: + post: + operationId: upsertProfile + description: Upsert a Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpsertArgs' + /profile/delete: + delete: + operationId: deleteProfile + description: Delete one unique Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Profile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileDeleteUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/deleteMany: + delete: + operationId: deleteManyProfile + description: Delete Profiles matching the given condition + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileDeleteManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/count: + get: + operationId: countProfile + description: Find a list of Profile + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + oneOf: + - type: integer + - $ref: '#/components/schemas/ProfileCountAggregateOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileCountArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/aggregate: + get: + operationId: aggregateProfile + description: Aggregate Profiles + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/AggregateProfile' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileAggregateArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /profile/groupBy: + get: + operationId: groupByProfile + description: Group Profiles by fields + tags: + - profile + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/ProfileGroupByOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileGroupByArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /post_Item/create: + post: + operationId: createPost_Item + description: Create a new Post_Item + tags: + - post_Item + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Post_Item' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemCreateArgs' + /post_Item/createMany: + post: + operationId: createManyPost_Item + description: Create several Post_Item + tags: + - post_Item + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemCreateManyArgs' + /post_Item/findUnique: + get: + operationId: findUniquePost_Item + description: Find one unique Post_Item + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Post_Item' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemFindUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /post_Item/findFirst: + get: + operationId: findFirstPost_Item + description: Find the first Post_Item matching the given condition + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Post_Item' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemFindFirstArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /post_Item/update: + patch: + operationId: updatePost_Item + description: Update a Post_Item + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Post_Item' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemUpdateArgs' + /post_Item/updateMany: + patch: + operationId: updateManyPost_Item + description: Update Post_Items matching the given condition + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemUpdateManyArgs' + /post_Item/upsert: + post: + operationId: upsertPost_Item + description: Upsert a Post_Item + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Post_Item' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemUpsertArgs' + /post_Item/delete: + delete: + operationId: deletePost_Item + description: Delete one unique Post_Item + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Post_Item' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemDeleteUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /post_Item/deleteMany: + delete: + operationId: deleteManyPost_Item + description: Delete Post_Items matching the given condition + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemDeleteManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /post_Item/count: + get: + operationId: countPost_Item + description: Find a list of Post_Item + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + oneOf: + - type: integer + - $ref: '#/components/schemas/Post_ItemCountAggregateOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemCountArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /post_Item/aggregate: + get: + operationId: aggregatePost_Item + description: Aggregate Post_Items + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/AggregatePost_Item' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemAggregateArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /post_Item/groupBy: + get: + operationId: groupByPost_Item + description: Group Post_Items by fields + tags: + - post_Item + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/Post_ItemGroupByOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/Post_ItemGroupByArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} diff --git a/packages/plugins/openapi/tests/baseline/rpc-type-coverage.baseline.yaml b/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.0.0.baseline.yaml similarity index 94% rename from packages/plugins/openapi/tests/baseline/rpc-type-coverage.baseline.yaml rename to packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.0.0.baseline.yaml index cbe6476f8..6e219e6e3 100644 --- a/packages/plugins/openapi/tests/baseline/rpc-type-coverage.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.0.0.baseline.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.0 +openapi: 3.0.0 info: title: ZenStack Generated API version: 1.0.0 @@ -29,6 +29,11 @@ components: enum: - default - insensitive + NullsOrder: + type: string + enum: + - first + - last Foo: type: object properties: @@ -54,6 +59,7 @@ components: bytes: type: string format: byte + nullable: true required: - id - string @@ -63,7 +69,6 @@ components: - float - decimal - boolean - - bytes FooWhereInput: type: object properties: @@ -120,9 +125,10 @@ components: - type: boolean bytes: oneOf: - - $ref: '#/components/schemas/BytesFilter' + - $ref: '#/components/schemas/BytesNullableFilter' - type: string format: byte + nullable: true FooOrderByWithRelationInput: type: object properties: @@ -143,7 +149,9 @@ components: boolean: $ref: '#/components/schemas/SortOrder' bytes: - $ref: '#/components/schemas/SortOrder' + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' FooWhereUniqueInput: type: object properties: @@ -205,9 +213,10 @@ components: - type: boolean bytes: oneOf: - - $ref: '#/components/schemas/BytesWithAggregatesFilter' + - $ref: '#/components/schemas/BytesNullableWithAggregatesFilter' - type: string format: byte + nullable: true FooCreateInput: type: object properties: @@ -233,6 +242,7 @@ components: bytes: type: string format: byte + nullable: true required: - string - int @@ -241,7 +251,6 @@ components: - float - decimal - boolean - - bytes FooUpdateInput: type: object properties: @@ -284,7 +293,8 @@ components: oneOf: - type: string format: byte - - $ref: '#/components/schemas/BytesFieldUpdateOperationsInput' + - $ref: '#/components/schemas/NullableBytesFieldUpdateOperationsInput' + nullable: true FooCreateManyInput: type: object properties: @@ -310,6 +320,7 @@ components: bytes: type: string format: byte + nullable: true required: - string - int @@ -318,7 +329,6 @@ components: - float - decimal - boolean - - bytes FooUpdateManyMutationInput: type: object properties: @@ -361,7 +371,8 @@ components: oneOf: - type: string format: byte - - $ref: '#/components/schemas/BytesFieldUpdateOperationsInput' + - $ref: '#/components/schemas/NullableBytesFieldUpdateOperationsInput' + nullable: true StringFilter: type: object properties: @@ -583,12 +594,13 @@ components: oneOf: - type: boolean - $ref: '#/components/schemas/NestedBoolFilter' - BytesFilter: + BytesNullableFilter: type: object properties: equals: type: string format: byte + nullable: true in: oneOf: - type: array @@ -597,6 +609,7 @@ components: format: byte - type: string format: byte + nullable: true notIn: oneOf: - type: array @@ -605,11 +618,22 @@ components: format: byte - type: string format: byte + nullable: true not: oneOf: - type: string format: byte - - $ref: '#/components/schemas/NestedBytesFilter' + - $ref: '#/components/schemas/NestedBytesNullableFilter' + nullable: true + SortOrderInput: + type: object + properties: + sort: + $ref: '#/components/schemas/SortOrder' + nulls: + $ref: '#/components/schemas/NullsOrder' + required: + - sort StringWithAggregatesFilter: type: object properties: @@ -889,12 +913,13 @@ components: $ref: '#/components/schemas/NestedBoolFilter' _max: $ref: '#/components/schemas/NestedBoolFilter' - BytesWithAggregatesFilter: + BytesNullableWithAggregatesFilter: type: object properties: equals: type: string format: byte + nullable: true in: oneOf: - type: array @@ -903,6 +928,7 @@ components: format: byte - type: string format: byte + nullable: true notIn: oneOf: - type: array @@ -911,17 +937,19 @@ components: format: byte - type: string format: byte + nullable: true not: oneOf: - type: string format: byte - - $ref: '#/components/schemas/NestedBytesWithAggregatesFilter' + - $ref: '#/components/schemas/NestedBytesNullableWithAggregatesFilter' + nullable: true _count: - $ref: '#/components/schemas/NestedIntFilter' + $ref: '#/components/schemas/NestedIntNullableFilter' _min: - $ref: '#/components/schemas/NestedBytesFilter' + $ref: '#/components/schemas/NestedBytesNullableFilter' _max: - $ref: '#/components/schemas/NestedBytesFilter' + $ref: '#/components/schemas/NestedBytesNullableFilter' StringFieldUpdateOperationsInput: type: object properties: @@ -1000,12 +1028,13 @@ components: properties: set: type: boolean - BytesFieldUpdateOperationsInput: + NullableBytesFieldUpdateOperationsInput: type: object properties: set: type: string format: byte + nullable: true NestedStringFilter: type: object properties: @@ -1225,12 +1254,13 @@ components: oneOf: - type: boolean - $ref: '#/components/schemas/NestedBoolFilter' - NestedBytesFilter: + NestedBytesNullableFilter: type: object properties: equals: type: string format: byte + nullable: true in: oneOf: - type: array @@ -1239,6 +1269,7 @@ components: format: byte - type: string format: byte + nullable: true notIn: oneOf: - type: array @@ -1247,11 +1278,13 @@ components: format: byte - type: string format: byte + nullable: true not: oneOf: - type: string format: byte - - $ref: '#/components/schemas/NestedBytesFilter' + - $ref: '#/components/schemas/NestedBytesNullableFilter' + nullable: true NestedStringWithAggregatesFilter: type: object properties: @@ -1529,12 +1562,13 @@ components: $ref: '#/components/schemas/NestedBoolFilter' _max: $ref: '#/components/schemas/NestedBoolFilter' - NestedBytesWithAggregatesFilter: + NestedBytesNullableWithAggregatesFilter: type: object properties: equals: type: string format: byte + nullable: true in: oneOf: - type: array @@ -1543,6 +1577,7 @@ components: format: byte - type: string format: byte + nullable: true notIn: oneOf: - type: array @@ -1551,17 +1586,52 @@ components: format: byte - type: string format: byte + nullable: true not: oneOf: - type: string format: byte - - $ref: '#/components/schemas/NestedBytesWithAggregatesFilter' + - $ref: '#/components/schemas/NestedBytesNullableWithAggregatesFilter' + nullable: true _count: - $ref: '#/components/schemas/NestedIntFilter' + $ref: '#/components/schemas/NestedIntNullableFilter' _min: - $ref: '#/components/schemas/NestedBytesFilter' + $ref: '#/components/schemas/NestedBytesNullableFilter' _max: - $ref: '#/components/schemas/NestedBytesFilter' + $ref: '#/components/schemas/NestedBytesNullableFilter' + NestedIntNullableFilter: + type: object + properties: + equals: + type: integer + nullable: true + in: + oneOf: + - type: array + items: + type: integer + - type: integer + nullable: true + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + nullable: true + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntNullableFilter' + nullable: true FooSelect: type: object properties: @@ -1674,15 +1744,25 @@ components: type: object properties: _count: - $ref: '#/components/schemas/FooCountAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooCountAggregateOutputType' + nullable: true _avg: - $ref: '#/components/schemas/FooAvgAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooAvgAggregateOutputType' + nullable: true _sum: - $ref: '#/components/schemas/FooSumAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooSumAggregateOutputType' + nullable: true _min: - $ref: '#/components/schemas/FooMinAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooMinAggregateOutputType' + nullable: true _max: - $ref: '#/components/schemas/FooMaxAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooMaxAggregateOutputType' + nullable: true FooGroupByOutputType: type: object properties: @@ -1708,16 +1788,27 @@ components: bytes: type: string format: byte + nullable: true _count: - $ref: '#/components/schemas/FooCountAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooCountAggregateOutputType' + nullable: true _avg: - $ref: '#/components/schemas/FooAvgAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooAvgAggregateOutputType' + nullable: true _sum: - $ref: '#/components/schemas/FooSumAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooSumAggregateOutputType' + nullable: true _min: - $ref: '#/components/schemas/FooMinAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooMinAggregateOutputType' + nullable: true _max: - $ref: '#/components/schemas/FooMaxAggregateOutputType' + allOf: + - $ref: '#/components/schemas/FooMaxAggregateOutputType' + nullable: true required: - id - string @@ -1727,7 +1818,6 @@ components: - float - decimal - boolean - - bytes FooCountAggregateOutputType: type: object properties: @@ -1767,77 +1857,103 @@ components: properties: int: type: number + nullable: true bigInt: type: number + nullable: true float: type: number + nullable: true decimal: oneOf: - type: string - type: number + nullable: true FooSumAggregateOutputType: type: object properties: int: type: integer + nullable: true bigInt: type: integer + nullable: true float: type: number + nullable: true decimal: oneOf: - type: string - type: number + nullable: true FooMinAggregateOutputType: type: object properties: id: type: string + nullable: true string: type: string + nullable: true int: type: integer + nullable: true bigInt: type: integer + nullable: true date: type: string format: date-time + nullable: true float: type: number + nullable: true decimal: oneOf: - type: string - type: number + nullable: true boolean: type: boolean + nullable: true bytes: type: string format: byte + nullable: true FooMaxAggregateOutputType: type: object properties: id: type: string + nullable: true string: type: string + nullable: true int: type: integer + nullable: true bigInt: type: integer + nullable: true date: type: string format: date-time + nullable: true float: type: number + nullable: true decimal: oneOf: - type: string - type: number + nullable: true boolean: type: boolean + nullable: true bytes: type: string format: byte + nullable: true _Meta: type: object properties: diff --git a/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.1.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.1.0.baseline.yaml new file mode 100644 index 000000000..e777f7580 --- /dev/null +++ b/packages/plugins/openapi/tests/baseline/rpc-type-coverage-3.1.0.baseline.yaml @@ -0,0 +1,2815 @@ +openapi: 3.1.0 +info: + title: ZenStack Generated API + version: 1.0.0 +tags: + - name: foo + description: Foo operations +components: + schemas: + FooScalarFieldEnum: + type: string + enum: + - id + - string + - int + - bigInt + - date + - float + - decimal + - boolean + - bytes + SortOrder: + type: string + enum: + - asc + - desc + QueryMode: + type: string + enum: + - default + - insensitive + NullsOrder: + type: string + enum: + - first + - last + Foo: + type: object + properties: + id: + type: string + string: + type: string + int: + type: integer + bigInt: + type: integer + date: + type: string + format: date-time + float: + type: number + decimal: + oneOf: + - type: string + - type: number + boolean: + type: boolean + bytes: + oneOf: + - type: 'null' + - type: string + format: byte + required: + - id + - string + - int + - bigInt + - date + - float + - decimal + - boolean + FooWhereInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/FooWhereInput' + - type: array + items: + $ref: '#/components/schemas/FooWhereInput' + OR: + type: array + items: + $ref: '#/components/schemas/FooWhereInput' + NOT: + oneOf: + - $ref: '#/components/schemas/FooWhereInput' + - type: array + items: + $ref: '#/components/schemas/FooWhereInput' + id: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + string: + oneOf: + - $ref: '#/components/schemas/StringFilter' + - type: string + int: + oneOf: + - $ref: '#/components/schemas/IntFilter' + - type: integer + bigInt: + oneOf: + - $ref: '#/components/schemas/BigIntFilter' + - type: integer + date: + oneOf: + - $ref: '#/components/schemas/DateTimeFilter' + - type: string + format: date-time + float: + oneOf: + - $ref: '#/components/schemas/FloatFilter' + - type: number + decimal: + oneOf: + - $ref: '#/components/schemas/DecimalFilter' + - oneOf: + - type: string + - type: number + boolean: + oneOf: + - $ref: '#/components/schemas/BoolFilter' + - type: boolean + bytes: + oneOf: + - $ref: '#/components/schemas/BytesNullableFilter' + - type: string + format: byte + - type: 'null' + FooOrderByWithRelationInput: + type: object + properties: + id: + $ref: '#/components/schemas/SortOrder' + string: + $ref: '#/components/schemas/SortOrder' + int: + $ref: '#/components/schemas/SortOrder' + bigInt: + $ref: '#/components/schemas/SortOrder' + date: + $ref: '#/components/schemas/SortOrder' + float: + $ref: '#/components/schemas/SortOrder' + decimal: + $ref: '#/components/schemas/SortOrder' + boolean: + $ref: '#/components/schemas/SortOrder' + bytes: + oneOf: + - $ref: '#/components/schemas/SortOrder' + - $ref: '#/components/schemas/SortOrderInput' + FooWhereUniqueInput: + type: object + properties: + id: + type: string + FooScalarWhereWithAggregatesInput: + type: object + properties: + AND: + oneOf: + - $ref: '#/components/schemas/FooScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/FooScalarWhereWithAggregatesInput' + OR: + type: array + items: + $ref: '#/components/schemas/FooScalarWhereWithAggregatesInput' + NOT: + oneOf: + - $ref: '#/components/schemas/FooScalarWhereWithAggregatesInput' + - type: array + items: + $ref: '#/components/schemas/FooScalarWhereWithAggregatesInput' + id: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + string: + oneOf: + - $ref: '#/components/schemas/StringWithAggregatesFilter' + - type: string + int: + oneOf: + - $ref: '#/components/schemas/IntWithAggregatesFilter' + - type: integer + bigInt: + oneOf: + - $ref: '#/components/schemas/BigIntWithAggregatesFilter' + - type: integer + date: + oneOf: + - $ref: '#/components/schemas/DateTimeWithAggregatesFilter' + - type: string + format: date-time + float: + oneOf: + - $ref: '#/components/schemas/FloatWithAggregatesFilter' + - type: number + decimal: + oneOf: + - $ref: '#/components/schemas/DecimalWithAggregatesFilter' + - oneOf: + - type: string + - type: number + boolean: + oneOf: + - $ref: '#/components/schemas/BoolWithAggregatesFilter' + - type: boolean + bytes: + oneOf: + - $ref: '#/components/schemas/BytesNullableWithAggregatesFilter' + - type: string + format: byte + - type: 'null' + FooCreateInput: + type: object + properties: + id: + type: string + string: + type: string + int: + type: integer + bigInt: + type: integer + date: + type: string + format: date-time + float: + type: number + decimal: + oneOf: + - type: string + - type: number + boolean: + type: boolean + bytes: + oneOf: + - type: 'null' + - type: string + format: byte + required: + - string + - int + - bigInt + - date + - float + - decimal + - boolean + FooUpdateInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + string: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + int: + oneOf: + - type: integer + - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + bigInt: + oneOf: + - type: integer + - $ref: '#/components/schemas/BigIntFieldUpdateOperationsInput' + date: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + float: + oneOf: + - type: number + - $ref: '#/components/schemas/FloatFieldUpdateOperationsInput' + decimal: + oneOf: + - oneOf: + - type: string + - type: number + - $ref: '#/components/schemas/DecimalFieldUpdateOperationsInput' + boolean: + oneOf: + - type: boolean + - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' + bytes: + oneOf: + - type: string + format: byte + - $ref: '#/components/schemas/NullableBytesFieldUpdateOperationsInput' + - type: 'null' + FooCreateManyInput: + type: object + properties: + id: + type: string + string: + type: string + int: + type: integer + bigInt: + type: integer + date: + type: string + format: date-time + float: + type: number + decimal: + oneOf: + - type: string + - type: number + boolean: + type: boolean + bytes: + oneOf: + - type: 'null' + - type: string + format: byte + required: + - string + - int + - bigInt + - date + - float + - decimal + - boolean + FooUpdateManyMutationInput: + type: object + properties: + id: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + string: + oneOf: + - type: string + - $ref: '#/components/schemas/StringFieldUpdateOperationsInput' + int: + oneOf: + - type: integer + - $ref: '#/components/schemas/IntFieldUpdateOperationsInput' + bigInt: + oneOf: + - type: integer + - $ref: '#/components/schemas/BigIntFieldUpdateOperationsInput' + date: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/DateTimeFieldUpdateOperationsInput' + float: + oneOf: + - type: number + - $ref: '#/components/schemas/FloatFieldUpdateOperationsInput' + decimal: + oneOf: + - oneOf: + - type: string + - type: number + - $ref: '#/components/schemas/DecimalFieldUpdateOperationsInput' + boolean: + oneOf: + - type: boolean + - $ref: '#/components/schemas/BoolFieldUpdateOperationsInput' + bytes: + oneOf: + - type: string + format: byte + - $ref: '#/components/schemas/NullableBytesFieldUpdateOperationsInput' + - type: 'null' + StringFilter: + type: object + properties: + equals: + type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + notIn: + oneOf: + - type: array + items: + type: string + - type: string + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringFilter' + IntFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntFilter' + BigIntFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedBigIntFilter' + DateTimeFilter: + type: object + properties: + equals: + type: string + format: date-time + in: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + notIn: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + lt: + type: string + format: date-time + lte: + type: string + format: date-time + gt: + type: string + format: date-time + gte: + type: string + format: date-time + not: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/NestedDateTimeFilter' + FloatFilter: + type: object + properties: + equals: + type: number + in: + oneOf: + - type: array + items: + type: number + - type: number + notIn: + oneOf: + - type: array + items: + type: number + - type: number + lt: + type: number + lte: + type: number + gt: + type: number + gte: + type: number + not: + oneOf: + - type: number + - $ref: '#/components/schemas/NestedFloatFilter' + DecimalFilter: + type: object + properties: + equals: + oneOf: + - type: string + - type: number + in: + oneOf: + - type: array + items: + oneOf: + - type: string + - type: number + - oneOf: + - type: string + - type: number + notIn: + oneOf: + - type: array + items: + oneOf: + - type: string + - type: number + - oneOf: + - type: string + - type: number + lt: + oneOf: + - type: string + - type: number + lte: + oneOf: + - type: string + - type: number + gt: + oneOf: + - type: string + - type: number + gte: + oneOf: + - type: string + - type: number + not: + oneOf: + - oneOf: + - type: string + - type: number + - $ref: '#/components/schemas/NestedDecimalFilter' + BoolFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolFilter' + BytesNullableFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: string + format: byte + in: + oneOf: + - type: array + items: + type: string + format: byte + - type: string + format: byte + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: string + format: byte + - type: string + format: byte + - type: 'null' + not: + oneOf: + - type: string + format: byte + - $ref: '#/components/schemas/NestedBytesNullableFilter' + - type: 'null' + SortOrderInput: + type: object + properties: + sort: + $ref: '#/components/schemas/SortOrder' + nulls: + $ref: '#/components/schemas/NullsOrder' + required: + - sort + StringWithAggregatesFilter: + type: object + properties: + equals: + type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + notIn: + oneOf: + - type: array + items: + type: string + - type: string + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + mode: + $ref: '#/components/schemas/QueryMode' + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedStringFilter' + _max: + $ref: '#/components/schemas/NestedStringFilter' + IntWithAggregatesFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedFloatFilter' + _sum: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedIntFilter' + _max: + $ref: '#/components/schemas/NestedIntFilter' + BigIntWithAggregatesFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedBigIntWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedFloatFilter' + _sum: + $ref: '#/components/schemas/NestedBigIntFilter' + _min: + $ref: '#/components/schemas/NestedBigIntFilter' + _max: + $ref: '#/components/schemas/NestedBigIntFilter' + DateTimeWithAggregatesFilter: + type: object + properties: + equals: + type: string + format: date-time + in: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + notIn: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + lt: + type: string + format: date-time + lte: + type: string + format: date-time + gt: + type: string + format: date-time + gte: + type: string + format: date-time + not: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/NestedDateTimeWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedDateTimeFilter' + _max: + $ref: '#/components/schemas/NestedDateTimeFilter' + FloatWithAggregatesFilter: + type: object + properties: + equals: + type: number + in: + oneOf: + - type: array + items: + type: number + - type: number + notIn: + oneOf: + - type: array + items: + type: number + - type: number + lt: + type: number + lte: + type: number + gt: + type: number + gte: + type: number + not: + oneOf: + - type: number + - $ref: '#/components/schemas/NestedFloatWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedFloatFilter' + _sum: + $ref: '#/components/schemas/NestedFloatFilter' + _min: + $ref: '#/components/schemas/NestedFloatFilter' + _max: + $ref: '#/components/schemas/NestedFloatFilter' + DecimalWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - type: string + - type: number + in: + oneOf: + - type: array + items: + oneOf: + - type: string + - type: number + - oneOf: + - type: string + - type: number + notIn: + oneOf: + - type: array + items: + oneOf: + - type: string + - type: number + - oneOf: + - type: string + - type: number + lt: + oneOf: + - type: string + - type: number + lte: + oneOf: + - type: string + - type: number + gt: + oneOf: + - type: string + - type: number + gte: + oneOf: + - type: string + - type: number + not: + oneOf: + - oneOf: + - type: string + - type: number + - $ref: '#/components/schemas/NestedDecimalWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedDecimalFilter' + _sum: + $ref: '#/components/schemas/NestedDecimalFilter' + _min: + $ref: '#/components/schemas/NestedDecimalFilter' + _max: + $ref: '#/components/schemas/NestedDecimalFilter' + BoolWithAggregatesFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedBoolFilter' + _max: + $ref: '#/components/schemas/NestedBoolFilter' + BytesNullableWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: string + format: byte + in: + oneOf: + - type: array + items: + type: string + format: byte + - type: string + format: byte + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: string + format: byte + - type: string + format: byte + - type: 'null' + not: + oneOf: + - type: string + format: byte + - $ref: '#/components/schemas/NestedBytesNullableWithAggregatesFilter' + - type: 'null' + _count: + $ref: '#/components/schemas/NestedIntNullableFilter' + _min: + $ref: '#/components/schemas/NestedBytesNullableFilter' + _max: + $ref: '#/components/schemas/NestedBytesNullableFilter' + StringFieldUpdateOperationsInput: + type: object + properties: + set: + type: string + IntFieldUpdateOperationsInput: + type: object + properties: + set: + type: integer + increment: + type: integer + decrement: + type: integer + multiply: + type: integer + divide: + type: integer + BigIntFieldUpdateOperationsInput: + type: object + properties: + set: + type: integer + increment: + type: integer + decrement: + type: integer + multiply: + type: integer + divide: + type: integer + DateTimeFieldUpdateOperationsInput: + type: object + properties: + set: + type: string + format: date-time + FloatFieldUpdateOperationsInput: + type: object + properties: + set: + type: number + increment: + type: number + decrement: + type: number + multiply: + type: number + divide: + type: number + DecimalFieldUpdateOperationsInput: + type: object + properties: + set: + oneOf: + - type: string + - type: number + increment: + oneOf: + - type: string + - type: number + decrement: + oneOf: + - type: string + - type: number + multiply: + oneOf: + - type: string + - type: number + divide: + oneOf: + - type: string + - type: number + BoolFieldUpdateOperationsInput: + type: object + properties: + set: + type: boolean + NullableBytesFieldUpdateOperationsInput: + type: object + properties: + set: + oneOf: + - type: 'null' + - type: string + format: byte + NestedStringFilter: + type: object + properties: + equals: + type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + notIn: + oneOf: + - type: array + items: + type: string + - type: string + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringFilter' + NestedIntFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntFilter' + NestedBigIntFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedBigIntFilter' + NestedDateTimeFilter: + type: object + properties: + equals: + type: string + format: date-time + in: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + notIn: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + lt: + type: string + format: date-time + lte: + type: string + format: date-time + gt: + type: string + format: date-time + gte: + type: string + format: date-time + not: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/NestedDateTimeFilter' + NestedFloatFilter: + type: object + properties: + equals: + type: number + in: + oneOf: + - type: array + items: + type: number + - type: number + notIn: + oneOf: + - type: array + items: + type: number + - type: number + lt: + type: number + lte: + type: number + gt: + type: number + gte: + type: number + not: + oneOf: + - type: number + - $ref: '#/components/schemas/NestedFloatFilter' + NestedDecimalFilter: + type: object + properties: + equals: + oneOf: + - type: string + - type: number + in: + oneOf: + - type: array + items: + oneOf: + - type: string + - type: number + - oneOf: + - type: string + - type: number + notIn: + oneOf: + - type: array + items: + oneOf: + - type: string + - type: number + - oneOf: + - type: string + - type: number + lt: + oneOf: + - type: string + - type: number + lte: + oneOf: + - type: string + - type: number + gt: + oneOf: + - type: string + - type: number + gte: + oneOf: + - type: string + - type: number + not: + oneOf: + - oneOf: + - type: string + - type: number + - $ref: '#/components/schemas/NestedDecimalFilter' + NestedBoolFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolFilter' + NestedBytesNullableFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: string + format: byte + in: + oneOf: + - type: array + items: + type: string + format: byte + - type: string + format: byte + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: string + format: byte + - type: string + format: byte + - type: 'null' + not: + oneOf: + - type: string + format: byte + - $ref: '#/components/schemas/NestedBytesNullableFilter' + - type: 'null' + NestedStringWithAggregatesFilter: + type: object + properties: + equals: + type: string + in: + oneOf: + - type: array + items: + type: string + - type: string + notIn: + oneOf: + - type: array + items: + type: string + - type: string + lt: + type: string + lte: + type: string + gt: + type: string + gte: + type: string + contains: + type: string + startsWith: + type: string + endsWith: + type: string + not: + oneOf: + - type: string + - $ref: '#/components/schemas/NestedStringWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedStringFilter' + _max: + $ref: '#/components/schemas/NestedStringFilter' + NestedIntWithAggregatesFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedFloatFilter' + _sum: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedIntFilter' + _max: + $ref: '#/components/schemas/NestedIntFilter' + NestedBigIntWithAggregatesFilter: + type: object + properties: + equals: + type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedBigIntWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedFloatFilter' + _sum: + $ref: '#/components/schemas/NestedBigIntFilter' + _min: + $ref: '#/components/schemas/NestedBigIntFilter' + _max: + $ref: '#/components/schemas/NestedBigIntFilter' + NestedDateTimeWithAggregatesFilter: + type: object + properties: + equals: + type: string + format: date-time + in: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + notIn: + oneOf: + - type: array + items: + type: string + format: date-time + - type: string + format: date-time + lt: + type: string + format: date-time + lte: + type: string + format: date-time + gt: + type: string + format: date-time + gte: + type: string + format: date-time + not: + oneOf: + - type: string + format: date-time + - $ref: '#/components/schemas/NestedDateTimeWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedDateTimeFilter' + _max: + $ref: '#/components/schemas/NestedDateTimeFilter' + NestedFloatWithAggregatesFilter: + type: object + properties: + equals: + type: number + in: + oneOf: + - type: array + items: + type: number + - type: number + notIn: + oneOf: + - type: array + items: + type: number + - type: number + lt: + type: number + lte: + type: number + gt: + type: number + gte: + type: number + not: + oneOf: + - type: number + - $ref: '#/components/schemas/NestedFloatWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedFloatFilter' + _sum: + $ref: '#/components/schemas/NestedFloatFilter' + _min: + $ref: '#/components/schemas/NestedFloatFilter' + _max: + $ref: '#/components/schemas/NestedFloatFilter' + NestedDecimalWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - type: string + - type: number + in: + oneOf: + - type: array + items: + oneOf: + - type: string + - type: number + - oneOf: + - type: string + - type: number + notIn: + oneOf: + - type: array + items: + oneOf: + - type: string + - type: number + - oneOf: + - type: string + - type: number + lt: + oneOf: + - type: string + - type: number + lte: + oneOf: + - type: string + - type: number + gt: + oneOf: + - type: string + - type: number + gte: + oneOf: + - type: string + - type: number + not: + oneOf: + - oneOf: + - type: string + - type: number + - $ref: '#/components/schemas/NestedDecimalWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _avg: + $ref: '#/components/schemas/NestedDecimalFilter' + _sum: + $ref: '#/components/schemas/NestedDecimalFilter' + _min: + $ref: '#/components/schemas/NestedDecimalFilter' + _max: + $ref: '#/components/schemas/NestedDecimalFilter' + NestedBoolWithAggregatesFilter: + type: object + properties: + equals: + type: boolean + not: + oneOf: + - type: boolean + - $ref: '#/components/schemas/NestedBoolWithAggregatesFilter' + _count: + $ref: '#/components/schemas/NestedIntFilter' + _min: + $ref: '#/components/schemas/NestedBoolFilter' + _max: + $ref: '#/components/schemas/NestedBoolFilter' + NestedBytesNullableWithAggregatesFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: string + format: byte + in: + oneOf: + - type: array + items: + type: string + format: byte + - type: string + format: byte + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: string + format: byte + - type: string + format: byte + - type: 'null' + not: + oneOf: + - type: string + format: byte + - $ref: '#/components/schemas/NestedBytesNullableWithAggregatesFilter' + - type: 'null' + _count: + $ref: '#/components/schemas/NestedIntNullableFilter' + _min: + $ref: '#/components/schemas/NestedBytesNullableFilter' + _max: + $ref: '#/components/schemas/NestedBytesNullableFilter' + NestedIntNullableFilter: + type: object + properties: + equals: + oneOf: + - type: 'null' + - type: integer + in: + oneOf: + - type: array + items: + type: integer + - type: integer + - type: 'null' + notIn: + oneOf: + - type: array + items: + type: integer + - type: integer + - type: 'null' + lt: + type: integer + lte: + type: integer + gt: + type: integer + gte: + type: integer + not: + oneOf: + - type: integer + - $ref: '#/components/schemas/NestedIntNullableFilter' + - type: 'null' + FooSelect: + type: object + properties: + id: + type: boolean + string: + type: boolean + int: + type: boolean + bigInt: + type: boolean + date: + type: boolean + float: + type: boolean + decimal: + type: boolean + boolean: + type: boolean + bytes: + type: boolean + FooCountAggregateInput: + type: object + properties: + id: + type: boolean + string: + type: boolean + int: + type: boolean + bigInt: + type: boolean + date: + type: boolean + float: + type: boolean + decimal: + type: boolean + boolean: + type: boolean + bytes: + type: boolean + _all: + type: boolean + FooAvgAggregateInput: + type: object + properties: + int: + type: boolean + bigInt: + type: boolean + float: + type: boolean + decimal: + type: boolean + FooSumAggregateInput: + type: object + properties: + int: + type: boolean + bigInt: + type: boolean + float: + type: boolean + decimal: + type: boolean + FooMinAggregateInput: + type: object + properties: + id: + type: boolean + string: + type: boolean + int: + type: boolean + bigInt: + type: boolean + date: + type: boolean + float: + type: boolean + decimal: + type: boolean + boolean: + type: boolean + bytes: + type: boolean + FooMaxAggregateInput: + type: object + properties: + id: + type: boolean + string: + type: boolean + int: + type: boolean + bigInt: + type: boolean + date: + type: boolean + float: + type: boolean + decimal: + type: boolean + boolean: + type: boolean + bytes: + type: boolean + AggregateFoo: + type: object + properties: + _count: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooCountAggregateOutputType' + _avg: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooAvgAggregateOutputType' + _sum: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooSumAggregateOutputType' + _min: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooMinAggregateOutputType' + _max: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooMaxAggregateOutputType' + FooGroupByOutputType: + type: object + properties: + id: + type: string + string: + type: string + int: + type: integer + bigInt: + type: integer + date: + type: string + format: date-time + float: + type: number + decimal: + oneOf: + - type: string + - type: number + boolean: + type: boolean + bytes: + oneOf: + - type: 'null' + - type: string + format: byte + _count: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooCountAggregateOutputType' + _avg: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooAvgAggregateOutputType' + _sum: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooSumAggregateOutputType' + _min: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooMinAggregateOutputType' + _max: + oneOf: + - type: 'null' + - $ref: '#/components/schemas/FooMaxAggregateOutputType' + required: + - id + - string + - int + - bigInt + - date + - float + - decimal + - boolean + FooCountAggregateOutputType: + type: object + properties: + id: + type: integer + string: + type: integer + int: + type: integer + bigInt: + type: integer + date: + type: integer + float: + type: integer + decimal: + type: integer + boolean: + type: integer + bytes: + type: integer + _all: + type: integer + required: + - id + - string + - int + - bigInt + - date + - float + - decimal + - boolean + - bytes + - _all + FooAvgAggregateOutputType: + type: object + properties: + int: + oneOf: + - type: 'null' + - type: number + bigInt: + oneOf: + - type: 'null' + - type: number + float: + oneOf: + - type: 'null' + - type: number + decimal: + oneOf: + - type: string + - type: number + - type: 'null' + FooSumAggregateOutputType: + type: object + properties: + int: + oneOf: + - type: 'null' + - type: integer + bigInt: + oneOf: + - type: 'null' + - type: integer + float: + oneOf: + - type: 'null' + - type: number + decimal: + oneOf: + - type: string + - type: number + - type: 'null' + FooMinAggregateOutputType: + type: object + properties: + id: + oneOf: + - type: 'null' + - type: string + string: + oneOf: + - type: 'null' + - type: string + int: + oneOf: + - type: 'null' + - type: integer + bigInt: + oneOf: + - type: 'null' + - type: integer + date: + oneOf: + - type: 'null' + - type: string + format: date-time + float: + oneOf: + - type: 'null' + - type: number + decimal: + oneOf: + - type: string + - type: number + - type: 'null' + boolean: + oneOf: + - type: 'null' + - type: boolean + bytes: + oneOf: + - type: 'null' + - type: string + format: byte + FooMaxAggregateOutputType: + type: object + properties: + id: + oneOf: + - type: 'null' + - type: string + string: + oneOf: + - type: 'null' + - type: string + int: + oneOf: + - type: 'null' + - type: integer + bigInt: + oneOf: + - type: 'null' + - type: integer + date: + oneOf: + - type: 'null' + - type: string + format: date-time + float: + oneOf: + - type: 'null' + - type: number + decimal: + oneOf: + - type: string + - type: number + - type: 'null' + boolean: + oneOf: + - type: 'null' + - type: boolean + bytes: + oneOf: + - type: 'null' + - type: string + format: byte + _Meta: + type: object + properties: + meta: + type: object + description: Meta information about the request or response + properties: + serialization: + description: Serialization metadata + additionalProperties: true + _Error: + type: object + required: + - error + properties: + error: + type: object + required: + - message + properties: + prisma: + type: boolean + description: Indicates if the error occurred during a Prisma call + rejectedByPolicy: + type: boolean + description: Indicates if the error was due to rejection by a policy + code: + type: string + description: Prisma error code. Only available when "prisma" field is true. + message: + type: string + description: Error message + reason: + type: string + description: Detailed error reason + zodErrors: + type: object + additionalProperties: true + description: Zod validation errors if the error is due to data validation + failure + additionalProperties: true + BatchPayload: + type: object + properties: + count: + type: integer + FooCreateArgs: + type: object + required: + - data + properties: + select: + $ref: '#/components/schemas/FooSelect' + data: + $ref: '#/components/schemas/FooCreateInput' + meta: + $ref: '#/components/schemas/_Meta' + FooCreateManyArgs: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/FooCreateManyInput' + meta: + $ref: '#/components/schemas/_Meta' + FooFindUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/FooSelect' + where: + $ref: '#/components/schemas/FooWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + FooFindFirstArgs: + type: object + properties: + select: + $ref: '#/components/schemas/FooSelect' + where: + $ref: '#/components/schemas/FooWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + FooFindManyArgs: + type: object + properties: + select: + $ref: '#/components/schemas/FooSelect' + where: + $ref: '#/components/schemas/FooWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + FooUpdateArgs: + type: object + required: + - where + - data + properties: + select: + $ref: '#/components/schemas/FooSelect' + where: + $ref: '#/components/schemas/FooWhereUniqueInput' + data: + $ref: '#/components/schemas/FooUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + FooUpdateManyArgs: + type: object + required: + - data + properties: + where: + $ref: '#/components/schemas/FooWhereInput' + data: + $ref: '#/components/schemas/FooUpdateManyMutationInput' + meta: + $ref: '#/components/schemas/_Meta' + FooUpsertArgs: + type: object + required: + - create + - update + - where + properties: + select: + $ref: '#/components/schemas/FooSelect' + where: + $ref: '#/components/schemas/FooWhereUniqueInput' + create: + $ref: '#/components/schemas/FooCreateInput' + update: + $ref: '#/components/schemas/FooUpdateInput' + meta: + $ref: '#/components/schemas/_Meta' + FooDeleteUniqueArgs: + type: object + required: + - where + properties: + select: + $ref: '#/components/schemas/FooSelect' + where: + $ref: '#/components/schemas/FooWhereUniqueInput' + meta: + $ref: '#/components/schemas/_Meta' + FooDeleteManyArgs: + type: object + properties: + where: + $ref: '#/components/schemas/FooWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + FooCountArgs: + type: object + properties: + select: + $ref: '#/components/schemas/FooSelect' + where: + $ref: '#/components/schemas/FooWhereInput' + meta: + $ref: '#/components/schemas/_Meta' + FooAggregateArgs: + type: object + properties: + where: + $ref: '#/components/schemas/FooWhereInput' + orderBy: + $ref: '#/components/schemas/FooOrderByWithRelationInput' + cursor: + $ref: '#/components/schemas/FooWhereUniqueInput' + take: + type: integer + skip: + type: integer + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/FooCountAggregateInput' + _min: + $ref: '#/components/schemas/FooMinAggregateInput' + _max: + $ref: '#/components/schemas/FooMaxAggregateInput' + _sum: + $ref: '#/components/schemas/FooSumAggregateInput' + _avg: + $ref: '#/components/schemas/FooAvgAggregateInput' + meta: + $ref: '#/components/schemas/_Meta' + FooGroupByArgs: + type: object + properties: + where: + $ref: '#/components/schemas/FooWhereInput' + orderBy: + $ref: '#/components/schemas/FooOrderByWithRelationInput' + by: + $ref: '#/components/schemas/FooScalarFieldEnum' + having: + $ref: '#/components/schemas/FooScalarWhereWithAggregatesInput' + take: + type: integer + skip: + type: integer + _count: + oneOf: + - type: boolean + - $ref: '#/components/schemas/FooCountAggregateInput' + _min: + $ref: '#/components/schemas/FooMinAggregateInput' + _max: + $ref: '#/components/schemas/FooMaxAggregateInput' + _sum: + $ref: '#/components/schemas/FooSumAggregateInput' + _avg: + $ref: '#/components/schemas/FooAvgAggregateInput' + meta: + $ref: '#/components/schemas/_Meta' +paths: + /foo/create: + post: + operationId: createFoo + description: Create a new Foo + tags: + - foo + security: [] + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Foo' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FooCreateArgs' + /foo/createMany: + post: + operationId: createManyFoo + description: Create several Foo + tags: + - foo + security: [] + responses: + '201': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FooCreateManyArgs' + /foo/findUnique: + get: + operationId: findUniqueFoo + description: Find one unique Foo + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Foo' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/FooFindUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /foo/findFirst: + get: + operationId: findFirstFoo + description: Find the first Foo matching the given condition + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Foo' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/FooFindFirstArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /foo/findMany: + get: + operationId: findManyFoo + description: Find a list of Foo + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/Foo' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/FooFindManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /foo/update: + patch: + operationId: updateFoo + description: Update a Foo + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Foo' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FooUpdateArgs' + /foo/updateMany: + patch: + operationId: updateManyFoo + description: Update Foos matching the given condition + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FooUpdateManyArgs' + /foo/upsert: + post: + operationId: upsertFoo + description: Upsert a Foo + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Foo' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FooUpsertArgs' + /foo/delete: + delete: + operationId: deleteFoo + description: Delete one unique Foo + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/Foo' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/FooDeleteUniqueArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /foo/deleteMany: + delete: + operationId: deleteManyFoo + description: Delete Foos matching the given condition + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/BatchPayload' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/FooDeleteManyArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /foo/count: + get: + operationId: countFoo + description: Find a list of Foo + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + oneOf: + - type: integer + - $ref: '#/components/schemas/FooCountAggregateOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/FooCountArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /foo/aggregate: + get: + operationId: aggregateFoo + description: Aggregate Foos + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/AggregateFoo' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/FooAggregateArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} + /foo/groupBy: + get: + operationId: groupByFoo + description: Group Foos by fields + tags: + - foo + security: [] + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/FooGroupByOutputType' + description: The Prisma response data serialized with superjson + meta: + $ref: '#/components/schemas/_Meta' + description: The superjson serialization metadata for the "data" field + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Invalid request + '403': + content: + application/json: + schema: + $ref: '#/components/schemas/_Error' + description: Request is forbidden + parameters: + - name: q + in: query + required: true + description: Superjson-serialized Prisma query object + content: + application/json: + schema: + $ref: '#/components/schemas/FooGroupByArgs' + - name: meta + in: query + description: Superjson serialization metadata for parameter "q" + content: + application/json: + schema: {} diff --git a/packages/plugins/openapi/tests/openapi-restful.test.ts b/packages/plugins/openapi/tests/openapi-restful.test.ts index 77d13885a..fb01e390e 100644 --- a/packages/plugins/openapi/tests/openapi-restful.test.ts +++ b/packages/plugins/openapi/tests/openapi-restful.test.ts @@ -3,18 +3,21 @@ import OpenAPIParser from '@readme/openapi-parser'; import { getLiteral, getObjectLiteral } from '@zenstackhq/sdk'; -import { isPlugin, Model, Plugin } from '@zenstackhq/sdk/ast'; +import { Model, Plugin, isPlugin } from '@zenstackhq/sdk/ast'; import { loadZModelAndDmmf } from '@zenstackhq/testtools'; -import * as fs from 'fs'; +import fs from 'fs'; +import path from 'path'; import * as tmp from 'tmp'; import YAML from 'yaml'; import generate from '../src'; -describe('Open API Plugin Tests', () => { +describe('Open API Plugin RESTful Tests', () => { it('run plugin', async () => { - const { model, dmmf, modelFile } = await loadZModelAndDmmf(` + for (const specVersion of ['3.0.0', '3.1.0']) { + const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' + specVersion = '${specVersion}' } enum role { @@ -29,6 +32,15 @@ model User { email String @unique role role @default(USER) posts post_Item[] + profile Profile? +} + +model Profile { + id String @id @default(cuid()) + image String? + + user User @relation(fields: [userId], references: [id]) + userId String @unique } model post_Item { @@ -40,6 +52,7 @@ model post_Item { authorId String? published Boolean @default(false) viewCount Int @default(0) + notes String? @@openapi.meta({ tagDescription: 'Post-related operations' @@ -57,48 +70,51 @@ model Bar { } `); - const { name: output } = tmp.fileSync({ postfix: '.yaml' }); - - const options = buildOptions(model, modelFile, output, '3.1.0'); - await generate(model, options, dmmf); - - console.log('OpenAPI specification generated:', output); - - const api = await OpenAPIParser.validate(output); - - expect(api.tags).toEqual( - expect.arrayContaining([ - expect.objectContaining({ name: 'user', description: 'User operations' }), - expect.objectContaining({ name: 'post_Item', description: 'Post-related operations' }), - ]) - ); - - expect(api.paths?.['/user']?.['get']).toBeTruthy(); - expect(api.paths?.['/user']?.['post']).toBeTruthy(); - expect(api.paths?.['/user']?.['put']).toBeFalsy(); - expect(api.paths?.['/user/{id}']?.['get']).toBeTruthy(); - expect(api.paths?.['/user/{id}']?.['patch']).toBeTruthy(); - expect(api.paths?.['/user/{id}']?.['delete']).toBeTruthy(); - expect(api.paths?.['/user/{id}/posts']?.['get']).toBeTruthy(); - expect(api.paths?.['/user/{id}/relationships/posts']?.['get']).toBeTruthy(); - expect(api.paths?.['/user/{id}/relationships/posts']?.['post']).toBeTruthy(); - expect(api.paths?.['/user/{id}/relationships/posts']?.['patch']).toBeTruthy(); - expect(api.paths?.['/post_Item/{id}/relationships/author']?.['get']).toBeTruthy(); - expect(api.paths?.['/post_Item/{id}/relationships/author']?.['post']).toBeUndefined(); - expect(api.paths?.['/post_Item/{id}/relationships/author']?.['patch']).toBeTruthy(); - expect(api.paths?.['/foo']).toBeUndefined(); - expect(api.paths?.['/bar']).toBeUndefined(); - - const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); - expect(parsed.openapi).toBe('3.1.0'); - const baseline = YAML.parse(fs.readFileSync(`${__dirname}/baseline/rest.baseline.yaml`, 'utf-8')); - expect(parsed).toMatchObject(baseline); + const { name: output } = tmp.fileSync({ postfix: '.yaml' }); + + const options = buildOptions(model, modelFile, output, '3.1.0'); + await generate(model, options, dmmf); + + console.log(`OpenAPI specification generated for ${specVersion}: ${output}`); + + const api = await OpenAPIParser.validate(output); + + expect(api.tags).toEqual( + expect.arrayContaining([ + expect.objectContaining({ name: 'user', description: 'User operations' }), + expect.objectContaining({ name: 'post_Item', description: 'Post-related operations' }), + ]) + ); + + expect(api.paths?.['/user']?.['get']).toBeTruthy(); + expect(api.paths?.['/user']?.['post']).toBeTruthy(); + expect(api.paths?.['/user']?.['put']).toBeFalsy(); + expect(api.paths?.['/user/{id}']?.['get']).toBeTruthy(); + expect(api.paths?.['/user/{id}']?.['patch']).toBeTruthy(); + expect(api.paths?.['/user/{id}']?.['delete']).toBeTruthy(); + expect(api.paths?.['/user/{id}/posts']?.['get']).toBeTruthy(); + expect(api.paths?.['/user/{id}/relationships/posts']?.['get']).toBeTruthy(); + expect(api.paths?.['/user/{id}/relationships/posts']?.['post']).toBeTruthy(); + expect(api.paths?.['/user/{id}/relationships/posts']?.['patch']).toBeTruthy(); + expect(api.paths?.['/post_Item/{id}/relationships/author']?.['get']).toBeTruthy(); + expect(api.paths?.['/post_Item/{id}/relationships/author']?.['post']).toBeUndefined(); + expect(api.paths?.['/post_Item/{id}/relationships/author']?.['patch']).toBeTruthy(); + expect(api.paths?.['/foo']).toBeUndefined(); + expect(api.paths?.['/bar']).toBeUndefined(); + + const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); + expect(parsed.openapi).toBe(specVersion); + const baseline = YAML.parse( + fs.readFileSync(`${__dirname}/baseline/rest-${specVersion}.baseline.yaml`, 'utf-8') + ); + expect(parsed).toMatchObject(baseline); + } }); it('options', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' specVersion = '3.0.0' title = 'My Awesome API' version = '1.0.0' @@ -135,7 +151,7 @@ model User { it('security schemes valid', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' securitySchemes = { myBasic: { type: 'http', scheme: 'basic' }, myBearer: { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' }, @@ -182,7 +198,7 @@ model Post { it('security model level override', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' securitySchemes = { myBasic: { type: 'http', scheme: 'basic' } } @@ -214,7 +230,7 @@ model User { it('security schemes invalid', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' securitySchemes = { myBasic: { type: 'invalid', scheme: 'basic' } } @@ -235,7 +251,7 @@ model User { it('ignored model used as relation', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' } model User { @@ -265,9 +281,11 @@ model Post { }); it('field type coverage', async () => { - const { model, dmmf, modelFile } = await loadZModelAndDmmf(` + for (const specVersion of ['3.0.0', '3.1.0']) { + const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' + specVersion = '${specVersion}' } model Foo { @@ -286,19 +304,22 @@ model Foo { } `); - const { name: output } = tmp.fileSync({ postfix: '.yaml' }); + const { name: output } = tmp.fileSync({ postfix: '.yaml' }); - const options = buildOptions(model, modelFile, output, '3.1.0'); - await generate(model, options, dmmf); + const options = buildOptions(model, modelFile, output, '3.1.0'); + await generate(model, options, dmmf); - console.log('OpenAPI specification generated:', output); + console.log(`OpenAPI specification generated for ${specVersion}: ${output}`); - await OpenAPIParser.validate(output); + await OpenAPIParser.validate(output); - const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); - expect(parsed.openapi).toBe('3.1.0'); - const baseline = YAML.parse(fs.readFileSync(`${__dirname}/baseline/rest-type-coverage.baseline.yaml`, 'utf-8')); - expect(parsed).toMatchObject(baseline); + const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); + expect(parsed.openapi).toBe(specVersion); + const baseline = YAML.parse( + fs.readFileSync(`${__dirname}/baseline/rest-type-coverage-${specVersion}.baseline.yaml`, 'utf-8') + ); + expect(parsed).toMatchObject(baseline); + } }); }); diff --git a/packages/plugins/openapi/tests/openapi-rpc.test.ts b/packages/plugins/openapi/tests/openapi-rpc.test.ts index 90d63e59e..c0cb74ab6 100644 --- a/packages/plugins/openapi/tests/openapi-rpc.test.ts +++ b/packages/plugins/openapi/tests/openapi-rpc.test.ts @@ -3,18 +3,21 @@ import OpenAPIParser from '@readme/openapi-parser'; import { getLiteral, getObjectLiteral } from '@zenstackhq/sdk'; -import { isPlugin, Model, Plugin } from '@zenstackhq/sdk/ast'; +import { Model, Plugin, isPlugin } from '@zenstackhq/sdk/ast'; import { loadZModelAndDmmf } from '@zenstackhq/testtools'; -import * as fs from 'fs'; +import fs from 'fs'; +import path from 'path'; import * as tmp from 'tmp'; import YAML from 'yaml'; import generate from '../src'; -describe('Open API Plugin Tests', () => { +describe('Open API Plugin RPC Tests', () => { it('run plugin', async () => { - const { model, dmmf, modelFile } = await loadZModelAndDmmf(` + for (const specVersion of ['3.0.0', '3.1.0']) { + const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' + specVersion = '${specVersion}' } enum role { @@ -29,6 +32,7 @@ model User { email String @unique role role @default(USER) posts post_Item[] + profile Profile? @@openapi.meta({ findMany: { @@ -45,6 +49,14 @@ model User { }) } +model Profile { + id String @id @default(cuid()) + image String? + + user User @relation(fields: [userId], references: [id]) + userId String @unique +} + model post_Item { id String @id createdAt DateTime @default(now()) @@ -54,6 +66,7 @@ model post_Item { authorId String? published Boolean @default(false) viewCount Int @default(0) + notes String? @@openapi.meta({ tagDescription: 'Post-related operations', @@ -74,42 +87,47 @@ model Bar { } `); - const { name: output } = tmp.fileSync({ postfix: '.yaml' }); - - const options = buildOptions(model, modelFile, output); - await generate(model, options, dmmf); - - console.log('OpenAPI specification generated:', output); - - const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); - expect(parsed.openapi).toBe('3.1.0'); - const baseline = YAML.parse(fs.readFileSync(`${__dirname}/baseline/rpc.baseline.yaml`, 'utf-8')); - expect(parsed).toMatchObject(baseline); - - const api = await OpenAPIParser.validate(output); - - expect(api.tags).toEqual( - expect.arrayContaining([ - expect.objectContaining({ name: 'user', description: 'User operations' }), - expect.objectContaining({ name: 'post_Item', description: 'Post-related operations' }), - ]) - ); - - expect(api.paths?.['/user/findMany']?.['get']?.description).toBe('Find users matching the given conditions'); - const del = api.paths?.['/user/dodelete']?.['put']; - expect(del?.description).toBe('Delete a unique user'); - expect(del?.summary).toBe('Delete a user yeah yeah'); - expect(del?.tags).toEqual(expect.arrayContaining(['delete', 'user'])); - expect(del?.deprecated).toBe(true); - expect(api.paths?.['/post/findMany']).toBeUndefined(); - expect(api.paths?.['/foo/findMany']).toBeUndefined(); - expect(api.paths?.['/bar/findMany']).toBeUndefined(); + const { name: output } = tmp.fileSync({ postfix: '.yaml' }); + + const options = buildOptions(model, modelFile, output); + await generate(model, options, dmmf); + + console.log(`OpenAPI specification generated for ${specVersion}: ${output}`); + + const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); + expect(parsed.openapi).toBe(specVersion); + const baseline = YAML.parse( + fs.readFileSync(`${__dirname}/baseline/rpc-${specVersion}.baseline.yaml`, 'utf-8') + ); + expect(parsed).toMatchObject(baseline); + + const api = await OpenAPIParser.validate(output); + + expect(api.tags).toEqual( + expect.arrayContaining([ + expect.objectContaining({ name: 'user', description: 'User operations' }), + expect.objectContaining({ name: 'post_Item', description: 'Post-related operations' }), + ]) + ); + + expect(api.paths?.['/user/findMany']?.['get']?.description).toBe( + 'Find users matching the given conditions' + ); + const del = api.paths?.['/user/dodelete']?.['put']; + expect(del?.description).toBe('Delete a unique user'); + expect(del?.summary).toBe('Delete a user yeah yeah'); + expect(del?.tags).toEqual(expect.arrayContaining(['delete', 'user'])); + expect(del?.deprecated).toBe(true); + expect(api.paths?.['/post/findMany']).toBeUndefined(); + expect(api.paths?.['/foo/findMany']).toBeUndefined(); + expect(api.paths?.['/bar/findMany']).toBeUndefined(); + } }); it('options', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' specVersion = '3.0.0' title = 'My Awesome API' version = '1.0.0' @@ -146,7 +164,7 @@ model User { it('security schemes valid', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' securitySchemes = { myBasic: { type: 'http', scheme: 'basic' }, myBearer: { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' }, @@ -180,7 +198,7 @@ model User { it('security schemes invalid', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' securitySchemes = { myBasic: { type: 'invalid', scheme: 'basic' } } @@ -201,7 +219,7 @@ model User { it('security model level override', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' securitySchemes = { myBasic: { type: 'http', scheme: 'basic' } } @@ -229,7 +247,7 @@ model User { it('security operation level override', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' securitySchemes = { myBasic: { type: 'http', scheme: 'basic' } } @@ -262,7 +280,7 @@ model User { it('security inferred', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' securitySchemes = { myBasic: { type: 'http', scheme: 'basic' } } @@ -288,7 +306,7 @@ model User { it('v3.1.0 fields', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' summary = 'awesome api' } @@ -312,7 +330,7 @@ model User { it('ignored model used as relation', async () => { const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' } model User { @@ -341,9 +359,11 @@ model Post { }); it('field type coverage', async () => { - const { model, dmmf, modelFile } = await loadZModelAndDmmf(` + for (const specVersion of ['3.0.0', '3.1.0']) { + const { model, dmmf, modelFile } = await loadZModelAndDmmf(` plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' + specVersion = '${specVersion}' } model Foo { @@ -356,25 +376,28 @@ model Foo { float Float decimal Decimal boolean Boolean - bytes Bytes + bytes Bytes? @@allow('all', true) } `); - const { name: output } = tmp.fileSync({ postfix: '.yaml' }); + const { name: output } = tmp.fileSync({ postfix: '.yaml' }); - const options = buildOptions(model, modelFile, output); - await generate(model, options, dmmf); + const options = buildOptions(model, modelFile, output); + await generate(model, options, dmmf); - console.log('OpenAPI specification generated:', output); + console.log(`OpenAPI specification generated for ${specVersion}: ${output}`); - await OpenAPIParser.validate(output); + await OpenAPIParser.validate(output); - const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); - expect(parsed.openapi).toBe('3.1.0'); - const baseline = YAML.parse(fs.readFileSync(`${__dirname}/baseline/rpc-type-coverage.baseline.yaml`, 'utf-8')); - expect(parsed).toMatchObject(baseline); + const parsed = YAML.parse(fs.readFileSync(output, 'utf-8')); + expect(parsed.openapi).toBe(specVersion); + const baseline = YAML.parse( + fs.readFileSync(`${__dirname}/baseline/rpc-type-coverage-${specVersion}.baseline.yaml`, 'utf-8') + ); + expect(parsed).toMatchObject(baseline); + } }); it('full-text search', async () => { @@ -385,7 +408,7 @@ generator js { } plugin openapi { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' } enum role { diff --git a/packages/plugins/swr/tests/swr.test.ts b/packages/plugins/swr/tests/swr.test.ts index fca774d64..76db29b49 100644 --- a/packages/plugins/swr/tests/swr.test.ts +++ b/packages/plugins/swr/tests/swr.test.ts @@ -1,6 +1,7 @@ /// import { loadSchema } from '@zenstackhq/testtools'; +import path from 'path'; describe('SWR Plugin Tests', () => { let origDir: string; @@ -49,7 +50,7 @@ model Foo { await loadSchema( ` plugin swr { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/hooks' } diff --git a/packages/plugins/tanstack-query/tests/plugin.test.ts b/packages/plugins/tanstack-query/tests/plugin.test.ts index 252a4c04f..49a99df94 100644 --- a/packages/plugins/tanstack-query/tests/plugin.test.ts +++ b/packages/plugins/tanstack-query/tests/plugin.test.ts @@ -1,6 +1,7 @@ /// import { loadSchema } from '@zenstackhq/testtools'; +import path from 'path'; describe('Tanstack Query Plugin Tests', () => { let origDir: string; @@ -49,7 +50,7 @@ model Foo { await loadSchema( ` plugin tanstack { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/hooks' target = 'react' } @@ -70,7 +71,7 @@ ${sharedModel} await loadSchema( ` plugin tanstack { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/hooks' target = 'react' version = 'v5' @@ -92,7 +93,7 @@ ${sharedModel} await loadSchema( ` plugin tanstack { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/hooks' target = 'vue' } @@ -113,7 +114,7 @@ ${sharedModel} await loadSchema( ` plugin tanstack { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/hooks' target = 'vue' version = 'v5' @@ -135,7 +136,7 @@ ${sharedModel} await loadSchema( ` plugin tanstack { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/hooks' target = 'svelte' } @@ -156,7 +157,7 @@ ${sharedModel} await loadSchema( ` plugin tanstack { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/hooks' target = 'svelte' version = 'v5' diff --git a/packages/plugins/trpc/tests/trpc.test.ts b/packages/plugins/trpc/tests/trpc.test.ts index 251ac3d14..cf43c9a49 100644 --- a/packages/plugins/trpc/tests/trpc.test.ts +++ b/packages/plugins/trpc/tests/trpc.test.ts @@ -19,7 +19,7 @@ describe('tRPC Plugin Tests', () => { await loadSchema( ` plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/trpc' } @@ -67,7 +67,7 @@ model Foo { const { projectDir } = await loadSchema( ` plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = './trpc' } @@ -110,7 +110,7 @@ model Foo { const { projectDir } = await loadSchema( ` plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = './trpc' } @@ -141,7 +141,7 @@ model Post { const { projectDir } = await loadSchema( ` plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = './trpc' generateModelActions = 'findMany,findUnique,update' } @@ -171,7 +171,7 @@ model Post { const { projectDir } = await loadSchema( ` plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = './trpc' generateModelActions = ['findMany', 'findUnique', 'update'] } @@ -220,7 +220,7 @@ model Post { await loadSchema( ` plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/trpc' generateClientHelpers = 'react' } @@ -240,7 +240,7 @@ model Post { await loadSchema( ` plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/trpc' generateClientHelpers = 'next' } @@ -260,7 +260,7 @@ model Post { await loadSchema( ` plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/trpc' } @@ -299,7 +299,7 @@ generator js { } plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/trpc' generateModels = ['Post'] generateModelActions = ['findMany', 'update'] @@ -370,7 +370,7 @@ plugin zod { } plugin trpc { - provider = '${process.cwd()}/dist' + provider = '${path.resolve(__dirname, '../dist')}' output = '$projectRoot/trpc' generateModels = ['Post'] generateModelActions = ['findMany', 'update'] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de0f8a35f..9ddeb1f59 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,9 +100,15 @@ importers: openapi-types: specifier: ^12.1.0 version: 12.1.0 + semver: + specifier: ^7.3.8 + version: 7.5.4 tiny-invariant: specifier: ^1.3.1 version: 1.3.1 + ts-pattern: + specifier: ^4.3.0 + version: 4.3.0 upper-case-first: specifier: ^2.0.2 version: 2.0.2 @@ -122,6 +128,9 @@ importers: '@types/pluralize': specifier: ^0.0.29 version: 0.0.29 + '@types/semver': + specifier: ^7.3.13 + version: 7.5.0 '@types/tmp': specifier: ^0.2.3 version: 0.2.3 @@ -7616,7 +7625,7 @@ packages: proxy-addr: 2.0.7 rfdc: 1.3.0 secure-json-parse: 2.7.0 - semver: 7.5.3 + semver: 7.5.4 tiny-lru: 10.4.1 transitivePeerDependencies: - supports-color @@ -7957,7 +7966,7 @@ packages: get-it: 8.1.4 registry-auth-token: 5.0.2 registry-url: 5.1.0 - semver: 7.5.3 + semver: 7.5.4 transitivePeerDependencies: - supports-color dev: false @@ -12297,6 +12306,7 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 + dev: false /semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} @@ -12304,7 +12314,6 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - dev: true /send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} @@ -14110,7 +14119,7 @@ packages: engines: {vscode: ^1.67.0} dependencies: minimatch: 3.1.2 - semver: 7.5.3 + semver: 7.5.4 vscode-languageserver-protocol: 3.17.2 dev: false From e4aeee32ae3a5ab1718fd1daa2f93043fb68a8d5 Mon Sep 17 00:00:00 2001 From: Yiming Date: Sun, 31 Dec 2023 15:51:27 +0800 Subject: [PATCH 05/11] feat: RedwoodJS integration package (#911) --- packages/misc/LICENSE | 21 + packages/misc/redwood/LICENSE | 1 + packages/misc/redwood/README.md | 79 ++ packages/misc/redwood/package.json | 54 + packages/misc/redwood/src/cli-passthrough.ts | 51 + packages/misc/redwood/src/commands/setup.ts | 227 ++++ packages/misc/redwood/src/graphql.ts | 61 + packages/misc/redwood/src/index.ts | 11 + packages/misc/redwood/src/utils.ts | 20 + packages/misc/redwood/tsconfig.json | 8 + .../runtime/src/enhancements/policy/index.ts | 10 +- packages/runtime/src/enhancements/proxy.ts | 20 +- packages/schema/src/cli/cli-util.ts | 16 +- packages/schema/src/cli/plugin-runner.ts | 3 +- .../src/plugins/prisma/schema-generator.ts | 20 +- packages/schema/src/utils/pkg-utils.ts | 9 + pnpm-lock.yaml | 1070 ++++++++++++++++- pnpm-workspace.yaml | 1 + 18 files changed, 1604 insertions(+), 78 deletions(-) create mode 100644 packages/misc/LICENSE create mode 120000 packages/misc/redwood/LICENSE create mode 100644 packages/misc/redwood/README.md create mode 100644 packages/misc/redwood/package.json create mode 100644 packages/misc/redwood/src/cli-passthrough.ts create mode 100644 packages/misc/redwood/src/commands/setup.ts create mode 100644 packages/misc/redwood/src/graphql.ts create mode 100644 packages/misc/redwood/src/index.ts create mode 100644 packages/misc/redwood/src/utils.ts create mode 100644 packages/misc/redwood/tsconfig.json diff --git a/packages/misc/LICENSE b/packages/misc/LICENSE new file mode 100644 index 000000000..91d4584d3 --- /dev/null +++ b/packages/misc/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 ZenStack + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/misc/redwood/LICENSE b/packages/misc/redwood/LICENSE new file mode 120000 index 000000000..5853aaea5 --- /dev/null +++ b/packages/misc/redwood/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/packages/misc/redwood/README.md b/packages/misc/redwood/README.md new file mode 100644 index 000000000..55daa78fa --- /dev/null +++ b/packages/misc/redwood/README.md @@ -0,0 +1,79 @@ +# ZenStack RedwoodJS Integration + +This package provides the CLI and runtime APIs for integrating [ZenStack](https://zenstack.dev) into a [RedwoodJS](https://redwoodjs.com/) project. You can use ZenStack as a drop-in replacement to Prisma and define flexible access control policies declaratively inside the database schema. It's especially useful for building multi-tenant applications which tend to have complex authorization requirements beyond RBAC. + +ZenStack is a full-stack toolkit built above Prisma ORM. It extends Prisma at the schema and the runtime level for adding the following capabilities: + +- Flexible access control +- Data validation rules +- Multi-file schemas +- Custom attributes and functions in schemas + +Visit [homepage](https://zenstack.dev) for more details. + +## Setting up + +This package leverages RedwoodJS's experimental feature to register a custom CLI command to `yarn redwood`. To enable it, add the following to `redwood.toml`: + +```toml +[experimental.cli] + autoInstall = true + [[experimental.cli.plugins]] + package = "@zenstackhq/redwood" +``` + +Then you can run `yarn rw @zenstackhq setup` to install ZenStack into your Redwood project. The setup command will: + +1. Install ZenStack dependencies. +2. Copy your Prisma schema file "api/db/schema.prisma" to "api/db/schema.zmodel". +3. Add a "zenstack" section into "api/package.json" to specify the location of both the "schema.prisma" and "schema.zmodel" files. +4. Install a GraphQLYoga plugin in "api/src/functions/graphql.[ts|js]". +5. Eject service templates and modify the templates to use `context.db` (ZenStack-enhanced `PrismaClient`) instead of `db` for data access. + +## Modeling data and access policies + +ZenStack's ZModel language is a superset of Prisma schema language. You should use it to define both the data schema and access policies. The regular Prisma schema file will be regenerated from the ZModel file when you run + +```bash +yarn rw @zenstackhq generate +``` + +[The Complete Guide](https://zenstack.dev/docs/the-complete-guide/part1/) of ZenStack is the best way to learn how to author ZModel schemas. You can also use the + +```bash +yarn rw @zenstackhq sample +``` + +command to browse a list of sample schemas and create from them. + +## Development workflow + +The workflow of using ZenStack is very similar to using Prisma in RedwoodJS projects. The two main differences are: + +1. Generation + + You should run `yarn rw @zenstackhq generate` in place of `yarn rw prisma generate`. The ZenStack's generate command internally regenerates the Prisma schema from the ZModel schema, runs `prisma generate` automatically, and also generates other modules for supporting access policy enforcement at the runtime. + +2. Database access in services + + In your service code, you should use `context.db` instead of `db` for accessing the database. The `context.db` is an enhanced Prisma client that enforces access policies. + + The "setup" command prepared a customized service code template. When you run `yarn rw g service`, the generated code will already use `context.db`. + +Other Prisma-related workflows like generation migration or pushing schema to the database stay unchanged. + +## Deployment + +You should run the "generate" command in your deployment script before `yarn rw deploy`. For example, to deploy to Vercel, the command can be: + +```bash +yarn rw @zenstackhq generate && yarn rw deploy vercel +``` + +## Sample application + +You can find a complete multi-tenant Todo application built with RedwoodJS and ZenStack at: [https://github.com/zenstackhq/sample-todo-redwood](https://github.com/zenstackhq/sample-todo-redwood). + +## Getting help + +The best way to getting help and updates about ZenStack is by joining our [Discord server](https://discord.gg/Ykhr738dUe). diff --git a/packages/misc/redwood/package.json b/packages/misc/redwood/package.json new file mode 100644 index 000000000..d60812d62 --- /dev/null +++ b/packages/misc/redwood/package.json @@ -0,0 +1,54 @@ +{ + "name": "@zenstackhq/redwood", + "displayName": "ZenStack RedwoodJS Integration", + "version": "1.6.0", + "description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.", + "repository": { + "type": "git", + "url": "https://github.com/zenstackhq/zenstack" + }, + "scripts": { + "clean": "rimraf dist", + "build": "pnpm lint --max-warnings=0 && pnpm clean && tsc", + "watch": "tsc --watch", + "lint": "eslint src --ext ts", + "prepublishOnly": "pnpm build" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "default": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./graphql": { + "default": "./dist/graphql.js", + "types": "./dist/graphql.d.ts" + }, + "./package.json": { + "default": "./package.json" + } + }, + "author": { + "name": "ZenStack Team" + }, + "homepage": "https://zenstack.dev", + "license": "MIT", + "dependencies": { + "@zenstackhq/runtime": "workspace:*", + "colors": "1.4.0", + "ts-morph": "^16.0.0" + }, + "peerDependencies": { + "execa": "^5.0.0", + "listr2": "^6.0.0", + "terminal-link": "^2.0.0", + "yargs": "^17.7.2" + }, + "devDependencies": { + "@redwoodjs/graphql-server": "^6.6.0", + "@redwoodjs/cli-helpers": "^6.6.0", + "@types/yargs": "^17.0.32", + "graphql-yoga": "^5.0.2" + } +} diff --git a/packages/misc/redwood/src/cli-passthrough.ts b/packages/misc/redwood/src/cli-passthrough.ts new file mode 100644 index 000000000..4e327b5b6 --- /dev/null +++ b/packages/misc/redwood/src/cli-passthrough.ts @@ -0,0 +1,51 @@ +import { getPaths } from '@redwoodjs/cli-helpers'; +import colors from 'colors'; +import execa from 'execa'; +import { CommandModule } from 'yargs'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +async function runCommand(command: string, options: any) { + const args = ['zenstack', command]; + for (const [name, value] of Object.entries(options)) { + args.push(name.length > 1 ? `--${name}` : `-${name}`); + if (typeof value === 'string') { + // Make sure options that take multiple quoted words + // are passed to zenstack with quotes. + value.split(' ').length > 1 ? args.push(`"${value}"`) : args.push(value); + } + } + + console.log(); + console.log(colors.green('Running ZenStack CLI...')); + console.log(colors.underline('$ npx ' + args.join(' '))); + console.log(); + + try { + await execa('npx', args, { cwd: getPaths().api.base, shell: true, stdio: 'inherit', cleanup: true }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (e: any) { + process.exit(e?.exitCode || 1); + } +} + +/** + * Creates a yargs command that passes all options to the ZenStack CLI command. + */ +export function makePassthroughCommand(command: string): CommandModule { + return { + command, + describe: `Run \`zenstack ${command} ...\``, + builder: (yargs) => { + return yargs + .strictOptions(false) + .strictCommands(false) + .strict(false) + .parserConfiguration({ 'camel-case-expansion': false, 'boolean-negation': false }) + .help(false) + .version(false); + }, + handler: async ({ _, $0: _$0, ...options }) => { + await runCommand(command, options); + }, + }; +} diff --git a/packages/misc/redwood/src/commands/setup.ts b/packages/misc/redwood/src/commands/setup.ts new file mode 100644 index 000000000..e0ddfb81b --- /dev/null +++ b/packages/misc/redwood/src/commands/setup.ts @@ -0,0 +1,227 @@ +import { getPaths } from '@redwoodjs/cli-helpers'; +import colors from 'colors'; +import execa from 'execa'; +import fs from 'fs'; +import { Listr, ListrTask } from 'listr2'; +import path from 'path'; +import terminalLink from 'terminal-link'; +import { Project, SyntaxKind, type PropertyAssignment } from 'ts-morph'; +import type { CommandModule } from 'yargs'; +import { addApiPackages } from '../utils'; + +function installDependencies() { + return addApiPackages([ + { pkg: 'zenstack', dev: true }, + { pkg: '@zenstackhq/runtime' }, + { pkg: '@zenstackhq/redwood' }, + ]); +} + +// copy schema.prisma to schema.zmodel, and update package.json +function bootstrapSchema() { + return { + title: 'Bootstrapping ZModel schema...', + task: () => { + const apiPaths = getPaths().api; + const zmodel = path.join(path.dirname(apiPaths.dbSchema), 'schema.zmodel'); + if (!fs.existsSync(zmodel)) { + fs.cpSync(apiPaths.dbSchema, zmodel); + } else { + console.info( + colors.blue(`Schema file "${path.relative(getPaths().base, zmodel)}" already exists. Skipping.`) + ); + } + + const pkgJson = path.join(apiPaths.base, 'package.json'); + if (fs.existsSync(pkgJson)) { + const content = fs.readFileSync(pkgJson, 'utf-8'); + const pkg = JSON.parse(content); + if (!pkg.zenstack) { + pkg.zenstack = { + schema: path.relative(apiPaths.base, zmodel), + prisma: path.relative(apiPaths.base, apiPaths.dbSchema), + }; + fs.writeFileSync(pkgJson, JSON.stringify(pkg, null, 4)); + } + } + }, + }; +} + +// install ZenStack GraphQLYoga plugin +function installGraphQLPlugin() { + return { + title: 'Installing GraphQL plugin...', + task: async () => { + // locate "api/functions/graphql.[js|ts]" + let sourcePath: string | undefined; + const functionsDir = getPaths().api.functions; + if (fs.existsSync(path.join(functionsDir, 'graphql.ts'))) { + sourcePath = path.join(functionsDir, 'graphql.ts'); + } else if (fs.existsSync(path.join(functionsDir, 'graphql.js'))) { + sourcePath = path.join(functionsDir, 'graphql.js'); + } + + if (!sourcePath) { + console.warn( + colors.yellow(`Unable to find handler source file: ${path.join(functionsDir, 'graphql.(js|ts)')}`) + ); + return; + } + + // add import + const project = new Project(); + const sf = project.addSourceFileAtPathIfExists(sourcePath)!; + let changed = false; + let identified = false; + + const imports = sf.getImportDeclarations(); + if (!imports.some((i) => i.getModuleSpecifierValue() === '@zenstackhq/redwood')) { + sf.addImportDeclaration({ + moduleSpecifier: '@zenstackhq/redwood', + namedImports: ['useZenStack'], + }); + changed = true; + } + + // add "extraPlugins" option to `createGraphQLHandler` call + sf.getDescendantsOfKind(SyntaxKind.CallExpression).forEach((expr) => { + if (identified) { + return; + } + + if (expr.getExpression().asKind(SyntaxKind.Identifier)?.getText() === 'createGraphQLHandler') { + const arg = expr.getArguments()[0]?.asKind(SyntaxKind.ObjectLiteralExpression); + if (arg) { + identified = true; + const props = arg.getProperties(); + const pluginsProp = props.find( + (p): p is PropertyAssignment => + p.asKind(SyntaxKind.PropertyAssignment)?.getName() === 'extraPlugins' + ); + if (pluginsProp) { + const pluginArr = pluginsProp.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression); + if (pluginArr) { + if (!pluginArr.getElements().some((e) => e.getText().includes('useZenStack'))) { + pluginArr.addElement('useZenStack(db)'); + changed = true; + } + } + } else { + arg.addPropertyAssignment({ + name: 'extraPlugins', + initializer: '[useZenStack(db)]', + }); + changed = true; + } + } + } + }); + + if (!identified) { + console.warn( + colors.yellow( + 'Unable to determine how to install ZenStack GraphQL plugin. Please add it manually following https://zenstack.dev/docs/guides/redwood.' + ) + ); + } + + if (changed) { + sf.formatText(); + await project.save(); + } + }, + }; +} + +// eject templates used for `yarn rw generate service` +function ejectServiceTemplates() { + return { + title: 'Ejecting service templates...', + task: async () => { + if (fs.existsSync(path.join(getPaths().api.base, 'generators', 'service'))) { + console.info(colors.blue('Service templates already ejected. Skipping.')); + return; + } + + await execa('yarn', ['rw', 'setup', 'generator', 'service'], { cwd: getPaths().api.base }); + const serviceTemplateTsFile = path.join( + getPaths().api.base, + 'generators', + 'service', + 'service.ts.template' + ); + const serviceTemplateJsFile = path.join( + getPaths().api.base, + 'generators', + 'service', + 'service.js.template' + ); + const serviceTemplateFile = fs.existsSync(serviceTemplateTsFile) + ? serviceTemplateTsFile + : fs.existsSync(serviceTemplateJsFile) + ? serviceTemplateJsFile + : undefined; + + if (!serviceTemplateFile) { + console.warn(colors.red('Unable to find the ejected service template file.')); + return; + } + + // replace `db.` with `context.db.` + const templateContent = fs.readFileSync(serviceTemplateFile, 'utf-8'); + const newTemplateContent = templateContent + .replace(/^import { db } from.*\n$/gm, '') + .replace(/return db\./g, 'return context.db.'); + fs.writeFileSync(serviceTemplateFile, newTemplateContent); + }, + }; +} + +function whatsNext() { + const zmodel = path.relative(getPaths().base, path.join(path.dirname(getPaths().api.dbSchema), 'schema.zmodel')); + const task: ListrTask = { + title: `What's next...`, + task: (_ctx, task) => { + task.title = + `What's next...\n\n` + + ` - Install ${terminalLink('ZenStack IDE extensions', 'https://zenstack.dev/docs/guides/ide')}.\n` + + ` - Use "${zmodel}" to model your database schema and access control.\n` + + ` - Run \`yarn rw @zenstackhq generate\` to regenerate Prisma schema and client.\n` + + ` - Learn ${terminalLink( + "how ZenStack extends Prisma's power", + 'https://zenstack.dev/docs/the-complete-guide/part1' + )}.\n` + + ` - Create a sample schema with \`yarn rw @zenstackhq sample\`.\n` + + ` - Join ${terminalLink( + 'Discord community', + 'https://discord.gg/Ykhr738dUe' + )} for questions and updates.\n`; + }, + }; + return task; +} + +const setupCommand: CommandModule = { + command: 'setup', + describe: 'Set up ZenStack environment', + handler: async () => { + const tasks = new Listr([ + installDependencies(), + bootstrapSchema(), + installGraphQLPlugin(), + ejectServiceTemplates(), + whatsNext(), + ]); + + try { + await tasks.run(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (e: any) { + console.error(colors.red(e.message)); + process.exit(e?.exitCode || 1); + } + }, +}; + +export default setupCommand; diff --git a/packages/misc/redwood/src/graphql.ts b/packages/misc/redwood/src/graphql.ts new file mode 100644 index 000000000..69267b5e2 --- /dev/null +++ b/packages/misc/redwood/src/graphql.ts @@ -0,0 +1,61 @@ +import { ForbiddenError } from '@redwoodjs/graphql-server'; +import { + CrudFailureReason, + EnhancementOptions, + PrismaErrorCode, + ValidationError, + enhance, + isPrismaClientKnownRequestError, + type AuthUser, +} from '@zenstackhq/runtime'; +import { type Plugin } from 'graphql-yoga'; + +/** + * Plugin options + */ +export type ZenStackPluginOptions = EnhancementOptions; + +/** + * A GraphQLYoga plugin that adds a ZenStack-enhanced PrismaClient into the context + * as `context.db`. + * @param db The original PrismaClient. + * @param getAuthUser A hook function for getting the current user. By default `context.currentUser` is used. + * @param options Options for creating the enhanced PrismaClient. See https://zenstack.dev/docs/reference/runtime-api#enhance for more details. + * @returns + */ +export function useZenStack( + db: PrismaClient, + getAuthUser?: (currentUser: unknown) => Promise, + options?: ZenStackPluginOptions +): Plugin<{ currentUser: unknown; db: PrismaClient }> { + return { + onContextBuilding: () => { + return async ({ context }) => { + const user = getAuthUser ? await getAuthUser(context.currentUser) : (context.currentUser as AuthUser); + context.db = enhance( + db, + { user }, + { + errorTransformer: transformError, + ...options, + } + ); + }; + }, + }; +} + +// Transforms ZenStack errors into appropriate RedwoodJS errors +function transformError(error: unknown) { + if (isPrismaClientKnownRequestError(error) && error.code === PrismaErrorCode.CONSTRAINED_FAILED) { + if ( + error.meta?.reason === CrudFailureReason.ACCESS_POLICY_VIOLATION || + error.meta?.reason === CrudFailureReason.RESULT_NOT_READABLE + ) { + return new ForbiddenError(error.message); + } else if (error.meta?.reason === CrudFailureReason.DATA_VALIDATION_VIOLATION) { + return new ValidationError(error.message); + } + } + return error; +} diff --git a/packages/misc/redwood/src/index.ts b/packages/misc/redwood/src/index.ts new file mode 100644 index 000000000..67585bb3f --- /dev/null +++ b/packages/misc/redwood/src/index.ts @@ -0,0 +1,11 @@ +import { makePassthroughCommand } from './cli-passthrough'; +import setup from './commands/setup'; + +export const commands = [ + setup, + makePassthroughCommand('generate'), + makePassthroughCommand('info'), + makePassthroughCommand('format'), + makePassthroughCommand('repl'), +]; +export * from './graphql'; diff --git a/packages/misc/redwood/src/utils.ts b/packages/misc/redwood/src/utils.ts new file mode 100644 index 000000000..dbf8a1a04 --- /dev/null +++ b/packages/misc/redwood/src/utils.ts @@ -0,0 +1,20 @@ +import { getPaths } from '@redwoodjs/cli-helpers'; +import execa from 'execa'; + +/** + * Utility for adding npm dependencies to "api" package + */ +export const addApiPackages = (apiPackages: { pkg: string; dev?: boolean }[]) => ({ + title: 'Adding required api packages...', + task: async () => { + const devPkgs = apiPackages.filter((p) => p.dev).map((p) => p.pkg); + if (devPkgs.length > 0) { + await execa('yarn', ['add', '-D', ...devPkgs], { cwd: getPaths().api.base }); + } + + const runtimePkgs = apiPackages.filter((p) => !p.dev).map((p) => p.pkg); + if (runtimePkgs.length > 0) { + await execa('yarn', ['add', ...runtimePkgs], { cwd: getPaths().api.base }); + } + }, +}); diff --git a/packages/misc/redwood/tsconfig.json b/packages/misc/redwood/tsconfig.json new file mode 100644 index 000000000..a11845a55 --- /dev/null +++ b/packages/misc/redwood/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "lib": ["ESNext"], + "outDir": "dist" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/runtime/src/enhancements/policy/index.ts b/packages/runtime/src/enhancements/policy/index.ts index 22c4cf580..678f777ef 100644 --- a/packages/runtime/src/enhancements/policy/index.ts +++ b/packages/runtime/src/enhancements/policy/index.ts @@ -7,7 +7,7 @@ import { getIdFields, type ModelMeta } from '../../cross'; import { getDefaultModelMeta, getDefaultPolicy, getDefaultZodSchemas } from '../../loader'; import { AuthUser, DbClientContract } from '../../types'; import { hasAllFields } from '../../validation'; -import { makeProxy } from '../proxy'; +import { ErrorTransformer, makeProxy } from '../proxy'; import type { CommonEnhancementOptions, PolicyDef, ZodSchemas } from '../types'; import { PolicyProxyHandler } from './handler'; @@ -41,6 +41,11 @@ export interface WithPolicyOptions extends CommonEnhancementOptions { * Whether to log Prisma query */ logPrismaQuery?: boolean; + + /** + * Hook for transforming errors before they are thrown to the caller. + */ + errorTransformer?: ErrorTransformer; } /** @@ -110,6 +115,7 @@ export function withPolicy( context?.user, options?.logPrismaQuery ), - 'policy' + 'policy', + options?.errorTransformer ); } diff --git a/packages/runtime/src/enhancements/proxy.ts b/packages/runtime/src/enhancements/proxy.ts index 8c4d85ceb..358bff153 100644 --- a/packages/runtime/src/enhancements/proxy.ts +++ b/packages/runtime/src/enhancements/proxy.ts @@ -10,6 +10,11 @@ import { createDeferredPromise } from './policy/promise'; */ export type BatchResult = { count: number }; +/** + * Function for transforming errors. + */ +export type ErrorTransformer = (error: unknown) => unknown; + /** * Interface for proxy that intercepts Prisma operations. */ @@ -174,7 +179,8 @@ export function makeProxy( prisma: any, modelMeta: ModelMeta, makeHandler: (prisma: object, model: string) => T, - name = 'unnamed_enhancer' + name = 'unnamed_enhancer', + errorTransformer?: ErrorTransformer ) { const models = Object.keys(modelMeta.fields).map((k) => k.toLowerCase()); const proxy = new Proxy(prisma, { @@ -227,7 +233,7 @@ export function makeProxy( return propVal; } - return createHandlerProxy(makeHandler(target, prop), propVal); + return createHandlerProxy(makeHandler(target, prop), propVal, errorTransformer); }, }); @@ -235,7 +241,11 @@ export function makeProxy( } // A proxy for capturing errors and processing stack trace -function createHandlerProxy(handler: T, origTarget: any): T { +function createHandlerProxy( + handler: T, + origTarget: any, + errorTransformer?: ErrorTransformer +): T { return new Proxy(handler, { get(target, propKey) { const prop = target[propKey as keyof T]; @@ -266,6 +276,10 @@ function createHandlerProxy(handler: T, origTarget (err as any).internalStack = err.stack; err.stack = cleanCallStack(capture.stack, propKey.toString(), err.message); } + + if (errorTransformer) { + err = errorTransformer ? errorTransformer(err) : err; + } reject(err); } ); diff --git a/packages/schema/src/cli/cli-util.ts b/packages/schema/src/cli/cli-util.ts index bb9aa525b..000e92ca7 100644 --- a/packages/schema/src/cli/cli-util.ts +++ b/packages/schema/src/cli/cli-util.ts @@ -15,6 +15,7 @@ import { getVersion } from '../utils/version-utils'; import { CliError } from './cli-error'; import { ZModelFormatter } from '../language-server/zmodel-formatter'; import { TextDocument } from 'vscode-languageserver-textdocument'; +import { getPackageJson } from '../utils/pkg-utils'; // required minimal version of Prisma export const requiredPrismaVersion = '4.8.0'; @@ -280,17 +281,10 @@ export async function formatDocument(fileName: string) { export function getDefaultSchemaLocation() { let location = path.resolve('schema.zmodel'); - if (fs.existsSync('./package.json')) { - try { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const pkgJson = require(path.resolve('./package.json')); - if (typeof pkgJson.zenstack?.schema === 'string') { - location = path.resolve(pkgJson.zenstack.schema); - } - } catch (e) { - console.error(e); - // noop - } + // handle override from package.json + const pkgJson = getPackageJson(); + if (typeof pkgJson?.zenstack?.schema === 'string') { + location = path.resolve(pkgJson.zenstack.schema); } return location; diff --git a/packages/schema/src/cli/plugin-runner.ts b/packages/schema/src/cli/plugin-runner.ts index d76d43522..0609fd4fb 100644 --- a/packages/schema/src/cli/plugin-runner.ts +++ b/packages/schema/src/cli/plugin-runner.ts @@ -18,6 +18,7 @@ import fs from 'fs'; import ora from 'ora'; import path from 'path'; import { ensureDefaultOutputFolder } from '../plugins/plugin-utils'; +import { getDefaultPrismaOutputFile } from '../plugins/prisma/schema-generator'; import telemetry from '../telemetry'; import { getVersion } from '../utils/version-utils'; @@ -54,7 +55,7 @@ export class PluginRunner { const plugins: PluginInfo[] = []; const pluginDecls = options.schema.declarations.filter((d): d is Plugin => isPlugin(d)); - let prismaOutput = resolvePath('./prisma/schema.prisma', { schemaPath: options.schemaPath }); + let prismaOutput = getDefaultPrismaOutputFile(options.schemaPath); for (const pluginDecl of pluginDecls) { const pluginProvider = this.getPluginProvider(pluginDecl); diff --git a/packages/schema/src/plugins/prisma/schema-generator.ts b/packages/schema/src/plugins/prisma/schema-generator.ts index 0605f468b..45a025d27 100644 --- a/packages/schema/src/plugins/prisma/schema-generator.ts +++ b/packages/schema/src/plugins/prisma/schema-generator.ts @@ -63,6 +63,7 @@ import { SimpleField, } from './prisma-builder'; import { ZModelCodeGenerator } from '@zenstackhq/sdk'; +import { getPackageJson } from '../../utils/pkg-utils'; const MODEL_PASSTHROUGH_ATTR = '@@prisma.passthrough'; const FIELD_PASSTHROUGH_ATTR = '@prisma.passthrough'; @@ -112,8 +113,9 @@ export default class PrismaSchemaGenerator { } } - let outFile = (options.output as string) ?? './prisma/schema.prisma'; - outFile = resolvePath(outFile, options); + const outFile = options.output + ? resolvePath(options.output as string, options) + : getDefaultPrismaOutputFile(options.schemaPath); if (!fs.existsSync(path.dirname(outFile))) { fs.mkdirSync(path.dirname(outFile), { recursive: true }); @@ -430,3 +432,17 @@ export default class PrismaSchemaGenerator { _enum.addField(field.name, attributes, documentations); } } + +export function getDefaultPrismaOutputFile(schemaPath: string) { + let result: string | undefined; + + // handle override from package.json + const pkgJson = getPackageJson(); + if (typeof pkgJson.zenstack?.prisma === 'string') { + result = path.resolve(pkgJson.zenstack.prisma); + } else { + result = './prisma/schema.prisma'; + } + + return resolvePath(result, { schemaPath }); +} diff --git a/packages/schema/src/utils/pkg-utils.ts b/packages/schema/src/utils/pkg-utils.ts index 0d3633cd7..ffb9b0aea 100644 --- a/packages/schema/src/utils/pkg-utils.ts +++ b/packages/schema/src/utils/pkg-utils.ts @@ -84,3 +84,12 @@ export function ensurePackage( installPackage(pkg, dev, pkgManager, tag, resolvePath, exactVersion); } } + +export function getPackageJson() { + const pkgJsonPath = path.join(process.cwd(), 'package.json'); + if (fs.existsSync(pkgJsonPath)) { + return JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')); + } else { + return undefined; + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ddeb1f59..6eefd606f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -80,6 +80,43 @@ importers: version: 1.1.3 publishDirectory: dist + packages/misc/redwood: + dependencies: + '@zenstackhq/runtime': + specifier: workspace:* + version: link:../../runtime/dist + colors: + specifier: 1.4.0 + version: 1.4.0 + execa: + specifier: ^5.0.0 + version: 5.1.1 + listr2: + specifier: ^6.0.0 + version: 6.6.1 + terminal-link: + specifier: ^2.0.0 + version: 2.1.1 + ts-morph: + specifier: ^16.0.0 + version: 16.0.0 + yargs: + specifier: ^17.7.2 + version: 17.7.2 + devDependencies: + '@redwoodjs/cli-helpers': + specifier: ^6.6.0 + version: 6.6.0 + '@redwoodjs/graphql-server': + specifier: ^6.6.0 + version: 6.6.0 + '@types/yargs': + specifier: ^17.0.32 + version: 17.0.32 + graphql-yoga: + specifier: ^5.0.2 + version: 5.0.2(graphql@16.8.1) + packages/plugins/openapi: dependencies: '@prisma/generator-helper': @@ -1226,6 +1263,14 @@ packages: '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2) dev: true + /@babel/runtime-corejs3@7.23.6: + resolution: {integrity: sha512-Djs/ZTAnpyj0nyg7p1J6oiE/tZ9G2stqAFlLGZynrW+F3k2w2jGK2mLOBxzYIOcZYA89+c3d3wXKpYLcpwcU6w==} + engines: {node: '>=6.9.0'} + dependencies: + core-js-pure: 3.35.0 + regenerator-runtime: 0.14.1 + dev: true + /@babel/runtime@7.22.5: resolution: {integrity: sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==} engines: {node: '>=6.9.0'} @@ -1247,33 +1292,6 @@ packages: '@babel/types': 7.23.0 dev: true - /@babel/template@7.22.5: - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - dev: true - - /@babel/traverse@7.22.8: - resolution: {integrity: sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/traverse@7.23.2: resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} engines: {node: '>=6.9.0'} @@ -1521,6 +1539,84 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true + /@envelop/core@4.0.3: + resolution: {integrity: sha512-O0Vz8E0TObT6ijAob8jYFVJavcGywKThM3UAsxUIBBVPYZTMiqI9lo2gmAnbMUnrDcAYkUTZEW9FDYPRdF5l6g==} + engines: {node: '>=16.0.0'} + dependencies: + '@envelop/types': 4.0.1 + tslib: 2.6.0 + dev: true + + /@envelop/core@5.0.0: + resolution: {integrity: sha512-aJdnH/ptv+cvwfvciCBe7TSvccBwo9g0S5f6u35TBVzRVqIGkK03lFlIL+x1cnfZgN9EfR2b1PH2galrT1CdCQ==} + engines: {node: '>=18.0.0'} + dependencies: + '@envelop/types': 5.0.0 + tslib: 2.6.0 + dev: true + + /@envelop/depth-limit@3.0.3(@envelop/core@4.0.3)(graphql@16.8.1): + resolution: {integrity: sha512-fDyLQDVlSG3DPJmzwb6pdnpK67rNy9KLkN8LTthZOmEXGz0WuVP1EOOnjYY7PE566BySbNXl5z1lTeOPHR1KUw==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@envelop/core': ^4.0.3 + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + dependencies: + '@envelop/core': 4.0.3 + graphql: 16.8.1 + graphql-depth-limit: 1.1.0(graphql@16.8.1) + tslib: 2.6.0 + dev: true + + /@envelop/disable-introspection@5.0.3(@envelop/core@4.0.3)(graphql@16.8.1): + resolution: {integrity: sha512-PoKbaeCVGdgkgQUGl46L33SBB/bYKVOe1QHEW8++n9lnTTTLJTyo8EbtJb++UcuQCaaKn277fkUyc9sR9fOh5w==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@envelop/core': ^4.0.3 + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + dependencies: + '@envelop/core': 4.0.3 + graphql: 16.8.1 + tslib: 2.6.0 + dev: true + + /@envelop/filter-operation-type@5.0.3(@envelop/core@4.0.3)(graphql@16.8.1): + resolution: {integrity: sha512-z6gYb+y4O6lsOH+KMwrfYzN7b0ybGAZWSk/++z913nOSxtPm42sYdCQ56upw+tN/WHNxwKejCO54TjhrSdUX9Q==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@envelop/core': ^4.0.3 + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + dependencies: + '@envelop/core': 4.0.3 + graphql: 16.8.1 + tslib: 2.6.0 + dev: true + + /@envelop/on-resolve@3.0.3(@envelop/core@4.0.3)(graphql@16.8.1): + resolution: {integrity: sha512-Mo2w3CHmyLCScFuIO2VS2Co44vlPSc4zwujz0x+/zyaJ+eCwBQMRuE9u+9ORjvKImNxrbXI9FQVNlbF0iDk4iQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@envelop/core': ^4.0.3 + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + dependencies: + '@envelop/core': 4.0.3 + graphql: 16.8.1 + dev: true + + /@envelop/types@4.0.1: + resolution: {integrity: sha512-ULo27/doEsP7uUhm2iTnElx13qTO6I5FKvmLoX41cpfuw8x6e0NUFknoqhEsLzAbgz8xVS5mjwcxGCXh4lDYzg==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.0 + dev: true + + /@envelop/types@5.0.0: + resolution: {integrity: sha512-IPjmgSc4KpQRlO4qbEDnBEixvtb06WDmjKfi/7fkZaryh5HuOmTtixe1EupQI5XfXO8joc3d27uUZ0QdC++euA==} + engines: {node: '>=18.0.0'} + dependencies: + tslib: 2.6.0 + dev: true + /@esbuild/android-arm64@0.17.19: resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} @@ -2133,6 +2229,98 @@ packages: dev: true optional: true + /@escape.tech/graphql-armor-block-field-suggestions@2.1.0: + resolution: {integrity: sha512-Sna+jK02oUDJMWSfA7ica69HdtBroP3VakeMUK0+QgWlAEBEphT+SzKGDX5vn6sS7sAsEoY50gUAIgtTG+2qVw==} + engines: {node: '>=16.0.0'} + dependencies: + graphql: 16.8.1 + optionalDependencies: + '@envelop/core': 4.0.3 + dev: true + + /@escape.tech/graphql-armor-cost-limit@2.1.0: + resolution: {integrity: sha512-zejjLm3vn4MQDpXRaPGXclo1Tq1lc93Ltoh3UoqUDiFV29ZUAnSnuuEw/AdbkK+YFrSIfZYMAGDV8AZ2Xz76RQ==} + engines: {node: '>=16.0.0'} + dependencies: + graphql: 16.8.1 + optionalDependencies: + '@envelop/core': 4.0.3 + '@escape.tech/graphql-armor-types': 0.5.0 + dev: true + + /@escape.tech/graphql-armor-max-aliases@2.1.0: + resolution: {integrity: sha512-jaqB8YWIpfDSNrbiGEt301MQqSH7cLu+ZYZjEQ/irL5rqbSN1c9zE+nqEP1cXxB8jB6D+vp8jU30rrZWS9goAQ==} + engines: {node: '>=16.0.0'} + dependencies: + graphql: 16.8.1 + optionalDependencies: + '@envelop/core': 4.0.3 + '@escape.tech/graphql-armor-types': 0.5.0 + dev: true + + /@escape.tech/graphql-armor-max-depth@2.2.0: + resolution: {integrity: sha512-v0z2yelQL614mYFpYL/iRkieq/7H2XKbvJ6RvbGMFFSqo3eSIz8fyX0f6pyswR7myQxki4ur0MFxSn8S5jjfqw==} + engines: {node: '>=16.0.0'} + dependencies: + graphql: 16.8.1 + optionalDependencies: + '@envelop/core': 4.0.3 + '@escape.tech/graphql-armor-types': 0.5.0 + dev: true + + /@escape.tech/graphql-armor-max-directives@2.1.0: + resolution: {integrity: sha512-0OuvWBbOVdphyLPafqTknM4EIrFsGHjv9DcSw8mM7Ol0kKLwYG7tGuBmEzwopRntkqW3utID5tMtf/B6px/Eyw==} + engines: {node: '>=16.0.0'} + dependencies: + graphql: 16.8.1 + optionalDependencies: + '@envelop/core': 4.0.3 + '@escape.tech/graphql-armor-types': 0.5.0 + dev: true + + /@escape.tech/graphql-armor-max-tokens@2.2.0: + resolution: {integrity: sha512-s6IBS8R4fxQ9cVX1USf4dUOWEDbVVrlcGmVOuTCyW1LnpFJQ5vWCs0n93Lsw2ge/MlRIkZEtGuiXdr0YmLU4Pg==} + engines: {node: '>=16.0.0'} + dependencies: + graphql: 16.8.1 + optionalDependencies: + '@envelop/core': 4.0.3 + '@escape.tech/graphql-armor-types': 0.5.0 + dev: true + + /@escape.tech/graphql-armor-types@0.5.0: + resolution: {integrity: sha512-a7KMhb1qVHFFWw4bvGYQI637YaIZRozbfc+Fj1Vv/pwnTCJOzOgnvKO8+WBXJsFFGJ2Kj+fRORmSpz7J+lJF1w==} + requiresBuild: true + dependencies: + graphql: 16.8.1 + dev: true + optional: true + + /@escape.tech/graphql-armor@2.3.1(@envelop/core@4.0.3): + resolution: {integrity: sha512-2HV6ApCeb52eVTeXjgpo00VLDZkiQfxeMi9KTPHsK8/1f3X60gx51szHwTRYhPUeimUquRcxqlO36Iq3rbhywQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@apollo/server': ^4.0.0 + '@envelop/core': ^4.0.0 + '@escape.tech/graphql-armor-types': 0.5.0 + peerDependenciesMeta: + '@apollo/server': + optional: true + '@envelop/core': + optional: true + '@escape.tech/graphql-armor-types': + optional: true + dependencies: + '@envelop/core': 4.0.3 + '@escape.tech/graphql-armor-block-field-suggestions': 2.1.0 + '@escape.tech/graphql-armor-cost-limit': 2.1.0 + '@escape.tech/graphql-armor-max-aliases': 2.1.0 + '@escape.tech/graphql-armor-max-depth': 2.2.0 + '@escape.tech/graphql-armor-max-directives': 2.1.0 + '@escape.tech/graphql-armor-max-tokens': 2.2.0 + graphql: 16.8.1 + dev: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.55.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2197,6 +2385,115 @@ packages: fast-json-stringify: 5.7.0 dev: true + /@graphql-tools/executor@1.2.0(graphql@16.8.1): + resolution: {integrity: sha512-SKlIcMA71Dha5JnEWlw4XxcaJ+YupuXg0QCZgl2TOLFz4SkGCwU/geAsJvUJFwK2RbVLpQv/UMq67lOaBuwDtg==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/utils': 10.0.11(graphql@16.8.1) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1) + '@repeaterjs/repeater': 3.0.5 + graphql: 16.8.1 + tslib: 2.6.0 + value-or-promise: 1.0.12 + dev: true + + /@graphql-tools/merge@9.0.1(graphql@16.8.1): + resolution: {integrity: sha512-hIEExWO9fjA6vzsVjJ3s0cCQ+Q/BEeMVJZtMXd7nbaVefVy0YDyYlEkeoYYNV3NVVvu1G9lr6DM1Qd0DGo9Caw==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/utils': 10.0.11(graphql@16.8.1) + graphql: 16.8.1 + tslib: 2.6.0 + dev: true + + /@graphql-tools/schema@10.0.2(graphql@16.8.1): + resolution: {integrity: sha512-TbPsIZnWyDCLhgPGnDjt4hosiNU2mF/rNtSk5BVaXWnZqvKJ6gzJV4fcHcvhRIwtscDMW2/YTnK6dLVnk8pc4w==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-tools/merge': 9.0.1(graphql@16.8.1) + '@graphql-tools/utils': 10.0.11(graphql@16.8.1) + graphql: 16.8.1 + tslib: 2.6.0 + value-or-promise: 1.0.12 + dev: true + + /@graphql-tools/utils@10.0.11(graphql@16.8.1): + resolution: {integrity: sha512-vVjXgKn6zjXIlYBd7yJxCVMYGb5j18gE3hx3Qw3mNsSEsYQXbJbPdlwb7Fc9FogsJei5AaqiQerqH4kAosp1nQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1) + cross-inspect: 1.0.0 + dset: 3.1.3 + graphql: 16.8.1 + tslib: 2.6.0 + dev: true + + /@graphql-typed-document-node/core@3.2.0(graphql@16.8.1): + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + graphql: 16.8.1 + dev: true + + /@graphql-yoga/logger@1.0.0: + resolution: {integrity: sha512-JYoxwnPggH2BfO+dWlWZkDeFhyFZqaTRGLvFhy+Pjp2UxitEW6nDrw+pEDw/K9tJwMjIFMmTT9VfTqrnESmBHg==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.0 + dev: true + + /@graphql-yoga/logger@2.0.0: + resolution: {integrity: sha512-Mg8psdkAp+YTG1OGmvU+xa6xpsAmSir0hhr3yFYPyLNwzUj95DdIwsMpKadDj9xDpYgJcH3Hp/4JMal9DhQimA==} + engines: {node: '>=18.0.0'} + dependencies: + tslib: 2.6.0 + dev: true + + /@graphql-yoga/subscription@4.0.0: + resolution: {integrity: sha512-0qsN/BPPZNMoC2CZ8i+P6PgiJyHh1H35aKDt37qARBDaIOKDQuvEOq7+4txUKElcmXi7DYFo109FkhSQoEajrg==} + engines: {node: '>=16.0.0'} + dependencies: + '@graphql-yoga/typed-event-target': 2.0.0 + '@repeaterjs/repeater': 3.0.5 + '@whatwg-node/events': 0.1.1 + tslib: 2.6.0 + dev: true + + /@graphql-yoga/subscription@5.0.0: + resolution: {integrity: sha512-Ri7sK8hmxd/kwaEa0YT8uqQUb2wOLsmBMxI90QDyf96lzOMJRgBuNYoEkU1pSgsgmW2glceZ96sRYfaXqwVxUw==} + engines: {node: '>=18.0.0'} + dependencies: + '@graphql-yoga/typed-event-target': 3.0.0 + '@repeaterjs/repeater': 3.0.5 + '@whatwg-node/events': 0.1.1 + tslib: 2.6.0 + dev: true + + /@graphql-yoga/typed-event-target@2.0.0: + resolution: {integrity: sha512-oA/VGxGmaSDym1glOHrltw43qZsFwLLjBwvh57B79UKX/vo3+UQcRgOyE44c5RP7DCYjkrC2tuArZmb6jCzysw==} + engines: {node: '>=16.0.0'} + dependencies: + '@repeaterjs/repeater': 3.0.5 + tslib: 2.6.0 + dev: true + + /@graphql-yoga/typed-event-target@3.0.0: + resolution: {integrity: sha512-w+liuBySifrstuHbFrHoHAEyVnDFVib+073q8AeAJ/qqJfvFvAwUPLLtNohR/WDVRgSasfXtl3dcNuVJWN+rjg==} + engines: {node: '>=18.0.0'} + dependencies: + '@repeaterjs/repeater': 3.0.5 + tslib: 2.6.0 + dev: true + /@humanwhocodes/config-array@0.11.13: resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} engines: {node: '>=10.10.0'} @@ -2222,6 +2519,10 @@ packages: resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true + /@iarna/toml@2.2.5: + resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + dev: true + /@ioredis/commands@1.2.0: resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} dev: true @@ -2513,6 +2814,10 @@ packages: resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} dev: true + /@kamilkisiela/fast-url-parser@1.1.4: + resolution: {integrity: sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew==} + dev: true + /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: @@ -3034,6 +3339,11 @@ packages: engines: {node: '>=8.0.0'} dev: false + /@opentelemetry/api@1.7.0: + resolution: {integrity: sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==} + engines: {node: '>=8.0.0'} + dev: true + /@paralleldrive/cuid2@2.2.0: resolution: {integrity: sha512-CVQDpPIUHrUGGLdrMGz1NmqZvqmsB2j2rCIQEu1EvxWjlFh4fhvEGmgR409cY20/67/WlJsggenq0no3p3kYsw==} dependencies: @@ -3221,6 +3531,17 @@ packages: prisma: 4.16.2 dev: true + /@prisma/client@5.7.0: + resolution: {integrity: sha512-cZmglCrfNbYpzUtz7HscVHl38e9CrUs31nrVoGUK1nIPXGgt8hT4jj2s657UXcNdQ/jBUxDgGmHyu2Nyrq1txg==} + engines: {node: '>=16.13'} + requiresBuild: true + peerDependencies: + prisma: '*' + peerDependenciesMeta: + prisma: + optional: true + dev: true + /@prisma/debug@4.16.2: resolution: {integrity: sha512-7L7WbG0qNNZYgLpsVB8rCHCXEyHFyIycRlRDNwkVfjQmACC2OW6AWCYCbfdjQhkF/t7+S3njj8wAWAocSs+Brw==} dependencies: @@ -3241,10 +3562,18 @@ packages: - supports-color dev: false + /@prisma/debug@5.7.0: + resolution: {integrity: sha512-tZ+MOjWlVvz1kOEhNYMa4QUGURY+kgOUBqLHYIV8jmCsMuvA1tWcn7qtIMLzYWCbDcQT4ZS8xDgK0R2gl6/0wA==} + dev: true + /@prisma/engines-version@4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81: resolution: {integrity: sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg==} dev: true + /@prisma/engines-version@5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9: + resolution: {integrity: sha512-V6tgRVi62jRwTm0Hglky3Scwjr/AKFBFtS+MdbsBr7UOuiu1TKLPc6xfPiyEN1+bYqjEtjxwGsHgahcJsd1rNg==} + dev: true + /@prisma/engines@4.16.2: resolution: {integrity: sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==} requiresBuild: true @@ -3254,6 +3583,16 @@ packages: requiresBuild: true dev: false + /@prisma/engines@5.7.0: + resolution: {integrity: sha512-TkOMgMm60n5YgEKPn9erIvFX2/QuWnl3GBo6yTRyZKk5O5KQertXiNnrYgSLy0SpsKmhovEPQb+D4l0SzyE7XA==} + requiresBuild: true + dependencies: + '@prisma/debug': 5.7.0 + '@prisma/engines-version': 5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9 + '@prisma/fetch-engine': 5.7.0 + '@prisma/get-platform': 5.7.0 + dev: true + /@prisma/fetch-engine@4.16.2: resolution: {integrity: sha512-lnCnHcOaNn0kw8qTJbVcNhyfIf5Lus2GFXbj3qpkdKEIB9xLgqkkuTP+35q1xFaqwQ0vy4HFpdRUpFP7njE15g==} dependencies: @@ -3304,6 +3643,14 @@ packages: - supports-color dev: false + /@prisma/fetch-engine@5.7.0: + resolution: {integrity: sha512-zIn/qmO+N/3FYe7/L9o+yZseIU8ivh4NdPKSkQRIHfg2QVTVMnbhGoTcecbxfVubeTp+DjcbjS0H9fCuM4W04w==} + dependencies: + '@prisma/debug': 5.7.0 + '@prisma/engines-version': 5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9 + '@prisma/get-platform': 5.7.0 + dev: true + /@prisma/generator-helper@4.16.2: resolution: {integrity: sha512-bMOH7y73Ui7gpQrioFeavMQA+Tf8ksaVf8Nhs9rQNzuSg8SSV6E9baczob0L5KGZTSgYoqnrRxuo03kVJYrnIg==} dependencies: @@ -3326,6 +3673,12 @@ packages: - supports-color dev: false + /@prisma/generator-helper@5.7.0: + resolution: {integrity: sha512-Fn4hJHKGJ49+E8sxpfslRauB3Goa3RAENJ/W25NMR754B9KxvmbCJyE3MT/lIZxML2nGgIdXYUtoDHZHnRaKDw==} + dependencies: + '@prisma/debug': 5.7.0 + dev: true + /@prisma/get-platform@4.16.2: resolution: {integrity: sha512-fnDey1/iSefHJRMB+w243BhWENf+paRouPMdCqIVqu8dYkR1NqhldblsSUC4Zr2sKS7Ta2sK4OLdt9IH+PZTfw==} dependencies: @@ -3360,6 +3713,12 @@ packages: - supports-color dev: false + /@prisma/get-platform@5.7.0: + resolution: {integrity: sha512-ZeV/Op4bZsWXuw5Tg05WwRI8BlKiRFhsixPcAM+5BKYSiUZiMKIi713tfT3drBq8+T0E1arNZgYSA9QYcglWNA==} + dependencies: + '@prisma/debug': 5.7.0 + dev: true + /@prisma/internals@4.16.2: resolution: {integrity: sha512-/3OiSADA3RRgsaeEE+MDsBgL6oAMwddSheXn6wtYGUnjERAV/BmF5bMMLnTykesQqwZ1s8HrISrJ0Vf6cjOxMg==} dependencies: @@ -3462,6 +3821,19 @@ packages: - supports-color dev: false + /@prisma/internals@5.7.0: + resolution: {integrity: sha512-O9x47W1DECAyvNjYUx6oZHmTX10emKuBgsFHZemUbkIcJdCsp3X8Cy2JMJ5z3hqkRX6a6omMamFsWjuTARoaSw==} + dependencies: + '@prisma/debug': 5.7.0 + '@prisma/engines': 5.7.0 + '@prisma/fetch-engine': 5.7.0 + '@prisma/generator-helper': 5.7.0 + '@prisma/get-platform': 5.7.0 + '@prisma/prisma-schema-wasm': 5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9 + arg: 5.0.2 + prompts: 2.4.2 + dev: true + /@prisma/prisma-fmt-wasm@4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81: resolution: {integrity: sha512-g090+dEH7wrdCw359+8J9+TGH84qK28V/dxwINjhhNCtju9lej99z9w/AVsJP9UhhcCPS4psYz4iu8d53uxVpA==} dev: false @@ -3470,6 +3842,10 @@ packages: resolution: {integrity: sha512-JFdsnSgBPN8reDTLOI9Vh/6ccCb2aD1LbY/LWQnkcIgNo6IdpzvuM+qRVbBuA6IZP2SdqQI8Lu6RL2P8EFBQUA==} dev: false + /@prisma/prisma-schema-wasm@5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9: + resolution: {integrity: sha512-w+HdQtux0dJDEn6BG3fgNn+fXErXiekj9n//uHRAgrmZghockJkhnikOmG8aSXjTb1Tu5DrGasBX+rYX6rHT1w==} + dev: true + /@readme/better-ajv-errors@1.6.0(ajv@8.12.0): resolution: {integrity: sha512-9gO9rld84Jgu13kcbKRU+WHseNhaVt76wYMeRDGsUGYxwJtI3RmEJ9LY9dZCYQGI8eUZLuxb5qDja0nqklpFjQ==} engines: {node: '>=14'} @@ -3512,6 +3888,141 @@ packages: openapi-types: 12.1.0 dev: true + /@redwoodjs/api@6.6.0: + resolution: {integrity: sha512-QUlSI6YDurBDtE9t2FC/2JpGM+iVHxN6FoOfRqrfLsTPjrkH2pq7CPI38O5zOjWdsOkha0nxiV4te25cfgG5Lg==} + hasBin: true + peerDependencies: + memjs: 1.3.1 + redis: 4.6.7 + peerDependenciesMeta: + memjs: + optional: true + redis: + optional: true + dependencies: + '@babel/runtime-corejs3': 7.23.6 + '@prisma/client': 5.7.0 + '@whatwg-node/fetch': 0.9.14 + core-js: 3.34.0 + humanize-string: 2.1.0 + jsonwebtoken: 9.0.2 + pascalcase: 1.0.0 + pino: 8.16.2 + title-case: 3.0.3 + transitivePeerDependencies: + - prisma + dev: true + + /@redwoodjs/cli-helpers@6.6.0: + resolution: {integrity: sha512-mwBNnMMWe4EWrbMfcYTTmdUb+saGYBBtqKB1IAxzJQdHEX1jwxwZRM2adRZ1mPHFu+Qg9DZD7GlowaYD6cQaaw==} + dependencies: + '@babel/core': 7.23.2 + '@babel/runtime-corejs3': 7.23.6 + '@iarna/toml': 2.2.5 + '@opentelemetry/api': 1.7.0 + '@redwoodjs/project-config': 6.6.0 + '@redwoodjs/telemetry': 6.6.0 + chalk: 4.1.2 + core-js: 3.34.0 + dotenv: 16.3.1 + execa: 5.1.1 + listr2: 6.6.1 + lodash: 4.17.21 + pascalcase: 1.0.0 + prettier: 2.8.8 + prompts: 2.4.2 + terminal-link: 2.1.1 + transitivePeerDependencies: + - enquirer + - supports-color + dev: true + + /@redwoodjs/graphql-server@6.6.0: + resolution: {integrity: sha512-LuSHmQyZm9E8STfJszSAoNyMHREI/nx2zlA1UzQOG4605YgpljI2wXUxYw7UWCH3rU66Gt0daKdv8GSo2nPlSg==} + dependencies: + '@babel/runtime-corejs3': 7.23.6 + '@envelop/core': 4.0.3 + '@envelop/depth-limit': 3.0.3(@envelop/core@4.0.3)(graphql@16.8.1) + '@envelop/disable-introspection': 5.0.3(@envelop/core@4.0.3)(graphql@16.8.1) + '@envelop/filter-operation-type': 5.0.3(@envelop/core@4.0.3)(graphql@16.8.1) + '@envelop/on-resolve': 3.0.3(@envelop/core@4.0.3)(graphql@16.8.1) + '@escape.tech/graphql-armor': 2.3.1(@envelop/core@4.0.3) + '@graphql-tools/merge': 9.0.1(graphql@16.8.1) + '@graphql-tools/schema': 10.0.2(graphql@16.8.1) + '@graphql-tools/utils': 10.0.11(graphql@16.8.1) + '@opentelemetry/api': 1.7.0 + '@redwoodjs/api': 6.6.0 + core-js: 3.34.0 + graphql: 16.8.1 + graphql-scalars: 1.22.4(graphql@16.8.1) + graphql-tag: 2.12.6(graphql@16.8.1) + graphql-yoga: 4.0.4(graphql@16.8.1) + lodash: 4.17.21 + uuid: 9.0.1 + transitivePeerDependencies: + - '@apollo/server' + - '@escape.tech/graphql-armor-types' + - memjs + - prisma + - redis + dev: true + + /@redwoodjs/project-config@6.6.0: + resolution: {integrity: sha512-L0RZbzQfJrPTfR+w5OfY/FrZny2kXXXwY5ZUhb4k7yXCx3jXG9CrB71/Latek60H45DvS6eyfUd/d1T3lCb/eA==} + dependencies: + '@iarna/toml': 2.2.5 + deepmerge: 4.3.1 + fast-glob: 3.3.2 + string-env-interpolation: 1.0.1 + dev: true + + /@redwoodjs/structure@6.6.0: + resolution: {integrity: sha512-8i4ujrhBklYNPQ7/uAf/W/rrRs9/2dIwVxTjvQz8N7NU4s3J0IrdHj5Q74vIyGOCBA8Lx3SbyXVGjIdg1sdx5g==} + dependencies: + '@babel/runtime-corejs3': 7.23.6 + '@iarna/toml': 2.2.5 + '@prisma/internals': 5.7.0 + '@redwoodjs/project-config': 6.6.0 + '@types/line-column': 1.0.0 + camelcase: 6.3.0 + core-js: 3.34.0 + deepmerge: 4.3.1 + dotenv-defaults: 5.0.2 + enquirer: 2.4.1 + fast-glob: 3.3.2 + graphql: 16.8.1 + lazy-get-decorator: 2.2.1 + line-column: 1.0.2 + lodash: 4.17.21 + lodash-decorators: 6.0.1(lodash@4.17.21) + lru-cache: 7.18.3 + proxyquire: 2.1.3 + ts-morph: 15.1.0 + vscode-languageserver: 6.1.1 + vscode-languageserver-textdocument: 1.0.8 + vscode-languageserver-types: 3.17.3 + yargs-parser: 21.1.1 + dev: true + + /@redwoodjs/telemetry@6.6.0: + resolution: {integrity: sha512-9VEwngUBtbaPLaSdIQtthUiqrDHo4KFzDAmilvHUyV9Wgq49lCt/lpt7Dm3fO9C8l7n5WunXOKi7X2pp/IE1xw==} + dependencies: + '@babel/runtime-corejs3': 7.23.6 + '@redwoodjs/project-config': 6.6.0 + '@redwoodjs/structure': 6.6.0 + '@whatwg-node/fetch': 0.9.14 + ci-info: 4.0.0 + core-js: 3.34.0 + envinfo: 7.11.0 + systeminformation: 5.21.20 + uuid: 9.0.1 + yargs: 17.7.2 + dev: true + + /@repeaterjs/repeater@3.0.5: + resolution: {integrity: sha512-l3YHBLAol6d/IKnB9LhpD0cEZWAoe3eFKUyTYWmFmCO2Q/WOckxLQAUyMZWwZV2M/m3+4vgRoaolFqaII82/TA==} + dev: true + /@rollup/plugin-alias@5.0.1(rollup@3.29.4): resolution: {integrity: sha512-JObvbWdOHoMy9W7SU0lvGhDtWq9PllP5mjpAy+TUslZG/WzOId9u80Hsqq1vCUn9pFJ0cxpdcnAv+QzU2zFH3Q==} engines: {node: '>=14.0.0'} @@ -4038,10 +4549,19 @@ packages: engines: {node: '>=10.13.0'} dev: true + /@ts-morph/common@0.16.0: + resolution: {integrity: sha512-SgJpzkTgZKLKqQniCjLaE3c2L2sdL7UShvmTmPBejAKd2OKV/yfMpQ2IWpAuA+VY5wy7PkSUaEObIqEK6afFuw==} + dependencies: + fast-glob: 3.3.2 + minimatch: 5.1.6 + mkdirp: 1.0.4 + path-browserify: 1.0.1 + dev: true + /@ts-morph/common@0.17.0: resolution: {integrity: sha512-RMSSvSfs9kb0VzkvQ2NWobwnj7TxCA9vI/IjR9bDHqgAyVbu2T0DN4wiKVqomyDWqO7dPr/tErSfq7urQ1Q37g==} dependencies: - fast-glob: 3.3.0 + fast-glob: 3.3.1 minimatch: 5.1.6 mkdirp: 1.0.4 path-browserify: 1.0.1 @@ -4238,6 +4758,10 @@ packages: '@types/node': 18.0.0 dev: true + /@types/line-column@1.0.0: + resolution: {integrity: sha512-wbw+IDRw/xY/RGy+BL6f4Eey4jsUgHQrMuA4Qj0CSG3x/7C2Oc57pmRoM2z3M4DkylWRz+G1pfX06sCXQm0J+w==} + dev: true + /@types/mime@1.3.2: resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} dev: true @@ -4407,6 +4931,12 @@ packages: '@types/yargs-parser': 21.0.0 dev: true + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + /@typescript-eslint/eslint-plugin@6.13.1(@typescript-eslint/parser@6.13.1)(eslint@8.55.0)(typescript@5.3.2): resolution: {integrity: sha512-5bQDGkXaxD46bPvQt08BUz9YSaO4S0fB1LB5JHQuXTfkGPI3+UUeS387C/e9jRie5GqT8u5kFTrMvAjtX4O5kA==} engines: {node: ^16.0.0 || >=18.0.0} @@ -4783,8 +5313,8 @@ packages: '@babel/core': 7.23.2 '@babel/helper-module-imports': 7.22.5 '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.8 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 '@babel/types': 7.23.0 '@vue/babel-helper-vue-transform-on': 1.1.5 camelcase: 6.3.0 @@ -4881,6 +5411,38 @@ packages: resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} dev: true + /@whatwg-node/events@0.1.1: + resolution: {integrity: sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==} + engines: {node: '>=16.0.0'} + dev: true + + /@whatwg-node/fetch@0.9.14: + resolution: {integrity: sha512-wurZC82zzZwXRDSW0OS9l141DynaJQh7Yt0FD1xZ8niX7/Et/7RoiLiltbVU1fSF1RR9z6ndEaTUQBAmddTm1w==} + engines: {node: '>=16.0.0'} + dependencies: + '@whatwg-node/node-fetch': 0.5.2 + urlpattern-polyfill: 9.0.0 + dev: true + + /@whatwg-node/node-fetch@0.5.2: + resolution: {integrity: sha512-uVYCnmWoCiGbv5AtnSx5nZ1kQJ+U8f269/yHB62y7wXPdjYx6o4sBSefnfwUI8HNf4rf16VbvGR/AzuABhDD5g==} + engines: {node: '>=16.0.0'} + dependencies: + '@kamilkisiela/fast-url-parser': 1.1.4 + '@whatwg-node/events': 0.1.1 + busboy: 1.6.0 + fast-querystring: 1.1.2 + tslib: 2.6.0 + dev: true + + /@whatwg-node/server@0.9.19: + resolution: {integrity: sha512-GViwZq7iE1qCV6fSL2JHAHPQb6Jn2Ke34pkC5Wv7nAZi0qIqqPcBrEUG7TbJc79hYjCSrzRTi7FEs2xyWnQn7Q==} + engines: {node: '>=16.0.0'} + dependencies: + '@whatwg-node/fetch': 0.9.14 + tslib: 2.6.0 + dev: true + /abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} dev: true @@ -5015,6 +5577,12 @@ packages: dependencies: type-fest: 0.21.3 + /ansi-escapes@5.0.0: + resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} + engines: {node: '>=12'} + dependencies: + type-fest: 1.4.0 + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -5022,7 +5590,6 @@ packages: /ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} - dev: true /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -5044,7 +5611,6 @@ packages: /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - dev: true /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -5138,7 +5704,6 @@ packages: /arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - dev: false /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -5533,6 +6098,10 @@ packages: /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + /buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + dev: true + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true @@ -5820,6 +6389,11 @@ packages: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} engines: {node: '>=8'} + /ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + dev: true + /citty@0.1.4: resolution: {integrity: sha512-Q3bK1huLxzQrvj7hImJ7Z1vKYJRPQCDnd0EjXfHMidcjecGOMuLrmuQmtWmFkuKLcMThlGh1yCKG8IEc6VeNXQ==} dependencies: @@ -5846,6 +6420,12 @@ packages: restore-cursor: 3.1.0 dev: false + /cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + /cli-spinners@2.9.0: resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==} engines: {node: '>=6'} @@ -5865,7 +6445,6 @@ packages: dependencies: slice-ansi: 5.0.0 string-width: 5.1.2 - dev: true /client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} @@ -5903,7 +6482,6 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - dev: true /clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} @@ -5921,7 +6499,6 @@ packages: /code-block-writer@11.0.3: resolution: {integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==} - dev: false /code-error-fragment@0.0.230: resolution: {integrity: sha512-cadkfKp6932H8UkhzE/gcUqhRMNf8jHzkAN7+5Myabswaghu4xABTgPHDCjW+dBAJxj/SpkTYokpzDqY4pCzQw==} @@ -5970,7 +6547,6 @@ packages: /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - dev: true /colors@1.4.0: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} @@ -6164,6 +6740,16 @@ packages: yargs: 16.2.0 dev: true + /core-js-pure@3.35.0: + resolution: {integrity: sha512-f+eRYmkou59uh7BPcyJ8MC76DiGhspj1KMxVIcF24tzP8NA9HVa1uC7BTW2tgx7E1QVCzDzsgp7kArrzhlz8Ew==} + requiresBuild: true + dev: true + + /core-js@3.34.0: + resolution: {integrity: sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==} + requiresBuild: true + dev: true + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -6227,6 +6813,13 @@ packages: - encoding dev: false + /cross-inspect@1.0.0: + resolution: {integrity: sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==} + engines: {node: '>=16.0.0'} + dependencies: + tslib: 2.6.0 + dev: true + /cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} dependencies: @@ -6460,6 +7053,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /decamelize@2.0.0: + resolution: {integrity: sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==} + engines: {node: '>=4'} + dependencies: + xregexp: 4.0.0 + dev: true + /decimal.js@10.4.2: resolution: {integrity: sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==} @@ -6719,6 +7319,17 @@ packages: type-fest: 3.13.1 dev: true + /dotenv-defaults@5.0.2: + resolution: {integrity: sha512-y5z4NhblzwNk8XBIYVzjLcFkANK0rxbRDO6kGOfH9QrVYIGVEX52IqwSprKVsaLHM9pnNkCSxazZF/JPydDPvA==} + dependencies: + dotenv: 14.3.2 + dev: true + + /dotenv@14.3.2: + resolution: {integrity: sha512-vwEppIphpFdvaMCaHfCEv9IgwcxMljMw2TnAQBB4VWPvzXQLTb82jwmdOKzlEVUL3gNFT4l4TPKO+Bn+sqcrVQ==} + engines: {node: '>=12'} + dev: true + /dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} @@ -6728,12 +7339,22 @@ packages: engines: {node: '>=12'} dev: true + /dset@3.1.3: + resolution: {integrity: sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==} + engines: {node: '>=4'} + dev: true + /duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} dev: true /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + /ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + dependencies: + safe-buffer: 5.2.1 dev: true /ee-first@1.1.1: @@ -6758,7 +7379,6 @@ packages: /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true /emphasize@4.2.0: resolution: {integrity: sha512-yGKvcFUHlBsUPwlxTlzKLR8+zhpbitkFOMCUxN8fTJng9bdH3WNzUGkhdaGdjndSUgqmMPBN7umfwnUdLz5Axg==} @@ -6803,6 +7423,14 @@ packages: ansi-colors: 4.1.3 dev: true + /enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + dev: true + /entities@2.1.0: resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} dev: true @@ -6817,6 +7445,12 @@ packages: engines: {node: '>=6'} dev: false + /envinfo@7.11.0: + resolution: {integrity: sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==} + engines: {node: '>=4'} + hasBin: true + dev: true + /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true @@ -7210,7 +7844,6 @@ packages: /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} - dev: true /escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -7404,6 +8037,9 @@ packages: engines: {node: '>=6'} dev: true + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -7542,8 +8178,8 @@ packages: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} dev: true - /fast-glob@3.3.0: - resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==} + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7551,10 +8187,9 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: false - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7562,6 +8197,7 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 + dev: true /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -7673,6 +8309,14 @@ packages: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} dev: true + /fill-keys@1.0.2: + resolution: {integrity: sha512-tcgI872xXjwFF4xgQmLxi76GnwJG3g/3isB1l4/G5Z4zrbddGpBjqZCO9oEAcB5wX0Hj/5iQB3toxfO7in1hHA==} + engines: {node: '>=0.10.0'} + dependencies: + is-object: 1.0.2 + merge-descriptors: 1.0.1 + dev: true + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -7926,7 +8570,6 @@ packages: /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - dev: true /get-func-name@2.0.0: resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} @@ -8152,6 +8795,81 @@ packages: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true + /graphql-depth-limit@1.1.0(graphql@16.8.1): + resolution: {integrity: sha512-+3B2BaG8qQ8E18kzk9yiSdAa75i/hnnOwgSeAxVJctGQPvmeiLtqKOYF6HETCyRjiF7Xfsyal0HbLlxCQkgkrw==} + engines: {node: '>=6.0.0'} + peerDependencies: + graphql: '*' + dependencies: + arrify: 1.0.1 + graphql: 16.8.1 + dev: true + + /graphql-scalars@1.22.4(graphql@16.8.1): + resolution: {integrity: sha512-ILnv7jq5VKHLUyoaTFX7lgYrjCd6vTee9i8/B+D4zJKJT5TguOl0KkpPEbXHjmeor8AZYrVsrYUHdqRBMX1pjA==} + engines: {node: '>=10'} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + dependencies: + graphql: 16.8.1 + tslib: 2.6.0 + dev: true + + /graphql-tag@2.12.6(graphql@16.8.1): + resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} + engines: {node: '>=10'} + peerDependencies: + graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + dependencies: + graphql: 16.8.1 + tslib: 2.6.0 + dev: true + + /graphql-yoga@4.0.4(graphql@16.8.1): + resolution: {integrity: sha512-MvCLhFecYNIKuxAZisPjpIL9lxRYbpgPSNKENDO/8CV3oiFlsLJHZb5dp2sVAeLafXHeZ9TgkijLthUBc1+Jag==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^15.2.0 || ^16.0.0 + dependencies: + '@envelop/core': 4.0.3 + '@graphql-tools/executor': 1.2.0(graphql@16.8.1) + '@graphql-tools/schema': 10.0.2(graphql@16.8.1) + '@graphql-tools/utils': 10.0.11(graphql@16.8.1) + '@graphql-yoga/logger': 1.0.0 + '@graphql-yoga/subscription': 4.0.0 + '@whatwg-node/fetch': 0.9.14 + '@whatwg-node/server': 0.9.19 + dset: 3.1.3 + graphql: 16.8.1 + lru-cache: 10.0.1 + tslib: 2.6.0 + dev: true + + /graphql-yoga@5.0.2(graphql@16.8.1): + resolution: {integrity: sha512-+r0aZ5sBQaWTFEwmDdPR+XcsYaIIh40IA34F7rhnyY57KXgs18ZkCZ9NPvfi6XEuqkHEvc2PFox05c5NRSJ26g==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^15.2.0 || ^16.0.0 + dependencies: + '@envelop/core': 5.0.0 + '@graphql-tools/executor': 1.2.0(graphql@16.8.1) + '@graphql-tools/schema': 10.0.2(graphql@16.8.1) + '@graphql-tools/utils': 10.0.11(graphql@16.8.1) + '@graphql-yoga/logger': 2.0.0 + '@graphql-yoga/subscription': 5.0.0 + '@whatwg-node/fetch': 0.9.14 + '@whatwg-node/server': 0.9.19 + dset: 3.1.3 + graphql: 16.8.1 + lru-cache: 10.0.1 + tslib: 2.6.0 + dev: true + + /graphql@16.8.1: + resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + dev: true + /gzip-size@7.0.0: resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -8382,6 +9100,13 @@ packages: engines: {node: '>=16.17.0'} dev: true + /humanize-string@2.1.0: + resolution: {integrity: sha512-sQ+hqmxyXW8Cj7iqxcQxD7oSy3+AXnIZXdUF9lQMkzaG8dtbKAB8U7lCtViMnwQ+MpdCKsO2Kiij3G6UUXq/Xg==} + engines: {node: '>=6'} + dependencies: + decamelize: 2.0.0 + dev: true + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -8588,7 +9313,6 @@ packages: /is-fullwidth-code-point@4.0.0: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} - dev: true /is-generator-fn@2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} @@ -8630,6 +9354,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + /is-object@1.0.2: + resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} + dev: true + /is-path-cwd@2.2.0: resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} engines: {node: '>=6'} @@ -8795,6 +9523,13 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + /isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + dependencies: + isarray: 1.0.0 + dev: true + /isomorphic-fetch@3.0.0: resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} dependencies: @@ -9480,6 +10215,37 @@ packages: resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==} dev: true + /jsonwebtoken@9.0.2: + resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} + engines: {node: '>=12', npm: '>=6'} + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.5.4 + dev: true + + /jwa@1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: true + + /jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + dev: true + /keytar@7.9.0: resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==} requiresBuild: true @@ -9534,6 +10300,10 @@ packages: vscode-languageserver-textdocument: 1.0.8 vscode-uri: 3.0.7 + /lazy-get-decorator@2.2.1: + resolution: {integrity: sha512-Z5uxqhXT+h3s1az3JaEAi9eh8+p4pIUE3qJGgfkx9zIEiA3bIpg4ChxODLwCpFr9S+PDEJ/2Q1UaMqy8RdVCxg==} + dev: true + /lazystream@1.0.1: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} engines: {node: '>= 0.6.3'} @@ -9566,6 +10336,13 @@ packages: engines: {node: '>=10'} dev: true + /line-column@1.0.2: + resolution: {integrity: sha512-Ktrjk5noGYlHsVnYWh62FLVs4hTb8A3e+vucNZMgPeAOITdshMSgv4cCZQeRDjm7+goqmo6+liZwTXo+U3sVww==} + dependencies: + isarray: 1.0.0 + isobject: 2.1.0 + dev: true + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -9598,6 +10375,22 @@ packages: uqr: 0.1.2 dev: true + /listr2@6.6.1: + resolution: {integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==} + engines: {node: '>=16.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + dependencies: + cli-truncate: 3.1.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 5.0.1 + rfdc: 1.3.0 + wrap-ansi: 8.1.0 + /load-module@4.2.1: resolution: {integrity: sha512-Sbfg6R4LjvyThJpqUoADHMjyoI2+cL4msbCQeZ9kkY/CqP/TT2938eftKm7x4I2gd4/A+DEe6nePkbfWYbXwSw==} engines: {node: '>=12.17'} @@ -9641,6 +10434,16 @@ packages: dependencies: p-locate: 5.0.0 + /lodash-decorators@6.0.1(lodash@4.17.21): + resolution: {integrity: sha512-1M0YC8G3nFTkejZEk2ehyvryEdcqj6xATH+ybI8j53cLs/bKRsavaE//y7nz/A0vxEFhxYqev7vdWfsuTJ1AtQ==} + engines: {node: '>=0.12.0'} + peerDependencies: + lodash: 4.x + dependencies: + lodash: 4.17.21 + tslib: 1.14.1 + dev: true + /lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: true @@ -9660,13 +10463,32 @@ packages: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: false + /lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + dev: true + /lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} dev: true + /lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + dev: true + + /lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + dev: true + + /lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + dev: true + /lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - dev: false + + /lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + dev: true /lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} @@ -9676,6 +10498,10 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + dev: true + /lodash.pick@4.4.0: resolution: {integrity: sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==} dev: true @@ -9707,6 +10533,16 @@ packages: is-unicode-supported: 0.1.0 dev: false + /log-update@5.0.1: + resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + ansi-escapes: 5.0.0 + cli-cursor: 4.0.0 + slice-ansi: 5.0.0 + strip-ansi: 7.1.0 + wrap-ansi: 8.1.0 + /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -9763,6 +10599,11 @@ packages: dependencies: yallist: 4.0.0 + /lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + dev: true + /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -10043,6 +10884,10 @@ packages: ufo: 1.3.1 dev: true + /module-not-found-error@1.0.1: + resolution: {integrity: sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g==} + dev: true + /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -10924,9 +11769,13 @@ packages: tslib: 2.6.0 dev: false + /pascalcase@1.0.0: + resolution: {integrity: sha512-BSExi0rRnCHReJys6NocaK+cfTXNinAegfWBvr0JD3hiaEG7Nuc7r0CIdOJunXrs8gU/sbHQ9dxVAtiVQisjmg==} + engines: {node: '>=8'} + dev: true + /path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - dev: false /path-case@3.0.4: resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} @@ -11092,6 +11941,13 @@ packages: split2: 4.2.0 dev: true + /pino-abstract-transport@1.1.0: + resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==} + dependencies: + readable-stream: 4.4.0 + split2: 4.2.0 + dev: true + /pino-std-serializers@6.2.2: resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} dev: true @@ -11113,6 +11969,23 @@ packages: thread-stream: 2.3.0 dev: true + /pino@8.16.2: + resolution: {integrity: sha512-2advCDGVEvkKu9TTVSa/kWW7Z3htI/sBKEZpqiHk6ive0i/7f5b1rsU8jn0aimxqfnSz5bj/nOYkwhBUn5xxvg==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.2.0 + on-exit-leak-free: 2.1.0 + pino-abstract-transport: 1.1.0 + pino-std-serializers: 6.2.2 + process-warning: 2.2.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 3.7.0 + thread-stream: 2.3.0 + dev: true + /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -11717,6 +12590,14 @@ packages: ipaddr.js: 1.9.1 dev: true + /proxyquire@2.1.3: + resolution: {integrity: sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==} + dependencies: + fill-keys: 1.0.2 + module-not-found-error: 1.0.1 + resolve: 1.22.2 + dev: true + /prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} dev: true @@ -12015,6 +12896,10 @@ packages: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} dev: true + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: true + /regexp-to-ast@0.5.0: resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} @@ -12082,7 +12967,6 @@ packages: /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - dev: true /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} @@ -12135,6 +13019,13 @@ packages: signal-exit: 3.0.7 dev: false + /restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + /ret@0.2.2: resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} engines: {node: '>=4'} @@ -12151,7 +13042,6 @@ packages: /rfdc@1.3.0: resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - dev: true /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} @@ -12482,7 +13372,6 @@ packages: dependencies: ansi-styles: 6.2.1 is-fullwidth-code-point: 4.0.0 - dev: true /smartwrap@2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} @@ -12514,6 +13403,12 @@ packages: atomic-sleep: 1.0.0 dev: true + /sonic-boom@3.7.0: + resolution: {integrity: sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==} + dependencies: + atomic-sleep: 1.0.0 + dev: true + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -12649,6 +13544,10 @@ packages: queue-tick: 1.0.1 dev: true + /string-env-interpolation@1.0.1: + resolution: {integrity: sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==} + dev: true + /string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -12672,7 +13571,6 @@ packages: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 - dev: true /string.prototype.trim@1.2.7: resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} @@ -12724,7 +13622,6 @@ packages: engines: {node: '>=12'} dependencies: ansi-regex: 6.0.1 - dev: true /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} @@ -12902,7 +13799,6 @@ packages: dependencies: has-flag: 4.0.0 supports-color: 7.2.0 - dev: false /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} @@ -12977,6 +13873,13 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true + /systeminformation@5.21.20: + resolution: {integrity: sha512-AyS1fNc+MDoAJtFknFbbo587H8h6yejJwM+H9rVusnOToIEkiMehMyD5JM7o3j55Cto20MawIZrcgNMgd4BfOQ==} + engines: {node: '>=8.0.0'} + os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] + hasBin: true + dev: true + /table-layout@1.0.2: resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} engines: {node: '>=8.0.0'} @@ -13082,7 +13985,6 @@ packages: dependencies: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 - dev: false /terser@5.21.0: resolution: {integrity: sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==} @@ -13155,6 +14057,12 @@ packages: engines: {node: '>=14.0.0'} dev: true + /title-case@3.0.3: + resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} + dependencies: + tslib: 2.6.0 + dev: true + /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -13282,6 +14190,13 @@ packages: yargs-parser: 21.1.1 dev: true + /ts-morph@15.1.0: + resolution: {integrity: sha512-RBsGE2sDzUXFTnv8Ba22QfeuKbgvAGJFuTN7HfmIRUkgT/NaVLfDM/8OFm2NlFkGlWEXdpW5OaFIp1jvqdDuOg==} + dependencies: + '@ts-morph/common': 0.16.0 + code-block-writer: 11.0.3 + dev: true + /ts-morph@16.0.0: resolution: {integrity: sha512-jGNF0GVpFj0orFw55LTsQxVYEUOCWBAbR5Ls7fTYE5pQsbW18ssTb/6UXx/GYAEjS+DQTp8VoTw0vqYMiaaQuw==} dependencies: @@ -13458,6 +14373,10 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} + /type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + /type-fest@3.13.1: resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} engines: {node: '>=14.16'} @@ -13809,6 +14728,10 @@ packages: resolution: {integrity: sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==} dev: true + /urlpattern-polyfill@9.0.0: + resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==} + dev: true + /use-sync-external-store@1.2.0(react@18.2.0): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -13835,6 +14758,11 @@ packages: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} hasBin: true + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: true + /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true @@ -13854,6 +14782,11 @@ packages: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + /value-or-promise@1.0.12: + resolution: {integrity: sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==} + engines: {node: '>=12'} + dev: true + /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -14150,6 +15083,17 @@ packages: /vscode-languageserver-types@3.17.2: resolution: {integrity: sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==} + /vscode-languageserver-types@3.17.3: + resolution: {integrity: sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==} + dev: true + + /vscode-languageserver@6.1.1: + resolution: {integrity: sha512-DueEpkUAkD5XTR4MLYNr6bQIp/UFR0/IPApgXU3YfCBCB08u2sm9hRCs6DxYZELkk++STPjpcjksR2H8qI3cDQ==} + hasBin: true + dependencies: + vscode-languageserver-protocol: 3.17.2 + dev: true + /vscode-languageserver@7.0.0: resolution: {integrity: sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==} hasBin: true @@ -14399,7 +15343,14 @@ packages: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: true + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -14447,6 +15398,10 @@ packages: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} dev: true + /xregexp@4.0.0: + resolution: {integrity: sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==} + dev: true + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -14464,7 +15419,6 @@ packages: /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - dev: true /yallist@2.1.2: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} @@ -14508,7 +15462,6 @@ packages: /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - dev: true /yargs@15.4.1: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} @@ -14551,7 +15504,6 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: true /yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 198ac1918..531fc9ea4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,6 @@ packages: - 'packages/*' - 'packages/plugins/*' + - 'packages/misc/*' - 'packages/ide/*' - 'tests/*' From 3afe42f9b0b1fda4dfbe18d359824d0f4829fc3b Mon Sep 17 00:00:00 2001 From: Jiasheng Date: Mon, 1 Jan 2024 02:22:33 +0000 Subject: [PATCH 06/11] fix: VsCode error textDocument/codeAction failed (#915) --- .../src/language-server/zmodel-code-action.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/schema/src/language-server/zmodel-code-action.ts b/packages/schema/src/language-server/zmodel-code-action.ts index e9e7862ec..aace4d0fe 100644 --- a/packages/schema/src/language-server/zmodel-code-action.ts +++ b/packages/schema/src/language-server/zmodel-code-action.ts @@ -75,8 +75,6 @@ export class ZModelCodeActionProvider implements CodeActionProvider { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const oppositeModel = fieldAstNode.type.reference!.ref! as DataModel; - const lastField = oppositeModel.fields[oppositeModel.fields.length - 1]; - const currentModel = document.parseResult.value as Model; const container = currentModel.declarations.find( @@ -121,17 +119,22 @@ export class ZModelCodeActionProvider implements CodeActionProvider { '\n' + indent + `${fieldName} ${typeName} @relation(fields: [${referenceIdFieldName}], references: [${idFieldName}])` + - referenceField; + referenceField + + '\n'; } else { // user User @relation(fields: [userAbc], references: [id]) const typeName = container.name; const fieldName = this.lowerCaseFirstLetter(typeName); - newText = '\n' + indent + `${fieldName} ${typeName}[]`; + newText = '\n' + indent + `${fieldName} ${typeName}[]` + '\n'; } // the opposite model might be in the imported file const targetDocument = getDocument(oppositeModel); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const endOffset = oppositeModel.$cstNode!.end - 1; + const position = document.textDocument.positionAt(endOffset); + return { title: `Add opposite relation fields on ${oppositeModel.name}`, kind: CodeActionKind.QuickFix, @@ -142,10 +145,8 @@ export class ZModelCodeActionProvider implements CodeActionProvider { [targetDocument.textDocument.uri]: [ { range: { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - start: lastField.$cstNode!.range.end, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - end: lastField.$cstNode!.range.end, + start: position, + end: position, }, newText, }, From b71c1c53983f77bcfe8f40a1f931547499c9d4ff Mon Sep 17 00:00:00 2001 From: Jiasheng Date: Mon, 1 Jan 2024 02:30:52 +0000 Subject: [PATCH 07/11] fix: Show the correct incomplete error for multiple level inheritance (#916) --- .../validator/datamodel-validator.ts | 23 ++++++------------ .../validation/datamodel-validation.test.ts | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/packages/schema/src/language-server/validator/datamodel-validator.ts b/packages/schema/src/language-server/validator/datamodel-validator.ts index 8d7bb7740..ce1886f5e 100644 --- a/packages/schema/src/language-server/validator/datamodel-validator.ts +++ b/packages/schema/src/language-server/validator/datamodel-validator.ts @@ -235,22 +235,13 @@ export default class DataModelValidator implements AstValidator { const node = field.$isInherited ? field.$container : field; const info: DiagnosticInfo = { node, code: IssueCodes.MissingOppositeRelation }; - let relationFieldDocUri: string; - let relationDataModelName: string; - - if (field.$isInherited) { - info.property = 'name'; - const container = field.$container as DataModel; - const abstractContainer = container.superTypes.find((x) => - x.ref?.fields.find((f) => f.name === field.name) - )?.ref as DataModel; - - relationFieldDocUri = getDocument(abstractContainer).textDocument.uri; - relationDataModelName = abstractContainer.name; - } else { - relationFieldDocUri = getDocument(field).textDocument.uri; - relationDataModelName = field.$container.name; - } + info.property = 'name'; + // use cstNode because the field might be inherited from parent model + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const container = field.$cstNode!.element.$container as DataModel; + + const relationFieldDocUri = getDocument(container).textDocument.uri; + const relationDataModelName = container.name; const data: MissingOppositeRelationData = { relationFieldName: field.name, diff --git a/packages/schema/tests/schema/validation/datamodel-validation.test.ts b/packages/schema/tests/schema/validation/datamodel-validation.test.ts index a2d68f2c0..e1f06d268 100644 --- a/packages/schema/tests/schema/validation/datamodel-validation.test.ts +++ b/packages/schema/tests/schema/validation/datamodel-validation.test.ts @@ -633,5 +633,29 @@ describe('Data Model Validation Tests', () => { expect(errors.length).toBe(1); expect(errors[0]).toEqual(`Model A cannot be extended because it's not abstract`); + + // relation incomplete from multiple level inheritance + expect( + await loadModelWithError(` + ${prelude} + model User { + id Int @id @default(autoincrement()) + } + + abstract model Base { + id Int @id @default(autoincrement()) + user User @relation(fields: [userId], references: [id]) + userId Int + } + + abstract model Base1 extends Base { + isPublic Boolean @default(false) + } + + model A extends Base1 { + a String + } + `) + ).toContain(`The relation field "user" on model "A" is missing an opposite relation field on model "User"`); }); }); From 0f73e569b496da1dbedff61e1846af3b2bdc2b03 Mon Sep 17 00:00:00 2001 From: Yiming Date: Mon, 1 Jan 2024 10:32:38 +0800 Subject: [PATCH 08/11] fix: support default values in generated zod schemas (#914) --- packages/schema/src/plugins/zod/generator.ts | 19 +++++-- .../src/plugins/zod/utils/schema-gen.ts | 52 +++++++++++++++++-- .../tests/regression/issue-864.test.ts | 2 +- .../tests/regression/issue-886.test.ts | 22 ++++++++ 4 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 tests/integration/tests/regression/issue-886.test.ts diff --git a/packages/schema/src/plugins/zod/generator.ts b/packages/schema/src/plugins/zod/generator.ts index ad857fbda..2727a781f 100644 --- a/packages/schema/src/plugins/zod/generator.ts +++ b/packages/schema/src/plugins/zod/generator.ts @@ -26,7 +26,7 @@ import { name } from '.'; import { getDefaultOutputFolder } from '../plugin-utils'; import Transformer from './transformer'; import removeDir from './utils/removeDir'; -import { makeFieldSchema, makeValidationRefinements } from './utils/schema-gen'; +import { makeFieldSchema, makeValidationRefinements, getFieldSchemaDefault } from './utils/schema-gen'; export async function generate( model: Model, @@ -309,7 +309,7 @@ async function generateModelSchema(model: DataModel, project: Project, output: s writer.write(`const baseSchema = z.object(`); writer.inlineBlock(() => { scalarFields.forEach((field) => { - writer.writeLine(`${field.name}: ${makeFieldSchema(field)},`); + writer.writeLine(`${field.name}: ${makeFieldSchema(field, true)},`); }); }); writer.writeLine(');'); @@ -356,7 +356,12 @@ async function generateModelSchema(model: DataModel, project: Project, output: s //////////////////////////////////////////////// // 1. Model schema //////////////////////////////////////////////// - let modelSchema = makePartial('baseSchema'); + const fieldsWithoutDefault = scalarFields.filter((f) => !getFieldSchemaDefault(f)); + // mark fields without default value as optional + let modelSchema = makePartial( + 'baseSchema', + fieldsWithoutDefault.length < scalarFields.length ? fieldsWithoutDefault.map((f) => f.name) : undefined + ); // omit fields const fieldsToOmit = scalarFields.filter((field) => hasAttribute(field, '@omit')); @@ -475,9 +480,13 @@ async function generateModelSchema(model: DataModel, project: Project, output: s function makePartial(schema: string, fields?: string[]) { if (fields) { - return `${schema}.partial({ - ${fields.map((f) => `${f}: true`).join(', ')}, + if (fields.length === 0) { + return schema; + } else { + return `${schema}.partial({ + ${fields.map((f) => `${f}: true`).join(', ')} })`; + } } else { return `${schema}.partial()`; } diff --git a/packages/schema/src/plugins/zod/utils/schema-gen.ts b/packages/schema/src/plugins/zod/utils/schema-gen.ts index f84b25a2d..802127c58 100644 --- a/packages/schema/src/plugins/zod/utils/schema-gen.ts +++ b/packages/schema/src/plugins/zod/utils/schema-gen.ts @@ -1,5 +1,21 @@ -import { ExpressionContext, PluginError, getAttributeArg, getAttributeArgLiteral, getLiteral } from '@zenstackhq/sdk'; -import { DataModel, DataModelField, DataModelFieldAttribute, isDataModel, isEnum } from '@zenstackhq/sdk/ast'; +import { + ExpressionContext, + PluginError, + getAttributeArg, + getAttributeArgLiteral, + getLiteral, + isFromStdlib, +} from '@zenstackhq/sdk'; +import { + DataModel, + DataModelField, + DataModelFieldAttribute, + isDataModel, + isEnum, + isInvocationExpr, + isNumberLiteral, + isStringLiteral, +} from '@zenstackhq/sdk/ast'; import { upperCaseFirst } from 'upper-case-first'; import { name } from '..'; import { @@ -7,7 +23,7 @@ import { TypeScriptExpressionTransformerError, } from '../../../utils/typescript-expression-transformer'; -export function makeFieldSchema(field: DataModelField) { +export function makeFieldSchema(field: DataModelField, respectDefault = false) { if (isDataModel(field.type.reference?.ref)) { if (field.type.array) { // array field is always optional @@ -108,6 +124,13 @@ export function makeFieldSchema(field: DataModelField) { } } + if (respectDefault) { + const schemaDefault = getFieldSchemaDefault(field); + if (schemaDefault) { + schema += `.default(${schemaDefault})`; + } + } + if (field.type.optional) { schema += '.nullish()'; } @@ -202,3 +225,26 @@ function refineDecimal(op: 'gt' | 'gte' | 'lt' | 'lte', value: number, messageAr } }${messageArg})`; } + +export function getFieldSchemaDefault(field: DataModelField) { + const attr = field.attributes.find((attr) => attr.decl.ref?.name === '@default'); + if (!attr) { + return undefined; + } + const arg = attr.args.find((arg) => arg.$resolvedParam?.name === 'value'); + if (arg) { + if (isStringLiteral(arg.value)) { + return JSON.stringify(arg.value.value); + } else if (isNumberLiteral(arg.value)) { + return arg.value.value; + } else if ( + isInvocationExpr(arg.value) && + isFromStdlib(arg.value.function.ref!) && + arg.value.function.$refText === 'now' + ) { + return `() => new Date()`; + } + } + + return undefined; +} diff --git a/tests/integration/tests/regression/issue-864.test.ts b/tests/integration/tests/regression/issue-864.test.ts index 02aab81d1..eb50bc95f 100644 --- a/tests/integration/tests/regression/issue-864.test.ts +++ b/tests/integration/tests/regression/issue-864.test.ts @@ -1,6 +1,6 @@ import { loadSchema } from '@zenstackhq/testtools'; -describe('Regression: issue nested create', () => { +describe('Regression: issue 864', () => { it('safe create', async () => { const { prisma, enhance } = await loadSchema( ` diff --git a/tests/integration/tests/regression/issue-886.test.ts b/tests/integration/tests/regression/issue-886.test.ts new file mode 100644 index 000000000..a749db61e --- /dev/null +++ b/tests/integration/tests/regression/issue-886.test.ts @@ -0,0 +1,22 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('Regression: issue 886', () => { + it('regression', async () => { + const { zodSchemas } = await loadSchema( + ` + model Model { + id Int @id @default(autoincrement()) + a Int @default(100) + b String @default('') + c DateTime @default(now()) + } + ` + ); + + const r = zodSchemas.models.ModelSchema.parse({}); + expect(r.a).toBe(100); + expect(r.b).toBe(''); + expect(r.c).toBeInstanceOf(Date); + expect(r.id).toBeUndefined(); + }); +}); From 4ef3634dad3d110ddea9019c1b70fd83d0ab95e0 Mon Sep 17 00:00:00 2001 From: Yiming Date: Mon, 1 Jan 2024 18:26:04 +0800 Subject: [PATCH 09/11] chore: misc fixes around Redwood (#917) --- packages/misc/LICENSE | 21 --- packages/misc/redwood/README.md | 62 +++++--- packages/misc/redwood/bin/cli | 3 + packages/misc/redwood/package.json | 10 +- packages/misc/redwood/src/cli-passthrough.ts | 4 +- packages/misc/redwood/src/commands/setup.ts | 69 ++++++--- packages/misc/redwood/src/setup-package.ts | 11 ++ pnpm-lock.yaml | 150 +++++++------------ 8 files changed, 164 insertions(+), 166 deletions(-) delete mode 100644 packages/misc/LICENSE create mode 100755 packages/misc/redwood/bin/cli create mode 100644 packages/misc/redwood/src/setup-package.ts diff --git a/packages/misc/LICENSE b/packages/misc/LICENSE deleted file mode 100644 index 91d4584d3..000000000 --- a/packages/misc/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 ZenStack - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/misc/redwood/README.md b/packages/misc/redwood/README.md index 55daa78fa..7c4742dc4 100644 --- a/packages/misc/redwood/README.md +++ b/packages/misc/redwood/README.md @@ -9,44 +9,50 @@ ZenStack is a full-stack toolkit built above Prisma ORM. It extends Prisma at th - Multi-file schemas - Custom attributes and functions in schemas -Visit [homepage](https://zenstack.dev) for more details. +You can find a more detailed integration guide [here](https://zenstack.dev/docs/guides/redwood). -## Setting up +### Setting up -This package leverages RedwoodJS's experimental feature to register a custom CLI command to `yarn redwood`. To enable it, add the following to `redwood.toml`: +Run the following package setup command: -```toml -[experimental.cli] - autoInstall = true - [[experimental.cli.plugins]] - package = "@zenstackhq/redwood" +```bash +yarn rw setup package @zenstackhq/redwood ``` -Then you can run `yarn rw @zenstackhq setup` to install ZenStack into your Redwood project. The setup command will: +The setup command will: +1. Update "redwood.toml" to allow ZenStack CLI plugin. 1. Install ZenStack dependencies. -2. Copy your Prisma schema file "api/db/schema.prisma" to "api/db/schema.zmodel". -3. Add a "zenstack" section into "api/package.json" to specify the location of both the "schema.prisma" and "schema.zmodel" files. -4. Install a GraphQLYoga plugin in "api/src/functions/graphql.[ts|js]". -5. Eject service templates and modify the templates to use `context.db` (ZenStack-enhanced `PrismaClient`) instead of `db` for data access. +1. Copy your Prisma schema file "api/db/schema.prisma" to "api/db/schema.zmodel". +1. Add a "zenstack" section into "api/package.json" to specify the location 1f both the "schema.prisma" and "schema.zmodel" files. +1. Install a GraphQLYoga plugin in "api/src/functions/graphql.[ts|js]". +1. Eject service templates and modify the templates to use `context.db` (ZenStack-enhanced `PrismaClient`) instead of `db` for data access. + +### Modeling data and access policies -## Modeling data and access policies +ZenStack's ZModel language is a superset of Prisma schema language. You should use it to define both the data schema and access policies. [The Complete Guide](https://zenstack.dev/docs/the-complete-guide/part1/) of ZenStack is the best way to learn how to author ZModel schemas. -ZenStack's ZModel language is a superset of Prisma schema language. You should use it to define both the data schema and access policies. The regular Prisma schema file will be regenerated from the ZModel file when you run +You should run the following command after updating "schema.zmodel": ```bash yarn rw @zenstackhq generate ``` -[The Complete Guide](https://zenstack.dev/docs/the-complete-guide/part1/) of ZenStack is the best way to learn how to author ZModel schemas. You can also use the +The command does the following things: + +1. Regenerate "schema.prisma" +2. Run `prisma generate` to regenerate PrismaClient +3. Generates supporting JS modules for enforcing access policies at runtime + + -## Development workflow +### Development workflow The workflow of using ZenStack is very similar to using Prisma in RedwoodJS projects. The two main differences are: @@ -62,7 +68,7 @@ The workflow of using ZenStack is very similar to using Prisma in RedwoodJS proj Other Prisma-related workflows like generation migration or pushing schema to the database stay unchanged. -## Deployment +### Deployment You should run the "generate" command in your deployment script before `yarn rw deploy`. For example, to deploy to Vercel, the command can be: @@ -70,10 +76,22 @@ You should run the "generate" command in your deployment script before `yarn rw yarn rw @zenstackhq generate && yarn rw deploy vercel ``` -## Sample application +### Using the `@zenstackhq` CLI plugin + +The `@zenstackhq/redwood` package registers a set of custom commands to the RedwoodJS CLI under the `@zenstackhq` namespace. You can run it with: + +```bash +yarn rw @zenstackhq [options] +``` + +The plugin is a simple wrapper of the standard `zenstack` CLI, similar to how RedwoodJS wraps the standard `prisma` CLI. It's equivalent to running `npx zenstack ...` inside the "api" directory. + +See the [CLI references](https://zenstack.dev/docs/reference/cli) for the full list of commands. + +### Sample application You can find a complete multi-tenant Todo application built with RedwoodJS and ZenStack at: [https://github.com/zenstackhq/sample-todo-redwood](https://github.com/zenstackhq/sample-todo-redwood). -## Getting help +### Getting help -The best way to getting help and updates about ZenStack is by joining our [Discord server](https://discord.gg/Ykhr738dUe). +The best way to get help and updates about ZenStack is by joining our [Discord server](https://discord.gg/Ykhr738dUe). diff --git a/packages/misc/redwood/bin/cli b/packages/misc/redwood/bin/cli new file mode 100755 index 000000000..ef22870e9 --- /dev/null +++ b/packages/misc/redwood/bin/cli @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../dist/setup-package').default(); diff --git a/packages/misc/redwood/package.json b/packages/misc/redwood/package.json index d60812d62..fd4d3c63a 100644 --- a/packages/misc/redwood/package.json +++ b/packages/misc/redwood/package.json @@ -29,6 +29,10 @@ "default": "./package.json" } }, + "bin": "bin/cli", + "engines": { + "redwoodjs": ">=6.0.0" + }, "author": { "name": "ZenStack Team" }, @@ -37,9 +41,8 @@ "dependencies": { "@zenstackhq/runtime": "workspace:*", "colors": "1.4.0", - "ts-morph": "^16.0.0" - }, - "peerDependencies": { + "ts-morph": "^16.0.0", + "@redwoodjs/cli-helpers": "^6.6.0", "execa": "^5.0.0", "listr2": "^6.0.0", "terminal-link": "^2.0.0", @@ -47,7 +50,6 @@ }, "devDependencies": { "@redwoodjs/graphql-server": "^6.6.0", - "@redwoodjs/cli-helpers": "^6.6.0", "@types/yargs": "^17.0.32", "graphql-yoga": "^5.0.2" } diff --git a/packages/misc/redwood/src/cli-passthrough.ts b/packages/misc/redwood/src/cli-passthrough.ts index 4e327b5b6..367b5f06f 100644 --- a/packages/misc/redwood/src/cli-passthrough.ts +++ b/packages/misc/redwood/src/cli-passthrough.ts @@ -40,9 +40,7 @@ export function makePassthroughCommand(command: string): CommandModule .strictOptions(false) .strictCommands(false) .strict(false) - .parserConfiguration({ 'camel-case-expansion': false, 'boolean-negation': false }) - .help(false) - .version(false); + .parserConfiguration({ 'camel-case-expansion': false, 'boolean-negation': false }); }, handler: async ({ _, $0: _$0, ...options }) => { await runCommand(command, options); diff --git a/packages/misc/redwood/src/commands/setup.ts b/packages/misc/redwood/src/commands/setup.ts index e0ddfb81b..b8f9f16f0 100644 --- a/packages/misc/redwood/src/commands/setup.ts +++ b/packages/misc/redwood/src/commands/setup.ts @@ -1,4 +1,4 @@ -import { getPaths } from '@redwoodjs/cli-helpers'; +import { getPaths, updateTomlConfig } from '@redwoodjs/cli-helpers'; import colors from 'colors'; import execa from 'execa'; import fs from 'fs'; @@ -9,6 +9,15 @@ import { Project, SyntaxKind, type PropertyAssignment } from 'ts-morph'; import type { CommandModule } from 'yargs'; import { addApiPackages } from '../utils'; +function updateToml() { + return { + title: 'Updating redwood.toml...', + task: () => { + updateTomlConfig('@zenstackhq/redwood'); + }, + }; +} + function installDependencies() { return addApiPackages([ { pkg: 'zenstack', dev: true }, @@ -54,15 +63,15 @@ function installGraphQLPlugin() { title: 'Installing GraphQL plugin...', task: async () => { // locate "api/functions/graphql.[js|ts]" - let sourcePath: string | undefined; + let graphQlSourcePath: string | undefined; const functionsDir = getPaths().api.functions; if (fs.existsSync(path.join(functionsDir, 'graphql.ts'))) { - sourcePath = path.join(functionsDir, 'graphql.ts'); + graphQlSourcePath = path.join(functionsDir, 'graphql.ts'); } else if (fs.existsSync(path.join(functionsDir, 'graphql.js'))) { - sourcePath = path.join(functionsDir, 'graphql.js'); + graphQlSourcePath = path.join(functionsDir, 'graphql.js'); } - if (!sourcePath) { + if (!graphQlSourcePath) { console.warn( colors.yellow(`Unable to find handler source file: ${path.join(functionsDir, 'graphql.(js|ts)')}`) ); @@ -71,21 +80,21 @@ function installGraphQLPlugin() { // add import const project = new Project(); - const sf = project.addSourceFileAtPathIfExists(sourcePath)!; - let changed = false; + const graphQlSourceFile = project.addSourceFileAtPathIfExists(graphQlSourcePath)!; + let graphQlSourceFileChanged = false; let identified = false; - const imports = sf.getImportDeclarations(); + const imports = graphQlSourceFile.getImportDeclarations(); if (!imports.some((i) => i.getModuleSpecifierValue() === '@zenstackhq/redwood')) { - sf.addImportDeclaration({ + graphQlSourceFile.addImportDeclaration({ moduleSpecifier: '@zenstackhq/redwood', namedImports: ['useZenStack'], }); - changed = true; + graphQlSourceFileChanged = true; } // add "extraPlugins" option to `createGraphQLHandler` call - sf.getDescendantsOfKind(SyntaxKind.CallExpression).forEach((expr) => { + graphQlSourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).forEach((expr) => { if (identified) { return; } @@ -104,7 +113,7 @@ function installGraphQLPlugin() { if (pluginArr) { if (!pluginArr.getElements().some((e) => e.getText().includes('useZenStack'))) { pluginArr.addElement('useZenStack(db)'); - changed = true; + graphQlSourceFileChanged = true; } } } else { @@ -112,7 +121,7 @@ function installGraphQLPlugin() { name: 'extraPlugins', initializer: '[useZenStack(db)]', }); - changed = true; + graphQlSourceFileChanged = true; } } } @@ -126,8 +135,32 @@ function installGraphQLPlugin() { ); } - if (changed) { - sf.formatText(); + if (graphQlSourceFileChanged) { + graphQlSourceFile.formatText(); + } + + // create type-def file to add `db` into global context + let contextTypeDefCreated = false; + if (graphQlSourcePath.endsWith('.ts')) { + const typeDefPath = path.join(getPaths().api.src, 'zenstack.d.ts'); + if (!fs.existsSync(typeDefPath)) { + const typeDefSourceFile = project.createSourceFile( + typeDefPath, + `import type { PrismaClient } from '@prisma/client' + +declare module '@redwoodjs/graphql-server' { + interface GlobalContext { + db: PrismaClient + } +} +` + ); + typeDefSourceFile.formatText(); + contextTypeDefCreated = true; + } + } + + if (graphQlSourceFileChanged || contextTypeDefCreated) { await project.save(); } }, @@ -185,8 +218,8 @@ function whatsNext() { task: (_ctx, task) => { task.title = `What's next...\n\n` + - ` - Install ${terminalLink('ZenStack IDE extensions', 'https://zenstack.dev/docs/guides/ide')}.\n` + - ` - Use "${zmodel}" to model your database schema and access control.\n` + + ` - Install ${terminalLink('IDE extensions', 'https://zenstack.dev/docs/guides/ide')}.\n` + + ` - Use "${zmodel}" to model database schema and access control.\n` + ` - Run \`yarn rw @zenstackhq generate\` to regenerate Prisma schema and client.\n` + ` - Learn ${terminalLink( "how ZenStack extends Prisma's power", @@ -205,8 +238,10 @@ function whatsNext() { const setupCommand: CommandModule = { command: 'setup', describe: 'Set up ZenStack environment', + builder: (yargs) => yargs, handler: async () => { const tasks = new Listr([ + updateToml(), installDependencies(), bootstrapSchema(), installGraphQLPlugin(), diff --git a/packages/misc/redwood/src/setup-package.ts b/packages/misc/redwood/src/setup-package.ts new file mode 100644 index 000000000..8d916ac3a --- /dev/null +++ b/packages/misc/redwood/src/setup-package.ts @@ -0,0 +1,11 @@ +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; +import setupCommand from './commands/setup'; + +export default async function setupPackage() { + await yargs(hideBin(process.argv)) + .scriptName('zenstack-setup') + // @ts-expect-error yargs types are wrong + .command('$0', 'set up ZenStack', setupCommand.builder, setupCommand.handler) + .parseAsync(); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6eefd606f..253f1f6d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -82,6 +82,9 @@ importers: packages/misc/redwood: dependencies: + '@redwoodjs/cli-helpers': + specifier: ^6.6.0 + version: 6.6.0 '@zenstackhq/runtime': specifier: workspace:* version: link:../../runtime/dist @@ -104,9 +107,6 @@ importers: specifier: ^17.7.2 version: 17.7.2 devDependencies: - '@redwoodjs/cli-helpers': - specifier: ^6.6.0 - version: 6.6.0 '@redwoodjs/graphql-server': specifier: ^6.6.0 version: 6.6.0 @@ -854,7 +854,6 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 - dev: true /@antfu/ni@0.21.4: resolution: {integrity: sha512-O0Uv9LbLDSoEg26fnMDdDRiPwFJnQSoD4WnrflDwKCJm8Cx/0mV4cGxwBLXan5mGIrpK4Dd7vizf4rQm0QCEAA==} @@ -887,7 +886,6 @@ packages: /@babel/compat-data@7.22.9: resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} engines: {node: '>=6.9.0'} - dev: true /@babel/core@7.23.2: resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==} @@ -910,7 +908,6 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: true /@babel/generator@7.23.0: resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} @@ -920,7 +917,6 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 - dev: true /@babel/helper-annotate-as-pure@7.22.5: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} @@ -938,7 +934,6 @@ packages: browserslist: 4.22.1 lru-cache: 5.1.1 semver: 6.3.1 - dev: true /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==} @@ -961,7 +956,6 @@ packages: /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-environment-visitor@7.22.5: resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} @@ -982,14 +976,12 @@ packages: dependencies: '@babel/template': 7.22.15 '@babel/types': 7.23.0 - dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.23.0 - dev: true /@babel/helper-member-expression-to-functions@7.23.0: resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} @@ -1003,7 +995,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.23.0 - dev: true /@babel/helper-module-imports@7.22.5: resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} @@ -1024,7 +1015,6 @@ packages: '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 - dev: true /@babel/helper-optimise-call-expression@7.22.5: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} @@ -1055,7 +1045,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.23.0 - dev: true /@babel/helper-skip-transparent-expression-wrappers@7.22.5: resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} @@ -1069,12 +1058,10 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.23.0 - dev: true /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} @@ -1083,7 +1070,6 @@ packages: /@babel/helper-validator-option@7.22.15: resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} engines: {node: '>=6.9.0'} - dev: true /@babel/helpers@7.23.2: resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} @@ -1094,7 +1080,6 @@ packages: '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color - dev: true /@babel/highlight@7.22.20: resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} @@ -1119,7 +1104,6 @@ packages: hasBin: true dependencies: '@babel/types': 7.23.0 - dev: true /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.2): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} @@ -1269,7 +1253,6 @@ packages: dependencies: core-js-pure: 3.35.0 regenerator-runtime: 0.14.1 - dev: true /@babel/runtime@7.22.5: resolution: {integrity: sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==} @@ -1290,7 +1273,6 @@ packages: '@babel/code-frame': 7.22.13 '@babel/parser': 7.23.0 '@babel/types': 7.23.0 - dev: true /@babel/traverse@7.23.2: resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} @@ -1308,7 +1290,6 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: true /@babel/types@7.23.0: resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} @@ -1317,7 +1298,6 @@ packages: '@babel/helper-string-parser': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - dev: true /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -2521,7 +2501,7 @@ packages: /@iarna/toml@2.2.5: resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} - dev: true + dev: false /@ioredis/commands@1.2.0: resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} @@ -2764,12 +2744,10 @@ packages: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.18 - dev: true /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/resolve-uri@3.1.1: resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} @@ -2779,7 +2757,6 @@ packages: /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/source-map@0.3.5: resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} @@ -2790,18 +2767,15 @@ packages: /@jridgewell/sourcemap-codec@1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true /@jridgewell/trace-mapping@0.3.18: resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@jridgewell/trace-mapping@0.3.9: resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -2816,7 +2790,6 @@ packages: /@kamilkisiela/fast-url-parser@1.1.4: resolution: {integrity: sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew==} - dev: true /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} @@ -3342,7 +3315,6 @@ packages: /@opentelemetry/api@1.7.0: resolution: {integrity: sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==} engines: {node: '>=8.0.0'} - dev: true /@paralleldrive/cuid2@2.2.0: resolution: {integrity: sha512-CVQDpPIUHrUGGLdrMGz1NmqZvqmsB2j2rCIQEu1EvxWjlFh4fhvEGmgR409cY20/67/WlJsggenq0no3p3kYsw==} @@ -3564,7 +3536,7 @@ packages: /@prisma/debug@5.7.0: resolution: {integrity: sha512-tZ+MOjWlVvz1kOEhNYMa4QUGURY+kgOUBqLHYIV8jmCsMuvA1tWcn7qtIMLzYWCbDcQT4ZS8xDgK0R2gl6/0wA==} - dev: true + dev: false /@prisma/engines-version@4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81: resolution: {integrity: sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg==} @@ -3572,7 +3544,7 @@ packages: /@prisma/engines-version@5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9: resolution: {integrity: sha512-V6tgRVi62jRwTm0Hglky3Scwjr/AKFBFtS+MdbsBr7UOuiu1TKLPc6xfPiyEN1+bYqjEtjxwGsHgahcJsd1rNg==} - dev: true + dev: false /@prisma/engines@4.16.2: resolution: {integrity: sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==} @@ -3591,7 +3563,7 @@ packages: '@prisma/engines-version': 5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9 '@prisma/fetch-engine': 5.7.0 '@prisma/get-platform': 5.7.0 - dev: true + dev: false /@prisma/fetch-engine@4.16.2: resolution: {integrity: sha512-lnCnHcOaNn0kw8qTJbVcNhyfIf5Lus2GFXbj3qpkdKEIB9xLgqkkuTP+35q1xFaqwQ0vy4HFpdRUpFP7njE15g==} @@ -3649,7 +3621,7 @@ packages: '@prisma/debug': 5.7.0 '@prisma/engines-version': 5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9 '@prisma/get-platform': 5.7.0 - dev: true + dev: false /@prisma/generator-helper@4.16.2: resolution: {integrity: sha512-bMOH7y73Ui7gpQrioFeavMQA+Tf8ksaVf8Nhs9rQNzuSg8SSV6E9baczob0L5KGZTSgYoqnrRxuo03kVJYrnIg==} @@ -3677,7 +3649,7 @@ packages: resolution: {integrity: sha512-Fn4hJHKGJ49+E8sxpfslRauB3Goa3RAENJ/W25NMR754B9KxvmbCJyE3MT/lIZxML2nGgIdXYUtoDHZHnRaKDw==} dependencies: '@prisma/debug': 5.7.0 - dev: true + dev: false /@prisma/get-platform@4.16.2: resolution: {integrity: sha512-fnDey1/iSefHJRMB+w243BhWENf+paRouPMdCqIVqu8dYkR1NqhldblsSUC4Zr2sKS7Ta2sK4OLdt9IH+PZTfw==} @@ -3717,7 +3689,7 @@ packages: resolution: {integrity: sha512-ZeV/Op4bZsWXuw5Tg05WwRI8BlKiRFhsixPcAM+5BKYSiUZiMKIi713tfT3drBq8+T0E1arNZgYSA9QYcglWNA==} dependencies: '@prisma/debug': 5.7.0 - dev: true + dev: false /@prisma/internals@4.16.2: resolution: {integrity: sha512-/3OiSADA3RRgsaeEE+MDsBgL6oAMwddSheXn6wtYGUnjERAV/BmF5bMMLnTykesQqwZ1s8HrISrJ0Vf6cjOxMg==} @@ -3832,7 +3804,7 @@ packages: '@prisma/prisma-schema-wasm': 5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9 arg: 5.0.2 prompts: 2.4.2 - dev: true + dev: false /@prisma/prisma-fmt-wasm@4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81: resolution: {integrity: sha512-g090+dEH7wrdCw359+8J9+TGH84qK28V/dxwINjhhNCtju9lej99z9w/AVsJP9UhhcCPS4psYz4iu8d53uxVpA==} @@ -3844,7 +3816,7 @@ packages: /@prisma/prisma-schema-wasm@5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9: resolution: {integrity: sha512-w+HdQtux0dJDEn6BG3fgNn+fXErXiekj9n//uHRAgrmZghockJkhnikOmG8aSXjTb1Tu5DrGasBX+rYX6rHT1w==} - dev: true + dev: false /@readme/better-ajv-errors@1.6.0(ajv@8.12.0): resolution: {integrity: sha512-9gO9rld84Jgu13kcbKRU+WHseNhaVt76wYMeRDGsUGYxwJtI3RmEJ9LY9dZCYQGI8eUZLuxb5qDja0nqklpFjQ==} @@ -3935,7 +3907,7 @@ packages: transitivePeerDependencies: - enquirer - supports-color - dev: true + dev: false /@redwoodjs/graphql-server@6.6.0: resolution: {integrity: sha512-LuSHmQyZm9E8STfJszSAoNyMHREI/nx2zlA1UzQOG4605YgpljI2wXUxYw7UWCH3rU66Gt0daKdv8GSo2nPlSg==} @@ -3974,7 +3946,7 @@ packages: deepmerge: 4.3.1 fast-glob: 3.3.2 string-env-interpolation: 1.0.1 - dev: true + dev: false /@redwoodjs/structure@6.6.0: resolution: {integrity: sha512-8i4ujrhBklYNPQ7/uAf/W/rrRs9/2dIwVxTjvQz8N7NU4s3J0IrdHj5Q74vIyGOCBA8Lx3SbyXVGjIdg1sdx5g==} @@ -4002,7 +3974,7 @@ packages: vscode-languageserver-textdocument: 1.0.8 vscode-languageserver-types: 3.17.3 yargs-parser: 21.1.1 - dev: true + dev: false /@redwoodjs/telemetry@6.6.0: resolution: {integrity: sha512-9VEwngUBtbaPLaSdIQtthUiqrDHo4KFzDAmilvHUyV9Wgq49lCt/lpt7Dm3fO9C8l7n5WunXOKi7X2pp/IE1xw==} @@ -4017,7 +3989,7 @@ packages: systeminformation: 5.21.20 uuid: 9.0.1 yargs: 17.7.2 - dev: true + dev: false /@repeaterjs/repeater@3.0.5: resolution: {integrity: sha512-l3YHBLAol6d/IKnB9LhpD0cEZWAoe3eFKUyTYWmFmCO2Q/WOckxLQAUyMZWwZV2M/m3+4vgRoaolFqaII82/TA==} @@ -4556,7 +4528,7 @@ packages: minimatch: 5.1.6 mkdirp: 1.0.4 path-browserify: 1.0.1 - dev: true + dev: false /@ts-morph/common@0.17.0: resolution: {integrity: sha512-RMSSvSfs9kb0VzkvQ2NWobwnj7TxCA9vI/IjR9bDHqgAyVbu2T0DN4wiKVqomyDWqO7dPr/tErSfq7urQ1Q37g==} @@ -4760,7 +4732,7 @@ packages: /@types/line-column@1.0.0: resolution: {integrity: sha512-wbw+IDRw/xY/RGy+BL6f4Eey4jsUgHQrMuA4Qj0CSG3x/7C2Oc57pmRoM2z3M4DkylWRz+G1pfX06sCXQm0J+w==} - dev: true + dev: false /@types/mime@1.3.2: resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} @@ -5414,7 +5386,6 @@ packages: /@whatwg-node/events@0.1.1: resolution: {integrity: sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==} engines: {node: '>=16.0.0'} - dev: true /@whatwg-node/fetch@0.9.14: resolution: {integrity: sha512-wurZC82zzZwXRDSW0OS9l141DynaJQh7Yt0FD1xZ8niX7/Et/7RoiLiltbVU1fSF1RR9z6ndEaTUQBAmddTm1w==} @@ -5422,7 +5393,6 @@ packages: dependencies: '@whatwg-node/node-fetch': 0.5.2 urlpattern-polyfill: 9.0.0 - dev: true /@whatwg-node/node-fetch@0.5.2: resolution: {integrity: sha512-uVYCnmWoCiGbv5AtnSx5nZ1kQJ+U8f269/yHB62y7wXPdjYx6o4sBSefnfwUI8HNf4rf16VbvGR/AzuABhDD5g==} @@ -5433,7 +5403,6 @@ packages: busboy: 1.6.0 fast-querystring: 1.1.2 tslib: 2.6.0 - dev: true /@whatwg-node/server@0.9.19: resolution: {integrity: sha512-GViwZq7iE1qCV6fSL2JHAHPQb6Jn2Ke34pkC5Wv7nAZi0qIqqPcBrEUG7TbJc79hYjCSrzRTi7FEs2xyWnQn7Q==} @@ -5569,7 +5538,6 @@ packages: /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - dev: true /ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} @@ -5582,6 +5550,7 @@ packages: engines: {node: '>=12'} dependencies: type-fest: 1.4.0 + dev: false /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -5704,6 +5673,7 @@ packages: /arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: false /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -6080,7 +6050,6 @@ packages: electron-to-chromium: 1.4.551 node-releases: 2.0.13 update-browserslist-db: 1.0.13(browserslist@4.22.1) - dev: true /bs-logger@0.2.6: resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} @@ -6143,7 +6112,6 @@ packages: engines: {node: '>=10.16.0'} dependencies: streamsearch: 1.1.0 - dev: true /bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} @@ -6213,7 +6181,6 @@ packages: /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - dev: true /caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} @@ -6230,7 +6197,6 @@ packages: /caniuse-lite@1.0.30001547: resolution: {integrity: sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==} - dev: true /capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -6392,7 +6358,7 @@ packages: /ci-info@4.0.0: resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} engines: {node: '>=8'} - dev: true + dev: false /citty@0.1.4: resolution: {integrity: sha512-Q3bK1huLxzQrvj7hImJ7Z1vKYJRPQCDnd0EjXfHMidcjecGOMuLrmuQmtWmFkuKLcMThlGh1yCKG8IEc6VeNXQ==} @@ -6425,6 +6391,7 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: restore-cursor: 4.0.0 + dev: false /cli-spinners@2.9.0: resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==} @@ -6499,6 +6466,7 @@ packages: /code-block-writer@11.0.3: resolution: {integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==} + dev: false /code-error-fragment@0.0.230: resolution: {integrity: sha512-cadkfKp6932H8UkhzE/gcUqhRMNf8jHzkAN7+5Myabswaghu4xABTgPHDCjW+dBAJxj/SpkTYokpzDqY4pCzQw==} @@ -6701,7 +6669,6 @@ packages: /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true /cookie-es@1.0.0: resolution: {integrity: sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==} @@ -6743,12 +6710,10 @@ packages: /core-js-pure@3.35.0: resolution: {integrity: sha512-f+eRYmkou59uh7BPcyJ8MC76DiGhspj1KMxVIcF24tzP8NA9HVa1uC7BTW2tgx7E1QVCzDzsgp7kArrzhlz8Ew==} requiresBuild: true - dev: true /core-js@3.34.0: resolution: {integrity: sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==} requiresBuild: true - dev: true /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -7135,7 +7100,6 @@ packages: /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - dev: true /defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -7323,12 +7287,12 @@ packages: resolution: {integrity: sha512-y5z4NhblzwNk8XBIYVzjLcFkANK0rxbRDO6kGOfH9QrVYIGVEX52IqwSprKVsaLHM9pnNkCSxazZF/JPydDPvA==} dependencies: dotenv: 14.3.2 - dev: true + dev: false /dotenv@14.3.2: resolution: {integrity: sha512-vwEppIphpFdvaMCaHfCEv9IgwcxMljMw2TnAQBB4VWPvzXQLTb82jwmdOKzlEVUL3gNFT4l4TPKO+Bn+sqcrVQ==} engines: {node: '>=12'} - dev: true + dev: false /dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} @@ -7337,7 +7301,6 @@ packages: /dotenv@16.3.1: resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} engines: {node: '>=12'} - dev: true /dset@3.1.3: resolution: {integrity: sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==} @@ -7367,7 +7330,6 @@ packages: /electron-to-chromium@1.4.551: resolution: {integrity: sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==} - dev: true /emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -7429,7 +7391,7 @@ packages: dependencies: ansi-colors: 4.1.3 strip-ansi: 6.0.1 - dev: true + dev: false /entities@2.1.0: resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} @@ -7449,7 +7411,7 @@ packages: resolution: {integrity: sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==} engines: {node: '>=4'} hasBin: true - dev: true + dev: false /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} @@ -8039,6 +8001,7 @@ packages: /eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: false /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} @@ -8164,7 +8127,6 @@ packages: /fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} - dev: true /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -8197,7 +8159,7 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: true + dev: false /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -8222,7 +8184,6 @@ packages: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} dependencies: fast-decode-uri-component: 1.0.1 - dev: true /fast-redact@3.2.0: resolution: {integrity: sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw==} @@ -8315,7 +8276,7 @@ packages: dependencies: is-object: 1.0.2 merge-descriptors: 1.0.1 - dev: true + dev: false /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} @@ -8565,7 +8526,6 @@ packages: /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - dev: true /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} @@ -8736,7 +8696,6 @@ packages: /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - dev: true /globals@13.20.0: resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} @@ -8868,7 +8827,6 @@ packages: /graphql@16.8.1: resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - dev: true /gzip-size@7.0.0: resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} @@ -9356,7 +9314,7 @@ packages: /is-object@1.0.2: resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} - dev: true + dev: false /is-path-cwd@2.2.0: resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} @@ -9528,7 +9486,7 @@ packages: engines: {node: '>=0.10.0'} dependencies: isarray: 1.0.0 - dev: true + dev: false /isomorphic-fetch@3.0.0: resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} @@ -10155,7 +10113,6 @@ packages: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true - dev: true /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -10302,7 +10259,7 @@ packages: /lazy-get-decorator@2.2.1: resolution: {integrity: sha512-Z5uxqhXT+h3s1az3JaEAi9eh8+p4pIUE3qJGgfkx9zIEiA3bIpg4ChxODLwCpFr9S+PDEJ/2Q1UaMqy8RdVCxg==} - dev: true + dev: false /lazystream@1.0.1: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} @@ -10341,7 +10298,7 @@ packages: dependencies: isarray: 1.0.0 isobject: 2.1.0 - dev: true + dev: false /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -10390,6 +10347,7 @@ packages: log-update: 5.0.1 rfdc: 1.3.0 wrap-ansi: 8.1.0 + dev: false /load-module@4.2.1: resolution: {integrity: sha512-Sbfg6R4LjvyThJpqUoADHMjyoI2+cL4msbCQeZ9kkY/CqP/TT2938eftKm7x4I2gd4/A+DEe6nePkbfWYbXwSw==} @@ -10442,7 +10400,7 @@ packages: dependencies: lodash: 4.17.21 tslib: 1.14.1 - dev: true + dev: false /lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -10542,6 +10500,7 @@ packages: slice-ansi: 5.0.0 strip-ansi: 7.1.0 wrap-ansi: 8.1.0 + dev: false /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} @@ -10591,7 +10550,6 @@ packages: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: yallist: 3.1.1 - dev: true /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} @@ -10602,7 +10560,7 @@ packages: /lru-cache@7.18.3: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} - dev: true + dev: false /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} @@ -10718,7 +10676,6 @@ packages: /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - dev: true /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -10886,7 +10843,7 @@ packages: /module-not-found-error@1.0.1: resolution: {integrity: sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g==} - dev: true + dev: false /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -11269,7 +11226,6 @@ packages: /node-releases@2.0.13: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} - dev: true /noms@0.0.0: resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} @@ -11772,10 +11728,10 @@ packages: /pascalcase@1.0.0: resolution: {integrity: sha512-BSExi0rRnCHReJys6NocaK+cfTXNinAegfWBvr0JD3hiaEG7Nuc7r0CIdOJunXrs8gU/sbHQ9dxVAtiVQisjmg==} engines: {node: '>=8'} - dev: true /path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: false /path-case@3.0.4: resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} @@ -11918,7 +11874,6 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -12596,7 +12551,7 @@ packages: fill-keys: 1.0.2 module-not-found-error: 1.0.1 resolve: 1.22.2 - dev: true + dev: false /prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} @@ -12898,7 +12853,6 @@ packages: /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: true /regexp-to-ast@0.5.0: resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} @@ -13025,6 +12979,7 @@ packages: dependencies: onetime: 5.1.2 signal-exit: 3.0.7 + dev: false /ret@0.2.2: resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} @@ -13535,7 +13490,6 @@ packages: /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - dev: true /streamx@2.15.1: resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} @@ -13546,7 +13500,7 @@ packages: /string-env-interpolation@1.0.1: resolution: {integrity: sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==} - dev: true + dev: false /string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} @@ -13799,6 +13753,7 @@ packages: dependencies: has-flag: 4.0.0 supports-color: 7.2.0 + dev: false /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} @@ -13878,7 +13833,7 @@ packages: engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true - dev: true + dev: false /table-layout@1.0.2: resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} @@ -13985,6 +13940,7 @@ packages: dependencies: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 + dev: false /terser@5.21.0: resolution: {integrity: sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==} @@ -14083,7 +14039,6 @@ packages: /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} - dev: true /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -14195,7 +14150,7 @@ packages: dependencies: '@ts-morph/common': 0.16.0 code-block-writer: 11.0.3 - dev: true + dev: false /ts-morph@16.0.0: resolution: {integrity: sha512-jGNF0GVpFj0orFw55LTsQxVYEUOCWBAbR5Ls7fTYE5pQsbW18ssTb/6UXx/GYAEjS+DQTp8VoTw0vqYMiaaQuw==} @@ -14253,7 +14208,6 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true /tslib@2.4.1: resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} @@ -14376,6 +14330,7 @@ packages: /type-fest@1.4.0: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} + dev: false /type-fest@3.13.1: resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} @@ -14684,7 +14639,6 @@ packages: browserslist: 4.22.1 escalade: 3.1.1 picocolors: 1.0.0 - dev: true /upper-case-first@2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} @@ -14730,7 +14684,6 @@ packages: /urlpattern-polyfill@9.0.0: resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==} - dev: true /use-sync-external-store@1.2.0(react@18.2.0): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} @@ -14761,7 +14714,6 @@ packages: /uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - dev: true /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -15085,14 +15037,14 @@ packages: /vscode-languageserver-types@3.17.3: resolution: {integrity: sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==} - dev: true + dev: false /vscode-languageserver@6.1.1: resolution: {integrity: sha512-DueEpkUAkD5XTR4MLYNr6bQIp/UFR0/IPApgXU3YfCBCB08u2sm9hRCs6DxYZELkk++STPjpcjksR2H8qI3cDQ==} hasBin: true dependencies: vscode-languageserver-protocol: 3.17.2 - dev: true + dev: false /vscode-languageserver@7.0.0: resolution: {integrity: sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==} @@ -15351,6 +15303,7 @@ packages: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 + dev: false /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -15426,7 +15379,6 @@ packages: /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} From 8d5bfe402e2219b69520dbd0b820c9f3ba16a2ea Mon Sep 17 00:00:00 2001 From: Jiasheng Date: Mon, 1 Jan 2024 12:14:55 +0000 Subject: [PATCH 10/11] fix: Show validation error for the field comparison not in the same model (#912) --- .../validator/expression-validator.ts | 36 +++++++++++++++++-- .../src/language-server/zmodel-linker.ts | 16 ++------- packages/schema/src/utils/ast-utils.ts | 12 +++++++ .../validation/attribute-validation.test.ts | 29 +++++++++++++++ 4 files changed, 77 insertions(+), 16 deletions(-) diff --git a/packages/schema/src/language-server/validator/expression-validator.ts b/packages/schema/src/language-server/validator/expression-validator.ts index 474f918b9..7644521b8 100644 --- a/packages/schema/src/language-server/validator/expression-validator.ts +++ b/packages/schema/src/language-server/validator/expression-validator.ts @@ -4,12 +4,15 @@ import { ExpressionType, isDataModel, isEnum, + isMemberAccessExpr, isNullExpr, isThisExpr, + isDataModelField, + isLiteralExpr, } from '@zenstackhq/language/ast'; -import { isDataModelFieldReference } from '@zenstackhq/sdk'; +import { isDataModelFieldReference, isEnumFieldReference } from '@zenstackhq/sdk'; import { ValidationAcceptor } from 'langium'; -import { isAuthInvocation, isCollectionPredicate } from '../../utils/ast-utils'; +import { getContainingDataModel, isAuthInvocation, isCollectionPredicate } from '../../utils/ast-utils'; import { AstValidator } from '../types'; import { typeAssignable } from './utils'; @@ -124,6 +127,24 @@ export default class ExpressionValidator implements AstValidator { accept('error', 'incompatible operand types', { node: expr }); break; } + // not supported: + // - foo.a == bar + // - foo.user.id == userId + // except: + // - future().userId == userId + if(isMemberAccessExpr(expr.left) && isDataModelField(expr.left.member.ref) && expr.left.member.ref.$container != getContainingDataModel(expr) + || isMemberAccessExpr(expr.right) && isDataModelField(expr.right.member.ref) && expr.right.member.ref.$container != getContainingDataModel(expr)) + { + // foo.user.id == auth().id + // foo.user.id == "123" + // foo.user.id == null + // foo.user.id == EnumValue + if(!(this.isNotModelFieldExpr(expr.left) || this.isNotModelFieldExpr(expr.right))) + { + accept('error', 'comparison between fields of different models are not supported', { node: expr }); + break; + } + } if ( (expr.left.$resolvedType?.nullable && isNullExpr(expr.right)) || @@ -183,4 +204,15 @@ export default class ExpressionValidator implements AstValidator { } } } + + + private isNotModelFieldExpr(expr: Expression) { + return isLiteralExpr(expr) || isEnumFieldReference(expr) || isNullExpr(expr) || this.isAuthOrAuthMemberAccess(expr) + } + + private isAuthOrAuthMemberAccess(expr: Expression) { + return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && isAuthInvocation(expr.operand)); + } + } + diff --git a/packages/schema/src/language-server/zmodel-linker.ts b/packages/schema/src/language-server/zmodel-linker.ts index 23ada3d73..9951cbb68 100644 --- a/packages/schema/src/language-server/zmodel-linker.ts +++ b/packages/schema/src/language-server/zmodel-linker.ts @@ -9,7 +9,6 @@ import { DataModelFieldType, Enum, EnumField, - Expression, ExpressionType, FunctionDecl, FunctionParam, @@ -53,7 +52,7 @@ import { } from 'langium'; import { match } from 'ts-pattern'; import { CancellationToken } from 'vscode-jsonrpc'; -import { getAllDeclarationsFromImports, isAuthInvocation } from '../utils/ast-utils'; +import { getAllDeclarationsFromImports, isAuthInvocation, getContainingDataModel } from '../utils/ast-utils'; import { mapBuiltinTypeToExpressionType } from './validator/utils'; interface DefaultReference extends Reference { @@ -292,24 +291,13 @@ export class ZModelLinker extends DefaultLinker { } } else if (funcDecl.name === 'future' && isFromStdlib(funcDecl)) { // future() function is resolved to current model - node.$resolvedType = { decl: this.getContainingDataModel(node) }; + node.$resolvedType = { decl: getContainingDataModel(node) }; } else { this.resolveToDeclaredType(node, funcDecl.returnType); } } } - private getContainingDataModel(node: Expression): DataModel | undefined { - let curr: AstNode | undefined = node.$container; - while (curr) { - if (isDataModel(curr)) { - return curr; - } - curr = curr.$container; - } - return undefined; - } - private resolveLiteral(node: LiteralExpr) { const type = match(node) .when(isStringLiteral, () => 'String') diff --git a/packages/schema/src/utils/ast-utils.ts b/packages/schema/src/utils/ast-utils.ts index 138947be8..661f14b26 100644 --- a/packages/schema/src/utils/ast-utils.ts +++ b/packages/schema/src/utils/ast-utils.ts @@ -156,3 +156,15 @@ export function getAllDeclarationsFromImports(documents: LangiumDocuments, model export function isCollectionPredicate(node: AstNode): node is BinaryExpr { return isBinaryExpr(node) && ['?', '!', '^'].includes(node.operator); } + + +export function getContainingDataModel(node: Expression): DataModel | undefined { + let curr: AstNode | undefined = node.$container; + while (curr) { + if (isDataModel(curr)) { + return curr; + } + curr = curr.$container; + } + return undefined; +} \ No newline at end of file diff --git a/packages/schema/tests/schema/validation/attribute-validation.test.ts b/packages/schema/tests/schema/validation/attribute-validation.test.ts index 6a99799fa..e5dac56db 100644 --- a/packages/schema/tests/schema/validation/attribute-validation.test.ts +++ b/packages/schema/tests/schema/validation/attribute-validation.test.ts @@ -642,6 +642,35 @@ describe('Attribute tests', () => { `) ).toContain('comparison between model-typed fields are not supported'); + expect( + await loadModelWithError(` + ${prelude} + model User { + id Int @id + lists List[] + todos Todo[] + } + + model List { + id Int @id + user User @relation(fields: [userId], references: [id]) + userId Int + todos Todo[] + } + + model Todo { + id Int @id + user User @relation(fields: [userId], references: [id]) + userId Int + list List @relation(fields: [listId], references: [id]) + listId Int + + @@allow('read', list.user.id == userId) + } + + `) + ).toContain('comparison between fields of different models are not supported'); + expect( await loadModelWithError(` ${prelude} From 7e9cc35a68ed31e25e7c7eac764528f55a18ac7b Mon Sep 17 00:00:00 2001 From: Yiming Date: Mon, 1 Jan 2024 20:47:39 +0800 Subject: [PATCH 11/11] fix: disable textmate bundle when JetBrains plugin is uninstalled (#918) --- packages/ide/jetbrains/.idea/gradle.xml | 1 + packages/ide/jetbrains/.idea/vcs.xml | 2 +- packages/ide/jetbrains/build.gradle.kts | 2 +- .../src/main/kotlin/dev/zenstack/Utils.kt | 28 +++++++++++++++++++ .../lsp/ZenStackLspServerDescriptor.kt | 11 ++------ .../zenstack/plugin/PluginStateListener.kt | 18 ++++++++++++ .../src/main/resources/META-INF/plugin.xml | 10 +++++++ 7 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 packages/ide/jetbrains/src/main/kotlin/dev/zenstack/Utils.kt create mode 100644 packages/ide/jetbrains/src/main/kotlin/dev/zenstack/plugin/PluginStateListener.kt diff --git a/packages/ide/jetbrains/.idea/gradle.xml b/packages/ide/jetbrains/.idea/gradle.xml index f9163b40e..ce1c62c7c 100644 --- a/packages/ide/jetbrains/.idea/gradle.xml +++ b/packages/ide/jetbrains/.idea/gradle.xml @@ -1,5 +1,6 @@ +