@h3ravel/core 1.7.4 → 1.9.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/index.cjs CHANGED
@@ -1,568 +1,697 @@
1
- "use strict";
1
+ //#region rolldown:runtime
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- var __esm = (fn, res) => function __init() {
10
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
11
17
  };
12
- var __export = (target, all) => {
13
- for (var name in all)
14
- __defProp(target, name, { get: all[name], enumerable: true });
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ require("reflect-metadata");
25
+ let __h3ravel_shared = require("@h3ravel/shared");
26
+ __h3ravel_shared = __toESM(__h3ravel_shared);
27
+ let __h3ravel_support = require("@h3ravel/support");
28
+ __h3ravel_support = __toESM(__h3ravel_support);
29
+ let node_path = require("node:path");
30
+ node_path = __toESM(node_path);
31
+ let chalk = require("chalk");
32
+ chalk = __toESM(chalk);
33
+ let detect_port = require("detect-port");
34
+ detect_port = __toESM(detect_port);
35
+ let dotenv = require("dotenv");
36
+ dotenv = __toESM(dotenv);
37
+ let dotenv_expand = require("dotenv-expand");
38
+ dotenv_expand = __toESM(dotenv_expand);
39
+ let node_fs_promises = require("node:fs/promises");
40
+ node_fs_promises = __toESM(node_fs_promises);
41
+ let edge_js = require("edge.js");
42
+ edge_js = __toESM(edge_js);
43
+
44
+ //#region src/Container.ts
45
+ var Container = class {
46
+ bindings = /* @__PURE__ */ new Map();
47
+ singletons = /* @__PURE__ */ new Map();
48
+ /**
49
+ * Check if the target has any decorators
50
+ *
51
+ * @param target
52
+ * @returns
53
+ */
54
+ static hasAnyDecorator(target) {
55
+ if (Reflect.getMetadataKeys(target).length > 0) return true;
56
+ const paramLength = target.length;
57
+ for (let i = 0; i < paramLength; i++) if (Reflect.getMetadataKeys(target, `__param_${i}`).length > 0) return true;
58
+ return false;
59
+ }
60
+ bind(key, factory) {
61
+ this.bindings.set(key, factory);
62
+ }
63
+ /**
64
+ * Bind a singleton service to the container
65
+ */
66
+ singleton(key, factory) {
67
+ this.bindings.set(key, () => {
68
+ if (!this.singletons.has(key)) this.singletons.set(key, factory());
69
+ return this.singletons.get(key);
70
+ });
71
+ }
72
+ /**
73
+ * Resolve a service from the container
74
+ */
75
+ make(key) {
76
+ /**
77
+ * Direct factory binding
78
+ */
79
+ if (this.bindings.has(key)) return this.bindings.get(key)();
80
+ /**
81
+ * If this is a class constructor, auto-resolve via reflection
82
+ */
83
+ if (typeof key === "function") return this.build(key);
84
+ throw new Error(`No binding found for key: ${typeof key === "string" ? key : key?.name}`);
85
+ }
86
+ /**
87
+ * Automatically build a class with constructor dependency injection
88
+ */
89
+ build(ClassType) {
90
+ let dependencies = [];
91
+ if (Array.isArray(ClassType.__inject__)) dependencies = ClassType.__inject__.map((alias) => {
92
+ return this.make(alias);
93
+ });
94
+ else dependencies = (Reflect.getMetadata("design:paramtypes", ClassType) || []).map((dep) => this.make(dep));
95
+ return new ClassType(...dependencies);
96
+ }
97
+ /**
98
+ * Check if a service is registered
99
+ */
100
+ has(key) {
101
+ return this.bindings.has(key);
102
+ }
15
103
  };
16
- var __copyProps = (to, from, except, desc) => {
17
- if (from && typeof from === "object" || typeof from === "function") {
18
- for (let key of __getOwnPropNames(from))
19
- if (!__hasOwnProp.call(to, key) && key !== except)
20
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
- }
22
- return to;
104
+
105
+ //#endregion
106
+ //#region src/Di/ContainerResolver.ts
107
+ var ContainerResolver = class ContainerResolver {
108
+ constructor(app) {
109
+ this.app = app;
110
+ }
111
+ async resolveMethodParams(instance, method, _default) {
112
+ /**
113
+ * Get param types for instance method
114
+ */
115
+ let params = Reflect.getMetadata("design:paramtypes", instance, String(method)) || [];
116
+ /**
117
+ * Ensure that the Application class is always available
118
+ */
119
+ if (params.length < 1 && _default) params = [_default];
120
+ /**
121
+ * Resolve the bound dependencies
122
+ */
123
+ let args = params.filter((e) => ContainerResolver.isClass(e)).map((type) => {
124
+ return this.app.make(type);
125
+ });
126
+ return new Promise((resolve) => {
127
+ resolve(instance[method](...args));
128
+ });
129
+ }
130
+ static isClass(C) {
131
+ return typeof C === "function" && C.prototype !== void 0 && Object.toString.call(C).substring(0, 5) === "class";
132
+ }
23
133
  };
24
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
- // If the importer is in node compatibility mode or this is not an ESM
26
- // file that has been converted to a CommonJS file using a Babel-
27
- // compatible transform (i.e. "__esModule" has not been set), then set
28
- // "default" to the CommonJS "module.exports" for node compatibility.
29
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
- mod
31
- ));
32
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
134
 
