@lwrjs/shared-utils 0.11.0-alpha.0 → 0.11.0-alpha.10

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/build/cjs/env.cjs CHANGED
@@ -8,6 +8,7 @@ var __export = (target, all) => {
8
8
  // packages/@lwrjs/shared-utils/src/env.ts
9
9
  __markAsModule(exports);
10
10
  __export(exports, {
11
+ buildEnvironmentContext: () => buildEnvironmentContext,
11
12
  getFeatureFlags: () => getFeatureFlags
12
13
  });
13
14
  function getFeatureFlags() {
@@ -16,7 +17,20 @@ function getFeatureFlags() {
16
17
  LEGACY_LOADER: process.env.LEGACY_LOADER !== void 0 && process.env.LEGACY_LOADER.toLowerCase() === "true" ? true : false,
17
18
  SSR_SANDBOX_WORKER: process.env.SSR_SANDBOX_WORKER !== void 0 && process.env.SSR_SANDBOX_WORKER.toLowerCase() === "true" ? true : false,
18
19
  SSR_STATIC_BUNDLES: process.env.SSR_STATIC_BUNDLES !== void 0 && process.env.SSR_STATIC_BUNDLES.toLowerCase() === "true" ? true : false,
20
+ SSR_WITH_CSR_FALLBACK: process.env.SSR_WITH_CSR_FALLBACK !== void 0 && process.env.SSR_WITH_CSR_FALLBACK.toLowerCase() === "true" ? true : false,
19
21
  EXPERIMENTAL_UNVERSIONED_ALIASES: process.env.EXPERIMENTAL_UNVERSIONED_ALIASES !== void 0 && process.env.EXPERIMENTAL_UNVERSIONED_ALIASES.toLowerCase() === "true" ? true : false,
20
22
  LWR_TRACING: process.env.LWR_TRACING !== void 0 && process.env.LWR_TRACING.toLowerCase() !== "off" ? true : false
21
23
  };
22
24
  }
25
+ function buildEnvironmentContext(runtimeParams) {
26
+ const basePath = runtimeParams.basePath;
27
+ const locale = runtimeParams.locale;
28
+ const assetBasePath = runtimeParams.assetBasePath;
29
+ const uiBasePath = runtimeParams.uiBasePath;
30
+ return {
31
+ basePath,
32
+ locale,
33
+ assetBasePath,
34
+ uiBasePath
35
+ };
36
+ }
@@ -28,7 +28,7 @@ __export(exports, {
28
28
  });
29
29
  var import_chokidar = __toModule(require("chokidar"));
30
30
  var import_object = __toModule(require("./object.cjs"));
31
- var import_logger = __toModule(require("./logger.cjs"));
31
+ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
32
32
  var WatcherFactoryImpl = class {
33
33
  createFileWatcher(options = {persistent: true, ignored: "**/node_modules/**"}) {
34
34
  return import_chokidar.default.watch([], options);
@@ -37,7 +37,7 @@ var WatcherFactoryImpl = class {
37
37
  const fileWatcher = this.createFileWatcher();
38
38
  fileWatcher.on("change", (0, import_object.debounce)((file) => onModuleChange(file), 500));
39
39
  fileWatcher.on("unlink", (0, import_object.debounce)((file) => onModuleChange(file), 500));
40
- fileWatcher.on("add", (file) => import_logger.logger.info(`Watching: ${file}`));
40
+ fileWatcher.on("add", (file) => import_diagnostics.logger.info(`Watching: ${file}`));
41
41
  return fileWatcher;
42
42
  }
43
43
  };
package/build/cjs/fs.cjs CHANGED
@@ -43,7 +43,7 @@ var import_identity = __toModule(require("./identity.cjs"));
43
43
  var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
44
44
  var import_mime_types = __toModule(require("mime-types"));
45
45
  var import_stream = __toModule(require("stream"));
46
- var import_logger = __toModule(require("./logger.cjs"));
46
+ var import_diagnostics2 = __toModule(require("@lwrjs/diagnostics"));
47
47
  var fileCount = 0;
48
48
  var files = new Map();
49
49
  function hashContent(source) {
@@ -75,6 +75,9 @@ function resolveFileExtension(filePath) {
75
75
  }
76
76
  }
77
77
  function canResolveView(source, type) {
78
+ if (typeof source !== "string") {
79
+ return false;
80
+ }
78
81
  if (!source.endsWith(`.${type}`)) {
79
82
  return false;
80
83
  }
@@ -119,14 +122,14 @@ function normalizeResourcePath(rawPath, {rootDir, assets, contentDir, layoutsDir
119
122
  });
120
123
  }
121
124
  function logMetrics(filePath) {
122
- if (import_logger.logger.currentLevel == import_logger.DEBUG || import_logger.logger.currentLevel == import_logger.VERBOSE) {
125
+ if (import_diagnostics2.logger.currentLevel == import_diagnostics2.DEBUG || import_diagnostics2.logger.currentLevel == import_diagnostics2.VERBOSE) {
123
126
  let count = files.get(filePath) || 0;
124
127
  if (++count % 100 === 0) {
125
- import_logger.logger.debug(`[${count}] Repeat Read ${filePath}`);
128
+ import_diagnostics2.logger.debug(`[${count}] Repeat Read ${filePath}`);
126
129
  }
127
130
  files.set(filePath, count);
128
131
  if (++fileCount % 1e3 === 0) {
129
- import_logger.logger.debug(`Open file count [${fileCount}]`);
132
+ import_diagnostics2.logger.debug(`Open file count [${fileCount}]`);
130
133
  }
131
134
  }
132
135
  }
@@ -105,7 +105,7 @@ async function flatten(versionedSpecifier, flattened, idx, visited) {
105
105
  }
106
106
  async function getModuleGraphs(specifier, options, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visited) {
107
107
  const acc = visited || new Map();
108
- const versionedModuleId = await (0, import_identity.getVersionedModuleId)(specifier, moduleRegistry);
108
+ const versionedModuleId = await (0, import_identity.getVersionedModuleId)(specifier, moduleRegistry, runtimeParams);
109
109
  const depth = options.depth || {
110
110
  static: GraphDepth.DIRECT,
111
111
  dynamic: 1
@@ -121,7 +121,7 @@ async function getModuleGraphs(specifier, options, moduleRegistry, defRegistry,
121
121
  const uriMap = {};
122
122
  if (options.includeUris) {
123
123
  for (const visitedSpecifier of acc.keys()) {
124
- const moduleId = await (0, import_identity.getVersionedModuleId)(visitedSpecifier, moduleRegistry);
124
+ const moduleId = await (0, import_identity.getVersionedModuleId)(visitedSpecifier, moduleRegistry, runtimeParams);
125
125
  const uri = await defRegistry.resolveModuleUri(moduleId, runtimeEnvironment, runtimeParams);
126
126
  uriMap[visitedSpecifier] = uri;
127
127
  }
@@ -129,7 +129,7 @@ async function getModuleGraphs(specifier, options, moduleRegistry, defRegistry,
129
129
  const linkedDefinitions = {};
130
130
  if (options.includeLinkedDefinitions) {
131
131
  for (const visitedSpecifier of acc.keys()) {
132
- const versionedModuleId2 = await (0, import_identity.getVersionedModuleId)(visitedSpecifier, moduleRegistry);
132
+ const versionedModuleId2 = await (0, import_identity.getVersionedModuleId)(visitedSpecifier, moduleRegistry, runtimeParams);
133
133
  const module2 = isBundler(defRegistry) ? await defRegistry.getModuleBundle(versionedModuleId2, runtimeEnvironment, runtimeParams) : await defRegistry.getLinkedModule(versionedModuleId2, runtimeEnvironment, runtimeParams);
134
134
  linkedDefinitions[visitedSpecifier] = module2;
135
135
  }
@@ -61,13 +61,16 @@ function isSelfUrl(url) {
61
61
  return !url || !!url.match(isSelfUrlRegex);
62
62
  }
63
63
  var isSelfUrlRegex = /^\s*(data:|#)/i;
64
- async function extractMetadataFromHtml(htmlSource) {
64
+ function hasHydrationDirective(attrs = {}) {
65
+ return Object.keys(attrs).some((attr) => attr === HYDRATE_DIRECTIVE);
66
+ }
67
+ async function extractMetadataFromHtml(htmlSource, viewMetadata) {
68
+ const {customElements, assetReferences, serverData} = viewMetadata;
65
69
  return new Promise((resolve, reject) => {
66
- const customElements = [];
67
70
  const openElements = new Set();
68
- const assetReferences = [];
69
71
  const parser = new import_parse5_sax_parser.default({sourceCodeLocationInfo: true});
70
72
  const ceRefStack = [];
73
+ let nestedIslands = false;
71
74
  parser.on("startTag", ({
72
75
  tagName,
73
76
  attrs,
@@ -75,23 +78,23 @@ async function extractMetadataFromHtml(htmlSource) {
75
78
  }) => {
76
79
  if (tagName.includes("-") && !openElements.has(tagName)) {
77
80
  const {startOffset, endOffset} = sourceCodeLocation;
78
- const ceRef = {
79
- tagName,
80
- location: {startOffset, endOffset},
81
- props: attrs.length ? attrs.reduce((obj, {name, value}) => {
82
- obj[(0, import_identity.getPropFromAttrName)(name)] = value === "" ? "true" : value;
83
- return obj;
84
- }, {}) : void 0
85
- };
81
+ const props = attrs.length ? attrs.reduce((obj, {name, value}) => {
82
+ obj[(0, import_identity.getPropFromAttrName)(name)] = value === "" ? "true" : value;
83
+ return obj;
84
+ }, {}) : void 0;
85
+ const ceRef = {tagName, location: {startOffset, endOffset}, props};
86
86
  openElements.add(tagName);
87
87
  if (ceRefStack.length) {
88
88
  const last = ceRefStack[ceRefStack.length - 1];
89
89
  last.children = last.children ? [...last.children, ceRef] : [ceRef];
90
- ceRefStack.push(ceRef);
90
+ if (hasHydrationDirective(props)) {
91
+ customElements.push(ceRef);
92
+ nestedIslands = true;
93
+ }
91
94
  } else {
92
95
  customElements.push(ceRef);
93
- ceRefStack.push(ceRef);
94
96
  }
97
+ ceRefStack.push(ceRef);
95
98
  }
96
99
  if ((tagName === "img" || tagName === "script") && sourceCodeLocation.attrs) {
97
100
  if (sourceCodeLocation.attrs.src) {
@@ -118,7 +121,11 @@ async function extractMetadataFromHtml(htmlSource) {
118
121
  }
119
122
  });
120
123
  const inputStream = import_stream.Readable.from(htmlSource);
121
- inputStream.on("end", () => resolve({customElements, assetReferences}));
124
+ inputStream.on("end", () => resolve({
125
+ customElements: customElements.filter((ce) => !nestedIslands || hasHydrationDirective(ce.props)),
126
+ assetReferences,
127
+ serverData
128
+ }));
122
129
  inputStream.on("error", (error) => reject(error));
123
130
  inputStream.pipe(parser);
124
131
  });
@@ -47,13 +47,15 @@ __export(exports, {
47
47
  isAssetSourceExternal: () => isAssetSourceExternal,
48
48
  isBundleDefinition: () => isBundleDefinition,
49
49
  isExternalUrl: () => isExternalUrl,
50
+ isSpecifier: () => isSpecifier,
50
51
  kebabCaseToModuleSpecifier: () => kebabCaseToModuleSpecifier,
51
52
  moduleSpecifierToKebabCase: () => moduleSpecifierToKebabCase,
52
53
  normalizeVersionFromUri: () => normalizeVersionFromUri,
53
54
  normalizeVersionToUri: () => normalizeVersionToUri,
54
55
  parsePackageSpecifier: () => parsePackageSpecifier,
55
56
  prettyModuleUriSuffix: () => prettyModuleUriSuffix,
56
- slugify: () => slugify
57
+ slugify: () => slugify,
58
+ stringToVariableName: () => stringToVariableName
57
59
  });
58
60
  var import_slugify = __toModule(require("slugify"));
59
61
  var import_fast_json_stable_stringify = __toModule(require("fast-json-stable-stringify"));
@@ -78,6 +80,7 @@ var DEFAULT_LWR_BOOTSTRAP_CONFIG = {
78
80
  services: [],
79
81
  configAsSrc: false,
80
82
  ssr: false,
83
+ mixedMode: false,
81
84
  module: void 0,
82
85
  preloadModules: []
83
86
  };
@@ -123,14 +126,17 @@ function getSpecifier({specifier, namespace, name = "", version}) {
123
126
  const bareSpecifier = namespace ? `${namespace}/${name}` : name;
124
127
  return version ? `${bareSpecifier}${VERSION_SIGIL}${normalizeVersionToUri(version)}` : bareSpecifier;
125
128
  }
126
- async function getVersionedModuleId(rawSpecifier, moduleRegistry) {
129
+ async function getVersionedModuleId(rawSpecifier, moduleRegistry, runtimeParams) {
127
130
  const moduleId = explodeSpecifier(rawSpecifier);
128
131
  if (moduleId.version) {
129
132
  return {...moduleId, version: normalizeVersionFromUri(moduleId.version)};
130
133
  }
131
- const moduleEntry = await moduleRegistry.getModuleEntry(moduleId);
134
+ const moduleEntry = await moduleRegistry.getModuleEntry(moduleId, runtimeParams);
132
135
  return {...moduleId, version: moduleEntry.version};
133
136
  }
137
+ function isSpecifier(specifier) {
138
+ return !!specifier && /^@?[\w-]+(\/[\w-]+)*$/.test(specifier);
139
+ }
134
140
  var RE_SCOPED = /^(@[^/]+\/[^/@]+)(?:\/([^@]+))?(?:@([\s\S]+))?/;
135
141
  var RE_NORMAL = /^([^/@]+)(?:\/([^@]+))?(?:@([\s\S]+))?/;
136
142
  function parsePackageSpecifier(specifier) {
@@ -207,3 +213,10 @@ function isAssetSourceExternal(assetSource) {
207
213
  function isBundleDefinition(definition) {
208
214
  return definition.bundleRecord !== void 0;
209
215
  }
216
+ function stringToVariableName(inputString) {
217
+ const cleanedString = inputString.replace(/@/g, "").replace(/[^a-zA-Z0-9_$]/g, "_");
218
+ if (!cleanedString || /^[0-9$]+/.test(cleanedString)) {
219
+ return `_${cleanedString}`;
220
+ }
221
+ return cleanedString;
222
+ }
@@ -28,7 +28,7 @@ __export(exports, {
28
28
  getImportMetadata: () => getImportMetadata
29
29
  });
30
30
  var import_es_module_lexer = __toModule(require("es-module-lexer"));
31
- var import_logger = __toModule(require("./logger.cjs"));
31
+ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
32
32
  var IMPORT_META_REGEX = /^import\.meta(\.\w+)+/;
33
33
  var ModuleNameType;
34
34
  (function(ModuleNameType2) {
@@ -53,8 +53,8 @@ async function getImportMetadata(compiledSource) {
53
53
  const isStringLiteral = moduleSpecifier.startsWith("'") || moduleSpecifier.startsWith('"');
54
54
  const moduleNameType = isStringLiteral ? ModuleNameType.string : ModuleNameType.unresolved;
55
55
  moduleSpecifier = isStringLiteral ? moduleSpecifier.slice(1, -1) : moduleSpecifier;
56
- if (import_logger.logger.currentLevel === import_logger.DEBUG || import_logger.logger.currentLevel === import_logger.VERBOSE) {
57
- import_logger.logger.debug(`[import-metadata] Import from dynamic import ${compiledSource.slice(moduleImportLocation.ss, moduleImportLocation.se)} -> ${compiledSource.slice(moduleImportLocation.ss, moduleImportLocation.s)}`);
56
+ if (import_diagnostics.logger.currentLevel === import_diagnostics.DEBUG || import_diagnostics.logger.currentLevel === import_diagnostics.VERBOSE) {
57
+ import_diagnostics.logger.debug(`[import-metadata] Import from dynamic import ${compiledSource.slice(moduleImportLocation.ss, moduleImportLocation.se)} -> ${compiledSource.slice(moduleImportLocation.ss, moduleImportLocation.s)}`);
58
58
  }
59
59
  dynamicImports.push({
60
60
  moduleSpecifier,
@@ -32,6 +32,6 @@ __exportStar(exports, __toModule(require("./graph.cjs")));
32
32
  __exportStar(exports, __toModule(require("./mappings.cjs")));
33
33
  __exportStar(exports, __toModule(require("./urls.cjs")));
34
34
  __exportStar(exports, __toModule(require("./env.cjs")));
35
- __exportStar(exports, __toModule(require("./logger.cjs")));
36
35
  __exportStar(exports, __toModule(require("./lwr-app-observer.cjs")));
37
36
  __exportStar(exports, __toModule(require("./bundle.cjs")));
37
+ __exportStar(exports, __toModule(require("./localization.cjs")));
@@ -0,0 +1,34 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, {get: all[name], enumerable: true});
6
+ };
7
+
8
+ // packages/@lwrjs/shared-utils/src/localization.ts
9
+ __markAsModule(exports);
10
+ __export(exports, {
11
+ getFallbackLocale: () => getFallbackLocale,
12
+ walkLocaleFallbacks: () => walkLocaleFallbacks
13
+ });
14
+ function getFallbackLocale(localeId, i18n) {
15
+ const locale = i18n.locales.find((l) => l.id === localeId);
16
+ return locale?.fallback;
17
+ }
18
+ async function walkLocaleFallbacks(initialLocale, i18n, test) {
19
+ const visited = new Set();
20
+ let localeId = initialLocale;
21
+ while (localeId && !visited.has(localeId)) {
22
+ const result = await test(localeId);
23
+ if (result) {
24
+ return result;
25
+ }
26
+ visited.add(localeId);
27
+ const config = i18n.locales.find((l) => l.id === localeId);
28
+ localeId = config && config.fallback;
29
+ }
30
+ if (!visited.has(i18n.defaultLocale)) {
31
+ return test(i18n.defaultLocale);
32
+ }
33
+ return void 0;
34
+ }
@@ -37,7 +37,7 @@ async function getImportMetadataMappings(moduleIds, runtimeEnvironment, runtimeP
37
37
  };
38
38
  for (const moduleId of moduleIds) {
39
39
  const requestedSpecifier = (0, import_identity.getSpecifier)(moduleId);
40
- const specifier = await getVersionedSpecifier(moduleId, moduleRegistry);
40
+ const specifier = await getVersionedSpecifier(moduleId, moduleRegistry, runtimeParams);
41
41
  if (!visitedCache.has(specifier)) {
42
42
  const depth = {
43
43
  static: runtimeEnvironment.format === "esm" ? import_graph.GraphDepth.NONE : import_graph.GraphDepth.ALL,
@@ -136,12 +136,12 @@ async function createIndex(specifiers, moduleRegistry, runtimeEnvironment, runti
136
136
  await Promise.all(promises);
137
137
  return index;
138
138
  }
139
- async function getVersionedSpecifier(moduleId, moduleRegistry) {
139
+ async function getVersionedSpecifier(moduleId, moduleRegistry, runtimeParams) {
140
140
  if (!moduleId.importer || moduleId.version) {
141
141
  return (0, import_identity.getSpecifier)(moduleId);
142
142
  }
143
143
  const versionedModuleEntry = await moduleRegistry.getModuleEntry({
144
144
  ...moduleId
145
- });
145
+ }, runtimeParams);
146
146
  return (0, import_identity.getSpecifier)(versionedModuleEntry);
147
147
  }
@@ -23,7 +23,10 @@ function _deepFreeze(obj, maxDepth, depth) {
23
23
  }
24
24
  }
25
25
  function deepFreeze(obj, maxDepth = 5) {
26
- const objClone = JSON.parse(JSON.stringify(obj));
26
+ let objClone = obj;
27
+ if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION !== "true") {
28
+ objClone = JSON.parse(JSON.stringify(obj));
29
+ }
27
30
  return _deepFreeze(objClone, maxDepth, 0);
28
31
  }
29
32
  var debounce = (func, waitFor) => {
@@ -29,10 +29,13 @@ __export(exports, {
29
29
  getClientBootstrapConfigurationRoutes: () => getClientBootstrapConfigurationRoutes,
30
30
  getClientBootstrapConfigurationUri: () => getClientBootstrapConfigurationUri,
31
31
  getClientBootstrapConfigurationUriPrefix: () => getClientBootstrapConfigurationUriPrefix,
32
+ getViewUri: () => getViewUri,
32
33
  isModuleOrBundleUrl: () => isModuleOrBundleUrl,
34
+ isURL: () => isURL,
33
35
  removeClientBootstrapConfigurationSuffix: () => removeClientBootstrapConfigurationSuffix
34
36
  });
35
37
  var import_path_to_regexp = __toModule(require("path-to-regexp"));
38
+ var import_path = __toModule(require("path"));
36
39
  var CONFIG_SUFFIX = "/config.js";
37
40
  var SIGNATURE_SIGIL = "s";
38
41
  function getClientBootstrapConfigurationUri(routeInfo, runtimeEnvironment, runtimeParams, signature) {
@@ -100,3 +103,25 @@ var isModuleOrBundleRegEx = /^\/.*\/(module|bundle)\//i;
100
103
  function isModuleOrBundleUrl(url) {
101
104
  return isModuleOrBundleRegEx.test(url);
102
105
  }
106
+ function getViewUri(routePath, basePath, locale, i18n) {
107
+ if (isURL(routePath)) {
108
+ return routePath;
109
+ }
110
+ let url = basePath;
111
+ if (i18n.uriPattern === "path-prefix" && locale !== i18n.defaultLocale) {
112
+ url = import_path.default.join(url, `/${locale}`);
113
+ }
114
+ url = import_path.default.join(url, routePath);
115
+ if (i18n.uriPattern === "query-param" && locale !== i18n.defaultLocale) {
116
+ url = addQueryParamToAbsoluteURI(url, "locale", locale);
117
+ }
118
+ return url;
119
+ }
120
+ function isURL(uri) {
121
+ return /^https?:\/\//i.test(uri);
122
+ }
123
+ function addQueryParamToAbsoluteURI(absoluteURI, paramName, paramValue) {
124
+ const url = new URL(absoluteURI, "http://example.com");
125
+ url.searchParams.set(paramName, paramValue);
126
+ return url.pathname + url.search;
127
+ }
package/build/es/env.d.ts CHANGED
@@ -1,3 +1,7 @@
1
- import type { FeatureFlags } from '@lwrjs/types';
1
+ import type { EnvironmentContext, FeatureFlags, RuntimeParams } from '@lwrjs/types';
2
2
  export declare function getFeatureFlags(): FeatureFlags;
3
+ /**
4
+ * Create a serializable context for the lwr/environment variable
5
+ */
6
+ export declare function buildEnvironmentContext(runtimeParams: RuntimeParams): EnvironmentContext;
3
7
  //# sourceMappingURL=env.d.ts.map
package/build/es/env.js CHANGED
@@ -20,6 +20,11 @@ export function getFeatureFlags() {
20
20
  process.env.SSR_STATIC_BUNDLES.toLowerCase() === 'true'
21
21
  ? true
22
22
  : false,
23
+ // Islands fallback to CSR if SSR fails
24
+ SSR_WITH_CSR_FALLBACK: process.env.SSR_WITH_CSR_FALLBACK !== undefined &&
25
+ process.env.SSR_WITH_CSR_FALLBACK.toLowerCase() === 'true'
26
+ ? true
27
+ : false,
23
28
  // AMD Module Bundles include un-versioned aliases
24
29
  EXPERIMENTAL_UNVERSIONED_ALIASES: process.env.EXPERIMENTAL_UNVERSIONED_ALIASES !== undefined &&
25
30
  process.env.EXPERIMENTAL_UNVERSIONED_ALIASES.toLowerCase() === 'true'
@@ -30,4 +35,23 @@ export function getFeatureFlags() {
30
35
  : false,
31
36
  };
32
37
  }
38
+ /**
39
+ * Create a serializable context for the lwr/environment variable
40
+ */
41
+ export function buildEnvironmentContext(runtimeParams) {
42
+ // The baseBath form the config or set from the request (e.g. /shop)
43
+ const basePath = runtimeParams.basePath;
44
+ // The locale set from the request or the defaultLocale from the config (e.g. en-US)
45
+ const locale = runtimeParams.locale;
46
+ // Root base path for static assets (e.g. /shop/mobify/bundle/1234/site)
47
+ const assetBasePath = runtimeParams.assetBasePath;
48
+ // Base path for UI routing (e.g. /shop/en-US)
49
+ const uiBasePath = runtimeParams.uiBasePath;
50
+ return {
51
+ basePath,
52
+ locale,
53
+ assetBasePath,
54
+ uiBasePath,
55
+ };
56
+ }
33
57
  //# sourceMappingURL=env.js.map
@@ -1,6 +1,6 @@
1
1
  import chokidar from 'chokidar';
2
2
  import { debounce } from './object.js';
3
- import { logger } from './logger.js';
3
+ import { logger } from '@lwrjs/diagnostics';
4
4
  /**
5
5
  * Factory comptable with the LWR Runtime to create a file watch library for LWR dev server.
6
6
  * When importing this module make sure the optional library 'chokidar' is installed.
package/build/es/fs.d.ts CHANGED
@@ -21,10 +21,10 @@ export declare function resolveFileExtension(filePath: string): string;
21
21
  /**
22
22
  * Returns if view of specific type can be resolved
23
23
  *
24
- * @param source - path to view
24
+ * @param source - possible path to view
25
25
  * @param type - extension of file that should be expected, i.e. 'html'
26
26
  */
27
- export declare function canResolveView(source: string, type: string): boolean;
27
+ export declare function canResolveView(source: unknown, type: string): boolean;
28
28
  /**
29
29
  * Construct a ViewSource from the associated file on the fs
30
30
  * @param source - Filepath with the source (source can be an absolute or relative path)
package/build/es/fs.js CHANGED
@@ -5,7 +5,7 @@ import { slugify } from './identity.js';
5
5
  import { LwrUnresolvableError, createSingleDiagnosticError, descriptions } from '@lwrjs/diagnostics';
6
6
  import { lookup } from 'mime-types';
7
7
  import { Readable } from 'stream';
8
- import { DEBUG, logger, VERBOSE } from './logger.js';
8
+ import { DEBUG, logger, VERBOSE } from '@lwrjs/diagnostics';
9
9
  let fileCount = 0;
10
10
  const files = new Map();
11
11
  /**
@@ -57,10 +57,13 @@ export function resolveFileExtension(filePath) {
57
57
  /**
58
58
  * Returns if view of specific type can be resolved
59
59
  *
60
- * @param source - path to view
60
+ * @param source - possible path to view
61
61
  * @param type - extension of file that should be expected, i.e. 'html'
62
62
  */
63
63
  export function canResolveView(source, type) {
64
+ if (typeof source !== 'string') {
65
+ return false;
66
+ }
64
67
  if (!source.endsWith(`.${type}`)) {
65
68
  return false;
66
69
  }
@@ -6,5 +6,5 @@ export declare enum GraphDepth {
6
6
  }
7
7
  export declare function isBundler(registry: PublicModuleRegistry | PublicModuleBundler): registry is PublicModuleBundler;
8
8
  export declare function getModuleGraphs(specifier: string, // version | un-versioned specifiers
9
- options: GraphOptions, moduleRegistry: ModuleRegistry, defRegistry: ModuleRegistry | ModuleBundler, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams, visited?: Map<string, GraphNode>): Promise<FlattenedModuleGraphs>;
9
+ options: GraphOptions, moduleRegistry: ModuleRegistry, defRegistry: ModuleRegistry | ModuleBundler, runtimeEnvironment: RuntimeEnvironment, runtimeParams: RuntimeParams, visited?: Map<string, GraphNode>): Promise<FlattenedModuleGraphs>;
10
10
  //# sourceMappingURL=graph.d.ts.map
package/build/es/graph.js CHANGED
@@ -108,7 +108,7 @@ export async function getModuleGraphs(specifier, // version | un-versioned speci
108
108
  options, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visited) {
109
109
  const acc = visited || new Map();
110
110
  // normalize the specifier
111
- const versionedModuleId = await getVersionedModuleId(specifier, moduleRegistry);
111
+ const versionedModuleId = await getVersionedModuleId(specifier, moduleRegistry, runtimeParams);
112
112
  const depth = options.depth || {
113
113
  static: GraphDepth.DIRECT,
114
114
  dynamic: 1,
@@ -127,7 +127,7 @@ options, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visited
127
127
  if (options.includeUris) {
128
128
  for (const visitedSpecifier of acc.keys()) {
129
129
  // eslint-disable-next-line no-await-in-loop
130
- const moduleId = await getVersionedModuleId(visitedSpecifier, moduleRegistry);
130
+ const moduleId = await getVersionedModuleId(visitedSpecifier, moduleRegistry, runtimeParams);
131
131
  // eslint-disable-next-line no-await-in-loop
132
132
  const uri = await defRegistry.resolveModuleUri(moduleId, runtimeEnvironment, runtimeParams);
133
133
  uriMap[visitedSpecifier] = uri;
@@ -137,7 +137,7 @@ options, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visited
137
137
  if (options.includeLinkedDefinitions) {
138
138
  for (const visitedSpecifier of acc.keys()) {
139
139
  // eslint-disable-next-line no-await-in-loop
140
- const versionedModuleId = await getVersionedModuleId(visitedSpecifier, moduleRegistry);
140
+ const versionedModuleId = await getVersionedModuleId(visitedSpecifier, moduleRegistry, runtimeParams);
141
141
  const module = isBundler(defRegistry)
142
142
  ? // eslint-disable-next-line no-await-in-loop
143
143
  await defRegistry.getModuleBundle(versionedModuleId, runtimeEnvironment, runtimeParams)
@@ -5,7 +5,7 @@ export declare function isSelfUrl(url: string): boolean;
5
5
  * Pull the custom elements and img tags out of an HTML string, to use as metadata
6
6
  * @param htmlSource - An HTML string to parse
7
7
  */
8
- export declare function extractMetadataFromHtml(htmlSource: string): Promise<RenderedViewMetadata>;
8
+ export declare function extractMetadataFromHtml(htmlSource: string, viewMetadata: RenderedViewMetadata): Promise<RenderedViewMetadata>;
9
9
  export declare const HYDRATE_DIRECTIVE = "lwr:hydrate";
10
10
  export declare const HYDRATE_LOAD_VALUE = "load";
11
11
  export declare const HYDRATE_CLIENT_VALUE = "client-only";
@@ -29,46 +29,51 @@ export function isSelfUrl(url) {
29
29
  return !url || !!url.match(isSelfUrlRegex);
30
30
  }
31
31
  const isSelfUrlRegex = /^\s*(data:|#)/i;
32
+ function hasHydrationDirective(attrs = {}) {
33
+ return Object.keys(attrs).some((attr) => attr === HYDRATE_DIRECTIVE);
34
+ }
32
35
  /**
33
36
  * Pull the custom elements and img tags out of an HTML string, to use as metadata
34
37
  * @param htmlSource - An HTML string to parse
35
38
  */
36
- export async function extractMetadataFromHtml(htmlSource) {
39
+ export async function extractMetadataFromHtml(htmlSource, viewMetadata) {
40
+ const { customElements, assetReferences, serverData } = viewMetadata;
37
41
  return new Promise((resolve, reject) => {
38
- const customElements = [];
39
42
  const openElements = new Set();
40
- const assetReferences = [];
41
43
  const parser = new SAXParser({ sourceCodeLocationInfo: true }); // TODO: Would we need this in the future?
42
44
  const ceRefStack = [];
45
+ let nestedIslands = false;
43
46
  parser.on('startTag', ({ tagName, attrs, // attributes are passed into SSR
44
47
  sourceCodeLocation, }) => {
45
48
  // custom elements
46
49
  if (tagName.includes('-') && !openElements.has(tagName)) {
47
50
  const { startOffset, endOffset } = sourceCodeLocation;
48
- const ceRef = {
49
- tagName,
50
- location: { startOffset, endOffset },
51
- // transform attributes [{ name: 'some-attr', value: 'the value' }] into properties { someAttr: 'the value' }
52
- // leave props as undefined if there are no attributes
53
- // set boolean attribute values to "true", or lwc will see them as falsy
54
- props: attrs.length
55
- ? attrs.reduce((obj, { name, value }) => {
56
- obj[getPropFromAttrName(name)] = value === '' ? 'true' : value;
57
- return obj;
58
- }, {})
59
- : undefined,
60
- };
51
+ // transform attributes [{ name: 'some-attr', value: 'the value' }] into properties { someAttr: 'the value' }
52
+ // leave props as undefined if there are no attributes
53
+ // set boolean attribute values to "true", or lwc will see them as falsy
54
+ const props = attrs.length
55
+ ? attrs.reduce((obj, { name, value }) => {
56
+ obj[getPropFromAttrName(name)] = value === '' ? 'true' : value;
57
+ return obj;
58
+ }, {})
59
+ : undefined;
60
+ const ceRef = { tagName, location: { startOffset, endOffset }, props };
61
61
  openElements.add(tagName);
62
62
  if (ceRefStack.length) {
63
63
  // nested CE
64
64
  const last = ceRefStack[ceRefStack.length - 1];
65
65
  last.children = last.children ? [...last.children, ceRef] : [ceRef];
66
- ceRefStack.push(ceRef);
66
+ // nested CEs are collected if they have a hydration directive
67
+ if (hasHydrationDirective(props)) {
68
+ customElements.push(ceRef);
69
+ nestedIslands = true;
70
+ }
67
71
  }
68
72
  else {
73
+ // collect all top-level CEs
69
74
  customElements.push(ceRef);
70
- ceRefStack.push(ceRef);
71
75
  }
76
+ ceRefStack.push(ceRef);
72
77
  }
73
78
  // <img src="asset-url"/>
74
79
  // <script type="text/javascript" src="asset-url"></script>
@@ -99,8 +104,13 @@ export async function extractMetadataFromHtml(htmlSource) {
99
104
  }
100
105
  });
101
106
  const inputStream = Readable.from(htmlSource);
102
- // dedupe custom element references
103
- inputStream.on('end', () => resolve({ customElements, assetReferences }));
107
+ // If nested islands are found, ONLY collect custom elements with the hydration directive
108
+ // Otherwise, just collect top-level custom elements (ie: root components) as usual
109
+ inputStream.on('end', () => resolve({
110
+ customElements: customElements.filter((ce) => !nestedIslands || hasHydrationDirective(ce.props)),
111
+ assetReferences,
112
+ serverData,
113
+ }));
104
114
  inputStream.on('error', (error) => reject(error));
105
115
  inputStream.pipe(parser);
106
116
  });
@@ -81,7 +81,8 @@ interface VersionedAbstractModuleId extends AbstractModuleId {
81
81
  * @example - 'c/form/v/0.0.2' => {specifier: "c/form", version: "0.0.2"}
82
82
  * @example - 'c/form/v/0_0_2' => {specifier: "c/form", version: "0.0.2"}
83
83
  */
84
- export declare function getVersionedModuleId(rawSpecifier: string, moduleRegistry: PublicModuleRegistry): Promise<VersionedAbstractModuleId>;
84
+ export declare function getVersionedModuleId(rawSpecifier: string, moduleRegistry: PublicModuleRegistry, runtimeParams: RuntimeParams): Promise<VersionedAbstractModuleId>;
85
+ export declare function isSpecifier(specifier?: string): boolean;
85
86
  interface PackageIdentity {
86
87
  scope?: string;
87
88
  packageName: string;
@@ -140,4 +141,9 @@ export { getCacheKeyFromJson };
140
141
  export declare function isExternalUrl(url: string): boolean;
141
142
  export declare function isAssetSourceExternal(assetSource: AssetSource): boolean;
142
143
  export declare function isBundleDefinition(definition: ModuleDefinition | BundleDefinition): definition is BundleDefinition;
144
+ /**
145
+ * Create a js safe variable name
146
+ * @param name - Proposed name
147
+ */
148
+ export declare function stringToVariableName(inputString: string): string;
143
149
  //# sourceMappingURL=identity.d.ts.map
@@ -22,6 +22,7 @@ export const DEFAULT_LWR_BOOTSTRAP_CONFIG = {
22
22
  services: [],
23
23
  configAsSrc: false,
24
24
  ssr: false,
25
+ mixedMode: false,
25
26
  module: undefined,
26
27
  preloadModules: [],
27
28
  };
@@ -119,15 +120,18 @@ export function getSpecifier({ specifier, namespace, name = '', version }) {
119
120
  * @example - 'c/form/v/0.0.2' => {specifier: "c/form", version: "0.0.2"}
120
121
  * @example - 'c/form/v/0_0_2' => {specifier: "c/form", version: "0.0.2"}
121
122
  */
122
- export async function getVersionedModuleId(rawSpecifier, moduleRegistry) {
123
+ export async function getVersionedModuleId(rawSpecifier, moduleRegistry, runtimeParams) {
123
124
  const moduleId = explodeSpecifier(rawSpecifier);
124
125
  if (moduleId.version) {
125
126
  return { ...moduleId, version: normalizeVersionFromUri(moduleId.version) };
126
127
  }
127
128
  // Get version from Module Registry
128
- const moduleEntry = await moduleRegistry.getModuleEntry(moduleId);
129
+ const moduleEntry = await moduleRegistry.getModuleEntry(moduleId, runtimeParams);
129
130
  return { ...moduleId, version: moduleEntry.version };
130
131
  }
132
+ export function isSpecifier(specifier) {
133
+ return !!specifier && /^@?[\w-]+(\/[\w-]+)*$/.test(specifier);
134
+ }
131
135
  const RE_SCOPED = /^(@[^/]+\/[^/@]+)(?:\/([^@]+))?(?:@([\s\S]+))?/;
132
136
  const RE_NORMAL = /^([^/@]+)(?:\/([^@]+))?(?:@([\s\S]+))?/;
133
137
  /**
@@ -254,4 +258,18 @@ export function isAssetSourceExternal(assetSource) {
254
258
  export function isBundleDefinition(definition) {
255
259
  return definition.bundleRecord !== undefined;
256
260
  }
261
+ /**
262
+ * Create a js safe variable name
263
+ * @param name - Proposed name
264
+ */
265
+ export function stringToVariableName(inputString) {
266
+ // Remove at symbols (@)
267
+ // Remove non-alphanumeric characters except for underscore (_) and dollar sign ($)
268
+ const cleanedString = inputString.replace(/@/g, '').replace(/[^a-zA-Z0-9_$]/g, '_');
269
+ // Prepend an underscore if the resulting name is empty or starts with a number, underscore (_) and dollar sign ($)
270
+ if (!cleanedString || /^[0-9$]+/.test(cleanedString)) {
271
+ return `_${cleanedString}`;
272
+ }
273
+ return cleanedString;
274
+ }
257
275
  //# sourceMappingURL=identity.js.map
@@ -1,5 +1,5 @@
1
1
  import { parse as parseImports } from 'es-module-lexer';
2
- import { DEBUG, logger, VERBOSE } from './logger.js';
2
+ import { DEBUG, logger, VERBOSE } from '@lwrjs/diagnostics';
3
3
  const IMPORT_META_REGEX = /^import\.meta(\.\w+)+/;
4
4
  export var ModuleNameType;
5
5
  (function (ModuleNameType) {
@@ -11,7 +11,7 @@ export * from './graph.js';
11
11
  export * from './mappings.js';
12
12
  export * from './urls.js';
13
13
  export * from './env.js';
14
- export * from './logger.js';
15
14
  export * from './lwr-app-observer.js';
16
15
  export * from './bundle.js';
16
+ export * from './localization.js';
17
17
  //# sourceMappingURL=index.d.ts.map
package/build/es/index.js CHANGED
@@ -11,7 +11,7 @@ export * from './graph.js';
11
11
  export * from './mappings.js';
12
12
  export * from './urls.js';
13
13
  export * from './env.js';
14
- export * from './logger.js';
15
14
  export * from './lwr-app-observer.js';
16
15
  export * from './bundle.js';
16
+ export * from './localization.js';
17
17
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ import type { I18NConfig } from '@lwrjs/types';
2
+ export declare function getFallbackLocale(localeId: string, i18n: I18NConfig): string | undefined;
3
+ export declare function walkLocaleFallbacks<R>(initialLocale: string, i18n: I18NConfig, test: (locale: string) => Promise<R | undefined>): Promise<R | undefined>;
4
+ //# sourceMappingURL=localization.d.ts.map
@@ -0,0 +1,28 @@
1
+ // Utilities for working with localized content
2
+ export function getFallbackLocale(localeId, i18n) {
3
+ const locale = i18n.locales.find((l) => l.id === localeId);
4
+ return locale?.fallback;
5
+ }
6
+ // Utilities to walk locale fallback logic
7
+ export async function walkLocaleFallbacks(initialLocale, i18n, test) {
8
+ // Walk the locales
9
+ const visited = new Set();
10
+ let localeId = initialLocale;
11
+ while (localeId && !visited.has(localeId)) {
12
+ // eslint-disable-next-line no-await-in-loop
13
+ const result = await test(localeId);
14
+ if (result) {
15
+ return result;
16
+ }
17
+ visited.add(localeId);
18
+ const config = i18n.locales.find((l) => l.id === localeId);
19
+ localeId = config && config.fallback;
20
+ }
21
+ // If we did not already visit the default locale give that a try
22
+ if (!visited.has(i18n.defaultLocale)) {
23
+ return test(i18n.defaultLocale);
24
+ }
25
+ // Did not find what we were looking for
26
+ return undefined;
27
+ }
28
+ //# sourceMappingURL=localization.js.map
@@ -12,7 +12,7 @@ export async function getImportMetadataMappings(moduleIds, runtimeEnvironment, r
12
12
  for (const moduleId of moduleIds) {
13
13
  const requestedSpecifier = getSpecifier(moduleId);
14
14
  // eslint-disable-next-line no-await-in-loop
15
- const specifier = await getVersionedSpecifier(moduleId, moduleRegistry);
15
+ const specifier = await getVersionedSpecifier(moduleId, moduleRegistry, runtimeParams);
16
16
  // Check if we have already visited
17
17
  if (!visitedCache.has(specifier)) {
18
18
  // Traversal of the Module Graph is done to get all the URLs for discoverable dependencies.
@@ -154,13 +154,13 @@ async function createIndex(specifiers, moduleRegistry, runtimeEnvironment, runti
154
154
  await Promise.all(promises);
155
155
  return index;
156
156
  }
157
- async function getVersionedSpecifier(moduleId, moduleRegistry) {
157
+ async function getVersionedSpecifier(moduleId, moduleRegistry, runtimeParams) {
158
158
  if (!moduleId.importer || moduleId.version) {
159
159
  return getSpecifier(moduleId);
160
160
  }
161
161
  const versionedModuleEntry = await moduleRegistry.getModuleEntry({
162
162
  ...moduleId,
163
- });
163
+ }, runtimeParams);
164
164
  return getSpecifier(versionedModuleEntry);
165
165
  }
166
166
  //# sourceMappingURL=mappings.js.map
@@ -18,7 +18,12 @@ function _deepFreeze(obj, maxDepth, depth) {
18
18
  */
19
19
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
20
20
  export function deepFreeze(obj, maxDepth = 5) {
21
- const objClone = JSON.parse(JSON.stringify(obj));
21
+ let objClone = obj;
22
+ // Temporary fix for W-13723739 to prevent out of memory exceptions
23
+ // Only clone the object if we don't have the env variable set
24
+ if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION !== 'true') {
25
+ objClone = JSON.parse(JSON.stringify(obj));
26
+ }
22
27
  return _deepFreeze(objClone, maxDepth, 0);
23
28
  }
24
29
  /**
@@ -7,7 +7,7 @@ import type { LinkedModuleDefinition, ModuleJsonDefinition, ModuleRegistry, Runt
7
7
  * @param moduleRegistry
8
8
  * @returns - Promise to the JSON serialization of the module
9
9
  */
10
- export declare function serializeModuleToJson(code: string | undefined, { specifier, version, ownHash, runtimeEnvironment, linkedConfig: { minified }, moduleRecord: { imports }, }: LinkedModuleDefinition, moduleRegistry: ModuleRegistry, runtimeParams?: RuntimeParams): Promise<ModuleJsonDefinition>;
10
+ export declare function serializeModuleToJson(code: string | undefined, { specifier, version, ownHash, runtimeEnvironment, linkedConfig: { minified }, moduleRecord: { imports }, }: LinkedModuleDefinition, moduleRegistry: ModuleRegistry, runtimeParams: RuntimeParams): Promise<ModuleJsonDefinition>;
11
11
  /**
12
12
  * Replace a part of a source string at the indices with a different value
13
13
  *
@@ -1,4 +1,4 @@
1
- import type { RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
1
+ import type { I18NConfig, RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
2
2
  export declare function getClientBootstrapConfigurationUri(routeInfo: {
3
3
  id: string;
4
4
  url: string;
@@ -28,4 +28,12 @@ export declare function getClientBootstrapConfigurationRoutes(): string[];
28
28
  */
29
29
  export declare function extractRequestParams(parameterizedRoute: string, resolvedUrl: string, existingParams?: Record<string, string>): Record<string, string>;
30
30
  export declare function isModuleOrBundleUrl(url: string): boolean;
31
+ /**
32
+ * Return a view route URL considering the basePath and the i18N config
33
+ */
34
+ export declare function getViewUri(routePath: string, basePath: string, locale: string, i18n: I18NConfig): string;
35
+ /**
36
+ * Returns true is the URI starts with http:// or https://
37
+ */
38
+ export declare function isURL(uri: string): boolean;
31
39
  //# sourceMappingURL=urls.d.ts.map
package/build/es/urls.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { pathToRegexp } from 'path-to-regexp';
2
+ import path from 'path';
2
3
  const CONFIG_SUFFIX = '/config.js';
3
4
  const SIGNATURE_SIGIL = 's';
4
5
  export function getClientBootstrapConfigurationUri(routeInfo, runtimeEnvironment, runtimeParams, signature) {
@@ -91,4 +92,36 @@ const isModuleOrBundleRegEx = /^\/.*\/(module|bundle)\//i;
91
92
  export function isModuleOrBundleUrl(url) {
92
93
  return isModuleOrBundleRegEx.test(url);
93
94
  }
95
+ /**
96
+ * Return a view route URL considering the basePath and the i18N config
97
+ */
98
+ export function getViewUri(routePath, basePath, locale, i18n) {
99
+ // Use a regular expression to check if the URI has a domain
100
+ if (isURL(routePath)) {
101
+ return routePath;
102
+ }
103
+ let url = basePath;
104
+ if (i18n.uriPattern === 'path-prefix' && locale !== i18n.defaultLocale) {
105
+ url = path.join(url, `/${locale}`);
106
+ }
107
+ url = path.join(url, routePath);
108
+ if (i18n.uriPattern === 'query-param' && locale !== i18n.defaultLocale) {
109
+ url = addQueryParamToAbsoluteURI(url, 'locale', locale);
110
+ }
111
+ return url;
112
+ }
113
+ /**
114
+ * Returns true is the URI starts with http:// or https://
115
+ */
116
+ export function isURL(uri) {
117
+ return /^https?:\/\//i.test(uri);
118
+ }
119
+ function addQueryParamToAbsoluteURI(absoluteURI, paramName, paramValue) {
120
+ // Use a dummy domain for parsing
121
+ const url = new URL(absoluteURI, 'http://example.com');
122
+ // Add the query parameter
123
+ url.searchParams.set(paramName, paramValue);
124
+ // Get the modified URI with the query parameter
125
+ return url.pathname + url.search;
126
+ }
94
127
  //# sourceMappingURL=urls.js.map
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.11.0-alpha.0",
7
+ "version": "0.11.0-alpha.10",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -45,7 +45,8 @@
45
45
  "build/**/*.d.ts"
46
46
  ],
47
47
  "dependencies": {
48
- "es-module-lexer": "^1.2.1",
48
+ "@lwrjs/diagnostics": "0.11.0-alpha.10",
49
+ "es-module-lexer": "^1.3.0",
49
50
  "fast-json-stable-stringify": "^2.1.0",
50
51
  "magic-string": "^0.30.0",
51
52
  "mime-types": "^2.1.33",
@@ -61,13 +62,12 @@
61
62
  "rollup": "^2.78.0"
62
63
  },
63
64
  "devDependencies": {
64
- "@lwrjs/diagnostics": "0.11.0-alpha.0",
65
- "@lwrjs/types": "0.11.0-alpha.0",
65
+ "@lwrjs/types": "0.11.0-alpha.10",
66
66
  "@types/mime-types": "2.1.1",
67
67
  "@types/path-to-regexp": "^1.7.0"
68
68
  },
69
69
  "engines": {
70
70
  "node": ">=16.0.0"
71
71
  },
72
- "gitHead": "6917abefe32752eeed0f9ba98505ca2b76f1df9d"
72
+ "gitHead": "34b1e289e8de12531f5624b64512e870157195d4"
73
73
  }
@@ -1,146 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getProtoOf = Object.getPrototypeOf;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, {get: all[name], enumerable: true});
11
- };
12
- var __exportStar = (target, module2, desc) => {
13
- if (module2 && typeof module2 === "object" || typeof module2 === "function") {
14
- for (let key of __getOwnPropNames(module2))
15
- if (!__hasOwnProp.call(target, key) && key !== "default")
16
- __defProp(target, key, {get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable});
17
- }
18
- return target;
19
- };
20
- var __toModule = (module2) => {
21
- return __exportStar(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? {get: () => module2.default, enumerable: true} : {value: module2, enumerable: true})), module2);
22
- };
23
-
24
- // packages/@lwrjs/shared-utils/src/logger.ts
25
- __markAsModule(exports);
26
- __export(exports, {
27
- DEBUG: () => DEBUG,
28
- ERROR: () => ERROR,
29
- INFO: () => INFO,
30
- VERBOSE: () => VERBOSE,
31
- WARN: () => WARN,
32
- logger: () => logger,
33
- stringifyError: () => stringifyError
34
- });
35
- var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
36
- var VERBOSE = "verbose";
37
- var DEBUG = "debug";
38
- var INFO = "info";
39
- var WARN = "warn";
40
- var ERROR = "error";
41
- var options = {};
42
- var DUPES = new Set();
43
- var currentLevel = process.env.LOG_LEVEL || INFO;
44
- function log(level, message, additionalInfo) {
45
- const LOG_LEVEL = process.env.LOG_LEVEL || INFO;
46
- if (currentLevel !== LOG_LEVEL) {
47
- currentLevel = LOG_LEVEL;
48
- console.log(`LOG_LEVEL: ${LOG_LEVEL}`);
49
- }
50
- let shouldLog = false;
51
- switch (level) {
52
- case VERBOSE:
53
- shouldLog = LOG_LEVEL == VERBOSE;
54
- break;
55
- case DEBUG:
56
- shouldLog = LOG_LEVEL == VERBOSE || LOG_LEVEL == DEBUG;
57
- break;
58
- case INFO:
59
- shouldLog = LOG_LEVEL == VERBOSE || LOG_LEVEL == DEBUG || LOG_LEVEL == INFO;
60
- break;
61
- case WARN:
62
- shouldLog = LOG_LEVEL == VERBOSE || LOG_LEVEL == DEBUG || LOG_LEVEL == INFO || LOG_LEVEL == WARN;
63
- break;
64
- case ERROR:
65
- shouldLog = true;
66
- break;
67
- }
68
- if (shouldLog && options.dedupe && options.dedupe.has(level)) {
69
- const key = `[${level}] : ${message}`;
70
- if (DUPES.has(key)) {
71
- shouldLog = false;
72
- } else {
73
- DUPES.add(key);
74
- }
75
- }
76
- if (shouldLog) {
77
- const logMessage = `[${level}]${gap(message)}${message}`;
78
- const additionalMessage = additionalInfo ? `Additional Info: ${JSON.stringify(additionalInfo)}` : void 0;
79
- if (level == ERROR) {
80
- console.error("%s", logMessage);
81
- if (additionalInfo) {
82
- console.error("\n%s", additionalMessage);
83
- }
84
- } else if (level == WARN) {
85
- console.warn("%s", logMessage);
86
- if (additionalInfo) {
87
- console.warn("\n%s", additionalMessage);
88
- }
89
- } else if (level == DEBUG || level == VERBOSE) {
90
- console.log("%s", logMessage);
91
- if (additionalInfo) {
92
- console.log("\n%s", additionalMessage);
93
- }
94
- } else {
95
- console.log(logMessage);
96
- if (additionalInfo) {
97
- console.log(`
98
- ${additionalMessage}`);
99
- }
100
- }
101
- }
102
- }
103
- var stringifyError = (error) => {
104
- if (error instanceof import_diagnostics.DiagnosticsError) {
105
- return JSON.stringify({
106
- message: error.message,
107
- diagnostics: error.diagnostics,
108
- stack: error.stack
109
- });
110
- } else if (typeof error === "string" || error instanceof String) {
111
- return error;
112
- } else {
113
- const propertyNames = Object.getOwnPropertyNames(error);
114
- const retObj = {};
115
- for (let property, i = 0, len = propertyNames.length; i < len; ++i) {
116
- property = propertyNames[i];
117
- const descriptor = Object.getOwnPropertyDescriptor(error, property);
118
- retObj[property] = descriptor?.value;
119
- }
120
- return JSON.stringify(retObj);
121
- }
122
- };
123
- function gap(message) {
124
- return String(message)?.indexOf("[") === 0 ? "" : " ";
125
- }
126
- function logError(err, additionalInfo) {
127
- if (err instanceof import_diagnostics.DiagnosticsError || !err || !err.message) {
128
- log(ERROR, stringifyError(err), additionalInfo);
129
- }
130
- if (err && err.message) {
131
- console.error("%s", `[${ERROR}]${gap(err.message)}${err.message}`);
132
- console.error("%s", err);
133
- }
134
- }
135
- var logger = {
136
- verbose: (message, additionalInfo) => log(VERBOSE, message, additionalInfo),
137
- debug: (message, additionalInfo) => log(DEBUG, message, additionalInfo),
138
- info: (message, additionalInfo) => log(INFO, message, additionalInfo),
139
- warn: (message, additionalInfo) => log(WARN, message, additionalInfo),
140
- error: (error, additionalInfo) => logError(error, additionalInfo),
141
- log,
142
- setOptions: (opts) => {
143
- options = opts;
144
- },
145
- currentLevel
146
- };
@@ -1,23 +0,0 @@
1
- type LEVEL = 'verbose' | 'debug' | 'info' | 'warn' | 'error';
2
- export declare const VERBOSE: LEVEL;
3
- export declare const DEBUG: LEVEL;
4
- export declare const INFO: LEVEL;
5
- export declare const WARN: LEVEL;
6
- export declare const ERROR: LEVEL;
7
- type LoggerOptions = {
8
- dedupe?: Set<string>;
9
- };
10
- declare function log(level: string, message: string, additionalInfo?: any): void;
11
- export declare const stringifyError: (error: any) => string;
12
- export declare const logger: {
13
- verbose: (message: string, additionalInfo?: any) => void;
14
- debug: (message: string, additionalInfo?: any) => void;
15
- info: (message: string, additionalInfo?: any) => void;
16
- warn: (message: string, additionalInfo?: any) => void;
17
- error: (error: any, additionalInfo?: any) => void;
18
- log: typeof log;
19
- setOptions: (opts: LoggerOptions) => void;
20
- currentLevel: string;
21
- };
22
- export {};
23
- //# sourceMappingURL=logger.d.ts.map
@@ -1,124 +0,0 @@
1
- import { DiagnosticsError } from '@lwrjs/diagnostics';
2
- export const VERBOSE = 'verbose';
3
- export const DEBUG = 'debug';
4
- export const INFO = 'info';
5
- export const WARN = 'warn';
6
- export const ERROR = 'error';
7
- let options = {};
8
- const DUPES = new Set();
9
- let currentLevel = process.env.LOG_LEVEL || INFO;
10
- function log(level, message, additionalInfo) {
11
- const LOG_LEVEL = process.env.LOG_LEVEL || INFO;
12
- if (currentLevel !== LOG_LEVEL) {
13
- currentLevel = LOG_LEVEL;
14
- console.log(`LOG_LEVEL: ${LOG_LEVEL}`);
15
- }
16
- let shouldLog = false;
17
- switch (level) {
18
- case VERBOSE:
19
- shouldLog = LOG_LEVEL == VERBOSE;
20
- break;
21
- case DEBUG:
22
- shouldLog = LOG_LEVEL == VERBOSE || LOG_LEVEL == DEBUG;
23
- break;
24
- case INFO:
25
- shouldLog = LOG_LEVEL == VERBOSE || LOG_LEVEL == DEBUG || LOG_LEVEL == INFO;
26
- break;
27
- case WARN:
28
- shouldLog = LOG_LEVEL == VERBOSE || LOG_LEVEL == DEBUG || LOG_LEVEL == INFO || LOG_LEVEL == WARN;
29
- break;
30
- case ERROR:
31
- shouldLog = true;
32
- break;
33
- }
34
- // Check if we should suppress dupes and we have already logged this message
35
- if (shouldLog && options.dedupe && options.dedupe.has(level)) {
36
- const key = `[${level}] : ${message}`;
37
- if (DUPES.has(key)) {
38
- shouldLog = false;
39
- }
40
- else {
41
- // add key to de-duplicate cache
42
- DUPES.add(key);
43
- }
44
- }
45
- if (shouldLog) {
46
- const logMessage = `[${level}]${gap(message)}${message}`;
47
- const additionalMessage = additionalInfo
48
- ? `Additional Info: ${JSON.stringify(additionalInfo)}`
49
- : undefined;
50
- if (level == ERROR) {
51
- console.error('\x1b[31m%s\x1b[0m', logMessage); // red
52
- if (additionalInfo) {
53
- console.error('\n\x1b[31m%s\x1b[0m', additionalMessage); // red
54
- }
55
- }
56
- else if (level == WARN) {
57
- console.warn('\x1b[33m%s\x1b[0m', logMessage); // yellow
58
- if (additionalInfo) {
59
- console.warn('\n\x1b[33m%s\x1b[0m', additionalMessage); // yellow
60
- }
61
- }
62
- else if (level == DEBUG || level == VERBOSE) {
63
- console.log('\x1b[2m%s\x1b[0m', logMessage); // dim
64
- if (additionalInfo) {
65
- console.log('\n\x1b[2m%s\x1b[0m', additionalMessage); // dim
66
- }
67
- }
68
- else {
69
- console.log(logMessage);
70
- if (additionalInfo) {
71
- console.log(`\n${additionalMessage}`);
72
- }
73
- }
74
- }
75
- }
76
- export const stringifyError = (error) => {
77
- if (error instanceof DiagnosticsError) {
78
- return JSON.stringify({
79
- message: error.message,
80
- diagnostics: error.diagnostics,
81
- stack: error.stack,
82
- });
83
- }
84
- else if (typeof error === 'string' || error instanceof String) {
85
- return error;
86
- }
87
- else {
88
- const propertyNames = Object.getOwnPropertyNames(error);
89
- const retObj = {};
90
- for (let property, i = 0, len = propertyNames.length; i < len; ++i) {
91
- property = propertyNames[i];
92
- const descriptor = Object.getOwnPropertyDescriptor(error, property);
93
- retObj[property] = descriptor?.value;
94
- }
95
- return JSON.stringify(retObj);
96
- }
97
- };
98
- // Return a space if there should be a space between the message and the level
99
- function gap(message) {
100
- return String(message)?.indexOf('[') === 0 ? '' : ' ';
101
- }
102
- function logError(err, additionalInfo) {
103
- if (err instanceof DiagnosticsError || !err || !err.message) {
104
- log(ERROR, stringifyError(err), additionalInfo);
105
- }
106
- // If this is an error with a message update the message header and log as is...
107
- if (err && err.message) {
108
- console.error('\x1b[31m%s\x1b[0m', `[${ERROR}]${gap(err.message)}${err.message}`);
109
- console.error('\x1b[90m%s\x1b[0m', err);
110
- }
111
- }
112
- export const logger = {
113
- verbose: (message, additionalInfo) => log(VERBOSE, message, additionalInfo),
114
- debug: (message, additionalInfo) => log(DEBUG, message, additionalInfo),
115
- info: (message, additionalInfo) => log(INFO, message, additionalInfo),
116
- warn: (message, additionalInfo) => log(WARN, message, additionalInfo),
117
- error: (error, additionalInfo) => logError(error, additionalInfo),
118
- log,
119
- setOptions: (opts) => {
120
- options = opts;
121
- },
122
- currentLevel,
123
- };
124
- //# sourceMappingURL=logger.js.map