web_plsql 1.7.1 → 1.8.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/dist/frontend/assets/main-Co9Kke3j.js +147 -0
- package/dist/frontend/assets/main-Co9Kke3j.js.br +0 -0
- package/dist/frontend/assets/main-Co9Kke3j.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 +237 -76
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -8
- 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-Co9Kke3j.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,107 @@ 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.0";
|
|
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 ICON_GLOBE = "🌐";
|
|
229
|
+
const ICON_KEY = "🔑";
|
|
230
|
+
const ICON_DOC = "📄";
|
|
231
|
+
const ICON_PACKAGE = "📦";
|
|
232
|
+
const ICON_LINK = "🔗";
|
|
233
|
+
const ICON_FOLDER = "📁";
|
|
234
|
+
const ICON_GEAR = "🔧";
|
|
235
|
+
const ICON_HOME = "🏠";
|
|
236
|
+
const W = 80;
|
|
237
|
+
const LABEL_W = 35;
|
|
238
|
+
const VALUE_W = W - LABEL_W - 5;
|
|
239
|
+
const BOX = {
|
|
240
|
+
h: "─",
|
|
241
|
+
v: "│",
|
|
242
|
+
tl: "╭",
|
|
243
|
+
tr: "╮",
|
|
244
|
+
bl: "╰",
|
|
245
|
+
br: "╯",
|
|
246
|
+
ml: "├",
|
|
247
|
+
mr: "┤"
|
|
248
|
+
};
|
|
249
|
+
const displayWidth = (s) => stringWidth(s, { ambiguousIsNarrow: true });
|
|
250
|
+
const padTo = (s, w) => {
|
|
251
|
+
const delta = w - displayWidth(s);
|
|
252
|
+
return delta > 0 ? s + " ".repeat(delta) : s;
|
|
253
|
+
};
|
|
254
|
+
const truncateTo = (s, w) => w > 0 ? sliceAnsi(s, 0, w) : "";
|
|
255
|
+
const divider = () => chalk.dim(BOX.ml + BOX.h.repeat(W - 2) + BOX.mr);
|
|
256
|
+
const bottom = () => chalk.dim(BOX.bl + BOX.h.repeat(W - 2) + BOX.br);
|
|
257
|
+
/**
|
|
258
|
+
* Single key/value row.
|
|
259
|
+
* @param key - Label text.
|
|
260
|
+
* @param value - Display value; null/undefined/empty renders as a dim dash.
|
|
261
|
+
* @param icon - Optional leading icon (must be a single-cell or double-cell glyph).
|
|
262
|
+
* @returns Formatted string.
|
|
263
|
+
*/
|
|
264
|
+
const row = (key, value, icon) => {
|
|
265
|
+
const label = padTo(icon ? `${icon} ${key}` : ` ${key}`, LABEL_W);
|
|
266
|
+
const hasValue = value !== null && value !== void 0 && value !== "";
|
|
267
|
+
const valueText = hasValue ? String(value) : "—";
|
|
268
|
+
const colorFn = hasValue ? chalk.white : chalk.dim;
|
|
269
|
+
const valueCell = padTo(truncateTo(valueText, VALUE_W), VALUE_W);
|
|
270
|
+
return chalk.dim(BOX.v) + " " + chalk.dim(label) + " " + colorFn(valueCell) + " " + chalk.dim(BOX.v);
|
|
271
|
+
};
|
|
272
|
+
/**
|
|
273
|
+
* Renders the server startup banner to stdout.
|
|
274
|
+
* @param cfg - Server configuration.
|
|
275
|
+
*/
|
|
276
|
+
const printBanner = (cfg) => {
|
|
277
|
+
const adminRoute = cfg.adminRoute ?? "/admin";
|
|
278
|
+
const baseUrl = `http://localhost:${cfg.port}`;
|
|
279
|
+
const lines = [];
|
|
280
|
+
const title = `NODE PL/SQL SERVER ${getVersion()}`;
|
|
281
|
+
const pad = W - 2 - displayWidth(title);
|
|
282
|
+
lines.push(chalk.dim(BOX.tl + BOX.h.repeat(W - 2) + BOX.tr));
|
|
283
|
+
lines.push(chalk.dim(BOX.v) + " ".repeat(Math.floor(pad / 2)) + chalk.bold.cyan(title) + " ".repeat(Math.ceil(pad / 2)) + chalk.dim(BOX.v));
|
|
284
|
+
lines.push(divider());
|
|
285
|
+
lines.push(row("Port", cfg.port, ICON_GLOBE));
|
|
286
|
+
lines.push(row("Admin route", `${adminRoute}${cfg.adminUser ? " (authenticated)" : ""}`, ICON_KEY));
|
|
287
|
+
lines.push(row("Access log", cfg.loggerFilename, ICON_DOC));
|
|
288
|
+
lines.push(row("Upload limit", typeof cfg.uploadFileSizeLimit === "number" ? `${cfg.uploadFileSizeLimit} bytes` : null, ICON_PACKAGE));
|
|
289
|
+
lines.push(divider());
|
|
290
|
+
lines.push(row("Oracle pool min", cfg.oracle.poolMin, ICON_LINK));
|
|
291
|
+
lines.push(row("Oracle pool max", cfg.oracle.poolMax, ICON_LINK));
|
|
292
|
+
lines.push(row("Oracle pool increment", cfg.oracle.poolIncrement, ICON_LINK));
|
|
293
|
+
if (cfg.routeStatic.length > 0) {
|
|
294
|
+
lines.push(divider());
|
|
295
|
+
cfg.routeStatic.forEach((r, i) => {
|
|
296
|
+
lines.push(row(`Static route #${i + 1} route`, r.route, ICON_FOLDER));
|
|
297
|
+
lines.push(row(`Static route #${i + 1} path`, r.directoryPath));
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
if (cfg.routePlSql.length > 0) {
|
|
301
|
+
lines.push(divider());
|
|
302
|
+
cfg.routePlSql.forEach((r, i) => {
|
|
303
|
+
const txMode = typeof r.transactionMode === "string" ? r.transactionMode : r.transactionMode ? "custom" : "";
|
|
304
|
+
const n = `PL/SQL route #${i + 1}`;
|
|
305
|
+
lines.push(row(`${n} route`, r.route, ICON_GEAR));
|
|
306
|
+
lines.push(row(`${n} Oracle user`, r.user));
|
|
307
|
+
lines.push(row(`${n} Oracle server`, r.connectString));
|
|
308
|
+
lines.push(row(`${n} document table`, r.documentTable));
|
|
309
|
+
lines.push(row(`${n} default page`, r.defaultPage));
|
|
310
|
+
lines.push(row(`${n} path alias`, r.pathAlias ?? ""));
|
|
311
|
+
lines.push(row(`${n} path alias proc`, r.pathAliasProcedure ?? ""));
|
|
312
|
+
lines.push(row(`${n} exclusion list`, r.exclusionList?.join(", ") ?? ""));
|
|
313
|
+
lines.push(row(`${n} validation fn`, r.requestValidationFunction ?? ""));
|
|
314
|
+
lines.push(row(`${n} session mode`, txMode));
|
|
315
|
+
lines.push(row(`${n} auth`, typeof r.auth === "string" ? r.auth : ""));
|
|
316
|
+
lines.push(row(`${n} error style`, r.errorStyle));
|
|
261
317
|
});
|
|
262
318
|
}
|
|
263
|
-
|
|
319
|
+
lines.push(divider());
|
|
320
|
+
lines.push(row("Admin console", `${baseUrl}${adminRoute}`, ICON_HOME));
|
|
321
|
+
cfg.routePlSql.forEach((r) => {
|
|
322
|
+
lines.push(row(r.route, `${baseUrl}${r.route}`, ICON_GEAR));
|
|
323
|
+
});
|
|
324
|
+
lines.push(bottom());
|
|
325
|
+
console.log(lines.join("\n"));
|
|
264
326
|
};
|
|
265
327
|
//#endregion
|
|
266
328
|
//#region src/backend/server/server.ts
|
|
@@ -297,7 +359,7 @@ const createServer = (app, ssl) => {
|
|
|
297
359
|
const startServer = async (config, ssl) => {
|
|
298
360
|
debug$14("startServer: BEGIN", config, ssl);
|
|
299
361
|
const internalConfig = z$configType.parse(config);
|
|
300
|
-
|
|
362
|
+
printBanner(internalConfig);
|
|
301
363
|
const app = express();
|
|
302
364
|
if (internalConfig.devMode) app.use(cors({
|
|
303
365
|
origin: "http://localhost:5173",
|
|
@@ -322,7 +384,10 @@ const startServer = async (config, ssl) => {
|
|
|
322
384
|
const handler = handlerWebPlSql(await createPool({
|
|
323
385
|
user: i.user,
|
|
324
386
|
password: i.password,
|
|
325
|
-
connectString: i.connectString
|
|
387
|
+
connectString: i.connectString,
|
|
388
|
+
poolMin: internalConfig.oracle.poolMin,
|
|
389
|
+
poolMax: internalConfig.oracle.poolMax,
|
|
390
|
+
poolIncrement: internalConfig.oracle.poolIncrement
|
|
326
391
|
}), i, adminContext);
|
|
327
392
|
app.use([`${i.route}/:name`, i.route], (req, res, next) => {
|
|
328
393
|
const start = process.hrtime();
|
|
@@ -1819,6 +1884,68 @@ const tryDecodeDate = (value) => {
|
|
|
1819
1884
|
//#region src/backend/handler/plsql/sendResponse.ts
|
|
1820
1885
|
const debug$7 = debugModule("webplsql:sendResponse");
|
|
1821
1886
|
/**
|
|
1887
|
+
* Pipe a readable to the response and await completion.
|
|
1888
|
+
* Listeners are attached before piping to avoid races.
|
|
1889
|
+
*
|
|
1890
|
+
* @param readable - The source readable stream.
|
|
1891
|
+
* @param res - The HTTP response stream.
|
|
1892
|
+
*/
|
|
1893
|
+
const pipeReadableToResponse = async (readable, res) => {
|
|
1894
|
+
await new Promise((resolve, reject) => {
|
|
1895
|
+
let settled = false;
|
|
1896
|
+
const canAddResponseListener = typeof res.on === "function";
|
|
1897
|
+
const canRemoveResponseListener = typeof res.removeListener === "function";
|
|
1898
|
+
const cleanup = () => {
|
|
1899
|
+
readable.removeListener("end", onReadableEnd);
|
|
1900
|
+
readable.removeListener("close", onReadableClose);
|
|
1901
|
+
readable.removeListener("error", onReadableError);
|
|
1902
|
+
if (canRemoveResponseListener) {
|
|
1903
|
+
res.removeListener("finish", onResponseFinish);
|
|
1904
|
+
res.removeListener("close", onResponseClose);
|
|
1905
|
+
}
|
|
1906
|
+
};
|
|
1907
|
+
const resolveOnce = () => {
|
|
1908
|
+
if (settled) return;
|
|
1909
|
+
settled = true;
|
|
1910
|
+
cleanup();
|
|
1911
|
+
resolve();
|
|
1912
|
+
};
|
|
1913
|
+
const rejectOnce = (error) => {
|
|
1914
|
+
if (settled) return;
|
|
1915
|
+
settled = true;
|
|
1916
|
+
cleanup();
|
|
1917
|
+
reject(error);
|
|
1918
|
+
};
|
|
1919
|
+
const onReadableEnd = () => {
|
|
1920
|
+
resolveOnce();
|
|
1921
|
+
};
|
|
1922
|
+
const onReadableClose = () => {
|
|
1923
|
+
resolveOnce();
|
|
1924
|
+
};
|
|
1925
|
+
const onReadableError = (error) => {
|
|
1926
|
+
rejectOnce(error);
|
|
1927
|
+
};
|
|
1928
|
+
const onResponseFinish = () => {
|
|
1929
|
+
resolveOnce();
|
|
1930
|
+
};
|
|
1931
|
+
const onResponseClose = () => {
|
|
1932
|
+
resolveOnce();
|
|
1933
|
+
};
|
|
1934
|
+
readable.on("end", onReadableEnd);
|
|
1935
|
+
readable.on("close", onReadableClose);
|
|
1936
|
+
readable.on("error", onReadableError);
|
|
1937
|
+
if (canAddResponseListener) {
|
|
1938
|
+
res.on("finish", onResponseFinish);
|
|
1939
|
+
res.on("close", onResponseClose);
|
|
1940
|
+
}
|
|
1941
|
+
try {
|
|
1942
|
+
readable.pipe(res);
|
|
1943
|
+
} catch (error) {
|
|
1944
|
+
rejectOnce(error instanceof Error ? error : new Error(String(error)));
|
|
1945
|
+
}
|
|
1946
|
+
});
|
|
1947
|
+
};
|
|
1948
|
+
/**
|
|
1822
1949
|
* Send "default" response to the browser
|
|
1823
1950
|
* @param _req - The req object represents the HTTP request.
|
|
1824
1951
|
* @param res - The res object represents the HTTP response that an Express app sends when it gets an HTTP request.
|
|
@@ -1864,16 +1991,8 @@ const sendResponse = async (_req, res, page) => {
|
|
|
1864
1991
|
debugText.push(`res.pipe("${page.file.fileType ?? ""}") - streaming`);
|
|
1865
1992
|
debug$7(getBlock("RESPONSE", debugText.join("\n")));
|
|
1866
1993
|
}
|
|
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
|
-
});
|
|
1994
|
+
/* v8 ignore stop */
|
|
1995
|
+
await pipeReadableToResponse(page.file.fileBlob, res);
|
|
1877
1996
|
} else {
|
|
1878
1997
|
/* v8 ignore start */
|
|
1879
1998
|
if (debug$7.enabled) {
|
|
@@ -1908,16 +2027,7 @@ const sendResponse = async (_req, res, page) => {
|
|
|
1908
2027
|
debug$7(getBlock("RESPONSE", debugText.join("\n")));
|
|
1909
2028
|
}
|
|
1910
2029
|
/* 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
|
-
});
|
|
2030
|
+
if (page.body instanceof stream.Readable) await pipeReadableToResponse(page.body, res);
|
|
1921
2031
|
else res.send(page.body);
|
|
1922
2032
|
};
|
|
1923
2033
|
//#endregion
|
|
@@ -3302,8 +3412,7 @@ const createAdminRouter = (adminContext) => {
|
|
|
3302
3412
|
* @throws {Error} if project root cannot be found
|
|
3303
3413
|
*/
|
|
3304
3414
|
const resolveAdminStaticDir = () => {
|
|
3305
|
-
|
|
3306
|
-
let projectRoot = path.dirname(__filename);
|
|
3415
|
+
let projectRoot = import.meta.dirname;
|
|
3307
3416
|
while (!existsSync(path.join(projectRoot, "package.json")) && projectRoot !== "/") projectRoot = path.dirname(projectRoot);
|
|
3308
3417
|
if (projectRoot === "/") throw new Error("Could not find project root (package.json). Please provide explicit staticDir in AdminConsoleConfig.");
|
|
3309
3418
|
return path.join(projectRoot, "dist", "frontend");
|
|
@@ -3427,6 +3536,58 @@ const createSpaFallback = (directoryPath, _route) => {
|
|
|
3427
3536
|
};
|
|
3428
3537
|
};
|
|
3429
3538
|
//#endregion
|
|
3430
|
-
|
|
3539
|
+
//#region src/backend/util/printError.ts
|
|
3540
|
+
const C = {
|
|
3541
|
+
red: chalk.ansi256(196),
|
|
3542
|
+
gray: chalk.gray,
|
|
3543
|
+
dimGray: chalk.blackBright,
|
|
3544
|
+
white: chalk.whiteBright
|
|
3545
|
+
};
|
|
3546
|
+
/**
|
|
3547
|
+
* Prints a formatted CLI error block to stderr with timestamp.
|
|
3548
|
+
*
|
|
3549
|
+
* @param message - Primary error description
|
|
3550
|
+
* @param meta - Optional metadata
|
|
3551
|
+
*/
|
|
3552
|
+
const printError = (message, meta) => {
|
|
3553
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").replace(/(\.\d{3})Z$/, ".$1 UTC");
|
|
3554
|
+
const sep = C.dimGray("─".repeat(48));
|
|
3555
|
+
const header = `${C.red("✖ ERROR")} ${C.dimGray(ts)}`;
|
|
3556
|
+
const body = C.white(message);
|
|
3557
|
+
const defaultMeta = {
|
|
3558
|
+
pid: String(process$1.pid),
|
|
3559
|
+
node: process$1.version,
|
|
3560
|
+
...meta
|
|
3561
|
+
};
|
|
3562
|
+
const footer = Object.entries(defaultMeta).map(([k, v]) => `${C.dimGray(k)} ${C.gray(v)}`).join(" ");
|
|
3563
|
+
console.error([
|
|
3564
|
+
sep,
|
|
3565
|
+
header,
|
|
3566
|
+
body,
|
|
3567
|
+
sep,
|
|
3568
|
+
footer
|
|
3569
|
+
].join("\n"));
|
|
3570
|
+
};
|
|
3571
|
+
//#endregion
|
|
3572
|
+
//#region src/backend/util/logError.ts
|
|
3573
|
+
/**
|
|
3574
|
+
* Log an error.
|
|
3575
|
+
*
|
|
3576
|
+
* @param error - The error.
|
|
3577
|
+
*/
|
|
3578
|
+
const logError = (error) => {
|
|
3579
|
+
let message = "";
|
|
3580
|
+
if (error instanceof Error) message = errorToString(error);
|
|
3581
|
+
else if (typeof error === "string") message = error;
|
|
3582
|
+
logToFile(message);
|
|
3583
|
+
jsonLogger.log({
|
|
3584
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3585
|
+
type: "error",
|
|
3586
|
+
message
|
|
3587
|
+
});
|
|
3588
|
+
printError(message);
|
|
3589
|
+
};
|
|
3590
|
+
//#endregion
|
|
3591
|
+
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
3592
|
|
|
3432
3593
|
//# sourceMappingURL=index.mjs.map
|