@lwrjs/config 0.9.0-alpha.9 → 0.9.0

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.
Files changed (35) hide show
  1. package/build/cjs/defaults.cjs +40 -10
  2. package/build/cjs/{env-config.cjs → global-config.cjs} +71 -21
  3. package/build/cjs/hooks.cjs +69 -0
  4. package/build/cjs/index.cjs +11 -3
  5. package/build/cjs/modules.cjs +92 -0
  6. package/build/cjs/runtime-config.cjs +22 -3
  7. package/build/cjs/utils/global-data.cjs +54 -0
  8. package/build/cjs/utils/merge.cjs +22 -8
  9. package/build/cjs/utils/routes.cjs +30 -12
  10. package/build/cjs/validation/app-config-context.cjs +6 -2
  11. package/build/cjs/validation/app-config.cjs +14 -4
  12. package/build/es/defaults.d.ts +7 -2
  13. package/build/es/defaults.js +41 -9
  14. package/build/es/global-config.d.ts +65 -0
  15. package/build/es/{env-config.js → global-config.js} +92 -15
  16. package/build/es/hooks.d.ts +32 -0
  17. package/build/es/hooks.js +70 -0
  18. package/build/es/index.d.ts +5 -4
  19. package/build/es/index.js +5 -5
  20. package/build/es/modules.d.ts +32 -0
  21. package/build/es/modules.js +92 -0
  22. package/build/es/runtime-config.d.ts +12 -5
  23. package/build/es/runtime-config.js +30 -6
  24. package/build/es/utils/global-data.d.ts +3 -0
  25. package/build/es/utils/global-data.js +29 -0
  26. package/build/es/utils/merge.d.ts +1 -1
  27. package/build/es/utils/merge.js +28 -9
  28. package/build/es/utils/routes.d.ts +3 -2
  29. package/build/es/utils/routes.js +33 -16
  30. package/build/es/validation/app-config-context.d.ts +4 -3
  31. package/build/es/validation/app-config-context.js +5 -1
  32. package/build/es/validation/app-config.js +20 -5
  33. package/package.cjs +21 -2
  34. package/package.json +16 -9
  35. package/build/es/env-config.d.ts +0 -22
@@ -0,0 +1,32 @@
1
+ import type { HooksPlugin, NormalizedLwrGlobalConfig, RouteHandlers, Services } from '@lwrjs/types';
2
+ /**
3
+ * Import and instantiate hooks defined in the global config
4
+ *
5
+ * @remarks
6
+ * The optional dependency `esbuild` MUST be installed to load hook modules.
7
+ *
8
+ * @param config - global config
9
+ * @returns {HooksPlugin[]} all instantiated hooks
10
+ */
11
+ export declare function loadHooks(config: NormalizedLwrGlobalConfig): Promise<HooksPlugin[]>;
12
+ /**
13
+ * Load service modules from the filepaths configured in the global config
14
+ *
15
+ * @remarks
16
+ * The optional dependency `esbuild` MUST be installed to load service modules.
17
+ *
18
+ * @param config - global config
19
+ * @returns {Services} all of the imported service constructors
20
+ */
21
+ export declare function loadServices(config: NormalizedLwrGlobalConfig): Promise<Services>;
22
+ /**
23
+ * Load all route handlers from the filepaths configured in the global config
24
+ *
25
+ * @remarks
26
+ * The optional dependency `esbuild` MUST be installed to load route handler modules.
27
+ *
28
+ * @param config - global config
29
+ * @returns {Routes} resolved route handlers mapped by id
30
+ */
31
+ export declare function loadRouteHandlers(config: NormalizedLwrGlobalConfig): Promise<RouteHandlers>;
32
+ //# sourceMappingURL=modules.d.ts.map
@@ -0,0 +1,92 @@
1
+ import path from 'path';
2
+ import { normalizeDirectory, resolveFileExtension } from '@lwrjs/shared-utils';
3
+ import { transpileTs } from '@lwrjs/shared-utils/typescript';
4
+ async function importModule(filepath, rootDir, cacheDir) {
5
+ // ensure paths are fully resolved before loading source
6
+ let resolvedFilePath = normalizeDirectory(filepath, rootDir);
7
+ const resolvedCacheDir = normalizeDirectory(cacheDir, rootDir);
8
+ try {
9
+ if (resolvedFilePath.endsWith('.ts')) {
10
+ const fullPath = resolveFileExtension(resolvedFilePath);
11
+ resolvedFilePath = await transpileTs(fullPath, { rootDir, cacheDir: resolvedCacheDir });
12
+ }
13
+ const moduleEntry = await import(resolvedFilePath);
14
+ const output = moduleEntry.default || moduleEntry;
15
+ return output;
16
+ }
17
+ catch (err) {
18
+ console.log(err);
19
+ throw new Error(`Unable to load configurable module: ${filepath}`);
20
+ }
21
+ }
22
+ async function loadServiceEntries(entries, rootDir, cacheDir) {
23
+ return Promise.all(entries.map(async ([entry, config]) => {
24
+ const ctor = await importModule(entry, rootDir, path.join(cacheDir, 'services'));
25
+ return [ctor, config];
26
+ }));
27
+ }
28
+ /**
29
+ * Import and instantiate hooks defined in the global config
30
+ *
31
+ * @remarks
32
+ * The optional dependency `esbuild` MUST be installed to load hook modules.
33
+ *
34
+ * @param config - global config
35
+ * @returns {HooksPlugin[]} all instantiated hooks
36
+ */
37
+ export async function loadHooks(config) {
38
+ if (!config.hooks) {
39
+ return [];
40
+ }
41
+ const hookCtors = await loadServiceEntries(config.hooks, config.rootDir, config.cacheDir);
42
+ const hooks = hookCtors.map(([hookCtor, hookConfig = {}]) => {
43
+ return new hookCtor(hookConfig);
44
+ });
45
+ return hooks;
46
+ }
47
+ /**
48
+ * Load service modules from the filepaths configured in the global config
49
+ *
50
+ * @remarks
51
+ * The optional dependency `esbuild` MUST be installed to load service modules.
52
+ *
53
+ * @param config - global config
54
+ * @returns {Services} all of the imported service constructors
55
+ */
56
+ export async function loadServices(config) {
57
+ const moduleProviders = await loadServiceEntries(config.moduleProviders, config.rootDir, config.cacheDir);
58
+ const bundleProviders = await loadServiceEntries(config.bundleProviders, config.rootDir, config.cacheDir);
59
+ const assetProviders = await loadServiceEntries(config.assetProviders, config.rootDir, config.cacheDir);
60
+ const assetTransformers = await loadServiceEntries(config.assetTransformers, config.rootDir, config.cacheDir);
61
+ const resourceProviders = await loadServiceEntries(config.resourceProviders, config.rootDir, config.cacheDir);
62
+ const viewProviders = await loadServiceEntries(config.viewProviders, config.rootDir, config.cacheDir);
63
+ const viewTransformers = await loadServiceEntries(config.viewTransformers, config.rootDir, config.cacheDir);
64
+ return {
65
+ moduleProviders,
66
+ bundleProviders,
67
+ assetProviders,
68
+ assetTransformers,
69
+ resourceProviders,
70
+ viewProviders,
71
+ viewTransformers,
72
+ };
73
+ }
74
+ /**
75
+ * Load all route handlers from the filepaths configured in the global config
76
+ *
77
+ * @remarks
78
+ * The optional dependency `esbuild` MUST be installed to load route handler modules.
79
+ *
80
+ * @param config - global config
81
+ * @returns {Routes} resolved route handlers mapped by id
82
+ */
83
+ export async function loadRouteHandlers(config) {
84
+ const routeHandlers = {};
85
+ await Promise.all(Object.keys(config.routeHandlers).map(async (id) => {
86
+ const handlerPath = config.routeHandlers[id];
87
+ const handler = await importModule(handlerPath, config.rootDir, path.join(config.cacheDir, 'routeHandlers'));
88
+ routeHandlers[id] = handler;
89
+ }));
90
+ return routeHandlers;
91
+ }
92
+ //# sourceMappingURL=modules.js.map
@@ -1,12 +1,19 @@
1
- import { ServerModeConfig } from '@lwrjs/types';
1
+ import type { ServerModeConfig, NormalizedLwrGlobalConfig, RuntimeEnvironment } from '@lwrjs/types';
2
2
  export declare const RUNTIME_CONFIGS: Record<string, ServerModeConfig>;
3
3
  /**
4
- * Get the runtime environment config for the mode.
4
+ * Get server mode config by name
5
5
  *
6
6
  * @throws {LwrServerError} Mode must be supported by LWR.
7
7
  *
8
- * @param {string} mode - the name of the server mode
9
- * @returns {ServerModeConfig} the runtime environment config for the mode
8
+ * @param {string} serverMode - the name of the server mode
9
+ * @returns {ServerModeConfig} the server mode config
10
10
  */
11
- export declare function getServerModeConfig(mode: string): ServerModeConfig;
11
+ export declare function getServerModeConfig(serverMode: string): ServerModeConfig;
12
+ /**
13
+ * Get runtime environment
14
+ *
15
+ * @param {NormalizedLwrGlobalConfig} config - the normalized global config object
16
+ * @returns {RuntimeEnvironment} the complete runtime environment
17
+ */
18
+ export declare function getRuntimeEnvironment(config: NormalizedLwrGlobalConfig): RuntimeEnvironment;
12
19
  //# sourceMappingURL=runtime-config.d.ts.map
@@ -1,10 +1,12 @@
1
1
  import { createSingleDiagnosticError, descriptions, LwrServerError } from '@lwrjs/diagnostics';
2
+ import { getFeatureFlags } from '@lwrjs/shared-utils';
2
3
  export const RUNTIME_CONFIGS = {
3
4
  dev: {
4
5
  bundle: false,
5
6
  minify: false,
6
7
  format: 'esm',
7
8
  compat: '0',
9
+ debug: false,
8
10
  watchFiles: true,
9
11
  defaultLocale: 'en_US',
10
12
  hmrEnabled: true,
@@ -18,6 +20,7 @@ export const RUNTIME_CONFIGS = {
18
20
  minify: true,
19
21
  format: 'esm',
20
22
  compat: '0',
23
+ debug: false,
21
24
  watchFiles: false,
22
25
  defaultLocale: 'en_US',
23
26
  hmrEnabled: false,
@@ -31,6 +34,7 @@ export const RUNTIME_CONFIGS = {
31
34
  minify: false,
32
35
  format: 'amd',
33
36
  compat: '1',
37
+ debug: false,
34
38
  watchFiles: true,
35
39
  defaultLocale: 'en_US',
36
40
  hmrEnabled: false,
@@ -44,6 +48,7 @@ export const RUNTIME_CONFIGS = {
44
48
  minify: true,
45
49
  format: 'amd',
46
50
  compat: '1',
51
+ debug: false,
47
52
  watchFiles: false,
48
53
  defaultLocale: 'en_US',
49
54
  hmrEnabled: false,
@@ -54,18 +59,37 @@ export const RUNTIME_CONFIGS = {
54
59
  },
55
60
  };
56
61
  /**
57
- * Get the runtime environment config for the mode.
62
+ * Get server mode config by name
58
63
  *
59
64
  * @throws {LwrServerError} Mode must be supported by LWR.
60
65
  *
61
- * @param {string} mode - the name of the server mode
62
- * @returns {ServerModeConfig} the runtime environment config for the mode
66
+ * @param {string} serverMode - the name of the server mode
67
+ * @returns {ServerModeConfig} the server mode config
63
68
  */
64
- export function getServerModeConfig(mode) {
65
- const selectedMode = RUNTIME_CONFIGS[mode];
69
+ export function getServerModeConfig(serverMode) {
70
+ const selectedMode = RUNTIME_CONFIGS[serverMode];
66
71
  if (!selectedMode) {
67
- throw createSingleDiagnosticError({ description: descriptions.SERVER.INVALID_MODE(mode) }, LwrServerError);
72
+ throw createSingleDiagnosticError({ description: descriptions.SERVER.INVALID_MODE(serverMode) }, LwrServerError);
68
73
  }
69
74
  return selectedMode;
70
75
  }
76
+ /**
77
+ * Get runtime environment
78
+ *
79
+ * @param {NormalizedLwrGlobalConfig} config - the normalized global config object
80
+ * @returns {RuntimeEnvironment} the complete runtime environment
81
+ */
82
+ export function getRuntimeEnvironment(config) {
83
+ const { serverMode, lwrVersion, apiVersion, basePath, minify } = config;
84
+ const serverModeConfig = getServerModeConfig(config.serverMode);
85
+ return {
86
+ ...serverModeConfig,
87
+ minify: minify !== null ? minify : serverModeConfig.minify,
88
+ featureFlags: getFeatureFlags(),
89
+ serverMode,
90
+ lwrVersion,
91
+ apiVersion,
92
+ basePath,
93
+ };
94
+ }
71
95
  //# sourceMappingURL=runtime-config.js.map
@@ -0,0 +1,3 @@
1
+ import { GlobalData } from '@lwrjs/types';
2
+ export declare function getGlobalData(globalDataDir: string, defaultData?: GlobalData): GlobalData;
3
+ //# sourceMappingURL=global-data.d.ts.map
@@ -0,0 +1,29 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
+ function recursiveJsonCollector(resources, currentPath, collector) {
5
+ for (const resource of resources) {
6
+ const resourcePath = path.join(currentPath, resource);
7
+ if (resource.endsWith('.json')) {
8
+ const resourceName = path.basename(resource, '.json');
9
+ const jsonSource = JSON.parse(fs.readFileSync(resourcePath, 'utf-8'));
10
+ collector[resourceName] = jsonSource;
11
+ }
12
+ else if (fs.statSync(resourcePath).isDirectory()) {
13
+ const dirContentList = fs.readdirSync(resourcePath);
14
+ collector[resource] = recursiveJsonCollector(dirContentList, resourcePath, {});
15
+ }
16
+ }
17
+ return collector;
18
+ }
19
+ export function getGlobalData(globalDataDir, defaultData = {}) {
20
+ if (!fs.existsSync(globalDataDir) || !fs.statSync(globalDataDir).isDirectory()) {
21
+ return defaultData;
22
+ }
23
+ const dirContentList = fs.readdirSync(globalDataDir);
24
+ return {
25
+ ...recursiveJsonCollector(dirContentList, globalDataDir, {}),
26
+ ...defaultData,
27
+ };
28
+ }
29
+ //# sourceMappingURL=global-data.js.map
@@ -1,7 +1,7 @@
1
1
  import type { BundleConfig, LwcConfig, LwrGlobalConfig, LwrLockerConfig, StaticSiteGenerator } from '@lwrjs/types';
2
2
  export declare function trimLwrConfig(config: LwrGlobalConfig): LwrGlobalConfig;
3
3
  export declare function mergeLwcConfig(config1: LwrGlobalConfig | undefined, config2: LwrGlobalConfig | undefined): LwcConfig;
4
- export declare function mergeBundleConfig(jsonConfig: LwrGlobalConfig | undefined, config: LwrGlobalConfig | undefined): BundleConfig;
4
+ export declare function mergeBundleConfig(config1: LwrGlobalConfig | undefined, config2: LwrGlobalConfig | undefined): BundleConfig;
5
5
  export declare function mergeLockerConfig(jsonConfig: LwrGlobalConfig | undefined, config: LwrGlobalConfig | undefined): LwrLockerConfig;
6
6
  export declare function mergeStaticGenerationConfig(configFile?: LwrGlobalConfig, configArg?: LwrGlobalConfig): StaticSiteGenerator;
7
7
  //# sourceMappingURL=merge.d.ts.map
@@ -1,5 +1,8 @@
1
1
  import { DEFAULT_LOCKER_TRUSTED_CMP, DEFAULT_LWR_LOCKER_CONFIG } from '@lwrjs/shared-utils';
2
- import { DEFAULT_BUNDLE_EXCLUSIONS, DEFAULT_GENERATOR_CONFIG, DEFAULT_LWR_MODULES } from '../defaults.js';
2
+ import { getDefaultBundleConfig, DEFAULT_GENERATOR_CONFIG, DEFAULT_LWR_MODULES } from '../defaults.js';
3
+ function isNormalizedLwrGlobalConfig(config) {
4
+ return config?.lwrVersion !== undefined;
5
+ }
3
6
  export function trimLwrConfig(config) {
4
7
  Object.keys(config).forEach((k) => {
5
8
  if (config[k] === undefined)
@@ -9,6 +12,10 @@ export function trimLwrConfig(config) {
9
12
  }
10
13
  // deep merge LWC configs
11
14
  export function mergeLwcConfig(config1, config2) {
15
+ // normalized config already contains the defaults
16
+ const defaultModules = !isNormalizedLwrGlobalConfig(config1) && !isNormalizedLwrGlobalConfig(config2)
17
+ ? DEFAULT_LWR_MODULES
18
+ : [];
12
19
  const modules1 = config1?.lwc?.modules || [];
13
20
  const modules2 = config2?.lwc?.modules || [];
14
21
  const interchangeable1 = config1?.lwc?.interchangeable || [];
@@ -18,7 +25,7 @@ export function mergeLwcConfig(config1, config2) {
18
25
  const interchangeableModules2 = config2?.lwc?.interchangeableModules || [];
19
26
  const mergedInterchangeableModules = [...interchangeableModules1, ...interchangeableModules2];
20
27
  return {
21
- modules: [...DEFAULT_LWR_MODULES, ...modules1, ...modules2],
28
+ modules: [...defaultModules, ...modules1, ...modules2],
22
29
  interchangeable: mergedInterchangeable.length ? mergedInterchangeable : undefined,
23
30
  interchangeableModules: mergedInterchangeableModules.length
24
31
  ? mergedInterchangeableModules
@@ -26,15 +33,21 @@ export function mergeLwcConfig(config1, config2) {
26
33
  };
27
34
  }
28
35
  // merge default bundle exclusions with any bundle exclusions specified in config
29
- export function mergeBundleConfig(jsonConfig, config) {
30
- const defaultExclusions = config?.bundleConfig?.UNSAFE_lwrDefaultExclude ||
31
- jsonConfig?.bundleConfig?.UNSAFE_lwrDefaultExclude ||
32
- DEFAULT_BUNDLE_EXCLUSIONS;
33
- const configExclusions = config?.bundleConfig?.exclude || jsonConfig?.bundleConfig?.exclude || [];
36
+ export function mergeBundleConfig(config1, config2) {
37
+ const mode = config2?.serverMode || config1?.serverMode;
38
+ const DEFAULT_BUNDLE_CONFIG = getDefaultBundleConfig(mode);
39
+ const defaultExclusions = config2?.bundleConfig?.UNSAFE_lwrDefaultExclude ||
40
+ config1?.bundleConfig?.UNSAFE_lwrDefaultExclude ||
41
+ DEFAULT_BUNDLE_CONFIG.exclude ||
42
+ [];
43
+ const configExclusions = config2?.bundleConfig?.exclude || config1?.bundleConfig?.exclude || [];
44
+ const configExternals = config2?.bundleConfig?.external || config1?.bundleConfig?.external || {};
34
45
  return {
35
- ...jsonConfig?.bundleConfig,
36
- ...config?.bundleConfig,
46
+ ...config1?.bundleConfig,
47
+ ...config2?.bundleConfig,
37
48
  exclude: [...new Set([...defaultExclusions, ...configExclusions])],
49
+ // Merge default externals with configured externals
50
+ external: { ...DEFAULT_BUNDLE_CONFIG.external, ...configExternals },
38
51
  };
39
52
  }
40
53
  // merge default locker trusted namespaces/cmps with any trusted namespaces/cmps specified in config
@@ -49,10 +62,16 @@ export function mergeLockerConfig(jsonConfig, config) {
49
62
  };
50
63
  }
51
64
  export function mergeStaticGenerationConfig(configFile, configArg) {
65
+ const fileAdditionalModules = configFile?.staticSiteGenerator?._additionalModules || [];
66
+ const argAdditionalModules = configArg?.staticSiteGenerator?._additionalModules || [];
67
+ const fileAdditionalPaths = configFile?.staticSiteGenerator?._additionalRoutePaths || [];
68
+ const argAdditionalPaths = configArg?.staticSiteGenerator?._additionalRoutePaths || [];
52
69
  return {
53
70
  ...DEFAULT_GENERATOR_CONFIG,
54
71
  ...configFile?.staticSiteGenerator,
55
72
  ...configArg?.staticSiteGenerator,
73
+ _additionalModules: [...new Set([...fileAdditionalModules, ...argAdditionalModules])],
74
+ _additionalRoutePaths: [...new Set([...fileAdditionalPaths, ...argAdditionalPaths])],
56
75
  };
57
76
  }
58
77
  //# sourceMappingURL=merge.js.map
@@ -1,7 +1,8 @@
1
- import type { LwrErrorRoute, LwrRoute, NormalizedLwrErrorRoute, NormalizedLwrRoute, ResourcePaths } from '@lwrjs/types';
1
+ import type { LwrErrorRoute, LwrRoute, NormalizedLwrErrorRoute, NormalizedLwrRoute, ResourcePaths, RouteHandlersConfig } from '@lwrjs/types';
2
2
  declare type ViewOrErrorRoute = LwrRoute | LwrErrorRoute;
3
3
  declare type NormalizedRoute<T extends ViewOrErrorRoute> = T extends LwrRoute ? NormalizedLwrRoute : NormalizedLwrErrorRoute;
4
- export declare function normalizeRoutes<T extends ViewOrErrorRoute>(routes?: T[]): NormalizedRoute<T>[];
4
+ export declare function normalizeRoutes<T extends ViewOrErrorRoute>(routes: T[], routeHandlers: RouteHandlersConfig): NormalizedRoute<T>[];
5
5
  export declare function normalizeRoutePaths<T extends ViewOrErrorRoute>(routes: T[] | undefined, resourcePaths: ResourcePaths): NormalizedRoute<T>[];
6
+ export declare function normalizeRouteHandlerPaths(routeHandlers: RouteHandlersConfig, resourcePaths: ResourcePaths): RouteHandlersConfig;
6
7
  export {};
7
8
  //# sourceMappingURL=routes.d.ts.map
@@ -1,25 +1,42 @@
1
1
  import path from 'path';
2
2
  import { DEFAULT_LWR_BOOTSTRAP_CONFIG, normalizeDirectory, normalizeResourcePath } from '@lwrjs/shared-utils';
3
- export function normalizeRoutes(routes = []) {
4
- return routes.map((route) => ({
5
- ...route,
6
- bootstrap: {
7
- ...DEFAULT_LWR_BOOTSTRAP_CONFIG,
8
- ...route.bootstrap,
9
- },
10
- }));
3
+ export function normalizeRoutes(routes, routeHandlers) {
4
+ return routes.map((route) => {
5
+ // when a route handler is set, ensure it is set in the route handler config
6
+ if (route.routeHandler && !routeHandlers[route.routeHandler]) {
7
+ const handlerPath = route.routeHandler;
8
+ // the non-normalized path to the handler will be the id used when invoking the route handler
9
+ routeHandlers[handlerPath] = handlerPath;
10
+ }
11
+ return {
12
+ ...route,
13
+ bootstrap: {
14
+ ...DEFAULT_LWR_BOOTSTRAP_CONFIG,
15
+ ...route.bootstrap,
16
+ },
17
+ };
18
+ });
11
19
  }
12
20
  export function normalizeRoutePaths(routes = [], resourcePaths) {
13
21
  return routes.map((route) => {
14
- const { routeHandler, contentTemplate, layoutTemplate, subRoutes } = route;
15
- route.routeHandler =
16
- routeHandler && path.resolve(normalizeDirectory(routeHandler, resourcePaths.rootDir));
17
- route.contentTemplate =
18
- contentTemplate && path.resolve(normalizeResourcePath(contentTemplate, resourcePaths));
19
- route.layoutTemplate =
20
- layoutTemplate && path.resolve(normalizeResourcePath(layoutTemplate, resourcePaths));
21
- route.subRoutes = subRoutes && path.resolve(normalizeResourcePath(subRoutes, resourcePaths));
22
+ // route handler paths are NOT normalized here to maintain the id lookup for route handler invocation
23
+ const { contentTemplate, layoutTemplate, subRoutes } = route;
24
+ if (contentTemplate) {
25
+ route.contentTemplate = path.resolve(normalizeResourcePath(contentTemplate, resourcePaths));
26
+ }
27
+ if (layoutTemplate) {
28
+ route.layoutTemplate = path.resolve(normalizeResourcePath(layoutTemplate, resourcePaths));
29
+ }
30
+ if (subRoutes) {
31
+ route.subRoutes = path.resolve(normalizeResourcePath(subRoutes, resourcePaths));
32
+ }
22
33
  return route;
23
34
  });
24
35
  }
36
+ export function normalizeRouteHandlerPaths(routeHandlers, resourcePaths) {
37
+ for (const [id, handlerPath] of Object.entries(routeHandlers)) {
38
+ routeHandlers[id] = path.resolve(normalizeDirectory(handlerPath, resourcePaths.rootDir));
39
+ }
40
+ return routeHandlers;
41
+ }
25
42
  //# sourceMappingURL=routes.js.map
@@ -1,4 +1,4 @@
1
- import { AssetDirConfig, AssetFileConfig, LwrErrorRoute, LwrRoute, NormalizedLwrGlobalConfig, NormalizedLwrAppBootstrapConfig, LwrLockerConfig } from '@lwrjs/types';
1
+ import { AssetDirConfig, AssetFileConfig, LwrErrorRoute, LwrRoute, NormalizedLwrGlobalConfig, NormalizedLwrAppBootstrapConfig, LwrLockerConfig, RouteHandlersConfig } from '@lwrjs/types';
2
2
  import { Node } from 'jsonc-parser';
3
3
  import { Diagnostic } from '@lwrjs/diagnostics';
4
4
  declare type RequiredAssetDirConfig = Required<AssetDirConfig>;
@@ -12,16 +12,17 @@ interface ConfigMap {
12
12
  assetFile: RequiredAssetFileConfig;
13
13
  routes: RequiredLwrRoute;
14
14
  errorRoutes: RequiredLwrErrorRoute;
15
+ routeHandlers: RouteHandlersConfig;
15
16
  bootstrap: NormalizedLwrAppBootstrapConfig;
16
17
  locker: RequiredLwrLockerConfig;
17
18
  }
18
- export declare const ROOT_ATTRIBUTE_KEYS: ["amdLoader", "apiVersion", "assets", "assetProviders", "assetTransformers", "bundleConfig", "cacheDir", "contentDir", "environment", "errorRoutes", "esmLoader", "staticSiteGenerator", "globalData", "globalDataDir", "hooks", "ignoreLwrConfigFile", "lwrConfigFile", "layoutsDir", "locker", "lwc", "lwrVersion", "moduleProviders", "port", "basePath", "resourceProviders", "rootDir", "routes", "serverMode", "serverType", "templateEngine", "viewProviders", "viewTransformers"];
19
+ export declare const ROOT_ATTRIBUTE_KEYS: ["amdLoader", "apiVersion", "assets", "assetProviders", "assetTransformers", "bundleConfig", "bundleProviders", "cacheDir", "contentDir", "environment", "errorRoutes", "esmLoader", "staticSiteGenerator", "globalData", "globalDataDir", "hooks", "ignoreLwrConfigFile", "lwrConfigFile", "layoutsDir", "locker", "lwc", "lwrVersion", "moduleProviders", "port", "basePath", "resourceProviders", "rootDir", "routeHandlers", "routes", "serverMode", "minify", "serverType", "viewProviders", "viewTransformers"];
19
20
  export declare const ASSET_DIR_ATTRIBUTE_KEYS: ["alias", "dir", "urlPath"];
20
21
  export declare const ASSET_FILE_ATTRIBUTE_KEYS: ["alias", "file", "urlPath"];
21
22
  export declare const LOCKER_ATTRIBUTE_KEYS: ["enabled", "trustedComponents", "clientOnly"];
22
23
  export declare const ROUTE_ATTRIBUTE_KEYS: ["bootstrap", "subRoutes", "contentTemplate", "id", "cache", "layoutTemplate", "method", "path", "rootComponent", "routeHandler", "properties"];
23
24
  export declare const ERROR_ROUTE_ATTRIBUTE_KEYS: ["bootstrap", "subRoutes", "contentTemplate", "id", "layoutTemplate", "rootComponent", "routeHandler", "status", "properties", "cache"];
24
- export declare const BOOTSTRAP_ATTRIBUTE_KEYS: ["autoBoot", "syntheticShadow", "workers", "services", "configAsSrc", "ssr"];
25
+ export declare const BOOTSTRAP_ATTRIBUTE_KEYS: ["autoBoot", "syntheticShadow", "workers", "services", "configAsSrc", "ssr", "module", "preloadModules"];
25
26
  export declare const BASE_PATH_REGEX: RegExp;
26
27
  export declare class ValidationContext {
27
28
  diagnostics: Diagnostic[];
@@ -13,6 +13,7 @@ export const ROOT_ATTRIBUTE_KEYS = createKeys('root', [
13
13
  'assetProviders',
14
14
  'assetTransformers',
15
15
  'bundleConfig',
16
+ 'bundleProviders',
16
17
  'cacheDir',
17
18
  'contentDir',
18
19
  'environment',
@@ -33,10 +34,11 @@ export const ROOT_ATTRIBUTE_KEYS = createKeys('root', [
33
34
  'basePath',
34
35
  'resourceProviders',
35
36
  'rootDir',
37
+ 'routeHandlers',
36
38
  'routes',
37
39
  'serverMode',
40
+ 'minify',
38
41
  'serverType',
39
- 'templateEngine',
40
42
  'viewProviders',
41
43
  'viewTransformers',
42
44
  ]);
@@ -75,6 +77,8 @@ export const BOOTSTRAP_ATTRIBUTE_KEYS = createKeys('bootstrap', [
75
77
  'services',
76
78
  'configAsSrc',
77
79
  'ssr',
80
+ 'module',
81
+ 'preloadModules',
78
82
  ]);
79
83
  const SPECIFIER_REGEX = /^@?[\w-]+(\/[\w-]+)*$/;
80
84
  function isNotEmptyString(node) {
@@ -13,16 +13,20 @@ export const SOURCE_BY_PHASE = {
13
13
  * - autoBoot: optional boolean
14
14
  * - syntheticShadow: optional boolean
15
15
  * - workers: optional map of string:specifier pairs
16
+ * - ssr: optional boolean
16
17
  * - configAsSrc: optional boolean to include the client bootstrap config as src via in-lined
18
+ * - module: optional string specifier
17
19
  */
18
20
  function validateBootstrap(node, validationContext, propPrefix) {
19
21
  if (node) {
20
22
  validationContext.assertIsObject(node, 'bootstrap');
21
23
  validationContext.assertValidKeys(node, 'bootstrap', BOOTSTRAP_ATTRIBUTE_KEYS);
22
24
  validationContext.assertArrayOfSpecifiers(findNode(node, ['services']), `${propPrefix}.services`);
25
+ validationContext.assertArrayOfSpecifiers(findNode(node, ['preloadModules']), `${propPrefix}.preloadModules`);
23
26
  validationContext.assertIsBoolean(findNode(node, ['autoBoot']), `${propPrefix}.autoBoot`);
24
27
  validationContext.assertIsBoolean(findNode(node, ['ssr']), `${propPrefix}.ssr`);
25
28
  validationContext.assertIsBoolean(findNode(node, ['configAsSrc']), `${propPrefix}.configAsSrc`);
29
+ validationContext.assertIsSpecifier(findNode(node, ['module']), `${propPrefix}.module`);
26
30
  validationContext.assertIsBoolean(findNode(node, ['syntheticShadow']), `${propPrefix}.syntheticShadow`);
27
31
  // Each value in the worker map msut be a specifier
28
32
  const workers = findNode(node, ['workers']);
@@ -68,9 +72,14 @@ function validateRouteCommon(node, validationContext, propPrefix) {
68
72
  * - path: required path segment string
69
73
  * - method: optional 'get' | 'post'
70
74
  */
71
- function validateRoutes(node, validationContext) {
75
+ function validateRoutes(node, validationContext, preMerge) {
72
76
  if (node) {
73
- validationContext.assertNotEmptyArray(node, 'routes');
77
+ // routes may not be defined until after config hooks are applied
78
+ // note: there are 2 "post" hooks (onConfig/onStart) that routes can be applied.
79
+ // We need to ensure that we only validate after the last one (if both are used)
80
+ if (!preMerge) {
81
+ validationContext.assertNotEmptyArray(node, 'routes');
82
+ }
74
83
  if (node.children) {
75
84
  node.children.forEach((n, index) => {
76
85
  const propPrefix = `routes[${index}]`;
@@ -103,6 +112,11 @@ function validateErrorRoutes(node, validationContext) {
103
112
  }
104
113
  }
105
114
  }
115
+ function validateRouteHandlers(node, validationContext) {
116
+ if (node) {
117
+ validationContext.assertIsObject(node, 'routeHandlers');
118
+ }
119
+ }
106
120
  /**
107
121
  * Check string config.asset OR
108
122
  * Check array config.assets[]:
@@ -174,7 +188,7 @@ function validateLocker(node, validationContext) {
174
188
  * - serverType: string
175
189
  * - rootDir, cacheDir, contentDir, layoutsDir, globalDataDir: strings
176
190
  * - hooks: array of strings
177
- * - templateEngine: string
191
+ * - bundleProviders: array of services
178
192
  * - moduleProviders: array of services
179
193
  * - viewProviders: array of services
180
194
  * - resourceProviders: array of services
@@ -192,8 +206,9 @@ function validateRoot(node, validationContext, preMerge) {
192
206
  const routes = findNode(node, ['routes']);
193
207
  const errorRoutes = findNode(node, ['errorRoutes']);
194
208
  validationContext.assertUniqueIds([...(routes?.children || []), ...(errorRoutes?.children || [])], 'routes');
195
- validateRoutes(routes, validationContext);
209
+ validateRoutes(routes, validationContext, preMerge);
196
210
  validateErrorRoutes(errorRoutes, validationContext);
211
+ validateRouteHandlers(findNode(node, ['routeHandlers']), validationContext);
197
212
  validateAssets(findNode(node, ['assets']), validationContext, preMerge);
198
213
  validateLocker(findNode(node, ['locker']), validationContext);
199
214
  validationContext.assertNotEmptyString(findNode(node, ['apiVersion']), 'apiVersion');
@@ -210,7 +225,7 @@ function validateRoot(node, validationContext, preMerge) {
210
225
  validationContext.assertNotEmptyString(findNode(node, ['layoutsDir']), 'layoutsDir');
211
226
  validationContext.assertNotEmptyString(findNode(node, ['globalDataDir']), 'globalDataDir');
212
227
  validationContext.assertArrayOfServices(findNode(node, ['hooks']), 'hooks');
213
- validationContext.assertNotEmptyString(findNode(node, ['templateEngine']), 'templateEngine');
228
+ validationContext.assertArrayOfServices(findNode(node, ['bundleProviders']), 'bundleProviders');
214
229
  validationContext.assertArrayOfServices(findNode(node, ['moduleProviders']), 'moduleProviders');
215
230
  validationContext.assertArrayOfServices(findNode(node, ['viewProviders']), 'viewProviders');
216
231
  validationContext.assertArrayOfServices(findNode(node, ['resourceProviders']), 'resourceProviders');
package/package.cjs CHANGED
@@ -1,9 +1,28 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const resolve = require('resolve');
3
4
  const rootPath = path.join(__dirname, './');
4
- const version = JSON.parse(fs.readFileSync(path.join(rootPath, 'package.json'), 'utf-8')).version;
5
+
6
+ // Get the LWR Version
7
+ let version;
8
+ if (globalThis.LWR_VERSION) {
9
+ version = globalThis.LWR_VERSION;
10
+ } else {
11
+ version = JSON.parse(fs.readFileSync(path.join(rootPath, 'package.json'), 'utf-8')).version;
12
+ }
13
+
14
+ // Get the LWC Version
15
+ let lwcVersion;
16
+ if (globalThis.LWC_VERSION) {
17
+ version = globalThis.LWC_VERSION;
18
+ } else {
19
+ const packageJsonPath = resolve.sync(`lwc/package.json`);
20
+ const { version: packageVersion } = JSON.parse(fs.readFileSync(packageJsonPath), 'utf-8');
21
+ lwcVersion = packageVersion;
22
+ }
5
23
 
6
24
  module.exports = {
7
25
  rootPath,
8
- version
26
+ version,
27
+ lwcVersion
9
28
  };
package/package.json CHANGED
@@ -4,15 +4,15 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.9.0-alpha.9",
7
+ "version": "0.9.0",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://github.com/salesforce/lwr.git",
11
+ "url": "https://github.com/salesforce-experience-platform-emu/lwr.git",
12
12
  "directory": "packages/@lwrjs/config"
13
13
  },
14
14
  "bugs": {
15
- "url": "https://github.com/salesforce/lwr/issues"
15
+ "url": "https://github.com/salesforce-experience-platform-emu/lwr/issues"
16
16
  },
17
17
  "type": "module",
18
18
  "types": "build/es/index.d.ts",
@@ -23,6 +23,10 @@
23
23
  "import": "./build/es/index.js",
24
24
  "require": "./build/cjs/index.cjs"
25
25
  },
26
+ "./modules": {
27
+ "import": "./build/es/modules.js",
28
+ "require": "./build/cjs/modules.cjs"
29
+ },
26
30
  "./package": "./package.cjs"
27
31
  },
28
32
  "files": [
@@ -32,16 +36,19 @@
32
36
  "package.cjs"
33
37
  ],
34
38
  "dependencies": {
35
- "@lwrjs/diagnostics": "0.9.0-alpha.9",
36
- "@lwrjs/shared-utils": "0.9.0-alpha.9",
37
- "fs-extra": "^10.1.0",
39
+ "@lwrjs/diagnostics": "0.9.0",
40
+ "@lwrjs/shared-utils": "0.9.0",
41
+ "fs-extra": "^11.1.0",
38
42
  "jsonc-parser": "^3.0.0"
39
43
  },
40
44
  "devDependencies": {
41
- "@lwrjs/types": "0.9.0-alpha.9"
45
+ "@lwrjs/types": "0.9.0"
46
+ },
47
+ "peerDependencies": {
48
+ "lwc": "2.x"
42
49
  },
43
50
  "engines": {
44
- "node": ">=14.15.4 <19"
51
+ "node": ">=16.0.0 <20"
45
52
  },
46
- "gitHead": "93522592d25375bb20da156f864d153ffcd3ec88"
53
+ "gitHead": "4e42b0dc5453f92b36b42aa8132c5bc281e616b7"
47
54
  }