diff --git a/packages/language/package.json b/packages/language/package.json index d1ef4ed9..8ab6c7de 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -51,7 +51,7 @@ "@types/pluralize": "^0.0.33", "@zenstackhq/eslint-config": "workspace:*", "@zenstackhq/typescript-config": "workspace:*", - "langium-cli": "~3.3.0" + "langium-cli": "catalog:" }, "volta": { "node": "18.19.1", diff --git a/packages/language/src/generated/ast.ts b/packages/language/src/generated/ast.ts index 114aad4f..0555c16d 100644 --- a/packages/language/src/generated/ast.ts +++ b/packages/language/src/generated/ast.ts @@ -1,11 +1,10 @@ /****************************************************************************** - * This file was generated by langium-cli 3.3.1. + * This file was generated by langium-cli 3.5.0. * DO NOT EDIT MANUALLY! ******************************************************************************/ /* eslint-disable */ -import type { AstNode, Reference, ReferenceInfo, TypeMetaData } from 'langium'; -import { AbstractAstReflection } from 'langium'; +import * as langium from 'langium'; export const ZModelTerminals = { WS: /\s+/, @@ -22,7 +21,7 @@ export const ZModelTerminals = { export type ZModelTerminalNames = keyof typeof ZModelTerminals; -export type ZModelKeywordNames = +export type ZModelKeywordNames = | "!" | "!=" | "&&" @@ -178,7 +177,7 @@ export function isTypeDefFieldTypes(item: unknown): item is TypeDefFieldTypes { return reflection.isInstance(item, TypeDefFieldTypes); } -export interface Argument extends AstNode { +export interface Argument extends langium.AstNode { readonly $container: InvocationExpr; readonly $type: 'Argument'; value: Expression; @@ -190,7 +189,7 @@ export function isArgument(item: unknown): item is Argument { return reflection.isInstance(item, Argument); } -export interface ArrayExpr extends AstNode { +export interface ArrayExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr; readonly $type: 'ArrayExpr'; items: Array; @@ -202,7 +201,7 @@ export function isArrayExpr(item: unknown): item is ArrayExpr { return reflection.isInstance(item, ArrayExpr); } -export interface Attribute extends AstNode { +export interface Attribute extends langium.AstNode { readonly $container: Model; readonly $type: 'Attribute'; attributes: Array; @@ -217,7 +216,7 @@ export function isAttribute(item: unknown): item is Attribute { return reflection.isInstance(item, Attribute); } -export interface AttributeArg extends AstNode { +export interface AttributeArg extends langium.AstNode { readonly $container: DataModelAttribute | DataModelFieldAttribute | InternalAttribute; readonly $type: 'AttributeArg'; name?: RegularID; @@ -230,7 +229,7 @@ export function isAttributeArg(item: unknown): item is AttributeArg { return reflection.isInstance(item, AttributeArg); } -export interface AttributeParam extends AstNode { +export interface AttributeParam extends langium.AstNode { readonly $container: Attribute; readonly $type: 'AttributeParam'; attributes: Array; @@ -246,12 +245,12 @@ export function isAttributeParam(item: unknown): item is AttributeParam { return reflection.isInstance(item, AttributeParam); } -export interface AttributeParamType extends AstNode { +export interface AttributeParamType extends langium.AstNode { readonly $container: AttributeParam; readonly $type: 'AttributeParamType'; array: boolean; optional: boolean; - reference?: Reference; + reference?: langium.Reference; type?: 'ContextType' | 'FieldReference' | 'TransitiveFieldReference' | ExpressionType; } @@ -261,7 +260,7 @@ export function isAttributeParamType(item: unknown): item is AttributeParamType return reflection.isInstance(item, AttributeParamType); } -export interface BinaryExpr extends AstNode { +export interface BinaryExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | ReferenceArg | UnaryExpr; readonly $type: 'BinaryExpr'; left: Expression; @@ -275,7 +274,7 @@ export function isBinaryExpr(item: unknown): item is BinaryExpr { return reflection.isInstance(item, BinaryExpr); } -export interface BooleanLiteral extends AstNode { +export interface BooleanLiteral extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType; readonly $type: 'BooleanLiteral'; value: Boolean; @@ -287,7 +286,7 @@ export function isBooleanLiteral(item: unknown): item is BooleanLiteral { return reflection.isInstance(item, BooleanLiteral); } -export interface ConfigArrayExpr extends AstNode { +export interface ConfigArrayExpr extends langium.AstNode { readonly $container: ConfigField; readonly $type: 'ConfigArrayExpr'; items: Array; @@ -299,7 +298,7 @@ export function isConfigArrayExpr(item: unknown): item is ConfigArrayExpr { return reflection.isInstance(item, ConfigArrayExpr); } -export interface ConfigField extends AstNode { +export interface ConfigField extends langium.AstNode { readonly $container: DataSource | GeneratorDecl; readonly $type: 'ConfigField'; name: RegularID; @@ -312,7 +311,7 @@ export function isConfigField(item: unknown): item is ConfigField { return reflection.isInstance(item, ConfigField); } -export interface ConfigInvocationArg extends AstNode { +export interface ConfigInvocationArg extends langium.AstNode { readonly $container: ConfigInvocationExpr; readonly $type: 'ConfigInvocationArg'; name: string; @@ -325,7 +324,7 @@ export function isConfigInvocationArg(item: unknown): item is ConfigInvocationAr return reflection.isInstance(item, ConfigInvocationArg); } -export interface ConfigInvocationExpr extends AstNode { +export interface ConfigInvocationExpr extends langium.AstNode { readonly $container: ConfigArrayExpr; readonly $type: 'ConfigInvocationExpr'; args: Array; @@ -338,7 +337,7 @@ export function isConfigInvocationExpr(item: unknown): item is ConfigInvocationE return reflection.isInstance(item, ConfigInvocationExpr); } -export interface DataModel extends AstNode { +export interface DataModel extends langium.AstNode { readonly $container: Model; readonly $type: 'DataModel'; attributes: Array; @@ -347,7 +346,7 @@ export interface DataModel extends AstNode { isAbstract: boolean; isView: boolean; name: RegularID; - superTypes: Array>; + superTypes: Array>; } export const DataModel = 'DataModel'; @@ -356,11 +355,11 @@ export function isDataModel(item: unknown): item is DataModel { return reflection.isInstance(item, DataModel); } -export interface DataModelAttribute extends AstNode { +export interface DataModelAttribute extends langium.AstNode { readonly $container: DataModel | Enum | TypeDef; readonly $type: 'DataModelAttribute'; args: Array; - decl: Reference; + decl: langium.Reference; } export const DataModelAttribute = 'DataModelAttribute'; @@ -369,7 +368,7 @@ export function isDataModelAttribute(item: unknown): item is DataModelAttribute return reflection.isInstance(item, DataModelAttribute); } -export interface DataModelField extends AstNode { +export interface DataModelField extends langium.AstNode { readonly $container: DataModel; readonly $type: 'DataModelField'; attributes: Array; @@ -384,11 +383,11 @@ export function isDataModelField(item: unknown): item is DataModelField { return reflection.isInstance(item, DataModelField); } -export interface DataModelFieldAttribute extends AstNode { +export interface DataModelFieldAttribute extends langium.AstNode { readonly $container: DataModelField | EnumField | TypeDefField; readonly $type: 'DataModelFieldAttribute'; args: Array; - decl: Reference; + decl: langium.Reference; } export const DataModelFieldAttribute = 'DataModelFieldAttribute'; @@ -397,12 +396,12 @@ export function isDataModelFieldAttribute(item: unknown): item is DataModelField return reflection.isInstance(item, DataModelFieldAttribute); } -export interface DataModelFieldType extends AstNode { +export interface DataModelFieldType extends langium.AstNode { readonly $container: DataModelField; readonly $type: 'DataModelFieldType'; array: boolean; optional: boolean; - reference?: Reference; + reference?: langium.Reference; type?: BuiltinType; unsupported?: UnsupportedFieldType; } @@ -413,7 +412,7 @@ export function isDataModelFieldType(item: unknown): item is DataModelFieldType return reflection.isInstance(item, DataModelFieldType); } -export interface DataSource extends AstNode { +export interface DataSource extends langium.AstNode { readonly $container: Model; readonly $type: 'DataSource'; fields: Array; @@ -426,7 +425,7 @@ export function isDataSource(item: unknown): item is DataSource { return reflection.isInstance(item, DataSource); } -export interface Enum extends AstNode { +export interface Enum extends langium.AstNode { readonly $container: Model; readonly $type: 'Enum'; attributes: Array; @@ -441,7 +440,7 @@ export function isEnum(item: unknown): item is Enum { return reflection.isInstance(item, Enum); } -export interface EnumField extends AstNode { +export interface EnumField extends langium.AstNode { readonly $container: Enum; readonly $type: 'EnumField'; attributes: Array; @@ -455,7 +454,7 @@ export function isEnumField(item: unknown): item is EnumField { return reflection.isInstance(item, EnumField); } -export interface FieldInitializer extends AstNode { +export interface FieldInitializer extends langium.AstNode { readonly $container: ObjectExpr; readonly $type: 'FieldInitializer'; name: RegularID | string; @@ -468,7 +467,7 @@ export function isFieldInitializer(item: unknown): item is FieldInitializer { return reflection.isInstance(item, FieldInitializer); } -export interface FunctionDecl extends AstNode { +export interface FunctionDecl extends langium.AstNode { readonly $container: Model; readonly $type: 'FunctionDecl'; attributes: Array; @@ -484,7 +483,7 @@ export function isFunctionDecl(item: unknown): item is FunctionDecl { return reflection.isInstance(item, FunctionDecl); } -export interface FunctionParam extends AstNode { +export interface FunctionParam extends langium.AstNode { readonly $container: FunctionDecl | Procedure; readonly $type: 'FunctionParam'; name: RegularID; @@ -498,11 +497,11 @@ export function isFunctionParam(item: unknown): item is FunctionParam { return reflection.isInstance(item, FunctionParam); } -export interface FunctionParamType extends AstNode { +export interface FunctionParamType extends langium.AstNode { readonly $container: FunctionDecl | FunctionParam | Procedure | ProcedureParam; readonly $type: 'FunctionParamType'; array: boolean; - reference?: Reference; + reference?: langium.Reference; type?: ExpressionType; } @@ -512,7 +511,7 @@ export function isFunctionParamType(item: unknown): item is FunctionParamType { return reflection.isInstance(item, FunctionParamType); } -export interface GeneratorDecl extends AstNode { +export interface GeneratorDecl extends langium.AstNode { readonly $container: Model; readonly $type: 'GeneratorDecl'; fields: Array; @@ -525,11 +524,11 @@ export function isGeneratorDecl(item: unknown): item is GeneratorDecl { return reflection.isInstance(item, GeneratorDecl); } -export interface InternalAttribute extends AstNode { +export interface InternalAttribute extends langium.AstNode { readonly $container: Attribute | AttributeParam | FunctionDecl | Procedure; readonly $type: 'InternalAttribute'; args: Array; - decl: Reference; + decl: langium.Reference; } export const InternalAttribute = 'InternalAttribute'; @@ -538,11 +537,11 @@ export function isInternalAttribute(item: unknown): item is InternalAttribute { return reflection.isInstance(item, InternalAttribute); } -export interface InvocationExpr extends AstNode { +export interface InvocationExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigField | FieldInitializer | FunctionDecl | MemberAccessExpr | ReferenceArg | UnaryExpr; readonly $type: 'InvocationExpr'; args: Array; - function: Reference; + function: langium.Reference; } export const InvocationExpr = 'InvocationExpr'; @@ -551,10 +550,10 @@ export function isInvocationExpr(item: unknown): item is InvocationExpr { return reflection.isInstance(item, InvocationExpr); } -export interface MemberAccessExpr extends AstNode { +export interface MemberAccessExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | ReferenceArg | UnaryExpr; readonly $type: 'MemberAccessExpr'; - member: Reference; + member: langium.Reference; operand: Expression; } @@ -564,7 +563,7 @@ export function isMemberAccessExpr(item: unknown): item is MemberAccessExpr { return reflection.isInstance(item, MemberAccessExpr); } -export interface Model extends AstNode { +export interface Model extends langium.AstNode { readonly $type: 'Model'; declarations: Array; imports: Array; @@ -576,7 +575,7 @@ export function isModel(item: unknown): item is Model { return reflection.isInstance(item, Model); } -export interface ModelImport extends AstNode { +export interface ModelImport extends langium.AstNode { readonly $container: Model; readonly $type: 'ModelImport'; path: string; @@ -588,7 +587,7 @@ export function isModelImport(item: unknown): item is ModelImport { return reflection.isInstance(item, ModelImport); } -export interface NullExpr extends AstNode { +export interface NullExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | ReferenceArg | UnaryExpr; readonly $type: 'NullExpr'; value: 'null'; @@ -600,7 +599,7 @@ export function isNullExpr(item: unknown): item is NullExpr { return reflection.isInstance(item, NullExpr); } -export interface NumberLiteral extends AstNode { +export interface NumberLiteral extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType; readonly $type: 'NumberLiteral'; value: string; @@ -612,7 +611,7 @@ export function isNumberLiteral(item: unknown): item is NumberLiteral { return reflection.isInstance(item, NumberLiteral); } -export interface ObjectExpr extends AstNode { +export interface ObjectExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr; readonly $type: 'ObjectExpr'; fields: Array; @@ -624,7 +623,7 @@ export function isObjectExpr(item: unknown): item is ObjectExpr { return reflection.isInstance(item, ObjectExpr); } -export interface Plugin extends AstNode { +export interface Plugin extends langium.AstNode { readonly $container: Model; readonly $type: 'Plugin'; fields: Array; @@ -637,7 +636,7 @@ export function isPlugin(item: unknown): item is Plugin { return reflection.isInstance(item, Plugin); } -export interface PluginField extends AstNode { +export interface PluginField extends langium.AstNode { readonly $container: Plugin; readonly $type: 'PluginField'; name: RegularID; @@ -650,7 +649,7 @@ export function isPluginField(item: unknown): item is PluginField { return reflection.isInstance(item, PluginField); } -export interface Procedure extends AstNode { +export interface Procedure extends langium.AstNode { readonly $container: Model; readonly $type: 'Procedure'; attributes: Array; @@ -666,7 +665,7 @@ export function isProcedure(item: unknown): item is Procedure { return reflection.isInstance(item, Procedure); } -export interface ProcedureParam extends AstNode { +export interface ProcedureParam extends langium.AstNode { readonly $container: Procedure; readonly $type: 'ProcedureParam'; name: RegularID; @@ -680,7 +679,7 @@ export function isProcedureParam(item: unknown): item is ProcedureParam { return reflection.isInstance(item, ProcedureParam); } -export interface ReferenceArg extends AstNode { +export interface ReferenceArg extends langium.AstNode { readonly $container: ReferenceExpr; readonly $type: 'ReferenceArg'; name: string; @@ -693,11 +692,11 @@ export function isReferenceArg(item: unknown): item is ReferenceArg { return reflection.isInstance(item, ReferenceArg); } -export interface ReferenceExpr extends AstNode { +export interface ReferenceExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | ReferenceArg | UnaryExpr; readonly $type: 'ReferenceExpr'; args: Array; - target: Reference; + target: langium.Reference; } export const ReferenceExpr = 'ReferenceExpr'; @@ -706,7 +705,7 @@ export function isReferenceExpr(item: unknown): item is ReferenceExpr { return reflection.isInstance(item, ReferenceExpr); } -export interface StringLiteral extends AstNode { +export interface StringLiteral extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType; readonly $type: 'StringLiteral'; value: string; @@ -718,7 +717,7 @@ export function isStringLiteral(item: unknown): item is StringLiteral { return reflection.isInstance(item, StringLiteral); } -export interface ThisExpr extends AstNode { +export interface ThisExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | ReferenceArg | UnaryExpr; readonly $type: 'ThisExpr'; value: 'this'; @@ -730,7 +729,7 @@ export function isThisExpr(item: unknown): item is ThisExpr { return reflection.isInstance(item, ThisExpr); } -export interface TypeDef extends AstNode { +export interface TypeDef extends langium.AstNode { readonly $container: Model; readonly $type: 'TypeDef'; attributes: Array; @@ -745,7 +744,7 @@ export function isTypeDef(item: unknown): item is TypeDef { return reflection.isInstance(item, TypeDef); } -export interface TypeDefField extends AstNode { +export interface TypeDefField extends langium.AstNode { readonly $container: TypeDef; readonly $type: 'TypeDefField'; attributes: Array; @@ -760,12 +759,12 @@ export function isTypeDefField(item: unknown): item is TypeDefField { return reflection.isInstance(item, TypeDefField); } -export interface TypeDefFieldType extends AstNode { +export interface TypeDefFieldType extends langium.AstNode { readonly $container: TypeDefField; readonly $type: 'TypeDefFieldType'; array: boolean; optional: boolean; - reference?: Reference; + reference?: langium.Reference; type?: BuiltinType; } @@ -775,7 +774,7 @@ export function isTypeDefFieldType(item: unknown): item is TypeDefFieldType { return reflection.isInstance(item, TypeDefFieldType); } -export interface UnaryExpr extends AstNode { +export interface UnaryExpr extends langium.AstNode { readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | FieldInitializer | FunctionDecl | MemberAccessExpr | ReferenceArg | UnaryExpr; readonly $type: 'UnaryExpr'; operand: Expression; @@ -788,7 +787,7 @@ export function isUnaryExpr(item: unknown): item is UnaryExpr { return reflection.isInstance(item, UnaryExpr); } -export interface UnsupportedFieldType extends AstNode { +export interface UnsupportedFieldType extends langium.AstNode { readonly $container: DataModelFieldType; readonly $type: 'UnsupportedFieldType'; value: LiteralExpr; @@ -857,7 +856,7 @@ export type ZModelAstType = { UnsupportedFieldType: UnsupportedFieldType } -export class ZModelAstReflection extends AbstractAstReflection { +export class ZModelAstReflection extends langium.AbstractAstReflection { getAllTypes(): string[] { return [AbstractDeclaration, Argument, ArrayExpr, Attribute, AttributeArg, AttributeParam, AttributeParamType, BinaryExpr, BooleanLiteral, ConfigArrayExpr, ConfigExpr, ConfigField, ConfigInvocationArg, ConfigInvocationExpr, DataModel, DataModelAttribute, DataModelField, DataModelFieldAttribute, DataModelFieldType, DataSource, Enum, EnumField, Expression, FieldInitializer, FunctionDecl, FunctionParam, FunctionParamType, GeneratorDecl, InternalAttribute, InvocationExpr, LiteralExpr, MemberAccessExpr, MemberAccessTarget, Model, ModelImport, NullExpr, NumberLiteral, ObjectExpr, Plugin, PluginField, Procedure, ProcedureParam, ReferenceArg, ReferenceExpr, ReferenceTarget, StringLiteral, ThisExpr, TypeDeclaration, TypeDef, TypeDefField, TypeDefFieldType, TypeDefFieldTypes, UnaryExpr, UnsupportedFieldType]; @@ -916,7 +915,7 @@ export class ZModelAstReflection extends AbstractAstReflection { } } - getReferenceType(refInfo: ReferenceInfo): string { + getReferenceType(refInfo: langium.ReferenceInfo): string { const referenceId = `${refInfo.container.$type}:${refInfo.property}`; switch (referenceId) { case 'AttributeParamType:reference': @@ -950,7 +949,7 @@ export class ZModelAstReflection extends AbstractAstReflection { } } - getTypeMetaData(type: string): TypeMetaData { + getTypeMetaData(type: string): langium.TypeMetaData { switch (type) { case Argument: { return { diff --git a/packages/language/src/generated/grammar.ts b/packages/language/src/generated/grammar.ts index 14b17a35..c2a61e5a 100644 --- a/packages/language/src/generated/grammar.ts +++ b/packages/language/src/generated/grammar.ts @@ -1,5 +1,5 @@ /****************************************************************************** - * This file was generated by langium-cli 3.3.1. + * This file was generated by langium-cli 3.5.0. * DO NOT EDIT MANUALLY! ******************************************************************************/ @@ -14,8 +14,8 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel "rules": [ { "$type": "ParserRule", - "name": "Model", "entry": true, + "name": "Model", "definition": { "$type": "Group", "elements": [ @@ -701,8 +701,8 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel }, { "$type": "ParserRule", - "name": "ConfigInvocationArgList", "fragment": true, + "name": "ConfigInvocationArgList", "definition": { "$type": "Group", "elements": [ @@ -1009,8 +1009,8 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel }, { "$type": "ParserRule", - "name": "ReferenceArgList", "fragment": true, + "name": "ReferenceArgList", "definition": { "$type": "Group", "elements": [ @@ -1826,8 +1826,8 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel }, { "$type": "ParserRule", - "name": "ArgumentList", "fragment": true, + "name": "ArgumentList", "definition": { "$type": "Group", "elements": [ @@ -3695,8 +3695,8 @@ export const ZModelGrammar = (): Grammar => loadedZModelGrammar ?? (loadedZModel }, { "$type": "ParserRule", - "name": "AttributeArgList", "fragment": true, + "name": "AttributeArgList", "definition": { "$type": "Group", "elements": [ diff --git a/packages/language/src/generated/module.ts b/packages/language/src/generated/module.ts index 95f3f94d..58849979 100644 --- a/packages/language/src/generated/module.ts +++ b/packages/language/src/generated/module.ts @@ -1,5 +1,5 @@ /****************************************************************************** - * This file was generated by langium-cli 3.3.1. + * This file was generated by langium-cli 3.5.0. * DO NOT EDIT MANUALLY! ******************************************************************************/ diff --git a/packages/runtime/test/policy/client-extensions.test.ts b/packages/runtime/test/policy/client-extensions.test.ts new file mode 100644 index 00000000..813ab518 --- /dev/null +++ b/packages/runtime/test/policy/client-extensions.test.ts @@ -0,0 +1,181 @@ +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 () => { + const db = await createPolicyTestClient( + ` + model Model { + id String @id @default(uuid()) + x Int + y Int + + @@allow('read', x > 0) + } + `, + ); + + const rawDb = db.$unuseAll(); + await rawDb.model.create({ data: { x: 0, y: 100 } }); + await rawDb.model.create({ data: { x: 1, y: 200 } }); + await rawDb.model.create({ data: { x: 2, y: 300 } }); + + const ext = definePlugin({ + id: 'prisma-extension-queryOverride', + onQuery: { + model: { + findMany({ args, query }: any) { + args = args ?? {}; + args.where = { ...args.where, y: { lt: 300 } }; + return query(args); + }, + }, + }, + }); + + await expect(db.$use(ext).model.findMany()).resolves.toHaveLength(1); + await expect(db.$use(ext).model.findMany()).resolves.toHaveLength(1); + }); + + it('query override all models', async () => { + const db = await createPolicyTestClient( + ` + model Model { + id String @id @default(uuid()) + x Int + y Int + + @@allow('read', x > 0) + } + `, + ); + + const rawDb = db.$unuseAll(); + await rawDb.model.create({ data: { x: 0, y: 100 } }); + await rawDb.model.create({ data: { x: 1, y: 200 } }); + await rawDb.model.create({ data: { x: 2, y: 300 } }); + + const ext = definePlugin({ + id: 'prisma-extension-queryOverride', + onQuery: { + $allModels: { + async findMany({ args, query }: any) { + args = args ?? {}; + args.where = { ...args.where, y: { lt: 300 } }; + return query(args); + }, + }, + }, + }); + + await expect(db.$use(ext).model.findMany()).resolves.toHaveLength(1); + await expect(db.$use(ext).model.findMany()).resolves.toHaveLength(1); + }); + + it('query override all operations', async () => { + const db = await createPolicyTestClient( + ` + model Model { + id String @id @default(uuid()) + x Int + y Int + + @@allow('read', x > 0) + } + `, + ); + + const rawDb = db.$unuseAll(); + await rawDb.model.create({ data: { x: 0, y: 100 } }); + await rawDb.model.create({ data: { x: 1, y: 200 } }); + await rawDb.model.create({ data: { x: 2, y: 300 } }); + + const ext = definePlugin({ + id: 'prisma-extension-queryOverride', + onQuery: { + model: { + async $allOperations({ args, query }: any) { + args = args ?? {}; + args.where = { ...args.where, y: { lt: 300 } }; + return query(args); + }, + }, + }, + }); + + await expect(db.$use(ext).model.findMany()).resolves.toHaveLength(1); + await expect(db.$use(ext).model.findMany()).resolves.toHaveLength(1); + }); + + it('query override everything', async () => { + const db = await createPolicyTestClient( + ` + model Model { + id String @id @default(uuid()) + x Int + y Int + + @@allow('read', x > 0) + } + `, + ); + + const rawDb = db.$unuseAll(); + await rawDb.model.create({ data: { x: 0, y: 100 } }); + await rawDb.model.create({ data: { x: 1, y: 200 } }); + await rawDb.model.create({ data: { x: 2, y: 300 } }); + + const ext = definePlugin({ + id: 'prisma-extension-queryOverride', + onQuery: { + $allModels: { + $allOperations({ args, query }: any) { + args = args ?? {}; + args.where = { ...args.where, y: { lt: 300 } }; + return query(args); + }, + }, + }, + }); + + await expect(db.$use(ext).model.findMany()).resolves.toHaveLength(1); + await expect(db.$use(ext).model.findMany()).resolves.toHaveLength(1); + }); + + it('result mutation', async () => { + const db = await createPolicyTestClient( + ` + model Model { + id String @id @default(uuid()) + value Int + + @@allow('read', value > 0) + } + `, + ); + + const rawDb = db.$unuseAll(); + await rawDb.model.create({ data: { value: 0 } }); + await rawDb.model.create({ data: { value: 1 } }); + + const ext = definePlugin({ + id: 'prisma-extension-resultMutation', + onQuery: { + model: { + async findMany({ args, query }: any) { + const r: any = await query(args); + for (let i = 0; i < r.length; i++) { + r[i].value = r[i].value + 1; + } + return r; + }, + }, + }, + }); + + const expected = [expect.objectContaining({ value: 2 })]; + await expect(db.$use(ext).model.findMany()).resolves.toEqual(expected); + await expect(db.$use(ext).model.findMany()).resolves.toEqual(expected); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 45d2ff35..b817b6f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,8 +10,11 @@ catalogs: specifier: ^0.27.6 version: 0.27.6 langium: - specifier: ^3.3.0 - version: 3.3.0 + specifier: 3.5.0 + version: 3.5.0 + langium-cli: + specifier: 3.5.0 + version: 3.5.0 prisma: specifier: ^6.0.0 version: 6.9.0 @@ -85,7 +88,7 @@ importers: version: 8.3.0 langium: specifier: 'catalog:' - version: 3.3.0 + version: 3.5.0 ora: specifier: ^5.4.1 version: 5.4.1 @@ -155,7 +158,7 @@ importers: version: link:../../language langium: specifier: 'catalog:' - version: 3.3.0 + version: 3.5.0 vscode-languageclient: specifier: ^9.0.1 version: 9.0.1 @@ -177,7 +180,7 @@ importers: dependencies: langium: specifier: 'catalog:' - version: 3.3.0 + version: 3.5.0 pluralize: specifier: ^8.0.0 version: 8.0.0 @@ -195,8 +198,8 @@ importers: specifier: workspace:* version: link:../typescript-config langium-cli: - specifier: ~3.3.0 - version: 3.3.0 + specifier: 'catalog:' + version: 3.5.0 packages/runtime: dependencies: @@ -272,7 +275,7 @@ importers: version: link:../language langium: specifier: 'catalog:' - version: 3.3.0 + version: 3.5.0 ts-pattern: specifier: 'catalog:' version: 5.7.1 @@ -1704,17 +1707,17 @@ packages: resolution: {integrity: sha512-FIyV/64EkKhJmjgC0g2hygpBv5RNWVPyNCqSAD7eTCv6eFWNIi4PN1UvdSJGicN/o35bnevgis4Y0UDC0qi8jQ==} engines: {node: '>=14.0.0'} - langium-cli@3.3.0: - resolution: {integrity: sha512-QWvlOYdLbso8/lv6Ma+SBtvMN9k70JrplLx6VSIcV7gJNDTXeS+tjwC/f6T0aco1fg8uLL8GiAcaMovd1FnneA==} - engines: {node: '>=16.0.0'} + langium-cli@3.5.0: + resolution: {integrity: sha512-TPIzIiMAQwTPPphtHGSrFXo4t0orx3aRh0syg9jnOihvBkBDvsQdJP9fBo9hp5Qaosklpc2CfbH0wh/dkgZcJA==} + engines: {node: '>=18.0.0'} hasBin: true - langium-railroad@3.3.0: - resolution: {integrity: sha512-x56CU0KnLoqYLkHEPDJjFoekFoCVbbZbmHduldiXjKD8owt6t5aqgWfg31OeMeR+7XgONZTtmsO76yl6GvEkzQ==} + langium-railroad@3.5.0: + resolution: {integrity: sha512-80Enc6bOR6oHZD18IQlVTdfCh07rbrM5SOsPUPc1kyh7n3zQbmLs5P2E9hV4SoWlkhOjGKL1I9Z6uORpgy+jTQ==} - langium@3.3.0: - resolution: {integrity: sha512-y1n1MxeHtXvE0Ksi/HjLCvesHm3/Vr0pyyuA1fn+vmGSYR81NkxnC3bU4kd2o0CrZaz8xekz9rhm+lGfRgNFzw==} - engines: {node: '>=16.0.0'} + langium@3.5.0: + resolution: {integrity: sha512-tnqVzWOkUcoiY0bWlyE8diFrZjmGBCF7MesC1bjUaZM+YGQSfdPC+KkhmHM0DWFG+uLcPxidKaPP1SYGtg3J0Q==} + engines: {node: '>=18.0.0'} levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} @@ -3736,22 +3739,22 @@ snapshots: kysely@0.27.6: {} - langium-cli@3.3.0: + langium-cli@3.5.0: dependencies: chalk: 5.3.0 commander: 11.0.0 fs-extra: 11.1.1 jsonschema: 1.4.1 - langium: 3.3.0 - langium-railroad: 3.3.0 + langium: 3.5.0 + langium-railroad: 3.5.0 lodash: 4.17.21 - langium-railroad@3.3.0: + langium-railroad@3.5.0: dependencies: - langium: 3.3.0 + langium: 3.5.0 railroad-diagrams: 1.0.0 - langium@3.3.0: + langium@3.5.0: dependencies: chevrotain: 11.0.3 chevrotain-allstar: 0.3.1(chevrotain@11.0.3) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0adec6d2..46f0618c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,6 +6,7 @@ catalog: kysely: ^0.27.6 zod: ^3.25.67 prisma: ^6.0.0 - langium: ^3.3.0 + langium: 3.5.0 + langium-cli: 3.5.0 ts-pattern: ^5.7.1 typescript: ^5.0.0