order-management 0.0.16 → 0.0.18

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.
Files changed (42) hide show
  1. package/.medusa/server/src/admin/index.js +638 -5
  2. package/.medusa/server/src/admin/index.mjs +638 -5
  3. package/.medusa/server/src/api/admin/swaps/[id]/approve/route.js +45 -0
  4. package/.medusa/server/src/api/admin/swaps/[id]/reject/route.js +43 -0
  5. package/.medusa/server/src/api/admin/swaps/[id]/route.js +70 -0
  6. package/.medusa/server/src/api/admin/swaps/[id]/status/route.js +45 -0
  7. package/.medusa/server/src/api/admin/swaps/route.js +51 -0
  8. package/.medusa/server/src/api/admin/swaps/validators.js +22 -0
  9. package/.medusa/server/src/api/store/guest-orders/[id]/invoice/route.js +19 -2
  10. package/.medusa/server/src/api/store/guest-orders/[id]/returns/route.js +19 -2
  11. package/.medusa/server/src/api/store/guest-orders/[id]/route.js +19 -2
  12. package/.medusa/server/src/api/store/guest-orders/route.js +19 -2
  13. package/.medusa/server/src/api/store/orders/[order_id]/swaps/route.js +107 -0
  14. package/.medusa/server/src/api/store/otp/request/route.js +12 -5
  15. package/.medusa/server/src/api/store/otp/verify/route.js +3 -2
  16. package/.medusa/server/src/api/store/swaps/[id]/cancel/route.js +64 -0
  17. package/.medusa/server/src/api/store/swaps/[id]/route.js +112 -0
  18. package/.medusa/server/src/api/store/swaps/route.js +117 -0
  19. package/.medusa/server/src/config.js +3 -24
  20. package/.medusa/server/src/helpers/index.js +18 -0
  21. package/.medusa/server/src/helpers/swaps.js +88 -0
  22. package/.medusa/server/src/modules/swap/index.js +13 -0
  23. package/.medusa/server/src/modules/swap/migrations/Migration20260121164326.js +49 -0
  24. package/.medusa/server/src/modules/swap/models/swap.js +21 -0
  25. package/.medusa/server/src/modules/swap/service.js +154 -0
  26. package/.medusa/server/src/services/otp-service.js +21 -4
  27. package/.medusa/server/src/subscribers/send-order-email.js +29 -7
  28. package/.medusa/server/src/workflows/index.js +8 -2
  29. package/.medusa/server/src/workflows/steps/swap/calculate-difference-step.js +56 -0
  30. package/.medusa/server/src/workflows/steps/swap/create-swap-step.js +29 -0
  31. package/.medusa/server/src/workflows/steps/swap/index.js +16 -0
  32. package/.medusa/server/src/workflows/steps/swap/retrieve-swap-step.js +26 -0
  33. package/.medusa/server/src/workflows/steps/swap/update-swap-status-step.js +25 -0
  34. package/.medusa/server/src/workflows/steps/swap/validate-order-step.js +47 -0
  35. package/.medusa/server/src/workflows/steps/swap/validate-swap-items-step.js +41 -0
  36. package/.medusa/server/src/workflows/swaps/approve-swap-workflow.js +38 -0
  37. package/.medusa/server/src/workflows/swaps/create-swap-workflow.js +46 -0
  38. package/.medusa/server/src/workflows/swaps/types.js +3 -0
  39. package/.medusa/server/src/workflows/swaps/update-swap-status-workflow.js +23 -0
  40. package/README.md +247 -5
  41. package/package.json +1 -1
  42. package/.medusa/server/src/utils/resolve-options.js +0 -57
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSwapWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const swap_1 = require("../steps/swap");
6
+ exports.createSwapWorkflow = (0, workflows_sdk_1.createWorkflow)("create-swap", (input) => {
7
+ const { order_id, return_items, new_items, reason, note, customer_id } = input;
8
+ // Step 1: Validate order exists and belongs to customer
9
+ const { order } = (0, swap_1.validateOrderStep)({
10
+ order_id,
11
+ customer_id,
12
+ });
13
+ // Step 2: Validate swap items
14
+ const { return_items: validatedReturnItems, new_items: validatedNewItems } = (0, swap_1.validateSwapItemsStep)({
15
+ order,
16
+ return_items,
17
+ new_items,
18
+ });
19
+ // Step 3: Calculate price difference
20
+ const { difference_due } = (0, swap_1.calculateDifferenceStep)({
21
+ order,
22
+ return_items: validatedReturnItems,
23
+ new_items: validatedNewItems,
24
+ });
25
+ // Step 4: Create swap record
26
+ const { swap } = (0, swap_1.createSwapStep)({
27
+ order_id,
28
+ return_items: validatedReturnItems,
29
+ new_items: validatedNewItems,
30
+ difference_due,
31
+ reason,
32
+ note,
33
+ });
34
+ // Step 5: Send notification (optional - can be skipped if no email template)
35
+ // sendNotificationStep({
36
+ // to: order.email || "",
37
+ // subject: "Swap Request Created",
38
+ // renderedContent: null, // Would need email template
39
+ // templateData: {},
40
+ // })
41
+ return new workflows_sdk_1.WorkflowResponse({
42
+ swap,
43
+ });
44
+ });
45
+ exports.default = exports.createSwapWorkflow;
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLXN3YXAtd29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N3YXBzL2NyZWF0ZS1zd2FwLXdvcmtmbG93LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUcwQztBQUMxQyx3Q0FLc0I7QUFPVCxRQUFBLGtCQUFrQixHQUFHLElBQUEsOEJBQWMsRUFDOUMsYUFBYSxFQUNiLENBQ0UsS0FBd0QsRUFDWixFQUFFO0lBQzlDLE1BQU0sRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxHQUFHLEtBQUssQ0FBQTtJQUU5RSx3REFBd0Q7SUFDeEQsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLElBQUEsd0JBQWlCLEVBQUM7UUFDbEMsUUFBUTtRQUNSLFdBQVc7S0FDWixDQUFDLENBQUE7SUFFRiw4QkFBOEI7SUFDOUIsTUFBTSxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsR0FDeEUsSUFBQSw0QkFBcUIsRUFBQztRQUNwQixLQUFLO1FBQ0wsWUFBWTtRQUNaLFNBQVM7S0FDVixDQUFDLENBQUE7SUFFSixxQ0FBcUM7SUFDckMsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLElBQUEsOEJBQXVCLEVBQUM7UUFDakQsS0FBSztRQUNMLFlBQVksRUFBRSxvQkFBb0I7UUFDbEMsU0FBUyxFQUFFLGlCQUFpQjtLQUM3QixDQUFDLENBQUE7SUFFRiw2QkFBNkI7SUFDN0IsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUEscUJBQWMsRUFBQztRQUM5QixRQUFRO1FBQ1IsWUFBWSxFQUFFLG9CQUFvQjtRQUNsQyxTQUFTLEVBQUUsaUJBQWlCO1FBQzVCLGNBQWM7UUFDZCxNQUFNO1FBQ04sSUFBSTtLQUNMLENBQUMsQ0FBQTtJQUVGLDZFQUE2RTtJQUM3RSx5QkFBeUI7SUFDekIsMkJBQTJCO0lBQzNCLHFDQUFxQztJQUNyQyx3REFBd0Q7SUFDeEQsc0JBQXNCO0lBQ3RCLEtBQUs7SUFFTCxPQUFPLElBQUksZ0NBQWdCLENBQTJCO1FBQ3BELElBQUk7S0FDTCxDQUFDLENBQUE7QUFDSixDQUFDLENBQ0YsQ0FBQTtBQUVELGtCQUFlLDBCQUFrQixDQUFBIn0=
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3N3YXBzL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateSwapStatusWorkflow = void 0;
4
+ const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
+ const swap_1 = require("../steps/swap");
6
+ exports.updateSwapStatusWorkflow = (0, workflows_sdk_1.createWorkflow)("update-swap-status", (input) => {
7
+ const { swap_id, status, metadata } = input;
8
+ // Step 1: Retrieve swap to validate it exists
9
+ (0, swap_1.retrieveSwapStep)({
10
+ swap_id,
11
+ });
12
+ // Step 2: Update status (validation happens in updateSwapStatusStep)
13
+ const { swap } = (0, swap_1.updateSwapStatusStep)({
14
+ swap_id,
15
+ status,
16
+ metadata,
17
+ });
18
+ return new workflows_sdk_1.WorkflowResponse({
19
+ swap,
20
+ });
21
+ });
22
+ exports.default = exports.updateSwapStatusWorkflow;
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBkYXRlLXN3YXAtc3RhdHVzLXdvcmtmbG93LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zd2Fwcy91cGRhdGUtc3dhcC1zdGF0dXMtd29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBRzBDO0FBQzFDLHdDQUdzQjtBQU1ULFFBQUEsd0JBQXdCLEdBQUcsSUFBQSw4QkFBYyxFQUNwRCxvQkFBb0IsRUFDcEIsQ0FDRSxLQUFvQyxFQUNjLEVBQUU7SUFDcEQsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsS0FBSyxDQUFBO0lBRTNDLDhDQUE4QztJQUM5QyxJQUFBLHVCQUFnQixFQUFDO1FBQ2YsT0FBTztLQUNSLENBQUMsQ0FBQTtJQUVGLHFFQUFxRTtJQUNyRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBQSwyQkFBb0IsRUFBQztRQUNwQyxPQUFPO1FBQ1AsTUFBTTtRQUNOLFFBQVE7S0FDVCxDQUFDLENBQUE7SUFFRixPQUFPLElBQUksZ0NBQWdCLENBQWlDO1FBQzFELElBQUk7S0FDTCxDQUFDLENBQUE7QUFDSixDQUFDLENBQ0YsQ0FBQTtBQUVELGtCQUFlLGdDQUF3QixDQUFBIn0=
package/README.md CHANGED
@@ -43,22 +43,43 @@ This starter is compatible with versions >= 2.4.0 of `@medusajs/medusa`.
43
43
  - **Order Confirmation Emails**: Automatically sends email notifications when orders are placed (with "Claim Order" support for registered users)
