doboxa-js 1.0.3 → 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.
package/README.md CHANGED
@@ -28,7 +28,7 @@ import Doboxa from "doboxa-js";
28
28
 
29
29
  // Initialize the client
30
30
  const doboxa = new Doboxa({
31
- baseURL: "https://pl.doboxa.biz", // Optional: defaults to DOBOXA_API_URL env var or http://localhost
31
+ baseURL: "https://pl.doboxa.biz", // Optional: defaults to DOBOXA_API_URL env var or https://pl.doboxa.biz
32
32
  });
33
33
  ```
34
34
 
@@ -269,6 +269,54 @@ const me = await doboxa.users.me();
269
269
  console.log("Current user:", me.username);
270
270
  ```
271
271
 
272
+ ### Product catalog (BaseLinker connector)
273
+
274
+ The product catalog is not part of API v2 - it is served by Doboxa's BaseLinker
275
+ connector (shop integration file) on its own URL. The merchant finds both
276
+ credentials in the Doboxa client panel: **Integracje → Edycja** on the BaseLinker
277
+ integration. The modal shows the connector URL and the **Hasło** (password)
278
+ field.
279
+
280
+ ```typescript
281
+ const doboxa = new Doboxa({
282
+ baseURL: "https://pl.doboxa.biz",
283
+ catalog: {
284
+ url: "https://pl.doboxa.biz/api/base-linker/{clientToken}/{language}",
285
+ password: "YOUR_BL_PASS",
286
+ },
287
+ });
288
+ const catalog = doboxa.catalog!; // defined because `catalog` config was passed
289
+
290
+ // Connector capabilities
291
+ console.log(await catalog.fileVersion());
292
+ console.log(await catalog.supportedMethods());
293
+
294
+ // Categories: { "<id>": "Category / Path" }
295
+ const categories = await catalog.categories();
296
+
297
+ // One page of designs (100 per page)
298
+ const { pages, items } = await catalog.list({ page: 1 });
299
+ console.log(pages, items[0].id, items[0].name, items[0].price);
300
+
301
+ // Full data (images, variants) for selected designs
302
+ const data = await catalog.data({
303
+ products_id: [items[0].id],
304
+ });
305
+ ```
306
+
307
+ Notes:
308
+
309
+ - The catalog uses only the connector password, so no `apiKey` is needed - the
310
+ client works with the catalog, with the API and with both.
311
+ - `list()` returns one entry per design (the first variant); `data()` returns
312
+ the design with all of its variants.
313
+ - Prices are strings in PLN (up to 3 decimals) and are most likely **net**
314
+ prices - the markup is set by the merchant in the panel ("Zarządzanie cenami").
315
+ - The connector has no order methods, so orders are still created through
316
+ API v2 (`doboxa.orders`).
317
+ - Connector errors are returned with HTTP 200 and are thrown as
318
+ `DoboxaConnectorError` (with `errorCode` and `errorText`).
319
+
272
320
  ## Environment Variables
273
321
 
274
322
  You can set the API base URL using an environment variable:
@@ -369,6 +417,13 @@ import type {
369
417
  - **Users**: `doboxa.users`
370
418
  - `me()` - Get current user
371
419
 
420
+ - **Catalog**: `doboxa.catalog` (only when the `catalog` config is provided)
421
+ - `fileVersion()` - Get the connector platform and version
422
+ - `supportedMethods()` - Get the list of supported actions
423
+ - `categories()` - Get all product categories
424
+ - `list(params?)` - List one page of products (designs)
425
+ - `data(params)` - Get full product data (images, variants) for design ids
426
+
372
427
  ## License
373
428
 
374
429
  ISC
@@ -75,6 +75,15 @@ var DoboxaAuthenticationError = class _DoboxaAuthenticationError extends DoboxaE
75
75
  Object.setPrototypeOf(this, _DoboxaAuthenticationError.prototype);
76
76
  }
77
77
  };
