@h3ravel/core 1.21.7 → 1.22.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6,12 +6,16 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
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
- });
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
15
19
  }
16
20
  return to;
17
21
  };
@@ -23,7 +27,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
27
  //#endregion
24
28
  require("reflect-metadata");
25
29
  let __h3ravel_shared = require("@h3ravel/shared");
30
+ let h3 = require("h3");
31
+ let __h3ravel_contracts = require("@h3ravel/contracts");
26
32
  let __h3ravel_support = require("@h3ravel/support");
33
+ let __h3ravel_foundation = require("@h3ravel/foundation");
34
+ let module$1 = require("module");
27
35
  let fast_glob = require("fast-glob");
28
36
  fast_glob = __toESM(fast_glob);
29
37
  let node_path = require("node:path");
@@ -36,12 +44,91 @@ dotenv_expand = __toESM(dotenv_expand);
36
44
  let node_fs_promises = require("node:fs/promises");
37
45
  let semver = require("semver");
38
46
  semver = __toESM(semver);
39
- let __h3ravel_http = require("@h3ravel/http");
47
+ let node_module = require("node:module");
48
+ let __h3ravel_support_facades = require("@h3ravel/support/facades");
40
49
 
50
+ //#region src/Manager/ContainerResolver.ts
51
+ var ContainerResolver = class ContainerResolver {
52
+ constructor(app) {
53
+ this.app = app;
54
+ }
55
+ async resolveMethodParams(instance, method, ..._default) {
56
+ /**
57
+ * Get param types for instance method
58
+ */
59
+ let params = Reflect.getMetadata("design:paramtypes", instance, String(method)) || [];
60
+ /**
61
+ * Ensure that the Application class is always available
62
+ */
63
+ if (params.length < 1 && _default.length > 0) params = _default;
64
+ /**
65
+ * Resolve the bound dependencies
66
+ */
67
+ const args = params.filter((e) => ContainerResolver.isClass(e) || e instanceof Application).map((type) => {
68
+ if (type instanceof Application) return type;
69
+ return this.app.make(type);
70
+ });
71
+ return new Promise((resolve) => {
72
+ resolve(instance[method](...args));
73
+ });
74
+ }
75
+ static isClass(C) {
76
+ return typeof C === "function" && C.prototype !== void 0 && Object.toString.call(C).substring(0, 5) === "class";
77
+ }
78
+ static isAbstract(C) {
79
+ return this.isClass(C) && C.name.startsWith("I");
80
+ }
81
+ static isCallable(C) {
82
+ return typeof C === "function" && !ContainerResolver.isClass(C);
83
+ }
84
+ };
85
+
86
+ //#endregion
41
87
  //#region src/Container.ts