44
44
  - **Return Orders Admin Panel**: Complete return orders management section in the Medusa Admin Panel with list view, filtering, search, detail pages, and status management
45
45
  - **Guest Returns & Invoices**: Secure endpoints for guest users to initiate returns and download invoices
46
+ - **Customer-Initiated Swaps**: Complete swap/exchange functionality allowing customers to request item swaps directly from the storefront with full status lifecycle management
46
47
 
47
48
  ## Configuration
48
49
 
49
50
  The plugin can be configured in your `medusa-config.js` file:
50
51
 
51
52
  ```js
53
+ import { defineConfig } from "@medusajs/framework/utils"
54
+
52
55
  module.exports = defineConfig({
53
56
  // ...
54
57
  plugins: [
55
58
  {
56
59
  resolve: "order-management",
57
60
  options: {
61
+ // Required options
62
+ storefrontUrl: process.env.STOREFRONT_URL || "http://localhost:8000",
63
+ jwtSecret: process.env.JWT_SECRET || "medusa-secret-guest-access",
64
+
65
+ // Email template options
58
66
  email: {
59
67
  orderConfirmTemplate: "src/templates/emails/order-confirmation.html", // Path to HTML template file
60
68
  otpTemplate: "src/templates/emails/otp-verification.html", // Path to HTML template file (required)
61
69
  },
70
+
71
+ // Optional SMTP configuration (for email delivery)
72
+ smtp: {
73
+ enabled: process.env.FORCE_SMTP_REDELIVER === "true",
74
+ host: process.env.SMTP_HOST,
75
+ port: process.env.SMTP_PORT ? Number(process.env.SMTP_PORT) : undefined,
76
+ secure: process.env.SMTP_SECURE === "true",
77
+ auth: {
78
+ user: process.env.SMTP_AUTH_USER,
79
+ pass: process.env.SMTP_AUTH_PASS,
80
+ },
81
+ from: process.env.SMTP_FROM || process.env.SMTP_AUTH_USER,
82
+ },
62
83
  },
63
84
  },
64
85
  ],
@@ -67,15 +88,29 @@ module.exports = defineConfig({
67
88
 
68
89
  ### Configuration Options
69
90
 
70
- | Option | Type | Default | Description |
71
- |--------|------|---------|-------------|
72
- | `email.orderConfirmTemplate` | `string \| null` | `null` | Path to HTML template file for order confirmation emails (relative to project root or absolute path) |
73
- | `email.otpTemplate` | `string \| null` | `null` | Path to HTML template file for OTP verification emails (relative to project root or absolute path). **Required** for guest OTP functionality. |
91
+ **Required Options:**
92
+ - `storefrontUrl` - Your storefront URL (required)
93
+ - `jwtSecret` - JWT secret for guest order tokens (required)
94
+
95
+ **Email Template Options:**
96
+ - `email.orderConfirmTemplate` - Path to HTML template file for order confirmation emails (optional)
97
+ - `email.otpTemplate` - Path to HTML template file for OTP verification emails (required for guest OTP functionality)
98
+
99
+ **Optional SMTP Options:**
100
+ - `smtp.enabled` - Enable SMTP email delivery (default: `false`)
101
+ - `smtp.host` - SMTP server host (required if enabled)
102
+ - `smtp.port` - SMTP server port (required if enabled)
103
+ - `smtp.secure` - Use secure connection (default: `true`)
104
+ - `smtp.auth.user` - SMTP username (required if enabled)
105
+ - `smtp.auth.pass` - SMTP password (required if enabled)
106
+ - `smtp.from` - From email address (optional, defaults to `smtp.auth.user`)
74
107
 
75
108
  **Notes**:
109
+ - `storefrontUrl` and `jwtSecret` are required. All other options are optional.
76
110
  - Order confirmation emails are only sent if a template path is provided. If no template is configured, emails will not be sent.
77
- - OTP template is **mandatory**. The guest OTP request API will return an error if `email.otpTemplate` is not configured.
111
+ - OTP template is **mandatory** for guest OTP functionality. The guest OTP request API will return an error if `email.otpTemplate` is not configured.
78
112
  - OTP templates should include `{{otp}}` placeholder for the verification code.
113
+ - SMTP configuration is optional. If not enabled, emails will use Medusa's default email provider.
79
114
 
80
115
  ## Return Orders Admin Panel
81
116
 
@@ -210,6 +245,213 @@ The following variables are available in order confirmation email templates:
210
245
  | `{{is_registered}}` | Whether the customer email has a registered account | `true` |
211
246
  | `{{claim_link}}` | Link for registered users to claim their guest order | `http://.../claim?order_id=...` |
