@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lorion-org/nuxt",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.3",
4
4
  "description": "Nuxt module for LORION libraries and framework adapters.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,30 +21,57 @@
21
21
  "types": "./dist/index.d.ts",
22
22
  "exports": {
23
23
  ".": {
24
+ "lorion-source": {
25
+ "types": "./src/index.ts",
26
+ "default": "./src/index.ts"
27
+ },
24
28
  "types": "./dist/index.d.ts",
25
29
  "import": "./dist/index.js",
26
30
  "default": "./dist/index.js"
27
31
  },
28
32
  "./runtime-config": {
33
+ "lorion-source": {
34
+ "types": "./src/runtime-config.ts",
35
+ "default": "./src/runtime-config.ts"
36
+ },
29
37
  "types": "./dist/runtime-config.d.ts",
30
38
  "import": "./dist/runtime-config.js",
31
39
  "default": "./dist/runtime-config.js"
32
40
  },
33
41
  "./runtime-config-node": {
42
+ "lorion-source": {
43
+ "types": "./src/runtime-config-node.ts",
44
+ "default": "./src/runtime-config-node.ts"
45
+ },
34
46
  "types": "./dist/runtime-config-node.d.ts",
35
47
  "import": "./dist/runtime-config-node.js",
36
48
  "default": "./dist/runtime-config-node.js"
37
49
  },
38
50
  "./descriptor-schema": {
51
+ "lorion-source": {
52
+ "types": "./src/descriptor-schema.ts",
53
+ "default": "./src/descriptor-schema.ts"
54
+ },
39
55
  "types": "./dist/descriptor-schema.d.ts",
40
56
  "import": "./dist/descriptor-schema.js",
41
57
  "default": "./dist/descriptor-schema.js"
58
+ },
59
+ "./extensions": {
60
+ "lorion-source": {
61
+ "types": "./src/extensions.ts",
62
+ "default": "./src/extensions.ts"
63
+ },
64
+ "types": "./dist/extensions.d.ts",
65
+ "import": "./dist/extensions.js",
66
+ "default": "./dist/extensions.js"
42
67
  }
43
68
  },
44
69
  "files": [
45
70
  "dist",
46
- "examples",
47
- "LICENSE"
71
+ "LICENSE",
72
+ "src/**/*.ts",
73
+ "src/**/*.json",
74
+ "!src/**/*.spec.ts"
48
75
  ],
49
76
  "keywords": [
50
77
  "lorion",
@@ -56,11 +83,12 @@
56
83
  "node": "^20.19.0 || >=22.12.0"
57
84
  },
58
85
  "dependencies": {
59
- "@lorion-org/runtime-config": "^1.0.0-beta.0",
60
- "@lorion-org/runtime-config-node": "^1.0.0-beta.0",
61
- "@lorion-org/descriptor-discovery": "^1.0.0-beta.1",
62
- "@lorion-org/composition-graph": "^1.0.0-beta.1",
63
- "@lorion-org/provider-selection": "^1.0.0-beta.1"
86
+ "@lorion-org/descriptor-selection": "^1.0.0-beta.3",
87
+ "@lorion-org/provider-selection": "^1.0.0-beta.2",
88
+ "@lorion-org/runtime-config": "^1.0.0-beta.1",
89
+ "@lorion-org/runtime-config-node": "^1.0.0-beta.1",
90
+ "@lorion-org/composition-graph": "^1.0.0-beta.2",
91
+ "@lorion-org/descriptor-discovery": "^1.0.0-beta.3"
64
92
  },
65
93
  "peerDependencies": {
66
94
  "@nuxt/kit": "^4.0.0",
@@ -71,19 +99,17 @@
71
99
  "@nuxt/schema": "^4.4.2",
72
100
  "@nuxt/test-utils": "^3.23.0",
73
101
  "nuxt": "^4.4.2",
74
- "@lorion-org/registry-hub": "^1.0.0-beta.1"
102
+ "srvx": "^0.11.15",
103
+ "@lorion-org/registry-hub": "^1.0.0-beta.2"
75
104
  },
