diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index f9f1eb9a..ab0662d4 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -51,6 +51,11 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'pnpm' + - name: Use Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Get pnpm store directory id: pnpm-cache shell: bash diff --git a/.vscode/extensions.json b/.vscode/extensions.json index c8dffa94..551612d2 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,5 +3,5 @@ // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp // List of extensions which should be recommended for users of this workspace. - "recommendations": ["langium.langium-vscode", "kingwl.vscode-vitest-runner"] + "recommendations": ["langium.langium-vscode", "vitest.explorer"] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 0967ef42..6c4c331e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1 +1,3 @@ -{} +{ + "vitest.maximumConfigs": 20 +} diff --git a/package.json b/package.json index 45ad3252..8be97821 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { "name": "zenstack-v3", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack", "packageManager": "pnpm@10.23.0", + "type": "module", "scripts": { "build": "turbo run build", "watch": "turbo run watch build", "lint": "turbo run lint", - "test": "vitest run", + "test": "turbo run test", "format": "prettier --write \"**/*.{ts,tsx,md}\"", "pr": "gh pr create --fill-first --base dev", "merge-main": "gh pr create --title \"merge dev to main\" --body \"\" --base main --head dev", @@ -31,7 +32,7 @@ "turbo": "^2.5.4", "typescript": "catalog:", "typescript-eslint": "^8.34.1", - "vitest": "^3.2.4", + "vitest": "^4.0.14", "yaml": "^2.8.0" }, "pnpm": { diff --git a/packages/auth-adapters/better-auth/package.json b/packages/auth-adapters/better-auth/package.json index 91b1878e..115219a2 100644 --- a/packages/auth-adapters/better-auth/package.json +++ b/packages/auth-adapters/better-auth/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/better-auth", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack Better Auth Adapter. This adapter is modified from better-auth's Prisma adapter.", "type": "module", "scripts": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 533a91cc..3f6ce268 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-beta.26", + "version": "3.0.0-beta.27", "type": "module", "author": { "name": "ZenStack Team" diff --git a/packages/cli/src/utils/exec-utils.ts b/packages/cli/src/utils/exec-utils.ts index 0e4ad3ed..03629f62 100644 --- a/packages/cli/src/utils/exec-utils.ts +++ b/packages/cli/src/utils/exec-utils.ts @@ -43,11 +43,19 @@ export function execPrisma(args: string, options?: Omit // ignore and fallback } + const _options = { + ...options, + env: { + ...options?.env, + PRISMA_HIDE_UPDATE_MESSAGE: '1', + }, + }; + if (!prismaPath) { // fallback to npx/bunx execute - execPackage(`prisma ${args}`, options); + execPackage(`prisma ${args}`, _options); return; } - execSync(`node ${prismaPath} ${args}`, options); + execSync(`node ${prismaPath} ${args}`, _options); } diff --git a/packages/clients/tanstack-query/package.json b/packages/clients/tanstack-query/package.json index e00100f0..6e14662d 100644 --- a/packages/clients/tanstack-query/package.json +++ b/packages/clients/tanstack-query/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/tanstack-query", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "TanStack Query Client for consuming ZenStack v3's CRUD service", "main": "index.js", "type": "module", diff --git a/packages/common-helpers/package.json b/packages/common-helpers/package.json index 3020e8dc..1654b58d 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-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack Common Helpers", "type": "module", "scripts": { diff --git a/packages/config/eslint-config/package.json b/packages/config/eslint-config/package.json index f95ca2fd..6a6c3bf4 100644 --- a/packages/config/eslint-config/package.json +++ b/packages/config/eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/eslint-config", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "type": "module", "private": true, "license": "MIT" diff --git a/packages/config/typescript-config/package.json b/packages/config/typescript-config/package.json index 5e4aa3bd..3cc4bfe1 100644 --- a/packages/config/typescript-config/package.json +++ b/packages/config/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/typescript-config", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "private": true, "license": "MIT" } diff --git a/packages/config/vitest-config/package.json b/packages/config/vitest-config/package.json index 9e3f0c47..f3437726 100644 --- a/packages/config/vitest-config/package.json +++ b/packages/config/vitest-config/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/vitest-config", "type": "module", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "private": true, "license": "MIT", "exports": { diff --git a/packages/create-zenstack/package.json b/packages/create-zenstack/package.json index a17ebb75..216a99c3 100644 --- a/packages/create-zenstack/package.json +++ b/packages/create-zenstack/package.json @@ -1,6 +1,6 @@ { "name": "create-zenstack", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "Create a new ZenStack project", "type": "module", "scripts": { diff --git a/packages/ide/vscode/package.json b/packages/ide/vscode/package.json index c6d12348..bfaf079c 100644 --- a/packages/ide/vscode/package.json +++ b/packages/ide/vscode/package.json @@ -1,7 +1,7 @@ { "name": "zenstack-v3", "publisher": "zenstack", - "version": "3.0.13", + "version": "3.0.14", "displayName": "ZenStack V3 Language Tools", "description": "VSCode extension for ZenStack (v3) ZModel language", "private": true, diff --git a/packages/language/package.json b/packages/language/package.json index 57438636..e5a45c95 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-beta.26", + "version": "3.0.0-beta.27", "license": "MIT", "author": "ZenStack Team", "files": [ diff --git a/packages/language/src/validator.ts b/packages/language/src/validator.ts index efbc3794..dcbf549f 100644 --- a/packages/language/src/validator.ts +++ b/packages/language/src/validator.ts @@ -6,6 +6,7 @@ import type { Enum, Expression, FunctionDecl, + GeneratorDecl, InvocationExpr, Model, TypeDef, @@ -31,6 +32,7 @@ export function registerValidationChecks(services: ZModelServices) { const checks: ValidationChecks = { Model: validator.checkModel, DataSource: validator.checkDataSource, + GeneratorDecl: validator.checkGenerator, DataModel: validator.checkDataModel, TypeDef: validator.checkTypeDef, Enum: validator.checkEnum, @@ -56,6 +58,10 @@ export class ZModelValidator { new DataSourceValidator().validate(node, accept); } + checkGenerator(node: GeneratorDecl, accept: ValidationAcceptor): void { + accept('warning', '"generator" is not used by ZenStack and should be removed.', { node }); + } + checkDataModel(node: DataModel, accept: ValidationAcceptor): void { new DataModelValidator().validate(node, accept); } diff --git a/packages/language/test/attribute-application.test.ts b/packages/language/test/attribute-application.test.ts index 71d39323..ce17ce49 100644 --- a/packages/language/test/attribute-application.test.ts +++ b/packages/language/test/attribute-application.test.ts @@ -20,4 +20,29 @@ describe('Attribute application validation tests', () => { `"before()" is only allowed in "post-update" policy rules`, ); }); + + it('requires relation and fk to have consistent optionality', async () => { + await loadSchemaWithError( + ` + datasource db { + provider = 'sqlite' + url = 'file:./dev.db' + } + + model Foo { + id Int @id @default(autoincrement()) + bar Bar @relation(fields: [barId], references: [id]) + barId Int? + @@allow('all', true) + } + + model Bar { + id Int @id @default(autoincrement()) + foos Foo[] + @@allow('all', true) + } + `, + /relation "bar" is not optional/, + ); + }); }); diff --git a/packages/language/test/this-resolution.test.ts b/packages/language/test/this-resolution.test.ts new file mode 100644 index 00000000..a9caa5a3 --- /dev/null +++ b/packages/language/test/this-resolution.test.ts @@ -0,0 +1,71 @@ +import { describe, expect, it } from 'vitest'; +import { loadSchema, loadSchemaWithError } from './utils'; + +describe('This keyword resolution tests', () => { + it('always resolves to the containing model', async () => { + await loadSchemaWithError( + ` + datasource db { + provider = 'sqlite' + url = 'file:./dev.db' + } + + model A { + id Int @id @default(autoincrement()) + av Int + b B[] + + @@allow('read', b?[c?[cv == this.cv]]) + } + + model B { + id Int @id @default(autoincrement()) + bv Int + aId Int + a A @relation(fields: [aId], references: [id]) + c C[] + } + + model C { + id Int @id @default(autoincrement()) + cv Int + bId Int + b B @relation(fields: [bId], references: [id]) + } + `, + /MemberAccessTarget named 'cv'/, + ); + + await expect( + loadSchema(` + datasource db { + provider = 'sqlite' + url = 'file:./dev.db' + } + + model A { + id Int @id @default(autoincrement()) + av Int + b B[] + + @@allow('read', b?[c?[cv == this.av]]) + } + + model B { + id Int @id @default(autoincrement()) + bv Int + aId Int + a A @relation(fields: [aId], references: [id]) + c C[] + } + + model C { + id Int @id @default(autoincrement()) + cv Int + bId Int + b B @relation(fields: [bId], references: [id]) + } + `), + ).resolves.toBeTruthy(); + }); +}); diff --git a/packages/orm/package.json b/packages/orm/package.json index 40250acd..0312e8ab 100644 --- a/packages/orm/package.json +++ b/packages/orm/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/orm", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack ORM", "type": "module", "scripts": { diff --git a/packages/orm/src/client/crud/dialects/postgresql.ts b/packages/orm/src/client/crud/dialects/postgresql.ts index 660356dd..aa4cedd0 100644 --- a/packages/orm/src/client/crud/dialects/postgresql.ts +++ b/packages/orm/src/client/crud/dialects/postgresql.ts @@ -9,6 +9,7 @@ import { type SelectQueryBuilder, } from 'kysely'; import { match } from 'ts-pattern'; +import z from 'zod'; import type { BuiltinType, FieldDef, GetModels, SchemaDef } from '../../../schema'; import { DELEGATE_JOINED_FIELD_PREFIX } from '../../constants'; import type { FindArgs } from '../../crud-types'; @@ -26,6 +27,8 @@ import { import { BaseCrudDialect } from './base-dialect'; export class PostgresCrudDialect extends BaseCrudDialect { + private isoDateSchema = z.iso.datetime({ local: true, offset: true }); + constructor(schema: Schema, options: ClientOptions) { super(schema, options); } @@ -106,7 +109,16 @@ export class PostgresCrudDialect extends BaseCrudDiale private transformOutputDate(value: unknown) { if (typeof value === 'string') { - return new Date(value); + // PostgreSQL's jsonb_build_object serializes timestamp as ISO 8601 strings + // without timezone, (e.g., "2023-01-01T12:00:00.123456"). Since Date is always + // stored as UTC `timestamp` type, we add 'Z' to explicitly mark them as UTC for + // correct Date object creation. + if (this.isoDateSchema.safeParse(value).success) { + const hasOffset = value.endsWith('Z') || /[+-]\d{2}:\d{2}$/.test(value); + return new Date(hasOffset ? value : `${value}Z`); + } else { + return value; + } } else if (value instanceof Date && this.options.fixPostgresTimezone !== false) { // SPECIAL NOTES: // node-pg has a terrible quirk that it returns the date value in local timezone diff --git a/packages/plugins/policy/package.json b/packages/plugins/policy/package.json index 16d7952a..66348a85 100644 --- a/packages/plugins/policy/package.json +++ b/packages/plugins/policy/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/plugin-policy", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack Policy Plugin", "type": "module", "scripts": { diff --git a/packages/schema/package.json b/packages/schema/package.json index 10437710..dabb3d56 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/schema", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack Runtime Schema", "type": "module", "scripts": { diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 19f49a23..5ff02b7d 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack SDK", "type": "module", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index 8ba75d41..43558442 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack automatic CRUD API handlers and server adapters", "type": "module", "scripts": { diff --git a/packages/server/src/adapter/elysia/handler.ts b/packages/server/src/adapter/elysia/handler.ts index 330465d2..5104e50c 100644 --- a/packages/server/src/adapter/elysia/handler.ts +++ b/packages/server/src/adapter/elysia/handler.ts @@ -25,7 +25,7 @@ export interface ElysiaOptions extends CommonAdapterOp export function createElysiaHandler(options: ElysiaOptions) { return async (app: Elysia) => { app.all('/*', async (ctx: ElysiaContext) => { - const { request, body, set } = ctx; + const { query, body, set, request } = ctx; const client = await options.getClient(ctx); if (!client) { set.status = 500; @@ -35,7 +35,6 @@ export function createElysiaHandler(options: ElysiaOpt } const url = new URL(request.url); - const query = Object.fromEntries(url.searchParams); let path = url.pathname; if (options.basePath && path.startsWith(options.basePath)) { diff --git a/packages/server/src/adapter/nuxt/handler.ts b/packages/server/src/adapter/nuxt/handler.ts index c1c2efcd..9f17b0e5 100644 --- a/packages/server/src/adapter/nuxt/handler.ts +++ b/packages/server/src/adapter/nuxt/handler.ts @@ -1,7 +1,14 @@ import type { ClientContract } from '@zenstackhq/orm'; import type { SchemaDef } from '@zenstackhq/orm/schema'; -import { H3Event, defineEventHandler, getQuery, getRouterParams, readBody, type EventHandlerRequest } from 'h3'; -import { setResponseStatus } from 'nuxt/app'; +import { + defineEventHandler, + getQuery, + getRouterParams, + readBody, + setResponseStatus, + type H3Event, + type EventHandlerRequest, +} from 'h3'; import { logInternalError, type CommonAdapterOptions } from '../common'; /** diff --git a/packages/testtools/package.json b/packages/testtools/package.json index bbae0430..453852c1 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "ZenStack Test Tools", "type": "module", "scripts": { diff --git a/packages/testtools/src/client.ts b/packages/testtools/src/client.ts index c756f126..1defaeaf 100644 --- a/packages/testtools/src/client.ts +++ b/packages/testtools/src/client.ts @@ -25,13 +25,15 @@ export function getTestDbProvider() { return val as 'sqlite' | 'postgresql'; } -const TEST_PG_CONFIG = { +export const TEST_PG_CONFIG = { host: process.env['TEST_PG_HOST'] ?? 'localhost', port: process.env['TEST_PG_PORT'] ? parseInt(process.env['TEST_PG_PORT']) : 5432, user: process.env['TEST_PG_USER'] ?? 'postgres', password: process.env['TEST_PG_PASSWORD'] ?? 'postgres', }; +export const TEST_PG_URL = `postgres://${TEST_PG_CONFIG.user}:${TEST_PG_CONFIG.password}@${TEST_PG_CONFIG.host}:${TEST_PG_CONFIG.port}`; + type ExtraTestClientOptions = { /** * Database provider @@ -104,10 +106,7 @@ export async function createTestClient( let _schema: SchemaDef; const provider = options?.provider ?? getTestDbProvider() ?? 'sqlite'; const dbName = options?.dbName ?? getTestDbName(provider); - const dbUrl = - provider === 'sqlite' - ? `file:${dbName}` - : `postgres://${TEST_PG_CONFIG.user}:${TEST_PG_CONFIG.password}@${TEST_PG_CONFIG.host}:${TEST_PG_CONFIG.port}/${dbName}`; + const dbUrl = provider === 'sqlite' ? `file:${dbName}` : `${TEST_PG_URL}/${dbName}`; let model: Model | undefined; diff --git a/packages/zod/package.json b/packages/zod/package.json index 0466d07d..03b734a0 100644 --- a/packages/zod/package.json +++ b/packages/zod/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/zod", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "", "type": "module", "main": "index.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e1199a7..b780f2f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -114,8 +114,8 @@ importers: specifier: ^8.34.1 version: 8.34.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3) vitest: - specifier: ^3.2.4 - version: 3.2.4(@types/node@20.19.24)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.1.0)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0) + specifier: ^4.0.14 + version: 4.0.14(@edge-runtime/vm@5.0.0)(@types/node@20.19.24)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.1.0)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0) yaml: specifier: ^2.8.0 version: 2.8.0 @@ -846,9 +846,6 @@ importers: specifier: ^11.0.5 version: 11.0.5 devDependencies: - '@types/uuid': - specifier: ^11.0.0 - version: 11.0.0 '@zenstackhq/typescript-config': specifier: workspace:* version: link:../../packages/config/typescript-config @@ -865,6 +862,9 @@ importers: specifier: 'catalog:' version: 10.6.0 devDependencies: + '@types/node': + specifier: 'catalog:' + version: 20.19.24 '@zenstackhq/cli': specifier: workspace:* version: link:../../packages/cli @@ -884,6 +884,77 @@ importers: specifier: workspace:* version: link:../../packages/config/vitest-config + tests/runtimes/bun: + dependencies: + '@zenstackhq/cli': + specifier: workspace:* + version: link:../../../packages/cli + '@zenstackhq/common-helpers': + specifier: workspace:* + version: link:../../../packages/common-helpers + '@zenstackhq/orm': + specifier: workspace:* + version: link:../../../packages/orm + '@zenstackhq/plugin-policy': + specifier: workspace:* + version: link:../../../packages/plugins/policy + '@zenstackhq/testtools': + specifier: workspace:* + version: link:../../../packages/testtools + kysely: + specifier: 'catalog:' + version: 0.28.8 + kysely-bun-sqlite: + specifier: ^0.4.0 + version: 0.4.0(kysely@0.28.8) + pg: + specifier: 'catalog:' + version: 8.16.3 + devDependencies: + '@types/pg': + specifier: ^8.15.6 + version: 8.15.6 + '@zenstackhq/typescript-config': + specifier: workspace:* + version: link:../../../packages/config/typescript-config + bun-types: + specifier: ^1.3.3 + version: 1.3.3 + + tests/runtimes/edge-runtime: + dependencies: + '@edge-runtime/vm': + specifier: ^5.0.0 + version: 5.0.0 + '@zenstackhq/cli': + specifier: workspace:* + version: link:../../../packages/cli + '@zenstackhq/common-helpers': + specifier: workspace:* + version: link:../../../packages/common-helpers + '@zenstackhq/orm': + specifier: workspace:* + version: link:../../../packages/orm + '@zenstackhq/plugin-policy': + specifier: workspace:* + version: link:../../../packages/plugins/policy + '@zenstackhq/testtools': + specifier: workspace:* + version: link:../../../packages/testtools + pg: + specifier: 'catalog:' + version: 8.16.3 + devDependencies: + '@types/pg': + specifier: ^8.15.6 + version: 8.15.6 + '@zenstackhq/typescript-config': + specifier: workspace:* + version: link:../../../packages/config/typescript-config + '@zenstackhq/vitest-config': + specifier: workspace:* + version: link:../../../packages/config/vitest-config + packages: '@acemir/cssom@0.9.23': @@ -1102,6 +1173,14 @@ packages: '@dxup/unimport@0.1.0': resolution: {integrity: sha512-6Q/Po8qGmlrShdG/R9+rpIhme9N/PGJumpvmwr1UAxGpt9DfOCt9kF8+yJkxhtPdJFL37KgUILZBRAkSU8cJZg==} + '@edge-runtime/primitives@6.0.0': + resolution: {integrity: sha512-FqoxaBT+prPBHBwE1WXS1ocnu/VLTQyZ6NMUBAdbP7N2hsFTTxMC/jMu2D/8GAlMQfxeuppcPuCUk/HO3fpIvA==} + engines: {node: '>=18'} + + '@edge-runtime/vm@5.0.0': + resolution: {integrity: sha512-NKBGBSIKUG584qrS1tyxVpX/AKJKQw5HgjYEnPLC0QsTw79JrGn+qUr8CXFb955Iy7GUdiiUv1rJ6JBGvaKb6w==} + engines: {node: '>=18'} + '@emnapi/core@1.6.0': resolution: {integrity: sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==} @@ -2916,6 +2995,9 @@ packages: '@types/pg@8.11.11': resolution: {integrity: sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==} + '@types/pg@8.15.6': + resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} + '@types/pluralize@0.0.33': resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} @@ -2963,10 +3045,6 @@ packages: '@types/toposort@2.0.7': resolution: {integrity: sha512-sQNk65vbC36+UixCkcky+dCr7MlflHcVILg1FVGqlUntsLFv9xd9ToWIVko/gTuin+cVe16t+2YubEFkhnSuPQ==} - '@types/uuid@11.0.0': - resolution: {integrity: sha512-HVyk8nj2m+jcFRNazzqyVKiZezyhDKrGUA3jlEcg/nZ6Ms+qHwocba1Y/AaVaznJTAM9xpdFSh+ptbNrhOGvZA==} - deprecated: This is a stub types definition. uuid provides its own type definitions, so you do not need this installed. - '@types/vscode@1.101.0': resolution: {integrity: sha512-ZWf0IWa+NGegdW3iU42AcDTFHWW7fApLdkdnBqwYEtHVIBGbTu0ZNQKP/kX3Ds/uMJXIMQNAojHR4vexCEEz5Q==} @@ -3210,34 +3288,34 @@ packages: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vue: ^3.2.25 - '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/expect@4.0.14': + resolution: {integrity: sha512-RHk63V3zvRiYOWAV0rGEBRO820ce17hz7cI2kDmEdfQsBjT2luEKB5tCOc91u1oSQoUOZkSv3ZyzkdkSLD7lKw==} - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + '@vitest/mocker@4.0.14': + resolution: {integrity: sha512-RzS5NujlCzeRPF1MK7MXLiEFpkIXeMdQ+rN3Kk3tDI9j0mtbr7Nmuq67tpkOJQpgyClbOltCXMjLZicJHsH5Cg==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + vite: ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/pretty-format@4.0.14': + resolution: {integrity: sha512-SOYPgujB6TITcJxgd3wmsLl+wZv+fy3av2PpiPpsWPZ6J1ySUYfScfpIt2Yv56ShJXR2MOA6q2KjKHN4EpdyRQ==} - '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@vitest/runner@4.0.14': + resolution: {integrity: sha512-BsAIk3FAqxICqREbX8SetIteT8PiaUL/tgJjmhxJhCsigmzzH8xeadtp7LRnTpCVzvf0ib9BgAfKJHuhNllKLw==} - '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@vitest/snapshot@4.0.14': + resolution: {integrity: sha512-aQVBfT1PMzDSA16Y3Fp45a0q8nKexx6N5Amw3MX55BeTeZpoC08fGqEZqVmPcqN0ueZsuUQ9rriPMhZ3Mu19Ag==} - '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/spy@4.0.14': + resolution: {integrity: sha512-JmAZT1UtZooO0tpY3GRyiC/8W7dCs05UOq9rfsUUgEZEdq+DuHLmWhPsrTt0TiW7WYeL/hXpaE07AZ2RCk44hg==} - '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vitest/utils@4.0.14': + resolution: {integrity: sha512-hLqXZKAWNg8pI+SQXyXxWCTOpA3MvsqcbVeNgSi8x/CSN2wi26dSzn1wrOhmCmFjEvN9p8/kLFRHa6PI8jHazw==} '@volar/language-core@2.4.23': resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} @@ -3464,10 +3542,6 @@ packages: resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} engines: {node: '>=12.0.0'} - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - ast-kit@2.1.3: resolution: {integrity: sha512-TH+b3Lv6pUjy/Nu0m6A2JULtdzLpmqF9x1Dhj00ZoEiML8qvVA9j1flkzTKNYgdEhWrjDwtWNpyyCUbfQe514g==} engines: {node: '>=20.19.0'} @@ -3630,6 +3704,9 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bun-types@1.3.3: + resolution: {integrity: sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ==} + bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} @@ -3686,9 +3763,9 @@ packages: caniuse-lite@1.0.30001751: resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} - chai@5.2.0: - resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} - engines: {node: '>=12'} + chai@6.2.1: + resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} + engines: {node: '>=18'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -3698,10 +3775,6 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} - chevrotain-allstar@0.3.1: resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} peerDependencies: @@ -4019,10 +4092,6 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -4430,8 +4499,8 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - expect-type@1.2.1: - resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + expect-type@1.2.2: + resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} express@5.1.0: @@ -5172,6 +5241,12 @@ packages: knitwork@1.2.0: resolution: {integrity: sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==} + kysely-bun-sqlite@0.4.0: + resolution: {integrity: sha512-2EkQE5sT4ewiw7IWfJsAkpxJ/QPVKXKO5sRYI/xjjJIJlECuOdtG+ssYM0twZJySrdrmuildNPFYVreyu1EdZg==} + engines: {bun: '>=1.1.31'} + peerDependencies: + kysely: ^0.28.2 + kysely@0.28.8: resolution: {integrity: sha512-QUOgl5ZrS9IRuhq5FvOKFSsD/3+IA6MLE81/bOOTRA/YQpKDza2sFdN5g6JCB9BOpqMJDGefLCQ9F12hRS13TA==} engines: {node: '>=20.0.0'} @@ -5342,9 +5417,6 @@ packages: engines: {node: '>= 8.x', npm: '>= 5.x'} hasBin: true - loupe@3.1.4: - resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} - lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -5705,6 +5777,9 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + ofetch@1.5.0: resolution: {integrity: sha512-A7llJ7eZyziA5xq9//3ZurA8OhFqtS99K5/V1sLBJ5j137CM/OAjlbA/TEJXBuOWwOfLqih+oH5U3ran4za1FQ==} @@ -5852,10 +5927,6 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - pathval@2.0.0: - resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} - engines: {node: '>= 14.16'} - perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} @@ -6663,9 +6734,6 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -6741,9 +6809,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@3.0.0: - resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} @@ -6881,16 +6946,8 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} - - tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} - - tinyspy@4.0.3: - resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} tldts-core@7.0.17: @@ -7333,46 +7390,6 @@ packages: vite: ^6.0.0 || ^7.0.0 vue: ^3.5.0 - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - vite@7.1.12: resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} engines: {node: ^20.19.0 || >=22.12.0} @@ -7421,26 +7438,32 @@ packages: vite: optional: true - vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vitest@4.0.14: + resolution: {integrity: sha512-d9B2J9Cm9dN9+6nxMnnNJKJCtcyKfnHj15N6YNJfaFHRLua/d3sRKU9RuKmO9mB0XdFtUizlxfz/VPbd3OxGhw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.4 - '@vitest/ui': 3.2.4 + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.14 + '@vitest/browser-preview': 4.0.14 + '@vitest/browser-webdriverio': 4.0.14 + '@vitest/ui': 4.0.14 happy-dom: '*' jsdom: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true - '@types/debug': + '@opentelemetry/api': optional: true '@types/node': optional: true - '@vitest/browser': + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': optional: true '@vitest/ui': optional: true @@ -7965,6 +7988,12 @@ snapshots: '@dxup/unimport@0.1.0': {} + '@edge-runtime/primitives@6.0.0': {} + + '@edge-runtime/vm@5.0.0': + dependencies: + '@edge-runtime/primitives': 6.0.0 + '@emnapi/core@1.6.0': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -9157,10 +9186,10 @@ snapshots: '@rollup/pluginutils': 5.3.0(rollup@4.52.5) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.4.6(picomatch@4.0.2) + fdir: 6.5.0(picomatch@4.0.3) is-reference: 1.2.1 magic-string: 0.30.21 - picomatch: 4.0.2 + picomatch: 4.0.3 optionalDependencies: rollup: 4.52.5 @@ -9207,7 +9236,7 @@ snapshots: dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.2 + picomatch: 4.0.3 optionalDependencies: rollup: 4.52.5 @@ -9615,7 +9644,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 20.17.24 + '@types/node': 20.19.24 '@types/cookie@0.6.0': {} @@ -9629,7 +9658,7 @@ snapshots: '@types/express-serve-static-core@5.1.0': dependencies: - '@types/node': 20.17.24 + '@types/node': 20.19.24 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.0 @@ -9668,6 +9697,12 @@ snapshots: pg-protocol: 1.10.3 pg-types: 4.0.2 + '@types/pg@8.15.6': + dependencies: + '@types/node': 20.19.24 + pg-protocol: 1.10.3 + pg-types: 2.2.0 + '@types/pluralize@0.0.33': {} '@types/qs@6.14.0': {} @@ -9689,16 +9724,16 @@ snapshots: '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.17.24 + '@types/node': 20.19.24 '@types/send@1.2.0': dependencies: - '@types/node': 20.17.24 + '@types/node': 20.19.24 '@types/serve-static@1.15.9': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 20.17.24 + '@types/node': 20.19.24 '@types/send': 0.17.5 '@types/sql.js@1.4.9': @@ -9710,7 +9745,7 @@ snapshots: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 20.17.24 + '@types/node': 20.19.24 form-data: 4.0.4 '@types/supertest@6.0.3': @@ -9722,10 +9757,6 @@ snapshots: '@types/toposort@2.0.7': {} - '@types/uuid@11.0.0': - dependencies: - uuid: 11.0.5 - '@types/vscode@1.101.0': {} '@types/whatwg-mimetype@3.0.2': {} @@ -9992,7 +10023,7 @@ snapshots: glob: 10.4.5 graceful-fs: 4.2.11 node-gyp-build: 4.8.4 - picomatch: 4.0.2 + picomatch: 4.0.3 resolve-from: 5.0.0 transitivePeerDependencies: - encoding @@ -10017,47 +10048,44 @@ snapshots: vite: 7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) - '@vitest/expect@3.2.4': + '@vitest/expect@4.0.14': dependencies: + '@standard-schema/spec': 1.0.0 '@types/chai': 5.2.2 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.2.0 - tinyrainbow: 2.0.0 + '@vitest/spy': 4.0.14 + '@vitest/utils': 4.0.14 + chai: 6.2.1 + tinyrainbow: 3.0.3 - '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0))': + '@vitest/mocker@4.0.14(vite@7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - '@vitest/spy': 3.2.4 + '@vitest/spy': 4.0.14 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.21 optionalDependencies: - vite: 6.3.5(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0) - '@vitest/pretty-format@3.2.4': + '@vitest/pretty-format@4.0.14': dependencies: - tinyrainbow: 2.0.0 + tinyrainbow: 3.0.3 - '@vitest/runner@3.2.4': + '@vitest/runner@4.0.14': dependencies: - '@vitest/utils': 3.2.4 + '@vitest/utils': 4.0.14 pathe: 2.0.3 - strip-literal: 3.0.0 - '@vitest/snapshot@3.2.4': + '@vitest/snapshot@4.0.14': dependencies: - '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.17 + '@vitest/pretty-format': 4.0.14 + magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@3.2.4': - dependencies: - tinyspy: 4.0.3 + '@vitest/spy@4.0.14': {} - '@vitest/utils@3.2.4': + '@vitest/utils@4.0.14': dependencies: - '@vitest/pretty-format': 3.2.4 - loupe: 3.1.4 - tinyrainbow: 2.0.0 + '@vitest/pretty-format': 4.0.14 + tinyrainbow: 3.0.3 '@volar/language-core@2.4.23': dependencies: @@ -10376,8 +10404,6 @@ snapshots: pvutils: 1.1.5 tslib: 2.8.1 - assertion-error@2.0.1: {} - ast-kit@2.1.3: dependencies: '@babel/parser': 7.28.5 @@ -10535,6 +10561,10 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bun-types@1.3.3: + dependencies: + '@types/node': 20.19.24 + bundle-name@4.1.0: dependencies: run-applescript: 7.1.0 @@ -10627,13 +10657,7 @@ snapshots: caniuse-lite@1.0.30001751: {} - chai@5.2.0: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.1.4 - pathval: 2.0.0 + chai@6.2.1: {} chalk@4.1.2: dependencies: @@ -10642,8 +10666,6 @@ snapshots: chalk@5.3.0: {} - check-error@2.1.1: {} - chevrotain-allstar@0.3.1(chevrotain@11.0.3): dependencies: chevrotain: 11.0.3 @@ -10929,8 +10951,6 @@ snapshots: dependencies: mimic-response: 3.1.0 - deep-eql@5.0.2: {} - deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -11509,7 +11529,7 @@ snapshots: expand-template@2.0.3: {} - expect-type@1.2.1: {} + expect-type@1.2.2: {} express@5.1.0: dependencies: @@ -12326,6 +12346,11 @@ snapshots: knitwork@1.2.0: {} + kysely-bun-sqlite@0.4.0(kysely@0.28.8): + dependencies: + bun-types: 1.3.3 + kysely: 0.28.8 + kysely@0.28.8: {} langium-cli@3.5.0: @@ -12494,8 +12519,6 @@ snapshots: dependencies: commander: 9.5.0 - loupe@3.1.4: {} - lru-cache@10.4.3: {} lru-cache@11.1.0: {} @@ -13016,6 +13039,8 @@ snapshots: obuf@1.1.2: {} + obug@2.1.1: {} + ofetch@1.5.0: dependencies: destr: 2.0.5 @@ -13211,8 +13236,6 @@ snapshots: pathe@2.0.3: {} - pathval@2.0.0: {} - perfect-debounce@1.0.0: {} perfect-debounce@2.0.0: {} @@ -13746,7 +13769,7 @@ snapshots: rollup-plugin-visualizer@6.0.5(rollup@4.52.5): dependencies: open: 8.4.2 - picomatch: 4.0.2 + picomatch: 4.0.3 source-map: 0.7.6 yargs: 17.7.2 optionalDependencies: @@ -14076,8 +14099,6 @@ snapshots: std-env@3.10.0: {} - std-env@3.9.0: {} - stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -14182,10 +14203,6 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@3.0.0: - dependencies: - js-tokens: 9.0.1 - strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 @@ -14365,11 +14382,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - tinypool@1.1.1: {} - - tinyrainbow@2.0.0: {} - - tinyspy@4.0.3: {} + tinyrainbow@3.0.3: {} tldts-core@7.0.17: optional: true @@ -14776,34 +14789,13 @@ snapshots: dependencies: vite: 7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1) - vite-node@3.2.4(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0): - dependencies: - cac: 6.7.14 - debug: 4.4.1 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 6.3.5(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - vite-node@3.2.4(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1) + vite: 7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -14861,14 +14853,14 @@ snapshots: vite: 7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1) vue: 3.5.22(typescript@5.9.3) - vite@6.3.5(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0): + vite@7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0): dependencies: - esbuild: 0.25.5 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 + esbuild: 0.25.11 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.44.0 - tinyglobby: 0.2.14 + rollup: 4.52.5 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 20.19.24 fsevents: 2.3.3 @@ -14878,30 +14870,13 @@ snapshots: tsx: 4.20.3 yaml: 2.8.0 - vite@6.3.5(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1): - dependencies: - esbuild: 0.25.5 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 - postcss: 8.5.6 - rollup: 4.44.0 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 20.19.24 - fsevents: 2.3.3 - jiti: 2.6.1 - lightningcss: 1.30.2 - terser: 5.44.0 - tsx: 4.20.3 - yaml: 2.8.1 - vite@7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1): dependencies: esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.44.0 + rollup: 4.52.5 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 20.19.24 @@ -14916,32 +14891,30 @@ snapshots: optionalDependencies: vite: 7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.1) - vitest@3.2.4(@types/node@20.19.24)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.1.0)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0): + vitest@4.0.14(@edge-runtime/vm@5.0.0)(@types/node@20.19.24)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@27.1.0)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0): dependencies: - '@types/chai': 5.2.2 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.2.0 - debug: 4.4.1 - expect-type: 1.2.1 - magic-string: 0.30.17 + '@vitest/expect': 4.0.14 + '@vitest/mocker': 4.0.14(vite@7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0)) + '@vitest/pretty-format': 4.0.14 + '@vitest/runner': 4.0.14 + '@vitest/snapshot': 4.0.14 + '@vitest/spy': 4.0.14 + '@vitest/utils': 4.0.14 + es-module-lexer: 1.7.0 + expect-type: 1.2.2 + magic-string: 0.30.21 + obug: 2.1.1 pathe: 2.0.3 - picomatch: 4.0.2 - std-env: 3.9.0 + picomatch: 4.0.3 + std-env: 3.10.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0) - vite-node: 3.2.4(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0) + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.1.12(@types/node@20.19.24)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.3)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: + '@edge-runtime/vm': 5.0.0 '@types/node': 20.19.24 happy-dom: 20.0.10 jsdom: 27.1.0 @@ -14954,7 +14927,6 @@ snapshots: - sass-embedded - stylus - sugarss - - supports-color - terser - tsx - yaml diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e5cc8997..b165d0c3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,28 +2,29 @@ packages: - packages/** - samples/** - tests/** + catalog: + '@tanstack/react-query': 5.90.6 + '@types/better-sqlite3': ^7.6.13 + '@types/node': ^20.19.0 + '@types/react': 19.2.0 + '@types/react-dom': 19.2.0 + '@types/tmp': ^0.2.6 + better-sqlite3: ^12.2.0 + decimal.js: ^10.4.3 kysely: ~0.28.8 - zod: ^4.0.0 - prisma: ^6.19.0 langium: 3.5.0 langium-cli: 3.5.0 - ts-pattern: ^5.7.1 - typescript: ^5.9.3 - '@types/node': ^20.19.0 - tmp: ^0.2.3 - '@types/tmp': ^0.2.6 - 'zod-validation-error': ^4.0.1 - 'better-sqlite3': ^12.2.0 - '@types/better-sqlite3': ^7.6.13 - 'pg': ^8.13.1 - 'sql.js': ^1.13.0 - 'decimal.js': '^10.4.3' + next: 16.0.1 + pg: ^8.13.1 + prisma: ^6.19.0 react: 19.2.0 - '@types/react': 19.2.0 react-dom: 19.2.0 - '@types/react-dom': 19.2.0 - '@tanstack/react-query': 5.90.6 - 'next': 16.0.1 - 'vue': 3.5.22 - 'svelte': 5.43.3 + sql.js: ^1.13.0 + svelte: 5.43.3 + tmp: ^0.2.3 + ts-pattern: ^5.7.1 + typescript: ^5.9.3 + vue: 3.5.22 + zod: ^4.0.0 + zod-validation-error: ^4.0.1 diff --git a/samples/next.js/package.json b/samples/next.js/package.json index 67db4521..a1f7b379 100644 --- a/samples/next.js/package.json +++ b/samples/next.js/package.json @@ -1,6 +1,6 @@ { "name": "next.js", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "private": true, "scripts": { "generate": "zen generate --lite", diff --git a/samples/orm/package.json b/samples/orm/package.json index 8a4663f4..11a29f8a 100644 --- a/samples/orm/package.json +++ b/samples/orm/package.json @@ -1,6 +1,6 @@ { "name": "sample-blog", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "description": "", "main": "index.js", "private": true, diff --git a/scripts/bump-version.ts b/scripts/bump-version.ts index 53057d4a..5fdda3fd 100644 --- a/scripts/bump-version.ts +++ b/scripts/bump-version.ts @@ -2,9 +2,12 @@ import * as fs from 'node:fs'; import { glob } from 'glob'; import * as path from 'node:path'; import * as yaml from 'yaml'; +import { fileURLToPath } from 'node:url'; const excludes = ['packages/ide/vscode/package.json']; +const _dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url)); + function getWorkspacePackageJsonFiles(workspaceFile: string): string[] { const workspaceYaml = fs.readFileSync(workspaceFile, 'utf8'); const workspace = yaml.parse(workspaceYaml) as { packages?: string[] }; @@ -23,7 +26,7 @@ function getWorkspacePackageJsonFiles(workspaceFile: string): string[] { } // include root package.json - files.add(path.resolve(__dirname, '../package.json')); + files.add(path.resolve(_dirname, '../package.json')); const result = Array.from(files).filter((f) => !excludes.some((e) => f.endsWith(e))); return result; @@ -39,11 +42,11 @@ function incrementVersion(version: string): string { } // find all package.json files in the workspace -const workspaceFile = path.resolve(__dirname, '../pnpm-workspace.yaml'); +const workspaceFile = path.resolve(_dirname, '../pnpm-workspace.yaml'); const packageFiles = getWorkspacePackageJsonFiles(workspaceFile); // get version from root package.json -const rootPackageJson = path.resolve(__dirname, '../package.json'); +const rootPackageJson = path.resolve(_dirname, '../package.json'); const rootPkg = JSON.parse(fs.readFileSync(rootPackageJson, 'utf8')) as { version?: string }; if (!rootPkg.version) throw new Error('No "version" key found in package.json'); const rootVersion = rootPkg.version; diff --git a/tests/e2e/package.json b/tests/e2e/package.json index f023e507..2160f3f7 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "e2e", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "private": true, "type": "module", "scripts": { @@ -27,7 +27,6 @@ "uuid": "^11.0.5" }, "devDependencies": { - "@types/uuid": "^11.0.0", "@zenstackhq/cli": "workspace:*", "@zenstackhq/typescript-config": "workspace:*", "@zenstackhq/vitest-config": "workspace:*" diff --git a/tests/regression/package.json b/tests/regression/package.json index af00968a..b1de3381 100644 --- a/tests/regression/package.json +++ b/tests/regression/package.json @@ -1,6 +1,6 @@ { "name": "regression", - "version": "3.0.0-beta.26", + "version": "3.0.0-beta.27", "private": true, "type": "module", "scripts": { @@ -17,6 +17,7 @@ "@zenstackhq/orm": "workspace:*", "@zenstackhq/sdk": "workspace:*", "@zenstackhq/typescript-config": "workspace:*", - "@zenstackhq/vitest-config": "workspace:*" + "@zenstackhq/vitest-config": "workspace:*", + "@types/node": "catalog:" } } diff --git a/tests/regression/test/issue-204/input.ts b/tests/regression/test/issue-204/input.ts index d39dc0e5..9564b7f2 100644 --- a/tests/regression/test/issue-204/input.ts +++ b/tests/regression/test/issue-204/input.ts @@ -6,7 +6,7 @@ /* eslint-disable */ import { type SchemaType as $Schema } from "./schema"; -import type { FindManyArgs as $FindManyArgs, FindUniqueArgs as $FindUniqueArgs, FindFirstArgs as $FindFirstArgs, CreateArgs as $CreateArgs, CreateManyArgs as $CreateManyArgs, CreateManyAndReturnArgs as $CreateManyAndReturnArgs, UpdateArgs as $UpdateArgs, UpdateManyArgs as $UpdateManyArgs, UpdateManyAndReturnArgs as $UpdateManyAndReturnArgs, UpsertArgs as $UpsertArgs, DeleteArgs as $DeleteArgs, DeleteManyArgs as $DeleteManyArgs, CountArgs as $CountArgs, AggregateArgs as $AggregateArgs, GroupByArgs as $GroupByArgs, WhereInput as $WhereInput, SelectInput as $SelectInput, IncludeInput as $IncludeInput, OmitInput as $OmitInput } from "@zenstackhq/orm"; +import type { FindManyArgs as $FindManyArgs, FindUniqueArgs as $FindUniqueArgs, FindFirstArgs as $FindFirstArgs, CreateArgs as $CreateArgs, CreateManyArgs as $CreateManyArgs, CreateManyAndReturnArgs as $CreateManyAndReturnArgs, UpdateArgs as $UpdateArgs, UpdateManyArgs as $UpdateManyArgs, UpdateManyAndReturnArgs as $UpdateManyAndReturnArgs, UpsertArgs as $UpsertArgs, DeleteArgs as $DeleteArgs, DeleteManyArgs as $DeleteManyArgs, CountArgs as $CountArgs, AggregateArgs as $AggregateArgs, GroupByArgs as $GroupByArgs, WhereInput as $WhereInput, SelectInput as $SelectInput, IncludeInput as $IncludeInput, OmitInput as $OmitInput, ClientOptions as $ClientOptions } from "@zenstackhq/orm"; import type { SimplifiedModelResult as $SimplifiedModelResult, SelectIncludeOmit as $SelectIncludeOmit } from "@zenstackhq/orm"; export type FooFindManyArgs = $FindManyArgs<$Schema, "Foo">; export type FooFindUniqueArgs = $FindUniqueArgs<$Schema, "Foo">; @@ -27,4 +27,4 @@ export type FooWhereInput = $WhereInput<$Schema, "Foo">; export type FooSelect = $SelectInput<$Schema, "Foo">; export type FooInclude = $IncludeInput<$Schema, "Foo">; export type FooOmit = $OmitInput<$Schema, "Foo">; -export type FooGetPayload> = $SimplifiedModelResult<$Schema, "Foo", Args>; +export type FooGetPayload, Options extends $ClientOptions<$Schema> = $ClientOptions<$Schema>> = $SimplifiedModelResult<$Schema, "Foo", Options, Args>; diff --git a/tests/regression/test/issue-422/input.ts b/tests/regression/test/issue-422/input.ts index 73b7ed9a..a931f068 100644 --- a/tests/regression/test/issue-422/input.ts +++ b/tests/regression/test/issue-422/input.ts @@ -6,7 +6,7 @@ /* eslint-disable */ import { type SchemaType as $Schema } from "./schema"; -import type { FindManyArgs as $FindManyArgs, FindUniqueArgs as $FindUniqueArgs, FindFirstArgs as $FindFirstArgs, CreateArgs as $CreateArgs, CreateManyArgs as $CreateManyArgs, CreateManyAndReturnArgs as $CreateManyAndReturnArgs, UpdateArgs as $UpdateArgs, UpdateManyArgs as $UpdateManyArgs, UpdateManyAndReturnArgs as $UpdateManyAndReturnArgs, UpsertArgs as $UpsertArgs, DeleteArgs as $DeleteArgs, DeleteManyArgs as $DeleteManyArgs, CountArgs as $CountArgs, AggregateArgs as $AggregateArgs, GroupByArgs as $GroupByArgs, WhereInput as $WhereInput, SelectInput as $SelectInput, IncludeInput as $IncludeInput, OmitInput as $OmitInput } from "@zenstackhq/orm"; +import type { FindManyArgs as $FindManyArgs, FindUniqueArgs as $FindUniqueArgs, FindFirstArgs as $FindFirstArgs, CreateArgs as $CreateArgs, CreateManyArgs as $CreateManyArgs, CreateManyAndReturnArgs as $CreateManyAndReturnArgs, UpdateArgs as $UpdateArgs, UpdateManyArgs as $UpdateManyArgs, UpdateManyAndReturnArgs as $UpdateManyAndReturnArgs, UpsertArgs as $UpsertArgs, DeleteArgs as $DeleteArgs, DeleteManyArgs as $DeleteManyArgs, CountArgs as $CountArgs, AggregateArgs as $AggregateArgs, GroupByArgs as $GroupByArgs, WhereInput as $WhereInput, SelectInput as $SelectInput, IncludeInput as $IncludeInput, OmitInput as $OmitInput, ClientOptions as $ClientOptions } from "@zenstackhq/orm"; import type { SimplifiedModelResult as $SimplifiedModelResult, SelectIncludeOmit as $SelectIncludeOmit } from "@zenstackhq/orm"; export type SessionFindManyArgs = $FindManyArgs<$Schema, "Session">; export type SessionFindUniqueArgs = $FindUniqueArgs<$Schema, "Session">; @@ -27,7 +27,7 @@ export type SessionWhereInput = $WhereInput<$Schema, "Session">; export type SessionSelect = $SelectInput<$Schema, "Session">; export type SessionInclude = $IncludeInput<$Schema, "Session">; export type SessionOmit = $OmitInput<$Schema, "Session">; -export type SessionGetPayload> = $SimplifiedModelResult<$Schema, "Session", Args>; +export type SessionGetPayload, Options extends $ClientOptions<$Schema> = $ClientOptions<$Schema>> = $SimplifiedModelResult<$Schema, "Session", Options, Args>; export type UserFindManyArgs = $FindManyArgs<$Schema, "User">; export type UserFindUniqueArgs = $FindUniqueArgs<$Schema, "User">; export type UserFindFirstArgs = $FindFirstArgs<$Schema, "User">; @@ -47,7 +47,7 @@ export type UserWhereInput = $WhereInput<$Schema, "User">; export type UserSelect = $SelectInput<$Schema, "User">; export type UserInclude = $IncludeInput<$Schema, "User">; export type UserOmit = $OmitInput<$Schema, "User">; -export type UserGetPayload> = $SimplifiedModelResult<$Schema, "User", Args>; +export type UserGetPayload, Options extends $ClientOptions<$Schema> = $ClientOptions<$Schema>> = $SimplifiedModelResult<$Schema, "User", Options, Args>; export type ProfileFindManyArgs = $FindManyArgs<$Schema, "Profile">; export type ProfileFindUniqueArgs = $FindUniqueArgs<$Schema, "Profile">; export type ProfileFindFirstArgs = $FindFirstArgs<$Schema, "Profile">; @@ -67,4 +67,4 @@ export type ProfileWhereInput = $WhereInput<$Schema, "Profile">; export type ProfileSelect = $SelectInput<$Schema, "Profile">; export type ProfileInclude = $IncludeInput<$Schema, "Profile">; export type ProfileOmit = $OmitInput<$Schema, "Profile">; -export type ProfileGetPayload> = $SimplifiedModelResult<$Schema, "Profile", Args>; +export type ProfileGetPayload, Options extends $ClientOptions<$Schema> = $ClientOptions<$Schema>> = $SimplifiedModelResult<$Schema, "Profile", Options, Args>; diff --git a/tests/regression/tsconfig.json b/tests/regression/tsconfig.json index e0b83aa8..1dd80744 100644 --- a/tests/regression/tsconfig.json +++ b/tests/regression/tsconfig.json @@ -2,7 +2,7 @@ "extends": "@zenstackhq/typescript-config/base.json", "compilerOptions": { "noEmit": true, - "types": ["@zenstackhq/testtools/types"] + "types": ["@zenstackhq/testtools/types", "node"] }, "include": ["src/**/*.ts", "test/**/*.ts"] } diff --git a/tests/runtimes/bun/bun-e2e.test.ts b/tests/runtimes/bun/bun-e2e.test.ts new file mode 100644 index 00000000..901daadd --- /dev/null +++ b/tests/runtimes/bun/bun-e2e.test.ts @@ -0,0 +1,117 @@ +import { clone } from '@zenstackhq/common-helpers'; +import { ZenStackClient } from '@zenstackhq/orm'; +import { PostgresDialect } from '@zenstackhq/orm/dialects/postgres'; +import { PolicyPlugin } from '@zenstackhq/plugin-policy'; +import { TEST_PG_URL } from '@zenstackhq/testtools'; +import { Database } from 'bun:sqlite'; +import { afterEach, describe, expect, it } from 'bun:test'; +import type { Dialect } from 'kysely'; +import { BunSqliteDialect } from 'kysely-bun-sqlite'; +import { Client, Pool } from 'pg'; +import { schema } from './schemas/schema'; + +describe('Bun e2e tests', () => { + const provider = (process.env['TEST_DB_PROVIDER'] ?? 'sqlite') as 'sqlite' | 'postgresql'; + + let _db: any; + + afterEach(async () => { + await _db?.$disconnect(); + }); + + it('works with simple CRUD', async () => { + const db = (_db = await createClient(provider, 'bun-e2e-crud')); + + const user = await db.user.create({ + data: { + id: '1', + email: 'u1@example.com', + name: 'Test User', + }, + }); + expect(user).toMatchObject({ + id: '1', + email: 'u1@example.com', + name: 'Test User', + }); + + let found = await db.user.findUnique({ + where: { id: '1' }, + }); + expect(found).toMatchObject(user); + + await db.user.update({ where: { id: '1' }, data: { name: 'Updated Name' } }); + found = await db.user.findFirst(); + expect(found).toMatchObject({ name: 'Updated Name' }); + + await db.user.delete({ where: { id: '1' } }); + const count = await db.user.count(); + expect(count).toBe(0); + }); + + it('enforces policies', async () => { + const db = (_db = await createClient(provider, 'bun-e2e-policies')); + const authDb = db.$use(new PolicyPlugin()); + + // create a user + await db.user.create({ + data: { + id: '1', + email: 'u1@example.com', + name: 'Test User', + posts: { + create: [ + { + id: 'p1', + title: 'First Post', + published: true, + }, + { + id: 'p2', + title: 'Second Post', + published: false, + }, + ], + }, + }, + }); + + const anonCount = await authDb.post.count(); + expect(anonCount).toBe(0); + + const user1DbCount = await authDb.$setAuth({ id: '1' }).post.count(); + expect(user1DbCount).toBe(2); + + const user2DbCount = await authDb.$setAuth({ id: '2' }).post.count(); + expect(user2DbCount).toBe(1); + }); +}); + +async function createClient(provider: 'sqlite' | 'postgresql', dbName: string) { + const _schema = clone(schema); + let dialect: Dialect; + if (provider === 'sqlite') { + (_schema as any).provider.type = 'sqlite'; + dialect = new BunSqliteDialect({ + database: new Database(':memory:'), + }); + } else { + (_schema as any).provider.type = 'postgresql'; + const pgClient = new Client({ + connectionString: TEST_PG_URL, + }); + await pgClient.connect(); + await pgClient.query(`DROP DATABASE IF EXISTS "${dbName}"`); + await pgClient.query(`CREATE DATABASE "${dbName}"`); + await pgClient.end(); + dialect = new PostgresDialect({ + pool: new Pool({ + connectionString: `${TEST_PG_URL}/${dbName}`, + }), + }); + } + + const db = new ZenStackClient(_schema, { dialect }); + await db.$pushSchema(); + return db; +} diff --git a/tests/runtimes/bun/package.json b/tests/runtimes/bun/package.json new file mode 100644 index 00000000..a5a29b3d --- /dev/null +++ b/tests/runtimes/bun/package.json @@ -0,0 +1,27 @@ +{ + "name": "bun-e2e", + "version": "3.0.0-beta.27", + "private": true, + "type": "module", + "scripts": { + "build": "pnpm test:generate && pnpm test:typecheck", + "test:generate": "tsx scripts/generate.ts", + "test:typecheck": "tsc --noEmit", + "test": "bun test" + }, + "dependencies": { + "@zenstackhq/cli": "workspace:*", + "@zenstackhq/orm": "workspace:*", + "@zenstackhq/plugin-policy": "workspace:*", + "@zenstackhq/common-helpers": "workspace:*", + "@zenstackhq/testtools": "workspace:*", + "kysely-bun-sqlite": "^0.4.0", + "pg": "catalog:", + "kysely": "catalog:" + }, + "devDependencies": { + "@types/pg": "^8.15.6", + "@zenstackhq/typescript-config": "workspace:*", + "bun-types": "^1.3.3" + } +} diff --git a/tests/runtimes/bun/schemas/input.ts b/tests/runtimes/bun/schemas/input.ts new file mode 100644 index 00000000..fb776314 --- /dev/null +++ b/tests/runtimes/bun/schemas/input.ts @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +/* eslint-disable */ + +import { type SchemaType as $Schema } from "./schema"; +import type { FindManyArgs as $FindManyArgs, FindUniqueArgs as $FindUniqueArgs, FindFirstArgs as $FindFirstArgs, CreateArgs as $CreateArgs, CreateManyArgs as $CreateManyArgs, CreateManyAndReturnArgs as $CreateManyAndReturnArgs, UpdateArgs as $UpdateArgs, UpdateManyArgs as $UpdateManyArgs, UpdateManyAndReturnArgs as $UpdateManyAndReturnArgs, UpsertArgs as $UpsertArgs, DeleteArgs as $DeleteArgs, DeleteManyArgs as $DeleteManyArgs, CountArgs as $CountArgs, AggregateArgs as $AggregateArgs, GroupByArgs as $GroupByArgs, WhereInput as $WhereInput, SelectInput as $SelectInput, IncludeInput as $IncludeInput, OmitInput as $OmitInput, ClientOptions as $ClientOptions } from "@zenstackhq/orm"; +import type { SimplifiedModelResult as $SimplifiedModelResult, SelectIncludeOmit as $SelectIncludeOmit } from "@zenstackhq/orm"; +export type UserFindManyArgs = $FindManyArgs<$Schema, "User">; +export type UserFindUniqueArgs = $FindUniqueArgs<$Schema, "User">; +export type UserFindFirstArgs = $FindFirstArgs<$Schema, "User">; +export type UserCreateArgs = $CreateArgs<$Schema, "User">; +export type UserCreateManyArgs = $CreateManyArgs<$Schema, "User">; +export type UserCreateManyAndReturnArgs = $CreateManyAndReturnArgs<$Schema, "User">; +export type UserUpdateArgs = $UpdateArgs<$Schema, "User">; +export type UserUpdateManyArgs = $UpdateManyArgs<$Schema, "User">; +export type UserUpdateManyAndReturnArgs = $UpdateManyAndReturnArgs<$Schema, "User">; +export type UserUpsertArgs = $UpsertArgs<$Schema, "User">; +export type UserDeleteArgs = $DeleteArgs<$Schema, "User">; +export type UserDeleteManyArgs = $DeleteManyArgs<$Schema, "User">; +export type UserCountArgs = $CountArgs<$Schema, "User">; +export type UserAggregateArgs = $AggregateArgs<$Schema, "User">; +export type UserGroupByArgs = $GroupByArgs<$Schema, "User">; +export type UserWhereInput = $WhereInput<$Schema, "User">; +export type UserSelect = $SelectInput<$Schema, "User">; +export type UserInclude = $IncludeInput<$Schema, "User">; +export type UserOmit = $OmitInput<$Schema, "User">; +export type UserGetPayload, Options extends $ClientOptions<$Schema> = $ClientOptions<$Schema>> = $SimplifiedModelResult<$Schema, "User", Options, Args>; +export type PostFindManyArgs = $FindManyArgs<$Schema, "Post">; +export type PostFindUniqueArgs = $FindUniqueArgs<$Schema, "Post">; +export type PostFindFirstArgs = $FindFirstArgs<$Schema, "Post">; +export type PostCreateArgs = $CreateArgs<$Schema, "Post">; +export type PostCreateManyArgs = $CreateManyArgs<$Schema, "Post">; +export type PostCreateManyAndReturnArgs = $CreateManyAndReturnArgs<$Schema, "Post">; +export type PostUpdateArgs = $UpdateArgs<$Schema, "Post">; +export type PostUpdateManyArgs = $UpdateManyArgs<$Schema, "Post">; +export type PostUpdateManyAndReturnArgs = $UpdateManyAndReturnArgs<$Schema, "Post">; +export type PostUpsertArgs = $UpsertArgs<$Schema, "Post">; +export type PostDeleteArgs = $DeleteArgs<$Schema, "Post">; +export type PostDeleteManyArgs = $DeleteManyArgs<$Schema, "Post">; +export type PostCountArgs = $CountArgs<$Schema, "Post">; +export type PostAggregateArgs = $AggregateArgs<$Schema, "Post">; +export type PostGroupByArgs = $GroupByArgs<$Schema, "Post">; +export type PostWhereInput = $WhereInput<$Schema, "Post">; +export type PostSelect = $SelectInput<$Schema, "Post">; +export type PostInclude = $IncludeInput<$Schema, "Post">; +export type PostOmit = $OmitInput<$Schema, "Post">; +export type PostGetPayload, Options extends $ClientOptions<$Schema> = $ClientOptions<$Schema>> = $SimplifiedModelResult<$Schema, "Post", Options, Args>; diff --git a/tests/runtimes/bun/schemas/models.ts b/tests/runtimes/bun/schemas/models.ts new file mode 100644 index 00000000..72654e58 --- /dev/null +++ b/tests/runtimes/bun/schemas/models.ts @@ -0,0 +1,11 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +/* eslint-disable */ + +import { type SchemaType as $Schema } from "./schema"; +import { type ModelResult as $ModelResult } from "@zenstackhq/orm"; +export type User = $ModelResult<$Schema, "User">; +export type Post = $ModelResult<$Schema, "Post">; diff --git a/tests/runtimes/bun/schemas/schema.ts b/tests/runtimes/bun/schemas/schema.ts new file mode 100644 index 00000000..b7d3bfcd --- /dev/null +++ b/tests/runtimes/bun/schemas/schema.ts @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +/* eslint-disable */ + +import { type SchemaDef, ExpressionUtils } from "@zenstackhq/orm/schema"; +const _schema = { + provider: { + type: "sqlite" + }, + models: { + User: { + name: "User", + fields: { + id: { + name: "id", + type: "String", + id: true, + attributes: [{ name: "@id" }, { name: "@default", args: [{ name: "value", value: ExpressionUtils.call("cuid") }] }], + default: ExpressionUtils.call("cuid") + }, + email: { + name: "email", + type: "String", + unique: true, + attributes: [{ name: "@unique" }] + }, + name: { + name: "name", + type: "String", + optional: true + }, + posts: { + name: "posts", + type: "Post", + array: true, + relation: { opposite: "author" } + } + }, + attributes: [ + { name: "@@allow", args: [{ name: "operation", value: ExpressionUtils.literal("all") }, { name: "condition", value: ExpressionUtils.binary(ExpressionUtils.member(ExpressionUtils.call("auth"), ["id"]), "==", ExpressionUtils.field("id")) }] }, + { name: "@@allow", args: [{ name: "operation", value: ExpressionUtils.literal("read") }, { name: "condition", value: ExpressionUtils.binary(ExpressionUtils.call("auth"), "!=", ExpressionUtils._null()) }] } + ], + idFields: ["id"], + uniqueFields: { + id: { type: "String" }, + email: { type: "String" } + } + }, + Post: { + name: "Post", + fields: { + id: { + name: "id", + type: "String", + id: true, + attributes: [{ name: "@id" }, { name: "@default", args: [{ name: "value", value: ExpressionUtils.call("cuid") }] }], + default: ExpressionUtils.call("cuid") + }, + title: { + name: "title", + type: "String" + }, + published: { + name: "published", + type: "Boolean", + attributes: [{ name: "@default", args: [{ name: "value", value: ExpressionUtils.literal(false) }] }], + default: false + }, + author: { + name: "author", + type: "User", + attributes: [{ name: "@relation", args: [{ name: "fields", value: ExpressionUtils.array([ExpressionUtils.field("authorId")]) }, { name: "references", value: ExpressionUtils.array([ExpressionUtils.field("id")]) }, { name: "onUpdate", value: ExpressionUtils.literal("Cascade") }, { name: "onDelete", value: ExpressionUtils.literal("Cascade") }] }], + relation: { opposite: "posts", fields: ["authorId"], references: ["id"], onUpdate: "Cascade", onDelete: "Cascade" } + }, + authorId: { + name: "authorId", + type: "String", + foreignKeyFor: [ + "author" + ] + } + }, + attributes: [ + { name: "@@deny", args: [{ name: "operation", value: ExpressionUtils.literal("all") }, { name: "condition", value: ExpressionUtils.binary(ExpressionUtils.call("auth"), "==", ExpressionUtils._null()) }] }, + { name: "@@allow", args: [{ name: "operation", value: ExpressionUtils.literal("all") }, { name: "condition", value: ExpressionUtils.binary(ExpressionUtils.member(ExpressionUtils.call("auth"), ["id"]), "==", ExpressionUtils.field("authorId")) }] }, + { name: "@@allow", args: [{ name: "operation", value: ExpressionUtils.literal("read") }, { name: "condition", value: ExpressionUtils.field("published") }] } + ], + idFields: ["id"], + uniqueFields: { + id: { type: "String" } + } + } + }, + authType: "User", + plugins: {} +} as const satisfies SchemaDef; +type Schema = typeof _schema & { + __brand?: "schema"; +}; +export const schema: Schema = _schema; +export type SchemaType = Schema; diff --git a/tests/runtimes/bun/schemas/schema.zmodel b/tests/runtimes/bun/schemas/schema.zmodel new file mode 100644 index 00000000..ee491c08 --- /dev/null +++ b/tests/runtimes/bun/schemas/schema.zmodel @@ -0,0 +1,31 @@ +datasource db { + provider = "sqlite" +} + +plugin policy { + provider = "../../../packages/plugins/policy" +} + +model User { + id String @id @default(cuid()) + email String @unique + name String? + posts Post[] + + // Access policies + @@allow('all', auth().id == id) + @@allow('read', auth() != null) +} + +model Post { + id String @id @default(cuid()) + title String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id], onUpdate: Cascade, onDelete: Cascade) + authorId String + + // Access policies + @@deny('all', auth() == null) + @@allow('all', auth().id == authorId) + @@allow('read', published) +} diff --git a/tests/runtimes/bun/scripts/generate.ts b/tests/runtimes/bun/scripts/generate.ts new file mode 100644 index 00000000..09a2ac23 --- /dev/null +++ b/tests/runtimes/bun/scripts/generate.ts @@ -0,0 +1,20 @@ +import { glob } from 'glob'; +import { execSync } from 'node:child_process'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const dir = path.dirname(fileURLToPath(import.meta.url)); + +async function main() { + const zmodelFiles = [...glob.sync(path.resolve(dir, '../schemas/*.zmodel'))]; + for (const file of zmodelFiles) { + console.log(`Generating TS schema for: ${file}`); + await generate(file); + } +} + +async function generate(schemaPath: string) { + execSync('bunx --bun zen generate', { cwd: path.dirname(schemaPath) }); +} + +main(); diff --git a/tests/runtimes/bun/tsconfig.json b/tests/runtimes/bun/tsconfig.json new file mode 100644 index 00000000..37dbe4e2 --- /dev/null +++ b/tests/runtimes/bun/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@zenstackhq/typescript-config/base.json", + "compilerOptions": { + "noEmit": true, + "noImplicitAny": false, + "types": ["bun-types"] + } +} diff --git a/tests/runtimes/edge-runtime/.DS_Store b/tests/runtimes/edge-runtime/.DS_Store new file mode 100644 index 00000000..d6f7ebb2 Binary files /dev/null and b/tests/runtimes/edge-runtime/.DS_Store differ diff --git a/tests/runtimes/edge-runtime/edge-runtime-e2e.test.ts b/tests/runtimes/edge-runtime/edge-runtime-e2e.test.ts new file mode 100644 index 00000000..ca3b57e2 --- /dev/null +++ b/tests/runtimes/edge-runtime/edge-runtime-e2e.test.ts @@ -0,0 +1,101 @@ +import { ZenStackClient } from '@zenstackhq/orm'; +import { PostgresDialect } from '@zenstackhq/orm/dialects/postgres'; +import { PolicyPlugin } from '@zenstackhq/plugin-policy'; +import { TEST_PG_URL } from '@zenstackhq/testtools'; +import { Client, Pool } from 'pg'; +import { afterEach, describe, expect, it } from 'vitest'; +import { schema } from './schemas/schema'; + +describe('Edge-runtime e2e tests', () => { + let _db: any; + + afterEach(async () => { + await _db?.$disconnect(); + }); + + it('works with simple CRUD', async () => { + const db = (_db = await createClient('edge-runtime-e2e-crud')); + + const user = await db.user.create({ + data: { + id: '1', + email: 'u1@example.com', + name: 'Test User', + }, + }); + expect(user).toMatchObject({ + id: '1', + email: 'u1@example.com', + name: 'Test User', + }); + + let found = await db.user.findUnique({ + where: { id: '1' }, + }); + expect(found).toMatchObject(user); + + await db.user.update({ where: { id: '1' }, data: { name: 'Updated Name' } }); + found = await db.user.findFirst(); + expect(found).toMatchObject({ name: 'Updated Name' }); + + await db.user.delete({ where: { id: '1' } }); + const count = await db.user.count(); + expect(count).toBe(0); + }); + + it('enforces policies', async () => { + const db = (_db = await createClient('edge-runtime-e2e-policies')); + const authDb = db.$use(new PolicyPlugin()); + + // create a user + await db.user.create({ + data: { + id: '1', + email: 'u1@example.com', + name: 'Test User', + posts: { + create: [ + { + id: 'p1', + title: 'First Post', + published: true, + }, + { + id: 'p2', + title: 'Second Post', + published: false, + }, + ], + }, + }, + }); + + const anonCount = await authDb.post.count(); + expect(anonCount).toBe(0); + + const user1DbCount = await authDb.$setAuth({ id: '1' }).post.count(); + expect(user1DbCount).toBe(2); + + const user2DbCount = await authDb.$setAuth({ id: '2' }).post.count(); + expect(user2DbCount).toBe(1); + }); +}); + +async function createClient(dbName: string) { + const pgClient = new Client({ + connectionString: TEST_PG_URL, + }); + await pgClient.connect(); + await pgClient.query(`DROP DATABASE IF EXISTS "${dbName}"`); + await pgClient.query(`CREATE DATABASE "${dbName}"`); + await pgClient.end(); + const dialect = new PostgresDialect({ + pool: new Pool({ + connectionString: `${TEST_PG_URL}/${dbName}`, + }), + }); + + const db = new ZenStackClient(schema, { dialect }); + await db.$pushSchema(); + return db; +} diff --git a/tests/runtimes/edge-runtime/package.json b/tests/runtimes/edge-runtime/package.json new file mode 100644 index 00000000..324a21ca --- /dev/null +++ b/tests/runtimes/edge-runtime/package.json @@ -0,0 +1,26 @@ +{ + "name": "edge-runtime-e2e", + "version": "3.0.0-beta.27", + "private": true, + "type": "module", + "scripts": { + "build": "pnpm test:generate && pnpm test:typecheck", + "test:generate": "tsx scripts/generate.ts", + "test:typecheck": "tsc --noEmit", + "test": "vitest run" + }, + "dependencies": { + "@edge-runtime/vm": "^5.0.0", + "@zenstackhq/cli": "workspace:*", + "@zenstackhq/common-helpers": "workspace:*", + "@zenstackhq/orm": "workspace:*", + "@zenstackhq/plugin-policy": "workspace:*", + "@zenstackhq/testtools": "workspace:*", + "pg": "catalog:" + }, + "devDependencies": { + "@types/pg": "^8.15.6", + "@zenstackhq/typescript-config": "workspace:*", + "@zenstackhq/vitest-config": "workspace:*" + } +} diff --git a/tests/runtimes/edge-runtime/schemas/input.ts b/tests/runtimes/edge-runtime/schemas/input.ts new file mode 100644 index 00000000..fb776314 --- /dev/null +++ b/tests/runtimes/edge-runtime/schemas/input.ts @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +/* eslint-disable */ + +import { type SchemaType as $Schema } from "./schema"; +import type { FindManyArgs as $FindManyArgs, FindUniqueArgs as $FindUniqueArgs, FindFirstArgs as $FindFirstArgs, CreateArgs as $CreateArgs, CreateManyArgs as $CreateManyArgs, CreateManyAndReturnArgs as $CreateManyAndReturnArgs, UpdateArgs as $UpdateArgs, UpdateManyArgs as $UpdateManyArgs, UpdateManyAndReturnArgs as $UpdateManyAndReturnArgs, UpsertArgs as $UpsertArgs, DeleteArgs as $DeleteArgs, DeleteManyArgs as $DeleteManyArgs, CountArgs as $CountArgs, AggregateArgs as $AggregateArgs, GroupByArgs as $GroupByArgs, WhereInput as $WhereInput, SelectInput as $SelectInput, IncludeInput as $IncludeInput, OmitInput as $OmitInput, ClientOptions as $ClientOptions } from "@zenstackhq/orm"; +import type { SimplifiedModelResult as $SimplifiedModelResult, SelectIncludeOmit as $SelectIncludeOmit } from "@zenstackhq/orm"; +export type UserFindManyArgs = $FindManyArgs<$Schema, "User">; +export type UserFindUniqueArgs = $FindUniqueArgs<$Schema, "User">; +export type UserFindFirstArgs = $FindFirstArgs<$Schema, "User">; +export type UserCreateArgs = $CreateArgs<$Schema, "User">; +export type UserCreateManyArgs = $CreateManyArgs<$Schema, "User">; +export type UserCreateManyAndReturnArgs = $CreateManyAndReturnArgs<$Schema, "User">; +export type UserUpdateArgs = $UpdateArgs<$Schema, "User">; +export type UserUpdateManyArgs = $UpdateManyArgs<$Schema, "User">; +export type UserUpdateManyAndReturnArgs = $UpdateManyAndReturnArgs<$Schema, "User">; +export type UserUpsertArgs = $UpsertArgs<$Schema, "User">; +export type UserDeleteArgs = $DeleteArgs<$Schema, "User">; +export type UserDeleteManyArgs = $DeleteManyArgs<$Schema, "User">; +export type UserCountArgs = $CountArgs<$Schema, "User">; +export type UserAggregateArgs = $AggregateArgs<$Schema, "User">; +export type UserGroupByArgs = $GroupByArgs<$Schema, "User">; +export type UserWhereInput = $WhereInput<$Schema, "User">; +export type UserSelect = $SelectInput<$Schema, "User">; +export type UserInclude = $IncludeInput<$Schema, "User">; +export type UserOmit = $OmitInput<$Schema, "User">; +export type UserGetPayload, Options extends $ClientOptions<$Schema> = $ClientOptions<$Schema>> = $SimplifiedModelResult<$Schema, "User", Options, Args>; +export type PostFindManyArgs = $FindManyArgs<$Schema, "Post">; +export type PostFindUniqueArgs = $FindUniqueArgs<$Schema, "Post">; +export type PostFindFirstArgs = $FindFirstArgs<$Schema, "Post">; +export type PostCreateArgs = $CreateArgs<$Schema, "Post">; +export type PostCreateManyArgs = $CreateManyArgs<$Schema, "Post">; +export type PostCreateManyAndReturnArgs = $CreateManyAndReturnArgs<$Schema, "Post">; +export type PostUpdateArgs = $UpdateArgs<$Schema, "Post">; +export type PostUpdateManyArgs = $UpdateManyArgs<$Schema, "Post">; +export type PostUpdateManyAndReturnArgs = $UpdateManyAndReturnArgs<$Schema, "Post">; +export type PostUpsertArgs = $UpsertArgs<$Schema, "Post">; +export type PostDeleteArgs = $DeleteArgs<$Schema, "Post">; +export type PostDeleteManyArgs = $DeleteManyArgs<$Schema, "Post">; +export type PostCountArgs = $CountArgs<$Schema, "Post">; +export type PostAggregateArgs = $AggregateArgs<$Schema, "Post">; +export type PostGroupByArgs = $GroupByArgs<$Schema, "Post">; +export type PostWhereInput = $WhereInput<$Schema, "Post">; +export type PostSelect = $SelectInput<$Schema, "Post">; +export type PostInclude = $IncludeInput<$Schema, "Post">; +export type PostOmit = $OmitInput<$Schema, "Post">; +export type PostGetPayload, Options extends $ClientOptions<$Schema> = $ClientOptions<$Schema>> = $SimplifiedModelResult<$Schema, "Post", Options, Args>; diff --git a/tests/runtimes/edge-runtime/schemas/models.ts b/tests/runtimes/edge-runtime/schemas/models.ts new file mode 100644 index 00000000..72654e58 --- /dev/null +++ b/tests/runtimes/edge-runtime/schemas/models.ts @@ -0,0 +1,11 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +/* eslint-disable */ + +import { type SchemaType as $Schema } from "./schema"; +import { type ModelResult as $ModelResult } from "@zenstackhq/orm"; +export type User = $ModelResult<$Schema, "User">; +export type Post = $ModelResult<$Schema, "Post">; diff --git a/tests/runtimes/edge-runtime/schemas/schema.ts b/tests/runtimes/edge-runtime/schemas/schema.ts new file mode 100644 index 00000000..7f4436f8 --- /dev/null +++ b/tests/runtimes/edge-runtime/schemas/schema.ts @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// DO NOT MODIFY THIS FILE // +// This file is automatically generated by ZenStack CLI and should not be manually updated. // +////////////////////////////////////////////////////////////////////////////////////////////// + +/* eslint-disable */ + +import { type SchemaDef, ExpressionUtils } from "@zenstackhq/orm/schema"; +const _schema = { + provider: { + type: "postgresql" + }, + models: { + User: { + name: "User", + fields: { + id: { + name: "id", + type: "String", + id: true, + attributes: [{ name: "@id" }, { name: "@default", args: [{ name: "value", value: ExpressionUtils.call("cuid") }] }], + default: ExpressionUtils.call("cuid") + }, + email: { + name: "email", + type: "String", + unique: true, + attributes: [{ name: "@unique" }] + }, + name: { + name: "name", + type: "String", + optional: true + }, + posts: { + name: "posts", + type: "Post", + array: true, + relation: { opposite: "author" } + } + }, + attributes: [ + { name: "@@allow", args: [{ name: "operation", value: ExpressionUtils.literal("all") }, { name: "condition", value: ExpressionUtils.binary(ExpressionUtils.member(ExpressionUtils.call("auth"), ["id"]), "==", ExpressionUtils.field("id")) }] }, + { name: "@@allow", args: [{ name: "operation", value: ExpressionUtils.literal("read") }, { name: "condition", value: ExpressionUtils.binary(ExpressionUtils.call("auth"), "!=", ExpressionUtils._null()) }] } + ], + idFields: ["id"], + uniqueFields: { + id: { type: "String" }, + email: { type: "String" } + } + }, + Post: { + name: "Post", + fields: { + id: { + name: "id", + type: "String", + id: true, + attributes: [{ name: "@id" }, { name: "@default", args: [{ name: "value", value: ExpressionUtils.call("cuid") }] }], + default: ExpressionUtils.call("cuid") + }, + title: { + name: "title", + type: "String" + }, + published: { + name: "published", + type: "Boolean", + attributes: [{ name: "@default", args: [{ name: "value", value: ExpressionUtils.literal(false) }] }], + default: false + }, + author: { + name: "author", + type: "User", + attributes: [{ name: "@relation", args: [{ name: "fields", value: ExpressionUtils.array([ExpressionUtils.field("authorId")]) }, { name: "references", value: ExpressionUtils.array([ExpressionUtils.field("id")]) }, { name: "onUpdate", value: ExpressionUtils.literal("Cascade") }, { name: "onDelete", value: ExpressionUtils.literal("Cascade") }] }], + relation: { opposite: "posts", fields: ["authorId"], references: ["id"], onUpdate: "Cascade", onDelete: "Cascade" } + }, + authorId: { + name: "authorId", + type: "String", + foreignKeyFor: [ + "author" + ] + } + }, + attributes: [ + { name: "@@deny", args: [{ name: "operation", value: ExpressionUtils.literal("all") }, { name: "condition", value: ExpressionUtils.binary(ExpressionUtils.call("auth"), "==", ExpressionUtils._null()) }] }, + { name: "@@allow", args: [{ name: "operation", value: ExpressionUtils.literal("all") }, { name: "condition", value: ExpressionUtils.binary(ExpressionUtils.member(ExpressionUtils.call("auth"), ["id"]), "==", ExpressionUtils.field("authorId")) }] }, + { name: "@@allow", args: [{ name: "operation", value: ExpressionUtils.literal("read") }, { name: "condition", value: ExpressionUtils.field("published") }] } + ], + idFields: ["id"], + uniqueFields: { + id: { type: "String" } + } + } + }, + authType: "User", + plugins: {} +} as const satisfies SchemaDef; +type Schema = typeof _schema & { + __brand?: "schema"; +}; +export const schema: Schema = _schema; +export type SchemaType = Schema; diff --git a/tests/runtimes/edge-runtime/schemas/schema.zmodel b/tests/runtimes/edge-runtime/schemas/schema.zmodel new file mode 100644 index 00000000..7872ce26 --- /dev/null +++ b/tests/runtimes/edge-runtime/schemas/schema.zmodel @@ -0,0 +1,31 @@ +datasource db { + provider = "postgresql" +} + +plugin policy { + provider = "../../../packages/plugins/policy" +} + +model User { + id String @id @default(cuid()) + email String @unique + name String? + posts Post[] + + // Access policies + @@allow('all', auth().id == id) + @@allow('read', auth() != null) +} + +model Post { + id String @id @default(cuid()) + title String + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id], onUpdate: Cascade, onDelete: Cascade) + authorId String + + // Access policies + @@deny('all', auth() == null) + @@allow('all', auth().id == authorId) + @@allow('read', published) +} diff --git a/tests/runtimes/edge-runtime/scripts/generate.ts b/tests/runtimes/edge-runtime/scripts/generate.ts new file mode 100644 index 00000000..cd68f93b --- /dev/null +++ b/tests/runtimes/edge-runtime/scripts/generate.ts @@ -0,0 +1,20 @@ +import { glob } from 'glob'; +import { execSync } from 'node:child_process'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const dir = path.dirname(fileURLToPath(import.meta.url)); + +async function main() { + const zmodelFiles = [...glob.sync(path.resolve(dir, '../schemas/*.zmodel'))]; + for (const file of zmodelFiles) { + console.log(`Generating TS schema for: ${file}`); + await generate(file); + } +} + +async function generate(schemaPath: string) { + execSync('npx zen generate', { cwd: path.dirname(schemaPath) }); +} + +main(); diff --git a/tests/runtimes/edge-runtime/tsconfig.json b/tests/runtimes/edge-runtime/tsconfig.json new file mode 100644 index 00000000..b17ade81 --- /dev/null +++ b/tests/runtimes/edge-runtime/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@zenstackhq/typescript-config/base.json", + "compilerOptions": { + "noEmit": true + } +} diff --git a/tests/runtimes/edge-runtime/vitest.config.ts b/tests/runtimes/edge-runtime/vitest.config.ts new file mode 100644 index 00000000..e9e63f31 --- /dev/null +++ b/tests/runtimes/edge-runtime/vitest.config.ts @@ -0,0 +1,11 @@ +import base from '@zenstackhq/vitest-config/base'; +import { defineConfig, mergeConfig } from 'vitest/config'; + +export default mergeConfig( + base, + defineConfig({ + test: { + environment: 'edge-runtime', + }, + }), +); diff --git a/turbo.json b/turbo.json index ab312f31..c6631358 100644 --- a/turbo.json +++ b/turbo.json @@ -15,7 +15,9 @@ "dependsOn": ["^lint"] }, "test": { - "dependsOn": ["build"] + "dependsOn": ["build"], + "cache": false } - } + }, + "globalPassThroughEnv": ["TEST_DB_PROVIDER"] } diff --git a/vitest.config.ts b/vitest.config.ts index f7268cb1..e4c2666a 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,6 +2,6 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { - projects: ['packages/*', 'tests/*'], + projects: ['packages/**', 'tests/**'], }, });