@intuitionrobotics/thunderstorm 2.0.12 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/app-backend/core/Storm.d.ts +11 -3
  2. package/dist/app-backend/core/Storm.d.ts.map +1 -1
  3. package/dist/app-backend/core/Storm.js +63 -16
  4. package/dist/app-backend/core/Storm.js.map +1 -1
  5. package/dist/app-backend/modules/SlackModule.d.ts +2 -3
  6. package/dist/app-backend/modules/SlackModule.d.ts.map +1 -1
  7. package/dist/app-backend/modules/SlackModule.js +13 -8
  8. package/dist/app-backend/modules/SlackModule.js.map +1 -1
  9. package/dist/app-backend/modules/http/AxiosHttpModule.d.ts +0 -1
  10. package/dist/app-backend/modules/http/AxiosHttpModule.d.ts.map +1 -1
  11. package/dist/app-backend/modules/http/AxiosHttpModule.js +2 -10
  12. package/dist/app-backend/modules/http/AxiosHttpModule.js.map +1 -1
  13. package/dist/app-backend/modules/proxy/RemoteProxy.d.ts +4 -3
  14. package/dist/app-backend/modules/proxy/RemoteProxy.d.ts.map +1 -1
  15. package/dist/app-backend/modules/proxy/RemoteProxy.js +10 -13
  16. package/dist/app-backend/modules/proxy/RemoteProxy.js.map +1 -1
  17. package/dist/app-backend/modules/proxy/RemoteProxyCaller.d.ts +2 -1
  18. package/dist/app-backend/modules/proxy/RemoteProxyCaller.d.ts.map +1 -1
  19. package/dist/app-backend/modules/proxy/RemoteProxyCaller.js +21 -14
  20. package/dist/app-backend/modules/proxy/RemoteProxyCaller.js.map +1 -1
  21. package/dist/app-backend/modules/server/ApiFunction.d.ts +52 -0
  22. package/dist/app-backend/modules/server/ApiFunction.d.ts.map +1 -0
  23. package/dist/app-backend/modules/server/ApiFunction.js +63 -0
  24. package/dist/app-backend/modules/server/ApiFunction.js.map +1 -0
  25. package/dist/app-backend/modules/server/HttpServer.d.ts +16 -10
  26. package/dist/app-backend/modules/server/HttpServer.d.ts.map +1 -1
  27. package/dist/app-backend/modules/server/HttpServer.js +57 -29
  28. package/dist/app-backend/modules/server/HttpServer.js.map +1 -1
  29. package/dist/backend.d.ts +1 -0
  30. package/dist/backend.d.ts.map +1 -1
  31. package/dist/backend.js +1 -0
  32. package/dist/backend.js.map +1 -1
  33. package/dist/shared/BaseHttpModule.d.ts +6 -3
  34. package/dist/shared/BaseHttpModule.d.ts.map +1 -1
  35. package/dist/shared/BaseHttpModule.js +15 -4
  36. package/dist/shared/BaseHttpModule.js.map +1 -1
  37. package/dist/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +4 -4
