b3a7f98e5a
CI / E2E Cloudflare (4/8) (push) Failing after 0s
CI / E2E Cloudflare (8/8) (push) Failing after 1s
CI / Lint (push) Failing after 1s
Auto Extract / Extract (push) Failing after 4s
CI / Version Check (push) Failing after 9s
CI / Integration Tests (push) Failing after 1s
CI / E2E tests (1/8) (push) Failing after 1s
CI / E2E tests (2/8) (push) Failing after 2s
CI / E2E tests (3/8) (push) Failing after 2s
CI / Browser Tests (push) Failing after 1s
CI / E2E tests (5/8) (push) Failing after 1s
CI / E2E Cloudflare (2/8) (push) Failing after 2s
CI / Typecheck (push) Failing after 1s
CI / Changeset Validation (push) Failing after 2s
CI / E2E Cloudflare (5/8) (push) Failing after 1s
CI / E2E Cloudflare (6/8) (push) Failing after 1s
CI / E2E Cloudflare (7/8) (push) Failing after 1s
CodeQL / Analyze (javascript-typescript) (push) Failing after 1s
Format / Format (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 4s
CI / E2E tests (4/8) (push) Failing after 1s
CI / E2E tests (6/8) (push) Failing after 1s
CI / E2E tests (7/8) (push) Failing after 2s
CI / E2E tests (8/8) (push) Failing after 1s
CI / E2E Cloudflare (1/8) (push) Failing after 1s
CI / E2E Cloudflare (3/8) (push) Failing after 2s
Preview Releases / Publish Preview (push) Failing after 0s
zizmor / Run zizmor (push) Failing after 1s
Release / Release (push) Failing after 2s
CI / Smoke Tests (push) Failing after 5m36s
CI / Tests (push) Failing after 6m36s
Release / Sync Templates (push) Has been skipped
CI / E2E Tests (push) Has been cancelled
655 lines
16 KiB
JSON
655 lines
16 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://emdashcms.com/schemas/emdash-plugin.schema.json",
|
|
"title": "EmDash plugin manifest",
|
|
"description": "Hand-authored manifest for publishing a plugin to the EmDash plugin registry. Lives next to the plugin's `package.json` as `emdash-plugin.jsonc`.",
|
|
"type": "object",
|
|
"properties": {
|
|
"$schema": {
|
|
"$ref": "#/$defs/__schema0"
|
|
},
|
|
"slug": {
|
|
"$ref": "#/$defs/__schema1"
|
|
},
|
|
"version": {
|
|
"$ref": "#/$defs/__schema2"
|
|
},
|
|
"license": {
|
|
"$ref": "#/$defs/__schema3"
|
|
},
|
|
"publisher": {
|
|
"$ref": "#/$defs/__schema4"
|
|
},
|
|
"capabilities": {
|
|
"$ref": "#/$defs/__schema5"
|
|
},
|
|
"allowedHosts": {
|
|
"$ref": "#/$defs/__schema7"
|
|
},
|
|
"storage": {
|
|
"$ref": "#/$defs/__schema9"
|
|
},
|
|
"admin": {
|
|
"$ref": "#/$defs/__schema16"
|
|
},
|
|
"author": {
|
|
"$ref": "#/$defs/__schema27"
|
|
},
|
|
"authors": {
|
|
"$ref": "#/$defs/__schema32"
|
|
},
|
|
"security": {
|
|
"$ref": "#/$defs/__schema33"
|
|
},
|
|
"securityContacts": {
|
|
"$ref": "#/$defs/__schema37"
|
|
},
|
|
"name": {
|
|
"$ref": "#/$defs/__schema38"
|
|
},
|
|
"description": {
|
|
"$ref": "#/$defs/__schema39"
|
|
},
|
|
"keywords": {
|
|
"$ref": "#/$defs/__schema40"
|
|
},
|
|
"sections": {
|
|
"$ref": "#/$defs/__schema42"
|
|
},
|
|
"repo": {
|
|
"$ref": "#/$defs/__schema52"
|
|
},
|
|
"release": {
|
|
"$ref": "#/$defs/__schema53"
|
|
}
|
|
},
|
|
"required": [
|
|
"slug",
|
|
"license",
|
|
"publisher",
|
|
"capabilities",
|
|
"allowedHosts",
|
|
"storage"
|
|
],
|
|
"additionalProperties": false,
|
|
"$defs": {
|
|
"__schema0": {
|
|
"type": "string",
|
|
"description": "Path or URL to the JSON Schema describing this file. Editors use this for completion and validation."
|
|
},
|
|
"__schema1": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 64,
|
|
"pattern": "^[a-z][a-z0-9_-]*$",
|
|
"title": "Slug",
|
|
"description": "URL-safe plugin identifier within the publisher's namespace. ASCII letter then letters/digits/hyphens/underscores, max 64 characters. Combined with the publisher DID, this is the registry's primary key.",
|
|
"examples": [
|
|
"gallery",
|
|
"image-resizer",
|
|
"my-plugin"
|
|
]
|
|
},
|
|
"__schema2": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 64,
|
|
"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-]*))*))?$",
|
|
"title": "Version",
|
|
"description": "Plugin version. Semver 2.0 subset; build-metadata `+...` is disallowed (the atproto record-key alphabet has no `+`). Bumped on every release.",
|
|
"examples": [
|
|
"0.1.0",
|
|
"1.2.3",
|
|
"1.0.0-rc.1"
|
|
]
|
|
},
|
|
"__schema3": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 256,
|
|
"title": "License",
|
|
"description": "SPDX license expression (e.g. \"MIT\", \"Apache-2.0\", \"MIT OR Apache-2.0\"). Required on first publish; ignored on subsequent publishes (the existing profile wins).",
|
|
"examples": [
|
|
"MIT",
|
|
"Apache-2.0",
|
|
"MIT OR Apache-2.0"
|
|
]
|
|
},
|
|
"__schema4": {
|
|
"type": "string",
|
|
"title": "Publisher",
|
|
"description": "Atproto DID or handle of the publishing identity. Pinned on first publish to prevent accidental publishes from a different account. DIDs are recommended (durable); handles work but are mutable.",
|
|
"examples": [
|
|
"did:plc:abc123def456",
|
|
"example.com"
|
|
]
|
|
},
|
|
"__schema5": {
|
|
"default": [],
|
|
"maxItems": 32,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema6"
|
|
},
|
|
"title": "Capabilities",
|
|
"description": "Trust contract: what runtime APIs the plugin is allowed to use. Changing this between releases requires a version bump because installed users have consented to the old contract."
|
|
},
|
|
"__schema6": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"__schema7": {
|
|
"default": [],
|
|
"maxItems": 64,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema8"
|
|
},
|
|
"title": "Allowed hosts",
|
|
"description": "Allow-list of outbound host patterns when `network:request` is declared. Subdomain wildcards use a leading `*.`. Required (non-empty) when `network:request` is declared without `network:request:unrestricted`.",
|
|
"examples": [
|
|
[
|
|
"api.example.com",
|
|
"*.cdn.example.com"
|
|
]
|
|
]
|
|
},
|
|
"__schema8": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 256
|
|
},
|
|
"__schema9": {
|
|
"default": {},
|
|
"type": "object",
|
|
"propertyNames": {
|
|
"$ref": "#/$defs/__schema10"
|
|
},
|
|
"additionalProperties": {
|
|
"$ref": "#/$defs/__schema11"
|
|
},
|
|
"title": "Storage",
|
|
"description": "Storage collections the plugin uses. Each collection is namespaced to this plugin at runtime."
|
|
},
|
|
"__schema10": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"pattern": "^[a-z][a-z0-9_]*$"
|
|
},
|
|
"__schema11": {
|
|
"type": "object",
|
|
"properties": {
|
|
"indexes": {
|
|
"$ref": "#/$defs/__schema12"
|
|
},
|
|
"uniqueIndexes": {
|
|
"$ref": "#/$defs/__schema14"
|
|
}
|
|
},
|
|
"required": [
|
|
"indexes"
|
|
],
|
|
"additionalProperties": false,
|
|
"title": "Storage collection",
|
|
"description": "Index configuration for a single storage collection. Indexes are either single field names or composite (array of field names)."
|
|
},
|
|
"__schema12": {
|
|
"type": "array",
|
|
"items": {
|
|
"anyOf": [
|
|
{
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
{
|
|
"minItems": 1,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema13"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"__schema13": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"__schema14": {
|
|
"type": "array",
|
|
"items": {
|
|
"anyOf": [
|
|
{
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
{
|
|
"minItems": 1,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema15"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"__schema15": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"__schema16": {
|
|
"type": "object",
|
|
"properties": {
|
|
"pages": {
|
|
"$ref": "#/$defs/__schema17"
|
|
},
|
|
"widgets": {
|
|
"$ref": "#/$defs/__schema22"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"title": "Admin surface",
|
|
"description": "Pages and widgets the plugin exposes in the admin UI. The plugin's `admin` route handler renders Block Kit content for each path / widget id at runtime."
|
|
},
|
|
"__schema17": {
|
|
"maxItems": 32,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema18"
|
|
}
|
|
},
|
|
"__schema18": {
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {
|
|
"$ref": "#/$defs/__schema19"
|
|
},
|
|
"label": {
|
|
"$ref": "#/$defs/__schema20"
|
|
},
|
|
"icon": {
|
|
"$ref": "#/$defs/__schema21"
|
|
}
|
|
},
|
|
"required": [
|
|
"path",
|
|
"label"
|
|
],
|
|
"additionalProperties": false,
|
|
"title": "Admin page",
|
|
"description": "A single admin page declaration. The plugin's `admin` route handler is responsible for rendering Block Kit content for this path."
|
|
},
|
|
"__schema19": {
|
|
"type": "string",
|
|
"minLength": 2,
|
|
"maxLength": 128,
|
|
"pattern": "^\\/[a-z0-9][a-z0-9/_-]*$"
|
|
},
|
|
"__schema20": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 128
|
|
},
|
|
"__schema21": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 64
|
|
},
|
|
"__schema22": {
|
|
"maxItems": 32,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema23"
|
|
}
|
|
},
|
|
"__schema23": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"$ref": "#/$defs/__schema24"
|
|
},
|
|
"title": {
|
|
"$ref": "#/$defs/__schema25"
|
|
},
|
|
"size": {
|
|
"$ref": "#/$defs/__schema26"
|
|
}
|
|
},
|
|
"required": [
|
|
"id"
|
|
],
|
|
"additionalProperties": false,
|
|
"title": "Admin widget",
|
|
"description": "A single dashboard widget declaration."
|
|
},
|
|
"__schema24": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 64,
|
|
"pattern": "^[a-z][a-z0-9_-]*$"
|
|
},
|
|
"__schema25": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 128
|
|
},
|
|
"__schema26": {
|
|
"type": "string",
|
|
"enum": [
|
|
"full",
|
|
"half",
|
|
"third"
|
|
]
|
|
},
|
|
"__schema27": {
|
|
"$ref": "#/$defs/__schema28"
|
|
},
|
|
"__schema28": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"$ref": "#/$defs/__schema29"
|
|
},
|
|
"url": {
|
|
"$ref": "#/$defs/__schema30"
|
|
},
|
|
"email": {
|
|
"$ref": "#/$defs/__schema31"
|
|
}
|
|
},
|
|
"required": [
|
|
"name"
|
|
],
|
|
"additionalProperties": false,
|
|
"title": "Author",
|
|
"description": "A single author entry. Mirrors the lexicon's author shape."
|
|
},
|
|
"__schema29": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 256,
|
|
"description": "Display name."
|
|
},
|
|
"__schema30": {
|
|
"type": "string",
|
|
"maxLength": 1024,
|
|
"format": "uri",
|
|
"description": "Author's homepage or profile URL. Either this or `email` is recommended."
|
|
},
|
|
"__schema31": {
|
|
"type": "string",
|
|
"maxLength": 256,
|
|
"format": "email",
|
|
"pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
|
|
"description": "Author's contact email. Either this or `url` is recommended."
|
|
},
|
|
"__schema32": {
|
|
"minItems": 1,
|
|
"maxItems": 32,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema28"
|
|
},
|
|
"title": "Authors (multiple)",
|
|
"description": "Multi-author form. Mutually exclusive with `author`. Use the singular `author` if there is only one."
|
|
},
|
|
"__schema33": {
|
|
"$ref": "#/$defs/__schema34"
|
|
},
|
|
"__schema34": {
|
|
"type": "object",
|
|
"properties": {
|
|
"url": {
|
|
"$ref": "#/$defs/__schema35"
|
|
},
|
|
"email": {
|
|
"$ref": "#/$defs/__schema36"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"title": "Security contact",
|
|
"description": "A single security contact. At least one of `url` or `email` must be present."
|
|
},
|
|
"__schema35": {
|
|
"type": "string",
|
|
"maxLength": 1024,
|
|
"format": "uri",
|
|
"description": "Security disclosure URL (e.g. a security.txt or vulnerability-reporting page). Either this or `email` is required."
|
|
},
|
|
"__schema36": {
|
|
"type": "string",
|
|
"maxLength": 256,
|
|
"format": "email",
|
|
"pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
|
|
"description": "Security contact email. Either this or `url` is required."
|
|
},
|
|
"__schema37": {
|
|
"minItems": 1,
|
|
"maxItems": 8,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema34"
|
|
},
|
|
"title": "Security contacts (multiple)",
|
|
"description": "Multi-contact form. Mutually exclusive with `security`. Use the singular `security` if there is only one."
|
|
},
|
|
"__schema38": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 1024,
|
|
"title": "Display name",
|
|
"description": "Human-readable name shown in directory listings. Defaults to the plugin's `id` when omitted."
|
|
},
|
|
"__schema39": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 1024,
|
|
"title": "Description",
|
|
"description": "Short description (<= 140 graphemes by FAIR convention). Aggregators may truncate longer values when displaying in compact lists."
|
|
},
|
|
"__schema40": {
|
|
"maxItems": 5,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema41"
|
|
},
|
|
"title": "Keywords",
|
|
"description": "Search keywords (<= 5 entries, FAIR convention)."
|
|
},
|
|
"__schema41": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 128
|
|
},
|
|
"__schema42": {
|
|
"type": "object",
|
|
"properties": {
|
|
"description": {
|
|
"$ref": "#/$defs/__schema43"
|
|
},
|
|
"installation": {
|
|
"$ref": "#/$defs/__schema48"
|
|
},
|
|
"faq": {
|
|
"$ref": "#/$defs/__schema49"
|
|
},
|
|
"changelog": {
|
|
"$ref": "#/$defs/__schema50"
|
|
},
|
|
"security": {
|
|
"$ref": "#/$defs/__schema51"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"title": "Profile sections",
|
|
"description": "Long-form package documentation (description / installation / faq / changelog / security). Each value is CommonMark Markdown (inline or a `{ file }` ref) capped at 20000 bytes / 2000 graphemes. Rendered on the package's registry page."
|
|
},
|
|
"__schema43": {
|
|
"$ref": "#/$defs/__schema44"
|
|
},
|
|
"__schema44": {
|
|
"anyOf": [
|
|
{
|
|
"$ref": "#/$defs/__schema45"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/__schema46"
|
|
}
|
|
],
|
|
"title": "Section value",
|
|
"description": "Either inline CommonMark Markdown or a `{ file }` reference to a sibling Markdown file."
|
|
},
|
|
"__schema45": {
|
|
"type": "string",
|
|
"description": "Inline CommonMark Markdown for this section. Capped at 20000 bytes / 2000 graphemes."
|
|
},
|
|
"__schema46": {
|
|
"type": "object",
|
|
"properties": {
|
|
"file": {
|
|
"$ref": "#/$defs/__schema47"
|
|
}
|
|
},
|
|
"required": [
|
|
"file"
|
|
],
|
|
"additionalProperties": false,
|
|
"title": "Section file reference",
|
|
"description": "Loads the section's Markdown from a sibling file instead of inlining it in the manifest."
|
|
},
|
|
"__schema47": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 1024,
|
|
"description": "Path to a CommonMark Markdown file, relative to the manifest. Its content is read inline into the section at publish time."
|
|
},
|
|
"__schema48": {
|
|
"$ref": "#/$defs/__schema44"
|
|
},
|
|
"__schema49": {
|
|
"$ref": "#/$defs/__schema44"
|
|
},
|
|
"__schema50": {
|
|
"$ref": "#/$defs/__schema44"
|
|
},
|
|
"__schema51": {
|
|
"$ref": "#/$defs/__schema44"
|
|
},
|
|
"__schema52": {
|
|
"type": "string",
|
|
"maxLength": 1024,
|
|
"format": "uri",
|
|
"pattern": "^https:\\/\\/",
|
|
"title": "Source repository",
|
|
"description": "HTTPS URL of the plugin's source repository. Surfaced in registry listings.",
|
|
"examples": [
|
|
"https://github.com/emdash-cms/plugin-gallery"
|
|
]
|
|
},
|
|
"__schema53": {
|
|
"type": "object",
|
|
"properties": {
|
|
"requires": {
|
|
"$ref": "#/$defs/__schema54"
|
|
},
|
|
"artifacts": {
|
|
"$ref": "#/$defs/__schema57"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"title": "Release",
|
|
"description": "Per-release fields: environment constraints (`requires`) and media artifacts (icon / screenshot / banner)."
|
|
},
|
|
"__schema54": {
|
|
"type": "object",
|
|
"propertyNames": {
|
|
"$ref": "#/$defs/__schema55"
|
|
},
|
|
"additionalProperties": {
|
|
"$ref": "#/$defs/__schema56"
|
|
},
|
|
"title": "Environment requirements",
|
|
"description": "Host environment constraints for this release, keyed by `env:*` (e.g. \"env:astro\", \"env:emdash\") with semver-range values. EmDash refuses to install a release whose constraints the host does not satisfy.",
|
|
"examples": [
|
|
{
|
|
"env:emdash": ">=1.0.0",
|
|
"env:astro": ">=4.16"
|
|
}
|
|
]
|
|
},
|
|
"__schema55": {
|
|
"type": "string"
|
|
},
|
|
"__schema56": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"__schema57": {
|
|
"type": "object",
|
|
"properties": {
|
|
"icon": {
|
|
"$ref": "#/$defs/__schema58"
|
|
},
|
|
"banner": {
|
|
"$ref": "#/$defs/__schema62"
|
|
},
|
|
"screenshots": {
|
|
"$ref": "#/$defs/__schema63"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"title": "Artifacts",
|
|
"description": "Release media artifacts. `icon` and `banner` are single images; `screenshots` is a gallery array."
|
|
},
|
|
"__schema58": {
|
|
"$ref": "#/$defs/__schema59"
|
|
},
|
|
"__schema59": {
|
|
"type": "object",
|
|
"properties": {
|
|
"file": {
|
|
"$ref": "#/$defs/__schema60"
|
|
},
|
|
"lang": {
|
|
"$ref": "#/$defs/__schema61"
|
|
}
|
|
},
|
|
"required": [
|
|
"file"
|
|
],
|
|
"additionalProperties": false,
|
|
"title": "Artifact file reference",
|
|
"description": "A media file (PNG / JPEG / WebP / GIF / AVIF) bundled into a release as an icon, screenshot, or banner."
|
|
},
|
|
"__schema60": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"maxLength": 1024,
|
|
"description": "Path to the image file, relative to the manifest. Resolved, hashed, measured, and uploaded at publish time."
|
|
},
|
|
"__schema61": {
|
|
"type": "string",
|
|
"minLength": 2,
|
|
"maxLength": 64,
|
|
"description": "BCP 47 language tag for a localised artifact (e.g. \"en\", \"pt-BR\").",
|
|
"examples": [
|
|
"en",
|
|
"pt-BR"
|
|
]
|
|
},
|
|
"__schema62": {
|
|
"$ref": "#/$defs/__schema59"
|
|
},
|
|
"__schema63": {
|
|
"minItems": 1,
|
|
"maxItems": 8,
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/__schema59"
|
|
},
|
|
"title": "Screenshots",
|
|
"description": "Screenshot gallery for the plugin's detail page (<= 8 entries)."
|
|
}
|
|
}
|
|
}
|