@jytextiles/medusa-plugin-faire-store-sync 0.2.3 → 0.2.5

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.
@@ -1,5 +1,5 @@
1
1
  import { defineRouteConfig } from "@medusajs/admin-sdk"
2
- import { BuildingStorefront } from "@medusajs/icons"
2
+ import { BuildingStorefront, ChevronDownMini } from "@medusajs/icons"
3
3
  import {
4
4
  Alert,
5
5
  Button,
@@ -7,7 +7,10 @@ import {
7
7
  DataTable,
8
8
  DataTableFilteringState,
9
9
  DataTablePaginationState,
10
+ Drawer,
11
+ DropdownMenu,
10
12
  Heading,
13
+ Input,
11
14
  Label,
12
15
  Skeleton,
13
16
  StatusBadge,
@@ -53,6 +56,8 @@ const FaireSettingsPage = () => {
53
56
  pageSize: PAGE_SIZE,
54
57
  })
55
58
  const [filtering, setFiltering] = useState<DataTableFilteringState>({})
59
+ const [apiKeyOpen, setApiKeyOpen] = useState(false)
60
+ const [apiKey, setApiKey] = useState("")
56
61
 
57
62
  // ── Queries ───────────────────────────────────────────────────────────────
58
63
  const statusQuery = useQuery({
@@ -91,6 +96,20 @@ const FaireSettingsPage = () => {
91
96
  }),
92
97
  })
93
98
 
