@t4dhg/mcp-factorial 1.0.0 → 2.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/LICENSE +21 -0
- package/README.md +125 -26
- package/dist/api.d.ts +104 -8
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +261 -98
- package/dist/api.js.map +1 -1
- package/dist/cache.d.ts +88 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +169 -0
- package/dist/cache.js.map +1 -0
- package/dist/config.d.ts +57 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +112 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +100 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +186 -0
- package/dist/errors.js.map +1 -0
- package/dist/http-client.d.ts +43 -0
- package/dist/http-client.d.ts.map +1 -0
- package/dist/http-client.js +146 -0
- package/dist/http-client.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1021 -70
- package/dist/index.js.map +1 -1
- package/dist/pagination.d.ts +96 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +114 -0
- package/dist/pagination.js.map +1 -0
- package/dist/schemas.d.ts +502 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +241 -0
- package/dist/schemas.js.map +1 -0
- package/dist/types.d.ts +61 -48
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -1
- package/dist/types.js.map +1 -1
- package/package.json +42 -5
package/dist/api.js
CHANGED
|
@@ -1,136 +1,299 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
async function factorialFetch(endpoint, params) {
|
|
26
|
-
const url = new URL(`${FACTORIAL_BASE_URL}${endpoint}`);
|
|
27
|
-
if (params) {
|
|
28
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
29
|
-
if (value !== undefined) {
|
|
30
|
-
url.searchParams.append(key, String(value));
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
debug(`Fetching: ${url.toString()}`);
|
|
35
|
-
const controller = new AbortController();
|
|
36
|
-
const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
|
|
37
|
-
try {
|
|
38
|
-
const response = await fetch(url.toString(), {
|
|
39
|
-
method: 'GET',
|
|
40
|
-
headers: {
|
|
41
|
-
'x-api-key': getApiKey(),
|
|
42
|
-
'Accept': 'application/json',
|
|
43
|
-
},
|
|
44
|
-
signal: controller.signal,
|
|
45
|
-
});
|
|
46
|
-
clearTimeout(timeoutId);
|
|
47
|
-
if (!response.ok) {
|
|
48
|
-
const errorText = await response.text();
|
|
49
|
-
debug(`API error (${response.status}):`, errorText);
|
|
50
|
-
// Provide user-friendly error messages
|
|
51
|
-
if (response.status === 401) {
|
|
52
|
-
throw new Error('Invalid API key. Please check your FACTORIAL_API_KEY.');
|
|
53
|
-
}
|
|
54
|
-
if (response.status === 403) {
|
|
55
|
-
throw new Error('Access denied. Your API key may not have permission for this operation.');
|
|
56
|
-
}
|
|
57
|
-
if (response.status === 404) {
|
|
58
|
-
throw new Error('Resource not found. The requested employee, team, or location may not exist.');
|
|
59
|
-
}
|
|
60
|
-
if (response.status === 429) {
|
|
61
|
-
throw new Error('Rate limit exceeded. Please wait a moment before trying again.');
|
|
62
|
-
}
|
|
63
|
-
throw new Error(`FactorialHR API error (${response.status}): ${errorText}`);
|
|
1
|
+
/**
|
|
2
|
+
* FactorialHR API Client
|
|
3
|
+
*
|
|
4
|
+
* Provides access to FactorialHR API endpoints with caching, pagination, and retry logic.
|
|
5
|
+
*/
|
|
6
|
+
import { fetchList, fetchOne } from './http-client.js';
|
|
7
|
+
import { cache, cached, CACHE_TTL, CacheManager } from './cache.js';
|
|
8
|
+
import { buildPaginationParams, paginateResponse, sliceForPagination, } from './pagination.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Employee endpoints
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* List all employees with optional filtering and pagination
|
|
14
|
+
*/
|
|
15
|
+
export async function listEmployees(options) {
|
|
16
|
+
const params = buildPaginationParams(options);
|
|
17
|
+
const cacheKey = CacheManager.key('employees', options);
|
|
18
|
+
// For filtered requests, we need to fetch all and filter client-side
|
|
19
|
+
// because the API doesn't reliably filter
|
|
20
|
+
if (options?.team_id || options?.location_id) {
|
|
21
|
+
const allEmployees = await cached('employees:all', () => fetchList('/employees/employees'), CACHE_TTL.employees);
|
|
22
|
+
let filtered = allEmployees;
|
|
23
|
+
if (options.team_id) {
|
|
24
|
+
filtered = filtered.filter(e => e.team_ids?.includes(options.team_id));
|
|
64
25
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return data;
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
clearTimeout(timeoutId);
|
|
71
|
-
if (error instanceof Error) {
|
|
72
|
-
if (error.name === 'AbortError') {
|
|
73
|
-
throw new Error(`Request timed out after ${DEFAULT_TIMEOUT / 1000} seconds. Please try again.`);
|
|
74
|
-
}
|
|
75
|
-
throw error;
|
|
26
|
+
if (options.location_id) {
|
|
27
|
+
filtered = filtered.filter(e => e.location_id === options.location_id);
|
|
76
28
|
}
|
|
77
|
-
|
|
29
|
+
return sliceForPagination(filtered, params);
|
|
78
30
|
}
|
|
31
|
+
// Without filters, use pagination directly
|
|
32
|
+
const employees = await cached(cacheKey, () => fetchList('/employees/employees', { params }), CACHE_TTL.employees);
|
|
33
|
+
return paginateResponse(employees, params.page, params.limit);
|
|
79
34
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return data.data || [];
|
|
84
|
-
}
|
|
35
|
+
/**
|
|
36
|
+
* Get a specific employee by ID
|
|
37
|
+
*/
|
|
85
38
|
export async function getEmployee(id) {
|
|
86
39
|
if (!id || id <= 0) {
|
|
87
40
|
throw new Error('Invalid employee ID. Please provide a positive number.');
|
|
88
41
|
}
|
|
89
|
-
|
|
90
|
-
return data.data;
|
|
42
|
+
return cached(`employee:${id}`, () => fetchOne(`/employees/employees/${id}`), CACHE_TTL.employees);
|
|
91
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Search employees by name or email
|
|
46
|
+
*/
|
|
92
47
|
export async function searchEmployees(query) {
|
|
93
48
|
if (!query || query.trim().length < 2) {
|
|
94
49
|
throw new Error('Search query must be at least 2 characters long.');
|
|
95
50
|
}
|
|
96
|
-
const
|
|
51
|
+
const allEmployees = await cached('employees:all', () => fetchList('/employees/employees'), CACHE_TTL.employees);
|
|
97
52
|
const lowerQuery = query.toLowerCase().trim();
|
|
98
|
-
return
|
|
53
|
+
return allEmployees.filter(emp => emp.full_name?.toLowerCase().includes(lowerQuery) ||
|
|
99
54
|
emp.email?.toLowerCase().includes(lowerQuery) ||
|
|
100
55
|
emp.first_name?.toLowerCase().includes(lowerQuery) ||
|
|
101
56
|
emp.last_name?.toLowerCase().includes(lowerQuery));
|
|
102
57
|
}
|
|
58
|
+
// ============================================================================
|
|
103
59
|
// Team endpoints
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
60
|
+
// ============================================================================
|
|
61
|
+
/**
|
|
62
|
+
* List all teams
|
|
63
|
+
*/
|
|
64
|
+
export async function listTeams(options) {
|
|
65
|
+
const params = buildPaginationParams(options);
|
|
66
|
+
const cacheKey = CacheManager.key('teams', options);
|
|
67
|
+
const teams = await cached(cacheKey, () => fetchList('/teams/teams'), CACHE_TTL.teams);
|
|
68
|
+
return sliceForPagination(teams, params);
|
|
107
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Get a specific team by ID
|
|
72
|
+
*/
|
|
108
73
|
export async function getTeam(id) {
|
|
109
74
|
if (!id || id <= 0) {
|
|
110
75
|
throw new Error('Invalid team ID. Please provide a positive number.');
|
|
111
76
|
}
|
|
112
|
-
|
|
113
|
-
return data.data;
|
|
77
|
+
return cached(`team:${id}`, () => fetchOne(`/teams/teams/${id}`), CACHE_TTL.teams);
|
|
114
78
|
}
|
|
79
|
+
// ============================================================================
|
|
115
80
|
// Location endpoints
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
81
|
+
// ============================================================================
|
|
82
|
+
/**
|
|
83
|
+
* List all locations
|
|
84
|
+
*/
|
|
85
|
+
export async function listLocations(options) {
|
|
86
|
+
const params = buildPaginationParams(options);
|
|
87
|
+
const cacheKey = CacheManager.key('locations', options);
|
|
88
|
+
const locations = await cached(cacheKey, () => fetchList('/locations/locations'), CACHE_TTL.locations);
|
|
89
|
+
return sliceForPagination(locations, params);
|
|
119
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Get a specific location by ID
|
|
93
|
+
*/
|
|
120
94
|
export async function getLocation(id) {
|
|
121
95
|
if (!id || id <= 0) {
|
|
122
96
|
throw new Error('Invalid location ID. Please provide a positive number.');
|
|
123
97
|
}
|
|
124
|
-
|
|
125
|
-
return data.data;
|
|
98
|
+
return cached(`location:${id}`, () => fetchOne(`/locations/locations/${id}`), CACHE_TTL.locations);
|
|
126
99
|
}
|
|
100
|
+
// ============================================================================
|
|
127
101
|
// Contract endpoints
|
|
128
|
-
|
|
102
|
+
// ============================================================================
|
|
103
|
+
/**
|
|
104
|
+
* List contracts, optionally filtered by employee ID
|
|
105
|
+
*/
|
|
106
|
+
export async function listContracts(employeeId, options) {
|
|
129
107
|
if (employeeId !== undefined && employeeId <= 0) {
|
|
130
108
|
throw new Error('Invalid employee ID. Please provide a positive number.');
|
|
131
109
|
}
|
|
132
|
-
const params =
|
|
133
|
-
|
|
134
|
-
|
|
110
|
+
const params = buildPaginationParams(options);
|
|
111
|
+
// Note: The API doesn't reliably filter by employee_id query param,
|
|
112
|
+
// so we fetch all contracts and filter client-side
|
|
113
|
+
const allContracts = await cached('contracts:all', () => fetchList('/contracts/contract-versions'), CACHE_TTL.contracts);
|
|
114
|
+
const filtered = employeeId !== undefined
|
|
115
|
+
? allContracts.filter(c => c.employee_id === employeeId)
|
|
116
|
+
: allContracts;
|
|
117
|
+
return sliceForPagination(filtered, params);
|
|
118
|
+
}
|
|
119
|
+
// ============================================================================
|
|
120
|
+
// Time Off / Leave endpoints
|
|
121
|
+
// ============================================================================
|
|
122
|
+
/**
|
|
123
|
+
* List leaves with optional filtering
|
|
124
|
+
*/
|
|
125
|
+
export async function listLeaves(options) {
|
|
126
|
+
const params = buildPaginationParams(options);
|
|
127
|
+
const queryParams = {
|
|
128
|
+
page: params.page,
|
|
129
|
+
limit: params.limit,
|
|
130
|
+
};
|
|
131
|
+
if (options?.employee_id)
|
|
132
|
+
queryParams.employee_id = options.employee_id;
|
|
133
|
+
if (options?.status)
|
|
134
|
+
queryParams.status = options.status;
|
|
135
|
+
if (options?.start_on_gte)
|
|
136
|
+
queryParams.start_on_gte = options.start_on_gte;
|
|
137
|
+
if (options?.start_on_lte)
|
|
138
|
+
queryParams.start_on_lte = options.start_on_lte;
|
|
139
|
+
const leaves = await fetchList('/timeoff/leaves', { params: queryParams });
|
|
140
|
+
return paginateResponse(leaves, params.page, params.limit);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get a specific leave by ID
|
|
144
|
+
*/
|
|
145
|
+
export async function getLeave(id) {
|
|
146
|
+
if (!id || id <= 0) {
|
|
147
|
+
throw new Error('Invalid leave ID. Please provide a positive number.');
|
|
148
|
+
}
|
|
149
|
+
return fetchOne(`/timeoff/leaves/${id}`);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* List all leave types
|
|
153
|
+
*/
|
|
154
|
+
export async function listLeaveTypes() {
|
|
155
|
+
return cached('leave-types:all', () => fetchList('/timeoff/leave-types'), CACHE_TTL.leaves);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get a specific leave type by ID
|
|
159
|
+
*/
|
|
160
|
+
export async function getLeaveType(id) {
|
|
161
|
+
if (!id || id <= 0) {
|
|
162
|
+
throw new Error('Invalid leave type ID. Please provide a positive number.');
|
|
163
|
+
}
|
|
164
|
+
return fetchOne(`/timeoff/leave-types/${id}`);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* List allowances with optional filtering by employee
|
|
168
|
+
*/
|
|
169
|
+
export async function listAllowances(options) {
|
|
170
|
+
const params = buildPaginationParams(options);
|
|
171
|
+
const queryParams = {
|
|
172
|
+
page: params.page,
|
|
173
|
+
limit: params.limit,
|
|
174
|
+
};
|
|
175
|
+
if (options?.employee_id)
|
|
176
|
+
queryParams.employee_id = options.employee_id;
|
|
177
|
+
const allowances = await fetchList('/timeoff/allowances', { params: queryParams });
|
|
178
|
+
return paginateResponse(allowances, params.page, params.limit);
|
|
179
|
+
}
|
|
180
|
+
// ============================================================================
|
|
181
|
+
// Attendance / Shifts endpoints
|
|
182
|
+
// ============================================================================
|
|
183
|
+
/**
|
|
184
|
+
* List shifts with optional filtering
|
|
185
|
+
*/
|
|
186
|
+
export async function listShifts(options) {
|
|
187
|
+
const params = buildPaginationParams(options);
|
|
188
|
+
const queryParams = {
|
|
189
|
+
page: params.page,
|
|
190
|
+
limit: params.limit,
|
|
191
|
+
};
|
|
192
|
+
if (options?.employee_id)
|
|
193
|
+
queryParams.employee_id = options.employee_id;
|
|
194
|
+
if (options?.clock_in_gte)
|
|
195
|
+
queryParams.clock_in_gte = options.clock_in_gte;
|
|
196
|
+
if (options?.clock_in_lte)
|
|
197
|
+
queryParams.clock_in_lte = options.clock_in_lte;
|
|
198
|
+
const shifts = await fetchList('/attendance/shifts', { params: queryParams });
|
|
199
|
+
return paginateResponse(shifts, params.page, params.limit);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get a specific shift by ID
|
|
203
|
+
*/
|
|
204
|
+
export async function getShift(id) {
|
|
205
|
+
if (!id || id <= 0) {
|
|
206
|
+
throw new Error('Invalid shift ID. Please provide a positive number.');
|
|
207
|
+
}
|
|
208
|
+
return fetchOne(`/attendance/shifts/${id}`);
|
|
209
|
+
}
|
|
210
|
+
// ============================================================================
|
|
211
|
+
// Document endpoints (Read-only)
|
|
212
|
+
// ============================================================================
|
|
213
|
+
/**
|
|
214
|
+
* List all folders
|
|
215
|
+
*/
|
|
216
|
+
export async function listFolders() {
|
|
217
|
+
return cached('folders:all', () => fetchList('/documents/folders'), CACHE_TTL.default);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get a specific folder by ID
|
|
221
|
+
*/
|
|
222
|
+
export async function getFolder(id) {
|
|
223
|
+
if (!id || id <= 0) {
|
|
224
|
+
throw new Error('Invalid folder ID. Please provide a positive number.');
|
|
225
|
+
}
|
|
226
|
+
return fetchOne(`/documents/folders/${id}`);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* List documents with optional filtering by folder
|
|
230
|
+
*/
|
|
231
|
+
export async function listDocuments(options) {
|
|
232
|
+
const params = buildPaginationParams(options);
|
|
233
|
+
const queryParams = {
|
|
234
|
+
page: params.page,
|
|
235
|
+
limit: params.limit,
|
|
236
|
+
};
|
|
237
|
+
if (options?.folder_id)
|
|
238
|
+
queryParams.folder_id = options.folder_id;
|
|
239
|
+
const documents = await fetchList('/documents/documents', { params: queryParams });
|
|
240
|
+
return paginateResponse(documents, params.page, params.limit);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Get a specific document by ID
|
|
244
|
+
*/
|
|
245
|
+
export async function getDocument(id) {
|
|
246
|
+
if (!id || id <= 0) {
|
|
247
|
+
throw new Error('Invalid document ID. Please provide a positive number.');
|
|
248
|
+
}
|
|
249
|
+
return fetchOne(`/documents/documents/${id}`);
|
|
250
|
+
}
|
|
251
|
+
// ============================================================================
|
|
252
|
+
// Job Catalog endpoints
|
|
253
|
+
// ============================================================================
|
|
254
|
+
/**
|
|
255
|
+
* List all job roles
|
|
256
|
+
*/
|
|
257
|
+
export async function listJobRoles() {
|
|
258
|
+
return cached('job-roles:all', () => fetchList('/job_catalog/roles'), CACHE_TTL.default);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Get a specific job role by ID
|
|
262
|
+
*/
|
|
263
|
+
export async function getJobRole(id) {
|
|
264
|
+
if (!id || id <= 0) {
|
|
265
|
+
throw new Error('Invalid job role ID. Please provide a positive number.');
|
|
266
|
+
}
|
|
267
|
+
return fetchOne(`/job_catalog/roles/${id}`);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* List all job levels
|
|
271
|
+
*/
|
|
272
|
+
export async function listJobLevels() {
|
|
273
|
+
return cached('job-levels:all', () => fetchList('/job_catalog/levels'), CACHE_TTL.default);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Get a specific job level by ID
|
|
277
|
+
*/
|
|
278
|
+
export async function getJobLevel(id) {
|
|
279
|
+
if (!id || id <= 0) {
|
|
280
|
+
throw new Error('Invalid job level ID. Please provide a positive number.');
|
|
281
|
+
}
|
|
282
|
+
return fetchOne(`/job_catalog/levels/${id}`);
|
|
283
|
+
}
|
|
284
|
+
// ============================================================================
|
|
285
|
+
// Cache utilities
|
|
286
|
+
// ============================================================================
|
|
287
|
+
/**
|
|
288
|
+
* Invalidate all cached data
|
|
289
|
+
*/
|
|
290
|
+
export function clearCache() {
|
|
291
|
+
cache.clear();
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Invalidate cached data for a specific resource type
|
|
295
|
+
*/
|
|
296
|
+
export function invalidateCache(resourceType) {
|
|
297
|
+
cache.invalidatePrefix(resourceType);
|
|
135
298
|
}
|
|
136
299
|
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple in-memory TTL cache for MCP FactorialHR
|
|
3
|
+
*
|
|
4
|
+
* Reduces API calls by caching frequently accessed data.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* TTL values for different resource types (in milliseconds)
|
|
8
|
+
*/
|
|
9
|
+
export declare const CACHE_TTL: {
|
|
10
|
+
readonly employees: number;
|
|
11
|
+
readonly teams: number;
|
|
12
|
+
readonly locations: number;
|
|
13
|
+
readonly contracts: number;
|
|
14
|
+
readonly leaves: number;
|
|
15
|
+
readonly shifts: number;
|
|
16
|
+
readonly default: number;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Resource types for TTL lookup
|
|
20
|
+
*/
|
|
21
|
+
export type ResourceType = keyof typeof CACHE_TTL;
|
|
22
|
+
/**
|
|
23
|
+
* Simple TTL-based cache manager
|
|
24
|
+
*/
|
|
25
|
+
export declare class CacheManager {
|
|
26
|
+
private cache;
|
|
27
|
+
private cleanupInterval;
|
|
28
|
+
constructor();
|
|
29
|
+
/**
|
|
30
|
+
* Generate a cache key from resource type and parameters
|
|
31
|
+
*/
|
|
32
|
+
static key(resource: string, params?: object): string;
|
|
33
|
+
/**
|
|
34
|
+
* Get a value from the cache
|
|
35
|
+
* @returns The cached value or undefined if not found/expired
|
|
36
|
+
*/
|
|
37
|
+
get<T>(key: string): T | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Set a value in the cache
|
|
40
|
+
* @param key - Cache key
|
|
41
|
+
* @param data - Data to cache
|
|
42
|
+
* @param ttlMs - Time to live in milliseconds
|
|
43
|
+
*/
|
|
44
|
+
set<T>(key: string, data: T, ttlMs?: number): void;
|
|
45
|
+
/**
|
|
46
|
+
* Invalidate a specific cache entry
|
|
47
|
+
*/
|
|
48
|
+
invalidate(key: string): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Invalidate all cache entries matching a prefix
|
|
51
|
+
*/
|
|
52
|
+
invalidatePrefix(prefix: string): number;
|
|
53
|
+
/**
|
|
54
|
+
* Clear all cache entries
|
|
55
|
+
*/
|
|
56
|
+
clear(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Get cache statistics
|
|
59
|
+
*/
|
|
60
|
+
stats(): {
|
|
61
|
+
size: number;
|
|
62
|
+
keys: string[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Remove expired entries
|
|
66
|
+
*/
|
|
67
|
+
private cleanup;
|
|
68
|
+
/**
|
|
69
|
+
* Stop the cleanup interval (for testing/cleanup)
|
|
70
|
+
*/
|
|
71
|
+
destroy(): void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Global cache instance
|
|
75
|
+
*/
|
|
76
|
+
export declare const cache: CacheManager;
|
|
77
|
+
/**
|
|
78
|
+
* Helper to get cached data or fetch it
|
|
79
|
+
* @param key - Cache key
|
|
80
|
+
* @param fetcher - Function to fetch data if not cached
|
|
81
|
+
* @param ttlMs - Time to live in milliseconds
|
|
82
|
+
*/
|
|
83
|
+
export declare function cached<T>(key: string, fetcher: () => Promise<T>, ttlMs?: number): Promise<T>;
|
|
84
|
+
/**
|
|
85
|
+
* Get the TTL for a resource type
|
|
86
|
+
*/
|
|
87
|
+
export declare function getTTL(resourceType: ResourceType): number;
|
|
88
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH;;GAEG;AACH,eAAO,MAAM,SAAS;;;;;;;;CAQZ,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,SAAS,CAAC;AAElD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA0C;IACvD,OAAO,CAAC,eAAe,CAA+C;;IAOtE;;OAEG;IACH,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAcrD;;;OAGG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAgBlC;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,GAAE,MAA0B,GAAG,IAAI;IAQrE;;OAEG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQhC;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAcxC;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,KAAK,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE;IAOzC;;OAEG;IACH,OAAO,CAAC,OAAO;IAcf;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB;AAED;;GAEG;AACH,eAAO,MAAM,KAAK,cAAqB,CAAC;AAExC;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,KAAK,GAAE,MAA0B,GAChC,OAAO,CAAC,CAAC,CAAC,CASZ;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAEzD"}
|