diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..03571ca3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +packages/language/src/generated/** +**/schema.ts diff --git a/package.json b/package.json index 605d8adb..1295655d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-v3", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "ZenStack", "packageManager": "pnpm@10.12.1", "scripts": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 710c4ed3..1b3c92ed 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack CLI", "description": "FullStack database toolkit with built-in access control and automatic API generation.", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "type": "module", "author": { "name": "ZenStack Team" diff --git a/packages/cli/src/actions/action-utils.ts b/packages/cli/src/actions/action-utils.ts index 9f36d53c..2712e9cf 100644 --- a/packages/cli/src/actions/action-utils.ts +++ b/packages/cli/src/actions/action-utils.ts @@ -1,3 +1,4 @@ +import { findUp } from '@zenstackhq/common-helpers'; import { loadDocument } from '@zenstackhq/language'; import { PrismaSchemaGenerator } from '@zenstackhq/sdk'; import colors from 'colors'; @@ -13,6 +14,14 @@ export function getSchemaFile(file?: string) { return file; } + const pkgJsonConfig = getPkgJsonConfig(process.cwd()); + if (pkgJsonConfig.schema) { + if (!fs.existsSync(pkgJsonConfig.schema)) { + throw new CliError(`Schema file not found: ${pkgJsonConfig.schema}`); + } + return pkgJsonConfig.schema; + } + if (fs.existsSync('./zenstack/schema.zmodel')) { return './zenstack/schema.zmodel'; } else if (fs.existsSync('./schema.zmodel')) { @@ -51,3 +60,26 @@ export async function generateTempPrismaSchema(zmodelPath: string) { fs.writeFileSync(prismaSchemaFile, prismaSchema); return prismaSchemaFile; } + +export function getPkgJsonConfig(startPath: string) { + const result: { schema: string | undefined; output: string | undefined } = { schema: undefined, output: undefined }; + const pkgJsonFile = findUp(['package.json'], startPath, false); + + if (!pkgJsonFile) { + return result; + } + + let pkgJson: any = undefined; + try { + pkgJson = JSON.parse(fs.readFileSync(pkgJsonFile, 'utf8')); + } catch { + return result; + } + + if (pkgJson.zenstack && typeof pkgJson.zenstack === 'object') { + result.schema = pkgJson.zenstack.schema && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.schema); + result.output = pkgJson.zenstack.output && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.output); + } + + return result; +} diff --git a/packages/cli/src/actions/db.ts b/packages/cli/src/actions/db.ts index e588e8c2..e0839121 100644 --- a/packages/cli/src/actions/db.ts +++ b/packages/cli/src/actions/db.ts @@ -26,13 +26,16 @@ async function runPush(options: Options) { try { // run prisma db push - const cmd = `prisma db push --schema "${prismaSchemaFile}"${ - options.acceptDataLoss ? ' --accept-data-loss' : '' - }${options.forceReset ? ' --force-reset' : ''} --skip-generate`; + const cmd = [ + 'prisma db push', + ` --schema "${prismaSchemaFile}"`, + options.acceptDataLoss ? ' --accept-data-loss' : '', + options.forceReset ? ' --force-reset' : '', + ' --skip-generate', + ].join(''); + try { - await execPackage(cmd, { - stdio: 'inherit', - }); + await execPackage(cmd); } catch (err) { handleSubProcessError(err); } diff --git a/packages/cli/src/actions/generate.ts b/packages/cli/src/actions/generate.ts index 269f837a..3355d462 100644 --- a/packages/cli/src/actions/generate.ts +++ b/packages/cli/src/actions/generate.ts @@ -4,7 +4,7 @@ import { PrismaSchemaGenerator, TsSchemaGenerator, type CliGenerator } from '@ze import colors from 'colors'; import fs from 'node:fs'; import path from 'node:path'; -import { getSchemaFile, loadSchemaDocument } from './action-utils'; +import { getPkgJsonConfig, getSchemaFile, loadSchemaDocument } from './action-utils'; type Options = { schema?: string; @@ -20,7 +20,7 @@ export async function run(options: Options) { const schemaFile = getSchemaFile(options.schema); const model = await loadSchemaDocument(schemaFile); - const outputPath = options.output ?? path.dirname(schemaFile); + const outputPath = getOutputPath(options, schemaFile); // generate TS schema const tsSchemaFile = path.join(outputPath, 'schema.ts'); @@ -55,6 +55,18 @@ const client = new ZenStackClient(schema, { } } +function getOutputPath(options: Options, schemaFile: string) { + if (options.output) { + return options.output; + } + const pkgJsonConfig = getPkgJsonConfig(process.cwd()); + if (pkgJsonConfig.output) { + return pkgJsonConfig.output; + } else { + return path.dirname(schemaFile); + } +} + async function runPlugins(model: Model, outputPath: string, tsSchemaFile: string) { const plugins = model.declarations.filter(isPlugin); for (const plugin of plugins) { diff --git a/packages/cli/src/actions/migrate.ts b/packages/cli/src/actions/migrate.ts index d2bda8bb..bb13956d 100644 --- a/packages/cli/src/actions/migrate.ts +++ b/packages/cli/src/actions/migrate.ts @@ -53,12 +53,15 @@ export async function run(command: string, options: CommonOptions) { async function runDev(prismaSchemaFile: string, options: DevOptions) { try { - await execPackage( - `prisma migrate dev --schema "${prismaSchemaFile}" --skip-generate${options.name ? ` --name ${options.name}` : ''}${options.createOnly ? ' --create-only' : ''}`, - { - stdio: 'inherit', - }, - ); + const cmd = [ + 'prisma migrate dev', + ` --schema "${prismaSchemaFile}"`, + ' --skip-generate', + options.name ? ` --name ${options.name}` : '', + options.createOnly ? ' --create-only' : '', + ].join(''); + + await execPackage(cmd); } catch (err) { handleSubProcessError(err); } @@ -66,9 +69,11 @@ async function runDev(prismaSchemaFile: string, options: DevOptions) { async function runReset(prismaSchemaFile: string, options: ResetOptions) { try { - await execPackage(`prisma migrate reset --schema "${prismaSchemaFile}"${options.force ? ' --force' : ''}`, { - stdio: 'inherit', - }); + const cmd = ['prisma migrate reset', ` --schema "${prismaSchemaFile}"`, options.force ? ' --force' : ''].join( + '', + ); + + await execPackage(cmd); } catch (err) { handleSubProcessError(err); } @@ -76,9 +81,9 @@ async function runReset(prismaSchemaFile: string, options: ResetOptions) { async function runDeploy(prismaSchemaFile: string, _options: DeployOptions) { try { - await execPackage(`prisma migrate deploy --schema "${prismaSchemaFile}"`, { - stdio: 'inherit', - }); + const cmd = ['prisma migrate deploy', ` --schema "${prismaSchemaFile}"`].join(''); + + await execPackage(cmd); } catch (err) { handleSubProcessError(err); } @@ -86,9 +91,7 @@ async function runDeploy(prismaSchemaFile: string, _options: DeployOptions) { async function runStatus(prismaSchemaFile: string, _options: StatusOptions) { try { - await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`, { - stdio: 'inherit', - }); + await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`); } catch (err) { handleSubProcessError(err); } diff --git a/packages/cli/test/generate.test.ts b/packages/cli/test/generate.test.ts index 4372b869..ad9e0497 100644 --- a/packages/cli/test/generate.test.ts +++ b/packages/cli/test/generate.test.ts @@ -41,4 +41,19 @@ describe('CLI generate command test', () => { runCli('generate --save-prisma-schema "../prisma/schema.prisma"', workDir); expect(fs.existsSync(path.join(workDir, 'prisma/schema.prisma'))).toBe(true); }); + + it('should respect package.json config', () => { + const workDir = createProject(model); + fs.mkdirSync(path.join(workDir, 'foo')); + fs.renameSync(path.join(workDir, 'zenstack/schema.zmodel'), path.join(workDir, 'foo/schema.zmodel')); + fs.rmdirSync(path.join(workDir, 'zenstack')); + const pkgJson = JSON.parse(fs.readFileSync(path.join(workDir, 'package.json'), 'utf8')); + pkgJson.zenstack = { + schema: './foo/schema.zmodel', + output: './bar', + }; + fs.writeFileSync(path.join(workDir, 'package.json'), JSON.stringify(pkgJson, null, 2)); + runCli('generate', workDir); + expect(fs.existsSync(path.join(workDir, 'bar/schema.ts'))).toBe(true); + }); }); diff --git a/packages/common-helpers/package.json b/packages/common-helpers/package.json index c0511eb3..feec83e2 100644 --- a/packages/common-helpers/package.json +++ b/packages/common-helpers/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/common-helpers", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "ZenStack Common Helpers", "type": "module", "scripts": { diff --git a/packages/common-helpers/src/find-up.ts b/packages/common-helpers/src/find-up.ts new file mode 100644 index 00000000..afb2fed9 --- /dev/null +++ b/packages/common-helpers/src/find-up.ts @@ -0,0 +1,34 @@ +import fs from 'fs'; +import path from 'path'; + +/** + * A type named FindUp that takes a type parameter e which extends boolean. + */ +export type FindUpResult = Multiple extends true ? string[] | undefined : string | undefined; + +/** + * Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path. + * Optionally return a single path or multiple paths. + * If multiple allowed, return all paths found. + * If no paths are found, return undefined. + * + * @param names An array of strings representing names to search for within the directory + * @param cwd A string representing the current working directory + * @param multiple A boolean flag indicating whether to search for multiple levels. Useful for finding node_modules directories... + * @param An array of strings representing the accumulated results used in multiple results + * @returns Path(s) to a specific file or folder within the directory or parent directories + */ +export function findUp( + names: string[], + cwd: string = process.cwd(), + multiple: Multiple = false as Multiple, + result: string[] = [], +): FindUpResult { + if (!names.some((name) => !!name)) return undefined; + const target = names.find((name) => fs.existsSync(path.join(cwd, name))); + if (multiple === false && target) return path.join(cwd, target) as FindUpResult; + if (target) result.push(path.join(cwd, target)); + const up = path.resolve(cwd, '..'); + if (up === cwd) return (multiple && result.length > 0 ? result : undefined) as FindUpResult; // it'll fail anyway + return findUp(names, up, multiple, result); +} diff --git a/packages/common-helpers/src/index.ts b/packages/common-helpers/src/index.ts index 7f9c421b..3b0d2d3c 100644 --- a/packages/common-helpers/src/index.ts +++ b/packages/common-helpers/src/index.ts @@ -1,3 +1,4 @@ +export * from './find-up'; export * from './is-plain-object'; export * from './lower-case-first'; export * from './param-case'; diff --git a/packages/common-helpers/src/param-case.ts b/packages/common-helpers/src/param-case.ts index 3cb1f017..e08458bf 100644 --- a/packages/common-helpers/src/param-case.ts +++ b/packages/common-helpers/src/param-case.ts @@ -4,15 +4,19 @@ 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"); + .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--; + 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("-"); + return result + .slice(start, end) + .split('\0') + .map((str) => str.toLowerCase()) + .join('-'); } diff --git a/packages/create-zenstack/package.json b/packages/create-zenstack/package.json index 024c9450..b0206c89 100644 --- a/packages/create-zenstack/package.json +++ b/packages/create-zenstack/package.json @@ -1,6 +1,6 @@ { "name": "create-zenstack", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "Create a new ZenStack project", "type": "module", "scripts": { diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index 99326811..9d627ebd 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/eslint-config", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "type": "module", "private": true, "license": "MIT" diff --git a/packages/ide/vscode/package.json b/packages/ide/vscode/package.json index c354442f..d5eea4d4 100644 --- a/packages/ide/vscode/package.json +++ b/packages/ide/vscode/package.json @@ -1,7 +1,7 @@ { "name": "zenstack", "publisher": "zenstack", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "displayName": "ZenStack Language Tools", "description": "VSCode extension for ZenStack ZModel language", "private": true, diff --git a/packages/language/package.json b/packages/language/package.json index 6a7590de..d3845d85 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/language", "description": "ZenStack ZModel language specification", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "license": "MIT", "author": "ZenStack Team", "files": [ diff --git a/packages/language/src/utils.ts b/packages/language/src/utils.ts index c1e6ada2..224c89c3 100644 --- a/packages/language/src/utils.ts +++ b/packages/language/src/utils.ts @@ -331,9 +331,9 @@ export function getObjectLiteral(expr: Expression | ConfigExpr | undefined): return result as T; } -export function getLiteralArray< - T extends string | number | boolean | any = any, ->(expr: Expression | ConfigExpr | undefined): T[] | undefined { +export function getLiteralArray( + expr: Expression | ConfigExpr | undefined, +): T[] | undefined { const arr = getArray(expr); if (!arr) { return undefined; diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 5d02759c..825d0235 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/runtime", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "ZenStack Runtime", "type": "module", "scripts": { @@ -39,6 +39,16 @@ "default": "./dist/schema.cjs" } }, + "./helpers": { + "import": { + "types": "./dist/helpers.d.ts", + "default": "./dist/helpers.js" + }, + "require": { + "types": "./dist/helpers.d.cts", + "default": "./dist/helpers.cjs" + } + }, "./plugins/policy": { "import": { "types": "./dist/plugins/policy.d.ts", @@ -63,12 +73,12 @@ "nanoid": "^5.0.9", "ts-pattern": "catalog:", "ulid": "^3.0.0", - "uuid": "^11.0.5" + "uuid": "^11.0.5", + "zod": "catalog:" }, "peerDependencies": { "better-sqlite3": "^11.8.1", - "pg": "^8.13.1", - "zod": "catalog:" + "pg": "^8.13.1" }, "peerDependenciesMeta": { "better-sqlite3": { diff --git a/packages/runtime/src/client/client-impl.ts b/packages/runtime/src/client/client-impl.ts index 08f94a2f..6fa40a21 100644 --- a/packages/runtime/src/client/client-impl.ts +++ b/packages/runtime/src/client/client-impl.ts @@ -24,7 +24,7 @@ import { CountOperationHandler } from './crud/operations/count'; import { CreateOperationHandler } from './crud/operations/create'; import { DeleteOperationHandler } from './crud/operations/delete'; import { FindOperationHandler } from './crud/operations/find'; -import { GroupByeOperationHandler } from './crud/operations/group-by'; +import { GroupByOperationHandler } from './crud/operations/group-by'; import { UpdateOperationHandler } from './crud/operations/update'; import { InputValidator } from './crud/validator'; import { NotFoundError, QueryError } from './errors'; @@ -504,7 +504,7 @@ function createModelCrudHandler { - return createPromise('groupBy', args, new GroupByeOperationHandler(client, model, inputValidator)); + return createPromise('groupBy', args, new GroupByOperationHandler(client, model, inputValidator)); }, } as ModelOperations; } diff --git a/packages/runtime/src/client/contract.ts b/packages/runtime/src/client/contract.ts index ce58c5d0..531f3fa7 100644 --- a/packages/runtime/src/client/contract.ts +++ b/packages/runtime/src/client/contract.ts @@ -158,6 +158,14 @@ export type ClientContract = { [Key in GetModels as Uncapitalize]: ModelOperations; } & Procedures; +/** + * The contract for a client in a transaction. + */ +export type TransactionClientContract = Omit< + ClientContract, + TransactionUnsupportedMethods +>; + type _TypeMap = { String: string; Int: number; diff --git a/packages/runtime/src/client/crud/operations/aggregate.ts b/packages/runtime/src/client/crud/operations/aggregate.ts index 03b1ae6d..2bcd2014 100644 --- a/packages/runtime/src/client/crud/operations/aggregate.ts +++ b/packages/runtime/src/client/crud/operations/aggregate.ts @@ -7,10 +7,10 @@ import { BaseOperationHandler } from './base'; export class AggregateOperationHandler extends BaseOperationHandler { async handle(_operation: 'aggregate', args: unknown | undefined) { // normalize args to strip `undefined` fields - const normalizeArgs = this.normalizeArgs(args); + const normalizedArgs = this.normalizeArgs(args); // parse args - const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizeArgs); + const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs); let query = this.kysely.selectFrom((eb) => { // nested query for filtering and pagination diff --git a/packages/runtime/src/client/crud/operations/count.ts b/packages/runtime/src/client/crud/operations/count.ts index 9a8cc315..e44a5897 100644 --- a/packages/runtime/src/client/crud/operations/count.ts +++ b/packages/runtime/src/client/crud/operations/count.ts @@ -5,10 +5,10 @@ import { BaseOperationHandler } from './base'; export class CountOperationHandler extends BaseOperationHandler { async handle(_operation: 'count', args: unknown | undefined) { // normalize args to strip `undefined` fields - const normalizeArgs = this.normalizeArgs(args); + const normalizedArgs = this.normalizeArgs(args); // parse args - const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizeArgs); + const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs); let query = this.kysely.selectFrom((eb) => { // nested query for filtering and pagination diff --git a/packages/runtime/src/client/crud/operations/create.ts b/packages/runtime/src/client/crud/operations/create.ts index a908346b..bc15bb36 100644 --- a/packages/runtime/src/client/crud/operations/create.ts +++ b/packages/runtime/src/client/crud/operations/create.ts @@ -8,16 +8,16 @@ import { BaseOperationHandler } from './base'; export class CreateOperationHandler extends BaseOperationHandler { async handle(operation: 'create' | 'createMany' | 'createManyAndReturn', args: unknown | undefined) { // normalize args to strip `undefined` fields - const normalizeArgs = this.normalizeArgs(args); + const normalizedArgs = this.normalizeArgs(args); return match(operation) - .with('create', () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizeArgs))) + .with('create', () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))) .with('createMany', () => { - return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizeArgs)); + return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizedArgs)); }) .with('createManyAndReturn', () => { return this.runCreateManyAndReturn( - this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizeArgs), + this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizedArgs), ); }) .exhaustive(); diff --git a/packages/runtime/src/client/crud/operations/delete.ts b/packages/runtime/src/client/crud/operations/delete.ts index 7ee821c6..e20c48be 100644 --- a/packages/runtime/src/client/crud/operations/delete.ts +++ b/packages/runtime/src/client/crud/operations/delete.ts @@ -7,12 +7,12 @@ import { BaseOperationHandler } from './base'; export class DeleteOperationHandler extends BaseOperationHandler { async handle(operation: 'delete' | 'deleteMany', args: unknown | undefined) { // normalize args to strip `undefined` fields - const normalizeArgs = this.normalizeArgs(args); + const normalizedArgs = this.normalizeArgs(args); return match(operation) - .with('delete', () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizeArgs))) + .with('delete', () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))) .with('deleteMany', () => - this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizeArgs)), + this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs)), ) .exhaustive(); } diff --git a/packages/runtime/src/client/crud/operations/group-by.ts b/packages/runtime/src/client/crud/operations/group-by.ts index f1630c82..f309bf06 100644 --- a/packages/runtime/src/client/crud/operations/group-by.ts +++ b/packages/runtime/src/client/crud/operations/group-by.ts @@ -4,13 +4,13 @@ import type { SchemaDef } from '../../../schema'; import { getField } from '../../query-utils'; import { BaseOperationHandler } from './base'; -export class GroupByeOperationHandler extends BaseOperationHandler { +export class GroupByOperationHandler extends BaseOperationHandler { async handle(_operation: 'groupBy', args: unknown | undefined) { // normalize args to strip `undefined` fields - const normalizeArgs = this.normalizeArgs(args); + const normalizedArgs = this.normalizeArgs(args); // parse args - const parsedArgs = this.inputValidator.validateGroupByArgs(this.model, normalizeArgs); + const parsedArgs = this.inputValidator.validateGroupByArgs(this.model, normalizedArgs); let query = this.kysely.selectFrom((eb) => { // nested query for filtering and pagination diff --git a/packages/runtime/src/client/crud/operations/update.ts b/packages/runtime/src/client/crud/operations/update.ts index 577646ef..ab0c086f 100644 --- a/packages/runtime/src/client/crud/operations/update.ts +++ b/packages/runtime/src/client/crud/operations/update.ts @@ -8,19 +8,19 @@ import { BaseOperationHandler } from './base'; export class UpdateOperationHandler extends BaseOperationHandler { async handle(operation: 'update' | 'updateMany' | 'updateManyAndReturn' | 'upsert', args: unknown) { // normalize args to strip `undefined` fields - const normalizeArgs = this.normalizeArgs(args); + const normalizedArgs = this.normalizeArgs(args); return match(operation) - .with('update', () => this.runUpdate(this.inputValidator.validateUpdateArgs(this.model, normalizeArgs))) + .with('update', () => this.runUpdate(this.inputValidator.validateUpdateArgs(this.model, normalizedArgs))) .with('updateMany', () => - this.runUpdateMany(this.inputValidator.validateUpdateManyArgs(this.model, normalizeArgs)), + this.runUpdateMany(this.inputValidator.validateUpdateManyArgs(this.model, normalizedArgs)), ) .with('updateManyAndReturn', () => this.runUpdateManyAndReturn( - this.inputValidator.validateUpdateManyAndReturnArgs(this.model, normalizeArgs), + this.inputValidator.validateUpdateManyAndReturnArgs(this.model, normalizedArgs), ), ) - .with('upsert', () => this.runUpsert(this.inputValidator.validateUpsertArgs(this.model, normalizeArgs))) + .with('upsert', () => this.runUpsert(this.inputValidator.validateUpsertArgs(this.model, normalizedArgs))) .exhaustive(); } diff --git a/packages/runtime/src/client/crud/validator.ts b/packages/runtime/src/client/crud/validator.ts index d8eea71e..7d1aed7d 100644 --- a/packages/runtime/src/client/crud/validator.ts +++ b/packages/runtime/src/client/crud/validator.ts @@ -2,7 +2,7 @@ import { invariant } from '@zenstackhq/common-helpers'; import Decimal from 'decimal.js'; import stableStringify from 'json-stable-stringify'; import { match, P } from 'ts-pattern'; -import { z, ZodType } from 'zod/v4'; +import { z, ZodType } from 'zod'; import type { BuiltinType, EnumDef, FieldDef, GetModels, SchemaDef } from '../../schema'; import { NUMERIC_FIELD_TYPES } from '../constants'; import { diff --git a/packages/runtime/src/client/errors.ts b/packages/runtime/src/client/errors.ts index 0ec57b40..38c5077b 100644 --- a/packages/runtime/src/client/errors.ts +++ b/packages/runtime/src/client/errors.ts @@ -19,11 +19,7 @@ export class QueryError extends Error { /** * Error thrown when an internal error occurs. */ -export class InternalError extends Error { - constructor(message: string) { - super(message); - } -} +export class InternalError extends Error {} /** * Error thrown when an entity is not found. diff --git a/packages/runtime/src/helpers.ts b/packages/runtime/src/helpers.ts new file mode 100644 index 00000000..a58d0d1c --- /dev/null +++ b/packages/runtime/src/helpers.ts @@ -0,0 +1 @@ +export { sql } from 'kysely'; diff --git a/packages/runtime/tsup.config.ts b/packages/runtime/tsup.config.ts index 0f8a9d6f..9278c545 100644 --- a/packages/runtime/tsup.config.ts +++ b/packages/runtime/tsup.config.ts @@ -4,6 +4,7 @@ export default defineConfig({ entry: { index: 'src/index.ts', schema: 'src/schema/index.ts', + helpers: 'src/helpers.ts', 'plugins/policy': 'src/plugins/policy/index.ts', }, outDir: 'dist', diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 7d5d79dd..85c98311 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "ZenStack SDK", "type": "module", "scripts": { diff --git a/packages/tanstack-query/package.json b/packages/tanstack-query/package.json index 493ce35f..fc632591 100644 --- a/packages/tanstack-query/package.json +++ b/packages/tanstack-query/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/tanstack-query", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "", "main": "index.js", "type": "module", diff --git a/packages/testtools/package.json b/packages/testtools/package.json index 98f03ef0..9334d684 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "ZenStack Test Tools", "type": "module", "scripts": { diff --git a/packages/typescript-config/package.json b/packages/typescript-config/package.json index 232e65f0..b52c75f6 100644 --- a/packages/typescript-config/package.json +++ b/packages/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/typescript-config", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "private": true, "license": "MIT" } diff --git a/packages/zod/package.json b/packages/zod/package.json index cc737a13..adf86881 100644 --- a/packages/zod/package.json +++ b/packages/zod/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/zod", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "", "type": "module", "main": "index.js", diff --git a/packages/zod/src/index.ts b/packages/zod/src/index.ts index 4ca7ade0..a8180b18 100644 --- a/packages/zod/src/index.ts +++ b/packages/zod/src/index.ts @@ -1,6 +1,6 @@ import type { FieldDef, GetModels, SchemaDef } from '@zenstackhq/runtime/schema'; import { match, P } from 'ts-pattern'; -import { z, ZodType } from 'zod/v4'; +import { z, ZodType } from 'zod'; import type { SelectSchema } from './types'; export function makeSelectSchema>( diff --git a/packages/zod/src/types.ts b/packages/zod/src/types.ts index 389178e7..878aef87 100644 --- a/packages/zod/src/types.ts +++ b/packages/zod/src/types.ts @@ -1,5 +1,5 @@ import type { FieldType, GetModels, ScalarFields, SchemaDef } from '@zenstackhq/runtime/schema'; -import type { ZodBoolean, ZodNumber, ZodObject, ZodString, ZodUnknown } from 'zod/v4'; +import type { ZodBoolean, ZodNumber, ZodObject, ZodString, ZodUnknown } from 'zod'; export type SelectSchema> = ZodObject<{ [Key in ScalarFields]: MapScalarType; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a0be9341..36af9eb9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,8 +25,8 @@ catalogs: specifier: ^5.0.0 version: 5.8.3 zod: - specifier: ^3.25.67 - version: 3.25.67 + specifier: ^4.0.0 + version: 4.0.5 importers: @@ -127,15 +127,6 @@ importers: specifier: ^0.2.3 version: 0.2.3 - packages/cli/test: - devDependencies: - '@types/tmp': - specifier: ^0.2.6 - version: 0.2.6 - tmp: - specifier: ^0.2.3 - version: 0.2.3 - packages/common-helpers: devDependencies: '@zenstackhq/eslint-config': @@ -253,7 +244,7 @@ importers: version: 11.0.5 zod: specifier: 'catalog:' - version: 3.25.67 + version: 4.0.5 devDependencies: '@types/better-sqlite3': specifier: ^7.0.0 @@ -379,7 +370,7 @@ importers: version: 5.7.1 zod: specifier: 'catalog:' - version: 3.25.67 + version: 4.0.5 devDependencies: '@zenstackhq/eslint-config': specifier: workspace:* @@ -2518,8 +2509,8 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zod@3.25.67: - resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==} + zod@4.0.5: + resolution: {integrity: sha512-/5UuuRPStvHXu7RS+gmvRf4NXrNxpSllGwDnCBcJZtQsKrviYXm54yDGV2KYNLT5kq0lHGcl7lqWJLgSaG+tgA==} snapshots: @@ -4481,4 +4472,4 @@ snapshots: yocto-queue@0.1.0: {} - zod@3.25.67: {} + zod@4.0.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 50ebbc00..fcdfd392 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,7 +5,7 @@ packages: - tests/** catalog: kysely: ^0.27.6 - zod: ^3.25.67 + zod: ^4.0.0 prisma: ^6.0.0 langium: 3.5.0 langium-cli: 3.5.0 diff --git a/samples/blog/package.json b/samples/blog/package.json index fd486174..16476949 100644 --- a/samples/blog/package.json +++ b/samples/blog/package.json @@ -1,6 +1,6 @@ { "name": "sample-blog", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "description": "", "main": "index.js", "scripts": { diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 1b3268f2..ffb11c89 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "e2e", - "version": "3.0.0-alpha.9", + "version": "3.0.0-alpha.10", "private": true, "scripts": { "test": "vitest run"