medusa-contact-us 0.0.1 → 0.0.3

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.
@@ -31,13 +31,17 @@ const submitContactRequest = async (input, options = {}) => {
31
31
  };
32
32
  const clientRequest = getClientRequest(options.client);
33
33
  if (clientRequest) {
34
+ const headers = {
35
+ "Content-Type": "application/json",
36
+ ...(options.headers ?? {}),
37
+ };
38
+ if (options.publishableApiKey) {
39
+ headers["x-publishable-api-key"] = options.publishableApiKey;
40
+ }
34
41
  const raw = (await clientRequest(endpoint, {
35
42
  method: "POST",
36
43
  body: JSON.stringify(payload),
37
- headers: {
38
- "Content-Type": "application/json",
39
- ...(options.headers ?? {}),
40
- },
44
+ headers,
41
45
  }));
42
46
  return raw;
43
47
  }
@@ -46,12 +50,16 @@ const submitContactRequest = async (input, options = {}) => {
46
50
  throw new Error("No fetch implementation available. Provide `fetchImpl` or a Medusa client.");
47
51
  }
48
52
  const url = `${normalizeBaseUrl(options.baseUrl)}${endpoint}`;
53
+ const headers = {
54
+ "Content-Type": "application/json",
55
+ ...(options.headers ?? {}),
56
+ };
57
+ if (options.publishableApiKey) {
58
+ headers["x-publishable-api-key"] = options.publishableApiKey;
59
+ }
49
60
  const response = await fetchImpl(url || endpoint, {
50
61
  method: "POST",
51
- headers: {
52
- "Content-Type": "application/json",
53
- ...(options.headers ?? {}),
54
- },
62
+ headers,
55
63
  body: JSON.stringify(payload),
56
64
  });