34
- // src/Container.ts
35
- var Container;
36
- var init_Container = __esm({
37
- "src/Container.ts"() {
38
- "use strict";
39
- Container = class {
40
- static {
41
- __name(this, "Container");
42
- }
43
- bindings = /* @__PURE__ */ new Map();
44
- singletons = /* @__PURE__ */ new Map();
45
- /**
46
- * Check if the target has any decorators
47
- *
48
- * @param target
49
- * @returns
50
- */
51
- static hasAnyDecorator(target) {
52
- if (Reflect.getMetadataKeys(target).length > 0) return true;
53
- const paramLength = target.length;
54
- for (let i = 0; i < paramLength; i++) {
55
- if (Reflect.getMetadataKeys(target, `__param_${i}`).length > 0) {
56
- return true;
57
- }
58
- }
59
- return false;
60
- }
61
- bind(key, factory) {
62
- this.bindings.set(key, factory);
63
- }
64
- /**
65
- * Bind a singleton service to the container
66
- */
67
- singleton(key, factory) {
68
- this.bindings.set(key, () => {
69
- if (!this.singletons.has(key)) {
70
- this.singletons.set(key, factory());
71
- }
72
- return this.singletons.get(key);
73
- });
74
- }
75
- /**
76
- * Resolve a service from the container
77
- */
78
- make(key) {
79
- if (this.bindings.has(key)) {
80
- return this.bindings.get(key)();
81
- }
82
- if (typeof key === "function") {
83
- return this.build(key);
84
- }
85
- throw new Error(`No binding found for key: ${typeof key === "string" ? key : key?.name}`);
86
- }
87
- /**
88
- * Automatically build a class with constructor dependency injection
89
- */
90
- build(ClassType) {
91
- let dependencies = [];
92
- if (Array.isArray(ClassType.__inject__)) {
93
- dependencies = ClassType.__inject__.map((alias) => {
94
- return this.make(alias);
95
- });
96
- } else {
97
- const paramTypes = Reflect.getMetadata("design:paramtypes", ClassType) || [];
98
- dependencies = paramTypes.map((dep) => this.make(dep));
99
- }
100
- return new ClassType(...dependencies);
101
- }
102
- /**
103
- * Check if a service is registered
104
- */
105
- has(key) {
106
- return this.bindings.has(key);
107
- }
108
- };
109
- }
110
- });
135
+ //#endregion
136
+ //#region src/Registerer.ts
137
+ var Registerer = class Registerer {
138
+ constructor(app) {
139
+ this.app = app;
140
+ }
141
+ static register(app) {
142
+ new Registerer(app).bootRegister();
143
+ }
144
+ bootRegister() {
145
+ globalThis.dd = __h3ravel_support.dd;
146
+ globalThis.dump = __h3ravel_support.dump;
147
+ globalThis.app_path = (path$1) => this.appPath(path$1);
148
+ globalThis.base_path = (path$1) => this.basePath(path$1);
149
+ globalThis.public_path = (path$1) => this.publicPath(path$1);
150
+ globalThis.storage_path = (path$1) => this.storagePath(path$1);
151
+ globalThis.database_path = (path$1) => this.databasePath(path$1);
152
+ }
153
+ appPath(path$1) {
154
+ return this.app.getPath("base", node_path.default.join(`/${process.env.SRC_PATH ?? "src"}/`.replace(/([^:]\/)\/+/g, "$1"), "app", path$1 ?? ""));
155
+ }
156
+ basePath(path$1) {
157
+ return this.app.getPath("base", path$1);
158
+ }
159
+ publicPath(path$1) {
160
+ return this.app.getPath("public", path$1);
161
+ }
162
+ storagePath(path$1) {
163
+ return this.app.getPath("base", node_path.default.join("storage", path$1 ?? ""));
164
+ }
165
+ databasePath(path$1) {
166
+ return this.app.getPath("database", path$1);
167
+ }
168
+ };
111
169
 
112
- // src/Registerer.ts
113
- var import_support, Registerer;
114
- var init_Registerer = __esm({
115
- "src/Registerer.ts"() {
116
- "use strict";
117
- import_support = require("@h3ravel/support");
118
- Registerer = class {
119
- static {
120
- __name(this, "Registerer");
121
- }
122
- static register() {
123
- globalThis.dd = import_support.dd;
124
- globalThis.dump = import_support.dump;
125
- }
126
- };
127
- }
128
- });
170
+ //#endregion
171
+ //#region src/Application.ts
172
+ var Application = class Application extends Container {
173
+ paths = new __h3ravel_shared.PathLoader();
174
+ tries = 0;
175
+ booted = false;
176
+ versions = {
177
+ app: "0",
178
+ ts: "0"
179
+ };
180
+ basePath;
181
+ providers = [];
182
+ externalProviders = [];
183
+ /**
184
+ * List of registered console commands
185
+ */
186
+ registeredCommands = [];
187
+ constructor(basePath) {
188
+ super();
189
+ dotenv_expand.default.expand(dotenv.default.config({ quiet: true }));
190
+ this.basePath = basePath;
191
+ this.setPath("base", basePath);
192
+ this.loadOptions();
193
+ this.registerBaseBindings();
194
+ Registerer.register(this);
195
+ }
196
+ /**
197
+ * Register core bindings into the container
198
+ */
199
+ registerBaseBindings() {
200
+ this.bind(Application, () => this);
201
+ this.bind("path.base", () => this.basePath);
202
+ this.bind("load.paths", () => this.paths);
203
+ }
204
+ /**
205
+ * Dynamically register all configured providers
206
+ */
207
+ async registerConfiguredProviders() {
208
+ const providers = await this.getAllProviders();
209
+ for (const ProviderClass of providers) {
210
+ if (!ProviderClass) continue;
211
+ const provider = new ProviderClass(this);
212
+ await this.register(provider);
213
+ }
214
+ }
215
+ async loadOptions() {
216
+ const app = await this.safeImport(this.getPath("base", "package.json"));
217
+ const core = await this.safeImport("../package.json");
218
+ if (app && app.dependencies) this.versions.app = app.dependencies["@h3ravel/core"];
219
+ if (core && core.devDependencies) this.versions.ts = app.devDependencies.typescript;
220
+ }
221
+ /**
222
+ * Get all registered providers
223
+ */
224
+ getRegisteredProviders() {
225
+ return this.providers;
226
+ }
227
+ /**
228
+ * Load default and optional providers dynamically
229
+ *
230
+ * Auto-Registration Behavior
231
+ *
232
+ * Minimal App: Loads only core, config, http, router by default.
233
+ * Full-Stack App: Installs database, mail, queue, cache → they self-register via their providers.
234
+ */
235
+ async getConfiguredProviders() {
236
+ return [(await Promise.resolve().then(() => require("./index.cjs"))).CoreServiceProvider, (await Promise.resolve().then(() => require("./index.cjs"))).ViewServiceProvider];
237
+ }
238
+ async getAllProviders() {
239
+ const allProviders = [...await this.getConfiguredProviders(), ...this.externalProviders];
240
+ /**
241
+ * Deduplicate by class reference
242
+ */
243
+ const uniqueProviders = Array.from(new Set(allProviders));
244
+ return this.sortProviders(uniqueProviders);
245
+ }
246
+ sortProviders(providers) {
247
+ const priorityMap = /* @__PURE__ */ new Map();
248
+ /**
249
+ * Base priority (default 0)
250
+ */
251
+ providers.forEach((Provider) => {
252
+ priorityMap.set(Provider.name, Provider.priority ?? 0);
253
+ });
254
+ /**
255
+ * Handle before/after adjustments
256
+ */
257
+ providers.forEach((Provider) => {
258
+ const order = Provider.order;
259
+ if (!order) return;
260
+ const [direction, target] = order.split(":");
261
+ const targetPriority = priorityMap.get(target) ?? 0;
262
+ if (direction === "before") priorityMap.set(Provider.name, targetPriority - 1);
263
+ else if (direction === "after") priorityMap.set(Provider.name, targetPriority + 1);
264
+ });
265
+ /**
266
+ * Service providers sorted based on thier name and priority
267
+ */
268
+ const sorted = providers.sort((A, B) => (priorityMap.get(B.name) ?? 0) - (priorityMap.get(A.name) ?? 0));
269
+ /**
270
+ * If debug is enabled, let's show the loaded service provider info
271
+ */
272
+ if (process.env.APP_DEBUG === "true" && process.env.EXTENDED_DEBUG !== "false" && !sorted.some((e) => e.console)) {
273
+ console.table(sorted.map((P) => ({
274
+ Provider: P.name,
275
+ Priority: priorityMap.get(P.name),
276
+ Order: P.order || "N/A"
277
+ })));
278
+ console.info(`Set ${chalk.default.bgCyan(" APP_DEBUG = false ")} in your .env file to hide this information`, "\n");
279
+ }
280
+ return sorted;
281
+ }
282
+ registerProviders(providers) {
283
+ this.externalProviders.push(...providers);
284
+ }
285
+ /**
286
+ * Register a provider
287
+ */
288
+ async register(provider) {
289
+ await new ContainerResolver(this).resolveMethodParams(provider, "register", this);
290
+ if (provider.registeredCommands && provider.registeredCommands.length > 0) this.registeredCommands.push(...provider.registeredCommands);
291
+ this.providers.push(provider);
292
+ }
293
+ /**
294
+ * checks if the application is running in CLI
295
+ */
296
+ runningInConsole() {
297
+ return typeof process !== "undefined" && !!process.stdout && !!process.stdin;
298
+ }
299
+ getRuntimeEnv() {
300
+ if (typeof window !== "undefined" && typeof document !== "undefined") return "browser";
301
+ if (typeof process !== "undefined" && process.versions?.node) return "node";
302
+ return "unknown";
303
+ }
304
+ /**
305
+ * Boot all service providers after registration
306
+ */
307
+ async boot() {
308
+ if (this.booted) return;
309
+ for (const provider of this.providers) if (provider.boot) if (Container.hasAnyDecorator(provider.boot))
310
+ /**
311
+ * If the service provider is decorated use the IoC container
312
+ */
313
+ await this.make(provider.boot);
314
+ else
315
+ /**
316
+ * Otherwise instantiate manually so that we can at least
317
+ * pass the app instance
318
+ */
319
+ await provider.boot(this);
320
+ this.booted = true;
321
+ }
322
+ /**
323
+ * Fire up the developement server using the user provided arguments
324
+ *
325
+ * Port will be auto assigned if provided one is not available
326
+ *
327
+ * @param h3App The current H3 app instance
328
+ * @param preferedPort If provided, this will overide the port set in the evironment
329
+ */
330
+ async fire(h3App, preferedPort) {
331
+ const serve = this.make("http.serve");
332
+ const port = preferedPort ?? env("PORT", 3e3);
333
+ const tries = env("RETRIES", 1);
334
+ const hostname = env("HOSTNAME", "localhost");
335
+ try {
336
+ const realPort = await (0, detect_port.detect)(port);
337
+ if (port == realPort) {
338
+ const server = serve(h3App, {
339
+ port,
340
+ hostname,
341
+ silent: true
342
+ });
343
+ __h3ravel_shared.Logger.parse([[`🚀 H3ravel running at:`, "green"], [`${server.options.protocol ?? "http"}://${server.options.hostname}:${server.options.port}`, "cyan"]]);
344
+ } else if (this.tries <= tries) {
345
+ await this.fire(h3App, realPort);
346
+ this.tries++;
347
+ } else __h3ravel_shared.Logger.parse([["ERROR:", "bgRed"], ["No free port available", "red"]]);
348
+ } catch (e) {
349
+ __h3ravel_shared.Logger.parse([
350
+ ["An error occured", "bgRed"],
351
+ [e.message, "red"],
352
+ [e.stack, "red"]
353
+ ], "\n");
354
+ }
355
+ }
356
+ /**
357
+ * Attempt to dynamically import an optional module
358
+ */
359
+ async safeImport(moduleName) {
360
+ try {
361
+ const mod = await import(moduleName);
362
+ return mod.default ?? mod ?? {};
363
+ } catch {
364
+ return null;
365
+ }
366
+ }
367
+ /**
368
+ * Get the base path of the app
369
+ *
370
+ * @returns
371
+ */
372
+ getBasePath() {
373
+ return this.basePath;
374
+ }
375
+ /**
376
+ * Dynamically retrieves a path property from the class.
377
+ * Any property ending with "Path" is accessible automatically.
378
+ *
379
+ * @param name - The base name of the path property
380
+ * @returns
381
+ */
382
+ getPath(name, suffix) {
383
+ return node_path.default.join(this.paths.getPath(name, this.basePath), suffix ?? "");
384
+ }
385
+ /**
386
+ * Programatically set the paths.
387
+ *
388
+ * @param name - The base name of the path property
389
+ * @param path - The new path
390
+ * @returns
391
+ */
392
+ setPath(name, path$1) {
393
+ return this.paths.setPath(name, path$1, this.basePath);
394
+ }
395
+ /**
396
+ * Returns the installed version of the system core and typescript.
397
+ *
398
+ * @returns
399
+ */
400
+ getVersion(key) {
401
+ return this.versions[key]?.replaceAll(/\^|~/g, "");
402
+ }
403
+ };
129
404
 