78
+ var DoboxaConnectorError = class _DoboxaConnectorError extends DoboxaError {
79
+ constructor(errorCode, errorText, message) {
80
+ super(message || errorText || `BaseLinker connector error: ${errorCode}`);
81
+ this.name = "DoboxaConnectorError";
82
+ this.errorCode = errorCode;
83
+ this.errorText = errorText;
84
+ Object.setPrototypeOf(this, _DoboxaConnectorError.prototype);
85
+ }
86
+ };
78
87
  var DoboxaValidationError = class _DoboxaValidationError extends DoboxaAPIError {
79
88
  constructor(statusCode, message, body) {
80
89
  super(statusCode, message, body);
@@ -101,7 +110,8 @@ export {
101
110
  DoboxaError,
102
111
  DoboxaAPIError,
103
112
  DoboxaAuthenticationError,
113
+ DoboxaConnectorError,
104
114
  DoboxaValidationError,
105
115
  parseErrorResponse
106
116
  };
107
- //# sourceMappingURL=chunk-CGJD4ZO5.mjs.map
117
+ //# sourceMappingURL=chunk-7RN7PBJH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { InvalidRequestDataResponse, ServerErrorResponse } from './types/generated/src/models';\n\n/**\n * Base error class for all Doboxa errors\n */\nexport class DoboxaError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DoboxaError';\n Object.setPrototypeOf(this, DoboxaError.prototype);\n }\n}\n\n/**\n * Error thrown when API returns an error response\n */\nexport class DoboxaAPIError extends DoboxaError {\n public readonly statusCode: number;\n public readonly code?: number;\n public readonly errorMessage?: string;\n public readonly invalidParameters?: Array<{ parameter: string; error_cause: string }>;\n\n constructor(\n statusCode: number,\n message: string,\n body?: InvalidRequestDataResponse | ServerErrorResponse\n ) {\n super(message);\n this.name = 'DoboxaAPIError';\n this.statusCode = statusCode;\n\n if (body) {\n if ('result_code' in body) {\n this.code = body.result_code;\n }\n if ('error_message' in body) {\n this.errorMessage = body.error_message || undefined;\n }\n if ('invalid_parameters' in body && body.invalid_parameters) {\n this.invalidParameters = body.invalid_parameters.map((param) => ({\n parameter: param.parameter,\n error_cause: param.error_cause,\n }));\n }\n }\n\n Object.setPrototypeOf(this, DoboxaAPIError.prototype);\n }\n}\n\n/**\n * Error thrown when authentication fails\n */\nexport class DoboxaAuthenticationError extends DoboxaError {\n constructor(message: string = 'Authentication failed') {\n super(message);\n this.name = 'DoboxaAuthenticationError';\n Object.setPrototypeOf(this, DoboxaAuthenticationError.prototype);\n }\n}\n\n/**\n * Error thrown when the BaseLinker connector returns an error.\n * The connector always answers with HTTP 200, so the error is carried in the body.\n */\nexport class DoboxaConnectorError extends DoboxaError {\n /**\n * Machine readable error code, e.g. \"bad_password\", \"no_password\", \"unsupported_method\"\n */\n public readonly errorCode: string;\n /**\n * Human readable error text returned by the connector\n */\n public readonly errorText: string;\n\n constructor(errorCode: string, errorText: string, message?: string) {\n super(message || errorText || `BaseLinker connector error: ${errorCode}`);\n this.name = 'DoboxaConnectorError';\n this.errorCode = errorCode;\n this.errorText = errorText;\n Object.setPrototypeOf(this, DoboxaConnectorError.prototype);\n }\n}\n\n/**\n * Error thrown when request validation fails\n */\nexport class DoboxaValidationError extends DoboxaAPIError {\n constructor(statusCode: number, message: string, body?: InvalidRequestDataResponse) {\n super(statusCode, message, body);\n this.name = 'DoboxaValidationError';\n Object.setPrototypeOf(this, DoboxaValidationError.prototype);\n }\n}\n\n/**\n * Parse error response from API\n */\nexport function parseErrorResponse(\n statusCode: number,\n body: unknown\n): InvalidRequestDataResponse | ServerErrorResponse | undefined {\n if (typeof body === 'object' && body !== null) {\n if ('invalid_parameters' in body || 'error_message' in body) {\n return body as InvalidRequestDataResponse;\n }\n if ('error_message' in body && 'result_code' in body) {\n return body as ServerErrorResponse;\n }\n }\n return undefined;\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKO,IAAM,cAAN,MAAM,qBAAoB,MAAM;AAAA,EACrC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,aAAY,SAAS;AAAA,EACnD;AACF;AAKO,IAAM,iBAAN,MAAM,wBAAuB,YAAY;AAAA,EAM9C,YACE,YACA,SACA,MACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,aAAa;AAElB,QAAI,MAAM;AACR,UAAI,iBAAiB,MAAM;AACzB,aAAK,OAAO,KAAK;AAAA,MACnB;AACA,UAAI,mBAAmB,MAAM;AAC3B,aAAK,eAAe,KAAK,iBAAiB;AAAA,MAC5C;AACA,UAAI,wBAAwB,QAAQ,KAAK,oBAAoB;AAC3D,aAAK,oBAAoB,KAAK,mBAAmB,IAAI,CAAC,WAAW;AAAA,UAC/D,WAAW,MAAM;AAAA,UACjB,aAAa,MAAM;AAAA,QACrB,EAAE;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,eAAe,MAAM,gBAAe,SAAS;AAAA,EACtD;AACF;AAKO,IAAM,4BAAN,MAAM,mCAAkC,YAAY;AAAA,EACzD,YAAY,UAAkB,yBAAyB;AACrD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,2BAA0B,SAAS;AAAA,EACjE;AACF;AAMO,IAAM,uBAAN,MAAM,8BAA6B,YAAY;AAAA,EAUpD,YAAY,WAAmB,WAAmB,SAAkB;AAClE,UAAM,WAAW,aAAa,+BAA+B,SAAS,EAAE;AACxE,SAAK,OAAO;AACZ,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,WAAO,eAAe,MAAM,sBAAqB,SAAS;AAAA,EAC5D;AACF;AAKO,IAAM,wBAAN,MAAM,+BAA8B,eAAe;AAAA,EACxD,YAAY,YAAoB,SAAiB,MAAmC;AAClF,UAAM,YAAY,SAAS,IAAI;AAC/B,SAAK,OAAO;AACZ,WAAO,eAAe,MAAM,uBAAsB,SAAS;AAAA,EAC7D;AACF;AAKO,SAAS,mBACd,YACA,MAC8D;AAC9D,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,QAAI,wBAAwB,QAAQ,mBAAmB,MAAM;AAC3D,aAAO;AAAA,IACT;AACA,QAAI,mBAAmB,QAAQ,iBAAiB,MAAM;AACpD,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  DoboxaAPIError,
3
3
  DoboxaAuthenticationError,
4
+ DoboxaConnectorError,
4
5
  __async,
5
6
  __spreadProps,
6
7
  __spreadValues,
7
8
  parseErrorResponse
8
- } from "./chunk-CGJD4ZO5.mjs";
9
+ } from "./chunk-7RN7PBJH.mjs";
9
10
 
