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