Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/api/json/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -5576,6 +5576,12 @@
"fileMatch": ["**/sites/*/config.yaml", "**/sites/*/config.yml"],
"url": "https://json.schemastore.org/typo3.json"
},
{
"name": "Typst Manifest",
"description": "Typst package manifest file (typst.toml)",
"fileMatch": ["typst.toml"],
"url": "https://json.schemastore.org/typst.json"
},
{
"name": "typos.toml",
"description": "typos configuration file",
Expand Down
9 changes: 9 additions & 0 deletions src/negative_test/typst/invalid-author-type.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#:schema ../../schemas/json/typst.json
# Fails because package.authors is not an array
[package]
name = "wrong-authors"
version = "0.1.0"
entrypoint = "lib.typ"
authors = "Just Me" # INVALID TYPE (should be array)
license = "MIT"
description = "Authors should be a list."
9 changes: 9 additions & 0 deletions src/negative_test/typst/invalid-missing-required.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#:schema ../../schemas/json/typst.json
# Fails because package.version is missing
[package]
name = "missing-version"
# version = "0.1.0" # MISSING
entrypoint = "lib.typ"
authors = ["Incomplete Author"]
license = "MIT"
description = "This package is missing a version."
9 changes: 9 additions & 0 deletions src/negative_test/typst/invalid-name-pattern.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#:schema ../../schemas/json/typst.json
# Fails because package.name contains uppercase characters
[package]
name = "Invalid-Name" # INVALID PATTERN
version = "0.1.0"
entrypoint = "lib.typ"
authors = ["Rule Breaker"]
license = "MIT"
description = "This package has an invalid name."
9 changes: 9 additions & 0 deletions src/negative_test/typst/invalid-version-pattern.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#:schema ../../schemas/json/typst.json
# Fails because package.version is not a valid SemVer string
[package]
name = "bad-version"
version = "1.2" # INVALID PATTERN (missing patch)
entrypoint = "lib.typ"
authors = ["Version Violator"]
license = "MIT"
description = "This package has an invalid version format."
1 change: 1 addition & 0 deletions src/schema-validation.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
"tsoa.json",
"typings.json",
"typingsrc.json",
"typst.json",
"typo3.json",
"ubuntu-server-autoinstall.json",
"utam-page-object.json",
Expand Down
245 changes: 245 additions & 0 deletions src/schemas/json/typst.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/typst.json",
"title": "Typst Package Manifest",
"description": "Schema for typst.toml package manifest files, used by the Typst package manager and universe.",
"type": "object",
"required": ["package"],
"properties": {
"package": {
"type": "object",
"description": "Contains metadata about the package.",
"required": [
"name",
"version",
"entrypoint",
"authors",
"license",
"description"
],
"properties": {
"name": {
"type": "string",
"description": "The package's identifier in its namespace. Should use kebab-case if it contains multiple words. Should not contain 'typst'.",
"pattern": "^[a-z0-9][a-z0-9\\-]*$",
"examples": ["my-package", "example", "uni-stuttgart-template"]
},
"version": {
"type": "string",
"description": "The package's version as a full major-minor-patch triple (following SemVer). See https://semver.org/",
"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-]+)*))?$",
"examples": ["1.0.0", "0.2.1"]
},
"entrypoint": {
"type": "string",
"description": "The path to the main Typst file (relative to the package root) that is evaluated when the package is imported.",
"examples": ["lib.typ", "src/main.typ"]
},
"authors": {
"type": "array",
"description": "A list of the package's authors. Each author can provide an email address (<mailto:EMAIL>), homepage (<https://URL>), or GitHub handle (<@HANDLE>) in angle brackets.",
"items": {
"type": "string"
},
"minItems": 1,
"examples": [
["Jane Doe <jane.doe@example.com>", "John Doe <@johndoe>"],
["Typst GmbH <https://typst.app>"]
]
},
"license": {
"type": "string",
"description": "The package's license. Must contain a valid SPDX 2.3 expression describing one or multiple licenses that are either OSI-approved (https://opensource.org/licenses/) or CC-BY-4.0, CC-BY-SA-4.0, or CC0-1.0. See https://spdx.dev/learn/handling-license-info/",
"examples": [
"MIT",
"Apache-2.0",
"GPL-3.0-or-later",
"MIT OR Apache-2.0",
"CC-BY-SA-4.0"
]
},
"description": {
"type": "string",
"description": "A short, clear description of the package (one sentence recommended)."
},
"homepage": {
"type": "string",
"description": "A URL to the package's web presence (e.g., documentation website).",
"format": "uri",
"examples": ["https://example.com/my-package-docs"]
},
"repository": {
"type": "string",
"description": "A URL to the repository where this package is developed (e.g., GitHub, GitLab). Used if homepage is not set.",
"format": "uri",
"examples": ["https://github.com/user/my-package"]
},
"keywords": {
"type": "array",
"description": "An array of search keywords for the package.",
"items": {
"type": "string"
},
"uniqueItems": true,
"examples": [
["chart", "plot", "data visualization"],
["ieee", "template", "paper"]
]
},
"categories": {
"type": "array",
"description": "An array with up to three categories from the official list to help users discover the package.",
"items": {
"type": "string",
"enum": [
"components",
"visualization",
"model",
"layout",
"text",
"languages",
"scripting",
"integration",
"utility",
"fun",
"book",
"report",
"paper",
"thesis",
"poster",
"flyer",
"presentation",
"cv",
"office"
]
},
"maxItems": 3,
"uniqueItems": true,
"examples": [
["visualization", "components"],
["paper", "layout"]
]
},
"disciplines": {
"type": "array",
"description": "An array of disciplines from the official list defining the target audience. Should be empty if generally applicable.",
"items": {
"type": "string",
"enum": [
"agriculture",
"anthropology",
"archaeology",
"architecture",
"biology",
"business",
"chemistry",
"communication",
"computer-science",
"design",
"drawing",
"economics",
"education",
"engineering",
"fashion",
"film",
"geography",
"geology",
"history",
"journalism",
"law",
"linguistics",
"literature",
"mathematics",
"medicine",
"music",
"painting",
"philosophy",
"photography",
"physics",
"politics",
"psychology",
"sociology",
"theater",
"theology",
"transportation"
]
},
"uniqueItems": true,
"examples": [["computer-science", "mathematics"], ["physics"]]
},
"compiler": {
"type": "string",
"description": "The minimum Typst compiler version required for this package to work (SemVer format).",
"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-]+)*))?$",
"examples": ["0.8.0", "0.11.0"]
},
"exclude": {
"type": "array",
"description": "An array of globs specifying files (relative to package root) that should not be part of the published bundle. Do not exclude README or LICENSE.",
"items": {
"type": "string"
},
"examples": [["docs/", "*.pdf", "images/draft*.png"]]
}
},
"additionalProperties": false
},
"template": {
"type": "object",
"description": "If present, declares this package as a template.",
"required": ["path", "entrypoint", "thumbnail"],
"properties": {
"path": {
"type": "string",
"description": "The directory within the package (relative to package root) containing files to be copied into the user's new project directory.",
"examples": ["template", "skeleton"]
},
"entrypoint": {
"type": "string",
"description": "Path relative to the template 'path' directory pointing to the main file to be compiled after initialization.",
"examples": ["main.typ", "report.typ"]
},
"thumbnail": {
"type": "string",
"description": "Path relative to the package root pointing to a PNG or lossless WebP thumbnail (min 1080px on longer edge, max 3MB) depicting the initialized template.",
"pattern": "\\.(png|PNG|webp|WEBP)$",
"examples": ["thumbnail.png", "preview.webp"]
}
},
"additionalProperties": false
},
"tool": {
"type": "object",
"description": "Namespace for third-party tools to store their own configuration.",
"additionalProperties": true
}
},
"additionalProperties": false,
"allOf": [
{
"if": {
"required": ["template"]
},
"then": {
"properties": {
"package": {
"required": [
"name",
"version",
"entrypoint",
"authors",
"license",
"description",
"categories"
],
"properties": {
"categories": {
"minItems": 1
}
}
}
}
}
}
]
}
21 changes: 21 additions & 0 deletions src/test/typst/full-package.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#:schema ../../schemas/json/typst.json
# A package using many optional fields
[package]
name = "my-feature-rich-package"
version = "1.2.3"
entrypoint = "src/main.typ"
authors = ["Dev One <@dev1>", "Dev Two <https://example.com/dev2>"]
license = "Apache-2.0 OR MIT"
description = "A package demonstrating most of the available fields."
homepage = "https://example.com/my-package"
repository = "https://github.com/user/my-feature-rich-package"
keywords = ["utility", "example", "testing"]
categories = ["utility", "scripting"]
disciplines = ["computer-science"]
compiler = "0.9.0"
exclude = ["docs/", "*.pdf", "images/logo.png"]