57
65
  if (!response.ok) {
@@ -63,4 +71,4 @@ const submitContactRequest = async (input, options = {}) => {
63
71
  exports.submitContactRequest = submitContactRequest;
64
72
  const createSubmitContactRequest = (options = {}) => (input) => (0, exports.submitContactRequest)(input, options);
65
73
  exports.createSubmitContactRequest = createSubmitContactRequest;
66
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VibWl0LWNvbnRhY3QtcmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9oZWxwZXJzL3N1Ym1pdC1jb250YWN0LXJlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsTUFBTSxnQkFBZ0IsR0FBRyx5QkFBeUIsQ0FBQTtBQXlDbEQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxRQUFpQixFQUFFLEVBQUUsQ0FDNUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQTtBQUV6RCxNQUFNLGdCQUFnQixHQUFHLENBQUMsT0FBZ0IsRUFBRSxFQUFFO0lBQzVDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNiLE9BQU8sRUFBRSxDQUFBO0lBQ1gsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFBO0FBQy9ELENBQUMsQ0FBQTtBQUVELE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxNQUF5QixFQUFFLEVBQUU7SUFDckQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUVELElBQUksU0FBUyxJQUFJLE1BQU0sSUFBSSxPQUFPLE1BQU0sQ0FBQyxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDaEUsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNwQyxDQUFDO0lBRUQsSUFBSSxRQUFRLElBQUksTUFBTSxJQUFJLE9BQU8sTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDdkUsT0FBTyxNQUFNLENB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
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VibWl0LWNvbnRhY3QtcmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9oZWxwZXJzL3N1Ym1pdC1jb250YWN0LXJlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsTUFBTSxnQkFBZ0IsR0FBRyx5QkFBeUIsQ0FBQTtBQThDbEQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxRQUFpQixFQUFFLEVBQUUsQ0FDNUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQTtBQUV6RCxNQUFNLGdCQUFnQixHQUFHLENBQUMsT0FBZ0IsRUFBRSxFQUFFO0lBQzVDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNiLE9BQU8sRUFBRSxDQUFBO0lBQ1gsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFBO0FBQy9ELENBQUMsQ0FBQTtBQUVELE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxNQUF5QixFQUFFLEVBQUU7SUFDckQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUVELElBQUksU0FBUyxJQUFJLE1BQU0sSUFBSSxPQUFPLE1BQU0sQ0FBQyxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDaEUsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNwQyxDQUFDO0lBRUQsSUFBSSxRQUFRLElBQUksTUFBTSxJQUFJLE9BQU8sTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDdkUsT0FBTyxNQUFNLENB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
package/README.md CHANGED
@@ -20,9 +20,12 @@ yarn add medusa-contact-us
20
20
  npm install medusa-contact-us
21
21
  ```
22
22
 
23
+ ## Configuration
24
+
23
25
  Inside `medusa-config.ts` register the plugin and tailor the options:
24
26
 
25
27
  ```ts
28
+ import type { ConfigModule } from "@medusajs/framework/types"
26
29
  import {
27
30
  defineContactUsPluginOptions,
28
31
  ContactRequestModule,
@@ -32,56 +35,169 @@ const plugins = [
32
35
  {
33
36
  resolve: "medusa-contact-us",
34
37
  options: defineContactUsPluginOptions({
38
+ // Form configuration
35
39
  form: {
40
+ // Maximum payload size in KB
36
41
  max_payload_kb: 128,
42
+ // Additional custom fields beyond the required email field
37
43
  additional_fields: [
38
- { key: "subject", label: "Subject", type: "text", required: true },
44
+ {
45
+ key: "subject",
46
+ label: "Subject",
47
+ description: "Brief description of your inquiry",
48
+ type: "text",
49
+ required: true,
50
+ placeholder: "e.g., Order inquiry",
51
+ helper_text: "Please provide a clear subject line",
52
+ },
53
+ {
54
+ key: "message",
55
+ label: "Message",
56
+ description: "Detailed message about your inquiry",
57
+ type: "textarea",
58
+ required: true,
59
+ placeholder: "Please describe your issue or question...",
60
+ },
39
61
  {
40
62
  key: "priority",
41
63
  label: "Priority",
64
+ description: "How urgent is your request?",
42
65
  type: "select",
66
+ required: false,
43
67
  options: [
44
68
  { value: "low", label: "Low" },
69
+ { value: "medium", label: "Medium" },
45
70
  { value: "high", label: "High" },
71
+ { value: "urgent", label: "Urgent" },
72
+ ],
73
+ },
74
+ {
75
+ key: "order_number",
76
+ label: "Order Number",
77
+ description: "If this relates to an order, please provide the order number",
78
+ type: "text",
79
+ required: false,
80
+ placeholder: "order_123456",
81
+ },
82
+ {
83
+ key: "phone",
84
+ label: "Phone Number",
85
+ type: "text",
86
+ required: false,
87
+ placeholder: "+1 (555) 123-4567",
88
+ },
89
+ {
90
+ key: "preferred_contact_method",
91
+ label: "Preferred Contact Method",
92
+ type: "select",
93
+ required: false,
94
+ options: [
95
+ { value: "email", label: "Email" },
96
+ { value: "phone", label: "Phone" },
46
97
  ],
47
98
  },
99
+ {
100
+ key: "is_return_request",
101
+ label: "Is this a return request?",
102
+ type: "boolean",
103
+ required: false,
104
+ },
48
105
  ],
49
106
  },
107
+ // Status lifecycle configuration
108
+ statuses: {
109
+ // Initial status when a request is created
110
+ initial: "new",
111
+ // Intermediate statuses (work in progress)
112
+ intermediates: ["in_review", "waiting_for_customer"],
113
+ // Final status (request is complete)
114
+ final: "closed",
115
+ // Allowed status transitions
116
+ transitions: {
117
+ new: ["in_review", "closed"],
118
+ in_review: ["waiting_for_customer", "closed"],
119
+ waiting_for_customer: ["in_review", "closed"],
120
+ },
121
+ },
122
+ // Status options with labels and notification settings
50
123
  status_options: [
51
- { code: "new", label: "New", notify_customer: true },
52
- { code: "in_review", label: "In review" },
124
+ {
125
+ code: "new",
126
+ label: "New",
127
+ description: "Recently submitted requests awaiting review",
128
+ notify_customer: true,
129
+ template: "emails/contact-received.mjml",
130
+ },
131
+ {
132
+ code: "in_review",
133
+ label: "In Review",
134
+ description: "Assigned to an agent and being reviewed",
135
+ notify_customer: false,
136
+ },
137
+ {
138
+ code: "waiting_for_customer",
139
+ label: "Waiting for Customer",
140
+ description: "Awaiting response from customer",
141
+ notify_customer: true,
142
+ template: "emails/contact-waiting.mjml",
143
+ },
53
144
  {
54
145
  code: "closed",
55
146
  label: "Closed",
147
+ description: "Resolved and completed",
56
148
  notify_customer: true,
57
149
  template: "emails/contact-final.mjml",
58
150
  },
59
151
  ],
60
- statuses: {
61
- initial: "new",
62
- intermediates: ["in_review"],
63
- final: "closed",
64
- transitions: {
65
- new: ["in_review", "closed"],
66
- in_review: ["closed"],
67
- },
68
- },
152
+ // Notification configuration
69
153
  notifications: {
154
+ // Send email when a contact request is created
70
155
  send_on_create: true,
156
+ // Template for acknowledgement email
71
157
  acknowledgement_template: "emails/contact-received.mjml",
158
+ // Send email when request reaches final status
72
159
  send_on_final_status: true,
160
+ // Optional: Custom from address
161
+ from_address: "support@yourstore.com",
162
+ // Optional: Reply-to address
163
+ reply_to: "support@yourstore.com",
73
164
  },
165
+ // Comments configuration
74
166
  comments: {
167
+ // Enable admin comments on contact requests
75
168
  enabled: true,
169
+ // Require a note when changing status to final
76
170
  require_note_on_final: true,
77
171
  },
78
172
  }),
79
173
  },
80
174
  ]
81
175
 
176
+ // Register the ContactRequestModule
82
177
  const modules = [ContactRequestModule]
178
+
179
+ export default {
180
+ projectConfig: {
181
+ // Your Medusa project configuration
182
+ // database_url: process.env.DATABASE_URL,
183
+ // ...
184
+ },
185
+ plugins,
186
+ modules,
187
+ } satisfies ConfigModule
83
188
  ```
84
189
 
190
+ ### Field Types
191
+
192
+ Available field types for `additional_fields`:
193
+ - `text`: Single-line text input
194
+ - `textarea`: Multi-line text input
195
+ - `number`: Numeric input
196
+ - `select`: Dropdown selection (requires `options` array)
197
+ - `multi_select`: Multiple selection (requires `options` array)
198
+ - `boolean`: Checkbox
199
+ - `date`: Date picker
200
+
85
201
  ### Status lifecycle best practices
86
202
 
87
203
  - Define unique status codes (kebab or snake case) and map them in `status_options`.
@@ -165,32 +281,61 @@ All UI components follow the Medusa UI kit spacing (8pt grid), color, and access
165
281
 
166
282
  ## Frontend helper
167
283
 
168
- Skip hand-writing `fetch` calls by importing the provided helper:
284
+ Skip hand-writing `fetch` calls by importing the provided helper. **Most storefront requests require a publishable API key**, which you can create in the Medusa dashboard (`Settings → API Keys`).
169
285
 
170
286
  ```ts
171
287
  import { submitContactRequest } from "medusa-contact-us"
172
288
 
173
- await submitContactRequest({
174
- email: "customer@example.com",
175
- payload: { subject: "Question", priority: "high" },
176
- })
289
+ const options = {
290
+ baseUrl: "https://store.myshop.com",
291
+ publishableApiKey: "pk_your_publishable_api_key_here",
292
+ }
293
+
294
+ await submitContactRequest(
295
+ {
296
+ email: "customer@example.com",
297
+ payload: { subject: "Question", priority: "high" },
298
+ },
299
+ options
300
+ )
177
301
  ```
178
302
 
179
- Passing a Medusa JS client automatically reuses its transport:
303
+ Passing a Medusa JS client automatically reuses its transport and publishable key:
180
304
 
181
305
  ```ts
182
306
  import Medusa from "@medusajs/medusa-js"
183
307
  import { submitContactRequest } from "medusa-contact-us"
184
308
 
185
- const client = new Medusa({ baseUrl: "https://your-medusa.com" })
186
-
187
- await submitContactRequest({
188
- client,
189
- email: "customer@example.com",
190
- payload: { subject: "Returns" },
309
+ const client = new Medusa({
310
+ baseUrl: "https://store.myshop.com",
311
+ publishableKey: "pk_your_publishable_api_key_here",
191
312
  })
313
+
314
+ await submitContactRequest(
315
+ {
316
+ client,
317
+ email: "customer@example.com",
318
+ payload: { subject: "Returns" },
319
+ },
320
+ {
321
+ // Additional headers (cookies/JWT) can still be provided when needed
322
+ headers: {
323
+ Cookie: "connect.sid=...",
324
+ },
325
+ }
326
+ )
192
327
  ```
193
328
 
329
+ **Helper options:**
330
+
331
+ - `publishableApiKey` – Required for public storefront calls when not passing a Medusa JS client.
332
+ - `baseUrl` – Storefront API origin (ignored when `client` is provided).
333
+ - `client` – Pre-configured Medusa JS/SDK instance (reuses its base URL and publishable key).
334
+ - `fetchImpl` – Custom fetch implementation (SSR, React Native, etc.).
335
+ - `headers` – Additional headers merged into the request (e.g., session cookie, localization).
336
+
337
+ Customer-authenticated endpoints (like submitting a request from a logged-in area) still require the appropriate session cookie or JWT. Provide those via the `headers` option if they’re not already managed by the browser fetch call.
338
+
194
339
  ## Workflows & notifications
195
340
 
196
341
  - `createContactRequestWorkflow` validates payloads, persists the request, and optionally fires an acknowledgement email.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "medusa-contact-us",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A starter for Medusa plugins.",
5
5
  "author": "Medusa (https://medusajs.com)",
6
6
  "license": "MIT",
@@ -10,6 +10,7 @@
10
10
  "exports": {
11
11
  "./package.json": "./package.json",
12
12
  "./workflows": "./.medusa/server/src/workflows/index.js",
13
+ "./helpers": "./.medusa/server/src/helpers/index.js",
13
14
  "./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
14
15
  "./modules/*": "./.medusa/server/src/modules/*/index.js",
15
16
  "./providers/*": "./.medusa/server/src/providers/*/index.js",