@studious-lms/server 1.0.6 → 1.0.8

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 (115) hide show
  1. package/API_SPECIFICATION.md +1461 -0
  2. package/dist/exportType.d.ts +3 -3
  3. package/dist/exportType.d.ts.map +1 -1
  4. package/dist/exportType.js +1 -2
  5. package/dist/index.js +25 -30
  6. package/dist/lib/fileUpload.d.ts.map +1 -1
  7. package/dist/lib/fileUpload.js +31 -29
  8. package/dist/lib/googleCloudStorage.js +9 -14
  9. package/dist/lib/prisma.js +4 -7
  10. package/dist/lib/thumbnailGenerator.js +12 -20
  11. package/dist/middleware/auth.d.ts.map +1 -1
  12. package/dist/middleware/auth.js +17 -22
  13. package/dist/middleware/logging.js +5 -9
  14. package/dist/routers/_app.d.ts +3619 -1937
  15. package/dist/routers/_app.d.ts.map +1 -1
  16. package/dist/routers/_app.js +28 -27
  17. package/dist/routers/agenda.d.ts +14 -9
  18. package/dist/routers/agenda.d.ts.map +1 -1
  19. package/dist/routers/agenda.js +14 -17
  20. package/dist/routers/announcement.d.ts +5 -4
  21. package/dist/routers/announcement.d.ts.map +1 -1
  22. package/dist/routers/announcement.js +28 -31
  23. package/dist/routers/assignment.d.ts +283 -197
  24. package/dist/routers/assignment.d.ts.map +1 -1
  25. package/dist/routers/assignment.js +256 -202
  26. package/dist/routers/attendance.d.ts +6 -5
  27. package/dist/routers/attendance.d.ts.map +1 -1
  28. package/dist/routers/attendance.js +31 -34
  29. package/dist/routers/auth.d.ts +2 -1
  30. package/dist/routers/auth.d.ts.map +1 -1
  31. package/dist/routers/auth.js +80 -75
  32. package/dist/routers/class.d.ts +285 -15
  33. package/dist/routers/class.d.ts.map +1 -1
  34. package/dist/routers/class.js +440 -164
  35. package/dist/routers/event.d.ts +48 -39
  36. package/dist/routers/event.d.ts.map +1 -1
  37. package/dist/routers/event.js +76 -79
  38. package/dist/routers/file.d.ts +72 -2
  39. package/dist/routers/file.d.ts.map +1 -1
  40. package/dist/routers/file.js +260 -32
  41. package/dist/routers/folder.d.ts +296 -0
  42. package/dist/routers/folder.d.ts.map +1 -0
  43. package/dist/routers/folder.js +693 -0
  44. package/dist/routers/notifications.d.ts +103 -0
  45. package/dist/routers/notifications.d.ts.map +1 -0
  46. package/dist/routers/notifications.js +91 -0
  47. package/dist/routers/school.d.ts +208 -0
  48. package/dist/routers/school.d.ts.map +1 -0
  49. package/dist/routers/school.js +481 -0
  50. package/dist/routers/section.d.ts +2 -1
  51. package/dist/routers/section.d.ts.map +1 -1
  52. package/dist/routers/section.js +30 -33
  53. package/dist/routers/user.d.ts +3 -2
  54. package/dist/routers/user.d.ts.map +1 -1
  55. package/dist/routers/user.js +21 -24
  56. package/dist/seedDatabase.d.ts +22 -0
  57. package/dist/seedDatabase.d.ts.map +1 -0
  58. package/dist/seedDatabase.js +75 -0
  59. package/dist/socket/handlers.js +26 -30
  60. package/dist/trpc.d.ts +5 -0
  61. package/dist/trpc.d.ts.map +1 -1
  62. package/dist/trpc.js +35 -26
  63. package/dist/types/trpc.d.ts +1 -1
  64. package/dist/types/trpc.d.ts.map +1 -1
  65. package/dist/types/trpc.js +1 -2
  66. package/dist/utils/email.js +2 -8
  67. package/dist/utils/generateInviteCode.js +1 -5
  68. package/dist/utils/logger.d.ts.map +1 -1
  69. package/dist/utils/logger.js +13 -9
  70. package/dist/utils/prismaErrorHandler.d.ts +9 -0
  71. package/dist/utils/prismaErrorHandler.d.ts.map +1 -0
  72. package/dist/utils/prismaErrorHandler.js +234 -0
  73. package/dist/utils/prismaWrapper.d.ts +14 -0
  74. package/dist/utils/prismaWrapper.d.ts.map +1 -0
  75. package/dist/utils/prismaWrapper.js +64 -0
  76. package/package.json +12 -4
  77. package/prisma/migrations/20250807062924_init/migration.sql +436 -0
  78. package/prisma/migrations/migration_lock.toml +3 -0
  79. package/prisma/schema.prisma +68 -1
  80. package/src/exportType.ts +3 -3
  81. package/src/index.ts +6 -6
  82. package/src/lib/fileUpload.ts +19 -10
  83. package/src/lib/thumbnailGenerator.ts +2 -2
  84. package/src/middleware/auth.ts +2 -4
  85. package/src/middleware/logging.ts +2 -2
  86. package/src/routers/_app.ts +17 -13
  87. package/src/routers/agenda.ts +2 -2
  88. package/src/routers/announcement.ts +2 -2
  89. package/src/routers/assignment.ts +86 -26
  90. package/src/routers/attendance.ts +2 -2
  91. package/src/routers/auth.ts +83 -57
  92. package/src/routers/class.ts +339 -39
  93. package/src/routers/event.ts +2 -2
  94. package/src/routers/file.ts +276 -21
  95. package/src/routers/folder.ts +755 -0
  96. package/src/routers/notifications.ts +93 -0
  97. package/src/routers/section.ts +2 -2
  98. package/src/routers/user.ts +3 -3
  99. package/src/seedDatabase.ts +88 -0
  100. package/src/socket/handlers.ts +5 -5
  101. package/src/trpc.ts +17 -4
  102. package/src/types/trpc.ts +1 -1
  103. package/src/utils/logger.ts +14 -4
  104. package/src/utils/prismaErrorHandler.ts +275 -0
  105. package/src/utils/prismaWrapper.ts +91 -0
  106. package/tests/auth.test.ts +25 -0
  107. package/tests/class.test.ts +281 -0
  108. package/tests/setup.ts +98 -0
  109. package/tests/startup.test.ts +5 -0
  110. package/tsconfig.json +2 -1
  111. package/vitest.config.ts +11 -0
  112. package/dist/logger.d.ts +0 -26
  113. package/dist/logger.d.ts.map +0 -1
  114. package/dist/logger.js +0 -135
  115. package/src/logger.ts +0 -163
