├── .changeset ├── README.md └── config.json ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── release │ ├── .release-manifest.json │ └── release-main-config.json └── workflows │ ├── build-test.yml │ ├── codeql.yml │ ├── config │ └── codeql-config.yml │ ├── github-releases-to-discord.yml │ ├── integration-test.yml │ ├── regression-test.yml │ ├── security-dependency-review.yml │ ├── security-ossar.yml │ ├── security-scorecard.yml │ └── update-samples.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .vscode ├── extensions.json └── launch.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── jest.config.ts ├── package.json ├── packages ├── LICENSE ├── ide │ └── jetbrains │ │ ├── .gitignore │ │ ├── .idea │ │ ├── .gitignore │ │ ├── .name │ │ ├── gradle.xml │ │ ├── kotlinc.xml │ │ ├── misc.xml │ │ └── vcs.xml │ │ ├── CHANGELOG.md │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── package.json │ │ ├── settings.gradle.kts │ │ └── src │ │ └── main │ │ ├── kotlin │ │ └── dev │ │ │ └── zenstack │ │ │ ├── Utils.kt │ │ │ ├── lang │ │ │ ├── ZModelFileType.kt │ │ │ ├── ZModelIcons.kt │ │ │ └── ZModelLanguage.kt │ │ │ ├── lsp │ │ │ ├── ZenStackLspServerDescriptor.kt │ │ │ └── ZenStackLspServerSupportProvider.kt │ │ │ └── plugin │ │ │ └── PluginStateListener.kt │ │ ├── resources │ │ ├── META-INF │ │ │ ├── plugin.xml │ │ │ ├── pluginIcon.svg │ │ │ └── pluginIcon_dark.svg │ │ └── icons │ │ │ ├── zmodel.png │ │ │ └── zmodel_dark.png │ │ └── textMate │ │ └── zmodel.tmbundle │ │ └── info.plist ├── language │ ├── .eslintrc.json │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── langium-config.json │ ├── package.json │ ├── script │ │ └── generate-plist.ts │ ├── src │ │ ├── ast.ts │ │ ├── generated │ │ │ ├── ast.ts │ │ │ ├── grammar.ts │ │ │ └── module.ts │ │ ├── module.ts │ │ └── zmodel.langium │ ├── syntaxes │ │ ├── zmodel.tmLanguage │ │ └── zmodel.tmLanguage.json │ └── tsconfig.json ├── misc │ └── redwood │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── bin │ │ └── cli │ │ ├── package.json │ │ ├── src │ │ ├── cli-passthrough.ts │ │ ├── commands │ │ │ └── setup.ts │ │ ├── graphql.ts │ │ ├── index.ts │ │ ├── setup-package.ts │ │ └── utils.ts │ │ └── tsconfig.json ├── plugins │ ├── openapi │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── generator-base.ts │ │ │ ├── index.ts │ │ │ ├── meta.ts │ │ │ ├── plugin.zmodel │ │ │ ├── rest-generator.ts │ │ │ ├── rpc-generator.ts │ │ │ └── schema.ts │ │ ├── tests │ │ │ ├── baseline │ │ │ │ ├── rest-3.0.0.baseline.yaml │ │ │ │ ├── rest-3.1.0.baseline.yaml │ │ │ │ ├── rest-type-coverage-3.0.0.baseline.yaml │ │ │ │ ├── rest-type-coverage-3.1.0.baseline.yaml │ │ │ │ ├── rpc-3.0.0-omit.baseline.yaml │ │ │ │ ├── rpc-3.0.0.baseline.yaml │ │ │ │ ├── rpc-3.1.0-omit.baseline.yaml │ │ │ │ ├── rpc-3.1.0.baseline.yaml │ │ │ │ ├── rpc-type-coverage-3.0.0.baseline.yaml │ │ │ │ └── rpc-type-coverage-3.1.0.baseline.yaml │ │ │ ├── openapi-restful.test.ts │ │ │ └── openapi-rpc.test.ts │ │ └── tsconfig.json │ ├── prisma-types.ts │ ├── swr │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── generator.ts │ │ │ ├── index.ts │ │ │ └── runtime │ │ │ │ ├── index.ts │ │ │ │ └── prisma-types.ts │ │ ├── tests │ │ │ ├── react-hooks.test.tsx │ │ │ ├── swr.test.ts │ │ │ └── test-model-meta.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── tanstack-query │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── scripts │ │ │ └── postbuild.js │ │ ├── src │ │ │ ├── generator.ts │ │ │ ├── index.ts │ │ │ ├── runtime-v5 │ │ │ │ ├── index.ts │ │ │ │ ├── react.ts │ │ │ │ ├── svelte.ts │ │ │ │ └── vue.ts │ │ │ └── runtime │ │ │ │ ├── common.ts │ │ │ │ ├── index.ts │ │ │ │ ├── prisma-types.ts │ │ │ │ ├── react.ts │ │ │ │ ├── svelte.ts │ │ │ │ └── vue.ts │ │ ├── tests │ │ │ ├── plugin.test.ts │ │ │ ├── portable.test.ts │ │ │ ├── react-hooks-v5.test.tsx │ │ │ ├── react-hooks.test.tsx │ │ │ └── test-model-meta.ts │ │ ├── tsconfig.json │ │ ├── tsup-v5.config.ts │ │ └── tsup.config.ts │ └── trpc │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── res │ │ └── client │ │ │ ├── v10 │ │ │ ├── next.ts │ │ │ ├── nuxt.ts │ │ │ ├── react.ts │ │ │ └── utils.ts │ │ │ └── v11 │ │ │ ├── next.ts │ │ │ ├── nuxt.ts │ │ │ ├── react.ts │ │ │ └── utils.ts │ │ ├── src │ │ ├── client-helper │ │ │ ├── index.ts │ │ │ ├── next.ts │ │ │ ├── nuxt.ts │ │ │ └── react.ts │ │ ├── generator.ts │ │ ├── index.ts │ │ ├── project.ts │ │ └── utils.ts │ │ ├── tests │ │ ├── nuxt.test.ts │ │ ├── projects │ │ │ ├── nuxt-trpc-v10 │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── app.vue │ │ │ │ ├── nuxt.config.ts │ │ │ │ ├── package-lock.json │ │ │ │ ├── package.json │ │ │ │ ├── plugins │ │ │ │ │ └── client.ts │ │ │ │ ├── prisma │ │ │ │ │ └── schema.prisma │ │ │ │ ├── public │ │ │ │ │ └── favicon.ico │ │ │ │ ├── schema.zmodel │ │ │ │ ├── server │ │ │ │ │ ├── api │ │ │ │ │ │ └── trpc │ │ │ │ │ │ │ └── [trpc].ts │ │ │ │ │ ├── db.ts │ │ │ │ │ ├── trpc │ │ │ │ │ │ ├── context.ts │ │ │ │ │ │ ├── routers │ │ │ │ │ │ │ ├── generated │ │ │ │ │ │ │ │ ├── client │ │ │ │ │ │ │ │ │ ├── Post.nuxt.type.ts │ │ │ │ │ │ │ │ │ ├── User.nuxt.type.ts │ │ │ │ │ │ │ │ │ ├── nuxt.ts │ │ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ │ │ ├── helper.ts │ │ │ │ │ │ │ │ └── routers │ │ │ │ │ │ │ │ │ ├── Post.router.ts │ │ │ │ │ │ │ │ │ ├── User.router.ts │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── trpc.ts │ │ │ │ │ └── tsconfig.json │ │ │ │ └── tsconfig.json │ │ │ ├── nuxt-trpc-v11 │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── app.vue │ │ │ │ ├── nuxt.config.ts │ │ │ │ ├── package-lock.json │ │ │ │ ├── package.json │ │ │ │ ├── plugins │ │ │ │ │ └── client.ts │ │ │ │ ├── prisma │ │ │ │ │ └── schema.prisma │ │ │ │ ├── public │ │ │ │ │ └── favicon.ico │ │ │ │ ├── schema.zmodel │ │ │ │ ├── server │ │ │ │ │ ├── api │ │ │ │ │ │ └── trpc │ │ │ │ │ │ │ └── [trpc].ts │ │ │ │ │ ├── db.ts │ │ │ │ │ ├── trpc │ │ │ │ │ │ ├── context.ts │ │ │ │ │ │ ├── routers │ │ │ │ │ │ │ ├── generated-router-helper.ts │ │ │ │ │ │ │ ├── generated │ │ │ │ │ │ │ │ ├── client │ │ │ │ │ │ │ │ │ ├── Post.nuxt.type.ts │ │ │ │ │ │ │ │ │ ├── User.nuxt.type.ts │ │ │ │ │ │ │ │ │ ├── nuxt.ts │ │ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ │ │ ├── helper.ts │ │ │ │ │ │ │ │ └── routers │ │ │ │ │ │ │ │ │ ├── Post.router.ts │ │ │ │ │ │ │ │ │ ├── User.router.ts │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── trpc.ts │ │ │ │ │ └── tsconfig.json │ │ │ │ └── tsconfig.json │ │ │ ├── t3-trpc-v10 │ │ │ │ ├── .eslintrc.cjs │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── next.config.js │ │ │ │ ├── package.json │ │ │ │ ├── prisma │ │ │ │ │ └── schema.prisma │ │ │ │ ├── public │ │ │ │ │ └── favicon.ico │ │ │ │ ├── schema.zmodel │ │ │ │ ├── src │ │ │ │ │ ├── env.js │ │ │ │ │ ├── pages │ │ │ │ │ │ ├── _app.tsx │ │ │ │ │ │ ├── api │ │ │ │ │ │ │ └── trpc │ │ │ │ │ │ │ │ └── [trpc].ts │ │ │ │ │ │ ├── index.module.css │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── server │ │ │ │ │ │ ├── api │ │ │ │ │ │ │ ├── root.ts │ │ │ │ │ │ │ ├── routers │ │ │ │ │ │ │ │ ├── generated │ │ │ │ │ │ │ │ │ ├── client │ │ │ │ │ │ │ │ │ │ ├── Post.next.type.ts │ │ │ │ │ │ │ │ │ │ ├── User.next.type.ts │ │ │ │ │ │ │ │ │ │ ├── next.ts │ │ │ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ │ │ │ ├── helper.ts │ │ │ │ │ │ │ │ │ └── routers │ │ │ │ │ │ │ │ │ │ ├── Post.router.ts │ │ │ │ │ │ │ │ │ │ ├── User.router.ts │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── greet.ts │ │ │ │ │ │ │ │ └── post.ts │ │ │ │ │ │ │ └── trpc.ts │ │ │ │ │ │ └── db.ts │ │ │ │ │ ├── styles │ │ │ │ │ │ └── globals.css │ │ │ │ │ └── utils │ │ │ │ │ │ └── api.ts │ │ │ │ └── tsconfig.json │ │ │ └── t3-trpc-v11 │ │ │ │ ├── .eslintrc.cjs │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── next.config.js │ │ │ │ ├── package-lock.json │ │ │ │ ├── package.json │ │ │ │ ├── prisma │ │ │ │ └── schema.prisma │ │ │ │ ├── public │ │ │ │ └── favicon.ico │ │ │ │ ├── schema.zmodel │ │ │ │ ├── src │ │ │ │ ├── app │ │ │ │ │ ├── _components │ │ │ │ │ │ └── post.tsx │ │ │ │ │ ├── api │ │ │ │ │ │ └── trpc │ │ │ │ │ │ │ └── [trpc] │ │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── index.module.css │ │ │ │ │ ├── layout.tsx │ │ │ │ │ └── page.tsx │ │ │ │ ├── env.js │ │ │ │ ├── server │ │ │ │ │ ├── api │ │ │ │ │ │ ├── root.ts │ │ │ │ │ │ ├── routers │ │ │ │ │ │ │ ├── generated-router-helper.ts │ │ │ │ │ │ │ └── generated │ │ │ │ │ │ │ │ ├── client │ │ │ │ │ │ │ │ ├── Post.react.type.ts │ │ │ │ │ │ │ │ ├── User.react.type.ts │ │ │ │ │ │ │ │ ├── react.ts │ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ │ │ ├── helper.ts │ │ │ │ │ │ │ │ └── routers │ │ │ │ │ │ │ │ ├── Post.router.ts │ │ │ │ │ │ │ │ ├── User.router.ts │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── trpc.ts │ │ │ │ │ └── db.ts │ │ │ │ ├── styles │ │ │ │ │ └── globals.css │ │ │ │ └── trpc │ │ │ │ │ ├── query-client.ts │ │ │ │ │ ├── react.tsx │ │ │ │ │ └── server.ts │ │ │ │ └── tsconfig.json │ │ ├── t3.test.ts │ │ └── trpc.test.ts │ │ └── tsconfig.json ├── runtime │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── res │ │ ├── enhance-edge.d.ts │ │ ├── enhance-edge.js │ │ ├── enhance.d.ts │ │ ├── enhance.js │ │ ├── model-meta.d.ts │ │ ├── model-meta.js │ │ ├── models.d.ts │ │ ├── models.js │ │ └── zod │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── input.d.ts │ │ │ ├── input.js │ │ │ ├── models.d.ts │ │ │ ├── models.js │ │ │ ├── objects.d.ts │ │ │ └── objects.js │ ├── src │ │ ├── browser │ │ │ ├── index.ts │ │ │ └── serialization.ts │ │ ├── constants.ts │ │ ├── cross │ │ │ ├── clone.ts │ │ │ ├── index.ts │ │ │ ├── model-data-visitor.ts │ │ │ ├── model-meta.ts │ │ │ ├── mutator.ts │ │ │ ├── nested-read-visitor.ts │ │ │ ├── nested-write-visitor.ts │ │ │ ├── query-analyzer.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── edge.ts │ │ ├── encryption │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ ├── enhance-edge.d.ts │ │ ├── enhance.d.ts │ │ ├── enhancements │ │ │ ├── edge │ │ │ │ ├── create-enhancement.ts │ │ │ │ ├── default-auth.ts │ │ │ │ ├── delegate.ts │ │ │ │ ├── encryption.ts │ │ │ │ ├── index.ts │ │ │ │ ├── json-processor.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── omit.ts │ │ │ │ ├── password.ts │ │ │ │ ├── policy │ │ │ │ │ ├── check-utils.ts │ │ │ │ │ ├── handler.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── policy-utils.ts │ │ │ │ ├── promise.ts │ │ │ │ ├── proxy.ts │ │ │ │ ├── query-utils.ts │ │ │ │ ├── types.ts │ │ │ │ ├── utils.ts │ │ │ │ └── where-visitor.ts │ │ │ └── node │ │ │ │ ├── create-enhancement.ts │ │ │ │ ├── default-auth.ts │ │ │ │ ├── delegate.ts │ │ │ │ ├── encryption.ts │ │ │ │ ├── index.ts │ │ │ │ ├── json-processor.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── omit.ts │ │ │ │ ├── password.ts │ │ │ │ ├── policy │ │ │ │ ├── check-utils.ts │ │ │ │ ├── constraint-solver.ts │ │ │ │ ├── handler.ts │ │ │ │ ├── index.ts │ │ │ │ ├── logic-solver.d.ts │ │ │ │ └── policy-utils.ts │ │ │ │ ├── promise.ts │ │ │ │ ├── proxy.ts │ │ │ │ ├── query-utils.ts │ │ │ │ ├── types.ts │ │ │ │ ├── utils.ts │ │ │ │ └── where-visitor.ts │ │ ├── error.ts │ │ ├── index.ts │ │ ├── package.json │ │ ├── types.ts │ │ ├── validation.ts │ │ ├── version.ts │ │ └── zod-utils.ts │ ├── tests │ │ ├── policy │ │ │ └── reduction.test.ts │ │ └── zod │ │ │ └── smart-union.test.ts │ ├── tsconfig.json │ ├── tsup-browser.config.ts │ └── tsup-cross.config.ts ├── schema │ ├── .gitignore │ ├── .vscodeignore │ ├── LICENSE │ ├── README-global.md │ ├── README.md │ ├── asset │ │ ├── logo-256-bg.png │ │ ├── logo-dark-256.png │ │ └── logo-light-256.png │ ├── bin │ │ ├── cli │ │ └── post-install.js │ ├── build │ │ ├── bundle.js │ │ └── post-build.js │ ├── jest.config.ts │ ├── language-configuration.json │ ├── package.json │ ├── src │ │ ├── cli │ │ │ ├── actions │ │ │ │ ├── check.ts │ │ │ │ ├── format.ts │ │ │ │ ├── generate.ts │ │ │ │ ├── index.ts │ │ │ │ ├── info.ts │ │ │ │ ├── init.ts │ │ │ │ └── repl.ts │ │ │ ├── cli-error.ts │ │ │ ├── cli-util.ts │ │ │ ├── config.ts │ │ │ ├── index.ts │ │ │ └── plugin-runner.ts │ │ ├── constants.ts │ │ ├── extension.ts │ │ ├── global.d.ts │ │ ├── language-server │ │ │ ├── constants.ts │ │ │ ├── main.ts │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ ├── validator │ │ │ │ ├── attribute-application-validator.ts │ │ │ │ ├── attribute-validator.ts │ │ │ │ ├── datamodel-validator.ts │ │ │ │ ├── datasource-validator.ts │ │ │ │ ├── enum-validator.ts │ │ │ │ ├── expression-validator.ts │ │ │ │ ├── function-decl-validator.ts │ │ │ │ ├── function-invocation-validator.ts │ │ │ │ ├── schema-validator.ts │ │ │ │ ├── typedef-validator.ts │ │ │ │ ├── utils.ts │ │ │ │ └── zmodel-validator.ts │ │ │ ├── zmodel-code-action.ts │ │ │ ├── zmodel-completion-provider.ts │ │ │ ├── zmodel-definition.ts │ │ │ ├── zmodel-documentation-provider.ts │ │ │ ├── zmodel-formatter.ts │ │ │ ├── zmodel-highlight.ts │ │ │ ├── zmodel-hover.ts │ │ │ ├── zmodel-linker.ts │ │ │ ├── zmodel-module.ts │ │ │ ├── zmodel-scope.ts │ │ │ ├── zmodel-semantic.ts │ │ │ └── zmodel-workspace-manager.ts │ │ ├── package.json │ │ ├── plugins │ │ │ ├── enhancer │ │ │ │ ├── enhance │ │ │ │ │ ├── auth-type-generator.ts │ │ │ │ │ ├── checker-type-generator.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── model-typedef-generator.ts │ │ │ │ ├── enhancer-utils.ts │ │ │ │ ├── index.ts │ │ │ │ ├── model-meta │ │ │ │ │ └── index.ts │ │ │ │ └── policy │ │ │ │ │ ├── constraint-transformer.ts │ │ │ │ │ ├── expression-writer.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── policy-guard-generator.ts │ │ │ │ │ └── utils.ts │ │ │ ├── plugin-utils.ts │ │ │ ├── prisma │ │ │ │ ├── indent-string.ts │ │ │ │ ├── index.ts │ │ │ │ ├── prisma-builder.ts │ │ │ │ └── schema-generator.ts │ │ │ └── zod │ │ │ │ ├── generator.ts │ │ │ │ ├── index.ts │ │ │ │ ├── transformer.ts │ │ │ │ ├── types.ts │ │ │ │ └── utils │ │ │ │ └── schema-gen.ts │ │ ├── res │ │ │ ├── starter.zmodel │ │ │ └── stdlib.zmodel │ │ ├── telemetry.ts │ │ └── utils │ │ │ ├── ast-utils.ts │ │ │ ├── exec-utils.ts │ │ │ ├── is-docker.ts │ │ │ ├── machine-id-utils.ts │ │ │ ├── pkg-utils.ts │ │ │ └── version-utils.ts │ ├── tests │ │ ├── generator │ │ │ ├── expression-writer.test.ts │ │ │ ├── prisma-builder.test.ts │ │ │ ├── prisma-generator.test.ts │ │ │ ├── prisma │ │ │ │ ├── format.prisma │ │ │ │ └── multi-level-inheritance.prisma │ │ │ └── zmodel │ │ │ │ ├── schema.zmodel │ │ │ │ └── user │ │ │ │ └── user.zmodel │ │ ├── schema │ │ │ ├── abstract.test.ts │ │ │ ├── abstract.zmodel │ │ │ ├── all-features.zmodel │ │ │ ├── cal-com.test.ts │ │ │ ├── cal-com.zmodel │ │ │ ├── formatter.test.ts │ │ │ ├── mutil-files │ │ │ │ ├── multi-files.test.ts │ │ │ │ ├── schema.zmodel │ │ │ │ └── user.zmodel │ │ │ ├── parser.test.ts │ │ │ ├── sample-todo.test.ts │ │ │ ├── stdlib.test.ts │ │ │ ├── todo.zmodel │ │ │ ├── trigger-dev.test.ts │ │ │ ├── trigger-dev.zmodel │ │ │ ├── validation │ │ │ │ ├── attribute-validation.test.ts │ │ │ │ ├── cyclic-inheritance.test.ts │ │ │ │ ├── datamodel-validation.test.ts │ │ │ │ ├── datasource-validation.test.ts │ │ │ │ ├── enum-validation.test.ts │ │ │ │ └── schema-validation.test.ts │ │ │ └── zmodel-generator.test.ts │ │ └── utils.ts │ └── tsconfig.json ├── sdk │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── ast.ts │ │ ├── code-gen.ts │ │ ├── constants.ts │ │ ├── dmmf-helpers │ │ │ ├── aggregate-helpers.ts │ │ │ ├── include-helpers.ts │ │ │ ├── index.ts │ │ │ ├── missing-types-helper.ts │ │ │ ├── model-helpers.ts │ │ │ ├── modelArgs-helpers.ts │ │ │ ├── select-helpers.ts │ │ │ └── types.ts │ │ ├── index.ts │ │ ├── model-meta-generator.ts │ │ ├── names.ts │ │ ├── package.json │ │ ├── path.ts │ │ ├── policy.ts │ │ ├── prisma.ts │ │ ├── types.ts │ │ ├── typescript-expression-transformer.ts │ │ ├── utils.ts │ │ ├── validation.ts │ │ └── zmodel-code-generator.ts │ └── tsconfig.json ├── server │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── src │ │ ├── api │ │ │ ├── base.ts │ │ │ ├── index.ts │ │ │ ├── rest │ │ │ │ └── index.ts │ │ │ ├── rpc │ │ │ │ └── index.ts │ │ │ └── utils.ts │ │ ├── elysia │ │ │ ├── handler.ts │ │ │ └── index.ts │ │ ├── express │ │ │ ├── index.ts │ │ │ └── middleware.ts │ │ ├── fastify │ │ │ ├── index.ts │ │ │ └── plugin.ts │ │ ├── hono │ │ │ ├── handler.ts │ │ │ └── index.ts │ │ ├── nestjs │ │ │ ├── api-handler.service.ts │ │ │ ├── index.ts │ │ │ ├── interfaces │ │ │ │ ├── api-handler-options.interface.ts │ │ │ │ ├── index.ts │ │ │ │ └── zenstack-module-options.interface.ts │ │ │ ├── zenstack.constants.ts │ │ │ └── zenstack.module.ts │ │ ├── next │ │ │ ├── app-route-handler.ts │ │ │ ├── index.ts │ │ │ └── pages-route-handler.ts │ │ ├── nuxt │ │ │ ├── handler.ts │ │ │ └── index.ts │ │ ├── shared.ts │ │ ├── sveltekit │ │ │ ├── handler.ts │ │ │ └── index.ts │ │ └── types.ts │ ├── tests │ │ ├── adapter │ │ │ ├── elysia.test.ts │ │ │ ├── express.test.ts │ │ │ ├── fastify.test.ts │ │ │ ├── hono.test.ts │ │ │ ├── nestjs.test.ts │ │ │ ├── next.test.ts │ │ │ └── sveltekit.test.ts │ │ ├── api │ │ │ ├── rest-petstore.test.ts │ │ │ ├── rest.test.ts │ │ │ └── rpc.test.ts │ │ └── utils.ts │ └── tsconfig.json └── testtools │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ ├── db.ts │ ├── index.ts │ ├── jest-ext.ts │ ├── model.ts │ └── schema.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── script ├── set-test-env.ts ├── test-global-setup.ts └── test-scaffold.ts ├── test-setup.ts ├── tests ├── integration │ ├── .eslintrc.json │ ├── .gitignore │ ├── jest.config.ts │ ├── jest.d.ts │ ├── package.json │ ├── test-run │ │ ├── .gitignore │ │ └── package.json │ ├── test-setup.ts │ ├── tests │ │ ├── cli │ │ │ ├── format.test.ts │ │ │ ├── generate.test.ts │ │ │ ├── init.test.ts │ │ │ ├── plugins.test.ts │ │ │ └── share.ts │ │ ├── e2e │ │ │ ├── filter-function-coverage.test.ts │ │ │ ├── misc-function-coverage.test.ts │ │ │ ├── prisma-methods.test.ts │ │ │ ├── todo-presets.test.ts │ │ │ └── type-coverage.test.ts │ │ ├── enhancements │ │ │ ├── json │ │ │ │ ├── crud.test.ts │ │ │ │ ├── typing.test.ts │ │ │ │ └── validation.test.ts │ │ │ ├── proxy │ │ │ │ └── extension-context.test.ts │ │ │ ├── typing │ │ │ │ └── enhancement-typing.test.ts │ │ │ ├── with-delegate │ │ │ │ ├── enhanced-client.test.ts │ │ │ │ ├── omit-interaction.test.ts │ │ │ │ ├── password-interaction.test.ts │ │ │ │ ├── plugin-interaction.test.ts │ │ │ │ ├── policy-interaction.test.ts │ │ │ │ ├── utils.ts │ │ │ │ └── validation.test.ts │ │ │ ├── with-encrypted │ │ │ │ └── with-encrypted.test.ts │ │ │ ├── with-omit │ │ │ │ └── with-omit.test.ts │ │ │ ├── with-password │ │ │ │ └── with-password.test.ts │ │ │ └── with-policy │ │ │ │ ├── abstract.test.ts │ │ │ │ ├── auth.test.ts │ │ │ │ ├── cal-com-sample.test.ts │ │ │ │ ├── checker.test.ts │ │ │ │ ├── client-extensions.test.ts │ │ │ │ ├── connect-disconnect.test.ts │ │ │ │ ├── create-many-and-return.test.ts │ │ │ │ ├── cross-model-field-comparison.test.ts │ │ │ │ ├── currentModel.test.ts │ │ │ │ ├── currentOperation.test.ts │ │ │ │ ├── deep-nested.test.ts │ │ │ │ ├── empty-policy.test.ts │ │ │ │ ├── field-comparison.test.ts │ │ │ │ ├── field-level-policy.test.ts │ │ │ │ ├── field-validation.test.ts │ │ │ │ ├── fluent-api.test.ts │ │ │ │ ├── multi-field-unique.test.ts │ │ │ │ ├── multi-file.test.ts │ │ │ │ ├── multi-id-fields.test.ts │ │ │ │ ├── nested-to-many.test.ts │ │ │ │ ├── nested-to-one.test.ts │ │ │ │ ├── options.test.ts │ │ │ │ ├── petstore-sample.test.ts │ │ │ │ ├── post-update.test.ts │ │ │ │ ├── postgres.test.ts │ │ │ │ ├── prisma-omit.test.ts │ │ │ │ ├── prisma-pulse.test.ts │ │ │ │ ├── query-reduction.test.ts │ │ │ │ ├── refactor.test.ts │ │ │ │ ├── relation-check.test.ts │ │ │ │ ├── relation-many-to-many-filter.test.ts │ │ │ │ ├── relation-one-to-many-filter.test.ts │ │ │ │ ├── relation-one-to-one-filter.test.ts │ │ │ │ ├── self-relation.test.ts │ │ │ │ ├── todo-sample.test.ts │ │ │ │ ├── toplevel-operations.test.ts │ │ │ │ ├── unique-as-id.test.ts │ │ │ │ ├── update-many-and-return.test.ts │ │ │ │ └── view.test.ts │ │ ├── frameworks │ │ │ ├── nextjs │ │ │ │ ├── generation.test.ts │ │ │ │ └── test-project │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .npmrc │ │ │ │ │ ├── README.md │ │ │ │ │ ├── next.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── pages │ │ │ │ │ ├── _app.tsx │ │ │ │ │ ├── api │ │ │ │ │ │ └── model │ │ │ │ │ │ │ └── [...path].ts │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── postgres.zmodel │ │ │ │ │ ├── server │ │ │ │ │ └── db.ts │ │ │ │ │ ├── sqlite.zmodel │ │ │ │ │ └── tsconfig.json │ │ │ └── trpc │ │ │ │ ├── generation.test.ts │ │ │ │ └── test-project │ │ │ │ ├── .gitignore │ │ │ │ ├── .npmrc │ │ │ │ ├── README.md │ │ │ │ ├── lib │ │ │ │ └── trpc.ts │ │ │ │ ├── next.config.js │ │ │ │ ├── package.json │ │ │ │ ├── pages │ │ │ │ ├── _app.tsx │ │ │ │ ├── api │ │ │ │ │ └── model │ │ │ │ │ │ └── [...path].ts │ │ │ │ └── index.tsx │ │ │ │ ├── server │ │ │ │ ├── context.ts │ │ │ │ ├── db.ts │ │ │ │ └── routers │ │ │ │ │ └── _app.ts │ │ │ │ ├── todo.zmodel │ │ │ │ └── tsconfig.json │ │ ├── misc │ │ │ └── stacktrace.test.ts │ │ ├── plugins │ │ │ ├── policy.test.ts │ │ │ ├── prisma.test.ts │ │ │ └── zod.test.ts │ │ └── schema │ │ │ ├── cal-com.zmodel │ │ │ ├── petstore.zmodel │ │ │ ├── refactor-pg.zmodel │ │ │ ├── todo-pg.zmodel │ │ │ └── todo.zmodel │ └── tsconfig.json └── regression │ ├── .eslintrc.json │ ├── jest.config.ts │ ├── jest.d.ts │ ├── package.json │ ├── test-setup.ts │ ├── tests │ ├── issue-1014.test.ts │ ├── issue-1058.test.ts │ ├── issue-1064.test.ts │ ├── issue-1078.test.ts │ ├── issue-1080.test.ts │ ├── issue-1100.test.ts │ ├── issue-1123.test.ts │ ├── issue-1129.test.ts │ ├── issue-1135.test.ts │ ├── issue-1149.test.ts │ ├── issue-1167.test.ts │ ├── issue-1179.test.ts │ ├── issue-1186.test.ts │ ├── issue-1210.test.ts │ ├── issue-1235.test.ts │ ├── issue-1241.test.ts │ ├── issue-1243.test.ts │ ├── issue-1257.test.ts │ ├── issue-1265.test.ts │ ├── issue-1268.test.ts │ ├── issue-1271.test.ts │ ├── issue-1378.test.ts │ ├── issue-1381.test.ts │ ├── issue-1388.test.ts │ ├── issue-1410.test.ts │ ├── issue-1415.test.ts │ ├── issue-1416.test.ts │ ├── issue-1427.test.ts │ ├── issue-1435.test.ts │ ├── issue-1451.test.ts │ ├── issue-1454.test.ts │ ├── issue-1466.test.ts │ ├── issue-1467.test.ts │ ├── issue-1474.test.ts │ ├── issue-1483.test.ts │ ├── issue-1487.test.ts │ ├── issue-1493.test.ts │ ├── issue-1506.test.ts │ ├── issue-1507.test.ts │ ├── issue-1518.test.ts │ ├── issue-1520.test.ts │ ├── issue-1522.test.ts │ ├── issue-1530.test.ts │ ├── issue-1533.test.ts │ ├── issue-1551.test.ts │ ├── issue-1560.test.ts │ ├── issue-1562.test.ts │ ├── issue-1563.test.ts │ ├── issue-1574.test.ts │ ├── issue-1575.test.ts │ ├── issue-1576.test.ts │ ├── issue-1585.test.ts │ ├── issue-1596.test.ts │ ├── issue-1610.test.ts │ ├── issue-1627.test.ts │ ├── issue-1642.test.ts │ ├── issue-1644.test.ts │ ├── issue-1645.test.ts │ ├── issue-1647.test.ts │ ├── issue-1648.test.ts │ ├── issue-1667.test.ts │ ├── issue-1674.test.ts │ ├── issue-1681.test.ts │ ├── issue-1693.test.ts │ ├── issue-1695.test.ts │ ├── issue-1698.test.ts │ ├── issue-1710.test.ts │ ├── issue-1734.test.ts │ ├── issue-1743.test.ts │ ├── issue-1745.test.ts │ ├── issue-1746.test.ts │ ├── issue-1755.test.ts │ ├── issue-1758.test.ts │ ├── issue-1763.test.ts │ ├── issue-177.test.ts │ ├── issue-1770.test.ts │ ├── issue-1786.test.ts │ ├── issue-1835.test.ts │ ├── issue-1843.test.ts │ ├── issue-1849.test.ts │ ├── issue-1857.test.ts │ ├── issue-1859.test.ts │ ├── issue-1870.test.ts │ ├── issue-1894.test.ts │ ├── issue-1930.test.ts │ ├── issue-1955.test.ts │ ├── issue-1964.test.ts │ ├── issue-1978.test.ts │ ├── issue-1984.test.ts │ ├── issue-1991.test.ts │ ├── issue-1992.test.ts │ ├── issue-1993.test.ts │ ├── issue-1994.test.ts │ ├── issue-1997.test.ts │ ├── issue-1998.test.ts │ ├── issue-2000.test.ts │ ├── issue-2007.test.ts │ ├── issue-2014.test.ts │ ├── issue-2019.test.ts │ ├── issue-2028.test.ts │ ├── issue-2038.test.ts │ ├── issue-2039.test.ts │ ├── issue-2065.test.ts │ ├── issue-2106.test.ts │ ├── issue-2117.test.ts │ ├── issue-416.test.ts │ ├── issue-646.test.ts │ ├── issue-657.test.ts │ ├── issue-665.test.ts │ ├── issue-674.test.ts │ ├── issue-689.test.ts │ ├── issue-703.test.ts │ ├── issue-714.test.ts │ ├── issue-724.test.ts │ ├── issue-735.test.ts │ ├── issue-744.test.ts │ ├── issue-756.test.ts │ ├── issue-764.test.ts │ ├── issue-765.test.ts │ ├── issue-804.test.ts │ ├── issue-811.test.ts │ ├── issue-814.test.ts │ ├── issue-825.test.ts │ ├── issue-864.test.ts │ ├── issue-886.test.ts │ ├── issue-925.test.ts │ ├── issue-947.test.ts │ ├── issue-961.test.ts │ ├── issue-965.test.ts │ ├── issue-971.test.ts │ ├── issue-992.test.ts │ ├── issue-foo.test.ts │ ├── issue-prisma-extension.test.ts │ └── issues.test.ts │ └── tsconfig.json └── tsconfig.base.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/dist/** 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": ["@typescript-eslint"], 9 | "extends": [ 10 | "eslint:recommended", 11 | "plugin:@typescript-eslint/eslint-recommended", 12 | "plugin:@typescript-eslint/recommended", 13 | "plugin:jest/recommended" 14 | ], 15 | "rules": { 16 | "@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }], 17 | "jest/expect-expect": "off" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | 3 | *.bat text=auto eol=crlf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Description and expected behavior** 10 | A clear and concise description of what the bug is and what's the expected behavior. 11 | 12 | **Screenshots** 13 | If applicable, add screenshots to help explain your problem. 14 | 15 | **Environment (please complete the following information):** 16 | 17 | - ZenStack version: [e.g., 2.0.0] 18 | - Prisma version: [e.g., 5.7.0] 19 | - Database type: [e.g. Postgresql] 20 | 21 | **Additional context** 22 | Add any other context about the problem here. 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '[Feature Request] ' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/release/.release-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | ".": "2.0.0-alpha.1", 3 | "packages/ide/jetbrains": "2.0.0-alpha.2", 4 | "packages/language": "2.0.0-alpha.2", 5 | "packages/misc/redwood": "2.0.0-alpha.2", 6 | "packages/plugins/openapi": "2.0.0-alpha.2", 7 | "packages/plugins/swr": "2.0.0-alpha.2", 8 | "packages/plugins/tanstack-query": "2.0.0-alpha.2", 9 | "packages/plugins/trpc": "2.0.0-alpha.2", 10 | "packages/runtime": "2.0.0-alpha.2", 11 | "packages/sdk": "2.0.0-alpha.2", 12 | "packages/server": "2.0.0-alpha.2", 13 | "packages/testtools": "2.0.0-alpha.2" 14 | } -------------------------------------------------------------------------------- /.github/workflows/config/codeql-config.yml: -------------------------------------------------------------------------------- 1 | paths: 2 | - 'packages' 3 | paths-ignore: 4 | - '**/*.test.js' 5 | - '**/*.test.ts' 6 | - '**/*.test.tsx' 7 | - '**/__tests__/**' 8 | - 'packages/ide/**' 9 | -------------------------------------------------------------------------------- /.github/workflows/github-releases-to-discord.yml: -------------------------------------------------------------------------------- 1 | on: 2 | release: 3 | types: [published] 4 | jobs: 5 | github-releases-to-discord: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout 9 | uses: actions/checkout@v3 10 | - name: Github Releases To Discord 11 | uses: SethCohen/github-releases-to-discord@v1.13.1 12 | with: 13 | webhook_url: ${{ secrets.RELEASE_TO_DISCORD_WEBHOOK_URL }} 14 | avatar_url: 'https://cdn.discordapp.com/avatars/1297059323314176051/df91181b3f1cf0ef1592fbe18e0962d7.webp?size=160' 15 | reduce_headings: true 16 | -------------------------------------------------------------------------------- /.github/workflows/update-samples.yml: -------------------------------------------------------------------------------- 1 | name: Update Samples 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | dispatch: 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | matrix: 13 | repo: 14 | [ 15 | 'zenstackhq/sample-todo-nextjs', 16 | 'zenstackhq/sample-todo-nextjs-tanstack', 17 | 'zenstackhq/sample-todo-trpc', 18 | 'zenstackhq/sample-todo-sveltekit', 19 | 'zenstackhq/sample-todo-nuxt', 20 | ] 21 | 22 | steps: 23 | - name: Repository Dispatch 24 | uses: peter-evans/repository-dispatch@v3.0.0 25 | with: 26 | token: ${{ secrets.RELEASE_TRIGGER_TOKEN }} 27 | repository: ${{ matrix.repo }} 28 | event-type: zenstack-release 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .vercel 4 | .DS_Store 5 | .vscode/settings.json 6 | .env.local 7 | .npmcache 8 | coverage 9 | .build 10 | .test 11 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | auto-install-peers=true 2 | git-checks=false 3 | node-linker=hoisted 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | dist 4 | generated 5 | .vercel 6 | .next 7 | 8 | package.json 9 | package-lock.json 10 | pnpm-*.yaml 11 | 12 | test-run 13 | coverage 14 | .vscode 15 | 16 | samples/todo/lib/hooks 17 | samples/todo/server/routers/generated -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "useTabs": false, 4 | "printWidth": 120, 5 | "singleQuote": true 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | 5 | // List of extensions which should be recommended for users of this workspace. 6 | "recommendations": ["langium.langium-vscode", "firsttris.vscode-jest-runner"] 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ZenStack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | >=1.0.0 | :white_check_mark: | 8 | 9 | ## Reporting a Vulnerability 10 | 11 | Please send an email to contact@zenstack.dev. We'll actively watch, verify, and fix them with high priority. 12 | 13 | Thank you for helping us make a better project! 14 | -------------------------------------------------------------------------------- /packages/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ZenStack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/modules.xml 9 | .idea/jarRepositories.xml 10 | .idea/compiler.xml 11 | .idea/libraries/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | out/ 16 | !**/src/main/**/out/ 17 | !**/src/test/**/out/ 18 | .sign 19 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/.idea/.name: -------------------------------------------------------------------------------- 1 | zenstack -------------------------------------------------------------------------------- /packages/ide/jetbrains/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/gradle.properties: -------------------------------------------------------------------------------- 1 | # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib 2 | kotlin.stdlib.default.dependency=false 3 | # Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html 4 | org.gradle.configuration-cache=false 5 | # Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html 6 | org.gradle.caching=true 7 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/ide/jetbrains/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /packages/ide/jetbrains/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jetbrains", 3 | "version": "2.15.1", 4 | "displayName": "ZenStack JetBrains IDE Plugin", 5 | "description": "ZenStack JetBrains IDE plugin", 6 | "homepage": "https://zenstack.dev", 7 | "private": true, 8 | "scripts": { 9 | "build": "run-script-os", 10 | "build:win32": "gradlew.bat buildPlugin", 11 | "build:default": "./gradlew buildPlugin" 12 | }, 13 | "author": "ZenStack Team", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "@zenstackhq/language": "workspace:*", 17 | "run-script-os": "^1.1.6", 18 | "zenstack": "workspace:*" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenCentral() 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = "zenstack" -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelFileType.kt: -------------------------------------------------------------------------------- 1 | package dev.zenstack.lang 2 | 3 | import com.intellij.openapi.fileTypes.LanguageFileType 4 | import javax.swing.Icon 5 | 6 | object ZModelFileType : LanguageFileType(ZModelLanguage) { 7 | override fun getName(): String = "ZModel" 8 | 9 | override fun getDescription(): String = "ZModel Language" 10 | 11 | override fun getDefaultExtension(): String = "zmodel" 12 | 13 | override fun getIcon(): Icon = ZModelIcons.ZModel 14 | } -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelIcons.kt: -------------------------------------------------------------------------------- 1 | package dev.zenstack.lang 2 | 3 | import com.intellij.openapi.util.IconLoader; 4 | 5 | object ZModelIcons { 6 | @JvmField 7 | val ZModel = IconLoader.getIcon("/icons/zmodel.png", javaClass) 8 | } 9 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lang/ZModelLanguage.kt: -------------------------------------------------------------------------------- 1 | package dev.zenstack.lang 2 | 3 | import com.intellij.lang.Language 4 | 5 | object ZModelLanguage : Language("ZModel") { 6 | override fun getDisplayName(): String = "ZModel" 7 | } 8 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/kotlin/dev/zenstack/lsp/ZenStackLspServerSupportProvider.kt: -------------------------------------------------------------------------------- 1 | package dev.zenstack.lsp 2 | 3 | import com.intellij.javascript.nodejs.interpreter.NodeJsInterpreterManager 4 | import com.intellij.javascript.nodejs.interpreter.local.NodeJsLocalInterpreter 5 | import com.intellij.javascript.nodejs.interpreter.wsl.WslNodeInterpreter 6 | import com.intellij.openapi.project.Project 7 | import com.intellij.openapi.vfs.VirtualFile 8 | import com.intellij.platform.lsp.api.LspServerSupportProvider 9 | import dev.zenstack.lang.ZModelFileType 10 | 11 | class ZenStackLspServerSupportProvider : LspServerSupportProvider { 12 | override fun fileOpened(project: Project, file: VirtualFile, serverStarter: LspServerSupportProvider.LspServerStarter) { 13 | if (file.fileType != ZModelFileType) return 14 | 15 | val node = NodeJsInterpreterManager.getInstance(project).interpreter 16 | if (node !is NodeJsLocalInterpreter && node !is WslNodeInterpreter) return 17 | 18 | serverStarter.ensureServerStarted(ZenStackLspServerDescriptor(project)) 19 | } 20 | } -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/kotlin/dev/zenstack/plugin/PluginStateListener.kt: -------------------------------------------------------------------------------- 1 | package dev.zenstack.plugin 2 | 3 | import com.intellij.ide.plugins.DynamicPluginListener 4 | import com.intellij.ide.plugins.IdeaPluginDescriptor 5 | import dev.zenstack.Utils 6 | import org.jetbrains.plugins.textmate.TextMateService 7 | 8 | class PluginStateListener: DynamicPluginListener { 9 | override fun beforePluginLoaded(pluginDescriptor: IdeaPluginDescriptor) { 10 | // install TextMate bundle 11 | Utils.Companion.addTextMateBundle() 12 | } 13 | 14 | override fun beforePluginUnload(pluginDescriptor: IdeaPluginDescriptor, isUpdate: Boolean) { 15 | // uninstall TextMate bundle 16 | Utils.disableTextMateBundle() 17 | } 18 | } -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/resources/META-INF/pluginIcon_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/resources/icons/zmodel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/ide/jetbrains/src/main/resources/icons/zmodel.png -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/resources/icons/zmodel_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/ide/jetbrains/src/main/resources/icons/zmodel_dark.png -------------------------------------------------------------------------------- /packages/ide/jetbrains/src/main/textMate/zmodel.tmbundle/info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | contactEmailRot13 6 | contact@zenstack.dev 7 | contactName 8 | ZenStack Team 9 | description 10 | ZModel Language 11 | name 12 | zmodel 13 | uuid 14 | 0EA94AB2-A210-4A58-9A25-CFFF59AC430B 15 | 16 | 17 | -------------------------------------------------------------------------------- /packages/language/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": "src/generated/*", 3 | "extends": ["../../.eslintrc.json"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/language/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/language/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LICENSE -------------------------------------------------------------------------------- /packages/language/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack ZModel language compiler 2 | 3 | This package provides the AST of ZModel - ZenStack's modeling language. 4 | 5 | Visit [Homepage](https://zenstack.dev) for more details. 6 | -------------------------------------------------------------------------------- /packages/language/langium-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "ZModel", 3 | "languages": [ 4 | { 5 | "id": "zmodel", 6 | "grammar": "src/zmodel.langium", 7 | "fileExtensions": [".zmodel"], 8 | "textMate": { 9 | "out": "syntaxes/zmodel.tmLanguage.json" 10 | } 11 | } 12 | ], 13 | "out": "src/generated" 14 | } 15 | -------------------------------------------------------------------------------- /packages/language/script/generate-plist.ts: -------------------------------------------------------------------------------- 1 | // convert textmate grammar from json to plist with fixes 2 | 3 | import { json2plist } from 'plist2'; 4 | import fs from 'fs'; 5 | import path from 'path'; 6 | 7 | const src = fs.readFileSync(path.resolve(__dirname, '../syntaxes/zmodel.tmLanguage.json'), 'utf-8'); 8 | const json = JSON.parse(src); 9 | json['fileTypes'] = ['zmodel']; 10 | 11 | const plist = json2plist(JSON.stringify(json)); 12 | fs.writeFileSync(path.resolve(__dirname, '../syntaxes/zmodel.tmLanguage'), plist, 'utf-8'); 13 | -------------------------------------------------------------------------------- /packages/language/src/generated/module.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by langium-cli 1.3.1. 3 | * DO NOT EDIT MANUALLY! 4 | ******************************************************************************/ 5 | 6 | import type { LangiumGeneratedServices, LangiumGeneratedSharedServices, LangiumSharedServices, LangiumServices, LanguageMetaData, Module } from 'langium'; 7 | import { ZModelAstReflection } from './ast'; 8 | import { ZModelGrammar } from './grammar'; 9 | 10 | export const ZModelLanguageMetaData = { 11 | languageId: 'zmodel', 12 | fileExtensions: ['.zmodel'], 13 | caseInsensitive: false 14 | } as const satisfies LanguageMetaData; 15 | 16 | export const ZModelGeneratedSharedModule: Module = { 17 | AstReflection: () => new ZModelAstReflection() 18 | }; 19 | 20 | export const ZModelGeneratedModule: Module = { 21 | Grammar: () => ZModelGrammar(), 22 | LanguageMetaData: () => ZModelLanguageMetaData, 23 | parser: {} 24 | }; 25 | -------------------------------------------------------------------------------- /packages/language/src/module.ts: -------------------------------------------------------------------------------- 1 | export * from './generated/module'; 2 | -------------------------------------------------------------------------------- /packages/language/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*.ts"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/misc/redwood/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/misc/redwood/LICENSE: -------------------------------------------------------------------------------- 1 | ../../../LICENSE -------------------------------------------------------------------------------- /packages/misc/redwood/bin/cli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('../dist/setup-package').default(); 4 | -------------------------------------------------------------------------------- /packages/misc/redwood/src/index.ts: -------------------------------------------------------------------------------- 1 | import { makePassthroughCommand } from './cli-passthrough'; 2 | import setup from './commands/setup'; 3 | 4 | export const commands = [ 5 | setup, 6 | makePassthroughCommand('generate'), 7 | makePassthroughCommand('info'), 8 | makePassthroughCommand('format'), 9 | makePassthroughCommand('repl'), 10 | ]; 11 | export * from './graphql'; 12 | -------------------------------------------------------------------------------- /packages/misc/redwood/src/setup-package.ts: -------------------------------------------------------------------------------- 1 | import yargs from 'yargs'; 2 | import { hideBin } from 'yargs/helpers'; 3 | import setupCommand from './commands/setup'; 4 | 5 | export default async function setupPackage() { 6 | await yargs(hideBin(process.argv)) 7 | .scriptName('zenstack-setup') 8 | // @ts-expect-error yargs types are wrong 9 | .command('$0', 'set up ZenStack', setupCommand.builder, setupCommand.handler) 10 | .parseAsync(); 11 | } 12 | -------------------------------------------------------------------------------- /packages/misc/redwood/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { getPaths } from '@redwoodjs/cli-helpers'; 2 | import execa from 'execa'; 3 | 4 | /** 5 | * Utility for adding npm dependencies to "api" package 6 | */ 7 | export const addApiPackages = (apiPackages: { pkg: string; dev?: boolean }[]) => ({ 8 | title: 'Adding required api packages...', 9 | task: async () => { 10 | const devPkgs = apiPackages.filter((p) => p.dev).map((p) => p.pkg); 11 | if (devPkgs.length > 0) { 12 | await execa('yarn', ['add', '-D', ...devPkgs], { cwd: getPaths().api.base }); 13 | } 14 | 15 | const runtimePkgs = apiPackages.filter((p) => !p.dev).map((p) => p.pkg); 16 | if (runtimePkgs.length > 0) { 17 | await execa('yarn', ['add', ...runtimePkgs], { cwd: getPaths().api.base }); 18 | } 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /packages/misc/redwood/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "lib": ["ESNext"], 5 | "outDir": "dist" 6 | }, 7 | "include": ["src/**/*.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/plugins/openapi/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/plugins/openapi/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LICENSE -------------------------------------------------------------------------------- /packages/plugins/openapi/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack OpenAPI plugin 2 | 3 | This package contains ZenStack plugin for generating OpenAPI specification. 4 | 5 | Visit [Homepage](https://zenstack.dev) for more details. 6 | -------------------------------------------------------------------------------- /packages/plugins/openapi/jest.config.ts: -------------------------------------------------------------------------------- 1 | ../../../jest.config.ts -------------------------------------------------------------------------------- /packages/plugins/openapi/src/index.ts: -------------------------------------------------------------------------------- 1 | import { PluginError, PluginFunction } from '@zenstackhq/sdk'; 2 | import { RESTfulOpenAPIGenerator } from './rest-generator'; 3 | import { RPCOpenAPIGenerator } from './rpc-generator'; 4 | 5 | export const name = 'OpenAPI'; 6 | 7 | const run: PluginFunction = async (model, options, dmmf) => { 8 | if (!dmmf) { 9 | throw new Error('DMMF is required'); 10 | } 11 | 12 | const flavor = options.flavor ? (options.flavor as string) : 'rpc'; 13 | 14 | switch (flavor) { 15 | case 'rest': 16 | return new RESTfulOpenAPIGenerator(model, options, dmmf).generate(); 17 | case 'rpc': 18 | return new RPCOpenAPIGenerator(model, options, dmmf).generate(); 19 | default: 20 | throw new PluginError(name, `Unknown flavor: ${flavor}`); 21 | } 22 | }; 23 | 24 | export default run; 25 | -------------------------------------------------------------------------------- /packages/plugins/openapi/src/meta.ts: -------------------------------------------------------------------------------- 1 | import { getObjectLiteral } from '@zenstackhq/sdk'; 2 | import { DataModel } from '@zenstackhq/sdk/ast'; 3 | 4 | /** 5 | * Metadata for a resource, expressed by @@openapi.meta attribute. 6 | */ 7 | export type ModelMeta = { 8 | tagDescription?: string; 9 | security?: Array>; 10 | }; 11 | 12 | /** 13 | * Metadata for a resource operation, expressed by @@openapi.meta attribute. 14 | */ 15 | export type OperationMeta = { 16 | ignore?: boolean; 17 | method?: string; 18 | path?: string; 19 | summary?: string; 20 | description?: string; 21 | tags?: string[]; 22 | deprecated?: boolean; 23 | security?: Array>; 24 | }; 25 | 26 | /** 27 | * Metadata for a resource, expressed by @@openapi.meta attribute. 28 | */ 29 | export type ResourceMeta = ModelMeta & Record; 30 | 31 | export function getModelResourceMeta(model: DataModel) { 32 | return getObjectLiteral( 33 | model.attributes.find((attr) => attr.decl.ref?.name === '@@openapi.meta')?.args[0].value 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /packages/plugins/openapi/src/plugin.zmodel: -------------------------------------------------------------------------------- 1 | /** 2 | * Mark a data model to be ignored when generating OpenAPI specification. 3 | */ 4 | attribute @@openapi.ignore() 5 | 6 | /** 7 | * Provide metadata for a data model for generating OpenAPI specification. 8 | */ 9 | attribute @@openapi.meta(_ meta: Object) 10 | -------------------------------------------------------------------------------- /packages/plugins/openapi/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "strictPropertyInitialization": false 6 | }, 7 | "include": ["src/**/*.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/plugins/prisma-types.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | /// Types copied over from Prisma's generated code to avoid being broken due to Prisma upgrades 3 | 4 | export type Enumerable = T | Array; 5 | 6 | type _TupleToUnion = T extends (infer E)[] ? E : never; 7 | 8 | export type TupleToUnion = _TupleToUnion; 9 | 10 | export type MaybeTupleToUnion = T extends any[] ? TupleToUnion : T; 11 | 12 | export type PickEnumerable | keyof T> = Pick>; 13 | 14 | type SelectAndInclude = { 15 | select: any; 16 | include: any; 17 | }; 18 | type HasSelect = { 19 | select: any; 20 | }; 21 | type HasInclude = { 22 | include: any; 23 | }; 24 | 25 | export type CheckSelect = T extends SelectAndInclude 26 | ? 'Please either choose `select` or `include`' 27 | : T extends HasSelect 28 | ? U 29 | : T extends HasInclude 30 | ? U 31 | : S; 32 | -------------------------------------------------------------------------------- /packages/plugins/swr/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/plugins/swr/LICENSE: -------------------------------------------------------------------------------- 1 | ../../../LICENSE -------------------------------------------------------------------------------- /packages/plugins/swr/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack React plugin & runtime 2 | 3 | This package contains ZenStack plugin and runtime for ReactJS. 4 | 5 | Visit [Homepage](https://zenstack.dev) for more details. 6 | -------------------------------------------------------------------------------- /packages/plugins/swr/jest.config.ts: -------------------------------------------------------------------------------- 1 | ../../../jest.config.ts -------------------------------------------------------------------------------- /packages/plugins/swr/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { PluginFunction } from '@zenstackhq/sdk'; 2 | import { generate } from './generator'; 3 | 4 | export const name = 'SWR'; 5 | 6 | const run: PluginFunction = async (model, options, dmmf) => { 7 | if (!dmmf) { 8 | throw new Error('DMMF is required'); 9 | } 10 | return generate(model, options, dmmf); 11 | }; 12 | 13 | export default run; 14 | -------------------------------------------------------------------------------- /packages/plugins/swr/src/runtime/prisma-types.ts: -------------------------------------------------------------------------------- 1 | ../../../prisma-types.ts -------------------------------------------------------------------------------- /packages/plugins/swr/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "lib": ["ESNext", "DOM"], 5 | "outDir": "dist", 6 | "jsx": "react" 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["src/runtime"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/plugins/swr/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/runtime/index.ts'], 5 | outDir: 'dist/runtime', 6 | splitting: false, 7 | sourcemap: true, 8 | clean: true, 9 | dts: true, 10 | format: ['cjs', 'esm'], 11 | }); 12 | -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/LICENSE: -------------------------------------------------------------------------------- 1 | ../../../LICENSE -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack tanstack-query plugin & runtime 2 | 3 | This package contains ZenStack plugin for generating [tanstack-query](https://tanstack.com/query/latest) hooks. 4 | 5 | Visit [Homepage](https://zenstack.dev) for more details. 6 | -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/jest.config.ts: -------------------------------------------------------------------------------- 1 | ../../../jest.config.ts -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { PluginFunction } from '@zenstackhq/sdk'; 2 | import { generate } from './generator'; 3 | 4 | export const name = 'Tanstack Query'; 5 | 6 | const run: PluginFunction = async (model, options, dmmf) => { 7 | if (!dmmf) { 8 | throw new Error('DMMF is required'); 9 | } 10 | return generate(model, options, dmmf); 11 | }; 12 | 13 | export default run; 14 | -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/src/runtime-v5/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | getQueryKey, 3 | type ExtraMutationOptions, 4 | type ExtraQueryOptions, 5 | type FetchFn, 6 | type QueryError, 7 | } from '../runtime/common'; 8 | export * from '../runtime/prisma-types'; 9 | -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/src/runtime/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | getQueryKey, 3 | type ExtraMutationOptions, 4 | type ExtraQueryOptions, 5 | type FetchFn, 6 | type QueryError, 7 | } from './common'; 8 | export * from './prisma-types'; 9 | -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/src/runtime/prisma-types.ts: -------------------------------------------------------------------------------- 1 | ../../../prisma-types.ts -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "lib": ["ESNext", "DOM"], 5 | "outDir": "dist", 6 | "jsx": "react" 7 | }, 8 | "include": ["src/**/*.ts"], 9 | "exclude": ["src/runtime", "src/runtime-v5"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/tsup-v5.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/runtime-v5/index.ts', 'src/runtime-v5/react.ts', 'src/runtime-v5/vue.ts', 'src/runtime-v5/svelte.ts'], 5 | outDir: 'dist/runtime-v5', 6 | splitting: false, 7 | sourcemap: true, 8 | clean: true, 9 | dts: true, 10 | format: ['cjs', 'esm'], 11 | }); 12 | -------------------------------------------------------------------------------- /packages/plugins/tanstack-query/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/runtime/index.ts', 'src/runtime/react.ts', 'src/runtime/vue.ts', 'src/runtime/svelte.ts'], 5 | outDir: 'dist/runtime', 6 | splitting: false, 7 | sourcemap: true, 8 | clean: true, 9 | dts: true, 10 | format: ['cjs', 'esm'], 11 | }); 12 | -------------------------------------------------------------------------------- /packages/plugins/trpc/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/plugins/trpc/LICENSE: -------------------------------------------------------------------------------- 1 | ../../../LICENSE -------------------------------------------------------------------------------- /packages/plugins/trpc/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack tRPC plugin 2 | 3 | This package contains ZenStack plugin for tRPC. The implementation is based on [prisma-trpc-generator](https://github.com/omar-dulaimi/prisma-trpc-generator). 4 | 5 | Visit [Homepage](https://zenstack.dev) for more details. 6 | -------------------------------------------------------------------------------- /packages/plugins/trpc/jest.config.ts: -------------------------------------------------------------------------------- 1 | ../../../jest.config.ts -------------------------------------------------------------------------------- /packages/plugins/trpc/res/client/v10/next.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import type { AnyRouter } from '@trpc/server'; 4 | import type { NextPageContext } from 'next'; 5 | import { type CreateTRPCNext, createTRPCNext as _createTRPCNext } from '@trpc/next'; 6 | import type { DeepOverrideAtPath } from './utils'; 7 | 8 | export function createTRPCNext< 9 | TRouter extends AnyRouter, 10 | TPath extends string | undefined = undefined, 11 | TSSRContext extends NextPageContext = NextPageContext, 12 | TFlags = null 13 | >(opts: Parameters[0]) { 14 | const r: CreateTRPCNext = _createTRPCNext(opts); 15 | return r as DeepOverrideAtPath, ClientType, TPath>; 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugins/trpc/res/client/v10/nuxt.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import type { AnyRouter } from '@trpc/server'; 4 | import { createTRPCNuxtClient as _createTRPCNuxtClient } from 'trpc-nuxt/client'; 5 | import type { DeepOverrideAtPath } from './utils'; 6 | 7 | export function createTRPCNuxtClient( 8 | opts: Parameters>[0] 9 | ) { 10 | const r = _createTRPCNuxtClient(opts); 11 | return r as DeepOverrideAtPath, TPath>; 12 | } 13 | -------------------------------------------------------------------------------- /packages/plugins/trpc/res/client/v10/react.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import type { AnyRouter } from '@trpc/server'; 4 | import type { CreateTRPCReactOptions } from '@trpc/react-query/shared'; 5 | import { type CreateTRPCReact, createTRPCReact as _createTRPCReact } from '@trpc/react-query'; 6 | import type { DeepOverrideAtPath } from './utils'; 7 | 8 | export function createTRPCReact< 9 | TRouter extends AnyRouter, 10 | TPath extends string | undefined = undefined, 11 | TSSRContext = unknown, 12 | TFlags = null 13 | >(opts?: CreateTRPCReactOptions) { 14 | const r: CreateTRPCReact = _createTRPCReact(opts); 15 | return r as DeepOverrideAtPath, ClientType, TPath>; 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugins/trpc/res/client/v11/next.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; 4 | import type { NextPageContext } from 'next'; 5 | import { type CreateTRPCNext, createTRPCNext as _createTRPCNext } from '@trpc/next'; 6 | import type { DeepOverrideAtPath } from './utils'; 7 | 8 | export function createTRPCNext< 9 | TRouter extends AnyRouter, 10 | TPath extends string | undefined = undefined, 11 | TSSRContext extends NextPageContext = NextPageContext 12 | >(opts: Parameters[0]) { 13 | const r: CreateTRPCNext = _createTRPCNext(opts); 14 | return r as DeepOverrideAtPath, ClientType, TPath>; 15 | } 16 | -------------------------------------------------------------------------------- /packages/plugins/trpc/res/client/v11/nuxt.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; 4 | import { createTRPCNuxtClient as _createTRPCNuxtClient } from 'trpc-nuxt/client'; 5 | import type { DeepOverrideAtPath } from './utils'; 6 | 7 | export function createTRPCNuxtClient( 8 | opts: Parameters>[0] 9 | ) { 10 | const r = _createTRPCNuxtClient(opts); 11 | return r as DeepOverrideAtPath, TPath>; 12 | } 13 | -------------------------------------------------------------------------------- /packages/plugins/trpc/res/client/v11/react.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import type { AnyTRPCRouter as AnyRouter } from '@trpc/server'; 4 | import type { CreateTRPCReactOptions } from '@trpc/react-query/shared'; 5 | import { type CreateTRPCReact, createTRPCReact as _createTRPCReact } from '@trpc/react-query'; 6 | import type { DeepOverrideAtPath } from './utils'; 7 | 8 | export function createTRPCReact< 9 | TRouter extends AnyRouter, 10 | TPath extends string | undefined = undefined, 11 | TSSRContext = unknown 12 | >(opts?: CreateTRPCReactOptions) { 13 | const r: CreateTRPCReact = _createTRPCReact(opts); 14 | return r as DeepOverrideAtPath, ClientType, TPath>; 15 | } 16 | -------------------------------------------------------------------------------- /packages/plugins/trpc/res/client/v11/utils.ts: -------------------------------------------------------------------------------- 1 | ../v10/utils.ts -------------------------------------------------------------------------------- /packages/plugins/trpc/src/client-helper/next.ts: -------------------------------------------------------------------------------- 1 | import { CodeBlockWriter, SourceFile } from 'ts-morph'; 2 | import { 3 | generateProcedureTyping as generateProcedureTypingForReact, 4 | generateRouterTypingImports as generateRouterTypingImportsForReact, 5 | } from './react'; 6 | 7 | export function generateRouterTypingImports(sourceFile: SourceFile, version: string) { 8 | // next shares the same typing imports as react 9 | generateRouterTypingImportsForReact(sourceFile, version); 10 | } 11 | 12 | export function generateProcedureTyping( 13 | writer: CodeBlockWriter, 14 | opType: string, 15 | modelName: string, 16 | baseOpType: string, 17 | version: string 18 | ) { 19 | // next shares the same procedure typing as react 20 | generateProcedureTypingForReact(writer, opType, modelName, baseOpType, version); 21 | } 22 | -------------------------------------------------------------------------------- /packages/plugins/trpc/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { PluginFunction } from '@zenstackhq/sdk'; 2 | import { generate } from './generator'; 3 | 4 | export const name = 'tRPC'; 5 | export const dependencies = ['@core/zod']; 6 | 7 | const run: PluginFunction = async (model, options, dmmf) => { 8 | if (!dmmf) { 9 | throw new Error('DMMF is required'); 10 | } 11 | return generate(model, options, dmmf); 12 | }; 13 | 14 | export default run; 15 | -------------------------------------------------------------------------------- /packages/plugins/trpc/src/project.ts: -------------------------------------------------------------------------------- 1 | import { Project, ScriptTarget, ModuleKind, CompilerOptions } from 'ts-morph'; 2 | 3 | const compilerOptions: CompilerOptions = { 4 | target: ScriptTarget.ES2019, 5 | module: ModuleKind.CommonJS, 6 | emitDecoratorMetadata: true, 7 | experimentalDecorators: true, 8 | esModuleInterop: true, 9 | skipLibCheck: true, 10 | }; 11 | 12 | export const project = new Project({ 13 | compilerOptions: { 14 | ...compilerOptions, 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | 26 | *.db 27 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | compatibilityDate: '2024-04-03', 4 | devtools: { enabled: true }, 5 | build: { 6 | transpile: ['trpc-nuxt'], 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-app", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "nuxt typecheck && nuxt build", 7 | "dev": "nuxt dev", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview", 10 | "postinstall": "nuxt prepare" 11 | }, 12 | "dependencies": { 13 | "@prisma/client": "6.8.x", 14 | "@trpc/client": "^10.45.2", 15 | "@trpc/server": "^10.45.2", 16 | "nuxt": "^3.14.1592", 17 | "trpc-nuxt": "^0.10.22", 18 | "vue": "latest", 19 | "vue-router": "latest", 20 | "zod": "^3.22.4" 21 | }, 22 | "devDependencies": { 23 | "esbuild": "^0.24.0", 24 | "prisma": "6.8.x", 25 | "typescript": "^5.6.2", 26 | "vue-tsc": "^2.1.10" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/plugins/client.ts: -------------------------------------------------------------------------------- 1 | import { httpBatchLink } from 'trpc-nuxt/client'; 2 | import type { AppRouter } from '~/server/trpc/routers'; 3 | import { createTRPCNuxtClient } from '~/server/trpc/routers/generated/client/nuxt'; 4 | 5 | export default defineNuxtPlugin(() => { 6 | /** 7 | * createTRPCNuxtClient adds a `useQuery` composable 8 | * built on top of `useAsyncData`. 9 | */ 10 | const client = createTRPCNuxtClient({ 11 | links: [ 12 | httpBatchLink({ 13 | url: '/api/trpc', 14 | }), 15 | ], 16 | }); 17 | 18 | return { 19 | provide: { 20 | client, 21 | }, 22 | }; 23 | }); 24 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////////////////// 2 | // DO NOT MODIFY THIS FILE // 3 | // This file is automatically generated by ZenStack CLI and should not be manually updated. // 4 | ////////////////////////////////////////////////////////////////////////////////////////////// 5 | 6 | datasource db { 7 | provider = "sqlite" 8 | url = "file:./dev.db" 9 | } 10 | 11 | generator client { 12 | provider = "prisma-client-js" 13 | } 14 | 15 | model User { 16 | id String @id() @default(cuid()) 17 | email String @unique() 18 | password String 19 | posts Post[] 20 | } 21 | 22 | model Post { 23 | id String @id() @default(cuid()) 24 | createdAt DateTime @default(now()) 25 | updatedAt DateTime @updatedAt() 26 | title String 27 | content String 28 | published Boolean @default(false) 29 | author User @relation(fields: [authorId], references: [id]) 30 | authorId String 31 | } 32 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/public/favicon.ico -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/api/trpc/[trpc].ts: -------------------------------------------------------------------------------- 1 | import { createNuxtApiHandler } from 'trpc-nuxt'; 2 | import { appRouter } from '../../trpc/routers'; 3 | import { createContext } from '../../trpc/context'; 4 | 5 | // export API handler 6 | export default createNuxtApiHandler({ 7 | router: appRouter, 8 | createContext, 9 | }); 10 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client'; 2 | 3 | export const prisma = new PrismaClient(); 4 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/context.ts: -------------------------------------------------------------------------------- 1 | import { inferAsyncReturnType } from '@trpc/server'; 2 | import { prisma } from '../db'; 3 | 4 | /** 5 | * Creates context for an incoming request 6 | * @link https://trpc.io/docs/context 7 | */ 8 | export const createContext = () => ({ 9 | prisma, 10 | }); 11 | 12 | export type Context = inferAsyncReturnType; 13 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/generated/client/nuxt.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI 2.9.0. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | // @ts-nocheck 7 | 8 | import type { AnyRouter } from '@trpc/server'; 9 | import { createTRPCNuxtClient as _createTRPCNuxtClient } from 'trpc-nuxt/client'; 10 | import type { DeepOverrideAtPath } from './utils'; 11 | import { ClientType as UserClientType } from "./User.nuxt.type"; 12 | import { ClientType as PostClientType } from "./Post.nuxt.type"; 13 | 14 | export function createTRPCNuxtClient( 15 | opts: Parameters>[0] 16 | ) { 17 | const r = _createTRPCNuxtClient(opts); 18 | return r as DeepOverrideAtPath, TPath>; 19 | } 20 | 21 | export interface ClientType { 22 | user: UserClientType; 23 | post: PostClientType; 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { publicProcedure, router } from '../trpc'; 2 | import { createRouter as createCRUDRouter } from './generated/routers'; 3 | 4 | export const appRouter = createCRUDRouter(router, publicProcedure); 5 | 6 | // export type definition of API 7 | export type AppRouter = typeof appRouter; 8 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/trpc/trpc.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is your entry point to setup the root configuration for tRPC on the server. 3 | * - `initTRPC` should only be used once per app. 4 | * - We export only the functionality that we use so we can enforce which base procedures should be used 5 | * 6 | * Learn how to create protected base procedures and other things below: 7 | * @see https://trpc.io/docs/v10/router 8 | * @see https://trpc.io/docs/v10/procedures 9 | */ 10 | import { initTRPC } from '@trpc/server'; 11 | import { Context } from './context'; 12 | 13 | const t = initTRPC.context().create(); 14 | 15 | /** 16 | * Unprotected procedure 17 | **/ 18 | export const publicProcedure = t.procedure; 19 | export const router = t.router; 20 | export const middleware = t.middleware; 21 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v10/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json", 4 | "compilerOptions": { 5 | "verbatimModuleSyntax": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | 26 | *.db 27 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | compatibilityDate: '2024-04-03', 4 | devtools: { enabled: true }, 5 | build: { 6 | transpile: ['trpc-nuxt'], 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-app", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "nuxt typecheck && nuxt build", 7 | "dev": "nuxt dev", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview", 10 | "postinstall": "nuxt prepare" 11 | }, 12 | "dependencies": { 13 | "@prisma/client": "6.8.x", 14 | "@trpc/client": "^11.0.0-rc.563", 15 | "@trpc/server": "^11.0.0-rc.563", 16 | "nuxt": "^3.14.1592", 17 | "trpc-nuxt": "^0.11.0-beta.1", 18 | "vue": "latest", 19 | "vue-router": "latest", 20 | "zod": "^3.22.4" 21 | }, 22 | "devDependencies": { 23 | "esbuild": "^0.24.0", 24 | "prisma": "6.8.x", 25 | "typescript": "^5.6.2", 26 | "vue-tsc": "^2.1.10" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/plugins/client.ts: -------------------------------------------------------------------------------- 1 | import { httpBatchLink } from 'trpc-nuxt/client'; 2 | import type { AppRouter } from '~/server/trpc/routers'; 3 | import { createTRPCNuxtClient } from '~/server/trpc/routers/generated/client/nuxt'; 4 | 5 | export default defineNuxtPlugin(() => { 6 | /** 7 | * createTRPCNuxtClient adds a `useQuery` composable 8 | * built on top of `useAsyncData`. 9 | */ 10 | const client = createTRPCNuxtClient({ 11 | links: [ 12 | httpBatchLink({ 13 | url: '/api/trpc', 14 | }), 15 | ], 16 | }); 17 | 18 | return { 19 | provide: { 20 | client, 21 | }, 22 | }; 23 | }); 24 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////////////////// 2 | // DO NOT MODIFY THIS FILE // 3 | // This file is automatically generated by ZenStack CLI and should not be manually updated. // 4 | ////////////////////////////////////////////////////////////////////////////////////////////// 5 | 6 | datasource db { 7 | provider = "sqlite" 8 | url = "file:./dev.db" 9 | } 10 | 11 | generator client { 12 | provider = "prisma-client-js" 13 | } 14 | 15 | model User { 16 | id String @id() @default(cuid()) 17 | email String @unique() 18 | password String 19 | posts Post[] 20 | } 21 | 22 | model Post { 23 | id String @id() @default(cuid()) 24 | createdAt DateTime @default(now()) 25 | updatedAt DateTime @updatedAt() 26 | title String 27 | content String 28 | published Boolean @default(false) 29 | author User @relation(fields: [authorId], references: [id]) 30 | authorId String 31 | } 32 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/public/favicon.ico -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/api/trpc/[trpc].ts: -------------------------------------------------------------------------------- 1 | import { createNuxtApiHandler } from 'trpc-nuxt'; 2 | import { appRouter } from '../../trpc/routers'; 3 | import { createContext } from '../../trpc/context'; 4 | 5 | // export API handler 6 | export default createNuxtApiHandler({ 7 | router: appRouter, 8 | createContext, 9 | }); 10 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client'; 2 | 3 | export const prisma = new PrismaClient(); 4 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/context.ts: -------------------------------------------------------------------------------- 1 | import { inferAsyncReturnType } from '@trpc/server'; 2 | import { prisma } from '../db'; 3 | 4 | /** 5 | * Creates context for an incoming request 6 | * @link https://trpc.io/docs/context 7 | */ 8 | export const createContext = () => ({ 9 | prisma, 10 | }); 11 | 12 | export type Context = inferAsyncReturnType; 13 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated-router-helper.ts: -------------------------------------------------------------------------------- 1 | export { router as createTRPCRouter } from '../trpc'; 2 | export { publicProcedure as procedure } from '../trpc'; 3 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/generated/routers/index.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI 2.9.0. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | // @ts-nocheck 7 | 8 | import type { AnyTRPCRouter as AnyRouter } from "@trpc/server"; 9 | import type { PrismaClient } from "@prisma/client"; 10 | import { createTRPCRouter } from "../../generated-router-helper"; 11 | import createUserRouter from "./User.router"; 12 | import createPostRouter from "./Post.router"; 13 | 14 | export function db(ctx: any) { 15 | if (!ctx.prisma) { 16 | throw new Error('Missing "prisma" field in trpc context'); 17 | } 18 | return ctx.prisma as PrismaClient; 19 | } 20 | 21 | export function createRouter() { 22 | return createTRPCRouter({ 23 | user: createUserRouter(), 24 | post: createPostRouter(), 25 | } 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/routers/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter as createCRUDRouter } from './generated/routers'; 2 | 3 | export const appRouter = createCRUDRouter(); 4 | 5 | // export type definition of API 6 | export type AppRouter = typeof appRouter; 7 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/trpc/trpc.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is your entry point to setup the root configuration for tRPC on the server. 3 | * - `initTRPC` should only be used once per app. 4 | * - We export only the functionality that we use so we can enforce which base procedures should be used 5 | * 6 | * Learn how to create protected base procedures and other things below: 7 | * @see https://trpc.io/docs/v10/router 8 | * @see https://trpc.io/docs/v10/procedures 9 | */ 10 | import { initTRPC } from '@trpc/server'; 11 | import { Context } from './context'; 12 | 13 | const t = initTRPC.context().create(); 14 | 15 | /** 16 | * Unprotected procedure 17 | **/ 18 | export const publicProcedure = t.procedure; 19 | export const router = t.router; 20 | export const middleware = t.middleware; 21 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/nuxt-trpc-v11/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json", 4 | "compilerOptions": { 5 | "verbatimModuleSyntax": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # database 12 | /prisma/db.sqlite 13 | /prisma/db.sqlite-journal 14 | 15 | # next.js 16 | /.next/ 17 | /out/ 18 | next-env.d.ts 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # local env files 34 | # do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables 35 | .env 36 | .env*.local 37 | 38 | # vercel 39 | .vercel 40 | 41 | # typescript 42 | *.tsbuildinfo 43 | package-lock.json 44 | package.json -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/next.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful 3 | * for Docker builds. 4 | */ 5 | await import("./src/env.js"); 6 | 7 | /** @type {import("next").NextConfig} */ 8 | const config = { 9 | reactStrictMode: true, 10 | 11 | /** 12 | * If you are using `appDir` then you must comment the below `i18n` config out. 13 | * 14 | * @see https://github.com/vercel/next.js/issues/41980 15 | */ 16 | i18n: { 17 | locales: ["en"], 18 | defaultLocale: "en", 19 | }, 20 | }; 21 | 22 | export default config; 23 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////////////////// 2 | // DO NOT MODIFY THIS FILE // 3 | // This file is automatically generated by ZenStack CLI and should not be manually updated. // 4 | ////////////////////////////////////////////////////////////////////////////////////////////// 5 | 6 | datasource db { 7 | provider = "sqlite" 8 | url = "file:./dev.db" 9 | } 10 | 11 | generator client { 12 | provider = "prisma-client-js" 13 | } 14 | 15 | model User { 16 | id Int @id() @default(autoincrement()) 17 | email String @unique() 18 | posts Post[] 19 | } 20 | 21 | model Post { 22 | id Int @id() @default(autoincrement()) 23 | name String 24 | createdAt DateTime @default(now()) 25 | updatedAt DateTime @updatedAt() 26 | published Boolean @default(false) 27 | author User @relation(fields: [authorId], references: [id]) 28 | authorId Int 29 | 30 | @@index([name]) 31 | } 32 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/plugins/trpc/tests/projects/t3-trpc-v10/public/favicon.ico -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/schema.zmodel: -------------------------------------------------------------------------------- 1 | // This is your Prisma schema file, 2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 3 | 4 | generator client { 5 | provider = "prisma-client-js" 6 | } 7 | 8 | datasource db { 9 | provider = "sqlite" 10 | url = "file:./dev.db" 11 | } 12 | 13 | plugin trpc { 14 | provider = "../../../dist" 15 | output = "src/server/api/routers/generated" 16 | generateClientHelpers = "next" 17 | } 18 | 19 | model User { 20 | id Int @id @default(autoincrement()) 21 | email String @unique 22 | posts Post[] 23 | } 24 | 25 | model Post { 26 | id Int @id @default(autoincrement()) 27 | name String 28 | createdAt DateTime @default(now()) 29 | updatedAt DateTime @updatedAt 30 | published Boolean @default(false) 31 | author User @relation(fields: [authorId], references: [id]) 32 | authorId Int 33 | 34 | @@index([name]) 35 | } 36 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { type AppType } from "next/app"; 2 | 3 | import { api } from "~/utils/api"; 4 | 5 | import "~/styles/globals.css"; 6 | 7 | const MyApp: AppType = ({ Component, pageProps }) => { 8 | return ; 9 | }; 10 | 11 | export default api.withTRPC(MyApp); 12 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/src/pages/api/trpc/[trpc].ts: -------------------------------------------------------------------------------- 1 | import { createNextApiHandler } from "@trpc/server/adapters/next"; 2 | 3 | import { env } from "~/env"; 4 | import { appRouter } from "~/server/api/root"; 5 | import { createTRPCContext } from "~/server/api/trpc"; 6 | 7 | // export API handler 8 | export default createNextApiHandler({ 9 | router: appRouter, 10 | createContext: createTRPCContext, 11 | onError: 12 | env.NODE_ENV === "development" 13 | ? ({ path, error }) => { 14 | console.error( 15 | `❌ tRPC failed on ${path ?? ""}: ${error.message}` 16 | ); 17 | } 18 | : undefined, 19 | }); 20 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/root.ts: -------------------------------------------------------------------------------- 1 | import { greetRouter } from '~/server/api/routers/greet'; 2 | import { createTRPCRouter } from '~/server/api/trpc'; 3 | import { postRouter } from './routers/post'; 4 | 5 | /** 6 | * This is the primary router for your server. 7 | * 8 | * All routers added in /api/routers should be manually added here. 9 | */ 10 | export const appRouter = createTRPCRouter({ 11 | greet: greetRouter, 12 | post: postRouter, 13 | }); 14 | 15 | // export type definition of API 16 | export type AppRouter = typeof appRouter; 17 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/greet.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | 3 | import { createTRPCRouter, publicProcedure } from '~/server/api/trpc'; 4 | 5 | export const greetRouter = createTRPCRouter({ 6 | hello: publicProcedure.input(z.object({ text: z.string() })).query(({ input }) => { 7 | return { 8 | greeting: `Hello ${input.text}`, 9 | }; 10 | }), 11 | }); 12 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/api/routers/post.ts: -------------------------------------------------------------------------------- 1 | import { createTRPCRouter, publicProcedure } from '../trpc'; 2 | import { createRouter } from './generated/routers'; 3 | 4 | export const postRouter = createRouter(createTRPCRouter, publicProcedure); 5 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/src/server/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from "@prisma/client"; 2 | 3 | import { env } from "~/env"; 4 | 5 | const globalForPrisma = globalThis as unknown as { 6 | prisma: PrismaClient | undefined; 7 | }; 8 | 9 | export const db = 10 | globalForPrisma.prisma ?? 11 | new PrismaClient({ 12 | log: 13 | env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], 14 | }); 15 | 16 | if (env.NODE_ENV !== "production") globalForPrisma.prisma = db; 17 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/src/styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | } 8 | 9 | a { 10 | color: inherit; 11 | text-decoration: none; 12 | } 13 | 14 | * { 15 | box-sizing: border-box; 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v10/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Base Options: */ 4 | "esModuleInterop": true, 5 | "skipLibCheck": true, 6 | "target": "es2022", 7 | "allowJs": true, 8 | "resolveJsonModule": true, 9 | "moduleDetection": "force", 10 | "isolatedModules": true, 11 | 12 | /* Strictness */ 13 | "strict": true, 14 | "noUncheckedIndexedAccess": true, 15 | "checkJs": true, 16 | 17 | /* Bundled projects */ 18 | "lib": ["dom", "dom.iterable", "ES2022"], 19 | "noEmit": true, 20 | "module": "ESNext", 21 | "moduleResolution": "Bundler", 22 | "jsx": "preserve", 23 | "plugins": [{ "name": "next" }], 24 | "incremental": true, 25 | 26 | /* Path Aliases */ 27 | "baseUrl": ".", 28 | "paths": { 29 | "~/*": ["./src/*"] 30 | } 31 | }, 32 | "include": [ 33 | ".eslintrc.cjs", 34 | "next-env.d.ts", 35 | "**/*.ts", 36 | "**/*.tsx", 37 | "**/*.cjs", 38 | "**/*.js", 39 | ".next/types/**/*.ts" 40 | ], 41 | "exclude": ["node_modules"] 42 | } 43 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # database 12 | /prisma/db.sqlite 13 | /prisma/db.sqlite-journal 14 | db.sqlite 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | next-env.d.ts 20 | 21 | # production 22 | /build 23 | 24 | # misc 25 | .DS_Store 26 | *.pem 27 | 28 | # debug 29 | npm-debug.log* 30 | yarn-debug.log* 31 | yarn-error.log* 32 | .pnpm-debug.log* 33 | 34 | # local env files 35 | # do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables 36 | .env 37 | .env*.local 38 | 39 | # vercel 40 | .vercel 41 | 42 | # typescript 43 | *.tsbuildinfo 44 | 45 | # idea files 46 | .idea -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/next.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful 3 | * for Docker builds. 4 | */ 5 | await import("./src/env.js"); 6 | 7 | /** @type {import("next").NextConfig} */ 8 | const config = {}; 9 | 10 | export default config; 11 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////////////////// 2 | // DO NOT MODIFY THIS FILE // 3 | // This file is automatically generated by ZenStack CLI and should not be manually updated. // 4 | ////////////////////////////////////////////////////////////////////////////////////////////// 5 | 6 | datasource db { 7 | provider = "sqlite" 8 | url = "file:./dev.db" 9 | } 10 | 11 | generator client { 12 | provider = "prisma-client-js" 13 | } 14 | 15 | model User { 16 | id Int @id() @default(autoincrement()) 17 | email String @unique() 18 | posts Post[] 19 | } 20 | 21 | model Post { 22 | id Int @id() @default(autoincrement()) 23 | name String 24 | createdAt DateTime @default(now()) 25 | updatedAt DateTime @updatedAt() 26 | published Boolean @default(false) 27 | author User @relation(fields: [authorId], references: [id]) 28 | authorId Int 29 | 30 | @@index([name]) 31 | } 32 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/plugins/trpc/tests/projects/t3-trpc-v11/public/favicon.ico -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import "~/styles/globals.css"; 2 | 3 | import { GeistSans } from "geist/font/sans"; 4 | import { type Metadata } from "next"; 5 | 6 | import { TRPCReactProvider } from "~/trpc/react"; 7 | 8 | export const metadata: Metadata = { 9 | title: "Create T3 App", 10 | description: "Generated by create-t3-app", 11 | icons: [{ rel: "icon", url: "/favicon.ico" }], 12 | }; 13 | 14 | export default function RootLayout({ 15 | children, 16 | }: Readonly<{ children: React.ReactNode }>) { 17 | return ( 18 | 19 | 20 | {children} 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/root.ts: -------------------------------------------------------------------------------- 1 | import { createCallerFactory } from '~/server/api/trpc'; 2 | import { createRouter } from './routers/generated/routers'; 3 | 4 | /** 5 | * This is the primary router for your server. 6 | * 7 | * All routers added in /api/routers should be manually added here. 8 | */ 9 | export const appRouter = createRouter(); 10 | 11 | // export type definition of API 12 | export type AppRouter = typeof appRouter; 13 | 14 | /** 15 | * Create a server-side caller for the tRPC API. 16 | * @example 17 | * const trpc = createCaller(createContext); 18 | * const res = await trpc.post.all(); 19 | * ^? Post[] 20 | */ 21 | export const createCaller = createCallerFactory(appRouter); 22 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated-router-helper.ts: -------------------------------------------------------------------------------- 1 | export { createTRPCRouter } from '../trpc'; 2 | export { publicProcedure as procedure } from '../trpc'; 3 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/api/routers/generated/routers/index.ts: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * This file was generated by ZenStack CLI 2.9.0. 3 | ******************************************************************************/ 4 | 5 | /* eslint-disable */ 6 | // @ts-nocheck 7 | 8 | import type { AnyTRPCRouter as AnyRouter } from "@trpc/server"; 9 | import type { PrismaClient } from "@prisma/client"; 10 | import { createTRPCRouter } from "../../generated-router-helper"; 11 | import createUserRouter from "./User.router"; 12 | import createPostRouter from "./Post.router"; 13 | 14 | export function db(ctx: any) { 15 | if (!ctx.prisma) { 16 | throw new Error('Missing "prisma" field in trpc context'); 17 | } 18 | return ctx.prisma as PrismaClient; 19 | } 20 | 21 | export function createRouter() { 22 | return createTRPCRouter({ 23 | user: createUserRouter(), 24 | post: createPostRouter(), 25 | } 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/src/server/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from "@prisma/client"; 2 | 3 | import { env } from "~/env"; 4 | 5 | const createPrismaClient = () => 6 | new PrismaClient({ 7 | log: 8 | env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], 9 | }); 10 | 11 | const globalForPrisma = globalThis as unknown as { 12 | prisma: ReturnType | undefined; 13 | }; 14 | 15 | export const db = globalForPrisma.prisma ?? createPrismaClient(); 16 | 17 | if (env.NODE_ENV !== "production") globalForPrisma.prisma = db; 18 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/src/styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | } 8 | 9 | a { 10 | color: inherit; 11 | text-decoration: none; 12 | } 13 | 14 | * { 15 | box-sizing: border-box; 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/src/trpc/query-client.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defaultShouldDehydrateQuery, 3 | QueryClient, 4 | } from "@tanstack/react-query"; 5 | import SuperJSON from "superjson"; 6 | 7 | export const createQueryClient = () => 8 | new QueryClient({ 9 | defaultOptions: { 10 | queries: { 11 | // With SSR, we usually want to set some default staleTime 12 | // above 0 to avoid refetching immediately on the client 13 | staleTime: 30 * 1000, 14 | }, 15 | dehydrate: { 16 | serializeData: SuperJSON.serialize, 17 | shouldDehydrateQuery: (query) => 18 | defaultShouldDehydrateQuery(query) || 19 | query.state.status === "pending", 20 | }, 21 | hydrate: { 22 | deserializeData: SuperJSON.deserialize, 23 | }, 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/src/trpc/server.ts: -------------------------------------------------------------------------------- 1 | import "server-only"; 2 | 3 | import { createHydrationHelpers } from "@trpc/react-query/rsc"; 4 | import { headers } from "next/headers"; 5 | import { cache } from "react"; 6 | 7 | import { createCaller, type AppRouter } from "~/server/api/root"; 8 | import { createTRPCContext } from "~/server/api/trpc"; 9 | import { createQueryClient } from "./query-client"; 10 | 11 | /** 12 | * This wraps the `createTRPCContext` helper and provides the required context for the tRPC API when 13 | * handling a tRPC call from a React Server Component. 14 | */ 15 | const createContext = cache(() => { 16 | const heads = new Headers(headers()); 17 | heads.set("x-trpc-source", "rsc"); 18 | 19 | return createTRPCContext({ 20 | headers: heads, 21 | }); 22 | }); 23 | 24 | const getQueryClient = cache(createQueryClient); 25 | const caller = createCaller(createContext); 26 | 27 | export const { trpc: api, HydrateClient } = createHydrationHelpers( 28 | caller, 29 | getQueryClient 30 | ); 31 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tests/projects/t3-trpc-v11/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Base Options: */ 4 | "esModuleInterop": true, 5 | "skipLibCheck": true, 6 | "target": "es2022", 7 | "allowJs": true, 8 | "resolveJsonModule": true, 9 | "moduleDetection": "force", 10 | "isolatedModules": true, 11 | 12 | /* Strictness */ 13 | "strict": true, 14 | "noUncheckedIndexedAccess": true, 15 | "checkJs": true, 16 | 17 | /* Bundled projects */ 18 | "lib": ["dom", "dom.iterable", "ES2022"], 19 | "noEmit": true, 20 | "module": "ESNext", 21 | "moduleResolution": "Bundler", 22 | "jsx": "preserve", 23 | "plugins": [{ "name": "next" }], 24 | "incremental": true, 25 | 26 | /* Path Aliases */ 27 | "baseUrl": ".", 28 | "paths": { 29 | "~/*": ["./src/*"] 30 | } 31 | }, 32 | "include": [ 33 | ".eslintrc.cjs", 34 | "next-env.d.ts", 35 | "**/*.ts", 36 | "**/*.tsx", 37 | "**/*.cjs", 38 | "**/*.js", 39 | ".next/types/**/*.ts" 40 | ], 41 | "exclude": ["node_modules"] 42 | } 43 | -------------------------------------------------------------------------------- /packages/plugins/trpc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "lib": ["ESNext", "DOM"], 5 | "outDir": "dist" 6 | }, 7 | "include": ["src/**/*.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/runtime/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/runtime/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LICENSE -------------------------------------------------------------------------------- /packages/runtime/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack Runtime Library 2 | 3 | This package is the runtime library supporting web apps built using ZenStack. 4 | 5 | Visit [Homepage](https://zenstack.dev) for more details. 6 | -------------------------------------------------------------------------------- /packages/runtime/jest.config.ts: -------------------------------------------------------------------------------- 1 | ../../jest.config.ts -------------------------------------------------------------------------------- /packages/runtime/res/enhance-edge.d.ts: -------------------------------------------------------------------------------- 1 | export { auth, enhance, type PrismaClient } from '.zenstack/enhance-edge'; 2 | -------------------------------------------------------------------------------- /packages/runtime/res/enhance-edge.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, '__esModule', { value: true }); 3 | 4 | try { 5 | exports.enhance = require('.zenstack/enhance-edge').enhance; 6 | } catch { 7 | exports.enhance = function () { 8 | throw new Error('Generated "enhance" function not found. Please run `zenstack generate` first.'); 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /packages/runtime/res/enhance.d.ts: -------------------------------------------------------------------------------- 1 | export { auth, enhance, type PrismaClient, type Enhanced } from '.zenstack/enhance'; 2 | -------------------------------------------------------------------------------- /packages/runtime/res/enhance.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, '__esModule', { value: true }); 3 | 4 | try { 5 | exports.enhance = require('.zenstack/enhance').enhance; 6 | } catch { 7 | exports.enhance = function () { 8 | throw new Error('Generated "enhance" function not found. Please run `zenstack generate` first.'); 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /packages/runtime/res/model-meta.d.ts: -------------------------------------------------------------------------------- 1 | export { default } from '.zenstack/model-meta'; 2 | -------------------------------------------------------------------------------- /packages/runtime/res/model-meta.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, '__esModule', { value: true }); 3 | 4 | try { 5 | exports.default = require('.zenstack/model-meta').default; 6 | } catch { 7 | exports.default = function () { 8 | throw new Error('Generated model meta not found. Please run `zenstack generate` first.'); 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /packages/runtime/res/models.d.ts: -------------------------------------------------------------------------------- 1 | export * from '.zenstack/models'; 2 | -------------------------------------------------------------------------------- /packages/runtime/res/models.js: -------------------------------------------------------------------------------- 1 | module.exports = require('.zenstack/models'); 2 | -------------------------------------------------------------------------------- /packages/runtime/res/zod/index.d.ts: -------------------------------------------------------------------------------- 1 | export * as models from './models'; 2 | export * as input from './input'; 3 | export * as objects from './objects'; 4 | -------------------------------------------------------------------------------- /packages/runtime/res/zod/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | models: require('./models'), 3 | input: require('./input'), 4 | objects: require('./objects') 5 | }; 6 | -------------------------------------------------------------------------------- /packages/runtime/res/zod/input.d.ts: -------------------------------------------------------------------------------- 1 | export * from '.zenstack/zod/input'; 2 | -------------------------------------------------------------------------------- /packages/runtime/res/zod/input.js: -------------------------------------------------------------------------------- 1 | let schemas; 2 | try { 3 | schemas = require('.zenstack/zod/input'); 4 | } catch {} 5 | 6 | module.exports = schemas && { 7 | ...schemas, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/runtime/res/zod/models.d.ts: -------------------------------------------------------------------------------- 1 | export * from '.zenstack/zod/models'; 2 | -------------------------------------------------------------------------------- /packages/runtime/res/zod/models.js: -------------------------------------------------------------------------------- 1 | let schemas; 2 | try { 3 | schemas = require('.zenstack/zod/models'); 4 | } catch {} 5 | 6 | module.exports = schemas && { 7 | ...schemas, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/runtime/res/zod/objects.d.ts: -------------------------------------------------------------------------------- 1 | export * from '.zenstack/zod/objects'; 2 | -------------------------------------------------------------------------------- /packages/runtime/res/zod/objects.js: -------------------------------------------------------------------------------- 1 | let schemas; 2 | try { 3 | schemas = require('.zenstack/zod/objects'); 4 | } catch {} 5 | 6 | module.exports = schemas && { 7 | ...schemas, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/runtime/src/browser/index.ts: -------------------------------------------------------------------------------- 1 | export * from './serialization'; 2 | -------------------------------------------------------------------------------- /packages/runtime/src/cross/clone.ts: -------------------------------------------------------------------------------- 1 | import { isPlainObject } from 'is-plain-object'; 2 | 3 | /** 4 | * Clones the given object. Only arrays and plain objects are cloned. Other values are returned as is. 5 | */ 6 | export function clone(value: T): T { 7 | if (Array.isArray(value)) { 8 | return value.map((v) => clone(v)) as T; 9 | } 10 | 11 | if (typeof value === 'object') { 12 | if (!value || !isPlainObject(value)) { 13 | return value; 14 | } 15 | 16 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 17 | const result: any = {}; 18 | for (const key of Object.keys(value)) { 19 | result[key] = clone(value[key as keyof T]); 20 | } 21 | return result; 22 | } 23 | 24 | return value; 25 | } 26 | -------------------------------------------------------------------------------- /packages/runtime/src/cross/index.ts: -------------------------------------------------------------------------------- 1 | export * from './clone'; 2 | export * from './model-data-visitor'; 3 | export * from './model-meta'; 4 | export * from './mutator'; 5 | export * from './nested-read-visitor'; 6 | export * from './nested-write-visitor'; 7 | export * from './query-analyzer'; 8 | export * from './types'; 9 | export * from './utils'; 10 | -------------------------------------------------------------------------------- /packages/runtime/src/cross/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Prisma write operation kinds 3 | */ 4 | export const PrismaWriteActions = [ 5 | 'create', 6 | 'createMany', 7 | 'createManyAndReturn', 8 | 'connectOrCreate', 9 | 'update', 10 | 'updateMany', 11 | 'updateManyAndReturn', 12 | 'upsert', 13 | 'connect', 14 | 'disconnect', 15 | 'set', 16 | 'delete', 17 | 'deleteMany', 18 | ] as const; 19 | 20 | /** 21 | * Prisma write operation kinds 22 | */ 23 | export type PrismaWriteActionType = (typeof PrismaWriteActions)[number]; 24 | 25 | /** 26 | * Maybe promise 27 | */ 28 | export type MaybePromise = T | Promise | PromiseLike; 29 | -------------------------------------------------------------------------------- /packages/runtime/src/edge.ts: -------------------------------------------------------------------------------- 1 | export * from './enhance-edge'; 2 | -------------------------------------------------------------------------------- /packages/runtime/src/enhance-edge.d.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error stub for re-exporting generated code 2 | export { auth, enhance } from '.zenstack/enhance-edge'; 3 | -------------------------------------------------------------------------------- /packages/runtime/src/enhance.d.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error stub for re-exporting generated code 2 | export { auth, enhance, type PrismaClient, type Enhanced } from '.zenstack/enhance'; 3 | -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/create-enhancement.ts: -------------------------------------------------------------------------------- 1 | ../node/create-enhancement.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/default-auth.ts: -------------------------------------------------------------------------------- 1 | ../node/default-auth.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/delegate.ts: -------------------------------------------------------------------------------- 1 | ../node/delegate.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/encryption.ts: -------------------------------------------------------------------------------- 1 | ../node/encryption.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/index.ts: -------------------------------------------------------------------------------- 1 | ../node/index.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/json-processor.ts: -------------------------------------------------------------------------------- 1 | ../node/json-processor.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/logger.ts: -------------------------------------------------------------------------------- 1 | ../node/logger.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/omit.ts: -------------------------------------------------------------------------------- 1 | ../node/omit.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/password.ts: -------------------------------------------------------------------------------- 1 | ../node/password.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/policy/check-utils.ts: -------------------------------------------------------------------------------- 1 | import { ModelMeta } from '..'; 2 | import type { DbClientContract } from '../../../types'; 3 | import { PermissionCheckArgs } from '../types'; 4 | import { PolicyUtil } from './policy-utils'; 5 | 6 | export async function checkPermission( 7 | _model: string, 8 | _args: PermissionCheckArgs, 9 | _modelMeta: ModelMeta, 10 | _policyUtils: PolicyUtil, 11 | _prisma: DbClientContract, 12 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 13 | _prismaModule: any 14 | ): Promise { 15 | throw new Error('`check()` API is not supported on edge runtime'); 16 | } 17 | -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/policy/handler.ts: -------------------------------------------------------------------------------- 1 | ../../node/policy/handler.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/policy/index.ts: -------------------------------------------------------------------------------- 1 | ../../node/policy/index.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/policy/policy-utils.ts: -------------------------------------------------------------------------------- 1 | ../../node/policy/policy-utils.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/promise.ts: -------------------------------------------------------------------------------- 1 | ../node/promise.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/proxy.ts: -------------------------------------------------------------------------------- 1 | ../node/proxy.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/query-utils.ts: -------------------------------------------------------------------------------- 1 | ../node/query-utils.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/types.ts: -------------------------------------------------------------------------------- 1 | ../node/types.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/utils.ts: -------------------------------------------------------------------------------- 1 | ../node/utils.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/edge/where-visitor.ts: -------------------------------------------------------------------------------- 1 | ../node/where-visitor.ts -------------------------------------------------------------------------------- /packages/runtime/src/enhancements/node/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../../cross'; 2 | export * from './create-enhancement'; 3 | export * from './types'; 4 | export * from './utils'; 5 | -------------------------------------------------------------------------------- /packages/runtime/src/error.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | export function isPrismaClientKnownRequestError( 3 | err: any 4 | ): err is { code: string; message: string; meta?: Record } { 5 | return findConstructorName(err.__proto__, 'PrismaClientKnownRequestError'); 6 | } 7 | 8 | export function isPrismaClientUnknownRequestError(err: any): err is { message: string } { 9 | return findConstructorName(err.__proto__, 'PrismaClientUnknownRequestError'); 10 | } 11 | 12 | export function isPrismaClientValidationError(err: any): err is { message: string } { 13 | return findConstructorName(err.__proto__, 'PrismaClientValidationError'); 14 | } 15 | 16 | function findConstructorName(proto: any, name: string): boolean { 17 | if (!proto) { 18 | return false; 19 | } 20 | return proto.constructor.name === name || findConstructorName(proto.__proto__, name); 21 | } 22 | -------------------------------------------------------------------------------- /packages/runtime/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './cross'; 3 | export * from './enhance'; 4 | export * from './error'; 5 | export * from './types'; 6 | export * from './validation'; 7 | export * from './version'; 8 | -------------------------------------------------------------------------------- /packages/runtime/src/package.json: -------------------------------------------------------------------------------- 1 | ../package.json -------------------------------------------------------------------------------- /packages/runtime/src/version.ts: -------------------------------------------------------------------------------- 1 | import * as pkgJson from './package.json'; 2 | 3 | /** 4 | * Gets this package's version. 5 | * @returns 6 | */ 7 | export function getVersion() { 8 | return pkgJson.version; 9 | } 10 | -------------------------------------------------------------------------------- /packages/runtime/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "lib": ["ESNext", "DOM"], 5 | "outDir": "dist" 6 | }, 7 | "include": ["src/**/*.ts"], 8 | "exclude": ["src/browser", "src/cross"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/runtime/tsup-browser.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/browser/index.ts'], 5 | outDir: 'dist/browser', 6 | splitting: false, 7 | sourcemap: true, 8 | clean: true, 9 | dts: true, 10 | format: ['cjs', 'esm'], 11 | }); 12 | -------------------------------------------------------------------------------- /packages/runtime/tsup-cross.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/cross/index.ts'], 5 | outDir: 'dist/cross', 6 | splitting: false, 7 | sourcemap: true, 8 | clean: true, 9 | dts: true, 10 | format: ['cjs', 'esm'], 11 | }); 12 | -------------------------------------------------------------------------------- /packages/schema/.gitignore: -------------------------------------------------------------------------------- 1 | /out/ 2 | /tests/coverage/ 3 | /bundle 4 | *.vsix 5 | /bin/post-install.js 6 | .env 7 | -------------------------------------------------------------------------------- /packages/schema/.vscodeignore: -------------------------------------------------------------------------------- 1 | .env 2 | .vscode/** 3 | .vscode-test/** 4 | .gitignore 5 | src 6 | tests 7 | node_modules 8 | bin 9 | build 10 | jest.config.ts 11 | tsconfig.json 12 | dist 13 | README-global.md 14 | -------------------------------------------------------------------------------- /packages/schema/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LICENSE -------------------------------------------------------------------------------- /packages/schema/README-global.md: -------------------------------------------------------------------------------- 1 | ../../README.md -------------------------------------------------------------------------------- /packages/schema/asset/logo-256-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/schema/asset/logo-256-bg.png -------------------------------------------------------------------------------- /packages/schema/asset/logo-dark-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/schema/asset/logo-dark-256.png -------------------------------------------------------------------------------- /packages/schema/asset/logo-light-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenstackhq/zenstack/19f4870599ede6f19fe8f4b954377b518715d9ce/packages/schema/asset/logo-light-256.png -------------------------------------------------------------------------------- /packages/schema/bin/cli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('../cli').default(); 4 | -------------------------------------------------------------------------------- /packages/schema/bin/post-install.js: -------------------------------------------------------------------------------- 1 | try { 2 | if (process.env.DO_NOT_TRACK == '1') { 3 | process.exit(0); 4 | } 5 | 6 | const Mixpanel = require('mixpanel'); 7 | const machineId = require('node-machine-id'); 8 | const os = require('os'); 9 | const isDocker = require('../utils/is-docker').default; 10 | 11 | const mixpanel = Mixpanel.init('', { 12 | geolocate: true, 13 | }); 14 | 15 | const version = require('../package.json').version; 16 | const payload = { 17 | distinct_id: machineId.machineIdSync(), 18 | nodeVersion: process.version, 19 | time: new Date(), 20 | $os: os.type(), 21 | osType: os.type(), 22 | osRelease: os.release(), 23 | osPlatform: os.platform(), 24 | osArch: os.arch(), 25 | osVersion: os.version(), 26 | isDocker: isDocker(), 27 | version, 28 | }; 29 | 30 | mixpanel.track('npm:install', payload); 31 | } catch {} 32 | -------------------------------------------------------------------------------- /packages/schema/build/bundle.js: -------------------------------------------------------------------------------- 1 | const watch = process.argv.includes('--watch'); 2 | const minify = process.argv.includes('--minify'); 3 | const success = watch ? 'Watch build succeeded' : 'Build succeeded'; 4 | const fs = require('fs'); 5 | 6 | require('esbuild') 7 | .build({ 8 | entryPoints: ['src/extension.ts', 'src/language-server/main.ts'], 9 | outdir: 'bundle', 10 | bundle: true, 11 | external: ['vscode', '@prisma/*'], 12 | platform: 'node', 13 | sourcemap: !minify, 14 | minify, 15 | }) 16 | .then(() => { 17 | fs.cpSync('./src/res', 'bundle/res', { force: true, recursive: true }); 18 | fs.cpSync('../language/syntaxes', 'bundle/syntaxes', { force: true, recursive: true }); 19 | }) 20 | .then(() => console.log(success)) 21 | .catch((err) => { 22 | console.error(err); 23 | process.exit(1); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/schema/build/post-build.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config({ path: './.env.local' }); 2 | require('dotenv').config({ path: './.env' }); 3 | const fs = require('fs'); 4 | 5 | const filesToReplace = ['dist/bin/post-install.js', 'dist/constants.js']; 6 | for (const file of filesToReplace) { 7 | let content = fs.readFileSync(file, 'utf-8'); 8 | if (process.env.TELEMETRY_TRACKING_TOKEN) { 9 | content = content.replace('', process.env.TELEMETRY_TRACKING_TOKEN); 10 | } else { 11 | content = content.replace('', ''); 12 | } 13 | console.log('Updating file:', file); 14 | fs.writeFileSync(file, content, { 15 | encoding: 'utf-8', 16 | }); 17 | } 18 | 19 | let cliContent = fs.readFileSync('dist/cli/index.js', 'utf-8'); 20 | if (process.env.DEFAULT_NPM_TAG) { 21 | cliContent = cliContent.replace('', process.env.DEFAULT_NPM_TAG); 22 | } else { 23 | cliContent = cliContent.replace('', 'latest'); 24 | } 25 | 26 | console.log('Updating file: dist/cli/index.js'); 27 | fs.writeFileSync('dist/cli/index.js', cliContent, { 28 | encoding: 'utf-8', 29 | }); 30 | -------------------------------------------------------------------------------- /packages/schema/jest.config.ts: -------------------------------------------------------------------------------- 1 | ../../jest.config.ts -------------------------------------------------------------------------------- /packages/schema/src/cli/actions/check.ts: -------------------------------------------------------------------------------- 1 | import { getDefaultSchemaLocation, loadDocument } from '../cli-util'; 2 | 3 | type Options = { 4 | schema: string; 5 | }; 6 | 7 | /** 8 | * CLI action for checking schema 9 | */ 10 | export async function check(_projectPath: string, options: Options) { 11 | const schema = options.schema ?? getDefaultSchemaLocation(); 12 | await loadDocument(schema); 13 | console.log('The schema is valid.'); 14 | } 15 | -------------------------------------------------------------------------------- /packages/schema/src/cli/actions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './check'; 2 | export * from './format'; 3 | export * from './generate'; 4 | export * from './info'; 5 | export * from './init'; 6 | export * from './repl'; 7 | -------------------------------------------------------------------------------- /packages/schema/src/cli/cli-error.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Indicating an error during CLI execution 3 | */ 4 | export class CliError extends Error {} 5 | -------------------------------------------------------------------------------- /packages/schema/src/constants.ts: -------------------------------------------------------------------------------- 1 | // replaced at build time 2 | export const TELEMETRY_TRACKING_TOKEN = ''; 3 | -------------------------------------------------------------------------------- /packages/schema/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'env' { 2 | export const TELEMETRY_TRACKING_TOKEN: string; 3 | } 4 | -------------------------------------------------------------------------------- /packages/schema/src/language-server/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Supported Prisma db providers 3 | */ 4 | export const SUPPORTED_PROVIDERS = ['sqlite', 'postgresql', 'mysql', 'sqlserver', 'cockroachdb']; 5 | 6 | /** 7 | * All scalar types 8 | */ 9 | export const SCALAR_TYPES = ['String', 'Int', 'Float', 'Decimal', 'BigInt', 'Boolean', 'Bytes', 'DateTime']; 10 | 11 | /** 12 | * Name of standard library module 13 | */ 14 | export const STD_LIB_MODULE_NAME = 'stdlib.zmodel'; 15 | 16 | /** 17 | * Name of module contributed by plugins 18 | */ 19 | export const PLUGIN_MODULE_NAME = 'plugin.zmodel'; 20 | 21 | /** 22 | * Validation issues 23 | */ 24 | export enum IssueCodes { 25 | MissingOppositeRelation = 'miss-opposite-relation', 26 | } 27 | -------------------------------------------------------------------------------- /packages/schema/src/language-server/main.ts: -------------------------------------------------------------------------------- 1 | import { startLanguageServer } from 'langium'; 2 | import { NodeFileSystem } from 'langium/node'; 3 | import { createConnection, ProposedFeatures } from 'vscode-languageserver/node'; 4 | import { createZModelServices } from './zmodel-module'; 5 | 6 | // Create a connection to the client 7 | const connection = createConnection(ProposedFeatures.all); 8 | 9 | // Inject the shared services and language-specific services 10 | const { shared } = createZModelServices({ connection, ...NodeFileSystem }); 11 | 12 | // Start the language server with the shared services 13 | startLanguageServer(shared); 14 | -------------------------------------------------------------------------------- /packages/schema/src/language-server/types.ts: -------------------------------------------------------------------------------- 1 | import { AstNode, ValidationAcceptor } from 'langium'; 2 | 3 | /** 4 | * AST validator contract 5 | */ 6 | export interface AstValidator { 7 | /** 8 | * Validates an AST node 9 | */ 10 | validate(node: T, accept: ValidationAcceptor): void; 11 | } 12 | -------------------------------------------------------------------------------- /packages/schema/src/language-server/validator/attribute-validator.ts: -------------------------------------------------------------------------------- 1 | import { Attribute } from '@zenstackhq/language/ast'; 2 | import { ValidationAcceptor } from 'langium'; 3 | import { AstValidator } from '../types'; 4 | import { validateAttributeApplication } from './attribute-application-validator'; 5 | 6 | /** 7 | * Validates attribute declarations. 8 | */ 9 | export default class AttributeValidator implements AstValidator { 10 | // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function 11 | validate(attr: Attribute, accept: ValidationAcceptor): void { 12 | attr.attributes.forEach((attr) => validateAttributeApplication(attr, accept)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/schema/src/language-server/validator/function-decl-validator.ts: -------------------------------------------------------------------------------- 1 | import { FunctionDecl } from '@zenstackhq/language/ast'; 2 | import { ValidationAcceptor } from 'langium'; 3 | import { AstValidator } from '../types'; 4 | import { validateAttributeApplication } from './attribute-application-validator'; 5 | 6 | /** 7 | * Validates function declarations. 8 | */ 9 | export default class FunctionDeclValidator implements AstValidator { 10 | validate(funcDecl: FunctionDecl, accept: ValidationAcceptor) { 11 | funcDecl.attributes.forEach((attr) => validateAttributeApplication(attr, accept)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/schema/src/language-server/zmodel-documentation-provider.ts: -------------------------------------------------------------------------------- 1 | import { AstNode, JSDocDocumentationProvider } from 'langium'; 2 | 3 | /** 4 | * Documentation provider that first tries to use triple-slash comments and falls back to JSDoc comments. 5 | */ 6 | export class ZModelDocumentationProvider extends JSDocDocumentationProvider { 7 | getDocumentation(node: AstNode): string | undefined { 8 | // prefer to use triple-slash comments 9 | if ('comments' in node && Array.isArray(node.comments) && node.comments.length > 0) { 10 | return node.comments.map((c: string) => c.replace(/^[/]*\s*/, '')).join('\n'); 11 | } 12 | 13 | // fall back to JSDoc comments 14 | return super.getDocumentation(node); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/schema/src/language-server/zmodel-highlight.ts: -------------------------------------------------------------------------------- 1 | import { DefaultDocumentHighlightProvider, LangiumDocument } from 'langium'; 2 | import { DocumentHighlight, DocumentHighlightParams } from 'vscode-languageserver'; 3 | 4 | export class ZModelHighlightProvider extends DefaultDocumentHighlightProvider { 5 | override async getDocumentHighlight( 6 | document: LangiumDocument, 7 | params: DocumentHighlightParams 8 | ): Promise { 9 | try { 10 | return await super.getDocumentHighlight(document, params); 11 | } catch (e) { 12 | console.error('Highlight error:', (e as Error).message); 13 | return undefined; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/schema/src/language-server/zmodel-hover.ts: -------------------------------------------------------------------------------- 1 | import { AstNode, LangiumDocument, MultilineCommentHoverProvider } from 'langium'; 2 | import { Hover, HoverParams } from 'vscode-languageclient'; 3 | 4 | export class ZModelHoverProvider extends MultilineCommentHoverProvider { 5 | override async getHoverContent( 6 | document: LangiumDocument, 7 | params: HoverParams 8 | ): Promise { 9 | try { 10 | return await super.getHoverContent(document, params); 11 | } catch (e) { 12 | console.error('Hover error:', (e as Error).message); 13 | return undefined; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/schema/src/package.json: -------------------------------------------------------------------------------- 1 | ../package.json -------------------------------------------------------------------------------- /packages/schema/src/plugins/enhancer/enhancer-utils.ts: -------------------------------------------------------------------------------- 1 | import { isAuthInvocation } from '@zenstackhq/sdk'; 2 | import type { DataModelFieldAttribute } from '@zenstackhq/sdk/ast'; 3 | import { streamAst } from 'langium'; 4 | 5 | /** 6 | * Check if the given field attribute is a `@default` with `auth()` invocation 7 | */ 8 | export function isDefaultWithAuth(attr: DataModelFieldAttribute) { 9 | if (attr.decl.ref?.name !== '@default') { 10 | return false; 11 | } 12 | 13 | const expr = attr.args[0]?.value; 14 | if (!expr) { 15 | return false; 16 | } 17 | 18 | // find `auth()` in default value expression 19 | return streamAst(expr).some(isAuthInvocation); 20 | } 21 | -------------------------------------------------------------------------------- /packages/schema/src/plugins/enhancer/model-meta/index.ts: -------------------------------------------------------------------------------- 1 | import { generateModelMeta, getDataModels, type PluginOptions } from '@zenstackhq/sdk'; 2 | import { isTypeDef, type Model } from '@zenstackhq/sdk/ast'; 3 | import path from 'path'; 4 | import type { Project } from 'ts-morph'; 5 | 6 | export async function generate(model: Model, options: PluginOptions, project: Project, outDir: string) { 7 | const outFile = path.join(outDir, 'model-meta.ts'); 8 | const dataModels = getDataModels(model); 9 | const typeDefs = model.declarations.filter(isTypeDef); 10 | 11 | // save ts files if requested explicitly or the user provided 12 | const preserveTsFiles = options.preserveTsFiles === true || !!options.output; 13 | await generateModelMeta(project, dataModels, typeDefs, { 14 | output: outFile, 15 | generateAttributes: true, 16 | preserveTsFiles, 17 | shortNameMap: options.shortNameMap, 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/schema/src/plugins/enhancer/policy/index.ts: -------------------------------------------------------------------------------- 1 | import { type PluginOptions } from '@zenstackhq/sdk'; 2 | import type { Model } from '@zenstackhq/sdk/ast'; 3 | import type { Project } from 'ts-morph'; 4 | import { PolicyGenerator } from './policy-guard-generator'; 5 | 6 | export async function generate(model: Model, options: PluginOptions, project: Project, outDir: string) { 7 | return new PolicyGenerator(options).generate(project, model, outDir); 8 | } 9 | -------------------------------------------------------------------------------- /packages/schema/src/plugins/prisma/indent-string.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/sindresorhus/indent-string 2 | 3 | /** 4 | * Utility for indenting strings 5 | */ 6 | export default function indentString(string: string, count = 4): string { 7 | const indent = ' '; 8 | return string.replace(/^(?!\s*$)/gm, indent.repeat(count)); 9 | } 10 | -------------------------------------------------------------------------------- /packages/schema/src/plugins/zod/index.ts: -------------------------------------------------------------------------------- 1 | import { PluginFunction } from '@zenstackhq/sdk'; 2 | import invariant from 'tiny-invariant'; 3 | import { ZodSchemaGenerator } from './generator'; 4 | 5 | export const name = 'Zod'; 6 | export const description = 'Generating Zod schemas'; 7 | 8 | const run: PluginFunction = async (model, options, dmmf, globalOptions) => { 9 | invariant(dmmf); 10 | const generator = new ZodSchemaGenerator(model, options, dmmf, globalOptions); 11 | return generator.generate(); 12 | }; 13 | 14 | export default run; 15 | -------------------------------------------------------------------------------- /packages/schema/src/plugins/zod/types.ts: -------------------------------------------------------------------------------- 1 | import type { Model } from '@zenstackhq/sdk/ast'; 2 | import type { DMMF as PrismaDMMF } from '@zenstackhq/sdk/prisma'; 3 | import { Project } from 'ts-morph'; 4 | 5 | export type TransformerParams = { 6 | enumTypes?: readonly PrismaDMMF.SchemaEnum[]; 7 | fields?: readonly PrismaDMMF.SchemaArg[]; 8 | name?: string; 9 | models?: readonly PrismaDMMF.Model[]; 10 | modelOperations?: PrismaDMMF.ModelMapping[]; 11 | aggregateOperationSupport?: AggregateOperationSupport; 12 | isDefaultPrismaClientOutput?: boolean; 13 | prismaClientOutputPath?: string; 14 | project: Project; 15 | inputObjectTypes: PrismaDMMF.InputType[]; 16 | zmodel: Model; 17 | mode: ObjectMode; 18 | }; 19 | 20 | export type AggregateOperationSupport = { 21 | [model: string]: { 22 | count?: boolean; 23 | min?: boolean; 24 | max?: boolean; 25 | sum?: boolean; 26 | avg?: boolean; 27 | }; 28 | }; 29 | 30 | export type ObjectMode = 'strict' | 'strip' | 'passthrough'; 31 | -------------------------------------------------------------------------------- /packages/schema/src/utils/exec-utils.ts: -------------------------------------------------------------------------------- 1 | import { execSync as _exec, ExecSyncOptions } from 'child_process'; 2 | 3 | /** 4 | * Utility for executing command synchronously and prints outputs on current console 5 | */ 6 | export function execSync(cmd: string, options?: Omit & { env?: Record }): void { 7 | const { env, ...restOptions } = options ?? {}; 8 | const mergedEnv = env ? { ...process.env, ...env } : undefined; 9 | _exec(cmd, { encoding: 'utf-8', stdio: options?.stdio ?? 'inherit', env: mergedEnv, ...restOptions }); 10 | } 11 | 12 | /** 13 | * Utility for running package commands through npx/bunx 14 | */ 15 | export function execPackage(cmd: string, options?: Omit & { env?: Record }): void { 16 | const packageManager = process?.versions?.bun ? 'bunx' : 'npx'; 17 | execSync(`${packageManager} ${cmd}`, options) 18 | } -------------------------------------------------------------------------------- /packages/schema/src/utils/is-docker.ts: -------------------------------------------------------------------------------- 1 | // Copied over from https://github.com/sindresorhus/is-docker for CJS compatibility 2 | 3 | import fs from 'node:fs'; 4 | 5 | let isDockerCached: boolean | undefined; 6 | 7 | function hasDockerEnv() { 8 | try { 9 | fs.statSync('/.dockerenv'); 10 | return true; 11 | } catch { 12 | return false; 13 | } 14 | } 15 | 16 | function hasDockerCGroup() { 17 | try { 18 | return fs.readFileSync('/proc/self/cgroup', 'utf8').includes('docker'); 19 | } catch { 20 | return false; 21 | } 22 | } 23 | 24 | export default function isDocker() { 25 | // TODO: Use `??=` when targeting Node.js 16. 26 | if (isDockerCached === undefined) { 27 | isDockerCached = hasDockerEnv() || hasDockerCGroup(); 28 | } 29 | 30 | return isDockerCached; 31 | } 32 | -------------------------------------------------------------------------------- /packages/schema/src/utils/version-utils.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | export function getVersion(): string | undefined { 3 | try { 4 | return require('../package.json').version; 5 | } catch { 6 | try { 7 | // dev environment 8 | return require('../../package.json').version; 9 | } catch { 10 | return undefined; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/schema/tests/generator/prisma/format.prisma: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////////////////// 2 | // DO NOT MODIFY THIS FILE // 3 | // This file is automatically generated by ZenStack CLI and should not be manually updated. // 4 | ////////////////////////////////////////////////////////////////////////////////////////////// 5 | 6 | datasource db { 7 | provider = "postgresql" 8 | url = env("URL") 9 | } 10 | 11 | /// @@allow('read', published) 12 | model Post { 13 | id Int @id() @default(autoincrement()) 14 | title String 15 | content String? 16 | published Boolean @default(false) 17 | } 18 | -------------------------------------------------------------------------------- /packages/schema/tests/generator/prisma/multi-level-inheritance.prisma: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////////////////////// 2 | // DO NOT MODIFY THIS FILE // 3 | // This file is automatically generated by ZenStack CLI and should not be manually updated. // 4 | ////////////////////////////////////////////////////////////////////////////////////////////// 5 | 6 | datasource db { 7 | provider = "postgresql" 8 | url = env("URL") 9 | } 10 | 11 | /// @@deny('read', deleted) 12 | /// @@allow('all', true) 13 | model Test1 { 14 | id String @id() @default(cuid()) 15 | createdAt DateTime @default(now()) 16 | updatedAt DateTime @updatedAt() 17 | /// @omit 18 | deleted Boolean @default(false) 19 | } 20 | -------------------------------------------------------------------------------- /packages/schema/tests/generator/zmodel/schema.zmodel: -------------------------------------------------------------------------------- 1 | import "user/user" 2 | 3 | datasource db { 4 | provider = 'postgresql' 5 | url = env('URL') 6 | } 7 | 8 | model Post extends Basic { 9 | title String 10 | content String? 11 | 12 | @@allow('delete', owner == auth()) 13 | } 14 | 15 | model Todo extends Basic { 16 | title String 17 | isCompleted Boolean 18 | } -------------------------------------------------------------------------------- /packages/schema/tests/generator/zmodel/user/user.zmodel: -------------------------------------------------------------------------------- 1 | import "../schema" 2 | model User { 3 | id String @id() @default(uuid()) 4 | email String @unique() 5 | name String? 6 | posts Post[] 7 | todos Todo[] 8 | role UserRole 9 | 10 | // make user profile public 11 | @@allow('read', true) 12 | } 13 | 14 | 15 | enum UserRole { 16 | USER 17 | ADMIN 18 | } 19 | 20 | abstract model Basic { 21 | id String @id @default(uuid()) 22 | createdAt DateTime @default(now()) 23 | updatedAt DateTime @updatedAt 24 | owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) 25 | ownerId String 26 | 27 | @@allow('read', owner == auth()) 28 | } -------------------------------------------------------------------------------- /packages/schema/tests/schema/abstract.zmodel: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = 'postgresql' 3 | url = env('DATABASE_URL') 4 | } 5 | 6 | generator js { 7 | provider = 'prisma-client-js' 8 | } 9 | 10 | abstract model Base { 11 | id Int @id @default(autoincrement()) 12 | createdAt DateTime @default(now()) 13 | updatedAt DateTime @updatedAt 14 | user User @relation(fields: [userId], references: [id]) 15 | userId String 16 | } 17 | 18 | 19 | model Post extends Base { 20 | title String 21 | published Boolean @default(false) 22 | } 23 | 24 | model Todo extends Base { 25 | description String 26 | isDone Boolean @default(false) 27 | } 28 | 29 | model User { 30 | id String @id 31 | todos Todo[] 32 | posts Post[] 33 | } -------------------------------------------------------------------------------- /packages/schema/tests/schema/cal-com.test.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import path from 'path'; 3 | import { loadModel } from '../utils'; 4 | 5 | describe('Cal.com Schema Tests', () => { 6 | it('model loading', async () => { 7 | const content = fs.readFileSync(path.join(__dirname, './cal-com.zmodel'), { 8 | encoding: 'utf-8', 9 | }); 10 | await loadModel(content); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/schema/tests/schema/mutil-files/multi-files.test.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { loadDocument } from '../../../src/cli/cli-util'; 3 | 4 | describe('Mutiple files Tests', () => { 5 | it('model loading post', async () => { 6 | await loadDocument(path.join(__dirname, './schema.zmodel')); 7 | }); 8 | 9 | it('model loading user', async () => { 10 | await loadDocument(path.join(__dirname, './user.zmodel')); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/schema/tests/schema/mutil-files/schema.zmodel: -------------------------------------------------------------------------------- 1 | import "user" 2 | 3 | datasource db { 4 | provider="sqlite" 5 | url="file:./dev.db" 6 | } 7 | 8 | generator client { 9 | provider = "prisma-client-js" 10 | } 11 | 12 | 13 | model Post { 14 | id Int @id() @default(autoincrement()) 15 | author User? @relation(fields: [authorId], references: [id]) 16 | authorId Int? 17 | // author has full access 18 | @@allow('all', auth() == author) 19 | } -------------------------------------------------------------------------------- /packages/schema/tests/schema/mutil-files/user.zmodel: -------------------------------------------------------------------------------- 1 | import "schema" 2 | model User { 3 | id Int @id() @default(autoincrement()) 4 | email String @unique() 5 | name String? 6 | posts Post[] 7 | 8 | // make user profile public 9 | @@allow('read', true) 10 | } -------------------------------------------------------------------------------- /packages/schema/tests/schema/sample-todo.test.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import path from 'path'; 3 | import { loadModel } from '../utils'; 4 | 5 | describe('Sample Todo Schema Tests', () => { 6 | it('model loading', async () => { 7 | const content = fs.readFileSync(path.join(__dirname, './todo.zmodel'), { 8 | encoding: 'utf-8', 9 | }); 10 | await loadModel(content); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/schema/tests/schema/trigger-dev.test.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import path from 'path'; 3 | import { loadModel } from '../utils'; 4 | 5 | describe('Trigger.dev Schema Tests', () => { 6 | it('model loading', async () => { 7 | const content = fs.readFileSync(path.join(__dirname, './trigger-dev.zmodel'), { 8 | encoding: 'utf-8', 9 | }); 10 | await loadModel(content); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/schema/tests/schema/validation/enum-validation.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModelWithError } from '../../utils'; 2 | 3 | describe('Enum Validation Tests', () => { 4 | const prelude = ` 5 | datasource db { 6 | provider = "postgresql" 7 | url = "url" 8 | } 9 | `; 10 | 11 | it('duplicated fields', async () => { 12 | expect( 13 | await loadModelWithError(` 14 | ${prelude} 15 | enum E { 16 | A 17 | A 18 | } 19 | `) 20 | ).toContain('Duplicated declaration name "A"'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/schema/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*.ts"], 7 | "exclude": ["src/extension.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/sdk/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/sdk/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LICENSE -------------------------------------------------------------------------------- /packages/sdk/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack plugin development SDK 2 | 3 | This package provides types and utilities for developing a ZenStack plugin. 4 | 5 | Visit [Homepage](https://zenstack.dev) for more details. 6 | -------------------------------------------------------------------------------- /packages/sdk/src/ast.ts: -------------------------------------------------------------------------------- 1 | export * from '@zenstackhq/language/ast'; 2 | -------------------------------------------------------------------------------- /packages/sdk/src/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @zenstackhq/runtime package name 3 | */ 4 | export const RUNTIME_PACKAGE = '@zenstackhq/runtime'; 5 | 6 | export { CrudFailureReason } from '@zenstackhq/runtime'; 7 | 8 | /** 9 | * Expression context 10 | */ 11 | export enum ExpressionContext { 12 | DefaultValue = 'DefaultValue', 13 | AccessPolicy = 'AccessPolicy', 14 | ValidationRule = 'ValidationRule', 15 | Index = 'Index', 16 | } 17 | 18 | export const STD_LIB_MODULE_NAME = 'stdlib.zmodel'; 19 | -------------------------------------------------------------------------------- /packages/sdk/src/dmmf-helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './aggregate-helpers'; 2 | export * from './include-helpers'; 3 | export * from './model-helpers'; 4 | export * from './modelArgs-helpers'; 5 | export * from './select-helpers'; 6 | export * from './types'; 7 | export * from './missing-types-helper'; 8 | -------------------------------------------------------------------------------- /packages/sdk/src/dmmf-helpers/missing-types-helper.ts: -------------------------------------------------------------------------------- 1 | import type { DMMF } from '../prisma'; 2 | import { addMissingInputObjectTypesForAggregate } from './aggregate-helpers'; 3 | import { addMissingInputObjectTypesForInclude } from './include-helpers'; 4 | import { addMissingInputObjectTypesForModelArgs } from './modelArgs-helpers'; 5 | import { addMissingInputObjectTypesForSelect } from './select-helpers'; 6 | 7 | export function addMissingInputObjectTypes( 8 | inputObjectTypes: DMMF.InputType[], 9 | outputObjectTypes: DMMF.OutputType[], 10 | models: DMMF.Model[] 11 | ) { 12 | addMissingInputObjectTypesForAggregate(inputObjectTypes, outputObjectTypes); 13 | addMissingInputObjectTypesForSelect(inputObjectTypes, outputObjectTypes, models); 14 | addMissingInputObjectTypesForModelArgs(inputObjectTypes, models); 15 | addMissingInputObjectTypesForInclude(inputObjectTypes, models); 16 | } 17 | -------------------------------------------------------------------------------- /packages/sdk/src/dmmf-helpers/types.ts: -------------------------------------------------------------------------------- 1 | import type { DMMF } from '../prisma'; 2 | 3 | export type TransformerParams = { 4 | enumTypes?: DMMF.SchemaEnum[]; 5 | fields?: DMMF.SchemaArg[]; 6 | name?: string; 7 | models?: DMMF.Model[]; 8 | modelOperations?: DMMF.ModelMapping[]; 9 | aggregateOperationSupport?: AggregateOperationSupport; 10 | isDefaultPrismaClientOutput?: boolean; 11 | prismaClientOutputPath?: string; 12 | }; 13 | 14 | export type AggregateOperationSupport = { 15 | [model: string]: { 16 | count?: boolean; 17 | min?: boolean; 18 | max?: boolean; 19 | sum?: boolean; 20 | avg?: boolean; 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /packages/sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './code-gen'; 2 | export * from './constants'; 3 | export { generate as generateModelMeta } from './model-meta-generator'; 4 | export * from './names'; 5 | export * from './path'; 6 | export * from './policy'; 7 | export * from './types'; 8 | export * from './typescript-expression-transformer'; 9 | export * from './utils'; 10 | export * from './validation'; 11 | export * from './zmodel-code-generator'; 12 | -------------------------------------------------------------------------------- /packages/sdk/src/names.ts: -------------------------------------------------------------------------------- 1 | import { DataModel, DataModelField } from './ast'; 2 | 3 | /** 4 | * Gets the name of the function that computes a partial Prisma query guard. 5 | */ 6 | export function getQueryGuardFunctionName( 7 | model: DataModel, 8 | forField: DataModelField | undefined, 9 | fieldOverride: boolean, 10 | kind: string 11 | ) { 12 | return `${model.name}${forField ? '$' + forField.name : ''}${fieldOverride ? '$override' : ''}_${kind}`; 13 | } 14 | 15 | /** 16 | * Gets the name of the function that checks an entity for access policy rules. 17 | */ 18 | export function getEntityCheckerFunctionName( 19 | model: DataModel, 20 | forField: DataModelField | undefined, 21 | fieldOverride: boolean, 22 | kind: string 23 | ) { 24 | return `$check_${model.name}${forField ? '$' + forField.name : ''}${fieldOverride ? '$override' : ''}_${kind}`; 25 | } 26 | -------------------------------------------------------------------------------- /packages/sdk/src/package.json: -------------------------------------------------------------------------------- 1 | ../package.json -------------------------------------------------------------------------------- /packages/sdk/src/path.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | /** 4 | * Gets the relative path from `from` to `to` and normalizes it to start it with `./` 5 | */ 6 | export function normalizedRelative(from: string, to: string) { 7 | const result = path.relative(from, to); 8 | return result.startsWith('.') ? result : `./${result}`; 9 | } 10 | -------------------------------------------------------------------------------- /packages/sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*.ts"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/server/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/server/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LICENSE -------------------------------------------------------------------------------- /packages/server/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack Server Adapters 2 | 3 | This package provides adapters and utilities for integrating with popular Node.js servers, including Express, Fastify, and Nest.js. 4 | 5 | Visit [Homepage](https://zenstack.dev) for more details. 6 | -------------------------------------------------------------------------------- /packages/server/jest.config.ts: -------------------------------------------------------------------------------- 1 | ../../jest.config.ts -------------------------------------------------------------------------------- /packages/server/src/api/index.ts: -------------------------------------------------------------------------------- 1 | export { RPCApiHandler } from './rpc'; 2 | export { RestApiHandler } from './rest'; 3 | -------------------------------------------------------------------------------- /packages/server/src/elysia/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler'; -------------------------------------------------------------------------------- /packages/server/src/express/index.ts: -------------------------------------------------------------------------------- 1 | export { ZenStackMiddleware } from './middleware'; 2 | export * from './middleware'; 3 | -------------------------------------------------------------------------------- /packages/server/src/fastify/index.ts: -------------------------------------------------------------------------------- 1 | export { ZenStackFastifyPlugin } from './plugin'; 2 | export * from './plugin'; 3 | -------------------------------------------------------------------------------- /packages/server/src/hono/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler'; 2 | -------------------------------------------------------------------------------- /packages/server/src/nestjs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './zenstack.module'; 2 | export * from './api-handler.service'; 3 | export * from './zenstack.constants'; 4 | -------------------------------------------------------------------------------- /packages/server/src/nestjs/interfaces/api-handler-options.interface.ts: -------------------------------------------------------------------------------- 1 | import { AdapterBaseOptions } from "../../types"; 2 | 3 | export interface ApiHandlerOptions extends AdapterBaseOptions { 4 | /** 5 | * The base URL for the API handler. This is used to determine the base path for the API requests. 6 | * If you are using the ApiHandlerService in a route with a prefix, you should set this to the prefix. 7 | * 8 | * e.g. 9 | * without baseUrl(API handler default route): 10 | * - RPC API handler: [model]/findMany 11 | * - RESTful API handler: /:type 12 | * 13 | * with baseUrl(/api/crud): 14 | * - RPC API handler: /api/crud/[model]/findMany 15 | * - RESTful API handler: /api/crud/:type 16 | */ 17 | baseUrl?: string; 18 | } 19 | -------------------------------------------------------------------------------- /packages/server/src/nestjs/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './zenstack-module-options.interface' 2 | export * from './api-handler-options.interface' 3 | -------------------------------------------------------------------------------- /packages/server/src/nestjs/zenstack.constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The default token used to export the enhanced Prisma service. 3 | */ 4 | export const ENHANCED_PRISMA = 'ENHANCED_PRISMA'; 5 | -------------------------------------------------------------------------------- /packages/server/src/nuxt/index.ts: -------------------------------------------------------------------------------- 1 | export * from './handler'; 2 | -------------------------------------------------------------------------------- /packages/server/src/sveltekit/index.ts: -------------------------------------------------------------------------------- 1 | export { SvelteKitHandler } from './handler'; 2 | export * from './handler'; 3 | -------------------------------------------------------------------------------- /packages/server/tests/utils.ts: -------------------------------------------------------------------------------- 1 | import superjson from 'superjson'; 2 | 3 | export const schema = ` 4 | model User { 5 | id String @id @default(cuid()) 6 | createdAt DateTime @default (now()) 7 | updatedAt DateTime @updatedAt 8 | email String @unique @email 9 | posts Post[] 10 | 11 | @@allow('all', auth() == this) 12 | @@allow('create,read', true) 13 | } 14 | 15 | model Post { 16 | id String @id @default(cuid()) 17 | createdAt DateTime @default (now()) 18 | updatedAt DateTime @updatedAt 19 | title String 20 | author User? @relation(fields: [authorId], references: [id]) 21 | authorId String? 22 | published Boolean @default(false) 23 | publishedAt DateTime? 24 | viewCount Int @default(0) 25 | 26 | @@allow('all', author == auth()) 27 | @@allow('read', published) 28 | } 29 | `; 30 | 31 | export function makeUrl(path: string, q?: object, useSuperJson = false) { 32 | return q ? `${path}?q=${encodeURIComponent(useSuperJson ? superjson.stringify(q) : JSON.stringify(q))}` : path; 33 | } 34 | -------------------------------------------------------------------------------- /packages/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "target": "ES2020", 5 | "lib": ["ESNext", "DOM"], 6 | "outDir": "dist", 7 | "strictPropertyInitialization": false, 8 | "emitDecoratorMetadata": true 9 | }, 10 | "include": ["src/**/*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/testtools/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [2.0.0-alpha.2](https://github.com/zenstackhq/zenstack/compare/v2.0.0-alpha.1...v2.0.0-alpha.2) (2024-02-21) 4 | 5 | 6 | ### Miscellaneous Chores 7 | 8 | * release 2.0.0-alpha.2 ([f40d7e3](https://github.com/zenstackhq/zenstack/commit/f40d7e3718d4210137a2e131d28b5491d065b914)) 9 | -------------------------------------------------------------------------------- /packages/testtools/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LICENSE -------------------------------------------------------------------------------- /packages/testtools/README.md: -------------------------------------------------------------------------------- 1 | # ZenStack Test Tools 2 | -------------------------------------------------------------------------------- /packages/testtools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@zenstackhq/testtools", 3 | "version": "2.15.1", 4 | "description": "ZenStack Test Tools", 5 | "main": "index.js", 6 | "private": true, 7 | "publishConfig": { 8 | "directory": "dist", 9 | "linkDirectory": true 10 | }, 11 | "scripts": { 12 | "clean": "rimraf dist", 13 | "lint": "eslint src --ext ts", 14 | "build": "pnpm lint && pnpm clean && tsc && copyfiles ./package.json ./LICENSE ./README.md dist && pnpm pack dist --pack-destination ../../../.build", 15 | "watch": "tsc --watch", 16 | "prepublishOnly": "pnpm build" 17 | }, 18 | "keywords": [], 19 | "author": "", 20 | "license": "MIT", 21 | "dependencies": { 22 | "@zenstackhq/language": "workspace:*", 23 | "@zenstackhq/runtime": "workspace:*", 24 | "@zenstackhq/sdk": "workspace:*", 25 | "json5": "^2.2.3", 26 | "langium": "1.3.1", 27 | "pg": "^8.11.1", 28 | "tiny-invariant": "^1.3.1", 29 | "tmp": "^0.2.1", 30 | "vscode-uri": "^3.0.6", 31 | "zenstack": "workspace:*" 32 | }, 33 | "devDependencies": { 34 | "@types/pg": "^8.10.2", 35 | "@types/tmp": "^0.2.3" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/testtools/src/db.ts: -------------------------------------------------------------------------------- 1 | import { Pool } from 'pg'; 2 | 3 | const USERNAME = process.env.ZENSTACK_TEST_DB_USER || 'postgres'; 4 | const PASSWORD = process.env.ZENSTACK_TEST_DB_PASS || 'abc123'; 5 | const CONNECTION_DB = process.env.ZENSTACK_TEST_DB_NAME || 'postgres'; 6 | const HOST = process.env.ZENSTACK_TEST_DB_HOST || 'localhost'; 7 | const PORT = (process.env.ZENSTACK_TEST_DB_PORT ? parseInt(process.env.ZENSTACK_TEST_DB_PORT) : null) || 5432; 8 | 9 | function connect() { 10 | return new Pool({ 11 | user: USERNAME, 12 | password: PASSWORD, 13 | database: CONNECTION_DB, 14 | host: HOST, 15 | port: PORT 16 | }); 17 | } 18 | 19 | export async function createPostgresDb(db: string) { 20 | const pool = connect(); 21 | await pool.query(`DROP DATABASE IF EXISTS "${db}";`); 22 | await pool.query(`CREATE DATABASE "${db}";`); 23 | await pool.end(); 24 | return `postgresql://${USERNAME}:${PASSWORD}@${HOST}:${PORT}/${db}`; 25 | } 26 | 27 | export async function dropPostgresDb(db: string) { 28 | const pool = connect(); 29 | await pool.query(`DROP DATABASE IF EXISTS "${db}";`); 30 | await pool.end(); 31 | } 32 | -------------------------------------------------------------------------------- /packages/testtools/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './db'; 2 | export * from './model'; 3 | export * from './schema'; 4 | -------------------------------------------------------------------------------- /packages/testtools/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "CommonJS", 5 | "lib": ["ESNext", "DOM"], 6 | "sourceMap": true, 7 | "outDir": "dist", 8 | "strict": true, 9 | "noUnusedLocals": true, 10 | "noImplicitReturns": true, 11 | "moduleResolution": "node", 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "declaration": true, 16 | "resolveJsonModule": true, 17 | "strictPropertyInitialization": false, 18 | "paths": {} 19 | }, 20 | "include": ["src/**/*.ts"], 21 | "exclude": ["dist", "node_modules"] 22 | } 23 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | - 'packages/plugins/*' 4 | - 'packages/misc/*' 5 | - 'packages/ide/*' 6 | - 'tests/*' 7 | -------------------------------------------------------------------------------- /script/set-test-env.ts: -------------------------------------------------------------------------------- 1 | process.env.ZENSTACK_TEST = '1'; 2 | -------------------------------------------------------------------------------- /script/test-global-setup.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | export default function globalSetup() { 5 | if (!fs.existsSync(path.join(__dirname, '../.test/scaffold/package-lock.json'))) { 6 | console.error(`Test scaffold not found. Please run \`pnpm test-scaffold\` first.`); 7 | process.exit(1); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /script/test-scaffold.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import fs from 'fs'; 3 | import { execSync } from 'child_process'; 4 | 5 | const scaffoldPath = path.join(__dirname, '../.test/scaffold'); 6 | if (fs.existsSync(scaffoldPath)) { 7 | fs.rmSync(scaffoldPath, { recursive: true, force: true }); 8 | } 9 | fs.mkdirSync(scaffoldPath, { recursive: true }); 10 | 11 | function run(cmd: string) { 12 | console.log(`Running: ${cmd}, in ${scaffoldPath}`); 13 | try { 14 | execSync(cmd, { cwd: scaffoldPath, stdio: 'ignore' }); 15 | } catch (err) { 16 | console.error(`Test project scaffolding cmd error: ${err}`); 17 | throw err; 18 | } 19 | } 20 | 21 | run('npm init -y'); 22 | run('npm i --no-audit --no-fund typescript prisma@6.8.x @prisma/client@6.8.x zod@^3.22.4 decimal.js @types/node'); 23 | 24 | console.log('Test scaffold setup complete.'); 25 | -------------------------------------------------------------------------------- /test-setup.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | export default function globalSetup() { 5 | if (!fs.existsSync(path.join(__dirname, '.test/scaffold/package-lock.json'))) { 6 | console.error(`Test scaffold not found. Please run \`pnpm test-scaffold\` first.`); 7 | process.exit(1); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/integration/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": ["@typescript-eslint"], 9 | "extends": ["plugin:jest/recommended"], 10 | "rules": { 11 | "jest/expect-expect": "off" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/integration/.gitignore: -------------------------------------------------------------------------------- 1 | .npmcache 2 | node_modules 3 | test-run/cases 4 | tests/**/test-run 5 | -------------------------------------------------------------------------------- /tests/integration/jest.config.ts: -------------------------------------------------------------------------------- 1 | import baseConfig from '../../jest.config'; 2 | 3 | /* 4 | * For a detailed explanation regarding each configuration property and type check, visit: 5 | * https://jestjs.io/docs/configuration 6 | */ 7 | export default { 8 | ...baseConfig, 9 | setupFilesAfterEnv: ['./test-setup.ts'], 10 | }; 11 | -------------------------------------------------------------------------------- /tests/integration/jest.d.ts: -------------------------------------------------------------------------------- 1 | interface CustomMatchers { 2 | toBeRejectedByPolicy(expectedMessages?: string[]): Promise; 3 | toBeNotFound(): Promise; 4 | toResolveTruthy(): Promise; 5 | toResolveFalsy(): Promise; 6 | toResolveNull(): Promise; 7 | toBeRejectedWithCode(code: string): Promise; 8 | } 9 | declare global { 10 | namespace jest { 11 | interface Expect extends CustomMatchers {} 12 | interface Matchers extends CustomMatchers {} 13 | interface InverseAsymmetricMatchers extends CustomMatchers {} 14 | } 15 | } 16 | export {}; 17 | -------------------------------------------------------------------------------- /tests/integration/test-run/.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json -------------------------------------------------------------------------------- /tests/integration/test-run/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-run", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@prisma/client": "6.8.x", 14 | "@zenstackhq/runtime": "file:../../../packages/runtime/dist", 15 | "prisma": "6.8.x", 16 | "react": "^18.2.0", 17 | "swr": "^1.3.0", 18 | "typescript": "^4.9.3", 19 | "zenstack": "file:../../../packages/schema/dist", 20 | "zod": "^3.22.4" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/integration/test-setup.ts: -------------------------------------------------------------------------------- 1 | import { 2 | toBeRejectedByPolicy, 3 | toBeNotFound, 4 | toResolveTruthy, 5 | toResolveFalsy, 6 | toResolveNull, 7 | toBeRejectedWithCode, 8 | } from '@zenstackhq/testtools/jest-ext'; 9 | 10 | expect.extend({ 11 | toBeRejectedByPolicy, 12 | toBeNotFound, 13 | toResolveTruthy, 14 | toResolveFalsy, 15 | toResolveNull, 16 | toBeRejectedWithCode, 17 | }); 18 | -------------------------------------------------------------------------------- /tests/integration/tests/cli/share.ts: -------------------------------------------------------------------------------- 1 | import { getWorkspaceNpmCacheFolder } from '@zenstackhq/testtools'; 2 | import fs from 'fs'; 3 | 4 | export function createNpmrc() { 5 | fs.writeFileSync('.npmrc', `cache=${getWorkspaceNpmCacheFolder(__dirname)}`); 6 | } 7 | -------------------------------------------------------------------------------- /tests/integration/tests/enhancements/with-delegate/validation.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('Polymorphic input validation', () => { 3 | it('rejects aux fields in mutation', async () => { 4 | const { enhance } = await loadSchema( 5 | ` 6 | model Asset { 7 | id Int @id @default(autoincrement()) 8 | type String 9 | 10 | @@delegate(type) 11 | @@allow('all', true) 12 | } 13 | 14 | model Post extends Asset { 15 | title String 16 | } 17 | ` 18 | ); 19 | 20 | const db = enhance(); 21 | const asset = await db.post.create({ data: { title: 'Post1' } }); 22 | await expect( 23 | db.asset.update({ where: { id: asset.id }, data: { delegate_aux_post: { update: { title: 'Post2' } } } }) 24 | ).rejects.toThrow('Auxiliary relation field "delegate_aux_post" cannot be set directly'); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/integration/tests/enhancements/with-policy/cal-com-sample.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchemaFromFile } from '@zenstackhq/testtools'; 2 | import path from 'path'; 3 | 4 | describe('Cal.com Sample Integration Tests', () => { 5 | it('model loading', async () => { 6 | await loadSchemaFromFile(path.join(__dirname, '../../schema/cal-com.zmodel'), { 7 | addPrelude: false, 8 | pushDb: false, 9 | }); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/.npmrc: -------------------------------------------------------------------------------- 1 | cache=../../../.npmcache 2 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | swcMinify: true, 5 | } 6 | 7 | module.exports = nextConfig 8 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-project", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@prisma/client": "6.8.x", 13 | "@types/node": "18.11.18", 14 | "@types/react": "18.0.27", 15 | "@types/react-dom": "18.0.10", 16 | "next": "14.2.4", 17 | "react": "18.2.0", 18 | "react-dom": "18.2.0", 19 | "superjson": "^1.13.0", 20 | "swr": "^2.2.0", 21 | "typescript": "5.x", 22 | "zod": "^3.22.4", 23 | "@zenstackhq/language": "../../../../../../../packages/language/dist", 24 | "@zenstackhq/runtime": "../../../../../../../packages/runtime/dist", 25 | "@zenstackhq/sdk": "../../../../../../../packages/sdk/dist", 26 | "@zenstackhq/swr": "../../../../../../../packages/plugins/swr/dist" 27 | }, 28 | "devDependencies": { 29 | "prisma": "6.8.x" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { AppProps } from 'next/app'; 2 | 3 | export default function App({ Component, pageProps }: AppProps) { 4 | return ; 5 | } 6 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/pages/api/model/[...path].ts: -------------------------------------------------------------------------------- 1 | import { NextRequestHandler } from '@zenstackhq/server/next'; 2 | import { enhance } from '@zenstackhq/runtime'; 3 | import { prisma } from '../../../server/db'; 4 | 5 | export default NextRequestHandler({ 6 | getPrisma: (req, res) => enhance(prisma, { user: { id: 'user1' } }), 7 | }); 8 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { useFindManyPost } from '../lib/hooks'; 2 | 3 | export default function Home() { 4 | const { data: posts } = useFindManyPost(); 5 | return ( 6 |
7 | {posts?.map((post) => ( 8 |

{post.title}

9 | ))} 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/postgres.zmodel: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = 'postgresql' 3 | url = env('DATABASE_URL') 4 | } 5 | 6 | generator js { 7 | provider = 'prisma-client-js' 8 | } 9 | 10 | plugin swr { 11 | provider = '@zenstackhq/swr' 12 | output = 'lib/hooks' 13 | } 14 | 15 | model User { 16 | id String @id 17 | name String 18 | posts Post[] 19 | @@allow('create,read', true) 20 | @@allow('update,delete', auth() == this) 21 | } 22 | 23 | model Post { 24 | id String @id 25 | title String 26 | author User? @relation(fields: [authorId], references: [id]) 27 | authorId String? 28 | published Boolean @default(false) 29 | @@allow('all', auth() == author) 30 | @@allow('read', published) 31 | } 32 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/server/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client'; 2 | 3 | declare global { 4 | // eslint-disable-next-line no-var 5 | var prisma: PrismaClient | undefined; 6 | } 7 | 8 | export const prisma = global.prisma || new PrismaClient(); 9 | 10 | if (process.env.NODE_ENV !== 'production') { 11 | global.prisma = prisma; 12 | } 13 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/sqlite.zmodel: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = 'sqlite' 3 | url = 'file:./dev.db' 4 | } 5 | 6 | generator js { 7 | provider = 'prisma-client-js' 8 | } 9 | 10 | plugin swr { 11 | provider = '@zenstackhq/swr' 12 | output = 'lib/hooks' 13 | } 14 | 15 | model User { 16 | id String @id 17 | name String 18 | posts Post[] 19 | @@allow('create,read', true) 20 | @@allow('update,delete', auth() == this) 21 | } 22 | 23 | model Post { 24 | id String @id 25 | title String 26 | author User? @relation(fields: [authorId], references: [id]) 27 | authorId String? 28 | published Boolean @default(false) 29 | @@allow('all', auth() == author) 30 | @@allow('read', published) 31 | } 32 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/nextjs/test-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/generation.test.ts: -------------------------------------------------------------------------------- 1 | import { run } from '@zenstackhq/testtools'; 2 | import fs from 'fs'; 3 | import fse from 'fs-extra'; 4 | import path from 'path'; 5 | 6 | describe('tRPC Routers Generation Tests', () => { 7 | let origDir: string; 8 | 9 | beforeAll(() => { 10 | origDir = process.cwd(); 11 | }); 12 | 13 | afterEach(() => { 14 | process.chdir(origDir); 15 | }); 16 | 17 | it('basic', async () => { 18 | const testDir = path.join(__dirname, './test-run/basic'); 19 | if (fs.existsSync(testDir)) { 20 | fs.rmSync(testDir, { recursive: true, force: true }); 21 | } 22 | fs.mkdirSync(testDir, { recursive: true }); 23 | fse.copySync(path.join(__dirname, './test-project'), testDir); 24 | 25 | process.chdir(testDir); 26 | run('npm install'); 27 | run('npx zenstack generate --no-dependency-check --schema ./todo.zmodel', { 28 | NODE_PATH: 'node_modules', 29 | }); 30 | run('npm run build', { NODE_PATH: 'node_modules' }); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/.npmrc: -------------------------------------------------------------------------------- 1 | cache=../../../.npmcache 2 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/lib/trpc.ts: -------------------------------------------------------------------------------- 1 | import { TRPCClientError, httpBatchLink } from '@trpc/client'; 2 | import { createTRPCNext } from '@trpc/next'; 3 | import superjson from 'superjson'; 4 | import type { AppRouter } from '../server/routers/_app'; 5 | 6 | function getBaseUrl() { 7 | if (typeof window !== 'undefined') return ''; 8 | 9 | if (process.env.VERCEL_URL) { 10 | return `https://${process.env.VERCEL_URL}`; 11 | } else { 12 | return `http://localhost:${process.env.PORT ?? 3000}`; 13 | } 14 | } 15 | 16 | export const trpc = createTRPCNext({ 17 | config({ ctx }) { 18 | return { 19 | transformer: superjson, 20 | links: [ 21 | httpBatchLink({ 22 | url: `${getBaseUrl()}/api/trpc`, 23 | }), 24 | ], 25 | }; 26 | }, 27 | ssr: false, 28 | }); 29 | 30 | export function isTRPCClientError(error: unknown): error is TRPCClientError { 31 | return error instanceof TRPCClientError; 32 | } 33 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | swcMinify: true, 5 | } 6 | 7 | module.exports = nextConfig 8 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { AppProps } from 'next/app'; 2 | import { trpc } from '../lib/trpc'; 3 | 4 | function App({ Component, pageProps }: AppProps) { 5 | return ; 6 | } 7 | 8 | export default trpc.withTRPC(App); 9 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/pages/api/model/[...path].ts: -------------------------------------------------------------------------------- 1 | import { NextRequestHandler } from '@zenstackhq/server/next'; 2 | import { enhance } from '@zenstackhq/runtime'; 3 | import { prisma } from '../../../server/db'; 4 | 5 | export default NextRequestHandler({ 6 | getPrisma: (req, res) => enhance(prisma, { user: { id: 'user1' } }), 7 | }); 8 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { trpc } from '../lib/trpc'; 2 | 3 | export default function Home() { 4 | const { data: posts } = trpc.post.findMany.useQuery({}); 5 | return ( 6 |
7 | {posts?.map((post) => ( 8 |

{post.title}

9 | ))} 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/server/context.ts: -------------------------------------------------------------------------------- 1 | import { type inferAsyncReturnType } from '@trpc/server'; 2 | import { type CreateNextContextOptions } from '@trpc/server/adapters/next'; 3 | import { enhance } from '@zenstackhq/runtime'; 4 | import { prisma } from './db'; 5 | 6 | export const createContext = async ({ req, res }: CreateNextContextOptions) => { 7 | return { 8 | prisma: enhance(prisma, { user: { id: 'user1' } }), 9 | }; 10 | }; 11 | 12 | export type Context = inferAsyncReturnType; 13 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/server/db.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client'; 2 | 3 | declare global { 4 | // eslint-disable-next-line no-var 5 | var prisma: PrismaClient | undefined; 6 | } 7 | 8 | export const prisma = global.prisma || new PrismaClient(); 9 | 10 | if (process.env.NODE_ENV !== 'production') { 11 | global.prisma = prisma; 12 | } 13 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/server/routers/_app.ts: -------------------------------------------------------------------------------- 1 | import { createRouter } from './generated/routers'; 2 | import { initTRPC } from '@trpc/server'; 3 | import { type Context } from '../context'; 4 | import superjson from 'superjson'; 5 | 6 | const t = initTRPC.context().create({ 7 | transformer: superjson, 8 | }); 9 | 10 | export const appRouter = createRouter(t.router, t.procedure); 11 | 12 | export type AppRouter = typeof appRouter; 13 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/todo.zmodel: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = 'sqlite' 3 | url = 'file:./dev.db' 4 | } 5 | 6 | generator js { 7 | provider = 'prisma-client-js' 8 | } 9 | 10 | plugin trpc { 11 | provider = '@zenstackhq/trpc' 12 | output = 'server/routers/generated' 13 | } 14 | 15 | model User { 16 | id String @id 17 | name String 18 | posts Post[] 19 | @@allow('create,read', true) 20 | @@allow('update,delete', auth() == this) 21 | } 22 | 23 | model Post { 24 | id String @id 25 | title String 26 | author User? @relation(fields: [authorId], references: [id]) 27 | authorId String? 28 | published Boolean @default(false) 29 | @@allow('all', auth() == author) 30 | @@allow('read', published) 31 | } 32 | -------------------------------------------------------------------------------- /tests/integration/tests/frameworks/trpc/test-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "paths": { 18 | ".zenstack/zod/input": ["./node_modules/.zenstack/zod/input/index.d.ts"] 19 | } 20 | }, 21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /tests/integration/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "experimentalDecorators": true, 10 | "resolveJsonModule": true 11 | }, 12 | "include": ["**/*.ts", "**/*.d.ts"] 13 | } 14 | -------------------------------------------------------------------------------- /tests/regression/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": ["@typescript-eslint"], 9 | "extends": ["plugin:jest/recommended"], 10 | "rules": { 11 | "jest/expect-expect": "off" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/regression/jest.config.ts: -------------------------------------------------------------------------------- 1 | import baseConfig from '../../jest.config'; 2 | 3 | /* 4 | * For a detailed explanation regarding each configuration property and type check, visit: 5 | * https://jestjs.io/docs/configuration 6 | */ 7 | export default { 8 | ...baseConfig, 9 | setupFilesAfterEnv: ['./test-setup.ts'], 10 | }; 11 | -------------------------------------------------------------------------------- /tests/regression/jest.d.ts: -------------------------------------------------------------------------------- 1 | interface CustomMatchers { 2 | toBeRejectedByPolicy(expectedMessages?: string[]): Promise; 3 | toBeNotFound(): Promise; 4 | toResolveTruthy(): Promise; 5 | toResolveFalsy(): Promise; 6 | toResolveNull(): Promise; 7 | toBeRejectedWithCode(code: string): Promise; 8 | } 9 | declare global { 10 | namespace jest { 11 | interface Expect extends CustomMatchers {} 12 | interface Matchers extends CustomMatchers {} 13 | interface InverseAsymmetricMatchers extends CustomMatchers {} 14 | } 15 | } 16 | export {}; 17 | -------------------------------------------------------------------------------- /tests/regression/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "regression", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "lint": "eslint . --ext .ts", 8 | "test": "jest" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@zenstackhq/runtime": "workspace:*", 15 | "@zenstackhq/server": "workspace:*", 16 | "zenstack": "workspace: *" 17 | }, 18 | "dependencies": { 19 | "@types/node": "^18.0.0", 20 | "@zenstackhq/sdk": "workspace:*", 21 | "@zenstackhq/testtools": "workspace:*", 22 | "decimal.js": "^10.4.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/regression/test-setup.ts: -------------------------------------------------------------------------------- 1 | import { 2 | toBeNotFound, 3 | toBeRejectedByPolicy, 4 | toBeRejectedWithCode, 5 | toResolveFalsy, 6 | toResolveNull, 7 | toResolveTruthy, 8 | } from '@zenstackhq/testtools/jest-ext'; 9 | 10 | expect.extend({ 11 | toBeRejectedByPolicy, 12 | toBeNotFound, 13 | toResolveTruthy, 14 | toResolveFalsy, 15 | toResolveNull, 16 | toBeRejectedWithCode, 17 | }); 18 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1167.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1167', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | model FileAsset { 8 | id String @id @default(cuid()) 9 | delegate_type String 10 | @@delegate(delegate_type) 11 | @@map("file_assets") 12 | } 13 | 14 | model ImageAsset extends FileAsset { 15 | @@map("image_assets") 16 | } 17 | ` 18 | ); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1179.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModel } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1179', () => { 4 | it('regression', async () => { 5 | await loadModel( 6 | ` 7 | abstract model Base { 8 | id String @id @default(uuid()) 9 | } 10 | 11 | model User extends Base { 12 | email String 13 | posts Post[] 14 | @@allow('all', auth() == this) 15 | } 16 | 17 | model Post { 18 | id String @id @default(uuid()) 19 | 20 | user User @relation(fields: [userId], references: [id]) 21 | userId String 22 | @@allow('all', auth().id == userId) 23 | } 24 | ` 25 | ); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1265.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1265', () => { 4 | it('regression', async () => { 5 | const { zodSchemas } = await loadSchema( 6 | ` 7 | model User { 8 | id String @id @default(uuid()) 9 | posts Post[] 10 | @@allow('all', true) 11 | } 12 | 13 | model Post { 14 | id String @id @default(uuid()) 15 | title String @default('xyz') 16 | userId String @default(auth().id) 17 | user User @relation(fields: [userId], references: [id]) 18 | @@allow('all', true) 19 | } 20 | `, 21 | { fullZod: true, pushDb: false } 22 | ); 23 | 24 | expect(zodSchemas.models.PostCreateSchema.safeParse({ title: 'Post 1' }).success).toBeTruthy(); 25 | expect(zodSchemas.input.PostInputSchema.create.safeParse({ data: { title: 'Post 1' } }).success).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1268.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1268', () => { 4 | it('regression', async () => { 5 | const { zodSchemas } = await loadSchema( 6 | ` 7 | model Model { 8 | id String @id @default(uuid()) 9 | bytes Bytes 10 | } 11 | `, 12 | { 13 | fullZod: true, 14 | pushDb: false, 15 | compile: true, 16 | extraSourceFiles: [ 17 | { 18 | name: 'test.ts', 19 | content: ` 20 | import { ModelCreateInputObjectSchema } from '.zenstack/zod/objects'; 21 | ModelCreateInputObjectSchema.parse({ bytes: new Uint8Array(0) }); 22 | `, 23 | }, 24 | ], 25 | } 26 | ); 27 | 28 | expect( 29 | zodSchemas.objects.ModelCreateInputObjectSchema.safeParse({ bytes: new Uint8Array(0) }).success 30 | ).toBeTruthy(); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1388.test.ts: -------------------------------------------------------------------------------- 1 | import { FILE_SPLITTER, loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1388', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | `schema.zmodel 7 | import './auth' 8 | import './post' 9 | 10 | ${FILE_SPLITTER}auth.zmodel 11 | model User { 12 | id String @id @default(cuid()) 13 | role String 14 | } 15 | 16 | ${FILE_SPLITTER}post.zmodel 17 | model Post { 18 | id String @id @default(nanoid(6)) 19 | title String 20 | @@deny('all', auth() == null) 21 | @@allow('all', auth().id == 'user1') 22 | } 23 | ` 24 | ); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1415.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1415', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | model User { 8 | id String @id @default(cuid()) 9 | prices Price[] 10 | } 11 | 12 | model Price { 13 | id String @id @default(cuid()) 14 | owner User @relation(fields: [ownerId], references: [id]) 15 | ownerId String @default(auth().id) 16 | priceType String 17 | @@delegate(priceType) 18 | } 19 | ` 20 | ); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1416.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1416', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | model User { 8 | id String @id @default(cuid()) 9 | role String 10 | } 11 | 12 | model Price { 13 | id String @id @default(nanoid(6)) 14 | entity Entity? @relation(fields: [entityId], references: [id]) 15 | entityId String? 16 | priceType String 17 | @@delegate(priceType) 18 | } 19 | 20 | model MyPrice extends Price { 21 | foo String 22 | } 23 | 24 | model Entity { 25 | id String @id @default(nanoid(6)) 26 | price Price[] 27 | type String 28 | @@delegate(type) 29 | } 30 | 31 | model MyEntity extends Entity { 32 | foo String 33 | } 34 | ` 35 | ); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1474.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1474', () => { 3 | it('regression', async () => { 4 | await loadSchema( 5 | ` 6 | model A { 7 | id Int @id 8 | cs C[] 9 | } 10 | 11 | abstract model B { 12 | a A @relation(fields: [aId], references: [id]) 13 | aId Int 14 | } 15 | 16 | model C extends B { 17 | id Int @id 18 | type String 19 | @@delegate(type) 20 | } 21 | 22 | model D extends C { 23 | } 24 | ` 25 | ); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1507.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1507', () => { 3 | it('regression', async () => { 4 | const { prisma, enhance } = await loadSchema( 5 | ` 6 | model User { 7 | id Int @id @default(autoincrement()) 8 | age Int 9 | } 10 | 11 | model Profile { 12 | id Int @id @default(autoincrement()) 13 | age Int 14 | 15 | @@allow('read', auth().age == age) 16 | } 17 | `, 18 | { preserveTsFiles: true, logPrismaQuery: true } 19 | ); 20 | 21 | await prisma.profile.create({ data: { age: 18 } }); 22 | await prisma.profile.create({ data: { age: 20 } }); 23 | const db = enhance({ id: 1, age: 18 }); 24 | await expect(db.profile.findMany()).resolves.toHaveLength(1); 25 | await expect(db.profile.count()).resolves.toBe(1); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1518.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1518', () => { 3 | it('regression', async () => { 4 | const { enhance } = await loadSchema( 5 | ` 6 | model Activity { 7 | id String @id @default(uuid()) 8 | title String 9 | type String 10 | @@delegate(type) 11 | @@allow('all', true) 12 | } 13 | 14 | model TaskActivity extends Activity { 15 | description String 16 | @@map("task_activity") 17 | @@allow('all', true) 18 | } 19 | ` 20 | ); 21 | 22 | const db = enhance(); 23 | await db.taskActivity.create({ 24 | data: { 25 | id: '00000000-0000-0000-0000-111111111111', 26 | title: 'Test Activity', 27 | description: 'Description of task', 28 | }, 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1551.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1551', () => { 3 | it('regression', async () => { 4 | await loadSchema( 5 | ` 6 | model User { 7 | id Int @id 8 | profile Profile? @relation(fields: [profileId], references: [id]) 9 | profileId Int? @unique @map('profile_id') 10 | } 11 | 12 | model Profile { 13 | id Int @id 14 | contentType String 15 | user User? 16 | 17 | @@delegate(contentType) 18 | } 19 | 20 | model IndividualProfile extends Profile { 21 | name String 22 | } 23 | ` 24 | ); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1562.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1562', () => { 3 | it('regression', async () => { 4 | const { enhance } = await loadSchema( 5 | ` 6 | generator client { 7 | provider = "prisma-client-js" 8 | } 9 | 10 | datasource db { 11 | provider = "sqlite" 12 | url = "file:./dev.db" 13 | } 14 | 15 | plugin zod { 16 | provider = '@core/zod' 17 | } 18 | 19 | plugin enhancer { 20 | provider = '@core/enhancer' 21 | generatePermissionChecker = true 22 | } 23 | 24 | abstract model Base { 25 | id String @id @default(uuid()) 26 | createdAt DateTime @default(now()) 27 | updatedAt DateTime @updatedAt() 28 | 29 | // require login 30 | @@allow('all', true) 31 | } 32 | 33 | model User extends Base { 34 | name String @unique @regex('^[a-zA-Z0-9_]{3,30}$') 35 | 36 | @@allow('read', true) 37 | } 38 | `, 39 | { addPrelude: false } 40 | ); 41 | 42 | const db = enhance(); 43 | await expect(db.user.create({ data: { name: '1 2 3 4' } })).toBeRejectedByPolicy(); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1563.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1563', () => { 4 | it('regression', async () => { 5 | const { enhance } = await loadSchema( 6 | ` 7 | model ModelA { 8 | id String @id @default(cuid()) 9 | ref ModelB[] 10 | } 11 | 12 | model ModelB { 13 | id String @id @default(cuid()) 14 | ref ModelA? @relation(fields: [refId], references: [id]) 15 | refId String? 16 | 17 | @@validate(refId != null, "refId must be set") 18 | } 19 | `, 20 | { enhancements: ['validation'] } 21 | ); 22 | 23 | const db = enhance(); 24 | 25 | const a = await db.modelA.create({ data: {} }); 26 | const b = await db.modelB.create({ data: { refId: a.id } }); 27 | 28 | await expect(db.modelB.update({ where: { id: b.id }, data: { refId: a.id } })).toResolveTruthy(); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1575.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1575', () => { 3 | it('regression', async () => { 4 | await loadSchema( 5 | ` 6 | model UserAssets { 7 | id String @id @default(cuid()) 8 | videoId String 9 | videoStream Asset @relation("userVideo", fields: [videoId], references: [id]) 10 | subtitleId String 11 | subtitlesAsset Asset @relation("userSubtitles", fields: [subtitleId], references: [id]) 12 | } 13 | 14 | model Asset { 15 | id String @id @default(cuid()) 16 | type String 17 | userVideo UserAssets[] @relation("userVideo") 18 | userSubtitles UserAssets[] @relation("userSubtitles") 19 | 20 | @@delegate(type) 21 | } 22 | 23 | model Movie extends Asset { 24 | duration Int 25 | } 26 | ` 27 | ); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1585.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1585', () => { 3 | it('regression', async () => { 4 | const { enhance } = await loadSchema( 5 | ` 6 | model Asset { 7 | id Int @id @default(autoincrement()) 8 | type String 9 | views Int 10 | 11 | @@allow('all', true) 12 | @@delegate(type) 13 | } 14 | 15 | model Post extends Asset { 16 | title String 17 | } 18 | ` 19 | ); 20 | 21 | const db = enhance(); 22 | await db.post.create({ data: { title: 'Post1', views: 0 } }); 23 | await db.post.create({ data: { title: 'Post2', views: 1 } }); 24 | await expect( 25 | db.post.count({ 26 | where: { views: { gt: 0 } }, 27 | }) 28 | ).resolves.toBe(1); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1596.test.ts: -------------------------------------------------------------------------------- 1 | import { isPrismaClientValidationError } from '@zenstackhq/runtime'; 2 | import { loadSchema } from '@zenstackhq/testtools'; 3 | 4 | describe('issue 1596', () => { 5 | it('regression', async () => { 6 | const { enhance } = await loadSchema( 7 | ` 8 | model User { 9 | id Int @id 10 | posts Post[] 11 | } 12 | 13 | model Post { 14 | id Int @id 15 | title String 16 | author User @relation(fields: [authorId], references: [id]) 17 | authorId Int @default(auth().id) 18 | } 19 | ` 20 | ); 21 | 22 | const db = enhance(); 23 | 24 | try { 25 | await db.post.create({ data: { title: 'Post1' } }); 26 | } catch (e) { 27 | // eslint-disable-next-line jest/no-conditional-expect 28 | expect(isPrismaClientValidationError(e)).toBe(true); 29 | return; 30 | } 31 | 32 | throw new Error('Expected error'); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1644.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1644', () => { 3 | it('regression', async () => { 4 | const { prisma, enhance } = await loadSchema( 5 | ` 6 | model User { 7 | id Int @id @default(autoincrement()) 8 | email String @unique @email @length(6, 32) @allow('read', auth() == this) 9 | 10 | // full access to all 11 | @@allow('all', true) 12 | } 13 | ` 14 | ); 15 | 16 | await prisma.user.create({ data: { id: 1, email: 'a@example.com' } }); 17 | await prisma.user.create({ data: { id: 2, email: 'b@example.com' } }); 18 | 19 | const db = enhance({ id: 1 }); 20 | await expect(db.user.count({ where: { email: { contains: 'example.com' } } })).resolves.toBe(1); 21 | await expect(db.user.findMany({ where: { email: { contains: 'example.com' } } })).resolves.toHaveLength(1); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1681.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1681', () => { 3 | it('regression', async () => { 4 | const { enhance } = await loadSchema( 5 | ` 6 | model User { 7 | id Int @id @default(autoincrement()) 8 | posts Post[] 9 | @@allow('all', true) 10 | } 11 | 12 | model Post { 13 | id Int @id @default(autoincrement()) 14 | title String 15 | author User @relation(fields: [authorId], references: [id]) 16 | authorId Int @default(auth().id) 17 | @@allow('all', true) 18 | } 19 | ` 20 | ); 21 | 22 | const db = enhance({ id: 1 }); 23 | const user = await db.user.create({ data: {} }); 24 | await expect(db.post.createMany({ data: [{ title: 'Post1' }] })).resolves.toMatchObject({ count: 1 }); 25 | 26 | const r = await db.post.createManyAndReturn({ data: [{ title: 'Post2' }] }); 27 | expect(r[0].authorId).toBe(user.id); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1693.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1693', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | model Animal { 8 | id String @id @default(uuid()) 9 | animalType String @default("") 10 | @@delegate(animalType) 11 | } 12 | 13 | model Dog extends Animal { 14 | name String 15 | } 16 | `, 17 | { fullZod: true } 18 | ); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1695.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModel } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1695', () => { 4 | it('regression', async () => { 5 | await loadModel( 6 | ` 7 | abstract model SoftDelete { 8 | deleted Int @default(0) @omit 9 | } 10 | 11 | model MyModel extends SoftDelete { 12 | id String @id @default(cuid()) 13 | name String 14 | 15 | @@deny('update', deleted != 0 && future().deleted != 0) 16 | @@deny('read', this.deleted != 0) 17 | } 18 | ` 19 | ); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1743.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | describe('issue 1743', () => { 3 | it('regression', async () => { 4 | await loadSchema( 5 | ` 6 | generator client { 7 | provider = "prisma-client-js" 8 | output = '../lib/zenstack/prisma' 9 | } 10 | 11 | datasource db { 12 | provider = "sqlite" 13 | url = "file:./dev.db" 14 | } 15 | 16 | plugin enhancer { 17 | provider = '@core/enhancer' 18 | output = './lib/zenstack' 19 | compile = false 20 | } 21 | 22 | model User { 23 | id Int @id 24 | } 25 | `, 26 | { 27 | addPrelude: false, 28 | compile: true, 29 | output: './lib/zenstack', 30 | prismaLoadPath: './lib/zenstack/prisma', 31 | } 32 | ); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1758.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModelWithError } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1758', () => { 4 | it('regression', async () => { 5 | await expect( 6 | loadModelWithError( 7 | ` 8 | model Organization { 9 | id String @id @default(cuid()) 10 | contents Content[] @relation("OrganizationContents") 11 | } 12 | 13 | model Content { 14 | id String @id @default(cuid()) 15 | contentType String 16 | organization Organization @relation("OrganizationContents", fields: [organizationId], references: [id]) 17 | organizationId String 18 | @@delegate(contentType) 19 | } 20 | 21 | model Store extends Content { 22 | name String 23 | @@unique([organizationId, name]) 24 | } 25 | ` 26 | ) 27 | ).resolves.toContain('Cannot use fields inherited from a polymorphic base model in `@@unique`'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-177.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModelWithError } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 177', () => { 4 | it('regression', async () => { 5 | await expect( 6 | loadModelWithError( 7 | ` 8 | model Foo { 9 | id String @id @default(cuid()) 10 | 11 | bar Bar @relation(fields: [barId1, barId2], references: [id1, id2]) 12 | barId1 String? 13 | barId2 String 14 | } 15 | 16 | model Bar { 17 | id1 String @default(cuid()) 18 | id2 String @default(cuid()) 19 | foos Foo[] 20 | 21 | @@id([id1, id2]) 22 | } 23 | ` 24 | ) 25 | ).resolves.toContain('relation "bar" is not optional, but field "barId1" is optional'); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1835.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1835', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | enum Enum { 8 | SOME_VALUE 9 | ANOTHER_VALUE 10 | } 11 | 12 | model Model { 13 | id String @id @default(cuid()) 14 | value Enum 15 | @@ignore 16 | } 17 | 18 | model AnotherModel { 19 | id String @id @default(cuid()) 20 | } 21 | `, 22 | { 23 | provider: 'postgresql', 24 | pushDb: false, 25 | } 26 | ); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1849.test.ts: -------------------------------------------------------------------------------- 1 | import { FILE_SPLITTER, loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1849', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | `schema.zmodel 7 | import './enum' 8 | 9 | model Post { 10 | id Int @id 11 | status Status @default(PUBLISHED) 12 | } 13 | 14 | ${FILE_SPLITTER}enum.zmodel 15 | 16 | enum Status { 17 | PENDING 18 | PUBLISHED 19 | } 20 | `, 21 | { provider: 'postgresql', pushDb: false } 22 | ); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-1870.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModel, loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 1870', () => { 4 | it('regression', async () => { 5 | await loadModel( 6 | ` 7 | model Polygon { 8 | id Int @id @default(autoincrement()) 9 | geometry Unsupported("geometry(MultiPolygon, 4326)") 10 | @@index([geometry], name: "parcel_polygon_idx", type: Gist) 11 | } 12 | ` 13 | ); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-2038.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 2038', () => { 4 | it('regression', async () => { 5 | const { enhance } = await loadSchema( 6 | ` 7 | model User { 8 | id Int @id @default(autoincrement()) 9 | flag Boolean 10 | @@allow('all', true) 11 | } 12 | 13 | model Post { 14 | id Int @id @default(autoincrement()) 15 | published Boolean @default(auth().flag) 16 | @@allow('all', true) 17 | } 18 | ` 19 | ); 20 | 21 | const db = enhance({ id: 1, flag: true }); 22 | await expect(db.post.create({ data: {} })).resolves.toMatchObject({ 23 | published: true, 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-2065.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue [...]', () => { 4 | it('regression', async () => { 5 | const { zodSchemas } = await loadSchema( 6 | ` 7 | enum FooType { 8 | Bar 9 | Baz 10 | } 11 | 12 | type Meta { 13 | test String? 14 | } 15 | 16 | model Foo { 17 | id String @id @db.Uuid @default(uuid()) 18 | type FooType 19 | meta Meta @json 20 | 21 | @@validate(type == Bar, "FooType must be Bar") 22 | } 23 | `, 24 | { 25 | provider: 'postgresql', 26 | pushDb: false, 27 | } 28 | ); 29 | expect(zodSchemas.models.FooSchema).toBeTruthy(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-2106.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue 2106', () => { 4 | it('regression', async () => { 5 | const { enhance } = await loadSchema( 6 | ` 7 | model User { 8 | id Int @id 9 | age BigInt 10 | @@allow('all', true) 11 | } 12 | `, 13 | { logPrismaQuery: true } 14 | ); 15 | 16 | const db = enhance(); 17 | await expect(db.user.create({ data: { id: 1, age: 1n } })).toResolveTruthy(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-416.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 416', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | model Example { 8 | id Int @id 9 | doubleQuote String @default("s\\"1") 10 | singleQuote String @default('s\\'1') 11 | json Json @default("{\\"theme\\": \\"light\\", \\"consoleDrawer\\": false}") 12 | } 13 | `, 14 | { provider: 'postgresql', dbUrl: 'env("DATABASE_URL")', pushDb: false } 15 | ); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-646.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 646', () => { 4 | it('regression', async () => { 5 | await loadSchema(` 6 | model Example { 7 | id Int @id 8 | epsilon Decimal @default(0.00000001) 9 | } 10 | `); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-674.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 674', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | model Foo { 8 | id Int @id 9 | } 10 | 11 | enum MyUnUsedEnum { ABC CDE @@map('my_unused_enum') } 12 | `, 13 | { provider: 'postgresql', dbUrl: 'env("DATABASE_URL")', pushDb: false } 14 | ); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-703.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 703', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | model User { 8 | id Int @id @default(autoincrement()) 9 | name String? 10 | admin Boolean @default(false) 11 | 12 | companiesWorkedFor Company[] 13 | 14 | username String @unique @allow("all", auth() == this) @allow('read', companiesWorkedFor?[owner == auth()]) @allow("all", auth().admin) 15 | } 16 | 17 | model Company { 18 | id Int @id @default(autoincrement()) 19 | name String? 20 | owner User @relation(fields: [ownerId], references: [id]) 21 | ownerId Int 22 | } 23 | ` 24 | ); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-735.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 735', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | model MyModel { 8 | id String @id @default(cuid()) 9 | view String 10 | import Int 11 | } 12 | 13 | model view { 14 | id String @id @default(cuid()) 15 | name String 16 | } 17 | `, 18 | { pushDb: false } 19 | ); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-756.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModel, loadModelWithError } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 756', () => { 4 | it('regression', async () => { 5 | expect( 6 | await loadModelWithError( 7 | ` 8 | generator client { 9 | provider = "prisma-client-js" 10 | } 11 | 12 | datasource db { 13 | provider = "postgresql" 14 | url = env("DATABASE_URL") 15 | } 16 | 17 | model User { 18 | id Int @id @default(autoincrement()) 19 | email Int 20 | posts Post[] 21 | } 22 | 23 | model Post { 24 | id Int @id @default(autoincrement()) 25 | author User? @relation(fields: [authorId], references: [id]) 26 | authorId Int 27 | @@allow('all', auth().posts.authorId == authorId) 28 | } 29 | ` 30 | ) 31 | ).toContain(`Could not resolve reference to MemberAccessTarget named 'authorId'.`); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-804.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModelWithError } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 804', () => { 4 | it('regression', async () => { 5 | expect( 6 | await loadModelWithError( 7 | ` 8 | generator client { 9 | provider = "prisma-client-js" 10 | } 11 | 12 | datasource db { 13 | provider = "postgresql" 14 | url = env("DATABASE_URL") 15 | } 16 | 17 | model User { 18 | id Int @id @default(autoincrement()) 19 | email Int 20 | posts Post[] 21 | } 22 | 23 | model Post { 24 | id Int @id @default(autoincrement()) 25 | author User? @relation(fields: [authorId], references: [id]) 26 | authorId Int 27 | published Boolean 28 | 29 | @@allow('all', auth().posts?[published] == 'TRUE') 30 | } 31 | ` 32 | ) 33 | ).toContain('incompatible operand types'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-886.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 886', () => { 4 | it('regression', async () => { 5 | const { zodSchemas } = await loadSchema( 6 | ` 7 | model Model { 8 | id Int @id @default(autoincrement()) 9 | a Int @default(100) 10 | b String @default('') 11 | c DateTime @default(now()) 12 | } 13 | ` 14 | ); 15 | 16 | const r = zodSchemas.models.ModelSchema.parse({ id: 1 }); 17 | expect(r.a).toBe(100); 18 | expect(r.b).toBe(''); 19 | expect(r.c).toBeInstanceOf(Date); 20 | expect(r.id).toBe(1); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-947.test.ts: -------------------------------------------------------------------------------- 1 | import { loadModel } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 947', () => { 4 | it('regression', async () => { 5 | await loadModel( 6 | ` 7 | model Test { 8 | id String @id 9 | props TestEnum[] @default([]) 10 | } 11 | 12 | enum TestEnum { 13 | A 14 | B 15 | } 16 | ` 17 | ); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-971.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('Regression: issue 971', () => { 4 | it('regression', async () => { 5 | await loadSchema( 6 | ` 7 | abstract model Level1 { 8 | id String @id @default(cuid()) 9 | URL String? 10 | @@validate(URL != null, "URL must be provided") // works 11 | } 12 | abstract model Level2 extends Level1 { 13 | @@validate(URL != null, "URL must be provided") // works 14 | } 15 | abstract model Level3 extends Level2 { 16 | @@validate(URL != null, "URL must be provided") // doesn't work 17 | } 18 | model Foo extends Level3 { 19 | } 20 | ` 21 | ); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /tests/regression/tests/issue-foo.test.ts: -------------------------------------------------------------------------------- 1 | import { loadSchema } from '@zenstackhq/testtools'; 2 | 3 | describe('issue [...]', () => { 4 | it('regression', async () => { 5 | const { zodSchemas } = await loadSchema( 6 | ` 7 | enum FooType { 8 | Bar 9 | Baz 10 | } 11 | type Meta { 12 | test String? 13 | } 14 | model Foo { 15 | id String @id @db.Uuid @default(uuid()) 16 | type FooType 17 | meta Meta @json 18 | @@validate(type == Bar, "FooType must be Bar") 19 | } 20 | `, 21 | { 22 | provider: 'postgresql', 23 | pushDb: false, 24 | } 25 | ); 26 | expect( 27 | zodSchemas.models.FooSchema.safeParse({ 28 | id: '123e4567-e89b-12d3-a456-426614174000', 29 | type: 'Bar', 30 | meta: { test: 'test' }, 31 | }) 32 | ).toMatchObject({ 33 | success: true, 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /tests/regression/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "experimentalDecorators": true 10 | }, 11 | "include": ["**/*.ts", "**/*.d.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs", 5 | "lib": ["ESNext"], 6 | "sourceMap": true, 7 | "strict": true, 8 | "noUnusedLocals": false, 9 | "noImplicitReturns": true, 10 | "moduleResolution": "node", 11 | "esModuleInterop": true, 12 | "skipLibCheck": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "baseUrl": ".", 15 | "resolveJsonModule": true, 16 | "declaration": true, 17 | "experimentalDecorators": true 18 | } 19 | } 20 | --------------------------------------------------------------------------------