web_plsql 0.5.0 → 0.6.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 (96) hide show
  1. package/README.md +123 -110
  2. package/examples/server_apex.js +28 -0
  3. package/examples/server_sample.js +30 -0
  4. package/examples/sql/{doc_table.sql → doctable.sql} +1 -1
  5. package/examples/sql/install.sql +6 -9
  6. package/examples/sql/sample_package.sql +27 -0
  7. package/examples/sql/sample_package_body.sql +245 -0
  8. package/examples/static/sample.css +11 -10
  9. package/package.json +90 -83
  10. package/src/cgi.js +127 -0
  11. package/src/error.js +24 -0
  12. package/src/errorPage.js +296 -0
  13. package/src/file.js +77 -0
  14. package/src/handlerLogger.js +21 -0
  15. package/src/handlerMetrics.js +46 -0
  16. package/src/handlerPlSql.js +65 -0
  17. package/src/handlerUpload.js +32 -0
  18. package/src/index.js +17 -0
  19. package/src/oracle.js +80 -0
  20. package/src/parsePage.js +193 -0
  21. package/src/procedure.js +260 -0
  22. package/src/procedureError.js +40 -0
  23. package/src/procedureNamed.js +233 -0
  24. package/src/procedureSanitize.js +215 -0
  25. package/src/procedureVariable.js +57 -0
  26. package/src/request.js +103 -0
  27. package/src/{requestError.ts → requestError.js} +8 -4
  28. package/src/sendResponse.js +104 -0
  29. package/src/server.js +106 -0
  30. package/src/shutdown.js +53 -0
  31. package/src/stream.js +28 -0
  32. package/src/trace.js +74 -0
  33. package/src/tty.js +48 -0
  34. package/src/types.js +146 -0
  35. package/src/upload.js +92 -0
  36. package/src/version.js +23 -0
  37. package/types/cgi.d.ts +4 -0
  38. package/types/error.d.ts +1 -0
  39. package/types/errorPage.d.ts +10 -0
  40. package/types/file.d.ts +5 -0
  41. package/types/handlerLogger.d.ts +2 -0
  42. package/types/handlerMetrics.d.ts +4 -0
  43. package/types/handlerPlSql.d.ts +8 -0
  44. package/types/handlerUpload.d.ts +7 -0
  45. package/types/index.d.ts +10 -0
  46. package/types/oracle.d.ts +5 -0
  47. package/types/parsePage.d.ts +3 -0
  48. package/types/procedure.d.ts +10 -0
  49. package/types/procedureError.d.ts +23 -0
  50. package/types/procedureNamed.d.ts +14 -0
  51. package/types/procedureSanitize.d.ts +14 -0
  52. package/types/procedureVariable.d.ts +9 -0
  53. package/types/request.d.ts +7 -0
  54. package/types/requestError.d.ts +8 -0
  55. package/types/sendResponse.d.ts +4 -0
  56. package/types/server.d.ts +7 -0
  57. package/types/shutdown.d.ts +2 -0
  58. package/types/stream.d.ts +1 -0
  59. package/types/trace.d.ts +5 -0
  60. package/types/tty.d.ts +4 -0
  61. package/types/types.d.ts +251 -0
  62. package/types/upload.d.ts +5 -0
  63. package/types/version.d.ts +7 -0
  64. package/.editorconfig +0 -8
  65. package/.eslintignore +0 -3
  66. package/.eslintrc.js +0 -347
  67. package/CHANGELOG.md +0 -127
  68. package/examples/apex.js +0 -70
  69. package/examples/credentials.js +0 -22
  70. package/examples/oracledb_example.js +0 -30
  71. package/examples/sample.js +0 -101
  72. package/examples/sql/sample.pkb +0 -223
  73. package/examples/sql/sample.pks +0 -24
  74. package/jest.config.js +0 -204
  75. package/src/cgi.ts +0 -95
  76. package/src/config.ts +0 -97
  77. package/src/errorPage.ts +0 -286
  78. package/src/fileUpload.ts +0 -126
  79. package/src/index.ts +0 -65
  80. package/src/page.ts +0 -275
  81. package/src/procedure.ts +0 -360
  82. package/src/procedureError.ts +0 -27
  83. package/src/request.ts +0 -139
  84. package/src/stream.ts +0 -26
  85. package/src/trace.ts +0 -194
  86. package/test/.eslintrc.json +0 -5
  87. package/test/__tests__/cgi.ts +0 -96
  88. package/test/__tests__/config.ts +0 -41
  89. package/test/__tests__/errorPage.ts +0 -101
  90. package/test/__tests__/oracledb_mock.ts +0 -98
  91. package/test/__tests__/server.ts +0 -495
  92. package/test/__tests__/stream.ts +0 -21
  93. package/test/mock/oracledb.ts +0 -85
  94. package/test/static/static.html +0 -1
  95. package/tsconfig.json +0 -24
  96. package/tsconfig.src.json +0 -23
