web_plsql 1.7.1 → 1.8.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.
- package/dist/frontend/assets/main-soziFoIv.js +147 -0
- package/dist/frontend/assets/main-soziFoIv.js.br +0 -0
- package/dist/frontend/assets/main-soziFoIv.js.gz +0 -0
- package/dist/frontend/index.html +5 -12
- package/dist/frontend/index.html.br +0 -0
- package/dist/frontend/index.html.gz +0 -0
- package/dist/index.d.mts +21 -7
- package/dist/index.mjs +239 -76
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -10
- package/dist/frontend/assets/main-C1Ryd_4B.js +0 -147
- package/dist/frontend/assets/main-C1Ryd_4B.js.br +0 -0
- package/dist/frontend/assets/main-C1Ryd_4B.js.gz +0 -0
|
Binary file
|
|
Binary file
|
package/dist/frontend/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>web_plsql Admin Console</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="/admin/assets/favicon-mQAM4tVu.svg" />
|
|
8
8
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
|
9
|
-
<script type="module" crossorigin src="/admin/assets/main-
|
|
9
|
+
<script type="module" crossorigin src="/admin/assets/main-soziFoIv.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/admin/assets/main-CoERzZAr.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body class="dark">
|
|
@@ -128,8 +128,7 @@
|
|
|
128
128
|
</div>
|
|
129
129
|
<p id="cache-hit-rate-val" title="Percentage of requests served from cache">0%</p>
|
|
130
130
|
<small
|
|
131
|
-
><span id="cache-hits-val" title="Total cache hits">0</span> hits,
|
|
132
|
-
<span id="cache-misses-val" title="Total cache misses">0</span> misses</small
|
|
131
|
+
><span id="cache-hits-val" title="Total cache hits">0</span> hits, <span id="cache-misses-val" title="Total cache misses">0</span> misses</small
|
|
133
132
|
>
|
|
134
133
|
</div>
|
|
135
134
|
</div>
|
|
@@ -184,9 +183,7 @@
|
|
|
184
183
|
<section id="view-errors" class="view" style="display: none">
|
|
185
184
|
<div class="header-toolbar mb-4" style="justify-content: flex-start; gap: 12px">
|
|
186
185
|
<div class="search-group" style="flex: 1; max-width: 400px">
|
|
187
|
-
<span
|
|
188
|
-
class="material-symbols-rounded"
|
|
189
|
-
style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5"
|
|
186
|
+
<span class="material-symbols-rounded" style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5"
|
|
190
187
|
>search</span
|
|
191
188
|
>
|
|
192
189
|
<input
|
|
@@ -217,9 +214,7 @@
|
|
|
217
214
|
<section id="view-trace" class="view" style="display: none">
|
|
218
215
|
<div class="header-toolbar mb-4" style="justify-content: flex-start; gap: 12px">
|
|
219
216
|
<div class="search-group" style="flex: 1; max-width: 300px">
|
|
220
|
-
<span
|
|
221
|
-
class="material-symbols-rounded"
|
|
222
|
-
style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5"
|
|
217
|
+
<span class="material-symbols-rounded" style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5"
|
|
223
218
|
>search</span
|
|
224
219
|
>
|
|
225
220
|
<input type="text" id="trace-filter" placeholder="Filter traces..." class="input-sm" style="width: 100%; padding-left: 32px" />
|
|
@@ -254,9 +249,7 @@
|
|
|
254
249
|
<section id="view-access" class="view" style="display: none">
|
|
255
250
|
<div class="header-toolbar mb-4" style="justify-content: flex-start; gap: 12px">
|
|
256
251
|
<div class="search-group" style="flex: 1; max-width: 400px">
|
|
257
|
-
<span
|
|
258
|
-
class="material-symbols-rounded"
|
|
259
|
-
style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5"
|
|
252
|
+
<span class="material-symbols-rounded" style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5"
|
|
260
253
|
>search</span
|
|
261
254
|
>
|
|
262
255
|
<input type="text" id="access-filter" placeholder="Filter logs..." class="input-sm" style="width: 100%; padding-left: 32px" />
|
|
Binary file
|
|
Binary file
|
package/dist/index.d.mts
CHANGED
|
@@ -179,8 +179,14 @@ declare const z$configType: z$1.ZodObject<{
|
|
|
179
179
|
adminPassword: z$1.ZodOptional<z$1.ZodString>; /** Developer mode (skips frontend build check, enables CORS) */
|
|
180
180
|
devMode: z$1.ZodOptional<z$1.ZodBoolean>; /** Callback function to setup custom Express extensions */
|
|
181
181
|
setupExtensions: z$1.ZodOptional<z$1.ZodCustom<(app: Express, pools: Pool[]) => void | Promise<void>, (app: Express, pools: Pool[]) => void | Promise<void>>>;
|
|
182
|
+
oracle: z$1.ZodDefault<z$1.ZodOptional<z$1.ZodObject<{
|
|
183
|
+
poolMin: z$1.ZodDefault<z$1.ZodInt>;
|
|
184
|
+
poolMax: z$1.ZodDefault<z$1.ZodInt>;
|
|
185
|
+
poolIncrement: z$1.ZodDefault<z$1.ZodInt>;
|
|
186
|
+
}, z$1.core.$strict>>>;
|
|
182
187
|
}, z$1.core.$strict>;
|
|
183
|
-
type
|
|
188
|
+
type configInputType = z$1.input<typeof z$configType>;
|
|
189
|
+
type configType = z$1.output<typeof z$configType>;
|
|
184
190
|
/**
|
|
185
191
|
* Mapping of PL/SQL procedure argument names to their database types
|
|
186
192
|
*/
|
|
@@ -297,12 +303,12 @@ declare global {
|
|
|
297
303
|
*/
|
|
298
304
|
declare const getVersion: () => string;
|
|
299
305
|
//#endregion
|
|
300
|
-
//#region src/backend/server/
|
|
306
|
+
//#region src/backend/server/printBanner.d.ts
|
|
301
307
|
/**
|
|
302
|
-
*
|
|
303
|
-
* @param
|
|
308
|
+
* Renders the server startup banner to stdout.
|
|
309
|
+
* @param cfg - Server configuration.
|
|
304
310
|
*/
|
|
305
|
-
declare const
|
|
311
|
+
declare const printBanner: (cfg: configType) => void;
|
|
306
312
|
//#endregion
|
|
307
313
|
//#region src/backend/server/server.d.ts
|
|
308
314
|
type webServer = {
|
|
@@ -330,7 +336,7 @@ declare const createServer: (app: Express, ssl?: sslConfig) => http.Server | htt
|
|
|
330
336
|
* @param ssl - ssl configuration.
|
|
331
337
|
* @returns Promise resolving to the web server object.
|
|
332
338
|
*/
|
|
333
|
-
declare const startServer: (config:
|
|
339
|
+
declare const startServer: (config: configInputType, ssl?: sslConfig) => Promise<webServer>;
|
|
334
340
|
/**
|
|
335
341
|
* Load configuration.
|
|
336
342
|
* @param filename - The configuration filename.
|
|
@@ -614,6 +620,14 @@ declare const handlerAdminConsole: (config: AdminConsoleConfig, adminContext: Ad
|
|
|
614
620
|
*/
|
|
615
621
|
declare const createSpaFallback: (directoryPath: string, _route: string) => RequestHandler;
|
|
616
622
|
//#endregion
|
|
623
|
+
//#region src/backend/util/logError.d.ts
|
|
624
|
+
/**
|
|
625
|
+
* Log an error.
|
|
626
|
+
*
|
|
627
|
+
* @param error - The error.
|
|
628
|
+
*/
|
|
629
|
+
declare const logError: (error: unknown) => void;
|
|
630
|
+
//#endregion
|
|
617
631
|
//#region src/backend/util/file.d.ts
|
|
618
632
|
/**
|
|
619
633
|
* Read file.
|
|
@@ -655,5 +669,5 @@ declare const isDirectory: (directoryPath: unknown) => Promise<boolean>;
|
|
|
655
669
|
*/
|
|
656
670
|
declare const isFile: (filePath: unknown) => Promise<boolean>;
|
|
657
671
|
//#endregion
|
|
658
|
-
export { type AdminConsoleConfig, AdminContext, type configPlSqlType, type configType, createAdminRouter, createServer, createSpaFallback, forceShutdown, getJsonFile, getVersion, handlerAdminConsole, handlerLogger, handlerUpload, handlerWebPlSql, installShutdown, isDirectory, isFile, loadConfig, oracledb_provider_d_exports as oracledb, readFile, readFileSyncUtf8, removeFile,
|
|
672
|
+
export { type AdminConsoleConfig, AdminContext, type configInputType, type configPlSqlType, type configType, createAdminRouter, createServer, createSpaFallback, forceShutdown, getJsonFile, getVersion, handlerAdminConsole, handlerLogger, handlerUpload, handlerWebPlSql, installShutdown, isDirectory, isFile, loadConfig, logError, oracledb_provider_d_exports as oracledb, printBanner, readFile, readFileSyncUtf8, removeFile, startServer, startServerConfig, z$configType };
|
|
659
673
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -2,6 +2,9 @@ import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
|
|
|
2
2
|
import { n as setExecuteCallback } from "./oracledb-mock-Cya43xKB.mjs";
|
|
3
3
|
import z$1, { z } from "zod";
|
|
4
4
|
import oracledb from "oracledb";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import stringWidth from "string-width";
|
|
7
|
+
import sliceAnsi from "slice-ansi";
|
|
5
8
|
import debugModule from "debug";
|
|
6
9
|
import http from "node:http";
|
|
7
10
|
import https from "node:https";
|
|
@@ -16,10 +19,11 @@ import stream, { Readable } from "node:stream";
|
|
|
16
19
|
import fs, { existsSync, promises, readFileSync } from "node:fs";
|
|
17
20
|
import * as rotatingFileStream from "rotating-file-stream";
|
|
18
21
|
import path from "node:path";
|
|
19
|
-
import { URL as URL$1
|
|
22
|
+
import { URL as URL$1 } from "node:url";
|
|
20
23
|
import morgan from "morgan";
|
|
21
24
|
import multer from "multer";
|
|
22
25
|
import readline from "node:readline";
|
|
26
|
+
import process$1 from "node:process";
|
|
23
27
|
//#region src/common/configStaticSchema.ts
|
|
24
28
|
/**
|
|
25
29
|
* Configuration for serving static files
|
|
@@ -156,7 +160,16 @@ const z$configType = z$1.strictObject({
|
|
|
156
160
|
adminUser: z$1.string().optional(),
|
|
157
161
|
adminPassword: z$1.string().optional(),
|
|
158
162
|
devMode: z$1.boolean().optional(),
|
|
159
|
-
setupExtensions: z$1.custom((val) => typeof val === "function", { message: "Invalid setupExtensions callback" }).optional()
|
|
163
|
+
setupExtensions: z$1.custom((val) => typeof val === "function", { message: "Invalid setupExtensions callback" }).optional(),
|
|
164
|
+
oracle: z$1.strictObject({
|
|
165
|
+
poolMin: z$1.int().min(10).default(10),
|
|
166
|
+
poolMax: z$1.int().min(10).default(100),
|
|
167
|
+
poolIncrement: z$1.int().min(1).default(10)
|
|
168
|
+
}).optional().default({
|
|
169
|
+
poolMin: 10,
|
|
170
|
+
poolMax: 100,
|
|
171
|
+
poolIncrement: 10
|
|
172
|
+
})
|
|
160
173
|
});
|
|
161
174
|
//#endregion
|
|
162
175
|
//#region src/backend/util/oracledb-provider.ts
|
|
@@ -209,58 +222,109 @@ globalThis.__VERSION__ ??= "**development**";
|
|
|
209
222
|
* Returns the current library version
|
|
210
223
|
* @returns {string} - Version.
|
|
211
224
|
*/
|
|
212
|
-
const getVersion = () => "1.
|
|
225
|
+
const getVersion = () => "1.8.1";
|
|
213
226
|
//#endregion
|
|
214
|
-
//#region src/backend/server/
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
227
|
+
//#region src/backend/server/printBanner.ts
|
|
228
|
+
const IS_TTY = process.stdout.isTTY === true;
|
|
229
|
+
const ICON_GLOBE = "🌐";
|
|
230
|
+
const ICON_KEY = "🔑";
|
|
231
|
+
const ICON_DOC = "📄";
|
|
232
|
+
const ICON_PACKAGE = "📦";
|
|
233
|
+
const ICON_LINK = "🔗";
|
|
234
|
+
const ICON_FOLDER = "📁";
|
|
235
|
+
const ICON_GEAR = "🔧";
|
|
236
|
+
const ICON_HOME = "🏠";
|
|
237
|
+
const W = 80;
|
|
238
|
+
const LABEL_W = 35;
|
|
239
|
+
const VALUE_W = W - LABEL_W - 5;
|
|
240
|
+
const BOX = {
|
|
241
|
+
h: "─",
|
|
242
|
+
v: "│",
|
|
243
|
+
tl: "╭",
|
|
244
|
+
tr: "╮",
|
|
245
|
+
bl: "╰",
|
|
246
|
+
br: "╯",
|
|
247
|
+
ml: "├",
|
|
248
|
+
mr: "┤"
|
|
249
|
+
};
|
|
250
|
+
const displayWidth = (s) => stringWidth(s, { ambiguousIsNarrow: true });
|
|
251
|
+
const padTo = (s, w) => {
|
|
252
|
+
const delta = w - displayWidth(s);
|
|
253
|
+
return delta > 0 ? s + " ".repeat(delta) : s;
|
|
254
|
+
};
|
|
255
|
+
const truncateTo = (s, w) => w > 0 ? sliceAnsi(s, 0, w) : "";
|
|
256
|
+
const divider = () => IS_TTY ? chalk.dim(BOX.ml + BOX.h.repeat(W - 2) + BOX.mr) : "-".repeat(W);
|
|
257
|
+
const borderOpen = () => IS_TTY ? chalk.dim(BOX.tl + BOX.h.repeat(W - 2) + BOX.tr) : divider();
|
|
258
|
+
const borderClose = () => IS_TTY ? chalk.dim(BOX.bl + BOX.h.repeat(W - 2) + BOX.br) : divider();
|
|
259
|
+
/**
|
|
260
|
+
* Single key/value row.
|
|
261
|
+
* @param key - Label text.
|
|
262
|
+
* @param value - Display value; null/undefined/empty renders as a dim dash.
|
|
263
|
+
* @param icon - Optional leading icon (must be a single-cell or double-cell glyph).
|
|
264
|
+
* @returns Formatted string.
|
|
265
|
+
*/
|
|
266
|
+
const row = (key, value, icon) => {
|
|
267
|
+
const label = padTo(IS_TTY ? icon ? `${icon} ${key}` : ` ${key}` : `${key}`, LABEL_W);
|
|
268
|
+
const hasValue = value !== null && value !== void 0 && value !== "";
|
|
269
|
+
const valueText = hasValue ? String(value) : "—";
|
|
270
|
+
const colorFn = hasValue ? chalk.white : chalk.dim;
|
|
271
|
+
const valueCell = padTo(truncateTo(valueText, VALUE_W), VALUE_W);
|
|
272
|
+
return IS_TTY ? chalk.dim(BOX.v) + " " + chalk.dim(label) + " " + colorFn(valueCell) + " " + chalk.dim(BOX.v) : label + " " + valueCell;
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* Renders the server startup banner to stdout.
|
|
276
|
+
* @param cfg - Server configuration.
|
|
277
|
+
*/
|
|
278
|
+
const printBanner = (cfg) => {
|
|
279
|
+
const adminRoute = cfg.adminRoute ?? "/admin";
|
|
280
|
+
const baseUrl = `http://localhost:${cfg.port}`;
|
|
281
|
+
const lines = [];
|
|
282
|
+
lines.push(borderOpen());
|
|
283
|
+
const title = `NODE PL/SQL SERVER ${getVersion()}`;
|
|
284
|
+
const pad = W - 2 - displayWidth(title);
|
|
285
|
+
lines.push(IS_TTY ? chalk.dim(BOX.v) + " ".repeat(Math.floor(pad / 2)) + chalk.bold.cyan(title) + " ".repeat(Math.ceil(pad / 2)) + chalk.dim(BOX.v) : title);
|
|
286
|
+
lines.push(divider());
|
|
287
|
+
lines.push(row("Port", cfg.port, ICON_GLOBE));
|
|
288
|
+
lines.push(row("Admin route", `${adminRoute}${cfg.adminUser ? " (authenticated)" : ""}`, ICON_KEY));
|
|
289
|
+
lines.push(row("Access log", cfg.loggerFilename, ICON_DOC));
|
|
290
|
+
lines.push(row("Upload limit", typeof cfg.uploadFileSizeLimit === "number" ? `${cfg.uploadFileSizeLimit} bytes` : null, ICON_PACKAGE));
|
|
291
|
+
lines.push(divider());
|
|
292
|
+
lines.push(row("Oracle pool min", cfg.oracle.poolMin, ICON_LINK));
|
|
293
|
+
lines.push(row("Oracle pool max", cfg.oracle.poolMax, ICON_LINK));
|
|
294
|
+
lines.push(row("Oracle pool increment", cfg.oracle.poolIncrement, ICON_LINK));
|
|
295
|
+
if (cfg.routeStatic.length > 0) {
|
|
296
|
+
lines.push(divider());
|
|
297
|
+
cfg.routeStatic.forEach((r, i) => {
|
|
298
|
+
lines.push(row(`Static route #${i + 1} route`, r.route, ICON_FOLDER));
|
|
299
|
+
lines.push(row(`Static route #${i + 1} path`, r.directoryPath));
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
if (cfg.routePlSql.length > 0) {
|
|
303
|
+
lines.push(divider());
|
|
304
|
+
cfg.routePlSql.forEach((r, i) => {
|
|
305
|
+
const txMode = typeof r.transactionMode === "string" ? r.transactionMode : r.transactionMode ? "custom" : "";
|
|
306
|
+
const n = `PL/SQL route #${i + 1}`;
|
|
307
|
+
lines.push(row(`${n} route`, r.route, ICON_GEAR));
|
|
308
|
+
lines.push(row(`${n} Oracle user`, r.user));
|
|
309
|
+
lines.push(row(`${n} Oracle server`, r.connectString));
|
|
310
|
+
lines.push(row(`${n} document table`, r.documentTable));
|
|
311
|
+
lines.push(row(`${n} default page`, r.defaultPage));
|
|
312
|
+
lines.push(row(`${n} path alias`, r.pathAlias ?? ""));
|
|
313
|
+
lines.push(row(`${n} path alias proc`, r.pathAliasProcedure ?? ""));
|
|
314
|
+
lines.push(row(`${n} exclusion list`, r.exclusionList?.join(", ") ?? ""));
|
|
315
|
+
lines.push(row(`${n} validation fn`, r.requestValidationFunction ?? ""));
|
|
316
|
+
lines.push(row(`${n} session mode`, txMode));
|
|
317
|
+
lines.push(row(`${n} auth`, typeof r.auth === "string" ? r.auth : ""));
|
|
318
|
+
lines.push(row(`${n} error style`, r.errorStyle));
|
|
261
319
|
});
|
|
262
320
|
}
|
|
263
|
-
|
|
321
|
+
lines.push(divider());
|
|
322
|
+
lines.push(row("Admin console", `${baseUrl}${adminRoute}`, ICON_HOME));
|
|
323
|
+
cfg.routePlSql.forEach((r) => {
|
|
324
|
+
lines.push(row(r.route, `${baseUrl}${r.route}`, ICON_GEAR));
|
|
325
|
+
});
|
|
326
|
+
lines.push(borderClose());
|
|
327
|
+
console.log(lines.join("\n"));
|
|
264
328
|
};
|
|
265
329
|
//#endregion
|
|
266
330
|
//#region src/backend/server/server.ts
|
|
@@ -297,7 +361,7 @@ const createServer = (app, ssl) => {
|
|
|
297
361
|
const startServer = async (config, ssl) => {
|
|
298
362
|
debug$14("startServer: BEGIN", config, ssl);
|
|
299
363
|
const internalConfig = z$configType.parse(config);
|
|
300
|
-
|
|
364
|
+
printBanner(internalConfig);
|
|
301
365
|
const app = express();
|
|
302
366
|
if (internalConfig.devMode) app.use(cors({
|
|
303
367
|
origin: "http://localhost:5173",
|
|
@@ -322,7 +386,10 @@ const startServer = async (config, ssl) => {
|
|
|
322
386
|
const handler = handlerWebPlSql(await createPool({
|
|
323
387
|
user: i.user,
|
|
324
388
|
password: i.password,
|
|
325
|
-
connectString: i.connectString
|
|
389
|
+
connectString: i.connectString,
|
|
390
|
+
poolMin: internalConfig.oracle.poolMin,
|
|
391
|
+
poolMax: internalConfig.oracle.poolMax,
|
|
392
|
+
poolIncrement: internalConfig.oracle.poolIncrement
|
|
326
393
|
}), i, adminContext);
|
|
327
394
|
app.use([`${i.route}/:name`, i.route], (req, res, next) => {
|
|
328
395
|
const start = process.hrtime();
|
|
@@ -1819,6 +1886,68 @@ const tryDecodeDate = (value) => {
|
|
|
1819
1886
|
//#region src/backend/handler/plsql/sendResponse.ts
|
|
1820
1887
|
const debug$7 = debugModule("webplsql:sendResponse");
|
|
1821
1888
|
/**
|
|
1889
|
+
* Pipe a readable to the response and await completion.
|
|
1890
|
+
* Listeners are attached before piping to avoid races.
|
|
1891
|
+
*
|
|
1892
|
+
* @param readable - The source readable stream.
|
|
1893
|
+
* @param res - The HTTP response stream.
|
|
1894
|
+
*/
|
|
1895
|
+
const pipeReadableToResponse = async (readable, res) => {
|
|
1896
|
+
await new Promise((resolve, reject) => {
|
|
1897
|
+
let settled = false;
|
|
1898
|
+
const canAddResponseListener = typeof res.on === "function";
|
|
1899
|
+
const canRemoveResponseListener = typeof res.removeListener === "function";
|
|
1900
|
+
const cleanup = () => {
|
|
1901
|
+
readable.removeListener("end", onReadableEnd);
|
|
1902
|
+
readable.removeListener("close", onReadableClose);
|
|
1903
|
+
readable.removeListener("error", onReadableError);
|
|
1904
|
+
if (canRemoveResponseListener) {
|
|
1905
|
+
res.removeListener("finish", onResponseFinish);
|
|
1906
|
+
res.removeListener("close", onResponseClose);
|
|
1907
|
+
}
|
|
1908
|
+
};
|
|
1909
|
+
const resolveOnce = () => {
|
|
1910
|
+
if (settled) return;
|
|
1911
|
+
settled = true;
|
|
1912
|
+
cleanup();
|
|
1913
|
+
resolve();
|
|
1914
|
+
};
|
|
1915
|
+
const rejectOnce = (error) => {
|
|
1916
|
+
if (settled) return;
|
|
1917
|
+
settled = true;
|
|
1918
|
+
cleanup();
|
|
1919
|
+
reject(error);
|
|
1920
|
+
};
|
|
1921
|
+
const onReadableEnd = () => {
|
|
1922
|
+
resolveOnce();
|
|
1923
|
+
};
|
|
1924
|
+
const onReadableClose = () => {
|
|
1925
|
+
resolveOnce();
|
|
1926
|
+
};
|
|
1927
|
+
const onReadableError = (error) => {
|
|
1928
|
+
rejectOnce(error);
|
|
1929
|
+
};
|
|
1930
|
+
const onResponseFinish = () => {
|
|
1931
|
+
resolveOnce();
|
|
1932
|
+
};
|
|
1933
|
+
const onResponseClose = () => {
|
|
1934
|
+
resolveOnce();
|
|
1935
|
+
};
|
|
1936
|
+
readable.on("end", onReadableEnd);
|
|
1937
|
+
readable.on("close", onReadableClose);
|
|
1938
|
+
readable.on("error", onReadableError);
|
|
1939
|
+
if (canAddResponseListener) {
|
|
1940
|
+
res.on("finish", onResponseFinish);
|
|
1941
|
+
res.on("close", onResponseClose);
|
|
1942
|
+
}
|
|
1943
|
+
try {
|
|
1944
|
+
readable.pipe(res);
|
|
1945
|
+
} catch (error) {
|
|
1946
|
+
rejectOnce(error instanceof Error ? error : new Error(String(error)));
|
|
1947
|
+
}
|
|
1948
|
+
});
|
|
1949
|
+
};
|
|
1950
|
+
/**
|
|
1822
1951
|
* Send "default" response to the browser
|
|
1823
1952
|
* @param _req - The req object represents the HTTP request.
|
|
1824
1953
|
* @param res - The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
|
|
@@ -1864,16 +1993,8 @@ const sendResponse = async (_req, res, page) => {
|
|
|
1864
1993
|
debugText.push(`res.pipe("${page.file.fileType ?? ""}") - streaming`);
|
|
1865
1994
|
debug$7(getBlock("RESPONSE", debugText.join("\n")));
|
|
1866
1995
|
}
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
page.file.fileBlob.pipe(res);
|
|
1870
|
-
page.file.fileBlob.on("end", () => resolve());
|
|
1871
|
-
/* v8 ignore next - error handler */
|
|
1872
|
-
page.file.fileBlob.on("error", (err) => reject(err));
|
|
1873
|
-
/* v8 ignore next - error handler */
|
|
1874
|
-
res.on("close", () => resolve());
|
|
1875
|
-
}
|
|
1876
|
-
});
|
|
1996
|
+
/* v8 ignore stop */
|
|
1997
|
+
await pipeReadableToResponse(page.file.fileBlob, res);
|
|
1877
1998
|
} else {
|
|
1878
1999
|
/* v8 ignore start */
|
|
1879
2000
|
if (debug$7.enabled) {
|
|
@@ -1908,16 +2029,7 @@ const sendResponse = async (_req, res, page) => {
|
|
|
1908
2029
|
debug$7(getBlock("RESPONSE", debugText.join("\n")));
|
|
1909
2030
|
}
|
|
1910
2031
|
/* v8 ignore stop */
|
|
1911
|
-
if (page.body instanceof stream.Readable) await
|
|
1912
|
-
if (page.body instanceof stream.Readable) {
|
|
1913
|
-
page.body.pipe(res);
|
|
1914
|
-
page.body.on("end", () => resolve());
|
|
1915
|
-
/* v8 ignore next - error handler */
|
|
1916
|
-
page.body.on("error", (err) => reject(err));
|
|
1917
|
-
/* v8 ignore next - error handler */
|
|
1918
|
-
res.on("close", () => resolve());
|
|
1919
|
-
}
|
|
1920
|
-
});
|
|
2032
|
+
if (page.body instanceof stream.Readable) await pipeReadableToResponse(page.body, res);
|
|
1921
2033
|
else res.send(page.body);
|
|
1922
2034
|
};
|
|
1923
2035
|
//#endregion
|
|
@@ -3302,8 +3414,7 @@ const createAdminRouter = (adminContext) => {
|
|
|
3302
3414
|
* @throws {Error} if project root cannot be found
|
|
3303
3415
|
*/
|
|
3304
3416
|
const resolveAdminStaticDir = () => {
|
|
3305
|
-
|
|
3306
|
-
let projectRoot = path.dirname(__filename);
|
|
3417
|
+
let projectRoot = import.meta.dirname;
|
|
3307
3418
|
while (!existsSync(path.join(projectRoot, "package.json")) && projectRoot !== "/") projectRoot = path.dirname(projectRoot);
|
|
3308
3419
|
if (projectRoot === "/") throw new Error("Could not find project root (package.json). Please provide explicit staticDir in AdminConsoleConfig.");
|
|
3309
3420
|
return path.join(projectRoot, "dist", "frontend");
|
|
@@ -3427,6 +3538,58 @@ const createSpaFallback = (directoryPath, _route) => {
|
|
|
3427
3538
|
};
|
|
3428
3539
|
};
|
|
3429
3540
|
//#endregion
|
|
3430
|
-
|
|
3541
|
+
//#region src/backend/util/printError.ts
|
|
3542
|
+
const C = {
|
|
3543
|
+
red: chalk.ansi256(196),
|
|
3544
|
+
gray: chalk.gray,
|
|
3545
|
+
dimGray: chalk.blackBright,
|
|
3546
|
+
white: chalk.whiteBright
|
|
3547
|
+
};
|
|
3548
|
+
/**
|
|
3549
|
+
* Prints a formatted CLI error block to stderr with timestamp.
|
|
3550
|
+
*
|
|
3551
|
+
* @param message - Primary error description
|
|
3552
|
+
* @param meta - Optional metadata
|
|
3553
|
+
*/
|
|
3554
|
+
const printError = (message, meta) => {
|
|
3555
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").replace(/(\.\d{3})Z$/, ".$1 UTC");
|
|
3556
|
+
const sep = C.dimGray("─".repeat(48));
|
|
3557
|
+
const header = `${C.red("✖ ERROR")} ${C.dimGray(ts)}`;
|
|
3558
|
+
const body = C.white(message);
|
|
3559
|
+
const defaultMeta = {
|
|
3560
|
+
pid: String(process$1.pid),
|
|
3561
|
+
node: process$1.version,
|
|
3562
|
+
...meta
|
|
3563
|
+
};
|
|
3564
|
+
const footer = Object.entries(defaultMeta).map(([k, v]) => `${C.dimGray(k)} ${C.gray(v)}`).join(" ");
|
|
3565
|
+
console.error([
|
|
3566
|
+
sep,
|
|
3567
|
+
header,
|
|
3568
|
+
body,
|
|
3569
|
+
sep,
|
|
3570
|
+
footer
|
|
3571
|
+
].join("\n"));
|
|
3572
|
+
};
|
|
3573
|
+
//#endregion
|
|
3574
|
+
//#region src/backend/util/logError.ts
|
|
3575
|
+
/**
|
|
3576
|
+
* Log an error.
|
|
3577
|
+
*
|
|
3578
|
+
* @param error - The error.
|
|
3579
|
+
*/
|
|
3580
|
+
const logError = (error) => {
|
|
3581
|
+
let message = "";
|
|
3582
|
+
if (error instanceof Error) message = errorToString(error);
|
|
3583
|
+
else if (typeof error === "string") message = error;
|
|
3584
|
+
logToFile(message);
|
|
3585
|
+
jsonLogger.log({
|
|
3586
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3587
|
+
type: "error",
|
|
3588
|
+
message
|
|
3589
|
+
});
|
|
3590
|
+
printError(message);
|
|
3591
|
+
};
|
|
3592
|
+
//#endregion
|
|
3593
|
+
export { AdminContext, createAdminRouter, createServer, createSpaFallback, forceShutdown, getJsonFile, getVersion, handlerAdminConsole, handlerLogger, handlerUpload, handlerWebPlSql, installShutdown, isDirectory, isFile, loadConfig, logError, oracledb_provider_exports as oracledb, printBanner, readFile, readFileSyncUtf8, removeFile, startServer, startServerConfig, z$configType };
|
|
3431
3594
|
|
|
3432
3595
|
//# sourceMappingURL=index.mjs.map
|