@punchcommerce/punchcommerce-medusa-plugin 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.
Files changed (29) hide show
  1. package/.medusa/server/src/admin/index.js +265 -0
  2. package/.medusa/server/src/admin/index.mjs +264 -0
  3. package/.medusa/server/src/api/admin/customers/[id]/punchcommerce-customer/route.js +35 -0
  4. package/.medusa/server/src/api/middlewares.js +52 -0
  5. package/.medusa/server/src/api/store/punchout/actions/parse-items.js +32 -0
  6. package/.medusa/server/src/api/store/punchout/actions/route.js +70 -0
  7. package/.medusa/server/src/api/store/punchout/basket/route.js +17 -0
  8. package/.medusa/server/src/modules/punchcommerce-client/index.js +13 -0
  9. package/.medusa/server/src/modules/punchcommerce-client/service.js +36 -0
  10. package/.medusa/server/src/modules/punchcommerce-client/transform.js +43 -0
  11. package/.medusa/server/src/modules/punchcommerce-client/types.js +3 -0
  12. package/.medusa/server/src/providers/punchcommerce-auth/index.js +10 -0
  13. package/.medusa/server/src/providers/punchcommerce-auth/service.js +69 -0
  14. package/.medusa/server/src/subscribers/customer-deleted.js +26 -0
  15. package/.medusa/server/src/workflows/build-background-search-basket.js +49 -0
  16. package/.medusa/server/src/workflows/build-punchout-basket.js +40 -0
  17. package/.medusa/server/src/workflows/delete-punchcommerce-customer.js +12 -0
  18. package/.medusa/server/src/workflows/lookup-product-handle.js +10 -0
  19. package/.medusa/server/src/workflows/restore-punchout-basket.js +33 -0
  20. package/.medusa/server/src/workflows/steps/get-punchout-cart.js +48 -0
  21. package/.medusa/server/src/workflows/steps/link-punchcommerce-auth-identity.js +86 -0
  22. package/.medusa/server/src/workflows/steps/lookup-product-handle-by-sku.js +21 -0
  23. package/.medusa/server/src/workflows/steps/lookup-punchcommerce-uid.js +16 -0
  24. package/.medusa/server/src/workflows/steps/lookup-variants-by-sku.js +25 -0
  25. package/.medusa/server/src/workflows/steps/search-products.js +42 -0
  26. package/.medusa/server/src/workflows/steps/unlink-punchcommerce-auth-identity.js +37 -0
  27. package/.medusa/server/src/workflows/upsert-punchcommerce-customer.js +10 -0
  28. package/README.md +513 -0
  29. package/package.json +72 -0
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const adminSdk = require("@medusajs/admin-sdk");
4
+ const icons = require("@medusajs/icons");
5
+ const ui = require("@medusajs/ui");
6
+ const reactQuery = require("@tanstack/react-query");
7
+ const react = require("react");
8
+ const reactI18next = require("react-i18next");
9
+ const Medusa = require("@medusajs/js-sdk");
10
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
11
+ const Medusa__default = /* @__PURE__ */ _interopDefault(Medusa);
12
+ const sdk = new Medusa__default.default({
13
+ baseUrl: "/",
14
+ debug: false,
15
+ auth: {
16
+ type: "session"
17
+ }
18
+ });
19
+ const PunchCommerceCustomerWidget = ({
20
+ data: customer
21
+ }) => {
22
+ const { t } = reactI18next.useTranslation();
23
+ const [open, setOpen] = react.useState(false);
24
+ const [uid, setUid] = react.useState("");
25
+ const [error, setError] = react.useState(null);
26
+ const queryClient = reactQuery.useQueryClient();
27
+ const queryKey = ["punchcommerce-customer", customer.id];
28
+ const endpoint = `/admin/customers/${customer.id}/punchcommerce-customer`;
29
+ const { data, isLoading } = reactQuery.useQuery({
30
+ queryFn: () => sdk.client.fetch(endpoint),
31
+ queryKey
32
+ });
33
+ const existing = (data == null ? void 0 : data.punchcommerce_customer) ?? null;
34
+ react.useEffect(() => {
35
+ if (open) {
36
+ setUid((existing == null ? void 0 : existing.uid) ?? "");
37
+ setError(null);
38
+ }
39
+ }, [open, existing == null ? void 0 : existing.uid]);
40
+ const upsertMutation = reactQuery.useMutation({
41
+ mutationFn: (nextUid) => sdk.client.fetch(endpoint, {
42
+ method: "POST",
43
+ body: { uid: nextUid }
44
+ }),
45
+ onSuccess: () => {
46
+ queryClient.invalidateQueries({ queryKey });
47
+ ui.toast.success(
48
+ existing ? t("punchcommerce.customer.toast.updated") : t("punchcommerce.customer.toast.created")
49
+ );
50
+ setOpen(false);
51
+ },
52
+ onError: (err, nextUid) => {
53
+ const message = (err == null ? void 0 : err.message) ? t(err.message, { uid: nextUid }) : t("punchcommerce.customer.errors.save_failed");
54
+ setError(message);
55
+ ui.toast.error(message);
56
+ }
57
+ });
58
+ const deleteMutation = reactQuery.useMutation({
59
+ mutationFn: () => sdk.client.fetch(endpoint, {
60
+ method: "DELETE"
61
+ }),
62
+ onSuccess: () => {
63
+ queryClient.invalidateQueries({ queryKey });
64
+ ui.toast.success(t("punchcommerce.customer.toast.deleted"));
65
+ },
66
+ onError: (err) => {
67
+ ui.toast.error((err == null ? void 0 : err.message) ?? t("punchcommerce.customer.errors.delete_failed"));
68
+ }
69
+ });
70
+ const handleSubmit = () => {
71
+ const trimmed = uid.trim();
72
+ if (!trimmed) {
73
+ setError(t("punchcommerce.customer.errors.uid_required"));
74
+ return;
75
+ }
76
+ setError(null);
77
+ upsertMutation.mutate(trimmed);
78
+ };
79
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
80
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
81
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: t("punchcommerce.customer.heading") }),
82
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-x-2", children: existing ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
83
+ /* @__PURE__ */ jsxRuntime.jsxs(
84
+ ui.Button,
85
+ {
86
+ size: "small",
87
+ variant: "secondary",
88
+ onClick: () => setOpen(true),
89
+ children: [
90
+ /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {}),
91
+ t("punchcommerce.customer.edit")
92
+ ]
93
+ }
94
+ ),
95
+ /* @__PURE__ */ jsxRuntime.jsx(
96
+ ui.Button,
97
+ {
98
+ size: "small",
99
+ variant: "danger",
100
+ isLoading: deleteMutation.isPending,
101
+ disabled: deleteMutation.isPending,
102
+ onClick: () => deleteMutation.mutate(),
103
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
104
+ }
105
+ )
106
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(
107
+ ui.Button,
108
+ {
109
+ size: "small",
110
+ variant: "secondary",
111
+ onClick: () => setOpen(true),
112
+ children: [
113
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
114
+ t("punchcommerce.customer.add")
115
+ ]
116
+ }
117
+ ) })
118
+ ] }),
119
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4 px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
120
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", weight: "plus", children: t("punchcommerce.customer.uid_label") }),
121
+ /* @__PURE__ */ jsxRuntime.jsx(
122
+ ui.Text,
123
+ {
124
+ size: "small",
125
+ leading: "compact",
126
+ className: "text-ui-fg-subtle",
127
+ children: isLoading ? t("punchcommerce.customer.loading") : (existing == null ? void 0 : existing.uid) ?? "—"
128
+ }
129
+ )
130
+ ] }) }),
131
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Content, { children: [
132
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Title, { children: existing ? t("punchcommerce.customer.drawer.title_edit") : t("punchcommerce.customer.drawer.title_add") }) }),
133
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Body, { className: "flex-1 overflow-auto p-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2", children: [
134
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "punchcommerce-uid", children: t("punchcommerce.customer.uid_label") }),
135
+ /* @__PURE__ */ jsxRuntime.jsx(
136
+ ui.Input,
137
+ {
138
+ id: "punchcommerce-uid",
139
+ value: uid,
140
+ onChange: (e) => {
141
+ setUid(e.target.value);
142
+ setError(null);
143
+ }
144
+ }
145
+ ),
146
+ error && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-error", children: error })
147
+ ] }) }) }),
148
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
149
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
150
+ ui.Button,
151
+ {
152
+ size: "small",
153
+ variant: "secondary",
154
+ disabled: upsertMutation.isPending,
155
+ children: t("punchcommerce.customer.drawer.cancel")
156
+ }
157
+ ) }),
158
+ /* @__PURE__ */ jsxRuntime.jsx(
159
+ ui.Button,
160
+ {
161
+ size: "small",
162
+ onClick: handleSubmit,
163
+ isLoading: upsertMutation.isPending,
164
+ children: t("punchcommerce.customer.drawer.save")
165
+ }
166
+ )
167
+ ] }) })
168
+ ] }) })
169
+ ] });
170
+ };
171
+ adminSdk.defineWidgetConfig({
172
+ zone: "customer.details.side.after"
173
+ });
174
+ const punchcommerce$1 = {
175
+ customer: {
176
+ heading: "PunchCommerce",
177
+ uid_label: "PunchCommerce-Kundenkennung (uID)",
178
+ loading: "Lädt…",
179
+ add: "Hinzufügen",
180
+ edit: "Bearbeiten",
181
+ drawer: {
182
+ title_add: "PunchCommerce-Kundenkennung hinzufügen",
183
+ title_edit: "PunchCommerce-Kundenkennung bearbeiten",
184
+ cancel: "Abbrechen",
185
+ save: "Speichern"
186
+ },
187
+ toast: {
188
+ updated: "PunchCommerce-Kundenkennung aktualisiert",
189
+ created: "PunchCommerce-Kundenkennung hinterlegt",
190
+ deleted: "PunchCommerce-Kundenkennung entfernt"
191
+ },
192
+ errors: {
193
+ uid_required: "PunchCommerce-Kundenkennung darf nicht leer sein",
194
+ uid_conflict: "Die PunchCommerce-Kennung '{{uid}}' ist bereits mit einer anderen Auth-Identität verknüpft.",
195
+ save_failed: "Speichern fehlgeschlagen",
196
+ delete_failed: "Löschen fehlgeschlagen"
197
+ }
198
+ }
199
+ };
200
+ const de = {
201
+ punchcommerce: punchcommerce$1
202
+ };
203
+ const punchcommerce = {
204
+ customer: {
205
+ heading: "PunchCommerce",
206
+ uid_label: "PunchCommerce customer ID (uID)",
207
+ loading: "Loading…",
208
+ add: "Add",
209
+ edit: "Edit",
210
+ drawer: {
211
+ title_add: "Add PunchCommerce customer ID",
212
+ title_edit: "Edit PunchCommerce customer ID",
213
+ cancel: "Cancel",
214
+ save: "Save"
215
+ },
216
+ toast: {
217
+ updated: "PunchCommerce customer ID updated",
218
+ created: "PunchCommerce customer ID saved",
219
+ deleted: "PunchCommerce customer ID removed"
220
+ },
221
+ errors: {
222
+ uid_required: "PunchCommerce customer ID must not be empty",
223
+ uid_conflict: "The PunchCommerce ID '{{uid}}' is already linked to another auth identity.",
224
+ save_failed: "Save failed",
225
+ delete_failed: "Delete failed"
226
+ }
227
+ }
228
+ };
229
+ const en = {
230
+ punchcommerce
231
+ };
232
+ const i18nTranslations0 = {
233
+ de: {
234
+ translation: de
235
+ },
236
+ en: {
237
+ translation: en
238
+ }
239
+ };
240
+ const widgetModule = { widgets: [
241
+ {
242
+ Component: PunchCommerceCustomerWidget,
243
+ zone: ["customer.details.side.after"]
244
+ }
245
+ ] };
246
+ const routeModule = {
247
+ routes: []
248
+ };
249
+ const menuItemModule = {
250
+ menuItems: []
251
+ };
252
+ const formModule = { customFields: {} };
253
+ const displayModule = {
254
+ displays: {}
255
+ };
256
+ const i18nModule = { resources: i18nTranslations0 };
257
+ const plugin = {
258
+ widgetModule,
259
+ routeModule,
260
+ menuItemModule,
261
+ formModule,
262
+ displayModule,
263
+ i18nModule
264
+ };
265
+ module.exports = plugin;
@@ -0,0 +1,264 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { defineWidgetConfig } from "@medusajs/admin-sdk";
3
+ import { PencilSquare, Trash, Plus } from "@medusajs/icons";
4
+ import { toast, Container, Heading, Button, Text, Drawer, Label, Input } from "@medusajs/ui";
5
+ import { useQueryClient, useQuery, useMutation } from "@tanstack/react-query";
6
+ import { useState, useEffect } from "react";
7
+ import { useTranslation } from "react-i18next";
8
+ import Medusa from "@medusajs/js-sdk";
9
+ const sdk = new Medusa({
10
+ baseUrl: "/",
11
+ debug: false,
12
+ auth: {
13
+ type: "session"
14
+ }
15
+ });
16
+ const PunchCommerceCustomerWidget = ({
17
+ data: customer
18
+ }) => {
19
+ const { t } = useTranslation();
20
+ const [open, setOpen] = useState(false);
21
+ const [uid, setUid] = useState("");
22
+ const [error, setError] = useState(null);
23
+ const queryClient = useQueryClient();
24
+ const queryKey = ["punchcommerce-customer", customer.id];
25
+ const endpoint = `/admin/customers/${customer.id}/punchcommerce-customer`;
26
+ const { data, isLoading } = useQuery({
27
+ queryFn: () => sdk.client.fetch(endpoint),
28
+ queryKey
29
+ });
30
+ const existing = (data == null ? void 0 : data.punchcommerce_customer) ?? null;
31
+ useEffect(() => {
32
+ if (open) {
33
+ setUid((existing == null ? void 0 : existing.uid) ?? "");
34
+ setError(null);
35
+ }
36
+ }, [open, existing == null ? void 0 : existing.uid]);
37
+ const upsertMutation = useMutation({
38
+ mutationFn: (nextUid) => sdk.client.fetch(endpoint, {
39
+ method: "POST",
40
+ body: { uid: nextUid }
41
+ }),
42
+ onSuccess: () => {
43
+ queryClient.invalidateQueries({ queryKey });
44
+ toast.success(
45
+ existing ? t("punchcommerce.customer.toast.updated") : t("punchcommerce.customer.toast.created")
46
+ );
47
+ setOpen(false);
48
+ },
49
+ onError: (err, nextUid) => {
50
+ const message = (err == null ? void 0 : err.message) ? t(err.message, { uid: nextUid }) : t("punchcommerce.customer.errors.save_failed");
51
+ setError(message);
52
+ toast.error(message);
53
+ }
54
+ });
55
+ const deleteMutation = useMutation({
56
+ mutationFn: () => sdk.client.fetch(endpoint, {
57
+ method: "DELETE"
58
+ }),
59
+ onSuccess: () => {
60
+ queryClient.invalidateQueries({ queryKey });
61
+ toast.success(t("punchcommerce.customer.toast.deleted"));
62
+ },
63
+ onError: (err) => {
64
+ toast.error((err == null ? void 0 : err.message) ?? t("punchcommerce.customer.errors.delete_failed"));
65
+ }
66
+ });
67
+ const handleSubmit = () => {
68
+ const trimmed = uid.trim();
69
+ if (!trimmed) {
70
+ setError(t("punchcommerce.customer.errors.uid_required"));
71
+ return;
72
+ }
73
+ setError(null);
74
+ upsertMutation.mutate(trimmed);
75
+ };
76
+ return /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", children: [
77
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
78
+ /* @__PURE__ */ jsx(Heading, { level: "h2", children: t("punchcommerce.customer.heading") }),
79
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-x-2", children: existing ? /* @__PURE__ */ jsxs(Fragment, { children: [
80
+ /* @__PURE__ */ jsxs(
81
+ Button,
82
+ {
83
+ size: "small",
84
+ variant: "secondary",
85
+ onClick: () => setOpen(true),
86
+ children: [
87
+ /* @__PURE__ */ jsx(PencilSquare, {}),
88
+ t("punchcommerce.customer.edit")
89
+ ]
90
+ }
91
+ ),
92
+ /* @__PURE__ */ jsx(
93
+ Button,
94
+ {
95
+ size: "small",
96
+ variant: "danger",
97
+ isLoading: deleteMutation.isPending,
98
+ disabled: deleteMutation.isPending,
99
+ onClick: () => deleteMutation.mutate(),
100
+ children: /* @__PURE__ */ jsx(Trash, {})
101
+ }
102
+ )
103
+ ] }) : /* @__PURE__ */ jsxs(
104
+ Button,
105
+ {
106
+ size: "small",
107
+ variant: "secondary",
108
+ onClick: () => setOpen(true),
109
+ children: [
110
+ /* @__PURE__ */ jsx(Plus, {}),
111
+ t("punchcommerce.customer.add")
112
+ ]
113
+ }
114
+ ) })
115
+ ] }),
116
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 px-6 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-1", children: [
117
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", weight: "plus", children: t("punchcommerce.customer.uid_label") }),
118
+ /* @__PURE__ */ jsx(
119
+ Text,
120
+ {
121
+ size: "small",
122
+ leading: "compact",
123
+ className: "text-ui-fg-subtle",
124
+ children: isLoading ? t("punchcommerce.customer.loading") : (existing == null ? void 0 : existing.uid) ?? "—"
125
+ }
126
+ )
127
+ ] }) }),
128
+ /* @__PURE__ */ jsx(Drawer, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(Drawer.Content, { children: [
129
+ /* @__PURE__ */ jsx(Drawer.Header, { children: /* @__PURE__ */ jsx(Drawer.Title, { children: existing ? t("punchcommerce.customer.drawer.title_edit") : t("punchcommerce.customer.drawer.title_add") }) }),
130
+ /* @__PURE__ */ jsx(Drawer.Body, { className: "flex-1 overflow-auto p-4", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-2", children: [
131
+ /* @__PURE__ */ jsx(Label, { htmlFor: "punchcommerce-uid", children: t("punchcommerce.customer.uid_label") }),
132
+ /* @__PURE__ */ jsx(
133
+ Input,
134
+ {
135
+ id: "punchcommerce-uid",
136
+ value: uid,
137
+ onChange: (e) => {
138
+ setUid(e.target.value);
139
+ setError(null);
140
+ }
141
+ }
142
+ ),
143
+ error && /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-error", children: error })
144
+ ] }) }) }),
145
+ /* @__PURE__ */ jsx(Drawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
146
+ /* @__PURE__ */ jsx(Drawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(
147
+ Button,
148
+ {
149
+ size: "small",
150
+ variant: "secondary",
151
+ disabled: upsertMutation.isPending,
152
+ children: t("punchcommerce.customer.drawer.cancel")
153
+ }
154
+ ) }),
155
+ /* @__PURE__ */ jsx(
156
+ Button,
157
+ {
158
+ size: "small",
159
+ onClick: handleSubmit,
160
+ isLoading: upsertMutation.isPending,
161
+ children: t("punchcommerce.customer.drawer.save")
162
+ }
163
+ )
164
+ ] }) })
165
+ ] }) })
166
+ ] });
167
+ };
168
+ defineWidgetConfig({
169
+ zone: "customer.details.side.after"
170
+ });
171
+ const punchcommerce$1 = {
172
+ customer: {
173
+ heading: "PunchCommerce",
174
+ uid_label: "PunchCommerce-Kundenkennung (uID)",
175
+ loading: "Lädt…",
176
+ add: "Hinzufügen",
177
+ edit: "Bearbeiten",
178
+ drawer: {
179
+ title_add: "PunchCommerce-Kundenkennung hinzufügen",
180
+ title_edit: "PunchCommerce-Kundenkennung bearbeiten",
181
+ cancel: "Abbrechen",
182
+ save: "Speichern"
183
+ },
184
+ toast: {
185
+ updated: "PunchCommerce-Kundenkennung aktualisiert",
186
+ created: "PunchCommerce-Kundenkennung hinterlegt",
187
+ deleted: "PunchCommerce-Kundenkennung entfernt"
188
+ },
189
+ errors: {
190
+ uid_required: "PunchCommerce-Kundenkennung darf nicht leer sein",
191
+ uid_conflict: "Die PunchCommerce-Kennung '{{uid}}' ist bereits mit einer anderen Auth-Identität verknüpft.",
192
+ save_failed: "Speichern fehlgeschlagen",
193
+ delete_failed: "Löschen fehlgeschlagen"
194
+ }
195
+ }
196
+ };
197
+ const de = {
198
+ punchcommerce: punchcommerce$1
199
+ };
200
+ const punchcommerce = {
201
+ customer: {
202
+ heading: "PunchCommerce",
203
+ uid_label: "PunchCommerce customer ID (uID)",
204
+ loading: "Loading…",
205
+ add: "Add",
206
+ edit: "Edit",
207
+ drawer: {
208
+ title_add: "Add PunchCommerce customer ID",
209
+ title_edit: "Edit PunchCommerce customer ID",
210
+ cancel: "Cancel",
211
+ save: "Save"
212
+ },
213
+ toast: {
214
+ updated: "PunchCommerce customer ID updated",
215
+ created: "PunchCommerce customer ID saved",
216
+ deleted: "PunchCommerce customer ID removed"
217
+ },
218
+ errors: {
219
+ uid_required: "PunchCommerce customer ID must not be empty",
220
+ uid_conflict: "The PunchCommerce ID '{{uid}}' is already linked to another auth identity.",
221
+ save_failed: "Save failed",
222
+ delete_failed: "Delete failed"
223
+ }
224
+ }
225
+ };
226
+ const en = {
227
+ punchcommerce
228
+ };
229
+ const i18nTranslations0 = {
230
+ de: {
231
+ translation: de
232
+ },
233
+ en: {
234
+ translation: en
235
+ }
236
+ };
237
+ const widgetModule = { widgets: [
238
+ {
239
+ Component: PunchCommerceCustomerWidget,
240
+ zone: ["customer.details.side.after"]
241
+ }
242
+ ] };
243
+ const routeModule = {
244
+ routes: []
245
+ };
246
+ const menuItemModule = {
247
+ menuItems: []
248
+ };
249
+ const formModule = { customFields: {} };
250
+ const displayModule = {
251
+ displays: {}
252
+ };
253
+ const i18nModule = { resources: i18nTranslations0 };
254
+ const plugin = {
255
+ widgetModule,
256
+ routeModule,
257
+ menuItemModule,
258
+ formModule,
259
+ displayModule,
260
+ i18nModule
261
+ };
262
+ export {
263
+ plugin as default
264
+ };
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PROVIDER = void 0;
4
+ exports.GET = GET;
5
+ exports.POST = POST;
6
+ exports.DELETE = DELETE;
7
+ const utils_1 = require("@medusajs/framework/utils");
8
+ const upsert_punchcommerce_customer_1 = require("../../../../../workflows/upsert-punchcommerce-customer");
9
+ const delete_punchcommerce_customer_1 = require("../../../../../workflows/delete-punchcommerce-customer");
10
+ exports.PROVIDER = "punchcommerce";
11
+ async function GET(req, res) {
12
+ const { id: customer_id } = req.params;
13
+ const authModule = req.scope.resolve(utils_1.Modules.AUTH);
14
+ const [authIdentity] = await authModule.listAuthIdentities({ app_metadata: { customer_id } }, { relations: ["provider_identities"] });
15
+ const pcProvider = authIdentity?.provider_identities?.find((pi) => pi.provider === exports.PROVIDER);
16
+ res.status(200).json({
17
+ punchcommerce_customer: pcProvider ? { uid: pcProvider.entity_id } : null,
18
+ });
19
+ }
20
+ async function POST(req, res) {
21
+ const { id: customer_id } = req.params;
22
+ const { uid } = req.validatedBody;
23
+ const { result } = await (0, upsert_punchcommerce_customer_1.upsertPunchCommerceCustomerWorkflow)(req.scope).run({
24
+ input: { customer_id, uid },
25
+ });
26
+ res.status(200).json(result);
27
+ }
28
+ async function DELETE(req, res) {
29
+ const { id: customer_id } = req.params;
30
+ const { result } = await (0, delete_punchcommerce_customer_1.deletePunchCommerceCustomerWorkflow)(req.scope).run({
31
+ input: { customer_id },
32
+ });
33
+ res.status(200).json(result);
34
+ }
35
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2N1c3RvbWVycy9baWRdL3B1bmNoY29tbWVyY2UtY3VzdG9tZXIvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBUUEsa0JBZ0JDO0FBRUQsb0JBWUM7QUFFRCx3QkFRQztBQS9DRCxxREFBbUQ7QUFDbkQsMEdBQTRHO0FBQzVHLDBHQUE0RztBQUcvRixRQUFBLFFBQVEsR0FBRyxlQUFlLENBQUE7QUFFaEMsS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUFrQixFQUFFLEdBQW1CO0lBQy9ELE1BQU0sRUFBRSxFQUFFLEVBQUUsV0FBVyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQTtJQUN0QyxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFPLENBQUMsSUFBSSxDQUFDLENBQUE7SUFFbEQsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLE1BQU0sVUFBVSxDQUFDLGtCQUFrQixDQUN4RCxFQUFFLFlBQVksRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQ2pDLEVBQUUsU0FBUyxFQUFFLENBQUMscUJBQXFCLENBQUMsRUFBRSxDQUN2QyxDQUFBO0lBRUQsTUFBTSxVQUFVLEdBQUcsWUFBWSxFQUFFLG1CQUFtQixFQUFFLElBQUksQ0FDeEQsQ0FBQyxFQUFPLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEtBQUssZ0JBQVEsQ0FDdEMsQ0FBQTtJQUVELEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ25CLHNCQUFzQixFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJO0tBQzFFLENBQUMsQ0FBQTtBQUNKLENBQUM7QUFFTSxLQUFLLFVBQVUsSUFBSSxDQUN4QixHQUFxRCxFQUNyRCxHQUFtQjtJQUVuQixNQUFNLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUE7SUFDdEMsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxhQUFhLENBQUE7SUFFakMsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSxtRUFBbUMsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQzFFLEtBQUssRUFBRSxFQUFFLFdBQVcsRUFBRSxHQUFHLEVBQUU7S0FDNUIsQ0FBQyxDQUFBO0lBRUYsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7QUFDOUIsQ0FBQztBQUVNLEtBQUssVUFBVSxNQUFNLENBQUMsR0FBa0IsRUFBRSxHQUFtQjtJQUNsRSxNQUFNLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUE7SUFFdEMsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSxtRUFBbUMsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQzFFLEtBQUssRUFBRSxFQUFFLFdBQVcsRUFBRTtLQUN2QixDQUFDLENBQUE7SUFFRixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtBQUM5QixDQUFDIn0=
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PunchOutActionsSchema = exports.GetPunchOutBasketSchema = exports.UpsertPunchCommerceCustomerSchema = void 0;
4
+ const http_1 = require("@medusajs/framework/http");
5
+ const zod_1 = require("zod");
6
+ const actionsField = zod_1.z
7
+ .union([zod_1.z.string(), zod_1.z.array(zod_1.z.string())])
8
+ .transform((v) => (Array.isArray(v) ? v : [v]))
9
+ .default([]);
10
+ exports.UpsertPunchCommerceCustomerSchema = zod_1.z.object({
11
+ uid: zod_1.z.string().trim().min(1, "Parameter uid is required"),
12
+ });
13
+ exports.GetPunchOutBasketSchema = zod_1.z.object({
14
+ cart_id: zod_1.z.string().trim().min(1, "Parameter is required"),
15
+ });
16
+ exports.PunchOutActionsSchema = zod_1.z.object({
17
+ cart_id: zod_1.z.string().trim().min(1, "Parameter cart_id is required"),
18
+ actions: actionsField,
19
+ items: zod_1.z.string().trim().optional(),
20
+ ordernumber: zod_1.z.string().trim().optional(),
21
+ keyword: zod_1.z.string().trim().optional(),
22
+ sID: zod_1.z.string().optional(),
23
+ uID: zod_1.z.string().optional(),
24
+ });
25
+ exports.default = (0, http_1.defineMiddlewares)({
26
+ routes: [
27
+ {
28
+ matcher: "/admin/customers/:id/punchcommerce-customer",
29
+ method: "POST",
30
+ middlewares: [
31
+ (0, http_1.validateAndTransformBody)(exports.UpsertPunchCommerceCustomerSchema),
32
+ ],
33
+ },
34
+ {
35
+ matcher: "/store/punchout/basket",
36
+ method: "GET",
37
+ middlewares: [
38
+ (0, http_1.authenticate)("customer", ["bearer", "session"]),
39
+ (0, http_1.validateAndTransformQuery)(exports.GetPunchOutBasketSchema, {}),
40
+ ],
41
+ },
42
+ {
43
+ matcher: "/store/punchout/actions",
44
+ method: "GET",
45
+ middlewares: [
46
+ (0, http_1.authenticate)("customer", ["bearer", "session"]),
47
+ (0, http_1.validateAndTransformQuery)(exports.PunchOutActionsSchema, {}),
48
+ ],
49
+ },
50
+ ],
51
+ });
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1EQUtpQztBQUNqQyw2QkFBdUI7QUFFdkIsTUFBTSxZQUFZLEdBQUcsT0FBQztLQUNuQixLQUFLLENBQUMsQ0FBQyxPQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsT0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0tBQ3hDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM5QyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUE7QUFFRCxRQUFBLGlDQUFpQyxHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDeEQsR0FBRyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLDJCQUEyQixDQUFDO0NBQzNELENBQUMsQ0FBQTtBQUlXLFFBQUEsdUJBQXVCLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM5QyxPQUFPLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsdUJBQXVCLENBQUM7Q0FDM0QsQ0FBQyxDQUFBO0FBSVcsUUFBQSxxQkFBcUIsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQzVDLE9BQU8sRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSwrQkFBK0IsQ0FBQztJQUNsRSxPQUFPLEVBQUUsWUFBWTtJQUNyQixLQUFLLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNuQyxXQUFXLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUN6QyxPQUFPLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNyQyxHQUFHLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUMxQixHQUFHLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUMzQixDQUFDLENBQUE7QUFJRixrQkFBZSxJQUFBLHdCQUFpQixFQUFDO0lBQy9CLE1BQU0sRUFBRTtRQUNOO1lBQ0UsT0FBTyxFQUFFLDZDQUE2QztZQUN0RCxNQUFNLEVBQUUsTUFBTTtZQUNkLFdBQVcsRUFBRTtnQkFDWCxJQUFBLCtCQUF3QixFQUFDLHlDQUFpQyxDQUFDO2FBQzVEO1NBQ0Y7UUFDRDtZQUNFLE9BQU8sRUFBRSx3QkFBd0I7WUFDakMsTUFBTSxFQUFFLEtBQUs7WUFDYixXQUFXLEVBQUU7Z0JBQ1gsSUFBQSxtQkFBWSxFQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDL0MsSUFBQSxnQ0FBeUIsRUFBQywrQkFBdUIsRUFBRSxFQUFFLENBQUM7YUFDdkQ7U0FDRjtRQUNEO1lBQ0UsT0FBTyxFQUFFLHlCQUF5QjtZQUNsQyxNQUFNLEVBQUUsS0FBSztZQUNiLFdBQVcsRUFBRTtnQkFDWCxJQUFBLG1CQUFZLEVBQUMsVUFBVSxFQUFFLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUMvQyxJQUFBLGdDQUF5QixFQUFDLDZCQUFxQixFQUFFLEVBQUUsQ0FBQzthQUNyRDtTQUNGO0tBQ0Y7Q0FDRixDQUFDLENBQUEifQ==
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parsePunchOutItems = parsePunchOutItems;
7
+ const zod_1 = __importDefault(require("zod"));
8
+ const QuantityType = zod_1.default
9
+ .string()
10
+ .trim()
11
+ .regex(/^\d+$/)
12
+ .pipe(zod_1.default.coerce.number().int().positive());
13
+ const SkuType = zod_1.default.string().trim().min(1);
14
+ const ActionItemSchema = zod_1.default.tuple([
15
+ SkuType,
16
+ QuantityType,
17
+ ]);
18
+ function parsePunchOutItems(raw) {
19
+ if (!raw)
20
+ return [];
21
+ const items = [];
22
+ for (const item of raw.split(",")) {
23
+ const parts = item.split(':');
24
+ const result = ActionItemSchema.safeParse(parts);
25
+ if (!result.success)
26
+ continue;
27
+ const [sku, quantity] = result.data;
28
+ items.push({ sku: sku.trim(), quantity });
29
+ }
30
+ return items;
31
+ }
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UtaXRlbXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3B1bmNob3V0L2FjdGlvbnMvcGFyc2UtaXRlbXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFpQkEsZ0RBaUJDO0FBbENELDhDQUFvQjtBQUlwQixNQUFNLFlBQVksR0FBRyxhQUFDO0tBQ2pCLE1BQU0sRUFBRTtLQUNSLElBQUksRUFBRTtLQUNOLEtBQUssQ0FBQyxPQUFPLENBQUM7S0FDZCxJQUFJLENBQUMsYUFBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0FBRTlDLE1BQU0sT0FBTyxHQUFHLGFBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFFeEMsTUFBTSxnQkFBZ0IsR0FBRyxhQUFDLENBQUMsS0FBSyxDQUFDO0lBQzdCLE9BQU87SUFDUCxZQUFZO0NBQ2YsQ0FBQyxDQUFBO0FBRUYsU0FBZ0Isa0JBQWtCLENBQUMsR0FBdUI7SUFDdEQsSUFBSSxDQUFDLEdBQUc7UUFBRSxPQUFPLEVBQUUsQ0FBQTtJQUVuQixNQUFNLEtBQUssR0FBeUIsRUFBRSxDQUFBO0lBRXRDLEtBQUssTUFBTSxJQUFJLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUIsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRWhELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTztZQUFFLFNBQVE7UUFFN0IsTUFBTSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFBO1FBRW5DLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUE7SUFDN0MsQ0FBQztJQUVELE9BQU8sS0FBSyxDQUFBO0FBQ2hCLENBQUMifQ==