@navios/core 1.0.0 → 1.1.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/lib/{index-C0Sg16Eb.d.cts → index-3LcTrbxz.d.mts} +491 -52
  3. package/lib/index-3LcTrbxz.d.mts.map +1 -0
  4. package/lib/{index-DySQ6Dpd.d.mts → index-B14SekVb.d.cts} +491 -52
  5. package/lib/index-B14SekVb.d.cts.map +1 -0
  6. package/lib/index.cjs +18 -3
  7. package/lib/index.d.cts +2 -2
  8. package/lib/index.d.mts +2 -2
  9. package/lib/index.mjs +4 -4
  10. package/lib/legacy-compat/index.cjs +3 -3
  11. package/lib/legacy-compat/index.d.cts +1 -1
  12. package/lib/legacy-compat/index.d.mts +1 -1
  13. package/lib/legacy-compat/index.mjs +2 -2
  14. package/lib/{navios.factory-CO5MB_OK.cjs → navios.factory-CUrO_p6K.cjs} +461 -48
  15. package/lib/navios.factory-CUrO_p6K.cjs.map +1 -0
  16. package/lib/{navios.factory-D6Y94P9B.mjs → navios.factory-DjUOOVVL.mjs} +372 -49
  17. package/lib/navios.factory-DjUOOVVL.mjs.map +1 -0
  18. package/lib/testing/index.cjs +2 -2
  19. package/lib/testing/index.d.cts +1 -1
  20. package/lib/testing/index.d.mts +1 -1
  21. package/lib/testing/index.mjs +2 -2
  22. package/lib/{tokens-CWw9kyeD.cjs → tokens-BEuBMGGX.cjs} +18 -21
  23. package/lib/tokens-BEuBMGGX.cjs.map +1 -0
  24. package/lib/{tokens-4J9sredA.mjs → tokens-COyNGV1I.mjs} +17 -20
  25. package/lib/tokens-COyNGV1I.mjs.map +1 -0
  26. package/lib/{use-guards.decorator-BecoQSmE.mjs → use-guards.decorator-DLmRl2CV.mjs} +14 -17
  27. package/lib/use-guards.decorator-DLmRl2CV.mjs.map +1 -0
  28. package/lib/{use-guards.decorator-C4ml9XaT.cjs → use-guards.decorator-DhumFTk3.cjs} +15 -18
  29. package/lib/use-guards.decorator-DhumFTk3.cjs.map +1 -0
  30. package/package.json +2 -2
  31. package/src/interfaces/index.mts +3 -0
  32. package/src/interfaces/plugin-context.mts +104 -0
  33. package/src/interfaces/plugin-stage.mts +62 -0
  34. package/src/interfaces/plugin.interface.mts +42 -62
  35. package/src/interfaces/staged-plugin.interface.mts +209 -0
  36. package/src/metadata/controller.metadata.mts +29 -22
  37. package/src/metadata/module.metadata.mts +33 -25
  38. package/src/navios.application.mts +247 -53
  39. package/src/services/module-loader.service.mts +11 -8
  40. package/src/utils/define-plugin.mts +251 -0
  41. package/src/utils/index.mts +1 -0
  42. package/lib/index-C0Sg16Eb.d.cts.map +0 -1
  43. package/lib/index-DySQ6Dpd.d.mts.map +0 -1
  44. package/lib/navios.factory-CO5MB_OK.cjs.map +0 -1
  45. package/lib/navios.factory-D6Y94P9B.mjs.map +0 -1
  46. package/lib/tokens-4J9sredA.mjs.map +0 -1
  47. package/lib/tokens-CWw9kyeD.cjs.map +0 -1
  48. package/lib/use-guards.decorator-BecoQSmE.mjs.map +0 -1
  49. package/lib/use-guards.decorator-C4ml9XaT.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { a as NaviosOptionsToken, d as AdapterToken, p as extractModuleMetadata } from "./tokens-4J9sredA.mjs";
1
+ import { a as NaviosOptionsToken, d as AdapterToken, p as extractModuleMetadata } from "./tokens-COyNGV1I.mjs";
2
2
  import { Container, Injectable, InjectableScope, InjectionToken, getInjectableToken, inject, optional } from "@navios/di";
