@open-skills-hub/api 1.0.0

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.
Files changed (112) hide show
  1. package/dist/controllers/audit.d.ts +33 -0
  2. package/dist/controllers/audit.d.ts.map +1 -0
  3. package/dist/controllers/audit.js +122 -0
  4. package/dist/controllers/audit.js.map +1 -0
  5. package/dist/controllers/cache.d.ts +42 -0
  6. package/dist/controllers/cache.d.ts.map +1 -0
  7. package/dist/controllers/cache.js +247 -0
  8. package/dist/controllers/cache.js.map +1 -0
  9. package/dist/controllers/feedback.d.ts +44 -0
  10. package/dist/controllers/feedback.d.ts.map +1 -0
  11. package/dist/controllers/feedback.js +216 -0
  12. package/dist/controllers/feedback.js.map +1 -0
  13. package/dist/controllers/index.d.ts +9 -0
  14. package/dist/controllers/index.d.ts.map +1 -0
  15. package/dist/controllers/index.js +9 -0
  16. package/dist/controllers/index.js.map +1 -0
  17. package/dist/controllers/skills.d.ts +66 -0
  18. package/dist/controllers/skills.d.ts.map +1 -0
  19. package/dist/controllers/skills.js +355 -0
  20. package/dist/controllers/skills.js.map +1 -0
  21. package/dist/controllers/versions.d.ts +43 -0
  22. package/dist/controllers/versions.d.ts.map +1 -0
  23. package/dist/controllers/versions.js +298 -0
  24. package/dist/controllers/versions.js.map +1 -0
  25. package/dist/index.d.ts +9 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +78 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/middleware/auth.d.ts +34 -0
  30. package/dist/middleware/auth.d.ts.map +1 -0
  31. package/dist/middleware/auth.js +148 -0
  32. package/dist/middleware/auth.js.map +1 -0
  33. package/dist/middleware/error.d.ts +26 -0
  34. package/dist/middleware/error.d.ts.map +1 -0
  35. package/dist/middleware/error.js +102 -0
  36. package/dist/middleware/error.js.map +1 -0
  37. package/dist/middleware/index.d.ts +8 -0
  38. package/dist/middleware/index.d.ts.map +1 -0
  39. package/dist/middleware/index.js +8 -0
  40. package/dist/middleware/index.js.map +1 -0
  41. package/dist/middleware/logger.d.ts +19 -0
  42. package/dist/middleware/logger.d.ts.map +1 -0
  43. package/dist/middleware/logger.js +54 -0
  44. package/dist/middleware/logger.js.map +1 -0
  45. package/dist/middleware/validation.d.ts +671 -0
  46. package/dist/middleware/validation.d.ts.map +1 -0
  47. package/dist/middleware/validation.js +225 -0
  48. package/dist/middleware/validation.js.map +1 -0
  49. package/dist/routes/audit.d.ts +6 -0
  50. package/dist/routes/audit.d.ts.map +1 -0
  51. package/dist/routes/audit.js +54 -0
  52. package/dist/routes/audit.js.map +1 -0
  53. package/dist/routes/cache.d.ts +6 -0
  54. package/dist/routes/cache.d.ts.map +1 -0
  55. package/dist/routes/cache.js +70 -0
  56. package/dist/routes/cache.js.map +1 -0
  57. package/dist/routes/feedback.d.ts +6 -0
  58. package/dist/routes/feedback.d.ts.map +1 -0
  59. package/dist/routes/feedback.js +68 -0
  60. package/dist/routes/feedback.js.map +1 -0
  61. package/dist/routes/health.d.ts +6 -0
  62. package/dist/routes/health.d.ts.map +1 -0
  63. package/dist/routes/health.js +122 -0
  64. package/dist/routes/health.js.map +1 -0
  65. package/dist/routes/index.d.ts +12 -0
  66. package/dist/routes/index.d.ts.map +1 -0
  67. package/dist/routes/index.js +12 -0
  68. package/dist/routes/index.js.map +1 -0
  69. package/dist/routes/scan.d.ts +8 -0
  70. package/dist/routes/scan.d.ts.map +1 -0
  71. package/dist/routes/scan.js +315 -0
  72. package/dist/routes/scan.js.map +1 -0
  73. package/dist/routes/search.d.ts +6 -0
  74. package/dist/routes/search.d.ts.map +1 -0
  75. package/dist/routes/search.js +44 -0
  76. package/dist/routes/search.js.map +1 -0
  77. package/dist/routes/skills.d.ts +6 -0
  78. package/dist/routes/skills.d.ts.map +1 -0
  79. package/dist/routes/skills.js +74 -0
  80. package/dist/routes/skills.js.map +1 -0
  81. package/dist/routes/versions.d.ts +6 -0
  82. package/dist/routes/versions.d.ts.map +1 -0
  83. package/dist/routes/versions.js +66 -0
  84. package/dist/routes/versions.js.map +1 -0
  85. package/dist/server.d.ts +26 -0
  86. package/dist/server.d.ts.map +1 -0
  87. package/dist/server.js +166 -0
  88. package/dist/server.js.map +1 -0
  89. package/package.json +42 -0
  90. package/src/controllers/audit.ts +175 -0
  91. package/src/controllers/cache.ts +344 -0
  92. package/src/controllers/feedback.ts +309 -0
  93. package/src/controllers/index.ts +9 -0
  94. package/src/controllers/skills.ts +489 -0
  95. package/src/controllers/versions.ts +427 -0
  96. package/src/index.ts +87 -0
  97. package/src/middleware/auth.ts +219 -0
  98. package/src/middleware/error.ts +180 -0
  99. package/src/middleware/index.ts +8 -0
  100. package/src/middleware/logger.ts +71 -0
  101. package/src/middleware/validation.ts +270 -0
  102. package/src/routes/audit.ts +74 -0
  103. package/src/routes/cache.ts +93 -0
  104. package/src/routes/feedback.ts +93 -0
  105. package/src/routes/health.ts +151 -0
  106. package/src/routes/index.ts +12 -0
  107. package/src/routes/scan.ts +428 -0
  108. package/src/routes/search.ts +51 -0
  109. package/src/routes/skills.ts +102 -0
  110. package/src/routes/versions.ts +91 -0
  111. package/src/server.ts +205 -0
  112. package/tsconfig.json +13 -0
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Open Skills Hub - Scan Routes
3
+ *
4
+ * Security scanning endpoints using SkillsGuard
5
+ */
6
+ import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
7
+ export declare function scanRoutes(server: FastifyInstance, _opts: FastifyPluginOptions): Promise<void>;
8
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/routes/scan.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAgC,MAAM,SAAS,CAAC;AAuVnG,wBAAsB,UAAU,CAC9B,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA2Ef"}
@@ -0,0 +1,315 @@
1
+ /**
2
+ * Open Skills Hub - Scan Routes
3
+ *
4
+ * Security scanning endpoints using SkillsGuard
5
+ */
6
+ import { getStorage, getConfig, initScanner, getScanner, generateUUID, now, buildSkillFullName, parseSkillFullName, AppError, ErrorCodes, } from '@open-skills-hub/core';
7
+ import { sendSuccess } from '../middleware/error.js';
8
+ import { logger } from '../middleware/logger.js';
9
+ import { optionalAuth, requireAuth } from '../middleware/auth.js';
10
+ import { validateBody, validateParams, validateQuery, SkillNameParamSchema, ScanContentBodySchema, PaginationQuerySchema, IdParamSchema, } from '../middleware/validation.js';
11
+ // Initialize scanner on first use
12
+ let scannerInitialized = false;
13
+ function ensureScannerInitialized() {
14
+ if (!scannerInitialized) {
15
+ const config = getConfig().get();
16
+ initScanner({
17
+ enabled: config.scanner.enabled,
18
+ timeout: config.scanner.timeout,
19
+ maxFileSize: config.scanner.maxFileSize,
20
+ rulesPath: config.scanner.rulesPath,
21
+ });
22
+ scannerInitialized = true;
23
+ }
24
+ }
25
+ /**
26
+ * Scan content
27
+ */
28
+ async function scanContent(request, reply) {
29
+ ensureScannerInitialized();
30
+ const storage = await getStorage();
31
+ const scanner = getScanner();
32
+ const { content } = request.body;
33
+ const userId = request.user?.id;
34
+ // Run the scan
35
+ const result = await scanner.scan(content);
36
+ // Save scan record and issues to storage
37
+ await storage.createScanRecord({
38
+ ...result.record,
39
+ userId,
40
+ inputType: 'api',
41
+ });
42
+ if (result.issues.length > 0) {
43
+ await storage.createScanIssues(result.issues);
44
+ }
45
+ // Create audit log
46
+ const auditLog = {
47
+ id: generateUUID(),
48
+ timestamp: now(),
49
+ eventType: 'scan.completed',
50
+ actor: {
51
+ type: request.user?.type ?? 'user',
52
+ id: userId,
53
+ username: request.user?.username,
54
+ ip: request.ip,
55
+ userAgent: request.headers['user-agent'],
56
+ },
57
+ resource: {
58
+ type: 'skill',
59
+ id: result.record.id,
60
+ },
61
+ action: 'scan',
62
+ result: 'success',
63
+ details: {
64
+ score: result.summary.score,
65
+ level: result.summary.level,
66
+ issueCount: result.summary.issueCount,
67
+ duration: result.record.duration,
68
+ },
69
+ };
70
+ await storage.createAuditLog(auditLog);
71
+ // Log high-risk scans
72
+ if (result.summary.level === 'high') {
73
+ const highRiskLog = {
74
+ id: generateUUID(),
75
+ timestamp: now(),
76
+ eventType: 'scan.high_risk',
77
+ actor: {
78
+ type: request.user?.type ?? 'user',
79
+ id: userId,
80
+ username: request.user?.username,
81
+ ip: request.ip,
82
+ },
83
+ resource: {
84
+ type: 'skill',
85
+ id: result.record.id,
86
+ },
87
+ action: 'scan',
88
+ result: 'success',
89
+ details: {
90
+ score: result.summary.score,
91
+ highSeverityIssues: result.summary.issueCount.high,
92
+ riskCategories: result.summary.riskCategories,
93
+ },
94
+ };
95
+ await storage.createAuditLog(highRiskLog);
96
+ }
97
+ logger.info('Scan completed', {
98
+ recordId: result.record.id,
99
+ score: result.summary.score,
100
+ level: result.summary.level,
101
+ issueCount: result.summary.issueCount,
102
+ });
103
+ sendSuccess(request, reply, {
104
+ id: result.record.id,
105
+ score: result.summary.score,
106
+ level: result.summary.level,
107
+ issueCount: result.summary.issueCount,
108
+ issues: result.issues.map(i => ({
109
+ id: i.id,
110
+ ruleId: i.ruleId,
111
+ ruleName: i.ruleName,
112
+ category: i.ruleCategory,
113
+ severity: i.severity,
114
+ line: i.line,
115
+ column: i.column,
116
+ content: i.content,
117
+ message: i.message,
118
+ suggestion: i.suggestion,
119
+ })),
120
+ recommendations: result.summary.recommendations,
121
+ duration: result.record.duration,
122
+ scannerVersion: result.record.scannerVersion,
123
+ rulesApplied: result.record.rulesApplied,
124
+ });
125
+ }
126
+ /**
127
+ * Quick check content (high-severity only)
128
+ */
129
+ async function quickCheck(request, reply) {
130
+ ensureScannerInitialized();
131
+ const scanner = getScanner();
132
+ const { content } = request.body;
133
+ const result = await scanner.quickCheck(content);
134
+ sendSuccess(request, reply, result);
135
+ }
136
+ /**
137
+ * Get scan records for a skill
138
+ */
139
+ async function getSkillScans(request, reply) {
140
+ const storage = await getStorage();
141
+ const { name } = request.params;
142
+ const { cursor, limit } = request.query;
143
+ // Parse name
144
+ const { scope, name: skillName } = parseSkillFullName(name);
145
+ const fullName = buildSkillFullName(skillName, scope);
146
+ const skill = await storage.getSkillByName(fullName);
147
+ if (!skill) {
148
+ throw new AppError(ErrorCodes.SKILL_NOT_FOUND, `Skill '${fullName}' not found`, 404);
149
+ }
150
+ const result = await storage.getScanRecords(skill.id, { cursor, limit });
151
+ sendSuccess(request, reply, result.items, 200, result.pagination);
152
+ }
153
+ /**
154
+ * Get scan record by ID
155
+ */
156
+ async function getScanRecord(request, reply) {
157
+ const storage = await getStorage();
158
+ const { id } = request.params;
159
+ const record = await storage.getScanRecordById(id);
160
+ if (!record) {
161
+ throw new AppError(ErrorCodes.SKILL_NOT_FOUND, `Scan record '${id}' not found`, 404);
162
+ }
163
+ // Get issues if scan is completed
164
+ let issues = [];
165
+ if (record.status === 'completed') {
166
+ issues = await storage.getScanIssues(id);
167
+ }
168
+ sendSuccess(request, reply, {
169
+ ...record,
170
+ issues,
171
+ });
172
+ }
173
+ /**
174
+ * Get scan issues for a record
175
+ */
176
+ async function getScanIssues(request, reply) {
177
+ const storage = await getStorage();
178
+ const { id } = request.params;
179
+ const record = await storage.getScanRecordById(id);
180
+ if (!record) {
181
+ throw new AppError(ErrorCodes.SKILL_NOT_FOUND, `Scan record '${id}' not found`, 404);
182
+ }
183
+ const issues = await storage.getScanIssues(id);
184
+ sendSuccess(request, reply, issues);
185
+ }
186
+ /**
187
+ * Acknowledge an issue
188
+ */
189
+ async function acknowledgeIssue(request, reply) {
190
+ const storage = await getStorage();
191
+ const { id } = request.params;
192
+ const { reason } = request.body;
193
+ const userId = request.user?.id ?? 'unknown';
194
+ const issue = await storage.acknowledgeIssue(id, userId, reason);
195
+ if (!issue) {
196
+ throw new AppError(ErrorCodes.SKILL_NOT_FOUND, `Issue '${id}' not found`, 404);
197
+ }
198
+ logger.info('Issue acknowledged', { issueId: id, userId, reason });
199
+ sendSuccess(request, reply, issue);
200
+ }
201
+ /**
202
+ * Get scanner rules
203
+ */
204
+ async function getScannerRules(request, reply) {
205
+ ensureScannerInitialized();
206
+ const scanner = getScanner();
207
+ const rules = scanner.getEnabledRules();
208
+ sendSuccess(request, reply, {
209
+ version: scanner.getVersion(),
210
+ rulesCount: rules.length,
211
+ rules: rules.map(r => ({
212
+ id: r.id,
213
+ name: r.name,
214
+ description: r.description,
215
+ category: r.category,
216
+ severity: r.severity,
217
+ enabled: r.enabled,
218
+ isBuiltin: r.isBuiltin,
219
+ })),
220
+ });
221
+ }
222
+ /**
223
+ * Get scanner statistics
224
+ */
225
+ async function getScannerStats(request, reply) {
226
+ ensureScannerInitialized();
227
+ const scanner = getScanner();
228
+ const rules = scanner.getEnabledRules();
229
+ // Count rules by category and severity
230
+ const byCategory = {};
231
+ const bySeverity = {};
232
+ for (const rule of rules) {
233
+ byCategory[rule.category] = (byCategory[rule.category] || 0) + 1;
234
+ bySeverity[rule.severity] = (bySeverity[rule.severity] || 0) + 1;
235
+ }
236
+ sendSuccess(request, reply, {
237
+ version: scanner.getVersion(),
238
+ totalRules: rules.length,
239
+ enabledRules: rules.filter(r => r.enabled).length,
240
+ builtinRules: rules.filter(r => r.isBuiltin).length,
241
+ customRules: rules.filter(r => !r.isBuiltin).length,
242
+ byCategory,
243
+ bySeverity,
244
+ });
245
+ }
246
+ export async function scanRoutes(server, _opts) {
247
+ // Scan content
248
+ // POST /v1/scan
249
+ server.post('/', {
250
+ preHandler: [
251
+ optionalAuth,
252
+ validateBody(ScanContentBodySchema),
253
+ ],
254
+ handler: scanContent,
255
+ });
256
+ // Quick check (high-severity only)
257
+ // POST /v1/scan/quick
258
+ server.post('/quick', {
259
+ preHandler: [
260
+ optionalAuth,
261
+ validateBody(ScanContentBodySchema),
262
+ ],
263
+ handler: quickCheck,
264
+ });
265
+ // Get scanner rules
266
+ // GET /v1/scan/rules
267
+ server.get('/rules', {
268
+ preHandler: [optionalAuth],
269
+ handler: getScannerRules,
270
+ });
271
+ // Get scanner statistics
272
+ // GET /v1/scan/stats
273
+ server.get('/stats', {
274
+ preHandler: [optionalAuth],
275
+ handler: getScannerStats,
276
+ });
277
+ // Get scan records for a skill
278
+ // GET /v1/scan/skill/:name
279
+ server.get('/skill/:name', {
280
+ preHandler: [
281
+ optionalAuth,
282
+ validateParams(SkillNameParamSchema),
283
+ validateQuery(PaginationQuerySchema),
284
+ ],
285
+ handler: getSkillScans,
286
+ });
287
+ // Get scan record by ID
288
+ // GET /v1/scan/:id
289
+ server.get('/:id', {
290
+ preHandler: [
291
+ optionalAuth,
292
+ validateParams(IdParamSchema),
293
+ ],
294
+ handler: getScanRecord,
295
+ });
296
+ // Get issues for a scan record
297
+ // GET /v1/scan/:id/issues
298
+ server.get('/:id/issues', {
299
+ preHandler: [
300
+ optionalAuth,
301
+ validateParams(IdParamSchema),
302
+ ],
303
+ handler: getScanIssues,
304
+ });
305
+ // Acknowledge an issue
306
+ // POST /v1/scan/issues/:id/acknowledge
307
+ server.post('/issues/:id/acknowledge', {
308
+ preHandler: [
309
+ requireAuth,
310
+ validateParams(IdParamSchema),
311
+ ],
312
+ handler: acknowledgeIssue,
313
+ });
314
+ }
315
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/routes/scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Open Skills Hub - Search Routes
3
+ */
4
+ import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
5
+ export declare function searchRoutes(server: FastifyInstance, _opts: FastifyPluginOptions): Promise<void>;
6
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/routes/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAgC,MAAM,SAAS,CAAC;AAKnG,wBAAsB,YAAY,CAChC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAsCf"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Open Skills Hub - Search Routes
3
+ */
4
+ import { searchSkills } from '../controllers/skills.js';
5
+ import { optionalAuth } from '../middleware/auth.js';
6
+ import { validateQuery, SearchQuerySchema } from '../middleware/validation.js';
7
+ export async function searchRoutes(server, _opts) {
8
+ // Full-text search
9
+ // GET /v1/search?q=...&category=...&sort=...
10
+ server.get('/', {
11
+ preHandler: [
12
+ optionalAuth,
13
+ validateQuery(SearchQuerySchema),
14
+ ],
15
+ handler: searchSkills,
16
+ });
17
+ // Search by category (convenience endpoint)
18
+ // GET /v1/search/category/:category
19
+ server.get('/category/:category', {
20
+ preHandler: [
21
+ optionalAuth,
22
+ ],
23
+ handler: async (request, reply) => {
24
+ const { category } = request.params;
25
+ // Forward to main search with category filter
26
+ request.query.category = category;
27
+ return searchSkills(request, reply);
28
+ },
29
+ });
30
+ // Search by author (convenience endpoint)
31
+ // GET /v1/search/author/:author
32
+ server.get('/author/:author', {
33
+ preHandler: [
34
+ optionalAuth,
35
+ ],
36
+ handler: async (request, reply) => {
37
+ const { author } = request.params;
38
+ // Forward to main search with author filter
39
+ request.query.author = author;
40
+ return searchSkills(request, reply);
41
+ },
42
+ });
43
+ }
44
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/routes/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAoB,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE/E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAuB,EACvB,KAA2B;IAE3B,mBAAmB;IACnB,6CAA6C;IAC7C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;QACd,UAAU,EAAE;YACV,YAAY;YACZ,aAAa,CAAC,iBAAiB,CAAC;SACjC;QACD,OAAO,EAAE,YAA+E;KACzF,CAAC,CAAC;IAEH,4CAA4C;IAC5C,oCAAoC;IACpC,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE;QAChC,UAAU,EAAE;YACV,YAAY;SACb;QACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAChC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAA8B,CAAC;YAC5D,8CAA8C;YAC7C,OAAO,CAAC,KAAqB,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACnD,OAAQ,YAAgF,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC3G,CAAC;KACF,CAAC,CAAC;IAEH,0CAA0C;IAC1C,gCAAgC;IAChC,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE;QAC5B,UAAU,EAAE;YACV,YAAY;SACb;QACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAChC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAA4B,CAAC;YACxD,4CAA4C;YAC3C,OAAO,CAAC,KAAqB,CAAC,MAAM,GAAG,MAAM,CAAC;YAC/C,OAAQ,YAAgF,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC3G,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Open Skills Hub - Skills Routes
3
+ */
4
+ import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
5
+ export declare function skillsRoutes(server: FastifyInstance, _opts: FastifyPluginOptions): Promise<void>;
6
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/routes/skills.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAsBrE,wBAAsB,YAAY,CAChC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAwEf"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Open Skills Hub - Skills Routes
3
+ */
4
+ import { searchSkills, getSkillByName, getSkillContent, createSkill, updateSkill, deleteSkill, getDerivedSkills, } from '../controllers/skills.js';
5
+ import { optionalAuth, requireAuth } from '../middleware/auth.js';
6
+ import { validateBody, validateParams, validateQuery, SkillNameParamSchema, SearchQuerySchema, CreateSkillBodySchema, UpdateSkillBodySchema, PaginationQuerySchema, } from '../middleware/validation.js';
7
+ export async function skillsRoutes(server, _opts) {
8
+ // Search skills
9
+ // GET /v1/skills?q=...&category=...&author=...
10
+ server.get('/', {
11
+ preHandler: [
12
+ optionalAuth,
13
+ validateQuery(SearchQuerySchema),
14
+ ],
15
+ handler: searchSkills,
16
+ });
17
+ // Get skill by name
18
+ // GET /v1/skills/:name
19
+ server.get('/:name', {
20
+ preHandler: [
21
+ optionalAuth,
22
+ validateParams(SkillNameParamSchema),
23
+ ],
24
+ handler: getSkillByName,
25
+ });
26
+ // Get skill content (fetch-on-use)
27
+ // GET /v1/skills/:name/content?version=...
28
+ server.get('/:name/content', {
29
+ preHandler: [
30
+ optionalAuth,
31
+ validateParams(SkillNameParamSchema),
32
+ ],
33
+ handler: getSkillContent,
34
+ });
35
+ // Create/publish a new skill
36
+ // POST /v1/skills
37
+ server.post('/', {
38
+ preHandler: [
39
+ requireAuth,
40
+ validateBody(CreateSkillBodySchema),
41
+ ],
42
+ handler: createSkill,
43
+ });
44
+ // Update skill metadata
45
+ // PATCH /v1/skills/:name
46
+ server.patch('/:name', {
47
+ preHandler: [
48
+ requireAuth,
49
+ validateParams(SkillNameParamSchema),
50
+ validateBody(UpdateSkillBodySchema),
51
+ ],
52
+ handler: updateSkill,
53
+ });
54
+ // Delete skill
55
+ // DELETE /v1/skills/:name?hard=true
56
+ server.delete('/:name', {
57
+ preHandler: [
58
+ requireAuth,
59
+ validateParams(SkillNameParamSchema),
60
+ ],
61
+ handler: deleteSkill,
62
+ });
63
+ // Get derived skills
64
+ // GET /v1/skills/:name/derived
65
+ server.get('/:name/derived', {
66
+ preHandler: [
67
+ optionalAuth,
68
+ validateParams(SkillNameParamSchema),
69
+ validateQuery(PaginationQuerySchema),
70
+ ],
71
+ handler: getDerivedSkills,
72
+ });
73
+ }
74
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/routes/skills.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,WAAW,EACX,WAAW,EACX,WAAW,EACX,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAuB,EACvB,KAA2B;IAE3B,gBAAgB;IAChB,+CAA+C;IAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;QACd,UAAU,EAAE;YACV,YAAY;YACZ,aAAa,CAAC,iBAAiB,CAAC;SACjC;QACD,OAAO,EAAE,YAAY;KACtB,CAAC,CAAC;IAEH,oBAAoB;IACpB,uBAAuB;IACvB,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE;QACnB,UAAU,EAAE;YACV,YAAY;YACZ,cAAc,CAAC,oBAAoB,CAAC;SACrC;QACD,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;IAEH,mCAAmC;IACnC,2CAA2C;IAC3C,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE;QAC3B,UAAU,EAAE;YACV,YAAY;YACZ,cAAc,CAAC,oBAAoB,CAAC;SACrC;QACD,OAAO,EAAE,eAAe;KACzB,CAAC,CAAC;IAEH,6BAA6B;IAC7B,kBAAkB;IAClB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACf,UAAU,EAAE;YACV,WAAW;YACX,YAAY,CAAC,qBAAqB,CAAC;SACpC;QACD,OAAO,EAAE,WAAW;KACrB,CAAC,CAAC;IAEH,wBAAwB;IACxB,yBAAyB;IACzB,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE;QACrB,UAAU,EAAE;YACV,WAAW;YACX,cAAc,CAAC,oBAAoB,CAAC;YACpC,YAAY,CAAC,qBAAqB,CAAC;SACpC;QACD,OAAO,EAAE,WAAW;KACrB,CAAC,CAAC;IAEH,eAAe;IACf,oCAAoC;IACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE;QACtB,UAAU,EAAE;YACV,WAAW;YACX,cAAc,CAAC,oBAAoB,CAAC;SACrC;QACD,OAAO,EAAE,WAAW;KACrB,CAAC,CAAC;IAEH,qBAAqB;IACrB,+BAA+B;IAC/B,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE;QAC3B,UAAU,EAAE;YACV,YAAY;YACZ,cAAc,CAAC,oBAAoB,CAAC;YACpC,aAAa,CAAC,qBAAqB,CAAC;SACrC;QACD,OAAO,EAAE,gBAAgB;KAC1B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Open Skills Hub - Versions Routes
3
+ */
4
+ import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
5
+ export declare function versionsRoutes(server: FastifyInstance, _opts: FastifyPluginOptions): Promise<void>;
6
+ //# sourceMappingURL=versions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../src/routes/versions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AA8BrE,wBAAsB,cAAc,CAClC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAqDf"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Open Skills Hub - Versions Routes
3
+ */
4
+ import { z } from 'zod';
5
+ import { getVersions, getVersion, publishVersion, deprecateVersion, deleteVersion, } from '../controllers/versions.js';
6
+ import { optionalAuth, requireAuth } from '../middleware/auth.js';
7
+ import { validateBody, validateParams, validateQuery, SkillNameParamSchema, SkillVersionParamSchema, PublishVersionBodySchema, PaginationQuerySchema, } from '../middleware/validation.js';
8
+ // Extended query schema for versions
9
+ const VersionsQuerySchema = PaginationQuerySchema.extend({
10
+ includeDeprecated: z.string().optional(),
11
+ });
12
+ // Deprecate body schema
13
+ const DeprecateBodySchema = z.object({
14
+ message: z.string().optional(),
15
+ });
16
+ export async function versionsRoutes(server, _opts) {
17
+ // Get all versions of a skill
18
+ // GET /v1/skills/:name/versions
19
+ server.get('/:name/versions', {
20
+ preHandler: [
21
+ optionalAuth,
22
+ validateParams(SkillNameParamSchema),
23
+ validateQuery(VersionsQuerySchema),
24
+ ],
25
+ handler: getVersions,
26
+ });
27
+ // Get a specific version
28
+ // GET /v1/skills/:name/versions/:version
29
+ server.get('/:name/versions/:version', {
30
+ preHandler: [
31
+ optionalAuth,
32
+ validateParams(SkillVersionParamSchema),
33
+ ],
34
+ handler: getVersion,
35
+ });
36
+ // Publish a new version
37
+ // POST /v1/skills/:name/versions
38
+ server.post('/:name/versions', {
39
+ preHandler: [
40
+ requireAuth,
41
+ validateParams(SkillNameParamSchema),
42
+ validateBody(PublishVersionBodySchema),
43
+ ],
44
+ handler: publishVersion,
45
+ });
46
+ // Deprecate a version
47
+ // POST /v1/skills/:name/versions/:version/deprecate
48
+ server.post('/:name/versions/:version/deprecate', {
49
+ preHandler: [
50
+ requireAuth,
51
+ validateParams(SkillVersionParamSchema),
52
+ validateBody(DeprecateBodySchema),
53
+ ],
54
+ handler: deprecateVersion,
55
+ });
56
+ // Delete/yank a version
57
+ // DELETE /v1/skills/:name/versions/:version
58
+ server.delete('/:name/versions/:version', {
59
+ preHandler: [
60
+ requireAuth,
61
+ validateParams(SkillVersionParamSchema),
62
+ ],
63
+ handler: deleteVersion,
64
+ });
65
+ }
66
+ //# sourceMappingURL=versions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/routes/versions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,WAAW,EACX,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AAErC,qCAAqC;AACrC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,MAAM,CAAC;IACvD,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAC;AAEH,wBAAwB;AACxB,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAuB,EACvB,KAA2B;IAE3B,8BAA8B;IAC9B,gCAAgC;IAChC,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE;QAC5B,UAAU,EAAE;YACV,YAAY;YACZ,cAAc,CAAC,oBAAoB,CAAC;YACpC,aAAa,CAAC,mBAAmB,CAAC;SACnC;QACD,OAAO,EAAE,WAAW;KACrB,CAAC,CAAC;IAEH,yBAAyB;IACzB,yCAAyC;IACzC,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE;QACrC,UAAU,EAAE;YACV,YAAY;YACZ,cAAc,CAAC,uBAAuB,CAAC;SACxC;QACD,OAAO,EAAE,UAAU;KACpB,CAAC,CAAC;IAEH,wBAAwB;IACxB,iCAAiC;IACjC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE;QAC7B,UAAU,EAAE;YACV,WAAW;YACX,cAAc,CAAC,oBAAoB,CAAC;YACpC,YAAY,CAAC,wBAAwB,CAAC;SACvC;QACD,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;IAEH,sBAAsB;IACtB,oDAAoD;IACpD,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE;QAChD,UAAU,EAAE;YACV,WAAW;YACX,cAAc,CAAC,uBAAuB,CAAC;YACvC,YAAY,CAAC,mBAAmB,CAAC;SAClC;QACD,OAAO,EAAE,gBAAgB;KAC1B,CAAC,CAAC;IAEH,wBAAwB;IACxB,4CAA4C;IAC5C,MAAM,CAAC,MAAM,CAAC,0BAA0B,EAAE;QACxC,UAAU,EAAE;YACV,WAAW;YACX,cAAc,CAAC,uBAAuB,CAAC;SACxC;QACD,OAAO,EAAE,aAAa;KACvB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Open Skills Hub - API Server Configuration
3
+ */
4
+ import { FastifyInstance } from 'fastify';
5
+ export interface ServerOptions {
6
+ host?: string;
7
+ port?: number;
8
+ }
9
+ /**
10
+ * Create and configure the Fastify server
11
+ */
12
+ export declare function createServer(options?: ServerOptions): Promise<FastifyInstance>;
13
+ /**
14
+ * Start the server
15
+ */
16
+ export declare function startServer(server: FastifyInstance, options?: ServerOptions): Promise<string>;
17
+ /**
18
+ * Stop the server gracefully
19
+ */
20
+ export declare function stopServer(server: FastifyInstance): Promise<void>;
21
+ declare module 'fastify' {
22
+ interface FastifyRequest {
23
+ startTime?: number;
24
+ }
25
+ }
26
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAuBnD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CA4BpF;AA8FD;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBnG;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvE;AAGD,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;CACF"}