@jytextiles/medusa-plugin-faire-store-sync 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.
- package/.medusa/server/src/__tests__/ingest-faire-order-support.spec.js +74 -0
- package/.medusa/server/src/__tests__/webhook.spec.js +77 -0
- package/.medusa/server/src/admin/index.js +960 -0
- package/.medusa/server/src/admin/index.mjs +959 -0
- package/.medusa/server/src/api/admin/faire/auth/authorize/route.js +12 -0
- package/.medusa/server/src/api/admin/faire/auth/callback/route.js +25 -0
- package/.medusa/server/src/api/admin/faire/auth/disconnect/route.js +12 -0
- package/.medusa/server/src/api/admin/faire/brand/route.js +14 -0
- package/.medusa/server/src/api/admin/faire/ingest/orders/[batchId]/route.js +27 -0
- package/.medusa/server/src/api/admin/faire/ingest/orders/route.js +20 -0
- package/.medusa/server/src/api/admin/faire/products/route.js +16 -0
- package/.medusa/server/src/api/admin/faire/settings/route.js +19 -0
- package/.medusa/server/src/api/admin/faire/status/product/[id]/route.js +30 -0
- package/.medusa/server/src/api/admin/faire/status/route.js +46 -0
- package/.medusa/server/src/api/admin/faire/sync/bulk/[batchId]/route.js +29 -0
- package/.medusa/server/src/api/admin/faire/sync/bulk/route.js +20 -0
- package/.medusa/server/src/api/admin/faire/sync/product/[id]/route.js +14 -0
- package/.medusa/server/src/api/admin/faire/syncs/[id]/route.js +32 -0
- package/.medusa/server/src/api/admin/faire/syncs/route.js +18 -0
- package/.medusa/server/src/api/webhooks/faire/route.js +125 -0
- package/.medusa/server/src/jobs/pull-faire-orders.js +32 -0
- package/.medusa/server/src/jobs/refresh-faire-token.js +25 -0
- package/.medusa/server/src/lib/faire-client.js +321 -0
- package/.medusa/server/src/lib/types.js +10 -0
- package/.medusa/server/src/lib/webhook.js +58 -0
- package/.medusa/server/src/links/product-faire-sync-link.js +57 -0
- package/.medusa/server/src/modules/faire-sync/index.js +15 -0
- package/.medusa/server/src/modules/faire-sync/migrations/Migration20260707211346.js +34 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-order.js +21 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-sync-account.js +17 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-sync-batch.js +18 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-sync-record.js +22 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-sync-settings.js +26 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-webhook-event.js +21 -0
- package/.medusa/server/src/modules/faire-sync/service.js +222 -0
- package/.medusa/server/src/subscribers/faire-inventory-sync.js +87 -0
- package/.medusa/server/src/subscribers/faire-listing-events.js +46 -0
- package/.medusa/server/src/subscribers/faire-order-ingest.js +54 -0
- package/.medusa/server/src/subscribers/faire-order-lifecycle.js +71 -0
- package/.medusa/server/src/subscribers/faire-product-status-sync.js +71 -0
- package/.medusa/server/src/workflows/index.js +21 -0
- package/.medusa/server/src/workflows/ingest-faire-order-support.js +76 -0
- package/.medusa/server/src/workflows/ingest-faire-order.js +148 -0
- package/.medusa/server/src/workflows/ingest-faire-orders-bulk.js +124 -0
- package/.medusa/server/src/workflows/refresh-faire-token.js +20 -0
- package/.medusa/server/src/workflows/sync-product-to-faire.js +262 -0
- package/.medusa/server/src/workflows/sync-products-to-faire.js +90 -0
- package/LICENSE +21 -0
- package/README.md +180 -0
- package/package.json +84 -0
- package/scripts/postbuild.js +36 -0
- package/src/__tests__/ingest-faire-order-support.spec.ts +77 -0
- package/src/__tests__/webhook.spec.ts +81 -0
- package/src/admin/lib/api.ts +88 -0
- package/src/admin/routes/settings/faire/[id]/page.tsx +184 -0
- package/src/admin/routes/settings/faire/hooks/use-faire-sync-columns.tsx +80 -0
- package/src/admin/routes/settings/faire/page.tsx +445 -0
- package/src/admin/routes/settings/faire/settings/page.tsx +286 -0
- package/src/admin/routes/settings/oauth/faire/callback/page.tsx +67 -0
- package/src/admin/widgets/faire-product-widget.tsx +180 -0
- package/src/api/admin/faire/auth/authorize/route.ts +10 -0
- package/src/api/admin/faire/auth/callback/route.ts +29 -0
- package/src/api/admin/faire/auth/disconnect/route.ts +10 -0
- package/src/api/admin/faire/brand/route.ts +12 -0
- package/src/api/admin/faire/ingest/orders/[batchId]/route.ts +31 -0
- package/src/api/admin/faire/ingest/orders/route.ts +29 -0
- package/src/api/admin/faire/products/route.ts +14 -0
- package/src/api/admin/faire/settings/route.ts +17 -0
- package/src/api/admin/faire/status/product/[id]/route.ts +30 -0
- package/src/api/admin/faire/status/route.ts +47 -0
- package/src/api/admin/faire/sync/bulk/[batchId]/route.ts +33 -0
- package/src/api/admin/faire/sync/bulk/route.ts +27 -0
- package/src/api/admin/faire/sync/product/[id]/route.ts +13 -0
- package/src/api/admin/faire/syncs/[id]/route.ts +32 -0
- package/src/api/admin/faire/syncs/route.ts +17 -0
- package/src/api/webhooks/faire/route.ts +133 -0
- package/src/jobs/pull-faire-orders.ts +30 -0
- package/src/jobs/refresh-faire-token.ts +23 -0
- package/src/lib/faire-client.ts +436 -0
- package/src/lib/types.ts +117 -0
- package/src/lib/webhook.ts +85 -0
- package/src/links/product-faire-sync-link.ts +56 -0
- package/src/modules/faire-sync/index.ts +11 -0
- package/src/modules/faire-sync/migrations/.snapshot-medusa-faire-sync.json +1486 -0
- package/src/modules/faire-sync/migrations/Migration20260707211346.ts +43 -0
- package/src/modules/faire-sync/models/faire-order.ts +20 -0
- package/src/modules/faire-sync/models/faire-sync-account.ts +16 -0
- package/src/modules/faire-sync/models/faire-sync-batch.ts +17 -0
- package/src/modules/faire-sync/models/faire-sync-record.ts +21 -0
- package/src/modules/faire-sync/models/faire-sync-settings.ts +25 -0
- package/src/modules/faire-sync/models/faire-webhook-event.ts +20 -0
- package/src/modules/faire-sync/service.ts +252 -0
- package/src/subscribers/faire-inventory-sync.ts +97 -0
- package/src/subscribers/faire-listing-events.ts +48 -0
- package/src/subscribers/faire-order-ingest.ts +61 -0
- package/src/subscribers/faire-order-lifecycle.ts +81 -0
- package/src/subscribers/faire-product-status-sync.ts +76 -0
- package/src/workflows/index.ts +4 -0
- package/src/workflows/ingest-faire-order-support.ts +96 -0
- package/src/workflows/ingest-faire-order.ts +212 -0
- package/src/workflows/ingest-faire-orders-bulk.ts +168 -0
- package/src/workflows/refresh-faire-token.ts +28 -0
- package/src/workflows/sync-product-to-faire.ts +375 -0
- package/src/workflows/sync-products-to-faire.ts +133 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FaireClient = exports.FaireApiError = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
class FaireApiError extends Error {
|
|
6
|
+
constructor(message, status, body) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "FaireApiError";
|
|
9
|
+
this.status = status;
|
|
10
|
+
this.body = body;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.FaireApiError = FaireApiError;
|
|
14
|
+
/**
|
|
15
|
+
* Faire External Platform API v2 client.
|
|
16
|
+
*
|
|
17
|
+
* Auth model:
|
|
18
|
+
* - OAuth 2.0 authorization-code flow (no PKCE; Faire does not use PKCE).
|
|
19
|
+
* - Scoped requests send `Authorization: Bearer <access_token>`.
|
|
20
|
+
* - Faire's API-key mode (`X-FAIRE-ACCESS-TOKEN`) is not used here because the
|
|
21
|
+
* plugin connects a brand account via OAuth redirect.
|
|
22
|
+
*
|
|
23
|
+
* NOTE: Faire's developer portal is access-gated. Endpoint paths, payload
|
|
24
|
+
* shapes and the webhook signature scheme below reflect the publicly documented
|
|
25
|
+
* v2 surface and standard OAuth2 conventions; adjust via options / env if your
|
|
26
|
+
* Faire app uses a different base or signing scheme.
|
|
27
|
+
*/
|
|
28
|
+
class FaireClient {
|
|
29
|
+
constructor(opts) {
|
|
30
|
+
this.clientId = opts.clientId;
|
|
31
|
+
this.clientSecret = opts.clientSecret;
|
|
32
|
+
this.redirectUri = opts.redirectUri;
|
|
33
|
+
this.apiBase = opts.apiBase || types_1.DEFAULT_API_BASE;
|
|
34
|
+
this.authUrl = opts.authUrl || types_1.DEFAULT_AUTH_URL;
|
|
35
|
+
this.tokenUrl = opts.tokenUrl || types_1.DEFAULT_TOKEN_URL;
|
|
36
|
+
this.scope = opts.scope ?? "";
|
|
37
|
+
}
|
|
38
|
+
get redirectUriValue() {
|
|
39
|
+
return this.redirectUri;
|
|
40
|
+
}
|
|
41
|
+
// ── OAuth ───────────────────────────────────────────────────────────────
|
|
42
|
+
/**
|
|
43
|
+
* Build the Faire OAuth authorize URL. The caller must persist `state`
|
|
44
|
+
* (keyed by it) for the callback verification.
|
|
45
|
+
*/
|
|
46
|
+
getAuthorizationUrl(state) {
|
|
47
|
+
const params = new URLSearchParams({
|
|
48
|
+
response_type: "code",
|
|
49
|
+
client_id: this.clientId,
|
|
50
|
+
redirect_uri: this.redirectUri,
|
|
51
|
+
state,
|
|
52
|
+
});
|
|
53
|
+
if (this.scope)
|
|
54
|
+
params.set("scope", this.scope);
|
|
55
|
+
return `${this.authUrl}?${params.toString()}`;
|
|
56
|
+
}
|
|
57
|
+
async exchangeCodeForToken(code) {
|
|
58
|
+
const body = new URLSearchParams({
|
|
59
|
+
grant_type: "authorization_code",
|
|
60
|
+
client_id: this.clientId,
|
|
61
|
+
client_secret: this.clientSecret,
|
|
62
|
+
redirect_uri: this.redirectUri,
|
|
63
|
+
code,
|
|
64
|
+
});
|
|
65
|
+
const data = await this.requestJson(this.tokenUrl, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
68
|
+
body: body.toString(),
|
|
69
|
+
auth: false,
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
access_token: data.access_token,
|
|
73
|
+
refresh_token: data.refresh_token,
|
|
74
|
+
token_type: data.token_type || "Bearer",
|
|
75
|
+
expires_in: data.expires_in,
|
|
76
|
+
retrieved_at: Date.now(),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
async refreshAccessToken(refresh_token) {
|
|
80
|
+
const body = new URLSearchParams({
|
|
81
|
+
grant_type: "refresh_token",
|
|
82
|
+
client_id: this.clientId,
|
|
83
|
+
client_secret: this.clientSecret,
|
|
84
|
+
refresh_token,
|
|
85
|
+
});
|
|
86
|
+
const data = await this.requestJson(this.tokenUrl, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
89
|
+
body: body.toString(),
|
|
90
|
+
auth: false,
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
access_token: data.access_token,
|
|
94
|
+
refresh_token: data.refresh_token || refresh_token,
|
|
95
|
+
token_type: data.token_type || "Bearer",
|
|
96
|
+
expires_in: data.expires_in,
|
|
97
|
+
retrieved_at: Date.now(),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolve the brand the access token belongs to. Faire exposes the current
|
|
102
|
+
* brand via GET /api/v2/brand. Falls back gracefully if the shape differs.
|
|
103
|
+
*/
|
|
104
|
+
async getBrand(accessToken) {
|
|
105
|
+
const data = await this.requestJson(`${this.apiBase}/brand`, {
|
|
106
|
+
method: "GET",
|
|
107
|
+
accessToken,
|
|
108
|
+
});
|
|
109
|
+
const brand = data && typeof data === "object" && (data.brand_id || data.id)
|
|
110
|
+
? data
|
|
111
|
+
: data?.brand ?? data?.results?.[0] ?? data;
|
|
112
|
+
if (!brand?.brand_id && !brand?.id) {
|
|
113
|
+
throw new Error("No Faire brand found for the authorized account. Make sure you connected the brand owner.");
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
brand_id: String(brand.brand_id ?? brand.id),
|
|
117
|
+
brand_name: brand.name ?? brand.brand_name ?? "Faire Brand",
|
|
118
|
+
currency: brand.currency ?? brand.currency_code,
|
|
119
|
+
country: brand.country ?? brand.country_code,
|
|
120
|
+
raw: brand,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async fetchResource(accessToken, url) {
|
|
124
|
+
return this.requestJson(url, { method: "GET", accessToken });
|
|
125
|
+
}
|
|
126
|
+
// ── Products ────────────────────────────────────────────────────────────
|
|
127
|
+
async createProduct(accessToken, input) {
|
|
128
|
+
const data = await this.requestJson(`${this.apiBase}/products`, {
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: { "Content-Type": "application/json" },
|
|
131
|
+
body: JSON.stringify(input),
|
|
132
|
+
accessToken,
|
|
133
|
+
});
|
|
134
|
+
return this.mapProduct(data?.product ?? data);
|
|
135
|
+
}
|
|
136
|
+
async updateProduct(accessToken, productToken, input) {
|
|
137
|
+
const data = await this.requestJson(`${this.apiBase}/products/${productToken}`, {
|
|
138
|
+
method: "PUT",
|
|
139
|
+
headers: { "Content-Type": "application/json" },
|
|
140
|
+
body: JSON.stringify(input),
|
|
141
|
+
accessToken,
|
|
142
|
+
});
|
|
143
|
+
return this.mapProduct(data?.product ?? data);
|
|
144
|
+
}
|
|
145
|
+
async getProduct(accessToken, productToken) {
|
|
146
|
+
const data = await this.requestJson(`${this.apiBase}/products/${productToken}`, { method: "GET", accessToken });
|
|
147
|
+
return this.mapProduct(data?.product ?? data);
|
|
148
|
+
}
|
|
149
|
+
async listProducts(accessToken, opts = {}) {
|
|
150
|
+
const params = new URLSearchParams();
|
|
151
|
+
params.set("limit", String(opts.limit ?? 100));
|
|
152
|
+
if (opts.page != null)
|
|
153
|
+
params.set("page", String(opts.page));
|
|
154
|
+
const data = await this.requestJson(`${this.apiBase}/products?${params.toString()}`, { method: "GET", accessToken });
|
|
155
|
+
const results = (data.products ?? data.results ?? []).map((p) => this.mapProduct(p));
|
|
156
|
+
return { count: data.count ?? results.length, results };
|
|
157
|
+
}
|
|
158
|
+
// ── Inventory ───────────────────────────────────────────────────────────
|
|
159
|
+
async getInventory(accessToken, productToken) {
|
|
160
|
+
const params = new URLSearchParams();
|
|
161
|
+
if (productToken)
|
|
162
|
+
params.set("product_token", productToken);
|
|
163
|
+
const data = await this.requestJson(`${this.apiBase}/inventory?${params.toString()}`, { method: "GET", accessToken });
|
|
164
|
+
const rows = data.inventory ?? data.results ?? [];
|
|
165
|
+
return (Array.isArray(rows) ? rows : []).map((r) => ({
|
|
166
|
+
sku: String(r.sku ?? r.variant_id ?? ""),
|
|
167
|
+
product_token: r.product_token ? String(r.product_token) : undefined,
|
|
168
|
+
current_count: Number(r.current_count ?? r.inventory_count ?? 0),
|
|
169
|
+
raw: r,
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
async updateInventory(accessToken, levels) {
|
|
173
|
+
return this.requestJson(`${this.apiBase}/inventory`, {
|
|
174
|
+
method: "PUT",
|
|
175
|
+
headers: { "Content-Type": "application/json" },
|
|
176
|
+
body: JSON.stringify({ inventory: levels }),
|
|
177
|
+
accessToken,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
// ── Orders ──────────────────────────────────────────────────────────────
|
|
181
|
+
async listOrders(accessToken, opts = {}) {
|
|
182
|
+
const params = new URLSearchParams();
|
|
183
|
+
params.set("limit", String(opts.limit ?? 100));
|
|
184
|
+
if (opts.page != null)
|
|
185
|
+
params.set("page", String(opts.page));
|
|
186
|
+
const data = await this.requestJson(`${this.apiBase}/orders?${params.toString()}`, { method: "GET", accessToken });
|
|
187
|
+
const results = (data.orders ?? data.results ?? []).map((o) => this.mapOrder(o));
|
|
188
|
+
return { count: data.count ?? results.length, results };
|
|
189
|
+
}
|
|
190
|
+
async getOrder(accessToken, orderToken) {
|
|
191
|
+
const data = await this.requestJson(`${this.apiBase}/orders/${orderToken}`, { method: "GET", accessToken });
|
|
192
|
+
return this.mapOrder(data?.order ?? data);
|
|
193
|
+
}
|
|
194
|
+
async setOrderItemAvailability(accessToken, orderToken, items) {
|
|
195
|
+
return this.requestJson(`${this.apiBase}/orders/${orderToken}/items/availability`, {
|
|
196
|
+
method: "POST",
|
|
197
|
+
headers: { "Content-Type": "application/json" },
|
|
198
|
+
body: JSON.stringify({ items }),
|
|
199
|
+
accessToken,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// ── Webhooks ────────────────────────────────────────────────────────────
|
|
203
|
+
async registerWebhook(accessToken, payload) {
|
|
204
|
+
return this.requestJson(`${this.apiBase}/webhooks`, {
|
|
205
|
+
method: "POST",
|
|
206
|
+
headers: { "Content-Type": "application/json" },
|
|
207
|
+
body: JSON.stringify(payload),
|
|
208
|
+
accessToken,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
212
|
+
/**
|
|
213
|
+
* Fetch a remote image URL into a Buffer (used when Faire requires binary
|
|
214
|
+
* image payloads rather than remote URLs).
|
|
215
|
+
*/
|
|
216
|
+
static async fetchImageBuffer(url) {
|
|
217
|
+
const res = await fetch(url);
|
|
218
|
+
if (!res.ok) {
|
|
219
|
+
throw new Error(`Failed to fetch image ${url}: ${res.status}`);
|
|
220
|
+
}
|
|
221
|
+
const arrayBuffer = await res.arrayBuffer();
|
|
222
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
223
|
+
const filename = url.split("/").pop()?.split("?")[0] || "image.jpg";
|
|
224
|
+
return { buffer, filename };
|
|
225
|
+
}
|
|
226
|
+
mapProduct(data) {
|
|
227
|
+
return {
|
|
228
|
+
product_token: String(data.product_token ?? data.id ?? data.token),
|
|
229
|
+
brand_id: data.brand_id != null ? String(data.brand_id) : undefined,
|
|
230
|
+
name: data.name,
|
|
231
|
+
description: data.description,
|
|
232
|
+
state: data.state,
|
|
233
|
+
url: data.url,
|
|
234
|
+
wholesale_price_cents: data.wholesale_price_cents,
|
|
235
|
+
retail_price_cents: data.retail_price_cents,
|
|
236
|
+
variants: data.variants,
|
|
237
|
+
images: data.images,
|
|
238
|
+
raw: data,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
mapOrder(data) {
|
|
242
|
+
return {
|
|
243
|
+
order_token: String(data.order_token ?? data.id ?? data.token),
|
|
244
|
+
state: data.state ?? data.status,
|
|
245
|
+
currency: data.currency ?? data.currency_code,
|
|
246
|
+
total_cents: data.total_cents ?? data.grand_total_cents,
|
|
247
|
+
buyer_name: data.buyer_name ?? data.customer?.name,
|
|
248
|
+
raw: data,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
// ── Low-level request with rate-limit handling ──────────────────────────
|
|
252
|
+
async requestJson(url, init) {
|
|
253
|
+
const headers = {
|
|
254
|
+
Accept: "application/json",
|
|
255
|
+
...(init.headers || {}),
|
|
256
|
+
};
|
|
257
|
+
if (init.accessToken) {
|
|
258
|
+
headers["Authorization"] = `Bearer ${init.accessToken}`;
|
|
259
|
+
}
|
|
260
|
+
let attempt = 0;
|
|
261
|
+
const maxAttempts = 4;
|
|
262
|
+
while (attempt < maxAttempts) {
|
|
263
|
+
attempt++;
|
|
264
|
+
let res;
|
|
265
|
+
try {
|
|
266
|
+
res = await fetch(url, { method: init.method, headers, body: init.body });
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
if (attempt >= maxAttempts)
|
|
270
|
+
throw err;
|
|
271
|
+
await this.backoff(attempt);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (res.status === 429) {
|
|
275
|
+
const retryAfter = Number(res.headers.get("retry-after") || 1);
|
|
276
|
+
await this.sleep(Math.min(retryAfter * 1000, 10000));
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (res.status === 401) {
|
|
280
|
+
throw new FaireApiError("Faire access token expired or invalid", 401, null);
|
|
281
|
+
}
|
|
282
|
+
if (res.status === 204) {
|
|
283
|
+
return undefined;
|
|
284
|
+
}
|
|
285
|
+
const text = await res.text();
|
|
286
|
+
let body = null;
|
|
287
|
+
if (text) {
|
|
288
|
+
try {
|
|
289
|
+
body = JSON.parse(text);
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
body = text;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (!res.ok) {
|
|
296
|
+
const detail = body?.error_description ||
|
|
297
|
+
body?.error ||
|
|
298
|
+
body?.message ||
|
|
299
|
+
(Array.isArray(body?.errors)
|
|
300
|
+
? body.errors.map((e) => e?.message || e?.error || e).join("; ")
|
|
301
|
+
: undefined) ||
|
|
302
|
+
(typeof body === "string" && body ? body : undefined) ||
|
|
303
|
+
(body && typeof body === "object" ? JSON.stringify(body) : undefined);
|
|
304
|
+
const msg = detail
|
|
305
|
+
? `Faire API ${res.status}: ${detail}`
|
|
306
|
+
: `Faire API error ${res.status}`;
|
|
307
|
+
throw new FaireApiError(msg, res.status, body);
|
|
308
|
+
}
|
|
309
|
+
return body;
|
|
310
|
+
}
|
|
311
|
+
throw new FaireApiError("Max retries exceeded", 599, null);
|
|
312
|
+
}
|
|
313
|
+
async backoff(attempt) {
|
|
314
|
+
await this.sleep(Math.min(500 * Math.pow(2, attempt - 1), 8000));
|
|
315
|
+
}
|
|
316
|
+
sleep(ms) {
|
|
317
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
exports.FaireClient = FaireClient;
|
|
321
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpcmUtY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9mYWlyZS1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsbUNBWWdCO0FBRWhCLE1BQWEsYUFBYyxTQUFRLEtBQUs7SUFHdEMsWUFBWSxPQUFlLEVBQUUsTUFBYyxFQUFFLElBQVM7UUFDcEQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2QsSUFBSSxDQUFDLElBQUksR0FBRyxlQUFlLENBQUE7UUFDM0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7SUFDbEIsQ0FBQztDQUNGO0FBVEQsc0NBU0M7QUFFRDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBYSxXQUFXO0lBU3RCLFlBQVksSUFBd0I7UUFDbEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFBO1FBQzdCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQTtRQUNyQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUE7UUFDbkMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxJQUFJLHdCQUFnQixDQUFBO1FBQy9DLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSx3QkFBZ0IsQ0FBQTtRQUMvQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUkseUJBQWlCLENBQUE7UUFDbEQsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQTtJQUMvQixDQUFDO0lBRUQsSUFBSSxnQkFBZ0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFBO0lBQ3pCLENBQUM7SUFFRCwyRUFBMkU7SUFFM0U7OztPQUdHO0lBQ0gsbUJBQW1CLENB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
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_SCOPE = exports.DEFAULT_TOKEN_URL = exports.DEFAULT_AUTH_URL = exports.DEFAULT_API_BASE = void 0;
|
|
4
|
+
exports.DEFAULT_API_BASE = "https://www.faire.com/api/v2";
|
|
5
|
+
exports.DEFAULT_AUTH_URL = "https://www.faire.com/oauth/authorize";
|
|
6
|
+
exports.DEFAULT_TOKEN_URL = "https://www.faire.com/oauth/token";
|
|
7
|
+
// Faire OAuth currently exposes no granular scopes; the parameter is kept for
|
|
8
|
+
// forward-compat and to match the OAuth2 authorize URL shape.
|
|
9
|
+
exports.DEFAULT_SCOPE = "";
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVdhLFFBQUEsZ0JBQWdCLEdBQUcsOEJBQThCLENBQUE7QUFDakQsUUFBQSxnQkFBZ0IsR0FBRyx1Q0FBdUMsQ0FBQTtBQUMxRCxRQUFBLGlCQUFpQixHQUFHLG1DQUFtQyxDQUFBO0FBQ3BFLDhFQUE4RTtBQUM5RSw4REFBOEQ7QUFDakQsUUFBQSxhQUFhLEdBQUcsRUFBRSxDQUFBIn0=
|
|
@@ -0,0 +1,58 @@
|
|
|
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.verifyFaireWebhook = verifyFaireWebhook;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const TOLERANCE_SECONDS = 5 * 60;
|
|
9
|
+
const isHex = (s) => /^[0-9a-fA-F]+$/.test(s) && s.length % 2 === 0;
|
|
10
|
+
const safeEqual = (a, b) => {
|
|
11
|
+
if (a.length !== b.length)
|
|
12
|
+
return false;
|
|
13
|
+
return crypto_1.default.timingSafeEqual(a, b);
|
|
14
|
+
};
|
|
15
|
+
function verifyFaireWebhook(opts) {
|
|
16
|
+
const { secret, headers, rawBody } = opts;
|
|
17
|
+
const { signature, timestamp } = headers;
|
|
18
|
+
if (!secret)
|
|
19
|
+
return { valid: false, reason: "no signing secret configured" };
|
|
20
|
+
if (!signature) {
|
|
21
|
+
return { valid: false, reason: "missing webhook signature header" };
|
|
22
|
+
}
|
|
23
|
+
// Optional replay guard — only enforced when a timestamp is present.
|
|
24
|
+
if (timestamp) {
|
|
25
|
+
const ts = Number(timestamp);
|
|
26
|
+
const now = Math.floor((opts.now ?? Date.now()) / 1000);
|
|
27
|
+
const tolerance = opts.toleranceSeconds ?? TOLERANCE_SECONDS;
|
|
28
|
+
if (Number.isFinite(ts) && Math.abs(now - ts) > tolerance) {
|
|
29
|
+
return { valid: false, reason: "timestamp outside tolerance" };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const key = Buffer.from(secret, "utf8");
|
|
33
|
+
const computed = crypto_1.default
|
|
34
|
+
.createHmac("sha256", key)
|
|
35
|
+
.update(rawBody, "utf8")
|
|
36
|
+
.digest();
|
|
37
|
+
const candidates = signature
|
|
38
|
+
.split(" ")
|
|
39
|
+
.map((part) => (part.includes(",") ? part.split(",")[1] : part))
|
|
40
|
+
.filter(Boolean);
|
|
41
|
+
let passed = false;
|
|
42
|
+
for (const sig of candidates) {
|
|
43
|
+
const encoding = opts.encoding || (isHex(sig) ? "hex" : "base64");
|
|
44
|
+
let provided;
|
|
45
|
+
try {
|
|
46
|
+
provided = Buffer.from(sig, encoding);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (provided.length && safeEqual(provided, computed)) {
|
|
52
|
+
passed = true;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return passed ? { valid: true } : { valid: false, reason: "signature mismatch" };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViaG9vay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvd2ViaG9vay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQStCQSxnREFxREM7QUFwRkQsb0RBQTJCO0FBc0IzQixNQUFNLGlCQUFpQixHQUFHLENBQUMsR0FBRyxFQUFFLENBQUE7QUFFaEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFTLEVBQVcsRUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7QUFFcEYsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFXLEVBQUU7SUFDbEQsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxNQUFNO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDdkMsT0FBTyxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7QUFDckMsQ0FBQyxDQUFBO0FBRUQsU0FBZ0Isa0JBQWtCLENBQUMsSUFPbEM7SUFDQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUE7SUFDekMsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxPQUFPLENBQUE7SUFFeEMsSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsOEJBQThCLEVBQUUsQ0FBQTtJQUM1RSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDZixPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsa0NBQWtDLEVBQUUsQ0FBQTtJQUNyRSxDQUFDO0lBRUQscUVBQXFFO0lBQ3JFLElBQUksU0FBUyxFQUFFLENBQUM7UUFDZCxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDNUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUE7UUFDdkQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixJQUFJLGlCQUFpQixDQUFBO1FBQzVELElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsR0FBRyxTQUFTLEVBQUUsQ0FBQztZQUMxRCxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsNkJBQTZCLEVBQUUsQ0FBQTtRQUNoRSxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQ3ZDLE1BQU0sUUFBUSxHQUFHLGdCQUFNO1NBQ3BCLFVBQVUsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDO1NBQ3pCLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO1NBQ3ZCLE1BQU0sRUFBRSxDQUFBO0lBRVgsTUFBTSxVQUFVLEdBQUcsU0FBUztTQUN6QixLQUFLLENBQUMsR0FBRyxDQUFDO1NBQ1YsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQy9ELE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUVsQixJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUE7SUFDbEIsS0FBSyxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUM3QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQ2pFLElBQUksUUFBZ0IsQ0FBQTtRQUNwQixJQUFJLENBQUM7WUFDSCxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFDdkMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLFNBQVE7UUFDVixDQUFDO1FBQ0QsSUFBSSxRQUFRLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNyRCxNQUFNLEdBQUcsSUFBSSxDQUFBO1lBQ2IsTUFBSztRQUNQLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLG9CQUFvQixFQUFFLENBQUE7QUFDbEYsQ0FBQyJ9
|
|
@@ -0,0 +1,57 @@
|
|
|
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 product_1 = __importDefault(require("@medusajs/medusa/product"));
|
|
7
|
+
const faire_sync_1 = __importDefault(require("../modules/faire-sync"));
|
|
8
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
9
|
+
/**
|
|
10
|
+
* Link between Product and Faire account, storing the *current* per-product
|
|
11
|
+
* sync state. Historical sync attempts live in the faire_sync_record table.
|
|
12
|
+
*
|
|
13
|
+
* extraColumns:
|
|
14
|
+
* - faire_product_token: Faire product token once created
|
|
15
|
+
* - faire_url: public Faire product URL
|
|
16
|
+
* - sync_status: pending | synced | failed | out_of_sync
|
|
17
|
+
* - last_synced_at: last successful sync
|
|
18
|
+
* - sync_error: last error message
|
|
19
|
+
*/
|
|
20
|
+
exports.default = (0, utils_1.defineLink)({
|
|
21
|
+
linkable: product_1.default.linkable.product,
|
|
22
|
+
isList: true,
|
|
23
|
+
}, {
|
|
24
|
+
linkable: faire_sync_1.default.linkable.faireSyncAccount,
|
|
25
|
+
isList: false,
|
|
26
|
+
}, {
|
|
27
|
+
database: {
|
|
28
|
+
extraColumns: {
|
|
29
|
+
faire_product_token: {
|
|
30
|
+
type: "text",
|
|
31
|
+
nullable: true,
|
|
32
|
+
},
|
|
33
|
+
faire_url: {
|
|
34
|
+
type: "text",
|
|
35
|
+
nullable: true,
|
|
36
|
+
},
|
|
37
|
+
sync_status: {
|
|
38
|
+
type: "text",
|
|
39
|
+
defaultValue: "'pending'",
|
|
40
|
+
nullable: false,
|
|
41
|
+
},
|
|
42
|
+
last_synced_at: {
|
|
43
|
+
type: "datetime",
|
|
44
|
+
nullable: true,
|
|
45
|
+
},
|
|
46
|
+
sync_error: {
|
|
47
|
+
type: "text",
|
|
48
|
+
nullable: true,
|
|
49
|
+
},
|
|
50
|
+
metadata: {
|
|
51
|
+
type: "json",
|
|
52
|
+
nullable: true,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZHVjdC1mYWlyZS1zeW5jLWxpbmsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGlua3MvcHJvZHVjdC1mYWlyZS1zeW5jLWxpbmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx1RUFBb0Q7QUFDcEQsdUVBQW1EO0FBQ25ELHFEQUFzRDtBQUV0RDs7Ozs7Ozs7OztHQVVHO0FBQ0gsa0JBQWUsSUFBQSxrQkFBVSxFQUN2QjtJQUNFLFFBQVEsRUFBRSxpQkFBYSxDQUFDLFFBQVEsQ0FBQyxPQUFPO0lBQ3hDLE1BQU0sRUFBRSxJQUFJO0NBQ2IsRUFDRDtJQUNFLFFBQVEsRUFBRSxvQkFBZSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0I7SUFDbkQsTUFBTSxFQUFFLEtBQUs7Q0FDZCxFQUNEO0lBQ0UsUUFBUSxFQUFFO1FBQ1IsWUFBWSxFQUFFO1lBQ1osbUJBQW1CLEVBQUU7Z0JBQ25CLElBQUksRUFBRSxNQUFNO2dCQUNaLFFBQVEsRUFBRSxJQUFJO2FBQ2Y7WUFDRCxTQUFTLEVBQUU7Z0JBQ1QsSUFBSSxFQUFFLE1BQU07Z0JBQ1osUUFBUSxFQUFFLElBQUk7YUFDZjtZQUNELFdBQVcsRUFBRTtnQkFDWCxJQUFJLEVBQUUsTUFBTTtnQkFDWixZQUFZLEVBQUUsV0FBVztnQkFDekIsUUFBUSxFQUFFLEtBQUs7YUFDaEI7WUFDRCxjQUFjLEVBQUU7Z0JBQ2QsSUFBSSxFQUFFLFVBQVU7Z0JBQ2hCLFFBQVEsRUFBRSxJQUFJO2FBQ2Y7WUFDRCxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSxFQUFFLE1BQU07Z0JBQ1osUUFBUSxFQUFFLElBQUk7YUFDZjtZQUNELFFBQVEsRUFBRTtnQkFDUixJQUFJLEVBQUUsTUFBTTtnQkFDWixRQUFRLEVBQUUsSUFBSTthQUNmO1NBQ0Y7S0FDRjtDQUNGLENBQ0YsQ0FBQSJ9
|
|
@@ -0,0 +1,15 @@
|
|
|
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.FaireSyncService = exports.FAIRE_SYNC_MODULE = void 0;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const service_1 = __importDefault(require("./service"));
|
|
9
|
+
exports.FaireSyncService = service_1.default;
|
|
10
|
+
exports.FAIRE_SYNC_MODULE = "faireSync";
|
|
11
|
+
const FaireSyncModule = (0, utils_1.Module)(exports.FAIRE_SYNC_MODULE, {
|
|
12
|
+
service: service_1.default,
|
|
13
|
+
});
|
|
14
|
+
exports.default = FaireSyncModule;
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9mYWlyZS1zeW5jL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHFEQUFrRDtBQUNsRCx3REFBd0M7QUFTL0IsMkJBVEYsaUJBQWdCLENBU0U7QUFQWixRQUFBLGlCQUFpQixHQUFHLFdBQVcsQ0FBQTtBQUU1QyxNQUFNLGVBQWUsR0FBRyxJQUFBLGNBQU0sRUFBQyx5QkFBaUIsRUFBRTtJQUNoRCxPQUFPLEVBQUUsaUJBQWdCO0NBQzFCLENBQUMsQ0FBQTtBQUVGLGtCQUFlLGVBQWUsQ0FBQSJ9
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260707211346 = void 0;
|
|
4
|
+
const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
|
|
5
|
+
class Migration20260707211346 extends migrations_1.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
this.addSql(`alter table if exists "faire_webhook_event" drop constraint if exists "faire_webhook_event_webhook_id_unique";`);
|
|
8
|
+
this.addSql(`alter table if exists "faire_order" drop constraint if exists "faire_order_order_token_unique";`);
|
|
9
|
+
this.addSql(`create table if not exists "faire_order" ("id" text not null, "order_token" text not null, "order_id" text null, "status" text not null default 'created', "currency" text null, "total" text null, "buyer_name" text null, "raw" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "faire_order_pkey" primary key ("id"));`);
|
|
10
|
+
this.addSql(`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_faire_order_order_token_unique" ON "faire_order" ("order_token") WHERE deleted_at IS NULL;`);
|
|
11
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_faire_order_deleted_at" ON "faire_order" ("deleted_at") WHERE deleted_at IS NULL;`);
|
|
12
|
+
this.addSql(`create table if not exists "faire_sync_account" ("id" text not null, "brand_id" text not null, "brand_name" text not null, "currency" text null, "country" text null, "access_token" text not null, "refresh_token" text null, "token_expires_at" timestamptz null, "brand_info" jsonb null, "is_active" boolean not null default true, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "faire_sync_account_pkey" primary key ("id"));`);
|
|
13
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_faire_sync_account_deleted_at" ON "faire_sync_account" ("deleted_at") WHERE deleted_at IS NULL;`);
|
|
14
|
+
this.addSql(`create table if not exists "faire_sync_batch" ("id" text not null, "transaction_id" text null, "status" text check ("status" in ('pending', 'processing', 'completed', 'failed')) not null default 'pending', "total_products" integer not null default 0, "synced_count" integer not null default 0, "failed_count" integer not null default 0, "error_log" jsonb null, "started_at" timestamptz null, "completed_at" timestamptz null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "faire_sync_batch_pkey" primary key ("id"));`);
|
|
15
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_faire_sync_batch_deleted_at" ON "faire_sync_batch" ("deleted_at") WHERE deleted_at IS NULL;`);
|
|
16
|
+
this.addSql(`create table if not exists "faire_sync_record" ("id" text not null, "product_id" text not null, "account_id" text not null, "product_token" text null, "product_url" text null, "product_state" text null, "action" text check ("action" in ('create', 'update', 'delete')) not null default 'create', "status" text check ("status" in ('pending', 'syncing', 'success', 'failed', 'draft')) not null default 'pending', "published" boolean not null default false, "error_message" text null, "warnings" jsonb null, "metadata" jsonb null, "synced_at" timestamptz null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "faire_sync_record_pkey" primary key ("id"));`);
|
|
17
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_faire_sync_record_deleted_at" ON "faire_sync_record" ("deleted_at") WHERE deleted_at IS NULL;`);
|
|
18
|
+
this.addSql(`create table if not exists "faire_sync_settings" ("id" text not null, "account_id" text null, "default_brand_id" text null, "default_wholesale_markup_percent" integer null, "default_min_order_quantity" integer not null default 1, "default_lead_time_days" integer null, "default_shipping_policy_id" text null, "default_category" text null, "auto_publish" boolean not null default false, "follow_product_status" boolean not null default true, "pending_oauth" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "faire_sync_settings_pkey" primary key ("id"));`);
|
|
19
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_faire_sync_settings_deleted_at" ON "faire_sync_settings" ("deleted_at") WHERE deleted_at IS NULL;`);
|
|
20
|
+
this.addSql(`create table if not exists "faire_webhook_event" ("id" text not null, "webhook_id" text not null, "event_type" text not null, "brand_id" text null, "resource_url" text null, "payload" jsonb null, "resource" jsonb null, "processed" boolean not null default false, "error" text null, "received_at" timestamptz null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "faire_webhook_event_pkey" primary key ("id"));`);
|
|
21
|
+
this.addSql(`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_faire_webhook_event_webhook_id_unique" ON "faire_webhook_event" ("webhook_id") WHERE deleted_at IS NULL;`);
|
|
22
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_faire_webhook_event_deleted_at" ON "faire_webhook_event" ("deleted_at") WHERE deleted_at IS NULL;`);
|
|
23
|
+
}
|
|
24
|
+
async down() {
|
|
25
|
+
this.addSql(`drop table if exists "faire_order" cascade;`);
|
|
26
|
+
this.addSql(`drop table if exists "faire_sync_account" cascade;`);
|
|
27
|
+
this.addSql(`drop table if exists "faire_sync_batch" cascade;`);
|
|
28
|
+
this.addSql(`drop table if exists "faire_sync_record" cascade;`);
|
|
29
|
+
this.addSql(`drop table if exists "faire_sync_settings" cascade;`);
|
|
30
|
+
this.addSql(`drop table if exists "faire_webhook_event" cascade;`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.Migration20260707211346 = Migration20260707211346;
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNjA3MDcyMTEzNDYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9mYWlyZS1zeW5jL21pZ3JhdGlvbnMvTWlncmF0aW9uMjAyNjA3MDcyMTEzNDYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUVBQXFFO0FBRXJFLE1BQWEsdUJBQXdCLFNBQVEsc0JBQVM7SUFFM0MsS0FBSyxDQUFDLEVBQUU7UUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLGdIQUFnSCxDQUFDLENBQUM7UUFDOUgsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpR0FBaUcsQ0FBQyxDQUFDO1FBQy9HLElBQUksQ0FBQyxNQUFNLENBQUMsbWFBQW1hLENBQUMsQ0FBQztRQUNqYixJQUFJLENBQUMsTUFBTSxDQUFDLG1JQUFtSSxDQUFDLENBQUM7UUFDakosSUFBSSxDQUFDLE1BQU0sQ0FBQyxtSEFBbUgsQ0FBQyxDQUFDO1FBRWpJLElBQUksQ0FBQyxNQUFNLENBQUMsb2dCQUFvZ0IsQ0FBQyxDQUFDO1FBQ2xoQixJQUFJLENBQUMsTUFBTSxDQUFDLGlJQUFpSSxDQUFDLENBQUM7UUFFL0ksSUFBSSxDQUFDLE1BQU0sQ0FBQyxtbUJBQW1tQixDQUFDLENBQUM7UUFDam5CLElBQUksQ0FBQyxNQUFNLENBQUMsNkhBQTZILENBQUMsQ0FBQztRQUUzSSxJQUFJLENBQUMsTUFBTSxDQUFDLHd1QkFBd3VCLENBQUMsQ0FBQztRQUN0dkIsSUFBSSxDQUFDLE1BQU0sQ0FBQywrSEFBK0gsQ0FBQyxDQUFDO1FBRTdJLElBQUksQ0FBQyxNQUFNLENBQUMsa3BCQUFrcEIsQ0FBQyxDQUFDO1FBQ2hxQixJQUFJLENBQUMsTUFBTSxDQUFDLG1JQUFtSSxDQUFDLENBQUM7UUFFakosSUFBSSxDQUFDLE1BQU0sQ0FBQyx1ZkFBdWYsQ0FBQyxDQUFDO1FBQ3JnQixJQUFJLENBQUMsTUFBTSxDQUFDLGlKQUFpSixDQUFDLENBQUM7UUFDL0osSUFBSSxDQUFDLE1BQU0sQ0FBQyxtSUFBbUksQ0FBQyxDQUFDO0lBQ25KLENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSTtRQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLDZDQUE2QyxDQUFDLENBQUM7UUFFM0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBRWxFLElBQUksQ0FBQyxNQUFNLENBQUMsa0RBQWtELENBQUMsQ0FBQztRQUVoRSxJQUFJLENBQUMsTUFBTSxDQUFDLG1EQUFtRCxDQUFDLENBQUM7UUFFakUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO1FBRW5FLElBQUksQ0FBQyxNQUFNLENBQUMscURBQXFELENBQUMsQ0FBQztJQUNyRSxDQUFDO0NBRUY7QUF4Q0QsMERBd0NDIn0=
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
/**
|
|
5
|
+
* Maps a Faire order to the Medusa order created from it. `order_token` is
|
|
6
|
+
* unique — the idempotency key so a Faire webhook retry (or a later
|
|
7
|
+
* order.canceled/shipped event for the same order) never re-creates the
|
|
8
|
+
* Medusa order.
|
|
9
|
+
*/
|
|
10
|
+
const FaireOrder = utils_1.model.define("faire_order", {
|
|
11
|
+
id: utils_1.model.id().primaryKey(),
|
|
12
|
+
order_token: utils_1.model.text().unique(),
|
|
13
|
+
order_id: utils_1.model.text().nullable(), // Medusa order id
|
|
14
|
+
status: utils_1.model.text().default("created"),
|
|
15
|
+
currency: utils_1.model.text().nullable(),
|
|
16
|
+
total: utils_1.model.text().nullable(), // decimal string (cents as integer string)
|
|
17
|
+
buyer_name: utils_1.model.text().nullable(),
|
|
18
|
+
raw: utils_1.model.json().nullable(),
|
|
19
|
+
});
|
|
20
|
+
exports.default = FaireOrder;
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpcmUtb3JkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9mYWlyZS1zeW5jL21vZGVscy9mYWlyZS1vcmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUFpRDtBQUVqRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxHQUFHLGFBQUssQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFO0lBQzdDLEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQzNCLFdBQVcsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxFQUFFO0lBQ2xDLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsa0JBQWtCO0lBQ3JELE1BQU0sRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUN2QyxRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNqQyxLQUFLLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFFLDJDQUEyQztJQUMzRSxVQUFVLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNuQyxHQUFHLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUM3QixDQUFDLENBQUE7QUFFRixrQkFBZSxVQUFVLENBQUEifQ==
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const FaireSyncAccount = utils_1.model.define("faire_sync_account", {
|
|
5
|
+
id: utils_1.model.id().primaryKey(),
|
|
6
|
+
brand_id: utils_1.model.text(),
|
|
7
|
+
brand_name: utils_1.model.text(),
|
|
8
|
+
currency: utils_1.model.text().nullable(),
|
|
9
|
+
country: utils_1.model.text().nullable(),
|
|
10
|
+
access_token: utils_1.model.text(),
|
|
11
|
+
refresh_token: utils_1.model.text().nullable(),
|
|
12
|
+
token_expires_at: utils_1.model.dateTime().nullable(),
|
|
13
|
+
brand_info: utils_1.model.json().nullable(),
|
|
14
|
+
is_active: utils_1.model.boolean().default(true),
|
|
15
|
+
});
|
|
16
|
+
exports.default = FaireSyncAccount;
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpcmUtc3luYy1hY2NvdW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL21vZHVsZXMvZmFpcmUtc3luYy9tb2RlbHMvZmFpcmUtc3luYy1hY2NvdW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEscURBQWlEO0FBRWpELE1BQU0sZ0JBQWdCLEdBQUcsYUFBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRTtJQUMxRCxFQUFFLEVBQUUsYUFBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUMzQixRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRTtJQUN0QixVQUFVLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRTtJQUN4QixRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNqQyxPQUFPLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNoQyxZQUFZLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRTtJQUMxQixhQUFhLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUN0QyxnQkFBZ0IsRUFBRSxhQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQzdDLFVBQVUsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ25DLFNBQVMsRUFBRSxhQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztDQUN6QyxDQUFDLENBQUE7QUFFRixrQkFBZSxnQkFBZ0IsQ0FBQSJ9
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const FaireSyncBatch = utils_1.model.define("faire_sync_batch", {
|
|
5
|
+
id: utils_1.model.id().primaryKey(),
|
|
6
|
+
transaction_id: utils_1.model.text().nullable(),
|
|
7
|
+
status: utils_1.model
|
|
8
|
+
.enum(["pending", "processing", "completed", "failed"])
|
|
9
|
+
.default("pending"),
|
|
10
|
+
total_products: utils_1.model.number().default(0),
|
|
11
|
+
synced_count: utils_1.model.number().default(0),
|
|
12
|
+
failed_count: utils_1.model.number().default(0),
|
|
13
|
+
error_log: utils_1.model.json().nullable(),
|
|
14
|
+
started_at: utils_1.model.dateTime().nullable(),
|
|
15
|
+
completed_at: utils_1.model.dateTime().nullable(),
|
|
16
|
+
});
|
|
17
|
+
exports.default = FaireSyncBatch;
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpcmUtc3luYy1iYXRjaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2ZhaXJlLXN5bmMvbW9kZWxzL2ZhaXJlLXN5bmMtYmF0Y2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxxREFBaUQ7QUFFakQsTUFBTSxjQUFjLEdBQUcsYUFBSyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRTtJQUN0RCxFQUFFLEVBQUUsYUFBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUMzQixjQUFjLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUN2QyxNQUFNLEVBQUUsYUFBSztTQUNWLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ3RELE9BQU8sQ0FBQyxTQUFTLENBQUM7SUFDckIsY0FBYyxFQUFFLGFBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3pDLFlBQVksRUFBRSxhQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUN2QyxZQUFZLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDdkMsU0FBUyxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDbEMsVUFBVSxFQUFFLGFBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDdkMsWUFBWSxFQUFFLGFBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDMUMsQ0FBQyxDQUFBO0FBRUYsa0JBQWUsY0FBYyxDQUFBIn0=
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const FaireSyncRecord = utils_1.model.define("faire_sync_record", {
|
|
5
|
+
id: utils_1.model.id().primaryKey(),
|
|
6
|
+
product_id: utils_1.model.text(),
|
|
7
|
+
account_id: utils_1.model.text(),
|
|
8
|
+
product_token: utils_1.model.text().nullable(),
|
|
9
|
+
product_url: utils_1.model.text().nullable(),
|
|
10
|
+
product_state: utils_1.model.text().nullable(),
|
|
11
|
+
action: utils_1.model.enum(["create", "update", "delete"]).default("create"),
|
|
12
|
+
status: utils_1.model
|
|
13
|
+
.enum(["pending", "syncing", "success", "failed", "draft"])
|
|
14
|
+
.default("pending"),
|
|
15
|
+
published: utils_1.model.boolean().default(false),
|
|
16
|
+
error_message: utils_1.model.text().nullable(),
|
|
17
|
+
warnings: utils_1.model.json().nullable(),
|
|
18
|
+
metadata: utils_1.model.json().nullable(),
|
|
19
|
+
synced_at: utils_1.model.dateTime().nullable(),
|
|
20
|
+
});
|
|
21
|
+
exports.default = FaireSyncRecord;
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpcmUtc3luYy1yZWNvcmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9mYWlyZS1zeW5jL21vZGVscy9mYWlyZS1zeW5jLXJlY29yZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUFpRDtBQUVqRCxNQUFNLGVBQWUsR0FBRyxhQUFLLENBQUMsTUFBTSxDQUFDLG1CQUFtQixFQUFFO0lBQ3hELEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQzNCLFVBQVUsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3hCLFVBQVUsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3hCLGFBQWEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3RDLFdBQVcsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3BDLGFBQWEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3RDLE1BQU0sRUFBRSxhQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUM7SUFDcEUsTUFBTSxFQUFFLGFBQUs7U0FDVixJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDMUQsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUNyQixTQUFTLEVBQUUsYUFBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7SUFDekMsYUFBYSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDdEMsUUFBUSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDakMsUUFBUSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDakMsU0FBUyxFQUFFLGFBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDdkMsQ0FBQyxDQUFBO0FBRUYsa0JBQWUsZUFBZSxDQUFBIn0=
|