@thi.ng/server 0.12.21 → 0.12.23

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/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![Mastodon Follow](https://img.shields.io/mastodon/follow/109331703950160316?domain=https%3A%2F%2Fmastodon.thi.ng&style=social)](https://mastodon.thi.ng/@toxi)
8
8
 
9
9
  > [!NOTE]
10
- > This is one of 213 standalone projects, maintained as part
10
+ > This is one of 214 standalone projects, maintained as part
11
11
  > of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo
12
12
  > and anti-framework.
13
13
  >
package/api.d.ts CHANGED
@@ -140,7 +140,7 @@ export interface RequestCtx {
140
140
  /**
141
141
  * Parsed query string params (aka URL search params).
142
142
  */
143
- query: Record<string, any>;
143
+ query: ParsedFormData;
144
144
  /**
145
145
  * Parsed cookies, if any.
146
146
  */
@@ -150,6 +150,9 @@ export interface RequestCtx {
150
150
  */
151
151
  session?: ServerSession;
152
152
  }
153
+ export type ParsedFormData = {
154
+ [id: string]: string | string[] | ParsedFormData;
155
+ };
153
156
  export type HandlerResult = MaybePromise<void>;
154
157
  export type PreInterceptorResult = MaybePromise<boolean>;
155
158
  export type PostInterceptorResult = MaybePromise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/server",
3
- "version": "0.12.21",
3
+ "version": "0.12.23",
4
4
  "description": "Minimal HTTP server with declarative routing, static file serving and freely extensible via pre/post interceptors",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -8,7 +8,8 @@
8
8
  "sideEffects": false,
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://github.com/thi-ng/umbrella.git"
11
+ "url": "git+https://github.com/thi-ng/umbrella.git",
12
+ "directory": "packages/server"
12
13
  },
13
14
  "homepage": "https://thi.ng/server",
14
15
  "funding": [
@@ -39,25 +40,25 @@
39
40
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
40
41
  },
41
42
  "dependencies": {
42
- "@thi.ng/api": "^8.12.12",
43
- "@thi.ng/arrays": "^2.14.5",
44
- "@thi.ng/cache": "^2.3.61",
45
- "@thi.ng/checks": "^3.8.2",
46
- "@thi.ng/errors": "^2.6.1",
47
- "@thi.ng/file-io": "^2.2.22",
48
- "@thi.ng/leaky-bucket": "^0.2.24",
49
- "@thi.ng/logger": "^3.2.11",
50
- "@thi.ng/mime": "^2.8.4",
51
- "@thi.ng/paths": "^5.2.31",
52
- "@thi.ng/router": "^4.1.53",
53
- "@thi.ng/strings": "^3.9.33",
54
- "@thi.ng/timestamp": "^1.1.31",
55
- "@thi.ng/uuid": "^1.1.44"
43
+ "@thi.ng/api": "^8.12.14",
44
+ "@thi.ng/arrays": "^2.14.7",
45
+ "@thi.ng/cache": "^2.3.63",
46
+ "@thi.ng/checks": "^3.8.4",
47
+ "@thi.ng/errors": "^2.6.3",
48
+ "@thi.ng/file-io": "^2.2.24",
49
+ "@thi.ng/leaky-bucket": "^0.2.26",
50
+ "@thi.ng/logger": "^3.2.13",
51
+ "@thi.ng/mime": "^2.8.6",
52
+ "@thi.ng/paths": "^5.2.33",
53
+ "@thi.ng/router": "^4.1.55",
54
+ "@thi.ng/strings": "^3.9.35",
55
+ "@thi.ng/timestamp": "^1.1.33",
56
+ "@thi.ng/uuid": "^1.1.46"
56
57
  },
57
58
  "devDependencies": {
58
- "@types/node": "^24.10.1",
59
- "esbuild": "^0.27.0",
60
- "typedoc": "^0.28.14",
59
+ "@types/node": "^24.10.9",
60
+ "esbuild": "^0.27.2",
61
+ "typedoc": "^0.28.16",
61
62
  "typescript": "^5.9.3"
62
63
  },
63
64
  "keywords": [
@@ -167,5 +168,5 @@
167
168
  "status": "alpha",
168
169
  "year": 2024
169
170
  },
170
- "gitHead": "deb511294f7a120091b654af0ff7e8a399a465b3\n"
171
+ "gitHead": "4bd1b9d8ae52ba32b90a1b9a55d329c708ca7865\n"
171
172
  }
@@ -1,6 +1,33 @@
1
1
  import type { IncomingMessage } from "node:http";
2
- export declare const parseSearchParams: (params: URLSearchParams) => any;
3
- export declare const parseQuerystring: (url: string) => Record<string, any>;
4
- export declare const parseRequestFormData: (req: IncomingMessage) => Promise<Record<string, any>>;
5
- export declare const parseFormData: (body: string) => Record<string, any>;
2
+ import type { ParsedFormData } from "../api.js";
3
+ export declare const parseSearchParams: (params: URLSearchParams) => ParsedFormData;
4
+ /**
5
+ * Parses given URL's query string {@link parseFormData}. Any prefix
6
+ * before/including the first `?` will be ignored.
7
+ *
8
+ * @param url
9
+ */
10
+ export declare const parseQuerystring: (url: string) => ParsedFormData;
11
+ export declare const parseRequestFormData: (req: IncomingMessage) => Promise<ParsedFormData>;
12
+ /**
13
+ * Parses given URI-encoded string of key-value pairs into a
14
+ * {@link ParsedFormData} object. Throws an error if there're syntax/nesting
15
+ * errors.
16
+ *
17
+ * @remarks
18
+ * Supports the following syntax:
19
+ *
20
+ * - `key=value`
21
+ * - `key[]=value`: append value to `key` array
22
+ * - `key[a]=value`: set value `a` in object `key`
23
+ * - `key[a][b]=value`: set nested value in object `key`
24
+ * - `key[a][]=value`: append value to nested array in object `key`
25
+ *
26
+ * Ignores attempts to manipulate a JS prototype chain (via
27
+ * [`isProtoPath()`](https://docs.thi.ng/umbrella/checks/functions/isProtoPath.html)),
28
+ * i.e. `foo[__proto__][bar]=42` will be skipped.
29
+ *
30
+ * @param body
31
+ */
32
+ export declare const parseFormData: (body: string) => ParsedFormData;
6
33
  //# sourceMappingURL=formdata.d.ts.map
package/utils/formdata.js CHANGED
@@ -2,10 +2,10 @@ import { isArray, isProtoPath } from "@thi.ng/checks";
2
2
  import { illegalArgs } from "@thi.ng/errors";
3
3
  import { setInUnsafe, updateInUnsafe } from "@thi.ng/paths";
4
4
  const parseSearchParams = (params) => {
5
- const acc = {};
5
+ let acc = {};
6
6
  for (const [k, v] of params) {
7
- if (k.includes("[")) return parseObjectVal(acc, k, v);
8
- if (!isProtoPath(k)) acc[k] = v;
7
+ if (k.includes("[")) acc = parseObjectVal(acc, k, v);
8
+ else if (!isProtoPath(k)) acc[k] = v;
9
9
  }
10
10
  return acc;
11
11
  };