From d5b67b0a9d9c21e72dacafd7c64dae849a128cc6 Mon Sep 17 00:00:00 2001 From: Nokome Bentley Date: Mon, 12 Aug 2019 17:44:05 +1200 Subject: [PATCH] feat(Parameter): Add schema schemas This adds schemas for user defined data validation schemas to be used on `Parameter.schema` and `DatatableColumn.schema`. --- schema/ArraySchema.schema.yaml | 32 +++++++++ schema/BooleanSchema.schema.yaml | 11 ++++ schema/ConstantSchema.schema.yaml | 16 +++++ schema/DatatableColumn.schema.yaml | 2 +- schema/DatatableColumnSchema.schema.yaml | 19 ------ schema/EnumSchema.schema.yaml | 15 +++++ schema/IntegerSchema.schema.yaml | 13 ++++ schema/NumberSchema.schema.yaml | 50 ++++++++++++++ schema/Parameter.md | 83 ++++++++++++++++++++++++ schema/Parameter.schema.yaml | 30 +++++---- schema/Schema.schema.yaml | 12 ++++ schema/StringSchema.schema.yaml | 34 ++++++++++ schema/TupleSchema.schema.yaml | 14 ++++ 13 files changed, 297 insertions(+), 34 deletions(-) create mode 100644 schema/ArraySchema.schema.yaml create mode 100644 schema/BooleanSchema.schema.yaml create mode 100644 schema/ConstantSchema.schema.yaml delete mode 100644 schema/DatatableColumnSchema.schema.yaml create mode 100644 schema/EnumSchema.schema.yaml create mode 100644 schema/IntegerSchema.schema.yaml create mode 100644 schema/NumberSchema.schema.yaml create mode 100644 schema/Parameter.md create mode 100644 schema/Schema.schema.yaml create mode 100644 schema/StringSchema.schema.yaml create mode 100644 schema/TupleSchema.schema.yaml diff --git a/schema/ArraySchema.schema.yaml b/schema/ArraySchema.schema.yaml new file mode 100644 index 00000000..6338c16b --- /dev/null +++ b/schema/ArraySchema.schema.yaml @@ -0,0 +1,32 @@ +title: ArraySchema +'@id': stencila:ArraySchema +extends: Entity +role: validation +status: unstable +category: data +description: A schema specifying constraints on an array node. +properties: + items: + '@id': stencila:items + description: Another data schema node specifying the constraints on all items in the array. + allOf: + - $ref: Schema + contains: + '@id': stencila:contains + description: An array node is valid if at least one of its items is valid against the `contains` schema. + allOf: + - $ref: Schema + minItems: + '@id': stencila:minItems + description: An array node is valid if its size is greater than, or equal to, this value. + type: number + minimum: 0 + maxItems: + '@id': stencila:maxItems + description: An array node is valid if its size is less than, or equal to, this value. + type: number + minimum: 0 + uniqueItems: + '@id': stencila:uniqueItems + description: A flag to indicate that each value in the array should be unique. + type: boolean diff --git a/schema/BooleanSchema.schema.yaml b/schema/BooleanSchema.schema.yaml new file mode 100644 index 00000000..b2541d97 --- /dev/null +++ b/schema/BooleanSchema.schema.yaml @@ -0,0 +1,11 @@ +title: BooleanSchema +'@id': stencila:BooleanSchema +extends: Entity +role: validation +status: unstable +category: data +description: A schema specifying that a node must be a boolean value. +$comment: | + A node will be valid against this schema if it is either `true` or `false. + Analagous to the JSON Schema `boolean` type. +properties: {} diff --git a/schema/ConstantSchema.schema.yaml b/schema/ConstantSchema.schema.yaml new file mode 100644 index 00000000..75642401 --- /dev/null +++ b/schema/ConstantSchema.schema.yaml @@ -0,0 +1,16 @@ +title: ConstantSchema +'@id': stencila:ConstantSchema +extends: Entity +role: validation +status: unstable +category: data +description: A schema specifying a constant value that a node must have. +$comment: | + A node will be valid against this schema if it is equal to this + schema's `value` property. Analagous to the JSON Schema `const` keyword. +properties: + value: + '@id': schema:value + description: The value that the node must have. + allOf: + - $ref: Node diff --git a/schema/DatatableColumn.schema.yaml b/schema/DatatableColumn.schema.yaml index e0dabef4..08d2dca5 100644 --- a/schema/DatatableColumn.schema.yaml +++ b/schema/DatatableColumn.schema.yaml @@ -10,7 +10,7 @@ properties: '@id': stencila:schema description: The schema to use to validate data in the column. allOf: - - $ref: DatatableColumnSchema + - $ref: ArraySchema values: '@id': stencila:values description: The data values of the column. diff --git a/schema/DatatableColumnSchema.schema.yaml b/schema/DatatableColumnSchema.schema.yaml deleted file mode 100644 index b544e5d2..00000000 --- a/schema/DatatableColumnSchema.schema.yaml +++ /dev/null @@ -1,19 +0,0 @@ -title: DatatableColumnSchema -'@id': stencila:DatatableColumnSchema -extends: Entity -role: tertiary -status: unstable -category: data -description: | - A schema specifying the data values that are valid within a Datatable column. -properties: - items: - '@id': schema:itemListElement - description: An object representing the JSON Schema `items` keyword. - type: object - uniqueItems: - '@id': stencila:uniqueItems - description: A flag to indicate that each value in the column should be unique. - type: boolean -required: - - items diff --git a/schema/EnumSchema.schema.yaml b/schema/EnumSchema.schema.yaml new file mode 100644 index 00000000..44f1fba7 --- /dev/null +++ b/schema/EnumSchema.schema.yaml @@ -0,0 +1,15 @@ +title: EnumSchema +'@id': stencila:EnumSchema +extends: Entity +role: validation +status: unstable +category: data +description: A schema specifying that a node must be one of several values. +$comment: Analogous to the JSON Schema `enum` keyword. +properties: + values: + '@id': stencila:values + description: A node is valid if it is equal to any of these values. + type: array + items: + $ref: Node diff --git a/schema/IntegerSchema.schema.yaml b/schema/IntegerSchema.schema.yaml new file mode 100644 index 00000000..80fb6a7c --- /dev/null +++ b/schema/IntegerSchema.schema.yaml @@ -0,0 +1,13 @@ +title: IntegerSchema +'@id': stencila:IntegerSchema +extends: NumberSchema +role: validation +status: unstable +category: data +description: A schema specifying the constraints on an integer node. +$comment: | + A node will be valid against the schema if it is a number with no + fractional part and meets any additional constraints, such as `multipleOf`, + specified in the schema. + Analogous to the JSON Schema `integer` type. +properties: {} diff --git a/schema/NumberSchema.schema.yaml b/schema/NumberSchema.schema.yaml new file mode 100644 index 00000000..35b37492 --- /dev/null +++ b/schema/NumberSchema.schema.yaml @@ -0,0 +1,50 @@ +title: NumberSchema +'@id': stencila:NumberSchema +extends: Entity +role: validation +status: unstable +category: data +description: A schema specifying the constraints on a numeric node. +$comment: | + A node will be valid against the schema if it is a number that + meets the schemas `maximum`, `multipleOf` etc properties. + Analagous to the JSON Schema `number` type. + Note that the `IntegerSchema` extends this schema with the additional + constraint that the number have no fractional part. +properties: + minimum: + '@id': stencila:minimum + type: number + description: The inclusive lower limit for a numeric node. + $comment: | + A number is valid against the schema if it is greater than, + or exactly equal to, `minimum`. + exclusiveMinimum: + '@id': stencila:exclusiveMinimum + type: number + description: The exclusive lower limit for a numeric node. + $comment: | + A number is valid against the schema only if it has a value greater + than (not equal to) `exclusiveMinimum`. + maximum: + '@id': stencila:exclusiveMaximum + type: number + description: The inclusive upper limit for a numeric node. + $comment: | + A number is valid against the schema if it is less than, + or exactly equal to, `maximum`. + exclusiveMaximum: + '@id': stencila:exclusiveMaximum + type: number + description: The exclusive upper limit for a numeric node. + $comment: | + A number is valid against the schema only if it has a value less + than (not equal to) `exclusiveMaximum`. + multipleOf: + '@id': stencila:multipleOf + type: number + exclusiveMinimum: 0 + description: A number that a numeric node must be a multiple of. + $comment: | + A number is valid against the schema only if division by this value + results in an integer. diff --git a/schema/Parameter.md b/schema/Parameter.md new file mode 100644 index 00000000..7a12542e --- /dev/null +++ b/schema/Parameter.md @@ -0,0 +1,83 @@ +--- +title: Parameter +--- + +## Structure + +### Name + +Parameters must have a `name`. This allows them to be referred to by other executable nodes in a document and for callers to specify which parameter of a document or function that they are referring to. So, the simplest parameter would look like this: + +```json +{ + "type": "Parameter", + "name": "weight" +} +``` + +### Schema + +You can also specify a `schema` for a parameter which specifies constraints on the values bound to the parameter. + +For example, + +```json +{ + "type": "Parameter", + "name": "weight", + "schema": { + "type": "ArraySchema", + "items": { + "type": "NumberSchema", + "exclusiveMinimum": 0 + } + } +} +``` + + +### Default + +A parameter can have a default value. Of course if you have specified a `schema` for the parameter, then the... + + +## Usage + +Parameters can be used in two places: + +- as an item in the `parameters` property of a `CreativeWork` such as an `Article` or `Function` + +- as a node within the `content` tree of a `CreativeWork` such as an `Article` + +### Within `parameters` + +Put a parameter in the `parameters` property when you want it to be invisible to the end user of the document. These parameters will not be modifiable by the reader but authors will be able to bind to them when calling a document e.g. + +```json +{ + "type": "Call", + "target": "./my-figure.md", + "arguments": { + ... + } +} + +``` + + + +### Within `content` + +When a parameter is placed in the content of the document it becomes readable, and modifiable by the end user. This allows them to alter the parameter to see how it's value affects other content nodes in the document (e.g. a calculated value, a table, or a plot). + +When defining a parameter within the content of a document it is strongly recommended to specify its `schema`. This provides the user interfaces that are custom to the type of data specified by the schema (e.g. a number keyboard for a parameter with `schema` of type `NumberSchema`). + +## Encodings + +### HTML + +> Discuss how different schema types are encoded as different HTML [`` types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types) + +```html + +``` diff --git a/schema/Parameter.schema.yaml b/schema/Parameter.schema.yaml index 9522d0e9..fd8c399c 100644 --- a/schema/Parameter.schema.yaml +++ b/schema/Parameter.schema.yaml @@ -7,20 +7,22 @@ category: code description: A parameter that can be set and used in evaluated code. properties: name: - '@id': stencila:name - description: The name the parameter is referred to in code. Should be in the format ([A-z_][A-z0-9_]+) + '@id': schema:name + description: The name the parameter is referred to in code. type: string - # todo: can we have `format: ` here? - dataType: - '@id': stencila:dataType - description: The type of data this parameter accepts. - type: string - enum: - - string - - int - - float - - boolean - - json + pattern: '[a-z_][A-z0-9_]*' + $comment: | + This regex allows for snake_case and camelCase names but excludes + PascalCase for parameter names. + schema: + '@id': stencila:schema + description: The schema that the value of the parameter will be validated against. + allOf: + - $ref: Schema + default: + '@id': stencila:value + description: The default value of the parameter. + allOf: + - $ref: Node required: - name - - dataType diff --git a/schema/Schema.schema.yaml b/schema/Schema.schema.yaml new file mode 100644 index 00000000..50deecec --- /dev/null +++ b/schema/Schema.schema.yaml @@ -0,0 +1,12 @@ +title: Schema +category: data +description: Union type for all data schemas. +anyOf: + - $ref: ConstantSchema + - $ref: EnumSchema + - $ref: BooleanSchema + - $ref: NumberSchema + - $ref: IntegerSchema + - $ref: StringSchema + - $ref: ArraySchema + - $ref: TupleSchema diff --git a/schema/StringSchema.schema.yaml b/schema/StringSchema.schema.yaml new file mode 100644 index 00000000..49de61ca --- /dev/null +++ b/schema/StringSchema.schema.yaml @@ -0,0 +1,34 @@ +title: StringSchema +'@id': stencila:StringSchema +extends: Entity +role: validation +status: unstable +category: data +description: A schema specifying constraints on a string node. +$comment: | + A node will be valid against the schema if it is a string that + meets the schemas `minLength`, `maxLength` and `pattern` properties. + Analogous to the JSON Schema `string` type. +properties: + minLength: + '@id': stencila:minLength + type: number + minimum: 0 + description: The minimum length for a string node. + $comment: | + A string is valid against the schema if its length is greater than, + or exactly equal to, `minLength`. + maxLength: + '@id': stencila:maxLength + type: number + minimum: 0 + description: The maximum length for a string node. + $comment: | + A string is valid against the schema if its length is less than, + or exactly equal to, `maxLength`. + pattern: + '@id': stencila:pattern + type: string + description: A regular expression that a string node must match. + $comment: | + A string is valid against the schema if it is matched by the regular expression. diff --git a/schema/TupleSchema.schema.yaml b/schema/TupleSchema.schema.yaml new file mode 100644 index 00000000..3a321a3b --- /dev/null +++ b/schema/TupleSchema.schema.yaml @@ -0,0 +1,14 @@ +title: TupleSchema +'@id': stencila:TupleSchema +extends: Entity +role: validation +status: unstable +category: data +description: A schema specifying constraints on an array of heterogeneous items. +properties: + items: + '@id': stencila:items + description: An array of schemas specifying the constraints on each successive item in the array. + type: array + items: + $ref: Schema