@legenki/print2medusa 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 (28) hide show
  1. package/.medusa/server/examples/basic-store/medusa-config.snippet.js +57 -0
  2. package/.medusa/server/src/admin/index.js +133 -0
  3. package/.medusa/server/src/admin/index.mjs +134 -0
  4. package/.medusa/server/src/api/admin/printful/status/route.js +15 -0
  5. package/.medusa/server/src/api/admin/printful/sync/route.js +25 -0
  6. package/.medusa/server/src/jobs/sync-products.js +31 -0
  7. package/.medusa/server/src/modules/printful/index.js +13 -0
  8. package/.medusa/server/src/modules/printful/migrations/Migration20260726000000.js +103 -0
  9. package/.medusa/server/src/modules/printful/models/printful-order-link.js +12 -0
  10. package/.medusa/server/src/modules/printful/models/printful-product-link.js +13 -0
  11. package/.medusa/server/src/modules/printful/models/printful-sync-log.js +15 -0
  12. package/.medusa/server/src/modules/printful/models/printful-variant-link.js +13 -0
  13. package/.medusa/server/src/modules/printful/service.js +126 -0
  14. package/.medusa/server/src/providers/printful-fulfillment/index.js +11 -0
  15. package/.medusa/server/src/providers/printful-fulfillment/service.js +97 -0
  16. package/.medusa/server/src/subscribers/order-placed.js +37 -0
  17. package/.medusa/server/src/subscribers/payment-captured.js +61 -0
  18. package/.medusa/server/src/utils/errors.js +24 -0
  19. package/.medusa/server/src/utils/index.js +21 -0
  20. package/.medusa/server/src/utils/mappers.js +250 -0
  21. package/.medusa/server/src/utils/printful-client.js +169 -0
  22. package/.medusa/server/src/utils/types.js +3 -0
  23. package/.medusa/server/src/workflows/create-printful-order.js +123 -0
  24. package/.medusa/server/src/workflows/index.js +13 -0
  25. package/.medusa/server/src/workflows/sync-products.js +227 -0
  26. package/LICENSE +21 -0
  27. package/README.md +127 -0
  28. package/package.json +87 -0
