@nestia/fetcher 13.0.4 → 14.0.1

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
@@ -60,7 +60,7 @@ Check out the document in the [website](https://nestia.io/docs/):
60
60
  ### 🏠 Home
61
61
  - [Introduction](https://nestia.io/docs/)
62
62
  - [Setup](https://nestia.io/docs/setup/)
63
- - [Pure TypeScript](https://nestia.io/docs/pure)
63
+ - [Pure TypeScript](https://nestia.io/docs/core/TypedBody/)
64
64
 
65
65
  ### 📖 Features
66
66
  - Core Library
@@ -61,8 +61,9 @@ export declare namespace IPropagation {
61
61
  data: BodyData;
62
62
  headers: Record<string, string | string[]>;
63
63
  }
64
- /** Range of status codes by the first digit. */
65
- export type StatusRange<T extends "2XX" | "3XX" | "4XX" | "5XX"> = T extends 0 ? IntRange<200, 299> : T extends 3 ? IntRange<300, 399> : T extends 4 ? IntRange<400, 499> : IntRange<500, 599>;
64
+ /** Range of status codes by the first digit, `"4XX"` for `400` to `499`. */
65
+ export type StatusRange<T extends "2XX" | "3XX" | "4XX" | "5XX"> = T extends "2XX" ? IntRange<200, 300> : T extends "3XX" ? IntRange<300, 400> : T extends "4XX" ? IntRange<400, 500> : IntRange<500, 600>;
66
+ /** Integers from `F` up to, not including, `T`. */
66
67
  type IntRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;
67
68
  type Enumerate<N extends number, Acc extends number[] = []> = Acc["length"] extends N ? Acc[number] : Enumerate<N, [...Acc, Acc["length"]]>;
68
69
  export {};
@@ -2,12 +2,18 @@ export declare namespace NestiaSimulator {
2
2
  interface IProps {
3
3
  host: string;
4
4
  path: string;
5
- method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
6
- contentType: string;
5
+ method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD";
6
+ /**
7
+ * Content type of the route's success response, `null` for one without a
8
+ * body such as `HEAD`'s. The simulated 400 is JSON whatever it is, as the
9
+ * server's is.
10
+ */
11
+ contentType: string | null;
7
12
  }
8
13
  const assert: (props: IProps) => {
9
14
  param: (name: string) => <T>(task: () => T) => void;
10
15
  query: <T>(task: () => T) => void;
11
16
  body: <T>(task: () => T) => void;
17
+ headers: <T>(task: () => T) => void;
12
18
  };
13
19
  }
@@ -10,6 +10,7 @@ var NestiaSimulator;
10
10
  param: param(props),
11
11
  query: query(props),
12
12
  body: body(props),
13
+ headers: headers(props),
13
14
  };
14
15
  };
15
16
  const param = (props) => (name) => (task) => {
@@ -17,6 +18,7 @@ var NestiaSimulator;
17
18
  };
18
19
  const query = (props) => (task) => validate(() => "Request query parameters are not following the promised type.")(props)(task);
19
20
  const body = (props) => (task) => validate(() => "Request body is not following the promised type.")(props)(task);
21
+ const headers = (props) => (task) => validate(() => "Request headers are not following the promised type.")(props)(task);
20
22
  const validate = (message, path) => (props) => (task) => {
21
23
  try {
22
24
  task();
@@ -24,7 +26,7 @@ var NestiaSimulator;
24
26
  catch (exp) {
25
27
  if (isTypeGuardError(exp))
26
28
  throw new HttpError_1.HttpError(props.method, (0, join_host_and_path_1.join_host_and_path)(props.host, props.path), 400, {
27
- "Content-Type": props.contentType,
29
+ "Content-Type": "application/json",
28
30
  }, JSON.stringify({
29
31
  method: exp.method,
30
32
  path: path !== null && path !== void 0 ? path : exp.path,
@@ -1 +1 @@
1
- {"version":3,"file":"NestiaSimulator.js","sourceRoot":"","sources":["../src/NestiaSimulator.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,sEAAmE;AAEnE,IAAiB,eAAe,CAgE/B;AAhED,WAAiB,eAAe;IAQjB,sBAAM,GAAG,CAAC,KAAa,EAAE,EAAE;QACtC,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;YACnB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;YACnB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC;SAClB,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,KAAK,GACT,CAAC,KAAa,EAAE,EAAE,CAClB,CAAC,IAAY,EAAE,EAAE,CACjB,CAAI,IAAa,EAAQ,EAAE;QACzB,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,IAAI,YAAY,GAAG,CAAC,QAAQ,QAAQ,CAAC,CACvE,KAAK,CACN,CAAC,IAAI,CAAC,CAAC;IACV,CAAC,CAAC;IAEJ,MAAM,KAAK,GACT,CAAC,KAAa,EAAE,EAAE,CAClB,CAAI,IAAa,EAAQ,EAAE,CACzB,QAAQ,CACN,GAAG,EAAE,CAAC,+DAA+D,CACtE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IAEnB,MAAM,IAAI,GACR,CAAC,KAAa,EAAE,EAAE,CAClB,CAAI,IAAa,EAAQ,EAAE,CACzB,QAAQ,CAAC,GAAG,EAAE,CAAC,kDAAkD,CAAC,CAAC,KAAK,CAAC,CACvE,IAAI,CACL,CAAC;IAEN,MAAM,QAAQ,GACZ,CAAC,OAAwC,EAAE,IAAa,EAAE,EAAE,CAC5D,CAAC,KAAa,EAAE,EAAE,CAClB,CAAI,IAAa,EAAQ,EAAE;QACzB,IAAI,CAAC;YACH,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,gBAAgB,CAAC,GAAG,CAAC;gBACvB,MAAM,IAAI,qBAAS,CACjB,KAAK,CAAC,MAAM,EACZ,IAAA,uCAAkB,EAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAC1C,GAAG,EACH;oBACE,cAAc,EAAE,KAAK,CAAC,WAAW;iBAClC,EACD,IAAI,CAAC,SAAS,CAAC;oBACb,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,IAAI,EAAE,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,GAAG,CAAC,IAAI;oBACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC;iBACtB,CAAC,CACH,CAAC;YACJ,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACN,CAAC,EAhEgB,eAAe,aAAf,eAAe,GAAf,eAAe,QAgE/B;AAED,MAAM,gBAAgB,GAAG,CAAC,KAAU,EAA2B,EAAE,CAC/D,QAAQ,KAAK,OAAO,KAAK,CAAC,MAAM;IAChC,CAAC,SAAS,KAAK,KAAK,CAAC,IAAI,IAAI,QAAQ,KAAK,OAAO,KAAK,CAAC,IAAI,CAAC;IAC5D,QAAQ,KAAK,OAAO,KAAK,CAAC,QAAQ;IAClC,QAAQ,KAAK,OAAO,KAAK,CAAC,IAAI;IAC9B,QAAQ,KAAK,OAAO,KAAK,CAAC,OAAO;IACjC,CAAC,SAAS,KAAK,KAAK,CAAC,KAAK,IAAI,QAAQ,KAAK,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"NestiaSimulator.js","sourceRoot":"","sources":["../src/NestiaSimulator.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,sEAAmE;AAEnE,IAAiB,eAAe,CA8E/B;AA9ED,WAAiB,eAAe;IAcjB,sBAAM,GAAG,CAAC,KAAa,EAAE,EAAE;QACtC,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;YACnB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;YACnB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC;YACjB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC;SACxB,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,KAAK,GACT,CAAC,KAAa,EAAE,EAAE,CAClB,CAAC,IAAY,EAAE,EAAE,CACjB,CAAI,IAAa,EAAQ,EAAE;QACzB,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,IAAI,YAAY,GAAG,CAAC,QAAQ,QAAQ,CAAC,CACvE,KAAK,CACN,CAAC,IAAI,CAAC,CAAC;IACV,CAAC,CAAC;IAEJ,MAAM,KAAK,GACT,CAAC,KAAa,EAAE,EAAE,CAClB,CAAI,IAAa,EAAQ,EAAE,CACzB,QAAQ,CACN,GAAG,EAAE,CAAC,+DAA+D,CACtE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IAEnB,MAAM,IAAI,GACR,CAAC,KAAa,EAAE,EAAE,CAClB,CAAI,IAAa,EAAQ,EAAE,CACzB,QAAQ,CAAC,GAAG,EAAE,CAAC,kDAAkD,CAAC,CAAC,KAAK,CAAC,CACvE,IAAI,CACL,CAAC;IAEN,MAAM,OAAO,GACX,CAAC,KAAa,EAAE,EAAE,CAClB,CAAI,IAAa,EAAQ,EAAE,CACzB,QAAQ,CAAC,GAAG,EAAE,CAAC,sDAAsD,CAAC,CACpE,KAAK,CACN,CAAC,IAAI,CAAC,CAAC;IAEZ,MAAM,QAAQ,GACZ,CAAC,OAAwC,EAAE,IAAa,EAAE,EAAE,CAC5D,CAAC,KAAa,EAAE,EAAE,CAClB,CAAI,IAAa,EAAQ,EAAE;QACzB,IAAI,CAAC;YACH,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,gBAAgB,CAAC,GAAG,CAAC;gBACvB,MAAM,IAAI,qBAAS,CACjB,KAAK,CAAC,MAAM,EACZ,IAAA,uCAAkB,EAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAC1C,GAAG,EACH;oBACE,cAAc,EAAE,kBAAkB;iBACnC,EACD,IAAI,CAAC,SAAS,CAAC;oBACb,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,IAAI,EAAE,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,GAAG,CAAC,IAAI;oBACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC;iBACtB,CAAC,CACH,CAAC;YACJ,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACN,CAAC,EA9EgB,eAAe,aAAf,eAAe,GAAf,eAAe,QA8E/B;AAED,MAAM,gBAAgB,GAAG,CAAC,KAAU,EAA2B,EAAE,CAC/D,QAAQ,KAAK,OAAO,KAAK,CAAC,MAAM;IAChC,CAAC,SAAS,KAAK,KAAK,CAAC,IAAI,IAAI,QAAQ,KAAK,OAAO,KAAK,CAAC,IAAI,CAAC;IAC5D,QAAQ,KAAK,OAAO,KAAK,CAAC,QAAQ;IAClC,QAAQ,KAAK,OAAO,KAAK,CAAC,IAAI;IAC9B,QAAQ,KAAK,OAAO,KAAK,CAAC,OAAO;IACjC,CAAC,SAAS,KAAK,KAAK,CAAC,KAAK,IAAI,QAAQ,KAAK,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC"}
@@ -7,7 +7,8 @@ let NestiaSimulator;
7
7
  return {
8
8
  param: param(props),
9
9
  query: query(props),
10
- body: body(props)
10
+ body: body(props),
11
+ headers: headers(props)
11
12
  };
12
13
  };
13
14
  const param = (props) => (name) => (task) => {
@@ -15,11 +16,12 @@ let NestiaSimulator;
15
16
  };
16
17
  const query = (props) => (task) => validate(() => "Request query parameters are not following the promised type.")(props)(task);
17
18
  const body = (props) => (task) => validate(() => "Request body is not following the promised type.")(props)(task);
19
+ const headers = (props) => (task) => validate(() => "Request headers are not following the promised type.")(props)(task);
18
20
  const validate = (message, path) => (props) => (task) => {
19
21
  try {
20
22
  task();
21
23
  } catch (exp) {
22
- if (isTypeGuardError(exp)) throw new HttpError(props.method, join_host_and_path(props.host, props.path), 400, { "Content-Type": props.contentType }, JSON.stringify({
24
+ if (isTypeGuardError(exp)) throw new HttpError(props.method, join_host_and_path(props.host, props.path), 400, { "Content-Type": "application/json" }, JSON.stringify({
23
25
  method: exp.method,
24
26
  path: path ?? exp.path,
25
27
  expected: exp.expected,
@@ -1 +1 @@
1
- {"version":3,"file":"NestiaSimulator.mjs","names":[],"sources":["../src/NestiaSimulator.ts"],"sourcesContent":["import { HttpError } from \"./HttpError\";\nimport { join_host_and_path } from \"./internal/join_host_and_path\";\n\nexport namespace NestiaSimulator {\n export interface IProps {\n host: string;\n path: string;\n method: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n contentType: string;\n }\n\n export const assert = (props: IProps) => {\n return {\n param: param(props),\n query: query(props),\n body: body(props),\n };\n };\n const param =\n (props: IProps) =>\n (name: string) =>\n <T>(task: () => T): void => {\n validate((exp) => `URL parameter \"${name}\" is not ${exp.expected} type.`)(\n props,\n )(task);\n };\n\n const query =\n (props: IProps) =>\n <T>(task: () => T): void =>\n validate(\n () => \"Request query parameters are not following the promised type.\",\n )(props)(task);\n\n const body =\n (props: IProps) =>\n <T>(task: () => T): void =>\n validate(() => \"Request body is not following the promised type.\")(props)(\n task,\n );\n\n const validate =\n (message: (exp: TypeGuardError) => string, path?: string) =>\n (props: IProps) =>\n <T>(task: () => T): void => {\n try {\n task();\n } catch (exp) {\n if (isTypeGuardError(exp))\n throw new HttpError(\n props.method,\n join_host_and_path(props.host, props.path),\n 400,\n {\n \"Content-Type\": props.contentType,\n },\n JSON.stringify({\n method: exp.method,\n path: path ?? exp.path,\n expected: exp.expected,\n value: exp.value,\n message: message(exp),\n }),\n );\n throw exp;\n }\n };\n}\n\nconst isTypeGuardError = (input: any): input is TypeGuardError =>\n \"string\" === typeof input.method &&\n (undefined === input.path || \"string\" === typeof input.path) &&\n \"string\" === typeof input.expected &&\n \"string\" === typeof input.name &&\n \"string\" === typeof input.message &&\n (undefined === input.stack || \"string\" === typeof input.stack);\n\ninterface TypeGuardError extends Error {\n method: string;\n path: string | undefined;\n expected: string;\n value: any;\n}\n"],"mappings":";;;AAGO,IAAA;;4BAQkB,UAAkB;EACvC,OAAO;GACL,OAAO,MAAM,KAAK;GAClB,OAAO,MAAM,KAAK;GAClB,MAAM,KAAK,KAAK;EAClB;CACF;CACA,MAAM,SACH,WACA,UACG,SAAwB;EAC1B,UAAU,QAAQ,kBAAkB,KAAK,WAAW,IAAI,SAAS,OAAO,CAAC,CACvE,KACF,CAAC,CAAC,IAAI;CACR;CAEF,MAAM,SACH,WACG,SACF,eACQ,+DACR,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI;CAEjB,MAAM,QACH,WACG,SACF,eAAe,kDAAkD,CAAC,CAAC,KAAK,CAAC,CACvE,IACF;CAEJ,MAAM,YACH,SAA0C,UAC1C,WACG,SAAwB;EAC1B,IAAI;GACF,KAAK;EACP,SAAS,KAAK;GACZ,IAAI,iBAAiB,GAAG,GACtB,MAAM,IAAI,UACR,MAAM,QACN,mBAAmB,MAAM,MAAM,MAAM,IAAI,GACzC,KACA,EACE,gBAAgB,MAAM,YACxB,GACA,KAAK,UAAU;IACb,QAAQ,IAAI;IACZ,MAAM,QAAQ,IAAI;IAClB,UAAU,IAAI;IACd,OAAO,IAAI;IACX,SAAS,QAAQ,GAAG;GACtB,CAAC,CACH;GACF,MAAM;EACR;CACF;GACH,oBAAA,kBAAA,CAAA,EAAD;AAEA,MAAM,oBAAoB,UACxB,aAAa,OAAO,MAAM,WACzB,KAAA,MAAc,MAAM,QAAQ,aAAa,OAAO,MAAM,SACvD,aAAa,OAAO,MAAM,YAC1B,aAAa,OAAO,MAAM,QAC1B,aAAa,OAAO,MAAM,YACzB,KAAA,MAAc,MAAM,SAAS,aAAa,OAAO,MAAM"}
1
+ {"version":3,"file":"NestiaSimulator.mjs","names":[],"sources":["../src/NestiaSimulator.ts"],"sourcesContent":["import { HttpError } from \"./HttpError\";\nimport { join_host_and_path } from \"./internal/join_host_and_path\";\n\nexport namespace NestiaSimulator {\n export interface IProps {\n host: string;\n path: string;\n method: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\" | \"HEAD\";\n\n /**\n * Content type of the route's success response, `null` for one without a\n * body such as `HEAD`'s. The simulated 400 is JSON whatever it is, as the\n * server's is.\n */\n contentType: string | null;\n }\n\n export const assert = (props: IProps) => {\n return {\n param: param(props),\n query: query(props),\n body: body(props),\n headers: headers(props),\n };\n };\n const param =\n (props: IProps) =>\n (name: string) =>\n <T>(task: () => T): void => {\n validate((exp) => `URL parameter \"${name}\" is not ${exp.expected} type.`)(\n props,\n )(task);\n };\n\n const query =\n (props: IProps) =>\n <T>(task: () => T): void =>\n validate(\n () => \"Request query parameters are not following the promised type.\",\n )(props)(task);\n\n const body =\n (props: IProps) =>\n <T>(task: () => T): void =>\n validate(() => \"Request body is not following the promised type.\")(props)(\n task,\n );\n\n const headers =\n (props: IProps) =>\n <T>(task: () => T): void =>\n validate(() => \"Request headers are not following the promised type.\")(\n props,\n )(task);\n\n const validate =\n (message: (exp: TypeGuardError) => string, path?: string) =>\n (props: IProps) =>\n <T>(task: () => T): void => {\n try {\n task();\n } catch (exp) {\n if (isTypeGuardError(exp))\n throw new HttpError(\n props.method,\n join_host_and_path(props.host, props.path),\n 400,\n {\n \"Content-Type\": \"application/json\",\n },\n JSON.stringify({\n method: exp.method,\n path: path ?? exp.path,\n expected: exp.expected,\n value: exp.value,\n message: message(exp),\n }),\n );\n throw exp;\n }\n };\n}\n\nconst isTypeGuardError = (input: any): input is TypeGuardError =>\n \"string\" === typeof input.method &&\n (undefined === input.path || \"string\" === typeof input.path) &&\n \"string\" === typeof input.expected &&\n \"string\" === typeof input.name &&\n \"string\" === typeof input.message &&\n (undefined === input.stack || \"string\" === typeof input.stack);\n\ninterface TypeGuardError extends Error {\n method: string;\n path: string | undefined;\n expected: string;\n value: any;\n}\n"],"mappings":";;;AAGO,IAAA;;4BAckB,UAAkB;EACvC,OAAO;GACL,OAAO,MAAM,KAAK;GAClB,OAAO,MAAM,KAAK;GAClB,MAAM,KAAK,KAAK;GAChB,SAAS,QAAQ,KAAK;EACxB;CACF;CACA,MAAM,SACH,WACA,UACG,SAAwB;EAC1B,UAAU,QAAQ,kBAAkB,KAAK,WAAW,IAAI,SAAS,OAAO,CAAC,CACvE,KACF,CAAC,CAAC,IAAI;CACR;CAEF,MAAM,SACH,WACG,SACF,eACQ,+DACR,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI;CAEjB,MAAM,QACH,WACG,SACF,eAAe,kDAAkD,CAAC,CAAC,KAAK,CAAC,CACvE,IACF;CAEJ,MAAM,WACH,WACG,SACF,eAAe,sDAAsD,CAAC,CACpE,KACF,CAAC,CAAC,IAAI;CAEV,MAAM,YACH,SAA0C,UAC1C,WACG,SAAwB;EAC1B,IAAI;GACF,KAAK;EACP,SAAS,KAAK;GACZ,IAAI,iBAAiB,GAAG,GACtB,MAAM,IAAI,UACR,MAAM,QACN,mBAAmB,MAAM,MAAM,MAAM,IAAI,GACzC,KACA,EACE,gBAAgB,mBAClB,GACA,KAAK,UAAU;IACb,QAAQ,IAAI;IACZ,MAAM,QAAQ,IAAI;IAClB,UAAU,IAAI;IACd,OAAO,IAAI;IACX,SAAS,QAAQ,GAAG;GACtB,CAAC,CACH;GACF,MAAM;EACR;CACF;GACH,oBAAA,kBAAA,CAAA,EAAD;AAEA,MAAM,oBAAoB,UACxB,aAAa,OAAO,MAAM,WACzB,KAAA,MAAc,MAAM,QAAQ,aAAa,OAAO,MAAM,SACvD,aAAa,OAAO,MAAM,YAC1B,aAAa,OAAO,MAAM,QAC1B,aAAa,OAAO,MAAM,YACzB,KAAA,MAAc,MAAM,SAAS,aAAa,OAAO,MAAM"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The path parameters of a generated SDK function, as its URL carries them.
3
+ *
4
+ * @author Jeongho Nam - https://github.com/samchon
5
+ */
6
+ export declare namespace PathParameter {
7
+ /**
8
+ * The parameter's value as one URL path segment: its text URI-encoded, or
9
+ * `"null"` when the value is nullish.
10
+ *
11
+ * `.` and `..` are refused. `encodeURIComponent` leaves them as they are, and
12
+ * the URL parser that `fetch` and `new URL()` share resolves them as dot
13
+ * segments, so the request would reach the parent path instead of the route,
14
+ * with the value gone. Their percent-encoded form is a dot segment by the
15
+ * same standard, so no spelling carries them.
16
+ *
17
+ * @param name Name of the parameter, for the error
18
+ * @param value Value of the parameter
19
+ * @returns The URI-encoded segment
20
+ * @throws Error when the value is `.` or `..`
21
+ */
22
+ const encode: (name: string, value: unknown) => string;
23
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PathParameter = void 0;
4
+ /**
5
+ * The path parameters of a generated SDK function, as its URL carries them.
6
+ *
7
+ * @author Jeongho Nam - https://github.com/samchon
8
+ */
9
+ var PathParameter;
10
+ (function (PathParameter) {
11
+ /**
12
+ * The parameter's value as one URL path segment: its text URI-encoded, or
13
+ * `"null"` when the value is nullish.
14
+ *
15
+ * `.` and `..` are refused. `encodeURIComponent` leaves them as they are, and
16
+ * the URL parser that `fetch` and `new URL()` share resolves them as dot
17
+ * segments, so the request would reach the parent path instead of the route,
18
+ * with the value gone. Their percent-encoded form is a dot segment by the
19
+ * same standard, so no spelling carries them.
20
+ *
21
+ * @param name Name of the parameter, for the error
22
+ * @param value Value of the parameter
23
+ * @returns The URI-encoded segment
24
+ * @throws Error when the value is `.` or `..`
25
+ */
26
+ PathParameter.encode = (name, value) => {
27
+ const encoded = encodeURIComponent(value === null || value === undefined ? "null" : String(value));
28
+ if (encoded === "." || encoded === "..")
29
+ throw new Error(`Error on PathParameter.encode(): path parameter "${name}" is ${JSON.stringify(encoded)}, a dot segment the URL resolves away, which would send the request to another path.`);
30
+ return encoded;
31
+ };
32
+ })(PathParameter || (exports.PathParameter = PathParameter = {}));
33
+ //# sourceMappingURL=PathParameter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PathParameter.js","sourceRoot":"","sources":["../src/PathParameter.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,IAAiB,aAAa,CA0B7B;AA1BD,WAAiB,aAAa;IAC5B;;;;;;;;;;;;;;OAcG;IACU,oBAAM,GAAG,CAAC,IAAY,EAAE,KAAc,EAAU,EAAE;QAC7D,MAAM,OAAO,GAAW,kBAAkB,CACxC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAC/D,CAAC;QACF,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI;YACrC,MAAM,IAAI,KAAK,CACb,oDAAoD,IAAI,QAAQ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,sFAAsF,CAC9K,CAAC;QACJ,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC,EA1BgB,aAAa,aAAb,aAAa,GAAb,aAAa,QA0B7B"}
@@ -0,0 +1,13 @@
1
+ //#region src/PathParameter.ts
2
+ let PathParameter;
3
+ (function(_PathParameter) {
4
+ _PathParameter.encode = (name, value) => {
5
+ const encoded = encodeURIComponent(value === null || value === void 0 ? "null" : String(value));
6
+ if (encoded === "." || encoded === "..") throw new Error(`Error on PathParameter.encode(): path parameter "${name}" is ${JSON.stringify(encoded)}, a dot segment the URL resolves away, which would send the request to another path.`);
7
+ return encoded;
8
+ };
9
+ })(PathParameter || (PathParameter = {}));
10
+ //#endregion
11
+ export { PathParameter };
12
+
13
+ //# sourceMappingURL=PathParameter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PathParameter.mjs","names":[],"sources":["../src/PathParameter.ts"],"sourcesContent":["/**\n * The path parameters of a generated SDK function, as its URL carries them.\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport namespace PathParameter {\n /**\n * The parameter's value as one URL path segment: its text URI-encoded, or\n * `\"null\"` when the value is nullish.\n *\n * `.` and `..` are refused. `encodeURIComponent` leaves them as they are, and\n * the URL parser that `fetch` and `new URL()` share resolves them as dot\n * segments, so the request would reach the parent path instead of the route,\n * with the value gone. Their percent-encoded form is a dot segment by the\n * same standard, so no spelling carries them.\n *\n * @param name Name of the parameter, for the error\n * @param value Value of the parameter\n * @returns The URI-encoded segment\n * @throws Error when the value is `.` or `..`\n */\n export const encode = (name: string, value: unknown): string => {\n const encoded: string = encodeURIComponent(\n value === null || value === undefined ? \"null\" : String(value),\n );\n if (encoded === \".\" || encoded === \"..\")\n throw new Error(\n `Error on PathParameter.encode(): path parameter \"${name}\" is ${JSON.stringify(encoded)}, a dot segment the URL resolves away, which would send the request to another path.`,\n );\n return encoded;\n };\n}\n"],"mappings":";AAKO,IAAA;;0BAgBkB,MAAc,UAA2B;EAC9D,MAAM,UAAkB,mBACtB,UAAU,QAAQ,UAAU,KAAA,IAAY,SAAS,OAAO,KAAK,CAC/D;EACA,IAAI,YAAY,OAAO,YAAY,MACjC,MAAM,IAAI,MACR,oDAAoD,KAAK,OAAO,KAAK,UAAU,OAAO,EAAE,qFAC1F;EACF,OAAO;CACT;GACD,kBAAA,gBAAA,CAAA,EAAD"}
package/lib/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export * from "./IPropagation";
6
6
  export * from "./FormDataInput";
7
7
  export * from "./HttpError";
8
8
  export * from "./NestiaSimulator";
9
+ export * from "./PathParameter";
9
10
  export * from "./PlainFetcher";
package/lib/index.js CHANGED
@@ -22,5 +22,6 @@ __exportStar(require("./IPropagation"), exports);
22
22
  __exportStar(require("./FormDataInput"), exports);
23
23
  __exportStar(require("./HttpError"), exports);
24
24
  __exportStar(require("./NestiaSimulator"), exports);
25
+ __exportStar(require("./PathParameter"), exports);
25
26
  __exportStar(require("./PlainFetcher"), exports);
26
27
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,wDAAsC;AACtC,gDAA8B;AAC9B,gDAA8B;AAC9B,iDAA+B;AAC/B,kDAAgC;AAEhC,8CAA4B;AAC5B,oDAAkC;AAClC,iDAA+B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,wDAAsC;AACtC,gDAA8B;AAC9B,gDAA8B;AAC9B,iDAA+B;AAC/B,kDAAgC;AAEhC,8CAA4B;AAC5B,oDAAkC;AAClC,kDAAgC;AAChC,iDAA+B"}
package/lib/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { HttpError } from "./HttpError.mjs";
2
2
  import { NestiaSimulator } from "./NestiaSimulator.mjs";
3
+ import { PathParameter } from "./PathParameter.mjs";
3
4
  import { PlainFetcher } from "./PlainFetcher.mjs";
4
- export { HttpError, NestiaSimulator, PlainFetcher };
5
+ export { HttpError, NestiaSimulator, PathParameter, PlainFetcher };
@@ -32,16 +32,15 @@ var FetcherBase;
32
32
  //----
33
33
  // METHOD & HEADERS
34
34
  const headers = Object.assign({}, ((_h = connection.headers) !== null && _h !== void 0 ? _h : {}));
35
+ // a request carries its route's own content type, never the caller's:
36
+ // multipart sets none at all, as fetch writes it with the boundary
37
+ deleteHeader(headers, "content-type");
35
38
  if (input !== undefined) {
36
39
  if (((_a = route.request) === null || _a === void 0 ? void 0 : _a.type) === undefined)
37
40
  throw new Error(`Error on ${props.className}.fetch(): no content-type being configured.`);
38
- else if (route.request.type !== "multipart/form-data") {
39
- deleteHeader(headers, "content-type");
41
+ else if (route.request.type !== "multipart/form-data")
40
42
  headers["Content-Type"] = route.request.type;
41
- }
42
43
  }
43
- else if (input === undefined)
44
- deleteHeader(headers, "content-type");
45
44
  // INIT REQUEST DATA
46
45
  const init = Object.assign(Object.assign({}, ((_j = connection.options) !== null && _j !== void 0 ? _j : {})), { method: route.method, headers: (() => {
47
46
  const output = [];
@@ -1 +1 @@
1
- {"version":3,"file":"FetcherBase.js","sourceRoot":"","sources":["../../src/internal/FetcherBase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FetcherBase.js","sourceRoot":"","sources":["../../src/internal/FetcherBase.ts"],"names":[],"mappings":"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"}
@@ -13,13 +13,11 @@ let FetcherBase;
13
13
  /** @internal */
14
14
  const _Propagate = (method) => (props) => async (connection, route, input, stringify) => {
15
15
  const headers = { ...connection.headers ?? {} };
16
+ deleteHeader(headers, "content-type");
16
17
  if (input !== void 0) {
17
18
  if (route.request?.type === void 0) throw new Error(`Error on ${props.className}.fetch(): no content-type being configured.`);
18
- else if (route.request.type !== "multipart/form-data") {
19
- deleteHeader(headers, "content-type");
20
- headers["Content-Type"] = route.request.type;
21
- }
22
- } else if (input === void 0) deleteHeader(headers, "content-type");
19
+ else if (route.request.type !== "multipart/form-data") headers["Content-Type"] = route.request.type;
20
+ }
23
21
  const init = {
24
22
  ...connection.options ?? {},
25
23
  method: route.method,
@@ -1 +1 @@
1
- {"version":3,"file":"FetcherBase.mjs","names":[],"sources":["../../src/internal/FetcherBase.ts"],"sourcesContent":["import { HttpError } from \"../HttpError\";\nimport { IConnection } from \"../IConnection\";\nimport { IFetchEvent } from \"../IFetchEvent\";\nimport { IFetchRoute } from \"../IFetchRoute\";\nimport { IPropagation } from \"../IPropagation\";\nimport { is_binary_response_content_type } from \"./is_binary_response_content_type\";\nimport { join_host_and_path, normalize_route_path } from \"./join_host_and_path\";\n\n/** @internal */\nexport namespace FetcherBase {\n export interface IProps {\n className: string;\n encode: (\n input: any,\n headers: Record<string, IConnection.HeaderValue | undefined>,\n ) => string;\n decode: (\n input: string,\n headers: Record<string, IConnection.HeaderValue | undefined>,\n ) => any;\n }\n\n export const request =\n (props: IProps) =>\n async <Input, Output>(\n connection: IConnection,\n route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n input?: Input,\n stringify?: (input: Input) => string,\n ): Promise<Output> => {\n const result = await _Propagate(\"fetch\")(props)(\n connection,\n route,\n input,\n stringify,\n );\n if ((result as any).success === false)\n throw new HttpError(\n route.method,\n route.path,\n result.status as any as number,\n result.headers,\n result.data as string,\n );\n return result.data as Output;\n };\n\n export const propagate =\n (props: IProps) =>\n async <Input>(\n connection: IConnection,\n route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n input?: Input,\n stringify?: (input: Input) => string,\n ): Promise<IPropagation<any, any>> =>\n _Propagate(\"propagate\")(props)(connection, route, input, stringify);\n\n /** @internal */\n const _Propagate =\n (method: string) =>\n (props: IProps) =>\n async <Input>(\n connection: IConnection,\n route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n input?: Input,\n stringify?: (input: Input) => string,\n ): Promise<IPropagation<any, any>> => {\n //----\n // REQUEST MESSAGE\n //----\n // METHOD & HEADERS\n const headers: Record<string, IConnection.HeaderValue | undefined> = {\n ...(connection.headers ?? {}),\n };\n if (input !== undefined) {\n if (route.request?.type === undefined)\n throw new Error(\n `Error on ${props.className}.fetch(): no content-type being configured.`,\n );\n else if (route.request.type !== \"multipart/form-data\") {\n deleteHeader(headers, \"content-type\");\n headers[\"Content-Type\"] = route.request.type;\n }\n } else if (input === undefined) deleteHeader(headers, \"content-type\");\n\n // INIT REQUEST DATA\n const init: RequestInit = {\n ...(connection.options ?? {}),\n method: route.method,\n headers: (() => {\n const output: [string, string][] = [];\n for (const [key, value] of Object.entries(headers))\n if (value === undefined) continue;\n else if (Array.isArray(value))\n for (const v of value) output.push([key, String(v)]);\n else output.push([key, String(value)]);\n return output;\n })(),\n };\n\n // CONSTRUCT BODY DATA\n if (input !== undefined)\n init.body = props.encode(\n // BODY TRANSFORM\n route.request?.type === \"application/x-www-form-urlencoded\"\n ? request_query_body(input)\n : route.request?.type === \"multipart/form-data\"\n ? request_form_data_body(input as any)\n : route.request?.type !== \"text/plain\"\n ? (stringify ?? JSON.stringify)(input)\n : input,\n headers,\n );\n\n //----\n // RESPONSE MESSAGE\n //----\n // URL SPECIFICATION\n const path: string = normalize_route_path(route.path);\n const url: URL = new URL(join_host_and_path(connection.host, route.path));\n\n // DO FETCH\n const event: IFetchEvent = {\n route,\n path,\n status: null,\n input,\n output: undefined,\n started_at: new Date(),\n respond_at: null,\n completed_at: null!,\n };\n try {\n // TRY FETCH\n const response: Response = await (connection.fetch ?? fetch)(\n url.href,\n init,\n );\n event.respond_at = new Date();\n event.status = response.status;\n\n // CONSTRUCT RESULT DATA\n const result: IPropagation<any, any> = {\n success:\n response.status === 200 ||\n response.status === 201 ||\n response.status === route.status,\n status: response.status,\n headers: response_headers_to_object(response.headers),\n data: undefined!,\n } as any;\n if ((result as any).success === false) {\n // WHEN FAILED\n result.data = await response.text();\n const type = response.headers.get(\"content-type\");\n if (\n method !== \"fetch\" &&\n type &&\n type.indexOf(\"application/json\") !== -1\n )\n try {\n result.data = JSON.parse(result.data);\n } catch {}\n } else {\n // WHEN SUCCESS\n if (route.method === \"HEAD\") result.data = undefined!;\n else if (route.response?.type === \"application/json\") {\n const text: string = await response.text();\n result.data = text.length ? JSON.parse(text) : undefined;\n } else if (\n route.response?.type === \"application/x-www-form-urlencoded\"\n ) {\n const query: URLSearchParams = new URLSearchParams(\n await response.text(),\n );\n result.data = route.parseQuery ? route.parseQuery(query) : query;\n } else if (is_binary_response_content_type(route.response?.type))\n result.data = response.body ?? new ReadableStream<Uint8Array>();\n else\n result.data = props.decode(await response.text(), result.headers);\n }\n event.output = result.data;\n return result;\n } catch (exp) {\n throw exp;\n } finally {\n event.completed_at = new Date();\n if (connection.logger)\n try {\n await connection.logger(event);\n } catch {}\n }\n };\n}\n\n/** @internal */\nconst request_query_body = (input: any): URLSearchParams => {\n const q: URLSearchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(input))\n if (value === undefined) continue;\n else if (Array.isArray(value))\n value.forEach((elem) => q.append(key, String(elem)));\n else q.set(key, String(value));\n return q;\n};\n\n/** @internal */\nconst request_form_data_body = (input: Record<string, any>): FormData => {\n const encoded: FormData = new FormData();\n const append = (key: string) => (value: any) => {\n if (value === undefined) return;\n else if (typeof File === \"function\" && value instanceof File)\n encoded.append(key, value, value.name);\n else encoded.append(key, value);\n };\n for (const [key, value] of Object.entries(input))\n if (Array.isArray(value)) value.map(append(key));\n else append(key)(value);\n return encoded;\n};\n\n/** @internal */\nconst response_headers_to_object = (\n headers: Headers,\n): Record<string, string | string[]> => {\n const output: Record<string, string | string[]> = {};\n const cookieHeaders: string[] | undefined =\n typeof (headers as any).getSetCookie === \"function\"\n ? (headers as any).getSetCookie()\n : undefined;\n if (cookieHeaders?.length) output[\"set-cookie\"] = cookieHeaders;\n\n headers.forEach((value, key) => {\n if (key.toLowerCase() === \"set-cookie\") {\n if (cookieHeaders?.length) return;\n output[key] ??= [];\n (output[key] as string[]).push(value);\n } else output[key] = value;\n });\n return output;\n};\n\nconst deleteHeader = (\n headers: Record<string, IConnection.HeaderValue | undefined>,\n name: string,\n): void => {\n const normalized: string = name.toLowerCase();\n for (const key of Object.keys(headers))\n if (key.toLowerCase() === normalized) delete headers[key];\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"FetcherBase.mjs","names":[],"sources":["../../src/internal/FetcherBase.ts"],"sourcesContent":["import { HttpError } from \"../HttpError\";\nimport { IConnection } from \"../IConnection\";\nimport { IFetchEvent } from \"../IFetchEvent\";\nimport { IFetchRoute } from \"../IFetchRoute\";\nimport { IPropagation } from \"../IPropagation\";\nimport { is_binary_response_content_type } from \"./is_binary_response_content_type\";\nimport { join_host_and_path, normalize_route_path } from \"./join_host_and_path\";\n\n/** @internal */\nexport namespace FetcherBase {\n export interface IProps {\n className: string;\n encode: (\n input: any,\n headers: Record<string, IConnection.HeaderValue | undefined>,\n ) => string;\n decode: (\n input: string,\n headers: Record<string, IConnection.HeaderValue | undefined>,\n ) => any;\n }\n\n export const request =\n (props: IProps) =>\n async <Input, Output>(\n connection: IConnection,\n route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n input?: Input,\n stringify?: (input: Input) => string,\n ): Promise<Output> => {\n const result = await _Propagate(\"fetch\")(props)(\n connection,\n route,\n input,\n stringify,\n );\n if ((result as any).success === false)\n throw new HttpError(\n route.method,\n route.path,\n result.status as any as number,\n result.headers,\n result.data as string,\n );\n return result.data as Output;\n };\n\n export const propagate =\n (props: IProps) =>\n async <Input>(\n connection: IConnection,\n route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n input?: Input,\n stringify?: (input: Input) => string,\n ): Promise<IPropagation<any, any>> =>\n _Propagate(\"propagate\")(props)(connection, route, input, stringify);\n\n /** @internal */\n const _Propagate =\n (method: string) =>\n (props: IProps) =>\n async <Input>(\n connection: IConnection,\n route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n input?: Input,\n stringify?: (input: Input) => string,\n ): Promise<IPropagation<any, any>> => {\n //----\n // REQUEST MESSAGE\n //----\n // METHOD & HEADERS\n const headers: Record<string, IConnection.HeaderValue | undefined> = {\n ...(connection.headers ?? {}),\n };\n // a request carries its route's own content type, never the caller's:\n // multipart sets none at all, as fetch writes it with the boundary\n deleteHeader(headers, \"content-type\");\n if (input !== undefined) {\n if (route.request?.type === undefined)\n throw new Error(\n `Error on ${props.className}.fetch(): no content-type being configured.`,\n );\n else if (route.request.type !== \"multipart/form-data\")\n headers[\"Content-Type\"] = route.request.type;\n }\n\n // INIT REQUEST DATA\n const init: RequestInit = {\n ...(connection.options ?? {}),\n method: route.method,\n headers: (() => {\n const output: [string, string][] = [];\n for (const [key, value] of Object.entries(headers))\n if (value === undefined) continue;\n else if (Array.isArray(value))\n for (const v of value) output.push([key, String(v)]);\n else output.push([key, String(value)]);\n return output;\n })(),\n };\n\n // CONSTRUCT BODY DATA\n if (input !== undefined)\n init.body = props.encode(\n // BODY TRANSFORM\n route.request?.type === \"application/x-www-form-urlencoded\"\n ? request_query_body(input)\n : route.request?.type === \"multipart/form-data\"\n ? request_form_data_body(input as any)\n : route.request?.type !== \"text/plain\"\n ? (stringify ?? JSON.stringify)(input)\n : input,\n headers,\n );\n\n //----\n // RESPONSE MESSAGE\n //----\n // URL SPECIFICATION\n const path: string = normalize_route_path(route.path);\n const url: URL = new URL(join_host_and_path(connection.host, route.path));\n\n // DO FETCH\n const event: IFetchEvent = {\n route,\n path,\n status: null,\n input,\n output: undefined,\n started_at: new Date(),\n respond_at: null,\n completed_at: null!,\n };\n try {\n // TRY FETCH\n const response: Response = await (connection.fetch ?? fetch)(\n url.href,\n init,\n );\n event.respond_at = new Date();\n event.status = response.status;\n\n // CONSTRUCT RESULT DATA\n const result: IPropagation<any, any> = {\n success:\n response.status === 200 ||\n response.status === 201 ||\n response.status === route.status,\n status: response.status,\n headers: response_headers_to_object(response.headers),\n data: undefined!,\n } as any;\n if ((result as any).success === false) {\n // WHEN FAILED\n result.data = await response.text();\n const type = response.headers.get(\"content-type\");\n if (\n method !== \"fetch\" &&\n type &&\n type.indexOf(\"application/json\") !== -1\n )\n try {\n result.data = JSON.parse(result.data);\n } catch {}\n } else {\n // WHEN SUCCESS\n if (route.method === \"HEAD\") result.data = undefined!;\n else if (route.response?.type === \"application/json\") {\n const text: string = await response.text();\n result.data = text.length ? JSON.parse(text) : undefined;\n } else if (\n route.response?.type === \"application/x-www-form-urlencoded\"\n ) {\n const query: URLSearchParams = new URLSearchParams(\n await response.text(),\n );\n result.data = route.parseQuery ? route.parseQuery(query) : query;\n } else if (is_binary_response_content_type(route.response?.type))\n result.data = response.body ?? new ReadableStream<Uint8Array>();\n else\n result.data = props.decode(await response.text(), result.headers);\n }\n event.output = result.data;\n return result;\n } catch (exp) {\n throw exp;\n } finally {\n event.completed_at = new Date();\n if (connection.logger)\n try {\n await connection.logger(event);\n } catch {}\n }\n };\n}\n\n/** @internal */\nconst request_query_body = (input: any): URLSearchParams => {\n const q: URLSearchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(input))\n if (value === undefined) continue;\n else if (Array.isArray(value))\n value.forEach((elem) => q.append(key, String(elem)));\n else q.set(key, String(value));\n return q;\n};\n\n/** @internal */\nconst request_form_data_body = (input: Record<string, any>): FormData => {\n const encoded: FormData = new FormData();\n const append = (key: string) => (value: any) => {\n if (value === undefined) return;\n else if (typeof File === \"function\" && value instanceof File)\n encoded.append(key, value, value.name);\n else encoded.append(key, value);\n };\n for (const [key, value] of Object.entries(input))\n if (Array.isArray(value)) value.map(append(key));\n else append(key)(value);\n return encoded;\n};\n\n/** @internal */\nconst response_headers_to_object = (\n headers: Headers,\n): Record<string, string | string[]> => {\n const output: Record<string, string | string[]> = {};\n const cookieHeaders: string[] | undefined =\n typeof (headers as any).getSetCookie === \"function\"\n ? (headers as any).getSetCookie()\n : undefined;\n if (cookieHeaders?.length) output[\"set-cookie\"] = cookieHeaders;\n\n headers.forEach((value, key) => {\n if (key.toLowerCase() === \"set-cookie\") {\n if (cookieHeaders?.length) return;\n output[key] ??= [];\n (output[key] as string[]).push(value);\n } else output[key] = value;\n });\n return output;\n};\n\nconst deleteHeader = (\n headers: Record<string, IConnection.HeaderValue | undefined>,\n name: string,\n): void => {\n const normalized: string = name.toLowerCase();\n for (const key of Object.keys(headers))\n if (key.toLowerCase() === normalized) delete headers[key];\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestia/fetcher",
3
- "version": "13.0.4",
3
+ "version": "14.0.1",
4
4
  "description": "Fetcher library of Nestia SDK",
5
5
  "main": "lib/index.js",
6
6
  "exports": {
@@ -37,8 +37,8 @@
37
37
  },
38
38
  "homepage": "https://nestia.io",
39
39
  "dependencies": {
40
- "@typia/interface": "^14.0.2",
41
- "@typia/utils": "^14.0.2"
40
+ "@typia/interface": "^15.0.0",
41
+ "@typia/utils": "^15.0.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^25.3.3",
@@ -76,15 +76,17 @@ export namespace IPropagation {
76
76
  headers: Record<string, string | string[]>;
77
77
  }
78
78
 
79
- /** Range of status codes by the first digit. */
80
- export type StatusRange<T extends "2XX" | "3XX" | "4XX" | "5XX"> = T extends 0
81
- ? IntRange<200, 299>
82
- : T extends 3
83
- ? IntRange<300, 399>
84
- : T extends 4
85
- ? IntRange<400, 499>
86
- : IntRange<500, 599>;
79
+ /** Range of status codes by the first digit, `"4XX"` for `400` to `499`. */
80
+ export type StatusRange<T extends "2XX" | "3XX" | "4XX" | "5XX"> =
81
+ T extends "2XX"
82
+ ? IntRange<200, 300>
83
+ : T extends "3XX"
84
+ ? IntRange<300, 400>
85
+ : T extends "4XX"
86
+ ? IntRange<400, 500>
87
+ : IntRange<500, 600>;
87
88
 
89
+ /** Integers from `F` up to, not including, `T`. */
88
90
  type IntRange<F extends number, T extends number> = Exclude<
89
91
  Enumerate<T>,
90
92
  Enumerate<F>
@@ -5,8 +5,14 @@ export namespace NestiaSimulator {
5
5
  export interface IProps {
6
6
  host: string;
7
7
  path: string;
8
- method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
9
- contentType: string;
8
+ method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD";
9
+
10
+ /**
11
+ * Content type of the route's success response, `null` for one without a
12
+ * body such as `HEAD`'s. The simulated 400 is JSON whatever it is, as the
13
+ * server's is.
14
+ */
15
+ contentType: string | null;
10
16
  }
11
17
 
12
18
  export const assert = (props: IProps) => {
@@ -14,6 +20,7 @@ export namespace NestiaSimulator {
14
20
  param: param(props),
15
21
  query: query(props),
16
22
  body: body(props),
23
+ headers: headers(props),
17
24
  };
18
25
  };
19
26
  const param =
@@ -39,6 +46,13 @@ export namespace NestiaSimulator {
39
46
  task,
40
47
  );
41
48
 
49
+ const headers =
50
+ (props: IProps) =>
51
+ <T>(task: () => T): void =>
52
+ validate(() => "Request headers are not following the promised type.")(
53
+ props,
54
+ )(task);
55
+
42
56
  const validate =
43
57
  (message: (exp: TypeGuardError) => string, path?: string) =>
44
58
  (props: IProps) =>
@@ -52,7 +66,7 @@ export namespace NestiaSimulator {
52
66
  join_host_and_path(props.host, props.path),
53
67
  400,
54
68
  {
55
- "Content-Type": props.contentType,
69
+ "Content-Type": "application/json",
56
70
  },
57
71
  JSON.stringify({
58
72
  method: exp.method,
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The path parameters of a generated SDK function, as its URL carries them.
3
+ *
4
+ * @author Jeongho Nam - https://github.com/samchon
5
+ */
6
+ export namespace PathParameter {
7
+ /**
8
+ * The parameter's value as one URL path segment: its text URI-encoded, or
9
+ * `"null"` when the value is nullish.
10
+ *
11
+ * `.` and `..` are refused. `encodeURIComponent` leaves them as they are, and
12
+ * the URL parser that `fetch` and `new URL()` share resolves them as dot
13
+ * segments, so the request would reach the parent path instead of the route,
14
+ * with the value gone. Their percent-encoded form is a dot segment by the
15
+ * same standard, so no spelling carries them.
16
+ *
17
+ * @param name Name of the parameter, for the error
18
+ * @param value Value of the parameter
19
+ * @returns The URI-encoded segment
20
+ * @throws Error when the value is `.` or `..`
21
+ */
22
+ export const encode = (name: string, value: unknown): string => {
23
+ const encoded: string = encodeURIComponent(
24
+ value === null || value === undefined ? "null" : String(value),
25
+ );
26
+ if (encoded === "." || encoded === "..")
27
+ throw new Error(
28
+ `Error on PathParameter.encode(): path parameter "${name}" is ${JSON.stringify(encoded)}, a dot segment the URL resolves away, which would send the request to another path.`,
29
+ );
30
+ return encoded;
31
+ };
32
+ }
package/src/index.ts CHANGED
@@ -7,4 +7,5 @@ export * from "./FormDataInput";
7
7
 
8
8
  export * from "./HttpError";
9
9
  export * from "./NestiaSimulator";
10
+ export * from "./PathParameter";
10
11
  export * from "./PlainFetcher";
@@ -72,16 +72,17 @@ export namespace FetcherBase {
72
72
  const headers: Record<string, IConnection.HeaderValue | undefined> = {
73
73
  ...(connection.headers ?? {}),
74
74
  };
75
+ // a request carries its route's own content type, never the caller's:
76
+ // multipart sets none at all, as fetch writes it with the boundary
77
+ deleteHeader(headers, "content-type");
75
78
  if (input !== undefined) {
76
79
  if (route.request?.type === undefined)
77
80
  throw new Error(
78
81
  `Error on ${props.className}.fetch(): no content-type being configured.`,
79
82
  );
80
- else if (route.request.type !== "multipart/form-data") {
81
- deleteHeader(headers, "content-type");
83
+ else if (route.request.type !== "multipart/form-data")
82
84
  headers["Content-Type"] = route.request.type;
83
- }
84
- } else if (input === undefined) deleteHeader(headers, "content-type");
85
+ }
85
86
 
86
87
  // INIT REQUEST DATA
87
88
  const init: RequestInit = {