mirror of https://github.com/kdl-org/kdl.git
Merge b6d5eb2739 into b8570137b6
This commit is contained in:
commit
06dfc692fb
|
|
@ -1,17 +1,16 @@
|
|||
# KDL Schema Specification
|
||||
# KDL Schema Language Specification
|
||||
|
||||
The KDL Schema specification describes a schema language for use with KDL,
|
||||
written in KDL itself. A schema language allows users to describe and
|
||||
constrain the allowed semantics of a KDL document. This can be used for many
|
||||
purposes: documentation for users, automated verification, or even automated
|
||||
generation of bindings!
|
||||
The KDL Schema Language specification describes a schema language for use with
|
||||
KDL. A schema language allows users to describe and constrain the allowed
|
||||
semantics of a document. This can be used for many purposes: documentation for
|
||||
users, automated verification, or even automated generation of bindings!
|
||||
|
||||
This document describes KDL Schema version `1.0.0`. It was released on September 11, 2021.
|
||||
This document describes KDL Schema version `2.0.0`. It is unreleased.
|
||||
|
||||
## The Formal Schema
|
||||
|
||||
For the full KDL Schema schema itself, see
|
||||
[examples/kdl-schema.kdl](./examples/kdl-schema.kdl).
|
||||
For the full KDL Schema Language schema itself, see
|
||||
[schema/ksl-schema.kdl](./schema/ksl-schema.kdl).
|
||||
|
||||
## Definition
|
||||
|
||||
|
|
@ -39,6 +38,14 @@ None.
|
|||
* `tag-names` (optional): [Validations](#validation-nodes) to apply to the _names_ of tags of child nodes.
|
||||
* `other-tags-allowed` (optional): Whether to allow node tags other than the ones explicitly listed here. Defaults to `#false`.
|
||||
|
||||
#### Example
|
||||
|
||||
```kdl
|
||||
document {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### `info` node
|
||||
|
||||
The `info` node describes the schema itself.
|
||||
|
|
|
|||
|
|
@ -1,376 +0,0 @@
|
|||
document {
|
||||
info {
|
||||
title "KDL Schema" lang=en
|
||||
description "KDL Schema KDL schema in KDL" lang=en
|
||||
author "Kat Marchán" {
|
||||
link "https://github.com/zkat" rel=self
|
||||
}
|
||||
contributor "Lars Willighagen" {
|
||||
link "https://github.com/larsgw" rel=self
|
||||
}
|
||||
link "https://github.com/zkat/kdl" rel=documentation
|
||||
license "Creative Commons Attribution-ShareAlike 4.0 International License" spdx=CC-BY-SA-4.0 {
|
||||
link "https://creativecommons.org/licenses/by-sa/4.0/" lang=en
|
||||
}
|
||||
published "2021-08-31"
|
||||
modified "2021-09-01"
|
||||
}
|
||||
node document {
|
||||
min 1
|
||||
max 1
|
||||
children id=node-children {
|
||||
node node-names id=node-names-node description="Validations to apply specifically to arbitrary node names" {
|
||||
children ref=#"[id="validations"]"#
|
||||
}
|
||||
node other-nodes-allowed id=other-nodes-allowed-node description="Whether to allow child nodes other than the ones explicitly listed. Defaults to '#false'." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type boolean
|
||||
}
|
||||
}
|
||||
node tag-names description="Validations to apply specifically to arbitrary type tag names" {
|
||||
children ref=#"[id="validations"]"#
|
||||
}
|
||||
node other-tags-allowed description="Whether to allow child node tags other than the ones explicitly listed. Defaults to '#false'." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type boolean
|
||||
}
|
||||
}
|
||||
node info description="A child node that describes the schema itself." {
|
||||
children {
|
||||
node title description="The title of the schema or the format it describes" {
|
||||
value description="The title text" {
|
||||
type string
|
||||
min 1
|
||||
max 1
|
||||
}
|
||||
prop lang id=info-lang description="The language of the text" {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node description description="A description of the schema or the format it describes" {
|
||||
value description="The description text" {
|
||||
type string
|
||||
min 1
|
||||
max 1
|
||||
}
|
||||
prop ref=#"[id="info-lang"]"#
|
||||
}
|
||||
node author description="Author of the schema" {
|
||||
value id=info-person-name description="Person name" {
|
||||
type string
|
||||
min 1
|
||||
max 1
|
||||
}
|
||||
prop orcid id=info-orcid description="The ORCID of the person" {
|
||||
type string
|
||||
pattern #"\d{4}-\d{4}-\d{4}-\d{4}"#
|
||||
}
|
||||
children {
|
||||
node ref=#"[id="info-link"]"#
|
||||
}
|
||||
}
|
||||
node contributor description="Contributor to the schema" {
|
||||
value ref=#"[id="info-person-name"]"#
|
||||
prop ref=#"[id="info-orcid"]"#
|
||||
children {
|
||||
node ref=#"[id="info-link"]"#
|
||||
}
|
||||
}
|
||||
node link id=info-link description="Links to itself, and to sources describing it" {
|
||||
value description="A URL that the link points to" {
|
||||
type string
|
||||
format url irl
|
||||
min 1
|
||||
max 1
|
||||
}
|
||||
prop rel description="The relation between the current entity and the URL" {
|
||||
type string
|
||||
enum self documentation
|
||||
}
|
||||
prop ref=#"[id="info-lang"]"#
|
||||
}
|
||||
node license description="The license(s) that the schema is licensed under" {
|
||||
value description="Name of the used license" {
|
||||
type string
|
||||
min 1
|
||||
max 1
|
||||
}
|
||||
prop spdx description="An SPDX license identifier" {
|
||||
type string
|
||||
}
|
||||
children {
|
||||
node ref=#"[id="info-link"]"#
|
||||
}
|
||||
}
|
||||
node published description="When the schema was published" {
|
||||
value description="Publication date" {
|
||||
type string
|
||||
format date
|
||||
min 1
|
||||
max 1
|
||||
}
|
||||
prop time id=info-time description="A time to accompany the date" {
|
||||
type string
|
||||
format time
|
||||
}
|
||||
}
|
||||
node modified description="When the schema was last modified" {
|
||||
value description="Modification date" {
|
||||
type string
|
||||
format date
|
||||
min 1
|
||||
max 1
|
||||
}
|
||||
prop ref=#"[id="info-time"]"#
|
||||
}
|
||||
node version description="The version number of this version of the schema" {
|
||||
value description="Semver version number" {
|
||||
type string
|
||||
pattern #"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"#
|
||||
min 1
|
||||
max 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node tag id=tag-node description="A tag belonging to a child node of `document` or another node." {
|
||||
value description="The name of the tag. If a tag name is not supplied, the node rules apply to _all_ nodes belonging to the parent." {
|
||||
type string
|
||||
max 1
|
||||
}
|
||||
prop description description="A description of this node's purpose." {
|
||||
type string
|
||||
}
|
||||
prop id description="A globally-unique ID for this node." {
|
||||
type string
|
||||
}
|
||||
prop ref description="A globally unique reference to another node." {
|
||||
type string
|
||||
format kdl-query
|
||||
}
|
||||
children {
|
||||
node ref=#"[id="node-names-node"]"#
|
||||
node ref=#"[id="other-nodes-allowed-node"]"#
|
||||
node ref=#"[id="node-node"]"#
|
||||
}
|
||||
}
|
||||
node node id=node-node description="A child node belonging either to `document` or to another `node`. Nodes may be anonymous." {
|
||||
value description="The name of the node. If a node name is not supplied, the node rules apply to _all_ nodes belonging to the parent." {
|
||||
type string
|
||||
max 1
|
||||
}
|
||||
prop description description="A description of this node's purpose." {
|
||||
type string
|
||||
}
|
||||
prop id description="A globally-unique ID for this node." {
|
||||
type string
|
||||
}
|
||||
prop ref description="A globally unique reference to another node." {
|
||||
type string
|
||||
format kdl-query
|
||||
}
|
||||
children {
|
||||
node prop-names description="Validations to apply specifically to arbitrary property names" {
|
||||
children ref=#"[id="validations"]"#
|
||||
}
|
||||
node other-props-allowed description="Whether to allow properties other than the ones explicitly listed. Defaults to '#false'." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type boolean
|
||||
}
|
||||
}
|
||||
node min description="minimum number of instances of this node in its parent's children." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node max description="maximum number of instances of this node in its parent's children." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node ref=#"[id="value-tag-node"]"#
|
||||
node prop id="prop-node" description="A node property key/value pair." {
|
||||
value description="The property key." {
|
||||
type string
|
||||
}
|
||||
prop id description="A globally-unique ID of this property." {
|
||||
type string
|
||||
}
|
||||
prop ref description="A globally unique reference to another property node." {
|
||||
type string
|
||||
format kdl-query
|
||||
}
|
||||
prop description description="A description of this property's purpose." {
|
||||
type string
|
||||
}
|
||||
children description="Property-specific validations." {
|
||||
node required description="Whether this property is required if its parent is present." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
children id=validations description="General value validations." {
|
||||
node tag id=value-tag-node description="The tags associated with this value" {
|
||||
max 1
|
||||
children ref=#"[id="validations"]"#
|
||||
}
|
||||
node type description="The type for this prop's value." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
type string
|
||||
}
|
||||
}
|
||||
node enum description="An enumeration of possible values" {
|
||||
max 1
|
||||
value description="Enumeration choices" {
|
||||
min 1
|
||||
}
|
||||
}
|
||||
node pattern description="PCRE (Regex) pattern or patterns to test prop values against." {
|
||||
value {
|
||||
min 1
|
||||
type string
|
||||
}
|
||||
}
|
||||
node min-length description="Minimum length of prop value, if it's a string." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node max-length description="Maximum length of prop value, if it's a string." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node format description="Intended data format." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
type string
|
||||
// https://json-schema.org/understanding-json-schema/reference/string.html#format
|
||||
enum date-time date time duration decimal currency country-2 country-3 country-subdivision email idn-email hostname idn-hostname ipv4 ipv6 url url-reference irl irl-reference url-template regex uuid kdl-query i8 i16 i32 i64 u8 u16 u32 u64 isize usize f32 f64 decimal64 decimal128
|
||||
}
|
||||
}
|
||||
node % description="Only used for numeric values. Constrains them to be multiples of the given number(s)" {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node > description="Only used for numeric values. Constrains them to be greater than the given number(s)" {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node ">=" description="Only used for numeric values. Constrains them to be greater than or equal to the given number(s)" {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node < description="Only used for numeric values. Constrains them to be less than the given number(s)" {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node "<=" description="Only used for numeric values. Constrains them to be less than or equal to the given number(s)" {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node value id=value-node description="one or more direct node values" {
|
||||
prop id description="A globally-unique ID of this value." {
|
||||
type string
|
||||
}
|
||||
prop ref description="A globally unique reference to another value node." {
|
||||
type string
|
||||
format kdl-query
|
||||
}
|
||||
prop description description="A description of this property's purpose." {
|
||||
type string
|
||||
}
|
||||
children ref=#"[id="validations"]"#
|
||||
children description="Node value-specific validations" {
|
||||
node min description="minimum number of values for this node." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node max description="maximum number of values for this node." {
|
||||
max 1
|
||||
value {
|
||||
min 1
|
||||
max 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node children id=children-node {
|
||||
prop id description="A globally-unique ID of this children node." {
|
||||
type string
|
||||
}
|
||||
prop ref description="A globally unique reference to another children node." {
|
||||
type string
|
||||
format kdl-query
|
||||
}
|
||||
prop description description="A description of this these children's purpose." {
|
||||
type string
|
||||
}
|
||||
children ref=#"[id="node-children"]"#
|
||||
}
|
||||
}
|
||||
}
|
||||
node definitions description="Definitions to reference in parts of the top-level nodes" {
|
||||
children {
|
||||
node ref=#"[id="node-node"]"#
|
||||
node ref=#"[id="value-node"]"#
|
||||
node ref=#"[id="prop-node"]"#
|
||||
node ref=#"[id="children-node"]"#
|
||||
node ref=#"[id="tag-node"]"#
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
@kdl:schema "https://github.com/kdl-org/kdl/blob/main/schema/kdl-schema.kdl"
|
||||
|
||||
metadata {
|
||||
// TODO: update this link when we're ready to release something.
|
||||
link "https://github.com/kdl-org/kdl/blob/main/schema/cargo.kdl" rel=self
|
||||
title "Cargo Schema" lang=en
|
||||
description "KDL-based translation of the Cargo.toml schema." lang=en
|
||||
author "Kat Marchán" {
|
||||
link "https://github.com/zkat" rel=self
|
||||
}
|
||||
link "https://github.com/kdl-org/kdl" rel=documentation
|
||||
link "https://doc.rust-lang.org/cargo/reference/manifest.html" rel=documentation
|
||||
license "Creative Commons Attribution-ShareAlike 4.0 International License" spdx=CC-BY-SA-4.0 {
|
||||
link "https://creativecommons.org/licenses/by-sa/4.0/" lang=en
|
||||
}
|
||||
}
|
||||
|
||||
children {
|
||||
node package title="Describes a package" {
|
||||
children {
|
||||
node name title="The name of the package" {
|
||||
required
|
||||
arg {
|
||||
type string
|
||||
pattern #"^[a-zA-Z0-0\-_]+$"#
|
||||
}
|
||||
}
|
||||
node version title="The version of the package." {
|
||||
arg {
|
||||
type string
|
||||
// From https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
|
||||
pattern #"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"#
|
||||
}
|
||||
}
|
||||
node authors title="The authors of the package." {
|
||||
repeatable
|
||||
args {
|
||||
distinct
|
||||
type string
|
||||
}
|
||||
children {
|
||||
node - {
|
||||
repeatable
|
||||
arg title="Name" {
|
||||
type string
|
||||
}
|
||||
prop email title="Email address" {
|
||||
type string
|
||||
format email
|
||||
}
|
||||
prop about title="Brief note about author (role, etc)" {
|
||||
type string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node edition title="The Rust edition." {
|
||||
arg {
|
||||
type string
|
||||
enum "2015" "2018" "2021" "2024"
|
||||
}
|
||||
}
|
||||
node rust-version title="The minimal supported Rust version." {
|
||||
arg {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node description title="A description of the package." {
|
||||
arg {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node documentation title="URL of the package documentation." {
|
||||
arg {
|
||||
type string
|
||||
format url
|
||||
}
|
||||
}
|
||||
node readme title="Path to the package’s README file." {
|
||||
arg {
|
||||
type string #boolean
|
||||
}
|
||||
}
|
||||
node homepage title="URL of the package homepage." {
|
||||
arg {
|
||||
type string
|
||||
format url
|
||||
}
|
||||
}
|
||||
node repository title="URL of the package source repository." {
|
||||
arg {
|
||||
type string
|
||||
format url
|
||||
}
|
||||
}
|
||||
node license title="The package license." {
|
||||
arg {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node license-file title="Path to the text of the license." {
|
||||
arg {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node keywords title="Keywords for the package." {
|
||||
args {
|
||||
type string
|
||||
// No pattern because keyword restrictions are only on
|
||||
// crates.io
|
||||
}
|
||||
}
|
||||
node categories title="Categories of the package." {
|
||||
args {
|
||||
type string
|
||||
// No pattern because category restrictions are only on
|
||||
// crates.io
|
||||
}
|
||||
}
|
||||
node workspace title="Path to the workspace for the package." {
|
||||
arg {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node build title="Path to the package build script." {
|
||||
arg {
|
||||
type string boolean
|
||||
}
|
||||
}
|
||||
node links title="Name of the native library the package links with." {
|
||||
arg {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node exclude title="Files to exclude when publishing." {
|
||||
args {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node include title="Files to include when publishing." {
|
||||
args {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node publish title="Can be used to prevent publishing the package." {
|
||||
// TODO: This is a good example of where we might need smarter
|
||||
// comstraints ("either a single boolean, or 1+ strings")
|
||||
args {
|
||||
type string boolean
|
||||
}
|
||||
]
|
||||
node metadata title="Extra settings for external tools." {
|
||||
repeat
|
||||
args
|
||||
props {
|
||||
allow-others
|
||||
}
|
||||
}
|
||||
node default-run title="The default binary to run by cargo run." {
|
||||
arg {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node no-autolib title="Disables library auto discovery."
|
||||
node no-autobins title="Disables binary auto discovery."
|
||||
node no-autoexamples title="Disables example auto discovery."
|
||||
node no-autotests title="Disables test auto discovery."
|
||||
node no-autobenches title="Disables bench auto discovery."
|
||||
node resolver title="Sets the dependency resolver to use."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,951 @@
|
|||
// TODO:
|
||||
// * dependentRequired
|
||||
// * dependentSchema
|
||||
// * if-then-else
|
||||
// * composition (anyOf, allOf, oneOf, not, etc: https://json-schema.org/understanding-json-schema/reference/combining)
|
||||
// * something like `xsd:group` for the above, instead? Including `xsd:sequence` stuff.
|
||||
// * something to configure LSP semanticTokens with
|
||||
|
||||
@ksl:schema "https://github.com/kdl-org/kdl/blob/main/examples/ksl-schema.kdl"
|
||||
|
||||
metadata {
|
||||
// TODO: update this link when we're ready to release something.
|
||||
id "https://github.com/kdl-org/kdl/blob/main/examples/ksl-schema.kdl"
|
||||
title "KDL Schema"
|
||||
description "KDL Schema schema using KDL Schema"
|
||||
author "Kat Marchán" {
|
||||
link "https://github.com/zkat"
|
||||
}
|
||||
contributor "Lars Willighagen" {
|
||||
link "https://github.com/larsgw"
|
||||
}
|
||||
link "https://github.com/kdl-org/kdl" rel=documentation
|
||||
license "Creative Commons Attribution-ShareAlike 4.0 International License" spdx=CC-BY-SA-4.0 {
|
||||
link "https://creativecommons.org/licenses/by-sa/4.0/"
|
||||
}
|
||||
published "2021-08-31"
|
||||
modified "2021-09-01"
|
||||
}
|
||||
|
||||
document {
|
||||
node example about="""
|
||||
An example document validated by this schema
|
||||
|
||||
The `example` node is completely inert. It SHOULD contain an
|
||||
illustrative example of a document that would be valid if checked
|
||||
against this schema.
|
||||
""" {
|
||||
repeatable
|
||||
ref about-mixin
|
||||
arg about="""
|
||||
Example filename
|
||||
|
||||
A descriptive filename that this example document might have, e.g. `mylang-schema.kdl`.
|
||||
""" {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node metadata about="""
|
||||
Schema metadata
|
||||
|
||||
Contains metadata about the schema itself.
|
||||
""" {
|
||||
required
|
||||
children {
|
||||
node id about="""
|
||||
Schema identifier
|
||||
|
||||
The unique identifier for this schema. MUST be a valid URL/IRL.
|
||||
When parsing a schema, implementations SHOULD NOT attempt to
|
||||
visit the URL itself, as it is not necessary for it to be valid.
|
||||
Parsers verifying against a schema MAY look at the given URL for
|
||||
a document if they don't already have a valid copy.
|
||||
""" {
|
||||
arg {
|
||||
type string
|
||||
format url irl
|
||||
}
|
||||
}
|
||||
node title about="""
|
||||
Schema title
|
||||
|
||||
The title of the schema or the format it describes.
|
||||
""" {
|
||||
arg about="The title text" {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node description about="""
|
||||
Schema description
|
||||
|
||||
A description of the schema or the format it validates, which
|
||||
may include its purposes, its usage, and even examples.
|
||||
""" {
|
||||
arg about="Description text" {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node author about="""
|
||||
Schema author
|
||||
|
||||
An author for the schema.
|
||||
""" {
|
||||
ref person-mixin
|
||||
repeatable
|
||||
}
|
||||
node contributor about="""
|
||||
Schema contributor
|
||||
|
||||
A contributor to the schema might not be considered an author.
|
||||
""" {
|
||||
ref person-mixin
|
||||
repeatable
|
||||
}
|
||||
node link about="""
|
||||
External link
|
||||
|
||||
Link to an external resource of some sort, such as the
|
||||
containing item itself (`rel=self`, the default) or
|
||||
documentation (`rel=documentation`). Implementations MAY visit
|
||||
the URL, but MUST NOT assume it is valid.
|
||||
""" {
|
||||
ref link-mixin
|
||||
repeatable
|
||||
arg about="Link URL\n\nA URL that the link points to." {
|
||||
type string
|
||||
format url irl
|
||||
}
|
||||
prop rel about="Link relationship\n\nThe relation between the current entity and the URL." {
|
||||
type string
|
||||
enum self documentation disallow-others=#false
|
||||
}
|
||||
}
|
||||
node license about="""
|
||||
Schema license
|
||||
|
||||
The license(s) that the schema is licensed under.
|
||||
""" {
|
||||
repeatable
|
||||
arg description="Name of the used license" {
|
||||
type string
|
||||
}
|
||||
prop spdx description="An SPDX license identifier" {
|
||||
type string
|
||||
// TODO: validation?
|
||||
}
|
||||
prop path about="Path to a local license file" {
|
||||
type string
|
||||
}
|
||||
prop url about="URL to an externally-stored license" {
|
||||
type string
|
||||
format url url-reference irl irl-reference
|
||||
}
|
||||
children {
|
||||
node link about="Link to license" {
|
||||
ref link-mixin
|
||||
}
|
||||
}
|
||||
}
|
||||
node published about="""
|
||||
Schema publication date
|
||||
|
||||
Date or data+time when the schema was published.
|
||||
""" {
|
||||
arg about="Publication date" {
|
||||
type string
|
||||
format date date-time
|
||||
}
|
||||
}
|
||||
node modified about="""
|
||||
Schema modification date
|
||||
|
||||
When the schema was modified. If used multiple times, the most
|
||||
recent date will be considered 'latest'.
|
||||
""" {
|
||||
repeatable
|
||||
args about="Modification date" {
|
||||
type string
|
||||
format date date-time
|
||||
}
|
||||
}
|
||||
node version about="""
|
||||
Schema semver version
|
||||
|
||||
The version number of this version of the schema, in semver
|
||||
format.
|
||||
""" {
|
||||
arg about="Semver version number" {
|
||||
type string
|
||||
// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string.
|
||||
pattern #"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"#
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node definitions about="""
|
||||
Inert validation definitions
|
||||
|
||||
An optional set of definitions that may be referenced elsewhere in the
|
||||
schema. They will be inert (that is, not directly apply to the document)
|
||||
unless referenced by another node inside `document`.
|
||||
"""
|
||||
}
|
||||
node document {
|
||||
ref children-node
|
||||
node @ksl:schema about="""
|
||||
Schema reference
|
||||
|
||||
Reference(s) for the schema(s) describing this document. They
|
||||
MUST be properly-formatted URLs. Implementations MAY attempt to
|
||||
visit them, but MUST NOT assume they are valid.
|
||||
|
||||
If multiple URLs are provided, or if multiple `@ksl:schema`
|
||||
nodes are present, ALL schemas MUST successfully validate in
|
||||
order for the document to validate, unless `warn-only` is
|
||||
`#true`.
|
||||
|
||||
In such a case, implementations SHOULD warn that validation has
|
||||
failed and report which schema failed to pass--they SHOULD
|
||||
include more details about what the specific failure was, but
|
||||
MAY simply indicate that certain schema(s) failed to validate.
|
||||
""" {
|
||||
repeatable
|
||||
prop warn-only about="Validation failures should ONLY be warnings." {
|
||||
type boolean
|
||||
default #false
|
||||
}
|
||||
// TODO(@zkat): is this the best way to do it?
|
||||
one-of {
|
||||
arg {
|
||||
type string
|
||||
format url url-reference irl irl-reference
|
||||
}
|
||||
arg about="Disallow the `@ksl:schema` node altogether" {
|
||||
enum #false
|
||||
}
|
||||
}
|
||||
}
|
||||
children {
|
||||
node children about="""
|
||||
Node children
|
||||
|
||||
Validations and definitions used for all nodes in this scope.
|
||||
Children are only allowed on nodes (or the toplevel document) if
|
||||
at least one `children` node is present in their definitions.
|
||||
""" {
|
||||
children {
|
||||
node min about="""
|
||||
Minimum number of children
|
||||
""" {
|
||||
arg {
|
||||
type integer
|
||||
default 0
|
||||
}
|
||||
}
|
||||
node max about="""
|
||||
Maximum number of children
|
||||
""" {
|
||||
arg {
|
||||
type integer
|
||||
}
|
||||
}
|
||||
node names about="""
|
||||
Child node name validations
|
||||
|
||||
String validations to apply to all node names in this scope.
|
||||
""" {
|
||||
ref string-validations
|
||||
ref about-mixin
|
||||
repeatable
|
||||
}
|
||||
node disallow-others about="""
|
||||
Disallow other children
|
||||
|
||||
If present/`#true`, blocks child nodes in this scope
|
||||
other than the ones explicitly listed and those allowed
|
||||
by `names`.
|
||||
""" {
|
||||
arg {
|
||||
type boolean
|
||||
default #false
|
||||
}
|
||||
}
|
||||
node disallow about="""
|
||||
Disallows matching nodes
|
||||
|
||||
Node specifications under this node will be matched
|
||||
against children and fail validation if a child matches.
|
||||
""" {
|
||||
children {
|
||||
ref node
|
||||
}
|
||||
}
|
||||
node node about="""
|
||||
A KDL node
|
||||
|
||||
Declares a KDL node belonging either to the top-level
|
||||
document or to another `node`'s children.
|
||||
""" {
|
||||
ref about-mixin
|
||||
repeatable
|
||||
arg about="Node name\n\nThe name of the node." {
|
||||
type string
|
||||
}
|
||||
prop id about="Node identifier\n\nA schema-unique ID/anchor for this node." {
|
||||
type string
|
||||
}
|
||||
children {
|
||||
node ref about="""
|
||||
A reference to a node defined elsewhere.
|
||||
|
||||
Each `ref` child will be interpreted in order of
|
||||
appearance. Any overlapping definitions will replace
|
||||
preceding instances, with each subsequent `ref`
|
||||
replacing any duplicate node components.
|
||||
|
||||
The replacement rules are as follows, and apply recursively:
|
||||
* node properties MUST by replaced by key.
|
||||
* node arguments MUST be replaced by order of appearance.
|
||||
* `prop` definitions MUST be replaced by key (their first argument)
|
||||
* `arg` definitions MUST be replaced based on _order of
|
||||
appearance_. That is, the first `arg` in ref `B` till be
|
||||
merged into the first `arg` in preceding ref `A`.
|
||||
* For all other components:
|
||||
* If the definition specified is marked as
|
||||
`repeatable`, then all definitions using that node
|
||||
will be concatenated, with later `ref`s
|
||||
concatenating definitions after the previous `ref`'s
|
||||
definitions.
|
||||
* If the definition is NOT marked as `repeatable`,
|
||||
it will be replaced by subsequent `ref`s.
|
||||
|
||||
Once all `ref` children are resolved, the containing
|
||||
node's own items will override anything defined by
|
||||
`ref`s, using the same rules as above (essentially, the
|
||||
current node is treated as a 'final `ref`').
|
||||
|
||||
If both an ID argument and a `path` are provided,
|
||||
the ID will take precedence and, if not found, fall
|
||||
back to the path. For `id` and `path` children,
|
||||
precedence is in order of appearance, regardless of
|
||||
whether the child is an `id` or a `path`.
|
||||
|
||||
If no items resolve into a valid ref, validation
|
||||
MUST error, unless the ref is configured as
|
||||
`optional`, in which case validation MAY warn, but
|
||||
MUST NOT fail.
|
||||
""" {
|
||||
repeatable
|
||||
arg about="KPath-based reference to another node" {
|
||||
type string
|
||||
format kpath
|
||||
}
|
||||
prop base about="""
|
||||
Base schema
|
||||
|
||||
The schema to resolve references against. If not
|
||||
provided, the base schema SHALL be the one
|
||||
defined in `metadata > id` for the current
|
||||
schema.
|
||||
|
||||
Relative schema references SHALL be resolved
|
||||
against `metadata > id`.
|
||||
""" {
|
||||
type string
|
||||
format url-reference irl-reference
|
||||
}
|
||||
children {
|
||||
node path about="KPath-based reference to another node." {
|
||||
repeatable
|
||||
arg {
|
||||
type string
|
||||
format kpath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node undefine about="Undefine a node with this name" {
|
||||
arg {
|
||||
optional
|
||||
type boolean
|
||||
default #true
|
||||
}
|
||||
}
|
||||
node required about="""
|
||||
Node is required
|
||||
|
||||
By default, all declared child nodes are
|
||||
optional. Including this option will require
|
||||
that this node always appear in its parent's
|
||||
children block.
|
||||
""" {
|
||||
arg {
|
||||
type boolean
|
||||
default #true
|
||||
}
|
||||
}
|
||||
node repeatable about="""
|
||||
Node is repeatable
|
||||
|
||||
By default, each node in a `children` block may
|
||||
only appear once in its scope. When this option
|
||||
is present, the node will be allowed to have
|
||||
multiple instances within the same scope.
|
||||
""" {
|
||||
prop min about="""
|
||||
Minimum node count
|
||||
|
||||
Minimum number of repeated instances of this
|
||||
node that must appear in the same scope.
|
||||
""" {
|
||||
arg {
|
||||
gte 0
|
||||
type integer
|
||||
}
|
||||
}
|
||||
prop max about="""
|
||||
Maximum node count
|
||||
|
||||
Maximum numbers of repeated instances of
|
||||
this node that may appear in the same scope.
|
||||
""" {
|
||||
arg {
|
||||
gte 0
|
||||
type integer
|
||||
}
|
||||
}
|
||||
}
|
||||
node deprecated about="""
|
||||
Mark node as deprecated
|
||||
|
||||
When present, this node will be considered a
|
||||
deprecated part of the API. You may optionally
|
||||
supply a message, and/or a reference to a node
|
||||
that should be used instead.
|
||||
""" {
|
||||
arg {
|
||||
optional
|
||||
type boolean
|
||||
default #true
|
||||
}
|
||||
prop message about="""
|
||||
Deprecation message
|
||||
|
||||
A helpful deprecation message that may
|
||||
explain why the node was deprecated and
|
||||
other information, such as when the node
|
||||
will be removed altogether. Users SHOULD use
|
||||
`by=` and `by-kpath` to specify what node
|
||||
this will be replaced with instead of
|
||||
including it in the `message` itself.
|
||||
""" {
|
||||
type string
|
||||
}
|
||||
prop by about="Deprecated by this node `id`" {
|
||||
type string
|
||||
}
|
||||
prop by-kpath about="Deprecated by this node KPath" {
|
||||
type string
|
||||
format kpath
|
||||
}
|
||||
}
|
||||
node annotations about="""
|
||||
Node type annotations
|
||||
|
||||
Validations to apply specifically to arbitrary
|
||||
node type annotation names.
|
||||
""" {
|
||||
ref about-mixin
|
||||
ref string-validations
|
||||
repeatable
|
||||
}
|
||||
node prop about="""
|
||||
Node property
|
||||
|
||||
A node property key/value pair. Properties
|
||||
declared with `prop` are always optional, unless
|
||||
marked as `required` or included in
|
||||
`props:required`.
|
||||
""" {
|
||||
ref about-mixin
|
||||
ref value-validations
|
||||
repeatable
|
||||
arg about="The property key" {
|
||||
type string
|
||||
}
|
||||
children about="Property-specific validations" {
|
||||
node required about="Whether this property is required in the node." {
|
||||
arg {
|
||||
optional
|
||||
type boolean
|
||||
default #true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node props about="""
|
||||
General property validations
|
||||
|
||||
Validations to apply to all properties of this
|
||||
node.
|
||||
""" {
|
||||
ref about-mixin
|
||||
ref value-validations
|
||||
children {
|
||||
node names about="Validations to apply to all property names." {
|
||||
ref string-validations
|
||||
repeatable
|
||||
}
|
||||
node min about="""
|
||||
Minimum property count
|
||||
|
||||
Minimum number of properties this node
|
||||
must have.
|
||||
""" {
|
||||
arg {
|
||||
gte 0
|
||||
type integer
|
||||
}
|
||||
}
|
||||
node max about="""
|
||||
Maximum property count
|
||||
|
||||
Maximum number of properties this node
|
||||
may have.
|
||||
""" {
|
||||
arg {
|
||||
gte 0
|
||||
type integer
|
||||
}
|
||||
}
|
||||
node required about="""
|
||||
List of required props
|
||||
|
||||
List of property names that must be
|
||||
present on the node. Individual `prop`
|
||||
nodes may specify additional required
|
||||
properties beyond those specified in
|
||||
this list. Properties listed here which
|
||||
already have a `prop` node marked as
|
||||
`required` are allowed, but are
|
||||
redundant.
|
||||
""" {
|
||||
args {
|
||||
min 1
|
||||
type string
|
||||
}
|
||||
}
|
||||
node disallow-others about="""
|
||||
Disallow other properties
|
||||
|
||||
If present, block properties that don't
|
||||
match this validator.
|
||||
""" {
|
||||
arg {
|
||||
type boolean
|
||||
default #true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node arg about="""
|
||||
Defines an individual, ordered argument
|
||||
|
||||
Each nth instance of this node will specify
|
||||
validations for the corresponding nth instance
|
||||
of the arg. Every specified `arg` is required,
|
||||
in the given order, unless marked as `optional`.
|
||||
""" {
|
||||
ref about-mixin
|
||||
ref value-validations
|
||||
repeatable
|
||||
children {
|
||||
node optional about="""
|
||||
Argument is not required
|
||||
|
||||
Specified `arg`s are required by
|
||||
default.
|
||||
|
||||
`optional` only applies to *presence*:
|
||||
an existing argument in an optional
|
||||
`arg` \"slot\" that fails validation
|
||||
will fail normally, even though it is
|
||||
optional. As such, `optional` is only
|
||||
really useful if it is on the last
|
||||
`arg`, or is only followed by optional
|
||||
`arg`s.
|
||||
""" {
|
||||
arg {
|
||||
type boolean
|
||||
default #true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: add a feature that will let us specify that `args`
|
||||
// MUST be after any existing `arg` nodes in the current
|
||||
// scope. i.e. you can't do `node x { args; arg }`
|
||||
node args about="""
|
||||
Validations for all args
|
||||
|
||||
Specifies validations for all arguments. Can be
|
||||
used in conjunction with `arg`. If this node is
|
||||
not present, and if there are no `arg` nodes, no
|
||||
arguments will be allowed on the node at all
|
||||
""" {
|
||||
ref about-mixin
|
||||
ref value-validation
|
||||
children {
|
||||
// TODO: opportunity for mutual requirements here
|
||||
node min about="""
|
||||
Minimum argument count
|
||||
|
||||
Minimum number of arguments that must be
|
||||
present in a node. Must be less than or
|
||||
equal to `max`, if the latter is
|
||||
present.
|
||||
""" {
|
||||
arg {
|
||||
gte 0
|
||||
type integer
|
||||
}
|
||||
}
|
||||
node max about="""
|
||||
Maximum argument count
|
||||
|
||||
Maximum number of arguments that may be
|
||||
present in a node. Must be greater than or
|
||||
equal to `max`, if the latter is present.
|
||||
""" {
|
||||
arg {
|
||||
gte 0
|
||||
type integer
|
||||
}
|
||||
}
|
||||
node distinct about="""
|
||||
All arguments must be distinct
|
||||
|
||||
If present, all of this node's arguments
|
||||
need to be distinct values.
|
||||
""" {
|
||||
arg {
|
||||
type boolean
|
||||
default #true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node children {
|
||||
ref children
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
definitions {
|
||||
node link-mixin about="""
|
||||
External link
|
||||
|
||||
Link to an external resource of some sort, such as the schema
|
||||
itself (`rel=self`) or documentation (`rel=documentation`).
|
||||
Implementations MAY visit the URL, but MUST NOT assume it is
|
||||
valid.
|
||||
""" {
|
||||
repeatable
|
||||
arg about="Link URL\n\nA URL that the link points to." {
|
||||
type string
|
||||
format url irl
|
||||
}
|
||||
prop rel about="Link relationship\n\nThe relation between the current entity and the URL." {
|
||||
type string
|
||||
default self
|
||||
enum self documentation disallow-others=#false
|
||||
}
|
||||
}
|
||||
node person-mixin {
|
||||
arg description="Person name" {
|
||||
optional
|
||||
type string
|
||||
}
|
||||
prop orcid description="The ORCID of the person" {
|
||||
type string
|
||||
pattern #"\d{4}-\d{4}-\d{4}-\d{4}"#
|
||||
}
|
||||
children {
|
||||
node link {
|
||||
ref metadata-link
|
||||
}
|
||||
}
|
||||
}
|
||||
node lang-mixin {
|
||||
prop lang about="""
|
||||
Content language
|
||||
|
||||
The (human) language of the text.
|
||||
""" {
|
||||
type string
|
||||
}
|
||||
}
|
||||
node string-validations about="String-related validations" {
|
||||
ref shared-validations
|
||||
children {
|
||||
node pattern about="""
|
||||
Regex-based validations
|
||||
|
||||
Tests string values against a regular expression and passes if
|
||||
the regular expression matches.
|
||||
|
||||
Implementations SHOULD use an EcmaScript-compatible regex engine. If they choose not to, this SHOULD be clearly documented.
|
||||
""" {
|
||||
args {
|
||||
min 1
|
||||
type string
|
||||
}
|
||||
}
|
||||
node min-length about="""
|
||||
Minimum string length
|
||||
|
||||
Minimum length of the value, if it's a string.
|
||||
""" {
|
||||
arg {
|
||||
gte 0
|
||||
type integer
|
||||
}
|
||||
}
|
||||
node max-length about="""
|
||||
Maximum string length
|
||||
|
||||
Maximum length of the value, if it's a string.
|
||||
""" {
|
||||
arg {
|
||||
gte 0
|
||||
type integer
|
||||
}
|
||||
}
|
||||
node format about="""
|
||||
Specifies the format of the value
|
||||
|
||||
Any supported type annotation from the KDL spec may be
|
||||
specified. It is up to implementations whether they validate
|
||||
this node. They SHOULD document the ones they support, if any.
|
||||
|
||||
Any format that the implementation supports MUST be compliant
|
||||
with the specified reserved format in the KDL spec, and only
|
||||
apply it to the specified data types (e.g. `u8` can only apply
|
||||
to items of type `integer`, not to `string` or `number`). If the
|
||||
checked value is not of an applicable type, the implementation
|
||||
MUST skip applying this to the given type. It MAY choose to warn
|
||||
about skipping the format check.
|
||||
|
||||
If a value specifies multiple `type`s, any `format`s are checked
|
||||
as usual against the matrix of compatible `type`/`format`
|
||||
values.
|
||||
|
||||
Implementations MAY choose either error or simply warn about
|
||||
format violations. They SHOULD document the behavior, and MAY
|
||||
provide configuration for it.
|
||||
"""
|
||||
repeatable
|
||||
args {
|
||||
min 1
|
||||
type string
|
||||
// https://json-schema.org/understanding-json-schema/reference/string.html#format
|
||||
// TODO: Make sure this is up to date with the types listed in the spec.
|
||||
enum disallow-others=#false \
|
||||
// String validations
|
||||
date-time date time duration decimal currency country-2 \
|
||||
country- country-subdivision email idn-email hostname \
|
||||
idn-hostname ipv4 ipv6 url url-reference irl \
|
||||
irl-reference url-template regex uuid kpath \
|
||||
|
||||
// Number validations
|
||||
i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 isize usize f32 \
|
||||
f64 decimal64 decimal128
|
||||
}
|
||||
}
|
||||
node media-type about="""
|
||||
MIME type
|
||||
|
||||
MIME type of string value. May be applied to 'deserialized' data
|
||||
if value format is base64/base85 or some other stringly binary
|
||||
encoding.
|
||||
""" {
|
||||
repeatable
|
||||
args {
|
||||
min 1
|
||||
type string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Number-specific validations
|
||||
node number-validations {
|
||||
ref shared-validations
|
||||
children {
|
||||
node div about="
|
||||
Divisible by
|
||||
|
||||
Constrains them to be multiples of the given number(s). Only
|
||||
used for numeric values. If multiple numbers are given, _any_
|
||||
match will pass. In order to say something like `divisible by 3
|
||||
AND by 4`, use multiple `div` nodes: `div 3; div 4`.
|
||||
""" {
|
||||
repeatable
|
||||
args {
|
||||
min 1
|
||||
type number
|
||||
}
|
||||
}
|
||||
node gt about="""
|
||||
Greater than
|
||||
|
||||
Only used for numeric values. Constrains them to be greater than
|
||||
the given number.
|
||||
""" {
|
||||
arg {
|
||||
type number
|
||||
}
|
||||
}
|
||||
node gte about="""
|
||||
Greater than or equal to
|
||||
|
||||
Only used for numeric values. Constrains them to be greater than
|
||||
or equal to the given number.
|
||||
""" {
|
||||
arg {
|
||||
type number
|
||||
}
|
||||
}
|
||||
node lt about="""
|
||||
Less than
|
||||
|
||||
Only used for numeric values. Constrains them to be less than
|
||||
the given number.
|
||||
""" {
|
||||
arg {
|
||||
type number
|
||||
}
|
||||
}
|
||||
node lte about="""
|
||||
Less than or equal to
|
||||
|
||||
Only used for numeric values. Constrains them to be less than or
|
||||
equal to the given number
|
||||
""" {
|
||||
arg {
|
||||
type number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Validations shared across all types.
|
||||
node shared-validations {
|
||||
children {
|
||||
node type about="The type for this value\n\nMultiple arguments signify a sum type." {
|
||||
repeatable
|
||||
args {
|
||||
min 1
|
||||
type string
|
||||
enum string boolean number integer #null
|
||||
distinct
|
||||
}
|
||||
}
|
||||
// TODO: establish equality expectations.
|
||||
node enum about="""
|
||||
Enumeration of values
|
||||
|
||||
An enumeration of possible values
|
||||
""" {
|
||||
repeatable
|
||||
args about="Enumeration choices" {
|
||||
min 1
|
||||
}
|
||||
prop disallow-others about="""
|
||||
Disallow other choices
|
||||
|
||||
Whether other values than those explicitly enumerated
|
||||
may be provided, so long as they pass other validations
|
||||
in the node.
|
||||
|
||||
While apparently redundant, this option may be useful in
|
||||
cases where there's a set of suggested values, but
|
||||
others are acceptable. This information can then be used
|
||||
by tooling to e.g. suggest completion items.
|
||||
""" {
|
||||
type boolean
|
||||
default #true
|
||||
}
|
||||
children {
|
||||
node - about="Enumeration choice" {
|
||||
ref about-mixin
|
||||
arg about="Enum value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// General value validations
|
||||
node value-validations {
|
||||
ref string-validations number-validations
|
||||
children {
|
||||
node annotations about="""
|
||||
Validates value type annotations
|
||||
|
||||
String validations for the type annotations that can be applied
|
||||
to this value.
|
||||
""" {
|
||||
ref string-validations
|
||||
}
|
||||
node default about="""
|
||||
Default value
|
||||
|
||||
Sets a default value when optional. That is, it requires
|
||||
`optional` for `arg` nodes, and doesn't do anything useful if a
|
||||
`prop` is marked `required`, though it is not invalid to do so.
|
||||
""" {
|
||||
arg
|
||||
}
|
||||
}
|
||||
}
|
||||
node about-mixin {
|
||||
prop about about="""
|
||||
Description for this component.
|
||||
|
||||
By convention, the format of this value is intended to be similar to
|
||||
git's commit message system: The first line is treated as a short
|
||||
descriptor/summary, and any lines underneath it are treated as the
|
||||
longer-form documentation. As such, the first line SHOULD be up to
|
||||
50 characters in length.
|
||||
|
||||
Tooling SHOULD only display some or all of the first line in user
|
||||
interfaces that call for terseness, and they SHOULD display both the
|
||||
short descriptor and the longer explanation.
|
||||
""" {
|
||||
type string
|
||||
}
|
||||
children {
|
||||
node about about="""
|
||||
Description for this component.
|
||||
|
||||
By convention, the format of this value is intended to be similar to
|
||||
git's commit message system: The first line is treated as a short
|
||||
descriptor/summary, and any lines underneath it are treated as the
|
||||
longer-form documentation. Tooling SHOULD only display some or all
|
||||
of the first line in user interfaces that call for terseness, and
|
||||
they SHOULD display both the short descriptor and the longer
|
||||
explanation
|
||||
|
||||
If both an `about` property and an `about` child node are
|
||||
present in a definition, the child node's value MUST take
|
||||
precedence.
|
||||
""" {
|
||||
arg {
|
||||
type string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
// schema for a hypothetical package.kdl based on NPM's package.json.
|
||||
// It takes some liberties to make the format feel more "cuddly", rather than
|
||||
// trying to map the package.json structure 1:1.
|
||||
// Derived from https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/package.json
|
||||
|
||||
@ksl:schema "https://github.com/kdl-org/kdl/blob/main/examples/ksl-schema.kdl"
|
||||
|
||||
example "package.kdl" {
|
||||
name "@bgotink/kdl"
|
||||
version "0.3.1"
|
||||
author "Bram Gotink" url="https://github.com/bgotink"
|
||||
license MIT
|
||||
repository "https://github.com/bgotink/kdl" type=git
|
||||
homepage "https://github.bram.dev/kdl/"
|
||||
description "Modification-friendly KDL parser and serializer."
|
||||
keywords kdl parser serializer
|
||||
type module
|
||||
private
|
||||
no-side-effects
|
||||
package-manager yarn@4.0.2
|
||||
exports {
|
||||
"." "./src/index.js"
|
||||
"./json" "./src/json.js"
|
||||
"./v1-compat" "./src/v1-compat.js"
|
||||
"./dessert" "./src/dessert.js"
|
||||
"./package.json" "/package.json"
|
||||
}
|
||||
imports { "#v1" "@bgotink/kdl-v1" }
|
||||
scripts {
|
||||
postinstall "is-ci || husky"
|
||||
build "node scripts/build.js"
|
||||
test "uvu test"
|
||||
bench "node scripts/bench.js"
|
||||
book "scripts/book.sh"
|
||||
}
|
||||
dev-dependencies {
|
||||
"@bgotink/kdl-v1" "=0.1.7" package="@bgotink/kdl" workspace="./legacy"
|
||||
"@types/benchmark" ^2.1.5
|
||||
"@types/node" ^22
|
||||
benchmark ^2.1.4
|
||||
esbuild ^0.24.2
|
||||
express-check-in ^0.2.0
|
||||
husky "=9.1.7-dotconfig.0.1.0" package="@dot-config/husky"
|
||||
is-ci ^3.0.1
|
||||
kdljs ^0.2.0
|
||||
marked ^14.1.2
|
||||
prettier "=3.4.2-dotconfig.0.1.0" package="@dot-config/prettier"
|
||||
typedoc ^0.27.6
|
||||
typedoc-plugin-markdown ^4.3.3
|
||||
typescript ~5.6.2
|
||||
uvu ^0.5.6
|
||||
}
|
||||
}
|
||||
|
||||
metadata {
|
||||
// TODO: update this link when we're ready to release something.
|
||||
id "https://github.com/kdl-org/kdl/blob/main/schema/package.kdl"
|
||||
title "NPM package.kdl schema" lang=en
|
||||
description "KDL-based translation of the package.json schema." lang=en
|
||||
author "Kat Marchán" {
|
||||
link "https://github.com/zkat" rel=self
|
||||
}
|
||||
link "https://github.com/kdl-org/kdl" rel=documentation
|
||||
link "https://docs.npmjs.com/cli/v11/configuring-npm/package-json" rel=documentation
|
||||
license "Creative Commons Attribution-ShareAlike 4.0 International License" spdx=CC-BY-SA-4.0 {
|
||||
link "https://creativecommons.org/licenses/by-sa/4.0/"
|
||||
}
|
||||
}
|
||||
|
||||
document {
|
||||
node dependencies
|
||||
}
|
||||
|
||||
definitions {
|
||||
node person about="""
|
||||
A person
|
||||
|
||||
Someone who has been involved in creating and maintaining this package.
|
||||
""" {
|
||||
arg about="Person name" {
|
||||
type string
|
||||
}
|
||||
prop email about="Person's email address" {
|
||||
type string
|
||||
format email
|
||||
}
|
||||
prop url about="URL related to this person" {
|
||||
type string
|
||||
format url
|
||||
}
|
||||
}
|
||||
node dependency-block {
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue