@jazzdev/dpd-local-sdk 1.0.11 → 1.0.12

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
@@ -201,6 +201,9 @@ const result = await createCompleteShipment(
201
201
 
202
202
  if (result.success) {
203
203
  console.log('Shipment created!');
204
+ console.log('Shipment ID:', result.shipmentId); // Save this for label regeneration
205
+ console.log('Consignment Number:', result.consignmentNumber); // 10-digit reference
206
+ console.log('Parcel Number:', result.parcelNumber); // 14-digit tracking number
204
207
  console.log('Tracking URL:', result.trackingUrl);
205
208
  console.log('Label URL:', result.labelUrl);
206
209
  } else {
@@ -208,6 +211,71 @@ if (result.success) {
208
211
  }
209
212
  ```
210
213
 
214
+ ## Understanding DPD Identifiers
215
+
216
+ When you create a shipment with DPD, you receive three different identifiers:
217
+
218
+ 1. **shipmentId** - DPD's internal shipment identifier (numeric)
219
+ - Required for label regeneration
220
+ - Save this in your database!
221
+
222
+ 2. **consignmentNumber** - 10-digit reference number (e.g., `6504286395`)
223
+ - Used for internal tracking
224
+
225
+ 3. **parcelNumber** - 14-digit tracking number (e.g., `15976504286395`)
226
+ - What customers use to track their delivery
227
+ - Used in the tracking URL
228
+
229
+ ```typescript
230
+ // When creating a shipment, save ALL identifiers:
231
+ const result = await createCompleteShipment(...);
232
+
233
+ if (result.success) {
234
+ await saveToDatabase({
235
+ shipmentId: result.shipmentId, // Save for label regeneration
236
+ consignmentNumber: result.consignmentNumber,
237
+ parcelNumber: result.parcelNumber, // Give to customer for tracking
238
+ trackingUrl: result.trackingUrl,
239
+ });
240
+ }
241
+ ```
242
+
243
+ ### Regenerating Labels
244
+
245
+ If you need to regenerate a label (e.g., printer jam), use the `shipmentId`:
246
+
247
+ ```typescript
248
+ import { generateLabel } from '@jazzdev/dpd-local-sdk';
249
+
250
+ const result = await generateLabel(credentials, {
251
+ shipmentId: '12345678', // Use the shipmentId, not consignment/parcel number
252
+ labelFormat: 'zpl' // or 'clp', 'html'
253
+ });
254
+ ```
255
+
256
+ ### Testing Label Generation
257
+
258
+ A test script is included to verify label generation:
259
+
260
+ ```bash
261
+ # Using npm script
262
+ npm run test:label <shipmentId> [format]
263
+
264
+ # Or directly with tsx
265
+ npx tsx test-label-generation.ts <shipmentId> [format]
266
+
267
+ # Examples
268
+ npm run test:label 12345678
269
+ npm run test:label 12345678 html
270
+ npm run test:label 12345678 zpl
271
+ ```
272
+
273
+ The script will:
274
+ - Validate your DPD credentials
275
+ - Generate the label in the specified format
276
+ - Save it to a file (`label-<shipmentId>.<format>`)
277
+ - Display a preview of the label content
278
+
211
279
  ## API Reference
212
280
 
213
281
  ### Configuration
@@ -379,11 +447,12 @@ console.log('DPD_ENCRYPTION_KEY=' + key);
379
447
 
380
448
  Complete adapter examples are available in the `examples/` directory:
381
449
 
382
- - `examples/firestore-adapter.ts` - Firestore implementation
383
- - `examples/mongodb-adapter.ts` - MongoDB implementation
384
- - `examples/postgresql-adapter.ts` - PostgreSQL implementation
385
- - `examples/firebase-storage-adapter.ts` - Firebase Storage implementation
386
- - `examples/s3-storage-adapter.ts` - AWS S3 implementation
450
+ - `examples/basic-usage.ts` - Complete workflow example
451
+ - `examples/regenerate-label.ts` - Label regeneration example
452
+ - `examples/firestore-adapter.ts` - Firestore database adapter
453
+ - `examples/firebase-storage-adapter.ts` - Firebase Storage adapter
454
+
455
+ For other databases (MongoDB, PostgreSQL, etc.), implement the `DatabaseAdapter` interface following the Firestore example as a reference. The adapter pattern is database-agnostic by design.
387
456
 
388
457
  ## Error Handling
389
458
 
package/dist/index.js CHANGED
@@ -324,10 +324,6 @@ async function authenticatedRequest(credentials, options) {
324
324
  const isLabelRequest = acceptHeader === "text/vnd.zebra-zpl" || acceptHeader === "text/vnd.citizen-clp" || acceptHeader === "text/vnd.eltron-epl" || acceptHeader === "text/html";
325
325
  let data = null;
326
326
  if (isLabelRequest) {
327
- console.log("\u{1F3F7}\uFE0F [SDK auth] Label request detected");
328
- console.log(` HTTP Status: ${response.status} ${response.statusText}`);
329
- console.log(` Response length: ${raw.length} chars`);
330
- console.log(` Response preview (first 300 chars): ${raw.substring(0, 300)}`);
331
327
  if (!response.ok) {
332
328
  throw new Error(
333
329
  `Label request failed: ${response.status} ${response.statusText}`
@@ -335,20 +331,18 @@ async function authenticatedRequest(credentials, options) {
335
331
  }
336
332
  try {
337
333
  const parsed = JSON.parse(raw);
338
- console.log("\u{1F50D} [SDK auth] Label request - parsed JSON response:", parsed);
339
334
  if (parsed?.error || parsed?.data === null) {
340
- console.log("\u26A0\uFE0F [SDK auth] Detected error response:", {
341
- hasError: !!parsed?.error,
342
- dataIsNull: parsed?.data === null,
343
- errorObj: parsed?.error
344
- });
345
335
  const errorObj = parsed?.error;
346
336
  let errorMessage = "Label generation failed";
347
337
  let errorCode = "UNKNOWN";
348
338
  if (errorObj) {
349
- if (errorObj.errorMessage) {
339
+ if (Array.isArray(errorObj)) {
340
+ const firstError = errorObj[0];
341
+ errorMessage = firstError?.errorMessage || errorMessage;
342
+ errorCode = firstError?.errorCode || errorCode;
343
+ } else if (errorObj.errorMessage) {
350
344
  errorMessage = errorObj.errorMessage;
351
- errorCode = errorObj.errorCode || errorObj.name || "UNKNOWN";
345
+ errorCode = errorObj.errorCode || errorObj.name || errorCode;
352
346
  } else if (errorObj.name) {
353
347
  errorMessage = errorObj.name;
354
348
  errorCode = errorObj.name;
@@ -359,7 +353,6 @@ async function authenticatedRequest(credentials, options) {
359
353
  }
360
354
  }
361
355
  }
362
- console.error(`\u274C [SDK auth] Throwing error - Code: ${errorCode}, Message: ${errorMessage}`);
363
356
  throw new Error(`DPD API Error ${errorCode}: ${errorMessage}`);
364
357
  }
365
358
  if (parsed?.data) {
@@ -574,12 +567,7 @@ async function createShipment(credentials, params, businessConfig) {
574
567
  async function generateLabel(credentials, params) {
575
568
  try {
576
569
  const { shipmentId, labelFormat } = params;
577
- console.log("\n\u{1F3F7}\uFE0F [SDK generateLabel] Starting label generation");
578
- console.log(` Shipment ID: ${shipmentId} (type: ${typeof shipmentId})`);
579
- console.log(` Format: ${labelFormat}`);
580
- console.log(` Accept Header: ${getAcceptHeader(labelFormat)}`);
581
570
  const endpoint = `${DPD_API.ENDPOINTS.LABEL}/${shipmentId}/label/`;
582
- console.log(` Endpoint: ${endpoint}`);
583
571
  const response = await authenticatedRequest(credentials, {
584
572
  method: "GET",
585
573
  endpoint,
@@ -587,35 +575,17 @@ async function generateLabel(credentials, params) {
587
575
  Accept: getAcceptHeader(labelFormat)
588
576
  }
589
577
  });
590
- console.log("\u{1F4E6} [SDK generateLabel] Raw response type:", typeof response);
591
- console.log(
592
- "\u{1F4E6} [SDK generateLabel] Raw response:",
593
- typeof response === "string" ? `String (${response.length} chars): ${response.substring(0, 200)}...` : response
594
- );
595
- if (typeof response === "object" && response.error) {
596
- const errorObj = response.error;
597
- console.error("\u274C [SDK generateLabel] DPD returned error object:", errorObj);
598
- const errorMessage = errorObj.errorMessage || errorObj.name || JSON.stringify(errorObj);
599
- return {
600
- success: false,
601
- error: `DPD API error: ${errorMessage}`
602
- };
603
- }
604
- if (!response || typeof response === "object" && !response.data) {
605
- console.error("\u274C [SDK generateLabel] No label data in response");
578
+ if (!response || typeof response !== "string") {
606
579
  return {
607
580
  success: false,
608
581
  error: "No label data received from DPD"
609
582
  };
610
583
  }
611
- const labelData = typeof response === "string" ? response : response.data;
612
- console.log(`\u2705 [SDK generateLabel] Success! Label data length: ${labelData.length} chars`);
613
584
  return {
614
585
  success: true,
615
- labelData
586
+ labelData: response
616
587
  };
617
588
  } catch (error) {
618
- console.error("\u{1F4A5} [SDK generateLabel] Exception:", error);
619
589
  return {
620
590
  success: false,
621
591
  error: error instanceof Error ? error.message : "Unknown error"
@@ -760,7 +730,7 @@ async function createCompleteShipment(orderId, params, config2, dbAdapter, stora
760
730
  }
761
731
  const labelResult = await generateAndUploadLabel(
762
732
  shipmentResult.shipmentId,
763
- "zpl",
733
+ config2.labels.format,
764
734
  config2.credentials,
765
735
  storageAdapter
766
736
  );
package/dist/index.mjs CHANGED
@@ -236,10 +236,6 @@ async function authenticatedRequest(credentials, options) {
236
236
  const isLabelRequest = acceptHeader === "text/vnd.zebra-zpl" || acceptHeader === "text/vnd.citizen-clp" || acceptHeader === "text/vnd.eltron-epl" || acceptHeader === "text/html";
237
237
  let data = null;
238
238
  if (isLabelRequest) {
239
- console.log("\u{1F3F7}\uFE0F [SDK auth] Label request detected");
240
- console.log(` HTTP Status: ${response.status} ${response.statusText}`);
241
- console.log(` Response length: ${raw.length} chars`);
242
- console.log(` Response preview (first 300 chars): ${raw.substring(0, 300)}`);
243
239
  if (!response.ok) {
244
240
  throw new Error(
245
241
  `Label request failed: ${response.status} ${response.statusText}`
@@ -247,20 +243,18 @@ async function authenticatedRequest(credentials, options) {
247
243
  }
248
244
  try {
249
245
  const parsed = JSON.parse(raw);
250
- console.log("\u{1F50D} [SDK auth] Label request - parsed JSON response:", parsed);
251
246
  if (parsed?.error || parsed?.data === null) {
252
- console.log("\u26A0\uFE0F [SDK auth] Detected error response:", {
253
- hasError: !!parsed?.error,
254
- dataIsNull: parsed?.data === null,
255
- errorObj: parsed?.error
256
- });
257
247
  const errorObj = parsed?.error;
258
248
  let errorMessage = "Label generation failed";
259
249
  let errorCode = "UNKNOWN";
260
250
  if (errorObj) {
261
- if (errorObj.errorMessage) {
251
+ if (Array.isArray(errorObj)) {
252
+ const firstError = errorObj[0];
253
+ errorMessage = firstError?.errorMessage || errorMessage;
254
+ errorCode = firstError?.errorCode || errorCode;
255
+ } else if (errorObj.errorMessage) {
262
256
  errorMessage = errorObj.errorMessage;
263
- errorCode = errorObj.errorCode || errorObj.name || "UNKNOWN";
257
+ errorCode = errorObj.errorCode || errorObj.name || errorCode;
264
258
  } else if (errorObj.name) {
265
259
  errorMessage = errorObj.name;
266
260
  errorCode = errorObj.name;
@@ -271,7 +265,6 @@ async function authenticatedRequest(credentials, options) {
271
265
  }
272
266
  }
273
267
  }
274
- console.error(`\u274C [SDK auth] Throwing error - Code: ${errorCode}, Message: ${errorMessage}`);
275
268
  throw new Error(`DPD API Error ${errorCode}: ${errorMessage}`);
276
269
  }
277
270
  if (parsed?.data) {
@@ -486,12 +479,7 @@ async function createShipment(credentials, params, businessConfig) {
486
479
  async function generateLabel(credentials, params) {
487
480
  try {
488
481
  const { shipmentId, labelFormat } = params;
489
- console.log("\n\u{1F3F7}\uFE0F [SDK generateLabel] Starting label generation");
490
- console.log(` Shipment ID: ${shipmentId} (type: ${typeof shipmentId})`);
491
- console.log(` Format: ${labelFormat}`);
492
- console.log(` Accept Header: ${getAcceptHeader(labelFormat)}`);
493
482
  const endpoint = `${DPD_API.ENDPOINTS.LABEL}/${shipmentId}/label/`;
494
- console.log(` Endpoint: ${endpoint}`);
495
483
  const response = await authenticatedRequest(credentials, {
496
484
  method: "GET",
497
485
  endpoint,
@@ -499,35 +487,17 @@ async function generateLabel(credentials, params) {
499
487
  Accept: getAcceptHeader(labelFormat)
500
488
  }
501
489
  });
502
- console.log("\u{1F4E6} [SDK generateLabel] Raw response type:", typeof response);
503
- console.log(
504
- "\u{1F4E6} [SDK generateLabel] Raw response:",
505
- typeof response === "string" ? `String (${response.length} chars): ${response.substring(0, 200)}...` : response
506
- );
507
- if (typeof response === "object" && response.error) {
508
- const errorObj = response.error;
509
- console.error("\u274C [SDK generateLabel] DPD returned error object:", errorObj);
510
- const errorMessage = errorObj.errorMessage || errorObj.name || JSON.stringify(errorObj);
511
- return {
512
- success: false,
513
- error: `DPD API error: ${errorMessage}`
514
- };
515
- }
516
- if (!response || typeof response === "object" && !response.data) {
517
- console.error("\u274C [SDK generateLabel] No label data in response");
490
+ if (!response || typeof response !== "string") {
518
491
  return {
519
492
  success: false,
520
493
  error: "No label data received from DPD"
521
494
  };
522
495
  }
523
- const labelData = typeof response === "string" ? response : response.data;
524
- console.log(`\u2705 [SDK generateLabel] Success! Label data length: ${labelData.length} chars`);
525
496
  return {
526
497
  success: true,
527
- labelData
498
+ labelData: response
528
499
  };
529
500
  } catch (error) {
530
- console.error("\u{1F4A5} [SDK generateLabel] Exception:", error);
531
501
  return {
532
502
  success: false,
533
503
  error: error instanceof Error ? error.message : "Unknown error"
@@ -672,7 +642,7 @@ async function createCompleteShipment(orderId, params, config2, dbAdapter, stora
672
642
  }
673
643
  const labelResult = await generateAndUploadLabel(
674
644
  shipmentResult.shipmentId,
675
- "zpl",
645
+ config2.labels.format,
676
646
  config2.credentials,
677
647
  storageAdapter
678
648
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jazzdev/dpd-local-sdk",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "description": "TypeScript SDK for DPD Local shipping API integration - database-agnostic and framework-independent",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -22,7 +22,8 @@
22
22
  "build": "tsup src/index.ts --format cjs,esm --dts --clean",
23
23
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
24
24
  "typecheck": "tsc --noEmit",
25
- "prepublishOnly": "npm run build"
25
+ "prepublishOnly": "npm run build",
26
+ "test:label": "tsx test-label-generation.ts"
26
27
  },
27
28
  "keywords": [
28
29
  "dpd",