tungsten 0.5.8 → 0.6.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 (45) hide show
  1. package/dist/.build-complete +1 -1
  2. package/dist/Instance/Instance.d.ts +5 -1
  3. package/dist/Instance/Instance.d.ts.map +1 -1
  4. package/dist/Instance/Instance.js +18 -9
  5. package/dist/Servers/DevServer.d.ts +8 -3
  6. package/dist/Servers/DevServer.d.ts.map +1 -1
  7. package/dist/Servers/DevServer.js +56 -21
  8. package/dist/Servers/ProdServer.d.ts +2 -1
  9. package/dist/Servers/ProdServer.d.ts.map +1 -1
  10. package/dist/Servers/ProdServer.js +45 -14
  11. package/dist/Servers/TungstenServer.d.ts +2 -0
  12. package/dist/Servers/TungstenServer.d.ts.map +1 -1
  13. package/dist/Servers/TungstenServer.js +13 -0
  14. package/dist/Servers/tungstenCorePrivateEnvSchema.d.ts +1 -1
  15. package/dist/Servers/tungstenCorePrivateEnvSchema.js +2 -2
  16. package/dist/Servers/tungstenCorePublicEnvSchema.d.ts +2 -2
  17. package/dist/Servers/tungstenCorePublicEnvSchema.js +3 -3
  18. package/dist/Store/InternalStoreSchema.d.ts +1 -1
  19. package/dist/Store/InternalStoreSchema.d.ts.map +1 -1
  20. package/dist/bin/commands/dev.d.ts.map +1 -1
  21. package/dist/bin/commands/dev.js +4 -2
  22. package/dist/build/compileUserApp.d.ts.map +1 -1
  23. package/dist/components/Link.d.ts.map +1 -1
  24. package/dist/components/Link.js +1 -2
  25. package/dist/hydrate/hydrate.d.ts.map +1 -1
  26. package/dist/hydrate/hydrate.js +3 -1
  27. package/dist/routing/routeUrl.d.ts +4 -0
  28. package/dist/routing/routeUrl.d.ts.map +1 -0
  29. package/dist/routing/routeUrl.js +23 -0
  30. package/dist/staticGen/staticGenFunctions.d.ts.map +1 -1
  31. package/dist/staticGen/staticGenFunctions.js +2 -4
  32. package/dist/testing/host.js +3 -1
  33. package/dist/testing/testingComponentPackage.d.ts.map +1 -1
  34. package/dist/testing/testingComponentPackage.js +12 -0
  35. package/package.json +6 -5
  36. package/vendor/manifest.json +2 -2
  37. package/dist/auth/ref/auth.d.ts +0 -2
  38. package/dist/auth/ref/auth.d.ts.map +0 -1
  39. package/dist/auth/ref/auth.js +0 -23
  40. package/dist/auth/ref/checkPasswordResetToken.d.ts +0 -2
  41. package/dist/auth/ref/checkPasswordResetToken.d.ts.map +0 -1
  42. package/dist/auth/ref/checkPasswordResetToken.js +0 -27
  43. package/dist/auth/ref/createPasswordResetToken.d.ts +0 -2
  44. package/dist/auth/ref/createPasswordResetToken.d.ts.map +0 -1
  45. package/dist/auth/ref/createPasswordResetToken.js +0 -19
