@lwrjs/core 0.10.0-alpha.9 → 0.11.0-alpha.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.
@@ -45,6 +45,7 @@ var import_asset_middleware = __toModule(require("./middleware/asset-middleware.
45
45
  var import_view_middleware = __toModule(require("./middleware/view-middleware.cjs"));
46
46
  var import_resource_middleware = __toModule(require("./middleware/resource-middleware.cjs"));
47
47
  var import_hmr_middleware = __toModule(require("./middleware/hmr-middleware.cjs"));
48
+ var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
48
49
  function initMiddleware(app, server, serverContext) {
49
50
  app.useCompression();
50
51
  (0, import_locale_middleware.localeMiddleware)(app, serverContext);
@@ -67,10 +68,11 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
67
68
  if (hooks.length) {
68
69
  const skipValidation = true;
69
70
  await (0, import_config.executeConfigHooks)(hooks, appConfig, runtimeEnvironment, globalData, skipValidation);
71
+ (0, import_config.executeInstrumentationHooks)(hooks);
70
72
  (0, import_config.executeStartHooks)(hooks, appConfig);
71
73
  }
72
74
  const services = await (0, import_modules.loadServices)(appConfig);
73
- const serverContext = (0, import_server2.createServerContext)(appConfig, runtimeEnvironment, globalData);
75
+ const serverContext = (0, import_instrumentation.getTracer)().trace({name: import_instrumentation.CoreSpan.CreateServerContext}, () => (0, import_server2.createServerContext)(appConfig, runtimeEnvironment, globalData));
74
76
  const providerContext = (0, import_provider.createProviderContext)(serverContext);
75
77
  const {moduleRegistry, assetRegistry, resourceRegistry, viewRegistry, moduleBundler} = serverContext;
76
78
  const moduleProviders = createServices(services.moduleProviders, providerContext);
@@ -80,13 +82,16 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
80
82
  const viewProviders = createServices(services.viewProviders, providerContext);
81
83
  const viewTransformers = createServices(services.viewTransformers, providerContext);
82
84
  const bundleProviders = createServices(services.bundleProviders, providerContext);
83
- moduleRegistry.addModuleProviders(moduleProviders);
85
+ const uriTransformers = createServices(services.uriTransformers, providerContext);
84
86
  assetRegistry.addAssetProviders(assetProviders);
85
- assetRegistry.addAssetTransformers(assetTransformers);
87
+ assetRegistry.addAssetTransformers([...assetTransformers, ...uriTransformers]);
88
+ moduleBundler.addBundleProviders(bundleProviders);
89
+ moduleBundler.addBundleTransformers(uriTransformers);
90
+ moduleRegistry.addModuleProviders(moduleProviders);
86
91
  resourceRegistry.addResourceProviders(resourceProviders);
92
+ resourceRegistry.addResourceTransformers(uriTransformers);
87
93
  viewRegistry.addViewProviders(viewProviders);
88
94
  viewRegistry.addViewTransformers(viewTransformers);
89
- moduleBundler.addBundleProviders(bundleProviders);
90
95
  await serverContext.viewRegistry.initializeViewProviders();
91
96
  const routeHandlers = await (0, import_modules.loadRouteHandlers)(appConfig);
92
97
  serverContext.routeHandlers = routeHandlers;
@@ -95,6 +100,7 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
95
100
  var LwrApp = class {
96
101
  constructor(config = {}) {
97
102
  this.initialized = false;
103
+ const span = (0, import_instrumentation.getTracer)().startSpan({name: import_instrumentation.CoreSpan.CreateServer});
98
104
  const {appConfig, runtimeEnvironment, globalData} = (0, import_config.loadConfig)(config);
99
105
  this.config = appConfig;
100
106
  this.runtimeEnvironment = runtimeEnvironment;
@@ -102,6 +108,7 @@ var LwrApp = class {
102
108
  const {basePath} = this.config;
103
109
  this.app = (0, import_server.createInternalServer)(this.config.serverType, {basePath});
104
110
  this.server = this.app.createHttpServer();
111
+ span.end();
105
112
  }
106
113
  setConfig(config) {
107
114
  const {appConfig, runtimeEnvironment, globalData} = (0, import_config.loadConfig)(config);
@@ -113,6 +120,7 @@ var LwrApp = class {
113
120
  return this.config;
114
121
  }
115
122
  async init() {
123
+ const span = (0, import_instrumentation.getTracer)().startSpan({name: import_instrumentation.CoreSpan.InitServer});
116
124
  if (this.initialized) {
117
125
  return;
118
126
  }
@@ -124,8 +132,10 @@ var LwrApp = class {
124
132
  this.initialized = false;
125
133
  throw e;
126
134
  }
135
+ span.end();
127
136
  }
128
137
  async listen(callback) {
138
+ const span = (0, import_instrumentation.getTracer)().startSpan({name: import_instrumentation.CoreSpan.StartServer});
129
139
  await this.init();
130
140
  const {server, config, app} = this;
131
141
  const {serverMode, port} = config;
@@ -152,6 +162,7 @@ var LwrApp = class {
152
162
  }
153
163
  const opts = {serverMode, port};
154
164
  callback?.(opts);
165
+ span.end();
155
166
  resolve(opts);
156
167
  });
157
168
  });
@@ -29,42 +29,64 @@ __export(exports, {
29
29
  var import_path = __toModule(require("path"));
30
30
  var import_identity = __toModule(require("./utils/identity.cjs"));
31
31
  var import_error_handling = __toModule(require("./utils/error-handling.cjs"));
32
+ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
32
33
  function createAssetMiddleware(context) {
33
34
  const {
34
35
  assetRegistry,
35
36
  runtimeEnvironment: {basePath}
36
37
  } = context;
37
- return async (req, res) => {
38
+ return async (req, res, next) => {
38
39
  const {runtimeEnvironment} = req.getRuntimeContext(context.runtimeEnvironment);
39
40
  const {assetId, immutable, signature} = (0, import_identity.getAssetIdentity)(req);
40
41
  if (basePath && !assetId.specifier.startsWith(basePath)) {
41
42
  assetId.specifier = import_path.default.join(basePath, assetId.specifier);
42
43
  }
43
- const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
44
- if (assetUri.external) {
45
- res.set({
46
- Location: assetUri.uri,
47
- "cache-control": "public, max-age=60"
48
- });
49
- res.sendStatus(302);
50
- return;
44
+ try {
45
+ const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
46
+ if (assetUri.external) {
47
+ res.set({
48
+ Location: assetUri.uri,
49
+ "cache-control": "public, max-age=60"
50
+ });
51
+ res.sendStatus(302);
52
+ return;
53
+ }
54
+ const asset = await assetRegistry.getAsset({...assetId, signature}, runtimeEnvironment, req.isSiteGeneration());
55
+ if (req.isSiteGeneration()) {
56
+ res.setSiteGenerationMetadata({asset});
57
+ }
58
+ if (asset.mime) {
59
+ res.type(asset.mime);
60
+ }
61
+ if (runtimeEnvironment.immutableAssets && immutable) {
62
+ res.setHeader("Cache-control", "public, max-age=12895706, immutable");
63
+ } else if (runtimeEnvironment.immutableAssets) {
64
+ res.setHeader("Cache-control", "public, max-age=60");
65
+ }
66
+ res.status(200).stream(asset.stream());
67
+ } catch (error) {
68
+ if (import_path.default.dirname(assetId.specifier) === (basePath ? basePath : "/") && error instanceof import_diagnostics.DiagnosticsError && error?.diagnostics[0]?.description.category === "lwrUnresolvable/asset") {
69
+ await next();
70
+ return;
71
+ }
72
+ throw error;
51
73
  }
52
- const asset = await assetRegistry.getAsset({...assetId, signature}, runtimeEnvironment, req.isSiteGeneration());
53
- if (req.isSiteGeneration()) {
54
- res.setSiteGenerationMetadata({asset});
55
- }
56
- if (asset.mime) {
57
- res.type(asset.mime);
58
- }
59
- if (runtimeEnvironment.immutableAssets && immutable) {
60
- res.setHeader("Cache-control", "public, max-age=12895706, immutable");
61
- } else if (runtimeEnvironment.immutableAssets) {
62
- res.setHeader("Cache-control", "public, max-age=60");
63
- }
64
- res.status(200).stream(asset.stream());
65
74
  };
66
75
  }
67
76
  function assetMiddleware(app, context) {
68
- const paths = context.appConfig.assets.map((a) => a.urlPath + app.getRegexWildcard());
69
- app.get([...paths, "/:apiVersion/:assetType/:immutable?/s/:signature/" + app.getRegexWildcard()], (0, import_error_handling.handleErrors)(createAssetMiddleware(context)));
77
+ const paths = context.appConfig.assets.map((config) => {
78
+ const assetDirConfig = config;
79
+ let urlPath = config.urlPath;
80
+ if (assetDirConfig.root) {
81
+ urlPath = "/:filename";
82
+ } else if (assetDirConfig.dir) {
83
+ urlPath += app.getRegexWildcard();
84
+ }
85
+ return urlPath;
86
+ });
87
+ app.get([
88
+ ...[...new Set(paths)],
89
+ "/:apiVersion/:assetType(asset|content-asset)/:immutable?/s/:signature/" + app.getRegexWildcard(),
90
+ "/:apiVersion/:assetType(asset|content-asset)/:immutable?/" + app.getRegexWildcard()
91
+ ], (0, import_error_handling.handleErrors)(createAssetMiddleware(context)));
70
92
  }
@@ -75,7 +75,7 @@ function getResourceIdentity(req) {
75
75
  }
76
76
  function getAssetIdentity(req) {
77
77
  const {signature, immutable, assetType: type} = req.params;
78
- const specifier = signature && type ? "/" + req.params[0] : req.originalUrl.split("?")[0];
78
+ const specifier = type ? "/" + req.params[0] : req.originalUrl.split("?")[0];
79
79
  if (validateSpecifier(specifier) === false) {
80
80
  throw (0, import_diagnostics.createSingleDiagnosticError)({
81
81
  description: import_diagnostics.descriptions.UNRESOLVABLE.INVALID_SPECIFIER(specifier)
@@ -71,6 +71,8 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
71
71
  if (!errorRoute) {
72
72
  throw err;
73
73
  }
74
+ import_shared_utils.logger.error(`[view-middleware] Route Error ${req.originalUrl}`);
75
+ import_shared_utils.logger.error(err);
74
76
  viewResponse = await resolve.call(viewHandler, viewRequest, errorRoute, runtimeEnvironment, runtimeParams);
75
77
  resolvedRoute = errorRoute;
76
78
  }
@@ -100,10 +102,12 @@ function createConfigMiddleware(routes, context, viewHandler) {
100
102
  return;
101
103
  }
102
104
  const url = (0, import_shared_utils.decodeViewPath)(encodedViewPath);
105
+ const originalUrl = req.originalUrl;
103
106
  const requestPath = route.path;
104
107
  const params = (0, import_shared_utils.extractRequestParams)(requestPath, url, req.params);
105
108
  const viewRequest = {
106
109
  url,
110
+ originalUrl,
107
111
  params,
108
112
  query: req.query,
109
113
  requestPath
@@ -29,6 +29,7 @@ __export(exports, {
29
29
  });
30
30
  var import_perf_hooks = __toModule(require("perf_hooks"));
31
31
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
32
+ var import_site_metadata = __toModule(require("@lwrjs/static/site-metadata"));
32
33
  var import_path = __toModule(require("path"));
33
34
  var import_fs_extra = __toModule(require("fs-extra"));
34
35
  var import_stream = __toModule(require("./utils/stream.cjs"));
@@ -198,7 +199,8 @@ var SiteGenerator = class {
198
199
  const specifier = resourceDefinition.specifier;
199
200
  const resourceMetadata = {
200
201
  path: decodeURIComponent(url),
201
- mimeType: resourceDefinition.type
202
+ mimeType: resourceDefinition.type,
203
+ inline: resourceDefinition.inline
202
204
  };
203
205
  const siteResources = siteConfig.siteMetadata.getSiteResources();
204
206
  siteResources.resources[specifier] = resourceMetadata;
@@ -366,7 +368,8 @@ var SiteGenerator = class {
366
368
  const normalizedUrl = decodeURIComponent(url);
367
369
  (0, import_dir.createResourceDir)((0, import_path.dirname)(normalizedUrl), outputDir);
368
370
  const fullPath = (0, import_path.join)(outputDir, normalizedUrl);
369
- return fullPath;
371
+ const index = fullPath ? fullPath.indexOf("?") : -1;
372
+ return index !== -1 ? fullPath.substring(0, index) : fullPath;
370
373
  }
371
374
  writeNetlifyRedirectConfig(outputDir, urlRewriteMap) {
372
375
  const serveJsonPath = (0, import_path.join)(outputDir, "serve.json");
@@ -393,10 +396,24 @@ var SiteGenerator = class {
393
396
  try {
394
397
  const assetSrcFile = asset.file;
395
398
  const assetSrcDir = asset.dir;
396
- const assetsPath = (0, import_path.join)(outputDir, basePath ? basePath + asset.urlPath : asset.urlPath);
399
+ const isRootConfig = asset.root;
400
+ const urlPath = asset.urlPath;
401
+ const assetsPath = (0, import_path.join)(outputDir, basePath ? basePath + urlPath : urlPath);
397
402
  if (assetSrcDir && import_fs_extra.default.existsSync(assetSrcDir)) {
398
- import_fs_extra.default.copySync(assetSrcDir, assetsPath);
399
- this.addAssetsToMetadata(assetsPath, siteConfig);
403
+ if (isRootConfig) {
404
+ const files = import_fs_extra.default.readdirSync(assetSrcDir);
405
+ for (const file of files) {
406
+ const filePath = (0, import_path.join)(assetSrcDir, file);
407
+ if (import_fs_extra.default.statSync(filePath).isFile()) {
408
+ const fileDestPath = (0, import_path.join)(assetsPath, file);
409
+ import_fs_extra.default.copySync(filePath, fileDestPath);
410
+ this.addAssetToMetadata(fileDestPath, siteConfig);
411
+ }
412
+ }
413
+ } else {
414
+ import_fs_extra.default.copySync(assetSrcDir, assetsPath);
415
+ this.addAssetsToMetadata(assetsPath, siteConfig);
416
+ }
400
417
  } else if (assetSrcFile && import_fs_extra.default.existsSync(assetSrcFile)) {
401
418
  import_fs_extra.default.copySync(assetSrcFile, assetsPath);
402
419
  this.addAssetToMetadata(assetsPath, siteConfig);
@@ -404,7 +421,8 @@ var SiteGenerator = class {
404
421
  import_shared_utils.logger.warn("[SSG] Could not find assets to copy at path: " + assetsPath);
405
422
  }
406
423
  } catch (e) {
407
- import_shared_utils.logger.error("[SSG] Error occurred processing asset config: " + JSON.stringify(asset), e);
424
+ import_shared_utils.logger.error("[SSG] Error occurred processing asset config: " + JSON.stringify(asset));
425
+ import_shared_utils.logger.error(e);
408
426
  }
409
427
  }
410
428
  await siteConfig.siteMetadata?.persistSiteMetadata();
@@ -462,7 +480,7 @@ var SiteGenerator = class {
462
480
  endpoints,
463
481
  skipBaseDocumentGeneration,
464
482
  ...featureFlags,
465
- siteMetadata: new import_shared_utils.SiteMetadataImpl({rootDir: outputDir})
483
+ siteMetadata: new import_site_metadata.SiteMetadataImpl({rootDir: outputDir})
466
484
  };
467
485
  }
468
486
  filterFeatureFlags() {
@@ -1,3 +1,3 @@
1
- import { ProviderContext, ServerContext } from '@lwrjs/types';
1
+ import type { ProviderContext, ServerContext } from '@lwrjs/types';
2
2
  export declare function createProviderContext(serverContext: ServerContext): ProviderContext;
3
3
  //# sourceMappingURL=provider.d.ts.map
package/build/es/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { getFeatureFlags, DEFAULT_LWR_BOOTSTRAP_CONFIG, logger } from '@lwrjs/shared-utils';
2
2
  import { createInternalServer } from '@lwrjs/server';
3
3
  import { LwrServerError, createSingleDiagnosticError, descriptions } from '@lwrjs/diagnostics';
4
- import { loadConfig, executeConfigHooks, executeStartHooks } from '@lwrjs/config';
4
+ import { loadConfig, executeConfigHooks, executeStartHooks, executeInstrumentationHooks, } from '@lwrjs/config';
5
5
  import { loadHooks, loadServices, loadRouteHandlers } from '@lwrjs/config/modules';
6
6
  import SiteGenerator from './tools/static-generation.js';
7
7
  import { warmupServer } from './tools/server-warmup.js';
@@ -15,6 +15,7 @@ import { assetMiddleware } from './middleware/asset-middleware.js';
15
15
  import { viewMiddleware } from './middleware/view-middleware.js';
16
16
  import { resourceMiddleware } from './middleware/resource-middleware.js';
17
17
  import { hmrMiddleware } from './middleware/hmr-middleware.js';
18
+ import { getTracer, CoreSpan } from '@lwrjs/instrumentation';
18
19
  function initMiddleware(app, server, serverContext) {
19
20
  // all middleware attached AFTER compression will have compressed responses
20
21
  app.useCompression();
@@ -44,12 +45,13 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
44
45
  if (hooks.length) {
45
46
  const skipValidation = true; // skip for config hook, since `executeStartHooks` hook will validate
46
47
  await executeConfigHooks(hooks, appConfig, runtimeEnvironment, globalData, skipValidation);
48
+ executeInstrumentationHooks(hooks);
47
49
  executeStartHooks(hooks, appConfig);
48
50
  }
49
51
  // load all configurable modules
50
52
  const services = await loadServices(appConfig);
51
53
  // create all framework components(ie. registries)
52
- const serverContext = createServerContext(appConfig, runtimeEnvironment, globalData);
54
+ const serverContext = getTracer().trace({ name: CoreSpan.CreateServerContext }, () => createServerContext(appConfig, runtimeEnvironment, globalData));
53
55
  // create public subset of configurations
54
56
  const providerContext = createProviderContext(serverContext);
55
57
  const { moduleRegistry, assetRegistry, resourceRegistry, viewRegistry, moduleBundler } = serverContext;
@@ -61,14 +63,22 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
61
63
  const viewProviders = createServices(services.viewProviders, providerContext);
62
64
  const viewTransformers = createServices(services.viewTransformers, providerContext);
63
65
  const bundleProviders = createServices(services.bundleProviders, providerContext);
66
+ const uriTransformers = createServices(services.uriTransformers, providerContext);
64
67
  // add services to their corresponding registry
65
- moduleRegistry.addModuleProviders(moduleProviders);
68
+ // Assets
66
69
  assetRegistry.addAssetProviders(assetProviders);
67
- assetRegistry.addAssetTransformers(assetTransformers);
70
+ assetRegistry.addAssetTransformers([...assetTransformers, ...uriTransformers]);
71
+ // Bundles
72
+ moduleBundler.addBundleProviders(bundleProviders);
73
+ moduleBundler.addBundleTransformers(uriTransformers);
74
+ // Modules
75
+ moduleRegistry.addModuleProviders(moduleProviders);
76
+ // Resources
68
77
  resourceRegistry.addResourceProviders(resourceProviders);
78
+ resourceRegistry.addResourceTransformers(uriTransformers);
79
+ // Views
69
80
  viewRegistry.addViewProviders(viewProviders);
70
81
  viewRegistry.addViewTransformers(viewTransformers);
71
- moduleBundler.addBundleProviders(bundleProviders);
72
82
  // invoke async initialization
73
83
  await serverContext.viewRegistry.initializeViewProviders();
74
84
  // set routes on server context
@@ -79,6 +89,7 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
79
89
  export class LwrApp {
80
90
  constructor(config = {}) {
81
91
  this.initialized = false;
92
+ const span = getTracer().startSpan({ name: CoreSpan.CreateServer });
82
93
  const { appConfig, runtimeEnvironment, globalData } = loadConfig(config);
83
94
  this.config = appConfig;
84
95
  this.runtimeEnvironment = runtimeEnvironment;
@@ -86,6 +97,7 @@ export class LwrApp {
86
97
  const { basePath } = this.config;
87
98
  this.app = createInternalServer(this.config.serverType, { basePath });
88
99
  this.server = this.app.createHttpServer();
100
+ span.end();
89
101
  }
90
102
  setConfig(config) {
91
103
  const { appConfig, runtimeEnvironment, globalData } = loadConfig(config);
@@ -97,6 +109,7 @@ export class LwrApp {
97
109
  return this.config;
98
110
  }
99
111
  async init() {
112
+ const span = getTracer().startSpan({ name: CoreSpan.InitServer });
100
113
  if (this.initialized) {
101
114
  return;
102
115
  }
@@ -113,8 +126,10 @@ export class LwrApp {
113
126
  this.initialized = false;
114
127
  throw e;
115
128
  }
129
+ span.end();
116
130
  }
117
131
  async listen(callback) {
132
+ const span = getTracer().startSpan({ name: CoreSpan.StartServer });
118
133
  await this.init();
119
134
  const { server, config, app } = this;
120
135
  const { serverMode, port } = config;
@@ -142,6 +157,7 @@ export class LwrApp {
142
157
  }
143
158
  const opts = { serverMode, port };
144
159
  callback?.(opts);
160
+ span.end(); // TODO is this the right tracing for start server?
145
161
  resolve(opts);
146
162
  });
147
163
  });
@@ -1,42 +1,73 @@
1
1
  import path from 'path';
2
2
  import { getAssetIdentity } from './utils/identity.js';
3
3
  import { handleErrors } from './utils/error-handling.js';
4
+ import { DiagnosticsError } from '@lwrjs/diagnostics';
4
5
  function createAssetMiddleware(context) {
5
6
  const { assetRegistry, runtimeEnvironment: { basePath }, } = context;
6
- return async (req, res) => {
7
+ return async (req, res, next) => {
7
8
  const { runtimeEnvironment } = req.getRuntimeContext(context.runtimeEnvironment);
8
9
  const { assetId, immutable, signature } = getAssetIdentity(req);
9
10
  if (basePath && !assetId.specifier.startsWith(basePath)) {
10
11
  assetId.specifier = path.join(basePath, assetId.specifier);
11
12
  }
12
- // Redirect if this is an external asset
13
- const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
14
- if (assetUri.external) {
15
- res.set({
16
- Location: assetUri.uri,
17
- 'cache-control': 'public, max-age=60',
18
- });
19
- res.sendStatus(302);
20
- return;
13
+ try {
14
+ // Redirect if this is an external asset
15
+ const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
16
+ if (assetUri.external) {
17
+ res.set({
18
+ Location: assetUri.uri,
19
+ 'cache-control': 'public, max-age=60',
20
+ });
21
+ res.sendStatus(302);
22
+ return;
23
+ }
24
+ const asset = await assetRegistry.getAsset({ ...assetId, signature }, runtimeEnvironment, req.isSiteGeneration());
25
+ if (req.isSiteGeneration()) {
26
+ res.setSiteGenerationMetadata({ asset });
27
+ }
28
+ if (asset.mime) {
29
+ res.type(asset.mime);
30
+ }
31
+ if (runtimeEnvironment.immutableAssets && immutable) {
32
+ res.setHeader('Cache-control', 'public, max-age=12895706, immutable');
33
+ }
34
+ else if (runtimeEnvironment.immutableAssets) {
35
+ res.setHeader('Cache-control', 'public, max-age=60');
36
+ }
37
+ res.status(200).stream(asset.stream());
21
38
  }
22
- const asset = await assetRegistry.getAsset({ ...assetId, signature }, runtimeEnvironment, req.isSiteGeneration());
23
- if (req.isSiteGeneration()) {
24
- res.setSiteGenerationMetadata({ asset });
39
+ catch (error) {
40
+ // Ignore asset not found for root asset requests
41
+ if (path.dirname(assetId.specifier) === (basePath ? basePath : '/') &&
42
+ error instanceof DiagnosticsError &&
43
+ error?.diagnostics[0]?.description.category === 'lwrUnresolvable/asset') {
44
+ // Must await other middleware or this can respond before expected.
45
+ await next();
46
+ return;
47
+ }
48
+ // else throw the error
49
+ throw error;
25
50
  }
26
- if (asset.mime) {
27
- res.type(asset.mime);
28
- }
29
- if (runtimeEnvironment.immutableAssets && immutable) {
30
- res.setHeader('Cache-control', 'public, max-age=12895706, immutable');
31
- }
32
- else if (runtimeEnvironment.immutableAssets) {
33
- res.setHeader('Cache-control', 'public, max-age=60');
34
- }
35
- res.status(200).stream(asset.stream());
36
51
  };
37
52
  }
38
53
  export function assetMiddleware(app, context) {
39
- const paths = context.appConfig.assets.map((a) => a.urlPath + app.getRegexWildcard());
40
- app.get([...paths, '/:apiVersion/:assetType/:immutable?/s/:signature/' + app.getRegexWildcard()], handleErrors(createAssetMiddleware(context)));
54
+ const paths = context.appConfig.assets.map((config) => {
55
+ const assetDirConfig = config;
56
+ let urlPath = config.urlPath;
57
+ // If this is a root config add a /:filename path to match any file in the root. The middleware will fall through if there is no match.
58
+ if (assetDirConfig.root) {
59
+ urlPath = '/:filename';
60
+ }
61
+ else if (assetDirConfig.dir) {
62
+ urlPath += app.getRegexWildcard();
63
+ }
64
+ return urlPath;
65
+ });
66
+ app.get([
67
+ // De-dupe paths (i.e. root path may have been added more than once)
68
+ ...[...new Set(paths)],
69
+ '/:apiVersion/:assetType(asset|content-asset)/:immutable?/s/:signature/' + app.getRegexWildcard(),
70
+ '/:apiVersion/:assetType(asset|content-asset)/:immutable?/' + app.getRegexWildcard(),
71
+ ], handleErrors(createAssetMiddleware(context)));
41
72
  }
42
73
  //# sourceMappingURL=asset-middleware.js.map
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  import type { ServerContext } from '@lwrjs/types';
3
- import http from 'http';
3
+ import type http from 'http';
4
4
  export declare function hmrMiddleware(server: http.Server, context: ServerContext): void;
5
5
  //# sourceMappingURL=hmr-middleware.d.ts.map
@@ -1,3 +1,3 @@
1
- import { MiddlewareFunction } from '@lwrjs/types';
1
+ import type { MiddlewareFunction } from '@lwrjs/types';
2
2
  export declare function handleErrors(middleware: MiddlewareFunction): MiddlewareFunction;
3
3
  //# sourceMappingURL=error-handling.d.ts.map
@@ -44,7 +44,7 @@ export function getResourceIdentity(req) {
44
44
  }
45
45
  export function getAssetIdentity(req) {
46
46
  const { signature, immutable, assetType: type } = req.params;
47
- const specifier = signature && type ? '/' + req.params[0] : req.originalUrl.split('?')[0];
47
+ const specifier = type ? '/' + req.params[0] : req.originalUrl.split('?')[0];
48
48
  if (validateSpecifier(specifier) === false) {
49
49
  throw createSingleDiagnosticError({
50
50
  description: descriptions.UNRESOLVABLE.INVALID_SPECIFIER(specifier),
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import type { MiddlewareRequest, ModuleRegistry } from '@lwrjs/types';
3
- import http from 'http';
3
+ import type http from 'http';
4
4
  import qs from 'qs';
5
5
  interface Params {
6
6
  [key: string]: string;
@@ -1,6 +1,6 @@
1
1
  import { descriptions } from '@lwrjs/diagnostics';
2
2
  import { getClientRoutes } from '@lwrjs/router';
3
- import { decodeViewPath, extractRequestParams, getClientBootstrapConfigurationRoutes, shortestTtl, } from '@lwrjs/shared-utils';
3
+ import { decodeViewPath, extractRequestParams, getClientBootstrapConfigurationRoutes, logger, shortestTtl, } from '@lwrjs/shared-utils';
4
4
  import { handleErrors } from './utils/error-handling.js';
5
5
  import { LwrViewHandler } from '@lwrjs/view-registry';
6
6
  const CANONICAL_VIEW_ROUTES = [
@@ -45,6 +45,9 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
45
45
  if (!errorRoute) {
46
46
  throw err;
47
47
  }
48
+ // Log Unexpected Routing Errors
49
+ logger.error(`[view-middleware] Route Error ${req.originalUrl}`);
50
+ logger.error(err);
48
51
  viewResponse = await resolve.call(viewHandler, viewRequest, errorRoute, runtimeEnvironment, runtimeParams);
49
52
  resolvedRoute = errorRoute;
50
53
  }
@@ -79,10 +82,12 @@ function createConfigMiddleware(routes, context, viewHandler) {
79
82
  }
80
83
  // decode the resolved view path and extract any params.
81
84
  const url = decodeViewPath(encodedViewPath);
85
+ const originalUrl = req.originalUrl;
82
86
  const requestPath = route.path;
83
87
  const params = extractRequestParams(requestPath, url, req.params);
84
88
  const viewRequest = {
85
89
  url,
90
+ originalUrl,
86
91
  params,
87
92
  query: req.query,
88
93
  requestPath,
@@ -1,3 +1,3 @@
1
- import { NormalizedLwrGlobalConfig } from '@lwrjs/types';
1
+ import type { NormalizedLwrGlobalConfig } from '@lwrjs/types';
2
2
  export declare function warmupServer(config: NormalizedLwrGlobalConfig, internalRequestKey: string): Promise<void>;
3
3
  //# sourceMappingURL=server-warmup.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import type { ImportMetadata, LwrDispatcher, StaticSiteGenerator, LwrRoute, NormalizedLwrGlobalConfig, RuntimeEnvironment } from '@lwrjs/types';
2
- import { ResourceContextOpts, SiteConfig, ViewImportMetadata } from './types.js';
2
+ import type { ResourceContextOpts, SiteConfig, ViewImportMetadata } from './types.js';
3
3
  export default class SiteGenerator {
4
4
  /**
5
5
  * Build a static site in the configured directory
@@ -1,5 +1,6 @@
1
1
  import { performance } from 'perf_hooks';
2
- import { getSpecifier, getFeatureFlags, hashContent, isSelfUrl, getModuleUriPrefix, getMappingUriPrefix, logger, WARN, INFO, SiteMetadataImpl, isExternalUrl, mimeLookup, } from '@lwrjs/shared-utils';
2
+ import { getSpecifier, getFeatureFlags, hashContent, isSelfUrl, getModuleUriPrefix, getMappingUriPrefix, logger, WARN, INFO, isExternalUrl, mimeLookup, } from '@lwrjs/shared-utils';
3
+ import { SiteMetadataImpl } from '@lwrjs/static/site-metadata';
3
4
  import { join, dirname, extname, normalize } from 'path';
4
5
  import fs from 'fs-extra';
5
6
  import { writeResponse } from './utils/stream.js';
@@ -254,6 +255,7 @@ export default class SiteGenerator {
254
255
  const resourceMetadata = {
255
256
  path: decodeURIComponent(url),
256
257
  mimeType: resourceDefinition.type,
258
+ inline: resourceDefinition.inline,
257
259
  };
258
260
  const siteResources = siteConfig.siteMetadata.getSiteResources();
259
261
  siteResources.resources[specifier] = resourceMetadata;
@@ -502,7 +504,9 @@ export default class SiteGenerator {
502
504
  const normalizedUrl = decodeURIComponent(url);
503
505
  createResourceDir(dirname(normalizedUrl), outputDir);
504
506
  const fullPath = join(outputDir, normalizedUrl);
505
- return fullPath;
507
+ // Remove query params from file paths
508
+ const index = fullPath ? fullPath.indexOf('?') : -1;
509
+ return index !== -1 ? fullPath.substring(0, index) : fullPath;
506
510
  }
507
511
  /**
508
512
  * Write out redirect mapping files for static hosting services like netlify. Examples for why this is needed:
@@ -550,10 +554,27 @@ export default class SiteGenerator {
550
554
  try {
551
555
  const assetSrcFile = asset.file;
552
556
  const assetSrcDir = asset.dir;
553
- const assetsPath = join(outputDir, basePath ? basePath + asset.urlPath : asset.urlPath);
557
+ const isRootConfig = asset.root;
558
+ const urlPath = asset.urlPath;
559
+ const assetsPath = join(outputDir, basePath ? basePath + urlPath : urlPath);
554
560
  if (assetSrcDir && fs.existsSync(assetSrcDir)) {
555
- fs.copySync(assetSrcDir, assetsPath);
556
- this.addAssetsToMetadata(assetsPath, siteConfig);
561
+ // If this is a root folder we do not want to recurse sub directories.
562
+ if (isRootConfig) {
563
+ const files = fs.readdirSync(assetSrcDir);
564
+ for (const file of files) {
565
+ const filePath = join(assetSrcDir, file);
566
+ if (fs.statSync(filePath).isFile()) {
567
+ const fileDestPath = join(assetsPath, file);
568
+ fs.copySync(filePath, fileDestPath);
569
+ this.addAssetToMetadata(fileDestPath, siteConfig);
570
+ }
571
+ }
572
+ }
573
+ else {
574
+ // else copy the source to the ssg root and then add the ssg paths to the metadata
575
+ fs.copySync(assetSrcDir, assetsPath);
576
+ this.addAssetsToMetadata(assetsPath, siteConfig);
577
+ }
557
578
  }
558
579
  else if (assetSrcFile && fs.existsSync(assetSrcFile)) {
559
580
  fs.copySync(assetSrcFile, assetsPath);
@@ -564,7 +585,8 @@ export default class SiteGenerator {
564
585
  }
565
586
  }
566
587
  catch (e) {
567
- logger.error('[SSG] Error occurred processing asset config: ' + JSON.stringify(asset), e);
588
+ logger.error('[SSG] Error occurred processing asset config: ' + JSON.stringify(asset));
589
+ logger.error(e);
568
590
  }
569
591
  }
570
592
  await siteConfig.siteMetadata?.persistSiteMetadata();
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import http from 'http';
3
- import { LwrDispatcher, FsContext } from '@lwrjs/types';
3
+ import type { LwrDispatcher, FsContext } from '@lwrjs/types';
4
4
  export default class NetworkDispatcher implements LwrDispatcher {
5
5
  port: number;
6
6
  internalRequestKey: string;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
- import { Readable } from 'stream';
3
- import { FsContext } from '@lwrjs/types';
2
+ import type { Readable } from 'stream';
3
+ import type { FsContext } from '@lwrjs/types';
4
4
  export declare function writeStream(readStream: Readable, fullPath: string): Promise<void>;
5
5
  export declare function writeResponse(context: FsContext, fullPath: string): Promise<void>;
6
6
  /**
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.10.0-alpha.9",
7
+ "version": "0.11.0-alpha.0",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -35,48 +35,55 @@
35
35
  "build/**/*.d.ts",
36
36
  "package.cjs"
37
37
  ],
38
+ "scripts": {
39
+ "build": "tsc -b"
40
+ },
38
41
  "dependencies": {
39
- "@locker/compiler": "0.19.0",
40
- "@lwrjs/app-service": "0.10.0-alpha.9",
41
- "@lwrjs/asset-registry": "0.10.0-alpha.9",
42
- "@lwrjs/asset-transformer": "0.10.0-alpha.9",
43
- "@lwrjs/base-view-provider": "0.10.0-alpha.9",
44
- "@lwrjs/base-view-transformer": "0.10.0-alpha.9",
45
- "@lwrjs/client-modules": "0.10.0-alpha.9",
46
- "@lwrjs/config": "0.10.0-alpha.9",
47
- "@lwrjs/diagnostics": "0.10.0-alpha.9",
48
- "@lwrjs/fs-asset-provider": "0.10.0-alpha.9",
49
- "@lwrjs/html-view-provider": "0.10.0-alpha.9",
50
- "@lwrjs/loader": "0.10.0-alpha.9",
51
- "@lwrjs/lwc-module-provider": "0.10.0-alpha.9",
52
- "@lwrjs/markdown-view-provider": "0.10.0-alpha.9",
53
- "@lwrjs/module-bundler": "0.10.0-alpha.9",
54
- "@lwrjs/module-registry": "0.10.0-alpha.9",
55
- "@lwrjs/npm-module-provider": "0.10.0-alpha.9",
56
- "@lwrjs/nunjucks-view-provider": "0.10.0-alpha.9",
57
- "@lwrjs/o11y": "0.10.0-alpha.9",
58
- "@lwrjs/resource-registry": "0.10.0-alpha.9",
59
- "@lwrjs/router": "0.10.0-alpha.9",
60
- "@lwrjs/server": "0.10.0-alpha.9",
61
- "@lwrjs/shared-utils": "0.10.0-alpha.9",
62
- "@lwrjs/view-registry": "0.10.0-alpha.9",
42
+ "@lwrjs/app-service": "0.11.0-alpha.0",
43
+ "@lwrjs/asset-registry": "0.11.0-alpha.0",
44
+ "@lwrjs/asset-transformer": "0.11.0-alpha.0",
45
+ "@lwrjs/base-view-provider": "0.11.0-alpha.0",
46
+ "@lwrjs/base-view-transformer": "0.11.0-alpha.0",
47
+ "@lwrjs/client-modules": "0.11.0-alpha.0",
48
+ "@lwrjs/config": "0.11.0-alpha.0",
49
+ "@lwrjs/diagnostics": "0.11.0-alpha.0",
50
+ "@lwrjs/fs-asset-provider": "0.11.0-alpha.0",
51
+ "@lwrjs/html-view-provider": "0.11.0-alpha.0",
52
+ "@lwrjs/instrumentation": "0.11.0-alpha.0",
53
+ "@lwrjs/loader": "0.11.0-alpha.0",
54
+ "@lwrjs/lwc-module-provider": "0.11.0-alpha.0",
55
+ "@lwrjs/markdown-view-provider": "0.11.0-alpha.0",
56
+ "@lwrjs/module-bundler": "0.11.0-alpha.0",
57
+ "@lwrjs/module-registry": "0.11.0-alpha.0",
58
+ "@lwrjs/npm-module-provider": "0.11.0-alpha.0",
59
+ "@lwrjs/nunjucks-view-provider": "0.11.0-alpha.0",
60
+ "@lwrjs/o11y": "0.11.0-alpha.0",
61
+ "@lwrjs/resource-registry": "0.11.0-alpha.0",
62
+ "@lwrjs/router": "0.11.0-alpha.0",
63
+ "@lwrjs/server": "0.11.0-alpha.0",
64
+ "@lwrjs/shared-utils": "0.11.0-alpha.0",
65
+ "@lwrjs/static": "0.11.0-alpha.0",
66
+ "@lwrjs/view-registry": "0.11.0-alpha.0",
63
67
  "chokidar": "^3.5.3",
64
68
  "esbuild": "^0.9.7",
65
- "fs-extra": "^11.1.0",
69
+ "fs-extra": "^11.1.1",
66
70
  "path-to-regexp": "^6.2.0",
67
- "qs": "^6.9.4",
71
+ "qs": "^6.11.2",
68
72
  "rollup": "^2.78.0",
69
73
  "ws": "^8.8.1"
70
74
  },
71
75
  "devDependencies": {
72
- "@lwrjs/types": "0.10.0-alpha.9",
76
+ "@lwrjs/types": "0.11.0-alpha.0",
73
77
  "@types/ws": "^8.5.3"
74
78
  },
75
79
  "peerDependencies": {
76
- "lwc": "2.x"
80
+ "lwc": "2.x || 3.x"
77
81
  },
78
82
  "engines": {
79
- "node": ">=16.0.0 <20"
83
+ "node": ">=16.0.0"
84
+ },
85
+ "volta": {
86
+ "extends": "../../../package.json"
80
87
  },
81
- "gitHead": "6da48f5164ac881396055096a6c1e3d0f8d981aa"
88
+ "gitHead": "6917abefe32752eeed0f9ba98505ca2b76f1df9d"
82
89
  }