3
3
  import z from "zod/v4";
4
4
  import { inspect } from "util";
@@ -1129,6 +1129,57 @@ var LoggerInstance = class {
1129
1129
  }
1130
1130
  };
1131
1131
 
1132
+ //#endregion
1133
+ //#region src/interfaces/plugin-stage.mts
1134
+ /**
1135
+ * Base stage names (without pre:/post: prefix)
1136
+ */
1137
+ const PluginStageBase = {
1138
+ MODULES_TRAVERSE: "modules-traverse",
1139
+ ADAPTER_RESOLVE: "adapter-resolve",
1140
+ ADAPTER_SETUP: "adapter-setup",
1141
+ MODULES_INIT: "modules-init",
1142
+ READY: "ready"
1143
+ };
1144
+ /**
1145
+ * Helper to create pre stage name from base
1146
+ */
1147
+ const preStage = (base) => `pre:${base}`;
1148
+ /**
1149
+ * Helper to create post stage name from base
1150
+ */
1151
+ const postStage = (base) => `post:${base}`;
1152
+ /**
1153
+ * All stages as constants for direct access
1154
+ */
1155
+ const PluginStages = {
1156
+ PRE_MODULES_TRAVERSE: "pre:modules-traverse",
1157
+ POST_MODULES_TRAVERSE: "post:modules-traverse",
1158
+ PRE_ADAPTER_RESOLVE: "pre:adapter-resolve",
1159
+ POST_ADAPTER_RESOLVE: "post:adapter-resolve",
1160
+ PRE_ADAPTER_SETUP: "pre:adapter-setup",
1161
+ POST_ADAPTER_SETUP: "post:adapter-setup",
1162
+ PRE_MODULES_INIT: "pre:modules-init",
1163
+ POST_MODULES_INIT: "post:modules-init",
1164
+ PRE_READY: "pre:ready",
1165
+ POST_READY: "post:ready"
1166
+ };
1167
+ /**
1168
+ * All stages in execution order
1169
+ */
1170
+ const PLUGIN_STAGES_ORDER = [
1171
+ PluginStages.PRE_MODULES_TRAVERSE,
1172
+ PluginStages.POST_MODULES_TRAVERSE,
1173
+ PluginStages.PRE_ADAPTER_RESOLVE,
1174
+ PluginStages.POST_ADAPTER_RESOLVE,
1175
+ PluginStages.PRE_ADAPTER_SETUP,
1176
+ PluginStages.POST_ADAPTER_SETUP,
1177
+ PluginStages.PRE_MODULES_INIT,
1178
+ PluginStages.POST_MODULES_INIT,
1179
+ PluginStages.PRE_READY,
1180
+ PluginStages.POST_READY
1181
+ ];
1182
+
1132
1183
  //#endregion
1133
1184
  //#region src/responders/enums/framework-error.enum.mts
1134
1185
  /**
@@ -2766,9 +2817,15 @@ var ModuleLoaderService = class {
2766
2817
  * ```
2767
2818
  */ async extendModules(extensions) {
2768
2819
  if (!this.initialized) throw new Error("ModuleLoaderService must be initialized before extending. Call loadModules() first.");
2769
- for (const extension of extensions) if (extension.module) await this.traverseModules(extension.module);
2770
- else if (extension.controllers && extension.moduleName) await this.registerControllers(extension.controllers, extension.moduleName);
2771
- else if (extension.controllers) throw new Error("moduleName is required when providing controllers without a module");
2820
+ for (const extension of extensions) {
2821
+ if (extension.module) {
2822
+ await this.traverseModules(extension.module);
2823
+ continue;
2824
+ }
2825
+ if (!extension.controllers) continue;
2826
+ if (!extension.moduleName) throw new Error("moduleName is required when providing controllers without a module");
2827
+ await this.registerControllers(extension.controllers, extension.moduleName);
2828
+ }
2772
2829
  }
