@vue-skuilder/express 0.1.1

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 (78) hide show
  1. package/.env.development +9 -0
  2. package/.prettierignore +4 -0
  3. package/.prettierrc +8 -0
  4. package/.vscode/launch.json +20 -0
  5. package/assets/classroomDesignDoc.js +24 -0
  6. package/assets/courseValidateDocUpdate.js +56 -0
  7. package/assets/get-tagsDesignDoc.json +9 -0
  8. package/babel.config.js +6 -0
  9. package/dist/app.d.ts +6 -0
  10. package/dist/app.d.ts.map +1 -0
  11. package/dist/app.js +194 -0
  12. package/dist/app.js.map +1 -0
  13. package/dist/attachment-preprocessing/index.d.ts +11 -0
  14. package/dist/attachment-preprocessing/index.d.ts.map +1 -0
  15. package/dist/attachment-preprocessing/index.js +146 -0
  16. package/dist/attachment-preprocessing/index.js.map +1 -0
  17. package/dist/attachment-preprocessing/normalize.d.ts +7 -0
  18. package/dist/attachment-preprocessing/normalize.d.ts.map +1 -0
  19. package/dist/attachment-preprocessing/normalize.js +90 -0
  20. package/dist/attachment-preprocessing/normalize.js.map +1 -0
  21. package/dist/client-requests/classroom-requests.d.ts +26 -0
  22. package/dist/client-requests/classroom-requests.d.ts.map +1 -0
  23. package/dist/client-requests/classroom-requests.js +171 -0
  24. package/dist/client-requests/classroom-requests.js.map +1 -0
  25. package/dist/client-requests/course-requests.d.ts +10 -0
  26. package/dist/client-requests/course-requests.d.ts.map +1 -0
  27. package/dist/client-requests/course-requests.js +135 -0
  28. package/dist/client-requests/course-requests.js.map +1 -0
  29. package/dist/client.d.ts +31 -0
  30. package/dist/client.d.ts.map +1 -0
  31. package/dist/client.js +70 -0
  32. package/dist/client.js.map +1 -0
  33. package/dist/couchdb/authentication.d.ts +4 -0
  34. package/dist/couchdb/authentication.d.ts.map +1 -0
  35. package/dist/couchdb/authentication.js +64 -0
  36. package/dist/couchdb/authentication.js.map +1 -0
  37. package/dist/couchdb/index.d.ts +18 -0
  38. package/dist/couchdb/index.d.ts.map +1 -0
  39. package/dist/couchdb/index.js +52 -0
  40. package/dist/couchdb/index.js.map +1 -0
  41. package/dist/design-docs.d.ts +63 -0
  42. package/dist/design-docs.d.ts.map +1 -0
  43. package/dist/design-docs.js +90 -0
  44. package/dist/design-docs.js.map +1 -0
  45. package/dist/logger.d.ts +3 -0
  46. package/dist/logger.d.ts.map +1 -0
  47. package/dist/logger.js +62 -0
  48. package/dist/logger.js.map +1 -0
  49. package/dist/routes/logs.d.ts +3 -0
  50. package/dist/routes/logs.d.ts.map +1 -0
  51. package/dist/routes/logs.js +274 -0
  52. package/dist/routes/logs.js.map +1 -0
  53. package/dist/utils/env.d.ts +10 -0
  54. package/dist/utils/env.d.ts.map +1 -0
  55. package/dist/utils/env.js +38 -0
  56. package/dist/utils/env.js.map +1 -0
  57. package/dist/utils/processQueue.d.ts +39 -0
  58. package/dist/utils/processQueue.d.ts.map +1 -0
  59. package/dist/utils/processQueue.js +175 -0
  60. package/dist/utils/processQueue.js.map +1 -0
  61. package/eslint.config.js +19 -0
  62. package/jest.config.ts +24 -0
  63. package/package.json +74 -0
  64. package/src/app.ts +246 -0
  65. package/src/attachment-preprocessing/index.ts +204 -0
  66. package/src/attachment-preprocessing/normalize.ts +123 -0
  67. package/src/client-requests/classroom-requests.ts +234 -0
  68. package/src/client-requests/course-requests.ts +188 -0
  69. package/src/client.ts +97 -0
  70. package/src/couchdb/authentication.ts +85 -0
  71. package/src/couchdb/index.ts +76 -0
  72. package/src/design-docs.ts +107 -0
  73. package/src/logger.ts +75 -0
  74. package/src/routes/logs.ts +289 -0
  75. package/src/utils/env.ts +51 -0
  76. package/src/utils/processQueue.ts +218 -0
  77. package/test/client.test.ts +144 -0
  78. package/tsconfig.json +27 -0