130
- // src/Application.ts
131
- var import_shared, import_dotenv, import_node_path, Application;
132
- var init_Application = __esm({
133
- "src/Application.ts"() {
134
- "use strict";
135
- init_Container();
136
- import_shared = require("@h3ravel/shared");
137
- init_Registerer();
138
- import_dotenv = __toESM(require("dotenv"), 1);
139
- import_node_path = __toESM(require("path"), 1);
140
- Application = class _Application extends Container {
141
- static {
142
- __name(this, "Application");
143
- }
144
- paths = new import_shared.PathLoader();
145
- booted = false;
146
- versions = {
147
- app: "0",
148
- ts: "0"
149
- };
150
- basePath;
151
- providers = [];
152
- externalProviders = [];
153
- constructor(basePath) {
154
- super();
155
- this.basePath = basePath;
156
- this.setPath("base", basePath);
157
- this.loadOptions();
158
- this.registerBaseBindings();
159
- Registerer.register();
160
- import_dotenv.default.config({
161
- quiet: true
162
- });
163
- }
164
- /**
165
- * Register core bindings into the container
166
- */
167
- registerBaseBindings() {
168
- this.bind(_Application, () => this);
169
- this.bind("path.base", () => this.basePath);
170
- this.bind("load.paths", () => this.paths);
171
- }
172
- /**
173
- * Dynamically register all configured providers
174
- */
175
- async registerConfiguredProviders() {
176
- const providers = await this.getAllProviders();
177
- for (const ProviderClass of providers) {
178
- if (!ProviderClass) continue;
179
- const provider = new ProviderClass(this);
180
- await this.register(provider);
181
- }
182
- }
183
- async loadOptions() {
184
- const app = await this.safeImport(this.getPath("base", "package.json"));
185
- const core = await this.safeImport("../package.json");
186
- if (app && app.dependencies) {
187
- this.versions.app = app.dependencies["@h3ravel/core"];
188
- }
189
- if (core && core.devDependencies) {
190
- this.versions.ts = app.devDependencies.typescript;
191
- }
192
- }
193
- /**
194
- * Load default and optional providers dynamically
195
- *
196
- * Auto-Registration Behavior
197
- *
198
- * Minimal App: Loads only core, config, http, router by default.
199
- * Full-Stack App: Installs database, mail, queue, cache → they self-register via their providers.
200
- */
201
- async getConfiguredProviders() {
202
- return [
203
- (await Promise.resolve().then(() => (init_index(), index_exports))).CoreServiceProvider,
204
- (await Promise.resolve().then(() => (init_index(), index_exports))).ViewServiceProvider
205
- ];
206
- }
207
- async getAllProviders() {
208
- const coreProviders = await this.getConfiguredProviders();
209
- const allProviders = [
210
- ...coreProviders,
211
- ...this.externalProviders
212
- ];
213
- const uniqueProviders = Array.from(new Set(allProviders));
214
- return this.sortProviders(uniqueProviders);
215
- }
216
- sortProviders(providers) {
217
- const priorityMap = /* @__PURE__ */ new Map();
218
- providers.forEach((Provider) => {
219
- priorityMap.set(Provider.name, Provider.priority ?? 0);
220
- });
221
- providers.forEach((Provider) => {
222
- const order = Provider.order;
223
- if (!order) return;
224
- const [direction, target] = order.split(":");
225
- const targetPriority = priorityMap.get(target) ?? 0;
226
- if (direction === "before") {
227
- priorityMap.set(Provider.name, targetPriority - 1);
228
- } else if (direction === "after") {
229
- priorityMap.set(Provider.name, targetPriority + 1);
230
- }
231
- });
232
- const sorted = providers.sort((A, B) => (priorityMap.get(B.name) ?? 0) - (priorityMap.get(A.name) ?? 0));
233
- if (process.env.APP_DEBUG === "true") {
234
- console.table(sorted.map((P) => ({
235
- Provider: P.name,
236
- Priority: priorityMap.get(P.name),
237
- Order: P.order || "N/A"
238
- })));
239
- }
240
- return sorted;
241
- }
242
- registerProviders(providers) {
243
- this.externalProviders.push(...providers);
244
- }
245
- /**
246
- * Register a provider
247
- */
248
- async register(provider) {
249
- await provider.register();
250
- this.providers.push(provider);
251
- }
252
- /**
253
- * Boot all providers after registration
254
- */
255
- async boot() {
256
- if (this.booted) return;
257
- for (const provider of this.providers) {
258
- if (provider.boot) {
259
- await provider.boot();
260
- }
261
- }
262
- this.booted = true;
263
- }
264
- /**
265
- * Attempt to dynamically import an optional module
266
- */
267
- async safeImport(moduleName) {
268
- try {
269
- const mod = await import(moduleName);
270
- return mod.default ?? mod ?? {};
271
- } catch {
272
- return null;
273
- }
274
- }
275
- /**
276
- * Get the base path of the app
277
- *
278
- * @returns
279
- */
280
- getBasePath() {
281
- return this.basePath;
282
- }
283
- /**
284
- * Dynamically retrieves a path property from the class.
285
- * Any property ending with "Path" is accessible automatically.
286
- *
287
- * @param name - The base name of the path property
288
- * @returns
289
- */
290
- getPath(name, pth) {
291
- return import_node_path.default.join(this.paths.getPath(name, this.basePath), pth ?? "");
292
- }
293
- /**
294
- * Programatically set the paths.
295
- *
296
- * @param name - The base name of the path property
297
- * @param path - The new path
298
- * @returns
299
- */
300
- setPath(name, path2) {
301
- return this.paths.setPath(name, path2, this.basePath);
302
- }
303
- /**
304
- * Returns the installed version of the system core and typescript.
305
- *
306
- * @returns
307
- */
308
- getVersion(key) {
309
- return this.versions[key]?.replaceAll(/\^|~/g, "");
310
- }
311
- };
312
- }
313
- });
405
+ //#endregion
406
+ //#region src/Console/ConsoleCommand.ts
407
+ var ConsoleCommand = class {
408
+ constructor(app, kernel) {
409
+ this.app = app;
410
+ this.kernel = kernel;
411
+ }
412
+ /**
413
+ * The underlying commander instance.
414
+ *
415
+ * @var Command
416
+ */
417
+ program;
418
+ /**
419
+ * The name and signature of the console command.
420
+ *
421
+ * @var string
422
+ */
423
+ signature;
424
+ /**
425
+ * A dictionary of signatures or what not.
426
+ *
427
+ * @var object
428
+ */
429
+ dictionary = {};
430
+ /**
431
+ * The console command description.
432
+ *
433
+ * @var string
434
+ */
435
+ description;
436
+ /**
437
+ * The console command input.
438
+ *
439
+ * @var object
440
+ */
441
+ input = {
442
+ options: {},
443
+ arguments: {}
444
+ };
445
+ /**
446
+ * Execute the console command.
447
+ */
448
+ async handle(..._args) {}
449
+ setApplication(app) {
450
+ this.app = app;
451
+ }
452
+ setInput(options, args, regArgs, dictionary, program) {
453
+ this.program = program;
454
+ this.dictionary = dictionary;
455
+ this.input.options = options;
456
+ this.input.arguments = regArgs.map((e, i) => ({ [e.name()]: args[i] })).reduce((e, x) => Object.assign(e, x), {});
457
+ }
458
+ getSignature() {
459
+ return this.signature;
460
+ }
461
+ getDescription() {
462
+ return this.description;
463
+ }
464
+ option(key, def) {
465
+ return this.input.options[key] ?? def;
466
+ }
467
+ options(key) {
468
+ if (key) return this.input.options[key];
469
+ return this.input.options;
470
+ }
471
+ argument(key, def) {
472
+ return this.input.arguments[key] ?? def;
473
+ }
474
+ arguments() {
475
+ return this.input.arguments;
476
+ }
477
+ };
314
478
 