42
- var Container = class {
88
+ var Container = class Container extends __h3ravel_contracts.IContainer {
43
89
  bindings = /* @__PURE__ */ new Map();
44
90
  singletons = /* @__PURE__ */ new Map();
91
+ middlewareHandler;
92
+ /**
93
+ * The current globally available container (if any).
94
+ */
95
+ static instance;
96
+ /**
97
+ * All of the before resolving callbacks by class type.
98
+ */
99
+ beforeResolvingCallbacks = /* @__PURE__ */ new Map();
100
+ /**
101
+ * All of the after resolving callbacks by class type.
102
+ */
103
+ afterResolvingCallbacks = /* @__PURE__ */ new Map();
104
+ /**
105
+ * All of the registered rebound callbacks.
106
+ */
107
+ reboundCallbacks = /* @__PURE__ */ new Map();
108
+ /**
109
+ * The container's shared instances.
110
+ */
111
+ instances = /* @__PURE__ */ new Map();
112
+ /**
113
+ * The container's resolved instances.
114
+ */
115
+ resolvedInstances = /* @__PURE__ */ new Map();
116
+ /**
117
+ * The registered type alias.
118
+ */
119
+ aliases = /* @__PURE__ */ new Map();
120
+ /**
121
+ * The registered aliases keyed by the abstract name.
122
+ */
123
+ abstractAliases = /* @__PURE__ */ new Map();
124
+ /**
125
+ * The registered aliases keyed by the abstract name.
126
+ */
127
+ middlewares = /* @__PURE__ */ new Map();
128
+ /**
129
+ * The extension closures for services.
130
+ */
131
+ extenders = /* @__PURE__ */ new Map();
45
132
  static hasAnyDecorator(target) {
46
133
  if (Reflect.getMetadataKeys(target).length > 0) return true;
47
134
  const paramLength = target.length;
@@ -52,7 +139,22 @@ var Container = class {
52
139
  this.bindings.set(key, factory);
53
140
  }
54
141
  /**
142
+ * Bind unregistered middlewares to the service container so we can use them later
143
+ *
144
+ * @param key
145
+ * @param middleware
146
+ */
147
+ bindMiddleware(key, middleware) {
148
+ this.middlewares.set(key, middleware);
149
+ }
150
+ boundMiddlewares(key) {
151
+ if (key) return this.middlewares.get(key);
152
+ return this.middlewares.entries();
153
+ }
154
+ /**
55
155
  * Remove one or more transient services from the container
156
+ *
157
+ * @param key
56
158
  */
57
159
  unbind(key) {
58
160
  if (Array.isArray(key)) for (let i = 0; i < key.length; i++) {
@@ -64,28 +166,127 @@ var Container = class {
64
166
  this.singletons.delete(key);
65
167
  }
66
168
  }
67
- /**
68
- * Bind a singleton service to the container
69
- */
70
169
  singleton(key, factory) {
71
170
  this.bindings.set(key, () => {
72
- if (!this.singletons.has(key)) this.singletons.set(key, factory(this));
171
+ if (!this.singletons.has(key)) this.singletons.set(key, this.call(factory));
73
172
  return this.singletons.get(key);
74
173
  });
75
174
  }
175
+ /**
176
+ * Read reflected param types, resolve dependencies from the container and
177
+ * optionally transform them, finally invoke the specified method on a class instance
178
+ *
179
+ * @param instance
180
+ * @param method
181
+ * @param defaultArgs
182
+ * @param handler
183
+ * @returns
184
+ */
185
+ async invoke(instance, method, defaultArgs, handler) {
186
+ /**
187
+ * Get param types for the instance method
188
+ */
189
+ const paramTypes = Reflect.getMetadata("design:paramtypes", instance, method) || [];
190
+ /**
191
+ * Resolve the bound dependencies
192
+ */
193
+ let args = await Promise.all(paramTypes.map(async (paramType) => {
194
+ const inst = this.make(paramType);
195
+ if (handler) return await handler(inst);
196
+ return inst;
197
+ }));
198
+ /**
199
+ * Ensure that the args is always filled
200
+ */
201
+ if (args.length < 1) args = defaultArgs ?? [];
202
+ const fn = instance[method];
203
+ return Reflect.apply(fn, instance, args);
204
+ }
205
+ /**
206
+ * Read reflected param types, resolve dependencies from the container and return the result
207
+ *
208
+ * @param instance
209
+ * @param method
210
+ */
211
+ resolveParams(instance, method) {
212
+ /**
213
+ * Resolve and return the bound dependencies
214
+ */
215
+ return (Reflect.getMetadata("design:paramtypes", instance, method) || []).filter((e) => !!e).map((abstract) => {
216
+ if (typeof abstract === "function" && abstract.toString().startsWith("function Function")) return abstract;
217
+ return this.make(abstract);
218
+ });
219
+ }
76
220
  make(key) {
221
+ return this.resolve(key);
222
+ }
223
+ /**
224
+ * Resolve the gevein service from the container
225
+ *
226
+ * @param abstract
227
+ * @param raiseEvents
228
+ */
229
+ resolve(abstract, raiseEvents = true) {
230
+ abstract = this.getAlias(abstract);
77
231
  /**
78
232
  * Direct factory binding
79
233
  */
80
- if (this.bindings.has(key)) return this.bindings.get(key)();
81
- /**
234
+ let resolved;
235
+ if (this.resolvedInstances.has(abstract)) return this.resolvedInstances.get(abstract);
236
+ if (raiseEvents) this.runBeforeResolvingCallbacks(abstract);
237
+ if (this.bindings.has(abstract)) resolved = this.bindings.get(abstract)();
238
+ else if (this.instances.has(abstract)) resolved = this.instances.get(abstract);
239
+ else if (typeof abstract === "function")
240
+ /**
82
241
  * If this is a class constructor, auto-resolve via reflection
83
242
  */
84
- if (typeof key === "function") return this.build(key);
85
- throw new Error(`No binding found for key: ${typeof key === "string" ? key : key?.name}`);
243
+ resolved = this.build(abstract);
244
+ else throw new Error(`No binding found for key: ${typeof abstract === "string" ? abstract : abstract?.name}`);
245
+ /**
246
+ * If we defined any extenders for this type, we'll need to spin through them
247
+ * and apply them to the object being built. This allows for the extension
248
+ * of services, such as changing configuration or decorating the object.
249
+ */
250
+ for (const extender of this.getExtenders(abstract)) resolved = extender(resolved, this);
251
+ if (raiseEvents) this.runAfterResolvingCallbacks(abstract, resolved);
252
+ this.resolvedInstances.set(abstract, resolved);
253
+ return resolved;
254
+ }
255
+ afterResolving(key, callback) {
256
+ const existing = this.afterResolvingCallbacks.get(key) || [];
257
+ existing.push(callback);
258
+ this.afterResolvingCallbacks.set(key, existing);
259
+ }
260
+ beforeResolving(key, callback) {
261
+ const existing = this.beforeResolvingCallbacks.get(key) || [];
262
+ existing.push(callback);
263
+ this.beforeResolvingCallbacks.set(key, existing);
264
+ }
265
+ /**
266
+ * Execute all registered beforeResolving callbacks for a given key
267
+ *
268
+ * @param key
269
+ * @param resolved
270
+ */
271
+ runBeforeResolvingCallbacks(key) {
272
+ const callbacks = this.beforeResolvingCallbacks.get(key) || [];
273
+ for (let i = 0; i < callbacks.length; i++) callbacks[i](this);
274
+ }
275
+ /**
276
+ * Execute all registered afterResolving callbacks for a given key
277
+ *
278
+ * @param key
279
+ * @param resolved
280
+ */
281
+ runAfterResolvingCallbacks(key, resolved) {
282
+ const callbacks = this.afterResolvingCallbacks.get(key) || [];
283
+ for (let i = 0; i < callbacks.length; i++) callbacks[i](resolved, this);
86
284
  }
87
285
  /**
88
286
  * Automatically build a class with constructor dependency injection
287
+ *
288
+ * @param ClassType
289
+ * @returns
89
290
  */
90
291
  build(ClassType) {
91
292
  let dependencies = [];
@@ -93,44 +294,135 @@ var Container = class {
93
294
  return this.make(alias);
94
295
  });
95
296
  else dependencies = (Reflect.getMetadata("design:paramtypes", ClassType) || []).map((dep) => this.make(dep));
297
+ if (dependencies.length === 0) dependencies = [this];
96
298
  return new ClassType(...dependencies);
97
299
  }
98
300
  /**
99
- * Check if a service is registered
301
+ * Determine if a given string is an alias.
302
+ *
303
+ * @param name
304
+ */
305
+ isAlias(name) {
306
+ return this.aliases.has(name) && typeof this.aliases.get(name) !== "undefined";
307
+ }
308
+ /**
309
+ * Get the alias for an abstract if available.
310
+ *
311
+ * @param abstract
100
312
  */
313
+ getAlias(abstract) {
314
+ if (typeof abstract === "string" && this.aliases.has(abstract)) return this.getAlias(this.aliases.get(abstract));
315
+ if (abstract == null) return abstract;
316
+ return this.aliases.get(abstract) ?? abstract;
317
+ }
318
+ /**
319
+ * Get the extender callbacks for a given type.
320
+ *
321
+ * @param abstract
322
+ */
323
+ getExtenders(abstract) {
324
+ return this.extenders.get(this.getAlias(abstract)) ?? [];
325
+ }
326
+ /**
327
+ * Remove all of the extender callbacks for a given type.
328
+ *
329
+ * @param abstract
330
+ */
331
+ forgetExtenders(abstract) {
332
+ this.extenders.delete(this.getAlias(abstract));
333
+ }
334
+ alias(key, target) {
335
+ if (Array.isArray(key)) for (const [tokn, targ] of key) this.aliases.set(tokn, targ);
336
+ else this.aliases.set(key, target);
337
+ return this;
338
+ }
339
+ rebinding(abstract, callback) {
340
+ abstract = this.getAlias(abstract);
341
+ this.reboundCallbacks.set(abstract, this.reboundCallbacks.get(abstract)?.concat(callback) ?? [callback]);
342
+ if (this.bound(abstract)) return this.make(abstract);
343
+ }
344
+ bound(abstract) {
345
+ return this.bindings.has(abstract) || !!this.instances.get(abstract) || this.isAlias(abstract);
346
+ }
101
347
  has(key) {
102
- return this.bindings.has(key);
348
+ return this.bound(key);
103
349
  }
104
- };
105
-
106
- //#endregion
107
- //#region src/Di/ContainerResolver.ts
108
- var ContainerResolver = class ContainerResolver {
109
- constructor(app) {
110
- this.app = app;
350
+ /**
351
+ * Determine if the given abstract type has been resolved.
352
+ *
353
+ * @param abstract
354
+ */
355
+ resolved(abstract) {
356
+ if (this.isAlias(abstract)) abstract = this.getAlias(abstract);
357
+ return this.resolvedInstances.has(abstract) || this.instances.has(abstract);
358
+ }
359
+ extend(abstract, closure) {
360
+ abstract = this.getAlias(abstract);
361
+ if (this.instances.has(abstract)) {
362
+ this.instances.set(abstract, closure(this.instances.get(abstract), this));
363
+ this.rebound(abstract);
364
+ } else {
365
+ this.extenders.set(abstract, this.extenders.get(abstract)?.concat(closure) ?? [closure]);
366
+ if (this.resolved(abstract)) this.rebound(abstract);
367
+ }
111
368
  }
112
- async resolveMethodParams(instance, method, ..._default) {
113
- /**
114
- * Get param types for instance method
115
- */
116
- let params = Reflect.getMetadata("design:paramtypes", instance, String(method)) || [];
117
- /**
118
- * Ensure that the Application class is always available
119
- */
120
- if (params.length < 1 && _default.length > 0) params = _default;
121
- /**
122
- * Resolve the bound dependencies
123
- */
124
- const args = params.filter((e) => ContainerResolver.isClass(e) || e instanceof Application).map((type) => {
125
- if (type instanceof Application) return type;
126
- return this.app.make(type);
127
- });
128
- return new Promise((resolve) => {
129
- resolve(instance[method](...args));
130
- });
369
+ instance(abstract, instance) {
370
+ this.removeAbstractAlias(abstract);
371
+ const isBound = this.bound(abstract);
372
+ this.aliases.delete(abstract);
373
+ this.instances.set(abstract, instance);
374
+ if (isBound) this.rebound(abstract);
375
+ return instance;
131
376
  }
132
- static isClass(C) {
133
- return typeof C === "function" && C.prototype !== void 0 && Object.toString.call(C).substring(0, 5) === "class";
377
+ call(callback) {
378
+ if (ContainerResolver.isClass(callback)) return this.make(callback);
379
+ return callback(this);
380
+ }
381
+ /**
382
+ * Fire the "rebound" callbacks for the given abstract type.
383
+ *
384
+ * @param abstract
385
+ */
386
+ rebound(abstract) {
387
+ const callbacks = this.getReboundCallbacks(abstract);
388
+ if (!callbacks) return;
389
+ const instance = this.make(abstract);
390
+ for (const callback of callbacks) callback(this, instance);
391
+ }
392
+ /**
393
+ * Get the rebound callbacks for a given type.
394
+ *
395
+ * @param abstract
396
+ */
397
+ getReboundCallbacks(abstract) {
398
+ return this.reboundCallbacks.get(abstract) ?? [];
399
+ }
400
+ /**
401
+ * Remove an alias from the contextual binding alias cache.
402
+ *
403
+ * @param searched
404
+ */
405
+ removeAbstractAlias(searched) {
406
+ if (!this.aliases.has(searched)) return;
407
+ for (const [abstract, aliases] of this.abstractAliases.entries()) {
408
+ const filtered = aliases.filter((alias) => alias !== searched);
409
+ if (filtered.length > 0) this.abstractAliases.set(abstract, filtered);
410
+ else this.abstractAliases.delete(abstract);
411
+ }
412
+ }
413
+ /**
414
+ * Get the globally available instance of the container.
415
+ */
416
+ static getInstance() {
417
+ return this.instance ??= new Application(process.cwd(), "h3ravel");
418
+ }
419
+ /**
420
+ * Set the shared instance of the container.
421
+ *
422
+ * @param container
423
+ */
424
+ static setInstance(container) {
425
+ return Container.instance = container;
134
426
  }
135
427
  };
136
428
 
@@ -220,33 +512,25 @@ var ProviderRegistry = class {
220
512
  * @returns
221
513
  */
222
514
  static sort(providers) {
223
- /**
224
- * Base priority (default 0)
225
- */
226
- providers.forEach((Provider) => {
227
- const key = this.getKey(Provider);
228
- this.priorityMap.set(`${Provider.name}::${key}`, Provider.priority ?? 0);
229
- });
230
- /**
231
- * Handle before/after adjustments
232
- */
515
+ const makeKey = (Provider) => `${Provider.name}::${this.getKey(Provider)}`;
516
+ providers.sort((A, B) => (B.priority ?? 0) - (A.priority ?? 0));
517
+ const findIndex = (target) => {
518
+ if (target.includes("::")) return providers.findIndex((p) => makeKey(p) === target);
519
+ return providers.findIndex((p) => p.name === target);
520
+ };
233
521
  providers.forEach((Provider) => {
234
522
  const order = Provider.order;
235
523
  if (!order) return;
236
- const [direction, target] = order.split(":");
237
- const targetPriority = this.priorityMap.get(target) ?? 0;
238
- const key = this.getKey(Provider);
239
- if (direction === "before") this.priorityMap.set(`${Provider.name}::${key}`, targetPriority - 1);
240
- else if (direction === "after") this.priorityMap.set(`${Provider.name}::${key}`, targetPriority + 1);
241
- });
242
- /**
243
- * Return service providers sorted based on thier name and priority
244
- */
245
- return providers.sort((A, B) => {
246
- const keyA = this.getKey(A);
247
- const keyB = this.getKey(B);
248
- return (this.priorityMap.get(`${B.name}::${keyB}`) ?? 0) - (this.priorityMap.get(`${A.name}::${keyA}`) ?? 0);
524
+ const [direction, rawTarget] = order.split(":");
525
+ const targetIndex = findIndex(rawTarget);
526
+ if (targetIndex === -1) return;
527
+ const currentIndex = providers.indexOf(Provider);
528
+ if (currentIndex === -1) return;
529
+ providers.splice(currentIndex, 1);
530
+ const insertIndex = direction === "before" ? targetIndex : targetIndex + 1;
531
+ providers.splice(insertIndex, 0, Provider);
249
532
  });
533
+ return providers;
250
534
  }
251
535
  /**
252
536
  * Sort service providers
@@ -265,7 +549,8 @@ var ProviderRegistry = class {
265
549
  *
266
550
  * @param priorityMap
267
551
  */
268
- static log(providers) {
552
+ static log(providers, enabled = true) {
553
+ if (!enabled) return;
269
554
  const sorted = Array.from((providers ?? this.providers).values());
270
555
  console.table(sorted.map((P) => ({
271
556
  Name: P.constructor.name,
@@ -306,10 +591,10 @@ var ProviderRegistry = class {
306
591
  const providers = [];
307
592
  if (autoRegister) {
308
593
  for (const manifestPath of manifests) {
309
- const pkg = await this.getManifest(node_path.default.resolve(manifestPath));
594
+ const pkg = this.getManifest(node_path.default.resolve(manifestPath));
310
595
  if (pkg.h3ravel?.providers) providers.push(...await Promise.all(pkg.h3ravel.providers.map(async (name) => (await import(node_path.default.resolve(node_path.default.dirname(manifestPath), "dist/index.js")))[name])));
311
596
  }
312
- for (const provider of providers) {
597
+ for (const provider of providers.filter((e) => typeof e !== "undefined")) {
313
598
  const key = this.getKey(provider);
314
599
  this.providers.set(key, provider);
315
600
  }
@@ -322,22 +607,16 @@ var ProviderRegistry = class {
322
607
  * @param manifestPath
323
608
  * @returns
324
609
  */
325
- static async getManifest(manifestPath) {
326
- let pkg;
327
- try {
328
- pkg = (await import(manifestPath)).default;
329
- } catch {
330
- const { createRequire } = await import("module");
331
- pkg = createRequire(require("url").pathToFileURL(__filename).href)(manifestPath);
332
- }
333
- return pkg;
610
+ static getManifest(manifestPath) {
611
+ return (0, module$1.createRequire)(require("url").pathToFileURL(__filename).href)(manifestPath);
334
612
  }
335
613
  };
336
614
 
337
615
  //#endregion
338
616
  //#region src/Registerer.ts
339
- var Registerer = class Registerer {
617
+ var Registerer = class Registerer extends __h3ravel_contracts.IRegisterer {
340
618
  constructor(app) {
619
+ super();
341
620
  this.app = app;
342
621
  }
343
622
  static register(app) {
@@ -369,31 +648,87 @@ var Registerer = class Registerer {
369
648
  }
370
649
  };
371
650
 
651
+ //#endregion
652
+ //#region src/Providers/CoreServiceProvider.ts
653
+ /**
654
+ * Bootstraps core services and bindings.
655
+ *
656
+ * Bind essential services to the container (logger, config repository).
657
+ * Register app-level singletons.
658
+ * Set up exception handling.
659
+ *
660
+ * Auto-Registered
661
+ */
662
+ var CoreServiceProvider = class extends __h3ravel_support.ServiceProvider {
663
+ static priority = 999;
664
+ register() {
665
+ Object.assign(globalThis, { str: __h3ravel_support.str });
666
+ this.app.alias(__h3ravel_contracts.IApplication, Application);
667
+ }
668
+ boot() {}
669
+ };
670
+
372
671
  //#endregion
373
672
  //#region src/Application.ts
374
673
  var Application = class Application extends Container {
674
+ /**
675
+ * Indicates if the application has "booted".
676
+ */
677
+ #booted = false;
375
678
  paths = new __h3ravel_shared.PathLoader();
376
679
  context;
680
+ h3Event;
377
681
  tries = 0;
378
- booted = false;
379
682
  basePath;
380
683
  versions = {
381
684
  app: "0.0.0",
382
685
  ts: "0.0.0"
383
686
  };
687
+ namespace;
384
688
  static versions = {
385
689
  app: "0.0.0",
386
690
  ts: "0.0.0"
387
691
  };
692
+ h3App;
388
693
  providers = [];
389
694
  externalProviders = [];
390
695
  filteredProviders = [];
696
+ autoRegisterProviders = false;
697
+ /**
698
+ * The route resolver callback.
699
+ */
700
+ uriResolver;
391
701
  /**
392
702
  * List of registered console commands
393
703
  */
394
704
  registeredCommands = [];
395
- constructor(basePath) {
705
+ /**
706
+ * The array of booted callbacks.
707
+ */
708
+ bootedCallbacks = [];
709
+ /**
710
+ * The array of booting callbacks.
711
+ */
712
+ bootingCallbacks = [];
713
+ /**
714
+ * The array of terminating callbacks.
715
+ */
716
+ terminatingCallbacks = [];
717
+ /**
718
+ * Indicates if the application has been bootstrapped before.
719
+ */
720
+ bootstrapped = false;
721
+ /**
722
+ * Controls logging
723
+ */
724
+ logsDisabled = false;
725
+ /**
726
+ * The conrrent HttpContext
727
+ */
728
+ httpContext;
729
+ constructor(basePath, initializer) {
396
730
  super();
731
+ this.initializer = initializer;
397
732
  dotenv_expand.default.expand(dotenv.default.config({ quiet: true }));
398
733
  this.basePath = basePath;
399
734
  this.setPath("base", basePath);
@@ -405,6 +740,7 @@ var Application = class Application extends Container {
405
740
  * Register core bindings into the container
406
741
  */
407
742
  registerBaseBindings() {
743
+ Application.setInstance(this);
408
744
  this.bind(Application, () => this);
409
745
  this.bind("path.base", () => this.basePath);
410
746
  this.bind("load.paths", () => this.paths);
@@ -444,7 +780,7 @@ var Application = class Application extends Container {
444
780
  * Full-Stack App: Installs database, mail, queue, cache → they self-register via their providers.
445
781
  */
446
782
  async getConfiguredProviders() {
447
- return [(await import("@h3ravel/core")).CoreServiceProvider];
783
+ return [CoreServiceProvider];
448
784
  }
449
785
  async getAllProviders() {
450
786
  return [...await this.getConfiguredProviders(), ...this.externalProviders];
@@ -458,22 +794,30 @@ var Application = class Application extends Container {
458
794
  *
459
795
  * @returns
460
796
  */
461
- async quickStartup(providers, filtered = [], autoRegisterProviders = true) {
797
+ initialize(providers, filtered = [], autoRegisterProviders = true) {
798
+ /**
799
+ * Bind HTTP APP to the service container
800
+ */
801
+ this.singleton("http.app", () => {
802
+ return new h3.H3();
803
+ });
804
+ /**
805
+ * Bind the HTTP server to the service container
806
+ */
807
+ this.singleton("http.serve", () => h3.serve);
462
808
  this.registerProviders(providers, filtered);
463
- await this.registerConfiguredProviders(autoRegisterProviders);
464
- return this.boot();
809
+ this.autoRegisterProviders = autoRegisterProviders;
810
+ return this;
465
811
  }
466
812
  /**
467
813
  * Dynamically register all configured providers
468
- *
469
- * @param autoRegister If set to false, service providers will not be auto discovered and registered.
470
814
  */
471
- async registerConfiguredProviders(autoRegister = true) {
815
+ async registerConfiguredProviders() {
472
816
  const providers = await this.getAllProviders();
473
817
  ProviderRegistry.setSortable(false);
474
818
  ProviderRegistry.setFiltered(this.filteredProviders);
475
819
  ProviderRegistry.registerMany(providers);
476
- if (autoRegister) await ProviderRegistry.discoverProviders(autoRegister);
820
+ if (this.autoRegisterProviders) await ProviderRegistry.discoverProviders(this.autoRegisterProviders);
477
821
  ProviderRegistry.doSort();
478
822
  for (const ProviderClass of ProviderRegistry.all()) {
479
823
  if (!ProviderClass) continue;
@@ -489,7 +833,7 @@ var Application = class Application extends Container {
489
833
  */
490
834
  registerProviders(providers, filtered = []) {
491
835
  this.externalProviders.push(...providers);
492
- this.filteredProviders = filtered;
836
+ this.filteredProviders = Array.from(new Set(this.filteredProviders.concat(filtered)));
493
837
  }
494
838
  /**
495
839
  * Register a provider
@@ -514,44 +858,237 @@ var Application = class Application extends Container {
514
858
  runningInConsole() {
515
859
  return typeof process !== "undefined" && !!process.stdout && !!process.stdin;
516
860
  }
861
+ /**
862
+ * checks if the application is running in Unit Test
863
+ */
864
+ runningUnitTests() {
865
+ return process.env.VITEST === "true";
866
+ }
517
867
  getRuntimeEnv() {
518
868
  if (typeof window !== "undefined" && typeof document !== "undefined") return "browser";
519
869
  if (typeof process !== "undefined" && process.versions?.node) return "node";
520
870
  return "unknown";
521
871
  }
522
872
  /**
873
+ * Determine if the application has booted.
874
+ */
875
+ isBooted() {
876
+ return this.#booted;
877
+ }
878
+ /**
879
+ * Determine if the application has booted.
880
+ */
881
+ logging(logging = true) {
882
+ this.logsDisabled = !logging;
883
+ return this;
884
+ }
885
+ logsEnabled() {
886
+ if (this.logsDisabled) return false;
887
+ return (process.env.APP_DEBUG === "true" && process.env.EXTENDED_DEBUG !== "false" || Number(process.env.VERBOSE) > 1) && !this.providers.some((e) => e.runsInConsole);
888
+ }
889
+ /**
523
890
  * Boot all service providers after registration
524
891
  */
525
892
  async boot() {
526
- if (this.booted) return this;
893
+ if (this.#booted) return this;
894
+ this.fireAppCallbacks(this.bootingCallbacks);
895
+ /**
896
+ * Register all the configured service providers
897
+ */
898
+ await this.registerConfiguredProviders();
527
899
  /**
528
900
  * If debug is enabled, let's show the loaded service provider info
529
901
  */
530
- if ((process.env.APP_DEBUG === "true" && process.env.EXTENDED_DEBUG !== "false" || Number(process.env.VERBOSE) > 1) && !this.providers.some((e) => e.runsInConsole)) ProviderRegistry.log(this.providers);
531
- for (const provider of this.providers) if (provider.boot) if (Container.hasAnyDecorator(provider.boot))
902
+ ProviderRegistry.log(this.providers, this.logsEnabled());
903
+ for (const provider of this.providers) if (provider.boot) {
904
+ if (Container.hasAnyDecorator(provider.boot))
532
905
  /**
533
- * If the service provider is decorated use the IoC container
534
- */
535
- await this.make(provider.boot);
536
- else
906
+ * If the service provider is decorated use the IoC container
907
+ */
908
+ await this.make(provider.boot);
909
+ else
537
910
  /**
538
- * Otherwise instantiate manually so that we can at least
539
- * pass the app instance
540
- */
541
- await provider.boot(this);
542
- this.booted = true;
911
+ * Otherwise instantiate manually so that we can at least
912
+ * pass the app instance
913
+ */
914
+ await provider.boot(this);
915
+ if (provider.callBootedCallbacks) await provider.callBootedCallbacks();
916
+ }
917
+ this.#booted = true;
918
+ this.fireAppCallbacks(this.bootedCallbacks);
543
919
  return this;
544
920
  }
921
+ /**
922
+ * Register a new boot listener.
923
+ *
924
+ * @param callable $callback
925
+ */
926
+ booting(callback) {
927
+ this.bootingCallbacks.push(callback);
928
+ }
929
+ /**
930
+ * Register a new "booted" listener.
931
+ *
932
+ * @param callback
933
+ */
934
+ booted(callback) {
935
+ this.bootedCallbacks.push(callback);
936
+ if (this.isBooted()) callback(this);
937
+ }
938
+ /**
939
+ * Throw an HttpException with the given data.
940
+ *
941
+ * @param code
942
+ * @param message
943
+ * @param headers
944
+ *
945
+ * @throws {HttpException}
946
+ * @throws {NotFoundHttpException}
947
+ */
948
+ abort(code, message = "", headers = {}) {
949
+ if (code == 404) throw new __h3ravel_foundation.NotFoundHttpException(message, void 0, 0, headers);
950
+ throw new __h3ravel_foundation.HttpException(code, message, void 0, headers);
951
+ }
952
+ /**
953
+ * Register a terminating callback with the application.
954
+ *
955
+ * @param callback
956
+ */
957
+ terminating(callback) {
958
+ this.terminatingCallbacks.push(callback);
959
+ return this;
960
+ }
961
+ /**
962
+ * Terminate the application.
963
+ */
964
+ terminate() {
965
+ let index = 0;
966
+ while (index < this.terminatingCallbacks.length) {
967
+ this.call(this.terminatingCallbacks[index]);
968
+ index++;
969
+ }
970
+ }
971
+ /**
972
+ * Call the booting callbacks for the application.
973
+ *
974
+ * @param callbacks
975
+ */
976
+ fireAppCallbacks(callbacks) {
977
+ let index = 0;
978
+ while (index < callbacks.length) {
979
+ callbacks[index](this);
980
+ index++;
981
+ }
982
+ }
983
+ /**
984
+ * Handle the incoming HTTP request and send the response to the browser.
985
+ *
986
+ * @param config Configuration option to pass to the initializer
987
+ */
988
+ async handleRequest(config) {
989
+ this.h3App?.all("/**", async (event) => {
990
+ this.context = (event$1) => this.buildContext(event$1, config);
991
+ this.h3Event = event;
992
+ const context = await this.context(event);
993
+ const kernel = this.make(__h3ravel_contracts.IKernel);
994
+ this.bind("http.context", () => context);
995
+ this.bind("http.request", () => context.request);
996
+ this.bind("http.response", () => context.response);
997
+ const response = await kernel.handle(context.request);
998
+ if (response) this.bind("http.response", () => response);
999
+ kernel.terminate(context.request, response);
1000
+ let finalResponse;
1001
+ if (response && ["Response", "JsonResponse"].includes(response.constructor.name)) finalResponse = response.prepare(context.request).send();
1002
+ else finalResponse = response;
1003
+ return finalResponse;
1004
+ });
1005
+ }
1006
+ /**
1007
+ * Build the http context
1008
+ *
1009
+ * @param event
1010
+ * @param config
1011
+ * @returns
1012
+ */
1013
+ async buildContext(event, config, fresh = false) {
1014
+ const { HttpContext, Request, Response } = await import("@h3ravel/http");
1015
+ event = config?.h3Event ?? event;
1016
+ if (!fresh && event._h3ravelContext) return event._h3ravelContext;
1017
+ Request.enableHttpMethodParameterOverride();
1018
+ const ctx = HttpContext.init({
1019
+ app: this,
1020
+ request: await Request.create(event, this),
1021
+ response: new Response(this, event)
1022
+ }, event);
1023
+ event._h3ravelContext = ctx;
1024
+ return ctx;
1025
+ }
1026
+ /**
1027
+ * Handle the incoming Artisan command.
1028
+ */
1029
+ async handleCommand() {
1030
+ const kernel = this.make(__h3ravel_contracts.CKernel);
1031
+ const status = await kernel.handle();
1032
+ kernel.terminate(status);
1033
+ return status;
1034
+ }
1035
+ /**
1036
+ * Get the URI resolver callback.
1037
+ */
1038
+ getUriResolver() {
1039
+ return this.uriResolver ?? (() => void 0);
1040
+ }
1041
+ /**
1042
+ * Set the URI resolver callback.
1043
+ *
1044
+ * @param callback
1045
+ */
1046
+ setUriResolver(callback) {
1047
+ this.uriResolver = callback;
1048
+ return this;
1049
+ }
1050
+ /**
1051
+ * Determine if middleware has been disabled for the application.
1052
+ */
1053
+ shouldSkipMiddleware() {
1054
+ return this.bound("middleware.disable") && this.make("middleware.disable") === true;
1055
+ }
1056
+ /**
1057
+ * Provide safe overides for the app
1058
+ */
1059
+ configure() {
1060
+ return new __h3ravel_foundation.AppBuilder(this).withKernels().withCommands();
1061
+ }
1062
+ /**
1063
+ * Check if the current application environment matches the one provided
1064
+ */
1065
+ environment(env$1) {
1066
+ return this.make("config").get("app.env") === env$1;
1067
+ }
545
1068
  async fire(h3App, preferredPort) {
1069
+ if (h3App) this.h3App = h3App;
1070
+ if (!this?.h3App) throw new __h3ravel_foundation.ConfigException("[Provide a H3 app instance in the config or install @h3ravel/http]");
1071
+ return await this.serve(this.h3App, preferredPort);
1072
+ }
1073
+ /**
1074
+ * Fire up the developement server using the user provided arguments
1075
+ *
1076
+ * Port will be auto assigned if provided one is not available
1077
+ *
1078
+ * @param h3App The current H3 app instance
1079
+ * @param preferedPort If provided, this will overide the port set in the evironment
1080
+ */
1081
+ async serve(h3App, preferredPort) {
546
1082
  if (!h3App) throw new __h3ravel_support.InvalidArgumentException("No valid H3 app instance was provided.");
547
- const serve = this.make("http.serve");
1083
+ await this.boot();
1084
+ const serve$1 = this.make("http.serve");
548
1085
  const port = preferredPort ?? env("PORT", 3e3);
549
1086
  const tries = env("RETRIES", 1);
550
1087
  const hostname = env("HOSTNAME", "localhost");
551
1088
  try {
552
1089
  const realPort = await (0, detect_port.detect)(port);
553
1090
  if (port == realPort) {
554
- const server = serve(h3App, {
1091
+ const server = serve$1(h3App, {
555
1092
  port,
556
1093
  hostname,
557
1094
  silent: true
@@ -571,6 +1108,66 @@ var Application = class Application extends Container {
571
1108
  return this;
572
1109
  }
573
1110
  /**
1111
+ * Run the given array of bootstrap classes.
1112
+ *
1113
+ * @param bootstrappers
1114
+ */
1115
+ async bootstrapWith(bootstrappers) {
1116
+ for (const bootstrapper of bootstrappers) {
1117
+ if (this.has("app.events")) this.make("app.events").dispatch("bootstrapping: " + bootstrapper.name, [this]);
1118
+ await this.make(bootstrapper).bootstrap(this);
1119
+ if (this.has("app.events")) this.make("app.events").dispatch("bootstrapped: " + bootstrapper.name, [this]);
1120
+ }
1121
+ this.bootstrapped = true;
1122
+ }
1123
+ /**
1124
+ * Determine if the application has been bootstrapped before.
1125
+ */
1126
+ hasBeenBootstrapped() {
1127
+ return this.bootstrapped;
1128
+ }
1129
+ /**
1130
+ * Save the curretn H3 instance for possible future use.
1131
+ *
1132
+ * @param h3App The current H3 app instance
1133
+ * @returns
1134
+ */
1135
+ setH3App(h3App) {
1136
+ this.h3App = h3App;
1137
+ return this;
1138
+ }
1139
+ /**
1140
+ * Set the HttpContext.
1141
+ *
1142
+ * @param ctx
1143
+ */
1144
+ setHttpContext(ctx) {
1145
+ this.httpContext = ctx;
1146
+ return this;
1147
+ }
1148
+ getHttpContext(key) {
1149
+ return key ? this.httpContext?.[key] : this.httpContext;
1150
+ }
1151
+ /**
1152
+ * Get the application namespace.
1153
+ *
1154
+ * @throws {RuntimeException}
1155
+ */
1156
+ getNamespace() {
1157
+ if (this.namespace != null) return this.namespace;
1158
+ const pkg = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)(node_path.default.join(process.cwd(), "package.json"));
1159
+ for (const [namespace, pathChoice] of Object.entries((0, __h3ravel_support.data_get)(pkg, "autoload.namespaces"))) if (this.getPath("app", "/") === this.getPath("src", pathChoice)) return this.namespace = namespace;
1160
+ throw new __h3ravel_support.RuntimeException("Unable to detect application namespace.");
1161
+ }
1162
+ /**
1163
+ * Get the path of the app dir
1164
+ *
1165
+ * @returns
1166
+ */
1167
+ path() {
1168
+ return this.getPath("app");
1169
+ }
1170
+ /**
574
1171
  * Get the base path of the app
575
1172
  *
576
1173
  * @returns
@@ -621,52 +1218,14 @@ var Application = class Application extends Container {
621
1218
  /**
622
1219
  * Base controller class
623
1220
  */
624
- var Controller = class {
1221
+ var Controller = class extends __h3ravel_contracts.IController {
625
1222
  app;
626
1223
  constructor(app) {
1224
+ super();
627
1225
  this.app = app;
628
1226
  }
629
1227
  };
630
1228
 
631
- //#endregion
632
- //#region src/Di/Inject.ts
633
- function Inject(...dependencies) {
634
- return function(target) {
635
- target.__inject__ = dependencies;
636
- };
637
- }
638
- /**
639
- * Allows binding dependencies to both class and class methods
640
- *
641
- * @returns
642
- */
643
- function Injectable() {
644
- return (...args) => {
645
- if (args.length === 1) args[0];
646
- if (args.length === 3) {
647
- args[0];
648
- args[1];
649
- args[2];
650
- }
651
- };
652
- }
653
-
654
- //#endregion
655
- //#region src/Exceptions/ConfigException.ts
656
- var ConfigException = class extends Error {
657
- key;
658
- constructor(key, type = "config", cause) {
659
- const info = {
660
- any: `${key} not configured`,
661
- env: `${key} environment variable not configured`,
662
- config: `${key} config not set`
663
- };
664
- const message = __h3ravel_shared.Logger.log([["ERROR:", "bgRed"], [info[type], "white"]], " ", false);
665
- super(message, { cause });
666
- this.key = key;
667
- }
668
- };
669
-
670
1229
  //#endregion
671
1230
  //#region src/H3ravel.ts
672
1231
  /**
@@ -680,56 +1239,23 @@ const h3ravel = async (providers = [], basePath = process.cwd(), config = {
680
1239
  initialize: false,
681
1240
  autoload: false,
682
1241
  filteredProviders: []
683
- }, middleware = async () => void 0) => {
1242
+ }) => {
684
1243
  let h3App;
685
- const app = new Application(basePath);
686
- await app.quickStartup(providers, config.filteredProviders, config.autoload);
1244
+ const app = new Application(basePath, "h3ravel");
1245
+ if (config.customPaths) for (const [name, path$2] of Object.entries(config.customPaths)) app.setPath(name, path$2);
1246
+ app.initialize(providers, config.filteredProviders, config.autoload);
687
1247
  try {
688
1248
  h3App = app.make("http.app");
689
- app.context = async (event) => {
690
- if (event._h3ravelContext) return event._h3ravelContext;
691
- __h3ravel_http.Request.enableHttpMethodParameterOverride();
692
- const ctx = __h3ravel_http.HttpContext.init({
693
- app,
694
- request: await __h3ravel_http.Request.create(event, app),
695
- response: new __h3ravel_http.Response(event, app)
696
- });
697
- event._h3ravelContext = ctx;
698
- return ctx;
699
- };
700
- const kernel = new Kernel(async (event) => app.context(event), [new __h3ravel_http.LogRequests()]);
701
- h3App.use((event) => kernel.handle(event, middleware));
1249
+ app.setH3App(h3App);
1250
+ app.singleton(__h3ravel_contracts.IApplication, () => app);
1251
+ if (!__h3ravel_support_facades.Facades.getApplication()) __h3ravel_support_facades.Facades.setApplication(app);
1252
+ if (!__h3ravel_foundation.Helpers.isLoaded()) __h3ravel_foundation.Helpers.load(app);
1253
+ await app.handleRequest(config);
702
1254
  } catch {
703
1255
  if (!h3App && config.h3) h3App = config.h3;
704
1256
  }
705
- const originalFire = app.fire;
706
- const proxyThis = (function makeProxy(appRef, orig) {
707
- return new Proxy(appRef, {
708
- get(target, prop, receiver) {
709
- if (prop === "fire") return orig;
710
- return Reflect.get(target, prop, receiver);
711
- },
712
- has(target, prop) {
713
- if (prop === "fire") return true;
714
- return Reflect.has(target, prop);
715
- },
716
- getOwnPropertyDescriptor(target, prop) {
717
- if (prop === "fire") return {
718
- configurable: true,
719
- enumerable: false,
720
- writable: true,
721
- value: orig
722
- };
723
- return Reflect.getOwnPropertyDescriptor(target, prop);
724
- }
725
- });
726
- })(app, originalFire);
727
- if (config.initialize && h3App) return await Reflect.apply(originalFire, app, [h3App]);
728
- app.fire = function() {
729
- if (!h3App) throw new ConfigException("Provide a H3 app instance in the config or install @h3ravel/http");
730
- return Reflect.apply(originalFire, proxyThis, [h3App]);
731
- };
732
- return app;
1257
+ if (config.initialize && h3App) return await app.fire(h3App);
1258
+ return app.setH3App(h3App);
733
1259
  };
734
1260
 
735
1261
  //#endregion
@@ -740,12 +1266,23 @@ const h3ravel = async (providers = [], basePath = process.cwd(), config = {
740
1266
  */
741
1267
  var Kernel = class {
742
1268
  /**
743
- * @param context - A factory function that converts an H3Event into an HttpContext.
1269
+ * The router instance.
1270
+ */
1271
+ router;
1272
+ /**
1273
+ * A factory function that converts an H3Event into an HttpContext.
1274
+ */
1275
+ context;
1276
+ applicationContext;
1277
+ /**
1278
+ * @param app - The current application instance
744
1279
  * @param middleware - An array of middleware classes that will be executed in sequence.
745
1280
  */
746
- constructor(context, middleware = []) {
747
- this.context = context;
1281
+ constructor(app, middleware = []) {
1282
+ this.app = app;
748
1283
  this.middleware = middleware;
1284
+ this.router = app.make("router");
1285
+ this.context = async (event) => app.context(event);
749
1286
  }
750
1287
  /**
751
1288
  * Handles an incoming request and passes it through middleware before invoking the next handler.
@@ -755,157 +1292,71 @@ var Kernel = class {
755
1292
  * @returns A promise resolving to the result of the request pipeline.
756
1293
  */
757
1294
  async handle(event, next) {
1295
+ const { request } = await this.app.context(event);
758
1296
  /**
759
1297
  * Convert the raw event into a standardized HttpContext
760
1298
  */
761
- const ctx = await this.context(event);
762
- const { app } = ctx.request;
763
- /**
764
- * Bind HTTP Response instance to the service container
765
- */
766
- app.bind("http.response", () => {
767
- return ctx.response;
768
- });
769
- /**
770
- * Bind HTTP Request instance to the service container
1299
+ this.applicationContext = await this.context(event);
1300
+ /**
1301
+ * Bind HttpContext, request, and response to the container
771
1302
  */
772
- app.bind("http.request", () => {
773
- return ctx.request;
774
- });
1303
+ this.app.bind("http.context", () => this.applicationContext);
1304
+ this.app.bind("http.request", () => this.applicationContext.request);
1305
+ this.app.bind("http.response", () => this.applicationContext.response);
1306
+ this.app.middlewareHandler = this.app.has(__h3ravel_foundation.MiddlewareHandler) ? this.app.make(__h3ravel_foundation.MiddlewareHandler) : new __h3ravel_foundation.MiddlewareHandler([], this.app);
1307
+ request.constructor.enableHttpMethodParameterOverride();
775
1308
  /**
776
1309
  * Run middleware stack and obtain result
777
1310
  */
778
- const result = await this.runMiddleware(ctx, () => next(ctx));
1311
+ const result = await this.app.middlewareHandler.register(this.middleware).run(this.applicationContext, next);
779
1312
  /**
780
1313
  * If a plain object is returned from a controller or middleware,
781
1314
  * automatically set the JSON Content-Type header for the response.
782
1315
  */
783
- if (result !== void 0 && this.isPlainObject(result)) event.res.headers.set("Content-Type", "application/json; charset=UTF-8");
1316
+ if (result !== void 0 && __h3ravel_support.Obj.isPlainObject(result, true) && !result?.headers) event.res.headers.set("Content-Type", "application/json; charset=UTF-8");
784
1317
  return result;
785
1318
  }
786
1319
  /**
787
- * Sequentially runs middleware in the order they were registered.
788
- *
789
- * @param context - The standardized HttpContext.
790
- * @param next - Callback to execute when middleware completes.
791
- * @returns A promise resolving to the final handler's result.
792
- */
793
- async runMiddleware(context, next) {
794
- let index = -1;
795
- const runner = async (i) => {
796
- if (i <= index) throw new Error("next() called multiple times");
797
- index = i;
798
- const middleware = this.middleware[i];
799
- if (middleware)
800
- /**
801
- * Execute the current middleware and proceed to the next one
802
- */
803
- return middleware.handle(context, () => runner(i + 1));
804
- else
805
- /**
806
- * If no more middleware, call the final handler
807
- */
808
- return next(context);
809
- };
810
- return runner(0);
811
- }
812
- /**
813
- * Utility function to determine if a value is a plain object or array.
814
- *
815
- * @param value - The value to check.
816
- * @returns True if the value is a plain object or array, otherwise false.
817
- */
818
- isPlainObject(value) {
819
- return typeof value === "object" && value !== null && (value.constructor === Object || value.constructor === Array);
820
- }
821
- };
822
-
823
- //#endregion
824
- //#region src/ServiceProvider.ts
825
- const Inference = class {};
826
- var ServiceProvider = class extends Inference {
827
- /**
828
- * The current app instance
829
- */
830
- app;
831
- /**
832
- * Unique Identifier for the service providers
833
- */
834
- static uid;
835
- /**
836
- * Sort order
837
- */
838
- static order;
839
- /**
840
- * Sort priority
841
- */
842
- static priority = 0;
843
- /**
844
- * Indicate that this service provider only runs in console
845
- */
846
- static console = false;
847
- /**
848
- * List of registered console commands
849
- */
850
- registeredCommands;
851
- constructor(app) {
852
- super();
853
- this.app = app;
854
- }
855
- /**
856
- * Register the listed service providers.
857
- *
858
- * @param commands An array of console commands to register.
859
- *
860
- * @deprecated since version 1.16.0. Will be removed in future versions, use `registerCommands` instead
861
- */
862
- commands(commands) {
863
- this.registerCommands(commands);
864
- }
865
- /**
866
- * Register the listed service providers.
867
- *
868
- * @param commands An array of console commands to register.
1320
+ * Resolve the provided callback using the current H3 event instance
869
1321
  */
870
- registerCommands(commands) {
871
- this.registeredCommands = commands;
872
- }
873
- };
874
-
875
- //#endregion
876
- //#region src/Providers/CoreServiceProvider.ts
877
- /**
878
- * Bootstraps core services and bindings.
879
- *
880
- * Bind essential services to the container (logger, config repository).
881
- * Register app-level singletons.
882
- * Set up exception handling.
883
- *
884
- * Auto-Registered
885
- */
886
- var CoreServiceProvider = class extends ServiceProvider {
887
- static priority = 999;
888
- register() {
889
- Object.assign(globalThis, { str: __h3ravel_support.str });
890
- }
891
- boot() {
892
- try {
893
- Object.assign(globalThis, { asset: this.app.make("asset") });
894
- } catch {}
1322
+ async resolve(event, middleware, handler) {
1323
+ const { Response } = await import("@h3ravel/http");
1324
+ this.middleware = Array.from(new Set([...this.middleware, ...__h3ravel_support.Arr.wrap(middleware)]));
1325
+ return this.handle(event, (ctx) => new Promise((resolve) => {
1326
+ if (__h3ravel_shared.Resolver.isAsyncFunction(handler)) handler(ctx).then((response) => {
1327
+ if (response instanceof Response) resolve(response.prepare(ctx.request).send());
1328
+ else resolve(response);
1329
+ });
1330
+ else resolve(handler(ctx));
1331
+ }));
895
1332
  }
896
1333
  };
897
1334
 
898
1335
  //#endregion
899
1336
  exports.Application = Application;
900
- exports.ConfigException = ConfigException;
901
1337
  exports.Container = Container;
902
1338
  exports.ContainerResolver = ContainerResolver;
903
1339
  exports.Controller = Controller;
904
1340
  exports.CoreServiceProvider = CoreServiceProvider;
905
- exports.Inject = Inject;
906
- exports.Injectable = Injectable;
1341
+ Object.defineProperty(exports, 'Inject', {
1342
+ enumerable: true,
1343
+ get: function () {
1344
+ return __h3ravel_foundation.Inject;
1345
+ }
1346
+ });
1347
+ Object.defineProperty(exports, 'Injectable', {
1348
+ enumerable: true,
1349
+ get: function () {
1350
+ return __h3ravel_foundation.Injectable;
1351
+ }
1352
+ });
907
1353
  exports.Kernel = Kernel;
908
1354
  exports.ProviderRegistry = ProviderRegistry;
909
1355
  exports.Registerer = Registerer;
910
- exports.ServiceProvider = ServiceProvider;
1356
+ Object.defineProperty(exports, 'ServiceProvider', {
1357
+ enumerable: true,
1358
+ get: function () {
1359
+ return __h3ravel_support.ServiceProvider;
1360
+ }
1361
+ });
911
1362
  exports.h3ravel = h3ravel;