@@ -0,0 +1,52 @@
1
+ import { type Express, type Router } from "express";
2
+ import { type DeployableFunction, FirebaseFunction, type FirebaseFunctionOptions } from "@intuitionrobotics/firebase/backend-functions";
3
+ export type ApiFunctionArgs = {
4
+ /**
5
+ * A pre-built Express app (e.g. with app-specific middleware already added).
6
+ * ApiFunction still runs the framework server setup (compression/CORS/json)
7
+ * and mounts the router on it — AFTER anything already registered.
8
+ *
9
+ * Contract: a provided app carries MIDDLEWARE ONLY, never routes. Express is
10
+ * registration-order sensitive — a route registered on the app before this
11
+ * instance is built bypasses the framework chain (no CORS headers, no
12
+ * compression). Routes belong in the router; app-level extras (debug
13
+ * endpoints etc.) must be registered AFTER Storm.build(). And each instance
14
+ * needs its OWN app — never share one Express app between two instances.
15
+ */
16
+ app?: Express;
17
+ /** The route table this API serves (an Express Router built by the app). */
18
+ router?: Router;
19
+ /** Runtime options: memory, timeoutSeconds, generation ("v1"/"v2"), region, ... */
20
+ options?: FirebaseFunctionOptions;
21
+ };
22
+ /**
23
+ * An Express-backed HTTPS Cloud Function as a *regular module* — registered via
24
+ * `Storm.addModules(...)` like any other function, named after the module
25
+ * (no more hardcoded "api"), and instantiable as many times as needed:
26
+ *
27
+ * const Api = new ApiFunction("api", {router: rootRouter});
28
+ * const ApiTest = new ApiFunction("api_test", {router: rootRouter, options: {generation: "v2"}});
29
+ * new Storm().addModules(Api, ApiTest, ...modules).build();
30
+ *
31
+ * `api_test` deploys the exact same code as a separate function
32
+ * (`firebase deploy --only functions:api_test`) — a deployed test environment,
33
+ * or a safe gen-2 canary, without touching the real `api`.
34
+ *
35
+ * Server config (baseUrl/bodyParserLimit/cors) resolves through the module
36
+ * config store: the shared "HttpServer" slice applies to every instance, and
37
+ * the instance's own slice (config[name]) layers on top.
38
+ *
39
+ * When no ApiFunction is registered, Storm builds an implicit default named
40
+ * "api" from its legacy builder methods (setApp/setRoutes/setApiFunctionOptions)
41
+ * — registering ANY instance disables that default.
42
+ */
43
+ export declare class ApiFunction extends FirebaseFunction {
44
+ private readonly providedApp?;
45
+ private router?;
46
+ private _app?;
47
+ constructor(name: string, args?: ApiFunctionArgs);
48
+ setRoutes(router: Router): this;
49
+ private get app();
50
+ getFunction: () => DeployableFunction;
51
+ }
52
+ //# sourceMappingURL=ApiFunction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApiFunction.d.ts","sourceRoot":"","sources":["../../../../src/main/app-backend/modules/server/ApiFunction.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,OAAO,EAAE,KAAK,MAAM,EAAC,MAAM,SAAS,CAAC;AAClD,OAAO,EACH,KAAK,kBAAkB,EAEvB,gBAAgB,EAChB,KAAK,uBAAuB,EAC/B,MAAM,+CAA+C,CAAC;AAGvD,MAAM,MAAM,eAAe,GAAG;IAC1B;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,OAAO,CAAC,EAAE,uBAAuB,CAAC;CACrC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,WACT,SAAQ,gBAAgB;IAExB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAU;IACvC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,IAAI,CAAC,CAAU;gBAEX,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB;IAMpD,SAAS,CAAC,MAAM,EAAE,MAAM;IAQxB,OAAO,KAAK,GAAG,GAcd;IAED,WAAW,QAAO,kBAAkB,CAUlC;CACL"}
@@ -0,0 +1,63 @@
1
+ import express from "express";
2
+ import {} from "express";
3
+ import { Firebase_ExpressFunction, FirebaseFunction } from "@intuitionrobotics/firebase/backend-functions";
4
+ import { HttpServer_Class } from "./HttpServer.js";
5
+ /**
6
+ * An Express-backed HTTPS Cloud Function as a *regular module* — registered via
7
+ * `Storm.addModules(...)` like any other function, named after the module
8
+ * (no more hardcoded "api"), and instantiable as many times as needed:
9
+ *
10
+ * const Api = new ApiFunction("api", {router: rootRouter});
11
+ * const ApiTest = new ApiFunction("api_test", {router: rootRouter, options: {generation: "v2"}});
12
+ * new Storm().addModules(Api, ApiTest, ...modules).build();
13
+ *
14
+ * `api_test` deploys the exact same code as a separate function
15
+ * (`firebase deploy --only functions:api_test`) — a deployed test environment,
16
+ * or a safe gen-2 canary, without touching the real `api`.
17
+ *
18
+ * Server config (baseUrl/bodyParserLimit/cors) resolves through the module
19
+ * config store: the shared "HttpServer" slice applies to every instance, and
20
+ * the instance's own slice (config[name]) layers on top.
21
+ *
22
+ * When no ApiFunction is registered, Storm builds an implicit default named
23
+ * "api" from its legacy builder methods (setApp/setRoutes/setApiFunctionOptions)
24
+ * — registering ANY instance disables that default.
25
+ */
26
+ export class ApiFunction extends FirebaseFunction {
27
+ providedApp;
28
+ router;
29
+ _app;
30
+ constructor(name, args = {}) {
31
+ super(name, undefined, undefined, args.options ?? {});
32
+ this.providedApp = args.app;
33
+ this.router = args.router;
34
+ }
35
+ setRoutes(router) {
36
+ this.router = router;
37
+ return this;
38
+ }
39
+ // Built lazily at getFunction() time: framework middleware (compression/CORS/
40
+ // json — via HttpServer, whose config getter layers the shared "HttpServer"
41
+ // slice under this instance's own slice) + the instance's router.
42
+ get app() {
43
+ if (this._app)
44
+ return this._app;
45
+ const app = this.providedApp ?? express();
46
+ const httpServer = new HttpServer_Class(app, this.config);
47
+ httpServer.setup();
48
+ // The function name supplies the URL prefix on Cloud Functions (the `api`
49
+ // function serves `…/api/**`), so the router always mounts at root.
50
+ if (this.router)
51
+ httpServer.mountRouter(this.router);
52
+ return this._app = app;
53
+ }
54
+ getFunction = () => {
55
+ // Delegate the actual trigger wiring (v1/v2 branch, labels, lifecycle) to
56
+ // the low-level express wrapper, resolving generation lazily.
57
+ const expressFunction = new Firebase_ExpressFunction(this.app, this.getName(), undefined, undefined, { ...this.options, generation: this.generation });
58
+ this.onStart.forEach(hook => expressFunction.addOnStart(hook));
59
+ this.onDestroy.forEach(hook => expressFunction.addOnDestroy(hook));
60
+ return expressFunction.getFunction();
61
+ };
62
+ }
63
+ //# sourceMappingURL=ApiFunction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApiFunction.js","sourceRoot":"","sources":["../../../../src/main/app-backend/modules/server/ApiFunction.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAA2B,MAAM,SAAS,CAAC;AAClD,OAAO,EAEH,wBAAwB,EACxB,gBAAgB,EAEnB,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AAsBjD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,WACT,SAAQ,gBAAgB;IAEP,WAAW,CAAW;IAC/B,MAAM,CAAU;IAChB,IAAI,CAAW;IAEvB,YAAY,IAAY,EAAE,OAAwB,EAAE;QAChD,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,SAAS,CAAC,MAAc;QACpB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,8EAA8E;IAC9E,4EAA4E;IAC5E,kEAAkE;IAClE,IAAY,GAAG;QACX,IAAI,IAAI,CAAC,IAAI;YACT,OAAO,IAAI,CAAC,IAAI,CAAC;QAErB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1D,UAAU,CAAC,KAAK,EAAE,CAAC;QAEnB,0EAA0E;QAC1E,oEAAoE;QACpE,IAAI,IAAI,CAAC,MAAM;YACX,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAExC,OAAO,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IAC3B,CAAC;IAED,WAAW,GAAG,GAAuB,EAAE;QACnC,0EAA0E;QAC1E,8DAA8D;QAC9D,MAAM,eAAe,GAAG,IAAI,wBAAwB,CAChD,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAC9C,EAAC,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAC,CAAC,CAAC;QAEpD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QACnE,OAAO,eAAe,CAAC,WAAW,EAAE,CAAC;IACzC,CAAC,CAAC;CACL"}
@@ -2,31 +2,37 @@ import { Module } from "@intuitionrobotics/ts-common";
2
2
  import type { ObjectTS } from "@intuitionrobotics/ts-common";
