@rovela-ai/sdk 0.1.52 → 0.1.54
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/dist/admin/api/index.d.ts +17 -0
- package/dist/admin/api/index.d.ts.map +1 -1
- package/dist/admin/api/index.js +19 -0
- package/dist/admin/api/index.js.map +1 -1
- package/dist/admin/api/settings.d.ts +2 -1
- package/dist/admin/api/settings.d.ts.map +1 -1
- package/dist/admin/api/settings.js +9 -1
- package/dist/admin/api/settings.js.map +1 -1
- package/dist/admin/api/shipping.d.ts +148 -0
- package/dist/admin/api/shipping.d.ts.map +1 -0
- package/dist/admin/api/shipping.js +373 -0
- package/dist/admin/api/shipping.js.map +1 -0
- package/dist/admin/api/stripe-status.d.ts +39 -0
- package/dist/admin/api/stripe-status.d.ts.map +1 -0
- package/dist/admin/api/stripe-status.js +101 -0
- package/dist/admin/api/stripe-status.js.map +1 -0
- package/dist/admin/components/AdminNav.d.ts.map +1 -1
- package/dist/admin/components/AdminNav.js +9 -1
- package/dist/admin/components/AdminNav.js.map +1 -1
- package/dist/admin/components/PaymentSettings.d.ts +12 -0
- package/dist/admin/components/PaymentSettings.d.ts.map +1 -0
- package/dist/admin/components/PaymentSettings.js +144 -0
- package/dist/admin/components/PaymentSettings.js.map +1 -0
- package/dist/admin/components/ShippingSettings.d.ts +3 -0
- package/dist/admin/components/ShippingSettings.d.ts.map +1 -0
- package/dist/admin/components/ShippingSettings.js +322 -0
- package/dist/admin/components/ShippingSettings.js.map +1 -0
- package/dist/admin/components/StoreSettings.d.ts.map +1 -1
- package/dist/admin/components/StoreSettings.js +1 -15
- package/dist/admin/components/StoreSettings.js.map +1 -1
- package/dist/admin/components/index.d.ts +2 -0
- package/dist/admin/components/index.d.ts.map +1 -1
- package/dist/admin/components/index.js +5 -0
- package/dist/admin/components/index.js.map +1 -1
- package/dist/admin/index.d.ts +3 -3
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +7 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/types.d.ts +98 -2
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/checkout/server/create-checkout-session.d.ts +7 -0
- package/dist/checkout/server/create-checkout-session.d.ts.map +1 -1
- package/dist/checkout/server/create-checkout-session.js +179 -7
- package/dist/checkout/server/create-checkout-session.js.map +1 -1
- package/dist/checkout/stripe/client.d.ts +4 -2
- package/dist/checkout/stripe/client.d.ts.map +1 -1
- package/dist/checkout/stripe/client.js +4 -2
- package/dist/checkout/stripe/client.js.map +1 -1
- package/dist/core/db/queries.d.ts +107 -2
- package/dist/core/db/queries.d.ts.map +1 -1
- package/dist/core/db/queries.js +199 -0
- package/dist/core/db/queries.js.map +1 -1
- package/dist/core/db/schema.d.ts +407 -0
- package/dist/core/db/schema.d.ts.map +1 -1
- package/dist/core/db/schema.js +45 -0
- package/dist/core/db/schema.js.map +1 -1
- package/dist/core/types.d.ts +31 -0
- package/dist/core/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -53,6 +53,21 @@
|
|
|
53
53
|
*
|
|
54
54
|
* // app/api/admin/settings/route.ts (store settings)
|
|
55
55
|
* export { GET, PUT } from '@rovela/sdk/admin/api/settings'
|
|
56
|
+
*
|
|
57
|
+
* // app/api/admin/stripe-status/route.ts (Stripe connection & tax status)
|
|
58
|
+
* export { getStripeStatus as GET } from '@rovela/sdk/admin/api'
|
|
59
|
+
*
|
|
60
|
+
* // app/api/admin/shipping/zones/route.ts
|
|
61
|
+
* export { getZones as GET, createZone as POST } from '@rovela/sdk/admin/api/shipping'
|
|
62
|
+
*
|
|
63
|
+
* // app/api/admin/shipping/zones/[id]/route.ts
|
|
64
|
+
* export { getZone as GET, updateZone as PUT, deleteZone as DELETE } from '@rovela/sdk/admin/api/shipping'
|
|
65
|
+
*
|
|
66
|
+
* // app/api/admin/shipping/rates/route.ts
|
|
67
|
+
* export { createRate as POST } from '@rovela/sdk/admin/api/shipping'
|
|
68
|
+
*
|
|
69
|
+
* // app/api/admin/shipping/rates/[id]/route.ts
|
|
70
|
+
* export { updateRate as PUT, deleteRate as DELETE } from '@rovela/sdk/admin/api/shipping'
|
|
56
71
|
* ```
|
|
57
72
|
*/
|
|
58
73
|
export { createAdminAuthHandlers } from './auth';
|
|
@@ -65,4 +80,6 @@ export { GET as getCustomers, getCustomer, updateCustomer, deleteCustomer, } fro
|
|
|
65
80
|
export { POST as setupAdmin } from './setup';
|
|
66
81
|
export { GET as checkAdminExists } from './check';
|
|
67
82
|
export { GET as getSettings, PUT as updateSettings } from './settings';
|
|
83
|
+
export { GET as getStripeStatus } from './stripe-status';
|
|
84
|
+
export { getZones as getShippingZones, createZone as createShippingZone, getZone as getShippingZone, updateZone as updateShippingZone, deleteZone as deleteShippingZone, createRate as createShippingRate, updateRate as updateShippingRate, deleteRate as deleteShippingRate, } from './shipping';
|
|
68
85
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/admin/api/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/admin/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,QAAQ,CAAA;AAGhD,OAAO,EACL,GAAG,IAAI,WAAW,EAClB,IAAI,IAAI,aAAa,EACrB,UAAU,EACV,GAAG,IAAI,aAAa,EACpB,MAAM,IAAI,aAAa,EACvB,UAAU,EACV,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,GAAG,IAAI,SAAS,EAChB,QAAQ,EACR,GAAG,IAAI,WAAW,GACnB,MAAM,UAAU,CAAA;AAGjB,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,UAAU,CAAA;AAGhD,OAAO,EAAE,GAAG,IAAI,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGzC,OAAO,EACL,GAAG,IAAI,aAAa,EACpB,IAAI,IAAI,cAAc,EACtB,WAAW,EACX,GAAG,IAAI,cAAc,EACrB,MAAM,IAAI,cAAc,GACzB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,GAAG,IAAI,YAAY,EACnB,WAAW,EACX,cAAc,EACd,cAAc,GACf,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,SAAS,CAAA;AAG5C,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAGjD,OAAO,EAAE,GAAG,IAAI,WAAW,EAAE,GAAG,IAAI,cAAc,EAAE,MAAM,YAAY,CAAA;AAGtE,OAAO,EAAE,GAAG,IAAI,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGxD,OAAO,EACL,QAAQ,IAAI,gBAAgB,EAC5B,UAAU,IAAI,kBAAkB,EAChC,OAAO,IAAI,eAAe,EAC1B,UAAU,IAAI,kBAAkB,EAChC,UAAU,IAAI,kBAAkB,EAChC,UAAU,IAAI,kBAAkB,EAChC,UAAU,IAAI,kBAAkB,EAChC,UAAU,IAAI,kBAAkB,GACjC,MAAM,YAAY,CAAA"}
|
package/dist/admin/api/index.js
CHANGED
|
@@ -53,6 +53,21 @@
|
|
|
53
53
|
*
|
|
54
54
|
* // app/api/admin/settings/route.ts (store settings)
|
|
55
55
|
* export { GET, PUT } from '@rovela/sdk/admin/api/settings'
|
|
56
|
+
*
|
|
57
|
+
* // app/api/admin/stripe-status/route.ts (Stripe connection & tax status)
|
|
58
|
+
* export { getStripeStatus as GET } from '@rovela/sdk/admin/api'
|
|
59
|
+
*
|
|
60
|
+
* // app/api/admin/shipping/zones/route.ts
|
|
61
|
+
* export { getZones as GET, createZone as POST } from '@rovela/sdk/admin/api/shipping'
|
|
62
|
+
*
|
|
63
|
+
* // app/api/admin/shipping/zones/[id]/route.ts
|
|
64
|
+
* export { getZone as GET, updateZone as PUT, deleteZone as DELETE } from '@rovela/sdk/admin/api/shipping'
|
|
65
|
+
*
|
|
66
|
+
* // app/api/admin/shipping/rates/route.ts
|
|
67
|
+
* export { createRate as POST } from '@rovela/sdk/admin/api/shipping'
|
|
68
|
+
*
|
|
69
|
+
* // app/api/admin/shipping/rates/[id]/route.ts
|
|
70
|
+
* export { updateRate as PUT, deleteRate as DELETE } from '@rovela/sdk/admin/api/shipping'
|
|
56
71
|
* ```
|
|
57
72
|
*/
|
|
58
73
|
// Auth
|
|
@@ -75,4 +90,8 @@ export { POST as setupAdmin } from './setup';
|
|
|
75
90
|
export { GET as checkAdminExists } from './check';
|
|
76
91
|
// Settings
|
|
77
92
|
export { GET as getSettings, PUT as updateSettings } from './settings';
|
|
93
|
+
// Stripe Status
|
|
94
|
+
export { GET as getStripeStatus } from './stripe-status';
|
|
95
|
+
// Shipping
|
|
96
|
+
export { getZones as getShippingZones, createZone as createShippingZone, getZone as getShippingZone, updateZone as updateShippingZone, deleteZone as deleteShippingZone, createRate as createShippingRate, updateRate as updateShippingRate, deleteRate as deleteShippingRate, } from './shipping';
|
|
78
97
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/admin/api/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/admin/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAEH,OAAO;AACP,OAAO,EAAE,uBAAuB,EAAE,MAAM,QAAQ,CAAA;AAEhD,WAAW;AACX,OAAO,EACL,GAAG,IAAI,WAAW,EAClB,IAAI,IAAI,aAAa,EACrB,UAAU,EACV,GAAG,IAAI,aAAa,EACpB,MAAM,IAAI,aAAa,EACvB,UAAU,EACV,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,YAAY,CAAA;AAEnB,SAAS;AACT,OAAO,EACL,GAAG,IAAI,SAAS,EAChB,QAAQ,EACR,GAAG,IAAI,WAAW,GACnB,MAAM,UAAU,CAAA;AAEjB,SAAS;AACT,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,UAAU,CAAA;AAEhD,QAAQ;AACR,OAAO,EAAE,GAAG,IAAI,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEzC,aAAa;AACb,OAAO,EACL,GAAG,IAAI,aAAa,EACpB,IAAI,IAAI,cAAc,EACtB,WAAW,EACX,GAAG,IAAI,cAAc,EACrB,MAAM,IAAI,cAAc,GACzB,MAAM,cAAc,CAAA;AAErB,YAAY;AACZ,OAAO,EACL,GAAG,IAAI,YAAY,EACnB,WAAW,EACX,cAAc,EACd,cAAc,GACf,MAAM,aAAa,CAAA;AAEpB,oCAAoC;AACpC,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,SAAS,CAAA;AAE5C,gCAAgC;AAChC,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAEjD,WAAW;AACX,OAAO,EAAE,GAAG,IAAI,WAAW,EAAE,GAAG,IAAI,cAAc,EAAE,MAAM,YAAY,CAAA;AAEtE,gBAAgB;AAChB,OAAO,EAAE,GAAG,IAAI,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAExD,WAAW;AACX,OAAO,EACL,QAAQ,IAAI,gBAAgB,EAC5B,UAAU,IAAI,kBAAkB,EAChC,OAAO,IAAI,eAAe,EAC1B,UAAU,IAAI,kBAAkB,EAChC,UAAU,IAAI,kBAAkB,EAChC,UAAU,IAAI,kBAAkB,EAChC,UAAU,IAAI,kBAAkB,EAChC,UAAU,IAAI,kBAAkB,GACjC,MAAM,YAAY,CAAA"}
|
|
@@ -38,7 +38,8 @@ export declare function GET(): Promise<NextResponse<SettingsResponse | AdminApiE
|
|
|
38
38
|
* "taxEnabled": true,
|
|
39
39
|
* "taxRate": 8.5,
|
|
40
40
|
* "shippingEnabled": true,
|
|
41
|
-
* "freeShippingThreshold": 100
|
|
41
|
+
* "freeShippingThreshold": 100,
|
|
42
|
+
* "shippingCountries": ["US", "CA", "MX"]
|
|
42
43
|
* }
|
|
43
44
|
* ```
|
|
44
45
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/admin/api/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGvD,OAAO,EAAgC,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAM7C,UAAU,gBAAgB;IACxB,QAAQ,EAAE,iBAAiB,CAAA;CAC5B;
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/admin/api/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGvD,OAAO,EAAgC,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAM7C,UAAU,gBAAgB;IACxB,QAAQ,EAAE,iBAAiB,CAAA;CAC5B;AAiCD;;;;;GAKG;AACH,wBAAsB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,gBAAgB,GAAG,aAAa,CAAC,CAAC,CA6BnF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,GAAG,CACvB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,gBAAgB,GAAG,aAAa,CAAC,CAAC,CA4DzD"}
|
|
@@ -36,6 +36,7 @@ function getDefaultSettings() {
|
|
|
36
36
|
taxRate: 0,
|
|
37
37
|
shippingEnabled: true,
|
|
38
38
|
freeShippingThreshold: 0,
|
|
39
|
+
shippingCountries: ['US', 'CA'],
|
|
39
40
|
};
|
|
40
41
|
}
|
|
41
42
|
// =============================================================================
|
|
@@ -84,7 +85,8 @@ export async function GET() {
|
|
|
84
85
|
* "taxEnabled": true,
|
|
85
86
|
* "taxRate": 8.5,
|
|
86
87
|
* "shippingEnabled": true,
|
|
87
|
-
* "freeShippingThreshold": 100
|
|
88
|
+
* "freeShippingThreshold": 100,
|
|
89
|
+
* "shippingCountries": ["US", "CA", "MX"]
|
|
88
90
|
* }
|
|
89
91
|
* ```
|
|
90
92
|
*/
|
|
@@ -124,6 +126,12 @@ export async function PUT(request) {
|
|
|
124
126
|
if (typeof body.freeShippingThreshold === 'number') {
|
|
125
127
|
data.freeShippingThreshold = Math.max(0, body.freeShippingThreshold);
|
|
126
128
|
}
|
|
129
|
+
if (Array.isArray(body.shippingCountries)) {
|
|
130
|
+
data.shippingCountries = body.shippingCountries
|
|
131
|
+
.filter((c) => typeof c === 'string')
|
|
132
|
+
.map((c) => c.toUpperCase().trim().slice(0, 2))
|
|
133
|
+
.filter((c) => c.length === 2);
|
|
134
|
+
}
|
|
127
135
|
// Upsert settings
|
|
128
136
|
const settings = await upsertSettings(data);
|
|
129
137
|
return NextResponse.json({ settings });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/admin/api/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAe,YAAY,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAqB,MAAM,uBAAuB,CAAA;AAWvF,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,SAAS,kBAAkB;IACzB,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,UAAU;QAC/C,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE;QAC5E,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,KAAK;QAClD,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,kBAAkB;QAC/D,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,CAAC;QACV,eAAe,EAAE,IAAI;QACrB,qBAAqB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/admin/api/settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rovela/sdk/admin/api/shipping
|
|
3
|
+
*
|
|
4
|
+
* API route handlers for admin shipping zone and rate management.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* // app/api/admin/shipping/zones/route.ts
|
|
9
|
+
* export { getZones as GET, createZone as POST } from '@rovela/sdk/admin/api/shipping'
|
|
10
|
+
*
|
|
11
|
+
* // app/api/admin/shipping/zones/[id]/route.ts
|
|
12
|
+
* export { getZone as GET, updateZone as PUT, deleteZone as DELETE } from '@rovela/sdk/admin/api/shipping'
|
|
13
|
+
*
|
|
14
|
+
* // app/api/admin/shipping/rates/route.ts
|
|
15
|
+
* export { createRate as POST } from '@rovela/sdk/admin/api/shipping'
|
|
16
|
+
*
|
|
17
|
+
* // app/api/admin/shipping/rates/[id]/route.ts
|
|
18
|
+
* export { updateRate as PUT, deleteRate as DELETE } from '@rovela/sdk/admin/api/shipping'
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
22
|
+
import type { AdminApiError, CrudResult, ShippingZoneData } from '../types';
|
|
23
|
+
/**
|
|
24
|
+
* GET /api/admin/shipping/zones
|
|
25
|
+
*
|
|
26
|
+
* List all shipping zones with their rates.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getZones(): Promise<NextResponse<{
|
|
29
|
+
data: ShippingZoneData[];
|
|
30
|
+
} | AdminApiError>>;
|
|
31
|
+
/**
|
|
32
|
+
* POST /api/admin/shipping/zones
|
|
33
|
+
*
|
|
34
|
+
* Create a new shipping zone.
|
|
35
|
+
*
|
|
36
|
+
* Request Body:
|
|
37
|
+
* ```json
|
|
38
|
+
* {
|
|
39
|
+
* "name": "Domestic",
|
|
40
|
+
* "countries": ["US", "CA"],
|
|
41
|
+
* "isActive": true,
|
|
42
|
+
* "sortOrder": 0
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function createZone(request: NextRequest): Promise<NextResponse<CrudResult<unknown> | AdminApiError>>;
|
|
47
|
+
/**
|
|
48
|
+
* GET /api/admin/shipping/zones/[id]
|
|
49
|
+
*
|
|
50
|
+
* Get a single shipping zone by ID with its rates.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getZone(request: NextRequest, { params }: {
|
|
53
|
+
params: Promise<{
|
|
54
|
+
id: string;
|
|
55
|
+
}>;
|
|
56
|
+
}): Promise<NextResponse<{
|
|
57
|
+
data: ShippingZoneData;
|
|
58
|
+
} | AdminApiError>>;
|
|
59
|
+
/**
|
|
60
|
+
* PUT /api/admin/shipping/zones/[id]
|
|
61
|
+
*
|
|
62
|
+
* Update a shipping zone by ID.
|
|
63
|
+
*
|
|
64
|
+
* Request Body:
|
|
65
|
+
* ```json
|
|
66
|
+
* {
|
|
67
|
+
* "name": "Updated Zone Name",
|
|
68
|
+
* "countries": ["US", "CA", "MX"],
|
|
69
|
+
* "isActive": true,
|
|
70
|
+
* "sortOrder": 1
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function updateZone(request: NextRequest, { params }: {
|
|
75
|
+
params: Promise<{
|
|
76
|
+
id: string;
|
|
77
|
+
}>;
|
|
78
|
+
}): Promise<NextResponse<CrudResult<unknown> | AdminApiError>>;
|
|
79
|
+
/**
|
|
80
|
+
* DELETE /api/admin/shipping/zones/[id]
|
|
81
|
+
*
|
|
82
|
+
* Delete a shipping zone by ID. This cascades to delete all rates in the zone.
|
|
83
|
+
*/
|
|
84
|
+
export declare function deleteZone(request: NextRequest, { params }: {
|
|
85
|
+
params: Promise<{
|
|
86
|
+
id: string;
|
|
87
|
+
}>;
|
|
88
|
+
}): Promise<NextResponse<{
|
|
89
|
+
success: boolean;
|
|
90
|
+
} | AdminApiError>>;
|
|
91
|
+
/**
|
|
92
|
+
* POST /api/admin/shipping/rates
|
|
93
|
+
*
|
|
94
|
+
* Create a new shipping rate for a zone.
|
|
95
|
+
*
|
|
96
|
+
* Request Body:
|
|
97
|
+
* ```json
|
|
98
|
+
* {
|
|
99
|
+
* "zoneId": "uuid",
|
|
100
|
+
* "name": "Standard Shipping",
|
|
101
|
+
* "description": "5-7 business days",
|
|
102
|
+
* "price": 5.99,
|
|
103
|
+
* "minOrderAmount": 0,
|
|
104
|
+
* "maxOrderAmount": null,
|
|
105
|
+
* "estimatedDays": "5-7",
|
|
106
|
+
* "isActive": true,
|
|
107
|
+
* "sortOrder": 0
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export declare function createRate(request: NextRequest): Promise<NextResponse<CrudResult<unknown> | AdminApiError>>;
|
|
112
|
+
/**
|
|
113
|
+
* PUT /api/admin/shipping/rates/[id]
|
|
114
|
+
*
|
|
115
|
+
* Update a shipping rate by ID.
|
|
116
|
+
*
|
|
117
|
+
* Request Body:
|
|
118
|
+
* ```json
|
|
119
|
+
* {
|
|
120
|
+
* "name": "Express Shipping",
|
|
121
|
+
* "description": "2-3 business days",
|
|
122
|
+
* "price": 12.99,
|
|
123
|
+
* "minOrderAmount": 0,
|
|
124
|
+
* "maxOrderAmount": 100,
|
|
125
|
+
* "estimatedDays": "2-3",
|
|
126
|
+
* "isActive": true,
|
|
127
|
+
* "sortOrder": 1
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export declare function updateRate(request: NextRequest, { params }: {
|
|
132
|
+
params: Promise<{
|
|
133
|
+
id: string;
|
|
134
|
+
}>;
|
|
135
|
+
}): Promise<NextResponse<CrudResult<unknown> | AdminApiError>>;
|
|
136
|
+
/**
|
|
137
|
+
* DELETE /api/admin/shipping/rates/[id]
|
|
138
|
+
*
|
|
139
|
+
* Delete a shipping rate by ID.
|
|
140
|
+
*/
|
|
141
|
+
export declare function deleteRate(request: NextRequest, { params }: {
|
|
142
|
+
params: Promise<{
|
|
143
|
+
id: string;
|
|
144
|
+
}>;
|
|
145
|
+
}): Promise<NextResponse<{
|
|
146
|
+
success: boolean;
|
|
147
|
+
} | AdminApiError>>;
|
|
148
|
+
//# sourceMappingURL=shipping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shipping.d.ts","sourceRoot":"","sources":["../../../src/admin/api/shipping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAavD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAsB3E;;;;GAIG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;IAAE,IAAI,EAAE,gBAAgB,EAAE,CAAA;CAAE,GAAG,aAAa,CAAC,CAAC,CAepG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC,CAkD5D;AAMD;;;;GAIG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,WAAW,EACpB,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAC9C,OAAO,CAAC,YAAY,CAAC;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAAG,aAAa,CAAC,CAAC,CAuBnE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,EACpB,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAC9C,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC,CAiE5D;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,EACpB,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAC9C,OAAO,CAAC,YAAY,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,aAAa,CAAC,CAAC,CAuB7D;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC,CA8D5D;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,EACpB,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAC9C,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC,CAsE5D;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,EACpB,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAC9C,OAAO,CAAC,YAAY,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,aAAa,CAAC,CAAC,CAuB7D"}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rovela/sdk/admin/api/shipping
|
|
3
|
+
*
|
|
4
|
+
* API route handlers for admin shipping zone and rate management.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* // app/api/admin/shipping/zones/route.ts
|
|
9
|
+
* export { getZones as GET, createZone as POST } from '@rovela/sdk/admin/api/shipping'
|
|
10
|
+
*
|
|
11
|
+
* // app/api/admin/shipping/zones/[id]/route.ts
|
|
12
|
+
* export { getZone as GET, updateZone as PUT, deleteZone as DELETE } from '@rovela/sdk/admin/api/shipping'
|
|
13
|
+
*
|
|
14
|
+
* // app/api/admin/shipping/rates/route.ts
|
|
15
|
+
* export { createRate as POST } from '@rovela/sdk/admin/api/shipping'
|
|
16
|
+
*
|
|
17
|
+
* // app/api/admin/shipping/rates/[id]/route.ts
|
|
18
|
+
* export { updateRate as PUT, deleteRate as DELETE } from '@rovela/sdk/admin/api/shipping'
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
import { NextResponse } from 'next/server';
|
|
22
|
+
import { getServerSession } from 'next-auth';
|
|
23
|
+
import { createAuthOptions } from '../../auth/config';
|
|
24
|
+
import { findShippingZones, findShippingZoneById, createShippingZone, updateShippingZone, deleteShippingZone, createShippingRate, updateShippingRate, deleteShippingRate, } from '../../core/db/queries';
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// Auth Helper
|
|
27
|
+
// =============================================================================
|
|
28
|
+
async function requireAdmin() {
|
|
29
|
+
const session = await getServerSession(createAuthOptions());
|
|
30
|
+
const user = session?.user;
|
|
31
|
+
if (!user?.role || !['owner', 'admin'].includes(user.role)) {
|
|
32
|
+
return NextResponse.json({ error: 'Unauthorized', code: 'UNAUTHORIZED' }, { status: 401 });
|
|
33
|
+
}
|
|
34
|
+
return null; // Auth passed
|
|
35
|
+
}
|
|
36
|
+
// =============================================================================
|
|
37
|
+
// Shipping Zones - List & Create
|
|
38
|
+
// =============================================================================
|
|
39
|
+
/**
|
|
40
|
+
* GET /api/admin/shipping/zones
|
|
41
|
+
*
|
|
42
|
+
* List all shipping zones with their rates.
|
|
43
|
+
*/
|
|
44
|
+
export async function getZones() {
|
|
45
|
+
const authError = await requireAdmin();
|
|
46
|
+
if (authError)
|
|
47
|
+
return authError;
|
|
48
|
+
try {
|
|
49
|
+
const zones = await findShippingZones();
|
|
50
|
+
return NextResponse.json({ data: zones });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('[Admin Shipping API] getZones error:', error);
|
|
54
|
+
return NextResponse.json({ error: 'Failed to fetch shipping zones', code: 'INTERNAL_ERROR' }, { status: 500 });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* POST /api/admin/shipping/zones
|
|
59
|
+
*
|
|
60
|
+
* Create a new shipping zone.
|
|
61
|
+
*
|
|
62
|
+
* Request Body:
|
|
63
|
+
* ```json
|
|
64
|
+
* {
|
|
65
|
+
* "name": "Domestic",
|
|
66
|
+
* "countries": ["US", "CA"],
|
|
67
|
+
* "isActive": true,
|
|
68
|
+
* "sortOrder": 0
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export async function createZone(request) {
|
|
73
|
+
const authError = await requireAdmin();
|
|
74
|
+
if (authError)
|
|
75
|
+
return authError;
|
|
76
|
+
try {
|
|
77
|
+
const body = await request.json();
|
|
78
|
+
// Validate required fields
|
|
79
|
+
if (!body.name || typeof body.name !== 'string') {
|
|
80
|
+
return NextResponse.json({ error: 'Zone name is required', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
81
|
+
}
|
|
82
|
+
if (!Array.isArray(body.countries) || body.countries.length === 0) {
|
|
83
|
+
return NextResponse.json({ error: 'At least one country is required', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
84
|
+
}
|
|
85
|
+
// Sanitize countries (uppercase, 2-char codes, or '*')
|
|
86
|
+
const countries = body.countries
|
|
87
|
+
.filter((c) => typeof c === 'string')
|
|
88
|
+
.map((c) => c.toUpperCase().trim())
|
|
89
|
+
.filter((c) => c === '*' || c.length === 2);
|
|
90
|
+
if (countries.length === 0) {
|
|
91
|
+
return NextResponse.json({ error: 'Invalid country codes. Use 2-letter ISO codes or "*" for all countries.', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
92
|
+
}
|
|
93
|
+
const zone = await createShippingZone({
|
|
94
|
+
name: body.name.trim().slice(0, 255),
|
|
95
|
+
countries,
|
|
96
|
+
isActive: body.isActive !== false,
|
|
97
|
+
sortOrder: typeof body.sortOrder === 'number' ? body.sortOrder : 0,
|
|
98
|
+
});
|
|
99
|
+
return NextResponse.json({ success: true, data: zone }, { status: 201 });
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error('[Admin Shipping API] createZone error:', error);
|
|
103
|
+
return NextResponse.json({ error: 'Failed to create shipping zone', code: 'INTERNAL_ERROR' }, { status: 500 });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// =============================================================================
|
|
107
|
+
// Shipping Zones - Single Operations
|
|
108
|
+
// =============================================================================
|
|
109
|
+
/**
|
|
110
|
+
* GET /api/admin/shipping/zones/[id]
|
|
111
|
+
*
|
|
112
|
+
* Get a single shipping zone by ID with its rates.
|
|
113
|
+
*/
|
|
114
|
+
export async function getZone(request, { params }) {
|
|
115
|
+
const authError = await requireAdmin();
|
|
116
|
+
if (authError)
|
|
117
|
+
return authError;
|
|
118
|
+
try {
|
|
119
|
+
const { id } = await params;
|
|
120
|
+
const zone = await findShippingZoneById(id);
|
|
121
|
+
if (!zone) {
|
|
122
|
+
return NextResponse.json({ error: 'Shipping zone not found', code: 'NOT_FOUND' }, { status: 404 });
|
|
123
|
+
}
|
|
124
|
+
return NextResponse.json({ data: zone });
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.error('[Admin Shipping API] getZone error:', error);
|
|
128
|
+
return NextResponse.json({ error: 'Failed to fetch shipping zone', code: 'INTERNAL_ERROR' }, { status: 500 });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* PUT /api/admin/shipping/zones/[id]
|
|
133
|
+
*
|
|
134
|
+
* Update a shipping zone by ID.
|
|
135
|
+
*
|
|
136
|
+
* Request Body:
|
|
137
|
+
* ```json
|
|
138
|
+
* {
|
|
139
|
+
* "name": "Updated Zone Name",
|
|
140
|
+
* "countries": ["US", "CA", "MX"],
|
|
141
|
+
* "isActive": true,
|
|
142
|
+
* "sortOrder": 1
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export async function updateZone(request, { params }) {
|
|
147
|
+
const authError = await requireAdmin();
|
|
148
|
+
if (authError)
|
|
149
|
+
return authError;
|
|
150
|
+
try {
|
|
151
|
+
const { id } = await params;
|
|
152
|
+
const body = await request.json();
|
|
153
|
+
// Check zone exists
|
|
154
|
+
const existing = await findShippingZoneById(id);
|
|
155
|
+
if (!existing) {
|
|
156
|
+
return NextResponse.json({ error: 'Shipping zone not found', code: 'NOT_FOUND' }, { status: 404 });
|
|
157
|
+
}
|
|
158
|
+
// Build update data
|
|
159
|
+
const updateData = {};
|
|
160
|
+
if (body.name !== undefined) {
|
|
161
|
+
updateData.name = body.name.trim().slice(0, 255);
|
|
162
|
+
}
|
|
163
|
+
if (body.countries !== undefined) {
|
|
164
|
+
if (!Array.isArray(body.countries) || body.countries.length === 0) {
|
|
165
|
+
return NextResponse.json({ error: 'At least one country is required', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
166
|
+
}
|
|
167
|
+
const countries = body.countries
|
|
168
|
+
.filter((c) => typeof c === 'string')
|
|
169
|
+
.map((c) => c.toUpperCase().trim())
|
|
170
|
+
.filter((c) => c === '*' || c.length === 2);
|
|
171
|
+
if (countries.length === 0) {
|
|
172
|
+
return NextResponse.json({ error: 'Invalid country codes', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
173
|
+
}
|
|
174
|
+
updateData.countries = countries;
|
|
175
|
+
}
|
|
176
|
+
if (body.isActive !== undefined) {
|
|
177
|
+
updateData.isActive = Boolean(body.isActive);
|
|
178
|
+
}
|
|
179
|
+
if (body.sortOrder !== undefined) {
|
|
180
|
+
updateData.sortOrder = typeof body.sortOrder === 'number' ? body.sortOrder : 0;
|
|
181
|
+
}
|
|
182
|
+
const zone = await updateShippingZone(id, updateData);
|
|
183
|
+
return NextResponse.json({ success: true, data: zone });
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
console.error('[Admin Shipping API] updateZone error:', error);
|
|
187
|
+
return NextResponse.json({ error: 'Failed to update shipping zone', code: 'INTERNAL_ERROR' }, { status: 500 });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* DELETE /api/admin/shipping/zones/[id]
|
|
192
|
+
*
|
|
193
|
+
* Delete a shipping zone by ID. This cascades to delete all rates in the zone.
|
|
194
|
+
*/
|
|
195
|
+
export async function deleteZone(request, { params }) {
|
|
196
|
+
const authError = await requireAdmin();
|
|
197
|
+
if (authError)
|
|
198
|
+
return authError;
|
|
199
|
+
try {
|
|
200
|
+
const { id } = await params;
|
|
201
|
+
const deleted = await deleteShippingZone(id);
|
|
202
|
+
if (!deleted) {
|
|
203
|
+
return NextResponse.json({ error: 'Shipping zone not found', code: 'NOT_FOUND' }, { status: 404 });
|
|
204
|
+
}
|
|
205
|
+
return NextResponse.json({ success: true });
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
console.error('[Admin Shipping API] deleteZone error:', error);
|
|
209
|
+
return NextResponse.json({ error: 'Failed to delete shipping zone', code: 'INTERNAL_ERROR' }, { status: 500 });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// =============================================================================
|
|
213
|
+
// Shipping Rates - Create
|
|
214
|
+
// =============================================================================
|
|
215
|
+
/**
|
|
216
|
+
* POST /api/admin/shipping/rates
|
|
217
|
+
*
|
|
218
|
+
* Create a new shipping rate for a zone.
|
|
219
|
+
*
|
|
220
|
+
* Request Body:
|
|
221
|
+
* ```json
|
|
222
|
+
* {
|
|
223
|
+
* "zoneId": "uuid",
|
|
224
|
+
* "name": "Standard Shipping",
|
|
225
|
+
* "description": "5-7 business days",
|
|
226
|
+
* "price": 5.99,
|
|
227
|
+
* "minOrderAmount": 0,
|
|
228
|
+
* "maxOrderAmount": null,
|
|
229
|
+
* "estimatedDays": "5-7",
|
|
230
|
+
* "isActive": true,
|
|
231
|
+
* "sortOrder": 0
|
|
232
|
+
* }
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
export async function createRate(request) {
|
|
236
|
+
const authError = await requireAdmin();
|
|
237
|
+
if (authError)
|
|
238
|
+
return authError;
|
|
239
|
+
try {
|
|
240
|
+
const body = await request.json();
|
|
241
|
+
// Validate required fields
|
|
242
|
+
if (!body.zoneId || typeof body.zoneId !== 'string') {
|
|
243
|
+
return NextResponse.json({ error: 'Zone ID is required', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
244
|
+
}
|
|
245
|
+
if (!body.name || typeof body.name !== 'string') {
|
|
246
|
+
return NextResponse.json({ error: 'Rate name is required', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
247
|
+
}
|
|
248
|
+
if (typeof body.price !== 'number' || body.price < 0) {
|
|
249
|
+
return NextResponse.json({ error: 'Valid price is required (non-negative number)', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
250
|
+
}
|
|
251
|
+
// Verify zone exists
|
|
252
|
+
const zone = await findShippingZoneById(body.zoneId);
|
|
253
|
+
if (!zone) {
|
|
254
|
+
return NextResponse.json({ error: 'Shipping zone not found', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
255
|
+
}
|
|
256
|
+
const rate = await createShippingRate({
|
|
257
|
+
zoneId: body.zoneId,
|
|
258
|
+
name: body.name.trim().slice(0, 255),
|
|
259
|
+
description: body.description ? body.description.trim().slice(0, 500) : undefined,
|
|
260
|
+
price: body.price,
|
|
261
|
+
minOrderAmount: typeof body.minOrderAmount === 'number' && body.minOrderAmount >= 0
|
|
262
|
+
? body.minOrderAmount
|
|
263
|
+
: undefined,
|
|
264
|
+
maxOrderAmount: typeof body.maxOrderAmount === 'number' && body.maxOrderAmount >= 0
|
|
265
|
+
? body.maxOrderAmount
|
|
266
|
+
: undefined,
|
|
267
|
+
estimatedDays: body.estimatedDays ? body.estimatedDays.trim().slice(0, 50) : undefined,
|
|
268
|
+
isActive: body.isActive !== false,
|
|
269
|
+
sortOrder: typeof body.sortOrder === 'number' ? body.sortOrder : 0,
|
|
270
|
+
});
|
|
271
|
+
return NextResponse.json({ success: true, data: rate }, { status: 201 });
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
console.error('[Admin Shipping API] createRate error:', error);
|
|
275
|
+
return NextResponse.json({ error: 'Failed to create shipping rate', code: 'INTERNAL_ERROR' }, { status: 500 });
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// =============================================================================
|
|
279
|
+
// Shipping Rates - Update & Delete
|
|
280
|
+
// =============================================================================
|
|
281
|
+
/**
|
|
282
|
+
* PUT /api/admin/shipping/rates/[id]
|
|
283
|
+
*
|
|
284
|
+
* Update a shipping rate by ID.
|
|
285
|
+
*
|
|
286
|
+
* Request Body:
|
|
287
|
+
* ```json
|
|
288
|
+
* {
|
|
289
|
+
* "name": "Express Shipping",
|
|
290
|
+
* "description": "2-3 business days",
|
|
291
|
+
* "price": 12.99,
|
|
292
|
+
* "minOrderAmount": 0,
|
|
293
|
+
* "maxOrderAmount": 100,
|
|
294
|
+
* "estimatedDays": "2-3",
|
|
295
|
+
* "isActive": true,
|
|
296
|
+
* "sortOrder": 1
|
|
297
|
+
* }
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
export async function updateRate(request, { params }) {
|
|
301
|
+
const authError = await requireAdmin();
|
|
302
|
+
if (authError)
|
|
303
|
+
return authError;
|
|
304
|
+
try {
|
|
305
|
+
const { id } = await params;
|
|
306
|
+
const body = await request.json();
|
|
307
|
+
// Build update data
|
|
308
|
+
const updateData = {};
|
|
309
|
+
if (body.name !== undefined) {
|
|
310
|
+
updateData.name = body.name.trim().slice(0, 255);
|
|
311
|
+
}
|
|
312
|
+
if (body.description !== undefined) {
|
|
313
|
+
updateData.description = body.description ? body.description.trim().slice(0, 500) : null;
|
|
314
|
+
}
|
|
315
|
+
if (body.price !== undefined) {
|
|
316
|
+
if (typeof body.price !== 'number' || body.price < 0) {
|
|
317
|
+
return NextResponse.json({ error: 'Price must be a non-negative number', code: 'VALIDATION_ERROR' }, { status: 400 });
|
|
318
|
+
}
|
|
319
|
+
updateData.price = body.price;
|
|
320
|
+
}
|
|
321
|
+
if (body.minOrderAmount !== undefined) {
|
|
322
|
+
updateData.minOrderAmount = typeof body.minOrderAmount === 'number' && body.minOrderAmount >= 0
|
|
323
|
+
? body.minOrderAmount
|
|
324
|
+
: null;
|
|
325
|
+
}
|
|
326
|
+
if (body.maxOrderAmount !== undefined) {
|
|
327
|
+
updateData.maxOrderAmount = typeof body.maxOrderAmount === 'number' && body.maxOrderAmount >= 0
|
|
328
|
+
? body.maxOrderAmount
|
|
329
|
+
: null;
|
|
330
|
+
}
|
|
331
|
+
if (body.estimatedDays !== undefined) {
|
|
332
|
+
updateData.estimatedDays = body.estimatedDays ? body.estimatedDays.trim().slice(0, 50) : null;
|
|
333
|
+
}
|
|
334
|
+
if (body.isActive !== undefined) {
|
|
335
|
+
updateData.isActive = Boolean(body.isActive);
|
|
336
|
+
}
|
|
337
|
+
if (body.sortOrder !== undefined) {
|
|
338
|
+
updateData.sortOrder = typeof body.sortOrder === 'number' ? body.sortOrder : 0;
|
|
339
|
+
}
|
|
340
|
+
const rate = await updateShippingRate(id, updateData);
|
|
341
|
+
if (!rate) {
|
|
342
|
+
return NextResponse.json({ error: 'Shipping rate not found', code: 'NOT_FOUND' }, { status: 404 });
|
|
343
|
+
}
|
|
344
|
+
return NextResponse.json({ success: true, data: rate });
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
console.error('[Admin Shipping API] updateRate error:', error);
|
|
348
|
+
return NextResponse.json({ error: 'Failed to update shipping rate', code: 'INTERNAL_ERROR' }, { status: 500 });
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* DELETE /api/admin/shipping/rates/[id]
|
|
353
|
+
*
|
|
354
|
+
* Delete a shipping rate by ID.
|
|
355
|
+
*/
|
|
356
|
+
export async function deleteRate(request, { params }) {
|
|
357
|
+
const authError = await requireAdmin();
|
|
358
|
+
if (authError)
|
|
359
|
+
return authError;
|
|
360
|
+
try {
|
|
361
|
+
const { id } = await params;
|
|
362
|
+
const deleted = await deleteShippingRate(id);
|
|
363
|
+
if (!deleted) {
|
|
364
|
+
return NextResponse.json({ error: 'Shipping rate not found', code: 'NOT_FOUND' }, { status: 404 });
|
|
365
|
+
}
|
|
366
|
+
return NextResponse.json({ success: true });
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
console.error('[Admin Shipping API] deleteRate error:', error);
|
|
370
|
+
return NextResponse.json({ error: 'Failed to delete shipping rate', code: 'INTERNAL_ERROR' }, { status: 500 });
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=shipping.js.map
|