2773
2830
  /**
2774
2831
  * Registers controllers under a synthetic module.
@@ -2780,6 +2837,7 @@ var ModuleLoaderService = class {
2780
2837
  this.logger.debug(`Extended module ${moduleName} with ${controllers.length} controllers`);
2781
2838
  } else {
2782
2839
  const metadata = {
2840
+ name: moduleName,
2783
2841
  controllers: new Set(controllers),
2784
2842
  imports: /* @__PURE__ */ new Set(),
2785
2843
  guards: /* @__PURE__ */ new Set(),
@@ -2879,6 +2937,167 @@ var ModuleLoaderService = class {
2879
2937
  if (!adapterSupports(adapter, method)) throw new Error(`Current adapter does not implement '${method}()'`);
2880
2938
  }
2881
2939
 
2940
+ //#endregion
2941
+ //#region src/utils/define-plugin.mts
2942
+ /**
2943
+ * Creates a curried plugin factory for a specific stage.
2944
+ * Returns a function that takes config and returns a function that takes options.
2945
+ */ function createPluginFactory(stage) {
2946
+ return (config) => (options) => ({
2947
+ plugin: {
2948
+ name: config.name,
2949
+ stage,
2950
+ register: config.register
2951
+ },
2952
+ options
2953
+ });
2954
+ }
2955
+ /**
2956
+ * Define a plugin that runs before modules are traversed.
2957
+ *
2958
+ * Context: container only
2959
+ *
2960
+ * Use this stage for early DI setup before any modules are loaded.
2961
+ *
2962
+ * @example
2963
+ * ```typescript
2964
+ * export const defineEarlySetupPlugin = definePreModulesTraversePlugin({
2965
+ * name: 'early-setup',
2966
+ * register: (context, options: { key: string }) => {
2967
+ * context.container.addInstance(SomeToken, options.key)
2968
+ * },
2969
+ * })
2970
+ *
2971
+ * // Usage
2972
+ * app.usePlugin(defineEarlySetupPlugin({ key: 'value' }))
2973
+ * ```
2974
+ */ const definePreModulesTraversePlugin = createPluginFactory(PluginStages.PRE_MODULES_TRAVERSE);
2975
+ /**
2976
+ * Define a plugin that runs after modules are traversed.
2977
+ *
2978
+ * Context: container + modules + moduleLoader
2979
+ *
2980
+ * Use this stage to inspect loaded modules or extend the module tree.
2981
+ *
2982
+ * @example
2983
+ * ```typescript
2984
+ * export const defineModuleInspectorPlugin = definePostModulesTraversePlugin({
2985
+ * name: 'module-inspector',
2986
+ * register: (context, options) => {
2987
+ * console.log('Loaded modules:', context.modules.size)
2988
+ * },
2989
+ * })
2990
+ * ```
2991
+ */ const definePostModulesTraversePlugin = createPluginFactory(PluginStages.POST_MODULES_TRAVERSE);
2992
+ /**
2993
+ * Define a plugin that runs before adapter is resolved from container.
2994
+ *
2995
+ * Context: container + modules + moduleLoader (NO adapter yet!)
2996
+ *
2997
+ * Use this stage to modify registry/bindings before adapter instantiation.
2998
+ * This is ideal for instrumentation, service wrapping, or changing DI bindings.
2999
+ *
3000
+ * @example
3001
+ * ```typescript
3002
+ * export const defineOtelPlugin = definePreAdapterResolvePlugin({
3003
+ * name: 'otel',
3004
+ * register: (context, options: OtelOptions) => {
3005
+ * const registry = context.container.getRegistry()
3006
+ * // Modify registry before adapter is created
3007
+ * },
3008
+ * })
3009
+ *
3010
+ * // Usage
3011
+ * app.usePlugin(defineOtelPlugin({ serviceName: 'my-app' }))
3012
+ * ```
3013
+ */ const definePreAdapterResolvePlugin = createPluginFactory(PluginStages.PRE_ADAPTER_RESOLVE);
3014
+ /**
3015
+ * Define a plugin that runs after adapter is resolved.
3016
+ *
3017
+ * Context: full (container + modules + moduleLoader + adapter)
3018
+ *
3019
+ * @example
3020
+ * ```typescript
3021
+ * export const defineAdapterConfigPlugin = definePostAdapterResolvePlugin<
3022
+ * { prefix: string },
3023
+ * BunApplicationServiceInterface
3024
+ * >()({
3025
+ * name: 'adapter-config',
3026
+ * register: (context, options) => {
3027
+ * context.adapter.setGlobalPrefix(options.prefix)
3028
+ * },
3029
+ * })
3030
+ * ```
3031
+ */ function definePostAdapterResolvePlugin() {
3032
+ return createPluginFactory(PluginStages.POST_ADAPTER_RESOLVE);
3033
+ }
3034
+ /**
3035
+ * Define a plugin that runs before adapter setup.
3036
+ *
3037
+ * Context: full
3038
+ */ function definePreAdapterSetupPlugin() {
3039
+ return createPluginFactory(PluginStages.PRE_ADAPTER_SETUP);
3040
+ }
3041
+ /**
3042
+ * Define a plugin that runs after adapter setup.
3043
+ *
3044
+ * Context: full
3045
+ */ function definePostAdapterSetupPlugin() {
3046
+ return createPluginFactory(PluginStages.POST_ADAPTER_SETUP);
3047
+ }
3048
+ /**
3049
+ * Define a plugin that runs before modules init (route registration).
3050
+ *
3051
+ * Context: full
3052
+ */ function definePreModulesInitPlugin() {
3053
+ return createPluginFactory(PluginStages.PRE_MODULES_INIT);
3054
+ }
3055
+ /**
3056
+ * Define a plugin that runs after modules init (route registration).
3057
+ *
3058
+ * Context: full
3059
+ *
3060
+ * This is the default stage for legacy NaviosPlugin implementations.
3061
+ *
3062
+ * @example
3063
+ * ```typescript
3064
+ * export const defineOpenApiPlugin = definePostModulesInitPlugin<
3065
+ * BunApplicationServiceInterface
3066
+ * >()({
3067
+ * name: 'openapi',
3068
+ * register: async (context, options: OpenApiOptions) => {
3069
+ * // Routes are registered, can generate OpenAPI docs
3070
+ * },
3071
+ * })
3072
+ * ```
3073
+ */ function definePostModulesInitPlugin() {
3074
+ return createPluginFactory(PluginStages.POST_MODULES_INIT);
3075
+ }
3076
+ /**
3077
+ * Define a plugin that runs before adapter signals ready.
3078
+ *
3079
+ * Context: full
3080
+ */ function definePreReadyPlugin() {
3081
+ return createPluginFactory(PluginStages.PRE_READY);
3082
+ }
3083
+ /**
3084
+ * Define a plugin that runs after adapter signals ready.
3085
+ *
3086
+ * Context: full - this is the final stage, app is fully initialized
3087
+ *
3088
+ * @example
3089
+ * ```typescript
3090
+ * export const defineStartupLogPlugin = definePostReadyPlugin()({
3091
+ * name: 'startup-log',
3092
+ * register: (context) => {
3093
+ * console.log('Application fully initialized!')
3094
+ * },
3095
+ * })
3096
+ * ```
3097
+ */ function definePostReadyPlugin() {
3098
+ return createPluginFactory(PluginStages.POST_READY);
3099
+ }
3100
+
2882
3101
  //#endregion
