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

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,13 +15,19 @@ 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,
23
- resolveItemProviderSelection
28
+ collectSelectedProviderPreferences,
29
+ resolveItemProviderSelection,
30
+ resolveSelectedProviderRelationPreferences
24
31
  } from "@lorion-org/provider-selection";
25
32
 
26
33
  // src/extension-descriptor.schema.json
@@ -46,8 +53,19 @@ var extension_descriptor_schema_default = {
46
53
  },
47
54
  version: { $ref: "#/$defs/semver" },
48
55
  providesFor: {
49
- type: "string",
50
- minLength: 1
56
+ oneOf: [
57
+ {
58
+ type: "string",
59
+ minLength: 1
60
+ },
61
+ {
62
+ type: "array",
63
+ items: {
64
+ type: "string",
65
+ minLength: 1
66
+ }
67
+ }
68
+ ]
51
69
  },
52
70
  capabilities: {
53
71
  type: "array",
@@ -59,6 +77,21 @@ var extension_descriptor_schema_default = {
59
77
  dependencies: { $ref: "#/$defs/dependencyMap" },
60
78
  disabled: { type: "boolean" },
61
79
  location: { type: "string" },
80
+ defaultFor: {
81
+ oneOf: [
82
+ {
83
+ type: "string",
84
+ minLength: 1
85
+ },
86
+ {
87
+ type: "array",
88
+ items: {
89
+ type: "string",
90
+ minLength: 1
91
+ }
92
+ }
93
+ ]
94
+ },
62
95
  providerPreferences: {
63
96
  type: "object",
64
97
  additionalProperties: {
@@ -70,6 +103,16 @@ var extension_descriptor_schema_default = {
70
103
  type: "object",
71
104
  additionalProperties: true
72
105
  },
106
+ runtimeConfig: {
107
+ type: "object",
108
+ properties: {
109
+ validation: {
110
+ type: "string",
111
+ enum: ["none", "optional", "startup", "onUse"]
112
+ }
113
+ },
114
+ additionalProperties: false
115
+ },
73
116
  bundles: {
74
117
  type: "array",
75
118
  items: { $ref: "#/$defs/extension" }
@@ -90,20 +133,38 @@ var defaultExtensionOptions = {
90
133
  publicRuntimeConfigKey: "extensionSelection",
91
134
  descriptorPaths: ["extensions/*/extension.json"]
92
135
  };
136
+ var defaultExtensionSelectionSeedKey = "capability";
137
+ var defaultExtensionResolutionRelations = [
138
+ "dependencies",
139
+ "defaultProviders",
140
+ "providerPreferences"
141
+ ];
142
+ var defaultNuxtRelationDescriptors = [
143
+ {
144
+ direction: "incoming",
145
+ field: "defaultFor",
146
+ id: "defaultProviders"
147
+ },
148
+ {
149
+ id: "providerPreferences",
150
+ field: "providerPreferences",
151
+ targetMode: "values"
152
+ }
153
+ ];
93
154
  function isRecord(value) {
94
155
  return typeof value === "object" && value !== null && !Array.isArray(value);
95
156
  }
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
157
  function normalizeSelection(value) {
104
- return asArray(value).flatMap((entry) => {
105
- if (typeof entry !== "string") return [];
106
- return splitSelectionValue(entry);
158
+ return parseDescriptorIds(value);
159
+ }
160
+ function resolveNuxtExtensionSelectionSeed(seedOptions) {
161
+ if (seedOptions === false) return [];
162
+ return resolveDescriptorSelectionSeed({
163
+ argv: seedOptions?.argv ?? process.argv,
164
+ env: seedOptions?.env ?? process.env,
165
+ key: seedOptions?.key ?? defaultExtensionSelectionSeedKey,
166
+ ...seedOptions?.cliKeys ? { cliKeys: seedOptions.cliKeys } : {},
167
+ ...seedOptions?.envKeys ? { envKeys: seedOptions.envKeys } : {}
107
168
  });
108
169
  }
109
170
  function resolveExtensionOptions(options) {
@@ -133,6 +194,10 @@ function findNuxtConfigFile(cwd) {
133
194
  return ["nuxt.config.ts", "nuxt.config.mts", "nuxt.config.js", "nuxt.config.mjs"].map((fileName) => optionalFile(join(cwd, fileName))).find(Boolean);
134
195
  }
135
196
  function createExtensionEntry(input) {
197
+ const descriptor = {
198
+ ...input.descriptor,
199
+ location: input.descriptor.location ?? input.cwd
200
+ };
136
201
  const appDir = optionalDir(join(input.cwd, "app"));
137
202
  const modulesDir = optionalDir(join(input.cwd, "modules"));
138
203
  const publicDir = optionalDir(join(input.cwd, "public"));
@@ -141,7 +206,7 @@ function createExtensionEntry(input) {
141
206
  const configFile = findNuxtConfigFile(input.cwd);
142
207
  const entry = {
143
208
  cwd: input.cwd,
144
- descriptor: input.descriptor
209
+ descriptor
145
210
  };
146
211
  if (appDir) entry.appDir = appDir;
147
212
  if (configFile) entry.configFile = configFile;
@@ -159,7 +224,7 @@ function canRegisterExtensionLayer(entry) {
159
224
  function canExtendExtensionLayer(entry) {
160
225
  return Boolean(entry.configFile);
161
226
  }
162
- function discoverExtensionEntries(input) {
227
+ function discoverNuxtExtensionEntries(input) {
163
228
  const resolvedOptions = resolveExtensionOptions(input.options);
164
229
  return discoverDescriptors({
165
230
  cwd: input.projectRootDir,
@@ -177,9 +242,47 @@ function discoverExtensionEntries(input) {
177
242
  })
178
243
  );
179
244
  }
245
+ function createNuxtExtensionCatalog(input) {
246
+ return createDescriptorCatalog({
247
+ descriptors: input.entries.map((entry) => entry.descriptor),
248
+ relationDescriptors: [...defaultNuxtRelationDescriptors, ...input.relationDescriptors ?? []]
249
+ });
250
+ }
251
+ function createNuxtExtensionEntryMap(entries) {
252
+ return new Map(entries.map((entry) => [entry.descriptor.id, entry]));
253
+ }
180
254
  function pickEntriesById(ids, entryById) {
181
255
  return ids.map((id) => entryById.get(id)).filter((entry) => Boolean(entry));
182
256
  }
257
+ function createNuxtSelectedProviderPreferences(input) {
258
+ return collectSelectedProviderPreferences({
259
+ items: input.entries,
260
+ getCapabilityId: (entry) => entry.descriptor.providesFor,
261
+ getProviderId: (entry) => entry.descriptor.id,
262
+ selectedProviderIds: input.selectedExtensions
263
+ });
264
+ }
265
+ function createProviderSelectionAwareEntries(entries, selectedProviders) {
266
+ if (!Object.keys(selectedProviders).length) return entries;
267
+ return entries.map((entry) => {
268
+ const descriptor = { ...entry.descriptor };
269
+ const preferences = resolveSelectedProviderRelationPreferences({
270
+ providerId: entry.descriptor.id,
271
+ defaultFor: entry.descriptor.defaultFor,
272
+ providerPreferences: entry.descriptor.providerPreferences,
273
+ selectedProviders
274
+ });
275
+ delete descriptor.defaultFor;
276
+ delete descriptor.providerPreferences;
277
+ return {
278
+ ...entry,
279
+ descriptor: {
280
+ ...descriptor,
281
+ ...preferences
282
+ }
283
+ };
284
+ });
285
+ }
183
286
  function mergeRuntimeConfigSection(target = {}, source = {}) {
184
287
  const merged = { ...target };
185
288
  for (const [key, value] of Object.entries(source)) {
@@ -216,10 +319,10 @@ function createNuxtExtensionBootstrap(input) {
216
319
  const options = input.options ?? {};
217
320
  const selectedExtensions = resolveExtensionSelection({
218
321
  ...options.defaultSelection ? { defaultSelection: options.defaultSelection } : {},
219
- ...options.selected ? { selected: options.selected } : {}
322
+ selected: options.selected ?? resolveNuxtExtensionSelectionSeed(options.selectionSeed)
220
323
  });
221
- const createCatalog = (entries2) => createDescriptorCatalog({
222
- descriptors: entries2.map((entry) => entry.descriptor),
324
+ const createCatalog = (entries2) => createNuxtExtensionCatalog({
325
+ entries: entries2,
223
326
  ...options.relationDescriptors ? { relationDescriptors: options.relationDescriptors } : {}
224
327
  });
225
328
  if (options.enabled === false) {
@@ -234,7 +337,7 @@ function createNuxtExtensionBootstrap(input) {
234
337
  selectedExtensions
235
338
  };
236
339
  }
237
- const entries = discoverExtensionEntries({
340
+ const entries = discoverNuxtExtensionEntries({
238
341
  projectRootDir: input.rootDir,
239
342
  options
240
343
  });
@@ -243,7 +346,6 @@ function createNuxtExtensionBootstrap(input) {
243
346
  options,
244
347
  selectedExtensions
245
348
  });
246
- const entryById = new Map(entries.map((entry) => [entry.descriptor.id, entry]));
247
349
  if (!entries.length) {
248
350
  return {
249
351
  activeExtensions: [],
@@ -256,13 +358,26 @@ function createNuxtExtensionBootstrap(input) {
256
358
  selectedExtensions
257
359
  };
258
360
  }
259
- const catalog = createCatalog(entries);
361
+ const selectedProviders = createNuxtSelectedProviderPreferences({
362
+ entries,
363
+ selectedExtensions
364
+ });
365
+ const resolutionEntries = createProviderSelectionAwareEntries(entries, selectedProviders);
366
+ const catalog = createCatalog(resolutionEntries);
260
367
  const selection = catalog.resolveSelection({
261
368
  baseDescriptors: baseExtensionIds,
369
+ policy: {
370
+ inspectionRelationIds: defaultExtensionResolutionRelations,
371
+ provenanceRelationIds: defaultExtensionResolutionRelations,
372
+ resolutionRelationIds: defaultExtensionResolutionRelations
373
+ },
262
374
  selected: selectedExtensions
263
375
  });
264
376
  const resolvedExtensionIds = selection.getResolved();
265
- const resolvedExtensions = pickEntriesById(resolvedExtensionIds, entryById);
377
+ const resolvedExtensions = pickEntriesById(
378
+ resolvedExtensionIds,
379
+ createNuxtExtensionEntryMap(resolutionEntries)
380
+ );
266
381
  const activeExtensions = resolvedExtensions.filter(canRegisterExtensionLayer);
267
382
  return {
268
383
  activeExtensions,
@@ -291,21 +406,32 @@ function createNuxtProviderSelectionRuntimeConfig(extensions, options = {}) {
291
406
  items: extensions,
292
407
  getProviderPreferences: (extension) => extension.descriptor.providerPreferences
293
408
  });
294
- const configuredProviders = {
409
+ const providerDefaults = collectProviderDefaults({
410
+ items: extensions,
411
+ getDefaultFor: (extension) => extension.descriptor.defaultFor,
412
+ getProviderId: (extension) => extension.descriptor.id
413
+ });
414
+ const configuredProviders = options.configuredProviders ?? {};
415
+ const selectedProviders = options.selectedProviders ?? {};
416
+ const fallbackProviders = {
417
+ ...providerDefaults,
295
418
  ...descriptorPreferences,
296
- ...options.configuredProviders ?? {}
419
+ ...options.fallbackProviders ?? {}
297
420
  };
298
421
  const resolution = resolveItemProviderSelection({
299
422
  items: extensions,
300
423
  getCapabilityId: (extension) => extension.descriptor.providesFor,
301
424
  getProviderId: (extension) => extension.descriptor.id,
302
- configuredProviders
425
+ configuredProviders,
426
+ fallbackProviders,
427
+ selectedProviders
303
428
  });
304
429
  return {
305
430
  public: {
306
431
  [publicRuntimeConfigKey]: {
307
432
  configuredProviders,
308
433
  excludedProviderIds: resolution.excludedProviderIds,
434
+ fallbackProviders,
309
435
  mismatches: resolution.mismatches,
310
436
  selections: Object.fromEntries(resolution.selections)
311
437
  }
@@ -458,14 +584,27 @@ function validateNuxtRuntimeConfigSourceScopes(source, targets, options = {}) {
458
584
  }
459
585
 
460
586
  // src/module.ts
587
+ import {
588
+ resolveRuntimeConfigValidationMode,
589
+ shouldRequireRuntimeConfigAtStartup
590
+ } from "@lorion-org/runtime-config";
591
+ import {
592
+ assertRequiredRuntimeConfigValidationTargets,
593
+ readRuntimeConfigSchemaRegistry
594
+ } from "@lorion-org/runtime-config-node";
461
595
  var runtimeConfigImportNames = [
462
596
  "useRuntimeConfigFragment",
597
+ "useValidatedRuntimeConfigFragment",
463
598
  "useRuntimeConfigScope",
599
+ "useValidatedRuntimeConfigScope",
464
600
  "usePublicRuntimeConfigScope",
601
+ "usePublicValidatedRuntimeConfigScope",
465
602
  "usePrivateRuntimeConfigScope",
603
+ "usePrivateValidatedRuntimeConfigScope",
466
604
  "useRuntimeConfigValue"
467
605
  ];
468
- var runtimeConfigComposablesTemplate = "lorion/runtime-config-composables.ts";
606
+ var runtimeConfigComposablesTemplate = "lorion/runtime-config-composables.mjs";
607
+ var runtimeConfigComposablesImport = "#build/lorion/runtime-config-composables";
469
608
  var serverRuntimeConfigComposablesTemplate = "#internal/lorion-runtime-config-composables.mjs";
470
609
  var defaultRuntimeConfigSource = {
471
610
  contextInputKey: "contexts",
@@ -503,6 +642,7 @@ function normalizeImportPath(path) {
503
642
  return path.replace(/\\/g, "/");
504
643
  }
505
644
  function createRuntimeConfigComposablesSource(input) {
645
+ const validationSchemasSource = JSON.stringify(input.validationSchemas);
506
646
  const typeImports = input.typed ? `
507
647
  import type {
508
648
  GetRuntimeConfigFragmentOptions,
@@ -559,6 +699,7 @@ export type UseRuntimeConfigFragmentOptions =
559
699
  valueReturn: ""
560
700
  };
561
701
  return `import { useRuntimeConfig } from '${input.useRuntimeConfigFrom}'
702
+ import { createRuntimeConfigValidatorRegistry } from '@lorion-org/runtime-config'
562
703
  import {
563
704
  getNuxtRuntimeConfigFragment,
564
705
  getNuxtRuntimeConfigScope,
@@ -568,6 +709,12 @@ import {
568
709
  } from '${input.runtimeConfigFrom}'
569
710
  ${typeImports}
570
711
  const runtimeConfigDefaultsKey = '__lorionNuxt'
712
+ const runtimeConfigValidationSchemas = ${validationSchemasSource}
713
+ const runtimeConfigValidatorRegistry = createRuntimeConfigValidatorRegistry(runtimeConfigValidationSchemas)
714
+
715
+ function assertValidatedRuntimeConfigFragment(scopeId, fragment) {
716
+ runtimeConfigValidatorRegistry.assert(scopeId, fragment)
717
+ }
571
718
 
572
719
  function getComposableDefaults(runtimeConfig${typeAnnotations.runtimeConfig})${typeAnnotations.defaults} {
573
720
  const container = runtimeConfig.public?.[runtimeConfigDefaultsKey]
@@ -596,24 +743,66 @@ export function useRuntimeConfigFragment(scopeId, options${typeAnnotations.fragm
596
743
  return getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
597
744
  }
598
745
 
746
+ export function useValidatedRuntimeConfigFragment(scopeId, options${typeAnnotations.fragmentOptions} = {})${typeAnnotations.fragmentReturn} {
747
+ const runtimeConfig = useRuntimeConfig()
748
+ const fragment = getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
749
+
750
+ assertValidatedRuntimeConfigFragment(scopeId, fragment)
751
+
752
+ return fragment
753
+ }
754
+
599
755
  export function useRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.scopeOptions} = {}) {
600
756
  const runtimeConfig = useRuntimeConfig()
601
757
 
602
758
  return getNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
603
759
  }
604
760
 
761
+ export function useValidatedRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.scopeOptions} = {}) {
762
+ const runtimeConfig = useRuntimeConfig()
763
+
764
+ assertValidatedRuntimeConfigFragment(
765
+ scopeId,
766
+ getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options)),
767
+ )
768
+
769
+ return getNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
770
+ }
771
+
605
772
  export function usePublicRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.publicOptions} = {}) {
606
773
  const runtimeConfig = useRuntimeConfig()
607
774
 
608
775
  return getPublicNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
609
776
  }
610
777
 
778
+ export function usePublicValidatedRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.publicOptions} = {}) {
779
+ const runtimeConfig = useRuntimeConfig()
780
+
781
+ assertValidatedRuntimeConfigFragment(
782
+ scopeId,
783
+ getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options)),
784
+ )
785
+
786
+ return getPublicNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
787
+ }
788
+
611
789
  export function usePrivateRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.privateOptions} = {}) {
612
790
  const runtimeConfig = useRuntimeConfig()
613
791
 
614
792
  return getPrivateNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
615
793
  }
616
794
 
795
+ export function usePrivateValidatedRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.privateOptions} = {}) {
796
+ const runtimeConfig = useRuntimeConfig()
797
+
798
+ assertValidatedRuntimeConfigFragment(
799
+ scopeId,
800
+ getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options)),
801
+ )
802
+
803
+ return getPrivateNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
804
+ }
805
+
617
806
  export function useRuntimeConfigValue${typeAnnotations.valueOptions}(scopeId, key, options${typeAnnotations.valueOptionsType} = {})${typeAnnotations.valueReturn} {
618
807
  const runtimeConfig = useRuntimeConfig()
619
808
 
@@ -621,6 +810,72 @@ export function useRuntimeConfigValue${typeAnnotations.valueOptions}(scopeId, ke
621
810
  }
622
811
  `;
623
812
  }
813
+ function createRuntimeConfigComposablesTypesSource() {
814
+ return `declare module '${runtimeConfigComposablesImport}' {
815
+ import type {
816
+ GetRuntimeConfigFragmentOptions,
817
+ GetRuntimeConfigScopeOptions,
818
+ ResolveRuntimeConfigValueFromRuntimeConfigOptions,
819
+ RuntimeConfigContext,
820
+ RuntimeConfigSection,
821
+ } from '@lorion-org/runtime-config'
822
+
823
+ type NuxtPrivateRuntimeConfigMode = 'root' | 'section'
824
+ type ReadNuxtRuntimeConfigOptions = {
825
+ privateInput?: NuxtPrivateRuntimeConfigMode
826
+ }
827
+
828
+ export function useRuntimeConfigFragment(
829
+ scopeId: string,
830
+ options?: GetRuntimeConfigFragmentOptions & ReadNuxtRuntimeConfigOptions,
831
+ ): RuntimeConfigContext
832
+ export function useValidatedRuntimeConfigFragment(
833
+ scopeId: string,
834
+ options?: GetRuntimeConfigFragmentOptions & ReadNuxtRuntimeConfigOptions,
835
+ ): RuntimeConfigContext
836
+ export function useRuntimeConfigScope<T extends RuntimeConfigSection = RuntimeConfigSection>(
837
+ scopeId: string,
838
+ options?: GetRuntimeConfigScopeOptions & ReadNuxtRuntimeConfigOptions,
839
+ ): T
840
+ export function useValidatedRuntimeConfigScope<
841
+ T extends RuntimeConfigSection = RuntimeConfigSection,
842
+ >(scopeId: string, options?: GetRuntimeConfigScopeOptions & ReadNuxtRuntimeConfigOptions): T
843
+ export function usePublicRuntimeConfigScope<
844
+ T extends RuntimeConfigSection = RuntimeConfigSection,
845
+ >(
846
+ scopeId: string,
847
+ options?: Omit<GetRuntimeConfigScopeOptions, 'visibility'> & ReadNuxtRuntimeConfigOptions,
848
+ ): T
849
+ export function usePublicValidatedRuntimeConfigScope<
850
+ T extends RuntimeConfigSection = RuntimeConfigSection,
851
+ >(
852
+ scopeId: string,
853
+ options?: Omit<GetRuntimeConfigScopeOptions, 'visibility'> & ReadNuxtRuntimeConfigOptions,
854
+ ): T
855
+ export function usePrivateRuntimeConfigScope<
856
+ T extends RuntimeConfigSection = RuntimeConfigSection,
857
+ >(
858
+ scopeId: string,
859
+ options?: Omit<GetRuntimeConfigScopeOptions, 'visibility'> & ReadNuxtRuntimeConfigOptions,
860
+ ): T
861
+ export function usePrivateValidatedRuntimeConfigScope<
862
+ T extends RuntimeConfigSection = RuntimeConfigSection,
863
+ >(
864
+ scopeId: string,
865
+ options?: Omit<GetRuntimeConfigScopeOptions, 'visibility'> & ReadNuxtRuntimeConfigOptions,
866
+ ): T
867
+ export function useRuntimeConfigValue<T = unknown>(
868
+ scopeId: string,
869
+ key: string,
870
+ options?: ResolveRuntimeConfigValueFromRuntimeConfigOptions<T> & ReadNuxtRuntimeConfigOptions,
871
+ ): T | undefined
872
+ }
873
+
874
+ declare module '${serverRuntimeConfigComposablesTemplate}' {
875
+ export * from '${runtimeConfigComposablesImport}'
876
+ }
877
+ `;
878
+ }
624
879
  function createDefaultRuntimeConfigOptions(rootDir) {
625
880
  const paths = defaultRuntimeConfigSource.paths.map((pattern) => join2(rootDir, pattern));
626
881
  const runtimeConfigDir = join2(rootDir, ".runtimeconfig", "runtime-config");
@@ -650,43 +905,115 @@ function registerRuntimeConfigPublicAssets(options, nuxt) {
650
905
  });
651
906
  }
652
907
  function resolveRuntimeConfigValidationTargets(bootstrap) {
653
- return bootstrap?.resolvedExtensions.map((extension) => ({
908
+ return bootstrap?.resolvedExtensions.filter((extension) => extension.descriptor.runtimeConfig !== void 0).map((extension) => ({
654
909
  scopeId: extension.descriptor.id,
655
- cwd: extension.cwd
910
+ cwd: extension.cwd,
911
+ policy: extension.descriptor.runtimeConfig
656
912
  })) ?? [];
657
913
  }
914
+ function createRuntimeConfigValidationSchemas(options, bootstrap) {
915
+ if (options.validation === false || !options.validation) return {};
916
+ return readRuntimeConfigSchemaRegistry(resolveRuntimeConfigValidationTargets(bootstrap), {
917
+ ...options.validation.schemaFileName ? { schemaFileName: options.validation.schemaFileName } : {}
918
+ });
919
+ }
920
+ function createRuntimeConfigValidationPolicyByScope(targets) {
921
+ return new Map(targets.map((target) => [target.scopeId, target.policy]));
922
+ }
923
+ function formatRuntimeConfigValidationMode(policy) {
924
+ return resolveRuntimeConfigValidationMode(policy);
925
+ }
926
+ function isRuntimeConfigValidationFatal(scopeId, policyByScope) {
927
+ return shouldRequireRuntimeConfigAtStartup(policyByScope.get(scopeId));
928
+ }
929
+ function formatRuntimeConfigSkippedValidationDetails(skipped, mode) {
930
+ if (skipped.reason === "missing-schema") {
931
+ return [
932
+ `RuntimeConfig schema file missing for "${skipped.scopeId}" (${mode}).`,
933
+ ...skipped.schemaPath ? [`missing schema file: ${skipped.schemaPath}`] : [],
934
+ ...skipped.configPath ? [`runtime config file: ${skipped.configPath}`] : []
935
+ ].join(" ");
936
+ }
937
+ if (skipped.reason === "missing-config") {
938
+ return [
939
+ `RuntimeConfig file missing for "${skipped.scopeId}" (${mode}).`,
940
+ ...skipped.configPath ? [`expected runtime config file: ${skipped.configPath}`] : [],
941
+ ...skipped.schemaPath ? [`schema file: ${skipped.schemaPath}`] : []
942
+ ].join(" ");
943
+ }
944
+ return [
945
+ `RuntimeConfig validation target has no schema directory for "${skipped.scopeId}" (${mode}).`,
946
+ ...skipped.configPath ? [`runtime config file: ${skipped.configPath}`] : [],
947
+ ...skipped.schemaPath ? [`schema file: ${skipped.schemaPath}`] : []
948
+ ].join(" ");
949
+ }
950
+ function reportRuntimeConfigValidationResult(result, targets) {
951
+ if (!result.skipped.length && !result.invalid.length) return;
952
+ const logger = useLogger("lorion");
953
+ const policyByScope = createRuntimeConfigValidationPolicyByScope(targets);
954
+ for (const skipped of result.skipped) {
955
+ const fatal = isRuntimeConfigValidationFatal(skipped.scopeId, policyByScope);
956
+ const mode = formatRuntimeConfigValidationMode(policyByScope.get(skipped.scopeId));
957
+ const details = formatRuntimeConfigSkippedValidationDetails(skipped, mode);
958
+ logger[fatal ? "error" : "warn"](details);
959
+ }
960
+ for (const invalid of result.invalid) {
961
+ const fatal = isRuntimeConfigValidationFatal(invalid.scopeId, policyByScope);
962
+ const mode = formatRuntimeConfigValidationMode(policyByScope.get(invalid.scopeId));
963
+ logger[fatal ? "error" : "warn"](
964
+ [
965
+ `RuntimeConfig validation failed for "${invalid.scopeId}" (${mode}).`,
966
+ `runtime config file: ${invalid.configPath}`,
967
+ `schema file: ${invalid.schemaPath}`,
968
+ invalid.error.message
969
+ ].join(" ")
970
+ );
971
+ }
972
+ }
658
973
  function validateRuntimeConfigSource(options, bootstrap) {
659
974
  if (!options.source || options.validation === false || !options.validation) return;
660
975
  const targets = resolveRuntimeConfigValidationTargets(bootstrap);
661
976
  if (!targets.length) return;
662
- validateNuxtRuntimeConfigSourceScopes(options.source, targets, {
977
+ const result = validateNuxtRuntimeConfigSourceScopes(options.source, targets, {
663
978
  ...options.validation.formatError ? { formatError: options.validation.formatError } : {},
664
979
  ...options.validation.schemaFileName ? { schemaFileName: options.validation.schemaFileName } : {}
665
980
  });
981
+ reportRuntimeConfigValidationResult(result, targets);
982
+ assertRequiredRuntimeConfigValidationTargets(result, targets);
666
983
  }
667
- function addRuntimeConfigImports(options) {
668
- if (options.imports === false) return;
984
+ function addRuntimeConfigComposables(options, bootstrap, hostImports, registerImports = true) {
669
985
  const resolver = createResolver(import.meta.url);
670
986
  const runtimeConfigFrom = normalizeImportPath(resolver.resolve("./runtime-config"));
671
- const template = addTemplate({
987
+ const validationSchemas = createRuntimeConfigValidationSchemas(options, bootstrap);
988
+ addTemplate({
672
989
  filename: runtimeConfigComposablesTemplate,
990
+ write: true,
673
991
  getContents: () => createRuntimeConfigComposablesSource({
674
992
  runtimeConfigFrom,
675
- typed: true,
676
- useRuntimeConfigFrom: "nuxt/app"
993
+ typed: false,
994
+ useRuntimeConfigFrom: "nuxt/app",
995
+ validationSchemas
677
996
  })
678
997
  });
998
+ addTypeTemplate(
999
+ {
1000
+ filename: "types/lorion-runtime-config-composables.d.ts",
1001
+ getContents: createRuntimeConfigComposablesTypesSource
1002
+ },
1003
+ { nitro: true, nuxt: true }
1004
+ );
679
1005
  addServerTemplate({
680
1006
  filename: serverRuntimeConfigComposablesTemplate,
681
1007
  getContents: () => createRuntimeConfigComposablesSource({
682
1008
  runtimeConfigFrom,
683
1009
  typed: false,
684
- useRuntimeConfigFrom: "nitropack/runtime"
1010
+ useRuntimeConfigFrom: "nitropack/runtime",
1011
+ validationSchemas
685
1012
  })
686
1013
  });
687
1014
  const imports = runtimeConfigImportNames.map((name) => ({
688
1015
  as: name,
689
- from: `#build/${template.filename}`,
1016
+ from: runtimeConfigComposablesImport,
690
1017
  name
691
1018
  }));
692
1019
  const serverImports = runtimeConfigImportNames.map((name) => ({
@@ -694,9 +1021,15 @@ function addRuntimeConfigImports(options) {
694
1021
  from: serverRuntimeConfigComposablesTemplate,
695
1022
  name
696
1023
  }));
1024
+ if (!registerImports) return;
1025
+ if (!shouldRegisterRuntimeConfigImports(options, hostImports)) return;
697
1026
  addImports(imports);
698
1027
  addServerImports(serverImports);
699
1028
  }
1029
+ function shouldRegisterRuntimeConfigImports(options, hostImports) {
1030
+ if (options.imports !== void 0) return options.imports;
1031
+ return hostImports?.scan !== false;
1032
+ }
700
1033
  function createRuntimeConfigDefaultsConfig(options) {
701
1034
  return {
702
1035
  public: {
@@ -717,8 +1050,13 @@ function applyRuntimeConfigModule(input) {
717
1050
  input.rootDir
718
1051
  );
719
1052
  const runtimeConfig = runtimeConfigOptions ? createConfiguredNuxtRuntimeConfig({ runtimeConfig: runtimeConfigOptions }, input.bootstrap) : void 0;
1053
+ addRuntimeConfigComposables(
1054
+ runtimeConfigOptions ?? {},
1055
+ input.bootstrap,
1056
+ input.nuxt.options.imports,
1057
+ Boolean(runtimeConfigOptions)
1058
+ );
720
1059
  if (!runtimeConfigOptions) return input.currentRuntimeConfig;
721
- addRuntimeConfigImports(runtimeConfigOptions);
722
1060
  registerRuntimeConfigPublicAssets(runtimeConfigOptions, input.nuxt);
723
1061
  validateRuntimeConfigSource(runtimeConfigOptions, input.bootstrap);
724
1062
  return mergeNuxtRuntimeConfig(
@@ -728,7 +1066,16 @@ function applyRuntimeConfigModule(input) {
728
1066
  }
729
1067
  function createProviderSelectionRuntimeConfig(bootstrap, options) {
730
1068
  if (options?.enabled === false) return void 0;
731
- return createNuxtProviderSelectionRuntimeConfig(bootstrap.resolvedExtensions, options);
1069
+ return createNuxtProviderSelectionRuntimeConfig(bootstrap.resolvedExtensions, {
1070
+ ...options,
1071
+ selectedProviders: {
1072
+ ...createNuxtSelectedProviderPreferences({
1073
+ entries: bootstrap.resolvedExtensions,
1074
+ selectedExtensions: bootstrap.selectedExtensions
1075
+ }),
1076
+ ...options?.selectedProviders ?? {}
1077
+ }
1078
+ });
732
1079
  }
733
1080
  function createNuxtExtensionBootstrapLogEvent(input) {
734
1081
  const providerSelection = input.providerSelectionRuntimeConfig ? getNuxtProviderSelection(input.providerSelectionRuntimeConfig) : void 0;
@@ -845,10 +1192,14 @@ var module_default = lorionNuxtModule;
845
1192
  export {
846
1193
  createNuxtExtensionBootstrap,
847
1194
  createNuxtExtensionBootstrapLogEvent,
1195
+ createNuxtExtensionCatalog,
1196
+ createNuxtExtensionEntryMap,
848
1197
  createNuxtExtensionLayerPaths,
849
1198
  createNuxtProviderSelectionRuntimeConfig,
850
1199
  module_default as default,
1200
+ discoverNuxtExtensionEntries,
851
1201
  formatNuxtExtensionBootstrapLog,
1202
+ nuxtExtensionDescriptorSchema,
852
1203
  reportNuxtExtensionBootstrap,
853
1204
  resolveExtensionSelection
854
1205
  };