web_plsql 0.12.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +3 -5
  2. package/examples/config-apex.js +2 -3
  3. package/examples/config-docker.js +0 -1
  4. package/examples/config-docker.json +1 -2
  5. package/examples/config-native.js +2 -3
  6. package/examples/sql/install.sql +2 -0
  7. package/examples/sql/sample_package.sql +2 -1
  8. package/examples/sql/sample_package_body.sql +71 -16
  9. package/examples/sql/uninstall.sql +2 -0
  10. package/package.json +5 -5
  11. package/src/handler/handlerMetrics.js +68 -0
  12. package/src/{handlerUpload.js → handler/handlerUpload.js} +2 -2
  13. package/src/{cgi.js → handler/plsql/cgi.js} +6 -2
  14. package/src/{errorPage.js → handler/plsql/errorPage.js} +5 -5
  15. package/src/{handlerPlSql.js → handler/plsql/handlerPlSql.js} +2 -2
  16. package/src/{parsePage.js → handler/plsql/parsePage.js} +24 -8
  17. package/src/{procedure.js → handler/plsql/procedure.js} +7 -10
  18. package/src/{procedureError.js → handler/plsql/procedureError.js} +2 -2
  19. package/src/{procedureNamed.js → handler/plsql/procedureNamed.js} +4 -4
  20. package/src/{procedureSanitize.js → handler/plsql/procedureSanitize.js} +6 -6
  21. package/src/{procedureVariable.js → handler/plsql/procedureVariable.js} +3 -3
  22. package/src/{request.js → handler/plsql/request.js} +3 -9
  23. package/src/{sendResponse.js → handler/plsql/sendResponse.js} +6 -6
  24. package/src/{upload.js → handler/plsql/upload.js} +2 -2
  25. package/src/index.js +8 -10
  26. package/src/server/config.js +45 -0
  27. package/src/server/connections.js +40 -0
  28. package/src/server/server.js +185 -0
  29. package/src/types.js +2 -13
  30. package/src/util/date.js +23 -0
  31. package/src/{shutdown.js → util/shutdown.js} +3 -16
  32. package/src/util/type.js +6 -0
  33. package/types/handler/handlerMetrics.d.ts +25 -0
  34. package/types/{handlerUpload.d.ts → handler/handlerUpload.d.ts} +2 -2
  35. package/types/{cgi.d.ts → handler/plsql/cgi.d.ts} +2 -2
  36. package/types/{errorPage.d.ts → handler/plsql/errorPage.d.ts} +3 -3
  37. package/types/{handlerPlSql.d.ts → handler/plsql/handlerPlSql.d.ts} +2 -2
  38. package/types/handler/plsql/parsePage.d.ts +3 -0
  39. package/types/{procedure.d.ts → handler/plsql/procedure.d.ts} +5 -5
  40. package/types/{procedureError.d.ts → handler/plsql/procedureError.d.ts} +4 -4
  41. package/types/{procedureNamed.d.ts → handler/plsql/procedureNamed.d.ts} +3 -3
  42. package/types/{procedureSanitize.d.ts → handler/plsql/procedureSanitize.d.ts} +5 -5
  43. package/types/{procedureVariable.d.ts → handler/plsql/procedureVariable.d.ts} +3 -3
  44. package/types/{request.d.ts → handler/plsql/request.d.ts} +2 -2
  45. package/types/{sendResponse.d.ts → handler/plsql/sendResponse.d.ts} +3 -1
  46. package/types/{upload.d.ts → handler/plsql/upload.d.ts} +1 -1
  47. package/types/index.d.ts +8 -10
  48. package/types/server/config.d.ts +2 -0
  49. package/types/server/server.d.ts +52 -0
  50. package/types/types.d.ts +4 -37
  51. package/types/util/type.d.ts +1 -0
  52. package/src/handlerMetrics.js +0 -46
  53. package/src/server.js +0 -223
  54. package/src/tty.js +0 -48
  55. package/types/handlerMetrics.d.ts +0 -4
  56. package/types/parsePage.d.ts +0 -3
  57. package/types/server.d.ts +0 -14
  58. package/types/tty.d.ts +0 -4
  59. package/types/version.d.ts +0 -8
  60. /package/src/{handlerLogger.js → handler/handlerLogger.js} +0 -0
  61. /package/src/{requestError.js → handler/plsql/requestError.js} +0 -0
  62. /package/src/{stream.js → handler/plsql/stream.js} +0 -0
  63. /package/src/{error.js → util/errorToString.js} +0 -0
  64. /package/src/{file.js → util/file.js} +0 -0
  65. /package/src/{oracle.js → util/oracle.js} +0 -0
  66. /package/src/{trace.js → util/trace.js} +0 -0
  67. /package/types/{handlerLogger.d.ts → handler/handlerLogger.d.ts} +0 -0
  68. /package/types/{requestError.d.ts → handler/plsql/requestError.d.ts} +0 -0
  69. /package/types/{stream.d.ts → handler/plsql/stream.d.ts} +0 -0
  70. /package/types/{error.d.ts → util/errorToString.d.ts} +0 -0
  71. /package/types/{file.d.ts → util/file.d.ts} +0 -0
  72. /package/types/{oracle.d.ts → util/oracle.d.ts} +0 -0
  73. /package/types/{shutdown.d.ts → util/shutdown.d.ts} +0 -0
  74. /package/types/{trace.d.ts → util/trace.d.ts} +0 -0