3
3
  import type { ApiResponse, HttpRequestData } from "./server-api.js";
4
4
  import { ApiException } from "../../exceptions.js";
5
- import type { Express, ExpressRequest, ExpressRequestHandler } from "../../utils/types.js";
5
+ import type { Express, ExpressRequest } from "../../utils/types.js";
6
6
  type ConfigType = {
7
- port: number;
8
7
  baseUrl: string;
9
8
  cors: {
10
9
  origins?: string[];
11
10
  methods?: string[];
12
- headers: string[];
11
+ headers?: string[];
13
12
  exposedHeaders?: string[];
14
13
  };
15
- ssl: {
16
- key: string;
17
- cert: string;
18
- };
19
14
  bodyParserLimit: number | string;
20
15
  };
21
16
  export type HttpErrorHandler = (requestData: HttpRequestData, error: ApiException) => Promise<string>;
22
17
  export type ServerApi_Middleware = (request: ExpressRequest, data: HttpRequestData, response: ApiResponse, scopes: string[]) => Promise<ObjectTS | void>;
23
18
  export declare class HttpServer_Class extends Module<ConfigType> {
24
- private static readonly expressMiddleware;
25
19
  private readonly express;
26
20
  constructor(_express: Express, configElement: ConfigType);
27
- static addMiddleware(middleware: ExpressRequestHandler): typeof HttpServer_Class;
28
21
  getBaseUrl(): string;
29
- init(): void;
22
+ /**
23
+ * Collapse duplicate slashes in a URL's PATH only — the query string is
24
+ * preserved verbatim (a naive global replace mangles values like
25
+ * `?redirect=https://...`).
26
+ */
27
+ static normalizeUrlPath(url: string): string;
28
+ /**
29
+ * Collapse duplicate slashes and trim the trailing slash WITHOUT mangling
30
+ * the protocol separator. (The old in-line replace turned `http://` into
31
+ * `http:/` — which is why configs grew `http:////` workarounds. Both forms
32
+ * normalize correctly now.)
33
+ */
34
+ static normalizeBaseUrl(baseUrl: string): string;
35
+ setup(): void;
30
36
  mountRouter(router: import("express").Router, urlPrefix?: string): void;
31
37
  }
