@whatalo/plugin-sdk 1.1.0 → 1.2.1
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/dist/adapters/express.cjs +101 -10
- package/dist/adapters/express.cjs.map +1 -1
- package/dist/adapters/express.d.cts +9 -7
- package/dist/adapters/express.d.ts +9 -7
- package/dist/adapters/express.mjs +104 -10
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/hono.cjs +94 -7
- package/dist/adapters/hono.cjs.map +1 -1
- package/dist/adapters/hono.d.cts +4 -3
- package/dist/adapters/hono.d.ts +4 -3
- package/dist/adapters/hono.mjs +97 -7
- package/dist/adapters/hono.mjs.map +1 -1
- package/dist/adapters/nextjs.cjs +94 -7
- package/dist/adapters/nextjs.cjs.map +1 -1
- package/dist/adapters/nextjs.d.cts +4 -3
- package/dist/adapters/nextjs.d.ts +4 -3
- package/dist/adapters/nextjs.mjs +97 -7
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/bridge/index.cjs +33 -2
- package/dist/bridge/index.cjs.map +1 -1
- package/dist/bridge/index.d.cts +17 -5
- package/dist/bridge/index.d.ts +17 -5
- package/dist/bridge/index.mjs +33 -2
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/client/index.cjs +36 -2
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +31 -4
- package/dist/client/index.d.ts +31 -4
- package/dist/client/index.mjs +36 -2
- package/dist/client/index.mjs.map +1 -1
- package/dist/index.cjs +150 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.mjs +150 -25
- package/dist/index.mjs.map +1 -1
- package/dist/manifest/index.cjs +2 -17
- package/dist/manifest/index.cjs.map +1 -1
- package/dist/manifest/index.d.cts +10 -4
- package/dist/manifest/index.d.ts +10 -4
- package/dist/manifest/index.mjs +2 -17
- package/dist/manifest/index.mjs.map +1 -1
- package/dist/{types-M1eLMz6w.d.cts → types-B8BAV362.d.cts} +39 -3
- package/dist/{types-M1eLMz6w.d.ts → types-B8BAV362.d.ts} +39 -3
- package/dist/types-BU71_xQm.d.cts +25 -0
- package/dist/types-BhtVJPgF.d.ts +25 -0
- package/dist/types-Bo9GbqrM.d.ts +133 -0
- package/dist/types-rA6kVlpV.d.cts +133 -0
- package/dist/webhooks/index.cjs +78 -3
- package/dist/webhooks/index.cjs.map +1 -1
- package/dist/webhooks/index.d.cts +11 -4
- package/dist/webhooks/index.d.ts +11 -4
- package/dist/webhooks/index.mjs +78 -3
- package/dist/webhooks/index.mjs.map +1 -1
- package/package.json +32 -15
- package/dist/types-D2Efg3EG.d.ts +0 -19
- package/dist/types-DZ659i6f.d.ts +0 -68
- package/dist/types-Db_BeRCj.d.cts +0 -19
- package/dist/types-DdqKKyqX.d.cts +0 -68
package/dist/index.mjs
CHANGED
|
@@ -111,6 +111,8 @@ var WhataloClient = class {
|
|
|
111
111
|
inventory;
|
|
112
112
|
/** Webhook resource methods */
|
|
113
113
|
webhooks;
|
|
114
|
+
/** Geo reference data methods */
|
|
115
|
+
geo;
|
|
114
116
|
constructor(options) {
|
|
115
117
|
if (typeof window !== "undefined" && typeof process === "undefined") {
|
|
116
118
|
console.warn(
|
|
@@ -132,6 +134,7 @@ var WhataloClient = class {
|
|
|
132
134
|
this.store = new StoreResource(this);
|
|
133
135
|
this.inventory = new InventoryResource(this);
|
|
134
136
|
this.webhooks = new WebhookResource(this);
|
|
137
|
+
this.geo = new GeoResource(this);
|
|
135
138
|
}
|
|
136
139
|
/**
|
|
137
140
|
* Internal request method shared by all resource namespaces.
|
|
@@ -291,6 +294,9 @@ var OrderResource = class {
|
|
|
291
294
|
async updateStatus(id, data) {
|
|
292
295
|
return this.client.request("PATCH", `/orders/${id}`, { body: data });
|
|
293
296
|
}
|
|
297
|
+
async updatePaymentStatus(id, data) {
|
|
298
|
+
return this.client.request("PATCH", `/orders/${id}`, { body: data });
|
|
299
|
+
}
|
|
294
300
|
async count(status) {
|
|
295
301
|
return this.client.request("GET", "/orders/count", {
|
|
296
302
|
params: status ? { status } : void 0
|
|
@@ -370,10 +376,10 @@ var InventoryResource = class {
|
|
|
370
376
|
this.client = client;
|
|
371
377
|
}
|
|
372
378
|
async get(productId) {
|
|
373
|
-
return this.client.request("GET", `/products/${productId}
|
|
379
|
+
return this.client.request("GET", `/inventory/products/${productId}`);
|
|
374
380
|
}
|
|
375
381
|
async adjust(productId, data) {
|
|
376
|
-
return this.client.request("PATCH", `/products/${productId}
|
|
382
|
+
return this.client.request("PATCH", `/inventory/products/${productId}`, {
|
|
377
383
|
body: data
|
|
378
384
|
});
|
|
379
385
|
}
|
|
@@ -395,17 +401,57 @@ var WebhookResource = class {
|
|
|
395
401
|
return this.client.request("DELETE", `/webhooks/${id}`);
|
|
396
402
|
}
|
|
397
403
|
};
|
|
404
|
+
var GeoResource = class {
|
|
405
|
+
constructor(client) {
|
|
406
|
+
this.client = client;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* List countries.
|
|
410
|
+
* By default returns only supported countries (is_supported=true).
|
|
411
|
+
* Pass `{ all: true }` to retrieve all 250 countries.
|
|
412
|
+
*/
|
|
413
|
+
async listCountries(params) {
|
|
414
|
+
return this.client.request("GET", "/geo/countries", {
|
|
415
|
+
params: params?.all !== void 0 ? { all: params.all } : void 0
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Get a single country by ISO 3166-1 alpha-2 code.
|
|
420
|
+
*/
|
|
421
|
+
async getCountry(iso2) {
|
|
422
|
+
return this.client.request("GET", `/geo/countries/${iso2.toUpperCase()}`);
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* List provinces (states, departments, regions) for a country.
|
|
426
|
+
* Returns an empty array for countries with no province data.
|
|
427
|
+
*/
|
|
428
|
+
async listProvinces(countryIso2) {
|
|
429
|
+
return this.client.request("GET", `/geo/countries/${countryIso2.toUpperCase()}/provinces`);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
398
432
|
|
|
399
433
|
// src/webhooks/verify.ts
|
|
400
434
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
435
|
+
var DEFAULT_TOLERANCE_SECONDS = 300;
|
|
401
436
|
function verifyWebhook({
|
|
402
437
|
payload,
|
|
403
438
|
signature,
|
|
404
|
-
|
|
439
|
+
timestamp,
|
|
440
|
+
secret,
|
|
441
|
+
toleranceSeconds = DEFAULT_TOLERANCE_SECONDS,
|
|
442
|
+
currentTime = Math.floor(Date.now() / 1e3)
|
|
405
443
|
}) {
|
|
406
|
-
if (!payload || !signature || !secret) return false;
|
|
407
|
-
const
|
|
444
|
+
if (!payload || !signature || !secret || timestamp === "") return false;
|
|
445
|
+
const timestampString = String(timestamp);
|
|
446
|
+
const timestampValue = typeof timestamp === "number" ? timestamp : Number(timestamp);
|
|
447
|
+
if (!Number.isInteger(timestampValue)) return false;
|
|
448
|
+
if (!Number.isFinite(toleranceSeconds) || toleranceSeconds < 0) return false;
|
|
449
|
+
if (!Number.isFinite(currentTime)) return false;
|
|
450
|
+
const ageSeconds = Math.abs(currentTime - timestampValue);
|
|
451
|
+
if (ageSeconds > toleranceSeconds) return false;
|
|
452
|
+
const expected = createHmac("sha256", secret).update(`${timestampString}.${payload}`, "utf8").digest("hex");
|
|
408
453
|
if (expected.length !== signature.length) return false;
|
|
454
|
+
if (!/^[a-f0-9]+$/i.test(signature)) return false;
|
|
409
455
|
try {
|
|
410
456
|
return timingSafeEqual(
|
|
411
457
|
Buffer.from(expected, "hex"),
|
|
@@ -416,7 +462,68 @@ function verifyWebhook({
|
|
|
416
462
|
}
|
|
417
463
|
}
|
|
418
464
|
|
|
465
|
+
// src/webhooks/types.ts
|
|
466
|
+
import {
|
|
467
|
+
PUBLIC_WEBHOOK_EVENTS,
|
|
468
|
+
isPublicWebhookEvent
|
|
469
|
+
} from "@whatalo/protocol/events";
|
|
470
|
+
var WEBHOOK_EVENTS = PUBLIC_WEBHOOK_EVENTS;
|
|
471
|
+
function isWebhookEvent(value) {
|
|
472
|
+
return isPublicWebhookEvent(value);
|
|
473
|
+
}
|
|
474
|
+
function isRecord(value) {
|
|
475
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
476
|
+
}
|
|
477
|
+
function hasStringId(value) {
|
|
478
|
+
return isRecord(value) && typeof value.id === "string";
|
|
479
|
+
}
|
|
480
|
+
function isOptionalString(value, key) {
|
|
481
|
+
return value[key] === void 0 || typeof value[key] === "string";
|
|
482
|
+
}
|
|
483
|
+
function isRuntimeWebhookStore(value) {
|
|
484
|
+
return isRecord(value) && typeof value.id === "string" && typeof value.timezone === "string" && (value.name === void 0 || typeof value.name === "string");
|
|
485
|
+
}
|
|
486
|
+
function hasValidBasePayloadFields(value) {
|
|
487
|
+
if (!isOptionalString(value, "event_id")) return false;
|
|
488
|
+
if (!isOptionalString(value, "occurred_at")) return false;
|
|
489
|
+
return isRuntimeWebhookStore(value.store);
|
|
490
|
+
}
|
|
491
|
+
function isRuntimeOrderWebhookPayload(value) {
|
|
492
|
+
return hasValidBasePayloadFields(value) && hasStringId(value.order) && (value.customer === void 0 || hasStringId(value.customer));
|
|
493
|
+
}
|
|
494
|
+
function isRuntimeProductWebhookPayload(value) {
|
|
495
|
+
return hasValidBasePayloadFields(value) && hasStringId(value.product);
|
|
496
|
+
}
|
|
497
|
+
function isRuntimeCustomerWebhookPayload(value) {
|
|
498
|
+
return hasValidBasePayloadFields(value) && hasStringId(value.customer);
|
|
499
|
+
}
|
|
500
|
+
function isRuntimeCheckoutCompletedWebhookPayload(value) {
|
|
501
|
+
return hasValidBasePayloadFields(value) && hasStringId(value.order) && hasStringId(value.customer) && isRuntimeWebhookStore(value.store);
|
|
502
|
+
}
|
|
503
|
+
function isRuntimeWebhookPayload(value, event) {
|
|
504
|
+
if (!isRecord(value)) return false;
|
|
505
|
+
switch (event) {
|
|
506
|
+
case WEBHOOK_EVENTS.ORDER_CREATED:
|
|
507
|
+
case WEBHOOK_EVENTS.ORDER_UPDATED:
|
|
508
|
+
case WEBHOOK_EVENTS.ORDER_CANCELLED:
|
|
509
|
+
case WEBHOOK_EVENTS.ORDER_COMPLETED:
|
|
510
|
+
return isRuntimeOrderWebhookPayload(value);
|
|
511
|
+
case WEBHOOK_EVENTS.PRODUCT_CREATED:
|
|
512
|
+
case WEBHOOK_EVENTS.PRODUCT_UPDATED:
|
|
513
|
+
case WEBHOOK_EVENTS.PRODUCT_DELETED:
|
|
514
|
+
return isRuntimeProductWebhookPayload(value);
|
|
515
|
+
case WEBHOOK_EVENTS.CUSTOMER_CREATED:
|
|
516
|
+
case WEBHOOK_EVENTS.CUSTOMER_UPDATED:
|
|
517
|
+
return isRuntimeCustomerWebhookPayload(value);
|
|
518
|
+
case WEBHOOK_EVENTS.CHECKOUT_COMPLETED:
|
|
519
|
+
return isRuntimeCheckoutCompletedWebhookPayload(value);
|
|
520
|
+
default:
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
419
525
|
// src/manifest/validate.ts
|
|
526
|
+
import { SCOPE_LIST } from "@whatalo/protocol/scopes";
|
|
420
527
|
var ManifestValidationError = class extends Error {
|
|
421
528
|
errors;
|
|
422
529
|
constructor(errors) {
|
|
@@ -429,23 +536,7 @@ var ManifestValidationError = class extends Error {
|
|
|
429
536
|
var ID_REGEX = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
|
|
430
537
|
var SEMVER_REGEX = /^\d+\.\d+\.\d+$/;
|
|
431
538
|
var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
432
|
-
var VALID_PERMISSIONS =
|
|
433
|
-
"read:products",
|
|
434
|
-
"write:products",
|
|
435
|
-
"read:orders",
|
|
436
|
-
"write:orders",
|
|
437
|
-
"read:customers",
|
|
438
|
-
"write:customers",
|
|
439
|
-
"read:inventory",
|
|
440
|
-
"write:inventory",
|
|
441
|
-
"read:store",
|
|
442
|
-
"write:store",
|
|
443
|
-
"read:webhooks",
|
|
444
|
-
"write:webhooks",
|
|
445
|
-
"read:discounts",
|
|
446
|
-
"write:discounts",
|
|
447
|
-
"read:analytics"
|
|
448
|
-
]);
|
|
539
|
+
var VALID_PERMISSIONS = new Set(SCOPE_LIST.map((s) => s.token));
|
|
449
540
|
var VALID_CATEGORIES = /* @__PURE__ */ new Set([
|
|
450
541
|
"analytics",
|
|
451
542
|
"marketing",
|
|
@@ -540,8 +631,11 @@ var DATA_RESOURCE_SCOPE = {
|
|
|
540
631
|
products: "read:products",
|
|
541
632
|
orders: "read:orders",
|
|
542
633
|
customers: "read:customers",
|
|
543
|
-
categories: "read:products"
|
|
634
|
+
categories: "read:products",
|
|
544
635
|
// categories share the products scope
|
|
636
|
+
store: "read:store",
|
|
637
|
+
geo: "read:store"
|
|
638
|
+
// geo is global reference data, scoped to read:store
|
|
545
639
|
};
|
|
546
640
|
var BILLING_OPERATION = {
|
|
547
641
|
GET_PLANS: "getPlans",
|
|
@@ -953,16 +1047,44 @@ function useWhataloData() {
|
|
|
953
1047
|
},
|
|
954
1048
|
[fetchResource]
|
|
955
1049
|
);
|
|
1050
|
+
const storeGet = useCallback3(async () => {
|
|
1051
|
+
const ack = await fetchResource("store", "get");
|
|
1052
|
+
return extractAckData(ack);
|
|
1053
|
+
}, [fetchResource]);
|
|
1054
|
+
const geoCountries = useCallback3(
|
|
1055
|
+
async (params) => {
|
|
1056
|
+
const ack = await fetchResource(
|
|
1057
|
+
"geo",
|
|
1058
|
+
"list",
|
|
1059
|
+
{ ...params, _sub: "countries" }
|
|
1060
|
+
);
|
|
1061
|
+
return extractAckData(ack);
|
|
1062
|
+
},
|
|
1063
|
+
[fetchResource]
|
|
1064
|
+
);
|
|
1065
|
+
const geoProvinces = useCallback3(
|
|
1066
|
+
async (countryIso2) => {
|
|
1067
|
+
const ack = await fetchResource(
|
|
1068
|
+
"geo",
|
|
1069
|
+
"list",
|
|
1070
|
+
{ _sub: "provinces", country: countryIso2 }
|
|
1071
|
+
);
|
|
1072
|
+
return extractAckData(ack);
|
|
1073
|
+
},
|
|
1074
|
+
[fetchResource]
|
|
1075
|
+
);
|
|
956
1076
|
return {
|
|
957
1077
|
products: { list: productsList, get: productsGet },
|
|
958
1078
|
orders: { list: ordersList, get: ordersGet },
|
|
959
1079
|
customers: { list: customersList, get: customersGet },
|
|
960
|
-
categories: { list: categoriesList, get: categoriesGet }
|
|
1080
|
+
categories: { list: categoriesList, get: categoriesGet },
|
|
1081
|
+
store: { get: storeGet },
|
|
1082
|
+
geo: { countries: geoCountries, provinces: geoProvinces }
|
|
961
1083
|
};
|
|
962
1084
|
}
|
|
963
1085
|
|
|
964
1086
|
// src/index.ts
|
|
965
|
-
var SDK_VERSION = "
|
|
1087
|
+
var SDK_VERSION = "1.2.0";
|
|
966
1088
|
export {
|
|
967
1089
|
AuthenticationError,
|
|
968
1090
|
AuthorizationError,
|
|
@@ -974,10 +1096,13 @@ export {
|
|
|
974
1096
|
RateLimitError,
|
|
975
1097
|
SDK_VERSION,
|
|
976
1098
|
ValidationError,
|
|
1099
|
+
WEBHOOK_EVENTS,
|
|
977
1100
|
WhataloAPIError,
|
|
978
1101
|
WhataloClient,
|
|
979
1102
|
clearSessionTokenCache,
|
|
980
1103
|
defineApp,
|
|
1104
|
+
isRuntimeWebhookPayload,
|
|
1105
|
+
isWebhookEvent,
|
|
981
1106
|
sessionToken,
|
|
982
1107
|
useAppBridge,
|
|
983
1108
|
useWhataloAction,
|