@lorion-org/nuxt 1.0.0-beta.1 → 1.0.0-beta.3

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.js CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  addServerImports,
7
7
  addServerTemplate,
8
8
  addTemplate,
9
+ addTypeTemplate,
9
10
  createResolver,
10
11
  defineNuxtModule,
11
12
  useLogger
@@ -14,14 +15,25 @@ import {
14
15
  // src/extensions.ts
15
16
  import { existsSync } from "fs";
16
17
  import { join } from "path";
18
+ import process from "process";
17
19
  import {
18
- createDescriptorCatalog
20
+ createDescriptorCatalog,
21
+ parseDescriptorIds,
22
+ resolveDescriptorSelectionSeed
19
23
  } from "@lorion-org/composition-graph";
20
24
  import { discoverDescriptors } from "@lorion-org/descriptor-discovery";
21
25
  import {
26
+ collectProviderDefaults,
22
27
  collectProviderPreferences,
28
+ collectSelectedProviderPreferences,
23
29
  resolveItemProviderSelection
24
30
  } from "@lorion-org/provider-selection";
31
+ import {
32
+ applyProviderSelection,
33
+ assertSingleDefaultProvider,
34
+ descriptorSelectionPolicy,
35
+ providerRelationDescriptors
36
+ } from "@lorion-org/descriptor-selection";
25
37
 
26
38
  // src/extension-descriptor.schema.json
27
39
  var extension_descriptor_schema_default = {
@@ -46,8 +58,19 @@ var extension_descriptor_schema_default = {
46
58
  },
47
59
  version: { $ref: "#/$defs/semver" },
48
60
  providesFor: {
49
- type: "string",
50
- minLength: 1
61
+ oneOf: [
62
+ {
63
+ type: "string",
64
+ minLength: 1
65
+ },
66
+ {
67
+ type: "array",
68
+ items: {
69
+ type: "string",
70
+ minLength: 1
71
+ }
72
+ }
73
+ ]
51
74
  },
52
75
  capabilities: {
53
76
  type: "array",
@@ -59,6 +82,21 @@ var extension_descriptor_schema_default = {
59
82
  dependencies: { $ref: "#/$defs/dependencyMap" },
60
83
  disabled: { type: "boolean" },
61
84
  location: { type: "string" },
85
+ defaultFor: {
86
+ oneOf: [
87
+ {
88
+ type: "string",
89
+ minLength: 1
90
+ },
91
+ {
92
+ type: "array",
93
+ items: {
94
+ type: "string",
95
+ minLength: 1
96
+ }
97
+ }
98
+ ]
99
+ },
62
100
  providerPreferences: {
63
101
  type: "object",
64
102
  additionalProperties: {
@@ -70,6 +108,16 @@ var extension_descriptor_schema_default = {
70
108
  type: "object",
71
109
  additionalProperties: true
72
110
  },
111
+ runtimeConfig: {
112
+ type: "object",
113
+ properties: {
114
+ validation: {
115
+ type: "string",
116
+ enum: ["none", "optional", "startup", "onUse"]
117
+ }
118
+ },
119
+ additionalProperties: false
120
+ },
73
121
  bundles: {
74
122
  type: "array",
75
123
  items: { $ref: "#/$defs/extension" }
@@ -90,20 +138,21 @@ var defaultExtensionOptions = {
90
138
  publicRuntimeConfigKey: "extensionSelection",
91
139
  descriptorPaths: ["extensions/*/extension.json"]
92
140
  };
141
+ var defaultExtensionSelectionSeedKey = "capability";
93
142
  function isRecord(value) {
94
143
  return typeof value === "object" && value !== null && !Array.isArray(value);
95
144
  }
96
- function asArray(value) {
97
- if (value === void 0) return [];
98
- return Array.isArray(value) ? value : [value];
99
- }
100
- function splitSelectionValue(value) {
101
- return value.split(/[,\s]+/).map((entry) => entry.trim()).filter(Boolean);
102
- }
103
145
  function normalizeSelection(value) {
104
- return asArray(value).flatMap((entry) => {
105
- if (typeof entry !== "string") return [];
106
- return splitSelectionValue(entry);
146
+ return parseDescriptorIds(value);
147
+ }
148
+ function resolveNuxtExtensionSelectionSeed(seedOptions) {
149
+ if (seedOptions === false) return [];
150
+ return resolveDescriptorSelectionSeed({
151
+ argv: seedOptions?.argv ?? process.argv,
152
+ env: seedOptions?.env ?? process.env,
153
+ key: seedOptions?.key ?? defaultExtensionSelectionSeedKey,
154
+ ...seedOptions?.cliKeys ? { cliKeys: seedOptions.cliKeys } : {},
155
+ ...seedOptions?.envKeys ? { envKeys: seedOptions.envKeys } : {}
107
156
  });
108
157
  }
109
158
  function resolveExtensionOptions(options) {
@@ -133,6 +182,10 @@ function findNuxtConfigFile(cwd) {
133
182
  return ["nuxt.config.ts", "nuxt.config.mts", "nuxt.config.js", "nuxt.config.mjs"].map((fileName) => optionalFile(join(cwd, fileName))).find(Boolean);
134
183
  }
135
184
  function createExtensionEntry(input) {
185
+ const descriptor = {
186
+ ...input.descriptor,
187
+ location: input.descriptor.location ?? input.cwd
188
+ };
136
189
  const appDir = optionalDir(join(input.cwd, "app"));
137
190
  const modulesDir = optionalDir(join(input.cwd, "modules"));
138
191
  const publicDir = optionalDir(join(input.cwd, "public"));
@@ -141,7 +194,7 @@ function createExtensionEntry(input) {
141
194
  const configFile = findNuxtConfigFile(input.cwd);
142
195
  const entry = {
143
196
  cwd: input.cwd,
144
- descriptor: input.descriptor
197
+ descriptor
145
198
  };
146
199
  if (appDir) entry.appDir = appDir;
147
200
  if (configFile) entry.configFile = configFile;
@@ -159,7 +212,7 @@ function canRegisterExtensionLayer(entry) {
159
212
  function canExtendExtensionLayer(entry) {
160
213
  return Boolean(entry.configFile);
161
214
  }
162
- function discoverExtensionEntries(input) {
215
+ function discoverNuxtExtensionEntries(input) {
163
216
  const resolvedOptions = resolveExtensionOptions(input.options);
164
217
  return discoverDescriptors({
165
218
  cwd: input.projectRootDir,
@@ -177,9 +230,26 @@ function discoverExtensionEntries(input) {
177
230
  })
178
231
  );
179
232
  }
233
+ function createNuxtExtensionCatalog(input) {
234
+ return createDescriptorCatalog({
235
+ descriptors: input.entries.map((entry) => entry.descriptor),
236
+ relationDescriptors: [...providerRelationDescriptors, ...input.relationDescriptors ?? []]
237
+ });
238
+ }
239
+ function createNuxtExtensionEntryMap(entries) {
240
+ return new Map(entries.map((entry) => [entry.descriptor.id, entry]));
241
+ }
180
242
  function pickEntriesById(ids, entryById) {
181
243
  return ids.map((id) => entryById.get(id)).filter((entry) => Boolean(entry));
182
244
  }
245
+ function createNuxtSelectedProviderPreferences(input) {
246
+ return collectSelectedProviderPreferences({
247
+ items: input.entries,
248
+ getCapabilityId: (entry) => entry.descriptor.providesFor,
249
+ getProviderId: (entry) => entry.descriptor.id,
250
+ selectedProviderIds: input.selectedExtensions
251
+ });
252
+ }
183
253
  function mergeRuntimeConfigSection(target = {}, source = {}) {
184
254
  const merged = { ...target };
185
255
  for (const [key, value] of Object.entries(source)) {
@@ -216,10 +286,10 @@ function createNuxtExtensionBootstrap(input) {
216
286
  const options = input.options ?? {};
217
287
  const selectedExtensions = resolveExtensionSelection({
218
288
  ...options.defaultSelection ? { defaultSelection: options.defaultSelection } : {},
219
- ...options.selected ? { selected: options.selected } : {}
289
+ selected: options.selected ?? resolveNuxtExtensionSelectionSeed(options.selectionSeed)
220
290
  });
221
- const createCatalog = (entries2) => createDescriptorCatalog({
222
- descriptors: entries2.map((entry) => entry.descriptor),
291
+ const createCatalog = (entries2) => createNuxtExtensionCatalog({
292
+ entries: entries2,
223
293
  ...options.relationDescriptors ? { relationDescriptors: options.relationDescriptors } : {}
224
294
  });
225
295
  if (options.enabled === false) {
@@ -234,7 +304,7 @@ function createNuxtExtensionBootstrap(input) {
234
304
  selectedExtensions
235
305
  };
236
306
  }
237
- const entries = discoverExtensionEntries({
307
+ const entries = discoverNuxtExtensionEntries({
238
308
  projectRootDir: input.rootDir,
239
309
  options
240
310
  });
@@ -243,7 +313,6 @@ function createNuxtExtensionBootstrap(input) {
243
313
  options,
244
314
  selectedExtensions
245
315
  });
246
- const entryById = new Map(entries.map((entry) => [entry.descriptor.id, entry]));
247
316
  if (!entries.length) {
248
317
  return {
249
318
  activeExtensions: [],
@@ -256,13 +325,24 @@ function createNuxtExtensionBootstrap(input) {
256
325
  selectedExtensions
257
326
  };
258
327
  }
259
- const catalog = createCatalog(entries);
328
+ assertSingleDefaultProvider(entries.map((entry) => entry.descriptor));
329
+ const resolutionEntries = applyProviderSelection({
330
+ items: entries,
331
+ selected: selectedExtensions,
332
+ getDescriptor: (entry) => entry.descriptor,
333
+ withDescriptor: (entry, descriptor) => ({ ...entry, descriptor })
334
+ });
335
+ const catalog = createCatalog(resolutionEntries);
260
336
  const selection = catalog.resolveSelection({
261
337
  baseDescriptors: baseExtensionIds,
338
+ policy: descriptorSelectionPolicy(),
262
339
  selected: selectedExtensions
263
340
  });
264
341
  const resolvedExtensionIds = selection.getResolved();
265
- const resolvedExtensions = pickEntriesById(resolvedExtensionIds, entryById);
342
+ const resolvedExtensions = pickEntriesById(
343
+ resolvedExtensionIds,
344
+ createNuxtExtensionEntryMap(resolutionEntries)
345
+ );
266
346
  const activeExtensions = resolvedExtensions.filter(canRegisterExtensionLayer);
267
347
  return {
268
348
  activeExtensions,
@@ -291,21 +371,32 @@ function createNuxtProviderSelectionRuntimeConfig(extensions, options = {}) {
291
371
  items: extensions,
292
372
  getProviderPreferences: (extension) => extension.descriptor.providerPreferences
293
373
  });
294
- const configuredProviders = {
374
+ const providerDefaults = collectProviderDefaults({
375
+ items: extensions,
376
+ getDefaultFor: (extension) => extension.descriptor.defaultFor,
377
+ getProviderId: (extension) => extension.descriptor.id
378
+ });
379
+ const configuredProviders = options.configuredProviders ?? {};
380
+ const selectedProviders = options.selectedProviders ?? {};
381
+ const fallbackProviders = {
382
+ ...providerDefaults,
295
383
  ...descriptorPreferences,
296
- ...options.configuredProviders ?? {}
384
+ ...options.fallbackProviders ?? {}
297
385
  };
298
386
  const resolution = resolveItemProviderSelection({
299
387
  items: extensions,
300
388
  getCapabilityId: (extension) => extension.descriptor.providesFor,
301
389
  getProviderId: (extension) => extension.descriptor.id,
302
- configuredProviders
390
+ configuredProviders,
391
+ fallbackProviders,
392
+ selectedProviders
303
393
  });
304
394
  return {
305
395
  public: {
306
396
  [publicRuntimeConfigKey]: {
307
397
  configuredProviders,
308
398
  excludedProviderIds: resolution.excludedProviderIds,
399
+ fallbackProviders,
309
400
  mismatches: resolution.mismatches,
310
401
  selections: Object.fromEntries(resolution.selections)
311
402
  }
@@ -458,14 +549,27 @@ function validateNuxtRuntimeConfigSourceScopes(source, targets, options = {}) {
458
549
  }
459
550
 
460
551
  // src/module.ts
552
+ import {
553
+ resolveRuntimeConfigValidationMode,
554
+ shouldRequireRuntimeConfigAtStartup
555
+ } from "@lorion-org/runtime-config";
556
+ import {
557
+ assertRequiredRuntimeConfigValidationTargets,
558
+ readRuntimeConfigSchemaRegistry
559
+ } from "@lorion-org/runtime-config-node";
461
560
  var runtimeConfigImportNames = [
462
561
  "useRuntimeConfigFragment",
562
+ "useValidatedRuntimeConfigFragment",
463
563
  "useRuntimeConfigScope",
564
+ "useValidatedRuntimeConfigScope",
464
565
  "usePublicRuntimeConfigScope",
566
+ "usePublicValidatedRuntimeConfigScope",
465
567
  "usePrivateRuntimeConfigScope",
568
+ "usePrivateValidatedRuntimeConfigScope",
466
569
  "useRuntimeConfigValue"
467
570
  ];
468
- var runtimeConfigComposablesTemplate = "lorion/runtime-config-composables.ts";
571
+ var runtimeConfigComposablesTemplate = "lorion/runtime-config-composables.mjs";
572
+ var runtimeConfigComposablesImport = "#build/lorion/runtime-config-composables";
469
573
  var serverRuntimeConfigComposablesTemplate = "#internal/lorion-runtime-config-composables.mjs";
470
574
  var defaultRuntimeConfigSource = {
471
575
  contextInputKey: "contexts",
@@ -503,6 +607,7 @@ function normalizeImportPath(path) {
503
607
  return path.replace(/\\/g, "/");
504
608
  }
505
609
  function createRuntimeConfigComposablesSource(input) {
610
+ const validationSchemasSource = JSON.stringify(input.validationSchemas);
506
611
  const typeImports = input.typed ? `
507
612
  import type {
508
613
  GetRuntimeConfigFragmentOptions,
@@ -559,6 +664,7 @@ export type UseRuntimeConfigFragmentOptions =
559
664
  valueReturn: ""
560
665
  };
561
666
  return `import { useRuntimeConfig } from '${input.useRuntimeConfigFrom}'
667
+ import { createRuntimeConfigValidatorRegistry } from '@lorion-org/runtime-config'
562
668
  import {
563
669
  getNuxtRuntimeConfigFragment,
564
670
  getNuxtRuntimeConfigScope,
@@ -568,6 +674,12 @@ import {
568
674
  } from '${input.runtimeConfigFrom}'
569
675
  ${typeImports}
570
676
  const runtimeConfigDefaultsKey = '__lorionNuxt'
677
+ const runtimeConfigValidationSchemas = ${validationSchemasSource}
678
+ const runtimeConfigValidatorRegistry = createRuntimeConfigValidatorRegistry(runtimeConfigValidationSchemas)
679
+
680
+ function assertValidatedRuntimeConfigFragment(scopeId, fragment) {
681
+ runtimeConfigValidatorRegistry.assert(scopeId, fragment)
682
+ }
571
683
 
572
684
  function getComposableDefaults(runtimeConfig${typeAnnotations.runtimeConfig})${typeAnnotations.defaults} {
573
685
  const container = runtimeConfig.public?.[runtimeConfigDefaultsKey]
@@ -596,24 +708,66 @@ export function useRuntimeConfigFragment(scopeId, options${typeAnnotations.fragm
596
708
  return getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
597
709
  }
598
710
 
711
+ export function useValidatedRuntimeConfigFragment(scopeId, options${typeAnnotations.fragmentOptions} = {})${typeAnnotations.fragmentReturn} {
712
+ const runtimeConfig = useRuntimeConfig()
713
+ const fragment = getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
714
+
715
+ assertValidatedRuntimeConfigFragment(scopeId, fragment)
716
+
717
+ return fragment
718
+ }
719
+
599
720
  export function useRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.scopeOptions} = {}) {
600
721
  const runtimeConfig = useRuntimeConfig()
601
722
 
602
723
  return getNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
603
724
  }
604
725
 
726
+ export function useValidatedRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.scopeOptions} = {}) {
727
+ const runtimeConfig = useRuntimeConfig()
728
+
729
+ assertValidatedRuntimeConfigFragment(
730
+ scopeId,
731
+ getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options)),
732
+ )
733
+
734
+ return getNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
735
+ }
736
+
605
737
  export function usePublicRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.publicOptions} = {}) {
606
738
  const runtimeConfig = useRuntimeConfig()
607
739
 
608
740
  return getPublicNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
609
741
  }
610
742
 
743
+ export function usePublicValidatedRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.publicOptions} = {}) {
744
+ const runtimeConfig = useRuntimeConfig()
745
+
746
+ assertValidatedRuntimeConfigFragment(
747
+ scopeId,
748
+ getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options)),
749
+ )
750
+
751
+ return getPublicNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
752
+ }
753
+
611
754
  export function usePrivateRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.privateOptions} = {}) {
612
755
  const runtimeConfig = useRuntimeConfig()
613
756
 
614
757
  return getPrivateNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
615
758
  }
616
759
 
760
+ export function usePrivateValidatedRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.privateOptions} = {}) {
761
+ const runtimeConfig = useRuntimeConfig()
762
+
763
+ assertValidatedRuntimeConfigFragment(
764
+ scopeId,
765
+ getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options)),
766
+ )
767
+
768
+ return getPrivateNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
769
+ }
770
+
617
771
  export function useRuntimeConfigValue${typeAnnotations.valueOptions}(scopeId, key, options${typeAnnotations.valueOptionsType} = {})${typeAnnotations.valueReturn} {
618
772
  const runtimeConfig = useRuntimeConfig()
619
773
 
@@ -621,6 +775,72 @@ export function useRuntimeConfigValue${typeAnnotations.valueOptions}(scopeId, ke
621
775
  }
622
776
  `;
623
777
  }
778
+ function createRuntimeConfigComposablesTypesSource() {
779
+ return `declare module '${runtimeConfigComposablesImport}' {
780
+ import type {
781
+ GetRuntimeConfigFragmentOptions,
782
+ GetRuntimeConfigScopeOptions,
783
+ ResolveRuntimeConfigValueFromRuntimeConfigOptions,
784
+ RuntimeConfigContext,
785
+ RuntimeConfigSection,
786
+ } from '@lorion-org/runtime-config'
787
+
788
+ type NuxtPrivateRuntimeConfigMode = 'root' | 'section'
789
+ type ReadNuxtRuntimeConfigOptions = {
790
+ privateInput?: NuxtPrivateRuntimeConfigMode
791
+ }
792
+
793
+ export function useRuntimeConfigFragment(
794
+ scopeId: string,
795
+ options?: GetRuntimeConfigFragmentOptions & ReadNuxtRuntimeConfigOptions,
796
+ ): RuntimeConfigContext
797
+ export function useValidatedRuntimeConfigFragment(
798
+ scopeId: string,
799
+ options?: GetRuntimeConfigFragmentOptions & ReadNuxtRuntimeConfigOptions,
800
+ ): RuntimeConfigContext
801
+ export function useRuntimeConfigScope<T extends RuntimeConfigSection = RuntimeConfigSection>(
802
+ scopeId: string,
803
+ options?: GetRuntimeConfigScopeOptions & ReadNuxtRuntimeConfigOptions,
804
+ ): T
805
+ export function useValidatedRuntimeConfigScope<
806
+ T extends RuntimeConfigSection = RuntimeConfigSection,
807
+ >(scopeId: string, options?: GetRuntimeConfigScopeOptions & ReadNuxtRuntimeConfigOptions): T
808
+ export function usePublicRuntimeConfigScope<
809
+ T extends RuntimeConfigSection = RuntimeConfigSection,
810
+ >(
811
+ scopeId: string,
812
+ options?: Omit<GetRuntimeConfigScopeOptions, 'visibility'> & ReadNuxtRuntimeConfigOptions,
813
+ ): T
814
+ export function usePublicValidatedRuntimeConfigScope<
815
+ T extends RuntimeConfigSection = RuntimeConfigSection,
816
+ >(
817
+ scopeId: string,
818
+ options?: Omit<GetRuntimeConfigScopeOptions, 'visibility'> & ReadNuxtRuntimeConfigOptions,
819
+ ): T
820
+ export function usePrivateRuntimeConfigScope<
821
+ T extends RuntimeConfigSection = RuntimeConfigSection,
822
+ >(
823
+ scopeId: string,
824
+ options?: Omit<GetRuntimeConfigScopeOptions, 'visibility'> & ReadNuxtRuntimeConfigOptions,
825
+ ): T
826
+ export function usePrivateValidatedRuntimeConfigScope<
827
+ T extends RuntimeConfigSection = RuntimeConfigSection,
828
+ >(
829
+ scopeId: string,
830
+ options?: Omit<GetRuntimeConfigScopeOptions, 'visibility'> & ReadNuxtRuntimeConfigOptions,
831
+ ): T
832
+ export function useRuntimeConfigValue<T = unknown>(
833
+ scopeId: string,
834
+ key: string,
835
+ options?: ResolveRuntimeConfigValueFromRuntimeConfigOptions<T> & ReadNuxtRuntimeConfigOptions,
836
+ ): T | undefined
837
+ }
838
+
839
+ declare module '${serverRuntimeConfigComposablesTemplate}' {
840
+ export * from '${runtimeConfigComposablesImport}'
841
+ }
842
+ `;
843
+ }
624
844
  function createDefaultRuntimeConfigOptions(rootDir) {
625
845
  const paths = defaultRuntimeConfigSource.paths.map((pattern) => join2(rootDir, pattern));
626
846
  const runtimeConfigDir = join2(rootDir, ".runtimeconfig", "runtime-config");
@@ -650,43 +870,115 @@ function registerRuntimeConfigPublicAssets(options, nuxt) {
650
870
  });
651
871
  }
652
872
  function resolveRuntimeConfigValidationTargets(bootstrap) {
653
- return bootstrap?.resolvedExtensions.map((extension) => ({
873
+ return bootstrap?.resolvedExtensions.filter((extension) => extension.descriptor.runtimeConfig !== void 0).map((extension) => ({
654
874
  scopeId: extension.descriptor.id,
655
- cwd: extension.cwd
875
+ cwd: extension.cwd,
876
+ policy: extension.descriptor.runtimeConfig
656
877
  })) ?? [];
657
878
  }
879
+ function createRuntimeConfigValidationSchemas(options, bootstrap) {
880
+ if (options.validation === false || !options.validation) return {};
881
+ return readRuntimeConfigSchemaRegistry(resolveRuntimeConfigValidationTargets(bootstrap), {
882
+ ...options.validation.schemaFileName ? { schemaFileName: options.validation.schemaFileName } : {}
883
+ });
884
+ }
885
+ function createRuntimeConfigValidationPolicyByScope(targets) {
886
+ return new Map(targets.map((target) => [target.scopeId, target.policy]));
887
+ }
888
+ function formatRuntimeConfigValidationMode(policy) {
889
+ return resolveRuntimeConfigValidationMode(policy);
890
+ }
891
+ function isRuntimeConfigValidationFatal(scopeId, policyByScope) {
892
+ return shouldRequireRuntimeConfigAtStartup(policyByScope.get(scopeId));
893
+ }
894
+ function formatRuntimeConfigSkippedValidationDetails(skipped, mode) {
895
+ if (skipped.reason === "missing-schema") {
896
+ return [
897
+ `RuntimeConfig schema file missing for "${skipped.scopeId}" (${mode}).`,
898
+ ...skipped.schemaPath ? [`missing schema file: ${skipped.schemaPath}`] : [],
899
+ ...skipped.configPath ? [`runtime config file: ${skipped.configPath}`] : []
900
+ ].join(" ");
901
+ }
902
+ if (skipped.reason === "missing-config") {
903
+ return [
904
+ `RuntimeConfig file missing for "${skipped.scopeId}" (${mode}).`,
905
+ ...skipped.configPath ? [`expected runtime config file: ${skipped.configPath}`] : [],
906
+ ...skipped.schemaPath ? [`schema file: ${skipped.schemaPath}`] : []
907
+ ].join(" ");
908
+ }
909
+ return [
910
+ `RuntimeConfig validation target has no schema directory for "${skipped.scopeId}" (${mode}).`,
911
+ ...skipped.configPath ? [`runtime config file: ${skipped.configPath}`] : [],
912
+ ...skipped.schemaPath ? [`schema file: ${skipped.schemaPath}`] : []
913
+ ].join(" ");
914
+ }
915
+ function reportRuntimeConfigValidationResult(result, targets) {
916
+ if (!result.skipped.length && !result.invalid.length) return;
917
+ const logger = useLogger("lorion");
918
+ const policyByScope = createRuntimeConfigValidationPolicyByScope(targets);
919
+ for (const skipped of result.skipped) {
920
+ const fatal = isRuntimeConfigValidationFatal(skipped.scopeId, policyByScope);
921
+ const mode = formatRuntimeConfigValidationMode(policyByScope.get(skipped.scopeId));
922
+ const details = formatRuntimeConfigSkippedValidationDetails(skipped, mode);
923
+ logger[fatal ? "error" : "warn"](details);
924
+ }
925
+ for (const invalid of result.invalid) {
926
+ const fatal = isRuntimeConfigValidationFatal(invalid.scopeId, policyByScope);
927
+ const mode = formatRuntimeConfigValidationMode(policyByScope.get(invalid.scopeId));
928
+ logger[fatal ? "error" : "warn"](
929
+ [
930
+ `RuntimeConfig validation failed for "${invalid.scopeId}" (${mode}).`,
931
+ `runtime config file: ${invalid.configPath}`,
932
+ `schema file: ${invalid.schemaPath}`,
933
+ invalid.error.message
934
+ ].join(" ")
935
+ );
936
+ }
937
+ }
658
938
  function validateRuntimeConfigSource(options, bootstrap) {
659
939
  if (!options.source || options.validation === false || !options.validation) return;
660
940
  const targets = resolveRuntimeConfigValidationTargets(bootstrap);
661
941
  if (!targets.length) return;
662
- validateNuxtRuntimeConfigSourceScopes(options.source, targets, {
942
+ const result = validateNuxtRuntimeConfigSourceScopes(options.source, targets, {
663
943
  ...options.validation.formatError ? { formatError: options.validation.formatError } : {},
664
944
  ...options.validation.schemaFileName ? { schemaFileName: options.validation.schemaFileName } : {}
665
945
  });
946
+ reportRuntimeConfigValidationResult(result, targets);
947
+ assertRequiredRuntimeConfigValidationTargets(result, targets);
666
948
  }
667
- function addRuntimeConfigImports(options) {
668
- if (options.imports === false) return;
949
+ function addRuntimeConfigComposables(options, bootstrap, hostImports, registerImports = true) {
669
950
  const resolver = createResolver(import.meta.url);
670
951
  const runtimeConfigFrom = normalizeImportPath(resolver.resolve("./runtime-config"));
671
- const template = addTemplate({
952
+ const validationSchemas = createRuntimeConfigValidationSchemas(options, bootstrap);
953
+ addTemplate({
672
954
  filename: runtimeConfigComposablesTemplate,
955
+ write: true,
673
956
  getContents: () => createRuntimeConfigComposablesSource({
674
957
  runtimeConfigFrom,
675
- typed: true,
676
- useRuntimeConfigFrom: "nuxt/app"
958
+ typed: false,
959
+ useRuntimeConfigFrom: "nuxt/app",
960
+ validationSchemas
677
961
  })
678
962
  });
963
+ addTypeTemplate(
964
+ {
965
+ filename: "types/lorion-runtime-config-composables.d.ts",
966
+ getContents: createRuntimeConfigComposablesTypesSource
967
+ },
968
+ { nitro: true, nuxt: true }
969
+ );
679
970
  addServerTemplate({
680
971
  filename: serverRuntimeConfigComposablesTemplate,
681
972
  getContents: () => createRuntimeConfigComposablesSource({
682
973
  runtimeConfigFrom,
683
974
  typed: false,
684
- useRuntimeConfigFrom: "nitropack/runtime"
975
+ useRuntimeConfigFrom: "nitropack/runtime",
976
+ validationSchemas
685
977
  })
686
978
  });
687
979
  const imports = runtimeConfigImportNames.map((name) => ({
688
980
  as: name,
689
- from: `#build/${template.filename}`,
981
+ from: runtimeConfigComposablesImport,
690
982
  name
691
983
  }));
692
984
  const serverImports = runtimeConfigImportNames.map((name) => ({
@@ -694,9 +986,15 @@ function addRuntimeConfigImports(options) {
694
986
  from: serverRuntimeConfigComposablesTemplate,
695
987
  name
696
988
  }));
989
+ if (!registerImports) return;
990
+ if (!shouldRegisterRuntimeConfigImports(options, hostImports)) return;
697
991
  addImports(imports);
698
992
  addServerImports(serverImports);
699
993
  }
994
+ function shouldRegisterRuntimeConfigImports(options, hostImports) {
995
+ if (options.imports !== void 0) return options.imports;
996
+ return hostImports?.scan !== false;
997
+ }
700
998
  function createRuntimeConfigDefaultsConfig(options) {
701
999
  return {
702
1000
  public: {
@@ -717,8 +1015,13 @@ function applyRuntimeConfigModule(input) {
717
1015
  input.rootDir
718
1016
  );
719
1017
  const runtimeConfig = runtimeConfigOptions ? createConfiguredNuxtRuntimeConfig({ runtimeConfig: runtimeConfigOptions }, input.bootstrap) : void 0;
1018
+ addRuntimeConfigComposables(
1019
+ runtimeConfigOptions ?? {},
1020
+ input.bootstrap,
1021
+ input.nuxt.options.imports,
1022
+ Boolean(runtimeConfigOptions)
1023
+ );
720
1024
  if (!runtimeConfigOptions) return input.currentRuntimeConfig;
721
- addRuntimeConfigImports(runtimeConfigOptions);
722
1025
  registerRuntimeConfigPublicAssets(runtimeConfigOptions, input.nuxt);
723
1026
  validateRuntimeConfigSource(runtimeConfigOptions, input.bootstrap);
724
1027
  return mergeNuxtRuntimeConfig(
@@ -728,7 +1031,16 @@ function applyRuntimeConfigModule(input) {
728
1031
  }
729
1032
  function createProviderSelectionRuntimeConfig(bootstrap, options) {
730
1033
  if (options?.enabled === false) return void 0;
731
- return createNuxtProviderSelectionRuntimeConfig(bootstrap.resolvedExtensions, options);
1034
+ return createNuxtProviderSelectionRuntimeConfig(bootstrap.resolvedExtensions, {
1035
+ ...options,
1036
+ selectedProviders: {
1037
+ ...createNuxtSelectedProviderPreferences({
1038
+ entries: bootstrap.resolvedExtensions,
1039
+ selectedExtensions: bootstrap.selectedExtensions
1040
+ }),
1041
+ ...options?.selectedProviders ?? {}
1042
+ }
1043
+ });
732
1044
  }
733
1045
  function createNuxtExtensionBootstrapLogEvent(input) {
734
1046
  const providerSelection = input.providerSelectionRuntimeConfig ? getNuxtProviderSelection(input.providerSelectionRuntimeConfig) : void 0;
@@ -845,10 +1157,14 @@ var module_default = lorionNuxtModule;
845
1157
  export {
846
1158
  createNuxtExtensionBootstrap,
847
1159
  createNuxtExtensionBootstrapLogEvent,
1160
+ createNuxtExtensionCatalog,
1161
+ createNuxtExtensionEntryMap,
848
1162
  createNuxtExtensionLayerPaths,
849
1163
  createNuxtProviderSelectionRuntimeConfig,
850
1164
  module_default as default,
1165
+ discoverNuxtExtensionEntries,
851
1166
  formatNuxtExtensionBootstrapLog,
1167
+ nuxtExtensionDescriptorSchema,
852
1168
  reportNuxtExtensionBootstrap,
853
1169
  resolveExtensionSelection
854
1170
  };
@@ -1,9 +1,9 @@
1
1
  import { ValidateRuntimeConfigPatternSourceScopesOptions, RuntimeConfigSchemaTargetInput, RuntimeConfigValidateResult } from '@lorion-org/runtime-config-node';
2
2
  import { RuntimeConfigFragmentMap } from '@lorion-org/runtime-config';
3
- import { C as CreateNuxtRuntimeConfigOptions, n as RuntimeConfigNuxtSourceOptions, a as NuxtRuntimeConfig } from './extensions-vNob6d2x.js';
3
+ import { C as CreateNuxtRuntimeConfigOptions, s as RuntimeConfigNuxtSourceOptions, a as NuxtRuntimeConfig } from './extensions-DlFRz22Q.js';
4
4
  import '@lorion-org/composition-graph';
5
5
  import '@lorion-org/provider-selection';
6
- import '@lorion-org/descriptor-discovery';
6
+ import './descriptor-schema.js';
7
7
 
8
8
  type CreateNuxtRuntimeConfigFromSourceOptions = Omit<CreateNuxtRuntimeConfigOptions, 'fragments' | 'runtimeConfig'>;
9
9
  type ValidateNuxtRuntimeConfigSourceScopesOptions = Omit<ValidateRuntimeConfigPatternSourceScopesOptions, 'fileName' | 'runtimeConfigDirName'>;
@@ -1,10 +1,10 @@
1
1
  import { SectionedRuntimeConfig, GetRuntimeConfigFragmentOptions, RuntimeConfigContext, RuntimeConfigSection, GetRuntimeConfigScopeOptions, NamedRuntimeConfigFragment, RuntimeConfigFragmentMap, ResolveRuntimeConfigValueFromRuntimeConfigOptions } from '@lorion-org/runtime-config';
2
- import { C as CreateNuxtRuntimeConfigOptions, a as NuxtRuntimeConfig, o as NuxtRuntimeConfigInput, p as ReadNuxtRuntimeConfigOptions, q as NuxtExtensionSelection, j as NuxtProviderSelectionRuntimeConfig, s as RuntimeConfigNuxtFragments } from './extensions-vNob6d2x.js';
3
- export { t as NuxtExtensionSelectionRuntimeConfig, u as NuxtPrivateRuntimeConfigMode } from './extensions-vNob6d2x.js';
2
+ import { C as CreateNuxtRuntimeConfigOptions, a as NuxtRuntimeConfig, t as NuxtRuntimeConfigInput, u as ReadNuxtRuntimeConfigOptions, v as NuxtExtensionSelection, k as NuxtProviderSelectionRuntimeConfig, w as RuntimeConfigNuxtFragments } from './extensions-DlFRz22Q.js';
3
+ export { x as NuxtExtensionSelectionRuntimeConfig, y as NuxtPrivateRuntimeConfigMode } from './extensions-DlFRz22Q.js';
4
4
  import '@lorion-org/composition-graph';
5
5
  import '@lorion-org/provider-selection';
6
- import '@lorion-org/descriptor-discovery';
7
6
  import '@lorion-org/runtime-config-node';
7
+ import './descriptor-schema.js';
8
8
 
9
9
  declare function normalizeNuxtRuntimeConfigFragments(fragments?: RuntimeConfigNuxtFragments, options?: Pick<CreateNuxtRuntimeConfigOptions, 'contextInputKey'>): NamedRuntimeConfigFragment[] | RuntimeConfigFragmentMap;
10
10
  declare function toNuxtRuntimeConfig(runtimeConfig: SectionedRuntimeConfig, options?: Pick<CreateNuxtRuntimeConfigOptions, 'privateOutput'>): NuxtRuntimeConfig;