package/README.md CHANGED
@@ -39,12 +39,12 @@ Please visit the [node-oracledb](https://node-oracledb.readthedocs.io/en/latest/
39
39
  # Configuration
40
40
 
41
41
  There are 2 options on how to use the web_plsql express middleware:
42
- - Use the predefined `startHttpServer` api in `src/server.js` like in the `examples/config-native.js` example
42
+ - Use the predefined `startServer` api in `src/server.js` like in the `examples/config-native.js` example
43
43
  - Hand craft a new Express server using the `handlerWebPlSql` middleware in `src/handlerPlSql.js`
44
44
 
45
- ## Use the predefined `startHttpServer`
45
+ ## Use the predefined `startServer`
46
46
 
47
- The `startHttpServer` api uses the following configuration object:
47
+ The `startServer` api uses the following configuration object:
48
48
 
49
49
  ```
50
50
  /**
@@ -80,7 +80,6 @@ export const z$errorStyleType = z.enum(['basic', 'debug']);
80
80
  * @property {configPlSqlType[]} routePlSql - The PL/SQL routes.
81
81
  * @property {errorStyleType} errorStyle - The error style.
82
82
  * @property {string} loggerFilename - name of the request logger filename or '' if not required.
83
- * @property {boolean} monitorConsole - Enable console status monitor.
84
83
  */
85
84
  ```
86
85
 
@@ -138,7 +137,6 @@ The following mod_plsql DAD configuration translates to the configuration option
138
137
  },
139
138
  ],
140
139
  loggerFilename: 'access.log', // PlsqlLogEnable and PlsqlLogDirectory
141
- monitorConsole: false,
142
140
  }
