web_plsql 1.0.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +108 -13
  2. package/dist/chunk-DQk6qfdC.mjs +18 -0
  3. package/dist/frontend/assets/main-0oxRTIkL.js +147 -0
  4. package/dist/frontend/assets/main-0oxRTIkL.js.br +0 -0
  5. package/dist/frontend/assets/main-0oxRTIkL.js.gz +0 -0
  6. package/dist/frontend/assets/main-TYgLak6O.css +1 -0
  7. package/dist/frontend/assets/main-TYgLak6O.css.br +0 -0
  8. package/dist/frontend/assets/main-TYgLak6O.css.gz +0 -0
  9. package/dist/frontend/index.html +516 -0
  10. package/dist/frontend/index.html.br +0 -0
  11. package/dist/frontend/index.html.gz +0 -0
  12. package/dist/index.d.mts +646 -0
  13. package/dist/index.mjs +3548 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/dist/oracledb-mock-Dn8aHtd7.mjs +68 -0
  16. package/dist/oracledb-mock-Dn8aHtd7.mjs.map +1 -0
  17. package/examples/config-apex.js +1 -1
  18. package/examples/config-docker.js +1 -2
  19. package/package.json +45 -32
  20. package/examples/config-native.js +0 -68
  21. package/src/admin/client/charts.ts +0 -299
  22. package/src/admin/client/main.js +0 -3
  23. package/src/admin/client/tailwind.css +0 -41
  24. package/src/admin/index.html +0 -315
  25. package/src/admin/js/api.ts +0 -95
  26. package/src/admin/js/app.ts +0 -306
  27. package/src/admin/js/eslint.config.js +0 -74
  28. package/src/admin/js/schemas.ts +0 -153
  29. package/src/admin/js/templates/config.ts +0 -146
  30. package/src/admin/js/templates/errorRow.ts +0 -18
  31. package/src/admin/js/templates/index.ts +0 -3
  32. package/src/admin/js/templates/poolCard.ts +0 -61
  33. package/src/admin/js/tsconfig.json +0 -24
  34. package/src/admin/js/types.ts +0 -223
  35. package/src/admin/js/ui/theme.ts +0 -93
  36. package/src/admin/js/ui/views.ts +0 -164
  37. package/src/admin/js/util/format.ts +0 -27
  38. package/src/admin/lib/assets/main-zpdhQ1gD.css +0 -1
  39. package/src/admin/lib/chart.bundle.js +0 -139
  40. package/src/admin/style.css +0 -1321
  41. package/src/bin/load-test.js +0 -202
  42. package/src/handler/handlerAdmin.js +0 -198
  43. package/src/handler/handlerLogger.js +0 -21
  44. package/src/handler/handlerMetrics.js +0 -68
  45. package/src/handler/handlerUpload.js +0 -26
  46. package/src/handler/plsql/cgi.js +0 -131
  47. package/src/handler/plsql/errorPage.js +0 -117
  48. package/src/handler/plsql/handlerPlSql.js +0 -90
  49. package/src/handler/plsql/parsePage.js +0 -213
  50. package/src/handler/plsql/procedure.js +0 -356
  51. package/src/handler/plsql/procedureError.js +0 -40
  52. package/src/handler/plsql/procedureNamed.js +0 -268
  53. package/src/handler/plsql/procedureSanitize.js +0 -262
  54. package/src/handler/plsql/procedureVariable.js +0 -54
  55. package/src/handler/plsql/request.js +0 -124
  56. package/src/handler/plsql/requestError.js +0 -23
  57. package/src/handler/plsql/sendResponse.js +0 -136
  58. package/src/handler/plsql/stream.js +0 -28
  59. package/src/handler/plsql/upload.js +0 -109
  60. package/src/index.js +0 -20
  61. package/src/server/config.js +0 -57
  62. package/src/server/connections.js +0 -40
  63. package/src/server/server.js +0 -289
  64. package/src/types.js +0 -150
  65. package/src/util/cache.js +0 -123
  66. package/src/util/errorToString.js +0 -24
  67. package/src/util/file.js +0 -91
  68. package/src/util/html.js +0 -53
  69. package/src/util/jsonLogger.js +0 -47
  70. package/src/util/oracle.js +0 -80
  71. package/src/util/shutdown.js +0 -44
  72. package/src/util/trace.js +0 -325
  73. package/src/util/type.js +0 -6
  74. package/src/util/util.js +0 -66
  75. package/src/version.js +0 -5
  76. package/types/handler/handlerAdmin.d.ts +0 -9
  77. package/types/handler/handlerLogger.d.ts +0 -2
  78. package/types/handler/handlerMetrics.d.ts +0 -25
  79. package/types/handler/handlerUpload.d.ts +0 -7
  80. package/types/handler/plsql/cgi.d.ts +0 -4
  81. package/types/handler/plsql/errorPage.d.ts +0 -11
  82. package/types/handler/plsql/handlerPlSql.d.ts +0 -13
  83. package/types/handler/plsql/parsePage.d.ts +0 -3
  84. package/types/handler/plsql/procedure.d.ts +0 -12
  85. package/types/handler/plsql/procedureError.d.ts +0 -23
  86. package/types/handler/plsql/procedureNamed.d.ts +0 -14
  87. package/types/handler/plsql/procedureSanitize.d.ts +0 -11
  88. package/types/handler/plsql/procedureVariable.d.ts +0 -10
  89. package/types/handler/plsql/request.d.ts +0 -9
  90. package/types/handler/plsql/requestError.d.ts +0 -8
  91. package/types/handler/plsql/sendResponse.d.ts +0 -6
  92. package/types/handler/plsql/upload.d.ts +0 -5
  93. package/types/index.d.ts +0 -11
  94. package/types/server/config.d.ts +0 -2
  95. package/types/server/server.d.ts +0 -74
  96. package/types/types.d.ts +0 -328
  97. package/types/util/cache.d.ts +0 -69
  98. package/types/util/errorToString.d.ts +0 -1
  99. package/types/util/file.d.ts +0 -6
  100. package/types/util/html.d.ts +0 -3
  101. package/types/util/jsonLogger.d.ts +0 -45
  102. package/types/util/oracle.d.ts +0 -5
  103. package/types/util/shutdown.d.ts +0 -2
  104. package/types/util/trace.d.ts +0 -22
  105. package/types/util/type.d.ts +0 -1
  106. package/types/util/util.d.ts +0 -3
  107. package/types/version.d.ts +0 -1
  108. /package/{src/admin/favicon.svg → dist/frontend/assets/favicon-mQAM4tVu.svg} +0 -0
