@medyll/idae-api 0.137.0 → 0.139.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 (47) hide show
  1. package/README.md +61 -0
  2. package/dist/__tests__/README.md +583 -0
  3. package/dist/__tests__/fixtures/mockData.d.ts +219 -0
  4. package/dist/__tests__/fixtures/mockData.js +243 -0
  5. package/dist/__tests__/helpers/testUtils.d.ts +153 -0
  6. package/dist/__tests__/helpers/testUtils.js +328 -0
  7. package/dist/client/IdaeApiClient.d.ts +7 -0
  8. package/dist/client/IdaeApiClient.js +15 -2
  9. package/dist/client/IdaeApiClientCollection.d.ts +17 -9
  10. package/dist/client/IdaeApiClientCollection.js +32 -11
  11. package/dist/client/IdaeApiClientConfig.d.ts +2 -0
  12. package/dist/client/IdaeApiClientConfig.js +10 -2
  13. package/dist/client/IdaeApiClientRequest.js +30 -15
  14. package/dist/config/routeDefinitions.d.ts +8 -0
  15. package/dist/config/routeDefinitions.js +63 -15
  16. package/dist/index.d.ts +10 -0
  17. package/dist/index.js +10 -0
  18. package/dist/openApi/redoc.html +12 -0
  19. package/dist/openApi/swagger-ui.html +23 -0
  20. package/dist/server/IdaeApi.d.ts +15 -0
  21. package/dist/server/IdaeApi.js +94 -22
  22. package/dist/server/engine/requestDatabaseManager.d.ts +1 -1
  23. package/dist/server/engine/requestDatabaseManager.js +6 -10
  24. package/dist/server/engine/routeManager.d.ts +1 -0
  25. package/dist/server/engine/routeManager.js +33 -17
  26. package/dist/server/middleware/README.md +46 -0
  27. package/dist/server/middleware/authMiddleware.d.ts +63 -0
  28. package/dist/server/middleware/authMiddleware.js +121 -12
  29. package/dist/server/middleware/authorizationMiddleware.d.ts +18 -0
  30. package/dist/server/middleware/authorizationMiddleware.js +38 -0
  31. package/dist/server/middleware/databaseMiddleware.d.ts +6 -1
  32. package/dist/server/middleware/databaseMiddleware.js +111 -6
  33. package/dist/server/middleware/docsMiddleware.d.ts +13 -0
  34. package/dist/server/middleware/docsMiddleware.js +30 -0
  35. package/dist/server/middleware/healthMiddleware.d.ts +15 -0
  36. package/dist/server/middleware/healthMiddleware.js +19 -0
  37. package/dist/server/middleware/mcpMiddleware.d.ts +10 -0
  38. package/dist/server/middleware/mcpMiddleware.js +14 -0
  39. package/dist/server/middleware/openApiMiddleware.d.ts +7 -0
  40. package/dist/server/middleware/openApiMiddleware.js +20 -0
  41. package/dist/server/middleware/tenantContextMiddleware.d.ts +25 -0
  42. package/dist/server/middleware/tenantContextMiddleware.js +31 -0
  43. package/dist/server/middleware/validationLayer.d.ts +8 -0
  44. package/dist/server/middleware/validationLayer.js +23 -0
  45. package/dist/server/middleware/validationMiddleware.d.ts +16 -0
  46. package/dist/server/middleware/validationMiddleware.js +30 -0
  47. package/package.json +18 -4
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Test Fixtures & Mock Data
3
+ * Centralized test data for consistent test scenarios
4
+ */
5
+ export declare const mockUsers: {
6
+ id: string;
7
+ name: string;
8
+ email: string;
9
+ role: string;
10
+ age: number;
11
+ active: boolean;
12
+ createdAt: string;
13
+ }[];
14
+ export declare const mockPosts: {
15
+ id: string;
16
+ title: string;
17
+ content: string;
18
+ authorId: string;
19
+ published: boolean;
20
+ createdAt: string;
21
+ }[];
22
+ export declare const mockComments: {
23
+ id: string;
24
+ text: string;
25
+ postId: string;
26
+ authorId: string;
27
+ createdAt: string;
28
+ }[];
29
+ export declare const mockTokens: {
30
+ valid: {
31
+ admin: string;
32
+ user: string;
33
+ expired: string;
34
+ };
35
+ invalid: {
36
+ malformed: string;
37
+ tampered: string;
38
+ none: string;
39
+ };
40
+ };
41
+ export declare const mockSQLInjectionPayloads: string[];
42
+ export declare const mockNoSQLInjectionPayloads: ({
43
+ $ne: null;
44
+ $where?: undefined;
45
+ $function?: undefined;
46
+ $regex?: undefined;
47
+ $gt?: undefined;
48
+ } | {
49
+ $where: string;
50
+ $ne?: undefined;
51
+ $function?: undefined;
52
+ $regex?: undefined;
53
+ $gt?: undefined;
54
+ } | {
55
+ $function: {
56
+ body: string;
57
+ args: string[];
58
+ lang: string;
59
+ };
60
+ $ne?: undefined;
61
+ $where?: undefined;
62
+ $regex?: undefined;
63
+ $gt?: undefined;
64
+ } | {
65
+ $regex: string;
66
+ $ne?: undefined;
67
+ $where?: undefined;
68
+ $function?: undefined;
69
+ $gt?: undefined;
70
+ } | {
71
+ $gt: string;
72
+ $ne?: undefined;
73
+ $where?: undefined;
74
+ $function?: undefined;
75
+ $regex?: undefined;
76
+ })[];
77
+ export declare const mockXSSPayloads: string[];
78
+ export declare const mockCSRFPayloads: ({
79
+ csrfToken: string;
80
+ _token?: undefined;
81
+ 'x-csrf-token'?: undefined;
82
+ } | {
83
+ _token: string;
84
+ csrfToken?: undefined;
85
+ 'x-csrf-token'?: undefined;
86
+ } | {
87
+ 'x-csrf-token': string;
88
+ csrfToken?: undefined;
89
+ _token?: undefined;
90
+ })[];
91
+ export declare const mockEdgeCasesData: {
92
+ veryLongString: string;
93
+ unicodeChars: string;
94
+ specialChars: string;
95
+ nullByte: string;
96
+ newlines: string;
97
+ tabs: string;
98
+ };
99
+ export declare const mockDatabaseConfigs: {
100
+ mongodb: {
101
+ host: string;
102
+ port: number;
103
+ dbName: string;
104
+ uri: string;
105
+ };
106
+ mysql: {
107
+ host: string;
108
+ port: number;
109
+ dbName: string;
110
+ uri: string;
111
+ };
112
+ };
113
+ export declare const mockErrorResponses: {
114
+ unauthorized: {
115
+ status: number;
116
+ body: {
117
+ error: string;
118
+ message: string;
119
+ };
120
+ };
121
+ forbidden: {
122
+ status: number;
123
+ body: {
124
+ error: string;
125
+ message: string;
126
+ };
127
+ };
128
+ notFound: {
129
+ status: number;
130
+ body: {
131
+ error: string;
132
+ message: string;
133
+ };
134
+ };
135
+ badRequest: {
136
+ status: number;
137
+ body: {
138
+ error: string;
139
+ message: string;
140
+ };
141
+ };
142
+ internalError: {
143
+ status: number;
144
+ body: {
145
+ error: string;
146
+ message: string;
147
+ };
148
+ };
149
+ serviceUnavailable: {
150
+ status: number;
151
+ body: {
152
+ error: string;
153
+ message: string;
154
+ };
155
+ };
156
+ };
157
+ export declare const mockMiddlewareContext: {
158
+ req: {
159
+ headers: {};
160
+ params: {};
161
+ query: {};
162
+ body: {};
163
+ };
164
+ res: {
165
+ statusCode: number;
166
+ headers: {};
167
+ body: null;
168
+ };
169
+ next: () => void;
170
+ };
171
+ /**
172
+ * Helper to create mock request with standard properties
173
+ */
174
+ export declare function createMockRequest(overrides?: any): any;
175
+ /**
176
+ * Helper to create mock response with standard methods
177
+ */
178
+ export declare function createMockResponse(): {
179
+ status: (code: number) => {
180
+ json: (data: any) => {};
181
+ };
182
+ json: (data: any) => {};
183
+ send: (data: any) => {};
184
+ statusCode: number;
185
+ responseData: any;
186
+ };
187
+ /**
188
+ * Helper to create mock IdaeDb instance
189
+ */
190
+ export declare function createMockIdaeDb(): {
191
+ init: (uri: string, options: any) => Promise<{
192
+ db: (dbName: string) => Promise<{
193
+ collection: (collectionName: string) => Promise<{
194
+ find: (filter?: any) => Promise<{
195
+ id: string;
196
+ name: string;
197
+ email: string;
198
+ role: string;
199
+ age: number;
200
+ active: boolean;
201
+ createdAt: string;
202
+ }[]>;
203
+ findById: (id: string) => Promise<{
204
+ id: string;
205
+ name: string;
206
+ email: string;
207
+ role: string;
208
+ age: number;
209
+ active: boolean;
210
+ createdAt: string;
211
+ } | null>;
212
+ create: (data: any) => Promise<any>;
213
+ update: (id: string, data: any) => Promise<any>;
214
+ deleteById: (id: string) => Promise<undefined>;
215
+ deleteWhere: (filter: any) => Promise<number>;
216
+ }>;
217
+ }>;
218
+ }>;
219
+ };
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Test Fixtures & Mock Data
3
+ * Centralized test data for consistent test scenarios
4
+ */
5
+ export const mockUsers = [
6
+ {
7
+ id: '1',
8
+ name: 'Alice Johnson',
9
+ email: 'alice@example.com',
10
+ role: 'admin',
11
+ age: 28,
12
+ active: true,
13
+ createdAt: '2026-01-01T00:00:00Z'
14
+ },
15
+ {
16
+ id: '2',
17
+ name: 'Bob Smith',
18
+ email: 'bob@example.com',
19
+ role: 'user',
20
+ age: 25,
21
+ active: true,
22
+ createdAt: '2026-01-02T00:00:00Z'
23
+ },
24
+ {
25
+ id: '3',
26
+ name: 'Charlie Brown',
27
+ email: 'charlie@example.com',
28
+ role: 'user',
29
+ age: 32,
30
+ active: false,
31
+ createdAt: '2026-01-03T00:00:00Z'
32
+ }
33
+ ];
34
+ export const mockPosts = [
35
+ {
36
+ id: '1',
37
+ title: 'First Post',
38
+ content: 'This is the first post',
39
+ authorId: '1',
40
+ published: true,
41
+ createdAt: '2026-01-10T00:00:00Z'
42
+ },
43
+ {
44
+ id: '2',
45
+ title: 'Second Post',
46
+ content: 'This is the second post',
47
+ authorId: '2',
48
+ published: false,
49
+ createdAt: '2026-01-11T00:00:00Z'
50
+ }
51
+ ];
52
+ export const mockComments = [
53
+ {
54
+ id: '1',
55
+ text: 'Great post!',
56
+ postId: '1',
57
+ authorId: '2',
58
+ createdAt: '2026-01-10T12:00:00Z'
59
+ },
60
+ {
61
+ id: '2',
62
+ text: 'I agree',
63
+ postId: '1',
64
+ authorId: '3',
65
+ createdAt: '2026-01-10T13:00:00Z'
66
+ }
67
+ ];
68
+ export const mockTokens = {
69
+ valid: {
70
+ admin: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIn0.mock',
71
+ user: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciJ9.mock',
72
+ expired: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJleHAiOjE2MDAwMDAwMDB9.mock'
73
+ },
74
+ invalid: {
75
+ malformed: 'not.a.token',
76
+ tampered: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImhhY2tlciIsInJvbGUiOiJhZG1pbiJ9.wrong',
77
+ none: 'eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VybmFtZSI6ImhheGVyIn0.'
78
+ }
79
+ };
80
+ export const mockSQLInjectionPayloads = [
81
+ "'; DROP TABLE users; --",
82
+ "1' OR '1'='1",
83
+ "admin'--",
84
+ "1; DELETE FROM users; --",
85
+ "' OR 1=1 --"
86
+ ];
87
+ export const mockNoSQLInjectionPayloads = [
88
+ { $ne: null },
89
+ { $where: 'function() { return true }' },
90
+ { $function: { body: 'function(x) { return true }', args: ['$field'], lang: 'js' } },
91
+ { $regex: '.*' },
92
+ { $gt: '' }
93
+ ];
94
+ export const mockXSSPayloads = [
95
+ '<script>alert("XSS")</script>',
96
+ '<img src=x onerror="alert(\'XSS\')">',
97
+ '<svg onload="alert(\'XSS\')">',
98
+ 'javascript:alert("XSS")',
99
+ '<iframe src="javascript:alert(\'XSS\')">',
100
+ '<body onload="alert(\'XSS\')">',
101
+ '<input onfocus="alert(\'XSS\')" autofocus>',
102
+ '<marquee onstart="alert(\'XSS\')">'
103
+ ];
104
+ export const mockCSRFPayloads = [
105
+ { csrfToken: 'forged' },
106
+ { _token: 'invalid' },
107
+ { 'x-csrf-token': 'wrong' }
108
+ ];
109
+ export const mockEdgeCasesData = {
110
+ veryLongString: 'a'.repeat(10000),
111
+ unicodeChars: '你好世界🚀',
112
+ specialChars: "!@#$%^&*()_+-=[]{}|;':\",./<>?",
113
+ nullByte: 'test\x00value',
114
+ newlines: 'line1\nline2\rline3\r\nline4',
115
+ tabs: 'col1\tcol2\tcol3'
116
+ };
117
+ export const mockDatabaseConfigs = {
118
+ mongodb: {
119
+ host: 'localhost',
120
+ port: 27017,
121
+ dbName: 'testdb',
122
+ uri: 'mongodb://localhost:27017/testdb'
123
+ },
124
+ mysql: {
125
+ host: 'localhost',
126
+ port: 3306,
127
+ dbName: 'testdb',
128
+ uri: 'mysql://localhost:3306/testdb'
129
+ }
130
+ };
131
+ export const mockErrorResponses = {
132
+ unauthorized: {
133
+ status: 401,
134
+ body: { error: 'Unauthorized', message: 'No Authorization header provided' }
135
+ },
136
+ forbidden: {
137
+ status: 403,
138
+ body: { error: 'Forbidden', message: 'Insufficient permissions' }
139
+ },
140
+ notFound: {
141
+ status: 404,
142
+ body: { error: 'Not Found', message: 'Resource not found' }
143
+ },
144
+ badRequest: {
145
+ status: 400,
146
+ body: { error: 'Bad Request', message: 'Invalid request parameters' }
147
+ },
148
+ internalError: {
149
+ status: 500,
150
+ body: { error: 'Internal Server Error', message: 'An unexpected error occurred' }
151
+ },
152
+ serviceUnavailable: {
153
+ status: 503,
154
+ body: { error: 'Service Unavailable', message: 'Database connection failed' }
155
+ }
156
+ };
157
+ export const mockMiddlewareContext = {
158
+ req: {
159
+ headers: {},
160
+ params: {},
161
+ query: {},
162
+ body: {}
163
+ },
164
+ res: {
165
+ statusCode: 200,
166
+ headers: {},
167
+ body: null
168
+ },
169
+ next: () => { }
170
+ };
171
+ /**
172
+ * Helper to create mock request with standard properties
173
+ */
174
+ export function createMockRequest(overrides = {}) {
175
+ return {
176
+ headers: {},
177
+ params: {},
178
+ query: {},
179
+ body: {},
180
+ user: { username: 'testuser' },
181
+ idaeDb: undefined,
182
+ dbName: undefined,
183
+ collectionName: undefined,
184
+ connectedCollection: undefined,
185
+ ...overrides
186
+ };
187
+ }
188
+ /**
189
+ * Helper to create mock response with standard methods
190
+ */
191
+ export function createMockResponse() {
192
+ let statusCode = 200;
193
+ let responseData;
194
+ return {
195
+ status: (code) => {
196
+ statusCode = code;
197
+ return {
198
+ json: (data) => {
199
+ responseData = data;
200
+ return {};
201
+ }
202
+ };
203
+ },
204
+ json: (data) => {
205
+ responseData = data;
206
+ return {};
207
+ },
208
+ send: (data) => {
209
+ responseData = data;
210
+ return {};
211
+ },
212
+ statusCode,
213
+ responseData
214
+ };
215
+ }
216
+ /**
217
+ * Helper to create mock IdaeDb instance
218
+ */
219
+ export function createMockIdaeDb() {
220
+ return {
221
+ init: async (uri, options) => {
222
+ return {
223
+ db: async (dbName) => {
224
+ return {
225
+ collection: async (collectionName) => {
226
+ return {
227
+ find: async (filter) => mockUsers.filter(u => u.role === filter?.role || true),
228
+ findById: async (id) => mockUsers.find(u => u.id === id) || null,
229
+ create: async (data) => ({ id: '4', ...data }),
230
+ update: async (id, data) => ({
231
+ ...mockUsers.find(u => u.id === id),
232
+ ...data
233
+ }),
234
+ deleteById: async (id) => undefined,
235
+ deleteWhere: async (filter) => 1
236
+ };
237
+ }
238
+ };
239
+ }
240
+ };
241
+ }
242
+ };
243
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Test Utilities & Helpers
3
+ * Common patterns and utilities for consistent testing
4
+ */
5
+ /**
6
+ * Generate a mock JWT token for testing
7
+ */
8
+ export declare function generateMockToken(payload?: any, secret?: string, expiresIn?: string): never;
9
+ /**
10
+ * Create a mock Express Request object
11
+ */
12
+ export declare function createMockRequest(overrides?: any): any;
13
+ /**
14
+ * Create a mock Express Response object
15
+ */
16
+ export declare function createMockResponse(): {
17
+ status: (code: number) => {
18
+ json: (data: any) => {};
19
+ send: (data: any) => {};
20
+ };
21
+ json: (data: any) => {};
22
+ send: (data: any) => {};
23
+ setHeader: (key: string, value: string) => {};
24
+ getHeader: (key: string) => string | undefined;
25
+ getStatusCode: () => number;
26
+ getResponseData: () => any;
27
+ statusCode: number;
28
+ responseData: any;
29
+ headers: Map<string, string>;
30
+ };
31
+ /**
32
+ * Create a mock NextFunction
33
+ */
34
+ export declare function createMockNextFunction(): import("vitest").Mock<(err?: any) => void>;
35
+ /**
36
+ * Create a complete mock middleware context
37
+ */
38
+ export declare function createMockMiddlewareContext(overrides?: any): {
39
+ req: any;
40
+ res: {
41
+ status: (code: number) => {
42
+ json: (data: any) => {};
43
+ send: (data: any) => {};
44
+ };
45
+ json: (data: any) => {};
46
+ send: (data: any) => {};
47
+ setHeader: (key: string, value: string) => {};
48
+ getHeader: (key: string) => string | undefined;
49
+ getStatusCode: () => number;
50
+ getResponseData: () => any;
51
+ statusCode: number;
52
+ responseData: any;
53
+ headers: Map<string, string>;
54
+ };
55
+ next: import("vitest").Mock<(err?: any) => void>;
56
+ };
57
+ /**
58
+ * Wait for async operations to complete
59
+ */
60
+ export declare function waitFor(condition: () => boolean, timeout?: number): Promise<void>;
61
+ /**
62
+ * Create a mock IdaeDb collection adapter
63
+ */
64
+ export declare function createMockCollection(defaultData?: any[]): {
65
+ find: import("vitest").Mock<(filter?: any) => Promise<any[]>>;
66
+ findById: import("vitest").Mock<(id: string) => Promise<any>>;
67
+ findAll: import("vitest").Mock<() => Promise<any[]>>;
68
+ create: import("vitest").Mock<(data: any) => Promise<any>>;
69
+ update: import("vitest").Mock<(id: string, data: any) => Promise<any>>;
70
+ deleteById: import("vitest").Mock<(id: string) => Promise<void>>;
71
+ deleteWhere: import("vitest").Mock<(filter: any) => Promise<number>>;
72
+ };
73
+ /**
74
+ * Create a mock IdaeDb database adapter
75
+ */
76
+ export declare function createMockIdaeDb(collections?: Record<string, any>): {
77
+ init: import("vitest").Mock<(uri: string, options: any) => Promise<{
78
+ db: import("vitest").Mock<(dbName: string) => Promise<{
79
+ collection: import("vitest").Mock<(collectionName: string) => any>;
80
+ }>>;
81
+ }>>;
82
+ collection: import("vitest").Mock<(collectionName: string) => any>;
83
+ };
84
+ /**
85
+ * Create a mock HTTP fetch response
86
+ */
87
+ export declare function createMockFetchResponse(data?: any, options?: any): Promise<{
88
+ ok: boolean;
89
+ status: any;
90
+ headers: Map<unknown, unknown>;
91
+ json: () => Promise<any>;
92
+ text: () => Promise<string>;
93
+ blob: () => Promise<Blob>;
94
+ clone: () => Promise</*elided*/ any>;
95
+ }>;
96
+ /**
97
+ * Assert that a middleware was called with specific arguments
98
+ */
99
+ export declare function assertMiddlewareCalled(middleware: any, argIndex: number, expected: any): void;
100
+ /**
101
+ * Mock an external module
102
+ */
103
+ export declare function mockModule(moduleName: string, implementation: any): void;
104
+ /**
105
+ * Restore all mocks
106
+ */
107
+ export declare function resetAllMocks(): void;
108
+ /**
109
+ * Create a test database URI
110
+ */
111
+ export declare function createTestDatabaseUri(dbType?: string, dbName?: string): string;
112
+ /**
113
+ * Extract bearer token from Authorization header
114
+ */
115
+ export declare function extractBearerToken(authHeader?: string): string | null;
116
+ /**
117
+ * Validate token format
118
+ */
119
+ export declare function isValidTokenFormat(token: string): boolean;
120
+ /**
121
+ * Create assertion helpers for common patterns
122
+ */
123
+ export declare const testAssertions: {
124
+ /**
125
+ * Assert middleware sets status code
126
+ */
127
+ statusCode: (res: any, expectedCode: number) => void;
128
+ /**
129
+ * Assert middleware sets Authorization header
130
+ */
131
+ hasAuthHeader: (req: any) => void;
132
+ /**
133
+ * Assert response has error
134
+ */
135
+ hasError: (res: any) => void;
136
+ /**
137
+ * Assert response has success data
138
+ */
139
+ hasData: (res: any) => void;
140
+ };
141
+ /**
142
+ * Performance testing helper
143
+ */
144
+ export declare function measurePerformance(fn: () => Promise<any>, iterations?: number): Promise<{
145
+ average: number;
146
+ min: number;
147
+ max: number;
148
+ times: number[];
149
+ }>;
150
+ /**
151
+ * Test data sanitizer - remove sensitive info before assertions
152
+ */
153
+ export declare function sanitizeForAssertion(data: any, keysToRemove?: string[]): any;