@@ -0,0 +1,25 @@
1
+ import { test, expect } from 'vitest';
2
+ import { appRouter } from '../src/routers/_app';
3
+ import { createTRPCContext } from '../src/trpc';
4
+ import { prisma } from '../src/lib/prisma';
5
+ import { caller, login1, login2, session1, session2, user1Caller, verification1, verification2 } from './setup';
6
+
7
+ test('registration', async () => {
8
+ expect(session1).toBeDefined();
9
+ expect(session2).toBeDefined();
10
+ });
11
+
12
+ test('email verification', async () => {
13
+ expect(verification1).toBeDefined();
14
+ expect(verification2).toBeDefined();
15
+ });
16
+
17
+ test('login', async () => {
18
+ expect(login1).toBeDefined();
19
+ expect(login2).toBeDefined();
20
+ });
21
+
22
+ test('logout', async () => {
23
+ const logout = await user1Caller.auth.logout();
24
+ expect(logout).toBeDefined();
25
+ });
@@ -0,0 +1,281 @@
1
+ import { test, expect, describe, beforeEach } from 'vitest';
2
+ import { appRouter } from '../src/routers/_app';
3
+ import { createTRPCContext } from '../src/trpc';
4
+ import { prisma } from '../src/lib/prisma';
5
+ import { caller, user1Caller, user2Caller } from './setup';
6
+
7
+ describe('Class Router', () => {
8
+ let testClass: any;
9
+ let testClass2: any;
10
+
11
+ beforeEach(async () => {
12
+ // Create test classes for each test
13
+ testClass = await user1Caller.class.create({
14
+ name: 'Test Class 1',
15
+ subject: 'Mathematics',
16
+ section: '10th Grade',
17
+ });
18
+
19
+ testClass2 = await user2Caller.class.create({
20
+ name: 'Test Class 2',
21
+ subject: 'Science',
22
+ section: '11th Grade',
23
+ });
24
+ });
25
+
26
+ describe('create', () => {
27
+ test('should create a class successfully', async () => {
28
+ expect(testClass).toBeDefined();
29
+ expect(testClass.name).toBe('Test Class 1');
30
+ expect(testClass.subject).toBe('Mathematics');
31
+ expect(testClass.section).toBe('10th Grade');
32
+ });
33
+
34
+ test('should create multiple classes', async () => {
35
+ expect(testClass).toBeDefined();
36
+ expect(testClass2).toBeDefined();
37
+ expect(testClass.id).not.toBe(testClass2.id);
38
+ });
39
+
40
+ test('should fail to create class without authentication', async () => {
41
+ const invalidCaller = await createTRPCContext({
42
+ req: { headers: {} } as any,
43
+ res: {} as any,
44
+ });
45
+ const router = appRouter.createCaller(invalidCaller);
46
+
47
+ await expect(router.class.create({
48
+ name: 'Test Class',
49
+ subject: 'Mathematics',
50
+ section: '10th Grade',
51
+ })).rejects.toThrow();
52
+ });
53
+
54
+ test('should fail to create class with missing required fields', async () => {
55
+ await expect(user1Caller.class.create({
56
+ name: '',
57
+ subject: 'Mathematics',
58
+ section: '10th Grade',
59
+ })).rejects.toThrow();
60
+ });
61
+ });
62
+
63
+ describe('getAll', () => {
64
+ test('should get all classes for authenticated user', async () => {
65
+ const classes = await user1Caller.class.getAll();
66
+ expect(classes).toBeDefined();
67
+ expect(classes.teacherInClass).toBeDefined();
68
+ expect(classes.studentInClass).toBeDefined();
69
+ expect(Array.isArray(classes.teacherInClass)).toBe(true);
70
+ expect(Array.isArray(classes.studentInClass)).toBe(true);
71
+ });
72
+
73
+ test('should include user\'s own classes as teacher', async () => {
74
+ const classes = await user1Caller.class.getAll();
75
+ const userClass = classes.teacherInClass.find((c: any) => c.name === 'Test Class 1');
76
+ expect(userClass).toBeDefined();
77
+ });
78
+
79
+ test('should fail to get classes without authentication', async () => {
80
+ const invalidCaller = await createTRPCContext({
81
+ req: { headers: {} } as any,
82
+ res: {} as any,
83
+ });
84
+ const router = appRouter.createCaller(invalidCaller);
85
+
86
+ await expect(router.class.getAll()).rejects.toThrow();
87
+ });
88
+ });
89
+
90
+ describe('get', () => {
91
+ test('should get class by ID successfully', async () => {
92
+ const classData = await user1Caller.class.get({ classId: testClass.id });
93
+ expect(classData).toBeDefined();
94
+ expect(classData.class).toBeDefined();
95
+ expect(classData.class.id).toBe(testClass.id);
96
+ expect(classData.class.name).toBe('Test Class 1');
97
+ });
98
+
99
+ test('should fail to get non-existent class', async () => {
100
+ await expect(user1Caller.class.get({ classId: 'non-existent-id' })).rejects.toThrow();
101
+ });
102
+
103
+ test('should fail to get class without authentication', async () => {
104
+ const invalidCaller = await createTRPCContext({
105
+ req: { headers: {} } as any,
106
+ res: {} as any,
107
+ });
108
+ const router = appRouter.createCaller(invalidCaller);
109
+
110
+ await expect(router.class.get({ classId: testClass.id })).rejects.toThrow();
111
+ });
112
+ });
113
+
114
+ describe('update', () => {
115
+ test('should update class successfully', async () => {
116
+ const updatedClass = await user1Caller.class.update({
117
+ classId: testClass.id,
118
+ name: 'Updated Test Class',
119
+ subject: 'Physics',
120
+ section: '12th Grade',
121
+ });
122
+
123
+ expect(updatedClass).toBeDefined();
124
+ expect(updatedClass.updatedClass).toBeDefined();
125
+ expect(updatedClass.updatedClass.name).toBe('Updated Test Class');
126
+ expect(updatedClass.updatedClass.subject).toBe('Physics');
127
+ expect(updatedClass.updatedClass.section).toBe('12th Grade');
128
+ });
129
+
130
+ test('should fail to update class user is not teacher of', async () => {
131
+ await expect(user2Caller.class.update({
132
+ classId: testClass.id,
133
+ name: 'Updated Test Class',
134
+ subject: 'Physics',
135
+ section: '12th Grade',
136
+ })).rejects.toThrow();
137
+ });
138
+
139
+ test('should fail to update non-existent class', async () => {
140
+ await expect(user1Caller.class.update({
141
+ classId: 'non-existent-id',
142
+ name: 'Updated Test Class',
143
+ subject: 'Physics',
144
+ section: '12th Grade',
145
+ })).rejects.toThrow();
146
+ });
147
+ });
148
+
149
+ describe('delete', () => {
150
+ test('should delete class successfully', async () => {
151
+ const result = await user1Caller.class.delete({ classId: testClass.id, id: testClass.id });
152
+ expect(result).toBeDefined();
153
+ expect(result.deletedClass).toBeDefined();
154
+ expect(result.deletedClass.id).toBe(testClass.id);
155
+ });
156
+
157
+ test('should fail to delete class user is not teacher of', async () => {
158
+ await expect(user2Caller.class.delete({ classId: testClass.id, id: testClass.id })).rejects.toThrow();
159
+ });
160
+
161
+ test('should fail to delete non-existent class', async () => {
162
+ await expect(user1Caller.class.delete({ classId: 'non-existent-id', id: 'non-existent-id' })).rejects.toThrow();
163
+ });
164
+ });
165
+
166
+ describe('addStudent', () => {
167
+ test('should add student successfully', async () => {
168
+ const user2Profile = await user2Caller.user.getProfile();
169
+ const result = await user1Caller.class.addStudent({
170
+ classId: testClass.id,
171
+ studentId: user2Profile.id,
172
+ });
173
+ expect(result).toBeDefined();
174
+ expect(result.updatedClass).toBeDefined();
175
+ expect(result.newStudent).toBeDefined();
176
+ });
177
+
178
+ test('should fail to add student if user is not class teacher', async () => {
179
+ const user1Profile = await user1Caller.user.getProfile();
180
+ await expect(user2Caller.class.addStudent({
181
+ classId: testClass.id,
182
+ studentId: user1Profile.id,
183
+ })).rejects.toThrow();
184
+ });
185
+ });
186
+
187
+ describe('changeRole', () => {
188
+ test('should change user role successfully', async () => {
189
+ const user2Profile = await user2Caller.user.getProfile();
190
+ const result = await user1Caller.class.changeRole({
191
+ classId: testClass.id,
192
+ userId: user2Profile.id,
193
+ type: 'teacher',
194
+ });
195
+ expect(result).toBeDefined();
196
+ expect(result.updatedClass).toBeDefined();
197
+ expect(result.user).toBeDefined();
198
+ expect(result.user.type).toBe('teacher');
199
+ });
200
+
201
+ test('should fail to change role if user is not class teacher', async () => {
202
+ const user1Profile = await user1Caller.user.getProfile();
203
+ await expect(user2Caller.class.changeRole({
204
+ classId: testClass.id,
205
+ userId: user1Profile.id,
206
+ type: 'teacher',
207
+ })).rejects.toThrow();
208
+ });
209
+ });
210
+
211
+ describe('removeMember', () => {
212
+ test('should remove member successfully', async () => {
213
+ // First add a student
214
+ const user2Profile = await user2Caller.user.getProfile();
215
+ await user1Caller.class.addStudent({
216
+ classId: testClass.id,
217
+ studentId: user2Profile.id,
218
+ });
219
+
220
+ // Then remove them
221
+ const result = await user1Caller.class.removeMember({
222
+ classId: testClass.id,
223
+ userId: user2Profile.id,
224
+ });
225
+ expect(result).toBeDefined();
226
+ expect(result.updatedClass).toBeDefined();
227
+ expect(result.removedUserId).toBe(user2Profile.id);
228
+ });
229
+
230
+ test('should fail to remove member if user is not class teacher', async () => {
231
+ const user1Profile = await user1Caller.user.getProfile();
232
+ await expect(user2Caller.class.removeMember({
233
+ classId: testClass.id,
234
+ userId: user1Profile.id,
235
+ })).rejects.toThrow();
236
+ });
237
+ });
238
+
239
+ describe('join', () => {
240
+ test('should join class with class code successfully', async () => {
241
+ // First create an invite code
242
+ const inviteCode = await user1Caller.class.createInviteCode({ classId: testClass.id });
243
+
244
+ // Then join with the code
245
+ const result = await user2Caller.class.join({ classCode: inviteCode.code });
246
+ expect(result).toBeDefined();
247
+ expect(result.joinedClass).toBeDefined();
248
+ expect(result.joinedClass.id).toBe(testClass.id);
249
+ });
250
+
251
+ test('should fail to join with invalid class code', async () => {
252
+ await expect(user2Caller.class.join({ classCode: 'invalid-code' })).rejects.toThrow();
253
+ });
254
+ });
255
+
256
+ describe('getInviteCode', () => {
257
+ test('should get invite code successfully', async () => {
258
+ const result = await user1Caller.class.getInviteCode({ classId: testClass.id });
259
+ expect(result).toBeDefined();
260
+ expect(result.code).toBeDefined();
261
+ expect(typeof result.code).toBe('string');
262
+ });
263
+
264
+ test('should fail to get invite code if user is not class teacher', async () => {
265
+ await expect(user2Caller.class.getInviteCode({ classId: testClass.id })).rejects.toThrow();
266
+ });
267
+ });
268
+
269
+ describe('createInviteCode', () => {
270
+ test('should create invite code successfully', async () => {
271
+ const result = await user1Caller.class.createInviteCode({ classId: testClass.id });
272
+ expect(result).toBeDefined();
273
+ expect(result.code).toBeDefined();
274
+ expect(typeof result.code).toBe('string');
275
+ });
276
+
277
+ test('should fail to create invite code if user is not class teacher', async () => {
278
+ await expect(user2Caller.class.createInviteCode({ classId: testClass.id })).rejects.toThrow();
279
+ });
280
+ });
281
+ });
package/tests/setup.ts ADDED
@@ -0,0 +1,98 @@
1
+ import { execSync } from 'child_process';
2
+ import { prisma } from '../src/lib/prisma';
3
+ import { beforeAll, beforeEach, afterAll, afterEach } from 'vitest';
4
+ import { logger } from '../src/utils/logger';
5
+ import { appRouter } from '../src/routers/_app';
6
+ import { createTRPCContext } from '../src/trpc';
7
+ import { Session } from '@prisma/client';
8
+
9
+ const getCaller = async (token: string) => {
10
+ const ctx = await createTRPCContext({
11
+ req: { headers: {
12
+ authorization: `Bearer ${token}`,
13
+ 'x-user': token,
14
+ } } as any,
15
+ res: {} as any,
16
+ });
17
+ return appRouter.createCaller(ctx);
18
+ };
19
+
20
+ // Before the entire test suite runs
21
+ beforeAll(async () => {
22
+ // // Run migrations so the test DB has the latest schema
23
+ // try {
24
+ // logger.info('Setting up test database');
25
+ // execSync('rm -f prisma/test.db');
26
+ // execSync('npx prisma db push --force-reset --schema=prisma/schema.prisma');
27
+
28
+ // } catch (error) {
29
+ // logger.error('Error initializing test database');
30
+ // }
31
+
32
+ logger.info('Getting caller');
33
+
34
+ caller = await getCaller('');
35
+
36
+ const user1 = await caller.auth.register({
37
+ username: 'testuser1',
38
+ email: 'test@test.com',
39
+ password: 'password_is_1234',
40
+ confirmPassword: 'password_is_1234',
41
+ });
42
+
43
+ const user2 = await caller.auth.register({
44
+ username: 'testuser2',
45
+ email: 'test2@test.com',
46
+ password: 'password_is_1234',
47
+ confirmPassword: 'password_is_1234',
48
+ });
49
+
50
+ session1 = await prisma.session.findFirst({
51
+ where: {
52
+ userId: user1.user.id,
53
+ },
54
+ }) as Session;
55
+
56
+ session2 = (await prisma.session.findFirst({
57
+ where: {
58
+ userId: user2.user.id,
59
+ },
60
+ })) as Session;
61
+
62
+ verification1 = await caller.auth.verify({
63
+ token: session1.id,
64
+ });
65
+
66
+ verification2 = await caller.auth.verify({
67
+ token: session2.id,
68
+ });
69
+
70
+ login1 = await caller.auth.login({
71
+ username: 'testuser1',
72
+ password: 'password_is_1234',
73
+ });
74
+
75
+ login2 = await caller.auth.login({
76
+ username: 'testuser2',
77
+ password: 'password_is_1234',
78
+ });
79
+
80
+ user1Caller = await getCaller(login1.token);
81
+ user2Caller = await getCaller(login2.token);
82
+ });
83
+
84
+
85
+ // After all tests, close the DB
86
+ afterAll(async () => {
87
+ await prisma.$disconnect();
88
+ });
89
+
90
+ export let user1Caller: ReturnType<typeof appRouter.createCaller>;
91
+ export let user2Caller: ReturnType<typeof appRouter.createCaller>;
92
+ export let caller: ReturnType<typeof appRouter.createCaller>;
93
+ export let session1: Session;
94
+ export let session2: Session;
95
+ export let verification1: any;
96
+ export let verification2: any;
97
+ export let login1: any;
98
+ export let login2: any;
@@ -0,0 +1,5 @@
1
+ import { expect, test } from "vitest";
2
+
3
+ test('setup works', () => {
4
+ expect(1).toBe(1);
5
+ });
package/tsconfig.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2020",
4
- "module": "CommonJS",
4
+ "module": "ESNext",
5
5
  "moduleResolution": "node",