@@ -1 +1 @@
1
- 1789634748309
1
+ 1789682694258
@@ -36,9 +36,13 @@ export declare class Instance {
36
36
  runtimeContext: ClientRuntimeContext | undefined;
37
37
  registeredComponents: DisposableComponent[];
38
38
  constructor(location: string, instanceConfig: InstanceConfig, reqRes: ReqRes | null, appRoutes: AppRoutes, routes: Routes, internalStore: TrueStore<InternalStoreSchema>, stores: TrueStore<any>[], storeSubscriptions: StoreSubscriptionsMap, globalData: GlobalData, matchedRouteInfo: MatchedRouteInfo, runtimeContext?: ClientRuntimeContext);
39
+ routeKeyToUrl: (routeKey: RouteKey) => string;
40
+ urlToRouteKey: (pathname: string) => RouteKey;
39
41
  getRoutes: () => Routes;
40
42
  updateLocation: (location: string) => void;
41
- goto: (routeKey: RouteKey) => Promise<void>;
43
+ goto: (routeKey: RouteKey, { pushHistory }?: {
44
+ pushHistory?: boolean;
45
+ }) => Promise<void>;
42
46
  redirect: (url: string, code?: RedirectCode) => void;
43
47
  setDefaultTitle: (defaultTitle: string) => void;
44
48
  setTitle: (title: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"Instance.d.ts","sourceRoot":"","sources":["../../src/Instance/Instance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Instance.d.ts","sourceRoot":"","sources":["../../src/Instance/Instance.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
4
4
  import { isClient } from '../isClient.js';
5
5
  import { routing } from "../Servers/routing.js";
6
6
  import { RoutingRedirect } from '../routing/RoutingRedirect.js';
7
+ import { routeKeyToUrl, urlToRouteKey } from '../routing/routeUrl.js';
7
8
  import { isProd } from '../isProd.js';
8
9
  import { WebRedirect } from '../routing/WebRedirect.js';
9
10
  import { RouteRedirectComponent } from "../components/RouteRedirectComponent.js";
@@ -41,6 +42,14 @@ export class Instance {
41
42
  _defineProperty(this, "navigating", false);
42
43
  _defineProperty(this, "runtimeContext", void 0);
43
44
  _defineProperty(this, "registeredComponents", []);
45
+ _defineProperty(this, "routeKeyToUrl", routeKey => {
46
+ return routeKeyToUrl(routeKey, this.config.siteBasePath, isProd && this.config.staticSite);
47
+ });
48
+ // unchecked: goto's routing() does the pattern matching and 404 fallback
49
+ _defineProperty(this, "urlToRouteKey", pathname => {
50
+ const routeKey = urlToRouteKey(pathname, this.config.siteBasePath, isProd && this.config.staticSite);
51
+ return routeKey; // eslint-disable-line @typescript-eslint/no-unsafe-type-assertion
52
+ });
44
53
  _defineProperty(this, "getRoutes", () => {
45
54
  return typeof this.appRoutes === 'function' ? this.appRoutes(this.reqRes) : this.appRoutes;
46
55
  });
@@ -51,7 +60,9 @@ export class Instance {
51
60
  this.location = location;
52
61
  this.internalStore.location.set(location);
53
62
  });
54
- _defineProperty(this, "goto", async routeKey => {
63
+ _defineProperty(this, "goto", async (routeKey, {
64
+ pushHistory = true
65
+ } = {}) => {
55
66
  // get route data
56
67
  this.navigating = true;
57
68
  let matchedRouteInfo;
@@ -108,11 +119,9 @@ export class Instance {
108
119
  //console.log('location', location)
109
120
  //console.log('final dest', this.config.siteBasePath + location)
110
121
  this.matchedRouteInfo = matchedRouteInfo;
111
- const publicUrl = isProd && this.config.staticSite === true // add .html suffix for static sites
112
- ? routeKey === '/' ? '/' : routeKey + '.html' : routeKey;
113
- if (isClient) {
122
+ if (isClient && pushHistory) {
114
123
  const runtimeWindow = this.runtimeContext?.window ?? window;
115
- runtimeWindow.history.pushState(null, '', this.config.siteBasePath + publicUrl);
124
+ runtimeWindow.history.pushState(null, '', this.routeKeyToUrl(routeKey));
116
125
  }
117
126
  this.setTitleToDefault();
118
127
  this.updateLocation(routeKey); // this.internalStore.set('location', to)
@@ -206,10 +215,10 @@ export class Instance {
206
215
  runtimeWindow.addEventListener('popstate', event => {
207
216
  //console.log('popstate', window.location.pathname)
208
217
  //this.updateLocation(window.location.pathname)
209
- const newLocation = runtimeWindow.location.pathname;
210
- // unchecked: goto's routing() does the pattern matching and 404 fallback
211
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
212
- void this.goto(newLocation);
218
+ const newLocation = this.urlToRouteKey(runtimeWindow.location.pathname);
219
+ void this.goto(newLocation, {
220
+ pushHistory: false
221
+ });
213
222
  });
214
223
  }
215
224
  }
@@ -11,8 +11,9 @@ export declare class DevServer extends TungstenServer {
11
11
  framework: Framework;
12
12
  config: FrameworkConfigComplete;
13
13
  compilationInfo: CompilationInfo;
14
- port: number;
15
- location: string | null;
14
+ requestedPort: number;
15
+ publicOrigin: string | null;
16
+ expectedHost: string | null;
16
17
  initialProcessEnv: Record<string, string>;
17
18
  app: express.Application;
18
19
  apiRoutes?: ApiRoutes;
@@ -40,7 +41,11 @@ export declare class DevServer extends TungstenServer {
40
41
  getGlobalData: (func: GlobalDataFunction, reqRes: ReqRes) => Promise<GlobalData>;
41
42
  errorLog: (error: unknown) => void;
42
43
  errorPage: (error: unknown, errorTrack: string[]) => string;
43
- start: () => Promise<string>;
44
+ start: () => Promise<{
45
+ localOrigin: string;
46
+ publicOrigin: string;
47
+ port: number;
48
+ }>;
44
49
  stop: () => void;
45
50
  }
46
51
  //# sourceMappingURL=DevServer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevServer.d.ts","sourceRoot":"","sources":["../../src/Servers/DevServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAClC,OAAO,OAAgF,MAAM,SAAS,CAAA;AAOtG,OAAO,KAAK,EAAE,uBAAuB,EAAwB,MAAM,uBAAuB,CAAA;AAC1F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AA0B1C,OAAO,EAAkB,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AAC3G,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAsBrD,qBAAa,SAAU,SAAQ,cAAc;IACzC,SAAS,EAAE,SAAS,CAAA;IACpB,MAAM,EAAE,uBAAuB,CAAA;IAC/B,eAAe,EAAE,eAAe,CAAA;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAO;IAC9B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAA;IAExB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,OAAO,CAAO;IAC3B,cAAc,EAAE,MAAM,CAAI;IAC1B,oBAAoB,EAAE,MAAM,CAAI;IAChC,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,iBAAiB,CAA4B;IAIrD,OAAO,CAAC,MAAM,CAA2C;gBAErD,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,uBAAuB,EAAE,eAAe,EAAE,eAAe,EACvF,iBAAiB,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAiIlD,OAAO,CAAC,mBAAmB,CA2E1B;IAKD,OAAO,CAAC,sBAAsB,CAQ7B;IACD,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAC9C,OAAO,CAAC,oBAAoB,CAwB3B;IACD,OAAO,CAAC,mBAAmB,CAK1B;IACD,OAAO,CAAC,gBAAgB,CAcvB;IAED,OAAO,CAAC,aAAa,CAuOpB;IAaD,OAAO,CAAC,mBAAmB,CAsC1B;IAID,aAAa,GAAU,MAAM,kBAAkB,EAAE,QAAQ,MAAM,yBAQ9D;IACD,QAAQ,GAAI,OAAO,OAAO,UAIzB;IACD,SAAS,GAAI,OAAO,OAAO,EAAE,YAAY,MAAM,EAAE,YAiBhD;IAGD,KAAK,QAAa,OAAO,CAAC,MAAM,CAAC,CAKhC;IACD,IAAI,aAMH;CAGJ"}
1
+ {"version":3,"file":"DevServer.d.ts","sourceRoot":"","sources":["../../src/Servers/DevServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAClC,OAAO,OAAgF,MAAM,SAAS,CAAA;AAOtG,OAAO,KAAK,EAAE,uBAAuB,EAAwB,MAAM,uBAAuB,CAAA;AAC1F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AA0B1C,OAAO,EAAkB,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AAC3G,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAsBrD,qBAAa,SAAU,SAAQ,cAAc;IACzC,SAAS,EAAE,SAAS,CAAA;IACpB,MAAM,EAAE,uBAAuB,CAAA;IAC/B,eAAe,EAAE,eAAe,CAAA;IAChC,aAAa,EAAE,MAAM,CAAA;IAGrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAO;IAGlC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAO;IAClC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAA;IAExB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,OAAO,CAAO;IAC3B,cAAc,EAAE,MAAM,CAAI;IAC1B,oBAAoB,EAAE,MAAM,CAAI;IAChC,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,iBAAiB,CAA4B;IAIrD,OAAO,CAAC,MAAM,CAA2C;gBAErD,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,uBAAuB,EAAE,eAAe,EAAE,eAAe,EACvF,iBAAiB,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAoIlD,OAAO,CAAC,mBAAmB,CA2E1B;IAKD,OAAO,CAAC,sBAAsB,CAQ7B;IACD,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAC9C,OAAO,CAAC,oBAAoB,CAwB3B;IACD,OAAO,CAAC,mBAAmB,CAK1B;IACD,OAAO,CAAC,gBAAgB,CAcvB;IAED,OAAO,CAAC,aAAa,CAiOpB;IAaD,OAAO,CAAC,mBAAmB,CAsC1B;IAID,aAAa,GAAU,MAAM,kBAAkB,EAAE,QAAQ,MAAM,yBAQ9D;IACD,QAAQ,GAAI,OAAO,OAAO,UAIzB;IACD,SAAS,GAAI,OAAO,OAAO,EAAE,YAAY,MAAM,EAAE,YAiBhD;IAGD,KAAK;;;;OA+BJ;IACD,IAAI,aAMH;CAGJ"}
@@ -49,8 +49,13 @@ export class DevServer extends TungstenServer {
49
49
  _defineProperty(this, "framework", void 0);
50
50
  _defineProperty(this, "config", void 0);
51
51
  _defineProperty(this, "compilationInfo", void 0);
52
- _defineProperty(this, "port", void 0);
53
- _defineProperty(this, "location", null);
52
+ _defineProperty(this, "requestedPort", void 0);
53
+ // the origin the browser is expected to use (FRONTEND_*, so not this server's own when a proxy
54
+ // sits in front). Both are set in start(), once a random port has resolved
55
+ _defineProperty(this, "publicOrigin", null);
56
+ // the same thing as a host header: host:port, the port dropped when the public scheme's
57
+ // default. What the warning above compares a request's Origin against
58
+ _defineProperty(this, "expectedHost", null);
54
59
  _defineProperty(this, "initialProcessEnv", void 0);
55
60
  _defineProperty(this, "app", void 0);
56
61
  //apiRoutesPromise?: Promise<ApiRoutes>
@@ -475,11 +480,37 @@ export class DevServer extends TungstenServer {
475
480
  // the port - a swallowed failure here looked like "dev is up but not responding"
476
481
  _defineProperty(this, "start", async () => {
477
482
  const {
478
- server
479
- } = await listenVerified(this.app, this.port, this.bootId);
483
+ server,
484
+ port
485
+ } = await listenVerified(this.app, this.requestedPort, this.bootId);
480
486
  this.server = server;
481
- cliNews(`Dev server ready at ${this.location}`);
482
- return this.location ?? '';
487
+ const localOrigin = `http://localhost:${port}`;
488
+ cliNews(`Dev server ready at ${localOrigin}`);
489
+ // a fixed FRONTEND_PORT cannot track a port the OS re-picks on every boot
490
+ const {
491
+ FRONTEND_PROTO,
492
+ FRONTEND_HOSTNAME,
493
+ FRONTEND_PORT
494
+ } = tungstenPublicEnv;
495
+ const publicOrigin = this.makeOrigin(FRONTEND_PROTO ?? 'http', FRONTEND_HOSTNAME ?? 'localhost', FRONTEND_PORT || port);
496
+ this.publicOrigin = publicOrigin;
497
+ if (localOrigin !== publicOrigin) {
498
+ cliNews(`Dev server ready at ${publicOrigin}`);
499
+ }
500
+ // Tungsten only serves over http, so the seen origin will always
501
+ // be http even if the FRONTEND_PROTO is https. The hostname+port
502
+ // will match the frontend, so 'site.com' not 'site.com:443' when serving
503
+ // over https port 443. The results in an origin of 'http:site.com' for
504
+ // https requests
505
+ this.expectedHost = new URL(publicOrigin).host;
506
+ if (this.requestedPort === 0 && Number(FRONTEND_PORT) > 0) {
507
+ cliWarn(`Tungsten server is running on a random free port (${port}),` + ` but FRONTEND_PORT is set to ${FRONTEND_PORT}.` + ` This is likely an error because it will be difficult` + ` for a router to route requests to a randomly selected port`);
508
+ }
509
+ return {
510
+ localOrigin,
511
+ publicOrigin,
512
+ port
513
+ };
483
514
  });
484
515
  _defineProperty(this, "stop", () => {
485
516
  if (this.server !== undefined) this.server.close();
@@ -499,13 +530,10 @@ export class DevServer extends TungstenServer {
499
530
  // + '\n Ensure that you have an env schema with this field, and a matching env file'
500
531
  // )
501
532
  // }
502
- const proto = tungstenPublicEnv.FRONTEND_PROTO ?? 'http';
503
- const host = tungstenPublicEnv.FRONTEND_HOST ?? 'localhost';
533
+ // 0 asks the OS for a free port - start() reports the one it actually bound
504
534
  const port = tungstenPrivateEnv.TUNGSTEN_SERVER_PORT ?? 3000;
505
- if (isNaN(port) || port === 0) throwError('DevServer', portError(port));
506
- this.port = port;
507
- //this.port = _port
508
- this.location = `${proto}://${host}:${port}`;
535
+ if (isNaN(port)) throwError('DevServer', portError(port));
536
+ this.requestedPort = port;
509
537
  this.initialProcessEnv = initialProcessEnv;
510
538
  this.app = express();
511
539
  this.reqId = 0;
@@ -517,25 +545,32 @@ export class DevServer extends TungstenServer {
517
545
  });
518
546
  //if (tungstenPrivateEnv.DEBUG === true) {
519
547
  this.app.use((req, res, next) => {
520
- const targetOrigin = req.protocol + '://' + String(req.header('host'));
521
- const target = targetOrigin + req.url;
548
+ const host = String(req.header('host')); // host:port, the port left out when default
549
+ const target = `${req.protocol}://${host}${req.url}`;
522
550
  const origin = req.header('origin');
523
551
  if (tungstenPrivateEnv.DEBUG === true) {
524
552
  // request log
525
553
  let message = 'Received request at ' + target;
526
554
  if (origin !== undefined) {
527
- message += ' from ' + String(req.header('origin'));
555
+ message += ' from ' + origin;
528
556
  // should we use referrer as a backup option?
529
557
  // not sure what that is
530
558
  }
531
559
  cliOut(message);
532
560
  }
533
- if (this.config.suppressOriginMismatchWarning !== true) {
534
- // origin-target mismatch warning
535
- if (origin !== undefined && origin === this.location && origin !== targetOrigin) {
536
- cliWarn(`Received a request from the frontend, but it's origin` + ` is not the same as the request origin.` + ` This may indicate a misconfiguration, and may prevent` + ` the passing of cookies to the tungsten server.`);
537
- cliWarn(`source: ${targetOrigin}`);
538
- cliWarn(`target: ${target}`);
561
+ // Did the request arrive where the page it came from was loaded? Compared as hosts,
562
+ // not origins: req.protocol is always http (tungsten serves no https), while the
563
+ // browser's origin reads https wherever a proxy terminates TLS - so comparing whole
564
+ // origins reports a mismatch on every request of a perfectly good https deployment
565
+ if (this.config.suppressOriginMismatchWarning !== true && origin !== undefined) {
566
+ const originHost = this.hostOfOrigin(origin);
567
+ // only the configured frontend's own traffic can be misconfigured this way - a
568
+ // request from anywhere else is an ordinary cross-origin call
569
+ if (originHost !== null && originHost === this.expectedHost && originHost !== host) {
570
+ cliWarn(`Received a request from the frontend, but it did not arrive at the` + ` address the frontend was loaded from. This may indicate a` + ` misconfiguration, and may prevent the passing of cookies to the` + ` tungsten server.`);
571
+ cliWarn(`request: ${target}`);
572
+ cliWarn(`loaded from: ${origin}`);
573
+ cliWarn(`arrived at: ${host}`);
539
574
  }
540
575
  }
541
576
  next();
@@ -14,7 +14,8 @@ export declare class ProdServer extends TungstenServer {
14
14
  compilationInfo: CompilationInfo;
15
15
  appRoutes: AppRoutes;
16
16
  RootComponentOrNull: AnyComponentType | null;
17
- location: string | null;
17
+ publicOrigin: string | null;
18
+ expectedHost: string | null;
18
19
  app: express.Application;
19
20
  apiRoutesPromise?: Promise<ApiRoutes>;
20
21
  apiRoutes?: ApiRoutes;
@@ -1 +1 @@
1
- {"version":3,"file":"ProdServer.d.ts","sourceRoot":"","sources":["../../src/Servers/ProdServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAClC,OAAO,OAAO,MAAM,SAAS,CAAA;AAK7B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAiB7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAWrD,qBAAa,UAAW,SAAQ,cAAc;IAC1C,SAAS,EAAE,SAAS,CAAA;IACpB,MAAM,EAAE,uBAAuB,CAAA;IAC/B,eAAe,EAAE,eAAe,CAAA;IAChC,SAAS,EAAE,SAAS,CAAA;IACpB,mBAAmB,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAK5C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAO;IAC9B,GAAG,EAAE,OAAO,CAAC,WAAW,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IACrC,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,MAAM,CAAc;gBAExB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,uBAAuB,EAC/B,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,SAAS,EACpB,mBAAmB,EAAE,gBAAgB,GAAG,IAAI,EAC5C,gBAAgB,EAAE,gBAAgB,GAAG,IAAI;IAmI7C,OAAO,CAAC,gBAAgB,CAgBvB;IACD,aAAa,GAAU,KAAK,OAAO,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC,QAAQ,KAAG,OAAO,CAAC,IAAI,CAAC,CA2HjF;IASD,OAAO,CAAC,mBAAmB,CA+C1B;IACD,SAAS,eASR;IAOK,KAAK,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBlE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAY9B"}
1
+ {"version":3,"file":"ProdServer.d.ts","sourceRoot":"","sources":["../../src/Servers/ProdServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAClC,OAAO,OAAO,MAAM,SAAS,CAAA;AAK7B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAiB7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAWrD,qBAAa,UAAW,SAAQ,cAAc;IAC1C,SAAS,EAAE,SAAS,CAAA;IACpB,MAAM,EAAE,uBAAuB,CAAA;IAC/B,eAAe,EAAE,eAAe,CAAA;IAChC,SAAS,EAAE,SAAS,CAAA;IACpB,mBAAmB,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAO5C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAO;IAGlC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAO;IAClC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IACrC,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,MAAM,CAAc;gBAExB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,uBAAuB,EAC/B,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,SAAS,EACpB,mBAAmB,EAAE,gBAAgB,GAAG,IAAI,EAC5C,gBAAgB,EAAE,gBAAgB,GAAG,IAAI;IAqJ7C,OAAO,CAAC,gBAAgB,CAgBvB;IACD,aAAa,GAAU,KAAK,OAAO,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC,QAAQ,KAAG,OAAO,CAAC,IAAI,CAAC,CA2HjF;IASD,OAAO,CAAC,mBAAmB,CA+C1B;IACD,SAAS,eASR;IAOK,KAAK,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IA4BlE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAa9B"}
@@ -37,7 +37,12 @@ export class ProdServer extends TungstenServer {
37
37
  // prodBuildLocation: string
38
38
  // bundleLocation: string
39
39
  //port: number
40
- _defineProperty(this, "location", null);
40
+ // the origin the browser is expected to use (FRONTEND_*, so not this server's own when a proxy
41
+ // sits in front). Both are set in start()
42
+ _defineProperty(this, "publicOrigin", null);
43
+ // the same thing as a host header: host:port, the port dropped when the public scheme's
44
+ // default. What the warning below compares a request's Origin against
45
+ _defineProperty(this, "expectedHost", null);
41
46
  _defineProperty(this, "app", void 0);
42
47
  _defineProperty(this, "apiRoutesPromise", void 0);
43
48
  _defineProperty(this, "apiRoutes", void 0);
@@ -113,7 +118,6 @@ export class ProdServer extends TungstenServer {
113
118
  // throwError('DevServer', 'useRootComponent = false not implemented yet')
114
119
  // }
115
120
  const {
116
- compilationInfo,
117
121
  config,
118
122
  appRoutes,
119
123
  RootComponentOrNull
@@ -282,24 +286,42 @@ export class ProdServer extends TungstenServer {
282
286
  }
283
287
  const requestLog = tungstenPrivateEnv.DEBUG === true;
284
288
  const originMismatchWarning = this.config.suppressOriginMismatchWarning !== true;
289
+ // a misconfigured prod site mismatches on every request, so each host warns once a day
290
+ const originWarningInterval = 24 * 60 * 60 * 1000;
291
+ const originWarnedAt = new Map();
285
292
  if (requestLog || originMismatchWarning) {
286
293
  this.app.use((req, res, next) => {
287
- const target = req.protocol + '://' + String(req.header('host')) + req.url;
294
+ const host = String(req.header('host')); // host:port, the port left out when default
295
+ const target = `${req.protocol}://${host}${req.url}`;
288
296
  const origin = req.header('origin');
289
297
  // request log
290
298
  if (requestLog) {
291
299
  let message = 'Received request at ' + target;
292
300
  if (origin !== undefined) {
293
- message += ' from ' + String(req.header('origin'));
301
+ message += ' from ' + origin;
294
302
  // should we use referrer as a backup option?
295
303
  // not sure what that is
296
304
  }
297
305
  cliOut(message);
298
306
  }
299
- // origin-target mismatch warning
300
- if (originMismatchWarning) {
301
- if (origin !== undefined && origin === this.location && origin !== target) {
302
- cliWarn(`Received a request from the frontend, but it's origin` + ` is not the same as the request origin.` + ` This may indicate a misconfiguration, and may prevent` + ` the passing of cookies to the tungsten server.`);
307
+ // Did the request arrive where the page it came from was loaded? Hosts, not
308
+ // origins - req.protocol is always http here, while the browser's origin reads
309
+ // https wherever a proxy terminates TLS. DevServer carries the same check
310
+ if (originMismatchWarning && origin !== undefined) {
311
+ const originHost = this.hostOfOrigin(origin);
312
+ if (originHost !== null && originHost === this.expectedHost && originHost !== host) {
313
+ const warnedAt = originWarnedAt.get(host);
314
+ const now = Date.now();
315
+ if (warnedAt === undefined || now - warnedAt >= originWarningInterval) {
316
+ // the host header is client-supplied, so cap the map rather than grow it
317
+ if (originWarnedAt.size >= 100) originWarnedAt.clear();
318
+ originWarnedAt.set(host, now);
319
+ cliWarn(`Received a request from the frontend, but it did not arrive at the` + ` address the frontend was loaded from. This may indicate a` + ` misconfiguration, and may prevent the passing of cookies to the` + ` tungsten server.`);
320
+ cliWarn(`request: ${target}`);
321
+ cliWarn(`loaded from: ${origin}`);
322
+ cliWarn(`arrived at: ${host}`);
323
+ cliWarn(`Further mismatches on ${host} are silenced for 24 hours`);
324
+ }
303
325
  }
304
326
  }
305
327
  next();
@@ -342,8 +364,6 @@ export class ProdServer extends TungstenServer {
342
364
  // I don't think we ever override the port, not sure why
343
365
  // rejects on a bind error, or if another process answers on the port (see listenVerified.ts)
344
366
  async start(portOverride, mute = false) {
345
- const proto = tungstenPublicEnv.FRONTEND_PROTO ?? 'http';
346
- const host = tungstenPublicEnv.FRONTEND_HOST ?? 'localhost';
347
367
  let port;
348
368
  if (portOverride !== undefined) {
349
369
  port = portOverride ?? 0; // null: any free port
@@ -354,9 +374,19 @@ export class ProdServer extends TungstenServer {
354
374
  }
355
375
  const listening = await listenVerified(this.app, port, this.bootId);
356
376
  this.server = listening.server;
357
- this.location = `${proto}://${host}:${listening.port}`;
358
- if (!mute) cliNews(`${packageNameCapitalized} prod server ready at ${this.location}`);
359
- return this.location;
377
+ const localOrigin = this.makeOrigin('http', 'localhost', listening.port);
378
+ const {
379
+ FRONTEND_PROTO,
380
+ FRONTEND_HOSTNAME,
381
+ FRONTEND_PORT
382
+ } = tungstenPublicEnv;
383
+ const publicOrigin = this.makeOrigin(FRONTEND_PROTO ?? 'http', FRONTEND_HOSTNAME ?? 'localhost', FRONTEND_PORT || listening.port);
384
+ this.publicOrigin = publicOrigin;
385
+ // URL.host is the host header's own shape - a port only when it is not the public scheme's
386
+ // default, so an https site on 443 gives `site.example` rather than `site.example:443`
387
+ this.expectedHost = new URL(publicOrigin).host;
388
+ if (!mute) cliNews(`${packageNameCapitalized} prod server ready at ${localOrigin}`);
389
+ return localOrigin;
360
390
  }
361
391
  // close() alone only stops new connections arriving - keep-alive sockets (fetch/undici
362
392
  // holds them open) keep the handle, and so the event loop, alive until they time out
@@ -368,6 +398,7 @@ export class ProdServer extends TungstenServer {
368
398
  server.closeAllConnections();
369
399
  });
370
400
  delete this.server;
371
- this.location = null;
401
+ this.publicOrigin = null;
402
+ this.expectedHost = null;
372
403
  }
373
404
  }
@@ -1,6 +1,8 @@
1
1
  import type { Response as ExpressResponse } from 'express';
2
2
  import type { MatchedRouteInfo } from './MatchedRouteInfo.js';
3
3
  export declare class TungstenServer {
4
+ protected makeOrigin(proto: string, host: string, port: number): string;
5
+ protected hostOfOrigin(origin: string): string | null;
4
6
  protected handleRedirects(res: ExpressResponse, matchedRouteInfo: MatchedRouteInfo): boolean;
5
7
  }
6
8
  //# sourceMappingURL=TungstenServer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TungstenServer.d.ts","sourceRoot":"","sources":["../../src/Servers/TungstenServer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,SAAS,CAAA;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAgB7D,qBAAa,cAAc;IACvB,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,OAAO;CAoD/F"}
1
+ {"version":3,"file":"TungstenServer.d.ts","sourceRoot":"","sources":["../../src/Servers/TungstenServer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,SAAS,CAAA;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAgB7D,qBAAa,cAAc;IAGvB,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAI9D,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOrD,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,OAAO;CAoD/F"}
@@ -9,6 +9,19 @@ function debug(...texts) {
9
9
  // console.log(...texts)
10
10
  }
11
11
  export class TungstenServer {
12
+ // URL drops the port when it is the scheme's default, so http://x:80 -> http://x, https://x:443
13
+ // -> https://x, and anything else keeps it. Throws on a host it cannot parse
14
+ makeOrigin(proto, host, port) {
15
+ return new URL(`${proto}://${host}:${port}`).origin;
16
+ }
17
+ // null for an origin that is not a URL - a sandboxed iframe or similar sends the literal `null`
18
+ hostOfOrigin(origin) {
19
+ try {
20
+ return new URL(origin).host;
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
12
25
  handleRedirects(res, matchedRouteInfo) {
13
26
  // handle any redirect issued during routing
14
27
  if (matchedRouteInfo.data instanceof RoutingRedirect) {
@@ -1,6 +1,6 @@
1
1
  import * as v from 'valibot';
2
2
  export declare const tungstenCorePrivateEnvSchema: v.LooseObjectSchema<{
3
- readonly TUNGSTEN_SERVER_PORT: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.GtValueAction<number, 0, undefined>]>, undefined>;
3
+ readonly TUNGSTEN_SERVER_PORT: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
4
4
  readonly DEBUG: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
5
5
  }, undefined>;
6
6
  export type TungstenCorePrivateEnv = v.InferOutput<typeof tungstenCorePrivateEnvSchema>;
@@ -1,11 +1,11 @@
1
1
  import * as v from 'valibot';
2
2
  // non-mutative: looseObject passes unrecognised keys through untouched, so parsing against this
3
3
  // never drops or rewrites an app's own env values
4
- const portSchema = v.pipe(v.number(), v.gtValue(0));
4
+ const portSchema = v.pipe(v.number(), v.minValue(0));
5
5
  export const tungstenCorePrivateEnvSchema = v.looseObject({
6
6
  TUNGSTEN_SERVER_PORT: v.optional(portSchema),
7
7
  // FRONTEND_PROTO: v.optional(v.picklist(['http', 'https'])),
8
- // FRONTEND_HOST: v.optional(v.string()),
8
+ // FRONTEND_HOSTNAME: v.optional(v.string()),
9
9
  // FRONTEND_PORT: v.optional(portSchema),
10
10
  DEBUG: v.optional(v.boolean())
11
11
  // SUPPRESS: v.optional(v.object({
@@ -1,8 +1,8 @@
1
1
  import * as v from 'valibot';
2
2
  export declare const tungstenCorePublicEnvSchema: v.LooseObjectSchema<{
3
3
  readonly FRONTEND_PROTO: v.OptionalSchema<v.PicklistSchema<["http", "https"], undefined>, undefined>;
4
- readonly FRONTEND_HOST: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
5
- readonly FRONTEND_PORT: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.GtValueAction<number, 0, undefined>]>, undefined>;
4
+ readonly FRONTEND_HOSTNAME: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
5
+ readonly FRONTEND_PORT: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
6
6
  }, undefined>;
7
7
  export type TungstenCorePublicEnv = v.InferOutput<typeof tungstenCorePublicEnvSchema>;
8
8
  //# sourceMappingURL=tungstenCorePublicEnvSchema.d.ts.map
@@ -1,13 +1,13 @@
1
1
  import * as v from 'valibot';
2
- // FRONTEND_PROTO/FRONTEND_HOST/FRONTEND_PORT are tungsten's own fields (used to
2
+ // FRONTEND_PROTO/FRONTEND_HOSTNAME/FRONTEND_PORT are tungsten's own fields (used to
3
3
  // report the dev/prod server's own location - see DevServer.ts/ProdServer.ts).
4
4
  // Optional here because most apps keep them in the private env instead - see
5
5
  // tungstenCorePrivateEnvSchema.ts, which declares the same three fields. An
6
6
  // app is free to declare either or both; the servers check private first,
7
7
  // then public.
8
- const portSchema = v.pipe(v.number(), v.gtValue(0));
8
+ const portSchema = v.pipe(v.number(), v.minValue(0));
9
9
  export const tungstenCorePublicEnvSchema = v.looseObject({
10
10
  FRONTEND_PROTO: v.optional(v.picklist(['http', 'https'])),
11
- FRONTEND_HOST: v.optional(v.string()),
11
+ FRONTEND_HOSTNAME: v.optional(v.string()),
12
12
  FRONTEND_PORT: v.optional(portSchema)
13
13
  });
@@ -6,5 +6,5 @@ export declare class InternalStoreSchema {
6
6
  popMessages: PopMessage[];
7
7
  constructor(location: string, matchedRouteInfo: MatchedRouteInfo);
8
8
  }
9
- export type PartialInternalStoreSchema = Pick<InternalStoreSchema, 'location' | 'popMessages'> & Partial<Omit<InternalStoreSchema, 'location' | 'popMessages'>>;
9
+ export type PartialInternalStoreSchema = Pick<InternalStoreSchema, 'popMessages'> & Partial<Omit<InternalStoreSchema, 'popMessages'>>;
10
10
  //# sourceMappingURL=InternalStoreSchema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InternalStoreSchema.d.ts","sourceRoot":"","sources":["../../src/Store/InternalStoreSchema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD,qBAAa,mBAAmB;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,WAAW,EAAE,UAAU,EAAE,CAAK;gBAClB,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB;CAInE;AAGD,MAAM,MAAM,0BAA0B,GAChC,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,aAAa,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,aAAa,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"InternalStoreSchema.d.ts","sourceRoot":"","sources":["../../src/Store/InternalStoreSchema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD,qBAAa,mBAAmB;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,WAAW,EAAE,UAAU,EAAE,CAAK;gBAClB,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB;CAInE;AAGD,MAAM,MAAM,0BAA0B,GAChC,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,GACxC,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/dev.ts"],"names":[],"mappings":"AA6EA,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/dev.ts"],"names":[],"mappings":"AAiFA,OAAO,EAAE,CAAA"}
@@ -43,7 +43,9 @@ await sxyFramework.build('dev');
43
43
  // start a dev server
44
44
  const devServer = await sxyFramework.createDevServer();
45
45
  //cliOut('Dev server ready')
46
- const devServerLocation = await sxyFramework.profiler.timeProfileAsync('start dev server', () => devServer.start());
46
+ const {
47
+ publicOrigin
48
+ } = await sxyFramework.profiler.timeProfileAsync('start dev server', () => devServer.start());
47
49
  // devmon already restarts this process itself on a framework rebuild, so the warning
48
50
  // (which just tells you to restart manually) would be redundant noise under it - see devmon.ts.
49
51
  if (config.warnOnFrameworkChange && process.env.__TUNGSTEN_DEVMON !== 'true') {
@@ -54,6 +56,6 @@ if (config.warnOnFrameworkChange && process.env.__TUNGSTEN_DEVMON !== 'true') {
54
56
  if (boot) {
55
57
  cliOut('Booting to the dev site in your browser');
56
58
  // awaited only so it can be timed - open resolves once the browser process is spawned
57
- await sxyFramework.profiler.timeProfileAsync('boot browser', () => open(devServerLocation));
59
+ await sxyFramework.profiler.timeProfileAsync('boot browser', () => open(publicOrigin));
58
60
  }
59
61
  reportRunTotal('total (dev startup)');
@@ -1 +1 @@
1
- {"version":3,"file":"compileUserApp.d.ts","sourceRoot":"","sources":["../../src/build/compileUserApp.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAWtC,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAM1E,wBAAsB,cAAc,CAChC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAClE,QAAQ,GAAE,YAAwC,EAAE,KAAK,UAAQ,EAAE,KAAK,UAAQ,EAAE,KAAK,UAAQ,GAChG,OAAO,CAAC,eAAe,CAAC,CAkF1B"}
1
+ {"version":3,"file":"compileUserApp.d.ts","sourceRoot":"","sources":["../../src/build/compileUserApp.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAWtC,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAM1E,wBAAsB,cAAc,CAChC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAClE,QAAQ,GAAE,YAAwC,EAClD,KAAK,UAAQ,EAAE,KAAK,UAAQ,EAAE,KAAK,UAAQ,GAC5C,OAAO,CAAC,eAAe,CAAC,CAkF1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/components/Link.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAI3D,MAAM,MAAM,SAAS,GAAG;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,WAAW,CAAA;CACxB,CAAA;AAED,qBAAa,IAAK,SAAQ,uBAAuB,CAAC,SAAS,CAAC;IACxD,IAAI,SAIe;IACnB,KAAK,GAAI,OAAO,gBAAgB,UAgB/B;IACD,OAAO,uDAUN;CACJ"}
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/components/Link.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAG3D,MAAM,MAAM,SAAS,GAAG;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,WAAW,CAAA;CACxB,CAAA;AAED,qBAAa,IAAK,SAAQ,uBAAuB,CAAC,SAAS,CAAC;IACxD,IAAI,SAA+C;IACnD,KAAK,GAAI,OAAO,gBAAgB,UAgB/B;IACD,OAAO,uDAUN;CACJ"}
@@ -2,12 +2,11 @@ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object
2
2
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
3
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
4
  import { TungstenSimpleComponent } from "../Components.js";
5
- import { isProd } from '../isProd.js';
6
5
  import { jsx as _jsx } from "tungsten/jsx-runtime";
7
6
  export class Link extends TungstenSimpleComponent {
8
7
  constructor(...args) {
9
8
  super(...args);
10
- _defineProperty(this, "href", isProd && this.__instance.config.staticSite ? this.props.to === '/' ? this.__instance.config.siteBasePath + '/' : this.__instance.config.siteBasePath + this.props.to + '.html' : this.props.to);
9
+ _defineProperty(this, "href", this.__instance.routeKeyToUrl(this.props.to));
11
10
  _defineProperty(this, "click", (event /* Event */) => {
12
11
  // GUARD if control key is pressed, allow the link to be opened in a new tab
13
12
  // should this only apply on chrome?
@@ -1 +1 @@
1
- {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../../src/hydrate/hydrate.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAQnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAoCxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAO7C,OAAO,EAGH,KAAK,yBAAyB,EAEjC,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAiBlD,OAAO,EAC4B,KAAK,uBAAuB,EAC9D,MAAM,oCAAoC,CAAA;AAS3C,OAAO,0BAA0B,CAAA;AASjC,MAAM,MAAM,WAAW,GAAG;IACtB,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,uBAAuB,EAAE,CAAA;IAGrC,WAAW,EAAE,OAAO,CAAA;CACvB,CAAA;AACD,wBAAgB,sBAAsB,IAAI,WAAW,CAEpD;AAID,wBAAsB,OAAO,CACzB,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,yBAAyB,GAAG,IAAI,EAC/C,cAAc,EAAE,cAAc,iBAgEjC;AAyBD,wBAAsB,oBAAoB,CACtC,aAAa,SAAS,yBAAyB,CAAC,GAAG,EAAE,GAAG,CAAC,EAEzD,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,WAAW,EAIjB,KAAK,GAAE,YAAY,CAAC,aAAa,CAAC,CAAC,OAAO,CAAM,EAChD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,SAAS,CAAC,EAAE,OAAO,GACpB,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CA6DtC"}
1
+ {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../../src/hydrate/hydrate.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAQnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAoCxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAO7C,OAAO,EAGH,KAAK,yBAAyB,EAEjC,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAmBlD,OAAO,EAC4B,KAAK,uBAAuB,EAC9D,MAAM,oCAAoC,CAAA;AAS3C,OAAO,0BAA0B,CAAA;AASjC,MAAM,MAAM,WAAW,GAAG;IACtB,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,uBAAuB,EAAE,CAAA;IAGrC,WAAW,EAAE,OAAO,CAAA;CACvB,CAAA;AACD,wBAAgB,sBAAsB,IAAI,WAAW,CAEpD;AAID,wBAAsB,OAAO,CACzB,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,yBAAyB,GAAG,IAAI,EAC/C,cAAc,EAAE,cAAc,iBAkEjC;AAyBD,wBAAsB,oBAAoB,CACtC,aAAa,SAAS,yBAAyB,CAAC,GAAG,EAAE,GAAG,CAAC,EAEzD,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,WAAW,EAIjB,KAAK,GAAE,YAAY,CAAC,aAAa,CAAC,CAAC,OAAO,CAAM,EAChD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,SAAS,CAAC,EAAE,OAAO,GACpB,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CA6DtC"}
@@ -27,6 +27,8 @@ import { checkedValueToBoolean } from '../checkedValueToBoolean.js';
27
27
  import { Default404 } from "../routing/Default404.js";
28
28
  import { MatchedRoute } from '../routing/MatchedRoute.js';
29
29
  import { isDev } from '../isDev.js';
30
+ import { isProd } from '../isProd.js';
31
+ import { urlToRouteKey } from '../routing/routeUrl.js';
30
32
  import { warn } from '../appOutput.js';
31
33
  import { reconcileHydratedAttributes } from './reconcileHydratedAttributes.js';
32
34
  import { markOptionSelected } from '../markOptionSelected.js';
@@ -58,7 +60,7 @@ export async function hydrate(appRoutes, RootComponent, instanceConfig) {
58
60
  // happens next (a read of its value throws below). Rendered again at the end, for the count.
59
61
  if (isDev) renderDocInitErrorBanner();
60
62
  //console.log('hydration global data ', __tungsten_global_data__)
61
- const location = window.location.pathname;
63
+ const location = urlToRouteKey(window.location.pathname, instanceConfig.siteBasePath, isProd && instanceConfig.staticSite);
62
64
  const routes = typeof appRoutes === 'function' ? appRoutes(null) : appRoutes;
63
65
  const matchedRouteInfo = hydrationRouting(__tungsten_matched_route_info__, routes);
64
66
  const globalData = __tungsten_global_data__;
@@ -0,0 +1,4 @@
1
+ import type { SiteBasePath } from '../render/HeadData.js';
2
+ export declare function routeKeyToUrl(routeKey: string, siteBasePath: SiteBasePath, staticFiles: boolean): string;
3
+ export declare function urlToRouteKey(pathname: string, siteBasePath: SiteBasePath, staticFiles: boolean): string;
4
+ //# sourceMappingURL=routeUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeUrl.d.ts","sourceRoot":"","sources":["../../src/routing/routeUrl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAOzD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,CASxG;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,CAWxG"}
@@ -0,0 +1,23 @@
1
+ // staticFiles: the site is served as generated .html files (a prod static site)
2
+ const trimBase = siteBasePath => siteBasePath.replace(/\/$/, '');
3
+ export function routeKeyToUrl(routeKey, siteBasePath, staticFiles) {
4
+ const base = trimBase(siteBasePath);
5
+ if (!staticFiles) return base + routeKey;
6
+ const suffixIndex = routeKey.search(/[?#]/);
7
+ const path = suffixIndex === -1 ? routeKey : routeKey.slice(0, suffixIndex);
8
+ const suffix = suffixIndex === -1 ? '' : routeKey.slice(suffixIndex);
9
+ // a directory route links to the directory; the host serves its index.html
10
+ const file = path.endsWith('/') ? path : path + '.html';
11
+ return base + file + suffix;
12
+ }
13
+ export function urlToRouteKey(pathname, siteBasePath, staticFiles) {
14
+ const base = trimBase(siteBasePath);
15
+ let path = pathname;
16
+ if (base !== '' && (path === base || path.startsWith(base + '/'))) {
17
+ path = path.slice(base.length) || '/';
18
+ }
19
+ if (staticFiles) {
20
+ if (path.endsWith('/index.html')) path = path.slice(0, -'index.html'.length);else if (path.endsWith('.html')) path = path.slice(0, -'.html'.length);
21
+ }
22
+ return path;
23
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"staticGenFunctions.d.ts","sourceRoot":"","sources":["../../src/staticGen/staticGenFunctions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAGzE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,UAM1C;AACD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,UAMlE;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQnD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAM/E"}
1
+ {"version":3,"file":"staticGenFunctions.d.ts","sourceRoot":"","sources":["../../src/staticGen/staticGenFunctions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAIzE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,UAM1C;AACD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,UAElE;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQnD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAM/E"}
@@ -1,3 +1,4 @@
1
+ import { routeKeyToUrl } from '../routing/routeUrl.js';
1
2
  export function pathToFileName(path) {
2
3
  // Is this good?
3
4
  // /foo/ becomes /foo/index.html
@@ -5,10 +6,7 @@ export function pathToFileName(path) {
5
6
  if (path.endsWith('/')) return path + 'index.html';else return path + '.html';
6
7
  }
7
8
  export function pathToLink(path, siteBasePath) {
8
- // Is this good?
9
- // /foo/ becomes /foo/index.html
10
- // seems like a bodge
11
- if (path.endsWith('/')) return siteBasePath + path + 'index.html';else return siteBasePath + path + '.html';
9
+ return routeKeyToUrl(path, siteBasePath, true);
12
10
  }
13
11
  export function findLinks(content) {
14
12
  const matches = [...content.matchAll(/href="(.+?)"/g)].map(x => {
@@ -37,7 +37,9 @@ async function hostedRouting(options) {
37
37
  return {
38
38
  routes: options.routes,
39
39
  internalStore: {
40
- location: location ?? '/',
40
+ ...(location !== undefined ? {
41
+ location
42
+ } : {}),
41
43
  ...(matchedRouteInfo !== undefined ? {
42
44
  matchedRouteInfo
43
45
  } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"testingComponentPackage.d.ts","sourceRoot":"","sources":["../../src/testing/testingComponentPackage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AACnE,OAAO,KAAK,EAAuB,0BAA0B,EAAE,MAAM,iCAAiC,CAAA;AACtG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAElE,OAAO,EAAE,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAGtE,MAAM,MAAM,8BAA8B,GAAG;IAIzC,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IAG/B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,UAAU,CAAA;IAMvB,aAAa,CAAC,EAAE,0BAA0B,CAAA;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAGhC,SAAS,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IAIjC,WAAW,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAA;IAGrC,SAAS,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IACjC,QAAQ,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAA;IAG/B,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACvB,QAAQ,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAA;CAClC,CAAA;AASD,eAAO,MAAM,UAAU,GAAI,KAAK,EAAE,cAAc,KAAK;;;oBAK7B,KAAK;;;;CAK5B,CAAA;AAID,eAAO,MAAM,iBAAiB,GAAI,KAAK,EAAE,KAAK,MAAM;;eAEvC,KAAK;;;;gBAIJ,KAAK;CACjB,CAAA;AAuBF,eAAO,MAAM,uBAAuB,GAAI,KAAK,SAAS,MAAM,EACxD,OAAO,KAAK,EACZ,UAAS,8BAAmC,KAC7C,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAyClC,CAAA"}
1
+ {"version":3,"file":"testingComponentPackage.d.ts","sourceRoot":"","sources":["../../src/testing/testingComponentPackage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AACnE,OAAO,KAAK,EAAuB,0BAA0B,EAAE,MAAM,iCAAiC,CAAA;AACtG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAElE,OAAO,EAAE,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAItE,MAAM,MAAM,8BAA8B,GAAG;IAIzC,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IAG/B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,UAAU,CAAA;IAMvB,aAAa,CAAC,EAAE,0BAA0B,CAAA;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAGhC,SAAS,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IAIjC,WAAW,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAA;IAGrC,SAAS,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IACjC,QAAQ,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAA;IAG/B,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACvB,QAAQ,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAA;CAClC,CAAA;AASD,eAAO,MAAM,UAAU,GAAI,KAAK,EAAE,cAAc,KAAK;;;oBAK7B,KAAK;;;;CAK5B,CAAA;AAID,eAAO,MAAM,iBAAiB,GAAI,KAAK,EAAE,KAAK,MAAM;;eAEvC,KAAK;;;;gBAIJ,KAAK;CACjB,CAAA;AAuBF,eAAO,MAAM,uBAAuB,GAAI,KAAK,SAAS,MAAM,EACxD,OAAO,KAAK,EACZ,UAAS,8BAAmC,KAC7C,gBAAgB,CAAC,KAAK,EAAE,SAAS,CA6ClC,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { $trueStoreCell } from '../Store/makeStore.js';
2
+ import { routeKeyToUrl } from '../routing/routeUrl.js';
2
3
  const missing = key => {
3
4
  throw new Error(`testingComponentPackage: no ${key} supplied. Pass one in the options if the value is part` + ` of the test, or use createTestApp() for a component that needs a real app.`);
4
5
  };
@@ -88,6 +89,17 @@ export const testingComponentPackage = (props, options = {}) => ({
88
89
  redirect: options.redirect ?? (to => {
89
90
  missing(`redirect (component redirected to '${to}')`);
90
91
  }),
92
+ routeKeyToUrl: routeKey => {
93
+ const {
94
+ siteBasePath,
95
+ prod,
96
+ staticSite
97
+ } = {
98
+ ...defaultConfig,
99
+ ...options.config
100
+ };
101
+ return routeKeyToUrl(routeKey, siteBasePath, prod && staticSite);
102
+ },
91
103
  ...(options.trackWork !== undefined ? {
92
104
  trackWork: options.trackWork
93
105
  } : {})
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tungsten",
3
- "version": "0.5.8",
3
+ "version": "0.6.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -94,7 +94,7 @@
94
94
  "npm-run-all": "^4.1.5",
95
95
  "rimraf": "^5.0.10",
96
96
  "rollup-plugin-visualizer": "^5.14.0",
97
- "sxy-test-runner": "^2.4.12",
97
+ "sxy-test-runner": "^2.4.17",
98
98
  "typescript": "^6.0.3",
99
99
  "typescript-eslint": "^8.70.0"
100
100
  },
@@ -120,13 +120,14 @@
120
120
  "__build": "pnpm clean && pnpm build-prep && pnpm build-watch",
121
121
  "build": "run-s -c clean build-prep build-watch",
122
122
  "clean": "rimraf intermed dist",
123
+ "build-prep": "pnpm build-ts-once",
124
+ "build-watch": "run-p build-ts build-babel",
125
+ "build-quick": "pnpm build-watch",
126
+ "build-tm": "rimraf dist && tscmon --on-first-success \"pnpm build-babel\"",
123
127
  "build-once": "rimraf intermed dist && pnpm build-ts-once && pnpm build-babel-once && pnpm build-component-styles",
124
128
  "build-component-styles": "node scripts/buildComponentStyles.ts",
125
129
  "build-vendor": "node scripts/bundleVendor.ts",
126
130
  "build-once-nd": "rimraf intermed dist.building && pnpm build-ts-once && pnpm build-babel-staged && node scripts/syncDist.ts && node scripts/writeBuildMarker.ts",
127
- "build-quick": "pnpm build-watch",
128
- "build-prep": "pnpm build-ts-once",
129
- "build-watch": "run-p build-ts build-babel",
130
131
  "build-ts": "tscmon",
131
132
  "build-ts-once": "tsc",
132
133
  "build-babel": "node scripts/watchBabelAndMark.ts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "lockfile": {
3
- "size": 239826,
4
- "mtimeMs": 1789513233215.041
3
+ "size": 238795,
4
+ "mtimeMs": 1789635426367.559
5
5
  },
6
6
  "specifiers": {
7
7
  "@babel/core": "babel-core",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=auth.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/auth/ref/auth.ts"],"names":[],"mappings":""}
@@ -1,23 +0,0 @@
1
- // export function doLogIn(req, user) {
2
- // req.session.loggedIn = true
3
- // req.session.userId = user.id
4
- // req.session.userType = user.type
5
- export {};
6
- // //console.log('session after doLogIn', req.session)
7
- // }
8
- // export function doLogOut(req) {
9
- // req.session.loggedIn = false
10
- // delete req.session.userId
11
- // delete req.session.userType
12
- // }
13
- // export function permittedToUseBackendReq(req) {
14
- // return req.session.loggedIn && permittedToUseBackend({ type: req.session.userType })
15
- // }
16
- // export function permittedToUseBackend(user) {
17
- // return [
18
- // 'administrator',
19
- // 'editor',
20
- // 'writer',
21
- // 'guest'
22
- // ].includes(user.type)
23
- // }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=checkPasswordResetToken.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"checkPasswordResetToken.d.ts","sourceRoot":"","sources":["../../../src/auth/ref/checkPasswordResetToken.ts"],"names":[],"mappings":""}
@@ -1,27 +0,0 @@
1
- // import crypto from 'crypto'
2
- // import { PasswordResetToken } from '../models/PasswordResetToken.js'
3
- export {};
4
- // export async function checkPasswordResetToken(user, token: string) {
5
- // const hash = crypto.createHash('sha256').update(user.id + token).digest('base64url')
6
- // const passwordResetToken
7
- // = await PasswordResetToken.find({
8
- // userId: user.id,
9
- // hash
10
- // })
11
- // if (passwordResetToken === null) {
12
- // return {
13
- // success: false,
14
- // reason: 'Invalid'
15
- // }
16
- // } else if (passwordResetToken.expiresAt < new Date()) {
17
- // return {
18
- // success: false,
19
- // reason: 'Expired'
20
- // }
21
- // } else {
22
- // return {
23
- // success: true,
24
- // reason: 'Valid'
25
- // }
26
- // }
27
- // }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=createPasswordResetToken.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createPasswordResetToken.d.ts","sourceRoot":"","sources":["../../../src/auth/ref/createPasswordResetToken.ts"],"names":[],"mappings":""}
@@ -1,19 +0,0 @@
1
- // import crypto from 'crypto'
2
- // import { PasswordResetToken } from '../models/PasswordResetToken.js'
3
- export {};
4
- // export function createPasswordResetToken(user) {
5
- // return new Promise( (resolve, reject) => {
6
- // crypto.randomBytes(16, async (err, buffer) => {
7
- // if (err) reject(err)
8
- // const token = buffer.toString('base64url')
9
- // const hash = crypto.createHash('sha256').update(user.id + token).digest('base64url')
10
- // const passwordResetToken = new PasswordResetToken
11
- // passwordResetToken.userId = user.id
12
- // passwordResetToken.hash = hash
13
- // const _1HourInMs = 1000*60*60
14
- // passwordResetToken.expiresAt = new Date(Date.now() + _1HourInMs)
15
- // await passwordResetToken.create()
16
- // resolve(token)
17
- // })
18
- // })
19
- // }