76
105
  "scripts": {
77
- "build": "rimraf dist && tsup src/index.ts src/runtime-config.ts src/runtime-config-node.ts src/descriptor-schema.ts --format esm --dts --splitting false",
106
+ "build": "rimraf dist && tsup src/index.ts src/runtime-config.ts src/runtime-config-node.ts src/descriptor-schema.ts src/extensions.ts --format esm --dts --splitting false",
78
107
  "clean": "rimraf coverage dist tsconfig.tsbuildinfo",
79
108
  "lint": "eslint src --ext .ts",
80
109
  "package:check": "pnpm build && pnpm pack --dry-run && publint",
81
110
  "test": "pnpm test:unit && pnpm test:e2e",
82
111
  "test:unit": "vitest run --config test/vitest.unit.config.mts",
83
112
  "test:e2e": "vitest run --config test/vitest.e2e.config.mts",
84
- "build:playground": "nuxi build playground",
85
- "dev:playground": "nuxi dev playground",
86
- "typecheck:playground": "nuxi typecheck playground",
87
113
  "typecheck": "tsc -p tsconfig.json --noEmit"
88
114
  }
89
115
  }
@@ -0,0 +1,5 @@
1
+ import extensionDescriptorSchemaData from './extension-descriptor.schema.json';
2
+
3
+ export type JsonSchemaObject = Record<string, unknown>;
4
+
5
+ export const nuxtExtensionDescriptorSchema = extensionDescriptorSchemaData as JsonSchemaObject;
@@ -0,0 +1,92 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://lorion.dev/schemas/nuxt-extension-descriptor.schema.json",
4
+ "$ref": "#/$defs/extension",
5
+ "$defs": {
6
+ "semver": {
7
+ "type": "string",
8
+ "pattern": "^(\\^|~)?\\d+\\.\\d+\\.\\d+$"
9
+ },
10
+ "dependencyMap": {
11
+ "type": "object",
12
+ "additionalProperties": { "$ref": "#/$defs/semver" }
13
+ },
14
+ "extension": {
15
+ "type": "object",
16
+ "properties": {
17
+ "id": {
18
+ "type": "string",
19
+ "minLength": 1
20
+ },
21
+ "version": { "$ref": "#/$defs/semver" },
22
+ "providesFor": {
23
+ "oneOf": [
24
+ {
25
+ "type": "string",
26
+ "minLength": 1
27
+ },
28
+ {
29
+ "type": "array",
30
+ "items": {
31
+ "type": "string",
32
+ "minLength": 1
33
+ }
34
+ }
35
+ ]
36
+ },
37
+ "capabilities": {
38
+ "type": "array",
39
+ "items": {
40
+ "type": "string",
41
+ "minLength": 1
42
+ }
43
+ },
44
+ "dependencies": { "$ref": "#/$defs/dependencyMap" },
45
+ "disabled": { "type": "boolean" },
46
+ "location": { "type": "string" },
47
+ "defaultFor": {
48
+ "oneOf": [
49
+ {
50
+ "type": "string",
51
+ "minLength": 1
52
+ },
53
+ {
54
+ "type": "array",
55
+ "items": {
56
+ "type": "string",
57
+ "minLength": 1
58
+ }
59
+ }
60
+ ]
61
+ },
62
+ "providerPreferences": {
63
+ "type": "object",
64
+ "additionalProperties": {
65
+ "type": "string",
66
+ "minLength": 1
67
+ }
68
+ },
69
+ "publicRuntimeConfig": {
70
+ "type": "object",
71
+ "additionalProperties": true
72
+ },
73
+ "runtimeConfig": {
74
+ "type": "object",
75
+ "properties": {
76
+ "validation": {
77
+ "type": "string",
78
+ "enum": ["none", "optional", "startup", "onUse"]
79
+ }
80
+ },
81
+ "additionalProperties": false
82
+ },
83
+ "bundles": {
84
+ "type": "array",
85
+ "items": { "$ref": "#/$defs/extension" }
86
+ }
87
+ },
88
+ "required": ["id", "version"],
89
+ "additionalProperties": true
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,458 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import process from 'node:process';
4
+ import {
5
+ createDescriptorCatalog,
6
+ parseDescriptorIds,
7
+ resolveDescriptorSelectionSeed,
8
+ type DescriptorCatalog,
9
+ type Descriptor,
10
+ type RelationDescriptor,
11
+ } from '@lorion-org/composition-graph';
12
+ import { discoverDescriptors } from '@lorion-org/descriptor-discovery';
13
+ import {
14
+ collectProviderDefaults,
15
+ collectProviderPreferences,
16
+ collectSelectedProviderPreferences,
17
+ resolveItemProviderSelection,
18
+ type ProviderPreferenceMap,
19
+ } from '@lorion-org/provider-selection';
20
+ import {
21
+ applyProviderSelection,
22
+ assertSingleDefaultProvider,
23
+ descriptorSelectionPolicy,
24
+ providerRelationDescriptors,
25
+ } from '@lorion-org/descriptor-selection';
26
+ import type { RuntimeConfigValidationPolicy } from '@lorion-org/runtime-config';
27
+ import type {
28
+ NuxtBaseExtensionSelectionInput,
29
+ NuxtExtensionSelectionRuntimeConfig,
30
+ NuxtExtensionModuleOptions,
31
+ NuxtExtensionSelectionSeedOptions,
32
+ NuxtProviderSelectionModuleOptions,
33
+ NuxtProviderSelectionRuntimeConfig,
34
+ NuxtRuntimeConfig,
35
+ } from './types';
36
+ import { nuxtExtensionDescriptorSchema } from './descriptor-schema';
37
+
38
+ export type {
39
+ LorionNuxtModuleOptions,
40
+ NuxtExtensionModuleOptions,
41
+ NuxtExtensionSelectionSeedOptions,
42
+ RuntimeConfigNuxtModuleOptions,
43
+ } from './types';
44
+
45
+ export type NuxtExtensionDescriptor = Descriptor & {
46
+ defaultFor?: string | string[];
47
+ providerPreferences?: ProviderPreferenceMap;
48
+ publicRuntimeConfig?: NuxtRuntimeConfig['public'];
49
+ runtimeConfig?: RuntimeConfigValidationPolicy;
50
+ };
51
+
52
+ export type NuxtExtensionEntry = {
53
+ appDir?: string;
54
+ configFile?: string;
55
+ cwd: string;
56
+ descriptor: NuxtExtensionDescriptor;
57
+ modulesDir?: string;
58
+ publicDir?: string;
59
+ serverDir?: string;
60
+ sharedDir?: string;
61
+ };
62
+
63
+ export type NuxtExtensionBootstrap = {
64
+ activeExtensions: NuxtExtensionEntry[];
65
+ baseExtensionIds: string[];
66
+ catalog: DescriptorCatalog;
67
+ discoveredExtensions: NuxtExtensionEntry[];
68
+ publicRuntimeConfig: NuxtRuntimeConfig;
69
+ resolvedExtensionIds: string[];
70
+ resolvedExtensions: NuxtExtensionEntry[];
71
+ selectedExtensions: string[];
72
+ };
73
+
74
+ type NuxtProviderSelectionOptions = Omit<NuxtProviderSelectionModuleOptions, 'enabled'>;
75
+
76
+ type ResolvedNuxtExtensionOptions = {
77
+ descriptorSchema: false | object;
78
+ descriptorPaths: string[];
79
+ };
80
+
81
+ const defaultExtensionOptions = {
82
+ defaultSelection: 'default',
83
+ publicRuntimeConfigKey: 'extensionSelection',
84
+ descriptorPaths: ['extensions/*/extension.json'],
85
+ } as const;
86
+ const defaultExtensionSelectionSeedKey = 'capability';
87
+
88
+ function isRecord(value: unknown): value is Record<string, unknown> {
89
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
90
+ }
91
+
92
+ function normalizeSelection(value: string | string[] | undefined): string[] {
93
+ return parseDescriptorIds(value);
94
+ }
95
+
96
+ function resolveNuxtExtensionSelectionSeed(
97
+ seedOptions: false | NuxtExtensionSelectionSeedOptions | undefined,
98
+ ): string[] {
99
+ if (seedOptions === false) return [];
100
+
101
+ return resolveDescriptorSelectionSeed({
102
+ argv: seedOptions?.argv ?? process.argv,
103
+ env: seedOptions?.env ?? process.env,
104
+ key: seedOptions?.key ?? defaultExtensionSelectionSeedKey,
105
+ ...(seedOptions?.cliKeys ? { cliKeys: seedOptions.cliKeys } : {}),
106
+ ...(seedOptions?.envKeys ? { envKeys: seedOptions.envKeys } : {}),
107
+ });
108
+ }
109
+
110
+ function resolveExtensionOptions(
111
+ options: NuxtExtensionModuleOptions,
112
+ ): ResolvedNuxtExtensionOptions {
113
+ return {
114
+ descriptorSchema: options.descriptorSchema ?? nuxtExtensionDescriptorSchema,
115
+ descriptorPaths: options.descriptorPaths ?? [...defaultExtensionOptions.descriptorPaths],
116
+ };
117
+ }
118
+
119
+ export function resolveExtensionSelection(
120
+ input: {
121
+ defaultSelection?: string | string[];
122
+ selected?: string | string[];
123
+ } = {},
124
+ ): string[] {
125
+ const candidates = [
126
+ normalizeSelection(input.selected),
127
+ normalizeSelection(input.defaultSelection ?? defaultExtensionOptions.defaultSelection),
128
+ ];
129
+
130
+ return candidates.find((candidate) => candidate.length > 0) ?? [];
131
+ }
132
+
133
+ function resolveBaseExtensionSelection(
134
+ input: NuxtBaseExtensionSelectionInput & {
135
+ options: NuxtExtensionModuleOptions;
136
+ },
137
+ ): string[] {
138
+ const baseExtensions = input.options.baseExtensions;
139
+
140
+ return typeof baseExtensions === 'function'
141
+ ? normalizeSelection(baseExtensions(input))
142
+ : normalizeSelection(baseExtensions);
143
+ }
144
+
145
+ function optionalDir(path: string): string | undefined {
146
+ return existsSync(path) ? path : undefined;
147
+ }
148
+
149
+ function optionalFile(path: string): string | undefined {
150
+ return existsSync(path) ? path : undefined;
151
+ }
152
+
153
+ function findNuxtConfigFile(cwd: string): string | undefined {
154
+ return ['nuxt.config.ts', 'nuxt.config.mts', 'nuxt.config.js', 'nuxt.config.mjs']
155
+ .map((fileName) => optionalFile(join(cwd, fileName)))
156
+ .find(Boolean);
157
+ }
158
+
159
+ function createExtensionEntry(input: {
160
+ cwd: string;
161
+ descriptor: NuxtExtensionDescriptor;
162
+ }): NuxtExtensionEntry {
163
+ const descriptor: NuxtExtensionDescriptor = {
164
+ ...input.descriptor,
165
+ location: input.descriptor.location ?? input.cwd,
166
+ };
167
+ const appDir = optionalDir(join(input.cwd, 'app'));
168
+ const modulesDir = optionalDir(join(input.cwd, 'modules'));
169
+ const publicDir = optionalDir(join(input.cwd, 'public'));
170
+ const serverDir = optionalDir(join(input.cwd, 'server'));
171
+ const sharedDir = optionalDir(join(input.cwd, 'shared'));
172
+ const configFile = findNuxtConfigFile(input.cwd);
173
+ const entry: NuxtExtensionEntry = {
174
+ cwd: input.cwd,
175
+ descriptor,
176
+ };
177
+
178
+ if (appDir) entry.appDir = appDir;
179
+ if (configFile) entry.configFile = configFile;
180
+ if (modulesDir) entry.modulesDir = modulesDir;
181
+ if (publicDir) entry.publicDir = publicDir;
182
+ if (serverDir) entry.serverDir = serverDir;
183
+ if (sharedDir) entry.sharedDir = sharedDir;
184
+
185
+ return entry;
186
+ }
187
+
188
+ function canRegisterExtensionLayer(entry: NuxtExtensionEntry): boolean {
189
+ return Boolean(
190
+ entry.appDir ||
191
+ entry.configFile ||
192
+ entry.modulesDir ||
193
+ entry.publicDir ||
194
+ entry.serverDir ||
195
+ entry.sharedDir,
196
+ );
197
+ }
198
+
199
+ function canExtendExtensionLayer(entry: NuxtExtensionEntry): boolean {
200
+ return Boolean(entry.configFile);
201
+ }
202
+
203
+ export function discoverNuxtExtensionEntries(input: {
204
+ projectRootDir: string;
205
+ options: NuxtExtensionModuleOptions;
206
+ }): NuxtExtensionEntry[] {
207
+ const resolvedOptions = resolveExtensionOptions(input.options);
208
+
209
+ return discoverDescriptors({
210
+ cwd: input.projectRootDir,
211
+ descriptorPaths: resolvedOptions.descriptorPaths,
212
+ nestedField: 'bundles',
213
+ ...(resolvedOptions.descriptorSchema === false
214
+ ? {}
215
+ : {
216
+ validation: {
217
+ schema: resolvedOptions.descriptorSchema,
218
+ },
219
+ }),
220
+ }).map((entry) =>
221
+ createExtensionEntry({
222
+ cwd: entry.cwd,
223
+ descriptor: entry.descriptor,
224
+ }),
225
+ );
226
+ }
227
+
228
+ export function createNuxtExtensionCatalog(input: {
229
+ entries: NuxtExtensionEntry[];
230
+ relationDescriptors?: RelationDescriptor[];
231
+ }): DescriptorCatalog {
232
+ return createDescriptorCatalog({
233
+ descriptors: input.entries.map((entry) => entry.descriptor),
234
+ relationDescriptors: [...providerRelationDescriptors, ...(input.relationDescriptors ?? [])],
235
+ });
236
+ }
237
+
238
+ export function createNuxtExtensionEntryMap(
239
+ entries: NuxtExtensionEntry[],
240
+ ): Map<string, NuxtExtensionEntry> {
241
+ return new Map(entries.map((entry) => [entry.descriptor.id, entry]));
242
+ }
243
+
244
+ function pickEntriesById(
245
+ ids: string[],
246
+ entryById: Map<string, NuxtExtensionEntry>,
247
+ ): NuxtExtensionEntry[] {
248
+ return ids
249
+ .map((id) => entryById.get(id))
250
+ .filter((entry): entry is NuxtExtensionEntry => Boolean(entry));
251
+ }
252
+
253
+ // The capability -> selected-provider map, used by the module to expose provider
254
+ // selection through runtime config. The selection cleaning itself is delegated to
255
+ // @lorion-org/descriptor-selection's `applyProviderSelection`.
256
+ export function createNuxtSelectedProviderPreferences(input: {
257
+ entries: NuxtExtensionEntry[];
258
+ selectedExtensions: string[];
259
+ }): ProviderPreferenceMap {
260
+ return collectSelectedProviderPreferences({
261
+ items: input.entries,
262
+ getCapabilityId: (entry) => entry.descriptor.providesFor,
263
+ getProviderId: (entry) => entry.descriptor.id,
264
+ selectedProviderIds: input.selectedExtensions,
265
+ });
266
+ }
267
+
268
+ function mergeRuntimeConfigSection(
269
+ target: NuxtRuntimeConfig['public'] = {},
270
+ source: NuxtRuntimeConfig['public'] = {},
271
+ ): NuxtRuntimeConfig['public'] {
272
+ const merged: NuxtRuntimeConfig['public'] = { ...target };
273
+
274
+ for (const [key, value] of Object.entries(source)) {
275
+ const current = merged[key];
276
+
277
+ merged[key] =
278
+ isRecord(current) && isRecord(value) ? mergeRuntimeConfigSection(current, value) : value;
279
+ }
280
+
281
+ return merged;
282
+ }
283
+
284
+ function createExtensionSelectionRuntimeConfig(input: {
285
+ activeExtensions: NuxtExtensionEntry[];
286
+ baseExtensionIds: string[];
287
+ discoveredExtensions: NuxtExtensionEntry[];
288
+ publicRuntimeConfigKey: false | string;
289
+ resolvedExtensionIds: string[];
290
+ selectedExtensions: string[];
291
+ }): NuxtRuntimeConfig {
292
+ const runtimeConfig = input.activeExtensions.reduce<NuxtRuntimeConfig>(
293
+ (current, extension) => ({
294
+ ...current,
295
+ public: mergeRuntimeConfigSection(
296
+ current.public,
297
+ extension.descriptor.publicRuntimeConfig ?? {},
298
+ ),
299
+ }),
300
+ { public: {} },
301
+ );
302
+
303
+ if (input.publicRuntimeConfigKey === false) return runtimeConfig;
304
+
305
+ return {
306
+ ...runtimeConfig,
307
+ public: {
308
+ ...runtimeConfig.public,
309
+ [defaultExtensionOptions.publicRuntimeConfigKey]: {
310
+ discoveredExtensionIds: input.discoveredExtensions
311
+ .map((extension) => extension.descriptor.id)
312
+ .sort((left, right) => left.localeCompare(right)),
313
+ resolvedExtensionIds: input.resolvedExtensionIds,
314
+ selectedExtensionIds: input.selectedExtensions,
315
+ } satisfies NuxtExtensionSelectionRuntimeConfig,
316
+ },
317
+ };
318
+ }
319
+
320
+ export function createNuxtExtensionBootstrap(input: {
321
+ options?: NuxtExtensionModuleOptions;
322
+ rootDir: string;
323
+ }): NuxtExtensionBootstrap {
324
+ const options = input.options ?? {};
325
+ const selectedExtensions = resolveExtensionSelection({
326
+ ...(options.defaultSelection ? { defaultSelection: options.defaultSelection } : {}),
327
+ selected: options.selected ?? resolveNuxtExtensionSelectionSeed(options.selectionSeed),
328
+ });
329
+ const createCatalog = (entries: NuxtExtensionEntry[]): DescriptorCatalog =>
330
+ createNuxtExtensionCatalog({
331
+ entries,
332
+ ...(options.relationDescriptors ? { relationDescriptors: options.relationDescriptors } : {}),
333
+ });
334
+
335
+ if (options.enabled === false) {
336
+ return {
337
+ activeExtensions: [],
338
+ baseExtensionIds: [],
339
+ catalog: createCatalog([]),
340
+ discoveredExtensions: [],
341
+ publicRuntimeConfig: { public: {} },
342
+ resolvedExtensionIds: [],
343
+ resolvedExtensions: [],
344
+ selectedExtensions,
345
+ };
346
+ }
347
+
348
+ const entries = discoverNuxtExtensionEntries({
349
+ projectRootDir: input.rootDir,
350
+ options,
351
+ });
352
+ const baseExtensionIds = resolveBaseExtensionSelection({
353
+ descriptors: entries.map((entry) => entry.descriptor),
354
+ options,
355
+ selectedExtensions,
356
+ });
357
+
358
+ if (!entries.length) {
359
+ return {
360
+ activeExtensions: [],
361
+ baseExtensionIds,
362
+ catalog: createCatalog(entries),
363
+ discoveredExtensions: entries,
364
+ publicRuntimeConfig: { public: {} },
365
+ resolvedExtensionIds: [],
366
+ resolvedExtensions: [],
367
+ selectedExtensions,
368
+ };
369
+ }
370
+
371
+ assertSingleDefaultProvider(entries.map((entry) => entry.descriptor));
372
+
373
+ const resolutionEntries = applyProviderSelection({
374
+ items: entries,
375
+ selected: selectedExtensions,
376
+ getDescriptor: (entry) => entry.descriptor,
377
+ withDescriptor: (entry, descriptor) => ({ ...entry, descriptor }),
378
+ });
379
+ const catalog = createCatalog(resolutionEntries);
380
+ const selection = catalog.resolveSelection({
381
+ baseDescriptors: baseExtensionIds,
382
+ policy: descriptorSelectionPolicy(),
383
+ selected: selectedExtensions,
384
+ });
385
+ const resolvedExtensionIds = selection.getResolved();
386
+ const resolvedExtensions = pickEntriesById(
387
+ resolvedExtensionIds,
388
+ createNuxtExtensionEntryMap(resolutionEntries),
389
+ );
390
+ const activeExtensions = resolvedExtensions.filter(canRegisterExtensionLayer);
391
+
392
+ return {
393
+ activeExtensions,
394
+ baseExtensionIds: selection.getBaseDescriptors(),
395
+ catalog,
396
+ discoveredExtensions: entries,
397
+ publicRuntimeConfig: createExtensionSelectionRuntimeConfig({
398
+ activeExtensions,
399
+ baseExtensionIds: selection.getBaseDescriptors(),
400
+ discoveredExtensions: entries,
401
+ publicRuntimeConfigKey: defaultExtensionOptions.publicRuntimeConfigKey,
402
+ resolvedExtensionIds,
403
+ selectedExtensions,
404
+ }),
405
+ resolvedExtensionIds,
406
+ resolvedExtensions,
407
+ selectedExtensions: selection.getSelected(),
408
+ };
409
+ }
410
+
411
+ export function createNuxtExtensionLayerPaths(bootstrap: NuxtExtensionBootstrap): string[] {
412
+ return bootstrap.activeExtensions
413
+ .filter(canExtendExtensionLayer)
414
+ .map((extension) => extension.cwd);
415
+ }
416
+
417
+ export function createNuxtProviderSelectionRuntimeConfig(
418
+ extensions: NuxtExtensionEntry[],
419
+ options: NuxtProviderSelectionOptions = {},
420
+ ): NuxtRuntimeConfig {
421
+ const publicRuntimeConfigKey = 'providerSelection';
422
+ const descriptorPreferences = collectProviderPreferences({
423
+ items: extensions,
424
+ getProviderPreferences: (extension) => extension.descriptor.providerPreferences,
425
+ });
426
+ const providerDefaults = collectProviderDefaults({
427
+ items: extensions,
428
+ getDefaultFor: (extension) => extension.descriptor.defaultFor,
429
+ getProviderId: (extension) => extension.descriptor.id,
430
+ });
431
+ const configuredProviders = options.configuredProviders ?? {};
432
+ const selectedProviders = options.selectedProviders ?? {};
433
+ const fallbackProviders = {
434
+ ...providerDefaults,
435
+ ...descriptorPreferences,
436
+ ...(options.fallbackProviders ?? {}),
437
+ };
438
+ const resolution = resolveItemProviderSelection({
439
+ items: extensions,
440
+ getCapabilityId: (extension) => extension.descriptor.providesFor,
441
+ getProviderId: (extension) => extension.descriptor.id,
442
+ configuredProviders,
443
+ fallbackProviders,
444
+ selectedProviders,
445
+ });
446
+
447
+ return {
448
+ public: {
449
+ [publicRuntimeConfigKey]: {
450
+ configuredProviders,
451
+ excludedProviderIds: resolution.excludedProviderIds,
452
+ fallbackProviders,
453
+ mismatches: resolution.mismatches,
454
+ selections: Object.fromEntries(resolution.selections),
455
+ } satisfies NuxtProviderSelectionRuntimeConfig,
456
+ },
457
+ };
458
+ }
package/src/index.ts ADDED
@@ -0,0 +1,31 @@
1
+ export {
2
+ createNuxtExtensionBootstrapLogEvent,
3
+ default,
4
+ formatNuxtExtensionBootstrapLog,
5
+ reportNuxtExtensionBootstrap,
6
+ } from './module';
7
+ export {
8
+ createNuxtExtensionBootstrap,
9
+ createNuxtExtensionCatalog,
10
+ createNuxtExtensionEntryMap,
11
+ createNuxtExtensionLayerPaths,
12
+ createNuxtProviderSelectionRuntimeConfig,
13
+ discoverNuxtExtensionEntries,
14
+ resolveExtensionSelection,
15
+ type NuxtExtensionBootstrap,
16
+ type NuxtExtensionDescriptor,
17
+ type NuxtExtensionEntry,
18
+ type NuxtExtensionModuleOptions,
19
+ type NuxtExtensionSelectionSeedOptions,
20
+ } from './extensions';
21
+ export { nuxtExtensionDescriptorSchema, type JsonSchemaObject } from './descriptor-schema';
22
+ export type {
23
+ LorionNuxtModuleOptions,
24
+ NuxtBaseExtensionSelection,
25
+ NuxtBaseExtensionSelectionInput,
26
+ NuxtExtensionBootstrapLogEvent,
27
+ NuxtExtensionBootstrapReporter,
28
+ NuxtProviderSelectionModuleOptions,
29
+ NuxtProviderSelectionRuntimeConfig,
30
+ RuntimeConfigNuxtModuleOptions,
31
+ } from './types';