315
- // src/Contracts/ServiceProviderConstructor.ts
316
- var init_ServiceProviderConstructor = __esm({
317
- "src/Contracts/ServiceProviderConstructor.ts"() {
318
- "use strict";
319
- }
320
- });
479
+ //#endregion
480
+ //#region src/Console/ConsoleKernel.ts
481
+ var ConsoleKernel = class {
482
+ cwd;
483
+ output = typeof __h3ravel_shared.Logger;
484
+ basePath = "";
485
+ modulePath;
486
+ consolePath;
487
+ modulePackage;
488
+ consolePackage;
489
+ constructor(app) {
490
+ this.app = app;
491
+ }
492
+ async ensureDirectoryExists(dir) {
493
+ await (0, node_fs_promises.mkdir)(dir, { recursive: true });
494
+ }
495
+ };
321
496
 
322
- // src/Controller.ts
323
- var Controller;
324
- var init_Controller = __esm({
325
- "src/Controller.ts"() {
326
- "use strict";
327
- Controller = class {
328
- static {
329
- __name(this, "Controller");
330
- }
331
- app;
332
- constructor(app) {
333
- this.app = app;
334
- }
335
- show(..._ctx) {
336
- return;
337
- }
338
- index(..._ctx) {
339
- return;
340
- }
341
- store(..._ctx) {
342
- return;
343
- }
344
- update(..._ctx) {
345
- return;
346
- }
347
- destroy(..._ctx) {
348
- return;
349
- }
350
- };
351
- }
352
- });
497
+ //#endregion
498
+ //#region src/Controller.ts
499
+ /**
500
+ * Base controller class
501
+ */
502
+ var Controller = class {
503
+ app;
504
+ constructor(app) {
505
+ this.app = app;
506
+ }
507
+ show(..._ctx) {}
508
+ index(..._ctx) {}
509
+ store(..._ctx) {}
510
+ update(..._ctx) {}
511
+ destroy(..._ctx) {}
512
+ };
353
513
 
