@lonca/trendyol 1.0.1 → 1.2.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.
@@ -1,4 +1,4 @@
1
- import { g as BatchRequestStatus, ba as TrendyolClient } from './client-CnDyop_o.cjs';
1
+ import { g as BatchRequestStatus, ba as TrendyolClient } from './client-BhSJFkFo.cjs';
2
2
  import '@lonca/core';
3
3
 
4
4
  /** A request the fake client received, normalized for matching in a `handler`. */
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { g as BatchRequestStatus, ba as TrendyolClient } from './client-CnDyop_o.js';
1
+ import { g as BatchRequestStatus, ba as TrendyolClient } from './client-BhSJFkFo.js';
2
2
  import '@lonca/core';
3
3
 
4
4
  /** A request the fake client received, normalized for matching in a `handler`. */
package/dist/testing.js CHANGED
@@ -2,6 +2,11 @@ import { createRequester, AuthError, LoncaError, ServerError, RateLimitError, No
2
2
 
3
3
  // src/resources/brands.ts
4
4
  var DEFAULT_PAGE_SIZE = 1e3;
5
+ function toBrand(node) {
6
+ const brand = { id: String(node.id), name: node.name };
7
+ if (typeof node.luxe === "boolean") brand.luxe = node.luxe;
8
+ return brand;
9
+ }
5
10
  var BrandsResource = class {
6
11
  constructor(transport, limiter) {
7
12
  this.transport = transport;
@@ -12,6 +17,14 @@ var BrandsResource = class {
12
17
  /**
13
18
  * List Trendyol brands, one page at a time.
14
19
  *
20
+ * **Next-page heuristic.** Trendyol's brand list carries no page count (neither the docs
21
+ * nor the prod wire have `totalPages` / `totalElements` — the response is just
22
+ * `{ brands: [...] }`). So when `totalPages` is absent, a **full page** (at least `limit`
23
+ * brands — Trendyol may send ~1000 even for a smaller `limit`) means "there may be more"
24
+ * and sets `nextCursor`; a short page is the last one. When the
25
+ * total is an exact multiple of the page size, `paginate()` makes one extra request that
26
+ * comes back empty and stops there. If Trendyol ever sends `totalPages`, it wins.
27
+ *
15
28
  * @example
16
29
  * ```ts
17
30
  * import { paginate } from '@lonca/core';
@@ -29,8 +42,10 @@ var BrandsResource = class {
29
42
  query: { page, size },
30
43
  rateLimiter: this.limiter
31
44
  });
32
- const items = data.brands.map((b) => ({ id: String(b.id), name: b.name }));
33
- const nextCursor = page + 1 < data.totalPages ? String(page + 1) : void 0;
45
+ const brands = data?.brands ?? [];
46
+ const items = brands.map(toBrand);
47
+ const hasMore = typeof data?.totalPages === "number" ? page + 1 < data.totalPages : size > 0 && brands.length >= size;
48
+ const nextCursor = hasMore ? String(page + 1) : void 0;
34
49
  return nextCursor !== void 0 ? { items, nextCursor } : { items };
35
50
  }
36
51
  /**
@@ -54,7 +69,7 @@ var BrandsResource = class {
54
69
  query: { name },
55
70
  rateLimiter: this.limiter
56
71
  });
57
- return (data ?? []).map((b) => ({ id: String(b.id), name: b.name }));
72
+ return (data ?? []).map(toBrand);
58
73
  }
59
74
  };
60
75
  function normalizeCategory(node) {
@@ -67,7 +82,6 @@ function normalizeCategory(node) {
67
82
  }
68
83
  function normalizeAttribute(node) {
69
84
  const attr = node.attribute ?? { id: 0, name: "" };
70
- const rawValues = node.attributeValues ?? [];
71
85
  const out = {
72
86
  id: String(attr.id),
73
87
  name: attr.name,
@@ -75,7 +89,8 @@ function normalizeAttribute(node) {
75
89
  allowCustom: !!node.allowCustom,
76
90
  varianter: !!node.varianter,
77
91
  slicer: !!node.slicer,
78
- values: rawValues.map((v) => ({ id: String(v.id), name: v.name }))
92
+ // Deprecated: normally empty — see `attributeValues` on the node above.
93
+ values: (node.attributeValues ?? []).map((v) => ({ id: String(v.id), name: v.name }))
79
94
  };
80
95
  if (node.categoryId !== void 0) {
81
96
  out.categoryId = String(node.categoryId);
@@ -137,8 +152,8 @@ var CategoriesResource = class {
137
152
  /**
138
153
  * Fetch the allowed values for a single category attribute (paginated).
139
154
  *
140
- * `getCategoryAttributes` returns attribute metadata + flags but typically
141
- * omits the value catalog. Use this method to fetch the catalog for an
155
+ * `getCategoryAttributes` returns attribute metadata + flags only, never the
156
+ * value catalog (docs and prod wire agree). Use this method to fetch the catalog for an
142
157
  * attribute when `allowCustom` is `false` and you need to map your data
143
158
  * onto Trendyol's accepted values.
144
159
  *
@@ -1019,7 +1034,7 @@ var LocationsResource = class {
1019
1034
  }
1020
1035
  // ─── Domestic (TR / AZ) ───────────────────────────────────────────────
1021
1036
  async getTurkeyCities() {
1022
- return this.cities(`/integration/member/countries/domestic/TR/cities`);
1037
+ return this.cities(`/integration/member/countries/domestic/TR/cities`, "TR");
1023
1038
  }
1024
1039
  /**
1025
1040
  * List districts for a Turkish city. **Pass the city `id`** (`City.id`) — the
@@ -1041,7 +1056,7 @@ var LocationsResource = class {
1041
1056
  );
1042
1057
  }
1043
1058
  async getAzerbaijanCities() {
1044
- return this.cities(`/integration/member/countries/domestic/AZ/cities`);
1059
+ return this.cities(`/integration/member/countries/domestic/AZ/cities`, "AZ");
1045
1060
  }
1046
1061
  /** List districts for an Azerbaijani city. **Pass the city `id`** (`City.id`), not `code`. */
1047
1062
  async getAzerbaijanDistricts(cityId) {
@@ -1051,7 +1066,10 @@ var LocationsResource = class {
1051
1066
  }
1052
1067
  // ─── International (GULF / CEE) ───────────────────────────────────────
1053
1068
  async getCitiesByCountry(countryCode) {
1054
- return this.cities(`/integration/member/countries/${encodeURIComponent(countryCode)}/cities`);
1069
+ return this.cities(
1070
+ `/integration/member/countries/${encodeURIComponent(countryCode)}/cities`,
1071
+ countryCode
1072
+ );
1055
1073
  }
1056
1074
  async getDistrictsByCity(countryCode, cityId) {
1057
1075
  return this.districts(
@@ -1059,7 +1077,8 @@ var LocationsResource = class {
1059
1077
  );
1060
1078
  }
1061
1079
  // ─── Shared paginators ────────────────────────────────────────────────
1062
- async cities(path) {
1080
+ /** `countryCode` is the lookup's country — city rows do not carry one on the wire. */
1081
+ async cities(path, countryCode) {
1063
1082
  const data = await this.transport.request({
1064
1083
  method: "GET",
1065
1084
  path,
@@ -1069,7 +1088,7 @@ var LocationsResource = class {
1069
1088
  id: node.id !== void 0 ? String(node.id) : void 0,
1070
1089
  code: String(node.code ?? node.id ?? ""),
1071
1090
  name: node.name,
1072
- countryCode: node.countryCode
1091
+ countryCode
1073
1092
  }));
1074
1093
  }
1075
1094
  async districts(path) {
@@ -1081,8 +1100,7 @@ var LocationsResource = class {
1081
1100
  return n(data, (node) => ({
1082
1101
  id: node.id !== void 0 ? String(node.id) : void 0,
1083
1102
  code: String(node.code ?? node.id ?? ""),
1084
- name: node.name,
1085
- cityCode: node.cityCode !== void 0 ? String(node.cityCode) : void 0
1103
+ name: node.name
1086
1104
  }));
1087
1105
  }
1088
1106
  async neighborhoods(path) {
@@ -1091,12 +1109,16 @@ var LocationsResource = class {
1091
1109
  path,
1092
1110
  rateLimiter: this.limiter
1093
1111
  });
1094
- return n(data, (node) => ({
1095
- id: node.id !== void 0 ? String(node.id) : void 0,
1096
- code: String(node.code ?? node.id ?? ""),
1097
- name: node.name,
1098
- districtCode: node.districtCode !== void 0 ? String(node.districtCode) : void 0
1099
- }));
1112
+ return n(data, (node) => {
1113
+ const id = node.id !== void 0 ? String(node.id) : void 0;
1114
+ return {
1115
+ id,
1116
+ // Neighborhood rows have no code; `code` mirrors the id (as it always did in practice).
1117
+ code: id ?? "",
1118
+ name: node.name,
1119
+ postCode: typeof node.postCode === "string" ? node.postCode : void 0
1120
+ };
1121
+ });
1100
1122
  }
1101
1123
  };
1102
1124
  var MAX_PAGE_SIZE = 200;
@@ -2449,29 +2471,35 @@ var VALID_TYPES = /* @__PURE__ */ new Set([
2449
2471
  "WAREHOUSE"
2450
2472
  ]);
2451
2473
  function normalizeAddressType(raw) {
2452
- if (raw && VALID_TYPES.has(raw)) {
2453
- return raw;
2474
+ const upper = typeof raw === "string" ? raw.toUpperCase() : void 0;
2475
+ if (upper && VALID_TYPES.has(upper)) {
2476
+ return upper;
2454
2477
  }
2455
- const stripped = raw?.replace(/_ADDRESS$/, "");
2478
+ const stripped = upper?.replace(/_ADDRESS$/, "");
2456
2479
  if (stripped && VALID_TYPES.has(stripped)) {
2457
2480
  return stripped;
2458
2481
  }
2459
2482
  return "SHIPMENT";
2460
2483
  }
2484
+ function optionalString(value) {
2485
+ return typeof value === "number" || typeof value === "string" ? String(value) : void 0;
2486
+ }
2461
2487
  function normalizeAddress2(node) {
2462
2488
  return {
2463
2489
  id: String(node.id),
2464
- name: node.name,
2465
2490
  addressType: normalizeAddressType(node.addressType),
2466
2491
  isShipmentAddress: node.isShipmentAddress ?? false,
2467
2492
  isReturningAddress: node.isReturningAddress ?? false,
2468
2493
  isInvoiceAddress: node.isInvoiceAddress ?? false,
2469
2494
  isDefault: node.isDefault ?? false,
2470
2495
  address: node.address,
2496
+ fullAddress: node.fullAddress,
2497
+ country: node.country,
2471
2498
  city: node.city,
2499
+ cityCode: optionalString(node.cityCode),
2472
2500
  district: node.district,
2473
- postCode: node.postCode,
2474
- fullName: node.fullName
2501
+ districtId: optionalString(node.districtId),
2502
+ postCode: node.postCode
2475
2503
  };
2476
2504
  }
2477
2505
  var DEFAULT_CACHE_TTL_MS = 60 * 60 * 1e3;