@optima-chat/logistics-cli 0.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.
@@ -0,0 +1,68 @@
1
+ import type { Address, AddressValidation, Label, RateParams, Shipment, ShippingRate, TrackingInfo } from '../types.js';
2
+ export declare class ApiError extends Error {
3
+ readonly statusCode: number;
4
+ constructor(statusCode: number, message: string);
5
+ }
6
+ export declare class LogisticsApi {
7
+ private readonly baseUrl;
8
+ private readonly token;
9
+ constructor(baseUrl?: string, token?: string);
10
+ getRates(params: RateParams): Promise<{
11
+ rates: ShippingRate[];
12
+ }>;
13
+ verifyRate(params: {
14
+ rateId: string;
15
+ origin: RateParams['origin'];
16
+ destination: RateParams['destination'];
17
+ items: RateParams['items'];
18
+ currency?: string;
19
+ incoterms?: string;
20
+ }): Promise<{
21
+ valid: boolean;
22
+ rate?: ShippingRate;
23
+ }>;
24
+ createShipment(params: {
25
+ logisticsOrderId: string;
26
+ orderId: string;
27
+ merchantId: string;
28
+ rateId: string;
29
+ origin: Address;
30
+ destination: Address;
31
+ items: RateParams['items'];
32
+ currency?: string;
33
+ incoterms?: string;
34
+ }): Promise<{
35
+ shipment: Shipment;
36
+ }>;
37
+ getShipment(id: string): Promise<{
38
+ shipment: Record<string, unknown>;
39
+ }>;
40
+ cancelShipment(id: string): Promise<{
41
+ success: boolean;
42
+ }>;
43
+ getLabel(id: string): Promise<{
44
+ label: Label;
45
+ }>;
46
+ getTracking(trackingNumber: string, courier?: string): Promise<{
47
+ tracking: TrackingInfo;
48
+ }>;
49
+ registerTracking(params: {
50
+ trackingNumber: string;
51
+ courier?: string;
52
+ logisticsOrderId?: string;
53
+ }): Promise<{
54
+ success: boolean;
55
+ }>;
56
+ detectCourier(trackingNumber: string): Promise<{
57
+ courier: string;
58
+ }>;
59
+ validateAddress(address: Address): Promise<{
60
+ validation: AddressValidation;
61
+ }>;
62
+ private headers;
63
+ private request;
64
+ private get;
65
+ private post;
66
+ private delete;
67
+ }
68
+ //# sourceMappingURL=logistics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logistics.d.ts","sourceRoot":"","sources":["../../src/api/logistics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,iBAAiB,EACjB,KAAK,EACL,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EACb,MAAM,aAAa,CAAA;AAEpB,qBAAa,QAAS,SAAQ,KAAK;aAEf,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM,EAClC,OAAO,EAAE,MAAM;CAKlB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;gBAElB,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAStC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;IAIhE,UAAU,CAAC,MAAM,EAAE;QACvB,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC5B,WAAW,EAAE,UAAU,CAAC,aAAa,CAAC,CAAA;QACtC,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;IAM9C,cAAc,CAAC,MAAM,EAAE;QAC3B,gBAAgB,EAAE,MAAM,CAAA;QACxB,OAAO,EAAE,MAAM,CAAA;QACf,UAAU,EAAE,MAAM,CAAA;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,OAAO,CAAA;QACf,WAAW,EAAE,OAAO,CAAA;QACpB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,QAAQ,CAAA;KAAE,CAAC;IAI7B,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAIvE,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIzD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;IAM/C,WAAW,CACf,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAA;KAAE,CAAC;IAOhC,gBAAgB,CAAC,MAAM,EAAE;QAC7B,cAAc,EAAE,MAAM,CAAA;QACtB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAC1B,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAI3B,aAAa,CACjB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAQzB,eAAe,CACnB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC;QAAE,UAAU,EAAE,iBAAiB,CAAA;KAAE,CAAC;IAS7C,OAAO,CAAC,OAAO;YAUD,OAAO;YA2BP,GAAG;YAIH,IAAI;YAIJ,MAAM;CAGrB"}
@@ -0,0 +1,97 @@
1
+ export class ApiError extends Error {
2
+ statusCode;
3
+ constructor(statusCode, message) {
4
+ super(message);
5
+ this.statusCode = statusCode;
6
+ this.name = 'ApiError';
7
+ }
8
+ }
9
+ export class LogisticsApi {
10
+ baseUrl;
11
+ token;
12
+ constructor(baseUrl, token) {
13
+ this.baseUrl = (baseUrl ?? process.env.LOGISTICS_URL ?? 'http://localhost:8380').replace(/\/+$/, '');
14
+ this.token = token ?? process.env.LOGISTICS_TOKEN ?? process.env.SERVICE_TOKEN ?? '';
15
+ }
16
+ // ── Rates ──────────────────────────────────────────────
17
+ async getRates(params) {
18
+ return this.post('/api/rates', params);
19
+ }
20
+ async verifyRate(params) {
21
+ return this.post('/api/rates/verify', params);
22
+ }
23
+ // ── Shipments ──────────────────────────────────────────
24
+ async createShipment(params) {
25
+ return this.post('/api/shipments', params);
26
+ }
27
+ async getShipment(id) {
28
+ return this.get(`/api/shipments/${encodeURIComponent(id)}`);
29
+ }
30
+ async cancelShipment(id) {
31
+ return this.delete(`/api/shipments/${encodeURIComponent(id)}`);
32
+ }
33
+ async getLabel(id) {
34
+ return this.get(`/api/shipments/${encodeURIComponent(id)}/label`);
35
+ }
36
+ // ── Tracking ───────────────────────────────────────────
37
+ async getTracking(trackingNumber, courier) {
38
+ const qs = courier ? `?courier=${encodeURIComponent(courier)}` : '';
39
+ return this.get(`/api/tracking/${encodeURIComponent(trackingNumber)}${qs}`);
40
+ }
41
+ async registerTracking(params) {
42
+ return this.post('/api/tracking/register', params);
43
+ }
44
+ async detectCourier(trackingNumber) {
45
+ return this.post('/api/tracking/detect-courier', {
46
+ trackingNumber,
47
+ });
48
+ }
49
+ // ── Address ────────────────────────────────────────────
50
+ async validateAddress(address) {
51
+ return this.post('/api/address/validate', address);
52
+ }
53
+ // ── Internal HTTP helpers ──────────────────────────────
54
+ headers() {
55
+ const h = {
56
+ 'Content-Type': 'application/json',
57
+ };
58
+ if (this.token) {
59
+ h['Authorization'] = `Bearer ${this.token}`;
60
+ }
61
+ return h;
62
+ }
63
+ async request(method, path, body) {
64
+ const url = `${this.baseUrl}${path}`;
65
+ const res = await fetch(url, {
66
+ method,
67
+ headers: this.headers(),
68
+ body: body !== undefined ? JSON.stringify(body) : undefined,
69
+ });
70
+ if (!res.ok) {
71
+ let message = res.statusText;
72
+ try {
73
+ const errBody = (await res.json());
74
+ message = errBody.message ?? errBody.error ?? message;
75
+ }
76
+ catch {
77
+ // ignore parse errors
78
+ }
79
+ throw new ApiError(res.status, message);
80
+ }
81
+ // 204 No Content
82
+ if (res.status === 204) {
83
+ return {};
84
+ }
85
+ return (await res.json());
86
+ }
87
+ async get(path) {
88
+ return this.request('GET', path);
89
+ }
90
+ async post(path, body) {
91
+ return this.request('POST', path, body);
92
+ }
93
+ async delete(path) {
94
+ return this.request('DELETE', path);
95
+ }
96
+ }
97
+ //# sourceMappingURL=logistics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logistics.js","sourceRoot":"","sources":["../../src/api/logistics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const addressCommand: Command;
3
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../src/commands/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,eAAO,MAAM,cAAc,SAE1B,CAAA"}
@@ -0,0 +1,22 @@
1
+ import { Command } from 'commander';
2
+ import { LogisticsApi } from '../api/logistics.js';
3
+ import { output, outputError } from '../utils/output.js';
4
+ export const addressCommand = new Command('address').description('Address operations');
5
+ addressCommand
6
+ .command('validate')
7
+ .description('Validate a postal address')
8
+ .requiredOption('--address <json>', 'Address to validate (JSON string)')
9
+ .option('--pretty', 'Human-readable output', false)
10
+ .action(async (opts) => {
11
+ try {
12
+ const address = JSON.parse(opts.address);
13
+ const api = new LogisticsApi();
14
+ const result = await api.validateAddress(address);
15
+ output(result, opts.pretty);
16
+ }
17
+ catch (err) {
18
+ outputError(err, opts.pretty);
19
+ process.exitCode = 1;
20
+ }
21
+ });
22
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../../src/commands/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAExD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAC9D,oBAAoB,CACrB,CAAA;AAED,cAAc;KACX,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,2BAA2B,CAAC;KACxC,cAAc,CAAC,kBAAkB,EAAE,mCAAmC,CAAC;KACvE,MAAM,CAAC,UAAU,EAAE,uBAAuB,EAAE,KAAK,CAAC;KAClD,MAAM,CAAC,KAAK,EAAE,IAA0C,EAAE,EAAE;IAC3D,IAAI,CAAC;QACH,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAY,CAAA;QAE5D,MAAM,GAAG,GAAG,IAAI,YAAY,EAAE,CAAA;QAC9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;QACjD,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const ratesCommand: Command;
3
+ //# sourceMappingURL=rates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rates.d.ts","sourceRoot":"","sources":["../../src/commands/rates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,eAAO,MAAM,YAAY,SAExB,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { Command } from 'commander';
2
+ import { LogisticsApi } from '../api/logistics.js';
3
+ import { output, outputError } from '../utils/output.js';
4
+ export const ratesCommand = new Command('rates').description('Query shipping rates');
5
+ ratesCommand
6
+ .command('query')
7
+ .description('Query available shipping rates')
8
+ .requiredOption('--origin <json>', 'Origin address (JSON string)')
9
+ .requiredOption('--destination <json>', 'Destination address (JSON string)')
10
+ .requiredOption('--items <json>', 'Parcel items (JSON string)')
11
+ .option('--currency <code>', 'Currency code')
12
+ .option('--pretty', 'Human-readable output', false)
13
+ .action(async (opts) => {
14
+ try {
15
+ const origin = JSON.parse(opts.origin);
16
+ const destination = JSON.parse(opts.destination);
17
+ const items = JSON.parse(opts.items);
18
+ const api = new LogisticsApi();
19
+ const result = await api.getRates({
20
+ origin,
21
+ destination,
22
+ items,
23
+ currency: opts.currency,
24
+ });
25
+ output(result, opts.pretty);
26
+ }
27
+ catch (err) {
28
+ outputError(err, opts.pretty);
29
+ process.exitCode = 1;
30
+ }
31
+ });
32
+ //# sourceMappingURL=rates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rates.js","sourceRoot":"","sources":["../../src/commands/rates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAExD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAC1D,sBAAsB,CACvB,CAAA;AAED,YAAY;KACT,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,gCAAgC,CAAC;KAC7C,cAAc,CAAC,iBAAiB,EAAE,8BAA8B,CAAC;KACjE,cAAc,CAAC,sBAAsB,EAAE,mCAAmC,CAAC;KAC3E,cAAc,CAAC,gBAAgB,EAAE,4BAA4B,CAAC;KAC9D,MAAM,CAAC,mBAAmB,EAAE,eAAe,CAAC;KAC5C,MAAM,CAAC,UAAU,EAAE,uBAAuB,EAAE,KAAK,CAAC;KAClD,MAAM,CACL,KAAK,EAAE,IAMN,EAAE,EAAE;IACH,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAY,CAAA;QAC1D,MAAM,WAAW,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAY,CAAA;QACpE,MAAM,KAAK,GAAiB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAiB,CAAA;QAElE,MAAM,GAAG,GAAG,IAAI,YAAY,EAAE,CAAA;QAC9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC;YAChC,MAAM;YACN,WAAW;YACX,KAAK;YACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC;AACH,CAAC,CACF,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const shipmentCommand: Command;
3
+ //# sourceMappingURL=shipment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipment.d.ts","sourceRoot":"","sources":["../../src/commands/shipment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAInC,eAAO,MAAM,eAAe,SAE3B,CAAA"}
@@ -0,0 +1,53 @@
1
+ import { Command } from 'commander';
2
+ import { LogisticsApi } from '../api/logistics.js';
3
+ import { output, outputError } from '../utils/output.js';
4
+ export const shipmentCommand = new Command('shipment').description('Manage shipments');
5
+ shipmentCommand
6
+ .command('get')
7
+ .description('Get shipment details')
8
+ .argument('<logistics-order-id>', 'Logistics order ID')
9
+ .option('--pretty', 'Human-readable output', false)
10
+ .action(async (id, opts) => {
11
+ try {
12
+ const api = new LogisticsApi();
13
+ const result = await api.getShipment(id);
14
+ output(result, opts.pretty);
15
+ }
16
+ catch (err) {
17
+ outputError(err, opts.pretty);
18
+ process.exitCode = 1;
19
+ }
20
+ });
21
+ shipmentCommand
22
+ .command('cancel')
23
+ .description('Cancel a shipment')
24
+ .argument('<logistics-order-id>', 'Logistics order ID')
25
+ .option('--pretty', 'Human-readable output', false)
26
+ .action(async (id, opts) => {
27
+ try {
28
+ const api = new LogisticsApi();
29
+ const result = await api.cancelShipment(id);
30
+ output(result, opts.pretty);
31
+ }
32
+ catch (err) {
33
+ outputError(err, opts.pretty);
34
+ process.exitCode = 1;
35
+ }
36
+ });
37
+ shipmentCommand
38
+ .command('label')
39
+ .description('Get shipment label')
40
+ .argument('<logistics-order-id>', 'Logistics order ID')
41
+ .option('--pretty', 'Human-readable output', false)
42
+ .action(async (id, opts) => {
43
+ try {
44
+ const api = new LogisticsApi();
45
+ const result = await api.getLabel(id);
46
+ output(result, opts.pretty);
47
+ }
48
+ catch (err) {
49
+ outputError(err, opts.pretty);
50
+ process.exitCode = 1;
51
+ }
52
+ });
53
+ //# sourceMappingURL=shipment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipment.js","sourceRoot":"","sources":["../../src/commands/shipment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAExD,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAChE,kBAAkB,CACnB,CAAA;AAED,eAAe;KACZ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,sBAAsB,CAAC;KACnC,QAAQ,CAAC,sBAAsB,EAAE,oBAAoB,CAAC;KACtD,MAAM,CAAC,UAAU,EAAE,uBAAuB,EAAE,KAAK,CAAC;KAClD,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,IAAyB,EAAE,EAAE;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,YAAY,EAAE,CAAA;QAC9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QACxC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC;AACH,CAAC,CAAC,CAAA;AAEJ,eAAe;KACZ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mBAAmB,CAAC;KAChC,QAAQ,CAAC,sBAAsB,EAAE,oBAAoB,CAAC;KACtD,MAAM,CAAC,UAAU,EAAE,uBAAuB,EAAE,KAAK,CAAC;KAClD,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,IAAyB,EAAE,EAAE;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,YAAY,EAAE,CAAA;QAC9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;QAC3C,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC;AACH,CAAC,CAAC,CAAA;AAEJ,eAAe;KACZ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oBAAoB,CAAC;KACjC,QAAQ,CAAC,sBAAsB,EAAE,oBAAoB,CAAC;KACtD,MAAM,CAAC,UAAU,EAAE,uBAAuB,EAAE,KAAK,CAAC;KAClD,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,IAAyB,EAAE,EAAE;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,YAAY,EAAE,CAAA;QAC9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;QACrC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const trackingCommand: Command;
3
+ //# sourceMappingURL=tracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracking.d.ts","sourceRoot":"","sources":["../../src/commands/tracking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAInC,eAAO,MAAM,eAAe,SAE3B,CAAA"}
@@ -0,0 +1,60 @@
1
+ import { Command } from 'commander';
2
+ import { LogisticsApi } from '../api/logistics.js';
3
+ import { output, outputError } from '../utils/output.js';
4
+ export const trackingCommand = new Command('tracking').description('Track shipments');
5
+ trackingCommand
6
+ .command('get')
7
+ .description('Get tracking info for a tracking number')
8
+ .argument('<tracking-number>', 'Tracking number')
9
+ .option('--courier <slug>', 'Courier slug')
10
+ .option('--pretty', 'Human-readable output', false)
11
+ .action(async (trackingNumber, opts) => {
12
+ try {
13
+ const api = new LogisticsApi();
14
+ const result = await api.getTracking(trackingNumber, opts.courier);
15
+ output(result, opts.pretty);
16
+ }
17
+ catch (err) {
18
+ outputError(err, opts.pretty);
19
+ process.exitCode = 1;
20
+ }
21
+ });
22
+ trackingCommand
23
+ .command('register')
24
+ .description('Register a tracking number for push notifications')
25
+ .argument('<tracking-number>', 'Tracking number')
26
+ .option('--courier <slug>', 'Courier slug')
27
+ .option('--logistics-order-id <id>', 'Logistics order ID to associate')
28
+ .option('--pretty', 'Human-readable output', false)
29
+ .action(async (trackingNumber, opts) => {
30
+ try {
31
+ const api = new LogisticsApi();
32
+ const result = await api.registerTracking({
33
+ trackingNumber,
34
+ courier: opts.courier,
35
+ logisticsOrderId: opts.logisticsOrderId,
36
+ });
37
+ output(result, opts.pretty);
38
+ }
39
+ catch (err) {
40
+ outputError(err, opts.pretty);
41
+ process.exitCode = 1;
42
+ }
43
+ });
44
+ trackingCommand
45
+ .command('detect-courier')
46
+ .description('Detect the courier for a tracking number')
47
+ .argument('<tracking-number>', 'Tracking number')
48
+ .option('--pretty', 'Human-readable output', false)
49
+ .action(async (trackingNumber, opts) => {
50
+ try {
51
+ const api = new LogisticsApi();
52
+ const result = await api.detectCourier(trackingNumber);
53
+ output(result, opts.pretty);
54
+ }
55
+ catch (err) {
56
+ outputError(err, opts.pretty);
57
+ process.exitCode = 1;
58
+ }
59
+ });
60
+ //# sourceMappingURL=tracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracking.js","sourceRoot":"","sources":["../../src/commands/tracking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { shipmentCommand } from './commands/shipment.js';
4
+ import { trackingCommand } from './commands/tracking.js';
5
+ import { ratesCommand } from './commands/rates.js';
6
+ import { addressCommand } from './commands/address.js';
7
+ const program = new Command();
8
+ program
9
+ .name('logistics')
10
+ .description('Optima Logistics CLI')
11
+ .version('0.1.0');
12
+ program.addCommand(shipmentCommand);
13
+ program.addCommand(trackingCommand);
14
+ program.addCommand(ratesCommand);
15
+ program.addCommand(addressCommand);
16
+ program.parse();
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,sBAAsB,CAAC;KACnC,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAA;AACnC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAA;AACnC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAElC,OAAO,CAAC,KAAK,EAAE,CAAA"}
@@ -0,0 +1,102 @@
1
+ /** Postal/shipping address */
2
+ export interface Address {
3
+ name: string;
4
+ company?: string;
5
+ street1: string;
6
+ street2?: string;
7
+ city: string;
8
+ state?: string;
9
+ postalCode: string;
10
+ country: string;
11
+ phone?: string;
12
+ email?: string;
13
+ }
14
+ /** Result of address validation */
15
+ export interface AddressValidation {
16
+ valid: boolean;
17
+ normalizedAddress?: Address;
18
+ messages?: string[];
19
+ }
20
+ /** Parameters for querying shipping rates */
21
+ export interface RateParams {
22
+ origin: Address;
23
+ destination: Address;
24
+ items: ParcelItem[];
25
+ currency?: string;
26
+ incoterms?: string;
27
+ }
28
+ /** Item in a parcel */
29
+ export interface ParcelItem {
30
+ title: string;
31
+ sku?: string;
32
+ quantity: number;
33
+ price: number;
34
+ currency: string;
35
+ weight: number;
36
+ weightUnit?: 'g' | 'kg' | 'lb' | 'oz';
37
+ dimensions?: {
38
+ length: number;
39
+ width: number;
40
+ height: number;
41
+ unit: 'cm' | 'in';
42
+ };
43
+ hsCode?: string;
44
+ originCountry?: string;
45
+ }
46
+ /** A shipping rate quote from a provider */
47
+ export interface ShippingRate {
48
+ rateId: string;
49
+ provider: string;
50
+ courierName: string;
51
+ courierId?: string;
52
+ serviceName?: string;
53
+ totalCharge: number;
54
+ currency: string;
55
+ minDeliveryDays?: number;
56
+ maxDeliveryDays?: number;
57
+ expiresAt?: string;
58
+ metadata?: Record<string, unknown>;
59
+ }
60
+ /** Label state */
61
+ export type LabelState = 'pending' | 'generating' | 'generated' | 'failed';
62
+ /** A created shipment */
63
+ export interface Shipment {
64
+ shipmentId: string;
65
+ provider: string;
66
+ trackingNumber?: string;
67
+ trackingUrl?: string;
68
+ carrier?: string;
69
+ labelUrl?: string;
70
+ labelState: LabelState;
71
+ status: string;
72
+ createdAt: string;
73
+ metadata?: Record<string, unknown>;
74
+ }
75
+ /** Shipping label */
76
+ export interface Label {
77
+ shipmentId: string;
78
+ url: string;
79
+ format?: string;
80
+ state: LabelState;
81
+ createdAt?: string;
82
+ }
83
+ /** A checkpoint in a tracking timeline */
84
+ export interface Checkpoint {
85
+ timestamp: string;
86
+ status: string;
87
+ message: string;
88
+ location?: string;
89
+ }
90
+ /** Full tracking information for a shipment */
91
+ export interface TrackingInfo {
92
+ trackingNumber: string;
93
+ courier: string;
94
+ courierName?: string;
95
+ status: string;
96
+ estimatedDelivery?: string;
97
+ checkpoints: Checkpoint[];
98
+ originCountry?: string;
99
+ destinationCountry?: string;
100
+ metadata?: Record<string, unknown>;
101
+ }
102
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Output data to stdout.
3
+ *
4
+ * - Default: JSON (machine-readable)
5
+ * - `pretty`: human-readable formatted output
6
+ */
7
+ export declare function output(data: unknown, pretty: boolean): void;
8
+ /**
9
+ * Output an error to stderr.
10
+ *
11
+ * - Default: JSON error object
12
+ * - `pretty`: human-readable error message
13
+ */
14
+ export declare function outputError(error: unknown, pretty: boolean): void;
15
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CA6B3D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CA0BjE"}
@@ -0,0 +1,106 @@
1
+ import { ApiError } from '../api/logistics.js';
2
+ /**
3
+ * Output data to stdout.
4
+ *
5
+ * - Default: JSON (machine-readable)
6
+ * - `pretty`: human-readable formatted output
7
+ */
8
+ export function output(data, pretty) {
9
+ if (!pretty) {
10
+ console.log(JSON.stringify(data, null, 2));
11
+ return;
12
+ }
13
+ if (data === null || data === undefined) {
14
+ console.log('(no data)');
15
+ return;
16
+ }
17
+ if (Array.isArray(data)) {
18
+ if (data.length === 0) {
19
+ console.log('(empty list)');
20
+ return;
21
+ }
22
+ for (const item of data) {
23
+ printObject(item);
24
+ console.log('---');
25
+ }
26
+ return;
27
+ }
28
+ if (typeof data === 'object') {
29
+ printObject(data);
30
+ return;
31
+ }
32
+ console.log(String(data));
33
+ }
34
+ /**
35
+ * Output an error to stderr.
36
+ *
37
+ * - Default: JSON error object
38
+ * - `pretty`: human-readable error message
39
+ */
40
+ export function outputError(error, pretty) {
41
+ if (error instanceof ApiError) {
42
+ if (!pretty) {
43
+ console.error(JSON.stringify({ error: error.message, statusCode: error.statusCode }, null, 2));
44
+ }
45
+ else {
46
+ console.error(`Error (${error.statusCode}): ${error.message}`);
47
+ }
48
+ return;
49
+ }
50
+ if (error instanceof Error) {
51
+ if (!pretty) {
52
+ console.error(JSON.stringify({ error: error.message }, null, 2));
53
+ }
54
+ else {
55
+ console.error(`Error: ${error.message}`);
56
+ }
57
+ return;
58
+ }
59
+ if (!pretty) {
60
+ console.error(JSON.stringify({ error: String(error) }, null, 2));
61
+ }
62
+ else {
63
+ console.error(`Error: ${String(error)}`);
64
+ }
65
+ }
66
+ function printObject(obj, indent = 0) {
67
+ if (obj === null || obj === undefined) {
68
+ console.log(' '.repeat(indent) + '(null)');
69
+ return;
70
+ }
71
+ if (typeof obj !== 'object') {
72
+ console.log(' '.repeat(indent) + String(obj));
73
+ return;
74
+ }
75
+ const record = obj;
76
+ for (const [key, value] of Object.entries(record)) {
77
+ if (value === null || value === undefined) {
78
+ continue;
79
+ }
80
+ if (typeof value === 'object' && !Array.isArray(value)) {
81
+ console.log(' '.repeat(indent) + `${key}:`);
82
+ printObject(value, indent + 2);
83
+ }
84
+ else if (Array.isArray(value)) {
85
+ console.log(' '.repeat(indent) + `${key}:`);
86
+ if (value.length === 0) {
87
+ console.log(' '.repeat(indent + 2) + '(empty)');
88
+ }
89
+ else {
90
+ for (const item of value) {
91
+ if (typeof item === 'object' && item !== null) {
92
+ printObject(item, indent + 2);
93
+ console.log(' '.repeat(indent + 2) + '---');
94
+ }
95
+ else {
96
+ console.log(' '.repeat(indent + 2) + `- ${String(item)}`);
97
+ }
98
+ }
99
+ }
100
+ }
101
+ else {
102
+ console.log(' '.repeat(indent) + `${key}: ${String(value)}`);
103
+ }
104
+ }
105
+ }
106
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@optima-chat/logistics-cli",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "logistics": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "dependencies": {
16
+ "commander": "^13.1.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^22.10.2",
20
+ "tsx": "^4.19.2",
21
+ "typescript": "^5.7.3",
22
+ "vitest": "^3.2.4"
23
+ },
24
+ "scripts": {
25
+ "dev": "tsx src/index.ts",
26
+ "build": "tsc",
27
+ "start": "node dist/index.js",
28
+ "typecheck": "tsc --noEmit",
29
+ "test": "vitest run --passWithNoTests"
30
+ }
31
+ }