32
38
  export declare class HeaderKey {
@@ -1 +1 @@
1
- {"version":3,"file":"HttpServer.d.ts","sourceRoot":"","sources":["../../../../src/main/app-backend/modules/server/HttpServer.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,MAAM,EAAC,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,8BAA8B,CAAC;AAE3D,OAAO,KAAK,EAAC,WAAW,EAAE,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAGjD,OAAO,KAAK,EAAC,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAC,MAAM,sBAAsB,CAAC;AAezF,KAAK,UAAU,GAAG;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;KAC5B,CAAA;IACD,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAClC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;CACnC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtG,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AACxJ,qBAAa,gBACT,SAAQ,MAAM,CAAC,UAAU,CAAC;IAE1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAA+B;IACxE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEtB,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU;IAMxD,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,qBAAqB;IAKtD,UAAU;IAIV,IAAI;IAkEG,WAAW,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW;CAM9E;AAED,qBAAa,SAAS;IAClB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,GAAG,EAAE,MAAM,EAAE,YAAY,GAAE,MAAY;IAKnD,GAAG,CAAC,OAAO,EAAE,cAAc;CAO9B"}
1
+ {"version":3,"file":"HttpServer.d.ts","sourceRoot":"","sources":["../../../../src/main/app-backend/modules/server/HttpServer.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,MAAM,EAAC,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,8BAA8B,CAAC;AAE3D,OAAO,KAAK,EAAC,WAAW,EAAE,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAGjD,OAAO,KAAK,EAAC,OAAO,EAAE,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAelE,KAAK,UAAU,GAAG;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;KAC5B,CAAA;IACD,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;CACnC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtG,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AACxJ,qBAAa,gBACT,SAAQ,MAAM,CAAC,UAAU,CAAC;IAE1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEtB,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU;IAMxD,UAAU;IAIV;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAO5C;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAUhD,KAAK;IAyEE,WAAW,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW;CAM9E;AAED,qBAAa,SAAS;IAClB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,GAAG,EAAE,MAAM,EAAE,YAAY,GAAE,MAAY;IAKnD,GAAG,CAAC,OAAO,EAAE,cAAc;CAO9B"}
@@ -16,53 +16,84 @@ const ExposedHeaders = [
16
16
  HeaderKey_JWT
17
17
  ];
18
18
  export class HttpServer_Class extends Module {
19
- static expressMiddleware = [];
20
19
  express;
21
20
  constructor(_express, configElement) {
22
21
  super("HttpServer");
23
22
  this.express = _express;
24
23
  this.setConfig(configElement);
25
24
  }
26
- static addMiddleware(middleware) {
27
- HttpServer_Class.expressMiddleware.push(middleware);
28
- return this;
29
- }
30
25
  getBaseUrl() {
31
26
  return this.config.baseUrl;
32
27
  }
33
- init() {
28
+ /**
29
+ * Collapse duplicate slashes in a URL's PATH only — the query string is
30
+ * preserved verbatim (a naive global replace mangles values like
31
+ * `?redirect=https://...`).
32
+ */
33
+ static normalizeUrlPath(url) {
34
+ const queryIndex = url.indexOf("?");
35
+ const path = queryIndex === -1 ? url : url.substring(0, queryIndex);
36
+ const query = queryIndex === -1 ? "" : url.substring(queryIndex);
37
+ return path.replace(/\/{2,}/g, "/") + query;
38
+ }
39
+ /**
40
+ * Collapse duplicate slashes and trim the trailing slash WITHOUT mangling
41
+ * the protocol separator. (The old in-line replace turned `http://` into
42
+ * `http:/` — which is why configs grew `http:////` workarounds. Both forms
43
+ * normalize correctly now.)
44
+ */
45
+ static normalizeBaseUrl(baseUrl) {
46
+ const match = baseUrl.match(/^([a-z]+:)\/+(.*)$/i);
47
+ const [protocol, rest] = match ? [`${match[1]}//`, match[2]] : ["", baseUrl];
48
+ return (protocol + rest.replace(/\/{2,}/g, "/")).replace(/\/+$/, "");
49
+ }
50
+ // Express middleware/CORS wiring for the api function. Called explicitly by
51
+ // ApiFunction when the instance's app is resolved — this is api-function
52
+ // infra, deliberately eager (and cheap), unlike app modules which must not
53
+ // override the (never-called) init().
54
+ setup() {
34
55
  this.setMinLevel(ServerApi.isDebug ? LogLevel.Verbose : LogLevel.Info);
35
- const baseUrl = this.config.baseUrl;
36
- if (baseUrl) {
37
- if (baseUrl.endsWith("/"))
38
- this.config.baseUrl = baseUrl.substring(0, baseUrl.length - 1);
39
- this.config.baseUrl = baseUrl.replace(/\/\//g, "/");
40
- }
41
- this.express.use((req, res, next) => {
56
+ if (this.config.baseUrl)
57
+ this.config.baseUrl = HttpServer_Class.normalizeBaseUrl(this.config.baseUrl);
58
+ this.express.use((req, _res, next) => {
42
59
  if (req)
43
- req.url = req.url.replace(/\/\//g, "/");
60
+ req.url = HttpServer_Class.normalizeUrlPath(req.url);
44
61
  next();
45
62
  });
63
+ // On Cloud Functions the platform pre-parses JSON bodies before the app
64
+ // runs, so this only matters for standalone/local `listen` setups.
46
65
  const parserLimit = this.config.bodyParserLimit;
47
66
  if (parserLimit)
48
67
  this.express.use(express.json({ limit: parserLimit }));
49
68
  this.express.use(compression());
50
69
  const myCors = this.config.cors || {};
51
- if (!myCors.exposedHeaders)
52
- myCors.exposedHeaders = ExposedHeaders;
53
- myCors.headers = DefaultHeaders.reduce((toRet, item) => {
54
- if (!toRet.includes(item))
55
- addItemToArray(toRet, item);
56
- return toRet;
57
- }, myCors.headers || []);
58
70
  const corsOptions = {
59
71
  credentials: true, // Allow cookies/auth headers
60
72
  optionsSuccessStatus: 200,
61
- exposedHeaders: myCors.exposedHeaders
73
+ // DO NOT remove/change lightly: the frontend reads these off
74
+ // responses (e.g. user-account's AccountModule pulls the refreshed
75
+ // JWT and the function execution id via getResponseHeader).
76
+ exposedHeaders: myCors.exposedHeaders || ExposedHeaders
62
77
  };
78
+ // Only wired when configured — otherwise the cors package keeps its
79
+ // defaults: allowedHeaders reflects the preflight's
80
+ // Access-Control-Request-Headers, methods = GET,HEAD,PUT,PATCH,POST,DELETE.
81
+ // (These two knobs existed in config but were never connected before.)
82
+ if (myCors.headers?.length)
83
+ corsOptions.allowedHeaders = DefaultHeaders.reduce((toRet, item) => {
84
+ if (!toRet.includes(item))
85
+ addItemToArray(toRet, item);
86
+ return toRet;
87
+ }, [...myCors.headers]);
88
+ if (myCors.methods?.length)
89
+ corsOptions.methods = myCors.methods;
63
90
  // Handle origin configuration
64
91
  if (!myCors.origins || myCors.origins.length === 0) {
65
- // No origins specified - allow all
92
+ // No origins configured: reflect ANY origin — combined with
93
+ // credentials this is wide open. Fine for local dev; deployed
94
+ // environments must configure cors.origins.
95
+ this.logWarning("CORS: no cors.origins configured — reflecting any origin WITH credentials. " +
96
+ "Set 'HttpServer.cors.origins' (or the ApiFunction instance's config slice) in deployed environments.");
66
97
  corsOptions.origin = true;
67
98
  }
68
99
  else {
@@ -71,9 +102,6 @@ export class HttpServer_Class extends Module {
71
102
  }
72
103
  const corsWithOptions = cors(corsOptions);
73
104
  this.express.use(corsWithOptions);
74
- for (const middleware of HttpServer_Class.expressMiddleware) {
75
- this.express.use(middleware);
76
- }
77
105
  this.express.options('*', corsWithOptions);
78
106
  }
79
107
  // v2.0 entrypoint: mount a user-built Express Router directly onto the
@@ -82,9 +110,9 @@ export class HttpServer_Class extends Module {
82
110
  // method just `app.use`s it. No RouteResolver, no fs walk, no codegen
83
111
  // walker — Express owns the route table.
84
112
  //
85
- // `urlPrefix` is optional and matches what `Storm.setInitialRoutePath`
86
- // gave callers: a local-dev URL prefix (e.g. "/api"). When empty, the
87
- // router mounts at the application root.
113
+ // The router mounts at the application root: on Cloud Functions the URL
114
+ // prefix comes from the function name (the `api` function serves `…/api/**`).
115
+ // `urlPrefix` is kept as an optional escape hatch but is normally unused.
88
116
  mountRouter(router, urlPrefix = "") {
89
117
  if (urlPrefix)
90
118
  this.express.use(urlPrefix, router);
@@ -1 +1 @@
1
- {"version":3,"file":"HttpServer.js","sourceRoot":"","sources":["../../../../src/main/app-backend/modules/server/HttpServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HttpServer.js","sourceRoot":"","sources":["../../../../src/main/app-backend/modules/server/HttpServer.ts"],"names":[],"mappings":"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"}
package/dist/backend.d.ts CHANGED
@@ -5,6 +5,7 @@ export * from "./app-backend/modules/FirestoreBackupScheduler.js";
5
5
  export * from "./app-backend/modules/server/server-errors.js";
6
6
  export * from "./app-backend/modules/server/server-api.js";
7
7
  export * from "./app-backend/modules/server/HttpServer.js";
8
+ export * from "./app-backend/modules/server/ApiFunction.js";
8
9
  export { HttpMethod } from "./shared/types.js";
9
10
  export * from "./app-backend/modules/http/AxiosHttpModule.js";
10
11
  export * from "./app-backend/modules/http/types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/main/backend.ts"],"names":[],"mappings":"AAqBA,cAAc,kDAAkD,CAAC;AACjE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,4CAA4C,CAAC;AAI3D,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAC7C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAE5C,cAAc,0CAA0C,CAAC;AACzD,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/main/backend.ts"],"names":[],"mappings":"AAqBA,cAAc,kDAAkD,CAAC;AACjE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,6CAA6C,CAAC;AAI5D,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAC7C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAE5C,cAAc,0CAA0C,CAAC;AACzD,cAAc,oBAAoB,CAAC"}
package/dist/backend.js CHANGED
@@ -25,6 +25,7 @@ export * from "./app-backend/modules/FirestoreBackupScheduler.js";
25
25
  export * from "./app-backend/modules/server/server-errors.js";
26
26
  export * from "./app-backend/modules/server/server-api.js";
27
27
  export * from "./app-backend/modules/server/HttpServer.js";
28
+ export * from "./app-backend/modules/server/ApiFunction.js";
28
29
  // Re-exported from /shared so endpoint files can write
29
30
  // `import {ServerApi, HttpMethod} from "@intuitionrobotics/thunderstorm/backend"`
30
31
  // without a second import line.
@@ -1 +1 @@
1
- {"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/main/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,cAAc,kDAAkD,CAAC;AACjE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,4CAA4C,CAAC;AAC3D,uDAAuD;AACvD,kFAAkF;AAClF,gCAAgC;AAChC,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAC7C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,wGAAwG;AACxG,cAAc,0CAA0C,CAAC;AACzD,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/main/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,cAAc,kDAAkD,CAAC;AACjE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,6CAA6C,CAAC;AAC5D,uDAAuD;AACvD,kFAAkF;AAClF,gCAAgC;AAChC,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAC7C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,wGAAwG;AACxG,cAAc,0CAA0C,CAAC;AACzD,cAAc,oBAAoB,CAAC"}
@@ -10,14 +10,17 @@ export type HttpConfig = {
10
10
  export declare abstract class BaseHttpModule_Class<Config extends HttpConfig = HttpConfig> extends Module<Config> {
11
11
  private defaultErrorHandlers;
12
12
  private defaultSuccessHandlers;
13
- protected origin?: string;
14
- protected timeout: number;
13
+ private _origin?;
14
+ private _timeout?;
15
15
  private readonly defaultResponseHandler;
16
16
  protected readonly defaultHeaders: {
17
17
  [s: string]: (() => string | string[]) | string | string[];
18
18
  };
19
19
  constructor(name: string);
20
- init(): void;
20
+ protected get origin(): string | undefined;
21
+ protected set origin(origin: string | undefined);
22
+ protected get timeout(): number;
23
+ protected set timeout(timeout: number);
21
24
  shouldCompress(): boolean | undefined;
22
25
  addDefaultHeader(key: string, header: (() => string | string[]) | string | string[]): void;
23
26
  abstract createRequest<Binder extends ApiTypeBinder<U, R, B, P, E>, U extends string = Binder["url"], R = Binder["response"], B = Binder["body"], P extends QueryParams = Binder["queryParams"], E extends void | object = Binder["error"]>(method: HttpMethod, key: string, data?: string): BaseHttpRequest<Binder>;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseHttpModule.d.ts","sourceRoot":"","sources":["../../src/main/shared/BaseHttpModule.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAC,KAAK,aAAa,EAAsB,UAAU,EAAE,KAAK,WAAW,EAAC,MAAM,YAAY,CAAC;AAEhG,OAAO,EAAiB,MAAM,EAAuB,MAAM,8BAA8B,CAAC;AAE1F,OAAO,EAAC,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,KAAK,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAE9G,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED,8BAAsB,oBAAoB,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,CAC7E,SAAQ,MAAM,CAAC,MAAM,CAAC;IAEtB,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,sBAAsB,CAA+B;IAE7D,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,OAAO,EAAE,MAAM,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAM;gBAE3F,IAAI,EAAE,MAAM;IAKxB,IAAI;IAIJ,cAAc;IAId,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE;IAInF,QAAQ,CAAC,aAAa,CAAC,MAAM,SAAS,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9D,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,EAChC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,EACtB,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,EAClB,CAAC,SAAS,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,EAC7C,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;IAEvH,8BAA8B,GAAI,aAAa,eAAe,CAAC,GAAG,CAAC,aAOjE;IAEF,yBAAyB,CAAC,sBAAsB,EAAE,eAAe;IAIjE,4BAA4B,CAAC,sBAAsB,EAAE,eAAe;IAIpE,gBAAgB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,CAAC,EAAE;IAIjE,kBAAkB,CAAC,oBAAoB,EAAE,qBAAqB,EAAE;IAIhE,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAc5C;IAEF,oBAAoB,EAAE,qBAAqB,CAUzC;CACL"}
1
+ {"version":3,"file":"BaseHttpModule.d.ts","sourceRoot":"","sources":["../../src/main/shared/BaseHttpModule.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAC,KAAK,aAAa,EAAsB,UAAU,EAAE,KAAK,WAAW,EAAC,MAAM,YAAY,CAAC;AAEhG,OAAO,EAAiB,MAAM,EAAuB,MAAM,8BAA8B,CAAC;AAE1F,OAAO,EAAC,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,KAAK,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAE9G,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED,8BAAsB,oBAAoB,CAAC,MAAM,SAAS,UAAU,GAAG,UAAU,CAC7E,SAAQ,MAAM,CAAC,MAAM,CAAC;IAEtB,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,sBAAsB,CAA+B;IAI7D,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAM;gBAE3F,IAAI,EAAE,MAAM;IAKxB,SAAS,KAAK,MAAM,IAAI,MAAM,GAAG,SAAS,CAEzC;IAED,SAAS,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAE9C;IAED,SAAS,KAAK,OAAO,IAAI,MAAM,CAE9B;IAED,SAAS,KAAK,OAAO,CAAC,OAAO,EAAE,MAAM,EAEpC;IAED,cAAc;IAId,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE;IAInF,QAAQ,CAAC,aAAa,CAAC,MAAM,SAAS,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9D,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,EAChC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,EACtB,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,EAClB,CAAC,SAAS,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,EAC7C,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;IAEvH,8BAA8B,GAAI,aAAa,eAAe,CAAC,GAAG,CAAC,aAOjE;IAEF,yBAAyB,CAAC,sBAAsB,EAAE,eAAe;IAIjE,4BAA4B,CAAC,sBAAsB,EAAE,eAAe;IAIpE,gBAAgB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,CAAC,EAAE;IAIjE,kBAAkB,CAAC,oBAAoB,EAAE,qBAAqB,EAAE;IAIhE,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAc5C;IAEF,oBAAoB,EAAE,qBAAqB,CAUzC;CACL"}
@@ -28,16 +28,27 @@ import { BaseHttpRequest } from "./BaseHttpRequest.js";
28
28
  export class BaseHttpModule_Class extends Module {
29
29
  defaultErrorHandlers = [];
30
30
  defaultSuccessHandlers = [];
31
- origin;
32
- timeout = 10000;
31
+ // origin/timeout fall back to config lazily (was init()); explicit assignments
32
+ // by subclasses still win via the setters.
33
+ _origin;
34
+ _timeout;
33
35
  defaultResponseHandler = [];
34
36
  defaultHeaders = {};
35
37
  constructor(name) {
36
38
  super(name);
37
39
  this.setDefaultConfig({ compress: true });
38
40
  }
39
- init() {
40
- this.timeout = this.config.timeout || this.timeout;
41
+ get origin() {
42
+ return this._origin ?? this.config.origin;
43
+ }
44
+ set origin(origin) {
45
+ this._origin = origin;
46
+ }
47
+ get timeout() {
48
+ return this._timeout ?? this.config.timeout ?? 10000;
49
+ }
50
+ set timeout(timeout) {
51
+ this._timeout = timeout;
41
52
  }
42
53
  shouldCompress() {
43
54
  return this.config.compress;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseHttpModule.js","sourceRoot":"","sources":["../../src/main/shared/BaseHttpModule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseHttpModule.js","sourceRoot":"","sources":["../../src/main/shared/BaseHttpModule.ts"],"names":[],"mappings":"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"}