354
- // src/Di/Inject.ts
514
+ //#endregion
515
+ //#region src/Di/Inject.ts
355
516
  function Inject(...dependencies) {
356
- return function(target) {
357
- target.__inject__ = dependencies;
358
- };
517
+ return function(target) {
518
+ target.__inject__ = dependencies;
519
+ };
359
520
  }
521
+ /**
522
+ * Allows binding dependencies to both class and class methods
523
+ *
524
+ * @returns
525
+ */
360
526
  function Injectable() {
361
- return (...args) => {
362
- if (args.length === 1) {
363
- void args[0];
364
- }
365
- if (args.length === 3) {
366
- void args[0];
367
- void args[1];
368
- void args[2];
369
- }
370
- };
527
+ return (...args) => {
528
+ if (args.length === 1) args[0];
529
+ if (args.length === 3) {
530
+ args[0];
531
+ args[1];
532
+ args[2];
533
+ }
534
+ };
371
535
  }
372
- var init_Inject = __esm({
373
- "src/Di/Inject.ts"() {
374
- "use strict";
375
- __name(Inject, "Inject");
376
- __name(Injectable, "Injectable");
377
- }
378
- });
379
536
 
380
- // src/Exceptions/Handler.ts
381
- var init_Handler = __esm({
382
- "src/Exceptions/Handler.ts"() {
383
- "use strict";
384
- }
385
- });
386
-
387
- // src/Http/Kernel.ts
388
- var Kernel;
389
- var init_Kernel = __esm({
390
- "src/Http/Kernel.ts"() {
391
- "use strict";
392
- Kernel = class {
393
- static {
394
- __name(this, "Kernel");
395
- }
396
- context;
397
- middleware;
398
- /**
399
- * @param context - A factory function that converts an H3Event into an HttpContext.
400
- * @param middleware - An array of middleware classes that will be executed in sequence.
401
- */
402
- constructor(context, middleware = []) {
403
- this.context = context;
404
- this.middleware = middleware;
405
- }
406
- /**
407
- * Handles an incoming request and passes it through middleware before invoking the next handler.
408
- *
409
- * @param event - The raw H3 event object.
410
- * @param next - A callback function that represents the next layer (usually the controller or final handler).
411
- * @returns A promise resolving to the result of the request pipeline.
412
- */
413
- async handle(event, next) {
414
- const ctx = this.context(event);
415
- const { app } = ctx.request;
416
- app.bind("view", () => async (template, params) => {
417
- const edge = app.make("edge");
418
- return ctx.response.html(await edge.render(template, params));
419
- });
420
- const result = await this.runMiddleware(ctx, () => next(ctx));
421
- if (result !== void 0 && this.isPlainObject(result)) {
422
- event.res.headers.set("Content-Type", "application/json; charset=UTF-8");
423
- }
424
- return result;
425
- }
426
- /**
427
- * Sequentially runs middleware in the order they were registered.
428
- *
429
- * @param context - The standardized HttpContext.
430
- * @param next - Callback to execute when middleware completes.
431
- * @returns A promise resolving to the final handler's result.
432
- */
433
- async runMiddleware(context, next) {
434
- let index = -1;
435
- const runner = /* @__PURE__ */ __name(async (i) => {
436
- if (i <= index) throw new Error("next() called multiple times");
437
- index = i;
438
- const middleware = this.middleware[i];
439
- if (middleware) {
440
- return middleware.handle(context, () => runner(i + 1));
441
- } else {
442
- return next(context);
443
- }
444
- }, "runner");
445
- return runner(0);
446
- }
447
- /**
448
- * Utility function to determine if a value is a plain object or array.
449
- *
450
- * @param value - The value to check.
451
- * @returns True if the value is a plain object or array, otherwise false.
452
- */
453
- isPlainObject(value) {
454
- return typeof value === "object" && value !== null && (value.constructor === Object || value.constructor === Array);
455
- }
456
- };
457
- }
458
- });
537
+ //#endregion
538
+ //#region src/Http/Kernel.ts
539
+ /**
540
+ * Kernel class handles middleware execution and response transformations.
541
+ * It acts as the core middleware pipeline for HTTP requests.
542
+ */
543
+ var Kernel = class {
544
+ /**
545
+ * @param context - A factory function that converts an H3Event into an HttpContext.
546
+ * @param middleware - An array of middleware classes that will be executed in sequence.
547
+ */
548
+ constructor(context, middleware = []) {
549
+ this.context = context;
550
+ this.middleware = middleware;
551
+ }
552
+ /**
553
+ * Handles an incoming request and passes it through middleware before invoking the next handler.
554
+ *
555
+ * @param event - The raw H3 event object.
556
+ * @param next - A callback function that represents the next layer (usually the controller or final handler).
557
+ * @returns A promise resolving to the result of the request pipeline.
558
+ */
559
+ async handle(event, next) {
560
+ /**
561
+ * Convert the raw event into a standardized HttpContext
562
+ */
563
+ const ctx = this.context(event);
564
+ const { app } = ctx.request;
565
+ /**
566
+ * Dynamically bind the view renderer to the service container.
567
+ * This allows any part of the request lifecycle to render templates using Edge.
568
+ */
569
+ app.bind("view", () => async (template, params) => {
570
+ const edge = app.make("edge");
571
+ return ctx.response.html(await edge.render(template, params));
572
+ });
573
+ /**
574
+ * Run middleware stack and obtain result
575
+ */
576
+ const result = await this.runMiddleware(ctx, () => next(ctx));
577
+ /**
578
+ * If a plain object is returned from a controller or middleware,
579
+ * automatically set the JSON Content-Type header for the response.
580
+ */
581
+ if (result !== void 0 && this.isPlainObject(result)) event.res.headers.set("Content-Type", "application/json; charset=UTF-8");
582
+ return result;
583
+ }
584
+ /**
585
+ * Sequentially runs middleware in the order they were registered.
586
+ *
587
+ * @param context - The standardized HttpContext.
588
+ * @param next - Callback to execute when middleware completes.
589
+ * @returns A promise resolving to the final handler's result.
590
+ */
591
+ async runMiddleware(context, next) {
592
+ let index = -1;
593
+ const runner = async (i) => {
594
+ if (i <= index) throw new Error("next() called multiple times");
595
+ index = i;
596
+ const middleware = this.middleware[i];
597
+ if (middleware)
598
+ /**
599
+ * Execute the current middleware and proceed to the next one
600
+ */
601
+ return middleware.handle(context, () => runner(i + 1));
602
+ else
603
+ /**
604
+ * If no more middleware, call the final handler
605
+ */
606
+ return next(context);
607
+ };
608
+ return runner(0);
609
+ }
610
+ /**
611
+ * Utility function to determine if a value is a plain object or array.
612
+ *
613
+ * @param value - The value to check.
614
+ * @returns True if the value is a plain object or array, otherwise false.
615
+ */
616
+ isPlainObject(value) {
617
+ return typeof value === "object" && value !== null && (value.constructor === Object || value.constructor === Array);
618
+ }
619
+ };
459
620
 
