@lonca/trendyol 1.0.1 → 1.1.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.
@@ -45,6 +45,11 @@ declare class TrendyolTransport {
45
45
  interface Brand {
46
46
  id: string;
47
47
  name: string;
48
+ /**
49
+ * Whether Trendyol flags the brand as a luxury brand. Undocumented by Trendyol but sent on
50
+ * every brand of the prod `brands.list` response; omitted when the response lacks it.
51
+ */
52
+ luxe?: boolean;
48
53
  }
49
54
 
50
55
  /**
@@ -63,6 +68,14 @@ declare class BrandsResource {
63
68
  /**
64
69
  * List Trendyol brands, one page at a time.
65
70
  *
71
+ * **Next-page heuristic.** Trendyol's brand list carries no page count (neither the docs
72
+ * nor the prod wire have `totalPages` / `totalElements` — the response is just
73
+ * `{ brands: [...] }`). So when `totalPages` is absent, a **full page** (at least `limit`
74
+ * brands — Trendyol may send ~1000 even for a smaller `limit`) means "there may be more"
75
+ * and sets `nextCursor`; a short page is the last one. When the
76
+ * total is an exact multiple of the page size, `paginate()` makes one extra request that
77
+ * comes back empty and stops there. If Trendyol ever sends `totalPages`, it wins.
78
+ *
66
79
  * @example
67
80
  * ```ts
68
81
  * import { paginate } from '@lonca/core';
@@ -797,6 +810,13 @@ interface City {
797
810
  id?: string;
798
811
  code: string;
799
812
  name?: string;
813
+ /**
814
+ * The country the city belongs to — the country code of the lookup that returned it
815
+ * (`'TR'` for `getTurkeyCities`, `'AZ'` for `getAzerbaijanCities`, the argument of
816
+ * `getCitiesByCountry`). Trendyol's city rows carry no country field (neither the docs nor
817
+ * the prod wire), so the SDK fills it from the request; earlier versions read a wire field
818
+ * that never arrives and always left it `undefined`.
819
+ */
800
820
  countryCode?: string;
801
821
  raw: Record<string, unknown>;
802
822
  }
@@ -1273,6 +1293,7 @@ declare class LocationsResource {
1273
1293
  getAzerbaijanDistricts(cityId: string | number): Promise<District[]>;
1274
1294
  getCitiesByCountry(countryCode: string): Promise<City[]>;
1275
1295
  getDistrictsByCity(countryCode: string, cityId: string | number): Promise<District[]>;
1296
+ /** `countryCode` is the lookup's country — city rows do not carry one on the wire. */
1276
1297
  private cities;
1277
1298
  private districts;
1278
1299
  private neighborhoods;
@@ -2749,6 +2770,11 @@ interface CreateClientOptions {
2749
2770
  logger?: Logger;
2750
2771
  /** Request timeout in ms. Default: 30_000. */
2751
2772
  timeoutMs?: number;
2773
+ /**
2774
+ * Custom `fetch` implementation (e.g. to add a proxy agent, record or mock
2775
+ * traffic). Defaults to the global `fetch`.
2776
+ */
2777
+ fetch?: typeof fetch;
2752
2778
  }
2753
2779
  interface TrendyolClient {
2754
2780
  brands: BrandsResource;
@@ -45,6 +45,11 @@ declare class TrendyolTransport {
45
45
  interface Brand {
46
46
  id: string;
47
47
  name: string;
48
+ /**
49
+ * Whether Trendyol flags the brand as a luxury brand. Undocumented by Trendyol but sent on
50
+ * every brand of the prod `brands.list` response; omitted when the response lacks it.
51
+ */
52
+ luxe?: boolean;
48
53
  }
49
54
 
50
55
  /**
@@ -63,6 +68,14 @@ declare class BrandsResource {
63
68
  /**
64
69
  * List Trendyol brands, one page at a time.
65
70
  *
71
+ * **Next-page heuristic.** Trendyol's brand list carries no page count (neither the docs
72
+ * nor the prod wire have `totalPages` / `totalElements` — the response is just
73
+ * `{ brands: [...] }`). So when `totalPages` is absent, a **full page** (at least `limit`
74
+ * brands — Trendyol may send ~1000 even for a smaller `limit`) means "there may be more"
75
+ * and sets `nextCursor`; a short page is the last one. When the
76
+ * total is an exact multiple of the page size, `paginate()` makes one extra request that
77
+ * comes back empty and stops there. If Trendyol ever sends `totalPages`, it wins.
78
+ *
66
79
  * @example
67
80
  * ```ts
68
81
  * import { paginate } from '@lonca/core';
@@ -797,6 +810,13 @@ interface City {
797
810
  id?: string;
798
811
  code: string;
799
812
  name?: string;
813
+ /**
814
+ * The country the city belongs to — the country code of the lookup that returned it
815
+ * (`'TR'` for `getTurkeyCities`, `'AZ'` for `getAzerbaijanCities`, the argument of
816
+ * `getCitiesByCountry`). Trendyol's city rows carry no country field (neither the docs nor
817
+ * the prod wire), so the SDK fills it from the request; earlier versions read a wire field
818
+ * that never arrives and always left it `undefined`.
819
+ */
800
820
  countryCode?: string;
801
821
  raw: Record<string, unknown>;
802
822
  }
@@ -1273,6 +1293,7 @@ declare class LocationsResource {
1273
1293
  getAzerbaijanDistricts(cityId: string | number): Promise<District[]>;
1274
1294
  getCitiesByCountry(countryCode: string): Promise<City[]>;
1275
1295
  getDistrictsByCity(countryCode: string, cityId: string | number): Promise<District[]>;
1296
+ /** `countryCode` is the lookup's country — city rows do not carry one on the wire. */
1276
1297
  private cities;
1277
1298
  private districts;
1278
1299
  private neighborhoods;
@@ -2749,6 +2770,11 @@ interface CreateClientOptions {
2749
2770
  logger?: Logger;
2750
2771
  /** Request timeout in ms. Default: 30_000. */
2751
2772
  timeoutMs?: number;
2773
+ /**
2774
+ * Custom `fetch` implementation (e.g. to add a proxy agent, record or mock
2775
+ * traffic). Defaults to the global `fetch`.
2776
+ */
2777
+ fetch?: typeof fetch;
2752
2778
  }
2753
2779
  interface TrendyolClient {
2754
2780
  brands: BrandsResource;
package/dist/index.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) {
@@ -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) {
@@ -2943,7 +2962,8 @@ function createTrendyolClient(opts) {
2943
2962
  integratorName: opts.integratorName,
2944
2963
  clientIp: opts.clientIp,
2945
2964
  logger: opts.logger,
2946
- timeoutMs: opts.timeoutMs
2965
+ timeoutMs: opts.timeoutMs,
2966
+ fetch: opts.fetch
2947
2967
  });
2948
2968
  return buildClient(transport);
2949
2969
  }