143
141
  ```
144
142
 
@@ -1,6 +1,6 @@
1
- import {startHttpServer} from '../src/index.js';
1
+ import {startServer} from '../src/index.js';
2
2
 
3
- void startHttpServer({
3
+ void startServer({
4
4
  port: 80,
5
5
  routeStatic: [
6
6
  {
@@ -22,5 +22,4 @@ void startHttpServer({
22
22
  },
23
23
  ],
24
24
  loggerFilename: 'access.log',
25
- monitorConsole: false,
26
25
  });
@@ -27,5 +27,4 @@ void startHttpServer({
27
27
  },
28
28
  ],
29
29
  loggerFilename: 'access.log', // PlsqlLogEnable and PlsqlLogDirectory
30
- monitorConsole: false,
31
30
  });
@@ -21,6 +21,5 @@
21
21
  "errorStyle": "debug"
22
22
  }
23
23
  ],
24
- "loggerFilename": "access.log",
25
- "monitorConsole": false
24
+ "loggerFilename": "access.log"
26
25
  }
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import {startHttpServer} from '../src/index.js';
3
+ import {startServer} from '../src/index.js';
4
4
 
5
- void startHttpServer({
5
+ void startServer({
6
6
  port: 8888,
7
7
  routeStatic: [
8
8
  {
@@ -26,5 +26,4 @@ void startHttpServer({
26
26
  },
27
27
  ],
28
28
  loggerFilename: 'access.log', // PlsqlLogEnable and PlsqlLogDirectory
29
- monitorConsole: false,
30
29
  });
@@ -26,3 +26,5 @@ ALTER SESSION SET CURRENT_SCHEMA=&&SAMPLE_USER;
26
26
  show errors
27
27
  @@sample_package_body.sql
28
28
  show errors
29
+
30
+ exit
@@ -9,8 +9,9 @@ PROCEDURE page_index(p IN VARCHAR2 DEFAULT NULL);
9
9
  PROCEDURE pag_simple(text IN VARCHAR2 DEFAULT NULL);
10
10
  PROCEDURE page_flexible(name_array IN owa.vc_arr, value_array IN owa.vc_arr);
11
11
  PROCEDURE page_array(text IN vc_arr);
12
+ PROCEDURE page_slow;
12
13
  PROCEDURE page_cgi;
13
- PROCEDURE page_cookie;
14
+ PROCEDURE page_cookie(p_action IN VARCHAR2 DEFAULT NULL);
14
15
  PROCEDURE page_form;
15
16
  PROCEDURE page_form_process(firstname IN VARCHAR2 DEFAULT NULL, lastname IN VARCHAR2 DEFAULT NULL, age IN VARCHAR2 DEFAULT NULL, sex IN VARCHAR2 DEFAULT NULL, vehicle IN vc_arr DEFAULT emptyArray);
16
17
  PROCEDURE page_file_upload;
@@ -1,6 +1,12 @@
1
1
  CREATE OR REPLACE
2
2
  PACKAGE BODY sample_pkg IS
3
3
 
4
+ COOKIE_ACTION_REMOVE CONSTANT VARCHAR2(30) := 'REMOVE';
5
+ COOKIE_ACTION_SEND CONSTANT VARCHAR2(30) := 'SEND';
6
+
7
+ COOKIE_NAME_NO_EXPIRES CONSTANT VARCHAR2(30) := 'COOKIE_NO_EXPIRES';
8
+ COOKIE_NAME_ONE_DAY CONSTANT VARCHAR2(30) := 'COOKIE_ONE_DAY';
9
+
4
10
  PROCEDURE open_page(title IN VARCHAR2);
5
11
  PROCEDURE close_page;
6
12
 
@@ -19,6 +25,7 @@ BEGIN
19
25
  htp.p('<li><a href="sample_pkg.pag_simple?text=some-text">Simple page</a></li>');
20
26
  htp.p('<li><a href="sample_pkg.page_array?text=some-text'||CHR(38)||'text=more-text'||CHR(38)||'text=last-text">Array passing</a></li>');
21
27
  htp.p('<li><a href="!sample_pkg.page_flexible?p1=v1'||CHR(38)||'p2=v2'||CHR(38)||'p3=v3.1'||CHR(38)||'p3=v3.2"">Flexible parameter passing</a></li>');
28
+ htp.p('<li><a href="sample_pkg.page_slow">Slow page (5 seconds)</a></li>');
22
29
  htp.p('<li><a href="sample_pkg.page_cgi">CGI</a></li>');
23
30
  htp.p('<li><a href="sample_pkg.page_cookie">Cookies</a></li>');
24
31
  htp.p('<li><a href="sample_pkg.page_form">Form</a></li>');
@@ -40,6 +47,21 @@ BEGIN
40
47
  close_page();
41
48
  END pag_simple;
42
49
 
50
+ PROCEDURE page_slow
51
+ IS
52
+ l_start TIMESTAMP := SYSTIMESTAMP;
53
+ l_now TIMESTAMP;
54
+ BEGIN
55
+ LOOP
56
+ l_now := SYSTIMESTAMP;
57
+ EXIT WHEN l_now >= l_start + INTERVAL '5' SECOND;
58
+ END LOOP;
59
+
60
+ open_page('web_plsql - Slow page');
61
+ htp.p('<p>I am slow</p>');
62
+ close_page();
63
+ END page_slow;
64
+
43
65
  PROCEDURE page_array(text IN vc_arr)
44
66
  IS
45
67
  BEGIN
@@ -79,26 +101,56 @@ BEGIN
79
101
  close_page();
80
102
  END page_cgi;
81
103
 
82
- PROCEDURE page_cookie
104
+ PROCEDURE page_cookie(p_action IN VARCHAR2 DEFAULT NULL)
83
105
  IS
84
- names owa_cookie.vc_arr;
85
- vals owa_cookie.vc_arr;
86
- num_vals INTEGER;
106
+ l_names owa_cookie.vc_arr;
107
+ l_vals owa_cookie.vc_arr;
108
+ l_num_vals INTEGER;
87
109
  BEGIN
88
- owa_cookie.get_all(names=>names, vals=>vals, num_vals=>num_vals);
110
+ CASE UPPER(p_action)
89
111
 
90
- owa_util.mime_header('text/html', FALSE);
91
- owa_cookie.send('demoCookie', TO_CHAR(SYSDATE, 'YYYY.MM.DD HH24:MI:SS'));
92
- owa_util.http_header_close;
112
+ WHEN COOKIE_ACTION_REMOVE THEN
113
+ owa_util.mime_header('text/html', FALSE);
93
114
 
94
- open_page('web_plsql - Cookies');
95
- htp.p('<table>');
96
- htp.p('<tr><th>name</th><th>value</th></tr>');
97
- FOR i IN 1 .. num_vals LOOP
98
- htp.p('<tr><td>'||names(i)||'</td><td>'||vals(i)||'</td></tr>');
99
- END LOOP;
100
- htp.p('</table>');
101
- close_page();
115
+ owa_cookie.remove(name=>COOKIE_NAME_NO_EXPIRES, val=>'');
116
+ owa_cookie.remove(name=>COOKIE_NAME_ONE_DAY, val=>'');
117
+
118
+ owa_util.redirect_url('sample_pkg.page_cookie');
119
+ owa_util.http_header_close;
120
+
121
+ WHEN COOKIE_ACTION_SEND THEN
122
+ owa_util.mime_header('text/html', FALSE);
123
+
124
+ owa_cookie.send(name=>COOKIE_NAME_NO_EXPIRES, value=>'VALUE-' || TO_CHAR(TRUNC(dbms_random.value(1, 101))));
125
+ owa_cookie.send(name=>COOKIE_NAME_ONE_DAY, value=>'VALUE-' || TO_CHAR(TRUNC(dbms_random.value(1, 101))), expires=>SYSDATE + 1);
126
+
127
+ owa_util.redirect_url('sample_pkg.page_cookie');
128
+ owa_util.http_header_close;
129
+
130
+ ELSE
131
+ owa_cookie.get_all(names=>l_names, vals=>l_vals, num_vals=>l_num_vals);
132
+
133
+ open_page('web_plsql - Cookies');
134
+
135
+ -- actions
136
+ htp.p('<p>');
137
+ htp.p('<form method="POST" action="sample_pkg.page_cookie">');
138
+ htp.p('<input type="submit" name="p_action" value="' || COOKIE_ACTION_REMOVE || '">');
139
+ htp.p('<input type="submit" name="p_action" value="' || COOKIE_ACTION_SEND || '">');
140
+ htp.p('</form>');
141
+ htp.p('</p>');
142
+
143
+ -- show cookies
144
+ htp.p('<table>');
145
+ htp.p('<tr><th>name</th><th>value</th></tr>');
146
+ FOR i IN 1 .. l_num_vals LOOP
147
+ htp.p('<tr><td>'||l_names(i)||'</td><td>'||l_vals(i)||'</td></tr>');
148
+ END LOOP;
149
+ htp.p('</table>');
150
+
151
+ close_page();
152
+
153
+ END CASE;
102
154
  END page_cookie;
103
155
 
104
156
  PROCEDURE page_form
@@ -241,5 +293,8 @@ BEGIN
241
293
  htp.p('</html>');
242
294
  END close_page;
243
295
 
296
+ BEGIN
297
+ dbms_random.seed(TO_CHAR(SYSDATE,'MM-DD-YYYY HH24:MI:SS'));
298
+
244
299
  END sample_pkg;
245
300
  /
@@ -3,3 +3,5 @@ define SAMPLE_USER=sample
3
3
 
4
4
  -- drop user
5
5
  DROP USER &&SAMPLE_USER CASCADE;
6
+
7
+ exit
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web_plsql",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "author": "Dieter Oberkofler <dieter.oberkofler@gmail.com>",
5
5
  "license": "MIT",
6
6
  "description": "The Express Middleware for Oracle PL/SQL",
@@ -47,7 +47,7 @@
47
47
  "test": "node --test --test-concurrency=1 \"./tests/**/*.test.js\"",
48
48
  "types": "rm -rf types && tsc --noEmit false --declaration true --declarationDir types --emitDeclarationOnly true --allowJs true --target es2020 --module es2020 --moduleResolution node --allowSyntheticDefaultImports true src/*.js",
49
49
  "clean": "shx rm -f *.tgz && shx rm -f *.log",
50
- "ci": "npm run clean && npm run lint && npm run test",
50
+ "ci": "npm run clean && npm run lint && npm run test && npm run types",
51
51
  "create-package": "shx rm -f *.tgz && npm pack",
52
52
  "image-build": "docker build --no-cache --progress=plain --tag=web_plsql .",
53
53
  "image-save": "docker save web_plsql | gzip > web_plsql.tar.gz"
@@ -83,13 +83,13 @@
83
83
  "@types/node": "24.3.1",
84
84
  "@types/oracledb": "6.9.1",
85
85
  "@types/supertest": "6.0.3",
86
- "eslint": "9.34.0",
87
- "eslint-plugin-jsdoc": "54.3.1",
86
+ "eslint": "9.35.0",
87
+ "eslint-plugin-jsdoc": "55.1.2",
88
88
  "prettier": "3.6.2",
89
89
  "rimraf": "6.0.1",
90
90
  "shx": "0.4.0",
91
91
  "supertest": "7.1.4",
92
92
  "typescript": "5.9.2",
93
- "typescript-eslint": "8.42.0"
93
+ "typescript-eslint": "8.43.0"
94
94
  }
95
95
  }
@@ -0,0 +1,68 @@
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
+ };
@@ -6,8 +6,8 @@ import multer from 'multer';
6
6
  * @typedef {import('express').Response} Response
7
7
  * @typedef {import('express').NextFunction} NextFunction
8
8
  * @typedef {import('oracledb').Pool} Pool
9
- * @typedef {import('./types.js').environmentType} environmentType
10
- * @typedef {import('./types.js').configType} configType
9
+ * @typedef {import('../types.js').environmentType} environmentType
10
+ * @typedef {import('../types.js').configType} configType
11
11
  */
12
12
 
13
13
  /**
@@ -4,11 +4,13 @@
4
4
 
5
5
  import os from 'node:os';
6
6
  import {URL} from 'node:url';
7
+ import debugModule from 'debug';
8
+ const debug = debugModule('webplsql:cgi');
7
9
 
8
10
  /**
9
11
  * @typedef {import('express').Request} Request
10
- * @typedef {import('./types.js').environmentType} environmentType
11
- * @typedef {import('./types.js').configPlSqlType} configPlSqlType
12
+ * @typedef {import('../../types.js').environmentType} environmentType
13
+ * @typedef {import('../../types.js').configPlSqlType} configPlSqlType
12
14
  */
13
15
 
14
16
  /** @type {environmentType} */
@@ -57,6 +59,8 @@ const getCookieString = (req) => {
57
59
  cookieString += `${propName}=${req.cookies[propName]};`;
58
60
  }
59
61
 
62
+ debug('getCookieString', req.cookies, cookieString);
63
+
60
64
  return cookieString;
61
65
  };
62
66
 
@@ -6,15 +6,15 @@ import util from 'node:util';
6
6
  import escape from 'escape-html';
7
7
  import {ProcedureError} from './procedureError.js';
8
8
  import {RequestError} from './requestError.js';
9
- import {inspectRequest, logToFile} from './trace.js';
10
- import {errorToString} from './error.js';
9
+ import {inspectRequest, logToFile} from '../../util/trace.js';
10
+ import {errorToString} from '../../util/errorToString.js';
11
11
 
12
12
  /**
13
13
  * @typedef {import('express').Request} Request
14
14
  * @typedef {import('express').Response} Response
15
- * @typedef {import('./types.js').BindParameterConfig} BindParameterConfig
16
- * @typedef {import('./types.js').environmentType} environmentType
17
- * @typedef {import('./types.js').configPlSqlHandlerType} configPlSqlHandlerType
15
+ * @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
16
+ * @typedef {import('../../types.js').environmentType} environmentType
17
+ * @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
18
18
  * @typedef {{html: string; text: string}} outputType
19
19
  */
20
20
 
@@ -16,8 +16,8 @@ import {errorPage} from './errorPage.js';
16
16
  * @typedef {import('express').Response} Response
17
17
  * @typedef {import('express').NextFunction} NextFunction
18
18
  * @typedef {import('oracledb').Pool} Pool
19
- * @typedef {import('./types.js').environmentType} environmentType
20
- * @typedef {import('./types.js').configPlSqlHandlerType} configPlSqlHandlerType
19
+ * @typedef {import('../../types.js').environmentType} environmentType
20
+ * @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
21
21
  */
22
22
 
23
23
  /**
@@ -1,6 +1,9 @@
1
+ import debugModule from 'debug';
2
+ const debug = debugModule('webplsql:parsePage');
3
+
1
4
  /**
2
- * @typedef {import('./types.js').pageType} pageType
3
- * @typedef {import('./types.js').cookieType} cookieType
5
+ * @typedef {import('../../types.js').pageType} pageType
6
+ * @typedef {import('../../types.js').cookieType} cookieType
4
7
  */
5
8
 
6
9
  /**
@@ -42,6 +45,7 @@ export const parsePage = (text) => {
42
45
  // 2) parse the headers
43
46
  //
44
47
 
48
+ debug('parsing the headers received from PL/SQL');
45
49
  head.split('\n').forEach((line) => {
46
50
  const header = getHeader(line);
47
51
 
@@ -50,15 +54,19 @@ export const parsePage = (text) => {
50
54
  case 'set-cookie':
51
55
  {
52
56
  const cookie = parseCookie(header.value);
57
+ debug(`oracle header "set-cookie" with value "${header.value}" was received has been parsed to ${JSON.stringify(cookie)}`);
53
58
  /* istanbul ignore else */
54
59
  if (cookie !== null) {
55
60
  page.head.cookies.push(cookie);
61
+ } else {
62
+ throw new Error(`Unable to parse header "set-cookie" with value "${header.value}" received from PL/SQL`);
56
63
  }
57
64
  }
58
65
  break;
59
66
 
60
67
  case 'content-type':
61
68
  page.head.contentType = header.value;
69
+ debug(`oracle header "content-type" with value "${page.head.contentType}" was parsed`);
62
70
  break;
63
71
 
64
72
  case 'x-db-content-length':
@@ -67,6 +75,9 @@ export const parsePage = (text) => {
67
75
  /* istanbul ignore else */
68
76
  if (!Number.isNaN(contentLength)) {
69
77
  page.head.contentLength = contentLength;
78
+ debug(`oracle header "x-db-content-length" with value "${page.head.contentLength}" was parsed`);
79
+ } else {
80
+ throw new Error(`Unable to parse header "x-db-content-length" with value "${header.value}" received from PL/SQL`);
70
81
  }
71
82
  }
72
83
  break;
@@ -77,17 +88,21 @@ export const parsePage = (text) => {
77
88
  /* istanbul ignore else */
78
89
  if (!Number.isNaN(statusCode)) {
79
90
  page.head.statusCode = statusCode;
91
+ debug(`oracle header "status" with value "${page.head.statusCode}" was parsed`);
80
92
  const index = header.value.indexOf(' ');
81
93
  /* istanbul ignore else */
82
94
  if (index !== -1) {
83
95
  page.head.statusDescription = header.value.substring(index + 1);
84
96
  }
97
+ } else {
98
+ throw new Error(`Unable to parse header "status" with value "${header.value}" received from PL/SQL`);
85
99
  }
86
100
  }
87
101
  break;
88
102
 
89
103
  case 'location':
90
104
  page.head.redirectLocation = header.value;
105
+ debug(`oracle header "location" with value "${page.head.statusCode}" was parsed`);
91
106
  break;
92
107
 
93
108
  case 'x-oracle-ignore':
@@ -151,27 +166,28 @@ const parseCookie = (text) => {
151
166
  const cookie = {
152
167
  name: cookieElements[0].substring(0, index).trim(),
153
168
  value: cookieElements[0].substring(index + 1).trim(),
169
+ options: {},
154
170
  };
155
171
 
156
- // remove the fisrt element
172
+ // remove the first element
157
173
  cookieElements.shift();
158
174
 
159
175
  // get the other options
160
176
  cookieElements.forEach((element) => {
161
177
  if (element.startsWith('path=')) {
162
- cookie.path = element.substring(5);
178
+ cookie.options.path = element.substring(5);
163
179
  } else if (element.toLowerCase().startsWith('domain=')) {
164
- cookie.domain = element.substring(7);
180
+ cookie.options.domain = element.substring(7);
165
181
  } else if (element.toLowerCase().startsWith('secure=')) {
166
182
  /* istanbul ignore next */
167
- cookie.secure = element.substring(7);
183
+ cookie.options.secure = true;
168
184
  } else if (element.toLowerCase().startsWith('expires=')) {
169
185
  const date = tryDecodeDate(element.substring(8));
170
186
  if (date) {
171
- cookie.expires = date;
187
+ cookie.options.expires = date;
172
188
  }
173
189
  } else if (element.toLowerCase().startsWith('httponly')) {
174
- cookie.httpOnly = true;
190
+ cookie.options.httpOnly = true;
175
191
  }
176
192
  });
177
193
 
@@ -16,19 +16,19 @@ import {getProcedureNamed} from './procedureNamed.js';
16
16
  import {parsePage} from './parsePage.js';
17
17
  import {sendResponse} from './sendResponse.js';
18
18
  import {ProcedureError} from './procedureError.js';
19
- import {inspect, getBlock} from './trace.js';
20
- import {errorToString} from './error.js';
19
+ import {inspect, getBlock} from '../../util/trace.js';
20
+ import {errorToString} from '../../util/errorToString.js';
21
21
 
22
22
  /**
23
23
  * @typedef {import('express').Request} Request
24
24
  * @typedef {import('express').Response} Response
25
25
  * @typedef {import('oracledb').Connection} Connection
26
26
  * @typedef {import('oracledb').Result<unknown>} Result
27
- * @typedef {import('./types.js').argObjType} argObjType
28
- * @typedef {import('./types.js').fileUploadType} fileUploadType
29
- * @typedef {import('./types.js').environmentType} environmentType
30
- * @typedef {import('./types.js').configPlSqlHandlerType} configPlSqlHandlerType
31
- * @typedef {import('./types.js').BindParameterConfig} BindParameterConfig
27
+ * @typedef {import('../../types.js').argObjType} argObjType
28
+ * @typedef {import('../../types.js').fileUploadType} fileUploadType
29
+ * @typedef {import('../../types.js').environmentType} environmentType
30
+ * @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
31
+ * @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
32
32
  */
33
33
 
34
34
  /**
@@ -215,9 +215,6 @@ export const invokeProcedure = async (req, res, argObj, cgiObj, filesToUpload, o
215
215
 
216
216
  // combine page
217
217
  const pageContent = data.lines.join('');
218
- if (debug.enabled && pageContent.length > 0) {
219
- debug(getBlock('PLAIN CONTENT', pageContent));
220
- }
221
218
 
222
219
  //
223
220
  // 6) PARSE PAGE
@@ -3,8 +3,8 @@
3
3
  */
4
4
 
5
5
  /**
6
- * @typedef {import('./types.js').environmentType} environmentType
7
- * @typedef {import('./types.js').BindParameterConfig} BindParameterConfig
6
+ * @typedef {import('../../types.js').environmentType} environmentType
7
+ * @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
8
8
  */
9
9
 
10
10
  export class ProcedureError extends Error {
@@ -9,7 +9,7 @@ import oracledb from 'oracledb';
9
9
  import z from 'zod';
10
10
  import {sanitizeProcName} from './procedureSanitize.js';
11
11
  import {RequestError} from './requestError.js';
12
- import {errorToString} from './error.js';
12
+ import {errorToString} from '../../util/errorToString.js';
13
13
 
14
14
  /**
15
15
  * @typedef {Record<string, string>} argsType
@@ -19,9 +19,9 @@ import {errorToString} from './error.js';
19
19
  /**
20
20
  * @typedef {import('oracledb').Connection} Connection
21
21
  * @typedef {import('oracledb').Result<unknown>} Result
22
- * @typedef {import('./types.js').configPlSqlHandlerType} configPlSqlHandlerType
23
- * @typedef {import('./types.js').argObjType} argObjType
24
- * @typedef {import('./types.js').BindParameterConfig} BindParameterConfig
22
+ * @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
23
+ * @typedef {import('../../types.js').argObjType} argObjType
24
+ * @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
25
25
  */
26
26
 
27
27
  const SQL_GET_ARGUMENT = [
@@ -4,18 +4,18 @@ const debug = debugModule('webplsql:procedureSanitize');
4
4
  import oracledb from 'oracledb';
5
5
  import z from 'zod';
6
6
  import {RequestError} from './requestError.js';
7
- import {errorToString} from './error.js';
7
+ import {errorToString} from '../../util/errorToString.js';
8
8
 
9
9
  /**
10
10
  * @typedef {import('express').Request} Request
11
11
  * @typedef {import('express').Response} Response
12
12
  * @typedef {import('oracledb').Connection} Connection
13
13
  * @typedef {import('oracledb').Result<unknown>} Result
14
- * @typedef {import('./types.js').argObjType} argObjType
15
- * @typedef {import('./types.js').fileUploadType} fileUploadType
16
- * @typedef {import('./types.js').environmentType} environmentType
17
- * @typedef {import('./types.js').configPlSqlHandlerType} configPlSqlHandlerType
18
- * @typedef {import('./types.js').BindParameterConfig} BindParameterConfig
14
+ * @typedef {import('../../types.js').argObjType} argObjType
15
+ * @typedef {import('../../types.js').fileUploadType} fileUploadType
16
+ * @typedef {import('../../types.js').environmentType} environmentType
17
+ * @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
18
+ * @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
19
19
  */
20
20
 
21
21
  const DEFAULT_EXCLUSION_LIST = ['sys.', 'dbms_', 'utl_', 'owa_', 'htp.', 'htf.', 'wpg_docload.', 'ctxsys.', 'mdsys.'];
@@ -11,9 +11,9 @@ import {sanitizeProcName} from './procedureSanitize.js';
11
11
  /**
12
12
  * @typedef {import('oracledb').Connection} Connection
13
13
  * @typedef {import('oracledb').Result<unknown>} Result
14
- * @typedef {import('./types.js').configPlSqlHandlerType} configPlSqlHandlerType
15
- * @typedef {import('./types.js').argObjType} argObjType
16
- * @typedef {import('./types.js').BindParameterConfig} BindParameterConfig
14
+ * @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
15
+ * @typedef {import('../../types.js').argObjType} argObjType
16
+ * @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
17
17
  */
18
18
 
19
19
  /**
@@ -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('./types.js').argObjType} argObjType
20
- * @typedef {import('./types.js').configPlSqlHandlerType} configPlSqlHandlerType
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.