460
- // src/ServiceProvider.ts
461
- var ServiceProvider;
462
- var init_ServiceProvider = __esm({
463
- "src/ServiceProvider.ts"() {
464
- "use strict";
465
- ServiceProvider = class {
466
- static {
467
- __name(this, "ServiceProvider");
468
- }
469
- static order;
470
- static priority = 0;
471
- app;
472
- constructor(app) {
473
- this.app = app;
474
- }
475
- };
476
- }
477
- });
621
+ //#endregion
622
+ //#region src/ServiceProvider.ts
623
+ var ServiceProvider = class {
624
+ /**
625
+ * Sort order
626
+ */
627
+ static order;
628
+ /**
629
+ * Sort priority
630
+ */
631
+ static priority = 0;
632
+ /**
633
+ * Indicate that this service provider only runs in console
634
+ */
635
+ static console = false;
636
+ /**
637
+ * List of registered console commands
638
+ */
639
+ registeredCommands;
640
+ app;
641
+ constructor(app) {
642
+ this.app = app;
643
+ }
644
+ /**
645
+ * An array of console commands to register.
646
+ */
647
+ commands(commands) {
648
+ this.registeredCommands = commands;
649
+ }
650
+ };
478
651
 
479
- // src/Providers/CoreServiceProvider.ts
480
- var import_reflect_metadata, CoreServiceProvider;
481
- var init_CoreServiceProvider = __esm({
482
- "src/Providers/CoreServiceProvider.ts"() {
483
- "use strict";
484
- import_reflect_metadata = require("reflect-metadata");
485
- init_ServiceProvider();
486
- CoreServiceProvider = class extends ServiceProvider {
487
- static {
488
- __name(this, "CoreServiceProvider");
489
- }
490
- static priority = 999;
491
- register() {
492
- }
493
- };
494
- }
495
- });
652
+ //#endregion
653
+ //#region src/Providers/CoreServiceProvider.ts
654
+ /**
655
+ * Bootstraps core services and bindings.
656
+ *
657
+ * Bind essential services to the container (logger, config repository).
658
+ * Register app-level singletons.
659
+ * Set up exception handling.
660
+ *
661
+ * Auto-Registered
662
+ */
663
+ var CoreServiceProvider = class extends ServiceProvider {
664
+ static priority = 999;
665
+ register() {}
666
+ };
496
667
 