212
247
 
248
+ ## Customer-Initiated Swaps
249
+
250
+ The plugin includes a complete swap/exchange feature that allows customers to request item swaps directly from the storefront. This extends Medusa v2's native OrderExchange functionality with customer-facing APIs and admin management tools.
251
+
252
+ ### Features
253
+
254
+ - **Customer-Initiated Swaps**: Customers can request swaps for their orders directly from the storefront
255
+ - **Complete Status Lifecycle**: Full status tracking from `requested` → `approved` → `return_started` → `return_shipped` → `return_received` → `new_items_shipped` → `completed`
256
+ - **Admin Management**: Complete admin panel for viewing, approving, rejecting, and managing swaps
257
+ - **Price Difference Calculation**: Automatic calculation of price differences between returned and new items
258
+ - **Status History**: Complete audit trail of all status changes
259
+
260
+ ### Swap Status Flow
261
+
262
+ ```
263
+ requested → approved → return_started → return_shipped → return_received → new_items_shipped → completed
264
+ ↘ rejected
265
+ ↘ cancelled (from any status except completed)
266
+ ```
267
+
268
+ ### Storefront API Endpoints
269
+
270
+ #### Create Swap Request
271
+
272
+ ```bash
273
+ POST /store/swaps
274
+ Authorization: Bearer <customer_token>
275
+ Content-Type: application/json
276
+
277
+ {
278
+ "order_id": "order_123",
279
+ "return_items": [
280
+ {
281
+ "id": "item_123",
282
+ "quantity": 1,
283
+ "reason": "Wrong size"
284
+ }
285
+ ],
286
+ "new_items": [
287
+ {
288
+ "variant_id": "variant_456",
289
+ "quantity": 1
290
+ }
291
+ ],
292
+ "reason": "Size exchange",
293
+ "note": "Please send size M instead"
294
+ }
295
+ ```
296
+
297
+ #### List Customer Swaps
298
+
299
+ ```bash
300
+ GET /store/swaps
301
+ Authorization: Bearer <customer_token>
302
+ ```
303
+
304
+ #### Get Swap Details
305
+
306
+ ```bash
307
+ GET /store/swaps/{swap_id}
308
+ Authorization: Bearer <customer_token>
309
+ ```
310
+
311
+ #### List Swaps for Order
312
+
313
+ ```bash
314
+ GET /store/orders/{order_id}/swaps
315
+ Authorization: Bearer <customer_token>
316
+ ```
317
+
318
+ #### Create Swap for Order
319
+
320
+ ```bash
321
+ POST /store/orders/{order_id}/swaps
322
+ Authorization: Bearer <customer_token>
323
+ Content-Type: application/json
324
+
325
+ {
326
+ "return_items": [
327
+ {
328
+ "id": "item_123",
329
+ "quantity": 1
330
+ }
331
+ ],
332
+ "new_items": [
333
+ {
334
+ "variant_id": "variant_456",
335
+ "quantity": 1
336
+ }
337
+ ],
338
+ "reason": "Size exchange"
339
+ }
340
+ ```
341
+
342
+ #### Cancel Swap
343
+
344
+ ```bash
345
+ POST /store/swaps/{swap_id}/cancel
346
+ Authorization: Bearer <customer_token>
347
+ ```
348
+
349
+ ### Admin API Endpoints
350
+
351
+ #### List All Swaps
352
+
353
+ ```bash
354
+ GET /admin/swaps?status=requested&order_id=order_123&limit=50&offset=0
355
+ ```
356
+
357
+ #### Get Swap Details
358
+
359
+ ```bash
360
+ GET /admin/swaps/{swap_id}
361
+ ```
362
+
363
+ #### Approve Swap
364
+
365
+ ```bash
366
+ POST /admin/swaps/{swap_id}/approve
367
+ ```
368
+
369
+ #### Reject Swap
370
+
371
+ ```bash
372
+ POST /admin/swaps/{swap_id}/reject
373
+ Content-Type: application/json
374
+
375
+ {
376
+ "reason": "Item out of stock"
377
+ }
378
+ ```
379
+
380
+ #### Update Swap Status
381
+
382
+ ```bash
383
+ POST /admin/swaps/{swap_id}/status
384
+ Content-Type: application/json
385
+
386
+ {
387
+ "status": "return_started",
388
+ "metadata": {
389
+ "return_label_id": "label_123"
390
+ }
391
+ }
392
+ ```
393
+
394
+ ### Admin UI
395
+
396
+ The plugin includes a complete admin UI for managing swaps:
397
+
398
+ - **Swaps List Page**: View all swaps with filtering by status, search by order ID, and pagination
399
+ - **Swap Detail Page**: View complete swap information including:
400
+ - Swap details (ID, status, dates, price difference)
401
+ - Original order information
402
+ - Return items list
403
+ - New items list
404
+ - Status history timeline
405
+ - Action buttons (approve/reject/update status)
406
+
407
+ Access the Swaps section from the Admin Panel sidebar.
408
+
409
+ ### Storefront Helpers
410
+
411
+ The plugin provides helper methods for easy integration:
412
+
413
+ ```typescript
414
+ import { createSwapRequest, getSwaps, getSwap, cancelSwap } from "order-management/helpers"
415
+
416
+ // Create a swap request
417
+ const swap = await createSwapRequest({
418
+ orderId: "order_123",
419
+ returnItems: [
420
+ { id: "item_123", quantity: 1, reason: "Wrong size" }
421
+ ],
422
+ newItems: [
423
+ { variant_id: "variant_456", quantity: 1 }
424
+ ],
425
+ reason: "Size exchange",
426
+ note: "Please send size M"
427
+ }, container)
428
+
429
+ // Get swaps for an order
430
+ const swaps = await getSwaps("order_123", container)
431
+
432
+ // Get a specific swap
433
+ const swapDetails = await getSwap("swap_123", container)
434
+
435
+ // Cancel a swap
436
+ const cancelledSwap = await cancelSwap("swap_123", container)
437
+ ```
438
+
439
+ ### Status Transitions
440
+
441
+ The swap status flow enforces valid transitions:
442
+
443
+ - **requested** → `approved`, `rejected`, `cancelled`
444
+ - **approved** → `return_started`, `cancelled`
445
+ - **return_started** → `return_shipped`, `cancelled`
446
+ - **return_shipped** → `return_received`, `cancelled`
447
+ - **return_received** → `new_items_shipped`, `cancelled`
448
+ - **new_items_shipped** → `completed`, `cancelled`
449
+ - **rejected** → (terminal state)
450
+ - **completed** → (terminal state)
451
+ - **cancelled** → (terminal state)
452
+
453
+ Invalid status transitions will be rejected with a descriptive error message.
454
+
213
455
  ## Getting Started
