@jazzdev/dpd-local-sdk 1.0.10 → 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 +74 -5
- package/dist/index.js +9 -28
- package/dist/index.mjs +9 -28
- package/package.json +3 -2
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/
|
|
383
|
-
- `examples/
|
|
384
|
-
- `examples/
|
|
385
|
-
- `examples/firebase-storage-adapter.ts` - Firebase Storage
|
|
386
|
-
|
|
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
|
@@ -336,9 +336,13 @@ async function authenticatedRequest(credentials, options) {
|
|
|
336
336
|
let errorMessage = "Label generation failed";
|
|
337
337
|
let errorCode = "UNKNOWN";
|
|
338
338
|
if (errorObj) {
|
|
339
|
-
if (errorObj
|
|
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) {
|
|
340
344
|
errorMessage = errorObj.errorMessage;
|
|
341
|
-
errorCode = errorObj.errorCode || errorObj.name ||
|
|
345
|
+
errorCode = errorObj.errorCode || errorObj.name || errorCode;
|
|
342
346
|
} else if (errorObj.name) {
|
|
343
347
|
errorMessage = errorObj.name;
|
|
344
348
|
errorCode = errorObj.name;
|
|
@@ -563,12 +567,7 @@ async function createShipment(credentials, params, businessConfig) {
|
|
|
563
567
|
async function generateLabel(credentials, params) {
|
|
564
568
|
try {
|
|
565
569
|
const { shipmentId, labelFormat } = params;
|
|
566
|
-
console.log("\n\u{1F3F7}\uFE0F [SDK generateLabel] Starting label generation");
|
|
567
|
-
console.log(` Shipment ID: ${shipmentId} (type: ${typeof shipmentId})`);
|
|
568
|
-
console.log(` Format: ${labelFormat}`);
|
|
569
|
-
console.log(` Accept Header: ${getAcceptHeader(labelFormat)}`);
|
|
570
570
|
const endpoint = `${DPD_API.ENDPOINTS.LABEL}/${shipmentId}/label/`;
|
|
571
|
-
console.log(` Endpoint: ${endpoint}`);
|
|
572
571
|
const response = await authenticatedRequest(credentials, {
|
|
573
572
|
method: "GET",
|
|
574
573
|
endpoint,
|
|
@@ -576,35 +575,17 @@ async function generateLabel(credentials, params) {
|
|
|
576
575
|
Accept: getAcceptHeader(labelFormat)
|
|
577
576
|
}
|
|
578
577
|
});
|
|
579
|
-
|
|
580
|
-
console.log(
|
|
581
|
-
"\u{1F4E6} [SDK generateLabel] Raw response:",
|
|
582
|
-
typeof response === "string" ? `String (${response.length} chars): ${response.substring(0, 200)}...` : response
|
|
583
|
-
);
|
|
584
|
-
if (typeof response === "object" && response.error) {
|
|
585
|
-
const errorObj = response.error;
|
|
586
|
-
console.error("\u274C [SDK generateLabel] DPD returned error object:", errorObj);
|
|
587
|
-
const errorMessage = errorObj.errorMessage || errorObj.name || JSON.stringify(errorObj);
|
|
588
|
-
return {
|
|
589
|
-
success: false,
|
|
590
|
-
error: `DPD API error: ${errorMessage}`
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
if (!response || typeof response === "object" && !response.data) {
|
|
594
|
-
console.error("\u274C [SDK generateLabel] No label data in response");
|
|
578
|
+
if (!response || typeof response !== "string") {
|
|
595
579
|
return {
|
|
596
580
|
success: false,
|
|
597
581
|
error: "No label data received from DPD"
|
|
598
582
|
};
|
|
599
583
|
}
|
|
600
|
-
const labelData = typeof response === "string" ? response : response.data;
|
|
601
|
-
console.log(`\u2705 [SDK generateLabel] Success! Label data length: ${labelData.length} chars`);
|
|
602
584
|
return {
|
|
603
585
|
success: true,
|
|
604
|
-
labelData
|
|
586
|
+
labelData: response
|
|
605
587
|
};
|
|
606
588
|
} catch (error) {
|
|
607
|
-
console.error("\u{1F4A5} [SDK generateLabel] Exception:", error);
|
|
608
589
|
return {
|
|
609
590
|
success: false,
|
|
610
591
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -749,7 +730,7 @@ async function createCompleteShipment(orderId, params, config2, dbAdapter, stora
|
|
|
749
730
|
}
|
|
750
731
|
const labelResult = await generateAndUploadLabel(
|
|
751
732
|
shipmentResult.shipmentId,
|
|
752
|
-
|
|
733
|
+
config2.labels.format,
|
|
753
734
|
config2.credentials,
|
|
754
735
|
storageAdapter
|
|
755
736
|
);
|
package/dist/index.mjs
CHANGED
|
@@ -248,9 +248,13 @@ async function authenticatedRequest(credentials, options) {
|
|
|
248
248
|
let errorMessage = "Label generation failed";
|
|
249
249
|
let errorCode = "UNKNOWN";
|
|
250
250
|
if (errorObj) {
|
|
251
|
-
if (errorObj
|
|
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) {
|
|
252
256
|
errorMessage = errorObj.errorMessage;
|
|
253
|
-
errorCode = errorObj.errorCode || errorObj.name ||
|
|
257
|
+
errorCode = errorObj.errorCode || errorObj.name || errorCode;
|
|
254
258
|
} else if (errorObj.name) {
|
|
255
259
|
errorMessage = errorObj.name;
|
|
256
260
|
errorCode = errorObj.name;
|
|
@@ -475,12 +479,7 @@ async function createShipment(credentials, params, businessConfig) {
|
|
|
475
479
|
async function generateLabel(credentials, params) {
|
|
476
480
|
try {
|
|
477
481
|
const { shipmentId, labelFormat } = params;
|
|
478
|
-
console.log("\n\u{1F3F7}\uFE0F [SDK generateLabel] Starting label generation");
|
|
479
|
-
console.log(` Shipment ID: ${shipmentId} (type: ${typeof shipmentId})`);
|
|
480
|
-
console.log(` Format: ${labelFormat}`);
|
|
481
|
-
console.log(` Accept Header: ${getAcceptHeader(labelFormat)}`);
|
|
482
482
|
const endpoint = `${DPD_API.ENDPOINTS.LABEL}/${shipmentId}/label/`;
|
|
483
|
-
console.log(` Endpoint: ${endpoint}`);
|
|
484
483
|
const response = await authenticatedRequest(credentials, {
|
|
485
484
|
method: "GET",
|
|
486
485
|
endpoint,
|
|
@@ -488,35 +487,17 @@ async function generateLabel(credentials, params) {
|
|
|
488
487
|
Accept: getAcceptHeader(labelFormat)
|
|
489
488
|
}
|
|
490
489
|
});
|
|
491
|
-
|
|
492
|
-
console.log(
|
|
493
|
-
"\u{1F4E6} [SDK generateLabel] Raw response:",
|
|
494
|
-
typeof response === "string" ? `String (${response.length} chars): ${response.substring(0, 200)}...` : response
|
|
495
|
-
);
|
|
496
|
-
if (typeof response === "object" && response.error) {
|
|
497
|
-
const errorObj = response.error;
|
|
498
|
-
console.error("\u274C [SDK generateLabel] DPD returned error object:", errorObj);
|
|
499
|
-
const errorMessage = errorObj.errorMessage || errorObj.name || JSON.stringify(errorObj);
|
|
500
|
-
return {
|
|
501
|
-
success: false,
|
|
502
|
-
error: `DPD API error: ${errorMessage}`
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
if (!response || typeof response === "object" && !response.data) {
|
|
506
|
-
console.error("\u274C [SDK generateLabel] No label data in response");
|
|
490
|
+
if (!response || typeof response !== "string") {
|
|
507
491
|
return {
|
|
508
492
|
success: false,
|
|
509
493
|
error: "No label data received from DPD"
|
|
510
494
|
};
|
|
511
495
|
}
|
|
512
|
-
const labelData = typeof response === "string" ? response : response.data;
|
|
513
|
-
console.log(`\u2705 [SDK generateLabel] Success! Label data length: ${labelData.length} chars`);
|
|
514
496
|
return {
|
|
515
497
|
success: true,
|
|
516
|
-
labelData
|
|
498
|
+
labelData: response
|
|
517
499
|
};
|
|
518
500
|
} catch (error) {
|
|
519
|
-
console.error("\u{1F4A5} [SDK generateLabel] Exception:", error);
|
|
520
501
|
return {
|
|
521
502
|
success: false,
|
|
522
503
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -661,7 +642,7 @@ async function createCompleteShipment(orderId, params, config2, dbAdapter, stora
|
|
|
661
642
|
}
|
|
662
643
|
const labelResult = await generateAndUploadLabel(
|
|
663
644
|
shipmentResult.shipmentId,
|
|
664
|
-
|
|
645
|
+
config2.labels.format,
|
|
665
646
|
config2.credentials,
|
|
666
647
|
storageAdapter
|
|
667
648
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jazzdev/dpd-local-sdk",
|
|
3
|
-
"version": "1.0.
|
|
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",
|