@lorion-org/nuxt 1.0.0-beta.0 → 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,12 +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 {
22
- resolveItemProviderSelection
26
+ collectProviderDefaults,
27
+ collectProviderPreferences,
28
+ collectSelectedProviderPreferences,
29
+ resolveItemProviderSelection,
30
+ resolveSelectedProviderRelationPreferences
23
31
  } from "@lorion-org/provider-selection";
24
32
 
25
33
  // src/extension-descriptor.schema.json
@@ -45,8 +53,19 @@ var extension_descriptor_schema_default = {
45
53
  },
46
54
  version: { $ref: "#/$defs/semver" },
47
55
  providesFor: {
48
- type: "string",
49
- 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
+ ]
50
69
  },
51
70
  capabilities: {
52
71
  type: "array",
@@ -58,6 +77,21 @@ var extension_descriptor_schema_default = {
58
77
  dependencies: { $ref: "#/$defs/dependencyMap" },
59
78
  disabled: { type: "boolean" },
60
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
+ },
61
95
  providerPreferences: {
62
96
  type: "object",
63
97
  additionalProperties: {
@@ -69,6 +103,16 @@ var extension_descriptor_schema_default = {
69
103
  type: "object",
70
104
  additionalProperties: true
71
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
+ },
72
116
  bundles: {
73
117
  type: "array",
74
118
  items: { $ref: "#/$defs/extension" }
@@ -89,20 +133,38 @@ var defaultExtensionOptions = {
89
133
  publicRuntimeConfigKey: "extensionSelection",
90
134
  descriptorPaths: ["extensions/*/extension.json"]
91
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
+ ];
92
154
  function isRecord(value) {
93
155
  return typeof value === "object" && value !== null && !Array.isArray(value);
94
156
  }
95
- function asArray(value) {
96
- if (value === void 0) return [];
97
- return Array.isArray(value) ? value : [value];
98
- }
99
- function splitSelectionValue(value) {
100
- return value.split(/[,\s]+/).map((entry) => entry.trim()).filter(Boolean);
101
- }
102
157
  function normalizeSelection(value) {
103
- return asArray(value).flatMap((entry) => {
104
- if (typeof entry !== "string") return [];
105
- 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 } : {}
106
168
  });
107
169
  }
108
170
  function resolveExtensionOptions(options) {
@@ -132,6 +194,10 @@ function findNuxtConfigFile(cwd) {
132
194
  return ["nuxt.config.ts", "nuxt.config.mts", "nuxt.config.js", "nuxt.config.mjs"].map((fileName) => optionalFile(join(cwd, fileName))).find(Boolean);
133
195
  }
134
196
  function createExtensionEntry(input) {
197
+ const descriptor = {
198
+ ...input.descriptor,
199
+ location: input.descriptor.location ?? input.cwd
200
+ };
135
201
  const appDir = optionalDir(join(input.cwd, "app"));
136
202
  const modulesDir = optionalDir(join(input.cwd, "modules"));
137
203
  const publicDir = optionalDir(join(input.cwd, "public"));
@@ -140,7 +206,7 @@ function createExtensionEntry(input) {
140
206
  const configFile = findNuxtConfigFile(input.cwd);
141
207
  const entry = {
142
208
  cwd: input.cwd,
143
- descriptor: input.descriptor
209
+ descriptor
144
210
  };
145
211
  if (appDir) entry.appDir = appDir;
146
212
  if (configFile) entry.configFile = configFile;
@@ -158,7 +224,7 @@ function canRegisterExtensionLayer(entry) {
158
224
  function canExtendExtensionLayer(entry) {
159
225
  return Boolean(entry.configFile);
160
226
  }
161
- function discoverExtensionEntries(input) {
227
+ function discoverNuxtExtensionEntries(input) {
162
228
  const resolvedOptions = resolveExtensionOptions(input.options);
163
229
  return discoverDescriptors({
164
230
  cwd: input.projectRootDir,
@@ -176,9 +242,47 @@ function discoverExtensionEntries(input) {
176
242
  })
177
243
  );
178
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
+ }
179
254
  function pickEntriesById(ids, entryById) {
180
255
  return ids.map((id) => entryById.get(id)).filter((entry) => Boolean(entry));
181
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
+ }
182
286
  function mergeRuntimeConfigSection(target = {}, source = {}) {
183
287
  const merged = { ...target };
184
288
  for (const [key, value] of Object.entries(source)) {
@@ -215,10 +319,10 @@ function createNuxtExtensionBootstrap(input) {
215
319
  const options = input.options ?? {};
216
320
  const selectedExtensions = resolveExtensionSelection({
217
321
  ...options.defaultSelection ? { defaultSelection: options.defaultSelection } : {},
218
- ...options.selected ? { selected: options.selected } : {}
322
+ selected: options.selected ?? resolveNuxtExtensionSelectionSeed(options.selectionSeed)
219
323
  });
220
- const createCatalog = (entries2) => createDescriptorCatalog({
221
- descriptors: entries2.map((entry) => entry.descriptor),
324
+ const createCatalog = (entries2) => createNuxtExtensionCatalog({
325
+ entries: entries2,
222
326
  ...options.relationDescriptors ? { relationDescriptors: options.relationDescriptors } : {}
223
327
  });
224
328
  if (options.enabled === false) {
@@ -233,7 +337,7 @@ function createNuxtExtensionBootstrap(input) {
233
337
  selectedExtensions
234
338
  };
235
339
  }
236
- const entries = discoverExtensionEntries({
340
+ const entries = discoverNuxtExtensionEntries({
237
341
  projectRootDir: input.rootDir,
238
342
  options
239
343
  });
@@ -242,7 +346,6 @@ function createNuxtExtensionBootstrap(input) {
242
346
  options,
243
347
  selectedExtensions
244
348
  });
245
- const entryById = new Map(entries.map((entry) => [entry.descriptor.id, entry]));
246
349
  if (!entries.length) {
247
350
  return {
248
351
  activeExtensions: [],
@@ -255,13 +358,26 @@ function createNuxtExtensionBootstrap(input) {
255
358
  selectedExtensions
256
359
  };
257
360
  }
258
- const catalog = createCatalog(entries);
361
+ const selectedProviders = createNuxtSelectedProviderPreferences({
362
+ entries,
363
+ selectedExtensions
364
+ });
365
+ const resolutionEntries = createProviderSelectionAwareEntries(entries, selectedProviders);
366
+ const catalog = createCatalog(resolutionEntries);
259
367
  const selection = catalog.resolveSelection({
260
368
  baseDescriptors: baseExtensionIds,
369
+ policy: {
370
+ inspectionRelationIds: defaultExtensionResolutionRelations,
371
+ provenanceRelationIds: defaultExtensionResolutionRelations,
372
+ resolutionRelationIds: defaultExtensionResolutionRelations
373
+ },
261
374
  selected: selectedExtensions
262
375
  });
263
376
  const resolvedExtensionIds = selection.getResolved();
264
- const resolvedExtensions = pickEntriesById(resolvedExtensionIds, entryById);
377
+ const resolvedExtensions = pickEntriesById(
378
+ resolvedExtensionIds,
379
+ createNuxtExtensionEntryMap(resolutionEntries)
380
+ );
265
381
  const activeExtensions = resolvedExtensions.filter(canRegisterExtensionLayer);
266
382
  return {
267
383
  activeExtensions,
@@ -284,38 +400,38 @@ function createNuxtExtensionBootstrap(input) {
284
400
  function createNuxtExtensionLayerPaths(bootstrap) {
285
401
  return bootstrap.activeExtensions.filter(canExtendExtensionLayer).map((extension) => extension.cwd);
286
402
  }
287
- function collectProviderPreferences(extensions) {
288
- return extensions.reduce((preferences, extension) => {
289
- const value = extension.descriptor.providerPreferences;
290
- if (!isRecord(value)) return preferences;
291
- return {
292
- ...preferences,
293
- ...Object.fromEntries(
294
- Object.entries(value).filter(
295
- (entry) => typeof entry[1] === "string" && entry[1].length > 0
296
- )
297
- )
298
- };
299
- }, {});
300
- }
301
403
  function createNuxtProviderSelectionRuntimeConfig(extensions, options = {}) {
302
404
  const publicRuntimeConfigKey = "providerSelection";
303
- const descriptorPreferences = collectProviderPreferences(extensions);
304
- const configuredProviders = {
405
+ const descriptorPreferences = collectProviderPreferences({
406
+ items: extensions,
407
+ getProviderPreferences: (extension) => extension.descriptor.providerPreferences
408
+ });
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,
305
418
  ...descriptorPreferences,
306
- ...options.configuredProviders ?? {}
419
+ ...options.fallbackProviders ?? {}
307
420
  };
308
421
  const resolution = resolveItemProviderSelection({
309
422
  items: extensions,
310
423
  getCapabilityId: (extension) => extension.descriptor.providesFor,
311
424
  getProviderId: (extension) => extension.descriptor.id,
312
- configuredProviders
425
+ configuredProviders,
426
+ fallbackProviders,
427
+ selectedProviders
313
428
  });
314
429
  return {
315
430
  public: {
316
431
  [publicRuntimeConfigKey]: {
317
432
  configuredProviders,
318
433
  excludedProviderIds: resolution.excludedProviderIds,
434
+ fallbackProviders,
319
435
  mismatches: resolution.mismatches,
320
436
  selections: Object.fromEntries(resolution.selections)
321
437
  }
@@ -468,14 +584,27 @@ function validateNuxtRuntimeConfigSourceScopes(source, targets, options = {}) {
468
584
  }
469
585
 
470
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";
471
595
  var runtimeConfigImportNames = [
472
596
  "useRuntimeConfigFragment",
597
+ "useValidatedRuntimeConfigFragment",
473
598
  "useRuntimeConfigScope",
599
+ "useValidatedRuntimeConfigScope",
474
600
  "usePublicRuntimeConfigScope",
601
+ "usePublicValidatedRuntimeConfigScope",
475
602
  "usePrivateRuntimeConfigScope",
603
+ "usePrivateValidatedRuntimeConfigScope",
476
604
  "useRuntimeConfigValue"
477
605
  ];
478
- var runtimeConfigComposablesTemplate = "lorion/runtime-config-composables.ts";
606
+ var runtimeConfigComposablesTemplate = "lorion/runtime-config-composables.mjs";
607
+ var runtimeConfigComposablesImport = "#build/lorion/runtime-config-composables";
479
608
  var serverRuntimeConfigComposablesTemplate = "#internal/lorion-runtime-config-composables.mjs";
480
609
  var defaultRuntimeConfigSource = {
481
610
  contextInputKey: "contexts",
@@ -513,6 +642,7 @@ function normalizeImportPath(path) {
513
642
  return path.replace(/\\/g, "/");
514
643
  }
515
644
  function createRuntimeConfigComposablesSource(input) {
645
+ const validationSchemasSource = JSON.stringify(input.validationSchemas);
516
646
  const typeImports = input.typed ? `
517
647
  import type {
518
648
  GetRuntimeConfigFragmentOptions,
@@ -569,6 +699,7 @@ export type UseRuntimeConfigFragmentOptions =
569
699
  valueReturn: ""
570
700
  };
571
701
  return `import { useRuntimeConfig } from '${input.useRuntimeConfigFrom}'
702
+ import { createRuntimeConfigValidatorRegistry } from '@lorion-org/runtime-config'
572
703
  import {
573
704
  getNuxtRuntimeConfigFragment,
574
705
  getNuxtRuntimeConfigScope,
@@ -578,6 +709,12 @@ import {
578
709
  } from '${input.runtimeConfigFrom}'
579
710
  ${typeImports}
580
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
+ }
581
718
 
582
719
  function getComposableDefaults(runtimeConfig${typeAnnotations.runtimeConfig})${typeAnnotations.defaults} {
583
720
  const container = runtimeConfig.public?.[runtimeConfigDefaultsKey]
@@ -606,24 +743,66 @@ export function useRuntimeConfigFragment(scopeId, options${typeAnnotations.fragm
606
743
  return getNuxtRuntimeConfigFragment(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
607
744
  }
608
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
+
609
755
  export function useRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.scopeOptions} = {}) {
610
756
  const runtimeConfig = useRuntimeConfig()
611
757
 
612
758
  return getNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
613
759
  }
614
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
+
615
772
  export function usePublicRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.publicOptions} = {}) {
616
773
  const runtimeConfig = useRuntimeConfig()
617
774
 
618
775
  return getPublicNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
619
776
  }
620
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
+
621
789
  export function usePrivateRuntimeConfigScope${typeAnnotations.scopeReturn}(scopeId, options${typeAnnotations.privateOptions} = {}) {
622
790
  const runtimeConfig = useRuntimeConfig()
623
791
 
624
792
  return getPrivateNuxtRuntimeConfigScope(runtimeConfig, scopeId, withComposableDefaults(runtimeConfig, options))
625
793
  }
626
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
+
627
806
  export function useRuntimeConfigValue${typeAnnotations.valueOptions}(scopeId, key, options${typeAnnotations.valueOptionsType} = {})${typeAnnotations.valueReturn} {
628
807
  const runtimeConfig = useRuntimeConfig()
629
808
 
@@ -631,6 +810,72 @@ export function useRuntimeConfigValue${typeAnnotations.valueOptions}(scopeId, ke
631
810
  }
632
811
  `;
633
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
+ }
634
879
  function createDefaultRuntimeConfigOptions(rootDir) {
635
880
  const paths = defaultRuntimeConfigSource.paths.map((pattern) => join2(rootDir, pattern));
636
881
  const runtimeConfigDir = join2(rootDir, ".runtimeconfig", "runtime-config");
@@ -660,43 +905,115 @@ function registerRuntimeConfigPublicAssets(options, nuxt) {
660
905
  });
661
906
  }
662
907
  function resolveRuntimeConfigValidationTargets(bootstrap) {
663
- return bootstrap?.resolvedExtensions.map((extension) => ({
908
+ return bootstrap?.resolvedExtensions.filter((extension) => extension.descriptor.runtimeConfig !== void 0).map((extension) => ({
664
909
  scopeId: extension.descriptor.id,
665
- cwd: extension.cwd
910
+ cwd: extension.cwd,
911
+ policy: extension.descriptor.runtimeConfig
666
912
  })) ?? [];
667
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
+ }
668
973
  function validateRuntimeConfigSource(options, bootstrap) {
669
974
  if (!options.source || options.validation === false || !options.validation) return;
670
975
  const targets = resolveRuntimeConfigValidationTargets(bootstrap);
671
976
  if (!targets.length) return;
672
- validateNuxtRuntimeConfigSourceScopes(options.source, targets, {
977
+ const result = validateNuxtRuntimeConfigSourceScopes(options.source, targets, {
673
978
  ...options.validation.formatError ? { formatError: options.validation.formatError } : {},
674
979
  ...options.validation.schemaFileName ? { schemaFileName: options.validation.schemaFileName } : {}
675
980
  });
981
+ reportRuntimeConfigValidationResult(result, targets);
982
+ assertRequiredRuntimeConfigValidationTargets(result, targets);
676
983
  }
677
- function addRuntimeConfigImports(options) {
678
- if (options.imports === false) return;
984
+ function addRuntimeConfigComposables(options, bootstrap, hostImports, registerImports = true) {
679
985
  const resolver = createResolver(import.meta.url);
680
986
  const runtimeConfigFrom = normalizeImportPath(resolver.resolve("./runtime-config"));
681
- const template = addTemplate({
987
+ const validationSchemas = createRuntimeConfigValidationSchemas(options, bootstrap);
988
+ addTemplate({
682
989
  filename: runtimeConfigComposablesTemplate,
990
+ write: true,
683
991
  getContents: () => createRuntimeConfigComposablesSource({
684
992
  runtimeConfigFrom,
685
- typed: true,
686
- useRuntimeConfigFrom: "nuxt/app"
993
+ typed: false,
994
+ useRuntimeConfigFrom: "nuxt/app",
995
+ validationSchemas
687
996
  })
688
997
  });
998
+ addTypeTemplate(
999
+ {
1000
+ filename: "types/lorion-runtime-config-composables.d.ts",
1001
+ getContents: createRuntimeConfigComposablesTypesSource
1002
+ },
1003
+ { nitro: true, nuxt: true }
1004
+ );
689
1005
  addServerTemplate({
690
1006
  filename: serverRuntimeConfigComposablesTemplate,
691
1007
  getContents: () => createRuntimeConfigComposablesSource({
692
1008
  runtimeConfigFrom,
693
1009
  typed: false,
694
- useRuntimeConfigFrom: "nitropack/runtime"
1010
+ useRuntimeConfigFrom: "nitropack/runtime",
1011
+ validationSchemas
695
1012
  })
696
1013
  });
697
1014
  const imports = runtimeConfigImportNames.map((name) => ({
698
1015
  as: name,
699
- from: `#build/${template.filename}`,
1016
+ from: runtimeConfigComposablesImport,
700
1017
  name
701
1018
  }));
702
1019
  const serverImports = runtimeConfigImportNames.map((name) => ({
@@ -704,9 +1021,15 @@ function addRuntimeConfigImports(options) {
704
1021
  from: serverRuntimeConfigComposablesTemplate,
705
1022
  name
706
1023
  }));
1024
+ if (!registerImports) return;
1025
+ if (!shouldRegisterRuntimeConfigImports(options, hostImports)) return;
707
1026
  addImports(imports);
708
1027
  addServerImports(serverImports);
709
1028
  }
1029
+ function shouldRegisterRuntimeConfigImports(options, hostImports) {
1030
+ if (options.imports !== void 0) return options.imports;
1031
+ return hostImports?.scan !== false;
1032
+ }
710
1033
  function createRuntimeConfigDefaultsConfig(options) {
711
1034
  return {
712
1035
  public: {
@@ -727,8 +1050,13 @@ function applyRuntimeConfigModule(input) {
727
1050
  input.rootDir
728
1051
  );
729
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
+ );
730
1059
  if (!runtimeConfigOptions) return input.currentRuntimeConfig;
731
- addRuntimeConfigImports(runtimeConfigOptions);
732
1060
  registerRuntimeConfigPublicAssets(runtimeConfigOptions, input.nuxt);
733
1061
  validateRuntimeConfigSource(runtimeConfigOptions, input.bootstrap);
734
1062
  return mergeNuxtRuntimeConfig(
@@ -738,7 +1066,16 @@ function applyRuntimeConfigModule(input) {
738
1066
  }
739
1067
  function createProviderSelectionRuntimeConfig(bootstrap, options) {
740
1068
  if (options?.enabled === false) return void 0;
741
- 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
+ });
742
1079
  }
743
1080
  function createNuxtExtensionBootstrapLogEvent(input) {
744
1081
  const providerSelection = input.providerSelectionRuntimeConfig ? getNuxtProviderSelection(input.providerSelectionRuntimeConfig) : void 0;
@@ -855,10 +1192,14 @@ var module_default = lorionNuxtModule;
855
1192
  export {
856
1193
  createNuxtExtensionBootstrap,
857
1194
  createNuxtExtensionBootstrapLogEvent,
1195
+ createNuxtExtensionCatalog,
1196
+ createNuxtExtensionEntryMap,
858
1197
  createNuxtExtensionLayerPaths,
859
1198
  createNuxtProviderSelectionRuntimeConfig,
860
1199
  module_default as default,
1200
+ discoverNuxtExtensionEntries,
861
1201
  formatNuxtExtensionBootstrapLog,
1202
+ nuxtExtensionDescriptorSchema,
862
1203
  reportNuxtExtensionBootstrap,
863
1204
  resolveExtensionSelection
864
1205
  };