@h3ravel/core
Version:
Core application container, lifecycle management and service providers for H3ravel.
911 lines (897 loc) • 26.8 kB
JavaScript
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
require("reflect-metadata");
let __h3ravel_shared = require("@h3ravel/shared");
let __h3ravel_support = require("@h3ravel/support");
let fast_glob = require("fast-glob");
fast_glob = __toESM(fast_glob);
let node_path = require("node:path");
node_path = __toESM(node_path);
let detect_port = require("detect-port");
let dotenv = require("dotenv");
dotenv = __toESM(dotenv);
let dotenv_expand = require("dotenv-expand");
dotenv_expand = __toESM(dotenv_expand);
let node_fs_promises = require("node:fs/promises");
let semver = require("semver");
semver = __toESM(semver);
let __h3ravel_http = require("@h3ravel/http");
//#region src/Container.ts
var Container = class {
bindings = /* @__PURE__ */ new Map();
singletons = /* @__PURE__ */ new Map();
static hasAnyDecorator(target) {
if (Reflect.getMetadataKeys(target).length > 0) return true;
const paramLength = target.length;
for (let i = 0; i < paramLength; i++) if (Reflect.getMetadataKeys(target, `__param_${i}`).length > 0) return true;
return false;
}
bind(key, factory) {
this.bindings.set(key, factory);
}
/**
* Remove one or more transient services from the container
*/
unbind(key) {
if (Array.isArray(key)) for (let i = 0; i < key.length; i++) {
this.bindings.delete(key[i]);
this.singletons.delete(key[i]);
}
else {
this.bindings.delete(key);
this.singletons.delete(key);
}
}
/**
* Bind a singleton service to the container
*/
singleton(key, factory) {
this.bindings.set(key, () => {
if (!this.singletons.has(key)) this.singletons.set(key, factory(this));
return this.singletons.get(key);
});
}
make(key) {
/**
* Direct factory binding
*/
if (this.bindings.has(key)) return this.bindings.get(key)();
/**
* If this is a class constructor, auto-resolve via reflection
*/
if (typeof key === "function") return this.build(key);
throw new Error(`No binding found for key: ${typeof key === "string" ? key : key?.name}`);
}
/**
* Automatically build a class with constructor dependency injection
*/
build(ClassType) {
let dependencies = [];
if (Array.isArray(ClassType.__inject__)) dependencies = ClassType.__inject__.map((alias) => {
return this.make(alias);
});
else dependencies = (Reflect.getMetadata("design:paramtypes", ClassType) || []).map((dep) => this.make(dep));
return new ClassType(...dependencies);
}
/**
* Check if a service is registered
*/
has(key) {
return this.bindings.has(key);
}
};
//#endregion
//#region src/Di/ContainerResolver.ts
var ContainerResolver = class ContainerResolver {
constructor(app) {
this.app = app;
}
async resolveMethodParams(instance, method, ..._default) {
/**
* Get param types for instance method
*/
let params = Reflect.getMetadata("design:paramtypes", instance, String(method)) || [];
/**
* Ensure that the Application class is always available
*/
if (params.length < 1 && _default.length > 0) params = _default;
/**
* Resolve the bound dependencies
*/
const args = params.filter((e) => ContainerResolver.isClass(e) || e instanceof Application).map((type) => {
if (type instanceof Application) return type;
return this.app.make(type);
});
return new Promise((resolve) => {
resolve(instance[method](...args));
});
}
static isClass(C) {
return typeof C === "function" && C.prototype !== void 0 && Object.toString.call(C).substring(0, 5) === "class";
}
};
//#endregion
//#region src/ProviderRegistry.ts
var ProviderRegistry = class {
static providers = /* @__PURE__ */ new Map();
static priorityMap = /* @__PURE__ */ new Map();
static filteredProviders = [];
static sortable = true;
/**
* Set wether providers should be sorted or not.
*
* @returns
*/
static setSortable(sort = true) {
this.sortable = sort;
}
/**
* Get a unique identifier for the Provider.
*
* @param provider
* @returns
*/
static getKey(provider) {
const anyProvider = provider;
if (typeof anyProvider.uid === "string") return anyProvider.uid;
if (typeof anyProvider.id === "string") return anyProvider.id;
return provider.name || "AnonymousProvider";
}
/**
* Register one or more providers.
* Duplicate constructors will be ignored.
*
* @param providers
* @returns
*/
static register(...providers) {
const list = this.sortable ? this.sort(providers.concat(...this.providers.values())) : providers.concat(...this.providers.values());
for (const provider of list) {
const key = this.getKey(provider);
this.providers.set(key, provider);
}
}
/**
* Bulk register providers from an array.
*
* @param providers
* @returns
*/
static registerMany(providers) {
const list = this.sortable ? this.sort(providers.concat(...this.providers.values())) : providers.concat(...this.providers.values());
for (const provider of list) {
const key = this.getKey(provider);
this.providers.set(key, provider);
}
}
/**
* Set the filtered providers.
*
* @returns
*/
static setFiltered(filtered) {
this.filteredProviders = filtered;
}
/**
* Resolve (instantiate) all providers with the given application or Service Container.
*
* @param app
* @returns
*/
static async resolve(app, useServiceContainer = false) {
const providers = Array.from(this.providers.values()).filter((e) => {
return !!e && (this.filteredProviders.length < 1 || !this.filteredProviders.includes(e.name));
});
return await Promise.all(providers.map(async (ProviderClass) => {
const provider = new ProviderClass(app);
if (!useServiceContainer) return Promise.resolve(provider);
await new ContainerResolver(app).resolveMethodParams(provider, "register", app);
return provider;
}));
}
/**
* Sort the service providers
*
* @param providers
* @returns
*/
static sort(providers) {
/**
* Base priority (default 0)
*/
providers.forEach((Provider) => {
const key = this.getKey(Provider);
this.priorityMap.set(`${Provider.name}::${key}`, Provider.priority ?? 0);
});
/**
* Handle before/after adjustments
*/
providers.forEach((Provider) => {
const order = Provider.order;
if (!order) return;
const [direction, target] = order.split(":");
const targetPriority = this.priorityMap.get(target) ?? 0;
const key = this.getKey(Provider);
if (direction === "before") this.priorityMap.set(`${Provider.name}::${key}`, targetPriority - 1);
else if (direction === "after") this.priorityMap.set(`${Provider.name}::${key}`, targetPriority + 1);
});
/**
* Return service providers sorted based on thier name and priority
*/
return providers.sort((A, B) => {
const keyA = this.getKey(A);
const keyB = this.getKey(B);
return (this.priorityMap.get(`${B.name}::${keyB}`) ?? 0) - (this.priorityMap.get(`${A.name}::${keyA}`) ?? 0);
});
}
/**
* Sort service providers
*/
static doSort() {
const raw = this.sort(Array.from(this.providers.values()));
const providers = /* @__PURE__ */ new Map();
for (const provider of raw) {
const key = this.getKey(provider);
providers.set(key, provider);
}
this.providers = providers;
}
/**
* Log the service providers in a table
*
* @param priorityMap
*/
static log(providers) {
const sorted = Array.from((providers ?? this.providers).values());
console.table(sorted.map((P) => ({
Name: P.constructor.name,
Order: P.constructor.order ?? "N/A",
Priority: P.constructor.priority
})));
console.info("");
}
/**
* Get all registered providers as an array.
*
* @returns
*/
static all() {
return Array.from(this.providers.values());
}
/**
* Check if a provider is already registered.
*
* @param provider
* @returns
*/
static has(provider) {
return this.providers.has(this.getKey(provider));
}
/**
* Automatically search for and discover service providers in packages.
*
* @param autoRegister
* @returns
*/
static async discoverProviders(autoRegister = true) {
const manifests = await (0, fast_glob.default)([
"node_modules/@h3ravel/*/package.json",
"node_modules/@h3ravel-community/*/package.json",
"node_modules/h3ravel-*/package.json"
]);
const providers = [];
if (autoRegister) {
for (const manifestPath of manifests) {
const pkg = await this.getManifest(node_path.default.resolve(manifestPath));
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])));
}
for (const provider of providers) {
const key = this.getKey(provider);
this.providers.set(key, provider);
}
}
return providers;
}
/**
* Get the content of the package.json file
*
* @param manifestPath
* @returns
*/
static async getManifest(manifestPath) {
let pkg;
try {
pkg = (await import(manifestPath)).default;
} catch {
const { createRequire } = await import("module");
pkg = createRequire(require("url").pathToFileURL(__filename).href)(manifestPath);
}
return pkg;
}
};
//#endregion
//#region src/Registerer.ts
var Registerer = class Registerer {
constructor(app) {
this.app = app;
}
static register(app) {
new Registerer(app).bootRegister();
}
bootRegister() {
globalThis.dd = __h3ravel_support.dd;
globalThis.dump = __h3ravel_support.dump;
globalThis.app_path = (path$2) => this.appPath(path$2);
globalThis.base_path = (path$2) => this.basePath(path$2);
globalThis.public_path = (path$2) => this.publicPath(path$2);
globalThis.storage_path = (path$2) => this.storagePath(path$2);
globalThis.database_path = (path$2) => this.databasePath(path$2);
}
appPath(path$2) {
return this.app.getPath("base", node_path.default.join(`/${process.env.DIST_DIR ?? "src"}/`.replace(/([^:]\/)\/+/g, "$1"), "app", path$2 ?? ""));
}
basePath(path$2) {
return this.app.getPath("base", path$2);
}
publicPath(path$2) {
return this.app.getPath("public", path$2);
}
storagePath(path$2) {
return this.app.getPath("base", node_path.default.join("storage", path$2 ?? ""));
}
databasePath(path$2) {
return this.app.getPath("database", path$2);
}
};
//#endregion
//#region src/Application.ts
var Application = class Application extends Container {
paths = new __h3ravel_shared.PathLoader();
context;
tries = 0;
booted = false;
basePath;
versions = {
app: "0.0.0",
ts: "0.0.0"
};
static versions = {
app: "0.0.0",
ts: "0.0.0"
};
providers = [];
externalProviders = [];
filteredProviders = [];
/**
* List of registered console commands
*/
registeredCommands = [];
constructor(basePath) {
super();
dotenv_expand.default.expand(dotenv.default.config({ quiet: true }));
this.basePath = basePath;
this.setPath("base", basePath);
this.loadOptions();
this.registerBaseBindings();
Registerer.register(this);
}
/**
* Register core bindings into the container
*/
registerBaseBindings() {
this.bind(Application, () => this);
this.bind("path.base", () => this.basePath);
this.bind("load.paths", () => this.paths);
}
async loadOptions() {
try {
const corePath = __h3ravel_shared.FileSystem.findModulePkg("@h3ravel/core", process.cwd()) ?? "";
const app = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.join(process.cwd(), "/package.json"), { encoding: "utf8" }));
const core = JSON.parse(await (0, node_fs_promises.readFile)(node_path.default.join(corePath, "package.json"), { encoding: "utf8" }));
if (core) {
this.versions.app = semver.default.minVersion(core.version)?.version ?? this.versions.app;
Application.versions.app = this.versions.app;
}
if (app && app.devDependencies) {
this.versions.ts = semver.default.minVersion(app.devDependencies.typescript)?.version ?? this.versions.ts;
Application.versions.ts = this.versions.ts;
}
if (app && app.dependencies) {
const versions = Object.fromEntries(Object.entries(app.dependencies).filter(([e]) => e.includes("@h3ravel")).map(([name, ver]) => [__h3ravel_support.Str.afterLast(name, "/"), semver.default.minVersion(ver.includes("work") ? this.versions.app : ver)?.version]));
Object.assign(this.versions, versions);
Object.assign(Application.versions, versions);
}
} catch {}
}
/**
* Get all registered providers
*/
getRegisteredProviders() {
return this.providers;
}
/**
* Load default and optional providers dynamically
*
* Auto-Registration Behavior
*
* Minimal App: Loads only core, config, http, router by default.
* Full-Stack App: Installs database, mail, queue, cache → they self-register via their providers.
*/
async getConfiguredProviders() {
return [(await import("@h3ravel/core")).CoreServiceProvider];
}
async getAllProviders() {
return [...await this.getConfiguredProviders(), ...this.externalProviders];
}
/**
* Configure and Dynamically register all configured service providers, then boot the app.
*
* @param providers All regitererable service providers
* @param filtered A list of service provider name strings we do not want to register at all cost
* @param autoRegisterProviders If set to false, service providers will not be auto discovered and registered.
*
* @returns
*/
async quickStartup(providers, filtered = [], autoRegisterProviders = true) {
this.registerProviders(providers, filtered);
await this.registerConfiguredProviders(autoRegisterProviders);
return this.boot();
}
/**
* Dynamically register all configured providers
*
* @param autoRegister If set to false, service providers will not be auto discovered and registered.
*/
async registerConfiguredProviders(autoRegister = true) {
const providers = await this.getAllProviders();
ProviderRegistry.setSortable(false);
ProviderRegistry.setFiltered(this.filteredProviders);
ProviderRegistry.registerMany(providers);
if (autoRegister) await ProviderRegistry.discoverProviders(autoRegister);
ProviderRegistry.doSort();
for (const ProviderClass of ProviderRegistry.all()) {
if (!ProviderClass) continue;
const provider = new ProviderClass(this);
await this.register(provider);
}
}
/**
* Register service providers
*
* @param providers
* @param filtered
*/
registerProviders(providers, filtered = []) {
this.externalProviders.push(...providers);
this.filteredProviders = filtered;
}
/**
* Register a provider
*/
async register(provider) {
await new ContainerResolver(this).resolveMethodParams(provider, "register", this);
if (provider.registeredCommands && provider.registeredCommands.length > 0) this.registeredCommands.push(...provider.registeredCommands);
this.providers.push(provider);
}
/**
* Register the listed service providers.
*
* @param commands An array of console commands to register.
*/
withCommands(commands) {
this.registeredCommands = commands;
return this;
}
/**
* checks if the application is running in CLI
*/
runningInConsole() {
return typeof process !== "undefined" && !!process.stdout && !!process.stdin;
}
getRuntimeEnv() {
if (typeof window !== "undefined" && typeof document !== "undefined") return "browser";
if (typeof process !== "undefined" && process.versions?.node) return "node";
return "unknown";
}
/**
* Boot all service providers after registration
*/
async boot() {
if (this.booted) return this;
/**
* If debug is enabled, let's show the loaded service provider info
*/
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);
for (const provider of this.providers) if (provider.boot) if (Container.hasAnyDecorator(provider.boot))
/**
* If the service provider is decorated use the IoC container
*/
await this.make(provider.boot);
else
/**
* Otherwise instantiate manually so that we can at least
* pass the app instance
*/
await provider.boot(this);
this.booted = true;
return this;
}
async fire(h3App, preferredPort) {
if (!h3App) throw new __h3ravel_support.InvalidArgumentException("No valid H3 app instance was provided.");
const serve = this.make("http.serve");
const port = preferredPort ?? env("PORT", 3e3);
const tries = env("RETRIES", 1);
const hostname = env("HOSTNAME", "localhost");
try {
const realPort = await (0, detect_port.detect)(port);
if (port == realPort) {
const server = serve(h3App, {
port,
hostname,
silent: true
});
__h3ravel_shared.Logger.parse([["🚀 H3ravel running at:", "green"], [`${server.options.protocol ?? "http"}://${server.options.hostname}:${server.options.port}`, "cyan"]]);
} else if (this.tries <= tries) {
await this.fire(h3App, realPort);
this.tries++;
} else __h3ravel_shared.Logger.parse([["ERROR:", "bgRed"], ["No free port available", "red"]]);
} catch (e) {
__h3ravel_shared.Logger.parse([
["An error occured", "bgRed"],
[e.message, "red"],
[e.stack, "red"]
], "\n");
}
return this;
}
/**
* Get the base path of the app
*
* @returns
*/
getBasePath() {
return this.basePath;
}
/**
* Dynamically retrieves a path property from the class.
* Any property ending with "Path" is accessible automatically.
*
* @param name - The base name of the path property
* @returns
*/
getPath(name, suffix) {
return node_path.default.join(this.paths.getPath(name, this.basePath), suffix ?? "");
}
/**
* Programatically set the paths.
*
* @param name - The base name of the path property
* @param path - The new path
* @returns
*/
setPath(name, path$2) {
return this.paths.setPath(name, path$2, this.basePath);
}
/**
* Returns the installed version of the system core and typescript.
*
* @returns
*/
getVersion(key) {
return this.versions[key]?.replaceAll(/\^|~/g, "");
}
/**
* Returns the installed version of the system core and typescript.
*
* @returns
*/
static getVersion(key) {
return this.versions[key]?.replaceAll(/\^|~/g, "");
}
};
//#endregion
//#region src/Controller.ts
/**
* Base controller class
*/
var Controller = class {
app;
constructor(app) {
this.app = app;
}
};
//#endregion
//#region src/Di/Inject.ts
function Inject(...dependencies) {
return function(target) {
target.__inject__ = dependencies;
};
}
/**
* Allows binding dependencies to both class and class methods
*
* @returns
*/
function Injectable() {
return (...args) => {
if (args.length === 1) args[0];
if (args.length === 3) {
args[0];
args[1];
args[2];
}
};
}
//#endregion
//#region src/Exceptions/ConfigException.ts
var ConfigException = class extends Error {
key;
constructor(key, type = "config", cause) {
const info = {
any: `${key} not configured`,
env: `${key} environment variable not configured`,
config: `${key} config not set`
};
const message = __h3ravel_shared.Logger.log([["ERROR:", "bgRed"], [info[type], "white"]], " ", false);
super(message, { cause });
this.key = key;
}
};
//#endregion
//#region src/H3ravel.ts
/**
* Simple global entry point for H3ravel applications
*
* @param providers
* @param basePath
* @param callback
*/
const h3ravel = async (providers = [], basePath = process.cwd(), config = {
initialize: false,
autoload: false,
filteredProviders: []
}, middleware = async () => void 0) => {
let h3App;
const app = new Application(basePath);
await app.quickStartup(providers, config.filteredProviders, config.autoload);
try {
h3App = app.make("http.app");
app.context = async (event) => {
if (event._h3ravelContext) return event._h3ravelContext;
__h3ravel_http.Request.enableHttpMethodParameterOverride();
const ctx = __h3ravel_http.HttpContext.init({
app,
request: await __h3ravel_http.Request.create(event, app),
response: new __h3ravel_http.Response(event, app)
});
event._h3ravelContext = ctx;
return ctx;
};
const kernel = new Kernel(async (event) => app.context(event), [new __h3ravel_http.LogRequests()]);
h3App.use((event) => kernel.handle(event, middleware));
} catch {
if (!h3App && config.h3) h3App = config.h3;
}
const originalFire = app.fire;
const proxyThis = (function makeProxy(appRef, orig) {
return new Proxy(appRef, {
get(target, prop, receiver) {
if (prop === "fire") return orig;
return Reflect.get(target, prop, receiver);
},
has(target, prop) {
if (prop === "fire") return true;
return Reflect.has(target, prop);
},
getOwnPropertyDescriptor(target, prop) {
if (prop === "fire") return {
configurable: true,
enumerable: false,
writable: true,
value: orig
};
return Reflect.getOwnPropertyDescriptor(target, prop);
}
});
})(app, originalFire);
if (config.initialize && h3App) return await Reflect.apply(originalFire, app, [h3App]);
app.fire = function() {
if (!h3App) throw new ConfigException("Provide a H3 app instance in the config or install @h3ravel/http");
return Reflect.apply(originalFire, proxyThis, [h3App]);
};
return app;
};
//#endregion
//#region src/Http/Kernel.ts
/**
* Kernel class handles middleware execution and response transformations.
* It acts as the core middleware pipeline for HTTP requests.
*/
var Kernel = class {
/**
* @param context - A factory function that converts an H3Event into an HttpContext.
* @param middleware - An array of middleware classes that will be executed in sequence.
*/
constructor(context, middleware = []) {
this.context = context;
this.middleware = middleware;
}
/**
* Handles an incoming request and passes it through middleware before invoking the next handler.
*
* @param event - The raw H3 event object.
* @param next - A callback function that represents the next layer (usually the controller or final handler).
* @returns A promise resolving to the result of the request pipeline.
*/
async handle(event, next) {
/**
* Convert the raw event into a standardized HttpContext
*/
const ctx = await this.context(event);
const { app } = ctx.request;
/**
* Bind HTTP Response instance to the service container
*/
app.bind("http.response", () => {
return ctx.response;
});
/**
* Bind HTTP Request instance to the service container
*/
app.bind("http.request", () => {
return ctx.request;
});
/**
* Run middleware stack and obtain result
*/
const result = await this.runMiddleware(ctx, () => next(ctx));
/**
* If a plain object is returned from a controller or middleware,
* automatically set the JSON Content-Type header for the response.
*/
if (result !== void 0 && this.isPlainObject(result)) event.res.headers.set("Content-Type", "application/json; charset=UTF-8");
return result;
}
/**
* Sequentially runs middleware in the order they were registered.
*
* @param context - The standardized HttpContext.
* @param next - Callback to execute when middleware completes.
* @returns A promise resolving to the final handler's result.
*/
async runMiddleware(context, next) {
let index = -1;
const runner = async (i) => {
if (i <= index) throw new Error("next() called multiple times");
index = i;
const middleware = this.middleware[i];
if (middleware)
/**
* Execute the current middleware and proceed to the next one
*/
return middleware.handle(context, () => runner(i + 1));
else
/**
* If no more middleware, call the final handler
*/
return next(context);
};
return runner(0);
}
/**
* Utility function to determine if a value is a plain object or array.
*
* @param value - The value to check.
* @returns True if the value is a plain object or array, otherwise false.
*/
isPlainObject(value) {
return typeof value === "object" && value !== null && (value.constructor === Object || value.constructor === Array);
}
};
//#endregion
//#region src/ServiceProvider.ts
const Inference = class {};
var ServiceProvider = class extends Inference {
/**
* The current app instance
*/
app;
/**
* Unique Identifier for the service providers
*/
static uid;
/**
* Sort order
*/
static order;
/**
* Sort priority
*/
static priority = 0;
/**
* Indicate that this service provider only runs in console
*/
static console = false;
/**
* List of registered console commands
*/
registeredCommands;
constructor(app) {
super();
this.app = app;
}
/**
* Register the listed service providers.
*
* @param commands An array of console commands to register.
*
* @deprecated since version 1.16.0. Will be removed in future versions, use `registerCommands` instead
*/
commands(commands) {
this.registerCommands(commands);
}
/**
* Register the listed service providers.
*
* @param commands An array of console commands to register.
*/
registerCommands(commands) {
this.registeredCommands = commands;
}
};
//#endregion
//#region src/Providers/CoreServiceProvider.ts
/**
* Bootstraps core services and bindings.
*
* Bind essential services to the container (logger, config repository).
* Register app-level singletons.
* Set up exception handling.
*
* Auto-Registered
*/
var CoreServiceProvider = class extends ServiceProvider {
static priority = 999;
register() {
Object.assign(globalThis, { str: __h3ravel_support.str });
}
boot() {
try {
Object.assign(globalThis, { asset: this.app.make("asset") });
} catch {}
}
};
//#endregion
exports.Application = Application;
exports.ConfigException = ConfigException;
exports.Container = Container;
exports.ContainerResolver = ContainerResolver;
exports.Controller = Controller;
exports.CoreServiceProvider = CoreServiceProvider;
exports.Inject = Inject;
exports.Injectable = Injectable;
exports.Kernel = Kernel;
exports.ProviderRegistry = ProviderRegistry;
exports.Registerer = Registerer;
exports.ServiceProvider = ServiceProvider;
exports.h3ravel = h3ravel;