497
- // src/Providers/ViewServiceProvider.ts
498
- var import_edge, ViewServiceProvider;
499
- var init_ViewServiceProvider = __esm({
500
- "src/Providers/ViewServiceProvider.ts"() {
501
- "use strict";
502
- import_edge = require("edge.js");
503
- init_ServiceProvider();
504
- ViewServiceProvider = class extends ServiceProvider {
505
- static {
506
- __name(this, "ViewServiceProvider");
507
- }
508
- static priority = 995;
509
- register() {
510
- const config = this.app.make("config");
511
- const edge = import_edge.Edge.create({
512
- cache: process.env.NODE_ENV === "production"
513
- });
514
- edge.mount(this.app.getPath("views"));
515
- edge.global("asset", this.app.make("asset"));
516
- edge.global("config", config.get);
517
- edge.global("app", this.app);
518
- this.app.bind("edge", () => edge);
519
- }
520
- };
521
- }
522
- });
668
+ //#endregion
669
+ //#region src/Providers/ViewServiceProvider.ts
670
+ var ViewServiceProvider = class extends ServiceProvider {
671
+ static priority = 995;
672
+ register() {
673
+ const config = this.app.make("config");
674
+ const edge = edge_js.Edge.create({ cache: process.env.NODE_ENV === "production" });
675
+ edge.mount(this.app.getPath("views"));
676
+ edge.global("asset", this.app.make("asset"));
677
+ edge.global("config", config.get);
678
+ edge.global("app", this.app);
679
+ this.app.bind("edge", () => edge);
680
+ }
681
+ };
523
682
 
524
- // src/index.ts
525
- var index_exports = {};
526
- __export(index_exports, {
527
- Application: () => Application,
528
- Container: () => Container,
529
- Controller: () => Controller,
530
- CoreServiceProvider: () => CoreServiceProvider,
531
- Inject: () => Inject,
532
- Injectable: () => Injectable,
533
- Kernel: () => Kernel,
534
- Registerer: () => Registerer,
535
- ServiceProvider: () => ServiceProvider,
536
- ViewServiceProvider: () => ViewServiceProvider
537
- });
538
- module.exports = __toCommonJS(index_exports);
539
- var init_index = __esm({
540
- "src/index.ts"() {
541
- init_Application();
542
- init_Container();
543
- init_ServiceProviderConstructor();
544
- init_Controller();
545
- init_Inject();
546
- init_Handler();
547
- init_Kernel();
548
- init_CoreServiceProvider();
549
- init_ViewServiceProvider();
550
- init_Registerer();
551
- init_ServiceProvider();
552
- }
553
- });
554
- init_index();
555
- // Annotate the CommonJS export names for ESM import in node:
556
- 0 && (module.exports = {
557
- Application,
558
- Container,
559
- Controller,
560
- CoreServiceProvider,
561
- Inject,
562
- Injectable,
563
- Kernel,
564
- Registerer,
565
- ServiceProvider,
566
- ViewServiceProvider
567
- });
683
+ //#endregion
684
+ exports.Application = Application;
685
+ exports.ConsoleCommand = ConsoleCommand;
686
+ exports.ConsoleKernel = ConsoleKernel;
687
+ exports.Container = Container;
688
+ exports.ContainerResolver = ContainerResolver;
689
+ exports.Controller = Controller;
690
+ exports.CoreServiceProvider = CoreServiceProvider;
691
+ exports.Inject = Inject;
692
+ exports.Injectable = Injectable;
693
+ exports.Kernel = Kernel;
694
+ exports.Registerer = Registerer;
695
+ exports.ServiceProvider = ServiceProvider;
696
+ exports.ViewServiceProvider = ViewServiceProvider;
568
697
  //# sourceMappingURL=index.cjs.map