- πΊπΈUnited States m.stenta
We have automated tests now ( π Add basic test coverage Active ) so it would be good to include a test to demonstrate this issue and prevent regressions.
As I was working on various issues to make the config schema for field_storage_config
be exposed via this wonderful module (see
#3324769: Schema incorrect for config entity types with multi-part IDs (field_storage_config, field_config, entity_view_mode, entity_form_mode, entity_view_display and entity_form_display) β
+
#3324824: Schema incorrect for config entity "fields" that are Maps and Sequences β
), specifically for
https://www.drupal.org/project/field_ui_modern β
, I discovered/realized that there is a lot left to be explored WRT JSON Schema and specifically the validation aspects of it, which are covered by https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validati....
This module already exposes things like required
, but rarely more than that. Ideally, we should be able to automatically transform both content entity validation constraints and config schema types + validation constraints (see
π±
[META] Untie config validation from form validation β enables validatable Recipes, decoupled admin UIs β¦
Active
).
Relates issues but with a narrower scope: π Ensure valid "type" values for JSON data types Active , #3174991: Include all bundles in the enum for entity_reference fields β and π Properly handle nullable values Active
P.S.: I thought https://modern-json-schema.com/json-schema-is-a-constraint-system was a particularly good high-level introduction.
Generate a far richer schema, somewhat like this β note the use of:
uniqueItems
exclusiveMinimum
required
enum
$drupalUiHint
β Drupal-specific addition!$drupalPluginIdOfType
β Drupal-specific addition!{
"$schema": "https://json-schema.org/draft/2019-09/hyper-schema",
"$id": "/jsonapi/field_storage_config/field_storage_config/resource/schema",
"title": "Field storage",
"allOf": [
{
"type": "object",
"properties": {
"type": {
"$ref": "#/definitions/type"
},
"attributes": {
"$ref": "#/definitions/attributes"
}
}
},
{
"$ref": "https://jsonapi.org/schema#/definitions/resource"
}
],
"definitions": {
"type": {
"const": "field_storage_config--field_storage_config"
},
"attributes": {
"type": "object",
"description": "Entity attributes",
"required": [
"entity_type",
"field_name",
"field_storage_config_type"
],
"properties": {
"uuid": {
"type": "string",
"title": "UUID",
"format": "uuid",
"maxLength": 128,
"$drupalUiHint": "no-ui"
},
"drupal_internal__id": {
"type": "string",
"title": "drupal_internal__id",
"pattern": "^(node|media|taxonomy_term|user)\\.[_a-z]+[_a-z0-9]*$",
"$comment": "The ID consists of 2 parts: the entity type and the field name."
},
"field_name": {
"type": "string",
"title": "Field name",
"pattern": "^[_a-z]+[_a-z0-9]*$",
"description": "The name of the field."
},
"entity_type": {
"type": "string",
"title": "Entity Type",
"enum": [
"node",
"media",
"taxonomy_term",
"user"
],
"$drupalPluginIdOfType": "content_entity_type",
"$drupalUiHint": "dropdown"
},
"field_storage_config_type": {
"type": "string",
"title": "Field type",
"$comment": "Tricky: This is only not called 'type' because that is a reserved keyword in JSON:API.",
"description": "Choose a field type.",
"enum": [
"uuid",
"boolean",
"decimal",
"email",
"entity_reference",
"float",
"integer",
"string",
"string_long",
"timestamp",
"comment",
"datetime",
"daterange"
],
"$drupalPluginIdOfType": "field_type",
"$drupalUiHint": "dropdown"
},
"langcode": {
"type": "string",
"title": "Language",
"enum": ["en"],
"default": "en",
"$drupalUiHint": "no-ui"
},
"status": {
"type": "boolean",
"title": "Status",
"default": true
},
"dependencies": {
"type": "object",
"title": "Dependencies",
"$drupalUiHint": "no-ui",
"additionalProperties": false,
"properties": {
"config": {
"type": "array",
"uniqueItems": true,
"title": "Configuration dependencies",
"items": {
"type": "string",
"title": "Configuration dependency"
}
},
"content": {
"type": "array",
"uniqueItems": true,
"title": "Content dependencies",
"items": {
"type": "string",
"title": "Content dependency"
}
},
"module": {
"type": "array",
"uniqueItems": true,
"title": "Module dependencies",
"items": {
"type": "string",
"title": "Module dependency"
}
},
"theme": {
"type": "array",
"uniqueItems": true,
"title": "Theme dependencies",
"items": {
"type": "string",
"title": "Theme dependency"
}
}
},
"enforced": {
"type": "object",
"title": "Enforced dependencies",
"additionalProperties": false,
"properties": {
"config": {
"type": "array",
"uniqueItems": true,
"title": "Configuration dependencies",
"items": {
"type": "string",
"title": "Configuration dependency"
}
},
"content": {
"type": "array",
"uniqueItems": true,
"title": "Content dependencies",
"items": {
"type": "string",
"title": "Content dependency"
}
},
"module": {
"type": "array",
"uniqueItems": true,
"title": "Module dependencies",
"items": {
"type": "string",
"title": "Module dependency"
}
},
"theme": {
"type": "array",
"uniqueItems": true,
"title": "Theme dependencies",
"items": {
"type": "string",
"title": "Theme dependency"
}
}
}
}
},
"third_party_settings": {
"type": "array",
"items": {
"properties": {
"third_party_settings": {
"title": "third_party_settings"
}
}
}
},
"locked": {
"type": "boolean",
"title": "Locked",
"description": "Whether the field storage is locked or not. When locked, field settings cannot be changed, no new fields can be created using this storage, and existing fields using this storage cannot be deleted.",
"default": false,
"$drupalUiHint": "no-ui-when-creating"
},
"cardinality": {
"type": "integer",
"title": "Cardinality",
"description": "Allowed number of values",
"exclusiveMinimum": 1,
"default": 1
},
"translatable": {
"type": "boolean",
"title": "Translatable",
"default": true
},
"indexes": {
"type": "array",
"$drupalUiHint": "no-ui",
"items": {
"properties": {
"indexes": {
"title": "indexes"
}
}
}
},
"persist_with_no_fields": {
"type": "boolean",
"title": "Whether the field storage should be persisted when orphaned",
"default": false,
"$drupalUiHint": "no-ui"
},
"custom_storage": {
"type": "boolean",
"title": "custom_storage",
"default": false,
"$drupalUiHint": "no-ui"
}
},
"additionalProperties": false
}
}
}
TBD
TBD
TBD
TBD
Needs work
1.0
Code
It denotes an issue that prevents porting of a contributed project to the stable version of Drupal due to missing APIs, regressions, and so on.
The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.
We have automated tests now ( π Add basic test coverage Active ) so it would be good to include a test to demonstrate this issue and prevent regressions.