214
456
 
215
457
  Visit the [Quickstart Guide](https://docs.medusajs.com/learn/installation) to set up a server.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "order-management",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "A starter for Medusa plugins.",
5
5
  "author": "Medusa (https://medusajs.com)",
6
6
  "license": "MIT",
@@ -1,57 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveOrderManagementOptions = resolveOrderManagementOptions;
4
- exports.extractOrderManagementOptions = extractOrderManagementOptions;
5
- const DEFAULT_OPTIONS = {
6
- email: {
7
- orderConfirmTemplate: null,
8
- otpTemplate: null,
9
- },
10
- };
11
- /**
12
- * Resolve and normalize plugin options with defaults
13
- */
14
- function resolveOrderManagementOptions(options) {
15
- if (!options) {
16
- return DEFAULT_OPTIONS;
17
- }
18
- return {
19
- email: {
20
- orderConfirmTemplate: options.email?.orderConfirmTemplate ?? DEFAULT_OPTIONS.email.orderConfirmTemplate,
21
- otpTemplate: options.email?.otpTemplate ?? DEFAULT_OPTIONS.email.otpTemplate,
22
- },
23
- };
24
- }
25
- /**
26
- * Extract plugin options from config module
27
- */
28
- function extractOrderManagementOptions(configModule) {
29
- // Try from projectConfig.plugins first
30
- const plugins = configModule?.projectConfig?.plugins ?? [];
31
- for (const plugin of plugins) {
32
- if (typeof plugin === "string") {
33
- if (plugin === "order-management") {
34
- return {};
35
- }
36
- continue;
37
- }
38
- if (plugin?.resolve === "order-management") {
39
- return plugin.options;
40
- }
41
- }
42
- // Try from direct config.plugins (fallback)
43
- const directPlugins = configModule?.plugins ?? [];
44
- for (const plugin of directPlugins) {
45
- if (typeof plugin === "string") {
46
- if (plugin === "order-management") {
47
- return {};
48
- }
49
- continue;
50
- }
51
- if (plugin?.resolve === "order-management") {
52
- return plugin.options;
53
- }
54
- }
55
- return undefined;
56
- }
57
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS1vcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Jlc29sdmUtb3B0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW1CQSxzRUFhQztBQUtELHNFQW9DQztBQWhFRCxNQUFNLGVBQWUsR0FBbUM7SUFDdEQsS0FBSyxFQUFFO1FBQ0wsb0JBQW9CLEVBQUUsSUFBSTtRQUMxQixXQUFXLEVBQUUsSUFBSTtLQUNsQjtDQUNGLENBQUE7QUFFRDs7R0FFRztBQUNILFNBQWdCLDZCQUE2QixDQUMzQyxPQUE2QztJQUU3QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixPQUFPLGVBQWUsQ0FBQTtJQUN4QixDQUFDO0lBRUQsT0FBTztRQUNMLEtBQUssRUFBRTtZQUNMLG9CQUFvQixFQUFFLE9BQU8sQ0FBQyxLQUFLLEVBQUUsb0JBQW9CLElBQUksZUFBZSxDQUFDLEtBQUssQ0FBQyxvQkFBb0I7WUFDdkcsV0FBVyxFQUFFLE9BQU8sQ0FBQyxLQUFLLEVBQUUsV0FBVyxJQUFJLGVBQWUsQ0FBQyxLQUFLLENBQUMsV0FBVztTQUM3RTtLQUNGLENBQUE7QUFDSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQiw2QkFBNkIsQ0FDM0MsWUFBa0I7SUFFbEIsdUNBQXVDO0lBQ3ZDLE1BQU0sT0FBTyxHQUFHLFlBQVksRUFBRSxhQUFhLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQTtJQUUxRCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzdCLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDL0IsSUFBSSxNQUFNLEtBQUssa0JBQWtCLEVBQUUsQ0FBQztnQkFDbEMsT0FBTyxFQUFFLENBQUE7WUFDWCxDQUFDO1lBQ0QsU0FBUTtRQUNWLENBQUM7UUFFRCxJQUFJLE1BQU0sRUFBRSxPQUFPLEtBQUssa0JBQWtCLEVBQUUsQ0FBQztZQUMzQyxPQUFPLE1BQU0sQ0FBQyxPQUF1QyxDQUFBO1FBQ3ZELENBQUM7SUFDSCxDQUFDO0lBRUQsNENBQTRDO0lBQzVDLE1BQU0sYUFBYSxHQUFJLFlBQW9CLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQTtJQUUxRCxLQUFLLE1BQU0sTUFBTSxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ25DLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDL0IsSUFBSSxNQUFNLEtBQUssa0JBQWtCLEVBQUUsQ0FBQztnQkFDbEMsT0FBTyxFQUFFLENBQUE7WUFDWCxDQUFDO1lBQ0QsU0FBUTtRQUNWLENBQUM7UUFFRCxJQUFJLE1BQU0sRUFBRSxPQUFPLEtBQUssa0JBQWtCLEVBQUUsQ0FBQztZQUMzQyxPQUFPLE1BQU0sQ0FBQyxPQUF1QyxDQUFBO1FBQ3ZELENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQyJ9