From d7c8e8d4e0abdd5a83e644922785c5bbeb84b1cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SAL=C4=B0H=20=C3=96ZKARA?= Date: Wed, 18 Feb 2026 12:51:03 +0300 Subject: [PATCH] Add lowcode JSON schema definitions Introduce a set of JSON Schema definitions for the ABP Low Code model. Adds schema files for entities, properties, property types, UI descriptors, form availability, enums, foreign keys, interceptors, command interceptors, validators, and custom HTTP endpoints, plus a top-level model.schema.json that references these definitions to validate model.json configuration files. These schemas enable validation and tooling for lowcode entity/config definitions and custom endpoint JavaScript payloads. --- ...command-interceptor-descriptor.schema.json | 23 +++++++ .../endpoint-descriptor.schema.json | 44 ++++++++++++ .../definitions/entity-descriptor.schema.json | 42 +++++++++++ .../entity-property-descriptor.schema.json | 58 ++++++++++++++++ .../entity-property-type.schema.json | 25 +++++++ .../entity-property-ui-descriptor.schema.json | 32 +++++++++ ...-property-ui-form-availability.schema.json | 15 ++++ .../entity-ui-descriptor.schema.json | 14 ++++ .../definitions/enum-descriptor.schema.json | 40 +++++++++++ .../foreign-key-descriptor.schema.json | 27 ++++++++ .../definitions/interceptor-type.schema.json | 15 ++++ .../validator-descriptor.schema.json | 69 +++++++++++++++++++ lowcode/schema/model.schema.json | 34 +++++++++ 13 files changed, 438 insertions(+) create mode 100644 lowcode/schema/definitions/command-interceptor-descriptor.schema.json create mode 100644 lowcode/schema/definitions/endpoint-descriptor.schema.json create mode 100644 lowcode/schema/definitions/entity-descriptor.schema.json create mode 100644 lowcode/schema/definitions/entity-property-descriptor.schema.json create mode 100644 lowcode/schema/definitions/entity-property-type.schema.json create mode 100644 lowcode/schema/definitions/entity-property-ui-descriptor.schema.json create mode 100644 lowcode/schema/definitions/entity-property-ui-form-availability.schema.json create mode 100644 lowcode/schema/definitions/entity-ui-descriptor.schema.json create mode 100644 lowcode/schema/definitions/enum-descriptor.schema.json create mode 100644 lowcode/schema/definitions/foreign-key-descriptor.schema.json create mode 100644 lowcode/schema/definitions/interceptor-type.schema.json create mode 100644 lowcode/schema/definitions/validator-descriptor.schema.json create mode 100644 lowcode/schema/model.schema.json diff --git a/lowcode/schema/definitions/command-interceptor-descriptor.schema.json b/lowcode/schema/definitions/command-interceptor-descriptor.schema.json new file mode 100644 index 0000000000..ad0d0b02bd --- /dev/null +++ b/lowcode/schema/definitions/command-interceptor-descriptor.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "command-interceptor-descriptor.schema.json", + "title": "CommandInterceptorDescriptor", + "description": "Describes a command interceptor", + "type": "object", + "properties": { + "commandName": { + "type": "string", + "description": "Name of the command to intercept", + "enum": ["Create", "Update", "Delete"] + }, + "type": { + "$ref": "interceptor-type.schema.json" + }, + "javascript": { + "type": "string", + "description": "JavaScript code to execute" + } + }, + "required": ["commandName", "type", "javascript"], + "additionalProperties": false +} \ No newline at end of file diff --git a/lowcode/schema/definitions/endpoint-descriptor.schema.json b/lowcode/schema/definitions/endpoint-descriptor.schema.json new file mode 100644 index 0000000000..4be4ccb761 --- /dev/null +++ b/lowcode/schema/definitions/endpoint-descriptor.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Custom Endpoint Descriptor", + "description": "Defines a custom HTTP endpoint that executes JavaScript code", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Unique identifier for the endpoint" + }, + "route": { + "type": "string", + "description": "URL route pattern (e.g., '/api/custom/products/{id}')" + }, + "method": { + "type": "string", + "description": "HTTP method", + "enum": ["GET", "POST", "PUT", "DELETE", "PATCH"], + "default": "GET" + }, + "javascript": { + "type": "string", + "description": "JavaScript code to execute. Has access to context object with request, db, currentUser, emailSender." + }, + "requireAuthentication": { + "type": "boolean", + "description": "Whether authentication is required", + "default": true + }, + "requiredPermissions": { + "type": "array", + "description": "Permission names required to access the endpoint", + "items": { + "type": "string" + } + }, + "description": { + "type": "string", + "description": "Optional description for documentation" + } + }, + "required": ["name", "route", "javascript"], + "additionalProperties": false +} diff --git a/lowcode/schema/definitions/entity-descriptor.schema.json b/lowcode/schema/definitions/entity-descriptor.schema.json new file mode 100644 index 0000000000..2023a043bc --- /dev/null +++ b/lowcode/schema/definitions/entity-descriptor.schema.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "entity-descriptor.schema.json", + "title": "EntityDescriptor", + "description": "Describes an entity configuration", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Full name of the entity (e.g., 'Namespace.EntityName')", + "minLength": 1 + }, + "displayProperty": { + "type": "string", + "description": "The property to be used as the display property for the entity" + }, + "parent": { + "type": "string", + "description": "Full name of the parent entity (e.g., 'Namespace.EntityName')", + "minLength": 1 + }, + "ui": { + "$ref": "entity-ui-descriptor.schema.json" + }, + "properties": { + "type": "array", + "description": "List of property descriptors", + "items": { + "$ref": "entity-property-descriptor.schema.json" + } + }, + "interceptors": { + "type": "array", + "description": "List of command interceptors", + "items": { + "$ref": "command-interceptor-descriptor.schema.json" + } + } + }, + "required": ["name"], + "additionalProperties": false +} \ No newline at end of file diff --git a/lowcode/schema/definitions/entity-property-descriptor.schema.json b/lowcode/schema/definitions/entity-property-descriptor.schema.json new file mode 100644 index 0000000000..ceeeb9eb60 --- /dev/null +++ b/lowcode/schema/definitions/entity-property-descriptor.schema.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "entity-property-descriptor.schema.json", + "title": "EntityPropertyDescriptor", + "description": "Describes a property configuration", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the property", + "minLength": 1 + }, + "type": { + "$ref": "entity-property-type.schema.json" + }, + "enumType": { + "type": "string", + "description": "Name of a JSON-defined enum (or full type name for code enums)" + }, + "allowSetByClients": { + "type": "boolean", + "description": "Indicates whether clients are allowed to set this property" + }, + "serverOnly": { + "type": "boolean", + "description": "When true, this property is completely hidden from clients (API responses and UI definitions). Use for sensitive data like passwords." + }, + "isMappedToDbField": { + "type": "boolean", + "description": "Indicates whether the property is mapped to a database field" + }, + "isUnique": { + "type": "boolean", + "description": "Indicates whether the property value must be unique across all entities" + }, + "isRequired": { + "type": "boolean", + "description": "When true, the property is required (not nullable). Affects DB column (NOT NULL), UI validation, and backend validation." + }, + "ui": { + "$ref": "entity-property-ui-descriptor.schema.json" + }, + "foreignKey": { + "$ref": "foreign-key-descriptor.schema.json" + }, + "validators": { + "type": "array", + "description": "Array of validators to apply to this property", + "items": { + "$ref": "validator-descriptor.schema.json" + } + } + }, + "required": [ + "name" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/lowcode/schema/definitions/entity-property-type.schema.json b/lowcode/schema/definitions/entity-property-type.schema.json new file mode 100644 index 0000000000..5eb7defa6a --- /dev/null +++ b/lowcode/schema/definitions/entity-property-type.schema.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "entity-property-type.schema.json", + "title": "EntityPropertyType", + "description": "Data type of the property", + "type": "string", + "enum": [ + "string", + "String", + "int", + "Int", + "long", + "Long", + "decimal", + "Decimal", + "dateTime", + "DateTime", + "boolean", + "Boolean", + "guid", + "Guid", + "enum", + "Enum" + ] +} \ No newline at end of file diff --git a/lowcode/schema/definitions/entity-property-ui-descriptor.schema.json b/lowcode/schema/definitions/entity-property-ui-descriptor.schema.json new file mode 100644 index 0000000000..1a0ded7b76 --- /dev/null +++ b/lowcode/schema/definitions/entity-property-ui-descriptor.schema.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "entity-property-ui-descriptor.schema.json", + "title": "EntityPropertyUIDescriptor", + "description": "UI configuration for a property", + "type": "object", + "properties": { + "displayName": { + "type": "string", + "description": "Display name for the property in UI. Falls back to property name if not set." + }, + "isAvailableOnDataTable": { + "type": "boolean", + "description": "Whether the property is shown in the data table listing" + }, + "isAvailableOnDataTableFiltering": { + "type": "boolean", + "description": "Whether the property is available for filtering in the data table" + }, + "creationFormAvailability": { + "$ref": "entity-property-ui-form-availability.schema.json" + }, + "editingFormAvailability": { + "$ref": "entity-property-ui-form-availability.schema.json" + }, + "quickLookOrder": { + "type": "integer", + "description": "Order of the property in quick look views. Higher numbers appear first. Set to -1 to exclude from quick look. If no property has a value, first 5 properties by name are shown." + } + }, + "additionalProperties": false +} \ No newline at end of file diff --git a/lowcode/schema/definitions/entity-property-ui-form-availability.schema.json b/lowcode/schema/definitions/entity-property-ui-form-availability.schema.json new file mode 100644 index 0000000000..dff4a5665c --- /dev/null +++ b/lowcode/schema/definitions/entity-property-ui-form-availability.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "entity-property-ui-form-availability.schema.json", + "title": "EntityPropertyUIFormAvailability", + "description": "Availability of the property on forms", + "type": "string", + "enum": [ + "Available", + "available", + "Hidden", + "hidden", + "NotAvailable", + "notAvailable" + ] +} \ No newline at end of file diff --git a/lowcode/schema/definitions/entity-ui-descriptor.schema.json b/lowcode/schema/definitions/entity-ui-descriptor.schema.json new file mode 100644 index 0000000000..3525d6c38e --- /dev/null +++ b/lowcode/schema/definitions/entity-ui-descriptor.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "entity-ui-descriptor.schema.json", + "title": "EntityUIDescriptor", + "description": "UI configuration for the entity", + "type": "object", + "properties": { + "pageTitle": { + "type": "string", + "description": "Title to display on the entity's page" + } + }, + "additionalProperties": false +} \ No newline at end of file diff --git a/lowcode/schema/definitions/enum-descriptor.schema.json b/lowcode/schema/definitions/enum-descriptor.schema.json new file mode 100644 index 0000000000..055ca6e126 --- /dev/null +++ b/lowcode/schema/definitions/enum-descriptor.schema.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "enum-descriptor.schema.json", + "title": "EnumDescriptor", + "description": "Describes an enum definition for use in entity properties", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Unique name for the enum", + "minLength": 1 + }, + "values": { + "type": "array", + "description": "List of enum values", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Display name of the enum value" + }, + "value": { + "type": "integer", + "description": "Integer value (auto-assigned if omitted)" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1 + } + }, + "required": [ + "name", + "values" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/lowcode/schema/definitions/foreign-key-descriptor.schema.json b/lowcode/schema/definitions/foreign-key-descriptor.schema.json new file mode 100644 index 0000000000..27d0e81f03 --- /dev/null +++ b/lowcode/schema/definitions/foreign-key-descriptor.schema.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "foreign-key-descriptor.schema.json", + "title": "ForeignKeyDescriptor", + "description": "Describes a foreign key relationship", + "type": "object", + "properties": { + "entityName": { + "type": "string", + "description": "Full name of the related entity", + "minLength": 1 + }, + "displayPropertyName": { + "type": "string", + "description": "Property name to display from the related entity", + "minLength": 1 + }, + "access": { + "type": "string", + "description": "Access level for managing this relation from the referenced entity side. When set to 'view' or 'edit', the referenced entity can see/manage items that reference it.", + "enum": ["none", "view", "edit"], + "default": "none" + } + }, + "required": ["entityName"], + "additionalProperties": false +} \ No newline at end of file diff --git a/lowcode/schema/definitions/interceptor-type.schema.json b/lowcode/schema/definitions/interceptor-type.schema.json new file mode 100644 index 0000000000..435c26b434 --- /dev/null +++ b/lowcode/schema/definitions/interceptor-type.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "interceptor-type.schema.json", + "title": "InterceptorType", + "description": "When the interceptor runs", + "type": "string", + "enum": [ + "Pre", + "pre", + "Post", + "post", + "Replace", + "replace" + ] +} \ No newline at end of file diff --git a/lowcode/schema/definitions/validator-descriptor.schema.json b/lowcode/schema/definitions/validator-descriptor.schema.json new file mode 100644 index 0000000000..7eeac0eba9 --- /dev/null +++ b/lowcode/schema/definitions/validator-descriptor.schema.json @@ -0,0 +1,69 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "validator-descriptor.schema.json", + "title": "ValidatorDescriptor", + "description": "A single validator in the validators array", + "type": "object", + "required": ["type"], + "properties": { + "type": { + "type": "string", + "description": "Type of validator", + "enum": [ + "required", + "minLength", + "maxLength", + "stringLength", + "min", + "minimum", + "max", + "maximum", + "range", + "pattern", + "regularExpression", + "email", + "emailAddress", + "phone", + "url", + "creditCard" + ] + }, + "message": { + "type": "string", + "description": "Custom error message for this validator" + }, + "length": { + "type": "integer", + "description": "Length value for minLength, maxLength validators", + "minimum": 0 + }, + "minimumLength": { + "type": "integer", + "description": "Minimum length for stringLength validator", + "minimum": 0 + }, + "maximumLength": { + "type": "integer", + "description": "Maximum length for stringLength validator", + "minimum": 0 + }, + "value": { + "type": "number", + "description": "Value for min/minimum, max/maximum validators" + }, + "minimum": { + "type": "number", + "description": "Minimum value for range validator" + }, + "maximum": { + "type": "number", + "description": "Maximum value for range validator" + }, + "pattern": { + "type": "string", + "description": "Regular expression pattern for pattern/regularExpression validators" + } + }, + "additionalProperties": true +} + diff --git a/lowcode/schema/model.schema.json b/lowcode/schema/model.schema.json new file mode 100644 index 0000000000..3abcab70e4 --- /dev/null +++ b/lowcode/schema/model.schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "ABP Low Code Model", + "description": "Schema for ABP Low Code model.json configuration file", + "type": "object", + "properties": { + "$schema": { + "type": "string", + "description": "Reference to the JSON schema" + }, + "enums": { + "type": "array", + "description": "List of enum definitions", + "items": { + "$ref": "definitions/enum-descriptor.schema.json" + } + }, + "entities": { + "type": "array", + "description": "List of entity descriptors", + "items": { + "$ref": "definitions/entity-descriptor.schema.json" + } + }, + "endpoints": { + "type": "array", + "description": "List of custom HTTP endpoints that execute JavaScript code", + "items": { + "$ref": "definitions/endpoint-descriptor.schema.json" + } + } + }, + "additionalProperties": false +} \ No newline at end of file