From df0d471d6f6ca66bdba48f17ec21f5f267178b6b Mon Sep 17 00:00:00 2001 From: Giles Knap Date: Tue, 11 Jul 2023 09:19:25 +0000 Subject: [PATCH] switched Support to Pydantic2 (intermediate breaking change) --- src/ibek/__main__.py | 28 +- src/ibek/globals.py | 16 +- src/ibek/support.py | 183 ++-- tests/samples/schemas/ibek.defs.schema.json | 873 ++++++++++++-------- 4 files changed, 619 insertions(+), 481 deletions(-) diff --git a/src/ibek/__main__.py b/src/ibek/__main__.py index 62bf56324..4ec8e46fb 100644 --- a/src/ibek/__main__.py +++ b/src/ibek/__main__.py @@ -1,14 +1,11 @@ import json from pathlib import Path -from typing import Any, List, Mapping, Optional +from typing import List, Optional -import jsonschema import typer -from apischema.json_schema import JsonSchemaVersion, deserialization_schema from ruamel.yaml import YAML -from ibek import __version__ - +from ._version import __version__ from .gen_scripts import create_boot_script, create_db_script, ioc_deserialize from .ioc import IOC, make_entity_classes from .support import Support @@ -17,10 +14,6 @@ yaml = YAML() -def make_schema(cls: type) -> Mapping[str, Any]: - return deserialization_schema(cls, version=JsonSchemaVersion.DRAFT_7) - - def version_callback(value: bool): if value: typer.echo(__version__) @@ -45,8 +38,7 @@ def ibek_schema( output: Path = typer.Argument(..., help="The filename to write the schema to") ): """Produce JSON global schema for all .ibek.support.yaml files""" - schema = json.dumps(make_schema(Support), indent=2) - output.write_text(schema) + output.write_text(Support.get_schema()) @cli.command() @@ -61,18 +53,20 @@ def ioc_schema( Create a json schema from a .ibek.support.yaml file """ - # first check the definition file with jsonschema since it has more - # legible error messages than apischema for definition in definitions: support_dict = YAML(typ="safe").load(definition) if not no_schema: - schema_support = make_schema(Support) - jsonschema.validate(support_dict, schema_support) + # Verify the schema of the support module definition file + Support.model_validate(support_dict) - support = Support.deserialize(support_dict) + # deserialize the support module definition file + support = Support(**support_dict) + # make Entity classes described in the support module definition file make_entity_classes(support) - schema = json.dumps(make_schema(IOC), indent=2) + # Save the schema for IOC - it will include all subclasses of Entity + # that were created in the global namespace by make_entity_classes + schema = json.dumps(IOC.model_json_schema(), indent=2) output.write_text(schema) diff --git a/src/ibek/globals.py b/src/ibek/globals.py index bb4b7e6cf..6a71c1514 100644 --- a/src/ibek/globals.py +++ b/src/ibek/globals.py @@ -1,9 +1,9 @@ """ -A few global defintions +A few global definitions """ from typing import TypeVar -from apischema import schema +from pydantic import BaseModel, ConfigDict, Field #: A generic Type for use in type hints T = TypeVar("T") @@ -11,4 +11,14 @@ def desc(description: str): """a description Annotation to add to our Entity derived Types""" - return schema(description=description) + return Field(description=description) + + +class BaseSettings(BaseModel): + """A Base class for setting Pydantic model configuration""" + + # Pydantic model configuration + model_config = ConfigDict( + # arbitrary_types_allowed=True, + extra="forbid", + ) diff --git a/src/ibek/support.py b/src/ibek/support.py index d8f4548bb..f84680bcb 100644 --- a/src/ibek/support.py +++ b/src/ibek/support.py @@ -1,19 +1,16 @@ """ The Support Class represents a deserialized .ibek.support.yaml file. -It contains a hierarchy of Entity dataclasses. """ from __future__ import annotations -from dataclasses import dataclass +import json from enum import Enum -from typing import Any, Dict, Mapping, Optional, Sequence, Type, Union +from typing import Any, Dict, Optional, Sequence, Union -from apischema import Undefined, UndefinedType, deserialize, deserializer, identity -from apischema.conversions import Conversion -from typing_extensions import Annotated as A +from pydantic import Field from typing_extensions import Literal -from .globals import T, desc +from .globals import BaseSettings class When(Enum): @@ -22,25 +19,17 @@ class When(Enum): last = "last" -@dataclass -class Arg: +class Arg(BaseSettings): """Base class for all Argument Types""" - name: A[str, desc("Name of the argument that the IOC instance should pass")] - description: A[str, desc("Description of what the argument will be used for")] type: str - default: Any - - # https://wyfo.github.io/apischema/latest/examples/subclass_union/ - def __init_subclass__(cls): - # Deserializers stack directly as a Union - deserializer(Conversion(identity, source=cls, target=Arg)) - - -Default = A[ - Union[Optional[T], UndefinedType], - desc("If given, and instance doesn't supply argument, what value should be used"), -] + name: str = Field( + description="Name of the argument that the IOC instance should pass" + ) + description: str = Field( + description="Description of what the argument will be used for" + ) + # __discriminator__ = "type" # FloatArg must be defined before StrArg, otherwise we get: @@ -52,96 +41,90 @@ def __init_subclass__(cls): # Arg. When StrArg is before FloatArg, apischema attempts to deserialize as a # string first. The coercion from str to number requires a trailing f if there # is a decimal. -@dataclass class FloatArg(Arg): """An argument with a float value""" type: Literal["float"] = "float" - default: Default[float] = Undefined + default: Optional[float] = None -@dataclass class StrArg(Arg): """An argument with a str value""" type: Literal["str"] = "str" - default: Default[str] = Undefined + default: Optional[str] = None -@dataclass class IntArg(Arg): """An argument with an int value""" type: Literal["int"] = "int" - default: Default[int] = Undefined + default: Optional[int] = None -@dataclass class BoolArg(Arg): """An argument with an bool value""" type: Literal["bool"] = "bool" - default: Default[bool] = Undefined + default: Optional[bool] = None -@dataclass class ObjectArg(Arg): """A reference to another entity defined in this IOC""" type: Literal["object"] = "object" - default: Default[str] = Undefined + default: Optional[str] = None -@dataclass class IdArg(Arg): """Explicit ID argument that an object can refer to""" type: Literal["id"] = "id" - default: Default[str] = Undefined + default: Optional[str] = None -@dataclass -class Database: +class Database(BaseSettings): """ A database file that should be loaded by the startup script and its args """ - file: A[str, desc("Filename of the database template in /db")] - args: A[ - Dict[str, Optional[str]], - desc( + file: str = Field( + description="Filename of the database template in /db" + ) + + args: Dict[str, Optional[str]] = Field( + description=( "Dictionary of args and values to pass through to database. " "A value of None is equivalent to ARG: '{{ ARG }}'" - ), - ] + ) + ) -@dataclass -class EnvironmentVariable: +class EnvironmentVariable(BaseSettings): """ An environment variable that should be set in the startup script """ - name: A[str, desc("Name of environment variable")] - value: A[str, desc("Value to set")] + name: str = Field(description="Name of environment variable") + value: str = Field(description="Value to set") -@dataclass -class Function: +class Function(BaseSettings): """ A script snippet that defines a function to call """ - name: A[str, desc("Name of the function to call")] - args: A[Dict[str, Any], desc("The arguments to pass to the function")] - header: A[str, desc("commands/comments to appear before the function")] = "" + name: str = Field(description="Name of the function to call") + args: Dict[str, Any] = Field(description="The arguments to pass to the function") + header: str = Field( + description="commands/comments to appear before the function", default="" + ) # TODO will be an enum - when: A[str, desc("one of first / every / last")] = "every" + when: When = Field(description="one of first / every / last", default="every") type: Literal["function"] = "function" -@dataclass -class Comment: +class Comment(BaseSettings): """ A script snippet that will have '# ' prepended to every line for insertion into the startup script @@ -149,29 +132,31 @@ class Comment: type: Literal["comment"] = "comment" # TODO will be an enum - when: A[str, desc("One of first / every / last")] = "every" - value: A[str, desc("A comment to add into the startup script")] = "" + when: When = Field(description="One of first / every / last", default="every") + value: str = Field( + description="A comment to add into the startup script", default="" + ) -@dataclass -class Text: +class Text(BaseSettings): """ A script snippet to insert into the startup script """ type: Literal["text"] = "text" # TODO will be an enum - when: A[str, desc("One of first / every / last")] = "every" - value: A[str, desc("raw text to add to the startup script")] = "" + when: str = Field(description="One of first / every / last", default="every") + value: str = Field(description="raw text to add to the startup script", default="") -@dataclass -class Value: +class Value(BaseSettings): """A calculated string value for a definition""" - name: A[str, desc("Name of the value that the IOC instance will expose")] - description: A[str, desc("Description of what the value will be used for")] - value: A[str, desc("The contents of the value")] + name: str = Field(description="Name of the value that the IOC instance will expose") + description: str = Field( + description="Description of what the value will be used for" + ) + value: str = Field(description="The contents of the value") def __str__(self): return self.value @@ -180,45 +165,51 @@ def __str__(self): Script = Sequence[Union[Function, Comment, Text]] -@dataclass -class Definition: +class Definition(BaseSettings): """ A single definition of a class of Entity that an IOC instance may instantiate """ - name: A[str, desc("Publish Definition as type . for IOC instances")] - description: A[str, desc("Describes the purpose of the definition")] - args: A[Sequence[Arg], desc("The arguments IOC instance should supply")] = () - values: A[Sequence[Value], desc("The values IOC instance should supply")] = () - databases: A[Sequence[Database], desc("Databases to instantiate")] = () - pre_init: A[ - Script, - desc("Startup script snippets to add before iocInit()"), - ] = () - post_init: A[ - Script, - desc("Startup script snippets to add post iocInit(), such as dbpf"), - ] = () - env_vars: A[ - Sequence[EnvironmentVariable], - desc("Environment variables to set in the boot script"), - ] = () - - -@dataclass -class Support: + name: str = Field( + description="Publish Definition as type . for IOC instances" + ) + description: str = Field( + description="A description of the Support module defined here" + ) + # declare Arg as Union of its subclasses for Pydantic to be able to deserialize + args: Sequence[Union[tuple(Arg.__subclasses__())]] = Field( # type: ignore + description="The arguments IOC instance should supply", default=() + ) + values: Sequence[Value] = Field( + description="The values IOC instance should supply", default=() + ) + databases: Sequence[Database] = Field( + description="Databases to instantiate", default=() + ) + pre_init: Script = Field( + description="Startup script snippets to add before iocInit()", default=() + ) + post_init: Script = Field( + description="Startup script snippets to add post iocInit(), such as dbpf", + default=(), + ) + env_vars: Sequence[EnvironmentVariable] = Field( + description="Environment variables to set in the boot script", default=() + ) + + +class Support(BaseSettings): """ Lists the definitions for a support module, this defines what Entities it supports Provides the deserialize entry point. """ - module: A[str, desc("Support module name, normally the repo name")] - defs: A[ - Sequence[Definition], - desc("The definitions an IOC can create using this module"), - ] + module: str = Field(description="Support module name, normally the repo name") + defs: Sequence[Definition] = Field( + description="The definitions an IOC can create using this module" + ) @classmethod - def deserialize(cls: Type[T], d: Mapping[str, Any]) -> T: - return deserialize(cls, d) + def get_schema(cls): + return json.dumps(cls.model_json_schema(), indent=2) diff --git a/tests/samples/schemas/ibek.defs.schema.json b/tests/samples/schemas/ibek.defs.schema.json index 5d46653bc..7a682fc51 100644 --- a/tests/samples/schemas/ibek.defs.schema.json +++ b/tests/samples/schemas/ibek.defs.schema.json @@ -1,419 +1,562 @@ { - "type": "object", - "properties": { - "module": { - "type": "string", - "description": "Support module name, normally the repo name" + "$defs": { + "BoolArg": { + "additionalProperties": false, + "description": "An argument with an bool value", + "properties": { + "type": { + "const": "bool", + "default": "bool", + "title": "Type" + }, + "name": { + "description": "Name of the argument that the IOC instance should pass", + "title": "Name", + "type": "string" + }, + "description": { + "description": "Description of what the argument will be used for", + "title": "Description", + "type": "string" + }, + "default": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Default" + } + }, + "required": [ + "name", + "description" + ], + "title": "BoolArg", + "type": "object" }, - "defs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Publish Definition as type . for IOC instances" + "Comment": { + "additionalProperties": false, + "description": "\n A script snippet that will have '# ' prepended to every line\n for insertion into the startup script\n ", + "properties": { + "type": { + "const": "comment", + "default": "comment", + "title": "Type" + }, + "when": { + "allOf": [ + { + "$ref": "#/$defs/When" + } + ], + "default": "every", + "description": "One of first / every / last" + }, + "value": { + "default": "", + "description": "A comment to add into the startup script", + "title": "Value", + "type": "string" + } + }, + "title": "Comment", + "type": "object" + }, + "Database": { + "additionalProperties": false, + "description": "\n A database file that should be loaded by the startup script and its args\n ", + "properties": { + "file": { + "description": "Filename of the database template in /db", + "title": "File", + "type": "string" + }, + "args": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, - "description": { - "type": "string", - "description": "Describes the purpose of the definition" + "description": "Dictionary of args and values to pass through to database. A value of None is equivalent to ARG: '{{ ARG }}'", + "title": "Args", + "type": "object" + } + }, + "required": [ + "file", + "args" + ], + "title": "Database", + "type": "object" + }, + "Definition": { + "additionalProperties": false, + "description": "\n A single definition of a class of Entity that an IOC instance may instantiate\n ", + "properties": { + "name": { + "description": "Publish Definition as type . for IOC instances", + "title": "Name", + "type": "string" + }, + "description": { + "description": "A description of the Support module defined here", + "title": "Description", + "type": "string" + }, + "args": { + "default": [], + "description": "The arguments IOC instance should supply", + "items": { + "anyOf": [ + { + "$ref": "#/$defs/FloatArg" + }, + { + "$ref": "#/$defs/StrArg" + }, + { + "$ref": "#/$defs/IntArg" + }, + { + "$ref": "#/$defs/BoolArg" + }, + { + "$ref": "#/$defs/ObjectArg" + }, + { + "$ref": "#/$defs/IdArg" + } + ] }, - "args": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of the argument that the IOC instance should pass" - }, - "description": { - "type": "string", - "description": "Description of what the argument will be used for" - }, - "type": { - "type": "string", - "const": "float", - "default": "float" - }, - "default": { - "type": [ - "number", - "null" - ], - "description": "If given, and instance doesn't supply argument, what value should be used" - } - }, - "required": [ - "name", - "description" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of the argument that the IOC instance should pass" - }, - "description": { - "type": "string", - "description": "Description of what the argument will be used for" - }, - "type": { - "type": "string", - "const": "str", - "default": "str" - }, - "default": { - "type": [ - "string", - "null" - ], - "description": "If given, and instance doesn't supply argument, what value should be used" - } - }, - "required": [ - "name", - "description" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of the argument that the IOC instance should pass" - }, - "description": { - "type": "string", - "description": "Description of what the argument will be used for" - }, - "type": { - "type": "string", - "const": "int", - "default": "int" - }, - "default": { - "type": [ - "integer", - "null" - ], - "description": "If given, and instance doesn't supply argument, what value should be used" - } - }, - "required": [ - "name", - "description" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of the argument that the IOC instance should pass" - }, - "description": { - "type": "string", - "description": "Description of what the argument will be used for" - }, - "type": { - "type": "string", - "const": "bool", - "default": "bool" - }, - "default": { - "type": [ - "boolean", - "null" - ], - "description": "If given, and instance doesn't supply argument, what value should be used" - } - }, - "required": [ - "name", - "description" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of the argument that the IOC instance should pass" - }, - "description": { - "type": "string", - "description": "Description of what the argument will be used for" - }, - "type": { - "type": "string", - "const": "object", - "default": "object" - }, - "default": { - "type": [ - "string", - "null" - ], - "description": "If given, and instance doesn't supply argument, what value should be used" - } - }, - "required": [ - "name", - "description" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of the argument that the IOC instance should pass" - }, - "description": { - "type": "string", - "description": "Description of what the argument will be used for" - }, - "type": { - "type": "string", - "const": "id", - "default": "id" - }, - "default": { - "type": [ - "string", - "null" - ], - "description": "If given, and instance doesn't supply argument, what value should be used" - } - }, - "required": [ - "name", - "description" - ], - "additionalProperties": false - } - ] - }, - "description": "The arguments IOC instance should supply", - "default": [] + "title": "Args", + "type": "array" + }, + "values": { + "default": [], + "description": "The values IOC instance should supply", + "items": { + "$ref": "#/$defs/Value" }, - "values": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of the value that the IOC instance will expose" - }, - "description": { - "type": "string", - "description": "Description of what the value will be used for" - }, - "value": { - "type": "string", - "description": "The contents of the value" - } - }, - "required": [ - "name", - "description", - "value" - ], - "additionalProperties": false - }, - "description": "The values IOC instance should supply", - "default": [] + "title": "Values", + "type": "array" + }, + "databases": { + "default": [], + "description": "Databases to instantiate", + "items": { + "$ref": "#/$defs/Database" }, - "databases": { - "type": "array", - "items": { - "type": "object", - "properties": { - "file": { - "type": "string", - "description": "Filename of the database template in /db" - }, - "args": { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "null" - ] - }, - "description": "Dictionary of args and values to pass through to database. A value of None is equivalent to ARG: '{{ ARG }}'" - } + "title": "Databases", + "type": "array" + }, + "pre_init": { + "default": [], + "description": "Startup script snippets to add before iocInit()", + "items": { + "anyOf": [ + { + "$ref": "#/$defs/Function" }, - "required": [ - "file", - "args" - ], - "additionalProperties": false - }, - "description": "Databases to instantiate", - "default": [] + { + "$ref": "#/$defs/Comment" + }, + { + "$ref": "#/$defs/Text" + } + ] }, - "pre_init": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/Function" - }, - { - "$ref": "#/definitions/Comment" - }, - { - "$ref": "#/definitions/Text" - } - ] - }, - "description": "Startup script snippets to add before iocInit()", - "default": [] + "title": "Pre Init", + "type": "array" + }, + "post_init": { + "default": [], + "description": "Startup script snippets to add post iocInit(), such as dbpf", + "items": { + "anyOf": [ + { + "$ref": "#/$defs/Function" + }, + { + "$ref": "#/$defs/Comment" + }, + { + "$ref": "#/$defs/Text" + } + ] }, - "post_init": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/Function" - }, - { - "$ref": "#/definitions/Comment" - }, - { - "$ref": "#/definitions/Text" - } - ] - }, - "description": "Startup script snippets to add post iocInit(), such as dbpf", - "default": [] + "title": "Post Init", + "type": "array" + }, + "env_vars": { + "default": [], + "description": "Environment variables to set in the boot script", + "items": { + "$ref": "#/$defs/EnvironmentVariable" }, - "env_vars": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name of environment variable" - }, - "value": { - "type": "string", - "description": "Value to set" - } - }, - "required": [ - "name", - "value" - ], - "additionalProperties": false + "title": "Env Vars", + "type": "array" + } + }, + "required": [ + "name", + "description" + ], + "title": "Definition", + "type": "object" + }, + "EnvironmentVariable": { + "additionalProperties": false, + "description": "\n An environment variable that should be set in the startup script\n ", + "properties": { + "name": { + "description": "Name of environment variable", + "title": "Name", + "type": "string" + }, + "value": { + "description": "Value to set", + "title": "Value", + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "title": "EnvironmentVariable", + "type": "object" + }, + "FloatArg": { + "additionalProperties": false, + "description": "An argument with a float value", + "properties": { + "type": { + "const": "float", + "default": "float", + "title": "Type" + }, + "name": { + "description": "Name of the argument that the IOC instance should pass", + "title": "Name", + "type": "string" + }, + "description": { + "description": "Description of what the argument will be used for", + "title": "Description", + "type": "string" + }, + "default": { + "anyOf": [ + { + "type": "number" }, - "description": "Environment variables to set in the boot script", - "default": [] - } - }, - "required": [ - "name", - "description" - ], - "additionalProperties": false + { + "type": "null" + } + ], + "default": null, + "title": "Default" + } }, - "description": "The definitions an IOC can create using this module" - } - }, - "required": [ - "module", - "defs" - ], - "additionalProperties": false, - "definitions": { + "required": [ + "name", + "description" + ], + "title": "FloatArg", + "type": "object" + }, "Function": { - "type": "object", + "additionalProperties": false, + "description": "\n A script snippet that defines a function to call\n ", "properties": { "name": { - "type": "string", - "description": "Name of the function to call" + "description": "Name of the function to call", + "title": "Name", + "type": "string" }, "args": { - "type": "object", - "description": "The arguments to pass to the function" + "description": "The arguments to pass to the function", + "title": "Args", + "type": "object" }, "header": { - "type": "string", + "default": "", "description": "commands/comments to appear before the function", - "default": "" + "title": "Header", + "type": "string" }, "when": { - "type": "string", - "description": "one of first / every / last", - "default": "every" + "allOf": [ + { + "$ref": "#/$defs/When" + } + ], + "default": "every", + "description": "one of first / every / last" }, "type": { - "type": "string", "const": "function", - "default": "function" + "default": "function", + "title": "Type" } }, "required": [ "name", "args" ], - "additionalProperties": false + "title": "Function", + "type": "object" }, - "Comment": { - "type": "object", + "IdArg": { + "additionalProperties": false, + "description": "Explicit ID argument that an object can refer to", "properties": { "type": { - "type": "string", - "const": "comment", - "default": "comment" + "const": "id", + "default": "id", + "title": "Type" }, - "when": { - "type": "string", - "description": "One of first / every / last", - "default": "every" + "name": { + "description": "Name of the argument that the IOC instance should pass", + "title": "Name", + "type": "string" }, - "value": { - "type": "string", - "description": "A comment to add into the startup script", - "default": "" + "description": { + "description": "Description of what the argument will be used for", + "title": "Description", + "type": "string" + }, + "default": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Default" + } + }, + "required": [ + "name", + "description" + ], + "title": "IdArg", + "type": "object" + }, + "IntArg": { + "additionalProperties": false, + "description": "An argument with an int value", + "properties": { + "type": { + "const": "int", + "default": "int", + "title": "Type" + }, + "name": { + "description": "Name of the argument that the IOC instance should pass", + "title": "Name", + "type": "string" + }, + "description": { + "description": "Description of what the argument will be used for", + "title": "Description", + "type": "string" + }, + "default": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Default" } }, - "additionalProperties": false + "required": [ + "name", + "description" + ], + "title": "IntArg", + "type": "object" + }, + "ObjectArg": { + "additionalProperties": false, + "description": "A reference to another entity defined in this IOC", + "properties": { + "type": { + "const": "object", + "default": "object", + "title": "Type" + }, + "name": { + "description": "Name of the argument that the IOC instance should pass", + "title": "Name", + "type": "string" + }, + "description": { + "description": "Description of what the argument will be used for", + "title": "Description", + "type": "string" + }, + "default": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Default" + } + }, + "required": [ + "name", + "description" + ], + "title": "ObjectArg", + "type": "object" + }, + "StrArg": { + "additionalProperties": false, + "description": "An argument with a str value", + "properties": { + "type": { + "const": "str", + "default": "str", + "title": "Type" + }, + "name": { + "description": "Name of the argument that the IOC instance should pass", + "title": "Name", + "type": "string" + }, + "description": { + "description": "Description of what the argument will be used for", + "title": "Description", + "type": "string" + }, + "default": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Default" + } + }, + "required": [ + "name", + "description" + ], + "title": "StrArg", + "type": "object" }, "Text": { - "type": "object", + "additionalProperties": false, + "description": "\n A script snippet to insert into the startup script\n ", "properties": { "type": { - "type": "string", "const": "text", - "default": "text" + "default": "text", + "title": "Type" }, "when": { - "type": "string", + "default": "every", "description": "One of first / every / last", - "default": "every" + "title": "When", + "type": "string" }, "value": { - "type": "string", + "default": "", "description": "raw text to add to the startup script", - "default": "" + "title": "Value", + "type": "string" } }, - "additionalProperties": false + "title": "Text", + "type": "object" + }, + "Value": { + "additionalProperties": false, + "description": "A calculated string value for a definition", + "properties": { + "name": { + "description": "Name of the value that the IOC instance will expose", + "title": "Name", + "type": "string" + }, + "description": { + "description": "Description of what the value will be used for", + "title": "Description", + "type": "string" + }, + "value": { + "description": "The contents of the value", + "title": "Value", + "type": "string" + } + }, + "required": [ + "name", + "description", + "value" + ], + "title": "Value", + "type": "object" + }, + "When": { + "enum": [ + "first", + "every", + "last" + ], + "title": "When", + "type": "string" } }, - "$schema": "http://json-schema.org/draft-07/schema#" + "additionalProperties": false, + "description": "\n Lists the definitions for a support module, this defines what Entities it supports\n\n Provides the deserialize entry point.\n ", + "properties": { + "module": { + "description": "Support module name, normally the repo name", + "title": "Module", + "type": "string" + }, + "defs": { + "description": "The definitions an IOC can create using this module", + "items": { + "$ref": "#/$defs/Definition" + }, + "title": "Defs", + "type": "array" + } + }, + "required": [ + "module", + "defs" + ], + "title": "Support", + "type": "object" } \ No newline at end of file