@@ -0,0 +1,63 @@
1
+ export declare const classroomDbDesignDoc: string;
2
+ export declare const courseDBDesignDoc: string;
3
+ export declare const courseValidateDocUpdate: string;
4
+ export declare const elodoc: {
5
+ _id: string;
6
+ views: {
7
+ elo: {
8
+ map: string;
9
+ };
10
+ };
11
+ language: string;
12
+ };
13
+ export declare const tagsDoc: {
14
+ _id: string;
15
+ views: {
16
+ getTags: {
17
+ map: string;
18
+ };
19
+ };
20
+ language: string;
21
+ };
22
+ export declare const cardsByInexperienceDoc: {
23
+ _id: string;
24
+ views: {
25
+ cardsByInexperience: {
26
+ map: string;
27
+ };
28
+ };
29
+ language: string;
30
+ };
31
+ export declare const authDesignDoc: {
32
+ _id: string;
33
+ validate_doc_update: string;
34
+ };
35
+ export declare const courseDBDesignDocs: ({
36
+ _id: string;
37
+ views: {
38
+ elo: {
39
+ map: string;
40
+ };
41
+ };
42
+ language: string;
43
+ } | {
44
+ _id: string;
45
+ views: {
46
+ getTags: {
47
+ map: string;
48
+ };
49
+ };
50
+ language: string;
51
+ } | {
52
+ _id: string;
53
+ views: {
54
+ cardsByInexperience: {
55
+ map: string;
56
+ };
57
+ };
58
+ language: string;
59
+ } | {
60
+ _id: string;
61
+ validate_doc_update: string;
62
+ })[];
63
+ //# sourceMappingURL=design-docs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-docs.d.ts","sourceRoot":"","sources":["../src/design-docs.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,oBAAoB,QAGhC,CAAC;AAEF,eAAO,MAAM,iBAAiB,QAG7B,CAAC;AAEF,eAAO,MAAM,uBAAuB,QAGnC,CAAC;AAEF,eAAO,MAAM,MAAM;;;;;;;;CAqBlB,CAAC;AAEF,eAAO,MAAM,OAAO;;;;;;;;CAoBnB,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;;;;CAsBlC,CAAC;AAEF,eAAO,MAAM,aAAa;;;CAGzB,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;IAK9B,CAAC"}
@@ -0,0 +1,90 @@
1
+ import { DocType } from '@vue-skuilder/db';
2
+ import * as fileSystem from 'fs';
3
+ /**
4
+ * Fake fcn to allow usage in couchdb map fcns which, after passing
5
+ * through `.toString()`, are applied to all courses
6
+ */
7
+ function emit(key, value) {
8
+ return [key, value];
9
+ }
10
+ // Load design documents
11
+ export const classroomDbDesignDoc = fileSystem.readFileSync('./assets/classroomDesignDoc.js', 'utf-8');
12
+ export const courseDBDesignDoc = fileSystem.readFileSync('./assets/get-tagsDesignDoc.json', 'utf-8');
13
+ export const courseValidateDocUpdate = fileSystem.readFileSync('./assets/courseValidateDocUpdate.js', 'utf-8');
14
+ export const elodoc = {
15
+ _id: '_design/elo',
16
+ views: {
17
+ elo: {
18
+ map: `function (doc) {
19
+ if (doc.docType && doc.docType === 'CARD') {
20
+ if (doc.elo && typeof(doc.elo) === 'number') {
21
+ emit(doc.elo, doc._id);
22
+ } else if (doc.elo && doc.elo.global) {
23
+ emit(doc.elo.global.score, doc._id);
24
+ } else if (doc.elo) {
25
+ emit(doc.elo.score, doc._id);
26
+ } else {
27
+ const randElo = 995 + Math.round(10 * Math.random());
28
+ emit(randElo, doc._id);
29
+ }
30
+ }
31
+ }`,
32
+ },
33
+ },
34
+ language: 'javascript',
35
+ };
36
+ export const tagsDoc = {
37
+ _id: '_design/getTags',
38
+ views: {
39
+ getTags: {
40
+ map: `function (doc) {
41
+ if (doc.docType && doc.docType === "TAG") {
42
+ for (var cardIndex in doc.taggedCards) {
43
+ emit(doc.taggedCards[cardIndex], {
44
+ docType: doc.docType,
45
+ name: doc.name,
46
+ snippit: doc.snippit,
47
+ wiki: '',
48
+ taggedCards: []
49
+ });
50
+ }
51
+ }
52
+ }`,
53
+ },
54
+ },
55
+ language: 'javascript',
56
+ };
57
+ export const cardsByInexperienceDoc = {
58
+ _id: '_design/cardsByInexperience',
59
+ views: {
60
+ cardsByInexperience: {
61
+ map: function (doc) {
62
+ if (doc.docType && doc.docType === DocType.CARD) {
63
+ if (doc.elo &&
64
+ doc.elo.global &&
65
+ typeof doc.elo.global.count == 'number') {
66
+ emit(doc.elo.global.count, doc.elo);
67
+ }
68
+ else if (doc.elo && typeof doc.elo == 'number') {
69
+ emit(0, doc.elo);
70
+ }
71
+ else {
72
+ emit(0, 995 + Math.floor(10 * Math.random()));
73
+ }
74
+ }
75
+ }.toString(),
76
+ },
77
+ },
78
+ language: 'javascript',
79
+ };
80
+ export const authDesignDoc = {
81
+ _id: '_design/_auth',
82
+ validate_doc_update: courseValidateDocUpdate,
83
+ };
84
+ export const courseDBDesignDocs = [
85
+ elodoc,
86
+ tagsDoc,
87
+ cardsByInexperienceDoc,
88
+ authDesignDoc,
89
+ ];
90
+ //# sourceMappingURL=design-docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-docs.js","sourceRoot":"","sources":["../src/design-docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,IAAI,CAAC;AAEjC;;;GAGG;AACH,SAAS,IAAI,CAAC,GAAa,EAAE,KAAe;IAC1C,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACtB,CAAC;AAED,wBAAwB;AACxB,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC,YAAY,CACzD,gCAAgC,EAChC,OAAO,CACR,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC,YAAY,CACtD,iCAAiC,EACjC,OAAO,CACR,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC,YAAY,CAC5D,qCAAqC,EACrC,OAAO,CACR,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,GAAG,EAAE,aAAa;IAClB,KAAK,EAAE;QACL,GAAG,EAAE;YACH,GAAG,EAAE;;;;;;;;;;;;;cAaG;SACT;KACF;IACD,QAAQ,EAAE,YAAY;CACvB,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,GAAG,EAAE,iBAAiB;IACtB,KAAK,EAAE;QACL,OAAO,EAAE;YACP,GAAG,EAAE;;;;;;;;;;;;cAYG;SACT;KACF;IACD,QAAQ,EAAE,YAAY;CACvB,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,GAAG,EAAE,6BAA6B;IAClC,KAAK,EAAE;QACL,mBAAmB,EAAE;YACnB,GAAG,EAAE,UAAU,GAAa;gBAC1B,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;oBAChD,IACE,GAAG,CAAC,GAAG;wBACP,GAAG,CAAC,GAAG,CAAC,MAAM;wBACd,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,QAAQ,EACvC,CAAC;wBACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;oBACtC,CAAC;yBAAM,IAAI,GAAG,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,QAAQ,EAAE,CAAC;wBACjD,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;oBACnB,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,QAAQ,EAAE;SACb;KACF;IACD,QAAQ,EAAE,YAAY;CACvB,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,eAAe;IACpB,mBAAmB,EAAE,uBAAuB;CAC7C,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM;IACN,OAAO;IACP,sBAAsB;IACtB,aAAa;CACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const logger: import("winston").Logger;
2
+ export default logger;
3
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AA4CA,QAAA,MAAM,MAAM,0BA4BV,CAAC;AAEH,eAAe,MAAM,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,62 @@
1
+ import { createLogger, format, transports } from 'winston';
2
+ import DailyRotateFile from 'winston-daily-rotate-file';
3
+ const callerFormat = format((info) => {
4
+ const error = new Error();
5
+ const stackLines = error.stack?.split('\n');
6
+ if (stackLines) {
7
+ // Find the first line that isn't from node_modules or internal Winston code
8
+ const callerLine = stackLines.find((line) => {
9
+ return (line.includes('(') &&
10
+ !line.includes('node_modules') &&
11
+ !line.includes('logger.ts') &&
12
+ !line.includes('winston'));
13
+ });
14
+ if (callerLine) {
15
+ // Try to extract function name and location
16
+ const match = callerLine.match(/at (?:(?:Object|Module)\.)?([a-zA-Z0-9_$.]+)? \((.+?):(\d+):(\d+)\)/);
17
+ if (match) {
18
+ const [, functionName = '<anonymous>', file, line] = match;
19
+ // Clean up the file path - get just filename
20
+ const fileName = file.split('/').pop() || file;
21
+ info.caller = `${functionName} (${fileName}:${line})`;
22
+ }
23
+ else {
24
+ // Handle edge cases (like anonymous functions)
25
+ const basicMatch = callerLine.match(/\((.+?):(\d+):(\d+)\)$/);
26
+ if (basicMatch) {
27
+ const [, file, line] = basicMatch;
28
+ const fileName = file.split('/').pop() || file;
29
+ info.caller = `<anonymous> (${fileName}:${line})`;
30
+ }
31
+ }
32
+ }
33
+ }
34
+ return info;
35
+ });
36
+ const logger = createLogger({
37
+ level: 'info',
38
+ format: format.combine(callerFormat(), format.timestamp(), format.json()),
39
+ transports: [
40
+ new transports.Console({
41
+ format: format.combine(callerFormat(), format.timestamp(), format.printf(({ level, message, timestamp, caller, ...rest }) => {
42
+ const meta = Object.keys(rest).length ? JSON.stringify(rest) : '';
43
+ return `${timestamp} [${level}] ${caller || 'unknown'} - ${message} ${meta}`;
44
+ })),
45
+ }),
46
+ new DailyRotateFile({
47
+ filename: 'logs/error-%DATE%.log',
48
+ datePattern: 'YYYY-MM-DD',
49
+ level: 'error',
50
+ maxFiles: '7d',
51
+ maxSize: '20m',
52
+ }),
53
+ new DailyRotateFile({
54
+ filename: 'logs/combined-%DATE%.log',
55
+ datePattern: 'YYYY-MM-DD',
56
+ maxFiles: '7d',
57
+ maxSize: '20m',
58
+ }),
59
+ ],
60
+ });
61
+ export default logger;
62
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/routes/logs.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,MAAM,4CAAmB,CAAC;AAwRhC,eAAe,MAAM,CAAC"}
@@ -0,0 +1,274 @@
1
+ import express from 'express';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import rateLimit from 'express-rate-limit';
5
+ import logger from '../logger.js';
6
+ import process from 'process';
7
+ const router = express.Router();
8
+ // Rate limiting middleware for logs routes
9
+ const logsRateLimit = rateLimit({
10
+ windowMs: 15 * 60 * 1000, // 15 minutes
11
+ max: 20, // Limit each IP to 20 requests per windowMs
12
+ message: {
13
+ error: 'Too many log requests from this IP, please try again later.'
14
+ },
15
+ standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
16
+ legacyHeaders: false, // Disable the `X-RateLimit-*` headers
17
+ });
18
+ // Apply rate limiting to all routes in this router
19
+ router.use(logsRateLimit);
20
+ // Get list of available log files
21
+ router.get('/', (_req, res) => {
22
+ void (async () => {
23
+ // [ ] add an auth mechanism. Below fcn is based on
24
+ // the CouchDB auth mechanism, forwarded from the web-app (not direct-access of server).
25
+ //
26
+ // const auth = await requestIsAdminAuthenticated(req);
27
+ // if (!auth) {
28
+ // res.status(401).json({ error: 'Unauthorized' });
29
+ // return;
30
+ // }
31
+ try {
32
+ const logsDir = path.join(process.cwd(), 'logs');
33
+ const files = await fs.readdir(logsDir);
34
+ // Create HTML content
35
+ const html = `
36
+ <!DOCTYPE html>
37
+ <html>
38
+ <head>
39
+ <title>Log Files</title>
40
+ <style>
41
+ body {
42
+ font-family: Arial, sans-serif;
43
+ margin: 20px;
44
+ }
45
+ h1 {
46
+ color: #333;
47
+ }
48
+ .log-list {
49
+ list-style: none;
50
+ padding: 0;
51
+ }
52
+ .log-list li {
53
+ margin: 10px 0;
54
+ }
55
+ .log-list a {
56
+ color: #0066cc;
57
+ text-decoration: none;
58
+ padding: 5px;
59
+ }
60
+ .log-list a:hover {
61
+ text-decoration: underline;
62
+ }
63
+ </style>
64
+ </head>
65
+ <body>
66
+ <h1>Available Log Files</h1>
67
+ <ul class="log-list">
68
+ ${files
69
+ .map((file) => `
70
+ <li>
71
+ <a href="/logs/${file}">${file}</a>
72
+ </li>
73
+ `)
74
+ .join('')}
75
+ </ul>
76
+ </body>
77
+ </html>
78
+ `;
79
+ res.type('html').send(html);
80
+ }
81
+ catch (error) {
82
+ logger.error('Error reading logs directory:', error);
83
+ res.status(500).json({ error: 'Failed to retrieve log files' });
84
+ }
85
+ })();
86
+ });
87
+ router.get('/:filename', (req, res) => {
88
+ void (async () => {
89
+ try {
90
+ const filename = req.params.filename;
91
+ // Sanitize filename to prevent directory traversal
92
+ if (filename.includes('..') || !filename.match(/^[a-zA-Z0-9-_.]+$/)) {
93
+ res.status(400).send('<h1>Error</h1><p>Invalid filename</p>');
94
+ return;
95
+ }
96
+ const logPath = path.join(process.cwd(), 'logs', filename);
97
+ const content = (await fs.readFile(logPath, 'utf-8')).toString();
98
+ // Parse log lines
99
+ const lines = content
100
+ .split('\n')
101
+ .filter((line) => line.trim())
102
+ .map((line) => {
103
+ try {
104
+ return JSON.parse(line);
105
+ }
106
+ catch {
107
+ return line;
108
+ }
109
+ });
110
+ const html = `
111
+ <!DOCTYPE html>
112
+ <html>
113
+ <head>
114
+ <title>Log Viewer - ${filename}</title>
115
+ <style>
116
+ body {
117
+ font-family: Arial, sans-serif;
118
+ margin: 20px;
119
+ max-width: 1200px;
120
+ margin: 0 auto;
121
+ padding: 20px;
122
+ }
123
+ .header {
124
+ display: flex;
125
+ justify-content: space-between;
126
+ align-items: center;
127
+ margin-bottom: 20px;
128
+ }
129
+ .nav-links {
130
+ margin-bottom: 20px;
131
+ }
132
+ .nav-links a {
133
+ color: #0066cc;
134
+ text-decoration: none;
135
+ margin-right: 15px;
136
+ }
137
+ .nav-links a:hover {
138
+ text-decoration: underline;
139
+ }
140
+ .filters {
141
+ margin-bottom: 20px;
142
+ padding: 10px;
143
+ background-color: #f5f5f5;
144
+ border-radius: 4px;
145
+ }
146
+ .filters input, .filters select {
147
+ margin: 5px;
148
+ padding: 5px;
149
+ }
150
+ .log-entry {
151
+ padding: 8px;
152
+ border-bottom: 1px solid #eee;
153
+ font-family: monospace;
154
+ white-space: pre-wrap;
155
+ }
156
+ .log-entry:nth-child(odd) {
157
+ background-color: #f9f9f9;
158
+ }
159
+ .error { color: #d32f2f; }
160
+ .warn { color: #ff9800; }
161
+ .info { color: #2196f3; }
162
+ .debug { color: #4caf50; }
163
+ </style>
164
+ <script>
165
+ function filterLogs() {
166
+ const search = document.getElementById('search').value.toLowerCase();
167
+ const level = document.getElementById('level').value;
168
+ const entries = document.getElementsByClassName('log-entry');
169
+
170
+ Array.from(entries).forEach(entry => {
171
+ const text = entry.textContent.toLowerCase();
172
+ const matchesSearch = !search || text.includes(search);
173
+ const matchesLevel = !level || text.includes('"level":"' + level + '"');
174
+ entry.style.display = (matchesSearch && matchesLevel) ? 'block' : 'none';
175
+ });
176
+ }
177
+ </script>
178
+ </head>
179
+ <body>
180
+ <div class="header">
181
+ <h1>Log Viewer - ${filename}</h1>
182
+ <div class="nav-links">
183
+ <a href="/logs">← Back to Log List</a>
184
+ <a href="/logs/${filename}/raw">View Raw Log →</a>
185
+ </div>
186
+ </div>
187
+
188
+ <div class="filters">
189
+ <input
190
+ type="text"
191
+ id="search"
192
+ placeholder="Search logs..."
193
+ oninput="filterLogs()"
194
+ >
195
+ <select id="level" onchange="filterLogs()">
196
+ <option value="">All Levels</option>
197
+ <option value="error">Error</option>
198
+ <option value="warn">Warn</option>
199
+ <option value="info">Info</option>
200
+ <option value="debug">Debug</option>
201
+ </select>
202
+ </div>
203
+
204
+ <div class="log-content">
205
+ ${lines
206
+ .map((line) => {
207
+ let levelClass = '';
208
+ if (typeof line === 'object' && line.level) {
209
+ levelClass = line.level.toLowerCase();
210
+ }
211
+ return `<div class="log-entry ${levelClass}">
212
+ ${typeof line === 'object'
213
+ ? JSON.stringify(line, null, 2)
214
+ : line}
215
+ </div>`;
216
+ })
217
+ .join('')}
218
+ </div>
219
+ </body>
220
+ </html>
221
+ `;
222
+ res.type('html').send(html);
223
+ }
224
+ catch (error) {
225
+ logger.error(`Error reading log file ${req.params.filename}:`, error);
226
+ res.status(500).send('<h1>Error</h1><p>Failed to retrieve log file</p>');
227
+ }
228
+ })();
229
+ });
230
+ // Get contents of specific log file
231
+ router.get('/:filename/raw', (req, res) => {
232
+ void (async () => {
233
+ // const auth = await requestIsAdminAuthenticated(req);
234
+ // if (!auth) {
235
+ // res.status(401).json({ error: 'Unauthorized' });
236
+ // return;
237
+ // }
238
+ try {
239
+ const filename = req.params.filename;
240
+ // Sanitize filename to prevent directory traversal
241
+ if (filename.includes('..') || !filename.match(/^[a-zA-Z0-9-_.]+$/)) {
242
+ res.status(400).json({ error: 'Invalid filename' });
243
+ return;
244
+ }
245
+ const logPath = path.join(process.cwd(), 'logs', filename);
246
+ const content = (await fs.readFile(logPath, 'utf-8')).toString();
247
+ // If the client requests JSON format
248
+ if (req.headers.accept === 'application/json') {
249
+ const lines = content
250
+ .split('\n')
251
+ .filter((line) => line.trim())
252
+ .map((line) => {
253
+ try {
254
+ return JSON.parse(line);
255
+ }
256
+ catch {
257
+ return line;
258
+ }
259
+ });
260
+ res.json(lines);
261
+ }
262
+ else {
263
+ // Return plain text by default
264
+ res.type('text/plain').send(content);
265
+ }
266
+ }
267
+ catch (error) {
268
+ logger.error(`Error reading log file ${req.params.filename}:`, error);
269
+ res.status(500).json({ error: 'Failed to retrieve log file' });
270
+ }
271
+ })();
272
+ });
273
+ export default router;
274
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/routes/logs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ type Env = {
2
+ COUCHDB_SERVER: string;
3
+ COUCHDB_PROTOCOL: string;
4
+ COUCHDB_ADMIN: string;
5
+ COUCHDB_PASSWORD: string;
6
+ VERSION: string;
7
+ };
8
+ declare const env: Env;
9
+ export default env;
10
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAaA,KAAK,GAAG,GAAG;IACT,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAUF,QAAA,MAAM,GAAG,EAAE,GAMV,CAAC;AAeF,eAAe,GAAG,CAAC"}
@@ -0,0 +1,38 @@
1
+ import dotenv from 'dotenv';
2
+ import process from 'process';
3
+ import { initializeDataLayer } from '@vue-skuilder/db';
4
+ import logger from '../logger.js';
5
+ dotenv.config({
6
+ path: process.argv && process.argv.length == 3
7
+ ? process.argv[2]
8
+ : '.env.development',
9
+ });
10
+ function getVar(name) {
11
+ if (process.env[name]) {
12
+ return process.env[name];
13
+ }
14
+ else {
15
+ throw new Error(`${name} not defined in environment`);
16
+ }
17
+ }
18
+ const env = {
19
+ COUCHDB_SERVER: getVar('COUCHDB_SERVER'),
20
+ COUCHDB_PROTOCOL: getVar('COUCHDB_PROTOCOL'),
21
+ COUCHDB_ADMIN: getVar('COUCHDB_ADMIN'),
22
+ COUCHDB_PASSWORD: getVar('COUCHDB_PASSWORD'),
23
+ VERSION: getVar('VERSION'),
24
+ };
25
+ initializeDataLayer({
26
+ type: 'pouch',
27
+ options: {
28
+ COUCHDB_PASSWORD: env.COUCHDB_PASSWORD,
29
+ COUCHDB_USERNAME: env.COUCHDB_ADMIN,
30
+ COUCHDB_SERVER_PROTOCOL: env.COUCHDB_PROTOCOL,
31
+ COUCHDB_SERVER_URL: env.COUCHDB_SERVER,
32
+ },
33
+ }).catch((e) => {
34
+ logger.error('Error initializing data layer:', e);
35
+ process.exit(1);
36
+ });
37
+ export default env;
38
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,MAAM,MAAM,cAAc,CAAC;AAElC,MAAM,CAAC,MAAM,CAAC;IACZ,IAAI,EACF,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC;QACtC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACjB,CAAC,CAAC,kBAAkB;CACzB,CAAC,CAAC;AAUH,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,6BAA6B,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED,MAAM,GAAG,GAAQ;IACf,cAAc,EAAE,MAAM,CAAC,gBAAgB,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC,kBAAkB,CAAC;IAC5C,aAAa,EAAE,MAAM,CAAC,eAAe,CAAC;IACtC,gBAAgB,EAAE,MAAM,CAAC,kBAAkB,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,mBAAmB,CAAC;IAClB,IAAI,EAAE,OAAO;IACb,OAAO,EAAE;QACP,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,gBAAgB,EAAE,GAAG,CAAC,aAAa;QACnC,uBAAuB,EAAE,GAAG,CAAC,gBAAgB;QAC7C,kBAAkB,EAAE,GAAG,CAAC,cAAc;KACvC;CACF,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACb,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,eAAe,GAAG,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { IServerRequest } from '@vue-skuilder/common';
2
+ export interface Result {
3
+ status: 'ok' | 'awaiting' | 'warning' | 'error';
4
+ ok: boolean;
5
+ error?: unknown;
6
+ }
7
+ interface ProcessingFunction<T> {
8
+ (data: T): Promise<Result>;
9
+ }
10
+ /**
11
+ * This queue executes async prcesses sequentially, waiting
12
+ * for each to complete before launching the next.
13
+ */
14
+ export default class AsyncProcessQueue<T extends IServerRequest, R extends Result> {
15
+ private processRequest;
16
+ private queue;
17
+ private errors;
18
+ private completed;
19
+ private processing;
20
+ private nextID;
21
+ /**
22
+ * Returns 'complete' if the job is complete, 'error' if the
23
+ * job failed, and the job's position in queue if not yet
24
+ * completed.
25
+ *
26
+ * @param jobID The jobID returned by addRequest
27
+ */
28
+ jobStatus(jobID: number): 'complete' | 'error' | number;
29
+ private recurseGetResult;
30
+ getResult(jobID: number, _depth?: number): Promise<R>;
31
+ addRequest(req: T): number;
32
+ /**
33
+ *
34
+ */
35
+ constructor(processingFcn: ProcessingFunction<T>);
36
+ private process;
37
+ }
38
+ export {};
39
+ //# sourceMappingURL=processQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processQueue.d.ts","sourceRoot":"","sources":["../../src/utils/processQueue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAItD,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;IAChD,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,kBAAkB,CAAC,CAAC;IAC5B,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5B;AAcD;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB,CACpC,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,MAAM;IAEhB,OAAO,CAAC,cAAc,CAAwB;IAE9C,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,SAAS,CAA6B;IAE9C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAK;IAEnB;;;;;;OAMG;IACI,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM;YAuBhD,gBAAgB;IA+BjB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,CAAC,CAAC;IA2CtD,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,MAAM;IAejC;;OAEG;gBACS,aAAa,EAAE,kBAAkB,CAAC,CAAC,CAAC;YAIlC,OAAO;CAgDtB"}