10
11
  // src/types/generated/src/runtime.ts
11
12
  var BASE_PATH = "http://localhost".replace(/\/+$/, "");
@@ -477,20 +478,6 @@ var AuthenticationResource = class {
477
478
  }
478
479
  };
479
480
 
480
- // src/types/generated/src/models/Bool.ts
481
- function BoolFromJSON(json) {
482
- return json;
483
- }
484
- function BoolFromJSONTyped(json, ignoreDiscriminator) {
485
- return json;
486
- }
487
- function BoolToJSON(value) {
488
- return value;
489
- }
490
- function BoolToJSONTyped(value, ignoreDiscriminator = false) {
491
- return value;
492
- }
493
-
494
481
  // src/types/generated/src/models/Attachment.ts
495
482
  function instanceOfAttachment(value) {
496
483
  if (!("type" in value) || value["type"] === void 0) return false;
@@ -1361,7 +1348,7 @@ function OrderCancellationResponseFromJSONTyped(json, ignoreDiscriminator) {
1361
1348
  return json;
1362
1349
  }
1363
1350
  return {
1364
- "cancelled": json["cancelled"] == null ? void 0 : BoolFromJSON(json["cancelled"]),
1351
+ "cancelled": json["cancelled"] == null ? void 0 : json["cancelled"],
1365
1352
  "details": json["details"] == null ? void 0 : json["details"]
1366
1353
  };
1367
1354
  }
@@ -1373,7 +1360,7 @@ function OrderCancellationResponseToJSONTyped(value, ignoreDiscriminator = false
1373
1360
  return value;
1374
1361
  }
1375
1362
  return {
1376
- "cancelled": BoolToJSON(value["cancelled"]),
1363
+ "cancelled": value["cancelled"],
1377
1364
  "details": value["details"]
1378
1365
  };
1379
1366
  }
@@ -2810,6 +2797,118 @@ var UsersResource = class {
2810
2797
  }
2811
2798
  };
2812
2799
 
