Skip to content
Closed
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a3722b0
chore: bump version v2
ymc9 Dec 18, 2023
76bbe95
Merge remote-tracking branch 'origin/dev' into v2
ymc9 Jan 2, 2024
50e5dbc
Merge remote-tracking branch 'origin/dev' into v2
ymc9 Jan 8, 2024
e574048
refactor: generate `enhance` API and avoid dynamic `require` in runti…
ymc9 Jan 8, 2024
d2d07ae
refactor: merge core plugins (#939)
ymc9 Jan 9, 2024
e6e2171
refactor: unify enhancement API to `enhance` (#940)
ymc9 Jan 10, 2024
7048b0f
Merge remote-tracking branch 'origin/dev' into v2
ymc9 Jan 10, 2024
e2c2867
Merge remote-tracking branch 'origin/dev' into v2
ymc9 Jan 17, 2024
445dbca
Merge remote-tracking branch 'origin/dev' into v2
ymc9 Jan 26, 2024
2b3cf70
Support for auth() in @default attribute (#958)
Azzerty23 Jan 26, 2024
9f2dfb1
refactor: simplify zmodel linking by improving scope computation; mak…
ymc9 Jan 27, 2024
93d8812
new check method on proxy
Azzerty23 Jan 29, 2024
21e1061
Merge remote-tracking branch 'origin/dev' into v2
ymc9 Jan 31, 2024
a8fb39c
Merge remote-tracking branch 'origin/dev' into v2
ymc9 Feb 5, 2024
c8a19e9
Merge remote-tracking branch 'origin/dev' into v2
ymc9 Feb 10, 2024
bac3683
feat: polymorphism (#990)
ymc9 Feb 12, 2024
870cb54
wip
Azzerty23 Feb 13, 2024
0210e12
Merge branch 'v2' into feature/permission-checker
Azzerty23 Feb 13, 2024
57316df
chore: remove CLI config (#999)
ymc9 Feb 13, 2024
c1da257
merge from dev (#1001)
ymc9 Feb 13, 2024
6244f47
wip
Azzerty23 Feb 13, 2024
7b453f7
fix: improve generated typing for polymorphic models (#1002)
ymc9 Feb 14, 2024
3277ffd
feat(check method): handle very basic use cases
Azzerty23 Feb 15, 2024
4ff1628
refactor(z3-expr-transformer): remove inverse parameter
Azzerty23 Feb 15, 2024
df5e967
Merge branch 'v2' into feature/permission-checker
Azzerty23 Feb 15, 2024
03b5459
refactor: remove z3-solver dependency from generated policy file
Azzerty23 Feb 15, 2024
7c40fd3
fix: revert typing changes
Azzerty23 Feb 15, 2024
e3f1538
feat: improve auth constraints
Azzerty23 Feb 15, 2024
22ed47c
refactor(z3): remove normalizeUndefined option
Azzerty23 Feb 15, 2024
2504e8e
feat: transform null as undefined
Azzerty23 Feb 17, 2024
7ffb723
feat: add support for boolean
Azzerty23 Feb 18, 2024
6cd53a5
fix: avoid conflict and reserved word
Azzerty23 Feb 18, 2024
b53b05a
pass null expressions and fix auth() in right expr of binary expr
Azzerty23 Feb 19, 2024
e1497c0
fix: vue-query typing issue (#1009)
ymc9 Feb 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"plugin:jest/recommended"
],
"rules": {
"jest/expect-expect": "off",
"@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }]
"@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }],
"jest/expect-expect": "off"
}
}
9 changes: 1 addition & 8 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ env:

on:
pull_request:
branches: ['dev', 'main']
branches: ['dev', 'main', 'v2']

jobs:
build-test:
Expand All @@ -32,18 +32,11 @@ jobs:
strategy:
matrix:
node-version: [20.x]
prisma-version: [v4, v5]

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Set Prisma Version
if: ${{ matrix.prisma-version == 'v5' }}
shell: bash
run: |
bash ./script/test-prisma-v5.sh

- name: Install pnpm
uses: pnpm/action-setup@v2
with:
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ The ZModel language's definition, including its syntax definition and parser/lin

### `schema`

The `zenstack` CLI and ZModel VSCode extension implementation. The package also contains several built-in plugins: `@core/prisma`, `@core/model-meta`, `@core/access-policy`, and `core/zod`.
The `zenstack` CLI and ZModel VSCode extension implementation. The package also contains several built-in plugins: `@core/prisma`, `@core/enhancer`, and `core/zod`.

### `runtime`

Runtime enhancements to PrismaClient, including infrastructure for creating transparent proxies and concrete implementations for the `withPolicy`, `withPassword`, and `withOmit` proxies.
Runtime enhancements to PrismaClient, including infrastructure for creating transparent proxies and concrete implementations of various proxies.

### `server`

Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
{
"name": "zenstack-monorepo",
"version": "1.8.2",
"version": "2.0.0-alpha.1",
"description": "",
"scripts": {
"build": "pnpm -r build",
"lint": "pnpm -r lint",
"test": "ZENSTACK_TEST=1 pnpm -r run test --silent --forceExit",
"test": "ZENSTACK_TEST=1 pnpm --filter integration -r run test --verbose --silent=false --forceExit",
"test-ci": "ZENSTACK_TEST=1 pnpm -r run test --silent --forceExit",
"publish-all": "pnpm --filter \"./packages/**\" -r publish --access public",
"publish-preview": "pnpm --filter \"./packages/**\" -r publish --force --registry https://preview.registry.zenstack.dev/",
"unpublish-preview": "pnpm --recursive --shell-mode exec -- npm unpublish -f --registry https://preview.registry.zenstack.dev/ \"\\$PNPM_PACKAGE_NAME\""
"unpublish-preview": "pnpm --recursive --shell-mode exec -- npm unpublish -f --registry https://preview.registry.zenstack.dev/ \"\\$PNPM_PACKAGE_NAME\"",
"publish-next": "pnpm --filter \"./packages/**\" -r publish --access public --tag next",
"publish-preview-next": "pnpm --filter \"./packages/**\" -r publish --force --registry https://preview.registry.zenstack.dev/ --tag next",
"unpublish-preview-next": "pnpm --recursive --shell-mode exec -- npm unpublish -f --registry https://preview.registry.zenstack.dev/ --tag next \"\\$PNPM_PACKAGE_NAME\""
},
"keywords": [],
"author": "",
Expand Down
4 changes: 2 additions & 2 deletions packages/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ At runtime, transparent proxies are created around Prisma clients for intercepti
// Next.js example: pages/api/model/[...path].ts

import { requestHandler } from '@zenstackhq/next';
import { withPolicy } from '@zenstackhq/runtime';
import { enhance } from '@zenstackhq/runtime';
import { getSessionUser } from '@lib/auth';
import { prisma } from '@lib/db';

export default requestHandler({
getPrisma: (req, res) => withPolicy(prisma, { user: getSessionUser(req, res) }),
getPrisma: (req, res) => enhance(prisma, { user: getSessionUser(req, res) }),
});
```

Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

group = "dev.zenstack"
version = "1.8.2"
version = "2.0.0-alpha.1"

repositories {
mavenCentral()
Expand Down
4 changes: 2 additions & 2 deletions packages/ide/jetbrains/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "jetbrains",
"version": "1.8.2",
"version": "2.0.0-alpha.1",
"displayName": "ZenStack JetBrains IDE Plugin",
"description": "ZenStack JetBrains IDE plugin",
"homepage": "https://zenstack.dev",
"private": true,
"scripts": {
"build": "./gradlew buildPlugin"
"build": "./gradlew buildPlugin"
},
"author": "ZenStack Team",
"license": "MIT",
Expand Down
6 changes: 3 additions & 3 deletions packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/language",
"version": "1.8.2",
"version": "2.0.0-alpha.1",
"displayName": "ZenStack modeling language compiler",
"description": "ZenStack modeling language compiler",
"homepage": "https://zenstack.dev",
Expand All @@ -19,11 +19,11 @@
"author": "ZenStack Team",
"license": "MIT",
"devDependencies": {
"langium-cli": "1.2.0",
"langium-cli": "1.3.1",
"plist2": "^1.1.3"
},
"dependencies": {
"langium": "1.2.0"
"langium": "1.3.1"
},
"contributes": {
"languages": [
Expand Down
29 changes: 21 additions & 8 deletions packages/language/src/ast.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { AbstractDeclaration, ExpressionType, BinaryExpr } from './generated/ast';
import { AstNode } from 'langium';
import { AbstractDeclaration, BinaryExpr, DataModel, ExpressionType } from './generated/ast';

export * from './generated/ast';
export { AstNode, Reference } from 'langium';
export * from './generated/ast';

/**
* Shape of type resolution result: an expression type or reference to a declaration
Expand Down Expand Up @@ -44,16 +45,28 @@ declare module './generated/ast' {
$resolvedParam?: AttributeParam;
}

interface DataModel {
interface DataModelField {
$inheritedFrom?: DataModel;
}

interface DataModelAttribute {
$inheritedFrom?: DataModel;
}

export interface DataModel {
/**
* Resolved fields, include inherited fields
* Indicates whether the model is already merged with the base types
*/
$resolvedFields: Array<DataModelField>;
$baseMerged?: boolean;
}
}

interface DataModelField {
$isInherited?: boolean;
}
export interface InheritableNode extends AstNode {
$inheritedFrom?: DataModel;
}

export interface InheritableNode extends AstNode {
$inheritedFrom?: DataModel;
}

declare module 'langium' {
Expand Down
53 changes: 33 additions & 20 deletions packages/language/src/generated/ast.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
/******************************************************************************
* This file was generated by langium-cli 1.2.0.
* This file was generated by langium-cli 1.3.1.
* DO NOT EDIT MANUALLY!
******************************************************************************/

/* eslint-disable */
import { AstNode, AbstractAstReflection, Reference, ReferenceInfo, TypeMetaData } from 'langium';
import type { AstNode, Reference, ReferenceInfo, TypeMetaData } from 'langium';
import { AbstractAstReflection } from 'langium';

export const ZModelTerminals = {
WS: /\s+/,
INTERNAL_ATTRIBUTE_NAME: /@@@([_a-zA-Z][\w_]*\.)*[_a-zA-Z][\w_]*/,
MODEL_ATTRIBUTE_NAME: /@@([_a-zA-Z][\w_]*\.)*[_a-zA-Z][\w_]*/,
FIELD_ATTRIBUTE_NAME: /@([_a-zA-Z][\w_]*\.)*[_a-zA-Z][\w_]*/,
ID: /[_a-zA-Z][\w_]*/,
STRING: /"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/,
NUMBER: /[+-]?[0-9]+(\.[0-9]+)?/,
TRIPLE_SLASH_COMMENT: /\/\/\/[^\n\r]*/,
ML_COMMENT: /\/\*[\s\S]*?\*\//,
SL_COMMENT: /\/\/[^\n\r]*/,
};

export type AbstractDeclaration = Attribute | DataModel | DataSource | Enum | FunctionDecl | GeneratorDecl | Plugin;

Expand Down Expand Up @@ -64,10 +78,10 @@ export function isReferenceTarget(item: unknown): item is ReferenceTarget {
return reflection.isInstance(item, ReferenceTarget);
}

export type RegularID = 'abstract' | 'attribute' | 'datasource' | 'enum' | 'import' | 'in' | 'model' | 'plugin' | 'sort' | 'view' | string;
export type RegularID = 'abstract' | 'attribute' | 'datasource' | 'enum' | 'import' | 'in' | 'model' | 'plugin' | 'view' | string;

export function isRegularID(item: unknown): item is RegularID {
return item === 'model' || item === 'enum' || item === 'attribute' || item === 'datasource' || item === 'plugin' || item === 'abstract' || item === 'in' || item === 'sort' || item === 'view' || item === 'import' || (typeof item === 'string' && (/[_a-zA-Z][\w_]*/.test(item)));
return item === 'model' || item === 'enum' || item === 'attribute' || item === 'datasource' || item === 'plugin' || item === 'abstract' || item === 'in' || item === 'view' || item === 'import' || (typeof item === 'string' && (/[_a-zA-Z][\w_]*/.test(item)));
}

export type TypeDeclaration = DataModel | Enum;
Expand All @@ -81,7 +95,6 @@ export function isTypeDeclaration(item: unknown): item is TypeDeclaration {
export interface Argument extends AstNode {
readonly $container: InvocationExpr;
readonly $type: 'Argument';
name?: RegularID
value: Expression
}

Expand All @@ -92,7 +105,7 @@ export function isArgument(item: unknown): item is Argument {
}

export interface ArrayExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'ArrayExpr';
items: Array<Expression>
}
Expand Down Expand Up @@ -163,7 +176,7 @@ export function isAttributeParamType(item: unknown): item is AttributeParamType
}

export interface BinaryExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'BinaryExpr';
left: Expression
operator: '!' | '!=' | '&&' | '<' | '<=' | '==' | '>' | '>=' | '?' | '^' | 'in' | '||'
Expand All @@ -177,7 +190,7 @@ export function isBinaryExpr(item: unknown): item is BinaryExpr {
}

export interface BooleanLiteral extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'BooleanLiteral';
value: Boolean
}
Expand All @@ -189,7 +202,7 @@ export function isBooleanLiteral(item: unknown): item is BooleanLiteral {
}

export interface ConfigArrayExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'ConfigArrayExpr';
items: Array<ConfigInvocationExpr | LiteralExpr>
}
Expand Down Expand Up @@ -440,7 +453,7 @@ export function isInternalAttribute(item: unknown): item is InternalAttribute {
}

export interface InvocationExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'InvocationExpr';
args: Array<Argument>
function: Reference<FunctionDecl>
Expand All @@ -453,7 +466,7 @@ export function isInvocationExpr(item: unknown): item is InvocationExpr {
}

export interface MemberAccessExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'MemberAccessExpr';
member: Reference<DataModelField>
operand: Expression
Expand Down Expand Up @@ -490,7 +503,7 @@ export function isModelImport(item: unknown): item is ModelImport {
}

export interface NullExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'NullExpr';
value: 'null'
}
Expand All @@ -502,7 +515,7 @@ export function isNullExpr(item: unknown): item is NullExpr {
}

export interface NumberLiteral extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'NumberLiteral';
value: string
}
Expand All @@ -514,7 +527,7 @@ export function isNumberLiteral(item: unknown): item is NumberLiteral {
}

export interface ObjectExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'ObjectExpr';
fields: Array<FieldInitializer>
}
Expand Down Expand Up @@ -554,8 +567,8 @@ export function isPluginField(item: unknown): item is PluginField {
export interface ReferenceArg extends AstNode {
readonly $container: ReferenceExpr;
readonly $type: 'ReferenceArg';
name: 'sort'
value: 'Asc' | 'Desc'
name: string
value: Expression
}

export const ReferenceArg = 'ReferenceArg';
Expand All @@ -565,7 +578,7 @@ export function isReferenceArg(item: unknown): item is ReferenceArg {
}

export interface ReferenceExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'ReferenceExpr';
args: Array<ReferenceArg>
target: Reference<ReferenceTarget>
Expand All @@ -578,7 +591,7 @@ export function isReferenceExpr(item: unknown): item is ReferenceExpr {
}

export interface StringLiteral extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'StringLiteral';
value: string
}
Expand All @@ -590,7 +603,7 @@ export function isStringLiteral(item: unknown): item is StringLiteral {
}

export interface ThisExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'ThisExpr';
value: 'this'
}
Expand All @@ -602,7 +615,7 @@ export function isThisExpr(item: unknown): item is ThisExpr {
}

export interface UnaryExpr extends AstNode {
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | UnaryExpr | UnsupportedFieldType;
readonly $container: Argument | ArrayExpr | AttributeArg | BinaryExpr | ConfigArrayExpr | ConfigField | ConfigInvocationArg | FieldInitializer | FunctionDecl | MemberAccessExpr | PluginField | ReferenceArg | UnaryExpr | UnsupportedFieldType;
readonly $type: 'UnaryExpr';
operand: Expression
operator: '!'
Expand Down
Loading