# No template section

[tool.my-formatter]
line-width = 80
12 changes: 12 additions & 0 deletions src/test/typst/valid-basic-package.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#:schema ../../schemas/json/typst.json
# A minimal valid package manifest
[package]
name = "my-basic-pkg"
version = "0.1.0"
entrypoint = "lib.typ"
authors = ["Example Author <author@example.com>"]
license = "MIT"
description = "This is a minimal but valid package."

# No template section
# No tool section
10 changes: 10 additions & 0 deletions src/test/typst/valid-complex-version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#:schema ../../schemas/json/typst.json
# Testing SemVer patterns
[package]
name = "pre-release-pkg"
version = "1.0.0-beta.1+build.123" # Valid SemVer
entrypoint = "main.typ"
authors = ["Tester"]
license = "MIT"
description = "Testing complex version string."
compiler = "0.11.0-rc1" # Valid SemVer compiler version
19 changes: 19 additions & 0 deletions src/test/typst/valid-template.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#:schema ../../schemas/json/typst.json
# A valid template package manifest
[package]
name = "simple-report-template"
version = "0.2.0"
entrypoint = "lib.typ" # Package entrypoint (for potential imports)
authors = ["Template Creator <https://example.com>"]
license = "CC0-1.0" # License suitable for template content
description = "A simple report template."
# Template requires at least one category
categories = ["report"]
keywords = ["template", "report", "academic"]
disciplines = ["education"]
compiler = "0.10.0"

[template]
path = "template_files"
entrypoint = "main.typ" # Relative to template_files/
thumbnail = "assets/thumbnail.png" # Relative to package root