diff --git a/packages/cli/package.json b/packages/cli/package.json index 1275a901..3338728a 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -53,7 +53,7 @@ "@zenstackhq/testtools": "workspace:*", "@zenstackhq/typescript-config": "workspace:*", "@zenstackhq/vitest-config": "workspace:*", - "better-sqlite3": "^12.2.0", + "better-sqlite3": "catalog:", "tmp": "catalog:" } } diff --git a/packages/plugins/policy/eslint.config.js b/packages/plugins/policy/eslint.config.js new file mode 100644 index 00000000..5698b991 --- /dev/null +++ b/packages/plugins/policy/eslint.config.js @@ -0,0 +1,4 @@ +import config from '@zenstackhq/eslint-config/base.js'; + +/** @type {import("eslint").Linter.Config} */ +export default config; diff --git a/packages/plugins/policy/package.json b/packages/plugins/policy/package.json new file mode 100644 index 00000000..eb869945 --- /dev/null +++ b/packages/plugins/policy/package.json @@ -0,0 +1,50 @@ +{ + "name": "@zenstackhq/plugin-policy", + "version": "3.0.0-beta.8", + "description": "ZenStack Policy Plugin", + "type": "module", + "scripts": { + "build": "tsc --noEmit && tsup-node", + "watch": "tsup-node --watch", + "lint": "eslint src --ext ts", + "pack": "pnpm pack" + }, + "keywords": [], + "author": "ZenStack Team", + "license": "MIT", + "files": [ + "dist" + ], + "exports": { + ".": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./package.json": { + "import": "./package.json", + "require": "./package.json" + } + }, + "dependencies": { + "@zenstackhq/common-helpers": "workspace:*", + "@zenstackhq/sdk": "workspace:*", + "@zenstackhq/runtime": "workspace:*", + "ts-pattern": "catalog:" + }, + "peerDependencies": { + "kysely": "catalog:" + }, + "devDependencies": { + "@types/better-sqlite3": "^7.6.13", + "@types/pg": "^8.0.0", + "@zenstackhq/eslint-config": "workspace:*", + "@zenstackhq/typescript-config": "workspace:*", + "@zenstackhq/vitest-config": "workspace:*" + } +} diff --git a/packages/runtime/src/plugins/policy/column-collector.ts b/packages/plugins/policy/src/column-collector.ts similarity index 85% rename from packages/runtime/src/plugins/policy/column-collector.ts rename to packages/plugins/policy/src/column-collector.ts index 8b2a9f77..37d9df11 100644 --- a/packages/runtime/src/plugins/policy/column-collector.ts +++ b/packages/plugins/policy/src/column-collector.ts @@ -1,5 +1,5 @@ import type { ColumnNode, OperationNode } from 'kysely'; -import { DefaultOperationNodeVisitor } from '../../utils/default-operation-node-visitor'; +import { DefaultOperationNodeVisitor } from '@zenstackhq/sdk'; /** * Collects all column names from a query. diff --git a/packages/runtime/src/plugins/policy/expression-evaluator.ts b/packages/plugins/policy/src/expression-evaluator.ts similarity index 99% rename from packages/runtime/src/plugins/policy/expression-evaluator.ts rename to packages/plugins/policy/src/expression-evaluator.ts index a35530e5..330bf48f 100644 --- a/packages/runtime/src/plugins/policy/expression-evaluator.ts +++ b/packages/plugins/policy/src/expression-evaluator.ts @@ -10,7 +10,7 @@ import { type LiteralExpression, type MemberExpression, type UnaryExpression, -} from '../../schema'; +} from '@zenstackhq/runtime/schema'; type ExpressionEvaluatorContext = { auth?: any; diff --git a/packages/runtime/src/plugins/policy/expression-transformer.ts b/packages/plugins/policy/src/expression-transformer.ts similarity index 93% rename from packages/runtime/src/plugins/policy/expression-transformer.ts rename to packages/plugins/policy/src/expression-transformer.ts index 1eca04fa..58bcea2e 100644 --- a/packages/runtime/src/plugins/policy/expression-transformer.ts +++ b/packages/plugins/policy/src/expression-transformer.ts @@ -1,4 +1,31 @@ import { invariant } from '@zenstackhq/common-helpers'; +import { + getCrudDialect, + InternalError, + QueryError, + QueryUtils, + type BaseCrudDialect, + type ClientContract, + type CRUD_EXT, +} from '@zenstackhq/runtime'; +import type { + BinaryExpression, + BinaryOperator, + BuiltinType, + FieldDef, + GetModels, + LiteralExpression, + MemberExpression, + UnaryExpression, +} from '@zenstackhq/runtime/schema'; +import { + ExpressionUtils, + type ArrayExpression, + type CallExpression, + type Expression, + type FieldExpression, + type SchemaDef, +} from '@zenstackhq/runtime/schema'; import { AliasNode, BinaryOperationNode, @@ -20,35 +47,6 @@ import { type OperationNode, } from 'kysely'; import { match } from 'ts-pattern'; -import type { ClientContract, CRUD_EXT } from '../../client/contract'; -import { getCrudDialect } from '../../client/crud/dialects'; -import type { BaseCrudDialect } from '../../client/crud/dialects/base-dialect'; -import { InternalError, QueryError } from '../../client/errors'; -import { - getManyToManyRelation, - getModel, - getRelationForeignKeyFieldPairs, - requireField, - requireIdFields, -} from '../../client/query-utils'; -import type { - BinaryExpression, - BinaryOperator, - BuiltinType, - FieldDef, - GetModels, - LiteralExpression, - MemberExpression, - UnaryExpression, -} from '../../schema'; -import { - ExpressionUtils, - type ArrayExpression, - type CallExpression, - type Expression, - type FieldExpression, - type SchemaDef, -} from '../../schema'; import { ExpressionEvaluator } from './expression-evaluator'; import { conjunction, disjunction, falseNode, isBeforeInvocation, logicalNot, trueNode } from './utils'; @@ -124,7 +122,7 @@ export class ExpressionTransformer { @expr('field') private _field(expr: FieldExpression, context: ExpressionTransformerContext) { - const fieldDef = requireField(this.schema, context.model, expr.field); + const fieldDef = QueryUtils.requireField(this.schema, context.model, expr.field); if (!fieldDef.relation) { return this.createColumnRef(expr.field, context); } else { @@ -226,7 +224,7 @@ export class ExpressionTransformer { invariant(ExpressionUtils.isNull(expr.right), 'only null comparison is supported for relation field'); const leftRelDef = this.getFieldDefFromFieldRef(expr.left, context.model); invariant(leftRelDef, 'failed to get relation field definition'); - const idFields = requireIdFields(this.schema, leftRelDef.type); + const idFields = QueryUtils.requireIdFields(this.schema, leftRelDef.type); normalizedLeft = this.makeOrAppendMember(normalizedLeft, idFields[0]!); } let normalizedRight: Expression = expr.right; @@ -234,7 +232,7 @@ export class ExpressionTransformer { invariant(ExpressionUtils.isNull(expr.left), 'only null comparison is supported for relation field'); const rightRelDef = this.getFieldDefFromFieldRef(expr.right, context.model); invariant(rightRelDef, 'failed to get relation field definition'); - const idFields = requireIdFields(this.schema, rightRelDef.type); + const idFields = QueryUtils.requireIdFields(this.schema, rightRelDef.type); normalizedRight = this.makeOrAppendMember(normalizedRight, idFields[0]!); } return { normalizedLeft, normalizedRight }; @@ -265,10 +263,10 @@ export class ExpressionTransformer { ExpressionUtils.isMember(expr.left) && ExpressionUtils.isField(expr.left.receiver), 'left operand must be member access with field receiver', ); - const fieldDef = requireField(this.schema, context.model, expr.left.receiver.field); + const fieldDef = QueryUtils.requireField(this.schema, context.model, expr.left.receiver.field); newContextModel = fieldDef.type; for (const member of expr.left.members) { - const memberDef = requireField(this.schema, newContextModel, member); + const memberDef = QueryUtils.requireField(this.schema, newContextModel, member); newContextModel = memberDef.type; } } @@ -318,7 +316,7 @@ export class ExpressionTransformer { if (ExpressionUtils.isNull(other)) { return this.transformValue(expr.op === '==' ? !this.auth : !!this.auth, 'Boolean'); } else { - const authModel = getModel(this.schema, this.authType); + const authModel = QueryUtils.getModel(this.schema, this.authType); if (!authModel) { throw new QueryError( `Unsupported use of \`auth()\` in policy of model "${context.model}", comparing with \`auth()\` is only possible when auth type is a model`, @@ -481,7 +479,7 @@ export class ExpressionTransformer { return this._field(ExpressionUtils.field(expr.members[0]!), context); } else { // transform the first segment into a relation access, then continue with the rest of the members - const firstMemberFieldDef = requireField(this.schema, context.model, expr.members[0]!); + const firstMemberFieldDef = QueryUtils.requireField(this.schema, context.model, expr.members[0]!); receiver = this.transformRelationAccess(expr.members[0]!, firstMemberFieldDef.type, restContext); members = expr.members.slice(1); } @@ -493,7 +491,7 @@ export class ExpressionTransformer { let startType: string; if (ExpressionUtils.isField(expr.receiver)) { - const receiverField = requireField(this.schema, context.model, expr.receiver.field); + const receiverField = QueryUtils.requireField(this.schema, context.model, expr.receiver.field); startType = receiverField.type; } else { // "this." case, start type is the model of the context @@ -504,7 +502,7 @@ export class ExpressionTransformer { const memberFields: { fromModel: string; fieldDef: FieldDef }[] = []; let currType = startType; for (const member of members) { - const fieldDef = requireField(this.schema, currType, member); + const fieldDef = QueryUtils.requireField(this.schema, currType, member); memberFields.push({ fieldDef, fromModel: currType }); currType = fieldDef.type; } @@ -561,7 +559,7 @@ export class ExpressionTransformer { } const field = expr.members[0]!; - const fieldDef = requireField(this.schema, receiverType, field); + const fieldDef = QueryUtils.requireField(this.schema, receiverType, field); const fieldValue = receiver[field] ?? null; return this.transformValue(fieldValue, fieldDef.type as BuiltinType); } @@ -571,13 +569,13 @@ export class ExpressionTransformer { relationModel: string, context: ExpressionTransformerContext, ): SelectQueryNode { - const m2m = getManyToManyRelation(this.schema, context.model, field); + const m2m = QueryUtils.getManyToManyRelation(this.schema, context.model, field); if (m2m) { return this.transformManyToManyRelationAccess(m2m, context); } const fromModel = context.model; - const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, fromModel, field); + const { keyPairs, ownedByModel } = QueryUtils.getRelationForeignKeyFieldPairs(this.schema, fromModel, field); let condition: OperationNode; if (ownedByModel) { @@ -614,7 +612,7 @@ export class ExpressionTransformer { } private transformManyToManyRelationAccess( - m2m: NonNullable>, + m2m: NonNullable>, context: ExpressionTransformerContext, ) { const eb = expressionBuilder(); @@ -672,13 +670,13 @@ export class ExpressionTransformer { private getFieldDefFromFieldRef(expr: Expression, model: GetModels): FieldDef | undefined { if (ExpressionUtils.isField(expr)) { - return requireField(this.schema, model, expr.field); + return QueryUtils.requireField(this.schema, model, expr.field); } else if ( ExpressionUtils.isMember(expr) && expr.members.length === 1 && ExpressionUtils.isThis(expr.receiver) ) { - return requireField(this.schema, model, expr.members[0]!); + return QueryUtils.requireField(this.schema, model, expr.members[0]!); } else { return undefined; } diff --git a/packages/runtime/src/plugins/policy/functions.ts b/packages/plugins/policy/src/functions.ts similarity index 82% rename from packages/runtime/src/plugins/policy/functions.ts rename to packages/plugins/policy/src/functions.ts index c7fa09d7..5d6d6621 100644 --- a/packages/runtime/src/plugins/policy/functions.ts +++ b/packages/plugins/policy/src/functions.ts @@ -1,9 +1,7 @@ import { invariant } from '@zenstackhq/common-helpers'; +import type { ZModelFunction, ZModelFunctionContext } from '@zenstackhq/runtime'; +import { CRUD, QueryUtils } from '@zenstackhq/runtime'; import { ExpressionWrapper, ValueNode, type Expression, type ExpressionBuilder } from 'kysely'; -import { CRUD } from '../../client/contract'; -import { extractFieldName } from '../../client/kysely-utils'; -import type { ZModelFunction, ZModelFunctionContext } from '../../client/options'; -import { buildJoinPairs, requireField } from '../../client/query-utils'; import { PolicyHandler } from './policy-handler'; /** @@ -31,9 +29,9 @@ export const check: ZModelFunction = ( } // first argument must be a field reference - const fieldName = extractFieldName(arg1Node); + const fieldName = QueryUtils.extractFieldName(arg1Node); invariant(fieldName, 'Failed to extract field name from the first argument of "check" function'); - const fieldDef = requireField(client.$schema, model, fieldName); + const fieldDef = QueryUtils.requireField(client.$schema, model, fieldName); invariant(fieldDef.relation, `Field "${fieldName}" is not a relation field in model "${model}"`); invariant(!fieldDef.array, `Field "${fieldName}" is a to-many relation, which is not supported by "check"`); const relationModel = fieldDef.type; @@ -43,7 +41,7 @@ export const check: ZModelFunction = ( const policyHandler = new PolicyHandler(client); // join with parent model - const joinPairs = buildJoinPairs(client.$schema, model, modelAlias, fieldName, relationModel); + const joinPairs = QueryUtils.buildJoinPairs(client.$schema, model, modelAlias, fieldName, relationModel); const joinCondition = joinPairs.length === 1 ? eb(eb.ref(joinPairs[0]![0]), '=', eb.ref(joinPairs[0]![1])) diff --git a/packages/runtime/src/plugins/policy/index.ts b/packages/plugins/policy/src/index.ts similarity index 50% rename from packages/runtime/src/plugins/policy/index.ts rename to packages/plugins/policy/src/index.ts index 9958cffb..1110b645 100644 --- a/packages/runtime/src/plugins/policy/index.ts +++ b/packages/plugins/policy/src/index.ts @@ -1,2 +1 @@ -export * from './errors'; export * from './plugin'; diff --git a/packages/runtime/src/plugins/policy/plugin.ts b/packages/plugins/policy/src/plugin.ts similarity index 81% rename from packages/runtime/src/plugins/policy/plugin.ts rename to packages/plugins/policy/src/plugin.ts index 7ebd2882..bbb3d0a7 100644 --- a/packages/runtime/src/plugins/policy/plugin.ts +++ b/packages/plugins/policy/src/plugin.ts @@ -1,5 +1,5 @@ -import { type OnKyselyQueryArgs, type RuntimePlugin } from '../../client/plugin'; -import type { SchemaDef } from '../../schema'; +import { type OnKyselyQueryArgs, type RuntimePlugin } from '@zenstackhq/runtime'; +import type { SchemaDef } from '@zenstackhq/runtime/schema'; import { check } from './functions'; import { PolicyHandler } from './policy-handler'; diff --git a/packages/runtime/src/plugins/policy/policy-handler.ts b/packages/plugins/policy/src/policy-handler.ts similarity index 94% rename from packages/runtime/src/plugins/policy/policy-handler.ts rename to packages/plugins/policy/src/policy-handler.ts index 49e5afd1..f6daf04d 100644 --- a/packages/runtime/src/plugins/policy/policy-handler.ts +++ b/packages/plugins/policy/src/policy-handler.ts @@ -1,4 +1,23 @@ import { invariant } from '@zenstackhq/common-helpers'; +import type { BaseCrudDialect, ClientContract, ProceedKyselyQueryFunction } from '@zenstackhq/runtime'; +import { + getCrudDialect, + InternalError, + QueryError, + QueryUtils, + RejectedByPolicyError, + RejectedByPolicyReason, + type CRUD_EXT, +} from '@zenstackhq/runtime'; +import { + ExpressionUtils, + type BuiltinType, + type Expression, + type GetModels, + type MemberExpression, + type SchemaDef, +} from '@zenstackhq/runtime/schema'; +import { ExpressionVisitor } from '@zenstackhq/sdk'; import { AliasNode, BinaryOperationNode, @@ -33,24 +52,7 @@ import { type RootOperationNode, } from 'kysely'; import { match } from 'ts-pattern'; -import type { ClientContract } from '../../client'; -import { type CRUD_EXT } from '../../client/contract'; -import { getCrudDialect } from '../../client/crud/dialects'; -import type { BaseCrudDialect } from '../../client/crud/dialects/base-dialect'; -import { InternalError, QueryError } from '../../client/errors'; -import type { ProceedKyselyQueryFunction } from '../../client/plugin'; -import { getManyToManyRelation, requireField, requireIdFields, requireModel } from '../../client/query-utils'; -import { - ExpressionUtils, - type BuiltinType, - type Expression, - type GetModels, - type MemberExpression, - type SchemaDef, -} from '../../schema'; -import { ExpressionVisitor } from '../../utils/expression-utils'; import { ColumnCollector } from './column-collector'; -import { RejectedByPolicyError, RejectedByPolicyReason } from './errors'; import { ExpressionTransformer } from './expression-transformer'; import type { Policy, PolicyOperation } from './types'; import { buildIsFalse, conjunction, disjunction, falseNode, getTableName, isBeforeInvocation, trueNode } from './utils'; @@ -149,7 +151,7 @@ export class PolicyHandler extends OperationNodeTransf ), ]), selections: beforeUpdateInfo.fields.map((name, index) => { - const def = requireField(this.client.$schema, mutationModel, name); + const def = QueryUtils.requireField(this.client.$schema, mutationModel, name); const castedColumnRef = sql`CAST(${eb.ref(`column${index + 1}`)} as ${sql.raw(this.dialect.getFieldSqlType(def))})`.as( name, @@ -167,7 +169,7 @@ export class PolicyHandler extends OperationNodeTransf qb.leftJoin( () => new ExpressionWrapper(beforeUpdateTable!).as('$before'), (join) => { - const idFields = requireIdFields(this.client.$schema, mutationModel); + const idFields = QueryUtils.requireIdFields(this.client.$schema, mutationModel); return idFields.reduce( (acc, f) => acc.onRef(`${mutationModel}.${f}`, '=', `$before.${f}`), join, @@ -268,7 +270,7 @@ export class PolicyHandler extends OperationNodeTransf } // make sure id fields are included - requireIdFields(this.client.$schema, model).forEach((f) => fields.add(f)); + QueryUtils.requireIdFields(this.client.$schema, model).forEach((f) => fields.add(f)); return Array.from(fields).sort(); } @@ -350,7 +352,7 @@ export class PolicyHandler extends OperationNodeTransf let returning = result.returning; if (returning) { const { mutationModel } = this.getMutationModel(node); - const idFields = requireIdFields(this.client.$schema, mutationModel); + const idFields = QueryUtils.requireIdFields(this.client.$schema, mutationModel); returning = ReturningNode.create(idFields.map((f) => SelectionNode.create(ColumnNode.create(f)))); } @@ -382,7 +384,7 @@ export class PolicyHandler extends OperationNodeTransf // before-update rows if (returning || this.hasPostUpdatePolicies(mutationModel)) { - const idFields = requireIdFields(this.client.$schema, mutationModel); + const idFields = QueryUtils.requireIdFields(this.client.$schema, mutationModel); returning = ReturningNode.create(idFields.map((f) => SelectionNode.create(ColumnNode.create(f)))); } @@ -421,10 +423,10 @@ export class PolicyHandler extends OperationNodeTransf return true; } const { mutationModel } = this.getMutationModel(node); - const idFields = requireIdFields(this.client.$schema, mutationModel); + const idFields = QueryUtils.requireIdFields(this.client.$schema, mutationModel); if (node.returning.selections.some((s) => SelectAllNode.is(s.selection))) { - const modelDef = requireModel(this.client.$schema, mutationModel); + const modelDef = QueryUtils.requireModel(this.client.$schema, mutationModel); if (Object.keys(modelDef.fields).some((f) => !idFields.includes(f))) { // there are fields other than ID fields return false; @@ -538,7 +540,7 @@ export class PolicyHandler extends OperationNodeTransf values: OperationNode[], proceed: ProceedKyselyQueryFunction, ) { - const allFields = Object.entries(requireModel(this.client.$schema, model).fields).filter( + const allFields = Object.entries(QueryUtils.requireModel(this.client.$schema, model).fields).filter( ([, def]) => !def.relation, ); const allValues: OperationNode[] = []; @@ -625,7 +627,7 @@ export class PolicyHandler extends OperationNodeTransf for (let i = 0; i < data.length; i++) { const item = data[i]!; if (typeof item === 'object' && item && 'kind' in item) { - const fieldDef = requireField(this.client.$schema, model, fields[i]!); + const fieldDef = QueryUtils.requireField(this.client.$schema, model, fields[i]!); invariant(item.kind === 'ValueNode', 'expecting a ValueNode'); result.push({ node: ValueNode.create( @@ -644,7 +646,7 @@ export class PolicyHandler extends OperationNodeTransf // but there's no need to transform values anyway because they're the fields // are all foreign keys if (!isImplicitManyToManyJoinTable) { - const fieldDef = requireField(this.client.$schema, model, fields[i]!); + const fieldDef = QueryUtils.requireField(this.client.$schema, model, fields[i]!); value = this.dialect.transformPrimitive(item, fieldDef.type as BuiltinType, !!fieldDef.array); } if (Array.isArray(value)) { @@ -710,7 +712,7 @@ export class PolicyHandler extends OperationNodeTransf } private buildIdConditions(table: string, rows: any[]): OperationNode { - const idFields = requireIdFields(this.client.$schema, table); + const idFields = QueryUtils.requireIdFields(this.client.$schema, table); return disjunction( this.dialect, rows.map((row) => @@ -865,7 +867,7 @@ export class PolicyHandler extends OperationNodeTransf } private getModelPolicies(model: string, operation: PolicyOperation) { - const modelDef = requireModel(this.client.$schema, model); + const modelDef = QueryUtils.requireModel(this.client.$schema, model); const result: Policy[] = []; const extractOperations = (expr: Expression) => { @@ -902,7 +904,7 @@ export class PolicyHandler extends OperationNodeTransf private resolveManyToManyJoinTable(tableName: string) { for (const model of Object.values(this.client.$schema.models)) { for (const field of Object.values(model.fields)) { - const m2m = getManyToManyRelation(this.client.$schema, model.name, field.name); + const m2m = QueryUtils.getManyToManyRelation(this.client.$schema, model.name, field.name); if (m2m?.joinTable === tableName) { const sortedRecord = [ { @@ -915,8 +917,8 @@ export class PolicyHandler extends OperationNodeTransf }, ].sort(this.manyToManySorter); - const firstIdFields = requireIdFields(this.client.$schema, sortedRecord[0]!.model); - const secondIdFields = requireIdFields(this.client.$schema, sortedRecord[1]!.model); + const firstIdFields = QueryUtils.requireIdFields(this.client.$schema, sortedRecord[0]!.model); + const secondIdFields = QueryUtils.requireIdFields(this.client.$schema, sortedRecord[1]!.model); invariant( firstIdFields.length === 1 && secondIdFields.length === 1, 'only single-field id is supported for implicit many-to-many join table', diff --git a/packages/runtime/src/plugins/policy/types.ts b/packages/plugins/policy/src/types.ts similarity index 73% rename from packages/runtime/src/plugins/policy/types.ts rename to packages/plugins/policy/src/types.ts index 74c49d85..f4c12e13 100644 --- a/packages/runtime/src/plugins/policy/types.ts +++ b/packages/plugins/policy/src/types.ts @@ -1,5 +1,5 @@ -import type { CRUD_EXT } from '../../client/contract'; -import type { Expression } from '../../schema'; +import type { CRUD_EXT } from '@zenstackhq/runtime'; +import type { Expression } from '@zenstackhq/runtime/schema'; /** * Access policy kind. diff --git a/packages/runtime/src/plugins/policy/utils.ts b/packages/plugins/policy/src/utils.ts similarity index 97% rename from packages/runtime/src/plugins/policy/utils.ts rename to packages/plugins/policy/src/utils.ts index 5fc11410..8a62458f 100644 --- a/packages/runtime/src/plugins/policy/utils.ts +++ b/packages/plugins/policy/src/utils.ts @@ -1,3 +1,5 @@ +import type { BaseCrudDialect } from '@zenstackhq/runtime'; +import { ExpressionUtils, type Expression, type SchemaDef } from '@zenstackhq/runtime/schema'; import type { OperationNode } from 'kysely'; import { AliasNode, @@ -12,8 +14,6 @@ import { UnaryOperationNode, ValueNode, } from 'kysely'; -import type { BaseCrudDialect } from '../../client/crud/dialects/base-dialect'; -import { ExpressionUtils, type Expression, type SchemaDef } from '../../schema'; /** * Creates a `true` value node. diff --git a/packages/runtime/tsconfig.build.json b/packages/plugins/policy/tsconfig.json similarity index 62% rename from packages/runtime/tsconfig.build.json rename to packages/plugins/policy/tsconfig.json index aacb3723..41472d08 100644 --- a/packages/runtime/tsconfig.build.json +++ b/packages/plugins/policy/tsconfig.json @@ -1,7 +1,4 @@ { "extends": "@zenstackhq/typescript-config/base.json", - "compilerOptions": { - "rootDir": "." - }, "include": ["src/**/*"] } diff --git a/packages/plugins/policy/tsup.config.ts b/packages/plugins/policy/tsup.config.ts new file mode 100644 index 00000000..4b7a3428 --- /dev/null +++ b/packages/plugins/policy/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: { + index: 'src/index.ts', + }, + outDir: 'dist', + splitting: false, + sourcemap: true, + dts: true, + format: ['cjs', 'esm'], +}); diff --git a/packages/plugins/policy/vitest.config.ts b/packages/plugins/policy/vitest.config.ts new file mode 100644 index 00000000..75a9f709 --- /dev/null +++ b/packages/plugins/policy/vitest.config.ts @@ -0,0 +1,4 @@ +import base from '@zenstackhq/vitest-config/base'; +import { defineConfig, mergeConfig } from 'vitest/config'; + +export default mergeConfig(base, defineConfig({})); diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 9e563efa..52af6379 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -4,14 +4,9 @@ "description": "ZenStack Runtime", "type": "module", "scripts": { - "build": "tsc --project tsconfig.build.json --noEmit && tsup-node && pnpm test:generate", + "build": "tsc --noEmit && tsup-node", "watch": "tsup-node --watch", "lint": "eslint src --ext ts", - "test": "vitest run && pnpm test:typecheck", - "test:sqlite": "TEST_DB_PROVIDER=sqlite vitest run", - "test:postgresql": "TEST_DB_PROVIDER=postgresql vitest run", - "test:generate": "tsx test/scripts/generate.ts", - "test:typecheck": "tsc --project tsconfig.test.json", "pack": "pnpm pack" }, "keywords": [], @@ -79,9 +74,9 @@ "zod-validation-error": "catalog:" }, "peerDependencies": { - "better-sqlite3": "^12.2.0", + "better-sqlite3": "catalog:", "kysely": "catalog:", - "pg": "^8.13.1", + "pg": "catalog:", "zod": "catalog:" }, "peerDependenciesMeta": { @@ -99,7 +94,6 @@ "@zenstackhq/eslint-config": "workspace:*", "@zenstackhq/language": "workspace:*", "@zenstackhq/sdk": "workspace:*", - "@zenstackhq/testtools": "workspace:*", "@zenstackhq/typescript-config": "workspace:*", "@zenstackhq/vitest-config": "workspace:*", "tsx": "^4.19.2", diff --git a/packages/runtime/src/client/crud/operations/base.ts b/packages/runtime/src/client/crud/operations/base.ts index 7a4c9a66..34924952 100644 --- a/packages/runtime/src/client/crud/operations/base.ts +++ b/packages/runtime/src/client/crud/operations/base.ts @@ -14,7 +14,6 @@ import { match } from 'ts-pattern'; import { ulid } from 'ulid'; import * as uuid from 'uuid'; import type { ClientContract } from '../..'; -import { PolicyPlugin } from '../../../plugins/policy'; import type { BuiltinType, Expression, FieldDef } from '../../../schema'; import { ExpressionUtils, type GetModels, type ModelDef, type SchemaDef } from '../../../schema'; import { clone } from '../../../utils/clone'; @@ -108,7 +107,7 @@ export abstract class BaseOperationHandler { // TODO: this is not clean, needs a better solution protected get hasPolicyEnabled() { - return this.options.plugins?.some((plugin) => plugin instanceof PolicyPlugin); + return this.options.plugins?.some((plugin) => plugin.constructor.name === 'PolicyPlugin'); } protected requireModel(model: string) { diff --git a/packages/runtime/src/client/crud/operations/create.ts b/packages/runtime/src/client/crud/operations/create.ts index 26206d99..36e76211 100644 --- a/packages/runtime/src/client/crud/operations/create.ts +++ b/packages/runtime/src/client/crud/operations/create.ts @@ -1,7 +1,7 @@ import { match } from 'ts-pattern'; -import { RejectedByPolicyError, RejectedByPolicyReason } from '../../../plugins/policy/errors'; import type { GetModels, SchemaDef } from '../../../schema'; import type { CreateArgs, CreateManyAndReturnArgs, CreateManyArgs, WhereInput } from '../../crud-types'; +import { RejectedByPolicyError, RejectedByPolicyReason } from '../../errors'; import { getIdValues } from '../../query-utils'; import { BaseOperationHandler } from './base'; diff --git a/packages/runtime/src/client/crud/operations/delete.ts b/packages/runtime/src/client/crud/operations/delete.ts index 6eb1eca3..21539aed 100644 --- a/packages/runtime/src/client/crud/operations/delete.ts +++ b/packages/runtime/src/client/crud/operations/delete.ts @@ -1,9 +1,8 @@ import { match } from 'ts-pattern'; import type { SchemaDef } from '../../../schema'; import type { DeleteArgs, DeleteManyArgs } from '../../crud-types'; -import { NotFoundError } from '../../errors'; +import { NotFoundError, RejectedByPolicyError, RejectedByPolicyReason } from '../../errors'; import { BaseOperationHandler } from './base'; -import { RejectedByPolicyError, RejectedByPolicyReason } from '../../../plugins/policy'; export class DeleteOperationHandler extends BaseOperationHandler { async handle(operation: 'delete' | 'deleteMany', args: unknown | undefined) { diff --git a/packages/runtime/src/client/crud/operations/update.ts b/packages/runtime/src/client/crud/operations/update.ts index ad2fc613..567721b0 100644 --- a/packages/runtime/src/client/crud/operations/update.ts +++ b/packages/runtime/src/client/crud/operations/update.ts @@ -1,7 +1,7 @@ import { match } from 'ts-pattern'; -import { RejectedByPolicyError, RejectedByPolicyReason } from '../../../plugins/policy/errors'; import type { GetModels, SchemaDef } from '../../../schema'; import type { UpdateArgs, UpdateManyAndReturnArgs, UpdateManyArgs, UpsertArgs, WhereInput } from '../../crud-types'; +import { RejectedByPolicyError, RejectedByPolicyReason } from '../../errors'; import { getIdValues } from '../../query-utils'; import { BaseOperationHandler } from './base'; diff --git a/packages/runtime/src/client/errors.ts b/packages/runtime/src/client/errors.ts index 15961811..c1be626a 100644 --- a/packages/runtime/src/client/errors.ts +++ b/packages/runtime/src/client/errors.ts @@ -34,3 +34,36 @@ export class NotFoundError extends ZenStackError { super(`Entity not found for model "${model}"${details ? `: ${details}` : ''}`); } } + +/** + * Reason code for policy rejection. + */ +export enum RejectedByPolicyReason { + /** + * Rejected because the operation is not allowed by policy. + */ + NO_ACCESS = 'no-access', + + /** + * Rejected because the result cannot be read back after mutation due to policy. + */ + CANNOT_READ_BACK = 'cannot-read-back', + + /** + * Other reasons. + */ + OTHER = 'other', +} + +/** + * Error thrown when an operation is rejected by access policy. + */ +export class RejectedByPolicyError extends ZenStackError { + constructor( + public readonly model: string | undefined, + public readonly reason: RejectedByPolicyReason = RejectedByPolicyReason.NO_ACCESS, + message?: string, + ) { + super(message ?? `Operation rejected by policy${model ? ': ' + model : ''}`); + } +} diff --git a/packages/runtime/src/client/executor/name-mapper.ts b/packages/runtime/src/client/executor/name-mapper.ts index 83ef8a33..410aa7b7 100644 --- a/packages/runtime/src/client/executor/name-mapper.ts +++ b/packages/runtime/src/client/executor/name-mapper.ts @@ -17,8 +17,7 @@ import { type OperationNode, } from 'kysely'; import type { FieldDef, ModelDef, SchemaDef } from '../../schema'; -import { extractFieldName, extractModelName, stripAlias } from '../kysely-utils'; -import { getModel, requireModel } from '../query-utils'; +import { extractFieldName, extractModelName, getModel, requireModel, stripAlias } from '../query-utils'; type Scope = { model?: string; diff --git a/packages/runtime/src/client/executor/zenstack-query-executor.ts b/packages/runtime/src/client/executor/zenstack-query-executor.ts index c307bc4e..f3e855fa 100644 --- a/packages/runtime/src/client/executor/zenstack-query-executor.ts +++ b/packages/runtime/src/client/executor/zenstack-query-executor.ts @@ -26,8 +26,8 @@ import type { GetModels, SchemaDef } from '../../schema'; import { type ClientImpl } from '../client-impl'; import { TransactionIsolationLevel, type ClientContract } from '../contract'; import { InternalError, QueryError, ZenStackError } from '../errors'; -import { stripAlias } from '../kysely-utils'; import type { AfterEntityMutationCallback, OnKyselyQueryCallback } from '../plugin'; +import { stripAlias } from '../query-utils'; import { QueryNameMapper } from './name-mapper'; import type { ZenStackDriver } from './zenstack-driver'; diff --git a/packages/runtime/src/client/index.ts b/packages/runtime/src/client/index.ts index aaf50754..225aeba5 100644 --- a/packages/runtime/src/client/index.ts +++ b/packages/runtime/src/client/index.ts @@ -1,9 +1,11 @@ export { ZenStackClient } from './client-impl'; -export type { ClientConstructor, ClientContract } from './contract'; +export * from './contract'; export type * from './crud-types'; +export { getCrudDialect } from './crud/dialects'; +export { BaseCrudDialect } from './crud/dialects/base-dialect'; export * from './errors'; -export type { ClientOptions } from './options'; -export { definePlugin } from './plugin'; +export * from './options'; +export * from './plugin'; export type { ZenStackPromise } from './promise'; export type { ToKysely } from './query-builder'; -export { sql } from 'kysely'; +export * as QueryUtils from './query-utils'; diff --git a/packages/runtime/src/client/kysely-utils.ts b/packages/runtime/src/client/kysely-utils.ts deleted file mode 100644 index a46464c3..00000000 --- a/packages/runtime/src/client/kysely-utils.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { type OperationNode, AliasNode, ColumnNode, ReferenceNode, TableNode } from 'kysely'; - -/** - * Strips alias from the node if it exists. - */ -export function stripAlias(node: OperationNode) { - if (AliasNode.is(node)) { - return { alias: node.alias, node: node.node }; - } else { - return { alias: undefined, node }; - } -} - -/** - * Extracts model name from an OperationNode. - */ -export function extractModelName(node: OperationNode) { - const { node: innerNode } = stripAlias(node); - return TableNode.is(innerNode!) ? innerNode!.table.identifier.name : undefined; -} - -/** - * Extracts field name from an OperationNode. - */ -export function extractFieldName(node: OperationNode) { - if (ReferenceNode.is(node) && ColumnNode.is(node.column)) { - return node.column.column.name; - } else if (ColumnNode.is(node)) { - return node.column.name; - } else { - return undefined; - } -} diff --git a/packages/runtime/src/client/query-utils.ts b/packages/runtime/src/client/query-utils.ts index 1cfbdd14..869d3535 100644 --- a/packages/runtime/src/client/query-utils.ts +++ b/packages/runtime/src/client/query-utils.ts @@ -1,5 +1,14 @@ import { invariant } from '@zenstackhq/common-helpers'; -import type { Expression, ExpressionBuilder, ExpressionWrapper } from 'kysely'; +import { + AliasNode, + ColumnNode, + ReferenceNode, + TableNode, + type Expression, + type ExpressionBuilder, + type ExpressionWrapper, + type OperationNode, +} from 'kysely'; import { match } from 'ts-pattern'; import { ExpressionUtils, type FieldDef, type GetModels, type ModelDef, type SchemaDef } from '../schema'; import { extractFields } from '../utils/object-utils'; @@ -367,3 +376,35 @@ export function aggregate(eb: ExpressionBuilder, expr: Expression .with('_max', () => eb.fn.max(expr)) .exhaustive(); } + +/** + * Strips alias from the node if it exists. + */ +export function stripAlias(node: OperationNode) { + if (AliasNode.is(node)) { + return { alias: node.alias, node: node.node }; + } else { + return { alias: undefined, node }; + } +} + +/** + * Extracts model name from an OperationNode. + */ +export function extractModelName(node: OperationNode) { + const { node: innerNode } = stripAlias(node); + return TableNode.is(innerNode!) ? innerNode!.table.identifier.name : undefined; +} + +/** + * Extracts field name from an OperationNode. + */ +export function extractFieldName(node: OperationNode) { + if (ReferenceNode.is(node) && ColumnNode.is(node.column)) { + return node.column.column.name; + } else if (ColumnNode.is(node)) { + return node.column.name; + } else { + return undefined; + } +} diff --git a/packages/runtime/src/plugins/policy/errors.ts b/packages/runtime/src/plugins/policy/errors.ts deleted file mode 100644 index 42d57b18..00000000 --- a/packages/runtime/src/plugins/policy/errors.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ZenStackError } from '../../client'; - -/** - * Reason code for policy rejection. - */ -export enum RejectedByPolicyReason { - /** - * Rejected because the operation is not allowed by policy. - */ - NO_ACCESS = 'no-access', - - /** - * Rejected because the result cannot be read back after mutation due to policy. - */ - CANNOT_READ_BACK = 'cannot-read-back', - - /** - * Other reasons. - */ - OTHER = 'other', -} - -/** - * Error thrown when an operation is rejected by access policy. - */ -export class RejectedByPolicyError extends ZenStackError { - constructor( - public readonly model: string | undefined, - public readonly reason: RejectedByPolicyReason = RejectedByPolicyReason.NO_ACCESS, - message?: string, - ) { - super(message ?? `Operation rejected by policy${model ? ': ' + model : ''}`); - } -} diff --git a/packages/runtime/src/schema/index.ts b/packages/runtime/src/schema/index.ts index 4f98939e..10a69276 100644 --- a/packages/runtime/src/schema/index.ts +++ b/packages/runtime/src/schema/index.ts @@ -1,3 +1,4 @@ export type * from '@zenstackhq/sdk/schema'; export type { OperandExpression } from 'kysely'; +export * from './auth'; export * from './expression'; diff --git a/packages/runtime/test/policy/utils.ts b/packages/runtime/test/policy/utils.ts deleted file mode 100644 index 30b99577..00000000 --- a/packages/runtime/test/policy/utils.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { ClientContract } from '../../src'; -import { PolicyPlugin } from '../../src/plugins/policy'; -import type { SchemaDef } from '../../src/schema'; -import { createTestClient, type CreateTestClientOptions } from '../utils'; - -export async function createPolicyTestClient( - schema: Schema, - options?: CreateTestClientOptions, -): Promise>; -export async function createPolicyTestClient( - schema: string, - options?: CreateTestClientOptions, -): Promise; -export async function createPolicyTestClient( - schema: Schema | string, - options?: CreateTestClientOptions, -): Promise { - return createTestClient( - schema as any, - { - ...options, - plugins: [new PolicyPlugin()], - } as any, - ); -} diff --git a/packages/runtime/tsconfig.json b/packages/runtime/tsconfig.json index 6056fb01..aacb3723 100644 --- a/packages/runtime/tsconfig.json +++ b/packages/runtime/tsconfig.json @@ -3,5 +3,5 @@ "compilerOptions": { "rootDir": "." }, - "include": ["src/**/*", "test/**/*"] + "include": ["src/**/*"] } diff --git a/packages/runtime/tsup.config.ts b/packages/runtime/tsup.config.ts index 7f7a9348..b5acbfc2 100644 --- a/packages/runtime/tsup.config.ts +++ b/packages/runtime/tsup.config.ts @@ -5,7 +5,6 @@ export default defineConfig({ index: 'src/index.ts', schema: 'src/schema/index.ts', helpers: 'src/helpers.ts', - 'plugins/policy/index': 'src/plugins/policy/index.ts', }, outDir: 'dist', splitting: false, diff --git a/packages/runtime/vitest.config.ts b/packages/runtime/vitest.config.ts index ecf30fd7..75a9f709 100644 --- a/packages/runtime/vitest.config.ts +++ b/packages/runtime/vitest.config.ts @@ -1,12 +1,4 @@ import base from '@zenstackhq/vitest-config/base'; -import path from 'node:path'; import { defineConfig, mergeConfig } from 'vitest/config'; -export default mergeConfig( - base, - defineConfig({ - test: { - setupFiles: [path.resolve(__dirname, './test/vitest-ext.ts')], - }, - }), -); +export default mergeConfig(base, defineConfig({})); diff --git a/packages/runtime/src/utils/default-operation-node-visitor.ts b/packages/sdk/src/default-operation-node-visitor.ts similarity index 100% rename from packages/runtime/src/utils/default-operation-node-visitor.ts rename to packages/sdk/src/default-operation-node-visitor.ts diff --git a/packages/runtime/src/utils/expression-utils.ts b/packages/sdk/src/expression-utils.ts similarity index 98% rename from packages/runtime/src/utils/expression-utils.ts rename to packages/sdk/src/expression-utils.ts index 8c0824d4..ec423767 100644 --- a/packages/runtime/src/utils/expression-utils.ts +++ b/packages/sdk/src/expression-utils.ts @@ -10,7 +10,7 @@ import type { NullExpression, ThisExpression, UnaryExpression, -} from '../schema'; +} from './schema'; export class ExpressionVisitor { visit(expr: Expression): void { diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 649a7201..c74b1419 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -1,5 +1,7 @@ import * as ModelUtils from './model-utils'; export * from './cli-plugin'; +export * from './expression-utils'; +export * from './default-operation-node-visitor'; export { PrismaSchemaGenerator } from './prisma/prisma-schema-generator'; export * from './ts-schema-generator'; export * from './zmodel-code-generator'; diff --git a/packages/testtools/package.json b/packages/testtools/package.json index be36abc2..d34a1e4c 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -4,7 +4,7 @@ "description": "ZenStack Test Tools", "type": "module", "scripts": { - "build": "tsc --noEmit && tsup-node", + "build": "tsc --noEmit && tsup-node && copyfiles -f ./src/types.d.ts ./dist", "watch": "tsup-node --watch", "lint": "eslint src --ext ts", "pack": "pnpm pack" @@ -25,25 +25,35 @@ "types": "./dist/index.d.cts", "default": "./dist/index.cjs" } + }, + "./types": { + "types": "./dist/types.d.ts" } }, "dependencies": { + "@zenstackhq/common-helpers": "workspace:*", "@zenstackhq/language": "workspace:*", + "@zenstackhq/runtime": "workspace:*", "@zenstackhq/sdk": "workspace:*", + "@zenstackhq/plugin-policy": "workspace:*", "glob": "^11.0.2", - "tmp": "catalog:", - "ts-pattern": "catalog:", + "kysely": "catalog:", "prisma": "catalog:", - "typescript": "catalog:" + "tmp": "catalog:", + "ts-pattern": "catalog:" }, "peerDependencies": { - "better-sqlite3": "^12.2.0", - "pg": "^8.13.1" + "better-sqlite3": "catalog:", + "pg": "catalog:" }, "devDependencies": { + "@types/better-sqlite3": "^7.6.13", "@types/node": "catalog:", "@types/tmp": "catalog:", + "@types/pg": "^8.11.11", "@zenstackhq/eslint-config": "workspace:*", - "@zenstackhq/typescript-config": "workspace:*" + "@zenstackhq/typescript-config": "workspace:*", + "copyfiles": "^2.4.1", + "typescript": "catalog:" } } diff --git a/packages/runtime/test/utils.ts b/packages/testtools/src/client.ts similarity index 86% rename from packages/runtime/test/utils.ts rename to packages/testtools/src/client.ts index d5bea549..fcb1b1ec 100644 --- a/packages/runtime/test/utils.ts +++ b/packages/testtools/src/client.ts @@ -1,8 +1,10 @@ import { invariant } from '@zenstackhq/common-helpers'; import { loadDocument } from '@zenstackhq/language'; import type { Model } from '@zenstackhq/language/ast'; +import { PolicyPlugin } from '@zenstackhq/plugin-policy'; +import { ZenStackClient, type ClientContract, type ClientOptions } from '@zenstackhq/runtime'; +import type { SchemaDef } from '@zenstackhq/runtime/schema'; import { PrismaSchemaGenerator } from '@zenstackhq/sdk'; -import { createTestProject, generateTsSchema } from '@zenstackhq/testtools'; import SQLite from 'better-sqlite3'; import { PostgresDialect, SqliteDialect, type LogEvent } from 'kysely'; import { execSync } from 'node:child_process'; @@ -11,9 +13,8 @@ import fs from 'node:fs'; import path from 'node:path'; import { Client as PGClient, Pool } from 'pg'; import { expect } from 'vitest'; -import type { ClientContract, ClientOptions } from '../src/client'; -import { ZenStackClient } from '../src/client'; -import type { SchemaDef } from '../src/schema'; +import { createTestProject } from './project'; +import { generateTsSchema } from './schema'; export function getTestDbProvider() { const val = process.env['TEST_DB_PROVIDER'] ?? 'sqlite'; @@ -165,6 +166,27 @@ export async function createTestClient( return client; } +export async function createPolicyTestClient( + schema: Schema, + options?: CreateTestClientOptions, +): Promise>; +export async function createPolicyTestClient( + schema: string, + options?: CreateTestClientOptions, +): Promise; +export async function createPolicyTestClient( + schema: Schema | string, + options?: CreateTestClientOptions, +): Promise { + return createTestClient( + schema as any, + { + ...options, + plugins: [...(options?.plugins ?? []), new PolicyPlugin()], + } as any, + ); +} + export function testLogger(e: LogEvent) { console.log(e.query.sql, e.query.parameters); } diff --git a/packages/testtools/src/index.ts b/packages/testtools/src/index.ts index dd917ab1..96ce1534 100644 --- a/packages/testtools/src/index.ts +++ b/packages/testtools/src/index.ts @@ -1,2 +1,4 @@ +export * from './client'; export * from './project'; export * from './schema'; +export * from './vitest-ext'; diff --git a/packages/runtime/test/vitest.d.ts b/packages/testtools/src/types.d.ts similarity index 100% rename from packages/runtime/test/vitest.d.ts rename to packages/testtools/src/types.d.ts diff --git a/packages/runtime/test/vitest-ext.ts b/packages/testtools/src/vitest-ext.ts similarity index 96% rename from packages/runtime/test/vitest-ext.ts rename to packages/testtools/src/vitest-ext.ts index 096b2429..70b5a61b 100644 --- a/packages/runtime/test/vitest-ext.ts +++ b/packages/testtools/src/vitest-ext.ts @@ -1,6 +1,5 @@ +import { NotFoundError, RejectedByPolicyError } from '@zenstackhq/runtime'; import { expect } from 'vitest'; -import { NotFoundError } from '../src/client/errors'; -import { RejectedByPolicyError } from '../src/plugins/policy/errors'; function isPromise(value: any) { return typeof value.then === 'function' && typeof value.catch === 'function'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a6638dc1..3c85aa5e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,9 @@ catalogs: '@types/tmp': specifier: ^0.2.6 version: 0.2.6 + better-sqlite3: + specifier: ^12.2.0 + version: 12.2.0 kysely: specifier: ^0.27.6 version: 0.27.6 @@ -21,6 +24,9 @@ catalogs: langium-cli: specifier: 3.5.0 version: 3.5.0 + pg: + specifier: ^8.13.1 + version: 8.16.3 prisma: specifier: ^6.10.0 version: 6.14.0 @@ -142,7 +148,7 @@ importers: specifier: workspace:* version: link:../vitest-config better-sqlite3: - specifier: ^12.2.0 + specifier: 'catalog:' version: 12.2.0 tmp: specifier: 'catalog:' @@ -264,6 +270,40 @@ importers: specifier: 'catalog:' version: 0.2.3 + packages/plugins/policy: + dependencies: + '@zenstackhq/common-helpers': + specifier: workspace:* + version: link:../../common-helpers + '@zenstackhq/runtime': + specifier: workspace:* + version: link:../../runtime + '@zenstackhq/sdk': + specifier: workspace:* + version: link:../../sdk + kysely: + specifier: 'catalog:' + version: 0.27.6 + ts-pattern: + specifier: 'catalog:' + version: 5.7.1 + devDependencies: + '@types/better-sqlite3': + specifier: ^7.6.13 + version: 7.6.13 + '@types/pg': + specifier: ^8.0.0 + version: 8.11.11 + '@zenstackhq/eslint-config': + specifier: workspace:* + version: link:../../eslint-config + '@zenstackhq/typescript-config': + specifier: workspace:* + version: link:../../typescript-config + '@zenstackhq/vitest-config': + specifier: workspace:* + version: link:../../vitest-config + packages/runtime: dependencies: '@paralleldrive/cuid2': @@ -273,7 +313,7 @@ importers: specifier: workspace:* version: link:../common-helpers better-sqlite3: - specifier: ^12.2.0 + specifier: 'catalog:' version: 12.2.0 decimal.js: specifier: ^10.4.3 @@ -288,8 +328,8 @@ importers: specifier: ^5.0.9 version: 5.0.9 pg: - specifier: ^8.13.1 - version: 8.13.1 + specifier: 'catalog:' + version: 8.16.3 toposort: specifier: ^2.0.2 version: 2.0.2 @@ -324,9 +364,6 @@ importers: '@zenstackhq/sdk': specifier: workspace:* version: link:../sdk - '@zenstackhq/testtools': - specifier: workspace:* - version: link:../testtools '@zenstackhq/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -389,21 +426,33 @@ importers: packages/testtools: dependencies: + '@zenstackhq/common-helpers': + specifier: workspace:* + version: link:../common-helpers '@zenstackhq/language': specifier: workspace:* version: link:../language + '@zenstackhq/plugin-policy': + specifier: workspace:* + version: link:../plugins/policy + '@zenstackhq/runtime': + specifier: workspace:* + version: link:../runtime '@zenstackhq/sdk': specifier: workspace:* version: link:../sdk better-sqlite3: - specifier: ^12.2.0 + specifier: 'catalog:' version: 12.2.0 glob: specifier: ^11.0.2 version: 11.0.2 + kysely: + specifier: 'catalog:' + version: 0.27.6 pg: - specifier: ^8.13.1 - version: 8.13.1 + specifier: 'catalog:' + version: 8.16.3 prisma: specifier: 'catalog:' version: 6.14.0(typescript@5.8.3) @@ -413,13 +462,16 @@ importers: ts-pattern: specifier: 'catalog:' version: 5.7.1 - typescript: - specifier: 'catalog:' - version: 5.8.3 devDependencies: + '@types/better-sqlite3': + specifier: ^7.6.13 + version: 7.6.13 '@types/node': specifier: 'catalog:' version: 20.17.24 + '@types/pg': + specifier: ^8.11.11 + version: 8.11.11 '@types/tmp': specifier: 'catalog:' version: 0.2.6 @@ -429,6 +481,12 @@ importers: '@zenstackhq/typescript-config': specifier: workspace:* version: link:../typescript-config + copyfiles: + specifier: ^2.4.1 + version: 2.4.1 + typescript: + specifier: 'catalog:' + version: 5.8.3 packages/typescript-config: {} @@ -480,13 +538,49 @@ importers: tests/e2e: dependencies: + '@paralleldrive/cuid2': + specifier: ^2.2.2 + version: 2.2.2 + '@zenstackhq/cli': + specifier: workspace:* + version: link:../../packages/cli + '@zenstackhq/language': + specifier: workspace:* + version: link:../../packages/language + '@zenstackhq/plugin-policy': + specifier: workspace:* + version: link:../../packages/plugins/policy + '@zenstackhq/runtime': + specifier: workspace:* + version: link:../../packages/runtime + '@zenstackhq/sdk': + specifier: workspace:* + version: link:../../packages/sdk '@zenstackhq/testtools': specifier: workspace:* version: link:../../packages/testtools + better-sqlite3: + specifier: 'catalog:' + version: 12.2.0 + decimal.js: + specifier: ^10.4.3 + version: 10.4.3 + kysely: + specifier: 'catalog:' + version: 0.27.6 + ulid: + specifier: ^3.0.0 + version: 3.0.0 + uuid: + specifier: ^11.0.5 + version: 11.0.5 devDependencies: - '@zenstackhq/cli': + '@types/uuid': + specifier: ^11.0.0 + version: 11.0.0 + '@zenstackhq/typescript-config': specifier: workspace:* - version: link:../../packages/cli + version: link:../../packages/typescript-config '@zenstackhq/vitest-config': specifier: workspace:* version: link:../../packages/vitest-config @@ -1177,6 +1271,10 @@ 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==} @@ -1419,6 +1517,9 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -1459,6 +1560,13 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + copyfiles@2.4.1: + resolution: {integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==} + hasBin: true + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1563,6 +1671,10 @@ packages: engines: {node: '>=18'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -1687,6 +1799,9 @@ packages: resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} engines: {node: '>=14.14'} + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1695,6 +1810,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -1733,6 +1852,10 @@ packages: engines: {node: 20 || >=22} hasBin: true + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -1785,6 +1908,10 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1815,6 +1942,12 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -1981,6 +2114,11 @@ packages: mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} @@ -2013,6 +2151,9 @@ packages: node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + noms@0.0.0: + resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} + nypm@0.6.1: resolution: {integrity: sha512-hlacBiRiv1k9hZFiphPUkfSQ/ZfQzZDzC+8z0wL3lvDAOUu/2NnChkKuMoMjNur/9OpKuz2QsIeiPVN0xM5Q0w==} engines: {node: ^14.16.0 || >=16.10.0} @@ -2069,6 +2210,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -2091,11 +2236,11 @@ packages: perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} - pg-cloudflare@1.1.1: - resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} + pg-cloudflare@1.2.7: + resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} - pg-connection-string@2.7.0: - resolution: {integrity: sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==} + pg-connection-string@2.9.1: + resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} @@ -2105,13 +2250,13 @@ packages: resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} engines: {node: '>=4'} - pg-pool@3.7.0: - resolution: {integrity: sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==} + pg-pool@3.10.1: + resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} peerDependencies: pg: '>=8.0' - pg-protocol@1.7.0: - resolution: {integrity: sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==} + pg-protocol@1.10.3: + resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} @@ -2121,9 +2266,9 @@ packages: resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} engines: {node: '>=10'} - pg@8.13.1: - resolution: {integrity: sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==} - engines: {node: '>= 8.0.0'} + pg@8.16.3: + resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} + engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' peerDependenciesMeta: @@ -2239,6 +2384,9 @@ packages: typescript: optional: true + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -2266,6 +2414,12 @@ packages: resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} engines: {node: '>=0.10.0'} + readable-stream@1.0.34: + resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -2274,6 +2428,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2301,6 +2459,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -2367,6 +2528,12 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -2412,6 +2579,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -2563,6 +2733,10 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -2708,11 +2882,23 @@ packages: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yaml@2.8.0: resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} engines: {node: '>= 14.6'} hasBin: true + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -3177,7 +3363,7 @@ snapshots: '@types/pg@8.11.11': dependencies: '@types/node': 20.17.24 - pg-protocol: 1.7.0 + pg-protocol: 1.10.3 pg-types: 4.0.2 '@types/pluralize@0.0.33': {} @@ -3193,6 +3379,10 @@ snapshots: '@types/toposort@2.0.7': {} + '@types/uuid@11.0.0': + dependencies: + uuid: 11.0.5 + '@types/vscode@1.101.0': {} '@typescript-eslint/eslint-plugin@8.34.1(@typescript-eslint/parser@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': @@ -3493,6 +3683,12 @@ snapshots: cli-spinners@2.9.2: {} + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clone@1.0.4: {} color-convert@2.0.1: @@ -3517,6 +3713,18 @@ snapshots: consola@3.4.2: {} + copyfiles@2.4.1: + dependencies: + glob: 7.2.3 + minimatch: 3.1.2 + mkdirp: 1.0.4 + noms: 0.0.0 + through2: 2.0.5 + untildify: 4.0.0 + yargs: 16.2.0 + + core-util-is@1.0.3: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -3647,6 +3855,8 @@ snapshots: '@esbuild/win32-ia32': 0.25.5 '@esbuild/win32-x64': 0.25.5 + escalade@3.2.0: {} + escape-string-regexp@4.0.0: {} eslint-scope@8.4.0: @@ -3795,11 +4005,15 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true function-bind@1.1.2: {} + get-caller-file@2.0.5: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -3863,6 +4077,15 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 2.0.0 + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + globals@14.0.0: {} gopd@1.2.0: {} @@ -3903,6 +4126,11 @@ snapshots: imurmurhash@0.1.4: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + inherits@2.0.4: {} ini@1.3.8: {} @@ -3921,6 +4149,10 @@ snapshots: is-unicode-supported@0.1.0: {} + isarray@0.0.1: {} + + isarray@1.0.0: {} + isarray@2.0.5: {} isexe@2.0.0: {} @@ -4077,6 +4309,8 @@ snapshots: mkdirp-classic@0.5.3: {} + mkdirp@1.0.4: {} + mlly@1.7.4: dependencies: acorn: 8.15.0 @@ -4106,6 +4340,11 @@ snapshots: node-fetch-native@1.6.7: {} + noms@0.0.0: + dependencies: + inherits: 2.0.4 + readable-stream: 1.0.34 + nypm@0.6.1: dependencies: citty: 0.1.6 @@ -4169,6 +4408,8 @@ snapshots: path-exists@4.0.0: {} + path-is-absolute@1.0.1: {} + path-key@3.1.1: {} path-scurry@1.11.1: @@ -4187,20 +4428,20 @@ snapshots: perfect-debounce@1.0.0: {} - pg-cloudflare@1.1.1: + pg-cloudflare@1.2.7: optional: true - pg-connection-string@2.7.0: {} + pg-connection-string@2.9.1: {} pg-int8@1.0.1: {} pg-numeric@1.0.2: {} - pg-pool@3.7.0(pg@8.13.1): + pg-pool@3.10.1(pg@8.16.3): dependencies: - pg: 8.13.1 + pg: 8.16.3 - pg-protocol@1.7.0: {} + pg-protocol@1.10.3: {} pg-types@2.2.0: dependencies: @@ -4220,15 +4461,15 @@ snapshots: postgres-interval: 3.0.0 postgres-range: 1.1.4 - pg@8.13.1: + pg@8.16.3: dependencies: - pg-connection-string: 2.7.0 - pg-pool: 3.7.0(pg@8.13.1) - pg-protocol: 1.7.0 + pg-connection-string: 2.9.1 + pg-pool: 3.10.1(pg@8.16.3) + pg-protocol: 1.10.3 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: - pg-cloudflare: 1.1.1 + pg-cloudflare: 1.2.7 pgpass@1.0.5: dependencies: @@ -4321,6 +4562,8 @@ snapshots: transitivePeerDependencies: - magicast + process-nextick-args@2.0.1: {} + pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -4348,6 +4591,23 @@ snapshots: react@19.1.0: {} + readable-stream@1.0.34: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -4356,6 +4616,8 @@ snapshots: readdirp@4.1.2: {} + require-directory@2.1.1: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -4399,6 +4661,8 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} semver@7.7.2: {} @@ -4458,6 +4722,12 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + string_decoder@0.10.31: {} + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -4515,6 +4785,11 @@ snapshots: dependencies: any-promise: 1.3.0 + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -4652,6 +4927,8 @@ snapshots: universalify@2.0.1: {} + untildify@4.0.0: {} + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -4799,8 +5076,22 @@ snapshots: xtend@4.0.2: {} + y18n@5.0.8: {} + yaml@2.8.0: {} + yargs-parser@20.2.9: {} + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + yocto-queue@0.1.0: {} zod-validation-error@4.0.1(zod@3.25.76): diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index d54970c6..9dc25b4c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,3 +14,5 @@ catalog: tmp: ^0.2.3 '@types/tmp': ^0.2.6 'zod-validation-error': ^4.0.1 + 'better-sqlite3': ^12.2.0 + 'pg': ^8.13.1 diff --git a/tests/e2e/cal.com/cal-com.test.ts b/tests/e2e/github-repos/cal.com/cal-com.test.ts similarity index 100% rename from tests/e2e/cal.com/cal-com.test.ts rename to tests/e2e/github-repos/cal.com/cal-com.test.ts diff --git a/tests/e2e/cal.com/schema.zmodel b/tests/e2e/github-repos/cal.com/schema.zmodel similarity index 100% rename from tests/e2e/cal.com/schema.zmodel rename to tests/e2e/github-repos/cal.com/schema.zmodel diff --git a/tests/e2e/formbricks/formbricks.test.ts b/tests/e2e/github-repos/formbricks/formbricks.test.ts similarity index 100% rename from tests/e2e/formbricks/formbricks.test.ts rename to tests/e2e/github-repos/formbricks/formbricks.test.ts diff --git a/tests/e2e/formbricks/schema.zmodel b/tests/e2e/github-repos/formbricks/schema.zmodel similarity index 100% rename from tests/e2e/formbricks/schema.zmodel rename to tests/e2e/github-repos/formbricks/schema.zmodel diff --git a/tests/e2e/trigger.dev/schema.zmodel b/tests/e2e/github-repos/trigger.dev/schema.zmodel similarity index 100% rename from tests/e2e/trigger.dev/schema.zmodel rename to tests/e2e/github-repos/trigger.dev/schema.zmodel diff --git a/tests/e2e/trigger.dev/trigger-dev.test.ts b/tests/e2e/github-repos/trigger.dev/trigger-dev.test.ts similarity index 100% rename from tests/e2e/trigger.dev/trigger-dev.test.ts rename to tests/e2e/github-repos/trigger.dev/trigger-dev.test.ts diff --git a/packages/runtime/test/client-api/aggregate.test.ts b/tests/e2e/orm/client-api/aggregate.test.ts similarity index 97% rename from packages/runtime/test/client-api/aggregate.test.ts rename to tests/e2e/orm/client-api/aggregate.test.ts index 6b7edd64..9c1d2a1f 100644 --- a/packages/runtime/test/client-api/aggregate.test.ts +++ b/tests/e2e/orm/client-api/aggregate.test.ts @@ -1,8 +1,8 @@ +import type { ClientContract } from '@zenstackhq/runtime'; +import { createTestClient } from '@zenstackhq/testtools'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; import { schema } from '../schemas/basic'; import { createUser } from './utils'; -import { createTestClient } from '../utils'; describe('Client aggregate tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/compound-id.test.ts b/tests/e2e/orm/client-api/compound-id.test.ts similarity index 99% rename from packages/runtime/test/client-api/compound-id.test.ts rename to tests/e2e/orm/client-api/compound-id.test.ts index 88457467..b983b045 100644 --- a/packages/runtime/test/client-api/compound-id.test.ts +++ b/tests/e2e/orm/client-api/compound-id.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Compound ID tests', () => { describe('to-one relation', () => { diff --git a/packages/runtime/test/client-api/computed-fields.test.ts b/tests/e2e/orm/client-api/computed-fields.test.ts similarity index 98% rename from packages/runtime/test/client-api/computed-fields.test.ts rename to tests/e2e/orm/client-api/computed-fields.test.ts index 0ece9ddf..4969d21d 100644 --- a/packages/runtime/test/client-api/computed-fields.test.ts +++ b/tests/e2e/orm/client-api/computed-fields.test.ts @@ -1,6 +1,6 @@ -import { sql } from 'kysely'; +import { sql } from '@zenstackhq/runtime/helpers'; +import { createTestClient } from '@zenstackhq/testtools'; import { afterEach, describe, expect, it } from 'vitest'; -import { createTestClient } from '../utils'; describe('Computed fields tests', () => { let db: any; diff --git a/packages/runtime/test/client-api/count.test.ts b/tests/e2e/orm/client-api/count.test.ts similarity index 94% rename from packages/runtime/test/client-api/count.test.ts rename to tests/e2e/orm/client-api/count.test.ts index 22a89ddc..78050b95 100644 --- a/packages/runtime/test/client-api/count.test.ts +++ b/tests/e2e/orm/client-api/count.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client count tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/create-many-and-return.test.ts b/tests/e2e/orm/client-api/create-many-and-return.test.ts similarity index 95% rename from packages/runtime/test/client-api/create-many-and-return.test.ts rename to tests/e2e/orm/client-api/create-many-and-return.test.ts index be2a46e8..3b93ce22 100644 --- a/packages/runtime/test/client-api/create-many-and-return.test.ts +++ b/tests/e2e/orm/client-api/create-many-and-return.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client createManyAndReturn tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/create-many.test.ts b/tests/e2e/orm/client-api/create-many.test.ts similarity index 93% rename from packages/runtime/test/client-api/create-many.test.ts rename to tests/e2e/orm/client-api/create-many.test.ts index 3ccbbe73..961f3c36 100644 --- a/packages/runtime/test/client-api/create-many.test.ts +++ b/tests/e2e/orm/client-api/create-many.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client createMany tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/create.test.ts b/tests/e2e/orm/client-api/create.test.ts similarity index 98% rename from packages/runtime/test/client-api/create.test.ts rename to tests/e2e/orm/client-api/create.test.ts index 41ab341c..72e2ad7a 100644 --- a/packages/runtime/test/client-api/create.test.ts +++ b/tests/e2e/orm/client-api/create.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client create tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/default-values.test.ts b/tests/e2e/orm/client-api/default-values.test.ts similarity index 96% rename from packages/runtime/test/client-api/default-values.test.ts rename to tests/e2e/orm/client-api/default-values.test.ts index 1e257a10..73349e59 100644 --- a/packages/runtime/test/client-api/default-values.test.ts +++ b/tests/e2e/orm/client-api/default-values.test.ts @@ -1,11 +1,11 @@ import { isCuid } from '@paralleldrive/cuid2'; +import { ZenStackClient } from '@zenstackhq/runtime'; +import { ExpressionUtils, type SchemaDef } from '@zenstackhq/runtime/schema'; import SQLite from 'better-sqlite3'; import { SqliteDialect } from 'kysely'; import { isValid as isValidUlid } from 'ulid'; import { validate as isValidUuid } from 'uuid'; import { describe, expect, it } from 'vitest'; -import { ZenStackClient } from '../../src'; -import { ExpressionUtils, type SchemaDef } from '../../src/schema'; const schema = { provider: { diff --git a/packages/runtime/test/client-api/delegate.test.ts b/tests/e2e/orm/client-api/delegate.test.ts similarity index 99% rename from packages/runtime/test/client-api/delegate.test.ts rename to tests/e2e/orm/client-api/delegate.test.ts index d9efff6f..8d5cfbb9 100644 --- a/packages/runtime/test/client-api/delegate.test.ts +++ b/tests/e2e/orm/client-api/delegate.test.ts @@ -1,8 +1,8 @@ import path from 'node:path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema, type SchemaType } from '../schemas/delegate/schema'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Delegate model tests ', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/delete-many.test.ts b/tests/e2e/orm/client-api/delete-many.test.ts similarity index 94% rename from packages/runtime/test/client-api/delete-many.test.ts rename to tests/e2e/orm/client-api/delete-many.test.ts index b31896f0..d80f2f93 100644 --- a/packages/runtime/test/client-api/delete-many.test.ts +++ b/tests/e2e/orm/client-api/delete-many.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client deleteMany tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/delete.test.ts b/tests/e2e/orm/client-api/delete.test.ts similarity index 92% rename from packages/runtime/test/client-api/delete.test.ts rename to tests/e2e/orm/client-api/delete.test.ts index 4e518c07..668f3b9f 100644 --- a/packages/runtime/test/client-api/delete.test.ts +++ b/tests/e2e/orm/client-api/delete.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client delete tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/filter.test.ts b/tests/e2e/orm/client-api/filter.test.ts similarity index 99% rename from packages/runtime/test/client-api/filter.test.ts rename to tests/e2e/orm/client-api/filter.test.ts index 26af9dd7..fd1335fe 100644 --- a/packages/runtime/test/client-api/filter.test.ts +++ b/tests/e2e/orm/client-api/filter.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client filter tests ', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/find.test.ts b/tests/e2e/orm/client-api/find.test.ts similarity index 99% rename from packages/runtime/test/client-api/find.test.ts rename to tests/e2e/orm/client-api/find.test.ts index 1f8219ec..6d188843 100644 --- a/packages/runtime/test/client-api/find.test.ts +++ b/tests/e2e/orm/client-api/find.test.ts @@ -1,8 +1,8 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; -import { InputValidationError, NotFoundError } from '../../src/client/errors'; +import type { ClientContract } from '@zenstackhq/runtime'; +import { InputValidationError, NotFoundError } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; import { createPosts, createUser } from './utils'; describe('Client find tests ', () => { diff --git a/packages/runtime/test/client-api/group-by.test.ts b/tests/e2e/orm/client-api/group-by.test.ts similarity index 98% rename from packages/runtime/test/client-api/group-by.test.ts rename to tests/e2e/orm/client-api/group-by.test.ts index b0909e34..08da59fe 100644 --- a/packages/runtime/test/client-api/group-by.test.ts +++ b/tests/e2e/orm/client-api/group-by.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; import { createPosts, createUser } from './utils'; describe('Client groupBy tests', () => { diff --git a/packages/runtime/test/client-api/import.test.ts b/tests/e2e/orm/client-api/import.test.ts similarity index 97% rename from packages/runtime/test/client-api/import.test.ts rename to tests/e2e/orm/client-api/import.test.ts index 98e43f77..9e7657f8 100644 --- a/packages/runtime/test/client-api/import.test.ts +++ b/tests/e2e/orm/client-api/import.test.ts @@ -2,7 +2,7 @@ import { createTestProject, generateTsSchemaInPlace } from '@zenstackhq/testtool import fs from 'node:fs'; import path from 'node:path'; import { describe, expect, it } from 'vitest'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Import tests', () => { it('works with imported models', async () => { diff --git a/packages/runtime/test/client-api/mixin.test.ts b/tests/e2e/orm/client-api/mixin.test.ts similarity index 98% rename from packages/runtime/test/client-api/mixin.test.ts rename to tests/e2e/orm/client-api/mixin.test.ts index e7b9dcac..1e6d0f41 100644 --- a/packages/runtime/test/client-api/mixin.test.ts +++ b/tests/e2e/orm/client-api/mixin.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Mixin tests', () => { it('includes fields and attributes from mixins', async () => { diff --git a/packages/runtime/test/client-api/name-mapping.test.ts b/tests/e2e/orm/client-api/name-mapping.test.ts similarity index 99% rename from packages/runtime/test/client-api/name-mapping.test.ts rename to tests/e2e/orm/client-api/name-mapping.test.ts index cfb9bec2..3fafc038 100644 --- a/packages/runtime/test/client-api/name-mapping.test.ts +++ b/tests/e2e/orm/client-api/name-mapping.test.ts @@ -1,8 +1,8 @@ import path from 'node:path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema, type SchemaType } from '../schemas/name-mapping/schema'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Name mapping tests', () => { let db: ClientContract; diff --git a/packages/runtime/test/client-api/raw-query.test.ts b/tests/e2e/orm/client-api/raw-query.test.ts similarity index 95% rename from packages/runtime/test/client-api/raw-query.test.ts rename to tests/e2e/orm/client-api/raw-query.test.ts index f7838641..517dfb49 100644 --- a/packages/runtime/test/client-api/raw-query.test.ts +++ b/tests/e2e/orm/client-api/raw-query.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client raw query tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/relation/many-to-many.test.ts b/tests/e2e/orm/client-api/relation/many-to-many.test.ts similarity index 99% rename from packages/runtime/test/client-api/relation/many-to-many.test.ts rename to tests/e2e/orm/client-api/relation/many-to-many.test.ts index dd1eacf0..c6fdb2c5 100644 --- a/packages/runtime/test/client-api/relation/many-to-many.test.ts +++ b/tests/e2e/orm/client-api/relation/many-to-many.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { createTestClient } from '../../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Many-to-many relation tests', () => { let client: any; diff --git a/packages/runtime/test/client-api/relation/one-to-many.test.ts b/tests/e2e/orm/client-api/relation/one-to-many.test.ts similarity index 97% rename from packages/runtime/test/client-api/relation/one-to-many.test.ts rename to tests/e2e/orm/client-api/relation/one-to-many.test.ts index be847d5e..377b8e21 100644 --- a/packages/runtime/test/client-api/relation/one-to-many.test.ts +++ b/tests/e2e/orm/client-api/relation/one-to-many.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it } from 'vitest'; -import { createTestClient } from '../../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('One-to-many relation tests ', () => { let client: any; diff --git a/packages/runtime/test/client-api/relation/one-to-one.test.ts b/tests/e2e/orm/client-api/relation/one-to-one.test.ts similarity index 97% rename from packages/runtime/test/client-api/relation/one-to-one.test.ts rename to tests/e2e/orm/client-api/relation/one-to-one.test.ts index e41a0cf9..961961aa 100644 --- a/packages/runtime/test/client-api/relation/one-to-one.test.ts +++ b/tests/e2e/orm/client-api/relation/one-to-one.test.ts @@ -1,5 +1,5 @@ +import { createTestClient } from '@zenstackhq/testtools'; import { afterEach, describe, expect, it } from 'vitest'; -import { createTestClient } from '../../utils'; const TEST_DB = 'client-api-relation-test-one-to-one'; diff --git a/packages/runtime/test/client-api/relation/self-relation.test.ts b/tests/e2e/orm/client-api/relation/self-relation.test.ts similarity index 99% rename from packages/runtime/test/client-api/relation/self-relation.test.ts rename to tests/e2e/orm/client-api/relation/self-relation.test.ts index 65380b30..9e70ca00 100644 --- a/packages/runtime/test/client-api/relation/self-relation.test.ts +++ b/tests/e2e/orm/client-api/relation/self-relation.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it } from 'vitest'; -import { createTestClient } from '../../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Self relation tests', () => { let client: any; diff --git a/packages/runtime/test/client-api/scalar-list.test.ts b/tests/e2e/orm/client-api/scalar-list.test.ts similarity index 99% rename from packages/runtime/test/client-api/scalar-list.test.ts rename to tests/e2e/orm/client-api/scalar-list.test.ts index c9bfb0fc..22ea5d2f 100644 --- a/packages/runtime/test/client-api/scalar-list.test.ts +++ b/tests/e2e/orm/client-api/scalar-list.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Scalar list tests', () => { const schema = ` diff --git a/packages/runtime/test/client-api/transaction.test.ts b/tests/e2e/orm/client-api/transaction.test.ts similarity index 97% rename from packages/runtime/test/client-api/transaction.test.ts rename to tests/e2e/orm/client-api/transaction.test.ts index c235420a..98f7a49c 100644 --- a/packages/runtime/test/client-api/transaction.test.ts +++ b/tests/e2e/orm/client-api/transaction.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client raw query tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/type-coverage.test.ts b/tests/e2e/orm/client-api/type-coverage.test.ts similarity index 98% rename from packages/runtime/test/client-api/type-coverage.test.ts rename to tests/e2e/orm/client-api/type-coverage.test.ts index 1055c712..9ce29fce 100644 --- a/packages/runtime/test/client-api/type-coverage.test.ts +++ b/tests/e2e/orm/client-api/type-coverage.test.ts @@ -1,6 +1,6 @@ import Decimal from 'decimal.js'; import { describe, expect, it } from 'vitest'; -import { createTestClient, getTestDbProvider } from '../utils'; +import { createTestClient, getTestDbProvider } from '@zenstackhq/testtools'; describe('Zmodel type coverage tests', () => { it('supports all types - plain', async () => { diff --git a/packages/runtime/test/client-api/typed-json-fields.test.ts b/tests/e2e/orm/client-api/typed-json-fields.test.ts similarity index 98% rename from packages/runtime/test/client-api/typed-json-fields.test.ts rename to tests/e2e/orm/client-api/typed-json-fields.test.ts index 65757169..a213c1d8 100644 --- a/packages/runtime/test/client-api/typed-json-fields.test.ts +++ b/tests/e2e/orm/client-api/typed-json-fields.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Typed JSON fields', () => { const schema = ` diff --git a/packages/runtime/test/client-api/undefined-values.test.ts b/tests/e2e/orm/client-api/undefined-values.test.ts similarity index 90% rename from packages/runtime/test/client-api/undefined-values.test.ts rename to tests/e2e/orm/client-api/undefined-values.test.ts index 74d2851b..240ad1f4 100644 --- a/packages/runtime/test/client-api/undefined-values.test.ts +++ b/tests/e2e/orm/client-api/undefined-values.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; import { createUser } from './utils'; describe('Client undefined values tests ', () => { diff --git a/packages/runtime/test/client-api/update-many.test.ts b/tests/e2e/orm/client-api/update-many.test.ts similarity index 96% rename from packages/runtime/test/client-api/update-many.test.ts rename to tests/e2e/orm/client-api/update-many.test.ts index 934154fe..b37abf35 100644 --- a/packages/runtime/test/client-api/update-many.test.ts +++ b/tests/e2e/orm/client-api/update-many.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client updateMany tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/update.test.ts b/tests/e2e/orm/client-api/update.test.ts similarity index 99% rename from packages/runtime/test/client-api/update.test.ts rename to tests/e2e/orm/client-api/update.test.ts index 82ec4a5a..ab39d706 100644 --- a/packages/runtime/test/client-api/update.test.ts +++ b/tests/e2e/orm/client-api/update.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; import { createUser } from './utils'; describe('Client update tests', () => { diff --git a/packages/runtime/test/client-api/upsert.test.ts b/tests/e2e/orm/client-api/upsert.test.ts similarity index 94% rename from packages/runtime/test/client-api/upsert.test.ts rename to tests/e2e/orm/client-api/upsert.test.ts index cbb16d65..14f418b3 100644 --- a/packages/runtime/test/client-api/upsert.test.ts +++ b/tests/e2e/orm/client-api/upsert.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client upsert tests', () => { let client: ClientContract; diff --git a/packages/runtime/test/client-api/utils.ts b/tests/e2e/orm/client-api/utils.ts similarity index 92% rename from packages/runtime/test/client-api/utils.ts rename to tests/e2e/orm/client-api/utils.ts index 2f1b85d0..11fd2090 100644 --- a/packages/runtime/test/client-api/utils.ts +++ b/tests/e2e/orm/client-api/utils.ts @@ -1,4 +1,4 @@ -import type { ClientContract } from '../../src/client'; +import type { ClientContract } from '@zenstackhq/runtime'; import type { schema } from '../schemas/basic'; type ClientType = ClientContract; diff --git a/packages/runtime/test/plugin-infra/entity-mutation-hooks.test.ts b/tests/e2e/orm/plugin-infra/entity-mutation-hooks.test.ts similarity index 99% rename from packages/runtime/test/plugin-infra/entity-mutation-hooks.test.ts rename to tests/e2e/orm/plugin-infra/entity-mutation-hooks.test.ts index 9172d0f5..63133e65 100644 --- a/packages/runtime/test/plugin-infra/entity-mutation-hooks.test.ts +++ b/tests/e2e/orm/plugin-infra/entity-mutation-hooks.test.ts @@ -1,8 +1,8 @@ +import { type ClientContract } from '@zenstackhq/runtime'; +import { createTestClient } from '@zenstackhq/testtools'; import { DeleteQueryNode, InsertQueryNode, UpdateQueryNode } from 'kysely'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { type ClientContract } from '../../src'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; describe('Entity mutation hooks tests', () => { let _client: ClientContract; diff --git a/packages/runtime/test/plugin-infra/on-kysely-query.test.ts b/tests/e2e/orm/plugin-infra/on-kysely-query.test.ts similarity index 98% rename from packages/runtime/test/plugin-infra/on-kysely-query.test.ts rename to tests/e2e/orm/plugin-infra/on-kysely-query.test.ts index 4fe5855d..8d7d0507 100644 --- a/packages/runtime/test/plugin-infra/on-kysely-query.test.ts +++ b/tests/e2e/orm/plugin-infra/on-kysely-query.test.ts @@ -1,8 +1,8 @@ +import { type ClientContract } from '@zenstackhq/runtime'; +import { createTestClient } from '@zenstackhq/testtools'; import { InsertQueryNode, Kysely, PrimitiveValueListNode, ValuesNode, type QueryResult } from 'kysely'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { type ClientContract } from '../../src/client'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; describe('On kysely query tests', () => { let _client: ClientContract; diff --git a/packages/runtime/test/plugin-infra/on-query-hooks.test.ts b/tests/e2e/orm/plugin-infra/on-query-hooks.test.ts similarity index 98% rename from packages/runtime/test/plugin-infra/on-query-hooks.test.ts rename to tests/e2e/orm/plugin-infra/on-query-hooks.test.ts index 3a6df8ca..90073ab5 100644 --- a/packages/runtime/test/plugin-infra/on-query-hooks.test.ts +++ b/tests/e2e/orm/plugin-infra/on-query-hooks.test.ts @@ -1,7 +1,7 @@ +import { definePlugin, type ClientContract } from '@zenstackhq/runtime'; +import { createTestClient } from '@zenstackhq/testtools'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { definePlugin, type ClientContract } from '../../src/client'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; describe('On query hooks tests', () => { let _client: ClientContract; diff --git a/packages/runtime/test/policy/auth-equality.test.ts b/tests/e2e/orm/policy/auth-equality.test.ts similarity index 97% rename from packages/runtime/test/policy/auth-equality.test.ts rename to tests/e2e/orm/policy/auth-equality.test.ts index 2baf46ed..ebf9fd1a 100644 --- a/packages/runtime/test/policy/auth-equality.test.ts +++ b/tests/e2e/orm/policy/auth-equality.test.ts @@ -1,5 +1,5 @@ +import { createPolicyTestClient } from '@zenstackhq/testtools'; import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from './utils'; describe('Reference Equality Tests', () => { it('works with create and auth equality', async () => { diff --git a/packages/runtime/test/policy/basic-schema-read.test.ts b/tests/e2e/orm/policy/basic-schema-read.test.ts similarity index 90% rename from packages/runtime/test/policy/basic-schema-read.test.ts rename to tests/e2e/orm/policy/basic-schema-read.test.ts index c8b8c87e..40eb2bef 100644 --- a/packages/runtime/test/policy/basic-schema-read.test.ts +++ b/tests/e2e/orm/policy/basic-schema-read.test.ts @@ -1,8 +1,8 @@ +import { PolicyPlugin } from '@zenstackhq/plugin-policy'; +import { type ClientContract } from '@zenstackhq/runtime'; +import { createTestClient } from '@zenstackhq/testtools'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { type ClientContract } from '../../src/client'; -import { PolicyPlugin } from '../../src/plugins/policy/plugin'; import { schema } from '../schemas/basic'; -import { createTestClient } from '../utils'; describe('Read policy tests', () => { let client: ClientContract; @@ -23,7 +23,7 @@ describe('Read policy tests', () => { }); // anonymous auth context by default - const anonClient = client.$use(new PolicyPlugin()); + const anonClient = client.$use(new PolicyPlugin()); await expect(anonClient.user.findFirst()).toResolveNull(); const authClient = anonClient.$setAuth({ diff --git a/packages/runtime/test/policy/crud/create.test.ts b/tests/e2e/orm/policy/crud/create.test.ts similarity index 99% rename from packages/runtime/test/policy/crud/create.test.ts rename to tests/e2e/orm/policy/crud/create.test.ts index d5eb0657..67b01500 100644 --- a/packages/runtime/test/policy/crud/create.test.ts +++ b/tests/e2e/orm/policy/crud/create.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy create tests', () => { it('works with scalar field check', async () => { diff --git a/packages/runtime/test/policy/crud/delete.test.ts b/tests/e2e/orm/policy/crud/delete.test.ts similarity index 96% rename from packages/runtime/test/policy/crud/delete.test.ts rename to tests/e2e/orm/policy/crud/delete.test.ts index f515f0dc..1572d521 100644 --- a/packages/runtime/test/policy/crud/delete.test.ts +++ b/tests/e2e/orm/policy/crud/delete.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Delete policy tests', () => { it('works with top-level delete/deleteMany', async () => { diff --git a/packages/runtime/test/policy/crud/dumb-rules.test.ts b/tests/e2e/orm/policy/crud/dumb-rules.test.ts similarity index 94% rename from packages/runtime/test/policy/crud/dumb-rules.test.ts rename to tests/e2e/orm/policy/crud/dumb-rules.test.ts index b169e3a0..6b9e1f81 100644 --- a/packages/runtime/test/policy/crud/dumb-rules.test.ts +++ b/tests/e2e/orm/policy/crud/dumb-rules.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy dumb rules tests', () => { it('works with create dumb rules', async () => { diff --git a/packages/runtime/test/policy/crud/post-update.test.ts b/tests/e2e/orm/policy/crud/post-update.test.ts similarity index 99% rename from packages/runtime/test/policy/crud/post-update.test.ts rename to tests/e2e/orm/policy/crud/post-update.test.ts index 98c2b5b5..dfaa8599 100644 --- a/packages/runtime/test/policy/crud/post-update.test.ts +++ b/tests/e2e/orm/policy/crud/post-update.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy post-update tests', () => { it('allows post-update by default', async () => { diff --git a/packages/runtime/test/policy/crud/read.test.ts b/tests/e2e/orm/policy/crud/read.test.ts similarity index 99% rename from packages/runtime/test/policy/crud/read.test.ts rename to tests/e2e/orm/policy/crud/read.test.ts index 46f4e38b..d57d6385 100644 --- a/packages/runtime/test/policy/crud/read.test.ts +++ b/tests/e2e/orm/policy/crud/read.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Read policy tests', () => { describe('Find tests', () => { diff --git a/packages/runtime/test/policy/crud/update.test.ts b/tests/e2e/orm/policy/crud/update.test.ts similarity index 99% rename from packages/runtime/test/policy/crud/update.test.ts rename to tests/e2e/orm/policy/crud/update.test.ts index c092682b..9a83577f 100644 --- a/packages/runtime/test/policy/crud/update.test.ts +++ b/tests/e2e/orm/policy/crud/update.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Update policy tests', () => { describe('Scalar condition tests', () => { diff --git a/packages/runtime/test/policy/migrated/auth.test.ts b/tests/e2e/orm/policy/migrated/auth.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/auth.test.ts rename to tests/e2e/orm/policy/migrated/auth.test.ts index d075e3d7..fb8f30de 100644 --- a/packages/runtime/test/policy/migrated/auth.test.ts +++ b/tests/e2e/orm/policy/migrated/auth.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('auth() tests', () => { it('works with string id non-null test', async () => { diff --git a/packages/runtime/test/policy/migrated/client-extensions.test.ts b/tests/e2e/orm/policy/migrated/client-extensions.test.ts similarity index 97% rename from packages/runtime/test/policy/migrated/client-extensions.test.ts rename to tests/e2e/orm/policy/migrated/client-extensions.test.ts index 16692543..c62f49f9 100644 --- a/packages/runtime/test/policy/migrated/client-extensions.test.ts +++ b/tests/e2e/orm/policy/migrated/client-extensions.test.ts @@ -1,6 +1,6 @@ +import { definePlugin } from '@zenstackhq/runtime'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; import { describe, expect, it } from 'vitest'; -import { definePlugin } from '../../../src/client'; -import { createPolicyTestClient } from '../utils'; describe('client extensions tests for policies', () => { it('query override one model', async () => { diff --git a/packages/runtime/test/policy/migrated/connect-disconnect.test.ts b/tests/e2e/orm/policy/migrated/connect-disconnect.test.ts similarity index 97% rename from packages/runtime/test/policy/migrated/connect-disconnect.test.ts rename to tests/e2e/orm/policy/migrated/connect-disconnect.test.ts index 02d8e04e..ec338727 100644 --- a/packages/runtime/test/policy/migrated/connect-disconnect.test.ts +++ b/tests/e2e/orm/policy/migrated/connect-disconnect.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('connect and disconnect tests', () => { const modelToMany = ` @@ -302,8 +302,7 @@ describe('connect and disconnect tests', () => { } `; - // TODO: many-to-many support - it.skip('works with implicit many-to-many', async () => { + it('works with implicit many-to-many', async () => { const db = await createPolicyTestClient(modelImplicitManyToMany); const rawDb = db.$unuseAll(); @@ -350,8 +349,7 @@ describe('connect and disconnect tests', () => { } `; - // TODO: many-to-many support - it.skip('works with explicit many-to-many', async () => { + it('works with explicit many-to-many', async () => { const db = await createPolicyTestClient(modelExplicitManyToMany); const rawDb = db.$unuseAll(); diff --git a/packages/runtime/test/policy/migrated/create-many-and-return.test.ts b/tests/e2e/orm/policy/migrated/create-many-and-return.test.ts similarity index 97% rename from packages/runtime/test/policy/migrated/create-many-and-return.test.ts rename to tests/e2e/orm/policy/migrated/create-many-and-return.test.ts index 1df0e5b6..5191853c 100644 --- a/packages/runtime/test/policy/migrated/create-many-and-return.test.ts +++ b/tests/e2e/orm/policy/migrated/create-many-and-return.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('createManyAndReturn tests', () => { it('works with model-level policies', async () => { diff --git a/packages/runtime/test/policy/migrated/cross-model-field-comparison.test.ts b/tests/e2e/orm/policy/migrated/cross-model-field-comparison.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/cross-model-field-comparison.test.ts rename to tests/e2e/orm/policy/migrated/cross-model-field-comparison.test.ts index f0a35f79..d7138794 100644 --- a/packages/runtime/test/policy/migrated/cross-model-field-comparison.test.ts +++ b/tests/e2e/orm/policy/migrated/cross-model-field-comparison.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('cross-model field comparison tests', () => { it('works with to-one relation', async () => { diff --git a/packages/runtime/test/policy/migrated/current-model.test.ts b/tests/e2e/orm/policy/migrated/current-model.test.ts similarity index 95% rename from packages/runtime/test/policy/migrated/current-model.test.ts rename to tests/e2e/orm/policy/migrated/current-model.test.ts index 61ea1d24..04c9a30a 100644 --- a/packages/runtime/test/policy/migrated/current-model.test.ts +++ b/tests/e2e/orm/policy/migrated/current-model.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('currentModel tests', () => { it('works in models', async () => { @@ -107,20 +107,19 @@ describe('currentModel tests', () => { await expect(db.POST.create({ data: { id: 1 } })).toBeRejectedByPolicy(); }); - // TODO: abstract base support - it.skip('works when inherited from abstract base', async () => { + it('works when inherited from abstract base', async () => { const db = await createPolicyTestClient( ` - abstract model Base { + type Base { id Int @id @@allow('read', true) @@allow('create', currentModel() == 'User') } - model User extends Base { + model User with Base { } - model Post extends Base { + model Post with Base { } `, ); diff --git a/packages/runtime/test/policy/migrated/current-operation.test.ts b/tests/e2e/orm/policy/migrated/current-operation.test.ts similarity index 98% rename from packages/runtime/test/policy/migrated/current-operation.test.ts rename to tests/e2e/orm/policy/migrated/current-operation.test.ts index 42d67939..2b1610c9 100644 --- a/packages/runtime/test/policy/migrated/current-operation.test.ts +++ b/tests/e2e/orm/policy/migrated/current-operation.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('currentOperation tests', () => { it('works with specific rules', async () => { diff --git a/packages/runtime/test/policy/migrated/deep-nested.test.ts b/tests/e2e/orm/policy/migrated/deep-nested.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/deep-nested.test.ts rename to tests/e2e/orm/policy/migrated/deep-nested.test.ts index a88134ce..6bd38e1f 100644 --- a/packages/runtime/test/policy/migrated/deep-nested.test.ts +++ b/tests/e2e/orm/policy/migrated/deep-nested.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('deep nested operations tests', () => { const model = ` diff --git a/packages/runtime/test/policy/migrated/empty-policy.test.ts b/tests/e2e/orm/policy/migrated/empty-policy.test.ts similarity index 98% rename from packages/runtime/test/policy/migrated/empty-policy.test.ts rename to tests/e2e/orm/policy/migrated/empty-policy.test.ts index 452845b3..970afb9e 100644 --- a/packages/runtime/test/policy/migrated/empty-policy.test.ts +++ b/tests/e2e/orm/policy/migrated/empty-policy.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('empty policy tests', () => { it('works with simple operations', async () => { diff --git a/packages/runtime/test/policy/migrated/field-comparison.test.ts b/tests/e2e/orm/policy/migrated/field-comparison.test.ts similarity index 97% rename from packages/runtime/test/policy/migrated/field-comparison.test.ts rename to tests/e2e/orm/policy/migrated/field-comparison.test.ts index 1bf33c37..33f6c124 100644 --- a/packages/runtime/test/policy/migrated/field-comparison.test.ts +++ b/tests/e2e/orm/policy/migrated/field-comparison.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('field comparison tests', () => { it('works with policies involving field comparison', async () => { diff --git a/packages/runtime/test/policy/migrated/multi-field-unique.test.ts b/tests/e2e/orm/policy/migrated/multi-field-unique.test.ts similarity index 98% rename from packages/runtime/test/policy/migrated/multi-field-unique.test.ts rename to tests/e2e/orm/policy/migrated/multi-field-unique.test.ts index fba22b09..bd2d25d0 100644 --- a/packages/runtime/test/policy/migrated/multi-field-unique.test.ts +++ b/tests/e2e/orm/policy/migrated/multi-field-unique.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { QueryError } from '../../../src'; -import { createPolicyTestClient } from '../utils'; +import { QueryError } from '@zenstackhq/runtime'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy tests multi-field unique', () => { it('toplevel crud test unnamed constraint', async () => { diff --git a/packages/runtime/test/policy/migrated/multi-id-fields.test.ts b/tests/e2e/orm/policy/migrated/multi-id-fields.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/multi-id-fields.test.ts rename to tests/e2e/orm/policy/migrated/multi-id-fields.test.ts index 9444fe20..0c3bdf2a 100644 --- a/packages/runtime/test/policy/migrated/multi-id-fields.test.ts +++ b/tests/e2e/orm/policy/migrated/multi-id-fields.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy tests multiple id fields', () => { it('multi-id fields crud', async () => { diff --git a/packages/runtime/test/policy/migrated/nested-to-many.test.ts b/tests/e2e/orm/policy/migrated/nested-to-many.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/nested-to-many.test.ts rename to tests/e2e/orm/policy/migrated/nested-to-many.test.ts index 03415119..e6402eb3 100644 --- a/packages/runtime/test/policy/migrated/nested-to-many.test.ts +++ b/tests/e2e/orm/policy/migrated/nested-to-many.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy tests to-many', () => { it('read filtering', async () => { diff --git a/packages/runtime/test/policy/migrated/nested-to-one.test.ts b/tests/e2e/orm/policy/migrated/nested-to-one.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/nested-to-one.test.ts rename to tests/e2e/orm/policy/migrated/nested-to-one.test.ts index 432c8065..1db22569 100644 --- a/packages/runtime/test/policy/migrated/nested-to-one.test.ts +++ b/tests/e2e/orm/policy/migrated/nested-to-one.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('With Policy:nested to-one', () => { it('read filtering for optional relation', async () => { diff --git a/packages/runtime/test/policy/migrated/omit.test.ts b/tests/e2e/orm/policy/migrated/omit.test.ts similarity index 95% rename from packages/runtime/test/policy/migrated/omit.test.ts rename to tests/e2e/orm/policy/migrated/omit.test.ts index 57fdd014..84761f5b 100644 --- a/packages/runtime/test/policy/migrated/omit.test.ts +++ b/tests/e2e/orm/policy/migrated/omit.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('prisma omit', () => { it('per query', async () => { @@ -48,7 +48,6 @@ describe('prisma omit', () => { found = await db.user.findFirst({ select: { value: true, profile: { omit: { level: true } } }, }); - console.log(found); expect(found.age).toBeUndefined(); expect(found.value).toEqual(10); expect(found.profile.level).toBeUndefined(); diff --git a/packages/runtime/test/policy/migrated/petstore-sample.test.ts b/tests/e2e/orm/policy/migrated/petstore-sample.test.ts similarity index 95% rename from packages/runtime/test/policy/migrated/petstore-sample.test.ts rename to tests/e2e/orm/policy/migrated/petstore-sample.test.ts index 2b210827..9b7bebcf 100644 --- a/packages/runtime/test/policy/migrated/petstore-sample.test.ts +++ b/tests/e2e/orm/policy/migrated/petstore-sample.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; import { schema } from '../../schemas/petstore/schema'; describe('Pet Store Policy Tests', () => { diff --git a/packages/runtime/test/policy/migrated/query-reduction.test.ts b/tests/e2e/orm/policy/migrated/query-reduction.test.ts similarity index 98% rename from packages/runtime/test/policy/migrated/query-reduction.test.ts rename to tests/e2e/orm/policy/migrated/query-reduction.test.ts index 61b11d06..253156b0 100644 --- a/packages/runtime/test/policy/migrated/query-reduction.test.ts +++ b/tests/e2e/orm/policy/migrated/query-reduction.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('With Policy: query reduction', () => { it('test query reduction', async () => { diff --git a/packages/runtime/test/policy/migrated/relation-check.test.ts b/tests/e2e/orm/policy/migrated/relation-check.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/relation-check.test.ts rename to tests/e2e/orm/policy/migrated/relation-check.test.ts index be0947aa..dfff4dee 100644 --- a/packages/runtime/test/policy/migrated/relation-check.test.ts +++ b/tests/e2e/orm/policy/migrated/relation-check.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Relation checker', () => { it('should work for read', async () => { diff --git a/packages/runtime/test/policy/migrated/relation-many-to-many-filter.test.ts b/tests/e2e/orm/policy/migrated/relation-many-to-many-filter.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/relation-many-to-many-filter.test.ts rename to tests/e2e/orm/policy/migrated/relation-many-to-many-filter.test.ts index 916f8c50..eba86029 100644 --- a/packages/runtime/test/policy/migrated/relation-many-to-many-filter.test.ts +++ b/tests/e2e/orm/policy/migrated/relation-many-to-many-filter.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy many-to-many relation tests', () => { const model = ` diff --git a/packages/runtime/test/policy/migrated/relation-one-to-many-filter.test.ts b/tests/e2e/orm/policy/migrated/relation-one-to-many-filter.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/relation-one-to-many-filter.test.ts rename to tests/e2e/orm/policy/migrated/relation-one-to-many-filter.test.ts index 4330c008..4805af86 100644 --- a/packages/runtime/test/policy/migrated/relation-one-to-many-filter.test.ts +++ b/tests/e2e/orm/policy/migrated/relation-one-to-many-filter.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Relation one-to-many filter', () => { const model = ` diff --git a/packages/runtime/test/policy/migrated/relation-one-to-one-filter.test.ts b/tests/e2e/orm/policy/migrated/relation-one-to-one-filter.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/relation-one-to-one-filter.test.ts rename to tests/e2e/orm/policy/migrated/relation-one-to-one-filter.test.ts index 060eea77..d556103f 100644 --- a/packages/runtime/test/policy/migrated/relation-one-to-one-filter.test.ts +++ b/tests/e2e/orm/policy/migrated/relation-one-to-one-filter.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Relation one-to-one filter', () => { const model = ` diff --git a/packages/runtime/test/policy/migrated/self-relation.test.ts b/tests/e2e/orm/policy/migrated/self-relation.test.ts similarity index 98% rename from packages/runtime/test/policy/migrated/self-relation.test.ts rename to tests/e2e/orm/policy/migrated/self-relation.test.ts index f06c34d2..6abef62a 100644 --- a/packages/runtime/test/policy/migrated/self-relation.test.ts +++ b/tests/e2e/orm/policy/migrated/self-relation.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy self relations tests', () => { it('one-to-one', async () => { diff --git a/packages/runtime/test/policy/migrated/todo-sample.test.ts b/tests/e2e/orm/policy/migrated/todo-sample.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/todo-sample.test.ts rename to tests/e2e/orm/policy/migrated/todo-sample.test.ts index 541ca69b..a5d766e3 100644 --- a/packages/runtime/test/policy/migrated/todo-sample.test.ts +++ b/tests/e2e/orm/policy/migrated/todo-sample.test.ts @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, it } from 'vitest'; -import type { ClientContract } from '../../../src'; +import type { ClientContract } from '@zenstackhq/runtime'; import { schema, type SchemaType } from '../../schemas/todo/schema'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Todo Policy Tests', () => { let db: ClientContract; diff --git a/packages/runtime/test/policy/migrated/toplevel-operations.test.ts b/tests/e2e/orm/policy/migrated/toplevel-operations.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/toplevel-operations.test.ts rename to tests/e2e/orm/policy/migrated/toplevel-operations.test.ts index f427c4ad..086efaf0 100644 --- a/packages/runtime/test/policy/migrated/toplevel-operations.test.ts +++ b/tests/e2e/orm/policy/migrated/toplevel-operations.test.ts @@ -1,5 +1,5 @@ +import { createPolicyTestClient } from '@zenstackhq/testtools'; import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; describe('Policy toplevel operations tests', () => { it('read tests', async () => { diff --git a/packages/runtime/test/policy/migrated/unique-as-id.test.ts b/tests/e2e/orm/policy/migrated/unique-as-id.test.ts similarity index 99% rename from packages/runtime/test/policy/migrated/unique-as-id.test.ts rename to tests/e2e/orm/policy/migrated/unique-as-id.test.ts index 6b3e8588..b245baaa 100644 --- a/packages/runtime/test/policy/migrated/unique-as-id.test.ts +++ b/tests/e2e/orm/policy/migrated/unique-as-id.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy unique as id tests', () => { it('unique fields', async () => { diff --git a/packages/runtime/test/policy/migrated/update-many-and-return.test.ts b/tests/e2e/orm/policy/migrated/update-many-and-return.test.ts similarity index 98% rename from packages/runtime/test/policy/migrated/update-many-and-return.test.ts rename to tests/e2e/orm/policy/migrated/update-many-and-return.test.ts index ba83335b..32367c35 100644 --- a/packages/runtime/test/policy/migrated/update-many-and-return.test.ts +++ b/tests/e2e/orm/policy/migrated/update-many-and-return.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('Policy updateManyAndReturn tests', () => { it('model-level policies', async () => { diff --git a/packages/runtime/test/policy/migrated/view.test.ts b/tests/e2e/orm/policy/migrated/view.test.ts similarity index 97% rename from packages/runtime/test/policy/migrated/view.test.ts rename to tests/e2e/orm/policy/migrated/view.test.ts index 010a7f1f..7a8afe28 100644 --- a/packages/runtime/test/policy/migrated/view.test.ts +++ b/tests/e2e/orm/policy/migrated/view.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from '../utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('View Policy Test', () => { it('view policy', async () => { diff --git a/packages/runtime/test/policy/mixin.test.ts b/tests/e2e/orm/policy/mixin.test.ts similarity index 98% rename from packages/runtime/test/policy/mixin.test.ts rename to tests/e2e/orm/policy/mixin.test.ts index 247e9864..94e3028e 100644 --- a/packages/runtime/test/policy/mixin.test.ts +++ b/tests/e2e/orm/policy/mixin.test.ts @@ -1,5 +1,5 @@ +import { createPolicyTestClient } from '@zenstackhq/testtools'; import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from './utils'; describe('Abstract models', () => { it('connect test1', async () => { diff --git a/packages/runtime/test/policy/policy-functions.test.ts b/tests/e2e/orm/policy/policy-functions.test.ts similarity index 99% rename from packages/runtime/test/policy/policy-functions.test.ts rename to tests/e2e/orm/policy/policy-functions.test.ts index 2ac094b0..6d70426e 100644 --- a/packages/runtime/test/policy/policy-functions.test.ts +++ b/tests/e2e/orm/policy/policy-functions.test.ts @@ -1,5 +1,5 @@ +import { createPolicyTestClient } from '@zenstackhq/testtools'; import { describe, expect, it } from 'vitest'; -import { createPolicyTestClient } from './utils'; describe('policy functions tests', () => { it('supports contains case-sensitive', async () => { diff --git a/packages/runtime/test/policy/todo-sample.test.ts b/tests/e2e/orm/policy/todo-sample.test.ts similarity index 99% rename from packages/runtime/test/policy/todo-sample.test.ts rename to tests/e2e/orm/policy/todo-sample.test.ts index a53c7466..8164052f 100644 --- a/packages/runtime/test/policy/todo-sample.test.ts +++ b/tests/e2e/orm/policy/todo-sample.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; import { schema } from '../schemas/todo/schema'; -import { createPolicyTestClient } from './utils'; +import { createPolicyTestClient } from '@zenstackhq/testtools'; describe('todo sample tests', () => { it('works with user CRUD', async () => { diff --git a/tests/e2e/prisma-consistency/attributes.test.ts b/tests/e2e/orm/prisma-consistency/attributes.test.ts similarity index 95% rename from tests/e2e/prisma-consistency/attributes.test.ts rename to tests/e2e/orm/prisma-consistency/attributes.test.ts index 0e1b8044..0ff1f7be 100644 --- a/tests/e2e/prisma-consistency/attributes.test.ts +++ b/tests/e2e/orm/prisma-consistency/attributes.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, } from './test-utils'; describe('Attributes Validation', () => { diff --git a/tests/e2e/prisma-consistency/basic-models.test.ts b/tests/e2e/orm/prisma-consistency/basic-models.test.ts similarity index 96% rename from tests/e2e/prisma-consistency/basic-models.test.ts rename to tests/e2e/orm/prisma-consistency/basic-models.test.ts index bb075dbe..b44111e8 100644 --- a/tests/e2e/prisma-consistency/basic-models.test.ts +++ b/tests/e2e/orm/prisma-consistency/basic-models.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, } from './test-utils'; describe('Basic Models Validation', () => { diff --git a/tests/e2e/prisma-consistency/compound-ids.test.ts b/tests/e2e/orm/prisma-consistency/compound-ids.test.ts similarity index 93% rename from tests/e2e/prisma-consistency/compound-ids.test.ts rename to tests/e2e/orm/prisma-consistency/compound-ids.test.ts index 017d1f53..9797b08d 100644 --- a/tests/e2e/prisma-consistency/compound-ids.test.ts +++ b/tests/e2e/orm/prisma-consistency/compound-ids.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, } from './test-utils'; describe('Compound IDs Validation', () => { diff --git a/tests/e2e/prisma-consistency/datasource.test.ts b/tests/e2e/orm/prisma-consistency/datasource.test.ts similarity index 100% rename from tests/e2e/prisma-consistency/datasource.test.ts rename to tests/e2e/orm/prisma-consistency/datasource.test.ts diff --git a/tests/e2e/prisma-consistency/enums.test.ts b/tests/e2e/orm/prisma-consistency/enums.test.ts similarity index 93% rename from tests/e2e/prisma-consistency/enums.test.ts rename to tests/e2e/orm/prisma-consistency/enums.test.ts index c1e6cbc2..f77ae8e6 100644 --- a/tests/e2e/prisma-consistency/enums.test.ts +++ b/tests/e2e/orm/prisma-consistency/enums.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, } from './test-utils'; describe('Enums Validation', () => { diff --git a/tests/e2e/prisma-consistency/field-types.test.ts b/tests/e2e/orm/prisma-consistency/field-types.test.ts similarity index 94% rename from tests/e2e/prisma-consistency/field-types.test.ts rename to tests/e2e/orm/prisma-consistency/field-types.test.ts index d6a51931..090cba6c 100644 --- a/tests/e2e/prisma-consistency/field-types.test.ts +++ b/tests/e2e/orm/prisma-consistency/field-types.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, sqliteSchema, } from './test-utils'; diff --git a/tests/e2e/prisma-consistency/relation-validation.test.ts b/tests/e2e/orm/prisma-consistency/relation-validation.test.ts similarity index 93% rename from tests/e2e/prisma-consistency/relation-validation.test.ts rename to tests/e2e/orm/prisma-consistency/relation-validation.test.ts index 7ad878be..d5ef65ca 100644 --- a/tests/e2e/prisma-consistency/relation-validation.test.ts +++ b/tests/e2e/orm/prisma-consistency/relation-validation.test.ts @@ -1,11 +1,5 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { - ZenStackValidationTester, - createTestDir, - expectValidationSuccess, - expectValidationFailure, - baseSchema, -} from './test-utils'; +import { afterEach, beforeEach, describe, it } from 'vitest'; +import { ZenStackValidationTester, baseSchema, createTestDir, expectValidationFailure } from './test-utils'; describe('Relation Validation Rules', () => { let tester: ZenStackValidationTester; diff --git a/tests/e2e/prisma-consistency/relations-many-to-many.test.ts b/tests/e2e/orm/prisma-consistency/relations-many-to-many.test.ts similarity index 96% rename from tests/e2e/prisma-consistency/relations-many-to-many.test.ts rename to tests/e2e/orm/prisma-consistency/relations-many-to-many.test.ts index 9322948b..eb0b8f91 100644 --- a/tests/e2e/prisma-consistency/relations-many-to-many.test.ts +++ b/tests/e2e/orm/prisma-consistency/relations-many-to-many.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, } from './test-utils'; describe('Many-to-Many Relations Validation', () => { diff --git a/tests/e2e/prisma-consistency/relations-one-to-many.test.ts b/tests/e2e/orm/prisma-consistency/relations-one-to-many.test.ts similarity index 100% rename from tests/e2e/prisma-consistency/relations-one-to-many.test.ts rename to tests/e2e/orm/prisma-consistency/relations-one-to-many.test.ts diff --git a/tests/e2e/prisma-consistency/relations-one-to-one.test.ts b/tests/e2e/orm/prisma-consistency/relations-one-to-one.test.ts similarity index 96% rename from tests/e2e/prisma-consistency/relations-one-to-one.test.ts rename to tests/e2e/orm/prisma-consistency/relations-one-to-one.test.ts index 10459241..5107283f 100644 --- a/tests/e2e/prisma-consistency/relations-one-to-one.test.ts +++ b/tests/e2e/orm/prisma-consistency/relations-one-to-one.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, } from './test-utils'; describe('One-to-One Relations Validation', () => { diff --git a/tests/e2e/prisma-consistency/relations-self.test.ts b/tests/e2e/orm/prisma-consistency/relations-self.test.ts similarity index 95% rename from tests/e2e/prisma-consistency/relations-self.test.ts rename to tests/e2e/orm/prisma-consistency/relations-self.test.ts index 6a283685..5ec97ea7 100644 --- a/tests/e2e/prisma-consistency/relations-self.test.ts +++ b/tests/e2e/orm/prisma-consistency/relations-self.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, } from './test-utils'; describe('Self Relations Validation', () => { diff --git a/tests/e2e/prisma-consistency/test-utils.ts b/tests/e2e/orm/prisma-consistency/test-utils.ts similarity index 96% rename from tests/e2e/prisma-consistency/test-utils.ts rename to tests/e2e/orm/prisma-consistency/test-utils.ts index 5a53fead..2d125900 100644 --- a/tests/e2e/prisma-consistency/test-utils.ts +++ b/tests/e2e/orm/prisma-consistency/test-utils.ts @@ -21,7 +21,7 @@ export class ZenStackValidationTester { // Get path relative to current test file const currentDir = dirname(fileURLToPath(import.meta.url)); - this.cliPath = join(currentDir, '../node_modules/@zenstackhq/cli/bin/cli'); + this.cliPath = join(currentDir, '../../node_modules/@zenstackhq/cli/bin/cli'); } private setupTestDirectory() { diff --git a/tests/e2e/prisma-consistency/unique-constraints.test.ts b/tests/e2e/orm/prisma-consistency/unique-constraints.test.ts similarity index 95% rename from tests/e2e/prisma-consistency/unique-constraints.test.ts rename to tests/e2e/orm/prisma-consistency/unique-constraints.test.ts index dbb0cbf4..58a4784a 100644 --- a/tests/e2e/prisma-consistency/unique-constraints.test.ts +++ b/tests/e2e/orm/prisma-consistency/unique-constraints.test.ts @@ -1,10 +1,10 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, it } from 'vitest'; import { ZenStackValidationTester, + baseSchema, createTestDir, - expectValidationSuccess, expectValidationFailure, - baseSchema, + expectValidationSuccess, } from './test-utils'; describe('Unique Constraints Validation', () => { diff --git a/packages/runtime/test/query-builder/query-builder.test.ts b/tests/e2e/orm/query-builder/query-builder.test.ts similarity index 96% rename from packages/runtime/test/query-builder/query-builder.test.ts rename to tests/e2e/orm/query-builder/query-builder.test.ts index 32890468..23f31e12 100644 --- a/packages/runtime/test/query-builder/query-builder.test.ts +++ b/tests/e2e/orm/query-builder/query-builder.test.ts @@ -1,7 +1,7 @@ import { createId } from '@paralleldrive/cuid2'; import { describe, expect, it } from 'vitest'; import { getSchema } from '../schemas/basic'; -import { createTestClient } from '../utils'; +import { createTestClient } from '@zenstackhq/testtools'; describe('Client API tests', () => { const schema = getSchema('sqlite'); diff --git a/packages/runtime/test/schemas/basic/helper.ts b/tests/e2e/orm/schemas/basic/helper.ts similarity index 100% rename from packages/runtime/test/schemas/basic/helper.ts rename to tests/e2e/orm/schemas/basic/helper.ts diff --git a/packages/runtime/test/schemas/basic/index.ts b/tests/e2e/orm/schemas/basic/index.ts similarity index 100% rename from packages/runtime/test/schemas/basic/index.ts rename to tests/e2e/orm/schemas/basic/index.ts diff --git a/packages/runtime/test/schemas/basic/input.ts b/tests/e2e/orm/schemas/basic/input.ts similarity index 100% rename from packages/runtime/test/schemas/basic/input.ts rename to tests/e2e/orm/schemas/basic/input.ts diff --git a/packages/runtime/test/schemas/basic/models.ts b/tests/e2e/orm/schemas/basic/models.ts similarity index 100% rename from packages/runtime/test/schemas/basic/models.ts rename to tests/e2e/orm/schemas/basic/models.ts diff --git a/packages/runtime/test/schemas/basic/schema.ts b/tests/e2e/orm/schemas/basic/schema.ts similarity index 99% rename from packages/runtime/test/schemas/basic/schema.ts rename to tests/e2e/orm/schemas/basic/schema.ts index 8fd0b900..93cfb4df 100644 --- a/packages/runtime/test/schemas/basic/schema.ts +++ b/tests/e2e/orm/schemas/basic/schema.ts @@ -5,7 +5,7 @@ /* eslint-disable */ -import { type SchemaDef, ExpressionUtils } from "../../../dist/schema"; +import { type SchemaDef, ExpressionUtils } from "@zenstackhq/runtime/schema"; export const schema = { provider: { type: "sqlite" diff --git a/packages/runtime/test/schemas/basic/schema.zmodel b/tests/e2e/orm/schemas/basic/schema.zmodel similarity index 100% rename from packages/runtime/test/schemas/basic/schema.zmodel rename to tests/e2e/orm/schemas/basic/schema.zmodel diff --git a/packages/runtime/test/schemas/delegate/input.ts b/tests/e2e/orm/schemas/delegate/input.ts similarity index 100% rename from packages/runtime/test/schemas/delegate/input.ts rename to tests/e2e/orm/schemas/delegate/input.ts diff --git a/packages/runtime/test/schemas/delegate/models.ts b/tests/e2e/orm/schemas/delegate/models.ts similarity index 100% rename from packages/runtime/test/schemas/delegate/models.ts rename to tests/e2e/orm/schemas/delegate/models.ts diff --git a/packages/runtime/test/schemas/delegate/schema.ts b/tests/e2e/orm/schemas/delegate/schema.ts similarity index 99% rename from packages/runtime/test/schemas/delegate/schema.ts rename to tests/e2e/orm/schemas/delegate/schema.ts index a15d4f46..ca076fa3 100644 --- a/packages/runtime/test/schemas/delegate/schema.ts +++ b/tests/e2e/orm/schemas/delegate/schema.ts @@ -5,7 +5,7 @@ /* eslint-disable */ -import { type SchemaDef, ExpressionUtils } from "../../../dist/schema"; +import { type SchemaDef, ExpressionUtils } from "@zenstackhq/runtime/schema"; export const schema = { provider: { type: "sqlite" diff --git a/packages/runtime/test/schemas/delegate/schema.zmodel b/tests/e2e/orm/schemas/delegate/schema.zmodel similarity index 100% rename from packages/runtime/test/schemas/delegate/schema.zmodel rename to tests/e2e/orm/schemas/delegate/schema.zmodel diff --git a/packages/runtime/test/schemas/delegate/typecheck.ts b/tests/e2e/orm/schemas/delegate/typecheck.ts similarity index 99% rename from packages/runtime/test/schemas/delegate/typecheck.ts rename to tests/e2e/orm/schemas/delegate/typecheck.ts index 82b3e194..e9c15ed8 100644 --- a/packages/runtime/test/schemas/delegate/typecheck.ts +++ b/tests/e2e/orm/schemas/delegate/typecheck.ts @@ -1,6 +1,6 @@ +import { ZenStackClient } from '@zenstackhq/runtime'; import SQLite from 'better-sqlite3'; import { SqliteDialect } from 'kysely'; -import { ZenStackClient } from '../../../dist'; import { schema } from './schema'; const client = new ZenStackClient(schema, { diff --git a/packages/runtime/test/schemas/name-mapping/input.ts b/tests/e2e/orm/schemas/name-mapping/input.ts similarity index 100% rename from packages/runtime/test/schemas/name-mapping/input.ts rename to tests/e2e/orm/schemas/name-mapping/input.ts diff --git a/packages/runtime/test/schemas/name-mapping/models.ts b/tests/e2e/orm/schemas/name-mapping/models.ts similarity index 100% rename from packages/runtime/test/schemas/name-mapping/models.ts rename to tests/e2e/orm/schemas/name-mapping/models.ts diff --git a/packages/runtime/test/schemas/name-mapping/schema.ts b/tests/e2e/orm/schemas/name-mapping/schema.ts similarity index 97% rename from packages/runtime/test/schemas/name-mapping/schema.ts rename to tests/e2e/orm/schemas/name-mapping/schema.ts index a766ff99..984f36d1 100644 --- a/packages/runtime/test/schemas/name-mapping/schema.ts +++ b/tests/e2e/orm/schemas/name-mapping/schema.ts @@ -5,7 +5,7 @@ /* eslint-disable */ -import { type SchemaDef, ExpressionUtils } from "../../../dist/schema"; +import { type SchemaDef, ExpressionUtils } from "@zenstackhq/runtime/schema"; export const schema = { provider: { type: "sqlite" diff --git a/packages/runtime/test/schemas/name-mapping/schema.zmodel b/tests/e2e/orm/schemas/name-mapping/schema.zmodel similarity index 100% rename from packages/runtime/test/schemas/name-mapping/schema.zmodel rename to tests/e2e/orm/schemas/name-mapping/schema.zmodel diff --git a/packages/runtime/test/schemas/petstore/input.ts b/tests/e2e/orm/schemas/petstore/input.ts similarity index 100% rename from packages/runtime/test/schemas/petstore/input.ts rename to tests/e2e/orm/schemas/petstore/input.ts diff --git a/packages/runtime/test/schemas/petstore/models.ts b/tests/e2e/orm/schemas/petstore/models.ts similarity index 100% rename from packages/runtime/test/schemas/petstore/models.ts rename to tests/e2e/orm/schemas/petstore/models.ts diff --git a/packages/runtime/test/schemas/petstore/schema.ts b/tests/e2e/orm/schemas/petstore/schema.ts similarity index 98% rename from packages/runtime/test/schemas/petstore/schema.ts rename to tests/e2e/orm/schemas/petstore/schema.ts index a2eb7d67..0d208b8e 100644 --- a/packages/runtime/test/schemas/petstore/schema.ts +++ b/tests/e2e/orm/schemas/petstore/schema.ts @@ -5,7 +5,7 @@ /* eslint-disable */ -import { type SchemaDef, ExpressionUtils } from "../../../dist/schema"; +import { type SchemaDef, ExpressionUtils } from "@zenstackhq/runtime/schema"; export const schema = { provider: { type: "sqlite" diff --git a/packages/runtime/test/schemas/petstore/schema.zmodel b/tests/e2e/orm/schemas/petstore/schema.zmodel similarity index 100% rename from packages/runtime/test/schemas/petstore/schema.zmodel rename to tests/e2e/orm/schemas/petstore/schema.zmodel diff --git a/packages/runtime/test/schemas/todo/input.ts b/tests/e2e/orm/schemas/todo/input.ts similarity index 100% rename from packages/runtime/test/schemas/todo/input.ts rename to tests/e2e/orm/schemas/todo/input.ts diff --git a/packages/runtime/test/schemas/todo/models.ts b/tests/e2e/orm/schemas/todo/models.ts similarity index 100% rename from packages/runtime/test/schemas/todo/models.ts rename to tests/e2e/orm/schemas/todo/models.ts diff --git a/packages/runtime/test/schemas/todo/schema.ts b/tests/e2e/orm/schemas/todo/schema.ts similarity index 99% rename from packages/runtime/test/schemas/todo/schema.ts rename to tests/e2e/orm/schemas/todo/schema.ts index f0ae9c26..243e59d6 100644 --- a/packages/runtime/test/schemas/todo/schema.ts +++ b/tests/e2e/orm/schemas/todo/schema.ts @@ -5,7 +5,7 @@ /* eslint-disable */ -import { type SchemaDef, ExpressionUtils } from "../../../dist/schema"; +import { type SchemaDef, ExpressionUtils } from "@zenstackhq/runtime/schema"; export const schema = { provider: { type: "sqlite" diff --git a/packages/runtime/test/schemas/todo/todo.zmodel b/tests/e2e/orm/schemas/todo/todo.zmodel similarity index 100% rename from packages/runtime/test/schemas/todo/todo.zmodel rename to tests/e2e/orm/schemas/todo/todo.zmodel diff --git a/packages/runtime/test/schemas/typing/input.ts b/tests/e2e/orm/schemas/typing/input.ts similarity index 100% rename from packages/runtime/test/schemas/typing/input.ts rename to tests/e2e/orm/schemas/typing/input.ts diff --git a/packages/runtime/test/schemas/typing/models.ts b/tests/e2e/orm/schemas/typing/models.ts similarity index 100% rename from packages/runtime/test/schemas/typing/models.ts rename to tests/e2e/orm/schemas/typing/models.ts diff --git a/packages/runtime/test/schemas/typing/schema.ts b/tests/e2e/orm/schemas/typing/schema.ts similarity index 99% rename from packages/runtime/test/schemas/typing/schema.ts rename to tests/e2e/orm/schemas/typing/schema.ts index 18270ceb..d8287c0e 100644 --- a/packages/runtime/test/schemas/typing/schema.ts +++ b/tests/e2e/orm/schemas/typing/schema.ts @@ -5,7 +5,7 @@ /* eslint-disable */ -import { type SchemaDef, type OperandExpression, ExpressionUtils } from "../../../dist/schema"; +import { type SchemaDef, type OperandExpression, ExpressionUtils } from "@zenstackhq/runtime/schema"; export const schema = { provider: { type: "postgresql" diff --git a/packages/runtime/test/schemas/typing/schema.zmodel b/tests/e2e/orm/schemas/typing/schema.zmodel similarity index 100% rename from packages/runtime/test/schemas/typing/schema.zmodel rename to tests/e2e/orm/schemas/typing/schema.zmodel diff --git a/packages/runtime/test/schemas/typing/typecheck.ts b/tests/e2e/orm/schemas/typing/typecheck.ts similarity index 99% rename from packages/runtime/test/schemas/typing/typecheck.ts rename to tests/e2e/orm/schemas/typing/typecheck.ts index 94961400..f183766f 100644 --- a/packages/runtime/test/schemas/typing/typecheck.ts +++ b/tests/e2e/orm/schemas/typing/typecheck.ts @@ -1,6 +1,6 @@ +import { ZenStackClient } from '@zenstackhq/runtime'; import SQLite from 'better-sqlite3'; import { SqliteDialect } from 'kysely'; -import { ZenStackClient } from '../../../dist'; import { Role, Status, type Identity, type IdentityProvider } from './models'; import { schema } from './schema'; diff --git a/packages/runtime/test/scripts/generate.ts b/tests/e2e/orm/scripts/generate.ts similarity index 76% rename from packages/runtime/test/scripts/generate.ts rename to tests/e2e/orm/scripts/generate.ts index df405295..b4f78958 100644 --- a/packages/runtime/test/scripts/generate.ts +++ b/tests/e2e/orm/scripts/generate.ts @@ -1,7 +1,6 @@ import { loadDocument } from '@zenstackhq/language'; import { TsSchemaGenerator } from '@zenstackhq/sdk'; import { glob } from 'glob'; -import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -18,15 +17,11 @@ async function main() { async function generate(schemaPath: string) { const generator = new TsSchemaGenerator(); const outputDir = path.dirname(schemaPath); - const tsPath = path.join(outputDir, 'schema.ts'); const result = await loadDocument(schemaPath); if (!result.success) { throw new Error(`Failed to load schema from ${schemaPath}: ${result.errors}`); } await generator.generate(result.model, outputDir); - const content = fs.readFileSync(tsPath, 'utf-8'); - fs.writeFileSync(tsPath, content.replace(/@zenstackhq\/runtime/g, '../../../dist')); - console.log('TS schema generated at:', outputDir); } main(); diff --git a/tests/e2e/package.json b/tests/e2e/package.json index f1b847a1..c17d7750 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -4,13 +4,31 @@ "private": true, "type": "module", "scripts": { - "test": "vitest run" + "build": "pnpm test:generate && pnpm test:typecheck", + "test:generate": "tsx orm/scripts/generate.ts", + "test:typecheck": "tsc --noEmit", + "test": "vitest run", + "test:sqlite": "TEST_DB_PROVIDER=sqlite vitest run", + "test:postgresql": "TEST_DB_PROVIDER=postgresql vitest run" }, "dependencies": { - "@zenstackhq/testtools": "workspace:*" + "@paralleldrive/cuid2": "^2.2.2", + "@zenstackhq/cli": "workspace:*", + "@zenstackhq/language": "workspace:*", + "@zenstackhq/runtime": "workspace:*", + "@zenstackhq/plugin-policy": "workspace:*", + "@zenstackhq/sdk": "workspace:*", + "@zenstackhq/testtools": "workspace:*", + "better-sqlite3": "catalog:", + "decimal.js": "^10.4.3", + "kysely": "catalog:", + "ulid": "^3.0.0", + "uuid": "^11.0.5" }, "devDependencies": { + "@types/uuid": "^11.0.0", "@zenstackhq/cli": "workspace:*", + "@zenstackhq/typescript-config": "workspace:*", "@zenstackhq/vitest-config": "workspace:*" } } diff --git a/packages/runtime/tsconfig.test.json b/tests/e2e/tsconfig.json similarity index 69% rename from packages/runtime/tsconfig.test.json rename to tests/e2e/tsconfig.json index de56945b..6d8efbee 100644 --- a/packages/runtime/tsconfig.test.json +++ b/tests/e2e/tsconfig.json @@ -3,7 +3,6 @@ "compilerOptions": { "noEmit": true, "noImplicitAny": false, - "rootDir": "." - }, - "include": ["test/**/*.ts"] + "types": ["@zenstackhq/testtools/types"] + } } diff --git a/tests/e2e/vitest.config.ts b/tests/e2e/vitest.config.ts index 75a9f709..10606ce6 100644 --- a/tests/e2e/vitest.config.ts +++ b/tests/e2e/vitest.config.ts @@ -1,4 +1,11 @@ import base from '@zenstackhq/vitest-config/base'; import { defineConfig, mergeConfig } from 'vitest/config'; -export default mergeConfig(base, defineConfig({})); +export default mergeConfig( + base, + defineConfig({ + test: { + setupFiles: ['@zenstackhq/testtools'], + }, + }), +); diff --git a/tests/regression/tsconfig.json b/tests/regression/tsconfig.json index f3a2dbcb..e0b83aa8 100644 --- a/tests/regression/tsconfig.json +++ b/tests/regression/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "@zenstackhq/typescript-config/base.json", "compilerOptions": { - "noEmit": true + "noEmit": true, + "types": ["@zenstackhq/testtools/types"] }, "include": ["src/**/*.ts", "test/**/*.ts"] } diff --git a/tests/regression/vitest.config.ts b/tests/regression/vitest.config.ts index 75a9f709..10606ce6 100644 --- a/tests/regression/vitest.config.ts +++ b/tests/regression/vitest.config.ts @@ -1,4 +1,11 @@ import base from '@zenstackhq/vitest-config/base'; import { defineConfig, mergeConfig } from 'vitest/config'; -export default mergeConfig(base, defineConfig({})); +export default mergeConfig( + base, + defineConfig({ + test: { + setupFiles: ['@zenstackhq/testtools'], + }, + }), +); diff --git a/vitest.config.ts b/vitest.config.ts index f0b415da..f7268cb1 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,6 +2,6 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { - projects: ['packages/*'], + projects: ['packages/*', 'tests/*'], }, });