6
6
  "esModuleInterop": true,
7
7
  "strict": true,
8
+ "noImplicitAny": false,
8
9
  "skipLibCheck": true,
9
10
  "forceConsistentCasingInFileNames": true,
10
11
  "outDir": "dist",
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: 'node',
7
+ hookTimeout: 60000, // 60 seconds
8
+ include: ['tests/**/*.test.ts'],
9
+ setupFiles: ['./tests/setup.ts'], // run setup before tests
10
+ },
11
+ });
package/dist/logger.d.ts DELETED
@@ -1,26 +0,0 @@
1
- export declare enum LogLevel {
2
- INFO = "info",
3
- WARN = "warn",
4
- ERROR = "error",
5
- DEBUG = "debug"
6
- }
7
- type LogMode = 'silent' | 'minimal' | 'normal' | 'verbose';
8
- declare class Logger {
9
- private static instance;
10
- private isDevelopment;
11
- private mode;
12
- private levelEmojis;
13
- private constructor();
14
- static getInstance(): Logger;
15
- setMode(mode: LogMode): void;
16
- private shouldLog;
17
- private formatMessage;
18
- private log;
19
- info(message: string, context?: Record<string, any>): void;
20
- warn(message: string, context?: Record<string, any>): void;
21
- error(message: string, context?: Record<string, any>): void;
22
- debug(message: string, context?: Record<string, any>): void;
23
- }
24
- export declare const logger: Logger;
25
- export {};
26
- //# sourceMappingURL=logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ;IAClB,IAAI,SAAS;IACb,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;CAChB;AAED,KAAK,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAuC3D,cAAM,MAAM;IACV,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,WAAW,CAA2B;IAE9C,OAAO;WAYO,WAAW,IAAI,MAAM;IAO5B,OAAO,CAAC,IAAI,EAAE,OAAO;IAI5B,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,GAAG;IA6BJ,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAInD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAInD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIpD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAG5D;AAED,eAAO,MAAM,MAAM,QAAuB,CAAC"}
package/dist/logger.js DELETED
@@ -1,135 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logger = exports.LogLevel = void 0;
4
- var LogLevel;
5
- (function (LogLevel) {
6
- LogLevel["INFO"] = "info";
7
- LogLevel["WARN"] = "warn";
8
- LogLevel["ERROR"] = "error";
9
- LogLevel["DEBUG"] = "debug";
10
- })(LogLevel || (exports.LogLevel = LogLevel = {}));
11
- // Environment detection
12
- const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
13
- const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
14
- // ANSI color codes for Node.js
15
- const ansiColors = {
16
- reset: '\x1b[0m',
17
- bright: '\x1b[1m',
18
- dim: '\x1b[2m',
19
- red: '\x1b[31m',
20
- green: '\x1b[32m',
21
- yellow: '\x1b[33m',
22
- blue: '\x1b[34m',
23
- magenta: '\x1b[35m',
24
- cyan: '\x1b[36m',
25
- white: '\x1b[37m',
26
- gray: '\x1b[90m'
27
- };
28
- // CSS color codes for browser console
29
- const cssColors = {
30
- reset: '%c',
31
- info: 'color: #2196F3; font-weight: bold;',
32
- warn: 'color: #FFC107; font-weight: bold;',
33
- error: 'color: #F44336; font-weight: bold;',
34
- debug: 'color: #9C27B0; font-weight: bold;',
35
- gray: 'color: #9E9E9E;',
36
- context: 'color: #757575; font-style: italic;'
37
- };
38
- class Logger {
39
- constructor() {
40
- this.isDevelopment = process.env.NODE_ENV === 'development';
41
- this.mode = process.env.LOG_MODE || 'normal';
42
- this.levelEmojis = {
43
- [LogLevel.INFO]: 'ℹ️',
44
- [LogLevel.WARN]: '⚠️',
45
- [LogLevel.ERROR]: '❌',
46
- [LogLevel.DEBUG]: '🔍'
47
- };
48
- }
49
- static getInstance() {
50
- if (!Logger.instance) {
51
- Logger.instance = new Logger();
52
- }
53
- return Logger.instance;
54
- }
55
- setMode(mode) {
56
- this.mode = mode;
57
- }
58
- shouldLog(level) {
59
- const silent = [LogLevel.ERROR];
60
- const minimal = [LogLevel.ERROR, LogLevel.WARN];
61
- const normal = [LogLevel.ERROR, LogLevel.WARN, LogLevel.INFO];
62
- if (this.mode === 'silent')
63
- return silent.includes(level);
64
- if (this.mode === 'minimal')
65
- return minimal.includes(level);
66
- if (this.mode === 'normal')
67
- return normal.includes(level);
68
- return true; // verbose mode
69
- }
70
- formatMessage(logMessage) {
71
- const { level, message, timestamp, context } = logMessage;
72
- const emoji = this.levelEmojis[level];
73
- const timestampStr = `[${timestamp}]`;
74
- const levelStr = `[${level.toUpperCase()}]`;
75
- const messageStr = `${emoji} ${message}`;
76
- const contextStr = context
77
- ? `\nContext: ${JSON.stringify(context, null, 2)}`
78
- : '';
79
- if (isNode) {
80
- const color = ansiColors[level === LogLevel.INFO ? 'blue' :
81
- level === LogLevel.WARN ? 'yellow' :
82
- level === LogLevel.ERROR ? 'red' : 'magenta'];
83
- return `${ansiColors.gray}${timestampStr}${ansiColors.reset} ${color}${levelStr}${ansiColors.reset} ${messageStr}${contextStr}`;
84
- }
85
- else {
86
- const color = cssColors[level];
87
- return [
88
- `${timestampStr} ${levelStr} ${messageStr}${contextStr}`,
89
- cssColors.reset,
90
- color,
91
- cssColors.gray,
92
- cssColors.context
93
- ];
94
- }
95
- }
96
- log(level, message, context) {
97
- if (!this.shouldLog(level))
98
- return;
99
- const logMessage = {
100
- level,
101
- message,
102
- timestamp: new Date().toISOString(),
103
- context
104
- };
105
- const formattedMessage = this.formatMessage(logMessage);
106
- switch (level) {
107
- case LogLevel.ERROR:
108
- console.error(...(Array.isArray(formattedMessage) ? formattedMessage : [formattedMessage]));
109
- break;
110
- case LogLevel.WARN:
111
- console.warn(...(Array.isArray(formattedMessage) ? formattedMessage : [formattedMessage]));
112
- break;
113
- case LogLevel.DEBUG:
114
- if (this.isDevelopment) {
115
- console.debug(...(Array.isArray(formattedMessage) ? formattedMessage : [formattedMessage]));
116
- }
117
- break;
118
- default:
119
- console.log(...(Array.isArray(formattedMessage) ? formattedMessage : [formattedMessage]));
120
- }
121
- }
122
- info(message, context) {
123
- this.log(LogLevel.INFO, message, context);
124
- }
125
- warn(message, context) {
126
- this.log(LogLevel.WARN, message, context);
127
- }
128
- error(message, context) {
129
- this.log(LogLevel.ERROR, message, context);
130
- }
131
- debug(message, context) {
132
- this.log(LogLevel.DEBUG, message, context);
133
- }
134
- }
135
- exports.logger = Logger.getInstance();