web_plsql 0.12.1 → 0.13.2
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/README.md +3 -5
- package/examples/config-apex.js +2 -3
- package/examples/config-docker.js +0 -1
- package/examples/config-docker.json +1 -2
- package/examples/config-native.js +2 -3
- package/examples/sql/install.sql +2 -0
- package/examples/sql/sample_package.sql +2 -1
- package/examples/sql/sample_package_body.sql +71 -16
- package/examples/sql/uninstall.sql +2 -0
- package/package.json +9 -11
- package/src/handler/handlerMetrics.js +68 -0
- package/src/{handlerUpload.js → handler/handlerUpload.js} +2 -2
- package/src/{cgi.js → handler/plsql/cgi.js} +6 -2
- package/src/{errorPage.js → handler/plsql/errorPage.js} +5 -5
- package/src/{handlerPlSql.js → handler/plsql/handlerPlSql.js} +2 -2
- package/src/{parsePage.js → handler/plsql/parsePage.js} +24 -8
- package/src/{procedure.js → handler/plsql/procedure.js} +7 -10
- package/src/{procedureError.js → handler/plsql/procedureError.js} +2 -2
- package/src/{procedureNamed.js → handler/plsql/procedureNamed.js} +4 -4
- package/src/{procedureSanitize.js → handler/plsql/procedureSanitize.js} +6 -6
- package/src/{procedureVariable.js → handler/plsql/procedureVariable.js} +3 -3
- package/src/{request.js → handler/plsql/request.js} +3 -9
- package/src/{sendResponse.js → handler/plsql/sendResponse.js} +6 -6
- package/src/{upload.js → handler/plsql/upload.js} +2 -2
- package/src/index.js +8 -9
- package/src/server/config.js +45 -0
- package/src/server/connections.js +40 -0
- package/src/server/server.js +184 -0
- package/src/types.js +2 -13
- package/src/util/date.js +23 -0
- package/src/{shutdown.js → util/shutdown.js} +3 -16
- package/src/util/type.js +6 -0
- package/types/handler/handlerMetrics.d.ts +25 -0
- package/types/{handlerUpload.d.ts → handler/handlerUpload.d.ts} +2 -2
- package/types/{cgi.d.ts → handler/plsql/cgi.d.ts} +2 -2
- package/types/{errorPage.d.ts → handler/plsql/errorPage.d.ts} +3 -3
- package/types/{handlerPlSql.d.ts → handler/plsql/handlerPlSql.d.ts} +2 -2
- package/types/handler/plsql/parsePage.d.ts +3 -0
- package/types/{procedure.d.ts → handler/plsql/procedure.d.ts} +5 -5
- package/types/{procedureError.d.ts → handler/plsql/procedureError.d.ts} +4 -4
- package/types/{procedureNamed.d.ts → handler/plsql/procedureNamed.d.ts} +3 -3
- package/types/{procedureSanitize.d.ts → handler/plsql/procedureSanitize.d.ts} +5 -5
- package/types/{procedureVariable.d.ts → handler/plsql/procedureVariable.d.ts} +3 -3
- package/types/{request.d.ts → handler/plsql/request.d.ts} +2 -2
- package/types/{sendResponse.d.ts → handler/plsql/sendResponse.d.ts} +3 -1
- package/types/{upload.d.ts → handler/plsql/upload.d.ts} +1 -1
- package/types/index.d.ts +8 -9
- package/types/server/config.d.ts +2 -0
- package/types/server/server.d.ts +52 -0
- package/types/types.d.ts +4 -37
- package/types/util/type.d.ts +1 -0
- package/src/handlerMetrics.js +0 -46
- package/src/server.js +0 -223
- package/src/tty.js +0 -48
- package/types/handlerMetrics.d.ts +0 -4
- package/types/parsePage.d.ts +0 -3
- package/types/server.d.ts +0 -14
- package/types/tty.d.ts +0 -4
- /package/src/{handlerLogger.js → handler/handlerLogger.js} +0 -0
- /package/src/{requestError.js → handler/plsql/requestError.js} +0 -0
- /package/src/{stream.js → handler/plsql/stream.js} +0 -0
- /package/src/{error.js → util/errorToString.js} +0 -0
- /package/src/{file.js → util/file.js} +0 -0
- /package/src/{oracle.js → util/oracle.js} +0 -0
- /package/src/{trace.js → util/trace.js} +0 -0
- /package/types/{handlerLogger.d.ts → handler/handlerLogger.d.ts} +0 -0
- /package/types/{requestError.d.ts → handler/plsql/requestError.d.ts} +0 -0
- /package/types/{stream.d.ts → handler/plsql/stream.d.ts} +0 -0
- /package/types/{error.d.ts → util/errorToString.d.ts} +0 -0
- /package/types/{file.d.ts → util/file.d.ts} +0 -0
- /package/types/{oracle.d.ts → util/oracle.d.ts} +0 -0
- /package/types/{shutdown.d.ts → util/shutdown.d.ts} +0 -0
- /package/types/{trace.d.ts → util/trace.d.ts} +0 -0
|
@@ -10,14 +10,15 @@ import {invokeProcedure} from './procedure.js';
|
|
|
10
10
|
import {getCGI} from './cgi.js';
|
|
11
11
|
import {getFiles} from './upload.js';
|
|
12
12
|
import {RequestError} from './requestError.js';
|
|
13
|
+
import {isStringOrArrayOfString} from '../../util/type.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @typedef {import('express').Request} Request
|
|
16
17
|
* @typedef {import('express').Response} Response
|
|
17
18
|
* @typedef {import('oracledb').Pool} Pool
|
|
18
19
|
* @typedef {import('oracledb').Connection} Connection
|
|
19
|
-
* @typedef {import('
|
|
20
|
-
* @typedef {import('
|
|
20
|
+
* @typedef {import('../../types.js').argObjType} argObjType
|
|
21
|
+
* @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
|
|
21
22
|
*/
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -66,13 +67,6 @@ export const processRequest = async (req, res, options, connectionPool) => {
|
|
|
66
67
|
debug('executeRequest: EXIT');
|
|
67
68
|
};
|
|
68
69
|
|
|
69
|
-
/**
|
|
70
|
-
* Is the given value a string or an array of strings
|
|
71
|
-
* @param {unknown} value - The value to check.
|
|
72
|
-
* @returns {value is string | string[]} - True if the value is a string or an array of strings
|
|
73
|
-
*/
|
|
74
|
-
const isStringOrArrayOfString = (value) => typeof value === 'string' || (Array.isArray(value) && value.every((element) => typeof element === 'string'));
|
|
75
|
-
|
|
76
70
|
/**
|
|
77
71
|
* Normalize the body by making sure that only "simple" parameters and no nested objects are submitted
|
|
78
72
|
* @param {Request} req - The req object represents the HTTP request.
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
import debugModule from 'debug';
|
|
6
6
|
const debug = debugModule('webplsql:sendResponse');
|
|
7
7
|
|
|
8
|
-
import {getBlock} from '
|
|
8
|
+
import {getBlock} from '../../util/trace.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @typedef {import('express').Request} Request
|
|
12
12
|
* @typedef {import('express').Response} Response
|
|
13
|
-
* @typedef {import('
|
|
13
|
+
* @typedef {import('express').CookieOptions} CookieOptions
|
|
14
|
+
* @typedef {import('../../types.js').pageType} pageType
|
|
15
|
+
* @typedef {import('../../types.js').cookieType} cookieType
|
|
14
16
|
*/
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -26,13 +28,11 @@ export const sendResponse = (req, res, page) => {
|
|
|
26
28
|
|
|
27
29
|
// Send the "cookies"
|
|
28
30
|
page.head.cookies.forEach((cookie) => {
|
|
29
|
-
const {name, value} = cookie;
|
|
30
|
-
|
|
31
31
|
if (debug.enabled) {
|
|
32
|
-
debugText.push(`res.cookie
|
|
32
|
+
debugText.push(`res.cookie: name="${cookie.name}" value="${cookie.value}" options=${JSON.stringify(cookie.options)}`);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
res.cookie(name, value);
|
|
35
|
+
res.cookie(cookie.name, cookie.value, cookie.options);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
// If there is a "redirectLocation" header, we immediately redirect and return
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import debugModule from 'debug';
|
|
8
8
|
const debug = debugModule('webplsql:fileUpload');
|
|
9
9
|
|
|
10
|
-
import {readFile, removeFile} from '
|
|
10
|
+
import {readFile, removeFile} from '../../util/file.js';
|
|
11
11
|
import oracledb from 'oracledb';
|
|
12
12
|
import z from 'zod';
|
|
13
13
|
|
|
@@ -27,7 +27,7 @@ const z$reqFiles = z.array(
|
|
|
27
27
|
/**
|
|
28
28
|
* @typedef {import('express').Request} Request
|
|
29
29
|
* @typedef {import('oracledb').Connection} Connection
|
|
30
|
-
* @typedef {import('
|
|
30
|
+
* @typedef {import('../../types.js').fileUploadType} fileUploadType
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
/**
|
package/src/index.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
// server
|
|
2
|
-
export {
|
|
3
|
-
export * from './shutdown.js';
|
|
2
|
+
export {createServer, startServer, loadConfig, startServerConfig} from './server/server.js';
|
|
3
|
+
export * from './util/shutdown.js';
|
|
4
4
|
|
|
5
5
|
// handler
|
|
6
|
-
export {handlerWebPlSql} from './handlerPlSql.js';
|
|
7
|
-
export {handlerLogger} from './handlerLogger.js';
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
6
|
+
export {handlerWebPlSql} from './handler/plsql/handlerPlSql.js';
|
|
7
|
+
export {handlerLogger} from './handler/handlerLogger.js';
|
|
8
|
+
export {handlerUpload} from './handler/handlerUpload.js';
|
|
9
|
+
export {handlerMetrics} from './handler/handlerMetrics.js';
|
|
10
10
|
|
|
11
11
|
// oracle
|
|
12
|
-
export * from './oracle.js';
|
|
12
|
+
export * from './util/oracle.js';
|
|
13
13
|
|
|
14
14
|
// util
|
|
15
|
-
export * from './file.js';
|
|
16
|
-
export * from './tty.js';
|
|
15
|
+
export * from './util/file.js';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('../types.js').configType} configType
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Show configuration.
|
|
7
|
+
* @param {configType} config - The config.
|
|
8
|
+
* @returns {void}
|
|
9
|
+
*/
|
|
10
|
+
export const showConfig = (config) => {
|
|
11
|
+
const LINE = '-'.repeat(80);
|
|
12
|
+
|
|
13
|
+
console.log(LINE);
|
|
14
|
+
console.log('NODE PL/SQL SERVER');
|
|
15
|
+
console.log(LINE);
|
|
16
|
+
|
|
17
|
+
console.log(`Server port: ${config.port}`);
|
|
18
|
+
console.log(`Access log: ${config.loggerFilename.length > 0 ? config.loggerFilename : ''}`);
|
|
19
|
+
|
|
20
|
+
if (config.routeStatic.length > 0) {
|
|
21
|
+
console.log(LINE);
|
|
22
|
+
config.routeStatic.forEach((e) => {
|
|
23
|
+
console.log(`Static route: ${e.route}`);
|
|
24
|
+
console.log(`Directory path: ${e.directoryPath}`);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (config.routePlSql.length > 0) {
|
|
29
|
+
console.log(LINE);
|
|
30
|
+
config.routePlSql.forEach((e) => {
|
|
31
|
+
console.log(`Route: http://localhost:${config.port}${e.route}`);
|
|
32
|
+
console.log(`Oracle user: ${e.user}`);
|
|
33
|
+
console.log(`Oracle server: ${e.connectString}`);
|
|
34
|
+
console.log(`Oracle document table: ${e.documentTable}`);
|
|
35
|
+
console.log(`Default page: ${e.defaultPage}`);
|
|
36
|
+
console.log(`Path alias: ${e.pathAlias}`);
|
|
37
|
+
console.log(`Path alias procedure: ${e.pathAliasProcedure}`);
|
|
38
|
+
console.log(`Exclution list: ${e.exclusionList?.join(', ')}`);
|
|
39
|
+
console.log(`Validation function: ${e.requestValidationFunction}`);
|
|
40
|
+
console.log(`Error style: ${e.errorStyle}`);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log(LINE);
|
|
45
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('node:net').Socket} Socket
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} id - id
|
|
7
|
+
* @param {string} ip - address
|
|
8
|
+
* @param {string} port - port
|
|
9
|
+
* @param {string} read - bytes read
|
|
10
|
+
* @param {string} written - bytes written
|
|
11
|
+
*/
|
|
12
|
+
const line = (id, ip, port, read, written) => {
|
|
13
|
+
console.log(`${id.padStart(3)} ${ip.padEnd(15)} ${port.padStart(5)} ${read.padStart(10)} ${written.padStart(10)}`);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Show connections.
|
|
18
|
+
* @param {Set<Socket>} connections - The connections.
|
|
19
|
+
* @returns {void}
|
|
20
|
+
*/
|
|
21
|
+
export const showConnections = (connections) => {
|
|
22
|
+
if (connections.size === 0) {
|
|
23
|
+
console.log('No open connections.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Print header
|
|
28
|
+
line('ID', 'IP', 'Port', 'Read', 'Written');
|
|
29
|
+
|
|
30
|
+
let i = 0;
|
|
31
|
+
for (const socket of connections) {
|
|
32
|
+
line(
|
|
33
|
+
(i++).toString(),
|
|
34
|
+
socket.remoteAddress ?? '',
|
|
35
|
+
typeof socket.remotePort === 'number' ? socket.remotePort.toFixed() : '',
|
|
36
|
+
socket.bytesRead.toFixed(),
|
|
37
|
+
socket.bytesWritten.toFixed(),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import debugModule from 'debug';
|
|
2
|
+
const debug = debugModule('webplsql:server');
|
|
3
|
+
|
|
4
|
+
import http from 'node:http';
|
|
5
|
+
import https from 'node:https';
|
|
6
|
+
import express from 'express';
|
|
7
|
+
import cookieParser from 'cookie-parser';
|
|
8
|
+
import compression from 'compression';
|
|
9
|
+
import {z$configType} from '../types.js';
|
|
10
|
+
import {installShutdown} from '../util/shutdown.js';
|
|
11
|
+
import {poolCreate, poolsClose} from '../util/oracle.js';
|
|
12
|
+
import {handlerUpload} from '../handler/handlerUpload.js';
|
|
13
|
+
import {handlerLogger} from '../handler/handlerLogger.js';
|
|
14
|
+
import {handlerWebPlSql} from '../handler/plsql/handlerPlSql.js';
|
|
15
|
+
import {readFileSyncUtf8, getJsonFile} from '../util/file.js';
|
|
16
|
+
import {showConfig} from './config.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {import('node:net').Socket} Socket
|
|
20
|
+
* @typedef {import('express').Express} Express
|
|
21
|
+
* @typedef {import('express').Request} Request
|
|
22
|
+
* @typedef {import('express').Response} Response
|
|
23
|
+
* @typedef {import('express').NextFunction} NextFunction
|
|
24
|
+
* @typedef {import('oracledb').Pool} Pool
|
|
25
|
+
* @typedef {import('../types.js').environmentType} environmentType
|
|
26
|
+
* @typedef {import('../types.js').configType} configType
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {object} webServer - Web server interface.
|
|
31
|
+
* @property {configType} config - Configuration object.
|
|
32
|
+
* @property {Pool[]} connectionPools - Oracle connection pools.
|
|
33
|
+
* @property {Express} app - Express app.
|
|
34
|
+
* @property {http.Server | https.Server} server - Native Node http(s) server instance.
|
|
35
|
+
* @property {() => Promise<void>} shutdown - Shutdown function.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {object} sslConfig - SSL configuration.
|
|
40
|
+
* @property {string} keyFilename - key filename.
|
|
41
|
+
* @property {string} certFilename - cert filename.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Create HTTPS server.
|
|
46
|
+
* @param {Express} app - express application
|
|
47
|
+
* @param {sslConfig} [ssl] - ssl configuration.
|
|
48
|
+
* @returns {http.Server | https.Server} - server
|
|
49
|
+
*/
|
|
50
|
+
export const createServer = (app, ssl) => {
|
|
51
|
+
if (ssl) {
|
|
52
|
+
const key = readFileSyncUtf8(ssl.keyFilename);
|
|
53
|
+
const cert = readFileSyncUtf8(ssl.certFilename);
|
|
54
|
+
|
|
55
|
+
return https.createServer({key, cert}, app);
|
|
56
|
+
} else {
|
|
57
|
+
return http.createServer(app);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Start server.
|
|
63
|
+
* @param {configType} config - The config.
|
|
64
|
+
* @param {sslConfig} [ssl] - ssl configuration.
|
|
65
|
+
* @returns {Promise<webServer>} - Promise resolving to the web server object.
|
|
66
|
+
*/
|
|
67
|
+
export const startServer = async (config, ssl) => {
|
|
68
|
+
debug('startServer: BEGIN', config, ssl);
|
|
69
|
+
|
|
70
|
+
config = z$configType.parse(config);
|
|
71
|
+
|
|
72
|
+
showConfig(config);
|
|
73
|
+
|
|
74
|
+
// Create express app
|
|
75
|
+
const app = express();
|
|
76
|
+
|
|
77
|
+
// Access log
|
|
78
|
+
if (config.loggerFilename.length > 0) {
|
|
79
|
+
app.use(handlerLogger(config.loggerFilename));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Serving static files
|
|
83
|
+
for (const i of config.routeStatic) {
|
|
84
|
+
app.use(i.route, express.static(i.directoryPath));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Default middleware
|
|
88
|
+
app.use(handlerUpload());
|
|
89
|
+
app.use(express.json());
|
|
90
|
+
app.use(express.urlencoded({extended: true}));
|
|
91
|
+
app.use(cookieParser());
|
|
92
|
+
app.use(compression());
|
|
93
|
+
|
|
94
|
+
/** @type {Pool[]} */
|
|
95
|
+
const connectionPools = [];
|
|
96
|
+
|
|
97
|
+
// Oracle pl/sql express middleware
|
|
98
|
+
for (const i of config.routePlSql) {
|
|
99
|
+
// Allocate the Oracle database pool
|
|
100
|
+
const pool = await poolCreate(i.user, i.password, i.connectString);
|
|
101
|
+
connectionPools.push(pool);
|
|
102
|
+
|
|
103
|
+
app.use([`${i.route}/:name`, i.route], handlerWebPlSql(pool, i));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// create server
|
|
107
|
+
debug('startServer: createServer');
|
|
108
|
+
const server = createServer(app, ssl);
|
|
109
|
+
|
|
110
|
+
// Track open connections
|
|
111
|
+
/** @type {Set<Socket>} */
|
|
112
|
+
const connections = new Set();
|
|
113
|
+
server.on('connection', (/** @type {Socket} */ socket) => {
|
|
114
|
+
connections.add(socket);
|
|
115
|
+
socket.on('close', () => {
|
|
116
|
+
connections.delete(socket);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const closeAllConnections = () => {
|
|
121
|
+
for (const socket of connections) {
|
|
122
|
+
socket.destroy(); // forcibly closes the connection
|
|
123
|
+
connections.delete(socket);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const shutdown = async () => {
|
|
128
|
+
debug('startServer: onShutdown');
|
|
129
|
+
|
|
130
|
+
await poolsClose(connectionPools);
|
|
131
|
+
|
|
132
|
+
server.close(() => {
|
|
133
|
+
console.log('Server has closed');
|
|
134
|
+
process.exit(0);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
closeAllConnections();
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Install shutdown handler
|
|
141
|
+
installShutdown(shutdown);
|
|
142
|
+
|
|
143
|
+
// Listen
|
|
144
|
+
debug('startServer: start listener');
|
|
145
|
+
await /** @type {Promise<void>} */ (
|
|
146
|
+
new Promise((resolve, reject) => {
|
|
147
|
+
server
|
|
148
|
+
.listen(config.port)
|
|
149
|
+
.on('listening', () => {
|
|
150
|
+
debug('startServer: listener running');
|
|
151
|
+
resolve();
|
|
152
|
+
})
|
|
153
|
+
.on('error', (err) => {
|
|
154
|
+
console.error(err);
|
|
155
|
+
reject(err);
|
|
156
|
+
});
|
|
157
|
+
})
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
debug('startServer: END');
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
config,
|
|
164
|
+
connectionPools,
|
|
165
|
+
app,
|
|
166
|
+
server,
|
|
167
|
+
shutdown,
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Load configuration.
|
|
173
|
+
* @param {string} [filename] - The configuration filename.
|
|
174
|
+
* @returns {configType} - Promise.
|
|
175
|
+
*/
|
|
176
|
+
export const loadConfig = (filename = 'config.json') => z$configType.parse(getJsonFile(filename));
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Start server from config file.
|
|
180
|
+
* @param {string} [filename] - The configuration filename.
|
|
181
|
+
* @param {sslConfig} [ssl] - ssl configuration.
|
|
182
|
+
* @returns {Promise<webServer>} - Promise resolving to the web server object.
|
|
183
|
+
*/
|
|
184
|
+
export const startServerConfig = async (filename = 'config.json', ssl) => startServer(loadConfig(filename), ssl);
|
package/src/types.js
CHANGED
|
@@ -2,6 +2,7 @@ import z from 'zod';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @typedef {import('oracledb').BindParameter} BindParameter
|
|
5
|
+
* @typedef {import('express').CookieOptions} CookieOptions
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -68,14 +69,12 @@ export const z$configPlSqlType = z.strictObject({
|
|
|
68
69
|
* @property {configStaticType[]} routeStatic - The static routes.
|
|
69
70
|
* @property {configPlSqlType[]} routePlSql - The PL/SQL routes.
|
|
70
71
|
* @property {string} loggerFilename - name of the request logger filename or '' if not required.
|
|
71
|
-
* @property {boolean} monitorConsole - Enable console status monitor.
|
|
72
72
|
*/
|
|
73
73
|
export const z$configType = z.strictObject({
|
|
74
74
|
port: z.number(),
|
|
75
75
|
routeStatic: z.array(z$configStaticType),
|
|
76
76
|
routePlSql: z.array(z$configPlSqlType),
|
|
77
77
|
loggerFilename: z.string(),
|
|
78
|
-
monitorConsole: z.boolean(),
|
|
79
78
|
});
|
|
80
79
|
|
|
81
80
|
/**
|
|
@@ -109,11 +108,7 @@ export const z$configType = z.strictObject({
|
|
|
109
108
|
* @typedef {object} cookieType
|
|
110
109
|
* @property {string} name - The name of the cookie.
|
|
111
110
|
* @property {string} value - The value of the cookie.
|
|
112
|
-
* @property {
|
|
113
|
-
* @property {string} [domain] - The domain of the cookie.
|
|
114
|
-
* @property {string} [secure] - The secure flag.
|
|
115
|
-
* @property {Date} [expires] - The expiration date.
|
|
116
|
-
* @property {boolean} [httpOnly] - The httpOnly flag.
|
|
111
|
+
* @property {CookieOptions} options - The cookie options.
|
|
117
112
|
*/
|
|
118
113
|
|
|
119
114
|
/**
|
|
@@ -133,9 +128,3 @@ export const z$configType = z.strictObject({
|
|
|
133
128
|
* @property {number | null} file.fileSize - The file size.
|
|
134
129
|
* @property {Buffer | null} file.fileBlob - The file blob.
|
|
135
130
|
*/
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* @typedef {object} metricsType - The metrics.
|
|
139
|
-
* @property {number} totalRequests - The total number of requests.
|
|
140
|
-
* @property {number} requestsInLastInterval - The number of requests in the last second.
|
|
141
|
-
*/
|
package/src/util/date.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get duration as human readable string.
|
|
3
|
+
* @param {number} duration - Milliseconds.
|
|
4
|
+
* @returns {string} String.
|
|
5
|
+
*/
|
|
6
|
+
export const humanDuration = (duration) => {
|
|
7
|
+
if (!Number.isFinite(duration)) return 'invalid';
|
|
8
|
+
|
|
9
|
+
const ms = Math.floor(duration % 1000);
|
|
10
|
+
const s = Math.floor((duration / 1000) % 60);
|
|
11
|
+
const m = Math.floor((duration / (1000 * 60)) % 60);
|
|
12
|
+
const h = Math.floor((duration / (1000 * 60 * 60)) % 24);
|
|
13
|
+
const d = Math.floor(duration / (1000 * 60 * 60 * 24));
|
|
14
|
+
|
|
15
|
+
const parts = [];
|
|
16
|
+
if (d) parts.push(`${d}d`);
|
|
17
|
+
if (h) parts.push(`${h}h`);
|
|
18
|
+
if (m) parts.push(`${m}m`);
|
|
19
|
+
if (s) parts.push(`${s}s`);
|
|
20
|
+
if (ms || !parts.length) parts.push(`${ms}ms`);
|
|
21
|
+
|
|
22
|
+
return parts.join(' ');
|
|
23
|
+
};
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import debugModule from 'debug';
|
|
2
2
|
const debug = debugModule('webplsql:shutdown');
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* @param {() => Promise<void>} handler - Shutdown handler
|
|
6
|
-
* @returns {void}
|
|
7
|
-
*/
|
|
8
|
-
const shutdown = (handler) => {
|
|
9
|
-
handler().then(
|
|
10
|
-
() => process.exit(0),
|
|
11
|
-
() => process.exit(1),
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
process.exit(0);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
4
|
/**
|
|
18
5
|
* Install a shutdown handler.
|
|
19
6
|
* @param {() => Promise<void>} handler - Shutdown handler
|
|
@@ -27,18 +14,18 @@ export const installShutdown = (handler) => {
|
|
|
27
14
|
*/
|
|
28
15
|
process.on('unhandledRejection', (reason, p) => {
|
|
29
16
|
console.log('\nUnhandled promise rejection. Graceful shutdown...', reason, p);
|
|
30
|
-
|
|
17
|
+
void handler();
|
|
31
18
|
});
|
|
32
19
|
|
|
33
20
|
// install signal event handler
|
|
34
21
|
process.on('SIGTERM', function sigterm() {
|
|
35
22
|
console.log('\nGot SIGINT (aka ctrl-c in docker). Graceful shutdown...');
|
|
36
|
-
|
|
23
|
+
void handler();
|
|
37
24
|
});
|
|
38
25
|
|
|
39
26
|
process.on('SIGINT', function sigint() {
|
|
40
27
|
console.log('\nGot SIGTERM (aka docker container stop). Graceful shutdown...');
|
|
41
|
-
|
|
28
|
+
void handler();
|
|
42
29
|
});
|
|
43
30
|
};
|
|
44
31
|
|
package/src/util/type.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Is the given value a string or an array of strings
|
|
3
|
+
* @param {unknown} value - The value to check.
|
|
4
|
+
* @returns {value is string | string[]} - True if the value is a string or an array of strings
|
|
5
|
+
*/
|
|
6
|
+
export const isStringOrArrayOfString = (value) => typeof value === 'string' || (Array.isArray(value) && value.every((element) => typeof element === 'string'));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function initMetrics(): metricsType;
|
|
2
|
+
export function handlerMetrics(metrics: metricsType): RequestHandler;
|
|
3
|
+
export type RequestHandler = import("express").RequestHandler;
|
|
4
|
+
export type metricsType = {
|
|
5
|
+
/**
|
|
6
|
+
* - When was the server started.
|
|
7
|
+
*/
|
|
8
|
+
started: Date;
|
|
9
|
+
/**
|
|
10
|
+
* - Total number of requests.
|
|
11
|
+
*/
|
|
12
|
+
totalRequests: number;
|
|
13
|
+
/**
|
|
14
|
+
* - Total amount of time in ms in request.
|
|
15
|
+
*/
|
|
16
|
+
totalRequestDuration: number;
|
|
17
|
+
/**
|
|
18
|
+
* - Min amount of time in ms in request.
|
|
19
|
+
*/
|
|
20
|
+
minRequestDuration: number;
|
|
21
|
+
/**
|
|
22
|
+
* - Max amount of time in ms in request.
|
|
23
|
+
*/
|
|
24
|
+
maxRequestDuration: number;
|
|
25
|
+
};
|
|
@@ -3,5 +3,5 @@ export type RequestHandler = import("express").RequestHandler;
|
|
|
3
3
|
export type Response = import("express").Response;
|
|
4
4
|
export type NextFunction = import("express").NextFunction;
|
|
5
5
|
export type Pool = import("oracledb").Pool;
|
|
6
|
-
export type environmentType = import("
|
|
7
|
-
export type configType = import("
|
|
6
|
+
export type environmentType = import("../types.js").environmentType;
|
|
7
|
+
export type configType = import("../types.js").configType;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export function getCGI(req: Request, doctable: string, cgi: environmentType): environmentType;
|
|
2
2
|
export type Request = import("express").Request;
|
|
3
|
-
export type environmentType = import("
|
|
4
|
-
export type configPlSqlType = import("
|
|
3
|
+
export type environmentType = import("../../types.js").environmentType;
|
|
4
|
+
export type configPlSqlType = import("../../types.js").configPlSqlType;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export function errorPage(req: Request, res: Response, options: configPlSqlHandlerType, error: unknown): void;
|
|
2
2
|
export type Request = import("express").Request;
|
|
3
3
|
export type Response = import("express").Response;
|
|
4
|
-
export type BindParameterConfig = import("
|
|
5
|
-
export type environmentType = import("
|
|
6
|
-
export type configPlSqlHandlerType = import("
|
|
4
|
+
export type BindParameterConfig = import("../../types.js").BindParameterConfig;
|
|
5
|
+
export type environmentType = import("../../types.js").environmentType;
|
|
6
|
+
export type configPlSqlHandlerType = import("../../types.js").configPlSqlHandlerType;
|
|
7
7
|
export type outputType = {
|
|
8
8
|
html: string;
|
|
9
9
|
text: string;
|
|
@@ -4,5 +4,5 @@ export type Request = import("express").Request;
|
|
|
4
4
|
export type Response = import("express").Response;
|
|
5
5
|
export type NextFunction = import("express").NextFunction;
|
|
6
6
|
export type Pool = import("oracledb").Pool;
|
|
7
|
-
export type environmentType = import("
|
|
8
|
-
export type configPlSqlHandlerType = import("
|
|
7
|
+
export type environmentType = import("../../types.js").environmentType;
|
|
8
|
+
export type configPlSqlHandlerType = import("../../types.js").configPlSqlHandlerType;
|
|
@@ -3,8 +3,8 @@ export type Request = import("express").Request;
|
|
|
3
3
|
export type Response = import("express").Response;
|
|
4
4
|
export type Connection = import("oracledb").Connection;
|
|
5
5
|
export type Result = import("oracledb").Result<unknown>;
|
|
6
|
-
export type argObjType = import("
|
|
7
|
-
export type fileUploadType = import("
|
|
8
|
-
export type environmentType = import("
|
|
9
|
-
export type configPlSqlHandlerType = import("
|
|
10
|
-
export type BindParameterConfig = import("
|
|
6
|
+
export type argObjType = import("../../types.js").argObjType;
|
|
7
|
+
export type fileUploadType = import("../../types.js").fileUploadType;
|
|
8
|
+
export type environmentType = import("../../types.js").environmentType;
|
|
9
|
+
export type configPlSqlHandlerType = import("../../types.js").configPlSqlHandlerType;
|
|
10
|
+
export type BindParameterConfig = import("../../types.js").BindParameterConfig;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {import('
|
|
3
|
-
* @typedef {import('
|
|
2
|
+
* @typedef {import('../../types.js').environmentType} environmentType
|
|
3
|
+
* @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
|
|
4
4
|
*/
|
|
5
5
|
export class ProcedureError extends Error {
|
|
6
6
|
/**
|
|
@@ -19,5 +19,5 @@ export class ProcedureError extends Error {
|
|
|
19
19
|
/** @type {BindParameterConfig} */
|
|
20
20
|
bind: BindParameterConfig;
|
|
21
21
|
}
|
|
22
|
-
export type environmentType = import("
|
|
23
|
-
export type BindParameterConfig = import("
|
|
22
|
+
export type environmentType = import("../../types.js").environmentType;
|
|
23
|
+
export type BindParameterConfig = import("../../types.js").BindParameterConfig;
|
|
@@ -9,6 +9,6 @@ export type cacheEntryType = {
|
|
|
9
9
|
};
|
|
10
10
|
export type Connection = import("oracledb").Connection;
|
|
11
11
|
export type Result = import("oracledb").Result<unknown>;
|
|
12
|
-
export type configPlSqlHandlerType = import("
|
|
13
|
-
export type argObjType = import("
|
|
14
|
-
export type BindParameterConfig = import("
|
|
12
|
+
export type configPlSqlHandlerType = import("../../types.js").configPlSqlHandlerType;
|
|
13
|
+
export type argObjType = import("../../types.js").argObjType;
|
|
14
|
+
export type BindParameterConfig = import("../../types.js").BindParameterConfig;
|
|
@@ -3,11 +3,11 @@ export type Request = import("express").Request;
|
|
|
3
3
|
export type Response = import("express").Response;
|
|
4
4
|
export type Connection = import("oracledb").Connection;
|
|
5
5
|
export type Result = import("oracledb").Result<unknown>;
|
|
6
|
-
export type argObjType = import("
|
|
7
|
-
export type fileUploadType = import("
|
|
8
|
-
export type environmentType = import("
|
|
9
|
-
export type configPlSqlHandlerType = import("
|
|
10
|
-
export type BindParameterConfig = import("
|
|
6
|
+
export type argObjType = import("../../types.js").argObjType;
|
|
7
|
+
export type fileUploadType = import("../../types.js").fileUploadType;
|
|
8
|
+
export type environmentType = import("../../types.js").environmentType;
|
|
9
|
+
export type configPlSqlHandlerType = import("../../types.js").configPlSqlHandlerType;
|
|
10
|
+
export type BindParameterConfig = import("../../types.js").BindParameterConfig;
|
|
11
11
|
export type cacheEntryType = {
|
|
12
12
|
hitCount: number;
|
|
13
13
|
valid: boolean;
|
|
@@ -4,6 +4,6 @@ export function getProcedureVariable(procName: string, argObj: argObjType, datab
|
|
|
4
4
|
}>;
|
|
5
5
|
export type Connection = import("oracledb").Connection;
|
|
6
6
|
export type Result = import("oracledb").Result<unknown>;
|
|
7
|
-
export type configPlSqlHandlerType = import("
|
|
8
|
-
export type argObjType = import("
|
|
9
|
-
export type BindParameterConfig = import("
|
|
7
|
+
export type configPlSqlHandlerType = import("../../types.js").configPlSqlHandlerType;
|
|
8
|
+
export type argObjType = import("../../types.js").argObjType;
|
|
9
|
+
export type BindParameterConfig = import("../../types.js").BindParameterConfig;
|
|
@@ -3,5 +3,5 @@ export type Request = import("express").Request;
|
|
|
3
3
|
export type Response = import("express").Response;
|
|
4
4
|
export type Pool = import("oracledb").Pool;
|
|
5
5
|
export type Connection = import("oracledb").Connection;
|
|
6
|
-
export type argObjType = import("
|
|
7
|
-
export type configPlSqlHandlerType = import("
|
|
6
|
+
export type argObjType = import("../../types.js").argObjType;
|
|
7
|
+
export type configPlSqlHandlerType = import("../../types.js").configPlSqlHandlerType;
|