@jytextiles/medusa-plugin-faire-store-sync 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/__tests__/faire-client.spec.js +124 -7
- package/.medusa/server/src/__tests__/ingest-faire-order-support.spec.js +61 -1
- package/.medusa/server/src/admin/index.js +167 -137
- package/.medusa/server/src/admin/index.mjs +168 -138
- package/.medusa/server/src/api/admin/faire/status/route.js +4 -2
- package/.medusa/server/src/api/admin/faire/taxonomy/route.js +12 -0
- package/.medusa/server/src/lib/faire-client.js +120 -18
- package/.medusa/server/src/lib/types.js +6 -2
- package/.medusa/server/src/modules/faire-sync/service.js +18 -3
- package/.medusa/server/src/workflows/ingest-faire-order-support.js +81 -28
- package/.medusa/server/src/workflows/sync-product-to-faire.js +108 -37
- package/package.json +1 -1
- package/src/__tests__/faire-client.spec.ts +135 -6
- package/src/__tests__/ingest-faire-order-support.spec.ts +63 -0
- package/src/admin/lib/api.ts +4 -0
- package/src/admin/routes/settings/faire/[id]/page.tsx +56 -61
- package/src/admin/routes/settings/faire/settings/page.tsx +62 -13
- package/src/api/admin/faire/status/route.ts +3 -1
- package/src/api/admin/faire/taxonomy/route.ts +10 -0
- package/src/lib/faire-client.ts +139 -16
- package/src/lib/types.ts +57 -18
- package/src/modules/faire-sync/service.ts +23 -2
- package/src/workflows/ingest-faire-order-support.ts +96 -29
- package/src/workflows/sync-product-to-faire.ts +146 -42
|
@@ -16,6 +16,27 @@ const productDisplayUrl = (product) => {
|
|
|
16
16
|
return null;
|
|
17
17
|
return `https://www.faire.com/brand/products/${product.product_token}`;
|
|
18
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Faire variant prices are geo-scoped (`geo_constraint`). Derive a sensible
|
|
21
|
+
* default from the brand's currency (and country when known). Eurozone brands
|
|
22
|
+
* map to the EUROPEAN_UNION country_group; otherwise scope to a single country.
|
|
23
|
+
*/
|
|
24
|
+
const geoForCurrency = (currency, country) => {
|
|
25
|
+
switch (currency) {
|
|
26
|
+
case "EUR":
|
|
27
|
+
return { country_group: "EUROPEAN_UNION" };
|
|
28
|
+
case "GBP":
|
|
29
|
+
return { country: "GB" };
|
|
30
|
+
case "USD":
|
|
31
|
+
return { country: "US" };
|
|
32
|
+
case "CAD":
|
|
33
|
+
return { country: "CA" };
|
|
34
|
+
case "AUD":
|
|
35
|
+
return { country: "AU" };
|
|
36
|
+
default:
|
|
37
|
+
return country ? { country } : { country_group: "EUROPEAN_UNION" };
|
|
38
|
+
}
|
|
39
|
+
};
|
|
19
40
|
// ── Step 1: resolve account (fresh token) + settings ─────────────────────
|
|
20
41
|
const resolveFaireConfigStep = (0, workflows_sdk_1.createStep)("faire-resolve-config-step", async (_, { container }) => {
|
|
21
42
|
const service = container.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
@@ -27,6 +48,7 @@ const resolveFaireConfigStep = (0, workflows_sdk_1.createStep)("faire-resolve-co
|
|
|
27
48
|
access_token: account.access_token,
|
|
28
49
|
auth_mode: account.auth_mode ?? "oauth",
|
|
29
50
|
currency: account.currency ?? null,
|
|
51
|
+
country: account.country ?? null,
|
|
30
52
|
settings,
|
|
31
53
|
});
|
|
32
54
|
});
|
|
@@ -46,6 +68,8 @@ const prepareProductStep = (0, workflows_sdk_1.createStep)("faire-prepare-produc
|
|
|
46
68
|
"tags.*",
|
|
47
69
|
"variants.*",
|
|
48
70
|
"variants.prices.*",
|
|
71
|
+
"variants.options.*",
|
|
72
|
+
"variants.options.option.*",
|
|
49
73
|
"variants.inventory_items.*",
|
|
50
74
|
"images.*",
|
|
51
75
|
"variants.sku",
|
|
@@ -54,7 +78,7 @@ const prepareProductStep = (0, workflows_sdk_1.createStep)("faire-prepare-produc
|
|
|
54
78
|
});
|
|
55
79
|
const product = products?.[0];
|
|
56
80
|
if (!product) {
|
|
57
|
-
throw new
|
|
81
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Product ${input.product_id} not found`);
|
|
58
82
|
}
|
|
59
83
|
// Resolve existing Faire product (from link)
|
|
60
84
|
let existing_product_token = null;
|
|
@@ -75,53 +99,94 @@ const prepareProductStep = (0, workflows_sdk_1.createStep)("faire-prepare-produc
|
|
|
75
99
|
const settings = input.settings;
|
|
76
100
|
const metadata = product.metadata || {};
|
|
77
101
|
const variants = product.variants || [];
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
|
|
102
|
+
// ── Currency + geo constraint (Faire prices are geo-scoped) ────────────
|
|
103
|
+
// Prefer the brand's own currency; fall back to the price currency Medusa
|
|
104
|
+
// stored, then EUR. Currency picks the price row + drives the geo default.
|
|
105
|
+
const currency = String(metadata.faire_currency ||
|
|
106
|
+
input.currency ||
|
|
107
|
+
(variants.flatMap((v) => v.prices || [])[0]?.currency_code ?? "EUR")).toUpperCase();
|
|
108
|
+
const geoConstraint = metadata.faire_geo_constraint && typeof metadata.faire_geo_constraint === "object"
|
|
109
|
+
? metadata.faire_geo_constraint
|
|
110
|
+
: geoForCurrency(currency, input.country);
|
|
111
|
+
// Medusa v2 stores money as a whole decimal in the price's currency; Faire
|
|
112
|
+
// wants integer minor units (cents), so round.
|
|
113
|
+
const toMinor = (amount) => Math.round(Number(amount || 0) * 100);
|
|
81
114
|
const markupPercent = Number(metadata.faire_wholesale_markup_percent ?? settings.default_wholesale_markup_percent) ||
|
|
82
115
|
0;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
116
|
+
// Pick the price row matching the chosen currency (fall back to first).
|
|
117
|
+
const pickPrice = (prices) => prices.find((p) => String(p.currency_code || "").toUpperCase() === currency) ??
|
|
118
|
+
prices[0] ??
|
|
119
|
+
null;
|
|
120
|
+
const buildVariant = (v, idx) => {
|
|
121
|
+
const retail = pickPrice(v.prices || []);
|
|
122
|
+
const retailMinor = retail ? toMinor(retail.amount) : 0;
|
|
123
|
+
const wholesaleMinor = markupPercent > 0
|
|
124
|
+
? Math.round((retailMinor * (100 - markupPercent)) / 100)
|
|
125
|
+
: retailMinor;
|
|
126
|
+
const sku = v.sku || v.id;
|
|
127
|
+
const options = (v.options || [])
|
|
128
|
+
.map((o) => ({
|
|
129
|
+
name: String(o.option?.title || o.title || "Option"),
|
|
130
|
+
value: String(o.value ?? ""),
|
|
131
|
+
}))
|
|
132
|
+
.filter((o) => o.value) || [];
|
|
90
133
|
return {
|
|
91
|
-
sku
|
|
92
|
-
name: v.title ||
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
134
|
+
sku,
|
|
135
|
+
name: v.title || sku,
|
|
136
|
+
idempotence_token: `${product.id}:${v.id || sku}`,
|
|
137
|
+
options: options.length ? options : undefined,
|
|
138
|
+
available_quantity: Number(v.inventory_quantity) || 0,
|
|
139
|
+
prices: retailMinor > 0
|
|
140
|
+
? [
|
|
141
|
+
{
|
|
142
|
+
geo_constraint: geoConstraint,
|
|
143
|
+
wholesale_price: { amount_minor: wholesaleMinor, currency },
|
|
144
|
+
retail_price: { amount_minor: retailMinor, currency },
|
|
145
|
+
},
|
|
146
|
+
]
|
|
147
|
+
: undefined,
|
|
96
148
|
};
|
|
97
149
|
};
|
|
98
|
-
// Aggregate retail/wholesale from min-variant for the product-level price.
|
|
99
|
-
const allPrices = variants.flatMap((v) => v.prices || []);
|
|
100
|
-
const minRetail = allPrices
|
|
101
|
-
.map((p) => toCents(p.amount))
|
|
102
|
-
.filter((a) => a > 0)
|
|
103
|
-
.sort((a, b) => a - b)[0] ?? 0;
|
|
104
|
-
const minWholesale = markupPercent > 0
|
|
105
|
-
? Math.round((minRetail * (100 - markupPercent)) / 100)
|
|
106
|
-
: minRetail;
|
|
107
|
-
const tags = (product.tags || [])
|
|
108
|
-
.map((t) => t.value)
|
|
109
|
-
.filter(Boolean);
|
|
110
150
|
const images = (product.images || [])
|
|
111
151
|
.map((img) => ({ url: img.url }))
|
|
112
152
|
.filter((i) => i.url);
|
|
153
|
+
// Resolve taxonomy_type.id — REQUIRED by Faire create. Priority:
|
|
154
|
+
// product.metadata.faire_taxonomy_type_id (tt_… or a category name)
|
|
155
|
+
// → settings.default_category (id or name) → error.
|
|
156
|
+
const client = service.getClient(input.auth_mode);
|
|
157
|
+
const categoryHint = metadata.faire_taxonomy_type_id ||
|
|
158
|
+
metadata.faire_category ||
|
|
159
|
+
settings.default_category ||
|
|
160
|
+
"";
|
|
161
|
+
const taxonomyTypeId = await client.resolveTaxonomyTypeId(input.access_token, String(categoryHint));
|
|
162
|
+
if (!taxonomyTypeId) {
|
|
163
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Faire requires a product category (taxonomy_type). Set a Faire " +
|
|
164
|
+
"category in sync settings (default_category) or on the product " +
|
|
165
|
+
"(metadata.faire_taxonomy_type_id — a `tt_…` id or a category name).");
|
|
166
|
+
}
|
|
167
|
+
const lifecycle_state = settings.follow_product_status !== false && product.status === "published"
|
|
168
|
+
? "PUBLISHED"
|
|
169
|
+
: "DRAFT";
|
|
170
|
+
const builtVariants = (variants.length ? variants : [null]).map((v, i) => v
|
|
171
|
+
? buildVariant(v, i)
|
|
172
|
+
: {
|
|
173
|
+
// Single-variant fallback for products with no explicit variants.
|
|
174
|
+
sku: product.id,
|
|
175
|
+
name: product.title || "Default",
|
|
176
|
+
idempotence_token: `${product.id}:default`,
|
|
177
|
+
available_quantity: 0,
|
|
178
|
+
});
|
|
113
179
|
const product_input = {
|
|
114
|
-
brand_id: input.brand_id,
|
|
115
180
|
name: (product.title || "Untitled Product").slice(0, 140),
|
|
181
|
+
idempotence_token: product.id,
|
|
182
|
+
lifecycle_state,
|
|
183
|
+
taxonomy_type: { id: taxonomyTypeId },
|
|
116
184
|
description: product.description || "",
|
|
117
|
-
wholesale_price_cents: minWholesale || undefined,
|
|
118
|
-
retail_price_cents: minRetail || undefined,
|
|
119
|
-
images,
|
|
120
|
-
variants: variants.length ? variants.map(buildVariant) : undefined,
|
|
121
|
-
tags,
|
|
122
185
|
short_description: typeof metadata.faire_short_description === "string"
|
|
123
186
|
? metadata.faire_short_description
|
|
124
187
|
: undefined,
|
|
188
|
+
images,
|
|
189
|
+
variants: builtVariants,
|
|
125
190
|
};
|
|
126
191
|
return new workflows_sdk_1.StepResponse({
|
|
127
192
|
product_id: input.product_id,
|
|
@@ -144,9 +209,11 @@ const syncProductStep = (0, workflows_sdk_1.createStep)("faire-sync-product-step
|
|
|
144
209
|
product = await client.updateProduct(access_token, existing_product_token, {
|
|
145
210
|
name: product_input.name,
|
|
146
211
|
description: product_input.description,
|
|
212
|
+
short_description: product_input.short_description,
|
|
213
|
+
lifecycle_state: product_input.lifecycle_state,
|
|
214
|
+
taxonomy_type: product_input.taxonomy_type,
|
|
147
215
|
images: product_input.images,
|
|
148
216
|
variants: product_input.variants,
|
|
149
|
-
tags: product_input.tags,
|
|
150
217
|
});
|
|
151
218
|
}
|
|
152
219
|
else {
|
|
@@ -163,7 +230,7 @@ const syncProductStep = (0, workflows_sdk_1.createStep)("faire-sync-product-step
|
|
|
163
230
|
try {
|
|
164
231
|
const levels = product_input.variants.map((v) => ({
|
|
165
232
|
sku: v.sku,
|
|
166
|
-
|
|
233
|
+
on_hand_quantity: v.available_quantity ?? 0,
|
|
167
234
|
}));
|
|
168
235
|
await client.updateInventory(access_token, levels);
|
|
169
236
|
}
|
|
@@ -242,6 +309,10 @@ exports.syncProductToFaireWorkflow = (0, workflows_sdk_1.createWorkflow)(exports
|
|
|
242
309
|
product_id: data.input.product_id,
|
|
243
310
|
settings: data.config.settings,
|
|
244
311
|
brand_id: data.config.brand_id,
|
|
312
|
+
currency: data.config.currency,
|
|
313
|
+
country: data.config.country,
|
|
314
|
+
access_token: data.config.access_token,
|
|
315
|
+
auth_mode: data.config.auth_mode,
|
|
245
316
|
})));
|
|
246
317
|
const result = syncProductStep((0, workflows_sdk_1.transform)({ config, prepared }, (data) => ({
|
|
247
318
|
config: data.config,
|
|
@@ -260,4 +331,4 @@ exports.syncProductToFaireWorkflow = (0, workflows_sdk_1.createWorkflow)(exports
|
|
|
260
331
|
warnings: result.warnings,
|
|
261
332
|
});
|
|
262
333
|
});
|
|
263
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1wcm9kdWN0LXRvLWZhaXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zeW5jLXByb2R1Y3QtdG8tZmFpcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBTzBDO0FBQzFDLHFEQUE4RTtBQUc5RSxzREFBeUQ7QUFPNUMsUUFBQSxxQkFBcUIsR0FBRyxvQkFBb0IsQ0FBQTtBQTZCekQ7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE9BQXdCLEVBQWlCLEVBQUU7SUFDcEUsSUFBSSxPQUFPLENBQUMsR0FBRztRQUFFLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQTtJQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWE7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUN2QyxPQUFPLHdDQUF3QyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUE7QUFDeEUsQ0FBQyxDQUFBO0FBRUQsNEVBQTRFO0FBRTVFLE1BQU0sc0JBQXNCLEdBQUcsSUFBQSwwQkFBVSxFQUN2QywyQkFBMkIsRUFDM0IsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUF5QyxFQUFFO0lBQ2hFLE1BQU0sT0FBTyxHQUFxQixTQUFTLENBQUMsT0FBTyxDQUFDLDhCQUFpQixDQUFDLENBQUE7SUFDdEUsTUFBTSxPQUFPLEdBQUcsTUFBTSxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtJQUNoRCxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUM1QyxPQUFPLElBQUksNEJBQVksQ0FBQztRQUN0QixVQUFVLEVBQUUsT0FBTyxDQUFDLEVBQUU7UUFDdEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1FBQzFCLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtRQUNsQyxTQUFTLEVBQUcsT0FBTyxDQUFDLFNBQWdDLElBQUksT0FBTztRQUMvRCxRQUFRLEVB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
|
|
334
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1wcm9kdWN0LXRvLWZhaXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9zeW5jLXByb2R1Y3QtdG8tZmFpcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBTzBDO0FBQzFDLHFEQUEyRjtBQUczRixzREFBeUQ7QUFPNUMsUUFBQSxxQkFBcUIsR0FBRyxvQkFBb0IsQ0FBQTtBQThCekQ7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE9BQXdCLEVBQWlCLEVBQUU7SUFDcEUsSUFBSSxPQUFPLENBQUMsR0FBRztRQUFFLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQTtJQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWE7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUN2QyxPQUFPLHdDQUF3QyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUE7QUFDeEUsQ0FBQyxDQUFBO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLENBQ3JCLFFBQWdCLEVBQ2hCLE9BQXNCLEVBQ3dCLEVBQUU7SUFDaEQsUUFBUSxRQUFRLEVBQUUsQ0FBQztRQUNqQixLQUFLLEtBQUs7WUFDUixPQUFPLEVBQUUsYUFBYSxFQUFFLGdCQUFnQixFQUFFLENBQUE7UUFDNUMsS0FBSyxLQUFLO1lBQ1IsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQTtRQUMxQixLQUFLLEtBQUs7WUFDUixPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFBO1FBQzFCLEtBQUssS0FBSztZQUNSLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUE7UUFDMUIsS0FBSyxLQUFLO1lBQ1IsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQTtRQUMxQjtZQUNFLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLGFB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
|
package/package.json
CHANGED
|
@@ -15,6 +15,15 @@ const fetchMock = jest.fn(async (url: string, init: any) => {
|
|
|
15
15
|
} as any
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
+
// Shared taxonomy types fixture (matches the shape Faire returns).
|
|
19
|
+
const taxonomyTypes = [
|
|
20
|
+
{ id: "tt_1", name: "Apparel" },
|
|
21
|
+
{ id: "tt_2", name: "Accessories" },
|
|
22
|
+
{ id: "tt_3", name: "Home & Living" },
|
|
23
|
+
{ id: "tt_4", name: "Dresses" },
|
|
24
|
+
{ id: "tt_5", name: "Address Book" },
|
|
25
|
+
]
|
|
26
|
+
|
|
18
27
|
;(global as any).fetch = fetchMock
|
|
19
28
|
|
|
20
29
|
const oauthOpts = {
|
|
@@ -30,7 +39,7 @@ describe("FaireClient — issue #952 corrections", () => {
|
|
|
30
39
|
it("uses the verified base / auth / token URLs by default", () => {
|
|
31
40
|
const c = new FaireClient({})
|
|
32
41
|
// defaults are exported from types and consumed verbatim
|
|
33
|
-
expect(DEFAULT_API_BASE).toBe("https://faire.com/external-api/v2")
|
|
42
|
+
expect(DEFAULT_API_BASE).toBe("https://www.faire.com/external-api/v2")
|
|
34
43
|
expect(DEFAULT_AUTH_URL).toBe("https://faire.com/oauth2/authorize")
|
|
35
44
|
expect(DEFAULT_TOKEN_URL).toBe("https://www.faire.com/api/external-api-oauth2/token")
|
|
36
45
|
})
|
|
@@ -94,23 +103,45 @@ describe("FaireClient — issue #952 corrections", () => {
|
|
|
94
103
|
|
|
95
104
|
it("pushes inventory via PATCH /product-inventory/by-skus (not GET /inventory)", async () => {
|
|
96
105
|
const c = new FaireClient(oauthOpts)
|
|
97
|
-
await c.updateInventory("t", [{ sku: "S1",
|
|
106
|
+
await c.updateInventory("t", [{ sku: "S1", on_hand_quantity: 7 }])
|
|
98
107
|
expect(lastInit.method).toBe("PATCH")
|
|
99
108
|
expect(lastUrl).toBe(`${DEFAULT_API_BASE}/product-inventory/by-skus`)
|
|
100
109
|
expect(JSON.parse(lastInit.body)).toEqual({
|
|
101
|
-
inventories: [{ sku: "S1",
|
|
110
|
+
inventories: [{ sku: "S1", on_hand_quantity: 7 }],
|
|
102
111
|
})
|
|
103
112
|
})
|
|
104
113
|
|
|
105
|
-
it("lists orders with
|
|
114
|
+
it("lists orders with numeric page + updated_at_min", async () => {
|
|
106
115
|
const c = new FaireClient(oauthOpts)
|
|
107
|
-
await c.listOrders("t", { page: "
|
|
116
|
+
await c.listOrders("t", { page: "2", updated_at_min: "2026-01-01T00:00:00Z" })
|
|
108
117
|
const url = new URL(lastUrl)
|
|
109
118
|
expect(url.pathname).toBe("/external-api/v2/orders")
|
|
110
|
-
expect(url.searchParams.get("page")).toBe("
|
|
119
|
+
expect(url.searchParams.get("page")).toBe("2")
|
|
111
120
|
expect(url.searchParams.get("updated_at_min")).toBe("2026-01-01T00:00:00Z")
|
|
112
121
|
})
|
|
113
122
|
|
|
123
|
+
it("derives next_page from numeric page (Faire returns no cursor)", async () => {
|
|
124
|
+
const c = new FaireClient(oauthOpts)
|
|
125
|
+
const page = (rows: number) => ({
|
|
126
|
+
ok: true,
|
|
127
|
+
status: 200,
|
|
128
|
+
headers: new Map(),
|
|
129
|
+
text: async () =>
|
|
130
|
+
JSON.stringify({
|
|
131
|
+
page: undefined,
|
|
132
|
+
orders: Array.from({ length: rows }, (_, i) => ({ id: `bo_${i}` })),
|
|
133
|
+
}),
|
|
134
|
+
})
|
|
135
|
+
// A full page (rows === limit) → there may be more → next_page = current+1.
|
|
136
|
+
fetchMock.mockImplementationOnce(async () => page(2) as any)
|
|
137
|
+
const full = await c.listOrders("t", { limit: 2, page: "1" })
|
|
138
|
+
expect(full.next_page).toBe("2")
|
|
139
|
+
// A short page → last page → no next_page.
|
|
140
|
+
fetchMock.mockImplementationOnce(async () => page(1) as any)
|
|
141
|
+
const short = await c.listOrders("t", { limit: 2, page: "2" })
|
|
142
|
+
expect(short.next_page).toBeUndefined()
|
|
143
|
+
})
|
|
144
|
+
|
|
114
145
|
it("posts order processing (PUT) and shipments (POST) on the right paths", async () => {
|
|
115
146
|
const c = new FaireClient(oauthOpts)
|
|
116
147
|
await c.setOrderProcessing("t", "o_1", { accepted: true })
|
|
@@ -136,3 +167,101 @@ describe("FaireClient — issue #952 corrections", () => {
|
|
|
136
167
|
})
|
|
137
168
|
})
|
|
138
169
|
})
|
|
170
|
+
|
|
171
|
+
describe("FaireClient.resolveTaxonomyTypeId", () => {
|
|
172
|
+
beforeEach(() => {
|
|
173
|
+
fetchMock.mockClear()
|
|
174
|
+
// Reset the cache on each test by creating a fresh client.
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it("passes a tt_ id straight through without an API call", async () => {
|
|
178
|
+
const c = new FaireClient(oauthOpts)
|
|
179
|
+
const result = await c.resolveTaxonomyTypeId("tok", "tt_abc123")
|
|
180
|
+
expect(result).toBe("tt_abc123")
|
|
181
|
+
expect(fetchMock).not.toHaveBeenCalled()
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it("returns null for empty / falsy input", async () => {
|
|
185
|
+
const c = new FaireClient(oauthOpts)
|
|
186
|
+
await expect(c.resolveTaxonomyTypeId("tok", "")).resolves.toBeNull()
|
|
187
|
+
await expect(c.resolveTaxonomyTypeId("tok", "")).resolves.toBeNull()
|
|
188
|
+
expect(fetchMock).not.toHaveBeenCalled()
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
it("fetches taxonomy types on first call, caches, and resolves by exact name", async () => {
|
|
192
|
+
fetchMock.mockImplementationOnce(async () => ({
|
|
193
|
+
ok: true,
|
|
194
|
+
status: 200,
|
|
195
|
+
headers: new Map(),
|
|
196
|
+
text: async () => JSON.stringify({ taxonomy_types: taxonomyTypes }),
|
|
197
|
+
} as any))
|
|
198
|
+
const c = new FaireClient(oauthOpts)
|
|
199
|
+
const result = await c.resolveTaxonomyTypeId("tok", "Dresses")
|
|
200
|
+
expect(result).toBe("tt_4")
|
|
201
|
+
expect(fetchMock).toHaveBeenCalledTimes(1)
|
|
202
|
+
const callUrl = fetchMock.mock.calls[0][0] as string
|
|
203
|
+
expect(callUrl).toContain("/products/types")
|
|
204
|
+
|
|
205
|
+
// Second call uses the cache — no additional fetch.
|
|
206
|
+
const cached = await c.resolveTaxonomyTypeId("tok", "Accessories")
|
|
207
|
+
expect(cached).toBe("tt_2")
|
|
208
|
+
expect(fetchMock).toHaveBeenCalledTimes(1)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it("prefers whole-word match over loose substring (Dress vs Address Book)", async () => {
|
|
212
|
+
fetchMock.mockImplementationOnce(async () => ({
|
|
213
|
+
ok: true,
|
|
214
|
+
status: 200,
|
|
215
|
+
headers: new Map(),
|
|
216
|
+
text: async () => JSON.stringify({ taxonomy_types: taxonomyTypes }),
|
|
217
|
+
} as any))
|
|
218
|
+
const c = new FaireClient(oauthOpts)
|
|
219
|
+
// "Dress" should match "Dresses" (word-boundary) not "Address Book".
|
|
220
|
+
const result = await c.resolveTaxonomyTypeId("tok", "Dress")
|
|
221
|
+
expect(result).toBe("tt_4")
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
it("falls back to substring match when whole-word finds nothing", async () => {
|
|
225
|
+
fetchMock.mockImplementationOnce(async () => ({
|
|
226
|
+
ok: true,
|
|
227
|
+
status: 200,
|
|
228
|
+
headers: new Map(),
|
|
229
|
+
text: async () => JSON.stringify({ taxonomy_types: taxonomyTypes }),
|
|
230
|
+
} as any))
|
|
231
|
+
const c = new FaireClient(oauthOpts)
|
|
232
|
+
// "ccessori" is not a whole word but a substring of "Accessories".
|
|
233
|
+
const result = await c.resolveTaxonomyTypeId("tok", "ccessori")
|
|
234
|
+
expect(result).toBe("tt_2")
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
it("returns null when no taxonomy type matches — the condition that triggers the MedusaError", async () => {
|
|
238
|
+
fetchMock.mockImplementationOnce(async () => ({
|
|
239
|
+
ok: true,
|
|
240
|
+
status: 200,
|
|
241
|
+
headers: new Map(),
|
|
242
|
+
text: async () => JSON.stringify({ taxonomy_types: taxonomyTypes }),
|
|
243
|
+
} as any))
|
|
244
|
+
const c = new FaireClient(oauthOpts)
|
|
245
|
+
const result = await c.resolveTaxonomyTypeId("tok", "NonExistentCategory")
|
|
246
|
+
expect(result).toBeNull()
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
it("handles alternate response shapes (product_types / types / results)", async () => {
|
|
250
|
+
for (const key of ["product_types", "types", "results"]) {
|
|
251
|
+
fetchMock.mockImplementationOnce(async () => ({
|
|
252
|
+
ok: true,
|
|
253
|
+
status: 200,
|
|
254
|
+
headers: new Map(),
|
|
255
|
+
text: async () => JSON.stringify({ [key]: taxonomyTypes }),
|
|
256
|
+
} as any))
|
|
257
|
+
}
|
|
258
|
+
const c = new FaireClient(oauthOpts)
|
|
259
|
+
// Each call should reset the cache because we used a fresh client.
|
|
260
|
+
const c1 = new FaireClient(oauthOpts)
|
|
261
|
+
expect(await c1.resolveTaxonomyTypeId("tok", "Apparel")).toBe("tt_1")
|
|
262
|
+
const c2 = new FaireClient(oauthOpts)
|
|
263
|
+
expect(await c2.resolveTaxonomyTypeId("tok", "Accessories")).toBe("tt_2")
|
|
264
|
+
const c3 = new FaireClient(oauthOpts)
|
|
265
|
+
expect(await c3.resolveTaxonomyTypeId("tok", "Home & Living")).toBe("tt_3")
|
|
266
|
+
})
|
|
267
|
+
})
|
|
@@ -66,6 +66,69 @@ describe("mapFaireOrderToOrder", () => {
|
|
|
66
66
|
expect(mapped.items).toEqual([])
|
|
67
67
|
})
|
|
68
68
|
|
|
69
|
+
it("maps a real ExternalOrderV2 (customer/address/item.price, no top-level total)", () => {
|
|
70
|
+
const order = {
|
|
71
|
+
id: "bo_bxdmjbwxid",
|
|
72
|
+
state: "NEW",
|
|
73
|
+
customer: { first_name: "John", last_name: "Smith" },
|
|
74
|
+
address: {
|
|
75
|
+
name: "John Smith",
|
|
76
|
+
company_name: "Faire Wholesale, Inc",
|
|
77
|
+
address1: "41 King Street West",
|
|
78
|
+
address2: "3rd Floor",
|
|
79
|
+
city: "Kitchener",
|
|
80
|
+
state: "Ontario",
|
|
81
|
+
state_code: "ON",
|
|
82
|
+
postal_code: "N2G 1A1",
|
|
83
|
+
country: "Canada",
|
|
84
|
+
country_code: "CAN",
|
|
85
|
+
phone_number: "555-123-4567",
|
|
86
|
+
},
|
|
87
|
+
items: [
|
|
88
|
+
{
|
|
89
|
+
id: "oi_bq425ju5vh",
|
|
90
|
+
product_id: "p_fccaefnahr",
|
|
91
|
+
variant_id: "po_3745tjzrpc",
|
|
92
|
+
sku: "goldenretriever",
|
|
93
|
+
quantity: 2,
|
|
94
|
+
product_name: "Golden Dog",
|
|
95
|
+
price: { amount_minor: 4999, currency: "USD" },
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
payout_costs: { total_payout: { amount_minor: 8000, currency: "USD" } },
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const mapped = mapFaireOrderToOrder(order)
|
|
102
|
+
|
|
103
|
+
expect(mapped.order_token).toBe("bo_bxdmjbwxid")
|
|
104
|
+
expect(mapped.currency_code).toBe("usd")
|
|
105
|
+
// no order-level total → sum of line values: 49.99 × 2
|
|
106
|
+
expect(mapped.total).toBe(99.98)
|
|
107
|
+
expect(mapped.buyer_name).toBe("John Smith")
|
|
108
|
+
expect(mapped.shipping_address).toMatchObject({
|
|
109
|
+
first_name: "John",
|
|
110
|
+
last_name: "Smith",
|
|
111
|
+
company: "Faire Wholesale, Inc",
|
|
112
|
+
address_1: "41 King Street West",
|
|
113
|
+
address_2: "3rd Floor",
|
|
114
|
+
city: "Kitchener",
|
|
115
|
+
province: "ON",
|
|
116
|
+
postal_code: "N2G 1A1",
|
|
117
|
+
country_code: "ca", // ISO-3 CAN → ISO-2 ca
|
|
118
|
+
phone: "555-123-4567",
|
|
119
|
+
})
|
|
120
|
+
expect(mapped.items[0]).toMatchObject({
|
|
121
|
+
title: "Golden Dog",
|
|
122
|
+
quantity: 2,
|
|
123
|
+
unit_price: 49.99,
|
|
124
|
+
})
|
|
125
|
+
expect(mapped.items[0].metadata).toMatchObject({
|
|
126
|
+
faire_product_token: "p_fccaefnahr",
|
|
127
|
+
faire_variant_id: "po_3745tjzrpc",
|
|
128
|
+
faire_sku: "goldenretriever",
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
|
|
69
132
|
it("uses buyer email when provided", () => {
|
|
70
133
|
const mapped = mapFaireOrderToOrder({
|
|
71
134
|
order_token: "o_2",
|
package/src/admin/lib/api.ts
CHANGED
|
@@ -84,6 +84,10 @@ export const faireApi = {
|
|
|
84
84
|
retrySync: (id: string) =>
|
|
85
85
|
sdk.client.fetch(`/admin/faire/syncs/${id}`, { method: "POST" }),
|
|
86
86
|
brand: () => sdk.client.fetch("/admin/faire/brand"),
|
|
87
|
+
taxonomy: () =>
|
|
88
|
+
sdk.client.fetch<{ taxonomy: Array<{ id: string; name: string }> }>(
|
|
89
|
+
"/admin/faire/taxonomy"
|
|
90
|
+
),
|
|
87
91
|
products: (opts: { limit?: number; page?: string; updated_at_min?: string } = {}) => {
|
|
88
92
|
const query: Record<string, string> = {}
|
|
89
93
|
if (opts.limit !== undefined) query.limit = String(opts.limit)
|