client.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // src/client/client.ts
  2. import { serialize } from "../utils/cookie.js";
  3. import {
  4. buildSearchParams,
  5. deepMerge,
  6. mergePath,
  7. removeIndexString,
  8. replaceUrlParam,
  9. replaceUrlProtocol
  10. } from "./utils.js";
  11. var createProxy = (callback, path) => {
  12. const proxy = new Proxy(() => {
  13. }, {
  14. get(_obj, key) {
  15. if (typeof key !== "string" || key === "then") {
  16. return void 0;
  17. }
  18. return createProxy(callback, [...path, key]);
  19. },
  20. apply(_1, _2, args) {
  21. return callback({
  22. path,
  23. args
  24. });
  25. }
  26. });
  27. return proxy;
  28. };
  29. var ClientRequestImpl = class {
  30. url;
  31. method;
  32. buildSearchParams;
  33. queryParams = void 0;
  34. pathParams = {};
  35. rBody;
  36. cType = void 0;
  37. constructor(url, method, options) {
  38. this.url = url;
  39. this.method = method;
  40. this.buildSearchParams = options.buildSearchParams;
  41. }
  42. fetch = async (args, opt) => {
  43. if (args) {
  44. if (args.query) {
  45. this.queryParams = this.buildSearchParams(args.query);
  46. }
  47. if (args.form) {
  48. const form = new FormData();
  49. for (const [k, v] of Object.entries(args.form)) {
  50. if (v === void 0) {
  51. continue;
  52. }
  53. if (Array.isArray(v)) {
  54. for (const v2 of v) {
  55. form.append(k, v2);
  56. }
  57. } else {
  58. form.append(k, v);
  59. }
  60. }
  61. this.rBody = form;
  62. }
  63. if (args.json) {
  64. this.rBody = JSON.stringify(args.json);
  65. this.cType = "application/json";
  66. }
  67. if (args.param) {
  68. this.pathParams = args.param;
  69. }
  70. }
  71. let methodUpperCase = this.method.toUpperCase();
  72. const headerValues = {
  73. ...args?.header,
  74. ...typeof opt?.headers === "function" ? await opt.headers() : opt?.headers
  75. };
  76. if (args?.cookie) {
  77. const cookies = [];
  78. for (const [key, value] of Object.entries(args.cookie)) {
  79. cookies.push(serialize(key, value, { path: "/" }));
  80. }
  81. headerValues["Cookie"] = cookies.join(",");
  82. }
  83. if (this.cType) {
  84. headerValues["Content-Type"] = this.cType;
  85. }
  86. const headers = new Headers(headerValues ?? void 0);
  87. let url = this.url;
  88. url = removeIndexString(url);
  89. url = replaceUrlParam(url, this.pathParams);
  90. if (this.queryParams) {
  91. url = url + "?" + this.queryParams.toString();
  92. }
  93. methodUpperCase = this.method.toUpperCase();
  94. const setBody = !(methodUpperCase === "GET" || methodUpperCase === "HEAD");
  95. return (opt?.fetch || fetch)(url, {
  96. body: setBody ? this.rBody : void 0,
  97. method: methodUpperCase,
  98. headers,
  99. ...opt?.init
  100. });
  101. };
  102. };
  103. var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
  104. const buildSearchParamsOption = options?.buildSearchParams ?? buildSearchParams;
  105. const parts = [...opts.path];
  106. const lastParts = parts.slice(-3).reverse();
  107. if (lastParts[0] === "toString") {
  108. if (lastParts[1] === "name") {
  109. return lastParts[2] || "";
  110. }
  111. return proxyCallback.toString();
  112. }
  113. if (lastParts[0] === "valueOf") {
  114. if (lastParts[1] === "name") {
  115. return lastParts[2] || "";
  116. }
  117. return proxyCallback;
  118. }
  119. let method = "";
  120. if (/^\$/.test(lastParts[0])) {
  121. const last = parts.pop();
  122. if (last) {
  123. method = last.replace(/^\$/, "");
  124. }
  125. }
  126. const path = parts.join("/");
  127. const url = mergePath(baseUrl, path);
  128. if (method === "url" || method === "path") {
  129. let result = url;
  130. if (opts.args[0]) {
  131. if (opts.args[0].param) {
  132. result = replaceUrlParam(url, opts.args[0].param);
  133. }
  134. if (opts.args[0].query) {
  135. result = result + "?" + buildSearchParamsOption(opts.args[0].query).toString();
  136. }
  137. }
  138. result = removeIndexString(result);
  139. if (method === "url") {
  140. return new URL(result);
  141. }
  142. return result.slice(baseUrl.replace(/\/+$/, "").length).replace(/^\/?/, "/");
  143. }
  144. if (method === "ws") {
  145. const webSocketUrl = replaceUrlProtocol(
  146. opts.args[0] && opts.args[0].param ? replaceUrlParam(url, opts.args[0].param) : url,
  147. "ws"
  148. );
  149. const targetUrl = new URL(webSocketUrl);
  150. const queryParams = opts.args[0]?.query;
  151. if (queryParams) {
  152. Object.entries(queryParams).forEach(([key, value]) => {
  153. if (Array.isArray(value)) {
  154. value.forEach((item) => targetUrl.searchParams.append(key, item));
  155. } else {
  156. targetUrl.searchParams.set(key, value);
  157. }
  158. });
  159. }
  160. const establishWebSocket = (...args) => {
  161. if (options?.webSocket !== void 0 && typeof options.webSocket === "function") {
  162. return options.webSocket(...args);
  163. }
  164. return new WebSocket(...args);
  165. };
  166. return establishWebSocket(targetUrl.toString());
  167. }
  168. const req = new ClientRequestImpl(url, method, {
  169. buildSearchParams: buildSearchParamsOption
  170. });
  171. if (method) {
  172. options ??= {};
  173. const args = deepMerge(options, { ...opts.args[1] });
  174. return req.fetch(opts.args[0], args);
  175. }
  176. return req;
  177. }, []);
  178. export {
  179. hc
  180. };