@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.
- package/dist/controllers/audit.d.ts +33 -0
- package/dist/controllers/audit.d.ts.map +1 -0
- package/dist/controllers/audit.js +122 -0
- package/dist/controllers/audit.js.map +1 -0
- package/dist/controllers/cache.d.ts +42 -0
- package/dist/controllers/cache.d.ts.map +1 -0
- package/dist/controllers/cache.js +247 -0
- package/dist/controllers/cache.js.map +1 -0
- package/dist/controllers/feedback.d.ts +44 -0
- package/dist/controllers/feedback.d.ts.map +1 -0
- package/dist/controllers/feedback.js +216 -0
- package/dist/controllers/feedback.js.map +1 -0
- package/dist/controllers/index.d.ts +9 -0
- package/dist/controllers/index.d.ts.map +1 -0
- package/dist/controllers/index.js +9 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/controllers/skills.d.ts +66 -0
- package/dist/controllers/skills.d.ts.map +1 -0
- package/dist/controllers/skills.js +355 -0
- package/dist/controllers/skills.js.map +1 -0
- package/dist/controllers/versions.d.ts +43 -0
- package/dist/controllers/versions.d.ts.map +1 -0
- package/dist/controllers/versions.js +298 -0
- package/dist/controllers/versions.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +34 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +148 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/error.d.ts +26 -0
- package/dist/middleware/error.d.ts.map +1 -0
- package/dist/middleware/error.js +102 -0
- package/dist/middleware/error.js.map +1 -0
- package/dist/middleware/index.d.ts +8 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +8 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/logger.d.ts +19 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/logger.js +54 -0
- package/dist/middleware/logger.js.map +1 -0
- package/dist/middleware/validation.d.ts +671 -0
- package/dist/middleware/validation.d.ts.map +1 -0
- package/dist/middleware/validation.js +225 -0
- package/dist/middleware/validation.js.map +1 -0
- package/dist/routes/audit.d.ts +6 -0
- package/dist/routes/audit.d.ts.map +1 -0
- package/dist/routes/audit.js +54 -0
- package/dist/routes/audit.js.map +1 -0
- package/dist/routes/cache.d.ts +6 -0
- package/dist/routes/cache.d.ts.map +1 -0
- package/dist/routes/cache.js +70 -0
- package/dist/routes/cache.js.map +1 -0
- package/dist/routes/feedback.d.ts +6 -0
- package/dist/routes/feedback.d.ts.map +1 -0
- package/dist/routes/feedback.js +68 -0
- package/dist/routes/feedback.js.map +1 -0
- package/dist/routes/health.d.ts +6 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +122 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/index.d.ts +12 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +12 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/scan.d.ts +8 -0
- package/dist/routes/scan.d.ts.map +1 -0
- package/dist/routes/scan.js +315 -0
- package/dist/routes/scan.js.map +1 -0
- package/dist/routes/search.d.ts +6 -0
- package/dist/routes/search.d.ts.map +1 -0
- package/dist/routes/search.js +44 -0
- package/dist/routes/search.js.map +1 -0
- package/dist/routes/skills.d.ts +6 -0
- package/dist/routes/skills.d.ts.map +1 -0
- package/dist/routes/skills.js +74 -0
- package/dist/routes/skills.js.map +1 -0
- package/dist/routes/versions.d.ts +6 -0
- package/dist/routes/versions.d.ts.map +1 -0
- package/dist/routes/versions.js +66 -0
- package/dist/routes/versions.js.map +1 -0
- package/dist/server.d.ts +26 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +166 -0
- package/dist/server.js.map +1 -0
- package/package.json +42 -0
- package/src/controllers/audit.ts +175 -0
- package/src/controllers/cache.ts +344 -0
- package/src/controllers/feedback.ts +309 -0
- package/src/controllers/index.ts +9 -0
- package/src/controllers/skills.ts +489 -0
- package/src/controllers/versions.ts +427 -0
- package/src/index.ts +87 -0
- package/src/middleware/auth.ts +219 -0
- package/src/middleware/error.ts +180 -0
- package/src/middleware/index.ts +8 -0
- package/src/middleware/logger.ts +71 -0
- package/src/middleware/validation.ts +270 -0
- package/src/routes/audit.ts +74 -0
- package/src/routes/cache.ts +93 -0
- package/src/routes/feedback.ts +93 -0
- package/src/routes/health.ts +151 -0
- package/src/routes/index.ts +12 -0
- package/src/routes/scan.ts +428 -0
- package/src/routes/search.ts +51 -0
- package/src/routes/skills.ts +102 -0
- package/src/routes/versions.ts +91 -0
- package/src/server.ts +205 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Skills Hub - Audit Controller
|
|
3
|
+
*/
|
|
4
|
+
import type { FastifyRequest, FastifyReply } from 'fastify';
|
|
5
|
+
import type { SkillNameParam, IdParam, AuditQuery } from '../middleware/validation.js';
|
|
6
|
+
/**
|
|
7
|
+
* Get audit logs
|
|
8
|
+
*/
|
|
9
|
+
export declare function getAuditLogs(request: FastifyRequest<{
|
|
10
|
+
Querystring: AuditQuery;
|
|
11
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Get audit logs for a specific skill
|
|
14
|
+
*/
|
|
15
|
+
export declare function getSkillAuditLogs(request: FastifyRequest<{
|
|
16
|
+
Params: SkillNameParam;
|
|
17
|
+
Querystring: AuditQuery;
|
|
18
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Get audit log by ID
|
|
21
|
+
*/
|
|
22
|
+
export declare function getAuditLogById(request: FastifyRequest<{
|
|
23
|
+
Params: IdParam;
|
|
24
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Get audit statistics
|
|
27
|
+
*/
|
|
28
|
+
export declare function getAuditStats(request: FastifyRequest<{
|
|
29
|
+
Querystring: {
|
|
30
|
+
days?: number;
|
|
31
|
+
};
|
|
32
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
33
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/controllers/audit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAS5D,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,UAAU,EACX,MAAM,6BAA6B,CAAC;AAErC;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,CAAC;IAAE,WAAW,EAAE,UAAU,CAAA;CAAE,CAAC,EACpD,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,WAAW,EAAE,UAAU,CAAA;CAAE,CAAC,EAC5E,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC,EAC5C,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,CAAC;IAAE,WAAW,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,EAC3D,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAyDf"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Skills Hub - Audit Controller
|
|
3
|
+
*/
|
|
4
|
+
import { getStorage, buildSkillFullName, parseSkillFullName, AppError, ErrorCodes, } from '@open-skills-hub/core';
|
|
5
|
+
import { sendSuccess } from '../middleware/error.js';
|
|
6
|
+
/**
|
|
7
|
+
* Get audit logs
|
|
8
|
+
*/
|
|
9
|
+
export async function getAuditLogs(request, reply) {
|
|
10
|
+
const storage = await getStorage();
|
|
11
|
+
const { eventType, actor, resourceType, resourceName, from, to, cursor, limit } = request.query;
|
|
12
|
+
const result = await storage.getAuditLogs({
|
|
13
|
+
eventType,
|
|
14
|
+
actor,
|
|
15
|
+
resourceType,
|
|
16
|
+
resourceName,
|
|
17
|
+
from,
|
|
18
|
+
to,
|
|
19
|
+
cursor,
|
|
20
|
+
limit,
|
|
21
|
+
});
|
|
22
|
+
sendSuccess(request, reply, result.items, 200, result.pagination);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get audit logs for a specific skill
|
|
26
|
+
*/
|
|
27
|
+
export async function getSkillAuditLogs(request, reply) {
|
|
28
|
+
const storage = await getStorage();
|
|
29
|
+
const { name } = request.params;
|
|
30
|
+
const { from, to, cursor, limit } = request.query;
|
|
31
|
+
// Parse name
|
|
32
|
+
const { scope, name: skillName } = parseSkillFullName(name);
|
|
33
|
+
const fullName = buildSkillFullName(skillName, scope);
|
|
34
|
+
const skill = await storage.getSkillByName(fullName);
|
|
35
|
+
if (!skill) {
|
|
36
|
+
throw new AppError(ErrorCodes.SKILL_NOT_FOUND, `Skill '${fullName}' not found`, 404);
|
|
37
|
+
}
|
|
38
|
+
const result = await storage.getResourceAuditLogs('skill', skill.id, {
|
|
39
|
+
cursor,
|
|
40
|
+
limit,
|
|
41
|
+
});
|
|
42
|
+
// Filter by date if provided
|
|
43
|
+
let items = result.items;
|
|
44
|
+
if (from || to) {
|
|
45
|
+
items = items.filter(log => {
|
|
46
|
+
const timestamp = new Date(log.timestamp).getTime();
|
|
47
|
+
if (from && timestamp < new Date(from).getTime())
|
|
48
|
+
return false;
|
|
49
|
+
if (to && timestamp > new Date(to).getTime())
|
|
50
|
+
return false;
|
|
51
|
+
return true;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
sendSuccess(request, reply, items, 200, result.pagination);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get audit log by ID
|
|
58
|
+
*/
|
|
59
|
+
export async function getAuditLogById(request, reply) {
|
|
60
|
+
const storage = await getStorage();
|
|
61
|
+
const { id } = request.params;
|
|
62
|
+
// Search for the log
|
|
63
|
+
const result = await storage.getAuditLogs({ limit: 1000 });
|
|
64
|
+
const log = result.items.find(l => l.id === id);
|
|
65
|
+
if (!log) {
|
|
66
|
+
throw new AppError(ErrorCodes.SKILL_NOT_FOUND, // Using generic not found
|
|
67
|
+
`Audit log '${id}' not found`, 404);
|
|
68
|
+
}
|
|
69
|
+
sendSuccess(request, reply, log);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get audit statistics
|
|
73
|
+
*/
|
|
74
|
+
export async function getAuditStats(request, reply) {
|
|
75
|
+
const storage = await getStorage();
|
|
76
|
+
const days = request.query.days ?? 30;
|
|
77
|
+
const fromDate = new Date();
|
|
78
|
+
fromDate.setDate(fromDate.getDate() - days);
|
|
79
|
+
const result = await storage.getAuditLogs({
|
|
80
|
+
from: fromDate.toISOString(),
|
|
81
|
+
limit: 10000,
|
|
82
|
+
});
|
|
83
|
+
const logs = result.items;
|
|
84
|
+
// Calculate stats
|
|
85
|
+
const byEventType = {};
|
|
86
|
+
const byActorType = {};
|
|
87
|
+
const byResult = {};
|
|
88
|
+
const byDay = {};
|
|
89
|
+
for (const log of logs) {
|
|
90
|
+
// By event type
|
|
91
|
+
byEventType[log.eventType] = (byEventType[log.eventType] || 0) + 1;
|
|
92
|
+
// By actor type
|
|
93
|
+
byActorType[log.actor.type] = (byActorType[log.actor.type] || 0) + 1;
|
|
94
|
+
// By result
|
|
95
|
+
byResult[log.result] = (byResult[log.result] || 0) + 1;
|
|
96
|
+
// By day
|
|
97
|
+
const day = log.timestamp.split('T')[0];
|
|
98
|
+
if (day) {
|
|
99
|
+
byDay[day] = (byDay[day] || 0) + 1;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Convert byDay to sorted array
|
|
103
|
+
const dailyActivity = Object.entries(byDay)
|
|
104
|
+
.map(([date, count]) => ({ date, count }))
|
|
105
|
+
.sort((a, b) => a.date.localeCompare(b.date));
|
|
106
|
+
sendSuccess(request, reply, {
|
|
107
|
+
total: logs.length,
|
|
108
|
+
period: {
|
|
109
|
+
from: fromDate.toISOString(),
|
|
110
|
+
to: new Date().toISOString(),
|
|
111
|
+
days,
|
|
112
|
+
},
|
|
113
|
+
byEventType,
|
|
114
|
+
byActorType,
|
|
115
|
+
byResult,
|
|
116
|
+
dailyActivity,
|
|
117
|
+
successRate: logs.length > 0
|
|
118
|
+
? (byResult['success'] || 0) / logs.length
|
|
119
|
+
: 0,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/controllers/audit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,QAAQ,EACR,UAAU,GACX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAOrD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAoD,EACpD,KAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IAEhG,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC;QACxC,SAAS;QACT,KAAK;QACL,YAAY;QACZ,YAAY;QACZ,IAAI;QACJ,EAAE;QACF,MAAM;QACN,KAAK;KACN,CAAC,CAAC;IAEH,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA4E,EAC5E,KAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAChC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IAElD,aAAa;IACb,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAEtD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,QAAQ,CAChB,UAAU,CAAC,eAAe,EAC1B,UAAU,QAAQ,aAAa,EAC/B,GAAG,CACJ,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE;QACnE,MAAM;QACN,KAAK;KACN,CAAC,CAAC;IAEH,6BAA6B;IAC7B,IAAI,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QACf,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;YACzB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YACpD,IAAI,IAAI,IAAI,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE;gBAAE,OAAO,KAAK,CAAC;YAC/D,IAAI,EAAE,IAAI,SAAS,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE;gBAAE,OAAO,KAAK,CAAC;YAC3D,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAA4C,EAC5C,KAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAE9B,qBAAqB;IACrB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAEhD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,QAAQ,CAChB,UAAU,CAAC,eAAe,EAAE,0BAA0B;QACtD,cAAc,EAAE,aAAa,EAC7B,GAAG,CACJ,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAA2D,EAC3D,KAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IAEtC,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAE5C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC;QACxC,IAAI,EAAE,QAAQ,CAAC,WAAW,EAAE;QAC5B,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;IAE1B,kBAAkB;IAClB,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,KAAK,GAA2B,EAAE,CAAC;IAEzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,gBAAgB;QAChB,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAEnE,gBAAgB;QAChB,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAErE,YAAY;QACZ,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAEvD,SAAS;QACT,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,GAAG,EAAE,CAAC;YACR,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SACxC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;SACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhD,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE;QAC1B,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ,CAAC,WAAW,EAAE;YAC5B,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,IAAI;SACL;QACD,WAAW;QACX,WAAW;QACX,QAAQ;QACR,aAAa;QACb,WAAW,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC;YAC1B,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM;YAC1C,CAAC,CAAC,CAAC;KACN,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Skills Hub - Cache Controller
|
|
3
|
+
*/
|
|
4
|
+
import type { FastifyRequest, FastifyReply } from 'fastify';
|
|
5
|
+
import type { SkillNameParam, SkillVersionParam } from '../middleware/validation.js';
|
|
6
|
+
/**
|
|
7
|
+
* Get all cached skills
|
|
8
|
+
*/
|
|
9
|
+
export declare function getCachedSkills(request: FastifyRequest, reply: FastifyReply): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Get cache info for a specific skill
|
|
12
|
+
*/
|
|
13
|
+
export declare function getSkillCacheInfo(request: FastifyRequest<{
|
|
14
|
+
Params: SkillNameParam;
|
|
15
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Get cache info for a specific version
|
|
18
|
+
*/
|
|
19
|
+
export declare function getVersionCacheInfo(request: FastifyRequest<{
|
|
20
|
+
Params: SkillVersionParam;
|
|
21
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Invalidate cache for a skill
|
|
24
|
+
*/
|
|
25
|
+
export declare function invalidateSkillCache(request: FastifyRequest<{
|
|
26
|
+
Params: SkillNameParam;
|
|
27
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Invalidate cache for a specific version
|
|
30
|
+
*/
|
|
31
|
+
export declare function invalidateVersionCache(request: FastifyRequest<{
|
|
32
|
+
Params: SkillVersionParam;
|
|
33
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Clean expired cache entries
|
|
36
|
+
*/
|
|
37
|
+
export declare function cleanExpiredCache(request: FastifyRequest, reply: FastifyReply): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Get cache statistics
|
|
40
|
+
*/
|
|
41
|
+
export declare function getCacheStats(request: FastifyRequest, reply: FastifyReply): Promise<void>;
|
|
42
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/controllers/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAe5D,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AAErC;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAgDf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,EACnD,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC,EACtD,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,EACnD,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC,EACtD,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CA2Cf;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAgDf"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Skills Hub - Cache Controller
|
|
3
|
+
*/
|
|
4
|
+
import { getStorage, getConfig, generateUUID, now, buildSkillFullName, parseSkillFullName, AppError, ErrorCodes, } from '@open-skills-hub/core';
|
|
5
|
+
import { sendSuccess } from '../middleware/error.js';
|
|
6
|
+
import { logger } from '../middleware/logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Get all cached skills
|
|
9
|
+
*/
|
|
10
|
+
export async function getCachedSkills(request, reply) {
|
|
11
|
+
const storage = await getStorage();
|
|
12
|
+
const cacheEntries = await storage.getAllCacheMetadata();
|
|
13
|
+
// Group by skill name
|
|
14
|
+
const bySkill = {};
|
|
15
|
+
for (const entry of cacheEntries) {
|
|
16
|
+
if (!bySkill[entry.skillName]) {
|
|
17
|
+
bySkill[entry.skillName] = {
|
|
18
|
+
skillName: entry.skillName,
|
|
19
|
+
versions: [],
|
|
20
|
+
totalHits: 0,
|
|
21
|
+
totalSize: 0,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
bySkill[entry.skillName].versions.push({
|
|
25
|
+
version: entry.version,
|
|
26
|
+
cachedAt: entry.cachedAt,
|
|
27
|
+
expiresAt: entry.expiresAt,
|
|
28
|
+
size: entry.size,
|
|
29
|
+
hitCount: entry.hitCount,
|
|
30
|
+
lastHitAt: entry.lastHitAt,
|
|
31
|
+
});
|
|
32
|
+
bySkill[entry.skillName].totalHits += entry.hitCount;
|
|
33
|
+
bySkill[entry.skillName].totalSize += entry.size ?? 0;
|
|
34
|
+
}
|
|
35
|
+
const skills = Object.values(bySkill).sort((a, b) => b.totalHits - a.totalHits);
|
|
36
|
+
sendSuccess(request, reply, {
|
|
37
|
+
count: cacheEntries.length,
|
|
38
|
+
skills,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get cache info for a specific skill
|
|
43
|
+
*/
|
|
44
|
+
export async function getSkillCacheInfo(request, reply) {
|
|
45
|
+
const storage = await getStorage();
|
|
46
|
+
const { name } = request.params;
|
|
47
|
+
// Parse name
|
|
48
|
+
const { scope, name: skillName } = parseSkillFullName(name);
|
|
49
|
+
const fullName = buildSkillFullName(skillName, scope);
|
|
50
|
+
const allCache = await storage.getAllCacheMetadata();
|
|
51
|
+
const skillCache = allCache.filter(c => c.skillName === fullName);
|
|
52
|
+
if (skillCache.length === 0) {
|
|
53
|
+
throw new AppError(ErrorCodes.CACHE_MISS, `No cache entries found for skill '${fullName}'`, 404);
|
|
54
|
+
}
|
|
55
|
+
const totalHits = skillCache.reduce((sum, c) => sum + c.hitCount, 0);
|
|
56
|
+
const totalSize = skillCache.reduce((sum, c) => sum + (c.size ?? 0), 0);
|
|
57
|
+
sendSuccess(request, reply, {
|
|
58
|
+
skillName: fullName,
|
|
59
|
+
versions: skillCache.map(c => ({
|
|
60
|
+
version: c.version,
|
|
61
|
+
cachedAt: c.cachedAt,
|
|
62
|
+
expiresAt: c.expiresAt,
|
|
63
|
+
size: c.size,
|
|
64
|
+
hitCount: c.hitCount,
|
|
65
|
+
lastHitAt: c.lastHitAt,
|
|
66
|
+
integrityHash: c.integrityHash,
|
|
67
|
+
})),
|
|
68
|
+
totalVersions: skillCache.length,
|
|
69
|
+
totalHits,
|
|
70
|
+
totalSize,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get cache info for a specific version
|
|
75
|
+
*/
|
|
76
|
+
export async function getVersionCacheInfo(request, reply) {
|
|
77
|
+
const storage = await getStorage();
|
|
78
|
+
const { name, version } = request.params;
|
|
79
|
+
// Parse name
|
|
80
|
+
const { scope, name: skillName } = parseSkillFullName(name);
|
|
81
|
+
const fullName = buildSkillFullName(skillName, scope);
|
|
82
|
+
const cacheEntry = await storage.getCacheMetadata(fullName, version);
|
|
83
|
+
if (!cacheEntry) {
|
|
84
|
+
throw new AppError(ErrorCodes.CACHE_MISS, `No cache entry found for '${fullName}@${version}'`, 404);
|
|
85
|
+
}
|
|
86
|
+
sendSuccess(request, reply, cacheEntry);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Invalidate cache for a skill
|
|
90
|
+
*/
|
|
91
|
+
export async function invalidateSkillCache(request, reply) {
|
|
92
|
+
const storage = await getStorage();
|
|
93
|
+
const { name } = request.params;
|
|
94
|
+
const userId = request.user?.id;
|
|
95
|
+
// Parse name
|
|
96
|
+
const { scope, name: skillName } = parseSkillFullName(name);
|
|
97
|
+
const fullName = buildSkillFullName(skillName, scope);
|
|
98
|
+
const deleted = await storage.deleteCacheMetadata(fullName);
|
|
99
|
+
// Create audit log
|
|
100
|
+
const auditLog = {
|
|
101
|
+
id: generateUUID(),
|
|
102
|
+
timestamp: now(),
|
|
103
|
+
eventType: 'cache.invalidated',
|
|
104
|
+
actor: {
|
|
105
|
+
type: request.user?.type ?? 'user',
|
|
106
|
+
id: userId,
|
|
107
|
+
username: request.user?.username,
|
|
108
|
+
ip: request.ip,
|
|
109
|
+
userAgent: request.headers['user-agent'],
|
|
110
|
+
},
|
|
111
|
+
resource: {
|
|
112
|
+
type: 'skill',
|
|
113
|
+
name: fullName,
|
|
114
|
+
},
|
|
115
|
+
action: 'invalidate_cache',
|
|
116
|
+
result: deleted ? 'success' : 'failure',
|
|
117
|
+
};
|
|
118
|
+
await storage.createAuditLog(auditLog);
|
|
119
|
+
logger.info('Cache invalidated', { skillName: fullName, deleted });
|
|
120
|
+
sendSuccess(request, reply, { invalidated: deleted });
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Invalidate cache for a specific version
|
|
124
|
+
*/
|
|
125
|
+
export async function invalidateVersionCache(request, reply) {
|
|
126
|
+
const storage = await getStorage();
|
|
127
|
+
const { name, version } = request.params;
|
|
128
|
+
const userId = request.user?.id;
|
|
129
|
+
// Parse name
|
|
130
|
+
const { scope, name: skillName } = parseSkillFullName(name);
|
|
131
|
+
const fullName = buildSkillFullName(skillName, scope);
|
|
132
|
+
const deleted = await storage.deleteCacheMetadata(fullName, version);
|
|
133
|
+
// Create audit log
|
|
134
|
+
const auditLog = {
|
|
135
|
+
id: generateUUID(),
|
|
136
|
+
timestamp: now(),
|
|
137
|
+
eventType: 'cache.invalidated',
|
|
138
|
+
actor: {
|
|
139
|
+
type: request.user?.type ?? 'user',
|
|
140
|
+
id: userId,
|
|
141
|
+
username: request.user?.username,
|
|
142
|
+
ip: request.ip,
|
|
143
|
+
userAgent: request.headers['user-agent'],
|
|
144
|
+
},
|
|
145
|
+
resource: {
|
|
146
|
+
type: 'version',
|
|
147
|
+
name: fullName,
|
|
148
|
+
version,
|
|
149
|
+
},
|
|
150
|
+
action: 'invalidate_cache',
|
|
151
|
+
result: deleted ? 'success' : 'failure',
|
|
152
|
+
};
|
|
153
|
+
await storage.createAuditLog(auditLog);
|
|
154
|
+
logger.info('Version cache invalidated', { skillName: fullName, version, deleted });
|
|
155
|
+
sendSuccess(request, reply, { invalidated: deleted });
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Clean expired cache entries
|
|
159
|
+
*/
|
|
160
|
+
export async function cleanExpiredCache(request, reply) {
|
|
161
|
+
const storage = await getStorage();
|
|
162
|
+
const userId = request.user?.id;
|
|
163
|
+
const expiredEntries = await storage.getExpiredCacheEntries();
|
|
164
|
+
let cleaned = 0;
|
|
165
|
+
for (const entry of expiredEntries) {
|
|
166
|
+
const deleted = await storage.deleteCacheMetadata(entry.skillName, entry.version);
|
|
167
|
+
if (deleted)
|
|
168
|
+
cleaned++;
|
|
169
|
+
}
|
|
170
|
+
// Create audit log
|
|
171
|
+
const auditLog = {
|
|
172
|
+
id: generateUUID(),
|
|
173
|
+
timestamp: now(),
|
|
174
|
+
eventType: 'cache.invalidated',
|
|
175
|
+
actor: {
|
|
176
|
+
type: request.user?.type ?? 'system',
|
|
177
|
+
id: userId,
|
|
178
|
+
username: request.user?.username,
|
|
179
|
+
ip: request.ip,
|
|
180
|
+
userAgent: request.headers['user-agent'],
|
|
181
|
+
},
|
|
182
|
+
resource: {
|
|
183
|
+
type: 'config',
|
|
184
|
+
name: 'cache',
|
|
185
|
+
},
|
|
186
|
+
action: 'clean_expired',
|
|
187
|
+
result: 'success',
|
|
188
|
+
details: {
|
|
189
|
+
expired: expiredEntries.length,
|
|
190
|
+
cleaned,
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
await storage.createAuditLog(auditLog);
|
|
194
|
+
logger.info('Expired cache cleaned', { expired: expiredEntries.length, cleaned });
|
|
195
|
+
sendSuccess(request, reply, {
|
|
196
|
+
expired: expiredEntries.length,
|
|
197
|
+
cleaned,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Get cache statistics
|
|
202
|
+
*/
|
|
203
|
+
export async function getCacheStats(request, reply) {
|
|
204
|
+
const storage = await getStorage();
|
|
205
|
+
const config = getConfig().get();
|
|
206
|
+
const cacheEntries = await storage.getAllCacheMetadata();
|
|
207
|
+
const expiredEntries = await storage.getExpiredCacheEntries();
|
|
208
|
+
const totalSize = cacheEntries.reduce((sum, c) => sum + (c.size ?? 0), 0);
|
|
209
|
+
const totalHits = cacheEntries.reduce((sum, c) => sum + c.hitCount, 0);
|
|
210
|
+
const uniqueSkills = new Set(cacheEntries.map(c => c.skillName)).size;
|
|
211
|
+
// Most accessed
|
|
212
|
+
const mostAccessed = [...cacheEntries]
|
|
213
|
+
.sort((a, b) => b.hitCount - a.hitCount)
|
|
214
|
+
.slice(0, 10)
|
|
215
|
+
.map(c => ({
|
|
216
|
+
skillName: c.skillName,
|
|
217
|
+
version: c.version,
|
|
218
|
+
hitCount: c.hitCount,
|
|
219
|
+
}));
|
|
220
|
+
// Recently cached
|
|
221
|
+
const recentlyCached = [...cacheEntries]
|
|
222
|
+
.sort((a, b) => b.cachedAt.localeCompare(a.cachedAt))
|
|
223
|
+
.slice(0, 10)
|
|
224
|
+
.map(c => ({
|
|
225
|
+
skillName: c.skillName,
|
|
226
|
+
version: c.version,
|
|
227
|
+
cachedAt: c.cachedAt,
|
|
228
|
+
}));
|
|
229
|
+
sendSuccess(request, reply, {
|
|
230
|
+
totalEntries: cacheEntries.length,
|
|
231
|
+
uniqueSkills,
|
|
232
|
+
totalSize,
|
|
233
|
+
totalHits,
|
|
234
|
+
expiredCount: expiredEntries.length,
|
|
235
|
+
config: {
|
|
236
|
+
ttl: config.cache.ttl,
|
|
237
|
+
maxSize: config.cache.maxSize,
|
|
238
|
+
strategy: config.cache.strategy,
|
|
239
|
+
},
|
|
240
|
+
utilization: config.cache.maxSize > 0
|
|
241
|
+
? Math.round((totalSize / config.cache.maxSize) * 100)
|
|
242
|
+
: 0,
|
|
243
|
+
mostAccessed,
|
|
244
|
+
recentlyCached,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/controllers/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Skills Hub - Feedback Controller
|
|
3
|
+
*/
|
|
4
|
+
import type { FastifyRequest, FastifyReply } from 'fastify';
|
|
5
|
+
import type { SkillNameParam, IdParam, SubmitFeedbackBody, PaginationQuery } from '../middleware/validation.js';
|
|
6
|
+
/**
|
|
7
|
+
* Submit feedback for a skill
|
|
8
|
+
*/
|
|
9
|
+
export declare function submitFeedback(request: FastifyRequest<{
|
|
10
|
+
Body: SubmitFeedbackBody;
|
|
11
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Get feedbacks for a skill
|
|
14
|
+
*/
|
|
15
|
+
export declare function getSkillFeedbacks(request: FastifyRequest<{
|
|
16
|
+
Params: SkillNameParam;
|
|
17
|
+
Querystring: PaginationQuery & {
|
|
18
|
+
feedbackType?: string;
|
|
19
|
+
status?: string;
|
|
20
|
+
};
|
|
21
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Get feedback by ID
|
|
24
|
+
*/
|
|
25
|
+
export declare function getFeedbackById(request: FastifyRequest<{
|
|
26
|
+
Params: IdParam;
|
|
27
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Review feedback (admin)
|
|
30
|
+
*/
|
|
31
|
+
export declare function reviewFeedback(request: FastifyRequest<{
|
|
32
|
+
Params: IdParam;
|
|
33
|
+
Body: {
|
|
34
|
+
status: 'reviewed' | 'accepted' | 'rejected';
|
|
35
|
+
notes?: string;
|
|
36
|
+
};
|
|
37
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Get feedback statistics for a skill
|
|
40
|
+
*/
|
|
41
|
+
export declare function getFeedbackStats(request: FastifyRequest<{
|
|
42
|
+
Params: SkillNameParam;
|
|
43
|
+
}>, reply: FastifyReply): Promise<void>;
|
|
44
|
+
//# sourceMappingURL=feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/controllers/feedback.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAc5D,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,kBAAkB,EAClB,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAErC;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,CAAC;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC,EACrD,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAoGf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,eAAe,GAAG;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1E,CAAC,EACF,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC,EAC5C,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE;QAAE,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACvE,CAAC,EACF,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,cAAc,CAAC;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,EACnD,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
|