@@ -1,202 +0,0 @@
1
- /**
2
- * @file Load testing CLI tool for web_plsql.
3
- * This tool simulates parallel traffic to the middleware and provides real-time statistics.
4
- */
5
-
6
- import {performance} from 'node:perf_hooks';
7
-
8
- /**
9
- * @typedef {object} Metrics
10
- * @property {number} total Total requests made.
11
- * @property {number} success Number of successful requests (2xx).
12
- * @property {number} error Number of failed requests.
13
- * @property {number} minLatency Minimum latency in milliseconds.
14
- * @property {number} maxLatency Maximum latency in milliseconds.
15
- * @property {number} sumLatency Sum of all latencies for average calculation.
16
- * @property {Map<string|number, number>} statusCodes Frequency of status codes.
17
- */
18
-
19
- /** @type {Metrics} */
20
- const metrics = {
21
- total: 0,
22
- success: 0,
23
- error: 0,
24
- minLatency: Number.MAX_SAFE_INTEGER,
25
- maxLatency: 0,
26
- sumLatency: 0,
27
- statusCodes: new Map(),
28
- };
29
-
30
- let stopped = false;
31
-
32
- /**
33
- * Parse CLI arguments.
34
- * @returns {{ url: string, concurrency: number, duration: number }} Options object.
35
- */
36
- function parseArgs() {
37
- const args = process.argv.slice(2);
38
- const options = {
39
- url: '',
40
- concurrency: 10,
41
- duration: 30,
42
- };
43
-
44
- for (let i = 0; i < args.length; i++) {
45
- const arg = args[i];
46
- const nextArg = args[i + 1] ?? '';
47
-
48
- if (arg === '--url' || arg === '-u') {
49
- options.url = nextArg;
50
- i++;
51
- } else if (arg === '--concurrency' || arg === '-c') {
52
- options.concurrency = parseInt(nextArg, 10);
53
- i++;
54
- } else if (arg === '--duration' || arg === '-d') {
55
- options.duration = parseInt(nextArg, 10);
56
- i++;
57
- }
58
- }
59
-
60
- if (!options.url) {
61
- console.error('Usage: node src/bin/load-test.js --url <url> [-c concurrency] [-d duration]');
62
- process.exit(1);
63
- }
64
-
65
- return options;
66
- }
67
-
68
- /**
69
- * Record a single request's result.
70
- * @param {boolean} ok Whether the request succeeded.
71
- * @param {number} latency Latency in milliseconds.
72
- * @param {number|string} status Status code or error string.
73
- */
74
- function recordMetrics(ok, latency, status) {
75
- metrics.total++;
76
- if (ok) {
77
- metrics.success++;
78
- } else {
79
- metrics.error++;
80
- }
81
-
82
- metrics.minLatency = Math.min(metrics.minLatency, latency);
83
- metrics.maxLatency = Math.max(metrics.maxLatency, latency);
84
- metrics.sumLatency += latency;
85
-
86
- const count = metrics.statusCodes.get(status) ?? 0;
87
- metrics.statusCodes.set(status, count + 1);
88
- }
89
-
90
- /**
91
- * Clear the console and move cursor to the top.
92
- */
93
- function clearConsole() {
94
- process.stdout.write('\x1b[2J\x1b[0;0H');
95
- }
96
-
97
- /**
98
- * Render the dashboard.
99
- * @param {number} elapsed Elapsed time in seconds.
100
- * @param {number} duration Total duration in seconds.
101
- * @param {string} url Target URL.
102
- * @param {number} concurrency Concurrency level.
103
- */
104
- function renderDashboard(elapsed, duration, url, concurrency) {
105
- clearConsole();
106
- const rps = elapsed > 0 ? (metrics.total / elapsed).toFixed(1) : '0.0';
107
- const avgLatency = metrics.total > 0 ? (metrics.sumLatency / metrics.total).toFixed(1) : '0.0';
108
- const progress = Math.min(100, (elapsed / duration) * 100).toFixed(1);
109
- const barWidth = 30;
110
- const filledWidth = Math.floor((barWidth * parseFloat(progress)) / 100);
111
- const bar = '='.repeat(filledWidth) + '>'.padEnd(barWidth - filledWidth, ' ');
112
-
113
- console.log('\x1b[1m\x1b[36mWeb PL/SQL Load Test\x1b[0m');
114
- console.log('='.repeat(40));
115
- console.log(`\x1b[33mURL:\x1b[0m ${url}`);
116
- console.log(`\x1b[33mConcurrency:\x1b[0m ${concurrency}`);
117
- console.log(`\x1b[33mDuration:\x1b[0m ${duration}s`);
118
- console.log('='.repeat(40));
119
- console.log(`\x1b[32mProgress:\x1b[0m [${bar}] ${progress}% (${elapsed.toFixed(1)}s)`);
120
- console.log(`\x1b[32mRPS:\x1b[0m ${rps}`);
121
- console.log(`\x1b[32mTotal:\x1b[0m ${metrics.total}`);
122
- console.log(`\x1b[32mSuccess:\x1b[0m ${metrics.success}`);
123
- console.log(`\x1b[31mErrors:\x1b[0m ${metrics.error}`);
124
- console.log('='.repeat(40));
125
- console.log('\x1b[1mLatency (ms)\x1b[0m');
126
- console.log(`\x1b[34mAvg:\x1b[0m ${avgLatency.padStart(8)}`);
127
- console.log(`\x1b[34mMin:\x1b[0m ${(metrics.minLatency === Number.MAX_SAFE_INTEGER ? 0 : metrics.minLatency).toFixed(1).padStart(8)}`);
128
- console.log(`\x1b[34mMax:\x1b[0m ${metrics.maxLatency.toFixed(1).padStart(8)}`);
129
- console.log('='.repeat(40));
130
-
131
- if (metrics.statusCodes.size > 0) {
132
- console.log('\x1b[1mStatus Codes\x1b[0m');
133
- for (const [code, count] of metrics.statusCodes.entries()) {
134
- const numericCode = typeof code === 'number' ? code : 0;
135
- const color = numericCode >= 200 && numericCode < 300 ? '\x1b[32m' : '\x1b[31m';
136
- console.log(`${color}${code}\x1b[0m: ${count}`);
137
- }
138
- }
139
- }
140
-
141
- /**
142
- * Worker function to maintain concurrency.
143
- * @param {string} url The target URL.
144
- * @param {number} endTime The end time in milliseconds.
145
- */
146
- async function runWorker(url, endTime) {
147
- while (performance.now() < endTime && !stopped) {
148
- const start = performance.now();
149
- try {
150
- const res = await fetch(url, {
151
- signal: AbortSignal.timeout(10000), // 10s timeout
152
- });
153
- const latency = performance.now() - start;
154
- recordMetrics(res.ok, latency, res.status);
155
- // Consume body to free up connection
156
- await res.arrayBuffer();
157
- } catch (err) {
158
- const latency = performance.now() - start;
159
- const errorName = err instanceof Error ? err.name : 'UnknownError';
160
- recordMetrics(false, latency, errorName === 'TimeoutError' ? 'Timeout' : 'NetworkErr');
161
- }
162
- }
163
- }
164
-
165
- /**
166
- * Main function.
167
- */
168
- async function main() {
169
- const options = parseArgs();
170
- const startTime = performance.now();
171
- const endTime = startTime + options.duration * 1000;
172
-
173
- console.log(`Starting load test on ${options.url}...`);
174
-
175
- // Start workers
176
- const workers = Array.from({length: options.concurrency}, () => runWorker(options.url, endTime));
177
-
178
- // Dashboard refresh interval
179
- const uiInterval = setInterval(() => {
180
- const elapsed = (performance.now() - startTime) / 1000;
181
- renderDashboard(elapsed, options.duration, options.url, options.concurrency);
182
- }, 200);
183
-
184
- // Handle Ctrl+C
185
- process.on('SIGINT', () => {
186
- stopped = true;
187
- console.log('\nStopping...');
188
- });
189
-
190
- await Promise.all(workers);
191
- clearInterval(uiInterval);
192
-
193
- // Final render
194
- const finalElapsed = (performance.now() - startTime) / 1000;
195
- renderDashboard(finalElapsed, options.duration, options.url, options.concurrency);
196
- console.log('\n\x1b[1m\x1b[32mTest Complete!\x1b[0m\n');
197
- }
198
-
199
- main().catch((/** @type {unknown} */ err) => {
200
- console.error('Fatal error:', err);
201
- process.exit(1);
202
- });
@@ -1,198 +0,0 @@
1
- import express from 'express';
2
- import fs from 'node:fs';
3
- import readline from 'node:readline';
4
- import {AdminContext} from '../server/server.js';
5
- import {getVersion} from '../version.js';
6
-
7
- const version = getVersion();
8
- import {forceShutdown} from '../util/shutdown.js';
9
-
10
- /**
11
- * @typedef {import('express').Request} Request
12
- * @typedef {import('express').Response} Response
13
- * @typedef {import('express').NextFunction} NextFunction
14
- */
15
-
16
- export const handlerAdmin = express.Router();
17
-
18
- /**
19
- * Helper to read last N lines of a file
20
- * @param {string} filePath - Path to file
21
- * @param {number} n - Number of lines
22
- * @returns {Promise<string[]>} - The lines
23
- */
24
- const readLastLines = async (filePath, n = 100) => {
25
- if (!fs.existsSync(filePath)) {
26
- return [];
27
- }
28
-
29
- const fileStream = fs.createReadStream(filePath);
30
- const rl = readline.createInterface({
31
- input: fileStream,
32
- crlfDelay: Infinity,
33
- });
34
-
35
- /** @type {string[]} */
36
- const lines = [];
37
- for await (const line of rl) {
38
- lines.push(line);
39
- if (lines.length > n) {
40
- lines.shift();
41
- }
42
- }
43
- return lines;
44
- };
45
-
46
- // GET /api/status
47
- handlerAdmin.get('/api/status', (_req, res) => {
48
- const uptime = (new Date().getTime() - AdminContext.startTime.getTime()) / 1000;
49
-
50
- const poolStats = AdminContext.pools.map((pool, index) => {
51
- const name = AdminContext.caches[index]?.poolName ?? `pool-${index}`;
52
- const p = /** @type {import('oracledb').Pool & {getStatistics?: () => Record<string, unknown>}} */ (pool);
53
- return {
54
- name,
55
- stats: typeof p.getStatistics === 'function' ? p.getStatistics() : null,
56
- connectionsOpen: pool.connectionsOpen,
57
- connectionsInUse: pool.connectionsInUse,
58
- };
59
- });
60
-
61
- const memUsage = process.memoryUsage();
62
- const cpuUsage = process.cpuUsage();
63
-
64
- res.json({
65
- version,
66
- status: AdminContext.paused ? 'paused' : 'running',
67
- uptime,
68
- startTime: AdminContext.startTime,
69
- metrics: {
70
- ...AdminContext.metrics,
71
- avgResponseTime: AdminContext.metrics.requestCount > 0 ? AdminContext.metrics.totalDuration / AdminContext.metrics.requestCount : 0,
72
- },
73
- pools: poolStats,
74
- system: {
75
- nodeVersion: process.version,
76
- platform: process.platform,
77
- arch: process.arch,
78
- memory: {
79
- rss: memUsage.rss,
80
- heapTotal: memUsage.heapTotal,
81
- heapUsed: memUsage.heapUsed,
82
- external: memUsage.external,
83
- },
84
- cpu: {
85
- user: cpuUsage.user,
86
- system: cpuUsage.system,
87
- },
88
- },
89
- config: AdminContext.config
90
- ? {
91
- ...AdminContext.config,
92
- adminPassword: AdminContext.config.adminPassword ? '********' : undefined,
93
- routePlSql: AdminContext.config.routePlSql.map((p) => ({
94
- ...p,
95
- password: '********',
96
- })),
97
- }
98
- : null,
99
- });
100
- });
101
-
102
- // GET /api/logs/error
103
- handlerAdmin.get('/api/logs/error', async (req, res) => {
104
- try {
105
- const limit = Number(req.query.limit) || 100;
106
- const logFile = 'error.json.log';
107
- const lines = await readLastLines(logFile, limit);
108
-
109
- /** @type {Record<string, unknown>[]} */
110
- const logs = [];
111
- for (const line of lines) {
112
- try {
113
- const parsed = /** @type {unknown} */ (JSON.parse(line));
114
- if (parsed && typeof parsed === 'object') {
115
- logs.push(/** @type {Record<string, unknown>} */ (parsed));
116
- }
117
- } catch (e) {
118
- // ignore
119
- }
120
- }
121
-
122
- res.json(logs.reverse());
123
- } catch (err) {
124
- res.status(500).json({error: String(err)});
125
- }
126
- });
127
-
128
- // GET /api/logs/access
129
- handlerAdmin.get('/api/logs/access', async (req, res) => {
130
- try {
131
- const limit = Number(req.query.limit) || 100;
132
- const logFile = AdminContext.config?.loggerFilename ?? 'access.log';
133
-
134
- if (!AdminContext.config?.loggerFilename) {
135
- res.json({message: 'Access logging not enabled'});
136
- return;
137
- }
138
-
139
- const lines = await readLastLines(logFile, limit);
140
- res.json(lines.reverse());
141
- } catch (err) {
142
- res.status(500).json({error: String(err)});
143
- }
144
- });
145
-
146
- // GET /api/cache
147
- handlerAdmin.get('/api/cache', (_req, res) => {
148
- const caches = AdminContext.caches.map((c) => ({
149
- poolName: c.poolName,
150
- procedureNameCache: {
151
- size: c.procedureNameCache.keys().length,
152
- stats: c.procedureNameCache.getStats(),
153
- },
154
- argumentCache: {
155
- size: c.argumentCache.keys().length,
156
- stats: c.argumentCache.getStats(),
157
- },
158
- }));
159
- res.json(caches);
160
- });
161
-
162
- // POST /api/cache/clear
163
- handlerAdmin.post('/api/cache/clear', (req, res) => {
164
- const body = /** @type {unknown} */ (req.body);
165
- const poolName = body && typeof body === 'object' && 'poolName' in body && typeof body.poolName === 'string' ? body.poolName : undefined;
166
-
167
- let cleared = 0;
168
- AdminContext.caches.forEach((c) => {
169
- if (!poolName || c.poolName === poolName) {
170
- c.procedureNameCache.clear();
171
- cleared++;
172
- c.argumentCache.clear();
173
- cleared++;
174
- }
175
- });
176
-
177
- res.json({message: `Cleared ${cleared} caches`});
178
- });
179
-
180
- // POST /api/server/:action
181
- handlerAdmin.post('/api/server/:action', (req, res) => {
182
- const action = req.params.action;
183
-
184
- if (action === 'stop') {
185
- res.json({message: 'Server shutting down...'});
186
- setTimeout(() => {
187
- forceShutdown();
188
- }, 100);
189
- } else if (action === 'pause') {
190
- AdminContext.paused = true;
191
- res.json({message: 'Server paused', status: 'paused'});
192
- } else if (action === 'resume') {
193
- AdminContext.paused = false;
194
- res.json({message: 'Server resumed', status: 'running'});
195
- } else {
196
- res.status(400).json({error: 'Invalid action'});
197
- }
198
- });
@@ -1,21 +0,0 @@
1
- import debugModule from 'debug';
2
- const debug = debugModule('webplsql:handlerLogger');
3
-
4
- import fs from 'node:fs';
5
- import path from 'node:path';
6
- import morgan from 'morgan';
7
-
8
- /**
9
- * @typedef {import('express').RequestHandler} RequestHandler
10
- */
11
-
12
- /**
13
- * Create the upload middleware.
14
- * @param {string} filename - Output filename.
15
- * @returns {RequestHandler} - Request handler.
16
- */
17
- export const handlerLogger = (filename) => {
18
- debug('register');
19
-
20
- return morgan('combined', {stream: fs.createWriteStream(path.join(process.cwd(), filename), {flags: 'a'})});
21
- };
@@ -1,68 +0,0 @@
1
- import debugModule from 'debug';
2
- const debug = debugModule('webplsql:handlerMetrics');
3
-
4
- /**
5
- * @typedef {import('express').RequestHandler} RequestHandler
6
- */
7
-
8
- /**
9
- * @typedef {object} metricsType
10
- * @property {Date} started - When was the server started.
11
- * @property {number} totalRequests - Total number of requests.
12
- * @property {number} totalRequestDuration - Total amount of time in ms in request.
13
- * @property {number} minRequestDuration - Min amount of time in ms in request.
14
- * @property {number} maxRequestDuration - Max amount of time in ms in request.
15
- */
16
-
17
- /**
18
- * Convert hrtime to ms.
19
- * @param {[number, number]} hrtime - Time
20
- * @returns {number} Millisecoinds.
21
- */
22
- const hrtime2ms = (hrtime) => hrtime[0] * 1000 + hrtime[1] / 1_000_000;
23
-
24
- /**
25
- * metrics initializer.
26
- * @returns {metricsType} The metrics.
27
- */
28
- export const initMetrics = () => {
29
- return {
30
- started: new Date(),
31
- totalRequests: 0,
32
- totalRequestDuration: 0,
33
- minRequestDuration: -1,
34
- maxRequestDuration: -1,
35
- };
36
- };
37
-
38
- /**
39
- * The metrics handler.
40
- * @param {metricsType} metrics - the nmetrics.
41
- * @returns {RequestHandler} - Request handler.
42
- */
43
- export const handlerMetrics = (metrics) => {
44
- debug('register');
45
-
46
- return (req, res, next) => {
47
- metrics.totalRequests++;
48
-
49
- const start = hrtime2ms(process.hrtime());
50
- res.on('finish', () => {
51
- const duration = hrtime2ms(process.hrtime()) - start;
52
-
53
- metrics.totalRequestDuration += duration;
54
- if (metrics.minRequestDuration < 0 || duration < metrics.minRequestDuration) {
55
- metrics.minRequestDuration = duration;
56
- }
57
- if (metrics.maxRequestDuration < 0 || duration > metrics.maxRequestDuration) {
58
- metrics.maxRequestDuration = duration;
59
- }
60
-
61
- if (debug.enabled) {
62
- debug(`Request to ${req.params?.name} ${req.url} took ${duration.toFixed(3)}ms`);
63
- }
64
- });
65
-
66
- next();
67
- };
68
- };
@@ -1,26 +0,0 @@
1
- import multer from 'multer';
2
-
3
- /**
4
- * @typedef {import('express').RequestHandler} RequestHandler
5
- * @typedef {import('express').Response} Response
6
- * @typedef {import('express').NextFunction} NextFunction
7
- * @typedef {import('oracledb').Pool} Pool
8
- * @typedef {import('../types.js').environmentType} environmentType
9
- * @typedef {import('../types.js').configType} configType
10
- */
11
-
12
- /**
13
- * Create the upload middleware.
14
- * @param {number} [uploadFileSizeLimit] - Maximum size of each uploaded file in bytes or no limit if omitted.
15
- * @returns {RequestHandler} - Request handler.
16
- */
17
- export const handlerUpload = (uploadFileSizeLimit = Infinity) => {
18
- const upload = multer({
19
- storage: multer.diskStorage({}),
20
- limits: {
21
- fileSize: uploadFileSizeLimit,
22
- },
23
- });
24
-
25
- return upload.any();
26
- };
@@ -1,131 +0,0 @@
1
- /*
2
- * Prepare the CGI information
3
- */
4
-
5
- import os from 'node:os';
6
- import {URL} from 'node:url';
7
- import debugModule from 'debug';
8
- const debug = debugModule('webplsql:cgi');
9
-
10
- /**
11
- * @typedef {import('express').Request} Request
12
- * @typedef {import('../../types.js').environmentType} environmentType
13
- * @typedef {import('../../types.js').configPlSqlType} configPlSqlType
14
- */
15
-
16
- /** @type {environmentType} */
17
- const DEFAULT_CGI = {
18
- PLSQL_GATEWAY: 'WebDb',
19
- GATEWAY_IVERSION: '2',
20
- SERVER_SOFTWARE: 'web_plsql',
21
- GATEWAY_INTERFACE: 'CGI/1.1',
22
- SERVER_PORT: '',
23
- SERVER_NAME: os.hostname(),
24
- REQUEST_METHOD: '',
25
- PATH_INFO: '',
26
- SCRIPT_NAME: '',
27
- REMOTE_ADDR: '',
28
- SERVER_PROTOCOL: '',
29
- REQUEST_PROTOCOL: '',
30
- REMOTE_USER: '',
31
- HTTP_COOKIE: '',
32
- HTTP_USER_AGENT: '',
33
- HTTP_HOST: '',
34
- HTTP_ACCEPT: '',
35
- HTTP_ACCEPT_ENCODING: '',
36
- HTTP_ACCEPT_LANGUAGE: '',
37
- HTTP_REFERER: '',
38
- HTTP_X_FORWARDED_FOR: '',
39
- WEB_AUTHENT_PREFIX: '',
40
- DAD_NAME: '',
41
- DOC_ACCESS_PATH: 'doc',
42
- DOCUMENT_TABLE: '',
43
- PATH_ALIAS: '',
44
- REQUEST_CHARSET: 'UTF8',
45
- REQUEST_IANA_CHARSET: 'UTF-8',
46
- SCRIPT_PREFIX: '',
47
- };
48
-
49
- /**
50
- * Create the HTTP_COOKIE string
51
- *
52
- * @param {Request} req - The req object represents the HTTP request.
53
- * @returns {string} - The string representation of the cookies.
54
- */
55
- const getCookieString = (req) => {
56
- let cookieString = '';
57
-
58
- for (const propName in req.cookies) {
59
- cookieString += `${propName}=${req.cookies[propName]};`;
60
- }
61
-
62
- debug('getCookieString', req.cookies, cookieString);
63
-
64
- return cookieString;
65
- };
66
-
67
- /**
68
- * Get the script name and DAD name from a URL
69
- *
70
- * @param {Request} req - The req object represents the HTTP request.
71
- * @returns {{script: string; prefix: string; dad: string}} - The DAD structure.
72
- */
73
- const getPath = (req) => {
74
- // create a valid url
75
- const validUrl = `${req.protocol}://${os.hostname()}${req.originalUrl}`;
76
-
77
- // get the pathname from the url (new URL('https://example.org/abc/xyz?123').pathname => /abc/xyz)
78
- const pathname = new URL(validUrl).pathname;
79
-
80
- const tmp = trimPath(pathname.substring(0, pathname.lastIndexOf('/') + 1));
81
- const script = `/${tmp}`;
82
- const prefix = `/${tmp.substring(0, tmp.lastIndexOf('/'))}`;
83
- const dad = tmp.substring(tmp.indexOf('/') + 1);
84
-
85
- return {script, prefix, dad};
86
- };
87
-
88
- /**
89
- * Get a path that is not enclodes in slashes
90
- *
91
- * @param {string} value - The value to trim.
92
- * @returns {string} - The trimmed value.
93
- */
94
- const trimPath = (value) => value.replace(/^\/+|\/+$/g, '');
95
-
96
- /**
97
- * Create a CGI object
98
- *
99
- * @param {Request} req - The req object represents the HTTP request.
100
- * @param {string} doctable - The document table.
101
- * @param {environmentType} cgi - The additional cgi.
102
- * @returns {environmentType} CGI object
103
- */
104
- export const getCGI = (req, doctable, cgi) => {
105
- const PROTOCOL = req.protocol ? req.protocol.toUpperCase() : '';
106
- const PATH = getPath(req);
107
-
108
- /** @type {environmentType} */
109
- const CGI = {
110
- SERVER_PORT: typeof req.socket.localPort === 'number' ? req.socket.localPort.toString() : '',
111
- REQUEST_METHOD: req.method,
112
- PATH_INFO: Array.isArray(req.params.name) ? (req.params.name[0] ?? '') : (req.params.name ?? ''),
113
- SCRIPT_NAME: PATH.script,
114
- REMOTE_ADDR: (req.ip ?? '').replace('::ffff:', ''),
115
- SERVER_PROTOCOL: `${PROTOCOL}/${req.httpVersion}`,
116
- REQUEST_PROTOCOL: PROTOCOL,
117
- HTTP_COOKIE: getCookieString(req),
118
- HTTP_USER_AGENT: req.get('user-agent') ?? '',
119
- HTTP_HOST: req.get('host') ?? '',
120
- HTTP_ACCEPT: req.get('accept') ?? '',
121
- HTTP_ACCEPT_ENCODING: req.get('accept-encoding') ?? '',
122
- HTTP_ACCEPT_LANGUAGE: req.get('accept-language') ?? '',
123
- HTTP_REFERER: req.get('referer') ?? '',
124
- HTTP_X_FORWARDED_FOR: req.get('x-forwarded-for') ?? '',
125
- DAD_NAME: PATH.dad,
126
- DOCUMENT_TABLE: doctable,
127
- SCRIPT_PREFIX: PATH.prefix,
128
- };
129
-
130
- return Object.assign({}, DEFAULT_CGI, CGI, cgi);
131
- };