2883
3102
  //#region src/navios.environment.mts
2884
3103
  function applyDecs2203RFactory$1() {
@@ -3477,7 +3696,14 @@ var NaviosApplication = class {
3477
3696
  container = inject(Container);
3478
3697
  appModule = null;
3479
3698
  options = { adapter: [] };
3480
- plugins = [];
3699
+ /**
3700
+ * Plugin storage organized by stage for efficient execution.
3701
+ * Each stage has a Set of plugin definitions.
3702
+ */ plugins = new Map(PLUGIN_STAGES_ORDER.map((stage) => [stage, /* @__PURE__ */ new Set()]));
3703
+ /**
3704
+ * Queue of adapter configuration methods to apply after adapter resolution.
3705
+ * Allows calling methods like enableCors() before init().
3706
+ */ pendingAdapterCalls = [];
3481
3707
  /**
3482
3708
  * Indicates whether the application has been initialized.
3483
3709
  * Set to `true` after `init()` completes successfully.
@@ -3486,13 +3712,15 @@ var NaviosApplication = class {
3486
3712
  * Sets up the application with the provided module and options.
3487
3713
  * This is called automatically by NaviosFactory.create().
3488
3714
  *
3715
+ * Note: Adapter resolution has been moved to init() to allow
3716
+ * plugins to modify the container/registry before adapter instantiation.
3717
+ *
3489
3718
  * @param appModule - The root application module
3490
3719
  * @param options - Application configuration options
3491
3720
  * @internal
3492
3721
  */ async setup(appModule, options = { adapter: [] }) {
3493
3722
  this.appModule = appModule;
3494
3723
  this.options = options;
3495
- if (this.environment.hasAdapterSetup()) this.adapter = await this.container.get(AdapterToken);
3496
3724
  }
3497
3725
  /**
3498
3726
  * Gets the dependency injection container used by this application.
@@ -3511,35 +3739,58 @@ var NaviosApplication = class {
3511
3739
  return this.adapter;
3512
3740
  }
3513
3741
  /**
3514
- * Registers a plugin to be initialized after modules are loaded.
3742
+ * Registers one or more plugins for initialization during the application lifecycle.
3515
3743
  *
3516
- * Plugins are initialized in the order they are registered,
3517
- * after all modules are loaded but before the server starts listening.
3744
+ * Plugins can target specific stages or use the legacy interface (defaults to post:modules-init).
3745
+ * Plugins are executed in stage order, and within a stage in registration order.
3518
3746
  *
3519
- * @param definition - Plugin definition with options
3747
+ * @param definitions - Single plugin definition or array of definitions
3520
3748
  * @returns this for method chaining
3521
3749
  *
3522
3750
  * @example
3523
3751
  * ```typescript
3524
- * import { defineOpenApiPlugin } from '@navios/openapi-fastify'
3752
+ * // Single plugin (legacy or staged)
3753
+ * app.usePlugin(defineOpenApiPlugin({ info: { title: 'My API', version: '1.0.0' } }))
3525
3754
  *
3526
- * app.usePlugin(defineOpenApiPlugin({
3527
- * info: { title: 'My API', version: '1.0.0' },
3528
- * }))
3755
+ * // Multiple plugins in one call
3756
+ * app.usePlugin([
3757
+ * defineOtelPlugin({ serviceName: 'my-service' }),
3758
+ * defineOpenApiPlugin({ info: { title: 'My API', version: '1.0.0' } }),
3759
+ * ])
3760
+ *
3761
+ * // Staged plugin with explicit stage
3762
+ * app.usePlugin(definePreAdapterResolvePlugin({
3763
+ * name: 'early-setup',
3764
+ * register: (ctx) => { ... },
3765
+ * })({}))
3529
3766
  * ```
3530
- */ usePlugin(definition) {
3531
- this.plugins.push(definition);
3767
+ */ usePlugin(definitions) {
3768
+ const definitionsArray = Array.isArray(definitions) ? definitions : [definitions];
3769
+ for (const definition of definitionsArray) {
3770
+ const stage = this.resolvePluginStage(definition);
3771
+ const stageSet = this.plugins.get(stage);
3772
+ if (!stageSet) throw new Error(`Unknown plugin stage: ${stage}`);
3773
+ stageSet.add(definition);
3774
+ this.logger.debug(`Registered plugin "${definition.plugin.name}" for stage: ${stage}`);
3775
+ }
3532
3776
  return this;
3533
3777
  }
3534
3778
  /**
3779
+ * Resolves the stage for a plugin definition.
3780
+ * Staged plugins use their explicit stage, legacy plugins default to post:modules-init.
3781
+ */ resolvePluginStage(definition) {
3782
+ if ("stage" in definition.plugin) return definition.plugin.stage;
3783
+ return PluginStages.POST_MODULES_INIT;
3784
+ }
3785
+ /**
3535
3786
  * Initializes the application.
3536
3787
  *
3537
- * This method:
3538
- * - Loads all modules and their dependencies
3539
- * - Sets up the adapter if one is configured
3540
- * - Calls onModuleInit hooks on all modules
3541
- * - Initializes registered plugins
3542
- * - Marks the application as initialized
3788
+ * This method executes the following lifecycle stages:
3789
+ * 1. pre:modules-traverse Load modules post:modules-traverse
3790
+ * 2. pre:adapter-resolve Resolve adapter post:adapter-resolve
3791
+ * 3. pre:adapter-setup Setup adapter post:adapter-setup
3792
+ * 4. pre:modules-init Initialize modules → post:modules-init
3793
+ * 5. pre:ready Ready signal → post:ready
3543
3794
  *
3544
3795
  * Must be called before `listen()`.
3545
3796
  *
@@ -3555,31 +3806,83 @@ var NaviosApplication = class {
3555
3806
  * ```
3556
3807
  */ async init() {
3557
3808
  if (!this.appModule) throw new Error("App module is not set. Call setAppModule() first.");
3558
- await this.moduleLoader.loadModules(this.appModule);
3559
- if (this.environment.hasAdapterSetup() && this.adapter) await this.adapter.setupAdapter(this.options);
3560
- await this.initPlugins();
3561
- await this.initModules();
3562
- if (this.adapter) await this.adapter.ready();
3809
+ await this.wrapStage(PluginStageBase.MODULES_TRAVERSE, () => this.moduleLoader.loadModules(this.appModule));
3810
+ if (this.environment.hasAdapterSetup()) {
3811
+ await this.wrapStage(PluginStageBase.ADAPTER_RESOLVE, async () => {
3812
+ this.adapter = await this.container.get(AdapterToken);
3813
+ this.applyPendingAdapterCalls();
3814
+ });
3815
+ if (this.adapter) await this.wrapStage(PluginStageBase.ADAPTER_SETUP, () => this.adapter.setupAdapter(this.options));
3816
+ }
3817
+ await this.wrapStage(PluginStageBase.MODULES_INIT, () => this.initModules());
3818
+ if (this.adapter) await this.wrapStage(PluginStageBase.READY, () => this.adapter.ready());
3563
3819
  this.isInitialized = true;
3564
3820
  this.logger.debug("Navios application initialized");
3565
3821
  }
3566
- async initModules() {
3567
- const modules = this.moduleLoader.getAllModules();
3568
- if (this.adapter) await this.adapter.onModulesInit(modules);
3822
+ /**
3823
+ * Wraps an operation with pre/post plugin stage execution.
3824
+ *
3825
+ * @param baseName - The base stage name (e.g., 'modules-traverse')
3826
+ * @param operation - The operation to execute between pre/post stages
3827
+ */ async wrapStage(baseName, operation) {
3828
+ await this.executePluginStage(preStage(baseName));
3829
+ const result = await operation();
3830
+ await this.executePluginStage(postStage(baseName));
3831
+ return result;
3569
3832
  }
3570
- async initPlugins() {
3571
- if (this.plugins.length === 0) return;
3572
- if (!this.adapter) throw new Error("Cannot initialize plugins without an adapter");
3573
- const context = {
3833
+ /**
3834
+ * Executes all plugins registered for a specific stage.
3835
+ *
3836
+ * @param stage - The lifecycle stage to execute plugins for
3837
+ */ async executePluginStage(stage) {
3838
+ const stagePlugins = this.plugins.get(stage);
3839
+ if (!stagePlugins || stagePlugins.size === 0) return;
3840
+ const context = this.buildContextForStage(stage);
3841
+ this.logger.debug(`Executing ${stagePlugins.size} plugin(s) for stage: ${stage}`);
3842
+ for (const { plugin, options } of stagePlugins) {
3843
+ this.logger.debug(`Executing plugin: ${plugin.name} (stage: ${stage})`);
3844
+ try {
3845
+ await plugin.register(context, options);
3846
+ } catch (error) {
3847
+ this.logger.error(`Plugin "${plugin.name}" failed at stage "${stage}"`, error);
3848
+ throw error;
3849
+ }
3850
+ }
3851
+ }
3852
+ /**
3853
+ * Builds the appropriate context object for a given stage.
3854
+ *
3855
+ * @param stage - The lifecycle stage
3856
+ * @returns Context object with stage-appropriate properties
3857
+ */ buildContextForStage(stage) {
3858
+ const baseContext = { container: this.container };
3859
+ if (stage === PluginStages.PRE_MODULES_TRAVERSE) return baseContext;
3860
+ const modulesContext = {
3861
+ ...baseContext,
3574
3862
  modules: this.moduleLoader.getAllModules(),
3575
- adapter: this.adapter,
3576
- container: this.container,
3577
3863
  moduleLoader: this.moduleLoader
3578
3864
  };
3579
- for (const { plugin, options } of this.plugins) {
3580
- this.logger.debug(`Initializing plugin: ${plugin.name}`);
3581
- await plugin.register(context, options);
3865
+ if (stage === PluginStages.POST_MODULES_TRAVERSE || stage === PluginStages.PRE_ADAPTER_RESOLVE) return modulesContext;
3866
+ if (!this.adapter) throw new Error(`Cannot execute stage "${stage}" without adapter`);
3867
+ return {
3868
+ ...modulesContext,
3869
+ adapter: this.adapter
3870
+ };
3871
+ }
3872
+ async initModules() {
3873
+ const modules = this.moduleLoader.getAllModules();
3874
+ if (this.adapter) await this.adapter.onModulesInit(modules);
3875
+ }
3876
+ /**
3877
+ * Applies any pending adapter configuration calls that were queued
3878
+ * before the adapter was resolved.
3879
+ */ applyPendingAdapterCalls() {
3880
+ if (!this.adapter || this.pendingAdapterCalls.length === 0) return;
3881
+ for (const { method, args } of this.pendingAdapterCalls) {
3882
+ assertAdapterSupports(this.adapter, method);
3883
+ this.adapter[method](...args);
3582
3884
  }
3885
+ this.pendingAdapterCalls = [];
3583
3886
  }
3584
3887
  async get(token, args) {
3585
3888
  return this.container.get(token, args);
@@ -3604,8 +3907,13 @@ var NaviosApplication = class {
3604
3907
  * ```
3605
3908
  */ configure(options) {
3606
3909
  if (this.isInitialized) throw new Error("configure() must be called before init()");
3607
- assertAdapterSupports(this.adapter, "configure");
3608
- this.adapter.configure(options);
3910
+ if (this.adapter) {
3911
+ assertAdapterSupports(this.adapter, "configure");
3912
+ this.adapter.configure(options);
3913
+ } else this.pendingAdapterCalls.push({
3914
+ method: "configure",
3915
+ args: [options]
3916
+ });
3609
3917
  return this;
3610
3918
  }
3611
3919
  /**
@@ -3623,8 +3931,13 @@ var NaviosApplication = class {
3623
3931
  * })
3624
3932
  * ```
3625
3933
  */ enableCors(options) {
3626
- assertAdapterSupports(this.adapter, "enableCors");
3627
- this.adapter.enableCors(options);
3934
+ if (this.adapter) {
3935
+ assertAdapterSupports(this.adapter, "enableCors");
3936
+ this.adapter.enableCors(options);
3937
+ } else this.pendingAdapterCalls.push({
3938
+ method: "enableCors",
3939
+ args: [options]
3940
+ });
3628
3941
  }
3629
3942
  /**
3630
3943
  * Enables multipart/form-data support for file uploads.
@@ -3641,8 +3954,13 @@ var NaviosApplication = class {
3641
3954
  * })
3642
3955
  * ```
3643
3956
  */ enableMultipart(options) {
3644
- assertAdapterSupports(this.adapter, "enableMultipart");
3645
- this.adapter.enableMultipart(options);
3957
+ if (this.adapter) {
3958
+ assertAdapterSupports(this.adapter, "enableMultipart");
3959
+ this.adapter.enableMultipart(options);
3960
+ } else this.pendingAdapterCalls.push({
3961
+ method: "enableMultipart",
3962
+ args: [options]
3963
+ });
3646
3964
  }
3647
3965
  /**
3648
3966
  * Sets a global prefix for all routes.
@@ -3656,8 +3974,13 @@ var NaviosApplication = class {
3656
3974
  * // All routes will be prefixed with /api/v1
3657
3975
  * ```
3658
3976
  */ setGlobalPrefix(prefix) {
3659
- assertAdapterSupports(this.adapter, "setGlobalPrefix");
3660
- this.adapter.setGlobalPrefix(prefix);
3977
+ if (this.adapter) {
3978
+ assertAdapterSupports(this.adapter, "setGlobalPrefix");
3979
+ this.adapter.setGlobalPrefix(prefix);
3980
+ } else this.pendingAdapterCalls.push({
3981
+ method: "setGlobalPrefix",
3982
+ args: [prefix]
3983
+ });
3661
3984
  }
3662
3985
  /**
3663
3986
  * Gets the underlying HTTP server instance.
@@ -3824,5 +4147,5 @@ var NaviosApplication = class {
3824
4147
  };
3825
4148
 
3826
4149
  //#endregion
3827
- export { isNil as A, filterLogLevels as B, getRequestId as C, isConstructor as D, addLeadingSlash as E, isSymbol as F, LOG_LEVELS as H, isUndefined as I, normalizePath as L, isObject as M, isPlainObject as N, isEmpty as O, isString as P, stripEndSlash as R, generateRequestId as S, setRequestIdEnabled as T, clc as U, isLogLevel as V, yellow as W, _LoggerInstance as _, assertAdapterSupports as a, LoggerOutput as b, AbstractHandlerAdapterService as c, ForbiddenResponderToken as d, InternalServerErrorResponderToken as f, HttpException as g, FrameworkError as h, adapterSupports as i, isNumber as j, isFunction as k, _InstanceResolverService as l, ValidationErrorResponderToken as m, _NaviosApplication as n, _ModuleLoaderService as o, NotFoundResponderToken as p, _NaviosEnvironment as r, _GuardRunnerService as s, NaviosFactory as t, _ErrorResponseProducerService as u, _ConsoleLogger as v, runWithRequestId as w, loggerOptionsSchema as x, Logger as y, isLogLevelEnabled as z };
3828
- //# sourceMappingURL=navios.factory-D6Y94P9B.mjs.map
4150
+ export { stripEndSlash as $, preStage as A, setRequestIdEnabled as B, NotFoundResponderToken as C, PluginStageBase as D, PLUGIN_STAGES_ORDER as E, LoggerOutput as F, isNil as G, isConstructor as H, loggerOptionsSchema as I, isPlainObject as J, isNumber as K, generateRequestId as L, _LoggerInstance as M, _ConsoleLogger as N, PluginStages as O, Logger as P, normalizePath as Q, getRequestId as R, InternalServerErrorResponderToken as S, FrameworkError as T, isEmpty as U, addLeadingSlash as V, isFunction as W, isSymbol as X, isString as Y, isUndefined as Z, _GuardRunnerService as _, definePostAdapterSetupPlugin as a, yellow as at, _ErrorResponseProducerService as b, definePostReadyPlugin as c, definePreModulesInitPlugin as d, isLogLevelEnabled as et, definePreModulesTraversePlugin as f, _ModuleLoaderService as g, assertAdapterSupports as h, definePostAdapterResolvePlugin as i, clc as it, HttpException as j, postStage as k, definePreAdapterResolvePlugin as l, adapterSupports as m, _NaviosApplication as n, isLogLevel as nt, definePostModulesInitPlugin as o, definePreReadyPlugin as p, isObject as q, _NaviosEnvironment as r, LOG_LEVELS as rt, definePostModulesTraversePlugin as s, NaviosFactory as t, filterLogLevels as tt, definePreAdapterSetupPlugin as u, AbstractHandlerAdapterService as v, ValidationErrorResponderToken as w, ForbiddenResponderToken as x, _InstanceResolverService as y, runWithRequestId as z };
4151
+ //# sourceMappingURL=navios.factory-DjUOOVVL.mjs.map