diff --git a/.github/workflows/github-releases-to-discord.yml b/.github/workflows/github-releases-to-discord.yml index dbd4c8d13..0bb79bb33 100644 --- a/.github/workflows/github-releases-to-discord.yml +++ b/.github/workflows/github-releases-to-discord.yml @@ -12,4 +12,3 @@ jobs: with: webhook_url: ${{ secrets.RELEASE_TO_DISCORD_WEBHOOK_URL }} avatar_url: 'https://cdn.discordapp.com/avatars/1297059323314176051/df91181b3f1cf0ef1592fbe18e0962d7.webp?size=160' - reduce_headings: true diff --git a/package.json b/package.json index 4ac4b1699..f39b71e08 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "2.15.1", + "version": "2.16.0", "description": "", "scripts": { "build": "pnpm -r --filter=\"!./packages/ide/*\" build", @@ -34,10 +34,8 @@ "eslint": "^8.57.0", "eslint-plugin-jest": "^28.2.0", "jest": "^29.7.0", - "replace-in-file": "^7.0.1", "rimraf": "^3.0.2", "ts-jest": "^29.1.1", - "ts-node": "^10.9.1", "tsup": "^8.0.1", "tsx": "^4.7.1", "typescript": "^5.4.4" diff --git a/packages/ide/jetbrains/build.gradle.kts b/packages/ide/jetbrains/build.gradle.kts index e5311c8b7..ff1ea417e 100644 --- a/packages/ide/jetbrains/build.gradle.kts +++ b/packages/ide/jetbrains/build.gradle.kts @@ -85,9 +85,9 @@ changelog { introduction.set( """ [ZenStack](https://zenstack.dev) is a toolkit that simplifies the development of a web app's backend. This plugin provides code editing experiences for its ZModel schema language. - + ## Features - + - Syntax highlighting - Error highlighting - Go to definition diff --git a/packages/ide/jetbrains/package.json b/packages/ide/jetbrains/package.json index c2be72642..588f7a2b1 100644 --- a/packages/ide/jetbrains/package.json +++ b/packages/ide/jetbrains/package.json @@ -1,6 +1,6 @@ { "name": "jetbrains", - "version": "2.15.1", + "version": "2.16.0", "displayName": "ZenStack JetBrains IDE Plugin", "description": "ZenStack JetBrains IDE plugin", "homepage": "https://zenstack.dev", diff --git a/packages/language/package.json b/packages/language/package.json index 008354f28..43184864d 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/language", - "version": "2.15.1", + "version": "2.16.0", "displayName": "ZenStack modeling language compiler", "description": "ZenStack modeling language compiler", "homepage": "https://zenstack.dev", diff --git a/packages/language/src/zmodel.langium b/packages/language/src/zmodel.langium index 86d28276b..4b311bcba 100644 --- a/packages/language/src/zmodel.langium +++ b/packages/language/src/zmodel.langium @@ -164,7 +164,7 @@ Argument: DataModel: (comments+=TRIPLE_SLASH_COMMENT)* ( - ((isAbstract?='abstract')? 'model' name=RegularID + ((isAbstract?='abstract')? 'model' name=RegularID ('extends' superTypes+=[DataModel] (',' superTypes+=[DataModel])*)?) | ((isView?='view') name=RegularID) ) @@ -193,7 +193,7 @@ TypeDef: type TypeDefFieldTypes = TypeDef | Enum; TypeDefField: - (comments+=TRIPLE_SLASH_COMMENT)* + (comments+=TRIPLE_SLASH_COMMENT)* name=RegularIDWithTypeNames type=TypeDefFieldType (attributes+=DataModelFieldAttribute)*; TypeDefFieldType: @@ -208,7 +208,7 @@ Enum: 'enum' name=RegularID '{' ( fields+=EnumField | attributes+=DataModelAttribute - )+ + )+ '}'; EnumField: diff --git a/packages/misc/redwood/package.json b/packages/misc/redwood/package.json index be767c788..70aa6e8cd 100644 --- a/packages/misc/redwood/package.json +++ b/packages/misc/redwood/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/redwood", "displayName": "ZenStack RedwoodJS Integration", - "version": "2.15.1", + "version": "2.16.0", "description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.", "repository": { "type": "git", diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json index 8a3473009..82ca6ad55 100644 --- a/packages/plugins/openapi/package.json +++ b/packages/plugins/openapi/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/openapi", "displayName": "ZenStack Plugin and Runtime for OpenAPI", - "version": "2.15.1", + "version": "2.16.0", "description": "ZenStack plugin and runtime supporting OpenAPI", "main": "index.js", "repository": { @@ -28,15 +28,11 @@ "dependencies": { "@zenstackhq/runtime": "workspace:*", "@zenstackhq/sdk": "workspace:*", - "change-case": "^4.1.2", - "lower-case-first": "^2.0.2", "openapi-types": "^12.1.0", "semver": "^7.5.2", - "tiny-invariant": "^1.3.1", "ts-pattern": "^4.3.0", - "upper-case-first": "^2.0.2", "yaml": "^2.2.2", - "zod": "^3.22.4", + "zod": "^3.22.4", "zod-validation-error": "^1.5.0" }, "devDependencies": { diff --git a/packages/plugins/openapi/src/rest-generator.ts b/packages/plugins/openapi/src/rest-generator.ts index 88768b3e8..5a1344c2b 100644 --- a/packages/plugins/openapi/src/rest-generator.ts +++ b/packages/plugins/openapi/src/rest-generator.ts @@ -26,12 +26,11 @@ import { TypeDefFieldType, } from '@zenstackhq/sdk/ast'; import type { DMMF } from '@zenstackhq/sdk/prisma'; +import { invariant, lowerCaseFirst } from '@zenstackhq/runtime/local-helpers'; import fs from 'fs'; -import { lowerCaseFirst } from 'lower-case-first'; import type { OpenAPIV3_1 as OAPI } from 'openapi-types'; import path from 'path'; import pluralize from 'pluralize'; -import invariant from 'tiny-invariant'; import { match, P } from 'ts-pattern'; import YAML from 'yaml'; import { name } from '.'; diff --git a/packages/plugins/openapi/src/rpc-generator.ts b/packages/plugins/openapi/src/rpc-generator.ts index cb3b9ead1..5b47b810f 100644 --- a/packages/plugins/openapi/src/rpc-generator.ts +++ b/packages/plugins/openapi/src/rpc-generator.ts @@ -11,13 +11,11 @@ import { resolveAggregateOperationSupport, } from '@zenstackhq/sdk/dmmf-helpers'; import { supportCreateMany, type DMMF } from '@zenstackhq/sdk/prisma'; +import { lowerCaseFirst, upperCaseFirst, invariant } from '@zenstackhq/runtime/local-helpers'; import * as fs from 'fs'; -import { lowerCaseFirst } from 'lower-case-first'; import type { OpenAPIV3_1 as OAPI } from 'openapi-types'; import * as path from 'path'; -import invariant from 'tiny-invariant'; import { P, match } from 'ts-pattern'; -import { upperCaseFirst } from 'upper-case-first'; import YAML from 'yaml'; import { name } from '.'; import { OpenAPIGeneratorBase } from './generator-base'; diff --git a/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml b/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml index 364062e4e..1e331ab8e 100644 --- a/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml +++ b/packages/plugins/openapi/tests/baseline/rest-3.1.0.baseline.yaml @@ -10,7 +10,7 @@ tags: - name: post_Item description: Post-related operations - name: postLike - description: PostLike operations + description: PostLike operations paths: /user: get: diff --git a/packages/plugins/swr/package.json b/packages/plugins/swr/package.json index a4410973a..3b53435c2 100644 --- a/packages/plugins/swr/package.json +++ b/packages/plugins/swr/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/swr", "displayName": "ZenStack plugin for generating SWR hooks", - "version": "2.15.1", + "version": "2.16.0", "description": "ZenStack plugin for generating SWR hooks", "main": "index.js", "repository": { @@ -40,13 +40,10 @@ "dependencies": { "@zenstackhq/runtime": "workspace:*", "@zenstackhq/sdk": "workspace:*", - "change-case": "^4.1.2", "cross-fetch": "^4.0.0", - "lower-case-first": "^2.0.2", "semver": "^7.5.2", "ts-morph": "^16.0.0", - "ts-pattern": "^4.3.0", - "upper-case-first": "^2.0.2" + "ts-pattern": "^4.3.0" }, "peerDependencies": { "swr": "2.2.5 - 2" diff --git a/packages/plugins/swr/src/generator.ts b/packages/plugins/swr/src/generator.ts index 5ecfe4d84..a2fee939e 100644 --- a/packages/plugins/swr/src/generator.ts +++ b/packages/plugins/swr/src/generator.ts @@ -12,11 +12,10 @@ import { } from '@zenstackhq/sdk'; import { DataModel, DataModelFieldType, Model, isEnum, isTypeDef } from '@zenstackhq/sdk/ast'; import { getPrismaClientImportSpec, supportCreateMany, type DMMF } from '@zenstackhq/sdk/prisma'; -import { paramCase } from 'change-case'; +import { upperCaseFirst, paramCase } from '@zenstackhq/runtime/local-helpers'; import path from 'path'; import type { OptionalKind, ParameterDeclarationStructure, Project, SourceFile } from 'ts-morph'; import { P, match } from 'ts-pattern'; -import { upperCaseFirst } from 'upper-case-first'; import { name } from '.'; export async function generate(model: Model, options: PluginOptions, dmmf: DMMF.Document) { diff --git a/packages/plugins/swr/src/runtime/index.ts b/packages/plugins/swr/src/runtime/index.ts index 71004d66a..9f1df0b8e 100644 --- a/packages/plugins/swr/src/runtime/index.ts +++ b/packages/plugins/swr/src/runtime/index.ts @@ -7,7 +7,7 @@ import { type ModelMeta, type PrismaWriteActionType, } from '@zenstackhq/runtime/cross'; -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst } from '@zenstackhq/runtime/local-helpers'; import { createContext, useContext } from 'react'; import type { Cache, Fetcher, SWRConfiguration, SWRResponse } from 'swr'; import useSWR, { useSWRConfig } from 'swr'; diff --git a/packages/plugins/swr/tests/react-hooks.test.tsx b/packages/plugins/swr/tests/react-hooks.test.tsx index fa495f97a..78f41a40b 100644 --- a/packages/plugins/swr/tests/react-hooks.test.tsx +++ b/packages/plugins/swr/tests/react-hooks.test.tsx @@ -7,7 +7,7 @@ /// import { renderHook, waitFor } from '@testing-library/react'; -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst } from '@zenstackhq/runtime/local-helpers'; import nock from 'nock'; import { SWRConfig, useSWRConfig } from 'swr'; import { diff --git a/packages/plugins/tanstack-query/package.json b/packages/plugins/tanstack-query/package.json index 91d45f688..fc5455bad 100644 --- a/packages/plugins/tanstack-query/package.json +++ b/packages/plugins/tanstack-query/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/tanstack-query", "displayName": "ZenStack plugin for generating tanstack-query hooks", - "version": "2.15.1", + "version": "2.16.0", "description": "ZenStack plugin for generating tanstack-query hooks", "main": "index.js", "exports": { @@ -82,13 +82,10 @@ "dependencies": { "@zenstackhq/runtime": "workspace:*", "@zenstackhq/sdk": "workspace:*", - "change-case": "^4.1.2", "cross-fetch": "^4.0.0", - "lower-case-first": "^2.0.2", "semver": "^7.5.2", "ts-morph": "^16.0.0", - "ts-pattern": "^4.3.0", - "upper-case-first": "^2.0.2" + "ts-pattern": "^4.3.0" }, "devDependencies": { "@tanstack/react-query": "^4.29.7", @@ -101,11 +98,11 @@ "@types/semver": "^7.3.13", "@types/tmp": "^0.2.3", "@zenstackhq/testtools": "workspace:*", + "glob": "^8.1.0", "jest-environment-jsdom": "^29.7.0", "nock": "^13.3.6", "react": "18.2.0", "react-test-renderer": "^18.2.0", - "replace-in-file": "^7.0.1", "svelte": "^4.2.1", "swr": "^2.0.3", "tmp": "^0.2.3", diff --git a/packages/plugins/tanstack-query/scripts/postbuild.js b/packages/plugins/tanstack-query/scripts/postbuild.js index 3be17257c..9fbbace04 100755 --- a/packages/plugins/tanstack-query/scripts/postbuild.js +++ b/packages/plugins/tanstack-query/scripts/postbuild.js @@ -1,32 +1,47 @@ // tsup doesn't replace npm dependency aliases in the dist files, so we have to do it manually -const replace = require('replace-in-file'); +const fs = require('fs'); +const glob = require('glob'); + +function replaceSync({ file, from, to }) { + const paths = glob.sync(file, { ignore: [], nodir: true }); + + paths.forEach(path => { + const contents = fs.readFileSync(path, { encoding: 'utf-8' }); + + const newContents = contents.replace(from, to); + + if (newContents !== contents) { + fs.writeFileSync(path, newContents, { encoding: 'utf-8' }); + } + }); +} // tsup incorrectly resolve to legacy types, make a fix here console.log('Replacing @tanstack/react-query-v5/build/legacy/types'); -replace.sync({ - files: 'dist/runtime-v5/react*(.d.ts|.d.mts)', +replaceSync({ + file: 'dist/runtime-v5/react*(.d.ts|.d.mts)', from: /@tanstack\/react-query-v5\/build\/legacy\/types/g, to: '@tanstack/react-query', }); console.log('Replacing @tanstack/react-query-v5'); -replace.sync({ - files: 'dist/runtime-v5/react*(.d.ts|.d.mts|.js|.mjs)', +replaceSync({ + file: 'dist/runtime-v5/react*(.d.ts|.d.mts|.js|.mjs)', from: /@tanstack\/react-query-v5/g, to: '@tanstack/react-query', }); console.log('Replacing @tanstack/svelte-query-v5'); -replace.sync({ - files: 'dist/runtime-v5/svelte*(.d.ts|.d.mts|.js|.mjs)', +replaceSync({ + file: 'dist/runtime-v5/svelte*(.d.ts|.d.mts|.js|.mjs)', from: /@tanstack\/svelte-query-v5/g, to: '@tanstack/svelte-query', }); console.log('Replacing @tanstack/vue-query-v5'); -replace.sync({ - files: 'dist/runtime-v5/vue*(.d.ts|.d.mts|.js|.mjs)', +replaceSync({ + file: 'dist/runtime-v5/vue*(.d.ts|.d.mts|.js|.mjs)', from: /@tanstack\/vue-query-v5/g, to: '@tanstack/vue-query', }); diff --git a/packages/plugins/tanstack-query/src/generator.ts b/packages/plugins/tanstack-query/src/generator.ts index c45a32517..31e5c235a 100644 --- a/packages/plugins/tanstack-query/src/generator.ts +++ b/packages/plugins/tanstack-query/src/generator.ts @@ -6,6 +6,7 @@ import { ensureEmptyDir, generateModelMeta, getDataModels, + getPrismaClientGenerator, isDelegateModel, requireOption, resolvePath, @@ -13,13 +14,11 @@ import { } from '@zenstackhq/sdk'; import { DataModel, DataModelFieldType, Model, isEnum, isTypeDef } from '@zenstackhq/sdk/ast'; import { getPrismaClientImportSpec, supportCreateMany, type DMMF } from '@zenstackhq/sdk/prisma'; -import { paramCase } from 'change-case'; +import { lowerCaseFirst, upperCaseFirst, paramCase } from '@zenstackhq/runtime/local-helpers'; import fs from 'fs'; -import { lowerCaseFirst } from 'lower-case-first'; import path from 'path'; import { Project, SourceFile, VariableDeclarationKind } from 'ts-morph'; import { P, match } from 'ts-pattern'; -import { upperCaseFirst } from 'upper-case-first'; import { name } from '.'; const supportedTargets = ['react', 'vue', 'svelte']; @@ -52,7 +51,6 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF. `Invalid value for "portable" option: ${options.portable}, a boolean value is expected` ); } - const portable = options.portable ?? false; await generateModelMeta(project, models, typeDefs, { output: path.join(outDir, '__model_meta.ts'), @@ -70,8 +68,13 @@ export async function generate(model: Model, options: PluginOptions, dmmf: DMMF. generateModelHooks(target, version, project, outDir, dataModel, mapping, options); }); - if (portable) { - generateBundledTypes(project, outDir, options); + if (options.portable) { + const gen = getPrismaClientGenerator(model); + if (gen?.isNewGenerator) { + warnings.push(`The "portable" option is not supported with the "prisma-client" generator and is ignored.`); + } else { + generateBundledTypes(project, outDir, options); + } } await saveProject(project); diff --git a/packages/plugins/trpc/package.json b/packages/plugins/trpc/package.json index 44af8ef76..670883c74 100644 --- a/packages/plugins/trpc/package.json +++ b/packages/plugins/trpc/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/trpc", "displayName": "ZenStack plugin for tRPC", - "version": "2.15.1", + "version": "2.16.0", "description": "ZenStack plugin for tRPC", "main": "index.js", "repository": { @@ -26,15 +26,13 @@ "author": "ZenStack Team", "license": "MIT", "dependencies": { + "@zenstackhq/runtime": "workspace:*", "@zenstackhq/sdk": "workspace:*", - "change-case": "^4.1.2", - "lower-case-first": "^2.0.2", "ts-morph": "^16.0.0", - "tslib": "^2.4.1", - "upper-case-first": "^2.0.2" + "tslib": "^2.4.1" }, "peerDependencies": { - "zod": "^3.22.4" + "zod": "^3.22.4" }, "devDependencies": { "@trpc/next": "^10.32.0", diff --git a/packages/plugins/trpc/src/client-helper/index.ts b/packages/plugins/trpc/src/client-helper/index.ts index 99679c716..a90f1338d 100644 --- a/packages/plugins/trpc/src/client-helper/index.ts +++ b/packages/plugins/trpc/src/client-helper/index.ts @@ -1,7 +1,7 @@ import { PluginError, type PluginOptions } from '@zenstackhq/sdk'; import { getPrismaClientImportSpec } from '@zenstackhq/sdk/prisma'; +import { lowerCaseFirst, upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import fs from 'fs'; -import { lowerCaseFirst } from 'lower-case-first'; import path from 'path'; import { InterfaceDeclarationStructure, @@ -10,7 +10,6 @@ import { SourceFile, StructureKind, } from 'ts-morph'; -import { upperCaseFirst } from 'upper-case-first'; import { name } from '..'; import { SupportedClientHelpers } from '../utils'; import * as NextHelpers from './next'; diff --git a/packages/plugins/trpc/src/generator.ts b/packages/plugins/trpc/src/generator.ts index 5f7d8601b..66f067add 100644 --- a/packages/plugins/trpc/src/generator.ts +++ b/packages/plugins/trpc/src/generator.ts @@ -12,10 +12,9 @@ import { } from '@zenstackhq/sdk'; import { DataModel, isDataModel, Model } from '@zenstackhq/sdk/ast'; import { getPrismaClientImportSpec, supportCreateMany, type DMMF } from '@zenstackhq/sdk/prisma'; -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst, upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import path from 'path'; import { Project } from 'ts-morph'; -import { upperCaseFirst } from 'upper-case-first'; import { name } from '.'; import { createClientHelperEntries, generateClientTypingForModel } from './client-helper'; import { project } from './project'; @@ -169,12 +168,12 @@ function createAppRouter( >( procedures: ProcRouterRecord ) => CreateRouterInner; - + export type UnsetMarker = typeof unsetMarker; export type ProcBuilder = ProcedureBuilder< ProcedureParams - >; + >; `); } else { appRouter.addImportDeclaration({ diff --git a/packages/plugins/trpc/src/utils.ts b/packages/plugins/trpc/src/utils.ts index 258f697ff..86d626bdc 100644 --- a/packages/plugins/trpc/src/utils.ts +++ b/packages/plugins/trpc/src/utils.ts @@ -1,7 +1,6 @@ import { type DMMF } from '@zenstackhq/sdk/prisma'; -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst, upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import { CodeBlockWriter, SourceFile } from 'ts-morph'; -import { upperCaseFirst } from 'upper-case-first'; /** * Supported client helper types diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package-lock.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package-lock.json index d2afbe91c..bc1ff51f5 100644 --- a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package-lock.json +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package-lock.json @@ -6044,7 +6044,6 @@ "dependencies": { "@redocly/openapi-core": "^1.25.9", "ansi-colors": "^4.1.3", - "change-case": "^5.4.4", "parse-json": "^8.1.0", "supports-color": "^9.4.0", "yargs-parser": "^21.1.1" @@ -6056,11 +6055,6 @@ "typescript": "^5.x" } }, - "node_modules/openapi-typescript/node_modules/change-case": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", - "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==" - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -7507,10 +7501,6 @@ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==" }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "license": "MIT" - }, "node_modules/tinyglobby": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", @@ -8041,7 +8031,6 @@ "fs-extra": "^11.1.0", "npm-run-path": "^4.0.1", "strip-ansi": "^6.0.0", - "tiny-invariant": "^1.1.0", "vscode-languageclient": "^7.0.0", "vscode-languageserver": "^7.0.0", "vscode-languageserver-textdocument": "^1.0.1", diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json index 27196d87f..45b49215d 100644 --- a/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json @@ -10,18 +10,18 @@ "postinstall": "nuxt prepare" }, "dependencies": { - "@prisma/client": "6.8.x", + "@prisma/client": "6.10.x", "@trpc/client": "^10.45.2", "@trpc/server": "^10.45.2", "nuxt": "^3.14.1592", "trpc-nuxt": "^0.10.22", "vue": "latest", "vue-router": "latest", - "zod": "^3.22.4" + "zod": "^3.22.4" }, "devDependencies": { "esbuild": "^0.24.0", - "prisma": "6.8.x", + "prisma": "6.10.x", "typescript": "^5.6.2", "vue-tsc": "^2.1.10" } diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package-lock.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package-lock.json index 131cf5c05..702316fd3 100644 --- a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package-lock.json +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package-lock.json @@ -3224,11 +3224,6 @@ "node": ">=8" } }, - "node_modules/change-case": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", - "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==" - }, "node_modules/chokidar": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", @@ -6393,7 +6388,6 @@ "dependencies": { "@redocly/openapi-core": "^1.25.9", "ansi-colors": "^4.1.3", - "change-case": "^5.4.4", "parse-json": "^8.1.0", "supports-color": "^9.4.0", "yargs-parser": "^21.1.1" @@ -7904,11 +7898,6 @@ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==" }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, "node_modules/tinyglobby": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", @@ -8491,7 +8480,6 @@ "fs-extra": "^11.1.0", "npm-run-path": "^4.0.1", "strip-ansi": "^6.0.0", - "tiny-invariant": "^1.1.0", "vscode-languageclient": "^7.0.0", "vscode-languageserver": "^7.0.0", "vscode-languageserver-textdocument": "^1.0.1", diff --git a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json index b420e972a..e8be9a741 100644 --- a/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json +++ b/packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json @@ -10,18 +10,18 @@ "postinstall": "nuxt prepare" }, "dependencies": { - "@prisma/client": "6.8.x", + "@prisma/client": "6.10.x", "@trpc/client": "^11.0.0-rc.563", "@trpc/server": "^11.0.0-rc.563", "nuxt": "^3.14.1592", "trpc-nuxt": "^0.11.0-beta.1", "vue": "latest", "vue-router": "latest", - "zod": "^3.22.4" + "zod": "^3.22.4" }, "devDependencies": { "esbuild": "^0.24.0", - "prisma": "6.8.x", + "prisma": "6.10.x", "typescript": "^5.6.2", "vue-tsc": "^2.1.10" } diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v10/package.json b/packages/plugins/trpc/tests/projects/t3-trpc-v10/package.json index ad9203091..e26114fee 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v10/package.json +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v10/package.json @@ -24,7 +24,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "superjson": "^2.2.1", - "zod": "^3.22.4" + "zod": "^3.22.4" }, "devDependencies": { "@types/eslint": "^8.44.7", diff --git a/packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json b/packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json index ec275a98f..3b3d17c27 100644 --- a/packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json +++ b/packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json @@ -15,7 +15,7 @@ "start": "next start" }, "dependencies": { - "@prisma/client": "6.8.x", + "@prisma/client": "6.10.x", "@t3-oss/env-nextjs": "^0.10.1", "@tanstack/react-query": "^5.50.0", "@trpc/client": "^11.0.0-rc.446", @@ -28,7 +28,7 @@ "react-dom": "^18.3.1", "server-only": "^0.0.1", "superjson": "^2.2.1", - "zod": "^3.22.4" + "zod": "^3.22.4" }, "devDependencies": { "@types/eslint": "^8.56.10", @@ -39,7 +39,7 @@ "@typescript-eslint/parser": "^8.1.0", "eslint": "^8.57.0", "eslint-config-next": "^14.2.4", - "prisma": "6.8.x", + "prisma": "6.10.x", "typescript": "^5.5.3" }, "ct3aMetadata": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 4cc525ae5..c0453d148 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "2.15.1", + "version": "2.16.0", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", @@ -21,6 +21,10 @@ "types": "./index.d.ts", "default": "./index.js" }, + "./local-helpers": { + "types": "./local-helpers/index.d.ts", + "default": "./local-helpers/index.js" + }, "./edge": { "types": "./edge.d.ts", "default": "./edge.js" @@ -96,27 +100,22 @@ "dependencies": { "bcryptjs": "^2.4.3", "buffer": "^6.0.3", - "change-case": "^4.1.2", "decimal.js-light": "^2.5.1", "deepmerge": "^4.3.1", - "is-plain-object": "^5.0.0", "logic-solver": "^2.0.1", - "lower-case-first": "^2.0.2", "pluralize": "^8.0.0", "safe-json-stringify": "^1.2.0", "semver": "^7.5.2", "superjson": "^1.13.0", - "tiny-invariant": "^1.3.1", "traverse": "^0.6.10", "ts-pattern": "^4.3.0", "tslib": "^2.4.1", - "upper-case-first": "^2.0.2", "uuid": "^9.0.0", "zod": "^3.22.4", "zod-validation-error": "^1.5.0" }, "peerDependencies": { - "@prisma/client": "5.0.0 - 6.8.x" + "@prisma/client": "5.0.0 - 6.10.x" }, "author": { "name": "ZenStack Team" @@ -129,6 +128,9 @@ "@types/safe-json-stringify": "^1.1.5", "@types/semver": "^7.3.13", "@types/traverse": "^0.6.37", - "@types/uuid": "^8.3.4" + "@types/uuid": "^8.3.4", + "decimal.js-light": "^2.5.1", + "superjson": "^1.13.0", + "uuid": "^9.0.0" } } diff --git a/packages/runtime/src/cross/clone.ts b/packages/runtime/src/cross/clone.ts index 1a355d7bf..4ed5d8409 100644 --- a/packages/runtime/src/cross/clone.ts +++ b/packages/runtime/src/cross/clone.ts @@ -1,4 +1,4 @@ -import { isPlainObject } from 'is-plain-object'; +import { isPlainObject } from '../local-helpers'; /** * Clones the given object. Only arrays and plain objects are cloned. Other values are returned as is. diff --git a/packages/runtime/src/cross/model-meta.ts b/packages/runtime/src/cross/model-meta.ts index ad8d2aa76..e125eec8b 100644 --- a/packages/runtime/src/cross/model-meta.ts +++ b/packages/runtime/src/cross/model-meta.ts @@ -1,4 +1,4 @@ -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst } from '../local-helpers'; /** * Runtime information of a data model or field attribute diff --git a/packages/runtime/src/cross/query-analyzer.ts b/packages/runtime/src/cross/query-analyzer.ts index 9277688d5..ad8949998 100644 --- a/packages/runtime/src/cross/query-analyzer.ts +++ b/packages/runtime/src/cross/query-analyzer.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst } from '../local-helpers'; import type { ModelMeta } from './model-meta'; import { NestedReadVisitor } from './nested-read-visitor'; import { NestedWriteVisitor } from './nested-write-visitor'; diff --git a/packages/runtime/src/cross/utils.ts b/packages/runtime/src/cross/utils.ts index b1cb67e12..c56ff3cf9 100644 --- a/packages/runtime/src/cross/utils.ts +++ b/packages/runtime/src/cross/utils.ts @@ -1,4 +1,4 @@ -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst } from '../local-helpers'; import { requireField, type ModelInfo, type ModelMeta, type TypeDefInfo } from '.'; /** diff --git a/packages/runtime/src/enhancements/node/delegate.ts b/packages/runtime/src/enhancements/node/delegate.ts index 1d7cd3f53..06d6b2341 100644 --- a/packages/runtime/src/enhancements/node/delegate.ts +++ b/packages/runtime/src/enhancements/node/delegate.ts @@ -1,7 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import deepmerge, { type ArrayMergeOptions } from 'deepmerge'; -import { isPlainObject } from 'is-plain-object'; -import { lowerCaseFirst } from 'lower-case-first'; import traverse from 'traverse'; import { DELEGATE_AUX_RELATION_PREFIX } from '../../constants'; import { @@ -16,6 +14,7 @@ import { isDelegateModel, resolveField, } from '../../cross'; +import { isPlainObject, lowerCaseFirst } from '../../local-helpers'; import type { CrudContract, DbClientContract, EnhancementContext } from '../../types'; import type { InternalEnhancementOptions } from './create-enhancement'; import { Logger } from './logger'; diff --git a/packages/runtime/src/enhancements/node/policy/handler.ts b/packages/runtime/src/enhancements/node/policy/handler.ts index 4285d3bd2..f42dad01f 100644 --- a/packages/runtime/src/enhancements/node/policy/handler.ts +++ b/packages/runtime/src/enhancements/node/policy/handler.ts @@ -1,9 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import deepmerge from 'deepmerge'; -import { lowerCaseFirst } from 'lower-case-first'; -import invariant from 'tiny-invariant'; -import { upperCaseFirst } from 'upper-case-first'; import { fromZodError } from 'zod-validation-error'; import { CrudFailureReason } from '../../../constants'; import { @@ -18,6 +15,7 @@ import { type FieldInfo, type ModelMeta, } from '../../../cross'; +import { lowerCaseFirst, upperCaseFirst, invariant } from '../../../local-helpers'; import { EnhancementContext, PolicyOperationKind, type CrudContract, type DbClientContract } from '../../../types'; import type { InternalEnhancementOptions } from '../create-enhancement'; import { Logger } from '../logger'; diff --git a/packages/runtime/src/enhancements/node/policy/policy-utils.ts b/packages/runtime/src/enhancements/node/policy/policy-utils.ts index 2ee389476..36f4a3212 100644 --- a/packages/runtime/src/enhancements/node/policy/policy-utils.ts +++ b/packages/runtime/src/enhancements/node/policy/policy-utils.ts @@ -1,10 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import deepmerge from 'deepmerge'; -import { isPlainObject } from 'is-plain-object'; -import { lowerCaseFirst } from 'lower-case-first'; import traverse from 'traverse'; -import { upperCaseFirst } from 'upper-case-first'; import { z, type ZodError, type ZodObject, type ZodSchema } from 'zod'; import { fromZodError } from 'zod-validation-error'; import { CrudFailureReason, PrismaErrorCode } from '../../../constants'; @@ -18,6 +15,7 @@ import { type FieldInfo, type ModelMeta, } from '../../../cross'; +import { isPlainObject, lowerCaseFirst, upperCaseFirst } from '../../../local-helpers'; import { AuthUser, CrudContract, @@ -939,7 +937,7 @@ export class PolicyUtil extends QueryUtils { } } - if (schema) { + if (schema && !this.options.validation?.inputOnlyValidationForUpdate) { // TODO: push down schema check to the database this.validateZodSchema(model, undefined, result, true, (err) => { throw this.deniedByPolicy( diff --git a/packages/runtime/src/local-helpers/index.ts b/packages/runtime/src/local-helpers/index.ts new file mode 100644 index 000000000..ace4550d2 --- /dev/null +++ b/packages/runtime/src/local-helpers/index.ts @@ -0,0 +1,6 @@ +export * from './sleep'; +export * from './is-plain-object'; +export * from './lower-case-first'; +export * from './upper-case-first'; +export * from './param-case'; +export * from './tiny-invariant'; diff --git a/packages/runtime/src/local-helpers/is-plain-object.ts b/packages/runtime/src/local-helpers/is-plain-object.ts new file mode 100644 index 000000000..f5c13d6df --- /dev/null +++ b/packages/runtime/src/local-helpers/is-plain-object.ts @@ -0,0 +1,23 @@ +function isObject(o: unknown) { + return Object.prototype.toString.call(o) === '[object Object]'; +} + +export function isPlainObject(o: unknown) { + if (isObject(o) === false) return false; + + // If has modified constructor + const ctor = (o as { constructor: unknown }).constructor; + if (ctor === undefined) return true; + + // If has modified prototype + const prot = (ctor as { prototype: unknown }).prototype; + if (isObject(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (Object.prototype.hasOwnProperty.call(prot, 'isPrototypeOf') === false) { + return false; + } + + // Most likely a plain Object + return true; +} diff --git a/packages/runtime/src/local-helpers/lower-case-first.ts b/packages/runtime/src/local-helpers/lower-case-first.ts new file mode 100644 index 000000000..a05a05be1 --- /dev/null +++ b/packages/runtime/src/local-helpers/lower-case-first.ts @@ -0,0 +1,3 @@ +export function lowerCaseFirst(input: string) { + return input.charAt(0).toLowerCase() + input.slice(1); +} diff --git a/packages/runtime/src/local-helpers/param-case.ts b/packages/runtime/src/local-helpers/param-case.ts new file mode 100644 index 000000000..3cb1f0179 --- /dev/null +++ b/packages/runtime/src/local-helpers/param-case.ts @@ -0,0 +1,18 @@ +const DEFAULT_SPLIT_REGEXP_1 = /([a-z0-9])([A-Z])/g; +const DEFAULT_SPLIT_REGEXP_2 = /([A-Z])([A-Z][a-z])/g; +const DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; + +export function paramCase(input: string) { + const result = input + .replace(DEFAULT_SPLIT_REGEXP_1, "$1\0$2") + .replace(DEFAULT_SPLIT_REGEXP_2, "$1\0$2") + .replace(DEFAULT_STRIP_REGEXP, "\0"); + + let start = 0; + let end = result.length; + + while (result.charAt(start) === "\0") start++; + while (result.charAt(end - 1) === "\0") end--; + + return result.slice(start, end).split("\0").map((str) => str.toLowerCase()).join("-"); +} diff --git a/packages/runtime/src/local-helpers/sleep.ts b/packages/runtime/src/local-helpers/sleep.ts new file mode 100644 index 000000000..5281ad0b6 --- /dev/null +++ b/packages/runtime/src/local-helpers/sleep.ts @@ -0,0 +1,5 @@ +export function sleep(timeout: number) { + return new Promise((resolve) => { + setTimeout(() => resolve(), timeout); + }); +} diff --git a/packages/runtime/src/local-helpers/tiny-invariant.ts b/packages/runtime/src/local-helpers/tiny-invariant.ts new file mode 100644 index 000000000..5c0683a54 --- /dev/null +++ b/packages/runtime/src/local-helpers/tiny-invariant.ts @@ -0,0 +1,17 @@ +const isProduction = process.env.NODE_ENV === 'production'; +const prefix = 'Invariant failed'; + +export function invariant( + condition: unknown, + message?: string, +): asserts condition { + if (condition) { + return; + } + + if (isProduction) { + throw new Error(prefix); + } + + throw new Error(message ? `${prefix}: ${message}` : prefix); +} diff --git a/packages/runtime/src/local-helpers/upper-case-first.ts b/packages/runtime/src/local-helpers/upper-case-first.ts new file mode 100644 index 000000000..16a6a6e44 --- /dev/null +++ b/packages/runtime/src/local-helpers/upper-case-first.ts @@ -0,0 +1,3 @@ +export function upperCaseFirst(input: string) { + return input.charAt(0).toUpperCase() + input.slice(1); +} diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index 5027fb5c6..fe584bb1b 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -140,6 +140,11 @@ export type EnhancementOptions = { * The encryption options for using the `encrypted` enhancement. */ encryption?: SimpleEncryption | CustomEncryption; + + /** + * Options for data validation. + */ + validation?: ValidationOptions; }; /** @@ -209,3 +214,20 @@ export type CustomEncryption = { */ decrypt: (model: string, field: FieldInfo, cipher: string) => Promise; }; + +/** + * Options for data validation. + */ +export type ValidationOptions = { + /** + * Whether to validate "update" operations based only on the input data. By default, ZenStack + * validates the entity after a update operation completes (inside a transaction), and rejects + * the operation if validation fails. This implies the entire entity needs to satisfy the + * validation rules, even for fields that are not part of the update input data. + * + * You can use this option to toggle the behavior to only validate the input data. + * + * Default is `false`. + */ + inputOnlyValidationForUpdate?: boolean; +}; diff --git a/packages/schema/package.json b/packages/schema/package.json index a2c651f89..cfe1f124b 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "FullStack enhancement for Prisma ORM: seamless integration from database to UI", - "version": "2.15.1", + "version": "2.16.0", "author": { "name": "ZenStack Team" }, @@ -95,24 +95,19 @@ "@zenstackhq/language": "workspace:*", "@zenstackhq/sdk": "workspace:*", "async-exit-hook": "^2.0.1", - "change-case": "^4.1.2", "colors": "1.4.0", "commander": "^8.3.0", "deepmerge": "^4.3.1", "langium": "1.3.1", - "lower-case-first": "^2.0.2", "mixpanel": "^0.17.0", "ora": "^5.4.1", "pluralize": "^8.0.0", "pretty-repl": "^4.0.0", "semver": "^7.5.2", - "sleep-promise": "^9.1.0", "strip-color": "^0.1.0", "terminal-link": "^2.0.0", - "tiny-invariant": "^1.3.1", "ts-morph": "^16.0.0", "ts-pattern": "^4.3.0", - "upper-case-first": "^2.0.2", "uuid": "^9.0.0", "vscode-jsonrpc": "^8.0.2", "vscode-languageclient": "^8.0.2", @@ -123,10 +118,10 @@ "zod-validation-error": "^1.5.0" }, "peerDependencies": { - "prisma": "5.0.0 - 6.8.x" + "prisma": "5.0.0 - 6.10.x" }, "devDependencies": { - "@prisma/client": "6.8.x", + "@prisma/client": "6.10.x", "@types/async-exit-hook": "^2.0.0", "@types/pluralize": "^0.0.29", "@types/semver": "^7.3.13", diff --git a/packages/schema/src/cli/actions/generate.ts b/packages/schema/src/cli/actions/generate.ts index 229a9ddd8..2f5099312 100644 --- a/packages/schema/src/cli/actions/generate.ts +++ b/packages/schema/src/cli/actions/generate.ts @@ -1,4 +1,4 @@ -import { PluginError } from '@zenstackhq/sdk'; +import { getPrismaClientGenerator, PluginError } from '@zenstackhq/sdk'; import { isPlugin } from '@zenstackhq/sdk/ast'; import colors from 'colors'; import path from 'path'; @@ -70,6 +70,18 @@ async function runPlugins(options: Options) { const model = await loadDocument(schema); + const gen = getPrismaClientGenerator(model); + if (gen?.isNewGenerator && !options.output) { + console.error( + colors.red( + 'When using the "prisma-client" generator, you must provide an explicit output path with the "--output" CLI parameter.' + ) + ); + throw new CliError( + 'When using with the "prisma-client" generator, you must provide an explicit output path with the "--output" CLI parameter.' + ); + } + for (const name of [...(options.withPlugins ?? []), ...(options.withoutPlugins ?? [])]) { const pluginDecl = model.declarations.find((d) => isPlugin(d) && d.name === name); if (!pluginDecl) { diff --git a/packages/schema/src/cli/actions/init.ts b/packages/schema/src/cli/actions/init.ts index 1016d61a9..3345c745d 100644 --- a/packages/schema/src/cli/actions/init.ts +++ b/packages/schema/src/cli/actions/init.ts @@ -45,7 +45,7 @@ export async function init(projectPath: string, options: Options) { fs.copyFileSync(prismaSchema, zmodelFile); } else { // create a new model - const starterContent = fs.readFileSync(path.join(__dirname, '../../res/starter.zmodel'), 'utf-8'); + const starterContent = fs.readFileSync(path.join(__dirname, '../../res/starter.txt'), 'utf-8'); fs.writeFileSync(zmodelFile, starterContent); sampleModelGenerated = true; } diff --git a/packages/schema/src/cli/plugin-runner.ts b/packages/schema/src/cli/plugin-runner.ts index 54e13d41e..7c9ffdd66 100644 --- a/packages/schema/src/cli/plugin-runner.ts +++ b/packages/schema/src/cli/plugin-runner.ts @@ -112,10 +112,7 @@ export class PluginRunner { const otherPlugins = plugins.filter((p) => !p.options.preprocessor); // calculate all plugins (including core plugins implicitly enabled) - const { corePlugins, userPlugins } = this.calculateAllPlugins( - runnerOptions, - otherPlugins, - ); + const { corePlugins, userPlugins } = this.calculateAllPlugins(runnerOptions, otherPlugins); const allPlugins = [...corePlugins, ...userPlugins]; // check dependencies @@ -448,7 +445,7 @@ export class PluginRunner { } async function compileProject(project: Project, runnerOptions: PluginRunnerOptions) { - if (runnerOptions.compile !== false) { + if (!runnerOptions.output && runnerOptions.compile !== false) { // emit await emitProject(project); } else { diff --git a/packages/schema/src/language-server/zmodel-workspace-manager.ts b/packages/schema/src/language-server/zmodel-workspace-manager.ts index 734a785cd..d8ba7bd8a 100644 --- a/packages/schema/src/language-server/zmodel-workspace-manager.ts +++ b/packages/schema/src/language-server/zmodel-workspace-manager.ts @@ -1,6 +1,7 @@ import { isPlugin, Model } from '@zenstackhq/language/ast'; import { getLiteral } from '@zenstackhq/sdk'; import { DefaultWorkspaceManager, interruptAndCheck, LangiumDocument } from 'langium'; +import fs from 'fs'; import path from 'path'; import { CancellationToken, WorkspaceFolder } from 'vscode-languageserver'; import { URI, Utils } from 'vscode-uri'; @@ -17,7 +18,42 @@ export class ZModelWorkspaceManager extends DefaultWorkspaceManager { _collector: (document: LangiumDocument) => void ): Promise { await super.loadAdditionalDocuments(_folders, _collector); - const stdLibUri = URI.file(path.join(__dirname, '../res', STD_LIB_MODULE_NAME)); + + let stdLibPath: string; + // First, try to find the stdlib from an installed zenstack package + // in the project's node_modules + let installedStdlibPath: string | undefined; + for (const folder of _folders) { + const folderPath = this.getRootFolder(folder).fsPath; + try { + // Try to resolve zenstack from the workspace folder + const languagePackagePath = require.resolve('zenstack/package.json', { + paths: [folderPath] + }); + const languagePackageDir = path.dirname(languagePackagePath); + const candidateStdlibPath = path.join(languagePackageDir, 'res', STD_LIB_MODULE_NAME); + + // Check if the stdlib file exists in the installed package + if (fs.existsSync(candidateStdlibPath)) { + installedStdlibPath = candidateStdlibPath; + console.log(`Found installed zenstack package stdlib at ${installedStdlibPath}`); + break; + } + } catch (error) { + // Package not found or other error, continue to next folder + continue; + } + } + + if (installedStdlibPath) { + stdLibPath = installedStdlibPath; + } else { + // Fallback to bundled stdlib + stdLibPath = path.join(__dirname, '../res', STD_LIB_MODULE_NAME); + console.log(`Using bundled stdlib in extension`); + } + + const stdLibUri = URI.file(stdLibPath); console.log(`Adding stdlib document from ${stdLibUri}`); const stdlib = this.langiumDocuments.getOrCreateDocument(stdLibUri); _collector(stdlib); diff --git a/packages/schema/src/plugins/enhancer/enhance/checker-type-generator.ts b/packages/schema/src/plugins/enhancer/enhance/checker-type-generator.ts index 7202f2cdf..d65b84cf4 100644 --- a/packages/schema/src/plugins/enhancer/enhance/checker-type-generator.ts +++ b/packages/schema/src/plugins/enhancer/enhance/checker-type-generator.ts @@ -1,6 +1,6 @@ import { getDataModels } from '@zenstackhq/sdk'; import type { DataModel, DataModelField, Model } from '@zenstackhq/sdk/ast'; -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst } from '@zenstackhq/runtime/local-helpers'; import { P, match } from 'ts-pattern'; /** diff --git a/packages/schema/src/plugins/enhancer/enhance/index.ts b/packages/schema/src/plugins/enhancer/enhance/index.ts index f8db9c063..f30d756cc 100644 --- a/packages/schema/src/plugins/enhancer/enhance/index.ts +++ b/packages/schema/src/plugins/enhancer/enhance/index.ts @@ -7,7 +7,7 @@ import { getDataModelAndTypeDefs, getDataModels, getForeignKeyFields, - getLiteral, + getPrismaClientGenerator, getRelationField, hasAttribute, isDelegateModel, @@ -22,11 +22,11 @@ import { ReferenceExpr, isArrayExpr, isDataModel, - isGeneratorDecl, isTypeDef, type Model, } from '@zenstackhq/sdk/ast'; import { getDMMF, getPrismaClientImportSpec, getPrismaVersion, type DMMF } from '@zenstackhq/sdk/prisma'; +import { upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import fs from 'fs'; import path from 'path'; import semver from 'semver'; @@ -41,7 +41,6 @@ import { TypeAliasDeclaration, VariableStatement, } from 'ts-morph'; -import { upperCaseFirst } from 'upper-case-first'; import { name } from '..'; import { getConcreteModels, getDiscriminatorField } from '../../../utils/ast-utils'; import { execPackage } from '../../../utils/exec-utils'; @@ -56,7 +55,7 @@ import { generateTypeDefType } from './model-typedef-generator'; // information of delegate models and their sub models type DelegateInfo = [DataModel, DataModel[]][]; -const LOGICAL_CLIENT_GENERATION_PATH = './.logical-prisma-client'; +const LOGICAL_CLIENT_GENERATION_PATH = './logical-prisma-client'; export class EnhancerGenerator { // regex for matching "ModelCreateXXXInput" and "ModelUncheckedCreateXXXInput" type @@ -114,6 +113,9 @@ export class EnhancerGenerator { if (this.needsLogicalClient) { prismaTypesFixed = true; resultPrismaTypeImport = LOGICAL_CLIENT_GENERATION_PATH; + if (this.isNewPrismaClientGenerator) { + resultPrismaTypeImport += '/client'; + } const result = await this.generateLogicalPrisma(); dmmf = result.dmmf; } @@ -440,23 +442,14 @@ export type Enhanced = } private getPrismaClientGeneratorName(model: Model) { - for (const generator of model.declarations.filter(isGeneratorDecl)) { - if ( - generator.fields.some( - (f) => f.name === 'provider' && getLiteral(f.value) === 'prisma-client-js' - ) - ) { - return generator.name; - } + const gen = getPrismaClientGenerator(model); + if (!gen) { + throw new PluginError(name, `Cannot find "prisma-client-js" or "prisma-client" generator in the schema`); } - throw new PluginError(name, `Cannot find prisma-client-js generator in the schema`); + return gen.name; } private async processClientTypes(prismaClientDir: string) { - // make necessary updates to the generated `index.d.ts` file and overwrite it - const project = new Project(); - const sf = project.addSourceFileAtPath(path.join(prismaClientDir, 'index.d.ts')); - // build a map of delegate models and their sub models const delegateInfo: DelegateInfo = []; this.model.declarations @@ -468,6 +461,16 @@ export type Enhanced = } }); + if (this.isNewPrismaClientGenerator) { + await this.processClientTypesNewPrismaGenerator(prismaClientDir, delegateInfo); + } else { + await this.processClientTypesLegacyPrismaGenerator(prismaClientDir, delegateInfo); + } + } + private async processClientTypesLegacyPrismaGenerator(prismaClientDir: string, delegateInfo: DelegateInfo) { + const project = new Project(); + const sf = project.addSourceFileAtPath(path.join(prismaClientDir, 'index.d.ts')); + // transform index.d.ts and write it into a new file (better perf than in-line editing) const sfNew = project.createSourceFile(path.join(prismaClientDir, 'index-fixed.d.ts'), undefined, { overwrite: true, @@ -484,6 +487,36 @@ export type Enhanced = await sfNew.save(); } + private async processClientTypesNewPrismaGenerator(prismaClientDir: string, delegateInfo: DelegateInfo) { + const project = new Project(); + + for (const d of this.model.declarations.filter(isDataModel)) { + const fileName = `${prismaClientDir}/models/${d.name}.ts`; + const sf = project.addSourceFileAtPath(fileName); + const sfNew = project.createSourceFile(`${prismaClientDir}/models/${d.name}-fixed.ts`, undefined, { + overwrite: true, + }); + + const syntaxList = sf.getChildren()[0]; + if (!Node.isSyntaxList(syntaxList)) { + throw new PluginError(name, `Unexpected syntax list structure in ${fileName}`); + } + + syntaxList.getChildren().forEach((node) => { + if (Node.isInterfaceDeclaration(node)) { + sfNew.addInterface(this.transformInterface(node, delegateInfo)); + } else if (Node.isTypeAliasDeclaration(node)) { + sfNew.addTypeAlias(this.transformTypeAlias(node, delegateInfo)); + } else { + sfNew.addStatements(node.getText()); + } + }); + + await sfNew.move(sf.getFilePath(), { overwrite: true }); + await sfNew.save(); + } + } + private transformPrismaTypes(sf: SourceFile, sfNew: SourceFile, delegateInfo: DelegateInfo) { // copy toplevel imports sfNew.addImportDeclarations(sf.getImportDeclarations().map((n) => n.getStructure())); @@ -639,7 +672,7 @@ export type Enhanced = source = `${payloadRecord[1] .map( (concrete) => - `($${concrete.name}Payload & { scalars: { ${discriminatorDecl.name}: '${concrete.name}' } })` + `(Prisma.$${concrete.name}Payload & { scalars: { ${discriminatorDecl.name}: '${concrete.name}' } })` ) .join(' | ')}`; } @@ -916,4 +949,9 @@ export type Enhanced = private trimEmptyLines(source: string): string { return source.replace(/^\s*[\r\n]/gm, ''); } + + private get isNewPrismaClientGenerator() { + const gen = getPrismaClientGenerator(this.model); + return !!gen?.isNewGenerator; + } } diff --git a/packages/schema/src/plugins/enhancer/policy/expression-writer.ts b/packages/schema/src/plugins/enhancer/policy/expression-writer.ts index 2c3334fb3..d3dccfaa6 100644 --- a/packages/schema/src/plugins/enhancer/policy/expression-writer.ts +++ b/packages/schema/src/plugins/enhancer/policy/expression-writer.ts @@ -36,8 +36,7 @@ import { TypeScriptExpressionTransformer, TypeScriptExpressionTransformerError, } from '@zenstackhq/sdk'; -import { lowerCaseFirst } from 'lower-case-first'; -import invariant from 'tiny-invariant'; +import { lowerCaseFirst, invariant } from '@zenstackhq/runtime/local-helpers'; import { name } from '..'; import { isCheckInvocation } from '../../../utils/ast-utils'; diff --git a/packages/schema/src/plugins/enhancer/policy/policy-guard-generator.ts b/packages/schema/src/plugins/enhancer/policy/policy-guard-generator.ts index e7651754d..f257f0830 100644 --- a/packages/schema/src/plugins/enhancer/policy/policy-guard-generator.ts +++ b/packages/schema/src/plugins/enhancer/policy/policy-guard-generator.ts @@ -31,8 +31,8 @@ import { saveSourceFile, } from '@zenstackhq/sdk'; import { getPrismaClientImportSpec } from '@zenstackhq/sdk/prisma'; +import { lowerCaseFirst } from '@zenstackhq/runtime/local-helpers'; import { streamAst } from 'langium'; -import { lowerCaseFirst } from 'lower-case-first'; import path from 'path'; import { FunctionDeclarationStructure, OptionalKind, Project, SourceFile, VariableDeclarationKind } from 'ts-morph'; import { isCheckInvocation } from '../../../utils/ast-utils'; diff --git a/packages/schema/src/plugins/prisma/index.ts b/packages/schema/src/plugins/prisma/index.ts index aba67c90a..85832b266 100644 --- a/packages/schema/src/plugins/prisma/index.ts +++ b/packages/schema/src/plugins/prisma/index.ts @@ -2,11 +2,10 @@ import { PluginError, type PluginFunction, type PluginOptions, - getLiteral, + getPrismaClientGenerator, normalizedRelative, resolvePath, } from '@zenstackhq/sdk'; -import { GeneratorDecl, isGeneratorDecl } from '@zenstackhq/sdk/ast'; import { getDMMF } from '@zenstackhq/sdk/prisma'; import colors from 'colors'; import fs from 'fs'; @@ -58,13 +57,9 @@ const run: PluginFunction = async (model, options, _dmmf, _globalOptions) => { } // extract user-provided prisma client output path - const generator = model.declarations.find( - (d): d is GeneratorDecl => - isGeneratorDecl(d) && - d.fields.some((f) => f.name === 'provider' && getLiteral(f.value) === 'prisma-client-js') - ); - const clientOutputField = generator?.fields.find((f) => f.name === 'output'); - const clientOutput = getLiteral(clientOutputField?.value); + const gen = getPrismaClientGenerator(model); + const clientOutput = gen?.output; + const newGenerator = !!gen?.isNewGenerator; if (clientOutput) { if (path.isAbsolute(clientOutput)) { @@ -81,6 +76,11 @@ const run: PluginFunction = async (model, options, _dmmf, _globalOptions) => { clientOutputDir = prismaClientPath; } + if (newGenerator) { + // "prisma-client" generator requires an extra "/client" import suffix + prismaClientPath = `${prismaClientPath}/client`; + } + // get PrismaClient dts path if (clientOutput) { @@ -89,7 +89,7 @@ const run: PluginFunction = async (model, options, _dmmf, _globalOptions) => { prismaClientDtsPath = path.resolve(path.dirname(options.schemaPath), clientOutputDir, 'index.d.ts'); } - if (!prismaClientDtsPath || !fs.existsSync(prismaClientDtsPath)) { + if (!newGenerator && (!prismaClientDtsPath || !fs.existsSync(prismaClientDtsPath))) { // if the file does not exist, try node module resolution try { // the resolution is relative to the schema path by default diff --git a/packages/schema/src/plugins/prisma/schema-generator.ts b/packages/schema/src/plugins/prisma/schema-generator.ts index 177edbd0e..4e29bb91d 100644 --- a/packages/schema/src/plugins/prisma/schema-generator.ts +++ b/packages/schema/src/plugins/prisma/schema-generator.ts @@ -29,16 +29,12 @@ import { NumberLiteral, StringLiteral, } from '@zenstackhq/language/ast'; -import { getIdFields } from '@zenstackhq/sdk'; -import { getPrismaVersion } from '@zenstackhq/sdk/prisma'; -import { match, P } from 'ts-pattern'; - -import { DELEGATE_AUX_RELATION_PREFIX, PRISMA_MINIMUM_VERSION } from '@zenstackhq/runtime'; import { getAttribute, getAttributeArg, getAttributeArgLiteral, getDataSourceProvider, + getIdFields, getInheritedFromDelegate, getLiteral, getRelationKeyPairs, @@ -49,11 +45,14 @@ import { resolved, ZModelCodeGenerator, } from '@zenstackhq/sdk'; +import { getPrismaVersion } from '@zenstackhq/sdk/prisma'; +import { DELEGATE_AUX_RELATION_PREFIX, PRISMA_MINIMUM_VERSION } from '@zenstackhq/runtime'; +import { lowerCaseFirst } from '@zenstackhq/runtime/local-helpers'; import fs from 'fs'; import { writeFile } from 'fs/promises'; -import { lowerCaseFirst } from 'lower-case-first'; import path from 'path'; import semver from 'semver'; +import { match, P } from 'ts-pattern'; import { name } from '.'; import { getStringLiteral } from '../../language-server/validator/utils'; import { getConcreteModels } from '../../utils/ast-utils'; @@ -234,7 +233,10 @@ export class PrismaSchemaGenerator { // deal with configuring PrismaClient preview features const provider = generator.fields.find((f) => f.name === 'provider'); - if (provider?.text === JSON.stringify('prisma-client-js')) { + if ( + provider?.text === JSON.stringify('prisma-client-js') || + provider?.text === JSON.stringify('prisma-client') + ) { const prismaVersion = getPrismaVersion(); if (prismaVersion) { const previewFeatures = JSON.parse( diff --git a/packages/schema/src/plugins/zod/generator.ts b/packages/schema/src/plugins/zod/generator.ts index 9a5cd53b4..7a7a94b39 100644 --- a/packages/schema/src/plugins/zod/generator.ts +++ b/packages/schema/src/plugins/zod/generator.ts @@ -26,10 +26,10 @@ import { import { DataModel, EnumField, Model, TypeDef, isArrayExpr, isDataModel, isEnum, isTypeDef } from '@zenstackhq/sdk/ast'; import { addMissingInputObjectTypes, resolveAggregateOperationSupport } from '@zenstackhq/sdk/dmmf-helpers'; import { getPrismaClientImportSpec, supportCreateMany, type DMMF } from '@zenstackhq/sdk/prisma'; +import { upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import { streamAllContents } from 'langium'; import path from 'path'; import type { CodeBlockWriter, SourceFile } from 'ts-morph'; -import { upperCaseFirst } from 'upper-case-first'; import { name } from '.'; import { getDefaultOutputFolder } from '../plugin-utils'; import Transformer from './transformer'; diff --git a/packages/schema/src/plugins/zod/index.ts b/packages/schema/src/plugins/zod/index.ts index ffe198378..074002ee0 100644 --- a/packages/schema/src/plugins/zod/index.ts +++ b/packages/schema/src/plugins/zod/index.ts @@ -1,5 +1,5 @@ import { PluginFunction } from '@zenstackhq/sdk'; -import invariant from 'tiny-invariant'; +import { invariant } from '@zenstackhq/runtime/local-helpers'; import { ZodSchemaGenerator } from './generator'; export const name = 'Zod'; diff --git a/packages/schema/src/plugins/zod/transformer.ts b/packages/schema/src/plugins/zod/transformer.ts index b8669e8e2..0dc0414be 100644 --- a/packages/schema/src/plugins/zod/transformer.ts +++ b/packages/schema/src/plugins/zod/transformer.ts @@ -12,9 +12,9 @@ import { import { DataModel, DataModelField, Enum, isDataModel, isEnum, isTypeDef, type Model } from '@zenstackhq/sdk/ast'; import { checkModelHasModelRelation, findModelByName, isAggregateInputType } from '@zenstackhq/sdk/dmmf-helpers'; import { supportCreateMany, type DMMF as PrismaDMMF } from '@zenstackhq/sdk/prisma'; +import { upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import path from 'path'; import type { Project, SourceFile } from 'ts-morph'; -import { upperCaseFirst } from 'upper-case-first'; import { computePrismaClientImport } from './generator'; import { AggregateOperationSupport, ObjectMode, TransformerParams } from './types'; diff --git a/packages/schema/src/plugins/zod/utils/schema-gen.ts b/packages/schema/src/plugins/zod/utils/schema-gen.ts index 37466adbb..47f95e3c4 100644 --- a/packages/schema/src/plugins/zod/utils/schema-gen.ts +++ b/packages/schema/src/plugins/zod/utils/schema-gen.ts @@ -11,7 +11,7 @@ import { isTypeDef, TypeDefField, } from '@zenstackhq/sdk/ast'; -import { upperCaseFirst } from 'upper-case-first'; +import { upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import { isDefaultWithAuth } from '../../enhancer/enhancer-utils'; export function makeFieldSchema(field: DataModelField | TypeDefField) { diff --git a/packages/schema/src/res/starter.zmodel b/packages/schema/src/res/starter.txt similarity index 100% rename from packages/schema/src/res/starter.zmodel rename to packages/schema/src/res/starter.txt diff --git a/packages/schema/src/res/stdlib.zmodel b/packages/schema/src/res/stdlib.zmodel index dd92ff0ae..222765a29 100644 --- a/packages/schema/src/res/stdlib.zmodel +++ b/packages/schema/src/res/stdlib.zmodel @@ -25,7 +25,7 @@ enum ReferentialAction { * Used with "onUpdate": when updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL. */ SetNull - + /** * Used with "onDelete": the scalar field of the referencing object will be set to the fields default value. * Used with "onUpdate": the scalar field of the referencing object will be set to the fields default value. @@ -110,7 +110,7 @@ function ulid(): String { } @@@expressionContext([DefaultValue]) /** - * Creates a sequence of integers in the underlying database and assign the incremented + * Creates a sequence of integers in the underlying database and assign the incremented * values to the ID values of the created records based on the sequence. */ function autoincrement(): Int { @@ -180,9 +180,9 @@ function isEmpty(field: Any[]): Boolean { /** * The name of the model for which the policy rule is defined. If the rule is * inherited to a sub model, this function returns the name of the sub model. - * + * * @param optional parameter to control the casing of the returned value. Valid - * values are "original", "upper", "lower", "capitalize", "uncapitalize". Defaults + * values are "original", "upper", "lower", "capitalize", "uncapitalize". Defaults * to "original". */ function currentModel(casing: String?): String { @@ -537,7 +537,7 @@ attribute @@allow(_ operation: String @@@completionHint(["'create'", "'read'", " /** * Defines an access policy that allows the annotated field to be read or updated. - * You can pass a thrid argument as `true` to make it override the model-level policies. + * You can pass a third argument as `true` to make it override the model-level policies. * * @param operation: comma-separated list of "create", "read", "update", "delete". Use "all" to denote all operations. * @param condition: a boolean expression that controls if the operation should be allowed. @@ -585,7 +585,7 @@ attribute @password(saltLength: Int?, salt: String?) @@@targetField([StringField /** * Indicates that the field is encrypted when storing in the DB and should be decrypted when read * - * ZenStack uses the Web Crypto API to encrypt and decrypt the field. + * ZenStack uses the Web Crypto API to encrypt and decrypt the field. */ attribute @encrypted() @@@targetField([StringField]) @@ -713,7 +713,7 @@ function url(field: String): Boolean { * Checks if the current user can perform the given operation on the given field. * * @param field: The field to check access for - * @param operation: The operation to check access for. Can be "read", "create", "update", or "delete". If the operation is not provided, + * @param operation: The operation to check access for. Can be "read", "create", "update", or "delete". If the operation is not provided, * it defaults the operation of the containing policy rule. */ function check(field: Any, operation: String?): Boolean { diff --git a/packages/schema/src/telemetry.ts b/packages/schema/src/telemetry.ts index 9ecbb4672..f0a0afe5f 100644 --- a/packages/schema/src/telemetry.ts +++ b/packages/schema/src/telemetry.ts @@ -1,10 +1,10 @@ import { createId } from '@paralleldrive/cuid2'; import { getPrismaVersion } from '@zenstackhq/sdk/prisma'; +import { sleep } from '@zenstackhq/runtime/local-helpers'; import exitHook from 'async-exit-hook'; import { CommanderError } from 'commander'; import { init, Mixpanel } from 'mixpanel'; import * as os from 'os'; -import sleep from 'sleep-promise'; import { CliError } from './cli/cli-error'; import { TELEMETRY_TRACKING_TOKEN } from './constants'; import isDocker from './utils/is-docker'; diff --git a/packages/schema/tests/schema/all-features.zmodel b/packages/schema/tests/schema/all-features.zmodel index 8fbe6031d..6acd2a6ca 100644 --- a/packages/schema/tests/schema/all-features.zmodel +++ b/packages/schema/tests/schema/all-features.zmodel @@ -133,7 +133,7 @@ model List { // require login @@deny('all', auth() == null) - // can be read by owner or space members (only if not private) + // can be read by owner or space members (only if not private) @@allow('read', owner == auth() || (space.members?[user == auth()] && !private)) // when create, owner must be set to current user, and user must be in the space @@ -187,4 +187,4 @@ type Metadata { width Int height Int format String -} \ No newline at end of file +} diff --git a/packages/schema/tests/schema/todo.zmodel b/packages/schema/tests/schema/todo.zmodel index 2894c486c..61e449fd7 100644 --- a/packages/schema/tests/schema/todo.zmodel +++ b/packages/schema/tests/schema/todo.zmodel @@ -123,7 +123,7 @@ model List { // require login @@deny('all', auth() == null) - // can be read by owner or space members (only if not private) + // can be read by owner or space members (only if not private) @@allow('read', owner == auth() || (space.members?[user == auth()] && !private)) // when create, owner must be set to current user, and user must be in the space @@ -179,4 +179,4 @@ model Account { session_state String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([provider, providerAccountId]) -} \ No newline at end of file +} diff --git a/packages/sdk/package.json b/packages/sdk/package.json index defb02ef8..357ca3c92 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "2.15.1", + "version": "2.16.0", "description": "ZenStack plugin development SDK", "main": "index.js", "scripts": { @@ -18,16 +18,14 @@ "author": "", "license": "MIT", "dependencies": { - "@prisma/generator-helper": "6.8.x", - "@prisma/internals": "6.8.x", + "@prisma/generator-helper": "6.10.x", + "@prisma/internals": "6.10.x", "@zenstackhq/language": "workspace:*", "@zenstackhq/runtime": "workspace:*", "langium": "1.3.1", - "lower-case-first": "^2.0.2", "semver": "^7.5.2", "ts-morph": "^16.0.0", - "ts-pattern": "^4.3.0", - "upper-case-first": "^2.0.2" + "ts-pattern": "^4.3.0" }, "devDependencies": { "@types/semver": "^7.3.13" diff --git a/packages/sdk/src/dmmf-helpers/aggregate-helpers.ts b/packages/sdk/src/dmmf-helpers/aggregate-helpers.ts index bec9632a1..8ec07fe87 100644 --- a/packages/sdk/src/dmmf-helpers/aggregate-helpers.ts +++ b/packages/sdk/src/dmmf-helpers/aggregate-helpers.ts @@ -1,4 +1,4 @@ -import { upperCaseFirst } from 'upper-case-first'; +import { upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import type { DMMF } from '../prisma'; import { AggregateOperationSupport } from './types'; diff --git a/packages/sdk/src/model-meta-generator.ts b/packages/sdk/src/model-meta-generator.ts index 716e6ad7d..ad34fcffa 100644 --- a/packages/sdk/src/model-meta-generator.ts +++ b/packages/sdk/src/model-meta-generator.ts @@ -17,8 +17,8 @@ import { TypeDefField, } from '@zenstackhq/language/ast'; import type { RuntimeAttribute } from '@zenstackhq/runtime'; +import { lowerCaseFirst } from '@zenstackhq/runtime/local-helpers'; import { streamAst } from 'langium'; -import { lowerCaseFirst } from 'lower-case-first'; import { FunctionDeclarationStructure, OptionalKind, Project, VariableDeclarationKind } from 'ts-morph'; import { CodeWriter, diff --git a/packages/sdk/src/utils.ts b/packages/sdk/src/utils.ts index 93118b5f5..09a538f77 100644 --- a/packages/sdk/src/utils.ts +++ b/packages/sdk/src/utils.ts @@ -466,7 +466,12 @@ export function getPreviewFeatures(model: Model) { const jsGenerator = model.declarations.find( (d) => isGeneratorDecl(d) && - d.fields.some((f) => f.name === 'provider' && getLiteral(f.value) === 'prisma-client-js') + d.fields.some( + (f) => + f.name === 'provider' && + (getLiteral(f.value) === 'prisma-client-js' || + getLiteral(f.value) === 'prisma-client') + ) ) as GeneratorDecl | undefined; if (jsGenerator) { @@ -683,3 +688,28 @@ export function getRelationName(field: DataModelField) { } return getAttributeArgLiteral(relAttr, 'name'); } + +export function getPrismaClientGenerator(model: Model) { + const decl = model.declarations.find( + (d): d is GeneratorDecl => + isGeneratorDecl(d) && + d.fields.some( + (f) => + f.name === 'provider' && + (getLiteral(f.value) === 'prisma-client-js' || + getLiteral(f.value) === 'prisma-client') + ) + ); + if (!decl) { + return undefined; + } + + const provider = getLiteral(decl.fields.find((f) => f.name === 'provider')?.value); + return { + name: decl.name, + output: getLiteral(decl.fields.find((f) => f.name === 'output')?.value), + previewFeatures: getLiteralArray(decl.fields.find((f) => f.name === 'previewFeatures')?.value), + provider, + isNewGenerator: provider === 'prisma-client', + }; +} diff --git a/packages/server/package.json b/packages/server/package.json index 76bba5fb5..e0fd06baa 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "2.15.1", + "version": "2.16.0", "displayName": "ZenStack Server-side Adapters", "description": "ZenStack server-side adapters", "homepage": "https://zenstack.dev", @@ -28,12 +28,8 @@ "license": "MIT", "dependencies": { "@zenstackhq/runtime": "workspace:*", - "change-case": "^4.1.2", - "lower-case-first": "^2.0.2", "superjson": "^1.13.0", - "tiny-invariant": "^1.3.1", "ts-japi": "^1.10.1", - "upper-case-first": "^2.0.2", "url-pattern": "^1.0.3", "zod": "^3.22.4", "zod-validation-error": "^1.5.0", diff --git a/packages/server/src/api/rest/index.ts b/packages/server/src/api/rest/index.ts index 4146e63df..59558be98 100644 --- a/packages/server/src/api/rest/index.ts +++ b/packages/server/src/api/rest/index.ts @@ -10,11 +10,9 @@ import { getIdFields, isPrismaClientKnownRequestError, } from '@zenstackhq/runtime'; -import { paramCase } from 'change-case'; -import { lowerCaseFirst } from 'lower-case-first'; +import { lowerCaseFirst, upperCaseFirst, paramCase } from '@zenstackhq/runtime/local-helpers'; import SuperJSON from 'superjson'; import { Linker, Paginator, Relator, Serializer, SerializerOptions } from 'ts-japi'; -import { upperCaseFirst } from 'upper-case-first'; import UrlPattern from 'url-pattern'; import z, { ZodError } from 'zod'; import { fromZodError } from 'zod-validation-error'; diff --git a/packages/server/src/api/rpc/index.ts b/packages/server/src/api/rpc/index.ts index a1a71c1c6..ef237b779 100644 --- a/packages/server/src/api/rpc/index.ts +++ b/packages/server/src/api/rpc/index.ts @@ -7,8 +7,8 @@ import { isPrismaClientUnknownRequestError, isPrismaClientValidationError, } from '@zenstackhq/runtime'; +import { upperCaseFirst } from '@zenstackhq/runtime/local-helpers'; import SuperJSON from 'superjson'; -import { upperCaseFirst } from 'upper-case-first'; import { ZodError } from 'zod'; import { fromZodError } from 'zod-validation-error'; import { Response } from '../../types'; diff --git a/packages/server/src/nestjs/interfaces/api-handler-options.interface.ts b/packages/server/src/nestjs/interfaces/api-handler-options.interface.ts index c9731d24d..fe497afe9 100644 --- a/packages/server/src/nestjs/interfaces/api-handler-options.interface.ts +++ b/packages/server/src/nestjs/interfaces/api-handler-options.interface.ts @@ -5,7 +5,7 @@ export interface ApiHandlerOptions extends AdapterBaseOptions { * The base URL for the API handler. This is used to determine the base path for the API requests. * If you are using the ApiHandlerService in a route with a prefix, you should set this to the prefix. * - * e.g. + * e.g. * without baseUrl(API handler default route): * - RPC API handler: [model]/findMany * - RESTful API handler: /:type diff --git a/packages/testtools/package.json b/packages/testtools/package.json index 6d186f751..871487ef4 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "2.15.1", + "version": "2.16.0", "description": "ZenStack Test Tools", "main": "index.js", "private": true, @@ -25,7 +25,6 @@ "json5": "^2.2.3", "langium": "1.3.1", "pg": "^8.11.1", - "tiny-invariant": "^1.3.1", "tmp": "^0.2.1", "vscode-uri": "^3.0.6", "zenstack": "workspace:*" diff --git a/packages/testtools/src/db.ts b/packages/testtools/src/db.ts index 16142d527..774400a95 100644 --- a/packages/testtools/src/db.ts +++ b/packages/testtools/src/db.ts @@ -7,9 +7,9 @@ const HOST = process.env.ZENSTACK_TEST_DB_HOST || 'localhost'; const PORT = (process.env.ZENSTACK_TEST_DB_PORT ? parseInt(process.env.ZENSTACK_TEST_DB_PORT) : null) || 5432; function connect() { - return new Pool({ - user: USERNAME, - password: PASSWORD, + return new Pool({ + user: USERNAME, + password: PASSWORD, database: CONNECTION_DB, host: HOST, port: PORT diff --git a/packages/testtools/src/schema.ts b/packages/testtools/src/schema.ts index fabd180e2..c1b8c6aeb 100644 --- a/packages/testtools/src/schema.ts +++ b/packages/testtools/src/schema.ts @@ -18,7 +18,7 @@ import tmp from 'tmp'; import { loadDocument } from 'zenstack/cli/cli-util'; import prismaPlugin from 'zenstack/plugins/prisma'; -/** +/** * Use it to represent multiple files in a single string like this `schema.zmodel import "user" @@ -278,27 +278,6 @@ export async function loadSchema(schema: string, options?: SchemaLoadOptions) { fs.cpSync(dep, path.join(projectDir, 'node_modules', pkgJson.name), { recursive: true, force: true }); }); - const prismaLoadPath = options?.prismaLoadPath - ? path.isAbsolute(options.prismaLoadPath) - ? options.prismaLoadPath - : path.join(projectDir, options.prismaLoadPath) - : path.join(projectDir, 'node_modules/.prisma/client'); - const prismaModule = require(prismaLoadPath); - const PrismaClient = prismaModule.PrismaClient; - - let clientOptions: object = { log: ['info', 'warn', 'error'] }; - if (options?.prismaClientOptions) { - clientOptions = { ...clientOptions, ...options.prismaClientOptions }; - } - let prisma = new PrismaClient(clientOptions); - // https://github.com/prisma/prisma/issues/18292 - prisma[Symbol.for('nodejs.util.inspect.custom')] = 'PrismaClient'; - - if (opt.pulseApiKey) { - const withPulse = loadModule('@prisma/extension-pulse/node', projectDir).withPulse; - prisma = prisma.$extends(withPulse({ apiKey: opt.pulseApiKey })); - } - opt.extraSourceFiles?.forEach(({ name, content }) => { fs.writeFileSync(path.join(projectDir, name), content); }); @@ -325,6 +304,27 @@ export async function loadSchema(schema: string, options?: SchemaLoadOptions) { run('npx tsc --project tsconfig.json'); } + const prismaLoadPath = options?.prismaLoadPath + ? path.isAbsolute(options.prismaLoadPath) + ? options.prismaLoadPath + : path.join(projectDir, options.prismaLoadPath) + : path.join(projectDir, 'node_modules/.prisma/client'); + const prismaModule = require(prismaLoadPath); + const PrismaClient = prismaModule.PrismaClient; + + let clientOptions: object = { log: ['info', 'warn', 'error'] }; + if (options?.prismaClientOptions) { + clientOptions = { ...clientOptions, ...options.prismaClientOptions }; + } + let prisma = new PrismaClient(clientOptions); + // https://github.com/prisma/prisma/issues/18292 + prisma[Symbol.for('nodejs.util.inspect.custom')] = 'PrismaClient'; + + if (opt.pulseApiKey) { + const withPulse = loadModule('@prisma/extension-pulse/node', projectDir).withPulse; + prisma = prisma.$extends(withPulse({ apiKey: opt.pulseApiKey })); + } + if (options?.getPrismaOnly) { return { prisma, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index acd0182f3..061615d6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,18 +38,12 @@ importers: jest: specifier: ^29.7.0 version: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)) - replace-in-file: - specifier: ^7.0.1 - version: 7.2.0 rimraf: specifier: ^3.0.2 version: 3.0.2 ts-jest: specifier: ^29.1.1 version: 29.1.5(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(esbuild@0.21.5)(jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)))(typescript@5.5.2) - ts-node: - specifier: ^10.9.1 - version: 10.9.2(@types/node@20.14.9)(typescript@5.5.2) tsup: specifier: ^8.0.1 version: 8.1.0(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))(typescript@5.5.2) @@ -134,27 +128,15 @@ importers: '@zenstackhq/sdk': specifier: workspace:* version: link:../../sdk/dist - change-case: - specifier: ^4.1.2 - version: 4.1.2 - lower-case-first: - specifier: ^2.0.2 - version: 2.0.2 openapi-types: specifier: ^12.1.0 version: 12.1.3 semver: specifier: ^7.5.2 version: 7.6.2 - tiny-invariant: - specifier: ^1.3.1 - version: 1.3.3 ts-pattern: specifier: ^4.3.0 version: 4.3.0 - upper-case-first: - specifier: ^2.0.2 - version: 2.0.2 yaml: specifier: ^2.2.2 version: 2.4.5 @@ -199,15 +181,9 @@ importers: '@zenstackhq/sdk': specifier: workspace:* version: link:../../sdk/dist - change-case: - specifier: ^4.1.2 - version: 4.1.2 cross-fetch: specifier: ^4.0.0 version: 4.0.0(encoding@0.1.13) - lower-case-first: - specifier: ^2.0.2 - version: 2.0.2 semver: specifier: ^7.5.2 version: 7.6.2 @@ -220,9 +196,6 @@ importers: ts-pattern: specifier: ^4.3.0 version: 4.3.0 - upper-case-first: - specifier: ^2.0.2 - version: 2.0.2 devDependencies: '@tanstack/react-query': specifier: ^4.28.0 @@ -258,15 +231,9 @@ importers: '@zenstackhq/sdk': specifier: workspace:* version: link:../../sdk/dist - change-case: - specifier: ^4.1.2 - version: 4.1.2 cross-fetch: specifier: ^4.0.0 version: 4.0.0(encoding@0.1.13) - lower-case-first: - specifier: ^2.0.2 - version: 2.0.2 semver: specifier: ^7.5.2 version: 7.6.2 @@ -276,9 +243,6 @@ importers: ts-pattern: specifier: ^4.3.0 version: 4.3.0 - upper-case-first: - specifier: ^2.0.2 - version: 2.0.2 devDependencies: '@tanstack/react-query': specifier: ^4.29.7 @@ -310,6 +274,9 @@ importers: '@zenstackhq/testtools': specifier: workspace:* version: link:../../testtools/dist + glob: + specifier: ^8.1.0 + version: 8.1.0 jest-environment-jsdom: specifier: ^29.7.0 version: 29.7.0 @@ -322,9 +289,6 @@ importers: react-test-renderer: specifier: ^18.2.0 version: 18.3.1(react@18.2.0) - replace-in-file: - specifier: ^7.0.1 - version: 7.2.0 svelte: specifier: ^4.2.1 version: 4.2.18 @@ -341,24 +305,18 @@ importers: packages/plugins/trpc: dependencies: + '@zenstackhq/runtime': + specifier: workspace:* + version: link:../../runtime/dist '@zenstackhq/sdk': specifier: workspace:* version: link:../../sdk/dist - change-case: - specifier: ^4.1.2 - version: 4.1.2 - lower-case-first: - specifier: ^2.0.2 - version: 2.0.2 ts-morph: specifier: ^16.0.0 version: 16.0.0 tslib: specifier: ^2.4.1 version: 2.6.3 - upper-case-first: - specifier: ^2.0.2 - version: 2.0.2 zod: specifier: ^3.22.4 version: 3.23.8 @@ -392,32 +350,23 @@ importers: packages/runtime: dependencies: '@prisma/client': - specifier: 5.0.0 - 6.8.x - version: 6.8.2(prisma@6.0.0)(typescript@5.5.2) + specifier: 5.0.0 - 6.10.x + version: 6.10.0(prisma@6.0.0)(typescript@5.5.2) bcryptjs: specifier: ^2.4.3 version: 2.4.3 buffer: specifier: ^6.0.3 version: 6.0.3 - change-case: - specifier: ^4.1.2 - version: 4.1.2 decimal.js-light: specifier: ^2.5.1 version: 2.5.1 deepmerge: specifier: ^4.3.1 version: 4.3.1 - is-plain-object: - specifier: ^5.0.0 - version: 5.0.0 logic-solver: specifier: ^2.0.1 version: 2.0.1 - lower-case-first: - specifier: ^2.0.2 - version: 2.0.2 pluralize: specifier: ^8.0.0 version: 8.0.0 @@ -430,9 +379,6 @@ importers: superjson: specifier: ^1.13.0 version: 1.13.3 - tiny-invariant: - specifier: ^1.3.1 - version: 1.3.3 traverse: specifier: ^0.6.10 version: 0.6.10 @@ -442,9 +388,6 @@ importers: tslib: specifier: ^2.4.1 version: 2.6.3 - upper-case-first: - specifier: ^2.0.2 - version: 2.0.2 uuid: specifier: ^9.0.0 version: 9.0.1 @@ -492,9 +435,6 @@ importers: async-exit-hook: specifier: ^2.0.1 version: 2.0.1 - change-case: - specifier: ^4.1.2 - version: 4.1.2 colors: specifier: 1.4.0 version: 1.4.0 @@ -507,9 +447,6 @@ importers: langium: specifier: 1.3.1 version: 1.3.1 - lower-case-first: - specifier: ^2.0.2 - version: 2.0.2 mixpanel: specifier: ^0.17.0 version: 0.17.0 @@ -523,32 +460,23 @@ importers: specifier: ^4.0.0 version: 4.0.1 prisma: - specifier: 5.0.0 - 6.8.x + specifier: 5.0.0 - 6.10.x version: 6.0.0 semver: specifier: ^7.5.2 version: 7.6.2 - sleep-promise: - specifier: ^9.1.0 - version: 9.1.0 strip-color: specifier: ^0.1.0 version: 0.1.0 terminal-link: specifier: ^2.0.0 version: 2.1.1 - tiny-invariant: - specifier: ^1.3.1 - version: 1.3.3 ts-morph: specifier: ^16.0.0 version: 16.0.0 ts-pattern: specifier: ^4.3.0 version: 4.3.0 - upper-case-first: - specifier: ^2.0.2 - version: 2.0.2 uuid: specifier: ^9.0.0 version: 9.0.1 @@ -575,8 +503,8 @@ importers: version: 1.5.0(zod@3.23.8) devDependencies: '@prisma/client': - specifier: 6.8.x - version: 6.8.2(prisma@6.0.0)(typescript@5.5.2) + specifier: 6.10.x + version: 6.10.0(prisma@6.0.0)(typescript@5.5.2) '@types/async-exit-hook': specifier: ^2.0.0 version: 2.0.2 @@ -627,11 +555,11 @@ importers: packages/sdk: dependencies: '@prisma/generator-helper': - specifier: 6.8.x - version: 6.8.2 + specifier: 6.10.x + version: 6.10.0 '@prisma/internals': - specifier: 6.8.x - version: 6.8.2(typescript@5.5.2) + specifier: 6.10.x + version: 6.10.0(typescript@5.5.2) '@zenstackhq/language': specifier: workspace:* version: link:../language/dist @@ -641,9 +569,6 @@ importers: langium: specifier: 1.3.1 version: 1.3.1 - lower-case-first: - specifier: ^2.0.2 - version: 2.0.2 semver: specifier: ^7.5.2 version: 7.6.2 @@ -653,9 +578,6 @@ importers: ts-pattern: specifier: ^4.3.0 version: 4.3.0 - upper-case-first: - specifier: ^2.0.2 - version: 2.0.2 devDependencies: '@types/semver': specifier: ^7.3.13 @@ -667,27 +589,15 @@ importers: '@zenstackhq/runtime': specifier: workspace:* version: link:../runtime/dist - change-case: - specifier: ^4.1.2 - version: 4.1.2 decimal.js: specifier: ^10.4.2 version: 10.4.3 - lower-case-first: - specifier: ^2.0.2 - version: 2.0.2 superjson: specifier: ^1.13.0 version: 1.13.3 - tiny-invariant: - specifier: ^1.3.1 - version: 1.3.3 ts-japi: specifier: ^1.10.1 version: 1.11.4 - upper-case-first: - specifier: ^2.0.2 - version: 2.0.2 url-pattern: specifier: ^1.0.3 version: 1.0.3 @@ -706,7 +616,7 @@ importers: version: 10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.9) '@nestjs/testing': specifier: ^10.3.7 - version: 10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.9)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.9)) + version: 10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.9)(@nestjs/platform-express@10.3.9) '@sveltejs/kit': specifier: 1.21.0 version: 1.21.0(svelte@4.2.18)(vite@5.3.2(@types/node@20.14.9)(terser@5.31.1)) @@ -780,9 +690,6 @@ importers: pg: specifier: ^8.11.1 version: 8.12.0 - tiny-invariant: - specifier: ^1.3.1 - version: 1.3.3 tmp: specifier: ^0.2.1 version: 0.2.3 @@ -821,9 +728,6 @@ importers: pg: specifier: ^8.11.1 version: 8.12.0 - sleep-promise: - specifier: ^9.1.0 - version: 9.1.0 superjson: specifier: ^1.13.0 version: 1.13.3 @@ -861,9 +765,6 @@ importers: fs-extra: specifier: ^11.1.0 version: 11.2.0 - jest-fetch-mock: - specifier: ^3.0.3 - version: 3.0.3(encoding@0.1.13) next: specifier: 14.2.4 version: 14.2.4(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) @@ -2577,8 +2478,8 @@ packages: prisma: optional: true - '@prisma/client@6.8.2': - resolution: {integrity: sha512-5II+vbyzv4si6Yunwgkj0qT/iY0zyspttoDrL3R4BYgLdp42/d2C8xdi9vqkrYtKt9H32oFIukvyw3Koz5JoDg==} + '@prisma/client@6.10.0': + resolution: {integrity: sha512-C+3A6sPt8EwUlNwsbT22IoUq0O+wXXA4Sw39UmCATlfa8HVP5r0X/l9xGyELhfSmmO0sjgSAl7qmlCHS6Dkekw==} engines: {node: '>=18.18'} peerDependencies: prisma: '*' @@ -2589,8 +2490,8 @@ packages: typescript: optional: true - '@prisma/config@6.8.2': - resolution: {integrity: sha512-ZJY1fF4qRBPdLQ/60wxNtX+eu89c3AkYEcP7L3jkp0IPXCNphCYxikTg55kPJLDOG6P0X+QG5tCv6CmsBRZWFQ==} + '@prisma/config@6.10.0': + resolution: {integrity: sha512-9aA88Vub9O7zdb52PuJg88cN2GCjfY2I45CIttJe7fS5EyvTRRGE/PDQlbjTG9ij9+leD47fGLQCqYDpyCE5Iw==} '@prisma/debug@5.14.0': resolution: {integrity: sha512-iq56qBZuFfX3fCxoxT8gBX33lQzomBU0qIUaEj1RebsKVz1ob/BVH1XSBwwwvRVtZEV1b7Fxx2eVu34Ge/mg3w==} @@ -2598,14 +2499,14 @@ packages: '@prisma/debug@6.0.0': resolution: {integrity: sha512-eUjoNThlDXdyJ1iQ2d7U6aTVwm59EwvODb5zFVNJEokNoSiQmiYWNzZIwZyDmZ+j51j42/0iTaHIJ4/aZPKFRg==} - '@prisma/debug@6.8.2': - resolution: {integrity: sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg==} + '@prisma/debug@6.10.0': + resolution: {integrity: sha512-vzVu0Z3DfCzyx0m7LPZgdA/M7opv7B2R7agNLjh1PpIapCqHo/dwoXoj3Kl25A6TkmhexJzOZKedmhpXsMBwGA==} - '@prisma/dmmf@6.8.2': - resolution: {integrity: sha512-okGJF/7hQZam/2wt+Y0hPyNxyY5S+L0FzAgtL932Q3YxUWHusRllrN39bCV45oF3QWY992g7rTWYdL2Rynt1qg==} + '@prisma/dmmf@6.10.0': + resolution: {integrity: sha512-wLrw4Ro88jLQ7e3UfyAmktE6oNcIdPN7MNZQGX30KFvHOu6INz9SeMfVJ4kBgQkiVgq4jSEZ6Sfde54cra23tQ==} - '@prisma/driver-adapter-utils@6.8.2': - resolution: {integrity: sha512-5+CzN/41gBsRmA3ekbVy1TXnSImSPBtMlxWAttVH6tg94bv4zGGRmyk5tUCdT83nl0hG1Sq2oMXR7ml6aqILvw==} + '@prisma/driver-adapter-utils@6.10.0': + resolution: {integrity: sha512-+nApo/19QbfPy6smSwZValpNYbHrcI3ew6vhogYgJEijsB09Mxu2Wo+JDZIGF21DQq6RdRWeBFnJtUHLISlw4Q==} '@prisma/engines-version@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': resolution: {integrity: sha512-ip6pNkRo1UxWv+6toxNcYvItNYaqQjXdFNGJ+Nuk2eYtRoEdoF13wxo7/jsClJFFenMPVNVqXQDV0oveXnR1cA==} @@ -2613,8 +2514,8 @@ packages: '@prisma/engines-version@5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e': resolution: {integrity: sha512-JmIds0Q2/vsOmnuTJYxY4LE+sajqjYKhLtdOT6y4imojqv5d/aeVEfbBGC74t8Be1uSp0OP8lxIj2OqoKbLsfQ==} - '@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': - resolution: {integrity: sha512-Rkik9lMyHpFNGaLpPF3H5q5TQTkm/aE7DsGM5m92FZTvWQsvmi6Va8On3pWvqLHOt5aPUvFb/FeZTmphI4CPiQ==} + '@prisma/engines-version@6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8': + resolution: {integrity: sha512-Dy7cS5Sz/kzdj2nrYTiPfycf/ZeQXFoIcXgTLmYHpuDX0rGITEGe7JSTSNnLYRUnjTHerDTPGPJCiDeyb6lPBg==} '@prisma/engines@5.14.0': resolution: {integrity: sha512-lgxkKZ6IEygVcw6IZZUlPIfLQ9hjSYAtHjZ5r64sCLDgVzsPFCi2XBBJgzPMkOQ5RHzUD4E/dVdpn9+ez8tk1A==} @@ -2622,8 +2523,8 @@ packages: '@prisma/engines@6.0.0': resolution: {integrity: sha512-ZZCVP3q22ifN6Ex6C8RIcTDBlRtMJS2H1ljV0knCiWNGArvvkEbE88W3uDdq/l4+UvyvHpGzdf9ZsCWSQR7ZQQ==} - '@prisma/engines@6.8.2': - resolution: {integrity: sha512-XqAJ//LXjqYRQ1RRabs79KOY4+v6gZOGzbcwDQl0D6n9WBKjV7qdrbd042CwSK0v0lM9MSHsbcFnU2Yn7z8Zlw==} + '@prisma/engines@6.10.0': + resolution: {integrity: sha512-g/VL/J+b1rjzvPLZWSjOt/iWX/As44IF65x0XrsvwjD1UI0hLHzDAVx3AJz4k4cNsFzEQqVl/rLa6ICsLy8v5w==} '@prisma/fetch-engine@5.14.0': resolution: {integrity: sha512-VrheA9y9DMURK5vu8OJoOgQpxOhas3qF0IBHJ8G/0X44k82kc8E0w98HCn2nhnbOOMwbWsJWXfLC2/F8n5u0gQ==} @@ -2631,17 +2532,17 @@ packages: '@prisma/fetch-engine@6.0.0': resolution: {integrity: sha512-j2m+iO5RDPRI7SUc7sHo8wX7SA4iTkJ+18Sxch8KinQM46YiCQD1iXKN6qU79C1Fliw5Bw/qDyTHaTsa3JMerA==} - '@prisma/fetch-engine@6.8.2': - resolution: {integrity: sha512-lCvikWOgaLOfqXGacEKSNeenvj0n3qR5QvZUOmPE2e1Eh8cMYSobxonCg9rqM6FSdTfbpqp9xwhSAOYfNqSW0g==} + '@prisma/fetch-engine@6.10.0': + resolution: {integrity: sha512-7An09F6Xe886gSwcj1HEY/0LBuD4IR0ZnKbNv4d0kMnmNzGCz+IK4XRnd/yOkiptIks0nF+igLEin5MEoBejfA==} '@prisma/generator-helper@5.14.0': resolution: {integrity: sha512-xVc71cmTnPZ0lnSs4FAY6Ta72vFJ3webrQwKMQ2ujr6hDG1VPIEf820T1TOS3ZZQd/OKigNKXnq3co8biz9/qw==} - '@prisma/generator-helper@6.8.2': - resolution: {integrity: sha512-KBLW47sbwFBKKYMiICIAEWsG6TdpPapPT7e7hpmpF3xMgYAm6YIXu4JGwfQVDY9Vbcb+0vPdPdSEQtInYOOe5g==} + '@prisma/generator-helper@6.10.0': + resolution: {integrity: sha512-oztrNwQ70ridJ4qAGRUyAqoxU9lei7NkiTDg9HfRd1OCj8P2eEjEpUL2RAVeoCJJlTK4FAbTdo0vvp3APG5M9w==} - '@prisma/generator@6.8.2': - resolution: {integrity: sha512-yExkvgqiKg1WHzjYttz40g5DsOtud8RhapM0Mum6pw+wrDoQyhSAxs5NHyFCV+9VPvRd2v+jAP2CTT07bsibjw==} + '@prisma/generator@6.10.0': + resolution: {integrity: sha512-lQFnS2l/t/lzY5k8E3MTWI72d/1pNxmPOSkHpJXvRfBQi54pAcnyaZwMa+BC/MqP+Xl3INc+7xCPBCkPxjo5nA==} '@prisma/get-platform@5.14.0': resolution: {integrity: sha512-/yAyBvcEjRv41ynZrhdrPtHgk47xLRRq/o5eWGcUpBJ1YrUZTYB8EoPiopnP7iQrMATK8stXQdPOoVlrzuTQZw==} @@ -2649,14 +2550,14 @@ packages: '@prisma/get-platform@6.0.0': resolution: {integrity: sha512-PS6nYyIm9g8C03E4y7LknOfdCw/t2KyEJxntMPQHQZCOUgOpF82Ma60mdlOD08w90I3fjLiZZ0+MadenR3naDQ==} - '@prisma/get-platform@6.8.2': - resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==} + '@prisma/get-platform@6.10.0': + resolution: {integrity: sha512-6xqX2cxC2l0JHySyyFlXZ4QIESeEmkvSJfGy2r/NsQG+vjxBNDrlwDOgh+aQI1ivbgqwFRjSXuUjl/yd2Za2HQ==} '@prisma/internals@5.14.0': resolution: {integrity: sha512-s0JRNDmR2bvcyy0toz89jy7SbbjANAs4e9KCReNvSm5czctIaZzDf68tcOXdtH0G7m9mKhVhNPdS9lMky0DhWA==} - '@prisma/internals@6.8.2': - resolution: {integrity: sha512-lDZrOCUW+ubBTXfEgun969eHVc+Uiq2W7YfF/bWZ0hGX2wLGQsgLGXsRw6AxyvWNXR85BbSPQ2qVHzKtWP9qXA==} + '@prisma/internals@6.10.0': + resolution: {integrity: sha512-bUZZhfVL2xMZcIDm/g7G6J2Pkc3jDRZ3sRkw6JIA6ufxGhbmCh+KjeeECrvtSCWs/wIiInGz/4DXhibgaLiscQ==} peerDependencies: typescript: '>=5.1.0' peerDependenciesMeta: @@ -2669,17 +2570,17 @@ packages: '@prisma/prisma-schema-wasm@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': resolution: {integrity: sha512-WeTmJ0mK8ALoKJUQFO+465k9lm1JWS4ODUg7akJq1wjgyDU1RTAzDFli8ESmNJlMVgJgoAd6jXmzcnoA0HT9Lg==} - '@prisma/prisma-schema-wasm@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': - resolution: {integrity: sha512-s2pYG3FWY1ICGN6TVu/DrzwZWzn4oyeOZnJI8CG5fJey7i3r8EtxiBB9R9ahwL0Kqg+5KAYn37V2kVCu/9+Y/g==} + '@prisma/prisma-schema-wasm@6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8': + resolution: {integrity: sha512-AZO22bMnTa9fzlzDumgoHloQw5INU6/9kR7SlbZr7qMH11pyr0+cZE5r4yoi6JWlUXWsUA04XeGfsjXFoQx3WA==} - '@prisma/schema-engine-wasm@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': - resolution: {integrity: sha512-2NEk/2meUvvpcI+Sn9DdCjKDGWRxYPnHbLI6u05ZI2TIIgk/QwdAryn+xgO9VebmWSjpQoUhaIM+KCioKU1y5w==} + '@prisma/schema-engine-wasm@6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8': + resolution: {integrity: sha512-p1gYMKVY+AhrcG4ct/bBTKZzjud+17lzpUS1iDCg4L4xYSK9/PLr0f4BqoUdM0AYzJ3bTAvZ3ukYbpBHQfkVlw==} '@prisma/schema-files-loader@5.14.0': resolution: {integrity: sha512-n1QHR2C63dARKPZe0WPn7biybcBHzXe+BEmiHC5Drq9KPWnpmQtIfGpqm1ZKdvCZfcA5FF3wgpSMPK4LnB0obQ==} - '@prisma/schema-files-loader@6.8.2': - resolution: {integrity: sha512-JRXJ08xfA1cP30kgP15AMCOKZchy2ss2oN6nSHxN745euh2tijpzvW4yCD4Q/1ZtnDkfKae45Tcpx0Ytab7RPA==} + '@prisma/schema-files-loader@6.10.0': + resolution: {integrity: sha512-R1z5g97Jc3UU+ptcwDlVDTkpDNfRQKv/tRrYXwygvrI4XWneEIJHYM3SXbTFcu2arlUzDHJBXAylXkcD+RM5zQ==} '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -3920,9 +3821,6 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - camel-case@4.1.2: - resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} - camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -3937,9 +3835,6 @@ packages: caniuse-lite@1.0.30001638: resolution: {integrity: sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==} - capital-case@1.0.4: - resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} - chai@4.4.1: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} engines: {node: '>=4'} @@ -3956,9 +3851,6 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - change-case@4.1.2: - resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} - char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} @@ -4155,7 +4047,7 @@ packages: engines: {node: '>= 14'} concat-map@0.0.1: - resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} concat-stream@1.6.2: resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} @@ -4179,9 +4071,6 @@ packages: console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - constant-case@3.0.4: - resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} - content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -4260,9 +4149,6 @@ packages: resolution: {integrity: sha512-ULYhWIonJzlScCCQrPUG5uMXzXxSixty4djud9SS37DoNxDdkeRocxzHuAo4ImRBUK+mAuU5X9TSwEDccnnuPg==} hasBin: true - cross-fetch@3.1.8: - resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} - cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} @@ -4574,9 +4460,6 @@ packages: domutils@3.1.0: resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} - dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - dot-prop@8.0.2: resolution: {integrity: sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==} engines: {node: '>=16'} @@ -4606,7 +4489,7 @@ packages: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} ee-first@1.1.1: - resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} electron-to-chromium@1.4.814: resolution: {integrity: sha512-GVulpHjFu1Y9ZvikvbArHmAhZXtm3wHlpjTMcXNGKl4IQ4jMQjlnz8yMQYYqdLHKi/jEL2+CBC2akWVCoIGUdw==} @@ -4999,6 +4882,7 @@ packages: formidable@2.1.2: resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} + deprecated: 'ACTION REQUIRED: SWITCH TO v3 - v1 and v2 are VULNERABLE! v1 is DEPRECATED FOR OVER 2 YEARS! Use formidable@latest or try formidable-mini for fresh projects' forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} @@ -5258,9 +5142,6 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - header-case@2.0.4: - resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} - hexoid@1.0.0: resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} engines: {node: '>=8'} @@ -5543,10 +5424,6 @@ packages: resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} engines: {node: '>=12'} - is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -5736,9 +5613,6 @@ packages: resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-fetch-mock@3.0.3: - resolution: {integrity: sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==} - jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6120,12 +5994,6 @@ packages: loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - lower-case-first@2.0.2: - resolution: {integrity: sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==} - - lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - lowlight@1.17.0: resolution: {integrity: sha512-vmtBgYKD+QVNy7tIa7ulz5d//Il9R4MooOVh4nkOf9R9Cb/Dk5TXMSTieg/vDulkBkIWj59/BIlyFQxT9X1oAQ==} @@ -6193,7 +6061,7 @@ packages: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} media-typer@0.3.0: - resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} merge-descriptors@1.0.1: @@ -6414,9 +6282,6 @@ packages: xml2js: optional: true - no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - nock@13.5.4: resolution: {integrity: sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==} engines: {node: '>= 10.13'} @@ -6640,9 +6505,6 @@ packages: package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - param-case@3.0.4: - resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} - parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -6674,9 +6536,6 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} - pascal-case@3.1.2: - resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} - pascalcase@1.0.0: resolution: {integrity: sha512-BSExi0rRnCHReJys6NocaK+cfTXNinAegfWBvr0JD3hiaEG7Nuc7r0CIdOJunXrs8gU/sbHQ9dxVAtiVQisjmg==} engines: {node: '>=8'} @@ -6684,9 +6543,6 @@ packages: path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - path-case@3.0.4: - resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} - path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -7122,9 +6978,6 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - promise-polyfill@8.3.0: - resolution: {integrity: sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==} - promise-retry@2.0.1: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} @@ -7306,11 +7159,6 @@ packages: engines: {node: '>=12.17'} hasBin: true - replace-in-file@7.2.0: - resolution: {integrity: sha512-CiLXVop3o8/h2Kd1PwKPPimmS9wUV0Ki6Fl8+1ITD35nB3Gl/PrW5IONpTE0AXk0z4v8WYcpEpdeZqMXvSnWpg==} - engines: {node: '>=10'} - hasBin: true - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -7475,9 +7323,6 @@ packages: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} - sentence-case@3.0.4: - resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} - serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -7569,9 +7414,6 @@ packages: resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} engines: {node: '>=14.16'} - sleep-promise@9.1.0: - resolution: {integrity: sha512-UHYzVpz9Xn8b+jikYSD6bqvf754xL2uBUzDFwiU6NcdZeifPr6UfgU43xpkPu67VMS88+TI2PSI7Eohgqf2fKA==} - slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -7587,9 +7429,6 @@ packages: resolution: {integrity: sha512-OtZKrVrGIT+m++lxyF0z5n68nkwdgZotPhy89bfA4T7nSWe0xeQtfbjM1z5VLTilJdWXH46g8i0oAcpQNkzZTg==} engines: {node: '>= 18', pnpm: '>= 9'} - snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - socks-proxy-agent@8.0.4: resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==} engines: {node: '>= 14'} @@ -8332,12 +8171,6 @@ packages: peerDependencies: browserslist: '>= 4.21.0' - upper-case-first@2.0.2: - resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} - - upper-case@2.0.2: - resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} - uqr@0.1.2: resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} @@ -8369,7 +8202,7 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} utils-merge@1.0.1: - resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=} + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} uuid@10.0.0: @@ -9442,6 +9275,7 @@ snapshots: '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 + optional: true '@envelop/core@4.0.3': dependencies: @@ -10171,6 +10005,7 @@ snapshots: dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 + optional: true '@js-sdsl/ordered-map@4.4.2': {} @@ -10255,7 +10090,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/testing@10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.9)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.9))': + '@nestjs/testing@10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.9)(@nestjs/platform-express@10.3.9)': dependencies: '@nestjs/common': 10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.3.9(@nestjs/common@10.3.9(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.9)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -10783,12 +10618,12 @@ snapshots: optionalDependencies: prisma: 6.0.0 - '@prisma/client@6.8.2(prisma@6.0.0)(typescript@5.5.2)': + '@prisma/client@6.10.0(prisma@6.0.0)(typescript@5.5.2)': optionalDependencies: prisma: 6.0.0 typescript: 5.5.2 - '@prisma/config@6.8.2': + '@prisma/config@6.10.0': dependencies: jiti: 2.4.2 @@ -10796,19 +10631,19 @@ snapshots: '@prisma/debug@6.0.0': {} - '@prisma/debug@6.8.2': {} + '@prisma/debug@6.10.0': {} - '@prisma/dmmf@6.8.2': {} + '@prisma/dmmf@6.10.0': {} - '@prisma/driver-adapter-utils@6.8.2': + '@prisma/driver-adapter-utils@6.10.0': dependencies: - '@prisma/debug': 6.8.2 + '@prisma/debug': 6.10.0 '@prisma/engines-version@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': {} '@prisma/engines-version@5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e': {} - '@prisma/engines-version@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': {} + '@prisma/engines-version@6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8': {} '@prisma/engines@5.14.0': dependencies: @@ -10824,12 +10659,12 @@ snapshots: '@prisma/fetch-engine': 6.0.0 '@prisma/get-platform': 6.0.0 - '@prisma/engines@6.8.2': + '@prisma/engines@6.10.0': dependencies: - '@prisma/debug': 6.8.2 - '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e - '@prisma/fetch-engine': 6.8.2 - '@prisma/get-platform': 6.8.2 + '@prisma/debug': 6.10.0 + '@prisma/engines-version': 6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8 + '@prisma/fetch-engine': 6.10.0 + '@prisma/get-platform': 6.10.0 '@prisma/fetch-engine@5.14.0': dependencies: @@ -10843,23 +10678,23 @@ snapshots: '@prisma/engines-version': 5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e '@prisma/get-platform': 6.0.0 - '@prisma/fetch-engine@6.8.2': + '@prisma/fetch-engine@6.10.0': dependencies: - '@prisma/debug': 6.8.2 - '@prisma/engines-version': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e - '@prisma/get-platform': 6.8.2 + '@prisma/debug': 6.10.0 + '@prisma/engines-version': 6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8 + '@prisma/get-platform': 6.10.0 '@prisma/generator-helper@5.14.0': dependencies: '@prisma/debug': 5.14.0 - '@prisma/generator-helper@6.8.2': + '@prisma/generator-helper@6.10.0': dependencies: - '@prisma/debug': 6.8.2 - '@prisma/dmmf': 6.8.2 - '@prisma/generator': 6.8.2 + '@prisma/debug': 6.10.0 + '@prisma/dmmf': 6.10.0 + '@prisma/generator': 6.10.0 - '@prisma/generator@6.8.2': {} + '@prisma/generator@6.10.0': {} '@prisma/get-platform@5.14.0': dependencies: @@ -10869,9 +10704,9 @@ snapshots: dependencies: '@prisma/debug': 6.0.0 - '@prisma/get-platform@6.8.2': + '@prisma/get-platform@6.10.0': dependencies: - '@prisma/debug': 6.8.2 + '@prisma/debug': 6.10.0 '@prisma/internals@5.14.0': dependencies: @@ -10885,20 +10720,20 @@ snapshots: arg: 5.0.2 prompts: 2.4.2 - '@prisma/internals@6.8.2(typescript@5.5.2)': - dependencies: - '@prisma/config': 6.8.2 - '@prisma/debug': 6.8.2 - '@prisma/dmmf': 6.8.2 - '@prisma/driver-adapter-utils': 6.8.2 - '@prisma/engines': 6.8.2 - '@prisma/fetch-engine': 6.8.2 - '@prisma/generator': 6.8.2 - '@prisma/generator-helper': 6.8.2 - '@prisma/get-platform': 6.8.2 - '@prisma/prisma-schema-wasm': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e - '@prisma/schema-engine-wasm': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e - '@prisma/schema-files-loader': 6.8.2 + '@prisma/internals@6.10.0(typescript@5.5.2)': + dependencies: + '@prisma/config': 6.10.0 + '@prisma/debug': 6.10.0 + '@prisma/dmmf': 6.10.0 + '@prisma/driver-adapter-utils': 6.10.0 + '@prisma/engines': 6.10.0 + '@prisma/fetch-engine': 6.10.0 + '@prisma/generator': 6.10.0 + '@prisma/generator-helper': 6.10.0 + '@prisma/get-platform': 6.10.0 + '@prisma/prisma-schema-wasm': 6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8 + '@prisma/schema-engine-wasm': 6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8 + '@prisma/schema-files-loader': 6.10.0 arg: 5.0.2 prompts: 2.4.2 optionalDependencies: @@ -10908,18 +10743,18 @@ snapshots: '@prisma/prisma-schema-wasm@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': {} - '@prisma/prisma-schema-wasm@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': {} + '@prisma/prisma-schema-wasm@6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8': {} - '@prisma/schema-engine-wasm@6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e': {} + '@prisma/schema-engine-wasm@6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8': {} '@prisma/schema-files-loader@5.14.0': dependencies: '@prisma/prisma-schema-wasm': 5.14.0-17.56ca112d5a19c9925b53af75c3c6b7ada97f9f85 fs-extra: 11.1.1 - '@prisma/schema-files-loader@6.8.2': + '@prisma/schema-files-loader@6.10.0': dependencies: - '@prisma/prisma-schema-wasm': 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e + '@prisma/prisma-schema-wasm': 6.10.0-43.aee10d5a411e4360c6d3445ce4810ca65adbf3e8 fs-extra: 11.3.0 '@protobufjs/aspromise@1.1.2': {} @@ -11392,13 +11227,17 @@ snapshots: mkdirp: 1.0.4 path-browserify: 1.0.1 - '@tsconfig/node10@1.0.11': {} + '@tsconfig/node10@1.0.11': + optional: true - '@tsconfig/node12@1.0.11': {} + '@tsconfig/node12@1.0.11': + optional: true - '@tsconfig/node14@1.0.3': {} + '@tsconfig/node14@1.0.3': + optional: true - '@tsconfig/node16@1.0.4': {} + '@tsconfig/node16@1.0.4': + optional: true '@types/aria-query@5.0.4': {} @@ -12120,7 +11959,8 @@ snapshots: delegates: 1.0.0 readable-stream: 3.6.2 - arg@4.1.3: {} + arg@4.1.3: + optional: true arg@5.0.2: {} @@ -12437,11 +12277,6 @@ snapshots: callsites@3.1.0: {} - camel-case@4.1.2: - dependencies: - pascal-case: 3.1.2 - tslib: 2.6.3 - camelcase@5.3.1: {} camelcase@6.3.0: {} @@ -12455,12 +12290,6 @@ snapshots: caniuse-lite@1.0.30001638: {} - capital-case@1.0.4: - dependencies: - no-case: 3.0.4 - tslib: 2.6.3 - upper-case-first: 2.0.2 - chai@4.4.1: dependencies: assertion-error: 1.1.0 @@ -12484,21 +12313,6 @@ snapshots: chalk@5.3.0: {} - change-case@4.1.2: - dependencies: - camel-case: 4.1.2 - capital-case: 1.0.4 - constant-case: 3.0.4 - dot-case: 3.0.4 - header-case: 2.0.4 - no-case: 3.0.4 - param-case: 3.0.4 - pascal-case: 3.1.2 - path-case: 3.0.4 - sentence-case: 3.0.4 - snake-case: 3.0.4 - tslib: 2.6.3 - char-regex@1.0.2: {} chardet@0.7.0: {} @@ -12723,12 +12537,6 @@ snapshots: console-control-strings@1.1.0: {} - constant-case@3.0.4: - dependencies: - no-case: 3.0.4 - tslib: 2.6.3 - upper-case: 2.0.2 - content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -12802,12 +12610,6 @@ snapshots: cronstrue@2.50.0: {} - cross-fetch@3.1.8(encoding@0.1.13): - dependencies: - node-fetch: 2.7.0(encoding@0.1.13) - transitivePeerDependencies: - - encoding - cross-fetch@4.0.0(encoding@0.1.13): dependencies: node-fetch: 2.7.0(encoding@0.1.13) @@ -13068,7 +12870,8 @@ snapshots: diff-sequences@29.6.3: {} - diff@4.0.2: {} + diff@4.0.2: + optional: true diff@5.2.0: {} @@ -13104,11 +12907,6 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 - dot-case@3.0.4: - dependencies: - no-case: 3.0.4 - tslib: 2.6.3 - dot-prop@8.0.2: dependencies: type-fest: 3.13.1 @@ -14086,11 +13884,6 @@ snapshots: dependencies: function-bind: 1.1.2 - header-case@2.0.4: - dependencies: - capital-case: 1.0.4 - tslib: 2.6.3 - hexoid@1.0.0: {} highlight.js@10.4.1: {} @@ -14351,8 +14144,6 @@ snapshots: is-path-inside@4.0.0: {} - is-plain-object@5.0.0: {} - is-potential-custom-element-name@1.0.1: {} is-reference@1.2.1: @@ -14620,13 +14411,6 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 - jest-fetch-mock@3.0.3(encoding@0.1.13): - dependencies: - cross-fetch: 3.1.8(encoding@0.1.13) - promise-polyfill: 8.3.0 - transitivePeerDependencies: - - encoding - jest-get-type@29.6.3: {} jest-haste-map@29.7.0: @@ -15166,14 +14950,6 @@ snapshots: dependencies: get-func-name: 2.0.2 - lower-case-first@2.0.2: - dependencies: - tslib: 2.6.3 - - lower-case@2.0.2: - dependencies: - tslib: 2.6.3 - lowlight@1.17.0: dependencies: fault: 1.0.4 @@ -15531,11 +15307,6 @@ snapshots: - supports-color - uWebSockets.js - no-case@3.0.4: - dependencies: - lower-case: 2.0.2 - tslib: 2.6.3 - nock@13.5.4: dependencies: debug: 4.3.5 @@ -15870,11 +15641,6 @@ snapshots: package-json-from-dist@1.0.0: {} - param-case@3.0.4: - dependencies: - dot-case: 3.0.4 - tslib: 2.6.3 - parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -15914,20 +15680,10 @@ snapshots: parseurl@1.3.3: {} - pascal-case@3.1.2: - dependencies: - no-case: 3.0.4 - tslib: 2.6.3 - pascalcase@1.0.0: {} path-browserify@1.0.1: {} - path-case@3.0.4: - dependencies: - dot-case: 3.0.4 - tslib: 2.6.3 - path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -16343,8 +16099,6 @@ snapshots: process@0.11.10: {} - promise-polyfill@8.3.0: {} - promise-retry@2.0.1: dependencies: err-code: 2.0.3 @@ -16564,12 +16318,6 @@ snapshots: stream-read-all: 3.0.1 typical: 7.1.1 - replace-in-file@7.2.0: - dependencies: - chalk: 4.1.2 - glob: 8.1.0 - yargs: 17.7.2 - require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -16740,12 +16488,6 @@ snapshots: transitivePeerDependencies: - supports-color - sentence-case@3.0.4: - dependencies: - no-case: 3.0.4 - tslib: 2.6.3 - upper-case-first: 2.0.2 - serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 @@ -16846,8 +16588,6 @@ snapshots: slash@5.1.0: {} - sleep-promise@9.1.0: {} - slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 @@ -16859,11 +16599,6 @@ snapshots: smol-toml@1.2.1: {} - snake-case@3.0.4: - dependencies: - dot-case: 3.0.4 - tslib: 2.6.3 - socks-proxy-agent@8.0.4: dependencies: agent-base: 7.1.1 @@ -17361,6 +17096,7 @@ snapshots: typescript: 5.5.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + optional: true ts-pattern@4.3.0: {} @@ -17664,14 +17400,6 @@ snapshots: escalade: 3.1.2 picocolors: 1.0.1 - upper-case-first@2.0.2: - dependencies: - tslib: 2.6.3 - - upper-case@2.0.2: - dependencies: - tslib: 2.6.3 - uqr@0.1.2: {} uri-js@4.4.1: @@ -17705,7 +17433,8 @@ snapshots: uuid@9.0.1: {} - v8-compile-cache-lib@3.0.1: {} + v8-compile-cache-lib@3.0.1: + optional: true v8-to-istanbul@9.3.0: dependencies: @@ -18149,7 +17878,8 @@ snapshots: dependencies: buffer-crc32: 0.2.13 - yn@3.1.1: {} + yn@3.1.1: + optional: true yocto-queue@0.1.0: {} diff --git a/script/test-scaffold.ts b/script/test-scaffold.ts index c05b2c0f8..0773666fb 100644 --- a/script/test-scaffold.ts +++ b/script/test-scaffold.ts @@ -19,6 +19,6 @@ function run(cmd: string) { } run('npm init -y'); -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'); +run('npm i --no-audit --no-fund typescript prisma@6.10.x @prisma/client@6.10.x zod@^3.22.4 decimal.js @types/node'); console.log('Test scaffold setup complete.'); diff --git a/tests/integration/package.json b/tests/integration/package.json index 79404f3e8..000c5ee1b 100644 --- a/tests/integration/package.json +++ b/tests/integration/package.json @@ -22,7 +22,6 @@ "@zenstackhq/swr": "workspace:*", "@zenstackhq/trpc": "workspace:*", "fs-extra": "^11.1.0", - "jest-fetch-mock": "^3.0.3", "next": "14.2.4", "tmp": "^0.2.1", "uuid": "^10.0.0", @@ -35,7 +34,6 @@ "bcryptjs": "^2.4.3", "decimal.js": "^10.4.2", "pg": "^8.11.1", - "sleep-promise": "^9.1.0", "superjson": "^1.13.0" } } diff --git a/tests/integration/test-run/package.json b/tests/integration/test-run/package.json index 5eabb95cd..79a72aff6 100644 --- a/tests/integration/test-run/package.json +++ b/tests/integration/test-run/package.json @@ -10,9 +10,9 @@ "author": "", "license": "ISC", "dependencies": { - "@prisma/client": "6.8.x", + "@prisma/client": "6.10.x", "@zenstackhq/runtime": "file:../../../packages/runtime/dist", - "prisma": "6.8.x", + "prisma": "6.10.x", "react": "^18.2.0", "swr": "^1.3.0", "typescript": "^4.9.3", diff --git a/tests/integration/tests/cli/generate.test.ts b/tests/integration/tests/cli/generate.test.ts index c4aed8e51..857c4fed1 100644 --- a/tests/integration/tests/cli/generate.test.ts +++ b/tests/integration/tests/cli/generate.test.ts @@ -68,8 +68,10 @@ model Post { const program = createProgram(); await program.parseAsync(['generate', '--no-dependency-check', '-o', 'out'], { from: 'user' }); expect(fs.existsSync('./node_modules/.zenstack')).toBeFalsy(); - expect(fs.existsSync('./out/policy.js')).toBeTruthy(); - expect(fs.existsSync('./out/model-meta.js')).toBeTruthy(); + expect(fs.existsSync('./out/policy.ts')).toBeTruthy(); + expect(fs.existsSync('./out/model-meta.ts')).toBeTruthy(); + expect(fs.existsSync('./out/policy.js')).toBeFalsy(); + expect(fs.existsSync('./out/model-meta.js')).toBeFalsy(); expect(fs.existsSync('./out/zod')).toBeTruthy(); }); @@ -83,8 +85,10 @@ model Post { from: 'user', }); expect(fs.existsSync('./node_modules/.zenstack')).toBeFalsy(); - expect(fs.existsSync('./out/policy.js')).toBeTruthy(); - expect(fs.existsSync('./out/model-meta.js')).toBeTruthy(); + expect(fs.existsSync('./out/policy.ts')).toBeTruthy(); + expect(fs.existsSync('./out/model-meta.ts')).toBeTruthy(); + expect(fs.existsSync('./out/policy.js')).toBeFalsy(); + expect(fs.existsSync('./out/model-meta.js')).toBeFalsy(); expect(fs.existsSync('./out/zod')).toBeTruthy(); }); diff --git a/tests/integration/tests/cli/plugins.test.ts b/tests/integration/tests/cli/plugins.test.ts index 25a4fa117..3d1f32536 100644 --- a/tests/integration/tests/cli/plugins.test.ts +++ b/tests/integration/tests/cli/plugins.test.ts @@ -75,7 +75,7 @@ describe('CLI Plugins Tests', () => { 'swr', '@tanstack/react-query@5.56.x', '@trpc/server', - '@prisma/client@6.8.x', + '@prisma/client@6.10.x', `${path.join(__dirname, '../../../../.build/zenstackhq-language-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-sdk-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-runtime-' + ver + '.tgz')}`, @@ -85,7 +85,7 @@ describe('CLI Plugins Tests', () => { const devDepPkgs = [ 'typescript', '@types/react', - 'prisma@6.8.x', + 'prisma@6.10.x', `${path.join(__dirname, '../../../../.build/zenstack-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-tanstack-query-' + ver + '.tgz')}`, `${path.join(__dirname, '../../../../.build/zenstackhq-swr-' + ver + '.tgz')}`, diff --git a/tests/integration/tests/frameworks/nextjs/test-project/package.json b/tests/integration/tests/frameworks/nextjs/test-project/package.json index 81fcef311..149e98f23 100644 --- a/tests/integration/tests/frameworks/nextjs/test-project/package.json +++ b/tests/integration/tests/frameworks/nextjs/test-project/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@prisma/client": "6.8.x", + "@prisma/client": "6.10.x", "@types/node": "18.11.18", "@types/react": "18.0.27", "@types/react-dom": "18.0.10", @@ -26,6 +26,6 @@ "@zenstackhq/swr": "../../../../../../../packages/plugins/swr/dist" }, "devDependencies": { - "prisma": "6.8.x" + "prisma": "6.10.x" } } diff --git a/tests/integration/tests/frameworks/trpc/test-project/package.json b/tests/integration/tests/frameworks/trpc/test-project/package.json index 43170787e..5cc6318c8 100644 --- a/tests/integration/tests/frameworks/trpc/test-project/package.json +++ b/tests/integration/tests/frameworks/trpc/test-project/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@prisma/client": "6.8.x", + "@prisma/client": "6.10.x", "@tanstack/react-query": "^4.22.4", "@trpc/client": "^10.34.0", "@trpc/next": "^10.34.0", @@ -31,6 +31,6 @@ "@zenstackhq/trpc": "../../../../../../../packages/plugins/trpc/dist" }, "devDependencies": { - "prisma": "6.8.x" + "prisma": "6.10.x" } } diff --git a/tests/integration/tests/misc/prisma-client-generator.test.ts b/tests/integration/tests/misc/prisma-client-generator.test.ts new file mode 100644 index 000000000..fbb2813c9 --- /dev/null +++ b/tests/integration/tests/misc/prisma-client-generator.test.ts @@ -0,0 +1,124 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('New prisma-client generator tests', () => { + it('works with `auth` in `@default`', async () => { + const { enhance, prisma } = await loadSchema( + ` + datasource db { + provider = "sqlite" + url = "file:./dev.db" + } + + generator client { + provider = "prisma-client" + output = "./prisma-generated" + moduleFormat = "cjs" + } + + model User { + id Int @id + posts Post[] + @@allow('all', true) + } + + model Post { + id Int @id + title String + author User @relation(fields: [authorId], references: [id]) + authorId Int @default(auth().id) + @@allow('all', true) + } + `, + { + addPrelude: false, + output: './zenstack', + compile: true, + prismaLoadPath: './prisma/prisma-generated/client', + extraSourceFiles: [ + { + name: 'main.ts', + content: ` +import { PrismaClient } from './prisma/prisma-generated/client'; +import { enhance } from './zenstack/enhance'; + +const prisma = new PrismaClient(); +const db = enhance(prisma); + +async function main() { + const post = await db.post.create({ data: { id: 1, title: 'Hello World' } }); + console.log(post.authorId); +} + +main(); +`, + }, + ], + } + ); + + const user = await prisma.user.create({ data: { id: 1 } }); + const db = enhance({ id: user.id }); + await expect(db.post.create({ data: { id: 1, title: 'Hello World' } })).resolves.toMatchObject({ + authorId: user.id, + }); + }); + + it('works with delegate models', async () => { + const { enhance } = await loadSchema( + ` + datasource db { + provider = "sqlite" + url = "file:./dev.db" + } + + generator client { + provider = "prisma-client" + output = "./prisma-generated" + moduleFormat = "cjs" + } + + model Asset { + id Int @id + name String + type String + @@delegate(type) + } + + model Post extends Asset { + title String + } + `, + { + enhancements: ['delegate'], + addPrelude: false, + output: './zenstack', + compile: true, + prismaLoadPath: './prisma/prisma-generated/client', + extraSourceFiles: [ + { + name: 'main.ts', + content: ` +import { PrismaClient } from './prisma/prisma-generated/client'; +import { enhance } from './zenstack/enhance'; + +const prisma = new PrismaClient(); +const db = enhance(prisma); + +async function main() { + const post = await db.post.create({ data: { id: 1, name: 'Test Post', title: 'Hello World' } }); + console.log(post.type, post.name, post.title); +} + +main(); +`, + }, + ], + } + ); + + const db = enhance(); + await expect( + db.post.create({ data: { id: 1, name: 'Test Post', title: 'Hello World' } }) + ).resolves.toMatchObject({ id: 1, name: 'Test Post', type: 'Post', title: 'Hello World' }); + }); +}); diff --git a/tests/integration/tests/schema/petstore.zmodel b/tests/integration/tests/schema/petstore.zmodel index 42a279550..8f032b510 100644 --- a/tests/integration/tests/schema/petstore.zmodel +++ b/tests/integration/tests/schema/petstore.zmodel @@ -15,10 +15,10 @@ model User { id String @id @default(cuid()) email String @unique orders Order[] - + // everybody can signup @@allow('create', true) - + // user profile is publicly readable @@allow('read', true) } @@ -31,10 +31,10 @@ model Pet { category String order Order? @relation(fields: [orderId], references: [id]) orderId String? - + // unsold pets are readable to all; sold ones are readable to buyers only @@allow('read', orderId == null || order.user == auth()) - + // only allow update to 'orderId' field if it's not set yet (unsold) @@allow('update', name == future().name && category == future().category && orderId == null ) } @@ -46,7 +46,7 @@ model Order { pets Pet[] user User @relation(fields: [userId], references: [id]) userId String - + // users can read their orders @@allow('read,create', auth() == user) -} \ No newline at end of file +} diff --git a/tests/integration/tests/schema/refactor-pg.zmodel b/tests/integration/tests/schema/refactor-pg.zmodel index d0b4579e1..beb5c2125 100644 --- a/tests/integration/tests/schema/refactor-pg.zmodel +++ b/tests/integration/tests/schema/refactor-pg.zmodel @@ -10,7 +10,7 @@ model User { profile Profile? posts Post[] comments Comment[] - + // everybody can signup @@allow('create', true) @@ -30,10 +30,10 @@ model Profile { user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId Int @unique - + // user profile is publicly readable @@allow('read', auth() != null && !private) - + // user profile is only updatable by the user @@allow('all', auth() == user || auth().role == ADMIN) } @@ -60,7 +60,7 @@ model Post { // posts are readable by all @@allow('read', published) - + // posts are updatable by the author @@allow('all', auth() == author || auth().role == ADMIN) } @@ -76,7 +76,7 @@ model Comment { postId Int images Image[] - + // comments are readable by all @@allow('read', post.published) @@ -85,7 +85,7 @@ model Comment { @@allow('update', auth() == author && future().author == auth()) @@allow('delete', auth() == author || auth() == post.author) - + // comments are updatable by the author @@allow('all', auth().role == ADMIN) } diff --git a/tests/integration/tests/schema/todo-pg.zmodel b/tests/integration/tests/schema/todo-pg.zmodel index b301ce432..05255da44 100644 --- a/tests/integration/tests/schema/todo-pg.zmodel +++ b/tests/integration/tests/schema/todo-pg.zmodel @@ -103,7 +103,7 @@ model List { // require login @@deny('all', auth() == null) - // can be read by owner or space members (only if not private) + // can be read by owner or space members (only if not private) @@allow('read', owner == auth() || (space.members?[user == auth()] && !private)) // when create, owner must be set to current user, and user must be in the space diff --git a/tests/integration/tests/schema/todo.zmodel b/tests/integration/tests/schema/todo.zmodel index 02169b626..8b045ea3a 100644 --- a/tests/integration/tests/schema/todo.zmodel +++ b/tests/integration/tests/schema/todo.zmodel @@ -114,7 +114,7 @@ model List { // require login @@deny('all', auth() == null) - // can be read by owner or space members (only if not private) + // can be read by owner or space members (only if not private) @@allow('read', owner == auth() || (space.members?[user == auth()] && !private)) // when create, owner must be set to current user, and user must be in the space diff --git a/tests/regression/tests/issue-2025.test.ts b/tests/regression/tests/issue-2025.test.ts new file mode 100644 index 000000000..92a8b6388 --- /dev/null +++ b/tests/regression/tests/issue-2025.test.ts @@ -0,0 +1,42 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('issue 2025', () => { + it('regression', async () => { + const { enhanceRaw, prisma } = await loadSchema( + ` + model User { + id String @id @default(cuid()) + email String @unique @email + termsAndConditions Int? + @@allow('all', true) + } + ` + ); + + const user = await prisma.user.create({ + data: { + email: 'xyz', // invalid email + }, + }); + + const db = enhanceRaw(prisma, undefined, { validation: { inputOnlyValidationForUpdate: true } }); + await expect( + db.user.update({ + where: { id: user.id }, + data: { + termsAndConditions: 1, + }, + }) + ).toResolveTruthy(); + + const db1 = enhanceRaw(prisma); + await expect( + db1.user.update({ + where: { id: user.id }, + data: { + termsAndConditions: 1, + }, + }) + ).toBeRejectedByPolicy(); + }); +});