@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.
- package/.env.development +9 -0
- package/.prettierignore +4 -0
- package/.prettierrc +8 -0
- package/.vscode/launch.json +20 -0
- package/assets/classroomDesignDoc.js +24 -0
- package/assets/courseValidateDocUpdate.js +56 -0
- package/assets/get-tagsDesignDoc.json +9 -0
- package/babel.config.js +6 -0
- package/dist/app.d.ts +6 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +194 -0
- package/dist/app.js.map +1 -0
- package/dist/attachment-preprocessing/index.d.ts +11 -0
- package/dist/attachment-preprocessing/index.d.ts.map +1 -0
- package/dist/attachment-preprocessing/index.js +146 -0
- package/dist/attachment-preprocessing/index.js.map +1 -0
- package/dist/attachment-preprocessing/normalize.d.ts +7 -0
- package/dist/attachment-preprocessing/normalize.d.ts.map +1 -0
- package/dist/attachment-preprocessing/normalize.js +90 -0
- package/dist/attachment-preprocessing/normalize.js.map +1 -0
- package/dist/client-requests/classroom-requests.d.ts +26 -0
- package/dist/client-requests/classroom-requests.d.ts.map +1 -0
- package/dist/client-requests/classroom-requests.js +171 -0
- package/dist/client-requests/classroom-requests.js.map +1 -0
- package/dist/client-requests/course-requests.d.ts +10 -0
- package/dist/client-requests/course-requests.d.ts.map +1 -0
- package/dist/client-requests/course-requests.js +135 -0
- package/dist/client-requests/course-requests.js.map +1 -0
- package/dist/client.d.ts +31 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +70 -0
- package/dist/client.js.map +1 -0
- package/dist/couchdb/authentication.d.ts +4 -0
- package/dist/couchdb/authentication.d.ts.map +1 -0
- package/dist/couchdb/authentication.js +64 -0
- package/dist/couchdb/authentication.js.map +1 -0
- package/dist/couchdb/index.d.ts +18 -0
- package/dist/couchdb/index.d.ts.map +1 -0
- package/dist/couchdb/index.js +52 -0
- package/dist/couchdb/index.js.map +1 -0
- package/dist/design-docs.d.ts +63 -0
- package/dist/design-docs.d.ts.map +1 -0
- package/dist/design-docs.js +90 -0
- package/dist/design-docs.js.map +1 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +62 -0
- package/dist/logger.js.map +1 -0
- package/dist/routes/logs.d.ts +3 -0
- package/dist/routes/logs.d.ts.map +1 -0
- package/dist/routes/logs.js +274 -0
- package/dist/routes/logs.js.map +1 -0
- package/dist/utils/env.d.ts +10 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +38 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/processQueue.d.ts +39 -0
- package/dist/utils/processQueue.d.ts.map +1 -0
- package/dist/utils/processQueue.js +175 -0
- package/dist/utils/processQueue.js.map +1 -0
- package/eslint.config.js +19 -0
- package/jest.config.ts +24 -0
- package/package.json +74 -0
- package/src/app.ts +246 -0
- package/src/attachment-preprocessing/index.ts +204 -0
- package/src/attachment-preprocessing/normalize.ts +123 -0
- package/src/client-requests/classroom-requests.ts +234 -0
- package/src/client-requests/course-requests.ts +188 -0
- package/src/client.ts +97 -0
- package/src/couchdb/authentication.ts +85 -0
- package/src/couchdb/index.ts +76 -0
- package/src/design-docs.ts +107 -0
- package/src/logger.ts +75 -0
- package/src/routes/logs.ts +289 -0
- package/src/utils/env.ts +51 -0
- package/src/utils/processQueue.ts +218 -0
- package/test/client.test.ts +144 -0
- 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"}
|
package/dist/logger.d.ts
ADDED
|
@@ -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 @@
|
|
|
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":"AAAA,OAAO,OAA8B,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAE3C,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;AAEhC,2CAA2C;AAC3C,MAAM,aAAa,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACvC,GAAG,EAAE,EAAE,EAAE,4CAA4C;IACrD,OAAO,EAAE;QACP,KAAK,EAAE,6DAA6D;KACrE;IACD,eAAe,EAAE,IAAI,EAAE,sDAAsD;IAC7E,aAAa,EAAE,KAAK,EAAE,sCAAsC;CAC7D,CAAC,CAAC;AAEH,mDAAmD;AACnD,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAE1B,kCAAkC;AAClC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;IAC/C,KAAK,CAAC,KAAK,IAAI,EAAE;QACjB,mDAAmD;QACnD,4FAA4F;QAC5F,EAAE;QACF,uDAAuD;QACvD,eAAe;QACf,qDAAqD;QACrD,YAAY;QACZ,IAAI;QAEJ,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;YACjD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAExC,sBAAsB;YACtB,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiCC,KAAK;iBACJ,GAAG,CACF,CAAC,IAAI,EAAE,EAAE,CAAC;;qCAEO,IAAI,KAAK,IAAI;;iBAEjC,CACE;iBACA,IAAI,CAAC,EAAE,CAAC;;;;SAIlB,CAAC;YAEN,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACrD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;QAClE,CAAC;IACD,CAAC,CAAC,EAAE,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IACvD,KAAK,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;YACrC,mDAAmD;YACnD,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACpE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;gBAC9D,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YAEjE,kBAAkB;YAClB,MAAM,KAAK,GAAG,OAAO;iBAClB,KAAK,CAAC,IAAI,CAAC;iBACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;iBAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACZ,IAAI,CAAC;oBACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,CAAC;YAEL,MAAM,IAAI,GAAG;;;;gCAIe,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAmET,QAAQ;;;+BAGR,QAAQ;;;;;;;;;;;;;;;;;;;;;cAqBzB,KAAK;iBACJ,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACZ,IAAI,UAAU,GAAG,EAAE,CAAC;gBACpB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBAC3C,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACxC,CAAC;gBACD,OAAO,yBAAyB,UAAU;kBAExC,OAAO,IAAI,KAAK,QAAQ;oBACtB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC/B,CAAC,CAAC,IACN;qBACK,CAAC;YACR,CAAC,CAAC;iBACD,IAAI,CAAC,EAAE,CAAC;;;;KAIlB,CAAC;YAEF,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,0BAA0B,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;YACtE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;QAC3E,CAAC;IACD,CAAC,CAAC,EAAE,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,oCAAoC;AACpC,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IAC3D,KAAK,CAAC,KAAK,IAAI,EAAE;QACjB,uDAAuD;QACvD,eAAe;QACf,qDAAqD;QACrD,YAAY;QACZ,IAAI;QAEJ,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;YACrC,mDAAmD;YACnD,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACpE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YAEjE,qCAAqC;YACrC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,kBAAkB,EAAE,CAAC;gBAC9C,MAAM,KAAK,GAAG,OAAO;qBAClB,KAAK,CAAC,IAAI,CAAC;qBACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;qBAC7B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;oBACZ,IAAI,CAAC;wBACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC1B,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,IAAI,CAAC;oBACd,CAAC;gBACH,CAAC,CAAC,CAAC;gBACL,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,+BAA+B;gBAC/B,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,0BAA0B,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;YACtE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;QACjE,CAAC;IACD,CAAC,CAAC,EAAE,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
|
@@ -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"}
|