@arkstack/common 0.5.2 → 0.5.3
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 +754 -20
- package/dist/app.d.ts +61 -1
- package/dist/faker.d.ts +9 -0
- package/dist/faker.js +20 -0
- package/dist/helpers-BrQ0B-EX.d.ts +109 -0
- package/dist/index.d.ts +662 -49
- package/dist/index.js +129 -275
- package/dist/system-DUaI4u99.js +475 -0
- package/dist/utils/index.d.ts +188 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils-DLifcZWV.js +452 -0
- package/package.json +19 -7
- package/resources/views/error.edge +199 -0
- package/dist/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,138 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
1
|
+
import { _ as ConfigLoader, a as env, c as nodeEnv, d as resolveRuntimeDir, f as resolveRuntimeModule, g as CONFIG_KEY, h as envLoader, i as discoverCommands, l as outputDir, m as EnvLoader, n as appUrl, o as importFile, p as toOutputPath, r as config, s as interopDefault, t as appKey, u as rebuildOutput, v as configLoader } from "./system-DUaI4u99.js";
|
|
2
|
+
import { _ as Hash, c as abortIf, d as initializeGlobalContext, f as isClass, g as Exception, h as AppException, l as assertFound, m as RequestException, p as perPage, s as abort, u as getModel, v as Encryption } from "./utils-DLifcZWV.js";
|
|
3
|
+
import { Hook as Hook$1 } from "@arkstack/foundry";
|
|
4
|
+
import { Arkstack } from "@arkstack/contract";
|
|
5
|
+
import { str } from "@h3ravel/support";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { ModelNotFoundException } from "arkormx";
|
|
7
8
|
import { detect } from "detect-port";
|
|
8
9
|
import pino from "pino";
|
|
9
10
|
import chalk from "chalk";
|
|
10
|
-
import {
|
|
11
|
-
import { Secret, TOTP } from "otpauth";
|
|
12
|
-
import { compare, genSalt, hash } from "bcryptjs";
|
|
13
|
-
import { getUserConfig } from "arkormx";
|
|
11
|
+
import { networkInterfaces } from "node:os";
|
|
14
12
|
//#region src/lifecycle.ts
|
|
15
|
-
const bindGracefulShutdown = (shutdown) => {
|
|
13
|
+
const bindGracefulShutdown = (shutdown, defer) => {
|
|
14
|
+
if (defer) return;
|
|
16
15
|
[
|
|
17
16
|
"SIGINT",
|
|
18
17
|
"SIGTERM",
|
|
19
18
|
"SIGQUIT"
|
|
20
19
|
].forEach((signal) => {
|
|
21
20
|
process.on(signal, async () => {
|
|
21
|
+
if (Hook$1.has("shutdown", "before")) Hook$1.get("shutdown", "after", {});
|
|
22
22
|
await shutdown();
|
|
23
23
|
});
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
26
|
//#endregion
|
|
27
|
-
//#region src/
|
|
28
|
-
/**
|
|
29
|
-
* Read the .env file
|
|
30
|
-
*
|
|
31
|
-
* @param env
|
|
32
|
-
* @param def
|
|
33
|
-
* @returns
|
|
34
|
-
*/
|
|
35
|
-
const env = (env, defaultValue) => {
|
|
36
|
-
let val = process.env[env] ?? "";
|
|
37
|
-
if ([
|
|
38
|
-
true,
|
|
39
|
-
"true",
|
|
40
|
-
"on",
|
|
41
|
-
false,
|
|
42
|
-
"false",
|
|
43
|
-
"off"
|
|
44
|
-
].includes(val)) val = [
|
|
45
|
-
true,
|
|
46
|
-
"true",
|
|
47
|
-
"on"
|
|
48
|
-
].includes(val);
|
|
49
|
-
if (!isNaN(Number(val)) && typeof val !== "boolean" && typeof val !== "undefined" && val !== "") val = Number(val);
|
|
50
|
-
if (val === "") val = void 0;
|
|
51
|
-
if (val === "null") val = null;
|
|
52
|
-
val ??= defaultValue;
|
|
53
|
-
return val;
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* Build the app url
|
|
57
|
-
*
|
|
58
|
-
* @param link
|
|
59
|
-
* @returns
|
|
60
|
-
*/
|
|
61
|
-
const appUrl = (link) => {
|
|
62
|
-
const port = env("PORT") || "3000";
|
|
63
|
-
const defaultUrl = `http://localhost:${port}`;
|
|
64
|
-
const appUrl = env("APP_URL") ?? defaultUrl;
|
|
65
|
-
try {
|
|
66
|
-
const url = new URL(appUrl);
|
|
67
|
-
if (url.port || url.hostname === "localhost") url.port = port;
|
|
68
|
-
const baseUrl = url.toString().replace(/\/$/, "");
|
|
69
|
-
if (link) return `${baseUrl}${`/${link.replace(/^\/+/, "")}`}`;
|
|
70
|
-
return baseUrl;
|
|
71
|
-
} catch {
|
|
72
|
-
return link ? `${defaultUrl}/${link.replace(/^\/+/, "")}` : defaultUrl;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
/**
|
|
76
|
-
* Gets the application configuration.
|
|
77
|
-
*
|
|
78
|
-
* @param key The configuration key to retrieve.
|
|
79
|
-
* @param defaultValue The default value to return if the key is not found.
|
|
80
|
-
* @returns The configuration value.
|
|
81
|
-
*/
|
|
82
|
-
const config = (key, defaultValue) => {
|
|
83
|
-
const dist = path.relative(process.cwd(), outputDir());
|
|
84
|
-
const require = createRequire(import.meta.url);
|
|
85
|
-
const config = readdirSync(path.join(process.cwd(), `${dist}/config`), { withFileTypes: true }).filter((file) => {
|
|
86
|
-
if (file.name.includes("middleware") && globalThis.arkctx.runtime === "CLI") return false;
|
|
87
|
-
return file.isFile() && (file.name.endsWith(".js") || file.name.endsWith(".ts"));
|
|
88
|
-
}).reduce((configs, file) => {
|
|
89
|
-
const configName = path.basename(file.name, path.extname(file.name));
|
|
90
|
-
configs[configName] = require(path.join(file.parentPath, file.name)).default(globalThis.app());
|
|
91
|
-
return configs;
|
|
92
|
-
}, {});
|
|
93
|
-
if (key) return Obj.get(config, key, defaultValue);
|
|
94
|
-
return config;
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Gets the current Node environment (development or production).
|
|
98
|
-
*
|
|
99
|
-
* @returns
|
|
100
|
-
*/
|
|
101
|
-
const nodeEnv = () => {
|
|
102
|
-
let envValue = env("NODE_ENV", "development");
|
|
103
|
-
if (envValue !== "development" && envValue !== "production") envValue = "development";
|
|
104
|
-
return envValue === "production" ? "prod" : "dev";
|
|
105
|
-
};
|
|
27
|
+
//#region src/network.ts
|
|
106
28
|
/**
|
|
107
|
-
*
|
|
29
|
+
* Boots the app using an available port close to the requested port
|
|
30
|
+
*when requested port is not available
|
|
108
31
|
*
|
|
109
|
-
* @param
|
|
110
|
-
* @
|
|
32
|
+
* @param boot
|
|
33
|
+
* @param preferredPort
|
|
34
|
+
* @param app
|
|
35
|
+
* @param defer
|
|
111
36
|
*/
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
dev: env("OUTPUT_DIR_DEV", ".arkstack/build"),
|
|
116
|
-
prod: env("OUTPUT_DIR", "dist")
|
|
117
|
-
};
|
|
118
|
-
return path.isAbsolute(output[NODE_ENV] ?? output.dev) ? output[NODE_ENV] ?? output.dev : path.join(cwd, output[NODE_ENV] ?? output.dev);
|
|
119
|
-
};
|
|
120
|
-
const importFile = async (filePath) => {
|
|
121
|
-
const resolvedPath = resolve(filePath);
|
|
122
|
-
return await createJiti(pathToFileURL(resolvedPath).href, {
|
|
123
|
-
interopDefault: false,
|
|
124
|
-
tsconfigPaths: true
|
|
125
|
-
}).import(resolvedPath);
|
|
126
|
-
};
|
|
127
|
-
//#endregion
|
|
128
|
-
//#region src/network.ts
|
|
129
|
-
const bootWithDetectedPort = async (boot, preferredPort = 3e3, app) => {
|
|
37
|
+
const bootWithDetectedPort = async (boot, preferredPort = 3e3, app, defer) => {
|
|
38
|
+
const port = await detect(preferredPort);
|
|
39
|
+
if (Hook$1.has("boot", "before")) Hook$1.get("boot", "before", port, app);
|
|
130
40
|
if (app && !globalThis.app) globalThis.app = () => app;
|
|
131
41
|
globalThis.env = env;
|
|
132
42
|
globalThis.config = config;
|
|
133
43
|
globalThis.str = str;
|
|
44
|
+
globalThis.abort = abort;
|
|
45
|
+
globalThis.abortIf = abortIf;
|
|
46
|
+
globalThis.assertFound = assertFound;
|
|
134
47
|
globalThis.arkctx = { runtime: "HTTP" };
|
|
135
|
-
await boot(
|
|
48
|
+
await boot(port);
|
|
49
|
+
await initializeGlobalContext();
|
|
50
|
+
bindGracefulShutdown(async () => await app?.shutdown(), defer);
|
|
51
|
+
if (Hook$1.has("boot", "after")) Hook$1.get("boot", "after", port, app);
|
|
136
52
|
};
|
|
137
53
|
const renderError = ({ message = "An unexpected error occurred.", stack, title, code = 500 }) => {
|
|
138
54
|
title = {
|
|
@@ -180,56 +96,6 @@ const loadPrototypes = () => {
|
|
|
180
96
|
};
|
|
181
97
|
};
|
|
182
98
|
//#endregion
|
|
183
|
-
//#region src/Exceptions/Exception.ts
|
|
184
|
-
var Exception = class extends Error {
|
|
185
|
-
name;
|
|
186
|
-
constructor(message, options) {
|
|
187
|
-
super(message, options);
|
|
188
|
-
this.name = "Exception";
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
//#endregion
|
|
192
|
-
//#region src/Exceptions/AppException.ts
|
|
193
|
-
var AppException = class extends Exception {
|
|
194
|
-
errors = void 0;
|
|
195
|
-
statusCode;
|
|
196
|
-
constructor(message, statusCode = 400, options) {
|
|
197
|
-
super(message, options);
|
|
198
|
-
this.statusCode = statusCode;
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
//#endregion
|
|
202
|
-
//#region src/Exceptions/RequestException.ts
|
|
203
|
-
var RequestException = class RequestException extends AppException {
|
|
204
|
-
statusCode;
|
|
205
|
-
constructor(message, statusCode = 400, options) {
|
|
206
|
-
super(message, statusCode, options);
|
|
207
|
-
this.statusCode = statusCode;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Asserts that a value is not null or undefined.
|
|
211
|
-
*
|
|
212
|
-
* @param value
|
|
213
|
-
* @param message
|
|
214
|
-
* @param code
|
|
215
|
-
* @throws {RequestException} Throws if the value is null or undefined.
|
|
216
|
-
*/
|
|
217
|
-
static assertNotEmpty(value, message, code = 404) {
|
|
218
|
-
if (!value) throw new RequestException(message, code);
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Asserts that a boolean condition is true.
|
|
222
|
-
*
|
|
223
|
-
* @param boolean
|
|
224
|
-
* @param message
|
|
225
|
-
* @param code
|
|
226
|
-
* @throws {RequestException} Throws if the boolean condition is true.
|
|
227
|
-
*/
|
|
228
|
-
static abortIf(boolean, message, code) {
|
|
229
|
-
if (boolean) throw new RequestException(message, code);
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
//#endregion
|
|
233
99
|
//#region src/ErrorHandler.ts
|
|
234
100
|
var ErrorHandler = class ErrorHandler {
|
|
235
101
|
static loggerCache = /* @__PURE__ */ new Map();
|
|
@@ -244,7 +110,7 @@ var ErrorHandler = class ErrorHandler {
|
|
|
244
110
|
return Number.isInteger(code) && code >= 100 && code < 600 ? code : fallback;
|
|
245
111
|
}
|
|
246
112
|
static getErrorLogger() {
|
|
247
|
-
const destination = path.resolve(
|
|
113
|
+
const destination = path.resolve(Arkstack.rootDir(), "storage/logs/error.log");
|
|
248
114
|
if (!ErrorHandler.loggerCache.has(destination)) ErrorHandler.loggerCache.set(destination, pino({ level: "error" }, pino.destination({
|
|
249
115
|
dest: destination,
|
|
250
116
|
mkdir: true,
|
|
@@ -283,7 +149,12 @@ var ErrorHandler = class ErrorHandler {
|
|
|
283
149
|
return typeof ErrorHandler.toErrorShape(error)?.errors !== "undefined";
|
|
284
150
|
}
|
|
285
151
|
static isModelNotFoundError(error) {
|
|
286
|
-
|
|
152
|
+
const candidate = ErrorHandler.toErrorShape(error);
|
|
153
|
+
if (error.cause && error.cause instanceof ModelNotFoundException) {
|
|
154
|
+
error.getModelName = error.cause.getModelName;
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
return typeof candidate?.getModelName === "function" || error instanceof ModelNotFoundException;
|
|
287
158
|
}
|
|
288
159
|
static shouldHideStack() {
|
|
289
160
|
const value = process.env.HIDE_ERROR_STACK;
|
|
@@ -319,6 +190,7 @@ var ErrorHandler = class ErrorHandler {
|
|
|
319
190
|
delete payload.errors;
|
|
320
191
|
delete payload.stack;
|
|
321
192
|
}
|
|
193
|
+
if (detailedError?.body && typeof detailedError.body === "object") Object.assign(payload, detailedError.body);
|
|
322
194
|
return payload;
|
|
323
195
|
}
|
|
324
196
|
static logUnhandledError(err, request, message) {
|
|
@@ -341,6 +213,54 @@ const shouldLogError = ErrorHandler.shouldLogError;
|
|
|
341
213
|
const createErrorPayload = ErrorHandler.createErrorPayload;
|
|
342
214
|
const logUnhandledError = ErrorHandler.logUnhandledError;
|
|
343
215
|
//#endregion
|
|
216
|
+
//#region src/Publisher.ts
|
|
217
|
+
const REGISTRY_KEY = Symbol.for("arkstack.publishables");
|
|
218
|
+
/**
|
|
219
|
+
* Registry of artifacts packages want to publish into the consuming application.
|
|
220
|
+
*
|
|
221
|
+
* Packages call {@link Publisher.publishes} from their `setup` module so that
|
|
222
|
+
* `ark publish` can copy the artifacts (migrations, config stubs, assets, …)
|
|
223
|
+
* into the app. The registry is backed by a global symbol so it stays a single
|
|
224
|
+
* shared instance even across duplicated module copies.
|
|
225
|
+
*/
|
|
226
|
+
var Publisher = class {
|
|
227
|
+
/** The shared, global-symbol-backed registry of publishable groups. */
|
|
228
|
+
static get registry() {
|
|
229
|
+
return globalThis[REGISTRY_KEY] ??= [];
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Register artifacts a package wants to publish into the application.
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```ts
|
|
236
|
+
* Publisher.publishes({
|
|
237
|
+
* package: '@arkstack/cache',
|
|
238
|
+
* tag: 'cache-migrations',
|
|
239
|
+
* entries: [{ from: join(here, '../stubs/...'), to: 'src/database/migrations/...' }],
|
|
240
|
+
* })
|
|
241
|
+
* ```
|
|
242
|
+
*
|
|
243
|
+
* @param group The publishable group to register.
|
|
244
|
+
*/
|
|
245
|
+
static publishes(group) {
|
|
246
|
+
this.registry.push(group);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Read the registered publishable groups, optionally filtered by package or
|
|
250
|
+
* tag.
|
|
251
|
+
*
|
|
252
|
+
* @param filter Restrict the result to a package and/or tag.
|
|
253
|
+
* @returns The matching publishable groups.
|
|
254
|
+
*/
|
|
255
|
+
static publishables(filter = {}) {
|
|
256
|
+
return this.registry.filter((group) => (!filter.package || group.package === filter.package) && (!filter.tag || group.tag === filter.tag));
|
|
257
|
+
}
|
|
258
|
+
/** Remove every registered publishable group (primarily for tests). */
|
|
259
|
+
static clear() {
|
|
260
|
+
this.registry.length = 0;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
//#endregion
|
|
344
264
|
//#region src/Logger.ts
|
|
345
265
|
var Console = class {
|
|
346
266
|
static log = (...args) => Logger.log(args.map((e) => [e, "white"]));
|
|
@@ -553,30 +473,30 @@ var Hook = class {
|
|
|
553
473
|
* @param name
|
|
554
474
|
* @param value
|
|
555
475
|
*/
|
|
556
|
-
static set
|
|
476
|
+
static set(name, hook) {
|
|
557
477
|
const oldhook = this.hooks.get(name) ?? {};
|
|
558
478
|
this.hooks.set(name, {
|
|
559
479
|
...oldhook,
|
|
560
480
|
...hook
|
|
561
481
|
});
|
|
562
|
-
}
|
|
482
|
+
}
|
|
563
483
|
/**
|
|
564
484
|
* Check if a hook is defined by name
|
|
565
485
|
*
|
|
566
486
|
* @param name
|
|
567
487
|
*/
|
|
568
|
-
static has
|
|
488
|
+
static has(name, pos) {
|
|
569
489
|
if (pos && this.hooks.has(name)) return Boolean(this.get(name, pos));
|
|
570
490
|
return this.hooks.has(name);
|
|
571
|
-
}
|
|
572
|
-
static get(name, pos) {
|
|
491
|
+
}
|
|
492
|
+
static get(name, pos, ...args) {
|
|
573
493
|
const hook = this.hooks.get(name);
|
|
574
494
|
if (!hook) return void 0;
|
|
575
|
-
if (pos
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
return
|
|
495
|
+
if (pos === void 0) return hook;
|
|
496
|
+
const fn = hook[pos];
|
|
497
|
+
if (!fn) return void 0;
|
|
498
|
+
if (args.length > 0) return fn(...args);
|
|
499
|
+
return fn;
|
|
580
500
|
}
|
|
581
501
|
/**
|
|
582
502
|
* Retrieve all defined hooks
|
|
@@ -593,7 +513,7 @@ var Hook = class {
|
|
|
593
513
|
*
|
|
594
514
|
* @param name
|
|
595
515
|
*/
|
|
596
|
-
static unset
|
|
516
|
+
static unset(name, pos) {
|
|
597
517
|
if (name && this.hooks.has(name)) {
|
|
598
518
|
if (pos !== void 0) {
|
|
599
519
|
const hook = this.get(name);
|
|
@@ -603,7 +523,7 @@ var Hook = class {
|
|
|
603
523
|
}
|
|
604
524
|
this.hooks.delete(name);
|
|
605
525
|
} else this.clear();
|
|
606
|
-
}
|
|
526
|
+
}
|
|
607
527
|
/**
|
|
608
528
|
* Clear all the defined hooks
|
|
609
529
|
*/
|
|
@@ -612,107 +532,41 @@ var Hook = class {
|
|
|
612
532
|
};
|
|
613
533
|
};
|
|
614
534
|
//#endregion
|
|
615
|
-
//#region src/
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
var Hash = class {
|
|
644
|
-
/**
|
|
645
|
-
* Hash a value using bcrypt
|
|
646
|
-
*
|
|
647
|
-
* @param value
|
|
648
|
-
* @returns
|
|
649
|
-
*/
|
|
650
|
-
static async make(value) {
|
|
651
|
-
return await hash(value, await genSalt(10));
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Verify a value against a hashed value
|
|
655
|
-
*
|
|
656
|
-
* @param value
|
|
657
|
-
* @param hashedValue
|
|
658
|
-
* @returns
|
|
659
|
-
*/
|
|
660
|
-
static async verify(value, hashedValue) {
|
|
661
|
-
return await compare(value, hashedValue);
|
|
662
|
-
}
|
|
663
|
-
/**
|
|
664
|
-
* Generate a one-time password (OTP) using TOTP algorithm
|
|
665
|
-
*
|
|
666
|
-
* @param digits The number of digits for the OTP, default is 6.
|
|
667
|
-
* @param label A label to identify the OTP, can be an email or phone number.
|
|
668
|
-
* @param period Interval of time for which a token is valid, in seconds.
|
|
669
|
-
* @returns
|
|
670
|
-
*/
|
|
671
|
-
static otp(digits = 6, label = "Alice", period = 30) {
|
|
672
|
-
return new TOTP({
|
|
673
|
-
label,
|
|
674
|
-
digits,
|
|
675
|
-
issuer: env("APP_NAME", "Roseed"),
|
|
676
|
-
algorithm: "SHA1",
|
|
677
|
-
period,
|
|
678
|
-
secret: "US3WHSG7X5KAPV27VANWKQHF3SH3HULL"
|
|
679
|
-
});
|
|
680
|
-
}
|
|
681
|
-
static totp(secret, label, issuer = env("APP_NAME", "Roseed"), period = 30) {
|
|
682
|
-
return new TOTP({
|
|
683
|
-
issuer,
|
|
684
|
-
label,
|
|
685
|
-
algorithm: "SHA1",
|
|
686
|
-
digits: 6,
|
|
687
|
-
period,
|
|
688
|
-
secret: Secret.fromBase32(secret)
|
|
689
|
-
});
|
|
690
|
-
}
|
|
535
|
+
//#region src/tls.ts
|
|
536
|
+
let devCertCache;
|
|
537
|
+
/**
|
|
538
|
+
* Generate (and cache) an in-memory self-signed TLS certificate for local HTTPS
|
|
539
|
+
* development. `selfsigned` is imported lazily so it's only loaded when secure
|
|
540
|
+
* dev mode is actually used.
|
|
541
|
+
*
|
|
542
|
+
* The certificate is not trusted by browsers (expect the usual self-signed
|
|
543
|
+
* warning); it exists only so the dev server can speak HTTPS.
|
|
544
|
+
*
|
|
545
|
+
* @param host The common name for the certificate (defaults to `localhost`).
|
|
546
|
+
*/
|
|
547
|
+
const devTlsCredentials = async (host = "localhost") => {
|
|
548
|
+
if (devCertCache) return devCertCache;
|
|
549
|
+
const mod = await import("selfsigned");
|
|
550
|
+
const pems = (mod.default ?? mod).generate([{
|
|
551
|
+
name: "commonName",
|
|
552
|
+
value: host
|
|
553
|
+
}], {
|
|
554
|
+
days: 365,
|
|
555
|
+
keySize: 2048,
|
|
556
|
+
algorithm: "sha256"
|
|
557
|
+
});
|
|
558
|
+
devCertCache = {
|
|
559
|
+
key: pems.private,
|
|
560
|
+
cert: pems.cert
|
|
561
|
+
};
|
|
562
|
+
return devCertCache;
|
|
691
563
|
};
|
|
692
|
-
//#endregion
|
|
693
|
-
//#region src/utils/helpers.ts
|
|
694
564
|
/**
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
* @param query
|
|
698
|
-
* @returns
|
|
565
|
+
* The machine's first non-internal IPv4 address — its address on the local
|
|
566
|
+
* network — or `undefined` when only loopback interfaces are available.
|
|
699
567
|
*/
|
|
700
|
-
const
|
|
701
|
-
const
|
|
702
|
-
return Number.isFinite(requestedPerPage) && requestedPerPage > 0 ? Math.min(requestedPerPage, 50) : 15;
|
|
568
|
+
const localNetworkAddress = () => {
|
|
569
|
+
for (const list of Object.values(networkInterfaces())) for (const net of list ?? []) if (net.family === "IPv4" && !net.internal) return net.address;
|
|
703
570
|
};
|
|
704
|
-
async function getModel(modelName) {
|
|
705
|
-
const resolveModelExport = (module, modelName) => {
|
|
706
|
-
if (!isModelModule(module)) return module;
|
|
707
|
-
return module.default ?? module[modelName] ?? module;
|
|
708
|
-
};
|
|
709
|
-
const isModelModule = (value) => typeof value === "object" && value !== null;
|
|
710
|
-
const modelPath = getUserConfig().paths?.models || "./src/models";
|
|
711
|
-
const model = resolveModelExport(await importFile(path.join(path.isAbsolute(modelPath) ? modelPath : path.join(process.cwd(), modelPath), modelName)), path.basename(modelName, path.extname(modelName)));
|
|
712
|
-
if (typeof model !== "function") throw new Error(`Model "${modelName}" not found`);
|
|
713
|
-
return model;
|
|
714
|
-
}
|
|
715
571
|
//#endregion
|
|
716
|
-
export { AppException, Encryption, ErrorHandler, Exception, Hash, Hook, Logger, RequestException, appUrl, bindGracefulShutdown, bootWithDetectedPort, config, createErrorPayload, env, getErrorLogger, getModel, getPrimaryError, getValidationErrors, importFile, isModelNotFoundError, isValidationError, loadPrototypes, logUnhandledError, nodeEnv, normalizeStatusCode, outputDir, perPage, renderError, serializeError, shouldHideStack, shouldLogError, toErrorShape };
|
|
717
|
-
|
|
718
|
-
//# sourceMappingURL=index.js.map
|
|
572
|
+
export { AppException, CONFIG_KEY, ConfigLoader, Encryption, EnvLoader, ErrorHandler, Exception, Hash, Hook, Logger, Publisher, RequestException, abort, abortIf, appKey, appUrl, assertFound, bindGracefulShutdown, bootWithDetectedPort, config, configLoader, createErrorPayload, devTlsCredentials, discoverCommands, env, envLoader, getErrorLogger, getModel, getPrimaryError, getValidationErrors, importFile, initializeGlobalContext, interopDefault, isClass, isModelNotFoundError, isValidationError, loadPrototypes, localNetworkAddress, logUnhandledError, nodeEnv, normalizeStatusCode, outputDir, perPage, rebuildOutput, renderError, resolveRuntimeDir, resolveRuntimeModule, serializeError, shouldHideStack, shouldLogError, toErrorShape, toOutputPath };
|