web_plsql 1.3.1 → 1.4.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 +90 -166
- package/dist/frontend/assets/{main-C8GKnEhz.js → main-C_esuqtI.js} +1 -1
- package/dist/frontend/assets/main-C_esuqtI.js.br +0 -0
- package/dist/frontend/assets/{main-C8GKnEhz.js.gz → main-C_esuqtI.js.gz} +0 -0
- package/dist/frontend/index.html +1 -1
- package/dist/frontend/index.html.br +0 -0
- package/dist/frontend/index.html.gz +0 -0
- package/dist/index.d.mts +22 -10
- package/dist/index.mjs +90 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -9
- package/dist/frontend/assets/main-C8GKnEhz.js.br +0 -0
package/dist/index.mjs
CHANGED
|
@@ -111,11 +111,14 @@ const transactionModeSchema = z$1.union([
|
|
|
111
111
|
/**
|
|
112
112
|
* Authentication configuration for a PL/SQL route
|
|
113
113
|
*/
|
|
114
|
-
const z$authSchema = z$1.strictObject({
|
|
114
|
+
const z$authSchema = z$1.union([z$1.strictObject({
|
|
115
115
|
type: z$1.literal("basic"),
|
|
116
116
|
callback: z$1.custom((val) => typeof val === "function", { message: "Invalid auth callback" }),
|
|
117
117
|
realm: z$1.string().optional()
|
|
118
|
-
})
|
|
118
|
+
}), z$1.strictObject({
|
|
119
|
+
type: z$1.literal("custom"),
|
|
120
|
+
callback: z$1.custom((val) => typeof val === "function", { message: "Invalid auth callback" })
|
|
121
|
+
})]);
|
|
119
122
|
/**
|
|
120
123
|
* PL/SQL handler behavior configuration
|
|
121
124
|
*/
|
|
@@ -211,7 +214,7 @@ globalThis.__VERSION__ ??= "**development**";
|
|
|
211
214
|
* Returns the current library version
|
|
212
215
|
* @returns {string} - Version.
|
|
213
216
|
*/
|
|
214
|
-
const getVersion = () => "1.
|
|
217
|
+
const getVersion = () => "1.4.0";
|
|
215
218
|
|
|
216
219
|
//#endregion
|
|
217
220
|
//#region src/backend/server/config.ts
|
|
@@ -2969,33 +2972,36 @@ const processRequest = async (req, res, options, connectionPool, procedureNameCa
|
|
|
2969
2972
|
debug$2("processRequest: ENTER");
|
|
2970
2973
|
if (typeof req.params.name !== "string") console.warn(`processRequest: WARNING: the req.params.name is not a string but an array of string: ${req.params.name}`);
|
|
2971
2974
|
const connection = await connectionPool.getConnection();
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
aggregator
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2975
|
+
try {
|
|
2976
|
+
const cgiObj = getCGI(req, options.documentTable, options.cgi ?? {}, authenticatedUser);
|
|
2977
|
+
debug$2("processRequest: cgiObj=", cgiObj);
|
|
2978
|
+
const filesToUpload = getFiles(req);
|
|
2979
|
+
debug$2("processRequest: filesToUpload=", filesToUpload);
|
|
2980
|
+
const argObj = {};
|
|
2981
|
+
Object.assign(argObj, req.query);
|
|
2982
|
+
filesToUpload.reduce((aggregator, file) => {
|
|
2983
|
+
aggregator[file.fieldname] = file.filename;
|
|
2984
|
+
return aggregator;
|
|
2985
|
+
}, argObj);
|
|
2986
|
+
Object.assign(argObj, normalizeBody(req));
|
|
2987
|
+
debug$2("processRequest: argObj=", argObj);
|
|
2988
|
+
await invokeProcedure(req, res, argObj, cgiObj, filesToUpload, options, connection, procedureNameCache, argumentCache);
|
|
2989
|
+
if (options.transactionMode === "rollback") {
|
|
2990
|
+
debug$2("transactionMode: rollback");
|
|
2991
|
+
await connection.rollback();
|
|
2992
|
+
} else if (typeof options.transactionMode === "function") {
|
|
2993
|
+
debug$2("transactionMode: callback");
|
|
2994
|
+
const procName = Array.isArray(req.params.name) ? req.params.name[0] : req.params.name;
|
|
2995
|
+
const result = options.transactionMode(connection, procName ?? "");
|
|
2996
|
+
debug$2("transactionMode: callback restult", result);
|
|
2997
|
+
if (result && typeof result.then === "function") await result;
|
|
2998
|
+
} else {
|
|
2999
|
+
debug$2("transactionMode: commit");
|
|
3000
|
+
await connection.commit();
|
|
3001
|
+
}
|
|
3002
|
+
} finally {
|
|
3003
|
+
await connection.release();
|
|
3004
|
+
}
|
|
2999
3005
|
debug$2("processRequest: EXIT");
|
|
3000
3006
|
};
|
|
3001
3007
|
|
|
@@ -3099,6 +3105,10 @@ const errorPage = (req, res, options, error) => {
|
|
|
3099
3105
|
}
|
|
3100
3106
|
});
|
|
3101
3107
|
console.error(text);
|
|
3108
|
+
if (res.headersSent) {
|
|
3109
|
+
console.warn("errorPage: Response headers already sent. Cannot show error page.");
|
|
3110
|
+
return;
|
|
3111
|
+
}
|
|
3102
3112
|
if (options.errorStyle === "basic") res.status(404).send("Page not found");
|
|
3103
3113
|
else res.status(404).send(getHtmlPage(html));
|
|
3104
3114
|
};
|
|
@@ -3122,16 +3132,22 @@ const requestHandler = async (req, res, _next, connectionPool, options, procedur
|
|
|
3122
3132
|
if (options.auth?.type === "basic") {
|
|
3123
3133
|
const b64auth = (req.headers.authorization ?? "").split(" ")[1] ?? "";
|
|
3124
3134
|
const [login, password] = Buffer.from(b64auth, "base64").toString().split(":");
|
|
3125
|
-
if (login) authenticatedUser = await options.auth.callback(
|
|
3135
|
+
if (login) authenticatedUser = await options.auth.callback({
|
|
3126
3136
|
username: login,
|
|
3127
3137
|
password
|
|
3128
|
-
});
|
|
3138
|
+
}, connectionPool);
|
|
3129
3139
|
if (authenticatedUser === null) {
|
|
3130
3140
|
const realm = options.auth.realm ?? "PL/SQL Gateway";
|
|
3131
3141
|
res.set("WWW-Authenticate", `Basic realm="${realm}"`);
|
|
3132
3142
|
res.status(401).send("Authentication required.");
|
|
3133
3143
|
return;
|
|
3134
3144
|
}
|
|
3145
|
+
} else if (options.auth?.type === "custom") {
|
|
3146
|
+
authenticatedUser = await options.auth.callback(req, connectionPool);
|
|
3147
|
+
if (authenticatedUser === null) {
|
|
3148
|
+
res.status(401).send("Authentication required.");
|
|
3149
|
+
return;
|
|
3150
|
+
}
|
|
3135
3151
|
}
|
|
3136
3152
|
if (typeof req.params.name !== "string" || req.params.name.length === 0) if (typeof options.defaultPage === "string" && options.defaultPage.length > 0) {
|
|
3137
3153
|
const newUrl = url.resolve(`${req.originalUrl}/${options.defaultPage}`, "");
|
|
@@ -3237,8 +3253,8 @@ const createAdminRouter = (adminContext) => {
|
|
|
3237
3253
|
const name = cache?.poolName ?? `pool-${index}`;
|
|
3238
3254
|
const p = pool;
|
|
3239
3255
|
const stats = typeof p.getStatistics === "function" ? p.getStatistics() : null;
|
|
3240
|
-
const procStats = cache?.procedureNameCache
|
|
3241
|
-
const argStats = cache?.argumentCache
|
|
3256
|
+
const procStats = cache?.procedureNameCache?.getStats();
|
|
3257
|
+
const argStats = cache?.argumentCache?.getStats();
|
|
3242
3258
|
return {
|
|
3243
3259
|
name,
|
|
3244
3260
|
stats,
|
|
@@ -3246,12 +3262,12 @@ const createAdminRouter = (adminContext) => {
|
|
|
3246
3262
|
connectionsInUse: pool.connectionsInUse,
|
|
3247
3263
|
cache: {
|
|
3248
3264
|
procedureName: {
|
|
3249
|
-
size: cache?.procedureNameCache
|
|
3265
|
+
size: cache?.procedureNameCache?.keys().length ?? 0,
|
|
3250
3266
|
hits: procStats?.hits ?? 0,
|
|
3251
3267
|
misses: procStats?.misses ?? 0
|
|
3252
3268
|
},
|
|
3253
3269
|
argument: {
|
|
3254
|
-
size: cache?.argumentCache
|
|
3270
|
+
size: cache?.argumentCache?.keys().length ?? 0,
|
|
3255
3271
|
hits: argStats?.hits ?? 0,
|
|
3256
3272
|
misses: argStats?.misses ?? 0
|
|
3257
3273
|
}
|
|
@@ -3458,32 +3474,45 @@ const handlerAdminConsole = (config, adminContext) => {
|
|
|
3458
3474
|
const resolvedStaticDir = config.staticDir ?? resolveAdminStaticDir();
|
|
3459
3475
|
if (adminRoute && !adminRoute.startsWith("/")) throw new Error("adminRoute must start with /");
|
|
3460
3476
|
if (!config.devMode && !existsSync(resolvedStaticDir)) throw new Error(`Admin console not built. Run 'npm run build:frontend' first.\nExpected: ${resolvedStaticDir}`);
|
|
3461
|
-
const
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
const
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3477
|
+
const statsManager = adminContext.statsManager;
|
|
3478
|
+
const currentRotate = statsManager.rotateBucket;
|
|
3479
|
+
if (!Object.prototype.hasOwnProperty.call(currentRotate, "_isWrapped")) {
|
|
3480
|
+
const originalRotate = statsManager.rotateBucket;
|
|
3481
|
+
const wrappedRotate = (poolSnapshots = []) => {
|
|
3482
|
+
const mergedSnapshots = [...adminContext.pools.map((pool, index) => {
|
|
3483
|
+
const cache = adminContext.caches[index];
|
|
3484
|
+
const name = cache?.poolName ?? `pool-${index}`;
|
|
3485
|
+
const procStats = cache?.procedureNameCache?.getStats();
|
|
3486
|
+
const argStats = cache?.argumentCache?.getStats();
|
|
3487
|
+
return {
|
|
3488
|
+
name,
|
|
3489
|
+
connectionsOpen: pool.connectionsOpen,
|
|
3490
|
+
connectionsInUse: pool.connectionsInUse,
|
|
3491
|
+
cache: {
|
|
3492
|
+
procedureName: {
|
|
3493
|
+
size: cache?.procedureNameCache?.keys().length ?? 0,
|
|
3494
|
+
hits: procStats?.hits ?? 0,
|
|
3495
|
+
misses: procStats?.misses ?? 0
|
|
3496
|
+
},
|
|
3497
|
+
argument: {
|
|
3498
|
+
size: cache?.argumentCache?.keys().length ?? 0,
|
|
3499
|
+
hits: argStats?.hits ?? 0,
|
|
3500
|
+
misses: argStats?.misses ?? 0
|
|
3501
|
+
}
|
|
3482
3502
|
}
|
|
3483
|
-
}
|
|
3484
|
-
};
|
|
3485
|
-
|
|
3486
|
-
|
|
3503
|
+
};
|
|
3504
|
+
})];
|
|
3505
|
+
if (Array.isArray(poolSnapshots)) {
|
|
3506
|
+
for (const ps of poolSnapshots) if (!mergedSnapshots.some((s) => s.name === ps.name)) mergedSnapshots.push(ps);
|
|
3507
|
+
}
|
|
3508
|
+
originalRotate.call(statsManager, mergedSnapshots);
|
|
3509
|
+
};
|
|
3510
|
+
Object.defineProperty(wrappedRotate, "_isWrapped", {
|
|
3511
|
+
value: true,
|
|
3512
|
+
writable: false
|
|
3513
|
+
});
|
|
3514
|
+
statsManager.rotateBucket = wrappedRotate;
|
|
3515
|
+
}
|
|
3487
3516
|
const router = Router();
|
|
3488
3517
|
router.use((req, res, next) => {
|
|
3489
3518
|
if (adminContext.paused && !req.path.startsWith(adminRoute)) {
|