@lorion-org/react 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.d.ts CHANGED
@@ -1,10 +1,31 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
2
  import { Descriptor, DescriptorCatalog } from '@lorion-org/composition-graph';
3
3
  import { ProviderPreferenceMap, ProviderSelectionResolution } from '@lorion-org/provider-selection';
4
+ import { RuntimeConfigSection, RuntimeConfigValidationPolicy } from '@lorion-org/runtime-config';
5
+ export { descriptorSelectionPolicy as createCapabilityCompositionPolicy, providerRelationDescriptors as defaultCapabilityRelationDescriptors, defaultResolutionRelations as defaultCapabilityResolutionRelations } from '@lorion-org/descriptor-selection';
6
+
7
+ type CapabilityRuntimeConfig = {
8
+ public: Record<string, RuntimeConfigSection>;
9
+ };
10
+ type CapabilityRuntimeConfigFragment<T extends RuntimeConfigSection = RuntimeConfigSection> = {
11
+ public: T;
12
+ };
13
+ type CapabilityRuntimeConfigProviderProps = {
14
+ children: ReactNode;
15
+ runtimeConfig: CapabilityRuntimeConfig;
16
+ };
17
+ declare function CapabilityRuntimeConfigProvider({ children, runtimeConfig, }: CapabilityRuntimeConfigProviderProps): ReactElement;
18
+ declare function useCapabilityRuntimeConfigScope<T extends RuntimeConfigSection = RuntimeConfigSection>(capabilityId: string): T;
19
+ declare function useCapabilityRuntimeConfig<T extends RuntimeConfigSection = RuntimeConfigSection>(capabilityId: string): CapabilityRuntimeConfigFragment<T>;
20
+ declare function useCapabilityRuntimeConfigRoot(): CapabilityRuntimeConfig;
21
+ declare function getCapabilityRuntimeConfigScope<T extends RuntimeConfigSection = RuntimeConfigSection>(runtimeConfig: CapabilityRuntimeConfig, capabilityId: string): T;
22
+ declare function getCapabilityRuntimeConfig<T extends RuntimeConfigSection = RuntimeConfigSection>(runtimeConfig: CapabilityRuntimeConfig, capabilityId: string): CapabilityRuntimeConfigFragment<T>;
4
23
 
5
24
  type CapabilityManifest = Descriptor & {
25
+ defaultFor?: string | string[];
6
26
  description?: string;
7
27
  providerPreferences?: ProviderPreferenceMap;
28
+ runtimeConfig?: RuntimeConfigValidationPolicy;
8
29
  };
