UNPKG

@labex-labs/schema

Version:

JSON Schema definitions for LabEx lab and course configurations

528 lines 15.7 kB
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "LabEx index.json schema", "type": "object", "required": [ "type", "title", "description", "meta", "difficulty", "time", "details", "backend" ], "properties": { "type": { "type": "string", "enum": [ "lab", "challenge" ] }, "title": { "type": "string", "description": "English title of the lab, Use Title Case" }, "description": { "type": "string", "description": "Brief English description of the lab" }, "meta": { "type": "object", "required": [ "title", "description", "keywords" ], "properties": { "title": { "type": "string", "description": "English SEO title of the lab, Use Title Case" }, "description": { "type": "string", "description": "English SEO description of the lab" }, "keywords": { "type": "string", "description": "English SEO keywords of the lab, separated by commas" } } }, "difficulty": { "type": "string", "enum": [ "Beginner", "Intermediate", "Advanced" ], "description": "Difficulty level of the lab" }, "time": { "type": "integer", "description": "Estimated completion time (in minutes)" }, "hidden": { "type": "boolean", "default": false, "description": "Whether to hide in the list" }, "fee_type": { "type": "string", "enum": [ "free", "pro" ], "description": "Fee type" }, "show_in_tutorial": { "type": "boolean", "default": false, "description": "Whether to show in tutorials" }, "verified": { "type": "boolean", "default": false, "description": "Whether the lab is verified" }, "alias": { "type": "string", "description": "Alias of the lab, if configured, the lab will be redirected to the alias" }, "details": { "type": "object", "required": [ "steps", "intro", "finish" ], "properties": { "steps": { "type": "array", "items": { "type": "object", "required": [ "title", "text", "verify", "skills" ], "allOf": [ { "if": { "properties": { "$lab_type": { "const": "challenge" } }, "required": [ "$lab_type" ] }, "then": { "required": [ "solutions" ] } } ], "properties": { "title": { "type": "string", "description": "Step title" }, "text": { "type": "string", "pattern": "^(en/)?step[1-9][0-9]*.md$", "description": "Path to the step content Markdown file. Use 'step1.md' if no i18n exists, or 'en/step1.md' if i18n exists" }, "verify": { "type": "array", "items": { "type": "object", "required": [ "name", "file", "hint" ], "properties": { "name": { "type": "string", "description": "Verification step name, use Title Case" }, "file": { "type": "string", "pattern": "^verify[1-9][0-9]*-[1-9][0-9]*.sh$", "description": "Path to verification script, must follow pattern: verify1-1.sh, verify1-2.sh, etc." }, "hint": { "type": "string", "description": "Hint shown when verification fails" }, "timeout": { "type": "integer", "default": 0, "description": "Verification timeout in seconds" }, "showstderr": { "type": "boolean", "default": false, "description": "Whether to show stderr output" } } } }, "skills": { "type": "array", "default": [], "items": { "type": "string" }, "description": "Related skill tags, make sure the skill tags are in the skill list" }, "solutions": { "type": "array", "items": { "type": "string" }, "description": "List of paths to solution Markdown files, use relative path" } } } }, "intro": { "type": "object", "required": [ "text" ], "properties": { "text": { "type": "string", "pattern": "^(en/)?intro.md$", "description": "Path to introduction content Markdown file. Use 'intro.md' if no i18n exists, or 'en/intro.md' if i18n exists" }, "title": { "type": "string", "enum": [ "Introduction" ], "description": "Introduction title, use Title Case" }, "background": { "type": "string", "enum": [ "setup.sh" ], "description": "Path to background setup script, must be setup.sh" } } }, "finish": { "type": "object", "required": [ "text" ], "properties": { "text": { "type": "string", "pattern": "^(en/)?finish.md$", "description": "Path to summary content Markdown file. Use 'finish.md' if no i18n exists, or 'en/finish.md' if i18n exists" }, "title": { "type": "string", "enum": [ "Summary" ], "description": "Summary title, use Title Case" } } }, "assets": { "type": "object", "description": "Lab assets configuration", "patternProperties": { "host01": { "type": "array", "items": { "type": "object", "required": [ "file", "target" ], "properties": { "file": { "type": "string", "description": "Source file or pattern" }, "target": { "type": "string", "description": "Target path on the host" }, "chmod": { "type": "string", "description": "File permissions to set" } } } } } } } }, "backend": { "type": "object", "required": [ "imageid" ], "properties": { "imageid": { "type": "string", "enum": [ "vnc-ubuntu:2204", "webide-ubuntu:2204", "jupyter-ubuntu:2204", "vnc-instance-ubuntu:2204", "vnc-instance-ubuntu-bigdata:2204", "vnc-ubuntu-privileged:2204", "vnc-instance-ubuntu-kali:2204", "webide-instance-ubuntu:2204", "vnc-instance-ubuntu-jenkins:2204", "rhcsa-ubi9", "vnc-instance-ubuntu-docker:2204", "claude", "desktop-start" ], "description": "Docker image ID used by backend, make sure the image is in the image list" }, "open_network": { "type": "boolean", "default": false, "description": "Whether to enable network access" } } }, "contributors": { "type": "array", "items": { "type": "string" }, "description": "List of contributors" }, "license": { "type": "object", "properties": { "name": { "type": "string", "description": "License name" }, "url": { "type": "string", "description": "License URL" }, "repo": { "type": "string", "description": "Source code repository URL" } } }, "redirect_lab": { "type": "string", "pattern": "^[\\w-]+/[\\w-]+:[\\w/-]+$", "description": "Path to redirect to another lab (e.g., 'labex-labs/labs:python/lab-your-first-python-lab')" }, "i18n": { "type": "array", "items": { "type": "object", "required": [ "lang", "title", "description", "meta", "details" ], "properties": { "lang": { "type": "string", "enum": [ "zh", "es", "fr", "de", "ja", "ru" ], "description": "Language code" }, "title": { "type": "string", "description": "Localized title" }, "description": { "type": "string", "description": "Localized description" }, "meta": { "type": "object", "required": [ "title", "description", "keywords" ], "properties": { "title": { "type": "string", "description": "Localized SEO title" }, "description": { "type": "string", "description": "Localized SEO description" }, "keywords": { "type": "string", "description": "Localized SEO keywords" } } }, "details": { "type": "object", "required": [ "steps", "intro", "finish" ], "properties": { "steps": { "type": "array", "items": { "type": "object", "required": [ "title", "text", "verify" ], "allOf": [ { "if": { "properties": { "$lab_type": { "const": "challenge" } }, "required": [ "$lab_type" ] }, "then": { "required": [ "solutions" ] } } ], "properties": { "title": { "type": "string", "description": "Localized step title, use Title Case" }, "text": { "type": "string", "pattern": "^[a-z]{2}/step[1-9][0-9]*.md$", "description": "Localized step content file path, must follow pattern: {lang}/step1.md (e.g., zh/step1.md)" }, "verify": { "type": "array", "items": { "type": "object", "required": [ "name", "file", "hint" ], "properties": { "name": { "type": "string", "description": "Localized verification step name, use Title Case" }, "file": { "type": "string", "pattern": "^verify[1-9][0-9]*-[1-9][0-9]*.sh$", "description": "Path to verification script, must follow pattern: verify1-1.sh, verify1-2.sh, etc." }, "hint": { "type": "string", "description": "Localized verification failure hint" } } } }, "solutions": { "type": "array", "items": { "type": "string" }, "description": "List of paths to localized solution Markdown files, use relative path" } } } }, "intro": { "type": "object", "required": [ "text", "title" ], "properties": { "text": { "type": "string", "pattern": "^[a-z]{2}/intro.md$", "description": "Localized introduction content file path, must follow pattern: {lang}/intro.md (e.g., zh/intro.md)" }, "title": { "type": "string", "enum": [ "介绍", "Introducción", "Introduction", "Einführung", "はじめに", "Введение" ], "description": "Localized introduction title, use Title Case" } } }, "finish": { "type": "object", "required": [ "text", "title" ], "properties": { "text": { "type": "string", "pattern": "^[a-z]{2}/finish.md$", "description": "Localized summary content file path, must follow pattern: {lang}/finish.md (e.g., zh/finish.md)" }, "title": { "type": "string", "enum": [ "总结", "Resumen", "Résumé", "Zusammenfassung", "まとめ", "Резюме" ], "description": "Localized summary title, use Title Case" } } } } } } } } } }