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.
- package/README.md +108 -13
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/frontend/assets/main-0oxRTIkL.js +147 -0
- package/dist/frontend/assets/main-0oxRTIkL.js.br +0 -0
- package/dist/frontend/assets/main-0oxRTIkL.js.gz +0 -0
- package/dist/frontend/assets/main-TYgLak6O.css +1 -0
- package/dist/frontend/assets/main-TYgLak6O.css.br +0 -0
- package/dist/frontend/assets/main-TYgLak6O.css.gz +0 -0
- package/dist/frontend/index.html +516 -0
- package/dist/frontend/index.html.br +0 -0
- package/dist/frontend/index.html.gz +0 -0
- package/dist/index.d.mts +646 -0
- package/dist/index.mjs +3548 -0
- package/dist/index.mjs.map +1 -0
- package/dist/oracledb-mock-Dn8aHtd7.mjs +68 -0
- package/dist/oracledb-mock-Dn8aHtd7.mjs.map +1 -0
- package/examples/config-apex.js +1 -1
- package/examples/config-docker.js +1 -2
- package/package.json +45 -32
- package/examples/config-native.js +0 -68
- package/src/admin/client/charts.ts +0 -299
- package/src/admin/client/main.js +0 -3
- package/src/admin/client/tailwind.css +0 -41
- package/src/admin/index.html +0 -315
- package/src/admin/js/api.ts +0 -95
- package/src/admin/js/app.ts +0 -306
- package/src/admin/js/eslint.config.js +0 -74
- package/src/admin/js/schemas.ts +0 -153
- package/src/admin/js/templates/config.ts +0 -146
- package/src/admin/js/templates/errorRow.ts +0 -18
- package/src/admin/js/templates/index.ts +0 -3
- package/src/admin/js/templates/poolCard.ts +0 -61
- package/src/admin/js/tsconfig.json +0 -24
- package/src/admin/js/types.ts +0 -223
- package/src/admin/js/ui/theme.ts +0 -93
- package/src/admin/js/ui/views.ts +0 -164
- package/src/admin/js/util/format.ts +0 -27
- package/src/admin/lib/assets/main-zpdhQ1gD.css +0 -1
- package/src/admin/lib/chart.bundle.js +0 -139
- package/src/admin/style.css +0 -1321
- package/src/bin/load-test.js +0 -202
- package/src/handler/handlerAdmin.js +0 -198
- package/src/handler/handlerLogger.js +0 -21
- package/src/handler/handlerMetrics.js +0 -68
- package/src/handler/handlerUpload.js +0 -26
- package/src/handler/plsql/cgi.js +0 -131
- package/src/handler/plsql/errorPage.js +0 -117
- package/src/handler/plsql/handlerPlSql.js +0 -90
- package/src/handler/plsql/parsePage.js +0 -213
- package/src/handler/plsql/procedure.js +0 -356
- package/src/handler/plsql/procedureError.js +0 -40
- package/src/handler/plsql/procedureNamed.js +0 -268
- package/src/handler/plsql/procedureSanitize.js +0 -262
- package/src/handler/plsql/procedureVariable.js +0 -54
- package/src/handler/plsql/request.js +0 -124
- package/src/handler/plsql/requestError.js +0 -23
- package/src/handler/plsql/sendResponse.js +0 -136
- package/src/handler/plsql/stream.js +0 -28
- package/src/handler/plsql/upload.js +0 -109
- package/src/index.js +0 -20
- package/src/server/config.js +0 -57
- package/src/server/connections.js +0 -40
- package/src/server/server.js +0 -289
- package/src/types.js +0 -150
- package/src/util/cache.js +0 -123
- package/src/util/errorToString.js +0 -24
- package/src/util/file.js +0 -91
- package/src/util/html.js +0 -53
- package/src/util/jsonLogger.js +0 -47
- package/src/util/oracle.js +0 -80
- package/src/util/shutdown.js +0 -44
- package/src/util/trace.js +0 -325
- package/src/util/type.js +0 -6
- package/src/util/util.js +0 -66
- package/src/version.js +0 -5
- package/types/handler/handlerAdmin.d.ts +0 -9
- package/types/handler/handlerLogger.d.ts +0 -2
- package/types/handler/handlerMetrics.d.ts +0 -25
- package/types/handler/handlerUpload.d.ts +0 -7
- package/types/handler/plsql/cgi.d.ts +0 -4
- package/types/handler/plsql/errorPage.d.ts +0 -11
- package/types/handler/plsql/handlerPlSql.d.ts +0 -13
- package/types/handler/plsql/parsePage.d.ts +0 -3
- package/types/handler/plsql/procedure.d.ts +0 -12
- package/types/handler/plsql/procedureError.d.ts +0 -23
- package/types/handler/plsql/procedureNamed.d.ts +0 -14
- package/types/handler/plsql/procedureSanitize.d.ts +0 -11
- package/types/handler/plsql/procedureVariable.d.ts +0 -10
- package/types/handler/plsql/request.d.ts +0 -9
- package/types/handler/plsql/requestError.d.ts +0 -8
- package/types/handler/plsql/sendResponse.d.ts +0 -6
- package/types/handler/plsql/upload.d.ts +0 -5
- package/types/index.d.ts +0 -11
- package/types/server/config.d.ts +0 -2
- package/types/server/server.d.ts +0 -74
- package/types/types.d.ts +0 -328
- package/types/util/cache.d.ts +0 -69
- package/types/util/errorToString.d.ts +0 -1
- package/types/util/file.d.ts +0 -6
- package/types/util/html.d.ts +0 -3
- package/types/util/jsonLogger.d.ts +0 -45
- package/types/util/oracle.d.ts +0 -5
- package/types/util/shutdown.d.ts +0 -2
- package/types/util/trace.d.ts +0 -22
- package/types/util/type.d.ts +0 -1
- package/types/util/util.d.ts +0 -3
- package/types/version.d.ts +0 -1
- /package/{src/admin/favicon.svg → dist/frontend/assets/favicon-mQAM4tVu.svg} +0 -0
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Error handling
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {ProcedureError} from './procedureError.js';
|
|
6
|
-
import {RequestError} from './requestError.js';
|
|
7
|
-
import {getFormattedMessage, logToFile} from '../../util/trace.js';
|
|
8
|
-
import {errorToString} from '../../util/errorToString.js';
|
|
9
|
-
import {getHtmlPage} from '../../util/html.js';
|
|
10
|
-
import {jsonLogger} from '../../util/jsonLogger.js';
|
|
11
|
-
import {AdminContext} from '../../server/server.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {import('express').Request} Request
|
|
15
|
-
* @typedef {import('express').Response} Response
|
|
16
|
-
* @typedef {import('../../types.js').BindParameterConfig} BindParameterConfig
|
|
17
|
-
* @typedef {import('../../types.js').environmentType} environmentType
|
|
18
|
-
* @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
|
|
19
|
-
* @typedef {{html: string; text: string}} outputType
|
|
20
|
-
* @typedef {import('../../util/trace.js').messageType} messageType
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Get error data
|
|
25
|
-
* @param {Request} req - The req object represents the HTTP request.
|
|
26
|
-
* @param {unknown} error - The error.
|
|
27
|
-
* @returns {messageType} - The output.
|
|
28
|
-
*/
|
|
29
|
-
const getErrorData = (req, error) => {
|
|
30
|
-
let timestamp = new Date();
|
|
31
|
-
let message = '';
|
|
32
|
-
/** @type {environmentType | null} */
|
|
33
|
-
let environment = null;
|
|
34
|
-
/** @type {string | null} */
|
|
35
|
-
let sql = null;
|
|
36
|
-
/** @type {BindParameterConfig | null} */
|
|
37
|
-
let bind = null;
|
|
38
|
-
|
|
39
|
-
// what type of Error did we receive
|
|
40
|
-
if (error instanceof ProcedureError) {
|
|
41
|
-
timestamp = error.timestamp;
|
|
42
|
-
message = error.stack ?? '';
|
|
43
|
-
environment = error.environment;
|
|
44
|
-
sql = error.sql;
|
|
45
|
-
bind = error.bind;
|
|
46
|
-
} else if (error instanceof RequestError) {
|
|
47
|
-
timestamp = error.timestamp;
|
|
48
|
-
message = error.stack ?? '';
|
|
49
|
-
} else if (error instanceof Error) {
|
|
50
|
-
message = errorToString(error);
|
|
51
|
-
} else {
|
|
52
|
-
if (typeof error === 'string') {
|
|
53
|
-
message = `${error}\n`;
|
|
54
|
-
}
|
|
55
|
-
/* v8 ignore start - unreachable code: creating Error without throwing */
|
|
56
|
-
try {
|
|
57
|
-
new Error();
|
|
58
|
-
} catch (err) {
|
|
59
|
-
message += errorToString(err);
|
|
60
|
-
}
|
|
61
|
-
/* v8 ignore stop */
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return {type: 'error', timestamp, message, req, environment, sql, bind};
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Show an error page
|
|
69
|
-
*
|
|
70
|
-
* @param {Request} req - The req object represents the HTTP request.
|
|
71
|
-
* @param {Response} res - The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
|
|
72
|
-
* @param {configPlSqlHandlerType} options - The configuration options.
|
|
73
|
-
* @param {unknown} error - The error.
|
|
74
|
-
*/
|
|
75
|
-
export const errorPage = (req, res, options, error) => {
|
|
76
|
-
// get error data
|
|
77
|
-
const errorData = getErrorData(req, error);
|
|
78
|
-
|
|
79
|
-
// Update metrics
|
|
80
|
-
AdminContext.metrics.errorCount++;
|
|
81
|
-
|
|
82
|
-
// get formatted message
|
|
83
|
-
const {html, text} = getFormattedMessage(errorData);
|
|
84
|
-
|
|
85
|
-
// trace to file
|
|
86
|
-
logToFile(text);
|
|
87
|
-
|
|
88
|
-
// json log
|
|
89
|
-
const firstLine = errorData.message.split('\n')[0];
|
|
90
|
-
jsonLogger.log({
|
|
91
|
-
timestamp: errorData.timestamp?.toISOString() ?? new Date().toISOString(),
|
|
92
|
-
type: 'error',
|
|
93
|
-
message: firstLine ?? '',
|
|
94
|
-
req: {
|
|
95
|
-
method: req.method,
|
|
96
|
-
url: req.originalUrl,
|
|
97
|
-
ip: req.ip ?? '',
|
|
98
|
-
userAgent: req.get('user-agent') ?? '',
|
|
99
|
-
},
|
|
100
|
-
details: {
|
|
101
|
-
fullMessage: errorData.message,
|
|
102
|
-
sql: errorData.sql,
|
|
103
|
-
bind: errorData.bind,
|
|
104
|
-
environment: errorData.environment,
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// console
|
|
109
|
-
console.error(text);
|
|
110
|
-
|
|
111
|
-
// show page
|
|
112
|
-
if (options.errorStyle === 'basic') {
|
|
113
|
-
res.status(404).send('Page not found');
|
|
114
|
-
} else {
|
|
115
|
-
res.status(404).send(getHtmlPage(html));
|
|
116
|
-
}
|
|
117
|
-
};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Express middleware for Oracle PL/SQL
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import debugModule from 'debug';
|
|
6
|
-
const debug = debugModule('webplsql:handlerPlSql');
|
|
7
|
-
|
|
8
|
-
import url from 'node:url';
|
|
9
|
-
import {processRequest} from './request.js';
|
|
10
|
-
import {RequestError} from './requestError.js';
|
|
11
|
-
import {errorPage} from './errorPage.js';
|
|
12
|
-
import {Cache} from '../../util/cache.js';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @typedef {import('express').RequestHandler} RequestHandler
|
|
16
|
-
* @typedef {import('express').Request} Request
|
|
17
|
-
* @typedef {import('express').Response} Response
|
|
18
|
-
* @typedef {import('express').NextFunction} NextFunction
|
|
19
|
-
* @typedef {import('oracledb').Pool} Pool
|
|
20
|
-
* @typedef {import('../../types.js').environmentType} environmentType
|
|
21
|
-
* @typedef {import('../../types.js').configPlSqlHandlerType} configPlSqlHandlerType
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* express.Request handler
|
|
26
|
-
* @param {Request} req - The req object represents the HTTP request.
|
|
27
|
-
* @param {Response} res - The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
|
|
28
|
-
* @param {NextFunction} _next - The next function.
|
|
29
|
-
* @param {Pool} connectionPool - The connection pool.
|
|
30
|
-
* @param {configPlSqlHandlerType} options - the options for the middleware.
|
|
31
|
-
* @param {Cache<string>} procedureNameCache - The procedure name cache.
|
|
32
|
-
* @param {Cache<import('./procedureNamed.js').argsType>} argumentCache - The argument cache.
|
|
33
|
-
*/
|
|
34
|
-
const requestHandler = async (req, res, _next, connectionPool, options, procedureNameCache, argumentCache) => {
|
|
35
|
-
try {
|
|
36
|
-
// should we switch to the default page if there is one defined
|
|
37
|
-
if (typeof req.params.name !== 'string' || req.params.name.length === 0) {
|
|
38
|
-
if (typeof options.defaultPage === 'string' && options.defaultPage.length > 0) {
|
|
39
|
-
const newUrl = url.resolve(`${req.originalUrl}/${options.defaultPage}`, '');
|
|
40
|
-
debug(`Redirect to the url "${newUrl}"`);
|
|
41
|
-
res.redirect(newUrl);
|
|
42
|
-
} else {
|
|
43
|
-
errorPage(req, res, options, new RequestError('No procedure name given and no default page has been specified'));
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
// request handler
|
|
47
|
-
await processRequest(req, res, options, connectionPool, procedureNameCache, argumentCache);
|
|
48
|
-
}
|
|
49
|
-
} catch (err) {
|
|
50
|
-
errorPage(req, res, options, err);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @typedef {import('express').RequestHandler & {
|
|
56
|
-
* procedureNameCache: Cache<string>;
|
|
57
|
-
* argumentCache: Cache<import('./procedureNamed.js').argsType>;
|
|
58
|
-
* }} WebPlSqlRequestHandler
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Express middleware.
|
|
63
|
-
*
|
|
64
|
-
* @param {Pool} connectionPool - The connection pool.
|
|
65
|
-
* @param {configPlSqlHandlerType} config - The configuration options.
|
|
66
|
-
* @returns {WebPlSqlRequestHandler} - The handler.
|
|
67
|
-
*/
|
|
68
|
-
export const handlerWebPlSql = (connectionPool, config) => {
|
|
69
|
-
debug('options', config);
|
|
70
|
-
|
|
71
|
-
/** @type {Cache<string>} */
|
|
72
|
-
const procedureNameCache = new Cache();
|
|
73
|
-
/** @type {Cache<import('./procedureNamed.js').argsType>} */
|
|
74
|
-
const argumentCache = new Cache();
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @param {Request} req - The request.
|
|
78
|
-
* @param {Response} res - The response.
|
|
79
|
-
* @param {NextFunction} next - The next function.
|
|
80
|
-
*/
|
|
81
|
-
const handler = (req, res, next) => {
|
|
82
|
-
void requestHandler(req, res, next, connectionPool, config, procedureNameCache, argumentCache);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// Expose caches for Admin Console
|
|
86
|
-
handler.procedureNameCache = procedureNameCache;
|
|
87
|
-
handler.argumentCache = argumentCache;
|
|
88
|
-
|
|
89
|
-
return handler;
|
|
90
|
-
};
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import debugModule from 'debug';
|
|
2
|
-
const debug = debugModule('webplsql:parsePage');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {import('../../types.js').pageType} pageType
|
|
6
|
-
* @typedef {import('../../types.js').cookieType} cookieType
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Parse the header and split it up into the individual components
|
|
11
|
-
*
|
|
12
|
-
* @param {string} text - The text returned from the PL/SQL procedure.
|
|
13
|
-
* @returns {pageType} - The parsed page.
|
|
14
|
-
*/
|
|
15
|
-
export const parsePage = (text) => {
|
|
16
|
-
/** @type {pageType} */
|
|
17
|
-
const page = {
|
|
18
|
-
body: '',
|
|
19
|
-
head: {
|
|
20
|
-
cookies: [],
|
|
21
|
-
otherHeaders: {},
|
|
22
|
-
},
|
|
23
|
-
file: {
|
|
24
|
-
fileType: null,
|
|
25
|
-
fileSize: null,
|
|
26
|
-
fileBlob: null,
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
//
|
|
31
|
-
// 1) Split up the text in header and body
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
// Find the end of the header identified by \n\n
|
|
35
|
-
let head = '';
|
|
36
|
-
const headerEndPosition = text.indexOf('\n\n');
|
|
37
|
-
if (headerEndPosition === -1) {
|
|
38
|
-
head = text;
|
|
39
|
-
} else {
|
|
40
|
-
head = text.substring(0, headerEndPosition + 2);
|
|
41
|
-
page.body = text.substring(headerEndPosition + 2);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
// 2) parse the headers
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
debug('parsing the headers received from PL/SQL');
|
|
49
|
-
head.split('\n').forEach((line) => {
|
|
50
|
-
const header = getHeader(line);
|
|
51
|
-
|
|
52
|
-
if (header) {
|
|
53
|
-
switch (header.name.toLowerCase()) {
|
|
54
|
-
case 'set-cookie':
|
|
55
|
-
{
|
|
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)}`);
|
|
58
|
-
/* v8 ignore else - parseCookie validation ensures non-null */
|
|
59
|
-
if (cookie !== null) {
|
|
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`);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
break;
|
|
66
|
-
|
|
67
|
-
case 'content-type':
|
|
68
|
-
page.head.contentType = header.value;
|
|
69
|
-
debug(`oracle header "content-type" with value "${page.head.contentType}" was parsed`);
|
|
70
|
-
break;
|
|
71
|
-
|
|
72
|
-
case 'x-db-content-length':
|
|
73
|
-
{
|
|
74
|
-
const contentLength = parseInt(header.value, 10);
|
|
75
|
-
/* v8 ignore else - parseInt validation */
|
|
76
|
-
if (!Number.isNaN(contentLength)) {
|
|
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`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
break;
|
|
84
|
-
|
|
85
|
-
case 'status':
|
|
86
|
-
{
|
|
87
|
-
const statusCode = parseInt(header.value, 10);
|
|
88
|
-
/* v8 ignore else - parseInt validation */
|
|
89
|
-
if (!Number.isNaN(statusCode)) {
|
|
90
|
-
page.head.statusCode = statusCode;
|
|
91
|
-
debug(`oracle header "status" with value "${page.head.statusCode}" was parsed`);
|
|
92
|
-
const index = header.value.indexOf(' ');
|
|
93
|
-
/* v8 ignore else - status code may not have description */
|
|
94
|
-
if (index !== -1) {
|
|
95
|
-
page.head.statusDescription = header.value.substring(index + 1);
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
throw new Error(`Unable to parse header "status" with value "${header.value}" received from PL/SQL`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
break;
|
|
102
|
-
|
|
103
|
-
case 'location':
|
|
104
|
-
page.head.redirectLocation = header.value;
|
|
105
|
-
debug(`oracle header "location" with value "${page.head.statusCode}" was parsed`);
|
|
106
|
-
break;
|
|
107
|
-
|
|
108
|
-
case 'x-oracle-ignore':
|
|
109
|
-
break;
|
|
110
|
-
|
|
111
|
-
default:
|
|
112
|
-
page.head.otherHeaders[header.name] = header.value;
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
return page;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Get a header line
|
|
123
|
-
* @param {string} line - The line
|
|
124
|
-
* @returns {{name: string, value: string} | null} - The header.
|
|
125
|
-
*/
|
|
126
|
-
const getHeader = (line) => {
|
|
127
|
-
const index = line.indexOf(':');
|
|
128
|
-
|
|
129
|
-
if (index !== -1) {
|
|
130
|
-
return {
|
|
131
|
-
name: line.substring(0, index).trim(),
|
|
132
|
-
value: line.substring(index + 1).trim(),
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return null;
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Parses a cookie string
|
|
141
|
-
* @param {string} text - The cookie string.
|
|
142
|
-
* @returns {cookieType | null} - The parsed cookie.
|
|
143
|
-
*/
|
|
144
|
-
const parseCookie = (text) => {
|
|
145
|
-
// validate
|
|
146
|
-
/* v8 ignore next - input validation */
|
|
147
|
-
if (typeof text !== 'string' || text.trim().length === 0) {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// split the cookie into it's parts
|
|
152
|
-
let cookieElements = text.split(';');
|
|
153
|
-
|
|
154
|
-
// trim cookie elements
|
|
155
|
-
cookieElements = cookieElements.map((element) => element.trim());
|
|
156
|
-
|
|
157
|
-
// get name and value
|
|
158
|
-
const firstElement = cookieElements[0];
|
|
159
|
-
if (!firstElement) {
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
const index = firstElement.indexOf('=');
|
|
163
|
-
/* v8 ignore next - cookie format validation */
|
|
164
|
-
if (index <= 0) {
|
|
165
|
-
// if the index is -1, there is no equal sign and if it's 0 the name is empty
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** @type {cookieType} */
|
|
170
|
-
const cookie = {
|
|
171
|
-
name: firstElement.substring(0, index).trim(),
|
|
172
|
-
value: firstElement.substring(index + 1).trim(),
|
|
173
|
-
options: {},
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
// remove the first element
|
|
177
|
-
cookieElements.shift();
|
|
178
|
-
|
|
179
|
-
// get the other options
|
|
180
|
-
cookieElements.forEach((element) => {
|
|
181
|
-
if (element.startsWith('path=')) {
|
|
182
|
-
cookie.options.path = element.substring(5);
|
|
183
|
-
} else if (element.toLowerCase().startsWith('domain=')) {
|
|
184
|
-
cookie.options.domain = element.substring(7);
|
|
185
|
-
} else if (element.toLowerCase().startsWith('secure=')) {
|
|
186
|
-
/* v8 ignore next - secure cookie attribute */
|
|
187
|
-
cookie.options.secure = true;
|
|
188
|
-
} else if (element.toLowerCase().startsWith('expires=')) {
|
|
189
|
-
const date = tryDecodeDate(element.substring(8));
|
|
190
|
-
if (date) {
|
|
191
|
-
cookie.options.expires = date;
|
|
192
|
-
}
|
|
193
|
-
} else if (element.toLowerCase().startsWith('httponly')) {
|
|
194
|
-
cookie.options.httpOnly = true;
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
return cookie;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Try to decode a date
|
|
203
|
-
* @param {string} value - The value to decode.
|
|
204
|
-
* @returns {Date | null} - The decoded date or null.
|
|
205
|
-
*/
|
|
206
|
-
const tryDecodeDate = (value) => {
|
|
207
|
-
try {
|
|
208
|
-
return new Date(value);
|
|
209
|
-
} catch (err) {
|
|
210
|
-
/* v8 ignore next - invalid date format */
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
};
|