@tahanabavi/typefetch 1.2.1 → 1.3.0

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/dist/index.mjs CHANGED
@@ -18,6 +18,18 @@ var __spreadValues = (a, b) => {
18
18
  return a;
19
19
  };
20
20
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
21
33
  var __export = (target, all) => {
22
34
  for (var name in all)
23
35
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -4096,15 +4108,19 @@ var ApiClient = class {
4096
4108
  * path: z.object({...}).optional(),
4097
4109
  * query: z.object({...}).optional(),
4098
4110
  * body: z.any().optional(),
4111
+ * header: z.object({...}).optional(),
4099
4112
  * })
4100
4113
  *
4101
- * If the parsed request does not contain `path`, `query` or `body`,
4114
+ * If the parsed request does not contain `path`, `header`,`query` or `body`,
4102
4115
  * the entire input is treated as the legacy flat request body.
4103
4116
  */
4104
4117
  request(endpoint, input) {
4105
4118
  return __async(this, null, function* () {
4106
- var _a, _b, _c, _d;
4119
+ var _b, _c, _d, _e;
4107
4120
  const parsedInput = endpoint.request.parse(input);
4121
+ const isObject = typeof parsedInput === "object" && parsedInput !== null;
4122
+ const looksStructured = isObject && ("path" in parsedInput || "query" in parsedInput || "body" in parsedInput || "headers" in parsedInput);
4123
+ const _a = parsedInput, { headers: extraHeaders } = _a, restInput = __objRest(_a, ["headers"]);
4108
4124
  if (this.useMockData && endpoint.mockData) {
4109
4125
  return this.handleMockRequest(endpoint);
4110
4126
  }
@@ -4118,14 +4134,32 @@ var ApiClient = class {
4118
4134
  status: 401,
4119
4135
  code: "NO_TOKEN"
4120
4136
  });
4121
- (_a = this.errorHandler) == null ? void 0 : _a.call(this, error);
4137
+ (_b = this.errorHandler) == null ? void 0 : _b.call(this, error);
4122
4138
  throw error;
4123
4139
  }
4124
- const headers = { "Content-Type": "application/json" };
4140
+ const headers = {};
4125
4141
  if (endpoint.auth && token) {
4126
4142
  headers["Authorization"] = `Bearer ${token}`;
4127
4143
  }
4128
- const { url, body } = this.buildUrlAndBody(endpoint, parsedInput);
4144
+ if (endpoint.bodyType !== "form-data") {
4145
+ headers["Content-Type"] = "application/json";
4146
+ }
4147
+ if (endpoint.headers) {
4148
+ const endpointHeaders = typeof endpoint.headers === "function" ? endpoint.headers(parsedInput) : endpoint.headers;
4149
+ for (const [key, value] of Object.entries(endpointHeaders)) {
4150
+ headers[key] = value;
4151
+ }
4152
+ }
4153
+ if (extraHeaders) {
4154
+ for (const [key, value] of Object.entries(extraHeaders)) {
4155
+ headers[key] = value;
4156
+ }
4157
+ }
4158
+ const { url, body } = this.buildUrlAndBody(
4159
+ endpoint,
4160
+ restInput,
4161
+ looksStructured
4162
+ );
4129
4163
  const ctx = {
4130
4164
  url,
4131
4165
  init: {
@@ -4151,7 +4185,7 @@ var ApiClient = class {
4151
4185
  status: parsedResponse.code || res.status,
4152
4186
  code: `API_ERROR_${parsedResponse.code}`
4153
4187
  });
4154
- (_b = this.errorHandler) == null ? void 0 : _b.call(this, error);
4188
+ (_c = this.errorHandler) == null ? void 0 : _c.call(this, error);
4155
4189
  throw error;
4156
4190
  }
4157
4191
  responseData = parsedResponse.data;
@@ -4165,34 +4199,44 @@ var ApiClient = class {
4165
4199
  detail: json.detail,
4166
4200
  errors: json.errors
4167
4201
  });
4168
- (_c = this.errorHandler) == null ? void 0 : _c.call(this, error);
4202
+ (_d = this.errorHandler) == null ? void 0 : _d.call(this, error);
4169
4203
  throw error;
4170
4204
  }
4171
4205
  return this.responseTransform(endpoint.response.parse(responseData));
4172
4206
  } catch (err) {
4173
4207
  const error = this.normalizeError(err);
4174
- (_d = this.errorHandler) == null ? void 0 : _d.call(this, error);
4208
+ (_e = this.errorHandler) == null ? void 0 : _e.call(this, error);
4175
4209
  throw error;
4176
4210
  }
4177
4211
  });
4178
4212
  }
4179
4213
  /**
4180
- * Builds the effective URL and request body for an endpoint.
4181
- *
4182
- * - Legacy mode: if the input does not contain `path`, `query` or `body`,
4183
- * the entire input is used as the JSON request body for non-GET methods.
4184
- *
4185
- * - New mode: uses `path` to interpolate `:param` segments, `query` to
4186
- * construct the query string, and `body` as the JSON payload.
4214
+ * Builds final URL and body from endpoint + request input.
4215
+ * Supports both structured `{ path, query, body, headers }` and legacy flat input.
4187
4216
  */
