@forklaunch/express 1.2.37 → 1.2.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -603,6 +603,8 @@ function serveExpress(app, openTelemetryCollector, opts = {}) {
603
603
  strictContentLength: false,
604
604
  writeProcessing: () => {
605
605
  },
606
+ writeInformation: () => {
607
+ },
606
608
  chunkedEncoding: false,
607
609
  shouldKeepAlive: true,
608
610
  useChunkedEncodingByDefault: true,
@@ -1905,14 +1907,66 @@ var import_common2 = require("@forklaunch/common");
1905
1907
  var import_http = require("@forklaunch/core/http");
1906
1908
  var import_busboy = __toESM(require("busboy"));
1907
1909
  var import_express = __toESM(require("express"));
1910
+ var DEFAULT_CONTENT_TYPES = {
1911
+ json: "application/json",
1912
+ text: "text/plain",
1913
+ urlEncoded: "application/x-www-form-urlencoded",
1914
+ file: "application/octet-stream",
1915
+ multipart: "multipart/form-data"
1916
+ };
1908
1917
  function contentParse(options2) {
1909
- const jsonParser = import_express.default.json(options2?.json);
1910
- const urlencodedParser = import_express.default.urlencoded({
1911
- extended: true,
1912
- ...options2?.urlencoded
1913
- });
1914
- const textParser = import_express.default.text(options2?.text);
1915
- const rawParser = import_express.default.raw(options2?.raw);
1918
+ let resolvedOptions;
1919
+ const parserCache = /* @__PURE__ */ new Map();
1920
+ const captureRawBody = (base) => {
1921
+ const userVerify = base?.verify;
1922
+ return (req, res, buf, encoding) => {
1923
+ userVerify?.(req, res, buf, encoding);
1924
+ req._rawBody = buf;
1925
+ };
1926
+ };
1927
+ const buildParser = (parserType, contentTypeOverride) => {
1928
+ const typeOverride = contentTypeOverride ? { type: contentTypeOverride } : {};
1929
+ switch (parserType) {
1930
+ case "json":
1931
+ return import_express.default.json({
1932
+ ...resolvedOptions?.json,
1933
+ verify: captureRawBody(resolvedOptions?.json),
1934
+ ...typeOverride
1935
+ });
1936
+ case "urlEncoded":
1937
+ return import_express.default.urlencoded({
1938
+ extended: true,
1939
+ ...resolvedOptions?.urlencoded,
1940
+ verify: captureRawBody(resolvedOptions?.urlencoded),
1941
+ ...typeOverride
1942
+ });
1943
+ case "text":
1944
+ return import_express.default.text({
1945
+ ...resolvedOptions?.text,
1946
+ verify: captureRawBody(resolvedOptions?.text),
1947
+ ...typeOverride
1948
+ });
1949
+ case "file":
1950
+ return import_express.default.raw({
1951
+ ...resolvedOptions?.raw,
1952
+ verify: captureRawBody(resolvedOptions?.raw),
1953
+ ...typeOverride
1954
+ });
1955
+ default:
1956
+ (0, import_common2.isNever)(parserType);
1957
+ throw new Error("Unsupported parser type: " + parserType);
1958
+ }
1959
+ };
1960
+ const parserFor = (parserType, contentType) => {
1961
+ const contentTypeOverride = contentType !== DEFAULT_CONTENT_TYPES[parserType] ? contentType : void 0;
1962
+ const cacheKey = `${parserType}:${contentTypeOverride ?? ""}`;
1963
+ let parser = parserCache.get(cacheKey);
1964
+ if (!parser) {
1965
+ parser = buildParser(parserType, contentTypeOverride);
1966
+ parserCache.set(cacheKey, parser);
1967
+ }
1968
+ return parser;
1969
+ };
1916
1970
  return async (req, res, next) => {
1917
1971
  try {
1918
1972
  const coercedRequest = req;
@@ -1929,24 +1983,39 @@ function contentParse(options2) {
1929
1983
  if (!discriminatedBody) {
1930
1984
  return next();
1931
1985
  }
1986
+ if (!resolvedOptions) {
1987
+ const globalOptions = coercedRequest._globalOptions?.();
1988
+ resolvedOptions = {
1989
+ busboy: globalOptions?.busboy ?? options2?.busboy,
1990
+ text: globalOptions?.text ?? options2?.text,
1991
+ json: globalOptions?.json ?? options2?.json,
1992
+ urlencoded: globalOptions?.urlencoded ?? options2?.urlencoded,
1993
+ raw: globalOptions?.raw ?? options2?.raw
1994
+ };
1995
+ }
1932
1996
  switch (discriminatedBody.parserType) {
1933
1997
  case "json":
1934
- return jsonParser(req, res, next);
1935
1998
  case "urlEncoded":
1936
- return urlencodedParser(req, res, next);
1937
1999
  case "text":
1938
- return textParser(req, res, next);
2000
+ return parserFor(
2001
+ discriminatedBody.parserType,
2002
+ discriminatedBody.contentType
2003
+ )(req, res, next);
1939
2004
  case "file":
1940
- return rawParser(req, res, async (err) => {
1941
- if (err) {
1942
- return next(err);
2005
+ return parserFor("file", discriminatedBody.contentType)(
2006
+ req,
2007
+ res,
2008
+ async (err) => {
2009
+ if (err) {
2010
+ return next(err);
2011
+ }
2012
+ next();
1943
2013
  }
1944
- next();
1945
- });
2014
+ );
1946
2015
  case "multipart": {
1947
2016
  const bb = (0, import_busboy.default)({
1948
2017
  headers: req.headers,
1949
- ...options2?.busboy
2018
+ ...resolvedOptions?.busboy
1950
2019
  });
1951
2020
  const body = {};
1952
2021
  bb.on("file", (fieldname, file) => {
package/lib/index.mjs CHANGED
@@ -577,6 +577,8 @@ function serveExpress(app, openTelemetryCollector, opts = {}) {
577
577
  strictContentLength: false,
578
578
  writeProcessing: () => {
579
579
  },
580
+ writeInformation: () => {
581
+ },
580
582
  chunkedEncoding: false,
581
583
  shouldKeepAlive: true,
582
584
  useChunkedEncodingByDefault: true,
@@ -1879,14 +1881,66 @@ import { isNever } from "@forklaunch/common";
1879
1881
  import { discriminateBody } from "@forklaunch/core/http";
1880
1882
  import Busboy from "busboy";
1881
1883
  import express from "express";
1884
+ var DEFAULT_CONTENT_TYPES = {
1885
+ json: "application/json",
1886
+ text: "text/plain",
1887
+ urlEncoded: "application/x-www-form-urlencoded",
1888
+ file: "application/octet-stream",
1889
+ multipart: "multipart/form-data"
1890
+ };
1882
1891
  function contentParse(options2) {
1883
- const jsonParser = express.json(options2?.json);
1884
- const urlencodedParser = express.urlencoded({
1885
- extended: true,
1886
- ...options2?.urlencoded
1887
- });
1888
- const textParser = express.text(options2?.text);
1889
- const rawParser = express.raw(options2?.raw);
1892
+ let resolvedOptions;
1893
+ const parserCache = /* @__PURE__ */ new Map();
1894
+ const captureRawBody = (base) => {
1895
+ const userVerify = base?.verify;
1896
+ return (req, res, buf, encoding) => {
1897
+ userVerify?.(req, res, buf, encoding);
1898
+ req._rawBody = buf;
1899
+ };
1900
+ };
1901
+ const buildParser = (parserType, contentTypeOverride) => {
1902
+ const typeOverride = contentTypeOverride ? { type: contentTypeOverride } : {};
1903
+ switch (parserType) {
1904
+ case "json":
1905
+ return express.json({
1906
+ ...resolvedOptions?.json,
1907
+ verify: captureRawBody(resolvedOptions?.json),
1908
+ ...typeOverride
1909
+ });
1910
+ case "urlEncoded":
1911
+ return express.urlencoded({
1912
+ extended: true,
1913
+ ...resolvedOptions?.urlencoded,
1914
+ verify: captureRawBody(resolvedOptions?.urlencoded),
1915
+ ...typeOverride
1916
+ });
1917
+ case "text":
1918
+ return express.text({
1919
+ ...resolvedOptions?.text,
1920
+ verify: captureRawBody(resolvedOptions?.text),
1921
+ ...typeOverride
1922
+ });
1923
+ case "file":
1924
+ return express.raw({
1925
+ ...resolvedOptions?.raw,
1926
+ verify: captureRawBody(resolvedOptions?.raw),
1927
+ ...typeOverride
1928
+ });
1929
+ default:
1930
+ isNever(parserType);
1931
+ throw new Error("Unsupported parser type: " + parserType);
1932
+ }
1933
+ };
1934
+ const parserFor = (parserType, contentType) => {
1935
+ const contentTypeOverride = contentType !== DEFAULT_CONTENT_TYPES[parserType] ? contentType : void 0;
1936
+ const cacheKey = `${parserType}:${contentTypeOverride ?? ""}`;
1937
+ let parser = parserCache.get(cacheKey);
1938
+ if (!parser) {
1939
+ parser = buildParser(parserType, contentTypeOverride);
1940
+ parserCache.set(cacheKey, parser);
1941
+ }
1942
+ return parser;
1943
+ };
1890
1944
  return async (req, res, next) => {
1891
1945
  try {
1892
1946
  const coercedRequest = req;
@@ -1903,24 +1957,39 @@ function contentParse(options2) {
1903
1957
  if (!discriminatedBody) {
1904
1958
  return next();
1905
1959
  }
1960
+ if (!resolvedOptions) {
1961
+ const globalOptions = coercedRequest._globalOptions?.();
1962
+ resolvedOptions = {
1963
+ busboy: globalOptions?.busboy ?? options2?.busboy,
1964
+ text: globalOptions?.text ?? options2?.text,
1965
+ json: globalOptions?.json ?? options2?.json,
1966
+ urlencoded: globalOptions?.urlencoded ?? options2?.urlencoded,
1967
+ raw: globalOptions?.raw ?? options2?.raw
1968
+ };
1969
+ }
1906
1970
  switch (discriminatedBody.parserType) {
1907
1971
  case "json":
1908
- return jsonParser(req, res, next);
1909
1972
  case "urlEncoded":
1910
- return urlencodedParser(req, res, next);
1911
1973
  case "text":
1912
- return textParser(req, res, next);
1974
+ return parserFor(
1975
+ discriminatedBody.parserType,
1976
+ discriminatedBody.contentType
1977
+ )(req, res, next);
1913
1978
  case "file":
1914
- return rawParser(req, res, async (err) => {
1915
- if (err) {
1916
- return next(err);
1979
+ return parserFor("file", discriminatedBody.contentType)(
1980
+ req,
1981
+ res,
1982
+ async (err) => {
1983
+ if (err) {
1984
+ return next(err);
1985
+ }
1986
+ next();
1917
1987
  }
1918
- next();
1919
- });
1988
+ );
1920
1989
  case "multipart": {
1921
1990
  const bb = Busboy({
1922
1991
  headers: req.headers,
1923
- ...options2?.busboy
1992
+ ...resolvedOptions?.busboy
1924
1993
  });
1925
1994
  const body = {};
1926
1995
  bb.on("file", (fieldname, file) => {
@@ -1 +1 @@
1
- {"version":3,"file":"bun.serve.shim.d.ts","sourceRoot":"","sources":["../../../src/cluster/bun.serve.shim.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,OAAO,EAIR,MAAM,SAAS,CAAC;AA4KjB,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,sBAAsB,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,EACjE,IAAI,GAAE,YAAiB;;;;;;;QAs1CjB,IAAI;QACJ,MAAM;QACN,OAAO;;;;;gBAQC,MAAM,YAAY,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI;kBAO5C,MAAM,YAAY,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI;kBAO9C,MAAM,WAAW,OAAO,EAAE;qBAIjB,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI;6BAUnB,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI;EAgBtE"}
1
+ {"version":3,"file":"bun.serve.shim.d.ts","sourceRoot":"","sources":["../../../src/cluster/bun.serve.shim.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,OAAO,EAIR,MAAM,SAAS,CAAC;AA4KjB,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,YAAY,CAC1B,GAAG,EAAE,OAAO,EACZ,sBAAsB,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,EACjE,IAAI,GAAE,YAAiB;;;;;;;QAu1CjB,IAAI;QACJ,MAAM;QACN,OAAO;;;;;gBAQC,MAAM,YAAY,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI;kBAO5C,MAAM,YAAY,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI;kBAO9C,MAAM,WAAW,OAAO,EAAE;qBAIjB,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI;6BAUnB,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI;EAgBtE"}
@@ -2,12 +2,13 @@ import { AnySchemaValidator } from '@forklaunch/validator';
2
2
  import { Options, OptionsJson, OptionsText, OptionsUrlencoded } from 'body-parser';
3
3
  import { BusboyConfig } from 'busboy';
4
4
  import { NextFunction, Request, Response } from 'express';
5
- declare function contentParse<SV extends AnySchemaValidator>(options?: {
5
+ type ContentParseOptions = {
6
6
  busboy?: BusboyConfig;
7
7
  text?: OptionsText;
8
8
  json?: OptionsJson;
9
9
  urlencoded?: OptionsUrlencoded;
10
10
  raw?: Options;
11
- }): (req: Request, res: Response, next: NextFunction) => Promise<void>;
11
+ };
12
+ declare function contentParse<SV extends AnySchemaValidator>(options?: ContentParseOptions): (req: Request, res: Response, next: NextFunction) => Promise<unknown>;
12
13
  export { contentParse };
13
14
  //# sourceMappingURL=content.parse.middleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content.parse.middleware.d.ts","sourceRoot":"","sources":["../../../src/middleware/content.parse.middleware.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACX,iBAAiB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAe,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAgB,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAMnE,iBAAS,YAAY,CAAC,EAAE,SAAS,kBAAkB,EAAE,OAAO,CAAC,EAAE;IAC7D,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,SASoB,OAAO,OAAO,QAAQ,QAAQ,YAAY,mBAoF9D;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"content.parse.middleware.d.ts","sourceRoot":"","sources":["../../../src/middleware/content.parse.middleware.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACX,iBAAiB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAe,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAgB,EACd,YAAY,EACZ,OAAO,EAEP,QAAQ,EACT,MAAM,SAAS,CAAC;AAMjB,KAAK,mBAAmB,GAAG;IACzB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAuBF,iBAAS,YAAY,CAAC,EAAE,SAAS,kBAAkB,EACjD,OAAO,CAAC,EAAE,mBAAmB,SAyEV,OAAO,OAAO,QAAQ,QAAQ,YAAY,sBAqG9D;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forklaunch/express",
3
- "version": "1.2.37",
3
+ "version": "1.2.39",
4
4
  "description": "Forklaunch framework for express.",
5
5
  "homepage": "https://github.com/forklaunch/forklaunch-js#readme",
6
6
  "bugs": {
@@ -29,20 +29,20 @@
29
29
  ],
30
30
  "dependencies": {
31
31
  "@modelcontextprotocol/sdk": "^1.30.0",
32
- "@scalar/express-api-reference": "^0.10.11",
32
+ "@scalar/express-api-reference": "^0.10.13",
33
33
  "@types/multer": "^2.2.0",
34
34
  "body-parser": "^2.3.0",
35
35
  "busboy": "^1.6.0",
36
36
  "cors": "^2.8.6",
37
37
  "express": "^5.2.1",
38
- "fastmcp": "^4.12.1",
38
+ "fastmcp": "^4.14.1",
39
39
  "multer": "2.2.0",
40
40
  "qs": "^6.15.3",
41
41
  "range-parser": "^1.3.0",
42
42
  "swagger-ui-express": "^5.0.1",
43
- "@forklaunch/common": "^1.2.22",
44
- "@forklaunch/core": "^1.5.9",
45
- "@forklaunch/validator": "^1.2.23"
43
+ "@forklaunch/common": "^1.2.23",
44
+ "@forklaunch/core": "^1.5.12",
45
+ "@forklaunch/validator": "^1.2.24"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@eslint/js": "^10.0.1",
@@ -51,9 +51,9 @@
51
51
  "@types/busboy": "^1.5.4",
52
52
  "@types/cors": "^2.8.19",
53
53
  "@types/express": "^5.0.6",
54
- "@types/express-serve-static-core": "^5.1.2",
54
+ "@types/express-serve-static-core": "^5.1.3",
55
55
  "@types/jest": "^30.0.0",
56
- "@types/node": "^26.1.2",
56
+ "@types/node": "^26.2.0",
57
57
  "@types/qs": "^6.15.1",
58
58
  "@types/range-parser": "^1.2.7",
59
59
  "@types/swagger-ui-express": "^4.1.8",
@@ -66,7 +66,7 @@
66
66
  "tsup": "^8.5.1",
67
67
  "typedoc": "^0.28.20",
68
68
  "typescript": "npm:@typescript/typescript6@^6.0.2",
69
- "typescript-eslint": "^8.65.0"
69
+ "typescript-eslint": "^8.67.0"
70
70
  },
71
71
  "scripts": {
72
72
  "build": "tsgo --noEmit && tsup index.ts --format cjs,esm --no-splitting --tsconfig tsconfig.json --outDir lib --clean && tsgo -p tsconfig.build.json --emitDeclarationOnly",