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