package/src/procedure.ts DELETED
@@ -1,360 +0,0 @@
1
- /*
2
- * Invoke the Oracle procedure and return the raw content of the page
3
- */
4
-
5
- import oracledb from 'oracledb';
6
- import {streamToBuffer} from './stream';
7
- import {uploadFiles, filesUploadType} from './fileUpload';
8
- import {parse, send} from './page';
9
- import {ProcedureError} from './procedureError';
10
- import {RequestError} from './requestError';
11
- import {Trace} from './trace';
12
- import express from 'express';
13
- import {oracleExpressMiddleware$options} from './config';
14
-
15
- type argObjType = {[key: string]: string | Array<string>};
16
-
17
- /**
18
- * Invoke the Oracle procedure and return the page content
19
- *
20
- * @param {express.Request} req - The req object represents the HTTP request.
21
- * @param {express.Response} res - The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
22
- * @param {argObjType} argObj - - The arguments of the procedure to invoke.
23
- * @param {Object} cgiObj - The cgi of the procedure to invoke.
24
- * @param {filesUploadType} filesToUpload - Array of files to be uploaded
25
- * @param {oracleExpressMiddleware$options} options - the options for the middleware.
26
- * @param {oracledb.Connection} databaseConnection - Database connection.
27
- * @param {Trace} trace - Tracing object.
28
- * @returns {Promise<void>} - Promise resolving to the page content generated by the executed procedure
29
- */
30
- export async function invokeProcedure(req: express.Request, res: express.Response, argObj: argObjType, cgiObj: Record<string, string>, filesToUpload: filesUploadType, options: oracleExpressMiddleware$options, databaseConnection: oracledb.Connection, trace: Trace): Promise<void> {
31
- trace.write('invokeProcedure: ENTER');
32
-
33
- const procedure = req.params.name;
34
-
35
- //
36
- // 1) UPLOAD FILES
37
- //
38
-
39
- trace.write(`invokeProcedure: upload "${filesToUpload.length}" files`);
40
- /* istanbul ignore else */
41
- if (typeof options.doctable === 'string' && options.doctable.length > 0) {
42
- uploadFiles(filesToUpload, options.doctable, databaseConnection);
43
- }
44
-
45
- //
46
- // 2) GET SQL STATEMENT AND ARGUMENTS
47
- //
48
-
49
- const para = await getProcedure(procedure, argObj, options, databaseConnection, trace);
50
-
51
- //
52
- // 3) EXECUTE PROCEDURE
53
- //
54
-
55
- const HTBUF_LEN = 63;
56
- const MAX_IROWS = 100000;
57
-
58
- const cgi = {
59
- keys: Object.keys(cgiObj),
60
- values: Object.values(cgiObj)
61
- };
62
-
63
- const fileBlob = await databaseConnection.createLob(oracledb.BLOB);
64
-
65
- const bind = {
66
- cgicount: {dir: oracledb.BIND_IN, type: oracledb.NUMBER, val: cgi.keys.length},
67
- cginames: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: cgi.keys},
68
- cgivalues: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: cgi.values},
69
- htbuflen: {dir: oracledb.BIND_IN, type: oracledb.NUMBER, val: HTBUF_LEN},
70
- fileType: {dir: oracledb.BIND_OUT, type: oracledb.STRING},
71
- fileSize: {dir: oracledb.BIND_OUT, type: oracledb.NUMBER},
72
- fileBlob: {dir: oracledb.BIND_INOUT, type: oracledb.BLOB, val: fileBlob},
73
- lines: {dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: HTBUF_LEN * 2, maxArraySize: MAX_IROWS},
74
- irows: {dir: oracledb.BIND_INOUT, type: oracledb.NUMBER, val: MAX_IROWS}
75
- };
76
-
77
- // execute procedure and retrieve page
78
- const sqlStatement = getProcedureSQL(para.sql);
79
- let result: any;
80
- try {
81
- trace.write(`execute:\n${'-'.repeat(30)}\n${sqlStatement}\n${'-'.repeat(30)}\nwith bindings:\n${Trace.inspect(bind)}`);
82
- result = await databaseConnection.execute(sqlStatement, Object.assign(bind, para.bind));
83
- trace.write(`results:\n${Trace.inspect(result)}`);
84
- } catch (err) {
85
- /* istanbul ignore next */
86
- throwError(`Error when executing procedure\n${sqlStatement}\n${err instanceof Error ? err.toString() : ''}`, para, cgiObj, trace);
87
- }
88
-
89
- //
90
- // 4) PROCESS RESULTS
91
- //
92
-
93
- // internal error
94
- if (!result) {
95
- /* istanbul ignore next */
96
- throwError('Error when retrieving rows', para, cgiObj, trace);
97
- }
98
-
99
- // Make sure that we have retrieved all the rows
100
- if (result.outBinds.irows > MAX_IROWS) {
101
- /* istanbul ignore next */
102
- throwError(`Error when retrieving rows. irows="${result.outBinds.irows}"`, para, cgiObj, trace);
103
- }
104
-
105
- // combine page
106
- const pageContent = result.outBinds.lines.join('');
107
- trace.write(`PLAIN CONTENT:\n${'-'.repeat(30)}\n${pageContent}\n${'-'.repeat(30)}`);
108
-
109
- //
110
- // 6) PARSE PAGE
111
- //
112
-
113
- // parse what we received from PL/SQL
114
- const pageComponents = parse(pageContent);
115
-
116
- // add "Server" header
117
- pageComponents.head.server = cgiObj.SERVER_SOFTWARE;
118
-
119
- // add file download information
120
- pageComponents.file.fileType = result.outBinds.fileType;
121
- pageComponents.file.fileSize = result.outBinds.fileSize;
122
- pageComponents.file.fileBlob = result.outBinds.fileBlob !== null ? await streamToBuffer(result.outBinds.fileBlob) : null;
123
-
124
- trace.write(`PARSED CONTENT:\n${'-'.repeat(30)}\n${Trace.inspect(pageComponents)}\n${'-'.repeat(30)}`);
125
-
126
- //
127
- // 5) SEND THE RESPONSE
128
- //
129
-
130
- send(req, res, pageComponents, trace);
131
-
132
- //
133
- // 6) CLEANUP
134
- //
135
-
136
- await fileBlob.close();
137
-
138
- trace.write('invokeProcedure: EXIT');
139
-
140
- return Promise.resolve();
141
- }
142
-
143
- /*
144
- * Report error in procedure
145
- */
146
- /* istanbul ignore next */
147
- function throwError(error: string, para: {sql: string; bind: any}, cgiObj: any, trace: Trace) {
148
- /* istanbul ignore next */
149
- trace.write(error);
150
- /* istanbul ignore next */
151
- throw new ProcedureError(error, cgiObj, para.sql, para.bind);
152
- }
153
-
154
- /*
155
- * Get the procedure and arguments to execute
156
- */
157
- async function getProcedure(procedure: string, argObj: argObjType, options: oracleExpressMiddleware$options, databaseConnection: oracledb.Connection, trace: Trace): Promise<{sql: string; bind: any}> {
158
- if (options.pathAlias && options.pathAlias.alias === procedure) {
159
- trace.write(`getProcedure: path alias "${options.pathAlias.alias}" redirects to "${options.pathAlias.procedure}"`);
160
- return Promise.resolve({
161
- sql: options.pathAlias.procedure + '(p_path=>:p_path);',
162
- bind: {
163
- 'p_path': {dir: oracledb.BIND_IN, type: oracledb.STRING, val: procedure}
164
- }
165
- });
166
- } else if (procedure.substring(0, 1) === '!') {
167
- trace.write('getProcedure: get variable arguments');
168
- return getVarArgsPara(procedure, argObj);
169
- }
170
-
171
- trace.write('getProcedure: get named arguments');
172
- return getFixArgsPara(procedure, argObj, databaseConnection);
173
- }
174
-
175
- /*
176
- * Get the SQL statement to execute when a new procedure is invoked
177
- */
178
- function getProcedureSQL(procedure: string): string {
179
- return `
180
- DECLARE
181
- fileType VARCHAR2(32767);
182
- fileSize INTEGER;
183
- fileBlob BLOB;
184
- BEGIN
185
- -- Ensure a stateless environment by resetting package state (dbms_session.reset_package)
186
- dbms_session.modify_package_state(dbms_session.reinitialize);
187
-
188
- -- initialize the cgi
189
- owa.init_cgi_env(:cgicount, :cginames, :cgivalues);
190
-
191
- -- initialize the htp package
192
- htp.init;
193
-
194
- -- set the HTBUF_LEN
195
- htp.HTBUF_LEN := :htbuflen;
196
-
197
- -- execute the procedure
198
- BEGIN
199
- ${procedure}
200
- EXCEPTION WHEN OTHERS THEN
201
- raise_application_error(-20000, 'Error executing ${procedure}'||CHR(10)||SUBSTR(dbms_utility.format_error_stack()||CHR(10)||dbms_utility.format_error_backtrace(), 1, 2000));
202
- END;
203
-
204
- -- Check for file download
205
- IF (wpg_docload.is_file_download()) THEN
206
- wpg_docload.get_download_file(fileType);
207
- IF (filetype = 'B') THEN
208
- wpg_docload.get_download_blob(:fileBlob);
209
- fileSize := dbms_lob.getlength(:fileBlob);
210
- --dbms_lob.copy(dest_lob=>:fileBlob, src_lob=>fileBlob, amount=>fileSize);
211
- END IF;
212
- END IF;
213
- :fileType := fileType;
214
- :fileSize := fileSize;
215
-
216
- -- retrieve the page
217
- owa.get_page(thepage=>:lines, irows=>:irows);
218
- END;
219
- `;
220
- }
221
-
222
- /*
223
- * Get the sql statement and bindings for the procedure to execute for a variable number of arguments
224
- */
225
- async function getVarArgsPara(procedure: string, argObj: argObjType): Promise<{sql: string; bind: any}> {
226
- const names = [];
227
- const values = [];
228
-
229
- for (const key in argObj) {
230
- const value = argObj[key];
231
- if (typeof value === 'string') {
232
- names.push(key);
233
- values.push(value);
234
- } else if (Array.isArray(value)) {
235
- value.forEach(item => {
236
- names.push(key);
237
- values.push(item);
238
- });
239
- }
240
- }
241
-
242
- return Promise.resolve({
243
- sql: procedure.substring(1) + '(:argnames, :argvalues);',
244
- bind: {
245
- argnames: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: names},
246
- argvalues: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: values}
247
- }
248
- });
249
- }
250
-
251
- /*
252
- * Get the sql statement and bindings for the procedure to execute for a fixed number of arguments
253
- */
254
- async function getFixArgsPara(procedure: string, argObj: argObjType, databaseConnection: oracledb.Connection): Promise<{sql: string; bind: any}> {
255
- const bind: {[key: string]: any} = {};
256
- let index = 0;
257
-
258
- const argTypes = await getArguments(procedure, databaseConnection);
259
-
260
- // bindings for the statement
261
- let sql = procedure + '(';
262
- for (const key in argObj) {
263
- const value = argObj[key];
264
- const parameterName = 'p_' + key;
265
-
266
- // prepend the separator, if this is not the first argument
267
- if (index > 0) {
268
- sql += ',';
269
- }
270
- index++;
271
-
272
- // add the argument
273
- sql += key + '=>:' + parameterName;
274
-
275
- // add the binding
276
- bind[parameterName] = {dir: oracledb.BIND_IN, type: oracledb.STRING};
277
-
278
- // set the value or array of values
279
- if (Array.isArray(value) || argTypes[key] === 'PL/SQL TABLE') {
280
- bind[parameterName].val = [];
281
- if (typeof value === 'string') {
282
- bind[parameterName].val.push(value);
283
- } else {
284
- value.forEach(element => {
285
- bind[parameterName].val.push(element);
286
- });
287
- }
288
- } else if (typeof value === 'string') {
289
- bind[parameterName].val = value;
290
- }
291
- }
292
- sql += ');';
293
-
294
- return Promise.resolve({
295
- sql: sql,
296
- bind: bind
297
- });
298
- }
299
-
300
- /*
301
- * Retrieve the argument types for a given procedure to be executed.
302
- * This is important because if the procedure is defined to take a PL/SQL indexed table,
303
- * we must provise a table, even if there is only one argument to be submitted.
304
- */
305
- async function getArguments(procedure: string, databaseConnection: oracledb.Connection): Promise<{[key: string]: string}> {
306
- const sql = [
307
- 'DECLARE',
308
- ' schemaName VARCHAR2(32767);',
309
- ' part1 VARCHAR2(32767);',
310
- ' part2 VARCHAR2(32767);',
311
- ' dblink VARCHAR2(32767);',
312
- ' objectType NUMBER;',
313
- ' objectID NUMBER;',
314
- 'BEGIN',
315
- ' dbms_utility.name_resolve(name=>UPPER(:name), context=>1, schema=>schemaName, part1=>part1, part2=>part2, dblink=>dblink, part1_type=>objectType, object_number=>objectID);',
316
- ' IF (part1 IS NOT NULL) THEN',
317
- ' SELECT argument_name, data_type BULK COLLECT INTO :names, :types FROM all_arguments WHERE owner = schemaName AND package_name = part1 AND object_name = part2 AND argument_name IS NOT NULL ORDER BY overload, sequence;',
318
- ' ELSE',
319
- ' SELECT argument_name, data_type BULK COLLECT INTO :names, :types FROM all_arguments WHERE owner = schemaName AND package_name IS NULL AND object_name = part2 AND argument_name IS NOT NULL ORDER BY overload, sequence;',
320
- ' END IF;',
321
- 'END;'
322
- ];
323
- const MAX_PARAMETER_NUMBER = 1000;
324
-
325
- const bind = {
326
- name: {dir: oracledb.BIND_IN, type: oracledb.STRING, val: procedure},
327
- names: {dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 60, maxArraySize: MAX_PARAMETER_NUMBER},
328
- types: {dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 60, maxArraySize: MAX_PARAMETER_NUMBER}
329
- };
330
-
331
- let result;
332
-
333
- try {
334
- result = await databaseConnection.execute<{names: Array<string>; types: Array<string>}>(sql.join('\n'), bind);
335
- } catch (err) {
336
- /* istanbul ignore next */
337
- const message = `Error when retrieving arguments\n${sql.join('\n')}\n${err instanceof Error ? err.stack : ''}`;
338
- /* istanbul ignore next */
339
- throw new RequestError(message);
340
- }
341
-
342
- const argTypes: any = {};
343
- if (typeof result !== 'object' ||
344
- result === null ||
345
- typeof result.outBinds !== 'object' ||
346
- result.outBinds === null ||
347
- !Array.isArray(result.outBinds.names) ||
348
- !Array.isArray(result.outBinds.types)
349
- ) {
350
- /* istanbul ignore next */
351
- throw new RequestError('getArguments: invalid results');
352
- }
353
-
354
- for (let i = 0; i < result.outBinds.names.length; i++) {
355
- /* istanbul ignore next */
356
- argTypes[result.outBinds.names[i].toLowerCase()] = result.outBinds.types[i];
357
- }
358
-
359
- return Promise.resolve(argTypes);
360
- }
@@ -1,27 +0,0 @@
1
- /*
2
- * RequestError
3
- */
4
-
5
- import {environmentType} from './cgi';
6
-
7
- export class ProcedureError extends Error {
8
- timestamp: Date;
9
- environment: environmentType;
10
- sql: string;
11
- bind: unknown;
12
-
13
- constructor(message: string, environment: environmentType, sql: string, bind: unknown) {
14
- super(message);
15
-
16
- // Maintains proper stack trace for where our error was thrown (only available on V8)
17
- if (Error.captureStackTrace) {
18
- Error.captureStackTrace(this, ProcedureError);
19
- }
20
-
21
- // Custom debugging information
22
- this.timestamp = new Date();
23
- this.environment = environment;
24
- this.sql = sql;
25
- this.bind = bind;
26
- }
27
- }
package/src/request.ts DELETED
@@ -1,139 +0,0 @@
1
- /*
2
- * Process the http request
3
- */
4
-
5
- import util from 'util';
6
- import oracledb from 'oracledb';
7
- import {invokeProcedure} from './procedure';
8
- import {getCGI} from './cgi';
9
- import {getFiles} from './fileUpload';
10
- import {RequestError} from './requestError';
11
- import {Trace} from './trace';
12
- import express from 'express';
13
- import {oracleExpressMiddleware$options} from './config';
14
-
15
- /**
16
- * Process the request
17
- *
18
- * @param {express.Request} req - The req object represents the HTTP request.
19
- * @param {express.Response} res - The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
20
- * @param {oracleExpressMiddleware$options} options - the options for the middleware.
21
- * @param {Promise<oracledb.Pool>} databasePoolPromise - Promise returning a database pool.
22
- * @param {Trace} trace - Tracing object.
23
- * returns {Promise<void>} - Promise that resolves when the request has been fullfilled.
24
- */
25
- export async function processRequest(req: express.Request, res: express.Response, options: oracleExpressMiddleware$options, databasePoolPromise: Promise<oracledb.Pool>, trace: Trace): Promise<void> {
26
- trace.write('processRequest: ENTER');
27
-
28
- let databasePool;
29
- let databaseConnection;
30
-
31
- // wait until the database pool has been allocated
32
- try {
33
- databasePool = await databasePoolPromise;
34
- trace.write('processRequest: Connection pool has been allocated');
35
- } catch (err) {
36
- /* istanbul ignore next */
37
- throw new RequestError(`Unable to create database pool.\n${err instanceof Error ? err.message : ''}`);
38
- }
39
-
40
- // open database connection
41
- try {
42
- databaseConnection = await databasePool.getConnection();
43
- trace.write('processRequest: Connection has been allocated');
44
- } catch (err) {
45
- /* istanbul ignore next */
46
- throw new RequestError(`Unable to open database connection\n${err instanceof Error ? err.message: ''}`);
47
- }
48
-
49
- // execute request
50
- await executeRequest(req, res, options, databaseConnection, trace);
51
-
52
- // close database connection
53
- try {
54
- await databaseConnection.release();
55
- trace.write('processRequest: Connection has been released');
56
- } catch (err) {
57
- /* istanbul ignore next */
58
- console.error(`Unable to release database connection\n${err instanceof Error ? err.message : ''}`);
59
- }
60
-
61
- trace.write('processRequest: EXIT');
62
- }
63
-
64
- /**
65
- * Execute the request
66
- *
67
- * @param {express.Request} req - The req object represents the HTTP request.
68
- * @param {express.Response} res - The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
69
- * @param {oracleExpressMiddleware$options} options - the options for the middleware.
70
- * @param {oracledb.Connection} databaseConnection - Database connection.
71
- * @param {Trace} trace - Tracing object.
72
- * @returns {Promise<void>} - Promise resolving to th page
73
- */
74
- async function executeRequest(req: express.Request, res: express.Response, options: oracleExpressMiddleware$options, databaseConnection: oracledb.Connection, trace: Trace): Promise<void> {
75
- trace.write('executeRequest: ENTER');
76
-
77
- // Get the CGI
78
- const cgiObj = getCGI(req, options);
79
-
80
- // Add the query properties
81
- const argObj: any = {};
82
- Object.assign(argObj, req.query);
83
-
84
- // Does the request contain any files
85
- const filesToUpload = getFiles(req);
86
- trace.write(`executeRequest: "${filesToUpload.length}" files to upload:\n${Trace.inspect(filesToUpload)}`);
87
- /* istanbul ignore next */
88
- if (filesToUpload.length > 0 && (typeof options.doctable !== 'string' || options.doctable.length === 0)) {
89
- const error = 'Unable to upload files if no document table "doctable" has been configured';
90
- trace.write(error);
91
- throw new RequestError(error);
92
- }
93
-
94
- // Add the files to the arguments
95
- filesToUpload.reduce((aggregator, file) => {
96
- aggregator[file.fieldValue] = file.filename;
97
- return aggregator;
98
- }, argObj);
99
-
100
- // Does the request contain a body
101
- Object.assign(argObj, normalizeBody(req));
102
-
103
- // invoke the Oracle procedure and get the page contenst
104
- await invokeProcedure(req, res, argObj, cgiObj, filesToUpload, options, databaseConnection, trace);
105
-
106
- trace.write('executeRequest: EXIT');
107
-
108
- return Promise.resolve();
109
- }
110
-
111
- /*
112
- * Normalize the body by making sure that only "simple" parameters and no nested objects are submitted
113
- */
114
- function normalizeBody(req: express.Request): {[key: string]: string} {
115
- const args: {[key: string]: string} = {};
116
- /* istanbul ignore else */
117
- if (typeof req.body === 'object') {
118
- for (const key in req.body) {
119
- const value = req.body[key];
120
- /* istanbul ignore else */
121
- if (isStringOrArrayOfString(value)) {
122
- args[key] = value;
123
- } else {
124
- /* istanbul ignore next */
125
- throw new RequestError(`The element "${key}" in the body is not a string or an array of strings!\n` + util.inspect(req.body, {showHidden: false, depth: null, colors: false}));
126
- }
127
- }
128
- }
129
-
130
- return args;
131
- }
132
-
133
- /*
134
- * Is the given value a string or an array of strings
135
- */
136
- function isStringOrArrayOfString(value: any): boolean {
137
- /* istanbul ignore next */
138
- return typeof value === 'string' || (Array.isArray(value) && value.every(element => typeof element === 'string'));
139
- }
package/src/stream.ts DELETED
@@ -1,26 +0,0 @@
1
- import stream from 'stream';
2
-
3
- /**
4
- * Convert a readable stream to a buffer.
5
- *
6
- * @param {stream.Readable} readable - The readable stream.
7
- * @returns {Promise<Buffer>} - The buffer.
8
- */
9
- export async function streamToBuffer(readable: stream.Readable): Promise<Buffer> {
10
- return new Promise((resolve, reject) => {
11
- const buffers: Array<Buffer> = [];
12
-
13
- readable.on('data', buffer => {
14
- buffers.push(buffer);
15
- });
16
-
17
- readable.on('end', () => {
18
- resolve(Buffer.concat(buffers));
19
- });
20
-
21
- readable.on('error', err => {
22
- // istanbul ignore next
23
- reject(err);
24
- });
25
- });
26
- }