9
30
  type ExtensionPoint<T> = {
10
31
  id: string;
@@ -36,6 +57,7 @@ declare function createContributionContract<T>(id: string): ContributionContract
36
57
  type CapabilityProviderSelectionOptions = {
37
58
  configuredProviders?: ProviderPreferenceMap;
38
59
  fallbackProviders?: ProviderPreferenceMap;
60
+ selectedProviders?: ProviderPreferenceMap;
39
61
  };
40
62
  declare function getCapabilityProviderSelection(runtime: CapabilityRuntime, options?: CapabilityProviderSelectionOptions): ProviderSelectionResolution;
41
63
  declare function defineCapability(capability: RuntimeCapability): RuntimeCapability;
@@ -47,4 +69,4 @@ type CapabilityRuntimeProviderProps = {
47
69
  declare function CapabilityRuntimeProvider({ children, runtime, }: CapabilityRuntimeProviderProps): ReactElement;
48
70
  declare function useCapabilityRuntime(): CapabilityRuntime;
49
71
 
50
- export { type CapabilityContribution, type CapabilityManifest, type CapabilityProviderSelectionOptions, type CapabilityRuntime, CapabilityRuntimeProvider, type CapabilityRuntimeProviderProps, type ContributionContract, type ExtensionPoint, type RuntimeCapability, createCapabilityRuntime, createContributionContract, defineCapability, defineContribution, defineExtensionPoint, getCapabilityProviderSelection, useCapabilityRuntime };
72
+ export { type CapabilityContribution, type CapabilityManifest, type CapabilityProviderSelectionOptions, type CapabilityRuntime, type CapabilityRuntimeConfig, type CapabilityRuntimeConfigFragment, CapabilityRuntimeConfigProvider, type CapabilityRuntimeConfigProviderProps, CapabilityRuntimeProvider, type CapabilityRuntimeProviderProps, type ContributionContract, type ExtensionPoint, type RuntimeCapability, createCapabilityRuntime, createContributionContract, defineCapability, defineContribution, defineExtensionPoint, getCapabilityProviderSelection, getCapabilityRuntimeConfig, getCapabilityRuntimeConfigScope, useCapabilityRuntime, useCapabilityRuntimeConfig, useCapabilityRuntimeConfigRoot, useCapabilityRuntimeConfigScope };
package/dist/index.js CHANGED
@@ -1,13 +1,52 @@
1
1
  // src/index.ts
2
- import { createContext, createElement, useContext } from "react";
2
+ import { createContext as createContext2, createElement as createElement2, useContext as useContext2 } from "react";
3
3
  import {
4
4
  assertKnownDescriptorIds,
5
5
  createDescriptorCatalog
6
6
  } from "@lorion-org/composition-graph";
7
7
  import {
8
+ collectProviderDefaults,
8
9
  collectProviderPreferences,
9
10
  resolveItemProviderSelection
10
11
  } from "@lorion-org/provider-selection";
12
+
13
+ // src/relations.ts
14
+ import {
15
+ providerRelationDescriptors,
16
+ descriptorSelectionPolicy,
17
+ defaultResolutionRelations
18
+ } from "@lorion-org/descriptor-selection";
19
+
20
+ // src/runtime-config.ts
21
+ import { createContext, createElement, useContext } from "react";
22
+ var emptyRuntimeConfig = Object.freeze({ public: Object.freeze({}) });
23
+ var CapabilityRuntimeConfigContext = createContext(emptyRuntimeConfig);
24
+ function CapabilityRuntimeConfigProvider({
25
+ children,
26
+ runtimeConfig
27
+ }) {
28
+ return createElement(CapabilityRuntimeConfigContext.Provider, { value: runtimeConfig }, children);
29
+ }
30
+ function useCapabilityRuntimeConfigScope(capabilityId) {
31
+ return getCapabilityRuntimeConfigScope(useCapabilityRuntimeConfigRoot(), capabilityId);
32
+ }
33
+ function useCapabilityRuntimeConfig(capabilityId) {
34
+ return getCapabilityRuntimeConfig(useCapabilityRuntimeConfigRoot(), capabilityId);
35
+ }
36
+ function useCapabilityRuntimeConfigRoot() {
37
+ return useContext(CapabilityRuntimeConfigContext);
38
+ }
39
+ function getCapabilityRuntimeConfigScope(runtimeConfig, capabilityId) {
40
+ const publicConfig = runtimeConfig.public[capabilityId];
41
+ return publicConfig && typeof publicConfig === "object" && !Array.isArray(publicConfig) ? publicConfig : {};
42
+ }
43
+ function getCapabilityRuntimeConfig(runtimeConfig, capabilityId) {
44
+ return {
45
+ public: getCapabilityRuntimeConfigScope(runtimeConfig, capabilityId)
46
+ };
47
+ }
48
+
49
+ // src/index.ts
11
50
  function defineExtensionPoint(id) {
12
51
  return { id };
13
52
  }
@@ -29,16 +68,25 @@ function getCapabilityProviderSelection(runtime, options = {}) {
29
68
  items: descriptors,
30
69
  getProviderPreferences: (descriptor) => descriptor.providerPreferences
31
70
  });
32
- const configuredProviders = {
71
+ const providerDefaults = collectProviderDefaults({
72
+ items: descriptors,
73
+ getDefaultFor: (descriptor) => descriptor.defaultFor,
74
+ getProviderId: (descriptor) => descriptor.id
75
+ });
76
+ const configuredProviders = options.configuredProviders ?? {};
77
+ const selectedProviders = options.selectedProviders ?? {};
78
+ const fallbackProviders = {
79
+ ...providerDefaults,
33
80
  ...descriptorPreferences,
34
- ...options.configuredProviders ?? {}
81
+ ...options.fallbackProviders ?? {}
35
82
  };
36
83
  const resolution = resolveItemProviderSelection({
37
84
  items: descriptors,
38
85
  getCapabilityId: (descriptor) => descriptor.providesFor,
39
86
  getProviderId: (descriptor) => descriptor.id,
40
87
  configuredProviders,
41
- ...options.fallbackProviders ? { fallbackProviders: options.fallbackProviders } : {}
88
+ fallbackProviders,
89
+ selectedProviders
42
90
  });
43
91
  return {
44
92
  excludedProviderIds: resolution.excludedProviderIds,
@@ -68,15 +116,15 @@ function createCapabilityRuntime(capabilities) {
68
116
  getContributions: (extensionPoint) => [...contributions.get(extensionPoint.id) ?? []]
69
117
  };
70
118
  }
71
- var CapabilityRuntimeContext = createContext(null);
119
+ var CapabilityRuntimeContext = createContext2(null);
72
120
  function CapabilityRuntimeProvider({
73
121
  children,
74
122
  runtime
75
123
  }) {
76
- return createElement(CapabilityRuntimeContext.Provider, { value: runtime }, children);
124
+ return createElement2(CapabilityRuntimeContext.Provider, { value: runtime }, children);
77
125
  }
78
126
  function useCapabilityRuntime() {
79
- const runtime = useContext(CapabilityRuntimeContext);
127
+ const runtime = useContext2(CapabilityRuntimeContext);
80
128
  if (!runtime) {
81
129
  throw new Error("useCapabilityRuntime must be used inside CapabilityRuntimeProvider.");
82
130
  }
@@ -113,16 +161,26 @@ function collectContributions(capabilities) {
113
161
  }
114
162
  function createCapabilityCatalog(capabilities) {
115
163
  return createDescriptorCatalog({
116
- descriptors: capabilities.map((capability) => capability.manifest)
164
+ descriptors: capabilities.map((capability) => capability.manifest),
165
+ relationDescriptors: providerRelationDescriptors
117
166
  });
118
167
  }
119
168
  export {
169
+ CapabilityRuntimeConfigProvider,
120
170
  CapabilityRuntimeProvider,
171
+ descriptorSelectionPolicy as createCapabilityCompositionPolicy,
121
172
  createCapabilityRuntime,
122
173
  createContributionContract,
174
+ providerRelationDescriptors as defaultCapabilityRelationDescriptors,
175
+ defaultResolutionRelations as defaultCapabilityResolutionRelations,
123
176
  defineCapability,
124
177
  defineContribution,
125
178
  defineExtensionPoint,
126
179
  getCapabilityProviderSelection,
127
- useCapabilityRuntime
180
+ getCapabilityRuntimeConfig,
181
+ getCapabilityRuntimeConfigScope,
182
+ useCapabilityRuntime,
183
+ useCapabilityRuntimeConfig,
184
+ useCapabilityRuntimeConfigRoot,
185
+ useCapabilityRuntimeConfigScope
128
186
  };
package/dist/vite.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/vite.ts
@@ -22,21 +32,36 @@ var vite_exports = {};
22
32
  __export(vite_exports, {
23
33
  capabilityLoader: () => capabilityLoader,
24
34
  createCapabilityRouteConfig: () => createCapabilityRouteConfig,
35
+ createReactRuntimeConfig: () => createReactRuntimeConfig,
25
36
  discoverCapabilities: () => discoverCapabilities,
26
37
  discoverSelectedCapabilities: () => discoverSelectedCapabilities,
27
38
  lorionReact: () => lorionReact,
28
- renderCapabilityModule: () => renderCapabilityModule
39
+ renderCapabilityModule: () => renderCapabilityModule,
40
+ renderRuntimeConfigModule: () => renderRuntimeConfigModule,
41
+ renderServerRuntimeConfigModule: () => renderServerRuntimeConfigModule
29
42
  });
30
43
  module.exports = __toCommonJS(vite_exports);
31
44
  var import_node_fs = require("fs");
32
45
  var import_node_path = require("path");
33
- var import_composition_graph = require("@lorion-org/composition-graph");
46
+ var import_node_process = __toESM(require("process"), 1);
47
+ var import_vite = require("vite");
34
48
  var import_descriptor_discovery = require("@lorion-org/descriptor-discovery");
49
+ var import_descriptor_selection = require("@lorion-org/descriptor-selection");
50
+ var import_runtime_config = require("@lorion-org/runtime-config");
51
+ var import_runtime_config_node = require("@lorion-org/runtime-config-node");
52
+ var import_surface_activation = require("@lorion-org/surface-activation");
35
53
  var virtualModuleId = "virtual:capabilities";
36
54
  var resolvedVirtualModuleId = `\0${virtualModuleId}`;
55
+ var runtimeConfigModuleId = "virtual:capability-runtime-config";
56
+ var resolvedRuntimeConfigModuleId = `\0${runtimeConfigModuleId}`;
57
+ var serverRuntimeConfigModuleId = "virtual:capability-runtime-config/server";
58
+ var resolvedServerRuntimeConfigModuleId = `\0${serverRuntimeConfigModuleId}`;
59
+ var defaultRuntimeConfigFileName = "capability.runtime.json";
60
+ var defaultRuntimeConfigSchemaFileName = "capability.schema.json";
37
61
  function capabilityLoader(options = {}) {
38
62
  let config;
39
63
  let capabilities = [];
64
+ let runtimeConfig = { private: {}, public: {} };
40
65
  return {
41
66
  name: "lorion-react-capability-loader",
42
67
  enforce: "pre",
@@ -46,62 +71,132 @@ function capabilityLoader(options = {}) {
46
71
  resolveWorkspaceRoot(config.root, options),
47
72
  options
48
73
  );
74
+ runtimeConfig = createReactRuntimeConfig(
75
+ capabilities,
76
+ resolveWorkspaceRoot(config.root, options),
77
+ options.runtimeConfig,
78
+ config
79
+ );
49
80
  },
50
81
  resolveId(id) {
51
82
  if (id === virtualModuleId) return resolvedVirtualModuleId;
83
+ if (id === runtimeConfigModuleId) return resolvedRuntimeConfigModuleId;
84
+ if (id === serverRuntimeConfigModuleId) return resolvedServerRuntimeConfigModuleId;
52
85
  return capabilities.find((capability) => capability.importSpecifier === id)?.entryFile;
53
86
  },
54
- load(id) {
87
+ load(id, loadOptions) {
88
+ if (id === resolvedRuntimeConfigModuleId) return renderRuntimeConfigModule(runtimeConfig);
89
+ if (id === resolvedServerRuntimeConfigModuleId) {
90
+ if (!loadOptions?.ssr) {
91
+ throw new Error(
92
+ "virtual:capability-runtime-config/server may only be imported from SSR/server code."
93
+ );
94
+ }
95
+ return renderServerRuntimeConfigModule(runtimeConfig);
96
+ }
55
97
  if (id !== resolvedVirtualModuleId) return null;
56
- return renderCapabilityModule(capabilities);
98
+ return renderCapabilityModule(capabilities, resolveSelectionSeed(options));
57
99
  }
58
100
  };
59
101
  }
102
+ function createReactRuntimeConfig(capabilities, workspaceRoot, options = {}, viteConfig = {}) {
103
+ const normalizedOptions = normalizeRuntimeConfigOptions(options);
104
+ if (!normalizedOptions.enabled) return { private: {}, public: {} };
105
+ const runtimeEnv = resolveRuntimeConfigEnv(viteConfig, normalizedOptions.env ?? {});
106
+ const sourceFragments = normalizedOptions.source ? (0, import_runtime_config_node.loadRuntimeConfigSourceTree)(
107
+ resolveRuntimeConfigPatternSource(workspaceRoot, normalizedOptions, runtimeEnv)
108
+ ) : /* @__PURE__ */ new Map();
109
+ const schemaEntries = readRuntimeConfigSchemas(capabilities, normalizedOptions.schemaFileName);
110
+ const envFragments = normalizedOptions.env === false ? /* @__PURE__ */ new Map() : createRuntimeConfigEnvFragments(
111
+ createRuntimeConfigEnvFragmentOptions(
112
+ capabilities,
113
+ schemaEntries.schemas,
114
+ runtimeEnv,
115
+ normalizedOptions.env
116
+ )
117
+ );
118
+ const fragments = mergeRuntimeConfigFragmentMaps(sourceFragments, envFragments);
119
+ validateReactRuntimeConfig(capabilities, fragments, schemaEntries, normalizedOptions.validation);
120
+ const projected = (0, import_runtime_config.projectRuntimeConfigNamespaces)(fragments, {
121
+ namespaceStrategy: "nested",
122
+ scopeIds: capabilities.map((capability) => capability.id)
123
+ });
124
+ const { public: publicConfig, ...privateConfig } = projected;
125
+ return {
126
+ public: publicConfig,
127
+ private: privateConfig
128
+ };
129
+ }
60
130
  function lorionReact(options) {
61
131
  return {
62
132
  capabilityLoader: capabilityLoader(options),
63
133
  routeConfig: createCapabilityRouteConfig(options)
64
134
  };
65
135
  }
136
+ function toResolveActivation(options) {
137
+ if (options.surface) {
138
+ if (options.activation) {
139
+ throw new Error("capabilityLoader: pass either `surface` or `activation`, not both.");
140
+ }
141
+ const { name, resolver } = options.surface;
142
+ return ({ capabilityDir, descriptor }) => resolver(name, { directory: capabilityDir, id: descriptor.id });
143
+ }
144
+ return options.activation;
145
+ }
66
146
  function discoverCapabilities(workspaceRoot, options = {}) {
67
147
  const capabilitiesRoot = (0, import_node_path.resolve)(workspaceRoot, options.capabilitiesDir ?? "capabilities");
68
148
  if (!(0, import_node_fs.existsSync)(capabilitiesRoot)) {
69
149
  throw new Error(`Capabilities directory not found: ${capabilitiesRoot}`);
70
150
  }
71
- return discoverCapabilityDescriptors(workspaceRoot, options).map(discoverCapability).sort((left, right) => left.id.localeCompare(right.id));
151
+ const resolveActivation = toResolveActivation(options);
152
+ return discoverCapabilityDescriptors(workspaceRoot, options).map((entry) => discoverCapability(entry, resolveActivation)).sort((left, right) => left.id.localeCompare(right.id));
72
153
  }
73
154
  function discoverSelectedCapabilities(workspaceRoot, options = {}) {
74
155
  return selectCapabilities(discoverCapabilities(workspaceRoot, options), options);
75
156
  }
76
157
  function selectCapabilities(capabilities, options = {}) {
77
- const enabledCapabilities = capabilities.filter((capability) => capability.disabled !== true);
78
- if (!options.selected?.length && !options.baseDescriptors?.length) {
79
- return [...enabledCapabilities];
80
- }
81
- const catalog = (0, import_composition_graph.createDescriptorCatalog)({
82
- descriptors: enabledCapabilities.map((capability) => capability.manifest)
83
- });
84
- const selection = (0, import_composition_graph.createCompositionSelection)({
85
- catalog,
86
- selected: [...options.selected ?? []],
87
- baseDescriptors: [...options.baseDescriptors ?? []],
158
+ return (0, import_descriptor_selection.selectDescriptors)({
159
+ items: capabilities,
160
+ getDescriptor: (capability) => capability.manifest,
161
+ withDescriptor: (capability, manifest) => ({ ...capability, manifest }),
162
+ seed: options,
163
+ ...options.relationDescriptors ? { relationDescriptors: options.relationDescriptors } : {},
88
164
  ...options.policy ? { policy: options.policy } : {}
89
165
  });
90
- const selectedIds = new Set(selection.getResolved());
91
- return enabledCapabilities.filter((capability) => selectedIds.has(capability.id));
92
166
  }
93
- function renderCapabilityModule(capabilities) {
94
- const imports = capabilities.map(
95
- (capability) => `import { capability as ${capability.variableName} } from '${capability.importSpecifier}'`
167
+ function resolveSelectionSeed(options) {
168
+ return (0, import_descriptor_selection.resolveDescriptorSelection)(options);
169
+ }
170
+ function renderCapabilityModule(capabilities, selected = []) {
171
+ const activated = capabilities.filter(
172
+ (capability) => capability.exportName && capability.importSpecifier
173
+ );
174
+ const imports = activated.map(
175
+ (capability) => `import { ${capability.exportName} as ${capability.variableName} } from '${capability.importSpecifier}'`
96
176
  ).join("\n");
97
- const variables = capabilities.map((capability) => ` ${capability.variableName},`).join("\n");
177
+ const variables = activated.map((capability) => ` ${capability.variableName},`).join("\n");
178
+ const capabilityIds = capabilities.map((capability) => capability.id);
98
179
  return `${imports}
99
180
 
181
+ export const selectedCapabilityIds = ${JSON.stringify([...selected])}
182
+
183
+ export const resolvedCapabilityIds = ${JSON.stringify(capabilityIds)}
184
+
100
185
  export const capabilityModules = [
101
186
  ${variables}
102
187
  ]
103
188
  `;
104
189
  }
190
+ function renderRuntimeConfigModule(runtimeConfig) {
191
+ return `export const capabilityRuntimeConfig = ${JSON.stringify({ public: runtimeConfig.public })}
192
+
193
+ export const publicCapabilityRuntimeConfig = capabilityRuntimeConfig.public
194
+ `;
195
+ }
196
+ function renderServerRuntimeConfigModule(runtimeConfig) {
197
+ return `export const capabilityServerRuntimeConfig = ${JSON.stringify(runtimeConfig)}
198
+ `;
199
+ }
105
200
  function createCapabilityRouteConfig(options) {
106
201
  if (!options?.workspaceRoot) {
107
202
  throw new Error("createCapabilityRouteConfig requires a workspaceRoot option.");
@@ -140,7 +235,7 @@ function discoverCapabilityDescriptors(workspaceRoot, options) {
140
235
  }
141
236
  });
142
237
  }
143
- function discoverCapability(entry) {
238
+ function discoverCapability(entry, resolveActivation) {
144
239
  const capabilityDir = entry.cwd;
145
240
  const packagePath = (0, import_node_path.resolve)(capabilityDir, "package.json");
146
241
  if (!(0, import_node_fs.existsSync)(packagePath)) {
@@ -149,42 +244,235 @@ function discoverCapability(entry) {
149
244
  );
150
245
  }
151
246
  const packageJson = readJson(packagePath);
152
- const packageName = packageJson.name;
153
- if (typeof packageName !== "string") {
154
- throw new Error(`Capability package is missing "name": ${packagePath}`);
155
- }
156
- const activationEntry = resolveActivationEntry(capabilityDir, packageJson);
247
+ const packageName = (0, import_descriptor_discovery.requirePackageName)(packageJson, packagePath);
248
+ const activationEntry = resolveActivationEntry(
249
+ capabilityDir,
250
+ packageJson,
251
+ packageName,
252
+ entry.descriptor,
253
+ resolveActivation
254
+ );
157
255
  const routesDirectory = resolveRouteDirectory(capabilityDir);
158
256
  return {
257
+ capabilityDir,
159
258
  id: entry.descriptor.id,
160
259
  disabled: entry.descriptor.disabled === true,
161
- entryFile: activationEntry.entryFile,
162
- importSpecifier: activationEntry.importSpecifier,
163
260
  manifest: entry.descriptor,
164
261
  packageName,
262
+ ...activationEntry ? {
263
+ exportName: activationEntry.exportName,
264
+ importSpecifier: activationEntry.importSpecifier,
265
+ ...activationEntry.entryFile ? { entryFile: activationEntry.entryFile } : {}
266
+ } : {},
165
267
  ...routesDirectory ? { routesDirectory } : {},
166
268
  variableName: toVariableName(entry.descriptor.id)
167
269
  };
168
270
  }
169
- function resolveRouteDirectory(capabilityDir) {
170
- const routesDirectory = (0, import_node_path.resolve)(capabilityDir, "src", "routes");
171
- return (0, import_node_fs.existsSync)(routesDirectory) ? routesDirectory : void 0;
271
+ function normalizeRuntimeConfigOptions(options) {
272
+ if (options === false) {
273
+ return {
274
+ configFileName: defaultRuntimeConfigFileName,
275
+ enabled: false,
276
+ env: false,
277
+ schemaFileName: defaultRuntimeConfigSchemaFileName,
278
+ validation: false
279
+ };
280
+ }
281
+ const configFileName = options.configFileName ?? defaultRuntimeConfigFileName;
282
+ return {
283
+ configFileName,
284
+ enabled: options.enabled !== false,
285
+ env: options.env ?? {},
286
+ schemaFileName: options.schemaFileName ?? defaultRuntimeConfigSchemaFileName,
287
+ ...options.source === false ? {} : {
288
+ source: options.source ?? { paths: [] }
289
+ },
290
+ validation: options.validation === false ? false : options.validation ?? {},
291
+ ...options.varDir ? { varDir: options.varDir } : {}
292
+ };
172
293
  }
173
- function resolveActivationEntry(capabilityDir, packageJson) {
174
- const packageName = packageJson.name;
175
- const packageExports = packageJson.exports;
176
- if (typeof packageName !== "string") {
177
- throw new Error(
178
- `Capability package is missing "name": ${(0, import_node_path.resolve)(capabilityDir, "package.json")}`
179
- );
294
+ function resolveRuntimeConfigPatternSource(workspaceRoot, options, env) {
295
+ if (!options.source?.paths.length) {
296
+ const varDir = resolveRuntimeConfigVarDir(workspaceRoot, options.varDir, env);
297
+ return {
298
+ paths: [(0, import_node_path.join)(varDir, "runtime-config", "*", options.configFileName)]
299
+ };
300
+ }
301
+ return {
302
+ paths: options.source.paths.map(
303
+ (entry) => (0, import_node_path.isAbsolute)(entry) ? entry : (0, import_node_path.resolve)(workspaceRoot, entry)
304
+ )
305
+ };
306
+ }
307
+ function resolveRuntimeConfigVarDir(workspaceRoot, options, env) {
308
+ const rawVarDir = typeof options === "string" ? options : (0, import_runtime_config_node.resolveRuntimeConfigSource)({
309
+ defaultVarDir: (0, import_node_path.resolve)(workspaceRoot, ".data"),
310
+ env: options?.env ?? env,
311
+ envKey: options?.envKey ?? "RUNTIME_CONFIG_VAR_DIR",
312
+ ...options?.value ? { varDir: options.value } : {},
313
+ ...options?.defaultValue ? { defaultVarDir: options.defaultValue } : {}
314
+ }).varDir;
315
+ return (0, import_node_path.isAbsolute)(rawVarDir) ? rawVarDir : (0, import_node_path.resolve)(workspaceRoot, rawVarDir);
316
+ }
317
+ function resolveRuntimeConfigEnv(viteConfig, options) {
318
+ if (options === false) return {};
319
+ if (options.env) return options.env;
320
+ const mode = viteConfig.mode ?? import_node_process.default.env.NODE_ENV ?? "development";
321
+ const envDir = typeof viteConfig.envDir === "string" ? viteConfig.envDir : viteConfig.root ?? import_node_process.default.cwd();
322
+ return {
323
+ ...(0, import_vite.loadEnv)(mode, envDir, ""),
324
+ ...import_node_process.default.env,
325
+ ...viteConfig.env ?? {}
326
+ };
327
+ }
328
+ function readRuntimeConfigSchemas(capabilities, schemaFileName) {
329
+ const paths = /* @__PURE__ */ new Map();
330
+ const schemas = {};
331
+ for (const capability of capabilities) {
332
+ const schemaPath = (0, import_node_path.resolve)(capability.capabilityDir, schemaFileName);
333
+ const schema = (0, import_runtime_config_node.readJsonFile)(schemaPath, {
334
+ onParseError: (error, filePath) => {
335
+ throw new Error(`RuntimeConfig schema JSON parse error in "${filePath}": ${String(error)}`);
336
+ }
337
+ });
338
+ if (!schema) continue;
339
+ paths.set(capability.id, schemaPath);
340
+ schemas[capability.id] = schema;
180
341
  }
181
- if (!isRecord(packageExports) || typeof packageExports["./capability"] !== "string") {
182
- throw new Error(`Capability package is missing a "./capability" export: ${capabilityDir}`);
342
+ return { paths, schemas };
343
+ }
344
+ function isJsonSchemaObject(value) {
345
+ return typeof value === "object" && value !== null && !Array.isArray(value);
346
+ }
347
+ function getRuntimeConfigSchemaSectionKeys(schema, visibility) {
348
+ if (!isJsonSchemaObject(schema)) return [];
349
+ const section = schema.properties?.[visibility];
350
+ if (!isJsonSchemaObject(section) || !isJsonSchemaObject(section.properties)) return [];
351
+ return Object.keys(section.properties).sort();
352
+ }
353
+ function createRuntimeConfigEnvKey(input) {
354
+ return (0, import_runtime_config.toSnakeUpperCase)([input.prefix, input.scopeId, input.key].filter(Boolean).join("_"));
355
+ }
356
+ function createRuntimeConfigEnvFragments(input) {
357
+ const fragments = /* @__PURE__ */ new Map();
358
+ for (const capability of input.capabilities) {
359
+ const schema = input.schemas[capability.id];
360
+ const publicConfig = {};
361
+ const privateConfig = {};
362
+ for (const key of getRuntimeConfigSchemaSectionKeys(schema, "public")) {
363
+ const envKey = createRuntimeConfigEnvKey({
364
+ key,
365
+ prefix: input.publicPrefix ?? "VITE",
366
+ scopeId: capability.id
367
+ });
368
+ const value = input.env[envKey];
369
+ if (value !== void 0) publicConfig[key] = value;
370
+ }
371
+ for (const key of getRuntimeConfigSchemaSectionKeys(schema, "private")) {
372
+ const envKey = createRuntimeConfigEnvKey({
373
+ key,
374
+ scopeId: capability.id,
375
+ ...input.privatePrefix !== void 0 ? { prefix: input.privatePrefix } : {}
376
+ });
377
+ const value = input.env[envKey];
378
+ if (value !== void 0) privateConfig[key] = value;
379
+ }
380
+ if (Object.keys(publicConfig).length || Object.keys(privateConfig).length) {
381
+ fragments.set(capability.id, {
382
+ ...Object.keys(publicConfig).length ? { public: publicConfig } : {},
383
+ ...Object.keys(privateConfig).length ? { private: privateConfig } : {}
384
+ });
385
+ }
183
386
  }
387
+ return fragments;
388
+ }
389
+ function createRuntimeConfigEnvFragmentOptions(capabilities, schemas, env, options) {
184
390
  return {
185
- entryFile: (0, import_node_path.resolve)(capabilityDir, packageExports["./capability"]),
186
- importSpecifier: `${packageName}/capability`
391
+ capabilities,
392
+ env,
393
+ ...options.privatePrefix !== void 0 ? { privatePrefix: options.privatePrefix } : {},
394
+ ...options.publicPrefix !== void 0 ? { publicPrefix: options.publicPrefix } : {},
395
+ schemas
396
+ };
397
+ }
398
+ function mergeRuntimeConfigSections(left, right) {
399
+ const section = {
400
+ ...left ?? {},
401
+ ...right ?? {}
187
402
  };
403
+ return Object.keys(section).length ? section : void 0;
404
+ }
405
+ function mergeRuntimeConfigFragment(left, right) {
406
+ const publicConfig = mergeRuntimeConfigSections(left?.public, right?.public);
407
+ const privateConfig = mergeRuntimeConfigSections(left?.private, right?.private);
408
+ return (0, import_runtime_config.toRuntimeConfigFragment)({
409
+ ...publicConfig ? { public: publicConfig } : {},
410
+ ...privateConfig ? { private: privateConfig } : {}
411
+ });
412
+ }
413
+ function mergeRuntimeConfigFragmentMaps(left, right) {
414
+ const fragments = new Map(left);
415
+ for (const [scopeId, config] of right.entries()) {
416
+ fragments.set(scopeId, mergeRuntimeConfigFragment(fragments.get(scopeId), config));
417
+ }
418
+ return fragments;
419
+ }
420
+ function getCapabilityRuntimeConfigPolicy(capability, validation) {
421
+ return capability.manifest.runtimeConfig ?? validation.policy ?? "optional";
422
+ }
423
+ function shouldValidateRuntimeConfigFragment(input) {
424
+ if (!input.schema) return false;
425
+ const mode = (0, import_runtime_config.resolveRuntimeConfigValidationMode)(
426
+ getCapabilityRuntimeConfigPolicy(input.capability, input.validation)
427
+ );
428
+ if (mode === "none" || mode === "onUse") return false;
429
+ if (mode === "startup") return true;
430
+ return Boolean(input.fragment);
431
+ }
432
+ function validateReactRuntimeConfig(capabilities, fragments, schemas, validation) {
433
+ if (validation === false) return;
434
+ const registry = (0, import_runtime_config.createRuntimeConfigValidatorRegistry)(schemas.schemas, {
435
+ ...validation.formatError ? {
436
+ formatError: (target, validationError) => validation.formatError(
437
+ {
438
+ configPath: `${target.scopeId} runtime config`,
439
+ schemaPath: schemas.paths.get(target.scopeId) ?? "",
440
+ scopeId: target.scopeId
441
+ },
442
+ validationError
443
+ )
444
+ } : {}
445
+ });
446
+ for (const capability of capabilities) {
447
+ const fragment = fragments.get(capability.id);
448
+ const schema = schemas.schemas[capability.id];
449
+ if (!shouldValidateRuntimeConfigFragment({ capability, fragment, schema, validation })) {
450
+ continue;
451
+ }
452
+ registry.assert(capability.id, fragment ?? {});
453
+ }
454
+ }
455
+ function resolveRouteDirectory(capabilityDir) {
456
+ const routesDirectory = (0, import_node_path.resolve)(capabilityDir, "src", "routes");
457
+ return (0, import_node_fs.existsSync)(routesDirectory) ? routesDirectory : void 0;
458
+ }
459
+ function resolveActivationEntry(capabilityDir, packageJson, packageName, descriptor, resolveActivation) {
460
+ if (!resolveActivation) {
461
+ const packageExports = packageJson.exports;
462
+ if (!isRecord(packageExports) || typeof packageExports["./capability"] !== "string") {
463
+ throw new Error(`Capability package is missing a "./capability" export: ${capabilityDir}`);
464
+ }
465
+ return {
466
+ entryFile: (0, import_node_path.resolve)(capabilityDir, packageExports["./capability"]),
467
+ exportName: "capability",
468
+ importSpecifier: (0, import_surface_activation.capabilitySpecifier)(packageName, "./capability")
469
+ };
470
+ }
471
+ const activation = resolveActivation({ capabilityDir, descriptor, packageJson, packageName });
472
+ if (!activation) return null;
473
+ const exportName = activation.exportName ?? "capability";
474
+ const exportSubpath = activation.exportSubpath ?? "./capability";
475
+ return { exportName, importSpecifier: (0, import_surface_activation.capabilitySpecifier)(packageName, exportSubpath) };
188
476
  }
189
477
  function hasRouteDirectory(capability) {
190
478
  return typeof capability.routesDirectory === "string";
@@ -222,8 +510,11 @@ function toPosixPath(path) {
222
510
  0 && (module.exports = {
223
511
  capabilityLoader,
224
512
  createCapabilityRouteConfig,
513
+ createReactRuntimeConfig,
225
514
  discoverCapabilities,
226
515
  discoverSelectedCapabilities,
227
516
  lorionReact,
228
- renderCapabilityModule
517
+ renderCapabilityModule,
518
+ renderRuntimeConfigModule,
519
+ renderServerRuntimeConfigModule
229
520
  });