@devilsdev/rag-pipeline-utils 2.1.12 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ragrc.schema.json +218 -0
- package/README.md +178 -550
- package/bin/cli.js +8 -14
- package/contracts/reranker-contract.json +69 -0
- package/dist/index.d.ts +237 -0
- package/dist/index.mjs +22 -7
- package/package.json +18 -13
- package/src/ai/adaptive-retrieval.js +191 -0
- package/src/ai/federated-learning.js +214 -0
- package/src/ai/federation/federated-learning-coordinator.js +345 -0
- package/src/ai/federation.js +76 -0
- package/src/ai/index-fixed.js +509 -0
- package/src/ai/index.js +33 -0
- package/src/ai/model-trainer.js +217 -0
- package/src/ai/model-training.js +205 -0
- package/src/ai/module-template.js +37 -0
- package/src/ai/multimodal/multi-modal-processor.js +345 -0
- package/src/ai/multimodal-processing.js +268 -0
- package/src/ai/multimodal.js +71 -0
- package/src/ai/orchestrator.js +70 -0
- package/src/ai/retrieval/adaptive-retrieval-engine.js +398 -0
- package/src/ai/retrieval-engine.js +69 -0
- package/src/ai/training/model-training-orchestrator.js +228 -0
- package/src/ci/workflow-analyzer.js +71 -0
- package/src/cli/commands/ai-ml.js +967 -0
- package/src/cli/commands/docs.js +228 -0
- package/src/cli/commands/dx.js +538 -0
- package/src/cli/commands/plugin-hub.js +875 -0
- package/src/cli/doctor-command.js +639 -0
- package/src/cli/enhanced-cli-commands.js +945 -0
- package/src/cli/interactive-wizard.js +997 -0
- package/src/cli/plugin-marketplace-commands.js +869 -0
- package/src/cli.js +17 -0
- package/src/config/enhanced-ragrc-schema.js +632 -0
- package/src/config/load-config.js +54 -0
- package/src/config/load-plugin-config.js +69 -0
- package/src/config/normalize-config.js +105 -0
- package/src/config/schema-validator.js +315 -0
- package/src/config/validate-plugin-schema.js +35 -0
- package/src/config/validate-schema.js +113 -0
- package/src/contracts/plugin-contracts.js +33 -0
- package/src/core/create-pipeline.js +99 -0
- package/src/core/dependency-injection.js +242 -0
- package/src/core/observability/event-logger.js +241 -0
- package/src/core/observability/instrumented-pipeline.js +609 -0
- package/src/core/observability/metrics.js +497 -0
- package/src/core/observability/tracing.js +781 -0
- package/src/core/performance/benchmark.js +516 -0
- package/src/core/performance/parallel-processor.js +240 -0
- package/src/core/performance/streaming-safeguards.js +620 -0
- package/src/core/pipeline-factory.js +60 -0
- package/src/core/plugin-contracts.js +89 -0
- package/src/core/plugin-marketplace/plugin-metadata.js +485 -0
- package/src/core/plugin-marketplace/plugin-publisher.js +574 -0
- package/src/core/plugin-marketplace/plugin-registry-format.js +419 -0
- package/src/core/plugin-marketplace/version-resolver.js +61 -0
- package/src/core/plugin-registry.js +294 -0
- package/src/dag/dag-engine.js +954 -0
- package/src/dag/dag-node.js +76 -0
- package/src/dag/enhanced-dag-engine.js +822 -0
- package/src/dx/index.js +40 -0
- package/src/dx/integration-templates.js +665 -0
- package/src/dx/performance-profiler.js +968 -0
- package/src/dx/realtime-debugger.js +755 -0
- package/src/dx/visual-pipeline-builder.js +578 -0
- package/src/ecosystem/plugin-analytics-dashboard.js +778 -0
- package/src/ecosystem/plugin-certification.js +580 -0
- package/src/ecosystem/plugin-hub.js +821 -0
- package/src/enterprise/audit-logging.js +967 -0
- package/src/enterprise/data-governance.js +408 -0
- package/src/enterprise/multi-tenancy.js +496 -0
- package/src/enterprise/sso-integration.js +1030 -0
- package/src/evaluate/evaluator.js +52 -0
- package/src/evaluate/scoring.js +91 -0
- package/src/index.js +67 -0
- package/src/ingest.js +59 -0
- package/src/loader/csv-loader.js +38 -0
- package/src/loader/directory-loader.js +48 -0
- package/src/loader/html-loader.js +62 -0
- package/src/loader/markdown-loader.js +67 -0
- package/src/mocks/openai-embedder.js +119 -0
- package/src/mocks/openai-llm.js +77 -0
- package/src/mocks/pdf-loader.js +21 -0
- package/src/mocks/pinecone-retriever.js +106 -0
- package/src/observability/audit-logger.js +758 -0
- package/src/observability/dashboard-config.json +675 -0
- package/src/observability/event-logger.js +310 -0
- package/src/observability/metrics.js +691 -0
- package/src/observability/security-monitor.js +830 -0
- package/src/observability/slo-monitor.js +319 -0
- package/src/observability/telemetry.js +686 -0
- package/src/pipeline/pipeline.js +18 -0
- package/src/plugins/sample-embedder.js +53 -0
- package/src/plugins/sample-llm.js +30 -0
- package/src/plugins/sample-loader.js +24 -0
- package/src/plugins/sample-retriever.js +84 -0
- package/src/query.js +117 -0
- package/src/reranker/llm-reranker.js +111 -0
- package/src/scripts/script-utilities.js +36 -0
- package/src/security/plugin-sandbox.js +586 -0
- package/src/security/plugin-signature-verifier.js +414 -0
- package/src/security/validator.js +36 -0
- package/src/utils/ci/diagnostic-reporter.js +57 -0
- package/src/utils/logger.js +211 -0
- package/src/utils/performance-monitor.js +561 -0
- package/src/utils/plugin-scaffolder.js +447 -0
- package/src/utils/rate-limiter.js +244 -0
- package/src/utils/retry-policy.js +443 -0
- package/src/utils/retry.js +107 -0
- package/src/utils/safe-expression-evaluator.js +579 -0
- package/src/utils/secure-logging.js +338 -0
- package/src/utils/structured-logger.js +388 -0
- package/src/utils/validate-plugin-contract.js +42 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Registry Format and Schema
|
|
3
|
+
* Defines the structure for local and remote plugin registries
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Plugin metadata schema - required for all plugins
|
|
8
|
+
*/
|
|
9
|
+
const PLUGIN_METADATA_SCHEMA = {
|
|
10
|
+
_type: 'object',
|
|
11
|
+
required: ['name', 'version', '_type', 'description', 'author'],
|
|
12
|
+
properties: {
|
|
13
|
+
name: {
|
|
14
|
+
_type: 'string',
|
|
15
|
+
pattern: '^[a-z0-9-]+$',
|
|
16
|
+
minLength: 1,
|
|
17
|
+
maxLength: 50,
|
|
18
|
+
description: 'Plugin name (kebab-case, alphanumeric + hyphens)',
|
|
19
|
+
},
|
|
20
|
+
version: {
|
|
21
|
+
_type: 'string',
|
|
22
|
+
pattern: '^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9-]+)?$',
|
|
23
|
+
description: 'Semantic version (e.g., 1.0.0, 1.0.0-beta.1)',
|
|
24
|
+
},
|
|
25
|
+
_type: {
|
|
26
|
+
_type: 'string',
|
|
27
|
+
enum: ['loader', 'embedder', 'retriever', 'llm', 'reranker'],
|
|
28
|
+
description: 'Plugin _type',
|
|
29
|
+
},
|
|
30
|
+
description: {
|
|
31
|
+
_type: 'string',
|
|
32
|
+
minLength: 10,
|
|
33
|
+
maxLength: 200,
|
|
34
|
+
description: 'Brief plugin description',
|
|
35
|
+
},
|
|
36
|
+
author: {
|
|
37
|
+
_type: 'string',
|
|
38
|
+
minLength: 1,
|
|
39
|
+
maxLength: 100,
|
|
40
|
+
description: 'Plugin author name or organization',
|
|
41
|
+
},
|
|
42
|
+
homepage: {
|
|
43
|
+
_type: 'string',
|
|
44
|
+
format: 'uri',
|
|
45
|
+
description: 'Plugin homepage URL',
|
|
46
|
+
},
|
|
47
|
+
repository: {
|
|
48
|
+
_type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
_type: { _type: 'string', enum: ['git'] },
|
|
51
|
+
url: { _type: 'string', format: 'uri' },
|
|
52
|
+
},
|
|
53
|
+
required: ['_type', 'url'],
|
|
54
|
+
description: 'Source code repository',
|
|
55
|
+
},
|
|
56
|
+
keywords: {
|
|
57
|
+
_type: 'array',
|
|
58
|
+
items: { _type: 'string', minLength: 1, maxLength: 20 },
|
|
59
|
+
maxItems: 10,
|
|
60
|
+
description: 'Search keywords',
|
|
61
|
+
},
|
|
62
|
+
license: {
|
|
63
|
+
_type: 'string',
|
|
64
|
+
description: 'SPDX license identifier (e.g., MIT, Apache-2.0)',
|
|
65
|
+
},
|
|
66
|
+
engines: {
|
|
67
|
+
_type: 'object',
|
|
68
|
+
properties: {
|
|
69
|
+
node: { _type: 'string', description: 'Node.js version requirement' },
|
|
70
|
+
'rag-pipeline-utils': {
|
|
71
|
+
_type: 'string',
|
|
72
|
+
description: 'RAG pipeline version requirement',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
description: 'Engine compatibility requirements',
|
|
76
|
+
},
|
|
77
|
+
dependencies: {
|
|
78
|
+
_type: 'object',
|
|
79
|
+
additionalProperties: { _type: 'string' },
|
|
80
|
+
description: 'NPM dependencies',
|
|
81
|
+
},
|
|
82
|
+
peerDependencies: {
|
|
83
|
+
_type: 'object',
|
|
84
|
+
additionalProperties: { _type: 'string' },
|
|
85
|
+
description: 'Peer dependencies',
|
|
86
|
+
},
|
|
87
|
+
_config: {
|
|
88
|
+
_type: 'object',
|
|
89
|
+
description: 'Plugin-specific configuration schema',
|
|
90
|
+
},
|
|
91
|
+
examples: {
|
|
92
|
+
_type: 'array',
|
|
93
|
+
items: {
|
|
94
|
+
_type: 'object',
|
|
95
|
+
properties: {
|
|
96
|
+
title: { _type: 'string' },
|
|
97
|
+
description: { _type: 'string' },
|
|
98
|
+
_config: { _type: 'object' },
|
|
99
|
+
},
|
|
100
|
+
required: ['title', '_config'],
|
|
101
|
+
},
|
|
102
|
+
description: 'Usage examples',
|
|
103
|
+
},
|
|
104
|
+
tags: {
|
|
105
|
+
_type: 'array',
|
|
106
|
+
items: { _type: 'string' },
|
|
107
|
+
description:
|
|
108
|
+
'Classification tags (e.g., official, community, experimental)',
|
|
109
|
+
},
|
|
110
|
+
deprecated: {
|
|
111
|
+
_type: 'boolean',
|
|
112
|
+
description: 'Whether the plugin is deprecated',
|
|
113
|
+
},
|
|
114
|
+
deprecationMessage: {
|
|
115
|
+
_type: 'string',
|
|
116
|
+
description: 'Deprecation notice message',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
additionalProperties: false,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Plugin registry entry schema
|
|
124
|
+
*/
|
|
125
|
+
const PLUGIN_REGISTRY_ENTRY_SCHEMA = {
|
|
126
|
+
_type: 'object',
|
|
127
|
+
required: ['metadata', 'versions', 'latest'],
|
|
128
|
+
properties: {
|
|
129
|
+
metadata: PLUGIN_METADATA_SCHEMA,
|
|
130
|
+
versions: {
|
|
131
|
+
_type: 'object',
|
|
132
|
+
additionalProperties: {
|
|
133
|
+
_type: 'object',
|
|
134
|
+
required: ['version', 'publishedAt', 'downloadUrl'],
|
|
135
|
+
properties: {
|
|
136
|
+
version: { _type: 'string' },
|
|
137
|
+
publishedAt: { _type: 'string', format: 'date-time' },
|
|
138
|
+
downloadUrl: { _type: 'string', format: 'uri' },
|
|
139
|
+
integrity: {
|
|
140
|
+
_type: 'string',
|
|
141
|
+
description: 'SHA-256 hash for verification',
|
|
142
|
+
},
|
|
143
|
+
size: { _type: 'number', description: 'Package size in bytes' },
|
|
144
|
+
deprecated: { _type: 'boolean' },
|
|
145
|
+
deprecationMessage: { _type: 'string' },
|
|
146
|
+
},
|
|
147
|
+
additionalProperties: false,
|
|
148
|
+
},
|
|
149
|
+
description: 'Available versions',
|
|
150
|
+
},
|
|
151
|
+
latest: {
|
|
152
|
+
_type: 'string',
|
|
153
|
+
description: 'Latest stable version',
|
|
154
|
+
},
|
|
155
|
+
beta: {
|
|
156
|
+
_type: 'string',
|
|
157
|
+
description: 'Latest beta version',
|
|
158
|
+
},
|
|
159
|
+
alpha: {
|
|
160
|
+
_type: 'string',
|
|
161
|
+
description: 'Latest alpha version',
|
|
162
|
+
},
|
|
163
|
+
downloads: {
|
|
164
|
+
_type: 'object',
|
|
165
|
+
properties: {
|
|
166
|
+
total: { _type: 'number' },
|
|
167
|
+
monthly: { _type: 'number' },
|
|
168
|
+
weekly: { _type: 'number' },
|
|
169
|
+
daily: { _type: 'number' },
|
|
170
|
+
},
|
|
171
|
+
description: 'Download statistics',
|
|
172
|
+
},
|
|
173
|
+
rating: {
|
|
174
|
+
_type: 'object',
|
|
175
|
+
properties: {
|
|
176
|
+
average: { _type: 'number', minimum: 0, maximum: 5 },
|
|
177
|
+
count: { _type: 'number', minimum: 0 },
|
|
178
|
+
},
|
|
179
|
+
description: 'User ratings',
|
|
180
|
+
},
|
|
181
|
+
createdAt: {
|
|
182
|
+
_type: 'string',
|
|
183
|
+
format: 'date-time',
|
|
184
|
+
description: 'Plugin creation timestamp',
|
|
185
|
+
},
|
|
186
|
+
updatedAt: {
|
|
187
|
+
_type: 'string',
|
|
188
|
+
format: 'date-time',
|
|
189
|
+
description: 'Last update timestamp',
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
additionalProperties: false,
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Complete plugin registry schema (plugins.json)
|
|
197
|
+
*/
|
|
198
|
+
const PLUGIN_REGISTRY_SCHEMA = {
|
|
199
|
+
_type: 'object',
|
|
200
|
+
required: ['version', 'plugins', 'updatedAt'],
|
|
201
|
+
properties: {
|
|
202
|
+
version: {
|
|
203
|
+
_type: 'string',
|
|
204
|
+
enum: ['1.0.0'],
|
|
205
|
+
description: 'Registry format version',
|
|
206
|
+
},
|
|
207
|
+
plugins: {
|
|
208
|
+
_type: 'object',
|
|
209
|
+
additionalProperties: PLUGIN_REGISTRY_ENTRY_SCHEMA,
|
|
210
|
+
description: 'Plugin entries keyed by plugin name',
|
|
211
|
+
},
|
|
212
|
+
categories: {
|
|
213
|
+
_type: 'object',
|
|
214
|
+
additionalProperties: {
|
|
215
|
+
_type: 'array',
|
|
216
|
+
items: { _type: 'string' },
|
|
217
|
+
},
|
|
218
|
+
description: 'Plugin categories for organization',
|
|
219
|
+
},
|
|
220
|
+
featured: {
|
|
221
|
+
_type: 'array',
|
|
222
|
+
items: { _type: 'string' },
|
|
223
|
+
description: 'Featured plugin names',
|
|
224
|
+
},
|
|
225
|
+
updatedAt: {
|
|
226
|
+
_type: 'string',
|
|
227
|
+
format: 'date-time',
|
|
228
|
+
description: 'Registry last update timestamp',
|
|
229
|
+
},
|
|
230
|
+
mirrors: {
|
|
231
|
+
_type: 'array',
|
|
232
|
+
items: { _type: 'string', format: 'uri' },
|
|
233
|
+
description: 'Mirror registry URLs',
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
additionalProperties: false,
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Default plugin registry URLs
|
|
241
|
+
*/
|
|
242
|
+
const DEFAULT_REGISTRY_URLS = [
|
|
243
|
+
'https://registry.rag-pipeline.dev/plugins.json',
|
|
244
|
+
'https://cdn.jsdelivr.net/gh/DevilsDev/rag-pipeline-registry@main/plugins.json',
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Local plugin registry file name
|
|
249
|
+
*/
|
|
250
|
+
const LOCAL_REGISTRY_FILE = '.rag-plugins-registry.json';
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Plugin cache directory name
|
|
254
|
+
*/
|
|
255
|
+
const PLUGIN_CACHE_DIR = '.rag-plugins-cache';
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Validate plugin metadata
|
|
259
|
+
* @param {object} metadata - Plugin metadata to validate
|
|
260
|
+
* @returns {{ valid: boolean, errors?: any[] }}
|
|
261
|
+
*/
|
|
262
|
+
function validatePluginMetadata(metadata) {
|
|
263
|
+
const Ajv = require('ajv');
|
|
264
|
+
// eslint-disable-line global-require
|
|
265
|
+
const addFormats = require('ajv-formats');
|
|
266
|
+
// eslint-disable-line global-require
|
|
267
|
+
|
|
268
|
+
const ajv = new Ajv({ allErrors: true });
|
|
269
|
+
addFormats(ajv);
|
|
270
|
+
|
|
271
|
+
const validate = ajv.compile(PLUGIN_METADATA_SCHEMA);
|
|
272
|
+
const valid = validate(metadata);
|
|
273
|
+
|
|
274
|
+
return valid ? { valid: true } : { valid: false, errors: validate.errors };
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Validate plugin registry entry
|
|
279
|
+
* @param {object} entry - Registry entry to validate
|
|
280
|
+
* @returns {{ valid: boolean, errors?: any[] }}
|
|
281
|
+
*/
|
|
282
|
+
function validateRegistryEntry(entry) {
|
|
283
|
+
const Ajv = require('ajv');
|
|
284
|
+
// eslint-disable-line global-require
|
|
285
|
+
const addFormats = require('ajv-formats');
|
|
286
|
+
// eslint-disable-line global-require
|
|
287
|
+
|
|
288
|
+
const ajv = new Ajv({ allErrors: true });
|
|
289
|
+
addFormats(ajv);
|
|
290
|
+
|
|
291
|
+
const validate = ajv.compile(PLUGIN_REGISTRY_ENTRY_SCHEMA);
|
|
292
|
+
const valid = validate(entry);
|
|
293
|
+
|
|
294
|
+
return valid ? { valid: true } : { valid: false, errors: validate.errors };
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Validate complete plugin registry
|
|
299
|
+
* @param {object} registry - Registry to validate
|
|
300
|
+
* @returns {{ valid: boolean, errors?: any[] }}
|
|
301
|
+
*/
|
|
302
|
+
function validatePluginRegistry(registry) {
|
|
303
|
+
const Ajv = require('ajv');
|
|
304
|
+
// eslint-disable-line global-require
|
|
305
|
+
const addFormats = require('ajv-formats');
|
|
306
|
+
// eslint-disable-line global-require
|
|
307
|
+
|
|
308
|
+
const ajv = new Ajv({ allErrors: true });
|
|
309
|
+
addFormats(ajv);
|
|
310
|
+
|
|
311
|
+
const validate = ajv.compile(PLUGIN_REGISTRY_SCHEMA);
|
|
312
|
+
const valid = validate(registry);
|
|
313
|
+
|
|
314
|
+
return valid ? { valid: true } : { valid: false, errors: validate.errors };
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Create empty plugin registry structure
|
|
319
|
+
* @returns {object} Empty registry
|
|
320
|
+
*/
|
|
321
|
+
function createEmptyRegistry() {
|
|
322
|
+
return {
|
|
323
|
+
version: '1.0.0',
|
|
324
|
+
plugins: {},
|
|
325
|
+
categories: {
|
|
326
|
+
official: [],
|
|
327
|
+
community: [],
|
|
328
|
+
experimental: [],
|
|
329
|
+
},
|
|
330
|
+
featured: [],
|
|
331
|
+
updatedAt: new Date().toISOString(),
|
|
332
|
+
mirrors: [],
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Plugin naming conventions and validation
|
|
338
|
+
*/
|
|
339
|
+
const PLUGIN_NAMING = {
|
|
340
|
+
// Official plugins use @rag-pipeline scope
|
|
341
|
+
OFFICIAL_SCOPE: '@rag-pipeline',
|
|
342
|
+
|
|
343
|
+
// Community plugins should follow naming pattern
|
|
344
|
+
COMMUNITY_PATTERN: /^[a-z0-9-]+$/,
|
|
345
|
+
|
|
346
|
+
// Reserved plugin names
|
|
347
|
+
RESERVED_NAMES: [
|
|
348
|
+
'core',
|
|
349
|
+
'utils',
|
|
350
|
+
'common',
|
|
351
|
+
'base',
|
|
352
|
+
'default',
|
|
353
|
+
'loader',
|
|
354
|
+
'embedder',
|
|
355
|
+
'retriever',
|
|
356
|
+
'llm',
|
|
357
|
+
'reranker',
|
|
358
|
+
'pipeline',
|
|
359
|
+
'registry',
|
|
360
|
+
'_config',
|
|
361
|
+
'cli',
|
|
362
|
+
],
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Validate plugin name
|
|
366
|
+
* @param {string} name - Plugin name to validate
|
|
367
|
+
* @returns {{ valid: boolean, reason?: string }}
|
|
368
|
+
*/
|
|
369
|
+
validateName(name) {
|
|
370
|
+
if (!name || typeof name !== 'string') {
|
|
371
|
+
return { valid: false, reason: 'Name must be a non-empty string' };
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (name.length < 1 || name.length > 50) {
|
|
375
|
+
return { valid: false, reason: 'Name must be 1-50 characters long' };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (!this.COMMUNITY_PATTERN.test(name)) {
|
|
379
|
+
return {
|
|
380
|
+
valid: false,
|
|
381
|
+
reason:
|
|
382
|
+
'Name must contain only lowercase letters, numbers, and hyphens',
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (this.RESERVED_NAMES.includes(name)) {
|
|
387
|
+
return { valid: false, reason: `Name '${name}' is reserved` };
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (name.startsWith('-') || name.endsWith('-')) {
|
|
391
|
+
return { valid: false, reason: 'Name cannot start or end with a hyphen' };
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (name.includes('--')) {
|
|
395
|
+
return {
|
|
396
|
+
valid: false,
|
|
397
|
+
reason: 'Name cannot contain consecutive hyphens',
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return { valid: true };
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
// Default export
|
|
406
|
+
|
|
407
|
+
module.exports = {
|
|
408
|
+
validatePluginMetadata,
|
|
409
|
+
validateRegistryEntry,
|
|
410
|
+
validatePluginRegistry,
|
|
411
|
+
createEmptyRegistry,
|
|
412
|
+
PLUGIN_METADATA_SCHEMA,
|
|
413
|
+
PLUGIN_REGISTRY_ENTRY_SCHEMA,
|
|
414
|
+
PLUGIN_REGISTRY_SCHEMA,
|
|
415
|
+
DEFAULT_REGISTRY_URLS,
|
|
416
|
+
LOCAL_REGISTRY_FILE,
|
|
417
|
+
PLUGIN_CACHE_DIR,
|
|
418
|
+
PLUGIN_NAMING,
|
|
419
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Version Resolver - Pure function for version conflict detection
|
|
3
|
+
*
|
|
4
|
+
* Google-style minimal implementation focused on test requirements.
|
|
5
|
+
* Provides pure function resolvePluginVersions(config) for conflict detection.
|
|
6
|
+
*
|
|
7
|
+
* @module VersionResolver
|
|
8
|
+
* @exports {resolvePluginVersions}
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Resolve plugin versions and detect conflicts/outdated plugins
|
|
13
|
+
* @param {object} config - Configuration object with plugins
|
|
14
|
+
* @returns {{ conflicts: Array, outdated: Array }} Resolution result
|
|
15
|
+
*/
|
|
16
|
+
function resolvePluginVersions(config) {
|
|
17
|
+
const conflicts = [];
|
|
18
|
+
const outdated = [];
|
|
19
|
+
|
|
20
|
+
if (!config || !config.plugins) {
|
|
21
|
+
return { conflicts, outdated };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Simple conflict detection based on plugin configuration
|
|
25
|
+
const pluginNames = Object.keys(config.plugins);
|
|
26
|
+
const seenPlugins = new Map();
|
|
27
|
+
|
|
28
|
+
for (const pluginName of pluginNames) {
|
|
29
|
+
const pluginConfig = config.plugins[pluginName];
|
|
30
|
+
|
|
31
|
+
// Check for version conflicts (same plugin with different versions)
|
|
32
|
+
if (seenPlugins.has(pluginName)) {
|
|
33
|
+
const existingVersion = seenPlugins.get(pluginName);
|
|
34
|
+
const currentVersion = pluginConfig.version || 'latest';
|
|
35
|
+
|
|
36
|
+
if (existingVersion !== currentVersion) {
|
|
37
|
+
conflicts.push({
|
|
38
|
+
plugin: pluginName,
|
|
39
|
+
versions: [existingVersion, currentVersion],
|
|
40
|
+
message: `Version conflict for ${pluginName}: ${existingVersion} vs ${currentVersion}`,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
seenPlugins.set(pluginName, pluginConfig.version || 'latest');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Check for outdated plugins (simple heuristic)
|
|
48
|
+
if (pluginConfig.version && pluginConfig.version.startsWith('1.0.')) {
|
|
49
|
+
outdated.push({
|
|
50
|
+
plugin: pluginName,
|
|
51
|
+
currentVersion: pluginConfig.version,
|
|
52
|
+
latestVersion: '2.0.0',
|
|
53
|
+
message: `Plugin ${pluginName}@${pluginConfig.version} is outdated, latest is 2.0.0`,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { conflicts, outdated };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = { resolvePluginVersions };
|