@@ -0,0 +1,126 @@
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.PENDING_PRINTFUL_ORDER_ID = void 0;
7
+ exports.isUniqueViolation = isUniqueViolation;
8
+ const utils_1 = require("@medusajs/framework/utils");
9
+ const printful_client_1 = require("../../utils/printful-client");
10
+ const printful_order_link_1 = __importDefault(require("./models/printful-order-link"));
11
+ const printful_product_link_1 = __importDefault(require("./models/printful-product-link"));
12
+ const printful_sync_log_1 = __importDefault(require("./models/printful-sync-log"));
13
+ const printful_variant_link_1 = __importDefault(require("./models/printful-variant-link"));
14
+ /** Sentinel stored in a placeholder link before the Printful order exists. */
15
+ exports.PENDING_PRINTFUL_ORDER_ID = "pending";
16
+ /**
17
+ * Detect a Postgres unique-constraint violation (SQLSTATE 23505) regardless of
18
+ * how the ORM wraps the driver error. Used to turn a lost insert race into a
19
+ * clean "already claimed" signal instead of a thrown error.
20
+ */
21
+ function isUniqueViolation(err) {
22
+ if (!err || typeof err !== "object") {
23
+ return false;
24
+ }
25
+ const e = err;
26
+ if (e.code === "23505") {
27
+ return true;
28
+ }
29
+ if (typeof e.message === "string" && e.message.includes("23505")) {
30
+ return true;
31
+ }
32
+ if (e.cause && e.cause !== err) {
33
+ return isUniqueViolation(e.cause);
34
+ }
35
+ return false;
36
+ }
37
+ class PrintfulModuleService extends (0, utils_1.MedusaService)({
38
+ PrintfulProductLink: printful_product_link_1.default,
39
+ PrintfulVariantLink: printful_variant_link_1.default,
40
+ PrintfulSyncLog: printful_sync_log_1.default,
41
+ PrintfulOrderLink: printful_order_link_1.default,
42
+ }) {
43
+ constructor(container, options) {
44
+ // MedusaService multi-arg constructor
45
+ super(...arguments);
46
+ this.client_ = null;
47
+ this.options_ = options ?? {};
48
+ }
49
+ async getOptions() {
50
+ return this.options_;
51
+ }
52
+ async getClient() {
53
+ if (!this.client_) {
54
+ if (!this.options_?.apiToken) {
55
+ throw new Error("Printful apiToken is missing. Set it in plugin options (PRINTFUL_API_TOKEN).");
56
+ }
57
+ this.client_ = new printful_client_1.PrintfulClient({
58
+ apiToken: this.options_.apiToken,
59
+ storeId: this.options_.storeId,
60
+ });
61
+ }
62
+ return this.client_;
63
+ }
64
+ async getStoreId() {
65
+ return this.options_?.storeId ?? "default";
66
+ }
67
+ async findProductLink(syncProductId) {
68
+ const storeId = await this.getStoreId();
69
+ const [link] = await this.listPrintfulProductLinks({
70
+ printful_store_id: storeId,
71
+ printful_sync_product_id: String(syncProductId),
72
+ });
73
+ return link ?? null;
74
+ }
75
+ async findVariantLink(syncVariantId) {
76
+ const storeId = await this.getStoreId();
77
+ const [link] = await this.listPrintfulVariantLinks({
78
+ printful_store_id: storeId,
79
+ printful_sync_variant_id: String(syncVariantId),
80
+ });
81
+ return link ?? null;
82
+ }
83
+ async findVariantLinkByMedusaId(medusaVariantId) {
84
+ const [link] = await this.listPrintfulVariantLinks({
85
+ medusa_variant_id: medusaVariantId,
86
+ });
87
+ return link ?? null;
88
+ }
89
+ async findOrderLink(medusaOrderId) {
90
+ const [link] = await this.listPrintfulOrderLinks({
91
+ medusa_order_id: medusaOrderId,
92
+ });
93
+ return link ?? null;
94
+ }
95
+ /**
96
+ * Atomically claim an order for Printful creation. Relies on the unique index
97
+ * on `medusa_order_id` so that concurrent captures cannot both proceed to
98
+ * `client.createOrder` — the loser hits a unique-constraint violation and is
99
+ * reported as `claimed: false`, avoiding duplicate Printful orders.
100
+ *
101
+ * Returns the created placeholder link on success, or null if already claimed.
102
+ */
103
+ async claimOrderLink(medusaOrderId) {
104
+ try {
105
+ const link = await this.createPrintfulOrderLinks({
106
+ medusa_order_id: medusaOrderId,
107
+ printful_order_id: exports.PENDING_PRINTFUL_ORDER_ID,
108
+ external_id: medusaOrderId,
109
+ status: "pending",
110
+ });
111
+ return link;
112
+ }
113
+ catch (err) {
114
+ if (isUniqueViolation(err)) {
115
+ return null;
116
+ }
117
+ throw err;
118
+ }
119
+ }
120
+ async getLatestSyncLog() {
121
+ const logs = await this.listPrintfulSyncLogs({}, { take: 1, order: { started_at: "DESC" } });
122
+ return logs[0] ?? null;
123
+ }
124
+ }
125
+ exports.default = PrintfulModuleService;
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3ByaW50ZnVsL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBa0JBLDhDQWVDO0FBakNELHFEQUF5RDtBQUN6RCxpRUFBNEQ7QUFFNUQsdUZBQTREO0FBQzVELDJGQUFnRTtBQUNoRSxtRkFBd0Q7QUFDeEQsMkZBQWdFO0FBSWhFLDhFQUE4RTtBQUNqRSxRQUFBLHlCQUF5QixHQUFHLFNBQVMsQ0FBQTtBQUVsRDs7OztHQUlHO0FBQ0gsU0FBZ0IsaUJBQWlCLENBQUMsR0FBWTtJQUM1QyxJQUFJLENBQUMsR0FBRyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUNELE1BQU0sQ0FBQyxHQUFHLEdBQTJELENBQUE7SUFDckUsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztJQUNELElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxLQUFLLFFBQVEsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ2pFLE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztJQUNELElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQy9CLE9BQU8saUJBQWlCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ25DLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQTtBQUNkLENBQUM7QUFFRCxNQUFNLHFCQUFzQixTQUFRLElBQUEscUJBQWEsRUFBQztJQUNoRCxtQkFBbUIsRUFBbkIsK0JBQW1CO0lBQ25CLG1CQUFtQixFQUFuQiwrQkFBbUI7SUFDbkIsZUFBZSxFQUFmLDJC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
@@ -0,0 +1,11 @@
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
+ const utils_1 = require("@medusajs/framework/utils");
7
+ const service_1 = __importDefault(require("./service"));
8
+ exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.FULFILLMENT, {
9
+ services: [service_1.default],
10
+ });
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3ByaW50ZnVsLWZ1bGZpbGxtZW50L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEscURBQW1FO0FBQ25FLHdEQUEwRDtBQUUxRCxrQkFBZSxJQUFBLHNCQUFjLEVBQUMsZUFBTyxDQUFDLFdBQVcsRUFBRTtJQUNqRCxRQUFRLEVBQUUsQ0FBQyxpQkFBa0MsQ0FBQztDQUMvQyxDQUFDLENBQUEifQ==
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("@medusajs/framework/utils");
4
+ const printful_client_1 = require("../../utils/printful-client");
5
+ class PrintfulFulfillmentProviderService extends utils_1.AbstractFulfillmentProviderService {
6
+ constructor(container, options) {
7
+ super();
8
+ this.logger_ = container.logger;
9
+ this.options_ = options || {};
10
+ if (!this.options_.apiToken) {
11
+ this.logger_.warn("Printful fulfillment provider: apiToken is missing from options");
12
+ }
13
+ this.client_ = new printful_client_1.PrintfulClient({
14
+ apiToken: this.options_.apiToken || "",
15
+ storeId: this.options_.storeId,
16
+ });
17
+ }
18
+ async getFulfillmentOptions() {
19
+ return [
20
+ {
21
+ id: "printful-standard",
22
+ name: "Printful Standard",
23
+ },
24
+ {
25
+ id: "printful-return",
26
+ name: "Printful Return",
27
+ is_return: true,
28
+ },
29
+ ];
30
+ }
31
+ async validateOption(data) {
32
+ return typeof data?.id === "string" || data?.id == null;
33
+ }
34
+ async validateFulfillmentData(optionData, data, _context) {
35
+ return {
36
+ ...data,
37
+ printful_option_id: optionData?.id ?? "printful-standard",
38
+ };
39
+ }
40
+ async canCalculate(_data) {
41
+ // Live rates are Phase 2
42
+ return false;
43
+ }
44
+ async calculatePrice(_optionData, _data, _context) {
45
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Printful fulfillment does not support calculated prices yet");
46
+ }
47
+ async createFulfillment(data, items, order, fulfillment) {
48
+ // Prefer order created by payment.captured subscriber; attach id if present.
49
+ const existingId = data?.printful_order_id ||
50
+ fulfillment?.metadata?.printful_order_id;
51
+ if (existingId) {
52
+ return {
53
+ data: {
54
+ ...(typeof data === "object" ? data : {}),
55
+ printful_order_id: existingId,
56
+ },
57
+ labels: [],
58
+ };
59
+ }
60
+ // Best-effort: if order has external printful mapping via metadata, reuse.
61
+ // Full auto-create is handled by create-printful-order workflow (subscriber).
62
+ this.logger_.info(`Printful fulfillment created for order ${order?.id ?? "unknown"} ` +
63
+ `(items: ${items?.length ?? 0}). Expect Printful order from payment.captured subscriber.`);
64
+ return {
65
+ data: {
66
+ ...(typeof data === "object" ? data : {}),
67
+ medusa_order_id: order?.id,
68
+ },
69
+ labels: [],
70
+ };
71
+ }
72
+ async cancelFulfillment(data) {
73
+ const printfulOrderId = data?.printful_order_id;
74
+ if (!printfulOrderId) {
75
+ return {};
76
+ }
77
+ try {
78
+ await this.client_.cancelOrder(printfulOrderId);
79
+ }
80
+ catch (err) {
81
+ this.logger_.error(`Failed to cancel Printful order ${printfulOrderId}: ${err instanceof Error ? err.message : String(err)}`);
82
+ }
83
+ return {};
84
+ }
85
+ async createReturnFulfillment(fulfillment) {
86
+ return {
87
+ data: {
88
+ ...fulfillment?.data,
89
+ is_return: true,
90
+ },
91
+ labels: [],
92
+ };
93
+ }
94
+ }
95
+ PrintfulFulfillmentProviderService.identifier = "printful";
96
+ exports.default = PrintfulFulfillmentProviderService;
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvcHJpbnRmdWwtZnVsZmlsbG1lbnQvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUdrQztBQVdsQyxpRUFBNEQ7QUFXNUQsTUFBTSxrQ0FBbUMsU0FBUSwwQ0FBa0M7SUFPakYsWUFBWSxTQUErQixFQUFFLE9BQThCO1FBQ3pFLEtBQUssRUFBRSxDQUFBO1FBQ1AsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFBO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxJQUFLLEVBQTRCLENBQUE7UUFFeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ2YsaUVBQWlFLENBQ2xFLENBQUE7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGdDQUFjLENBQUM7WUFDaEMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLEVBQUU7WUFDdEMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTztTQUMvQixDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLHFCQUFxQjtRQUN6QixPQUFPO1lBQ0w7Z0JBQ0UsRUFBRSxFQUFFLG1CQUFtQjtnQkFDdkIsSUFBSSxFQUFFLG1CQUFtQjthQUMxQjtZQUNEO2dCQUNFLEVBQUUsRUFBRSxpQkFBaUI7Z0JBQ3JCLElBQUksRUFBRSxpQkFBaUI7Z0JBQ3ZCLFNBQVMsRUFBRSxJQUFJO2FBQ2hCO1NBQ0YsQ0FBQTtJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsY0FBYyxDQUFDLElBQTZCO1FBQ2hELE9BQU8sT0FBTyxJQUFJLEVBQUUsRUFBRSxLQUFLLFFBQVEsSUFBSSxJQUFJLEVBQUUsRUFB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
@@ -0,0 +1,37 @@
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.config = void 0;
7
+ exports.default = orderPlacedHandler;
8
+ const printful_1 = require("../modules/printful");
9
+ const create_printful_order_1 = __importDefault(require("../workflows/create-printful-order"));
10
+ /**
11
+ * Optional path for capture-on-place stores.
12
+ * Enabled when plugin option createOnOrderPlaced is true.
13
+ */
14
+ async function orderPlacedHandler({ event: { data }, container, }) {
15
+ const printful = container.resolve(printful_1.PRINTFUL_MODULE);
16
+ const options = await printful.getOptions();
17
+ if (!options.createOnOrderPlaced) {
18
+ return;
19
+ }
20
+ const orderId = data.id;
21
+ if (!orderId) {
22
+ return;
23
+ }
24
+ try {
25
+ await (0, create_printful_order_1.default)(container).run({
26
+ input: { order_id: orderId },
27
+ });
28
+ }
29
+ catch (err) {
30
+ const logger = container.resolve("logger");
31
+ logger.error(`Printful: failed to create order on place for ${orderId}: ${err instanceof Error ? err.message : String(err)}`);
32
+ }
33
+ }
34
+ exports.config = {
35
+ event: "order.placed",
36
+ };
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JkZXItcGxhY2VkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3N1YnNjcmliZXJzL29yZGVyLXBsYWNlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFTQSxxQ0E4QkM7QUF0Q0Qsa0RBQXFEO0FBRXJELCtGQUE0RTtBQUU1RTs7O0dBR0c7QUFDWSxLQUFLLFVBQVUsa0JBQWtCLENBQUMsRUFDL0MsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQ2YsU0FBUyxHQUNzQjtJQUMvQixNQUFNLFFBQVEsR0FBMEIsU0FBUyxDQUFDLE9BQU8sQ0FBQywwQkFBZSxDQUFDLENBQUE7SUFDMUUsTUFBTSxPQUFPLEdBQUcsTUFBTSxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUE7SUFFM0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ2pDLE9BQU07SUFDUixDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQTtJQUN2QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixPQUFNO0lBQ1IsQ0FBQztJQUVELElBQUksQ0FBQztRQUNILE1BQU0sSUFBQSwrQkFBMkIsRUFBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDL0MsS0FBSyxFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRTtTQUM3QixDQUFDLENBQUE7SUFDSixDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUV4QyxDQUFBO1FBQ0QsTUFBTSxDQUFDLEtBQUssQ0FDVixpREFBaUQsT0FBTyxLQUN0RCxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNqRCxFQUFFLENBQ0gsQ0FBQTtJQUNILENBQUM7QUFDSCxDQUFDO0FBRVksUUFBQSxNQUFNLEdBQXFCO0lBQ3RDLEtBQUssRUFBRSxjQUFjO0NBQ3RCLENBQUEifQ==
@@ -0,0 +1,61 @@
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.config = void 0;
7
+ exports.default = paymentCapturedHandler;
8
+ const utils_1 = require("@medusajs/framework/utils");
9
+ const create_printful_order_1 = __importDefault(require("../workflows/create-printful-order"));
10
+ /**
11
+ * Primary path: create Printful order when payment is captured.
12
+ * Event payload is `{ id: payment_id }` — resolve order via payment collection.
13
+ * Idempotent via PrintfulOrderLink.
14
+ */
15
+ async function paymentCapturedHandler({ event: { data }, container, }) {
16
+ const paymentId = data.id;
17
+ if (!paymentId) {
18
+ return;
19
+ }
20
+ const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
21
+ try {
22
+ const orderId = await resolveOrderIdFromPayment(container, paymentId);
23
+ if (!orderId) {
24
+ logger.error(`Printful: could not resolve order for payment ${paymentId}`);
25
+ return;
26
+ }
27
+ await (0, create_printful_order_1.default)(container).run({
28
+ input: { order_id: orderId },
29
+ });
30
+ }
31
+ catch (err) {
32
+ logger.error(`Printful: failed to create order for payment ${paymentId}: ${err instanceof Error ? err.message : String(err)}`);
33
+ }
34
+ }
35
+ async function resolveOrderIdFromPayment(container, paymentId) {
36
+ const paymentModule = container.resolve(utils_1.Modules.PAYMENT);
37
+ const payment = await paymentModule.retrievePayment(paymentId);
38
+ const collectionId = payment.payment_collection_id;
39
+ if (!collectionId) {
40
+ return null;
41
+ }
42
+ const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
43
+ const { data } = await query.graph({
44
+ entity: "order_payment_collection",
45
+ fields: ["order_id", "order.id"],
46
+ filters: {
47
+ payment_collection_id: collectionId,
48
+ },
49
+ });
50
+ const row = Array.isArray(data) ? data[0] : data;
51
+ if (!row) {
52
+ return null;
53
+ }
54
+ return (row.order_id ||
55
+ row.order?.id ||
56
+ null);
57
+ }
58
+ exports.config = {
59
+ event: "payment.captured",
60
+ };
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF5bWVudC1jYXB0dXJlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zdWJzY3JpYmVycy9wYXltZW50LWNhcHR1cmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQVVBLHlDQWlDQztBQXpDRCxxREFBOEU7QUFDOUUsK0ZBQTRFO0FBRTVFOzs7O0dBSUc7QUFDWSxLQUFLLFVBQVUsc0JBQXNCLENBQUMsRUFDbkQsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQ2YsU0FBUyxHQUNzQjtJQUMvQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFBO0lBQ3pCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNmLE9BQU07SUFDUixDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxNQUFNLENBR2hFLENBQUE7SUFFRCxJQUFJLENBQUM7UUFDSCxNQUFNLE9BQU8sR0FBRyxNQUFNLHlCQUF5QixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQTtRQUNyRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixNQUFNLENBQUMsS0FBSyxDQUNWLGlEQUFpRCxTQUFTLEVBQUUsQ0FDN0QsQ0FBQTtZQUNELE9BQU07UUFDUixDQUFDO1FBRUQsTUFBTSxJQUFBLCtCQUEyQixFQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUMvQyxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFO1NBQzdCLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FDVixnREFBZ0QsU0FBUyxLQUN2RCxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNqRCxFQUFFLENBQ0gsQ0FBQTtJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQsS0FBSyxVQUFVLHlCQUF5QixDQUN0QyxTQUEwQixFQUMxQixTQUFpQjtJQUVqQixNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUN4RCxNQUFNLE9BQU8sR0FBRyxNQUFNLGFBQWEsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDOUQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLHFCQUEyQyxDQUFBO0lBQ3hFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNsQixPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2hFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDakMsTUFBTSxFQUFFLDBCQUEwQjtRQUNsQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHFCQUFxQixFQUFFLFlBQVk7U0FDcEM7S0FDRixDQUFDLENBQUE7SUFFRixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtJQUNoRCxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDVCxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRCxPQUFPLENBQ0osR0FBc0QsQ0FBQyxRQUFRO1FBQy9ELEdBQW1DLENBQUMsS0FBSyxFQUFFLEVBQUU7UUFDOUMsSUFBSSxDQUNMLENBQUE7QUFDSCxDQUFDO0FBRVksUUFBQSxNQUFNLEdBQXFCO0lBQ3RDLEtBQUssRUFBRSxrQkFBa0I7Q0FDMUIsQ0FBQSJ9
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrintfulConfigError = exports.PrintfulApiError = void 0;
4
+ class PrintfulApiError extends Error {
5
+ constructor(message, options) {
6
+ super(message);
7
+ this.name = "PrintfulApiError";
8
+ this.status = options.status;
9
+ this.reason = options.reason;
10
+ this.body = options.body;
11
+ }
12
+ get isRetryable() {
13
+ return this.status === 429 || this.status >= 500;
14
+ }
15
+ }
16
+ exports.PrintfulApiError = PrintfulApiError;
17
+ class PrintfulConfigError extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "PrintfulConfigError";
21
+ }
22
+ }
23
+ exports.PrintfulConfigError = PrintfulConfigError;
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFhLGdCQUFpQixTQUFRLEtBQUs7SUFLekMsWUFDRSxPQUFlLEVBQ2YsT0FBNEQ7UUFFNUQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2QsSUFBSSxDQUFDLElBQUksR0FBRyxrQkFBa0IsQ0FBQTtRQUM5QixJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUE7UUFDNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFBO1FBQzVCLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQTtJQUMxQixDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQTtJQUNsRCxDQUFDO0NBQ0Y7QUFuQkQsNENBbUJDO0FBRUQsTUFBYSxtQkFBb0IsU0FBUSxLQUFLO0lBQzVDLFlBQVksT0FBZTtRQUN6QixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDZCxJQUFJLENBQUMsSUFBSSxHQUFHLHFCQUFxQixDQUFBO0lBQ25DLENBQUM7Q0FDRjtBQUxELGtEQUtDIn0=
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./errors"), exports);
18
+ __exportStar(require("./mappers"), exports);
19
+ __exportStar(require("./printful-client"), exports);
20
+ __exportStar(require("./types"), exports);
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUF3QjtBQUN4Qiw0Q0FBeUI7QUFDekIsb0RBQWlDO0FBQ2pDLDBDQUF1QiJ9