mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 15:15:24 +00:00
feat: add category and icon fields to plugin manifest schema
This commit is contained in:
1 parent
5a76d30637
commit
7f1beddccc
8 files changed
+72
No files matched your search
@@ -7,6 +7,7 @@
|
|||||||
"name": "Jane Doe"
|
"name": "Jane Doe"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"category": "Productivity",
|
||||||
"engine": {
|
"engine": {
|
||||||
"termix": ">=2.9.0",
|
"termix": ">=2.9.0",
|
||||||
"api": "1"
|
"api": "1"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"name": "Jane Doe"
|
"name": "Jane Doe"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"category": "Productivity",
|
||||||
"engine": {
|
"engine": {
|
||||||
"termix": ">=2.9.0",
|
"termix": ">=2.9.0",
|
||||||
"api": "1"
|
"api": "1"
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"id": "sample-plugin",
|
||||||
|
"name": "Sample Plugin",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Has a category that is not in the known category list.",
|
||||||
|
"author": {
|
||||||
|
"name": "Jane Doe"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"category": "Miscellaneous",
|
||||||
|
"engine": {
|
||||||
|
"termix": ">=2.9.0",
|
||||||
|
"api": "1"
|
||||||
|
},
|
||||||
|
"capabilities": {
|
||||||
|
"backend": true,
|
||||||
|
"frontend": true,
|
||||||
|
"electron": false,
|
||||||
|
"platforms": ["linux"]
|
||||||
|
},
|
||||||
|
"permissions": [],
|
||||||
|
"sidecars": []
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
"name": "Jane Doe"
|
"name": "Jane Doe"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"category": "Productivity",
|
||||||
"engine": {
|
"engine": {
|
||||||
"termix": ">=2.9.0",
|
"termix": ">=2.9.0",
|
||||||
"api": "1"
|
"api": "1"
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": "https://github.com/example/sample-plugin",
|
"repository": "https://github.com/example/sample-plugin",
|
||||||
|
"category": "Productivity",
|
||||||
|
"icon": "Box",
|
||||||
"engine": {
|
"engine": {
|
||||||
"termix": ">=2.9.0",
|
"termix": ">=2.9.0",
|
||||||
"api": "1"
|
"api": "1"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"author",
|
"author",
|
||||||
"license",
|
"license",
|
||||||
"engine",
|
"engine",
|
||||||
|
"category",
|
||||||
"capabilities",
|
"capabilities",
|
||||||
"permissions",
|
"permissions",
|
||||||
"sidecars"
|
"sidecars"
|
||||||
@@ -52,6 +53,24 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "uri"
|
"format": "uri"
|
||||||
},
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Terminal",
|
||||||
|
"Files & Transfer",
|
||||||
|
"Infrastructure",
|
||||||
|
"Monitoring",
|
||||||
|
"Networking",
|
||||||
|
"Access & Security",
|
||||||
|
"Productivity"
|
||||||
|
],
|
||||||
|
"description": "Store category used for browsing/filtering. Must match one of the categories the store UI filters by."
|
||||||
|
},
|
||||||
|
"icon": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"description": "Either a Lucide icon name (same convention as contributes.tabs[].icon) or a relative path to an icon.svg shipped in the plugin package root. If both a Lucide name and an icon.svg are present, the registry-index build should prefer icon.svg."
|
||||||
|
},
|
||||||
"engine": {
|
"engine": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ function knownPermissions(schema) {
|
|||||||
return schema.properties.permissions.items.enum;
|
return schema.properties.permissions.items.enum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function knownCategories(schema) {
|
||||||
|
return schema.properties.category.enum;
|
||||||
|
}
|
||||||
|
|
||||||
function validateManifest(manifest, schema) {
|
function validateManifest(manifest, schema) {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
||||||
@@ -56,6 +60,21 @@ function validateManifest(manifest, schema) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof manifest.category === "string") {
|
||||||
|
const categories = knownCategories(schema);
|
||||||
|
if (!categories.includes(manifest.category)) {
|
||||||
|
errors.push(
|
||||||
|
`Field "category" must be one of: ${categories.join(", ")}, got: "${manifest.category}"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if ("category" in manifest) {
|
||||||
|
errors.push('Field "category" must be a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("icon" in manifest && typeof manifest.icon !== "string") {
|
||||||
|
errors.push('Field "icon" must be a string');
|
||||||
|
}
|
||||||
|
|
||||||
if (manifest.engine && typeof manifest.engine === "object") {
|
if (manifest.engine && typeof manifest.engine === "object") {
|
||||||
if (!manifest.engine.termix) {
|
if (!manifest.engine.termix) {
|
||||||
errors.push('Field "engine.termix" is required');
|
errors.push('Field "engine.termix" is required');
|
||||||
|
|||||||
@@ -43,4 +43,10 @@ describe("validate-plugin-manifest.cjs", () => {
|
|||||||
expect(status).not.toBe(0);
|
expect(status).not.toBe(0);
|
||||||
expect(output).toContain('Unknown permission: "credentials.read"');
|
expect(output).toContain('Unknown permission: "credentials.read"');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("rejects a manifest with an unknown category", () => {
|
||||||
|
const { status, output } = runValidator("invalid-unknown-category.json");
|
||||||
|
expect(status).not.toBe(0);
|
||||||
|
expect(output).toMatch(/Field "category" must be one of/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user