4188
- buildUrlAndBody(endpoint, parsedInput) {
4189
- const isObject = typeof parsedInput === "object" && parsedInput !== null;
4190
- const hasNewShape = isObject && ("path" in parsedInput || "query" in parsedInput || "body" in parsedInput);
4191
- if (!hasNewShape) {
4217
+ buildUrlAndBody(endpoint, parsedInput, looksStructured) {
4218
+ if (!looksStructured) {
4192
4219
  const url2 = this.config.baseUrl + endpoint.path;
4193
4220
  let requestBody2 = void 0;
4194
4221
  if (endpoint.method !== "GET") {
4195
- requestBody2 = JSON.stringify(parsedInput);
4222
+ if (endpoint.bodyType === "form-data") {
4223
+ const form = new FormData();
4224
+ const flat = parsedInput || {};
4225
+ for (const [key, value] of Object.entries(flat)) {
4226
+ if (value === void 0 || value === null) continue;
4227
+ if (Array.isArray(value)) {
4228
+ for (const v of value) {
4229
+ if (v === void 0 || v === null) continue;
4230
+ form.append(key, v);
4231
+ }
4232
+ } else {
4233
+ form.append(key, value);
4234
+ }
4235
+ }
4236
+ requestBody2 = form;
4237
+ } else {
4238
+ requestBody2 = JSON.stringify(parsedInput);
4239
+ }
4196
4240
  }
4197
4241
  return { url: url2, body: requestBody2 };
4198
4242
  }
@@ -4208,9 +4252,13 @@ var ApiClient = class {
4208
4252
  url = url.replace(token, encodeURIComponent(String(value)));
4209
4253
  }
4210
4254
  }
4211
- const missingTokens = Array.from(url.matchAll(/:([A-Za-z0-9_]+)/g)).map(
4212
- (m) => m[1]
4213
- );
4255
+ const templatePlaceholders = Array.from(
4256
+ endpoint.path.matchAll(/:([A-Za-z0-9_]+)/g)
4257
+ ).map((m) => m[1]);
4258
+ const missingTokens = templatePlaceholders.filter((name) => {
4259
+ const v = path ? path[name] : void 0;
4260
+ return v === void 0 || v === null;
4261
+ });
4214
4262
  if (missingTokens.length > 0) {
4215
4263
  throw this.createError({
4216
4264
  message: `Missing path params for placeholders: ${missingTokens.join(
@@ -4241,8 +4289,24 @@ var ApiClient = class {
4241
4289
  }
4242
4290
  let requestBody = void 0;
4243
4291
  if (endpoint.method !== "GET") {
4244
- if (typeof body !== "undefined" && body !== null) {
4245
- requestBody = JSON.stringify(body);
4292
+ if (body !== void 0 && body !== null) {
4293
+ if (endpoint.bodyType === "form-data") {
4294
+ const form = new FormData();
4295
+ for (const [key, value] of Object.entries(body)) {
4296
+ if (value === void 0 || value === null) continue;
4297
+ if (Array.isArray(value)) {
4298
+ for (const v of value) {
4299
+ if (v === void 0 || v === null) continue;
4300
+ form.append(key, v);
4301
+ }
4302
+ } else {
4303
+ form.append(key, value);
4304
+ }
4305
+ }
4306
+ requestBody = form;
4307
+ } else {
4308
+ requestBody = JSON.stringify(body);
4309
+ }
4246
4310
  }
4247
4311
  }
4248
4312
  return { url, body: requestBody };
@@ -4366,12 +4430,24 @@ var cacheMiddleware = (options = {}) => {
4366
4430
  return next();
4367
4431
  });
4368
4432
  };
4433
+
4434
+ // src/utils/make-request-schema.ts
4435
+ var makeRequestSchema = () => (defs) => {
4436
+ var _a, _b, _c, _d, _e, _f;
4437
+ return external_exports.object({
4438
+ path: (_b = (_a = defs.path) != null ? _a : external_exports.object({})) == null ? void 0 : _b.optional(),
4439
+ query: (_d = (_c = defs.query) != null ? _c : external_exports.object({})) == null ? void 0 : _d.optional(),
4440
+ body: (_e = defs.body) != null ? _e : external_exports.undefined(),
4441
+ headers: (_f = defs.headers) != null ? _f : external_exports.record(external_exports.string()).optional()
4442
+ });
4443
+ };
4369
4444
  export {
4370
4445
  ApiClient,
4371
4446
  RichError,
4372
4447
  authMiddleware,
4373
4448
  cacheMiddleware,
4374
4449
  loggingMiddleware,
4450
+ makeRequestSchema,
4375
4451
  retryMiddleware
4376
4452
  };
4377
4453
  //# sourceMappingURL=index.mjs.map