99
+ const apiKeyMutation = useMutation({
100
+ mutationFn: () => faireApi.connectApiKey(apiKey.trim()),
101
+ onSuccess: () => {
102
+ queryClient.invalidateQueries({ queryKey: STATUS_KEY })
103
+ setApiKeyOpen(false)
104
+ setApiKey("")
105
+ toast.success("Connected to Faire with API key")
106
+ },
107
+ onError: (err: any) =>
108
+ toast.error("Failed to connect with API key", {
109
+ description: err.message,
110
+ }),
111
+ })
112
+
94
113
  const disconnectMutation = useMutation({
95
114
  mutationFn: () => faireApi.disconnect(),
96
115
  onSuccess: () => {
@@ -211,13 +230,22 @@ const FaireSettingsPage = () => {
211
230
  </Button>
212
231
  </div>
213
232
  ) : (
214
- <Button
215
- size="small"
216
- onClick={() => connectMutation.mutate()}
217
- isLoading={connectMutation.isPending}
218
- >
219
- Connect Faire
220
- </Button>
233
+ <DropdownMenu>
234
+ <DropdownMenu.Trigger asChild>
235
+ <Button size="small" isLoading={connectMutation.isPending}>
236
+ Connect Faire
237
+ <ChevronDownMini />
238
+ </Button>
239
+ </DropdownMenu.Trigger>
240
+ <DropdownMenu.Content>
241
+ <DropdownMenu.Item onClick={() => connectMutation.mutate()}>
242
+ Connect with OAuth
243
+ </DropdownMenu.Item>
244
+ <DropdownMenu.Item onClick={() => setApiKeyOpen(true)}>
245
+ Connect with API key (private)
246
+ </DropdownMenu.Item>
247
+ </DropdownMenu.Content>
248
+ </DropdownMenu>
221
249
  )}
222
250
  </div>
223
251
  {connected && status?.account && (
@@ -264,6 +292,48 @@ const FaireSettingsPage = () => {
264
292
  </DataTable>
265
293
  </Container>
266
294
 
295
+ {/* API-key connect (private integrations) */}
296
+ <Drawer open={apiKeyOpen} onOpenChange={setApiKeyOpen}>
297
+ <Drawer.Content>
298
+ <Drawer.Header>
299
+ <Drawer.Title>Connect with API key</Drawer.Title>
300
+ </Drawer.Header>
301
+ <Drawer.Body className="flex flex-col gap-y-3">
302
+ <Text className="text-ui-fg-subtle" size="small">
303
+ For private / unpublished Faire integrations, paste the API key
304
+ your Faire brand issued for this app. This connects without OAuth.
305
+ </Text>
306
+ <div className="flex flex-col gap-y-1">
307
+ <Label size="small">Faire API key</Label>
308
+ <Input
309
+ type="password"
310
+ placeholder="Paste the Faire API key…"
311
+ value={apiKey}
312
+ onChange={(e) => setApiKey(e.target.value)}
313
+ autoComplete="off"
314
+ />
315
+ </div>
316
+ </Drawer.Body>
317
+ <Drawer.Footer>
318
+ <Button
319
+ variant="secondary"
320
+ size="small"
321
+ onClick={() => setApiKeyOpen(false)}
322
+ >
323
+ Cancel
324
+ </Button>
325
+ <Button
326
+ size="small"
327
+ onClick={() => apiKeyMutation.mutate()}
328
+ isLoading={apiKeyMutation.isPending}
329
+ disabled={!apiKey.trim()}
330
+ >
331
+ Connect
332
+ </Button>
333
+ </Drawer.Footer>
334
+ </Drawer.Content>
335
+ </Drawer>
336
+
267
337
  <Toaster />
268
338
  </div>
269
339
  )
@@ -301,6 +301,25 @@
301
301
  "enumItems": [],
302
302
  "mappedType": "text"
303
303
  },
304
+ "auth_mode": {
305
+ "name": "auth_mode",
306
+ "type": "text",
307
+ "unsigned": false,
308
+ "autoincrement": false,
309
+ "primary": false,
310
+ "nullable": false,
311
+ "unique": false,
312
+ "length": null,
313
+ "precision": null,
314
+ "scale": null,
315
+ "default": "'oauth'",
316
+ "comment": null,
317
+ "enumItems": [
318
+ "oauth",
319
+ "apiKey"
320
+ ],
321
+ "mappedType": "enum"
322
+ },
304
323
  "access_token": {
305
324
  "name": "access_token",
306
325
  "type": "text",
@@ -1158,230 +1177,8 @@
1158
1177
  "enumItems": [],
1159
1178
  "mappedType": "json"
1160
1179
  },
1161
- "created_at": {
1162
- "name": "created_at",
1163
- "type": "timestamptz",
1164
- "unsigned": false,
1165
- "autoincrement": false,
1166
- "primary": false,
1167
- "nullable": false,
1168
- "unique": false,
1169
- "length": 6,
1170
- "precision": null,
1171
- "scale": null,
1172
- "default": "now()",
1173
- "comment": null,
1174
- "enumItems": [],
1175
- "mappedType": "datetime"
1176
- },
1177
- "updated_at": {
1178
- "name": "updated_at",
1179
- "type": "timestamptz",
1180
- "unsigned": false,
1181
- "autoincrement": false,
1182
- "primary": false,
1183
- "nullable": false,
1184
- "unique": false,
1185
- "length": 6,
1186
- "precision": null,
1187
- "scale": null,
1188
- "default": "now()",
1189
- "comment": null,
1190
- "enumItems": [],
1191
- "mappedType": "datetime"
1192
- },
1193
- "deleted_at": {
1194
- "name": "deleted_at",
1195
- "type": "timestamptz",
1196
- "unsigned": false,
1197
- "autoincrement": false,
1198
- "primary": false,
1199
- "nullable": true,
1200
- "unique": false,
1201
- "length": 6,
1202
- "precision": null,
1203
- "scale": null,
1204
- "default": null,
1205
- "comment": null,
1206
- "enumItems": [],
1207
- "mappedType": "datetime"
1208
- }
1209
- },
1210
- "name": "faire_sync_settings",
1211
- "schema": "public",
1212
- "indexes": [
1213
- {
1214
- "keyName": "IDX_faire_sync_settings_deleted_at",
1215
- "columnNames": [],
1216
- "composite": false,
1217
- "constraint": false,
1218
- "primary": false,
1219
- "unique": false,
1220
- "expression": "CREATE INDEX IF NOT EXISTS \"IDX_faire_sync_settings_deleted_at\" ON \"faire_sync_settings\" (\"deleted_at\") WHERE deleted_at IS NULL"
1221
- },
1222
- {
1223
- "keyName": "faire_sync_settings_pkey",
1224
- "columnNames": [
1225
- "id"
1226
- ],
1227
- "composite": false,
1228
- "constraint": true,
1229
- "primary": true,
1230
- "unique": true
1231
- }
1232
- ],
1233
- "checks": [],
1234
- "foreignKeys": {},
1235
- "nativeEnums": {}
1236
- },
1237
- {
1238
- "columns": {
1239
- "id": {
1240
- "name": "id",
1241
- "type": "text",
1242
- "unsigned": false,
1243
- "autoincrement": false,
1244
- "primary": true,
1245
- "nullable": false,
1246
- "unique": false,
1247
- "length": null,
1248
- "precision": null,
1249
- "scale": null,
1250
- "default": null,
1251
- "comment": null,
1252
- "enumItems": [],
1253
- "mappedType": "text"
1254
- },
1255
- "webhook_id": {
1256
- "name": "webhook_id",
1257
- "type": "text",
1258
- "unsigned": false,
1259
- "autoincrement": false,
1260
- "primary": false,
1261
- "nullable": false,
1262
- "unique": false,
1263
- "length": null,
1264
- "precision": null,
1265
- "scale": null,
1266
- "default": null,
1267
- "comment": null,
1268
- "enumItems": [],
1269
- "mappedType": "text"
1270
- },
1271
- "event_type": {
1272
- "name": "event_type",
1273
- "type": "text",
1274
- "unsigned": false,
1275
- "autoincrement": false,
1276
- "primary": false,
1277
- "nullable": false,
1278
- "unique": false,
1279
- "length": null,
1280
- "precision": null,
1281
- "scale": null,
1282
- "default": null,
1283
- "comment": null,
1284
- "enumItems": [],
1285
- "mappedType": "text"
1286
- },
1287
- "brand_id": {
1288
- "name": "brand_id",
1289
- "type": "text",
1290
- "unsigned": false,
1291
- "autoincrement": false,
1292
- "primary": false,
1293
- "nullable": true,
1294
- "unique": false,
1295
- "length": null,
1296
- "precision": null,
1297
- "scale": null,
1298
- "default": null,
1299
- "comment": null,
1300
- "enumItems": [],
1301
- "mappedType": "text"
1302
- },
1303
- "resource_url": {
1304
- "name": "resource_url",
1305
- "type": "text",
1306
- "unsigned": false,
1307
- "autoincrement": false,
1308
- "primary": false,
1309
- "nullable": true,
1310
- "unique": false,
1311
- "length": null,
1312
- "precision": null,
1313
- "scale": null,
1314
- "default": null,
1315
- "comment": null,
1316
- "enumItems": [],
1317
- "mappedType": "text"
1318
- },
1319
- "payload": {
1320
- "name": "payload",
1321
- "type": "jsonb",
1322
- "unsigned": false,
1323
- "autoincrement": false,
1324
- "primary": false,
1325
- "nullable": true,
1326
- "unique": false,
1327
- "length": null,
1328
- "precision": null,
1329
- "scale": null,
1330
- "default": null,
1331
- "comment": null,
1332
- "enumItems": [],
1333
- "mappedType": "json"
1334
- },
1335
- "resource": {
1336
- "name": "resource",
1337
- "type": "jsonb",
1338
- "unsigned": false,
1339
- "autoincrement": false,
1340
- "primary": false,
1341
- "nullable": true,
1342
- "unique": false,
1343
- "length": null,
1344
- "precision": null,
1345
- "scale": null,
1346
- "default": null,
1347
- "comment": null,
1348
- "enumItems": [],
1349
- "mappedType": "json"
1350
- },
1351
- "processed": {
1352
- "name": "processed",
1353
- "type": "boolean",
1354
- "unsigned": false,
1355
- "autoincrement": false,
1356
- "primary": false,
1357
- "nullable": false,
1358
- "unique": false,
1359
- "length": null,
1360
- "precision": null,
1361
- "scale": null,
1362
- "default": "false",
1363
- "comment": null,
1364
- "enumItems": [],
1365
- "mappedType": "boolean"
1366
- },
1367
- "error": {
1368
- "name": "error",
1369
- "type": "text",
1370
- "unsigned": false,
1371
- "autoincrement": false,
1372
- "primary": false,
1373
- "nullable": true,
1374
- "unique": false,
1375
- "length": null,
1376
- "precision": null,
1377
- "scale": null,
1378
- "default": null,
1379
- "comment": null,
1380
- "enumItems": [],
1381
- "mappedType": "text"
1382
- },
1383
- "received_at": {
1384
- "name": "received_at",
1180
+ "last_order_sync_at": {
1181
+ "name": "last_order_sync_at",
1385
1182
  "type": "timestamptz",
1386
1183
  "unsigned": false,
1387
1184
  "autoincrement": false,
@@ -1445,29 +1242,20 @@
1445
1242
  "mappedType": "datetime"
1446
1243
  }
1447
1244
  },
1448
- "name": "faire_webhook_event",
1245
+ "name": "faire_sync_settings",
1449
1246
  "schema": "public",
1450
1247
  "indexes": [
1451
1248
  {
1452
- "keyName": "IDX_faire_webhook_event_webhook_id_unique",
1453
- "columnNames": [],
1454
- "composite": false,
1455
- "constraint": false,
1456
- "primary": false,
1457
- "unique": false,
1458
- "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_faire_webhook_event_webhook_id_unique\" ON \"faire_webhook_event\" (\"webhook_id\") WHERE deleted_at IS NULL"
1459
- },
1460
- {
1461
- "keyName": "IDX_faire_webhook_event_deleted_at",
1249
+ "keyName": "IDX_faire_sync_settings_deleted_at",
1462
1250
  "columnNames": [],
1463
1251
  "composite": false,
1464
1252
  "constraint": false,
1465
1253
  "primary": false,
1466
1254
  "unique": false,
1467
- "expression": "CREATE INDEX IF NOT EXISTS \"IDX_faire_webhook_event_deleted_at\" ON \"faire_webhook_event\" (\"deleted_at\") WHERE deleted_at IS NULL"
1255
+ "expression": "CREATE INDEX IF NOT EXISTS \"IDX_faire_sync_settings_deleted_at\" ON \"faire_sync_settings\" (\"deleted_at\") WHERE deleted_at IS NULL"
1468
1256
  },
1469
1257
  {
1470
- "keyName": "faire_webhook_event_pkey",
1258
+ "keyName": "faire_sync_settings_pkey",
1471
1259
  "columnNames": [
1472
1260
  "id"
1473
1261
  ],
@@ -0,0 +1,19 @@
1
+ import { Migration } from "@medusajs/framework/mikro-orm/migrations";
2
+
3
+ export class Migration20260709154411 extends Migration {
4
+
5
+ override async up(): Promise<void> {
6
+ this.addSql(`drop table if exists "faire_webhook_event" cascade;`);
7
+
8
+ this.addSql(`alter table if exists "faire_sync_settings" add column if not exists "last_order_sync_at" timestamptz null;`);
9
+ }
10
+
11
+ override async down(): Promise<void> {
12
+ 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"));`);
13
+ 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;`);
14
+ this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_faire_webhook_event_deleted_at" ON "faire_webhook_event" ("deleted_at") WHERE deleted_at IS NULL;`);
15
+
16
+ this.addSql(`alter table if exists "faire_sync_settings" drop column if exists "last_order_sync_at";`);
17
+ }
18
+
19
+ }
@@ -0,0 +1,13 @@
1
+ import { Migration } from "@medusajs/framework/mikro-orm/migrations";
2
+
3
+ export class Migration20260709161201 extends Migration {
4
+
5
+ override async up(): Promise<void> {
6
+ this.addSql(`alter table if exists "faire_sync_account" add column if not exists "auth_mode" text check ("auth_mode" in ('oauth', 'apiKey')) not null default 'oauth';`);
7
+ }
8
+
9
+ override async down(): Promise<void> {
10
+ this.addSql(`alter table if exists "faire_sync_account" drop column if exists "auth_mode";`);
11
+ }
12
+
13
+ }
@@ -6,6 +6,10 @@ const FaireSyncAccount = model.define("faire_sync_account", {
6
6
  brand_name: model.text(),
7
7
  currency: model.text().nullable(),
8
8
  country: model.text().nullable(),
9
+ // How this account authenticates to Faire: OAuth (published apps) or a
10
+ // brand-issued API key (private/single-merchant integrations). Drives which
11
+ // auth header the client sends, so both connection types can coexist.
12
+ auth_mode: model.enum(["oauth", "apiKey"]).default("oauth"),
9
13
  access_token: model.text(),
10
14
  refresh_token: model.text().nullable(),
11
15
  token_expires_at: model.dateTime().nullable(),
@@ -3,7 +3,6 @@ import FaireSyncAccount from "./models/faire-sync-account"
3
3
  import FaireSyncRecord from "./models/faire-sync-record"
4
4
  import FaireSyncSettings from "./models/faire-sync-settings"
5
5
  import FaireSyncBatch from "./models/faire-sync-batch"
6
- import FaireWebhookEvent from "./models/faire-webhook-event"
7
6
  import FaireOrder from "./models/faire-order"
8
7
  import { FaireClient } from "../../lib/faire-client"
9
8
  import { encryptSecret, decryptSecret } from "../../lib/crypto"
@@ -83,7 +82,6 @@ class FaireSyncService extends MedusaService({
83
82
  FaireSyncRecord,
84
83
  FaireSyncSettings,
85
84
  FaireSyncBatch,
86
- FaireWebhookEvent,
87
85
  FaireOrder,
88
86
  }) {
89
87
  protected options_: ModuleOptions
@@ -94,7 +92,15 @@ class FaireSyncService extends MedusaService({
94
92
  this.options_ = resolveFaireOptions(options)
95
93
  }
96
94
 
97
- getClient(): FaireClient {
95
+ /**
96
+ * Build a Faire client. Pass `authModeOverride` (e.g. an account's `auth_mode`)
97
+ * to force the auth header for that connection type; without it, the plugin's
98
+ * configured default is used (cached).
99
+ */
100
+ getClient(authModeOverride?: "oauth" | "apiKey"): FaireClient {
101
+ if (authModeOverride) {
102
+ return new FaireClient({ ...this.options_, authMode: authModeOverride })
103
+ }
98
104
  if (!this.client_) {
99
105
  this.client_ = new FaireClient(this.options_)
100
106
  }
@@ -130,7 +136,11 @@ class FaireSyncService extends MedusaService({
130
136
  }
131
137
  }
132
138
 
133
- async saveAccount(token: TokenData, brand: BrandInfo) {
139
+ async saveAccount(
140
+ token: TokenData,
141
+ brand: BrandInfo,
142
+ authMode: "oauth" | "apiKey" = "oauth"
143
+ ) {
134
144
  const existing = await this.getActiveAccount()
135
145
  const expiresAt =
136
146
  token.expires_in != null
@@ -141,6 +151,7 @@ class FaireSyncService extends MedusaService({
141
151
  brand_name: brand.brand_name,
142
152
  currency: brand.currency ?? null,
143
153
  country: brand.country ?? null,
154
+ auth_mode: authMode,
144
155
  access_token: encryptSecret(token.access_token),
145
156
  refresh_token: encryptSecret(token.refresh_token ?? null),
146
157
  token_expires_at: expiresAt,
@@ -165,8 +176,9 @@ class FaireSyncService extends MedusaService({
165
176
  // Best-effort: a failed revoke must not block local disconnect.
166
177
  try {
167
178
  const accessToken = decryptSecret((account as any).access_token)
168
- if (accessToken && this.options_.authMode !== "apiKey") {
169
- await this.getClient().revokeToken(accessToken)
179
+ // Only OAuth tokens are revocable; a brand-issued API key is not.
180
+ if (accessToken && (account as any).auth_mode !== "apiKey") {
181
+ await this.getClient("oauth").revokeToken(accessToken)
170
182
  }
171
183
  } catch (err: any) {
172
184
  // eslint-disable-next-line no-console
@@ -256,12 +268,8 @@ class FaireSyncService extends MedusaService({
256
268
  }
257
269
 
258
270
  async startOAuth(): Promise<{ authorization_url: string; state: string }> {
259
- if (this.options_.authMode === "apiKey") {
260
- throw new MedusaError(
261
- MedusaError.Types.INVALID_DATA,
262
- "Faire is configured in API-key mode — use /admin/faire/auth/api-key to connect, not OAuth."
263
- )
264
- }
271
+ // Both connection types are available per-account, so OAuth is always
272
+ // offered here; the API-key path is a separate entry point.
265
273
  try {
266
274
  const state = crypto.randomUUID()
267
275
  await this.updateSettings({
@@ -270,7 +278,7 @@ class FaireSyncService extends MedusaService({
270
278
  created_at: Date.now(),
271
279
  },
272
280
  })
273
- const client = this.getClient()
281
+ const client = this.getClient("oauth")
274
282
  return {
275
283
  authorization_url: client.getAuthorizationUrl(state),
276
284
  state,
@@ -292,14 +300,16 @@ class FaireSyncService extends MedusaService({
292
300
  )
293
301
  }
294
302
  try {
295
- const client = this.getClient()
303
+ // Force API-key auth (X-FAIRE-ACCESS-TOKEN) for this connection regardless
304
+ // of the plugin's default mode, and persist it so later API calls use it.
305
+ const client = this.getClient("apiKey")
296
306
  const brand = await client.getBrand(accessToken)
297
307
  const token: TokenData = {
298
308
  access_token: accessToken,
299
309
  token_type: "Bearer",
300
310
  retrieved_at: Date.now(),
301
311
  }
302
- const account = await this.saveAccount(token, brand)
312
+ const account = await this.saveAccount(token, brand, "apiKey")
303
313
  await this.updateSettings({
304
314
  account_id: account.id,
305
315
  default_brand_id: brand.brand_id,
@@ -320,11 +330,12 @@ class FaireSyncService extends MedusaService({
320
330
  "Invalid or expired OAuth state. Please start the Faire connection again."
321
331
  )
322
332
  }
333
+ let token: TokenData | undefined
323
334
  try {
324
335
  const client = this.getClient()
325
- const token = await client.exchangeCodeForToken(code)
336
+ token = await client.exchangeCodeForToken(code)
326
337
  const brand = await client.getBrand(token.access_token)
327
- const account = await this.saveAccount(token, brand)
338
+ const account = await this.saveAccount(token, brand, "oauth")
328
339
  await this.updateSettings({
329
340
  account_id: account.id,
330
341
  default_brand_id: brand.brand_id,
@@ -332,6 +343,17 @@ class FaireSyncService extends MedusaService({
332
343
  })
333
344
  return { account, brand }
334
345
  } catch (err) {
346
+ // Self-heal a dropped OAuth so the next attempt starts clean:
347
+ // 1. clear the pending state (otherwise it sticks and confuses retries), and
348
+ // 2. if the code exchange succeeded but a later step failed, REVOKE the
349
+ // just-obtained token — otherwise Faire keeps the app "installed via an
350
+ // active OAuth access token" and every reconnect fails with that 400.
351
+ await this.updateSettings({ pending_oauth: null }).catch(() => {})
352
+ if (token?.access_token) {
353
+ await this.getClient()
354
+ .revokeToken(token.access_token)
355
+ .catch(() => {})
356
+ }
335
357
  throw toMedusaError(err)
336
358
  }
337
359
  }
@@ -70,7 +70,7 @@ const processBatchStep = createStep(
70
70
  ): Promise<StepResponse<{ synced: number; failed: number }>> => {
71
71
  const service: FaireSyncService = container.resolve(FAIRE_SYNC_MODULE)
72
72
  const account = await service.ensureFreshToken()
73
- const client = service.getClient()
73
+ const client = service.getClient((account as any).auth_mode)
74
74
 
75
75
  // Resolve the incremental window. Precedence:
76
76
  // explicit input > persisted high-water mark > full backfill (undefined).
@@ -26,6 +26,7 @@ type ResolvedConfig = {
26
26
  account_id: string
27
27
  brand_id: string
28
28
  access_token: string
29
+ auth_mode: "oauth" | "apiKey"
29
30
  currency: string | null
30
31
  settings: any
31
32
  }
@@ -66,6 +67,7 @@ const resolveFaireConfigStep = createStep(
66
67
  account_id: account.id,
67
68
  brand_id: account.brand_id,
68
69
  access_token: account.access_token,
70
+ auth_mode: (account.auth_mode as "oauth" | "apiKey") ?? "oauth",
69
71
  currency: account.currency ?? null,
70
72
  settings,
71
73
  })
@@ -211,7 +213,7 @@ const syncProductStep = createStep(
211
213
  { container }
212
214
  ): Promise<StepResponse<SyncResult>> => {
213
215
  const service: FaireSyncService = container.resolve(FAIRE_SYNC_MODULE)
214
- const client = service.getClient()
216
+ const client = service.getClient(input.config.auth_mode)
215
217
  const { access_token, settings } = input.config
216
218
  const { product_input, existing_product_token, product_status } =
217
219
  input.prepared
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const utils_1 = require("@medusajs/framework/utils");
4
- /**
5
- * Durable record of an inbound Faire webhook delivery. `webhook_id` is the
6
- * delivery id Faire sends (unique) so retries are idempotent.
7
- */
8
- const FaireWebhookEvent = utils_1.model.define("faire_webhook_event", {
9
- id: utils_1.model.id().primaryKey(),
10
- webhook_id: utils_1.model.text().unique(),
11
- event_type: utils_1.model.text(),
12
- brand_id: utils_1.model.text().nullable(),
13
- resource_url: utils_1.model.text().nullable(),
14
- payload: utils_1.model.json().nullable(),
15
- resource: utils_1.model.json().nullable(),
16
- processed: utils_1.model.boolean().default(false),
17
- error: utils_1.model.text().nullable(),
18
- received_at: utils_1.model.dateTime().nullable(),
19
- });
20
- exports.default = FaireWebhookEvent;
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpcmUtd2ViaG9vay1ldmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2ZhaXJlLXN5bmMvbW9kZWxzL2ZhaXJlLXdlYmhvb2stZXZlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxxREFBaUQ7QUFFakQ7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxhQUFLLENBQUMsTUFBTSxDQUFDLHFCQUFxQixFQUFFO0lBQzVELEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQzNCLFVBQVUsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxFQUFFO0lBQ2pDLFVBQVUsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3hCLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2pDLFlBQVksRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ3JDLE9BQU8sRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2hDLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2pDLFNBQVMsRUFBRSxhQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUN6QyxLQUFLLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM5QixXQUFXLEVBQUUsYUFBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUN6QyxDQUFDLENBQUE7QUFFRixrQkFBZSxpQkFBaUIsQ0FBQSJ9