Zelda Wiki

OoT Navi.png

Hey! Listen!

This wiki contains spoilers! Read at your own risk!

READ MORE

Zelda Wiki
Advertisement
Zelda Wiki
10,256
pages

A schema is a structure for documenting and validating Lua data. Without schemas, it can be difficult for others to know what input a module expects, given Lua's dynamic type system. This is especially true when modules have configuration data or table arguments.

A similar but distinct solution exists for documenting and validating template input.

This module is heavily inspired by JSON Schema. As such, Understanding JSON Schema is a useful resource for understanding how this module works.

Usage

Schemas integrate with Module:Documentation for documenting function parameters, like so:

Module:ModuleName Module:ModuleName/Documentation
p.Schemas = {
  fooFunction = {
    param1 = { <Schema> },
    param2 = { <Schema> },
  },
  barFunction = {
    param1 = { <Schema> },
    param2 = { <Schema> },
  },
  <...>
}

p.Documentation = {
  fooFunction = {
    params = {"param1", "param2"}
    <...>
  }, 
  barFunction = {
    params = {"param1", "param2"}
    <...>
  },
  <...>
}
{{#invoke:Documentation|Module}}

Schemas can also be made for Module Data like so:

Module:ModuleName Module:ModuleName/Data/Documentation
p.Schemas = {
  Data = { <Schema> }
  <...>
}
{{#invoke:Documentation|Module}}
{{#invoke:Schema|Validate}}

The first invocation generates schema documentation for Data. The second validates the data against the Data schema. Any validation errors that occur will be shown as warnings in the edit preview. Data pages that fail validation are placed in Category:Modules with invalid data.

[Schema]
[definitions]
Schema fragments for referencing.
Primitive SchemaArray SchemaRecord SchemaMap SchemaoneOfallOfReference
[_id]
An ID to use for referencing.
[required]
If true, the value cannot be nil.
[deprecated]
If true, validation fails when this value is present. A deprecation warning is logged.
[desc]
Description of the schema, for documentation.
type
"string", "number", "boolean", or "any"
[enum]
An array of values that are considered acceptable, plus an optional reference key.
[reference]
A link to a page that lists the accepted values.
[_id]
An ID to use for referencing.
[required]
If true, the value cannot be nil.
[deprecated]
If true, validation fails when this value is present. A deprecation warning is logged.
[desc]
Description of the schema, for documentation.
type
The string "array".
items
A schema that all items in the array must adhere to.
[_id]
An ID to use for referencing.
[required]
If true, the value cannot be nil.
[deprecated]
If true, validation fails when this value is present. A deprecation warning is logged.
[desc]
Description of the schema, for documentation.
type
The string "record".
properties
An array of schemas for each record entry, plus an additional field name for the name of the record entry.
name
The key for the record entry.
[_id]
An ID to use for referencing.
[required]
If true, the value cannot be nil.
[deprecated]
If true, validation fails when this value is present. A deprecation warning is logged.
[desc]
Description of the schema, for documentation.
type
The string "map".
keys
The schema for the keys of the map.
values
The schema for the values of the map.
[_id]
An ID to use for referencing.
[required]
If true, the value cannot be nil.
[deprecated]
If true, validation fails when this value is present. A deprecation warning is logged.
[desc]
Description of the schema, for documentation.
oneOf
A table of subschemas. The data must be valid against exactly one of them.
[_id]
An ID to use for referencing.
[required]
If true, the value cannot be nil.
[deprecated]
If true, validation fails when this value is present. A deprecation warning is logged.
[desc]
Description of the schema, for documentation.
allOf
An array of subschemas. The data must be valid against all of them.
[_id]
An ID to use for referencing.
[required]
If true, the value cannot be nil.
[deprecated]
If true, validation fails when this value is present. A deprecation warning is logged.
[desc]
Description of the schema, for documentation.
_ref
A reference to another part of the schema.
[_hideSubkeys]
Ignore reference when generating documentation. Use sparingly as there is already a mechanism for determining whether to show referenced schema fragments.

Examples

Altogether the following modules use every available schema feature:

Module:UtilsSchema has test cases that show how the validation works.

Concepts

Types

The types defined in schemas generally correspond to the Lua types, with an additional any type. The table type, however, does not exist as a concept in schemas. Instead, there are more specific types which indicate the kind of table in question:

  • array — A table with consecutive integer keys starting from 1.
  • record — A table with fixed set of string keys.
  • map — A table with any amount of keys, all of the same type. All values are of the same type, but possibly a different type from the keys.
Type Examples
Type Example
string
"Kooloo Limpah"
number
0
boolean
true
table schema types
array
{"Kooloo", "Limpah"}
record
{
  magicWords = {"Kooloo", "Limpah"},
  owner = "Tingle",
  canSteal = false,
}
map
{
  height = "50px",
  width = "auto",
  ["text-align"] = center,
}

Combining Schemas

It is possible to combine schemas using oneOf and allOf.

Combination Examples
Keyword Schema Example Data
oneOf
{
  type = "array",
  items = {
    oneOf = {
      { type = "string" },
      { type = "number" },
    },
  }
}
{ 1, 2, "Fooloo Limpah", 3, 4}
allOf
{
  allOf = {
    { 
      type = "record",
      properties = {
        {
          name = "foo",
          type = "string",
        },
      },
    },
    { 
      type = "array",
      items = { type = "number" },
    }
  },
}
{1, 2, 3, foo = "bar"}

The combination keywords are often used along with references to maximize reusability.

References

References allow you to reuse parts of the schema in multiple places. There are two ways of referencing schema fragments: using definitions and using the _id property.

Referencing Examples
Reference Type Schema Example Data
definitions
{
  type = "array",
  items = {
    oneOf = {
      _ref = "#/definitions/foo",
      _ref = "#/definitions/bar",
    },
  }
  definitions = {
    foo = {
      type = "string",
    },
    bar = {
      type = "number",
    },
  }
}
{ 1, 2, "Fooloo Limpah", 3, 4}
_id
{
  type = "array",
  items = {
    oneOf = {
      { 
        _id = "#foo", 
        type = "string" 
      },
      { 
        type = "array",
        items = { _ref = "#foo" }
      } 
    },
  }
}
{ "foo", "bar", { "baz", "quux" } }

local p = {}

local utilsSchema = require("Module:UtilsSchema")

function p.Validate(frame)
	return p.validate(frame:getParent():getTitle(), frame.args[1])
end

function p.validate(docPageName, schemaName)
	local docPage = mw.title.new(docPageName)
	local dataPage = docPage.basePageTitle
	if mw.title.getCurrentTitle().text ~= dataPage.text then
		return ""
	end
	local modulePage = dataPage.basePageTitle
	
	local module = require(modulePage.fullText)
	if not module.Schemas then
		error(string.format("Module '%s' does not export any schemas.", modulePage.text))
	end
	
	schemaName = schemaName or dataPage.subpageText
	if not module.Schemas[schemaName] then
		error(string.format("Module '%s' has no such schema '%s'.", modulePage.text, schemaName))
	end
	
	local data = mw.loadData(dataPage.fullText)
	local err = utilsSchema.validate(module.Schemas[schemaName], schemaName, data, "data")
	if err then
		return "[[Category:Modules with invalid data]]"
	end
end

return p
Advertisement