2800
+ // src/resources/catalog.ts
2801
+ var CatalogResource = class {
2802
+ constructor(config) {
2803
+ this.config = config;
2804
+ }
2805
+ /**
2806
+ * Call a connector action.
2807
+ *
2808
+ * @param action - Connector action, e.g. "ProductsList"
2809
+ * @param params - Additional action parameters
2810
+ * @throws DoboxaConnectorError on HTTP or connector errors
2811
+ */
2812
+ call(_0) {
2813
+ return __async(this, arguments, function* (action, params = {}) {
2814
+ const response = yield fetch(this.config.url, {
2815
+ method: "POST",
2816
+ headers: {
2817
+ "Content-Type": "application/x-www-form-urlencoded"
2818
+ },
2819
+ body: new URLSearchParams(__spreadValues({
2820
+ bl_pass: this.config.password,
2821
+ action
2822
+ }, params))
2823
+ });
2824
+ if (!response.ok) {
2825
+ throw new DoboxaConnectorError(
2826
+ `http_${response.status}`,
2827
+ response.statusText || "Unexpected HTTP status",
2828
+ `BaseLinker connector request failed with HTTP ${response.status}`
2829
+ );
2830
+ }
2831
+ let payload;
2832
+ try {
2833
+ payload = yield response.json();
2834
+ } catch (e) {
2835
+ throw new DoboxaConnectorError(
2836
+ "invalid_response",
2837
+ "Connector response is not valid JSON",
2838
+ "BaseLinker connector returned a non-JSON response"
2839
+ );
2840
+ }
2841
+ if (payload !== null && typeof payload === "object" && !Array.isArray(payload) && payload.error === true) {
2842
+ const error = payload;
2843
+ throw new DoboxaConnectorError(error.error_code, error.error_text);
2844
+ }
2845
+ return payload;
2846
+ });
2847
+ }
2848
+ /**
2849
+ * Get the connector platform and version.
2850
+ */
2851
+ fileVersion() {
2852
+ return __async(this, null, function* () {
2853
+ return this.call("FileVersion");
2854
+ });
2855
+ }
2856
+ /**
2857
+ * Get the list of actions the connector supports.
2858
+ */
2859
+ supportedMethods() {
2860
+ return __async(this, null, function* () {
2861
+ return this.call("SupportedMethods");
2862
+ });
2863
+ }
2864
+ /**
2865
+ * Get all product categories as a map of category id to category path.
2866
+ */
2867
+ categories() {
2868
+ return __async(this, null, function* () {
2869
+ return this.call("ProductsCategories");
2870
+ });
2871
+ }
2872
+ /**
2873
+ * List one page of products (designs).
2874
+ *
2875
+ * @param params - Page number and optional category filter
2876
+ */
2877
+ list() {
2878
+ return __async(this, arguments, function* (params = {}) {
2879
+ var _a;
2880
+ const response = yield this.call("ProductsList", __spreadValues({
2881
+ page: String((_a = params.page) != null ? _a : 1)
2882
+ }, params.category_id !== void 0 ? { category_id: params.category_id } : {}));
2883
+ const items = [];
2884
+ for (const id of Object.keys(response)) {
2885
+ if (id === "pages") {
2886
+ continue;
2887
+ }
2888
+ const value = response[id];
2889
+ if (typeof value !== "object" || value === null) {
2890
+ continue;
2891
+ }
2892
+ items.push(__spreadValues({ id }, value));
2893
+ }
2894
+ return { pages: response.pages, items };
2895
+ });
2896
+ }
2897
+ /**
2898
+ * Get full product data (images, variants) for the given design ids.
2899
+ *
2900
+ * @param params - Design ids from the product list
2901
+ */
2902
+ data(params) {
2903
+ return __async(this, null, function* () {
2904
+ const response = yield this.call("ProductsData", {
2905
+ products_id: params.products_id.join(",")
2906
+ });
2907
+ return Array.isArray(response) ? {} : response;
2908
+ });
2909
+ }
2910
+ };
2911
+
2813
2912
  // src/client.ts
2814
2913
  var Doboxa = class {
2815
2914
  constructor(config = {}) {
@@ -2876,15 +2975,14 @@ var Doboxa = class {
2876
2975
  this.config
2877
2976
  );
2878
2977
  this.users = new UsersResource(this.httpClient, this.config);
2978
+ if (config.catalog) {
2979
+ this.catalog = new CatalogResource(config.catalog);
2980
+ }
2879
2981
  }
2880
2982
  };
2881
2983
 
2882
2984
  export {
2883
2985
  AuthenticationResource,
2884
- BoolFromJSON,
2885
- BoolFromJSONTyped,
2886
- BoolToJSON,
2887
- BoolToJSONTyped,
2888
2986
  instanceOfAttachment,
2889
2987
  AttachmentFromJSON,
2890
2988
  AttachmentFromJSONTyped,
@@ -3092,6 +3190,7 @@ export {
3092
3190
  OrderCommentsResource,
3093
3191
  OrderStatusChangesResource,
3094
3192
  UsersResource,
3193
+ CatalogResource,
3095
3194
  Doboxa
3096
3195
  };
3097
- //# sourceMappingURL=chunk-WGEOQ35B.mjs.map
3196
+ //# sourceMappingURL=chunk-RTI5YLAB.mjs.map