Skip to content

Commit c40bdee

Browse files
committed
chore(plugins): bind ownership to plugin id
1 parent f9b4432 commit c40bdee

3 files changed

Lines changed: 63 additions & 3 deletions

File tree

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import { pluginOwnership } from './ownership.mjs';
22

3-
export const pluginMeta = {
3+
const baseMeta = {
44
id: 'prompt-templates',
55
title: 'Prompt Templates',
66
description: 'Standardized, template-driven prompts with variables and copy/export helpers.',
77
statusLabel: 'standard',
8-
tone: 'configured',
9-
...pluginOwnership
8+
tone: 'configured'
9+
};
10+
11+
if (pluginOwnership && pluginOwnership.pluginId && pluginOwnership.pluginId !== baseMeta.id) {
12+
throw new Error(`ownership.mjs pluginId mismatch: expected ${baseMeta.id}, got ${pluginOwnership.pluginId}`);
13+
}
14+
15+
export const pluginMeta = {
16+
...baseMeta,
17+
createdBy: pluginOwnership && typeof pluginOwnership.createdBy === 'string' ? pluginOwnership.createdBy : '',
18+
maintainers: pluginOwnership && Array.isArray(pluginOwnership.maintainers) ? pluginOwnership.maintainers : []
1019
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const pluginOwnership = {
2+
pluginId: 'prompt-templates',
23
createdBy: 'ymkiux',
34
maintainers: ['ymkiux']
45
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import assert from 'assert';
2+
import fs from 'fs';
3+
import path from 'path';
4+
import { fileURLToPath, pathToFileURL } from 'url';
5+
6+
const __filename = fileURLToPath(import.meta.url);
7+
const __dirname = path.dirname(__filename);
8+
const root = path.join(__dirname, '..', '..');
9+
const pluginsDir = path.join(root, 'plugins');
10+
11+
function listPluginFolders() {
12+
const entries = fs.readdirSync(pluginsDir, { withFileTypes: true });
13+
return entries
14+
.filter((entry) => entry.isDirectory())
15+
.map((entry) => entry.name)
16+
.filter((name) => !name.startsWith('.'))
17+
.sort((a, b) => a.localeCompare(b, 'en-US'));
18+
}
19+
20+
function isPluginFolder(name) {
21+
const manifestPath = path.join(pluginsDir, name, 'manifest.mjs');
22+
const overviewPath = path.join(pluginsDir, name, 'overview.mjs');
23+
return fs.existsSync(manifestPath) && fs.existsSync(overviewPath);
24+
}
25+
26+
test('each builtin plugin has ownership file matched to plugin id', async () => {
27+
const folders = listPluginFolders().filter((name) => isPluginFolder(name));
28+
assert.ok(folders.length > 0, 'expected at least one builtin plugin folder');
29+
30+
for (const folder of folders) {
31+
const ownershipPath = path.join(pluginsDir, folder, 'ownership.mjs');
32+
assert.ok(fs.existsSync(ownershipPath), `missing ownership.mjs for plugin: ${folder}`);
33+
34+
const manifestUrl = pathToFileURL(path.join(pluginsDir, folder, 'manifest.mjs')).href;
35+
const ownershipUrl = pathToFileURL(ownershipPath).href;
36+
const { pluginMeta } = await import(`${manifestUrl}?t=${Date.now()}`);
37+
const { pluginOwnership } = await import(`${ownershipUrl}?t=${Date.now()}`);
38+
39+
assert.ok(pluginMeta && typeof pluginMeta === 'object', `invalid pluginMeta for plugin: ${folder}`);
40+
assert.strictEqual(pluginMeta.id, folder, `pluginMeta.id must match folder name: ${folder}`);
41+
assert.ok(pluginOwnership && typeof pluginOwnership === 'object', `invalid pluginOwnership for plugin: ${folder}`);
42+
assert.strictEqual(pluginOwnership.pluginId, folder, `ownership pluginId must match folder name: ${folder}`);
43+
assert.ok(typeof pluginOwnership.createdBy === 'string' && pluginOwnership.createdBy.trim(), `ownership createdBy must be a github handle for plugin: ${folder}`);
44+
assert.ok(Array.isArray(pluginOwnership.maintainers) && pluginOwnership.maintainers.length > 0, `ownership maintainers must be non-empty for plugin: ${folder}`);
45+
for (const maintainer of pluginOwnership.maintainers) {
46+
assert.ok(typeof maintainer === 'string' && maintainer.trim(), `ownership maintainer must be a github handle for plugin: ${folder}`);
47+
}
48+
}
49+
});
50+

0 commit comments

Comments
 (0)