@01.software/sdk 0.32.0 → 0.33.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/README.md +43 -20
- package/dist/client.cjs +31 -2
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +6 -6
- package/dist/client.d.ts +6 -6
- package/dist/client.js +31 -2
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-DPGXnhoF.d.ts → collection-client-B6SlhzIP.d.ts} +3 -3
- package/dist/{collection-client-CORhppPb.d.cts → collection-client-De6eKW1J.d.cts} +3 -3
- package/dist/{const-Brk2Ff0q.d.cts → const-DwmSDeWq.d.ts} +2 -2
- package/dist/{const-DcY2_z9O.d.ts → const-sPR2IkCe.d.cts} +2 -2
- package/dist/index.cjs +256 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +256 -90
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-DVK1QCeU.d.cts → payload-types-dkeQyrDC.d.cts} +1562 -1436
- package/dist/{payload-types-DVK1QCeU.d.ts → payload-types-dkeQyrDC.d.ts} +1562 -1436
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +9 -9
- package/dist/query.d.ts +9 -9
- package/dist/query.js.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/server.cjs +37 -6
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +7 -7
- package/dist/server.d.ts +7 -7
- package/dist/server.js +37 -6
- package/dist/server.js.map +1 -1
- package/dist/{types-ByMrR_Z_.d.cts → types-B3YT092I.d.cts} +1 -1
- package/dist/{types-CYMSBkJC.d.ts → types-BHh0YLmq.d.ts} +27 -10
- package/dist/{types-CAkWqIr6.d.cts → types-BZKxss8Y.d.cts} +27 -10
- package/dist/{types-DUPC7Xn6.d.ts → types-Cel_4L9t.d.ts} +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/webhook.cjs +94 -0
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +82 -7
- package/dist/webhook.d.ts +82 -7
- package/dist/webhook.js +94 -0
- package/dist/webhook.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as Product, C as CustomerProfile, a as CustomerProfileList, b as ProductCollection, c as Post, d as Comment, R as Reaction, e as Config } from './payload-types-
|
|
1
|
+
import { P as Product, C as CustomerProfile, a as CustomerProfileList, b as ProductCollection, c as Post, d as Comment, R as Reaction, e as Config } from './payload-types-dkeQyrDC.cjs';
|
|
2
2
|
|
|
3
3
|
type PublicCustomerProfile = Omit<CustomerProfile, 'tenant' | 'customer' | 'isPublic' | 'anonymizedAt' | 'metadata'>;
|
|
4
4
|
type PublicProfileRelation = string | PublicCustomerProfile;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as PublicCollection } from './const-
|
|
2
|
-
import { P as PublicProduct, C as CollectionType } from './types-
|
|
3
|
-
import { O as Order, i as Cart, j as CartItem, m as Transaction, n as Fulfillment, o as Return } from './payload-types-
|
|
1
|
+
import { P as PublicCollection } from './const-DwmSDeWq.js';
|
|
2
|
+
import { P as PublicProduct, C as CollectionType } from './types-Cel_4L9t.js';
|
|
3
|
+
import { O as Order, i as Cart, j as CartItem, m as Transaction, n as Fulfillment, o as Return } from './payload-types-dkeQyrDC.js';
|
|
4
4
|
|
|
5
5
|
interface CommunityClientOptions {
|
|
6
6
|
publishableKey?: string;
|
|
@@ -504,10 +504,12 @@ type ProductListingSwatch = {
|
|
|
504
504
|
href: string;
|
|
505
505
|
availableForSale: boolean;
|
|
506
506
|
};
|
|
507
|
+
type ProductListingCardRepresentativeVariant = ProductListingGroupsItem['groups'][number]['variants'][number];
|
|
507
508
|
type ProductListingCard = {
|
|
508
509
|
id: EntityID;
|
|
509
510
|
href: string;
|
|
510
511
|
title: string;
|
|
512
|
+
representativeVariant?: ProductListingCardRepresentativeVariant | null;
|
|
511
513
|
primaryImage: ProductDetailMedia | null;
|
|
512
514
|
priceRange: ProductListingCardPriceRange;
|
|
513
515
|
availableForSale: boolean;
|
|
@@ -810,8 +812,9 @@ interface ProductDetail {
|
|
|
810
812
|
content?: unknown;
|
|
811
813
|
publishedAt?: string | null;
|
|
812
814
|
status: string;
|
|
813
|
-
totalInventory: number;
|
|
815
|
+
totalInventory: number | null;
|
|
814
816
|
totalVariants: number;
|
|
817
|
+
hasUnlimitedVariant: boolean;
|
|
815
818
|
hasOnlyDefaultVariant: boolean;
|
|
816
819
|
};
|
|
817
820
|
variants: ProductDetailVariant[];
|
|
@@ -823,6 +826,14 @@ interface ProductDetail {
|
|
|
823
826
|
videos: ProductDetailVideo[];
|
|
824
827
|
listing: ProductDetailListing;
|
|
825
828
|
}
|
|
829
|
+
type ProductDetailUnavailableReason = 'not_found' | 'not_published' | 'feature_disabled';
|
|
830
|
+
type ProductDetailResult = {
|
|
831
|
+
found: true;
|
|
832
|
+
product: ProductDetail;
|
|
833
|
+
} | {
|
|
834
|
+
found: false;
|
|
835
|
+
reason: ProductDetailUnavailableReason;
|
|
836
|
+
};
|
|
826
837
|
type ProductUpsertOptionValueInput = {
|
|
827
838
|
id?: string;
|
|
828
839
|
value: string;
|
|
@@ -889,11 +900,15 @@ declare class ProductApi extends BaseApi {
|
|
|
889
900
|
listingGroups(params: ListingGroupsParams): Promise<ProductListingGroupsResponse>;
|
|
890
901
|
/**
|
|
891
902
|
* Fetch full product detail by slug or id.
|
|
892
|
-
* Returns
|
|
893
|
-
*
|
|
894
|
-
*
|
|
903
|
+
* Returns a discriminated result so storefronts can distinguish missing,
|
|
904
|
+
* unpublished, and feature-disabled products.
|
|
905
|
+
*
|
|
906
|
+
* Only product-detail 404 responses carrying one of those allowlisted reasons
|
|
907
|
+
* are mapped to `{ found: false, reason }`. Unknown or uncoded 404s, plus
|
|
908
|
+
* permission/auth errors such as tenant mismatch, continue to throw typed SDK
|
|
909
|
+
* errors instead of being collapsed into a storefront absence result.
|
|
895
910
|
*/
|
|
896
|
-
detail(params: ProductDetailParams): Promise<
|
|
911
|
+
detail(params: ProductDetailParams): Promise<ProductDetailResult>;
|
|
897
912
|
/**
|
|
898
913
|
* Atomically create or update a product together with its options,
|
|
899
914
|
* option-values, and variants in a single transaction. Mirrors Shopify's
|
|
@@ -1019,6 +1034,7 @@ type ReturnWithRefundItem = {
|
|
|
1019
1034
|
orderItem: string | number;
|
|
1020
1035
|
quantity: number;
|
|
1021
1036
|
restockAction?: RestockAction;
|
|
1037
|
+
restockingFee?: number;
|
|
1022
1038
|
};
|
|
1023
1039
|
type ReturnWithRefundParams = {
|
|
1024
1040
|
orderNumber: string;
|
|
@@ -1026,6 +1042,7 @@ type ReturnWithRefundParams = {
|
|
|
1026
1042
|
reasonDetail?: string;
|
|
1027
1043
|
returnItems: ReturnWithRefundItem[];
|
|
1028
1044
|
refundAmount: number;
|
|
1045
|
+
returnShippingFee?: number;
|
|
1029
1046
|
pgPaymentId: string;
|
|
1030
1047
|
paymentKey?: string;
|
|
1031
1048
|
refundReceiptUrl?: string;
|
|
@@ -1110,7 +1127,7 @@ declare class CommerceClient {
|
|
|
1110
1127
|
readonly product: {
|
|
1111
1128
|
stockCheck: (params: StockCheckParams) => Promise<StockCheckResponse>;
|
|
1112
1129
|
listingGroups: (params: ListingGroupsParams) => Promise<ProductListingGroupsResponse>;
|
|
1113
|
-
detail: (params: ProductDetailParams) => Promise<
|
|
1130
|
+
detail: (params: ProductDetailParams) => Promise<ProductDetailResult>;
|
|
1114
1131
|
};
|
|
1115
1132
|
readonly cart: {
|
|
1116
1133
|
get: (cartId: string) => Promise<Cart>;
|
|
@@ -1319,4 +1336,4 @@ type DeepPartial<T> = {
|
|
|
1319
1336
|
};
|
|
1320
1337
|
type ExtractArrayType<T> = T extends (infer U)[] ? U : never;
|
|
1321
1338
|
|
|
1322
|
-
export { type NormalizedProductSelection as $, type ApiQueryOptions as A, BaseApi as B, CommerceClient as C, type DebugConfig as D, type ExtractArrayType as E, type CreateFulfillmentParams as F, type CreateOrderItem as G, type CreateOrderParams as H, type CreateReturnParams as I, CustomerAuth as J, type CustomerAuthOptions as K, type CustomerAuthResponse as L, type CustomerLoginData as M, type CustomerProfile as N, type CustomerRefreshResponse as O, type PayloadFindResponse as P, type CustomerRegisterData as Q, type RetryConfig as R, type Sort as S, type CustomerRegisterResponse as T, type CustomerSnapshot as U, DiscountApi as V, type Where as W, type DiscountApiOptions as X, type LegacyProductSelectionParamEvent as Y, type ListingGroupingState as Z, type ListingGroupsParams as _, CommunityClient as a, type
|
|
1339
|
+
export { type NormalizedProductSelection as $, type ApiQueryOptions as A, BaseApi as B, CommerceClient as C, type DebugConfig as D, type ExtractArrayType as E, type CreateFulfillmentParams as F, type CreateOrderItem as G, type CreateOrderParams as H, type CreateReturnParams as I, CustomerAuth as J, type CustomerAuthOptions as K, type CustomerAuthResponse as L, type CustomerLoginData as M, type CustomerProfile as N, type CustomerRefreshResponse as O, type PayloadFindResponse as P, type CustomerRegisterData as Q, type RetryConfig as R, type Sort as S, type CustomerRegisterResponse as T, type CustomerSnapshot as U, DiscountApi as V, type Where as W, type DiscountApiOptions as X, type LegacyProductSelectionParamEvent as Y, type ListingGroupingState as Z, type ListingGroupsParams as _, CommunityClient as a, type UpdateItemParams as a$, OrderApi as a0, type OrderApiOptions as a1, ProductApi as a2, type ProductApiOptions as a3, type ProductDetail as a4, type ProductDetailBrand as a5, type ProductDetailCategory as a6, type ProductDetailImage as a7, type ProductDetailImageMedia as a8, type ProductDetailListing as a9, type ProductOptionMatrixOption as aA, type ProductOptionMatrixValue as aB, type ProductOptionMatrixVariant as aC, type ProductOptionShape as aD, type ProductOptionValueShape as aE, type ProductSelectionAvailableValue as aF, type ProductSelectionByOptionValue as aG, ProductSelectionCodecError as aH, type ProductSelectionCodecOptions as aI, type ProductSelectionInput as aJ, type ProductSelectionResolution as aK, type ProductSelectionResolutionContext as aL, type ProductVariantShape as aM, type RemoveDiscountParams as aN, type RemoveItemParams as aO, type RequestOptions as aP, type ReturnItem as aQ, type ReturnReason as aR, type ReturnWithRefundItem as aS, type ReturnWithRefundParams as aT, type ServerApiOptions as aU, ShippingApi as aV, type ShippingApiOptions as aW, type StockCheckParams as aX, type StockCheckResponse as aY, type StockCheckResult as aZ, type UpdateFulfillmentParams as a_, type ProductDetailMedia as aa, type ProductDetailOption as ab, type ProductDetailOptionValue as ac, type ProductDetailParams as ad, type ProductDetailResult as ae, type ProductDetailTag as af, type ProductDetailUnavailableReason as ag, type ProductDetailVariant as ah, type ProductDetailVariantOptionValue as ai, type ProductDetailVideo as aj, type ProductHrefGroup as ak, type ProductHrefOptions as al, type ProductHrefProduct as am, type ProductListingCard as an, type ProductListingCardPriceRange as ao, type ProductListingCardRepresentativeVariant as ap, type ProductListingGroup as aq, type ProductListingGroupSummary as ar, type ProductListingGroupVariant as as, type ProductListingGroupsItem as at, type ProductListingGroupsProduct as au, type ProductListingGroupsResponse as av, type ProductListingProductShape as aw, type ProductListingProjection as ax, type ProductListingSwatch as ay, type ProductOptionMatrix as az, CustomerNamespace as b, type UpdateOrderParams as b0, type UpdateProfileData as b1, type UpdateReturnParams as b2, type UpdateTransactionParams as b3, type ValidateDiscountParams as b4, type ValidateDiscountResult as b5, buildProductHref as b6, buildProductListingCard as b7, buildProductListingGroupsByOption as b8, buildProductListingProjection as b9, buildProductOptionMatrix as ba, buildProductOptionMatrixFromDetail as bb, createProductSelectionCodec as bc, getAvailableOptionValues as bd, getProductSelectionImages as be, getSelectedValueByOptionId as bf, normalizeProductSelection as bg, normalizeProductSelectionFromMatrix as bh, normalizeSelectedValueIds as bi, parseProductSelection as bj, resolveProductSelection as bk, resolveProductSelectionFromMatrix as bl, resolveVariantForSelection as bm, stringifyProductSelection as bn, type ProductDetailPreviewParams as bo, type ProductDetailPreviewOptions as bp, type ProductUpsertParams as bq, type ProductUpsertResponse as br, type ClientServerConfig as bs, type ClientState as c, type ClientConfig as d, type ClientMetadata as e, type DeepPartial as f, type PayloadMutationResponse as g, type RootClient as h, type RootCollectionClient as i, type RootReadOnlyQueryBuilder as j, type AddItemParams as k, type ApplyDiscountParams as l, type BulkImportFulfillmentsParams as m, type BulkImportFulfillmentsResponse as n, type CalculateShippingParams as o, type CalculateShippingResult as p, CartApi as q, type CartApiOptions as r, type CheckoutParams as s, type ClearCartParams as t, type CommerceClientOptions as u, type CommunityClientOptions as v, type CommunityPost as w, type CompatibilityProductSelectionParamEvent as x, type ConfirmPaymentParams as y, type ConfirmPaymentResponse as z };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as PublicCollection } from './const-
|
|
2
|
-
import { P as PublicProduct, C as CollectionType } from './types-
|
|
3
|
-
import { O as Order, i as Cart, j as CartItem, m as Transaction, n as Fulfillment, o as Return } from './payload-types-
|
|
1
|
+
import { P as PublicCollection } from './const-sPR2IkCe.cjs';
|
|
2
|
+
import { P as PublicProduct, C as CollectionType } from './types-B3YT092I.cjs';
|
|
3
|
+
import { O as Order, i as Cart, j as CartItem, m as Transaction, n as Fulfillment, o as Return } from './payload-types-dkeQyrDC.cjs';
|
|
4
4
|
|
|
5
5
|
interface CommunityClientOptions {
|
|
6
6
|
publishableKey?: string;
|
|
@@ -504,10 +504,12 @@ type ProductListingSwatch = {
|
|
|
504
504
|
href: string;
|
|
505
505
|
availableForSale: boolean;
|
|
506
506
|
};
|
|
507
|
+
type ProductListingCardRepresentativeVariant = ProductListingGroupsItem['groups'][number]['variants'][number];
|
|
507
508
|
type ProductListingCard = {
|
|
508
509
|
id: EntityID;
|
|
509
510
|
href: string;
|
|
510
511
|
title: string;
|
|
512
|
+
representativeVariant?: ProductListingCardRepresentativeVariant | null;
|
|
511
513
|
primaryImage: ProductDetailMedia | null;
|
|
512
514
|
priceRange: ProductListingCardPriceRange;
|
|
513
515
|
availableForSale: boolean;
|
|
@@ -810,8 +812,9 @@ interface ProductDetail {
|
|
|
810
812
|
content?: unknown;
|
|
811
813
|
publishedAt?: string | null;
|
|
812
814
|
status: string;
|
|
813
|
-
totalInventory: number;
|
|
815
|
+
totalInventory: number | null;
|
|
814
816
|
totalVariants: number;
|
|
817
|
+
hasUnlimitedVariant: boolean;
|
|
815
818
|
hasOnlyDefaultVariant: boolean;
|
|
816
819
|
};
|
|
817
820
|
variants: ProductDetailVariant[];
|
|
@@ -823,6 +826,14 @@ interface ProductDetail {
|
|
|
823
826
|
videos: ProductDetailVideo[];
|
|
824
827
|
listing: ProductDetailListing;
|
|
825
828
|
}
|
|
829
|
+
type ProductDetailUnavailableReason = 'not_found' | 'not_published' | 'feature_disabled';
|
|
830
|
+
type ProductDetailResult = {
|
|
831
|
+
found: true;
|
|
832
|
+
product: ProductDetail;
|
|
833
|
+
} | {
|
|
834
|
+
found: false;
|
|
835
|
+
reason: ProductDetailUnavailableReason;
|
|
836
|
+
};
|
|
826
837
|
type ProductUpsertOptionValueInput = {
|
|
827
838
|
id?: string;
|
|
828
839
|
value: string;
|
|
@@ -889,11 +900,15 @@ declare class ProductApi extends BaseApi {
|
|
|
889
900
|
listingGroups(params: ListingGroupsParams): Promise<ProductListingGroupsResponse>;
|
|
890
901
|
/**
|
|
891
902
|
* Fetch full product detail by slug or id.
|
|
892
|
-
* Returns
|
|
893
|
-
*
|
|
894
|
-
*
|
|
903
|
+
* Returns a discriminated result so storefronts can distinguish missing,
|
|
904
|
+
* unpublished, and feature-disabled products.
|
|
905
|
+
*
|
|
906
|
+
* Only product-detail 404 responses carrying one of those allowlisted reasons
|
|
907
|
+
* are mapped to `{ found: false, reason }`. Unknown or uncoded 404s, plus
|
|
908
|
+
* permission/auth errors such as tenant mismatch, continue to throw typed SDK
|
|
909
|
+
* errors instead of being collapsed into a storefront absence result.
|
|
895
910
|
*/
|
|
896
|
-
detail(params: ProductDetailParams): Promise<
|
|
911
|
+
detail(params: ProductDetailParams): Promise<ProductDetailResult>;
|
|
897
912
|
/**
|
|
898
913
|
* Atomically create or update a product together with its options,
|
|
899
914
|
* option-values, and variants in a single transaction. Mirrors Shopify's
|
|
@@ -1019,6 +1034,7 @@ type ReturnWithRefundItem = {
|
|
|
1019
1034
|
orderItem: string | number;
|
|
1020
1035
|
quantity: number;
|
|
1021
1036
|
restockAction?: RestockAction;
|
|
1037
|
+
restockingFee?: number;
|
|
1022
1038
|
};
|
|
1023
1039
|
type ReturnWithRefundParams = {
|
|
1024
1040
|
orderNumber: string;
|
|
@@ -1026,6 +1042,7 @@ type ReturnWithRefundParams = {
|
|
|
1026
1042
|
reasonDetail?: string;
|
|
1027
1043
|
returnItems: ReturnWithRefundItem[];
|
|
1028
1044
|
refundAmount: number;
|
|
1045
|
+
returnShippingFee?: number;
|
|
1029
1046
|
pgPaymentId: string;
|
|
1030
1047
|
paymentKey?: string;
|
|
1031
1048
|
refundReceiptUrl?: string;
|
|
@@ -1110,7 +1127,7 @@ declare class CommerceClient {
|
|
|
1110
1127
|
readonly product: {
|
|
1111
1128
|
stockCheck: (params: StockCheckParams) => Promise<StockCheckResponse>;
|
|
1112
1129
|
listingGroups: (params: ListingGroupsParams) => Promise<ProductListingGroupsResponse>;
|
|
1113
|
-
detail: (params: ProductDetailParams) => Promise<
|
|
1130
|
+
detail: (params: ProductDetailParams) => Promise<ProductDetailResult>;
|
|
1114
1131
|
};
|
|
1115
1132
|
readonly cart: {
|
|
1116
1133
|
get: (cartId: string) => Promise<Cart>;
|
|
@@ -1319,4 +1336,4 @@ type DeepPartial<T> = {
|
|
|
1319
1336
|
};
|
|
1320
1337
|
type ExtractArrayType<T> = T extends (infer U)[] ? U : never;
|
|
1321
1338
|
|
|
1322
|
-
export { type NormalizedProductSelection as $, type ApiQueryOptions as A, BaseApi as B, CommerceClient as C, type DebugConfig as D, type ExtractArrayType as E, type CreateFulfillmentParams as F, type CreateOrderItem as G, type CreateOrderParams as H, type CreateReturnParams as I, CustomerAuth as J, type CustomerAuthOptions as K, type CustomerAuthResponse as L, type CustomerLoginData as M, type CustomerProfile as N, type CustomerRefreshResponse as O, type PayloadFindResponse as P, type CustomerRegisterData as Q, type RetryConfig as R, type Sort as S, type CustomerRegisterResponse as T, type CustomerSnapshot as U, DiscountApi as V, type Where as W, type DiscountApiOptions as X, type LegacyProductSelectionParamEvent as Y, type ListingGroupingState as Z, type ListingGroupsParams as _, CommunityClient as a, type
|
|
1339
|
+
export { type NormalizedProductSelection as $, type ApiQueryOptions as A, BaseApi as B, CommerceClient as C, type DebugConfig as D, type ExtractArrayType as E, type CreateFulfillmentParams as F, type CreateOrderItem as G, type CreateOrderParams as H, type CreateReturnParams as I, CustomerAuth as J, type CustomerAuthOptions as K, type CustomerAuthResponse as L, type CustomerLoginData as M, type CustomerProfile as N, type CustomerRefreshResponse as O, type PayloadFindResponse as P, type CustomerRegisterData as Q, type RetryConfig as R, type Sort as S, type CustomerRegisterResponse as T, type CustomerSnapshot as U, DiscountApi as V, type Where as W, type DiscountApiOptions as X, type LegacyProductSelectionParamEvent as Y, type ListingGroupingState as Z, type ListingGroupsParams as _, CommunityClient as a, type UpdateItemParams as a$, OrderApi as a0, type OrderApiOptions as a1, ProductApi as a2, type ProductApiOptions as a3, type ProductDetail as a4, type ProductDetailBrand as a5, type ProductDetailCategory as a6, type ProductDetailImage as a7, type ProductDetailImageMedia as a8, type ProductDetailListing as a9, type ProductOptionMatrixOption as aA, type ProductOptionMatrixValue as aB, type ProductOptionMatrixVariant as aC, type ProductOptionShape as aD, type ProductOptionValueShape as aE, type ProductSelectionAvailableValue as aF, type ProductSelectionByOptionValue as aG, ProductSelectionCodecError as aH, type ProductSelectionCodecOptions as aI, type ProductSelectionInput as aJ, type ProductSelectionResolution as aK, type ProductSelectionResolutionContext as aL, type ProductVariantShape as aM, type RemoveDiscountParams as aN, type RemoveItemParams as aO, type RequestOptions as aP, type ReturnItem as aQ, type ReturnReason as aR, type ReturnWithRefundItem as aS, type ReturnWithRefundParams as aT, type ServerApiOptions as aU, ShippingApi as aV, type ShippingApiOptions as aW, type StockCheckParams as aX, type StockCheckResponse as aY, type StockCheckResult as aZ, type UpdateFulfillmentParams as a_, type ProductDetailMedia as aa, type ProductDetailOption as ab, type ProductDetailOptionValue as ac, type ProductDetailParams as ad, type ProductDetailResult as ae, type ProductDetailTag as af, type ProductDetailUnavailableReason as ag, type ProductDetailVariant as ah, type ProductDetailVariantOptionValue as ai, type ProductDetailVideo as aj, type ProductHrefGroup as ak, type ProductHrefOptions as al, type ProductHrefProduct as am, type ProductListingCard as an, type ProductListingCardPriceRange as ao, type ProductListingCardRepresentativeVariant as ap, type ProductListingGroup as aq, type ProductListingGroupSummary as ar, type ProductListingGroupVariant as as, type ProductListingGroupsItem as at, type ProductListingGroupsProduct as au, type ProductListingGroupsResponse as av, type ProductListingProductShape as aw, type ProductListingProjection as ax, type ProductListingSwatch as ay, type ProductOptionMatrix as az, CustomerNamespace as b, type UpdateOrderParams as b0, type UpdateProfileData as b1, type UpdateReturnParams as b2, type UpdateTransactionParams as b3, type ValidateDiscountParams as b4, type ValidateDiscountResult as b5, buildProductHref as b6, buildProductListingCard as b7, buildProductListingGroupsByOption as b8, buildProductListingProjection as b9, buildProductOptionMatrix as ba, buildProductOptionMatrixFromDetail as bb, createProductSelectionCodec as bc, getAvailableOptionValues as bd, getProductSelectionImages as be, getSelectedValueByOptionId as bf, normalizeProductSelection as bg, normalizeProductSelectionFromMatrix as bh, normalizeSelectedValueIds as bi, parseProductSelection as bj, resolveProductSelection as bk, resolveProductSelectionFromMatrix as bl, resolveVariantForSelection as bm, stringifyProductSelection as bn, type ProductDetailPreviewParams as bo, type ProductDetailPreviewOptions as bp, type ProductUpsertParams as bq, type ProductUpsertResponse as br, type ClientServerConfig as bs, type ClientState as c, type ClientConfig as d, type ClientMetadata as e, type DeepPartial as f, type PayloadMutationResponse as g, type RootClient as h, type RootCollectionClient as i, type RootReadOnlyQueryBuilder as j, type AddItemParams as k, type ApplyDiscountParams as l, type BulkImportFulfillmentsParams as m, type BulkImportFulfillmentsResponse as n, type CalculateShippingParams as o, type CalculateShippingResult as p, CartApi as q, type CartApiOptions as r, type CheckoutParams as s, type ClearCartParams as t, type CommerceClientOptions as u, type CommunityClientOptions as v, type CommunityPost as w, type CompatibilityProductSelectionParamEvent as x, type ConfirmPaymentParams as y, type ConfirmPaymentResponse as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as Product, C as CustomerProfile, a as CustomerProfileList, b as ProductCollection, c as Post, d as Comment, R as Reaction, e as Config } from './payload-types-
|
|
1
|
+
import { P as Product, C as CustomerProfile, a as CustomerProfileList, b as ProductCollection, c as Post, d as Comment, R as Reaction, e as Config } from './payload-types-dkeQyrDC.js';
|
|
2
2
|
|
|
3
3
|
type PublicCustomerProfile = Omit<CustomerProfile, 'tenant' | 'customer' | 'isPublic' | 'anonymizedAt' | 'metadata'>;
|
|
4
4
|
type PublicProfileRelation = string | PublicCustomerProfile;
|
package/dist/ui/form.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { F as Form } from '../payload-types-
|
|
2
|
+
import { F as Form } from '../payload-types-dkeQyrDC.cjs';
|
|
3
3
|
import { RichTextData } from './rich-text.cjs';
|
|
4
4
|
import '@payloadcms/richtext-lexical';
|
|
5
5
|
import '@payloadcms/richtext-lexical/lexical';
|
package/dist/ui/form.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { F as Form } from '../payload-types-
|
|
2
|
+
import { F as Form } from '../payload-types-dkeQyrDC.js';
|
|
3
3
|
import { RichTextData } from './rich-text.js';
|
|
4
4
|
import '@payloadcms/richtext-lexical';
|
|
5
5
|
import '@payloadcms/richtext-lexical/lexical';
|
package/dist/ui/video.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { CSSProperties } from 'react';
|
|
2
2
|
import { MuxPlayerProps, MuxPlayerRefAttributes } from '@mux/mux-player-react';
|
|
3
3
|
export { MuxPlayerRefAttributes as VideoPlayerRef } from '@mux/mux-player-react';
|
|
4
|
-
import { V as Video } from '../payload-types-
|
|
4
|
+
import { V as Video } from '../payload-types-dkeQyrDC.cjs';
|
|
5
5
|
export { V as VideoGifOptions, a as VideoThumbnailOptions, g as getVideoGif, b as getVideoMp4Url, c as getVideoStoryboard, d as getVideoStreamUrl, e as getVideoThumbnail } from '../video-WR_TFO9a.cjs';
|
|
6
6
|
|
|
7
7
|
interface VideoPlayerCSSProperties extends CSSProperties {
|
package/dist/ui/video.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { CSSProperties } from 'react';
|
|
2
2
|
import { MuxPlayerProps, MuxPlayerRefAttributes } from '@mux/mux-player-react';
|
|
3
3
|
export { MuxPlayerRefAttributes as VideoPlayerRef } from '@mux/mux-player-react';
|
|
4
|
-
import { V as Video } from '../payload-types-
|
|
4
|
+
import { V as Video } from '../payload-types-dkeQyrDC.js';
|
|
5
5
|
export { V as VideoGifOptions, a as VideoThumbnailOptions, g as getVideoGif, b as getVideoMp4Url, c as getVideoStoryboard, d as getVideoStreamUrl, e as getVideoThumbnail } from '../video-WR_TFO9a.js';
|
|
6
6
|
|
|
7
7
|
interface VideoPlayerCSSProperties extends CSSProperties {
|
package/dist/webhook.cjs
CHANGED
|
@@ -20,11 +20,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/webhook.ts
|
|
21
21
|
var webhook_exports = {};
|
|
22
22
|
__export(webhook_exports, {
|
|
23
|
+
COMMERCE_NOTIFICATION_EVENTS: () => COMMERCE_NOTIFICATION_EVENTS,
|
|
24
|
+
COMMERCE_NOTIFICATION_EVENT_TYPE: () => COMMERCE_NOTIFICATION_EVENT_TYPE,
|
|
25
|
+
COMMERCE_NOTIFICATION_OPERATION: () => COMMERCE_NOTIFICATION_OPERATION,
|
|
23
26
|
CUSTOMER_PASSWORD_RESET_OPERATION: () => CUSTOMER_PASSWORD_RESET_OPERATION,
|
|
24
27
|
ORDER_CHANGED_EVENT_TYPE: () => ORDER_CHANGED_EVENT_TYPE,
|
|
28
|
+
createCommerceEmailWebhookHandler: () => createCommerceEmailWebhookHandler,
|
|
25
29
|
createCustomerAuthWebhookHandler: () => createCustomerAuthWebhookHandler,
|
|
26
30
|
createTypedWebhookHandler: () => createTypedWebhookHandler,
|
|
31
|
+
defineCommerceEmailConfig: () => defineCommerceEmailConfig,
|
|
32
|
+
getCommerceNotificationIdempotencyKey: () => getCommerceNotificationIdempotencyKey,
|
|
27
33
|
handleWebhook: () => handleWebhook,
|
|
34
|
+
isCommerceNotificationWebhookEvent: () => isCommerceNotificationWebhookEvent,
|
|
28
35
|
isCustomerPasswordResetWebhookEvent: () => isCustomerPasswordResetWebhookEvent,
|
|
29
36
|
isOrderChangedWebhookEvent: () => isOrderChangedWebhookEvent,
|
|
30
37
|
isValidWebhookEvent: () => isValidWebhookEvent,
|
|
@@ -35,11 +42,20 @@ module.exports = __toCommonJS(webhook_exports);
|
|
|
35
42
|
|
|
36
43
|
// src/core/webhook/index.ts
|
|
37
44
|
var ORDER_CHANGED_EVENT_TYPE = "collection.orderChanged";
|
|
45
|
+
var COMMERCE_NOTIFICATION_EVENT_TYPE = "commerce.notification";
|
|
38
46
|
function isValidWebhookEvent(data) {
|
|
39
47
|
if (typeof data !== "object" || data === null) return false;
|
|
40
48
|
const obj = data;
|
|
41
49
|
return typeof obj.collection === "string" && typeof obj.operation === "string" && obj.operation.length > 0 && typeof obj.data === "object" && obj.data !== null;
|
|
42
50
|
}
|
|
51
|
+
var COMMERCE_NOTIFICATION_OPERATION = "notification";
|
|
52
|
+
var COMMERCE_NOTIFICATION_EVENTS = [
|
|
53
|
+
"orderPaid",
|
|
54
|
+
"fulfillmentShipped",
|
|
55
|
+
"orderDelivered",
|
|
56
|
+
"returnRequested",
|
|
57
|
+
"returnCompleted"
|
|
58
|
+
];
|
|
43
59
|
function isStringOrNumber(value) {
|
|
44
60
|
return typeof value === "string" || typeof value === "number";
|
|
45
61
|
}
|
|
@@ -64,6 +80,30 @@ function isWebhookOrderChange(value) {
|
|
|
64
80
|
if (!isRecord(value)) return false;
|
|
65
81
|
return value.type === "order" && value.source === "payload-orderable" && (value.orderableFieldName === void 0 || typeof value.orderableFieldName === "string") && hasOptionalOrderValue(value, "previousOrder") && hasOptionalOrderValue(value, "nextOrder") && isWebhookOrderScope(value.scope) && isWebhookOrderMoved(value.moved);
|
|
66
82
|
}
|
|
83
|
+
function isCommerceNotificationEventName(value) {
|
|
84
|
+
return typeof value === "string" && COMMERCE_NOTIFICATION_EVENTS.includes(value);
|
|
85
|
+
}
|
|
86
|
+
function isCommerceNotificationSourceCollection(value) {
|
|
87
|
+
return value === "orders" || value === "fulfillments" || value === "returns";
|
|
88
|
+
}
|
|
89
|
+
function isCommerceNotificationData(value) {
|
|
90
|
+
if (!isRecord(value)) return false;
|
|
91
|
+
if (value.source !== void 0 && (!isRecord(value.source) || !isCommerceNotificationSourceCollection(value.source.collection) || !isStringOrNumber(value.source.id))) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
return (value.orderId === void 0 || isStringOrNumber(value.orderId)) && (value.orderNumber === void 0 || typeof value.orderNumber === "string") && (value.status === void 0 || typeof value.status === "string") && (value.totalAmount === void 0 || typeof value.totalAmount === "number") && (value.currency === void 0 || typeof value.currency === "string") && (value.fulfillmentId === void 0 || isStringOrNumber(value.fulfillmentId)) && (value.fulfillmentStatus === void 0 || typeof value.fulfillmentStatus === "string") && (value.shippedAt === void 0 || typeof value.shippedAt === "string") && (value.returnId === void 0 || isStringOrNumber(value.returnId)) && (value.returnStatus === void 0 || typeof value.returnStatus === "string") && (value.refundAmount === void 0 || typeof value.refundAmount === "number") && (value.completedAt === void 0 || typeof value.completedAt === "string");
|
|
95
|
+
}
|
|
96
|
+
function isCommerceNotification(value) {
|
|
97
|
+
if (!isRecord(value)) return false;
|
|
98
|
+
return isCommerceNotificationEventName(value.event) && typeof value.intentId === "string" && value.intentId.length > 0 && typeof value.dedupeKey === "string" && value.dedupeKey.length > 0 && (value.orderId === void 0 || typeof value.orderId === "string") && (value.fulfillmentId === void 0 || typeof value.fulfillmentId === "string") && (value.returnId === void 0 || typeof value.returnId === "string");
|
|
99
|
+
}
|
|
100
|
+
function isWebhookCommerceNotificationChange(value) {
|
|
101
|
+
if (!isRecord(value)) return false;
|
|
102
|
+
return value.type === "notification" && value.source === "commerce-notifications" && isCommerceNotificationEventName(value.event) && isCommerceNotificationSourceCollection(value.sourceCollection) && isStringOrNumber(value.sourceId);
|
|
103
|
+
}
|
|
104
|
+
function matchesOptionalId(actual, expected) {
|
|
105
|
+
return actual === void 0 || expected === void 0 || actual === expected;
|
|
106
|
+
}
|
|
67
107
|
function isOrderChangedWebhookEvent(event) {
|
|
68
108
|
if (!isValidWebhookEvent(event) || event.operation !== "update" || event.eventType !== ORDER_CHANGED_EVENT_TYPE || !isWebhookOrderChange(event.change)) {
|
|
69
109
|
return false;
|
|
@@ -76,6 +116,60 @@ function isOrderChangedWebhookEvent(event) {
|
|
|
76
116
|
}
|
|
77
117
|
return true;
|
|
78
118
|
}
|
|
119
|
+
function isCommerceNotificationWebhookEvent(event) {
|
|
120
|
+
if (!isValidWebhookEvent(event) || event.operation !== COMMERCE_NOTIFICATION_OPERATION || event.eventType !== COMMERCE_NOTIFICATION_EVENT_TYPE || !isCommerceNotificationData(event.data) || !isCommerceNotification(event.notification)) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
const notification = event.notification;
|
|
124
|
+
const data = event.data;
|
|
125
|
+
const change = event.change;
|
|
126
|
+
const sourceCollection = data.source?.collection ?? event.collection;
|
|
127
|
+
const sourceId = data.source?.id;
|
|
128
|
+
if (!isCommerceNotificationSourceCollection(sourceCollection)) return false;
|
|
129
|
+
if (data.source !== void 0 && event.collection !== data.source.collection) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
if (change !== void 0) {
|
|
133
|
+
if (!isWebhookCommerceNotificationChange(change)) return false;
|
|
134
|
+
if (change.sourceCollection !== sourceCollection) return false;
|
|
135
|
+
if (change.event !== notification.event) return false;
|
|
136
|
+
if (!matchesOptionalId(change.sourceId, sourceId)) return false;
|
|
137
|
+
}
|
|
138
|
+
const changeSourceId = isWebhookCommerceNotificationChange(change) ? change.sourceId : void 0;
|
|
139
|
+
if (notification.event === "orderPaid" || notification.event === "orderDelivered") {
|
|
140
|
+
return sourceCollection === "orders" && typeof notification.orderId === "string" && notification.orderId.length > 0 && matchesOptionalId(data.orderId, sourceId) && matchesOptionalId(notification.orderId, sourceId) && matchesOptionalId(data.orderId, notification.orderId) && matchesOptionalId(changeSourceId, data.orderId ?? notification.orderId);
|
|
141
|
+
}
|
|
142
|
+
if (notification.event === "fulfillmentShipped") {
|
|
143
|
+
return sourceCollection === "fulfillments" && matchesOptionalId(data.fulfillmentId, sourceId) && typeof notification.fulfillmentId === "string" && notification.fulfillmentId.length > 0 && matchesOptionalId(notification.fulfillmentId, sourceId) && matchesOptionalId(data.fulfillmentId, notification.fulfillmentId) && matchesOptionalId(changeSourceId, notification.fulfillmentId);
|
|
144
|
+
}
|
|
145
|
+
if (notification.event === "returnRequested" || notification.event === "returnCompleted") {
|
|
146
|
+
return sourceCollection === "returns" && matchesOptionalId(data.returnId, sourceId) && typeof notification.returnId === "string" && notification.returnId.length > 0 && matchesOptionalId(notification.returnId, sourceId) && matchesOptionalId(data.returnId, notification.returnId) && matchesOptionalId(changeSourceId, notification.returnId);
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
function getCommerceNotificationIdempotencyKey(event) {
|
|
151
|
+
return `${event.notification.intentId}:${event.notification.dedupeKey}`;
|
|
152
|
+
}
|
|
153
|
+
function defineCommerceEmailConfig(config) {
|
|
154
|
+
return config;
|
|
155
|
+
}
|
|
156
|
+
function createCommerceEmailWebhookHandler(handlers) {
|
|
157
|
+
return async (event) => {
|
|
158
|
+
if (!isCommerceNotificationWebhookEvent(event)) {
|
|
159
|
+
await handlers.unhandled?.(event);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const handler = handlers[event.notification.event];
|
|
163
|
+
if (!handler) {
|
|
164
|
+
await handlers.unhandled?.(event);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
await handler({
|
|
168
|
+
event,
|
|
169
|
+
idempotencyKey: getCommerceNotificationIdempotencyKey(event)
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
}
|
|
79
173
|
function isWebhookCollection(event, collection) {
|
|
80
174
|
return isValidWebhookEvent(event) && event.collection === collection;
|
|
81
175
|
}
|
package/dist/webhook.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/webhook.ts","../src/core/webhook/index.ts"],"sourcesContent":["export {\n handleWebhook,\n createTypedWebhookHandler,\n createCustomerAuthWebhookHandler,\n isValidWebhookEvent,\n isCustomerPasswordResetWebhookEvent,\n isOrderChangedWebhookEvent,\n isWebhookCollection,\n isWebhookOperation,\n CUSTOMER_PASSWORD_RESET_OPERATION,\n ORDER_CHANGED_EVENT_TYPE,\n} from './core/webhook'\nexport type {\n CollectionWebhookOperation,\n CustomerAuthWebhookEvent,\n CustomerAuthWebhookHandlers,\n CustomerPasswordResetWebhookData,\n CustomerPasswordResetWebhookEvent,\n OrderChangedWebhookEvent,\n WebhookChange,\n WebhookEvent,\n WebhookHandler,\n WebhookKnownOperation,\n WebhookOperation,\n WebhookOptions,\n WebhookOrderChange,\n WebhookOrderMoved,\n WebhookOrderScope,\n} from './core/webhook'\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\n\nexport type WebhookOperation = string\n\n/**\n * Semantic event type for manual Admin Panel ordering changes.\n *\n * Order-change webhooks remain `operation: \"update\"` events for compatibility.\n * Do not filter on or emit `operation: \"reorder\"`; use this event type with\n * `isOrderChangedWebhookEvent()` to distinguish ordering from normal content\n * updates.\n */\nexport const ORDER_CHANGED_EVENT_TYPE = 'collection.orderChanged' as const\n\n/** Collection webhook operations emitted for tenant collection writes. */\nexport type CollectionWebhookOperation = 'create' | 'update'\n\n/** Describes the ordered area affected by an order-change webhook. */\nexport type WebhookOrderScope =\n | { kind: 'collection'; collection: string }\n | { kind: 'join'; collection: string; field: string; id: string | number }\n\n/** Identifies the public moved document for the ordered scope. */\nexport type WebhookOrderMoved = {\n collection: string\n id: string | number\n relatedCollection?: string\n relatedId?: string | number\n}\n\n/** Metadata attached to `collection.orderChanged` webhook events. */\nexport type WebhookOrderChange = {\n type: 'order'\n source: 'payload-orderable'\n /**\n * Diagnostic Payload order field name.\n *\n * This may contain hidden implementation field names. Application routing\n * should use `change.scope` and `change.moved` instead.\n */\n orderableFieldName?: string\n previousOrder?: string | null\n nextOrder?: string | null\n scope: WebhookOrderScope\n moved: WebhookOrderMoved\n}\n\n/** Known semantic webhook change metadata. */\nexport type WebhookChange = WebhookOrderChange\n\nexport interface WebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> {\n collection: T\n operation: WebhookOperation\n data: TData\n eventType?: string\n change?: unknown\n timestamp?: string\n deliveryId?: string\n}\n\nexport type WebhookHandler<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = (event: WebhookEvent<T, TData>) => Promise<void> | void\n\nexport interface WebhookOptions {\n secret?: string\n /** Max accepted skew for signed webhook delivery timestamps. Default: 300s. */\n toleranceSeconds?: number\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n if (typeof data !== 'object' || data === null) return false\n const obj = data as Record<string, unknown>\n return (\n typeof obj.collection === 'string' &&\n typeof obj.operation === 'string' &&\n obj.operation.length > 0 &&\n typeof obj.data === 'object' &&\n obj.data !== null\n )\n}\n\n/** Webhook event emitted when manual Admin Panel ordering changes. */\nexport type OrderChangedWebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = WebhookEvent<T, TData> & {\n operation: 'update'\n eventType: typeof ORDER_CHANGED_EVENT_TYPE\n change: WebhookOrderChange\n}\n\nfunction isStringOrNumber(value: unknown): value is string | number {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction isWebhookOrderScope(value: unknown): value is WebhookOrderScope {\n if (!isRecord(value)) return false\n\n if (value.kind === 'collection') {\n return typeof value.collection === 'string'\n }\n\n if (value.kind === 'join') {\n return (\n typeof value.collection === 'string' &&\n typeof value.field === 'string' &&\n isStringOrNumber(value.id)\n )\n }\n\n return false\n}\n\nfunction isWebhookOrderMoved(value: unknown): value is WebhookOrderMoved {\n if (!isRecord(value)) return false\n\n return (\n typeof value.collection === 'string' &&\n isStringOrNumber(value.id) &&\n (value.relatedCollection === undefined ||\n typeof value.relatedCollection === 'string') &&\n (value.relatedId === undefined || isStringOrNumber(value.relatedId))\n )\n}\n\nfunction hasOptionalOrderValue(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return (\n value[key] === undefined ||\n value[key] === null ||\n typeof value[key] === 'string'\n )\n}\n\nfunction isWebhookOrderChange(value: unknown): value is WebhookOrderChange {\n if (!isRecord(value)) return false\n\n return (\n value.type === 'order' &&\n value.source === 'payload-orderable' &&\n (value.orderableFieldName === undefined ||\n typeof value.orderableFieldName === 'string') &&\n hasOptionalOrderValue(value, 'previousOrder') &&\n hasOptionalOrderValue(value, 'nextOrder') &&\n isWebhookOrderScope(value.scope) &&\n isWebhookOrderMoved(value.moved)\n )\n}\n\n/**\n * Returns true for semantic order-change webhooks emitted as update events.\n *\n * Use this guard with `ORDER_CHANGED_EVENT_TYPE` instead of filtering on\n * `operation: \"reorder\"`. Tenant order-change webhooks intentionally keep\n * `operation: \"update\"` for compatibility with existing webhook handlers.\n */\nexport function isOrderChangedWebhookEvent(\n event: unknown,\n): event is OrderChangedWebhookEvent<string, unknown> {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== 'update' ||\n event.eventType !== ORDER_CHANGED_EVENT_TYPE ||\n !isWebhookOrderChange(event.change)\n ) {\n return false\n }\n\n if (event.collection !== event.change.scope.collection) {\n return false\n }\n\n if (\n event.change.scope.kind === 'collection' &&\n event.change.moved.collection !== event.change.scope.collection\n ) {\n return false\n }\n\n return true\n}\n\n/** Narrows a webhook event to a specific collection. */\nexport function isWebhookCollection<TCollection extends string>(\n event: unknown,\n collection: TCollection,\n): event is WebhookEvent<TCollection, unknown> {\n return isValidWebhookEvent(event) && event.collection === collection\n}\n\n/** Narrows a webhook event to a specific operation. */\nexport function isWebhookOperation<TOperation extends string>(\n event: unknown,\n operation: TOperation,\n): event is WebhookEvent<string, unknown> & { operation: TOperation } {\n return isValidWebhookEvent(event) && event.operation === operation\n}\n\nexport const CUSTOMER_PASSWORD_RESET_OPERATION = 'password-reset' as const\n\nexport type WebhookKnownOperation =\n | CollectionWebhookOperation\n | typeof CUSTOMER_PASSWORD_RESET_OPERATION\n\nexport interface CustomerPasswordResetWebhookData {\n customerId: string | number\n email: string\n name: string\n resetPasswordToken: string\n resetPasswordExpiresAt: string\n}\n\nexport type CustomerPasswordResetWebhookEvent = WebhookEvent<\n 'customers',\n CustomerPasswordResetWebhookData\n> & {\n operation: typeof CUSTOMER_PASSWORD_RESET_OPERATION\n}\n\nexport type CustomerAuthWebhookEvent = CustomerPasswordResetWebhookEvent\n\ntype MaybePromise<T> = T | Promise<T>\n\nexport interface CustomerAuthWebhookHandlers {\n passwordReset?: (\n data: CustomerPasswordResetWebhookData,\n event: CustomerPasswordResetWebhookEvent,\n ) => MaybePromise<void>\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction hasString(value: Record<string, unknown>, key: string): boolean {\n return typeof value[key] === 'string'\n}\n\nfunction hasStringOrNumber(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return typeof value[key] === 'string' || typeof value[key] === 'number'\n}\n\nexport function isCustomerPasswordResetWebhookEvent(\n event: WebhookEvent<string, unknown>,\n): event is CustomerPasswordResetWebhookEvent {\n if (\n event.collection !== 'customers' ||\n event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION ||\n !isRecord(event.data)\n ) {\n return false\n }\n\n return (\n hasStringOrNumber(event.data, 'customerId') &&\n hasString(event.data, 'email') &&\n hasString(event.data, 'name') &&\n hasString(event.data, 'resetPasswordToken') &&\n hasString(event.data, 'resetPasswordExpiresAt')\n )\n}\n\nexport function createCustomerAuthWebhookHandler(\n handlers: CustomerAuthWebhookHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {\n await handlers.passwordReset(event.data, event)\n return\n }\n\n await handlers.unhandled?.(event)\n }\n}\n\nasync function verifySignature(\n payload: string,\n secret: string,\n signature: string,\n timestamp: string,\n deliveryId: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['verify'],\n )\n // Validate and convert hex signature to Uint8Array\n if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {\n return false\n }\n const sigBytes = new Uint8Array(\n (signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16)),\n )\n // crypto.subtle.verify performs constant-time comparison internally\n return crypto.subtle.verify(\n 'HMAC',\n key,\n sigBytes,\n encoder.encode(`${timestamp}.${deliveryId}.${payload}`),\n )\n}\n\nfunction timestampIsFresh(\n timestamp: string,\n toleranceSeconds: number,\n): boolean {\n if (!/^\\d+$/.test(timestamp)) return false\n const timestampMs = Number(timestamp)\n if (!Number.isFinite(timestampMs)) return false\n const skewMs = Math.abs(Date.now() - timestampMs)\n return skewMs <= toleranceSeconds * 1000\n}\n\nexport async function handleWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n options?: WebhookOptions,\n): Promise<Response> {\n try {\n const rawBody = await request.text()\n\n if (options?.secret) {\n const signature = request.headers.get('x-webhook-signature') || ''\n const timestamp = request.headers.get('x-webhook-timestamp') || ''\n const deliveryId = request.headers.get('x-webhook-delivery-id') || ''\n const toleranceSeconds = options.toleranceSeconds ?? 300\n const valid =\n Boolean(timestamp && deliveryId) &&\n timestampIsFresh(timestamp, toleranceSeconds) &&\n (await verifySignature(\n rawBody,\n options.secret,\n signature,\n timestamp,\n deliveryId,\n ))\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n } else {\n console.warn(\n '[@01.software/sdk] Webhook signature verification is disabled. ' +\n 'Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification.',\n )\n }\n\n const body = JSON.parse(rawBody)\n\n if (!isValidWebhookEvent(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T, TData>)\n\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n\n return new Response(JSON.stringify({ error: 'Internal server error' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(\n `Expected collection \"${collection}\", got \"${event.collection}\"`,\n )\n }\n return handler(event)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACaO,IAAM,2BAA2B;AA8DjC,SAAS,oBAAoB,MAAqC;AACvE,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,QAAM,MAAM;AACZ,SACE,OAAO,IAAI,eAAe,YAC1B,OAAO,IAAI,cAAc,YACzB,IAAI,UAAU,SAAS,KACvB,OAAO,IAAI,SAAS,YACpB,IAAI,SAAS;AAEjB;AAYA,SAAS,iBAAiB,OAA0C;AAClE,SAAO,OAAO,UAAU,YAAY,OAAO,UAAU;AACvD;AAEA,SAAS,oBAAoB,OAA4C;AACvE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,MAAI,MAAM,SAAS,cAAc;AAC/B,WAAO,OAAO,MAAM,eAAe;AAAA,EACrC;AAEA,MAAI,MAAM,SAAS,QAAQ;AACzB,WACE,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,UAAU,YACvB,iBAAiB,MAAM,EAAE;AAAA,EAE7B;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAA4C;AACvE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,SACE,OAAO,MAAM,eAAe,YAC5B,iBAAiB,MAAM,EAAE,MACxB,MAAM,sBAAsB,UAC3B,OAAO,MAAM,sBAAsB,cACpC,MAAM,cAAc,UAAa,iBAAiB,MAAM,SAAS;AAEtE;AAEA,SAAS,sBACP,OACA,KACS;AACT,SACE,MAAM,GAAG,MAAM,UACf,MAAM,GAAG,MAAM,QACf,OAAO,MAAM,GAAG,MAAM;AAE1B;AAEA,SAAS,qBAAqB,OAA6C;AACzE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,SACE,MAAM,SAAS,WACf,MAAM,WAAW,wBAChB,MAAM,uBAAuB,UAC5B,OAAO,MAAM,uBAAuB,aACtC,sBAAsB,OAAO,eAAe,KAC5C,sBAAsB,OAAO,WAAW,KACxC,oBAAoB,MAAM,KAAK,KAC/B,oBAAoB,MAAM,KAAK;AAEnC;AASO,SAAS,2BACd,OACoD;AACpD,MACE,CAAC,oBAAoB,KAAK,KAC1B,MAAM,cAAc,YACpB,MAAM,cAAc,4BACpB,CAAC,qBAAqB,MAAM,MAAM,GAClC;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,eAAe,MAAM,OAAO,MAAM,YAAY;AACtD,WAAO;AAAA,EACT;AAEA,MACE,MAAM,OAAO,MAAM,SAAS,gBAC5B,MAAM,OAAO,MAAM,eAAe,MAAM,OAAO,MAAM,YACrD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAGO,SAAS,oBACd,OACA,YAC6C;AAC7C,SAAO,oBAAoB,KAAK,KAAK,MAAM,eAAe;AAC5D;AAGO,SAAS,mBACd,OACA,WACoE;AACpE,SAAO,oBAAoB,KAAK,KAAK,MAAM,cAAc;AAC3D;AAEO,IAAM,oCAAoC;AAiCjD,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,UAAU,OAAgC,KAAsB;AACvE,SAAO,OAAO,MAAM,GAAG,MAAM;AAC/B;AAEA,SAAS,kBACP,OACA,KACS;AACT,SAAO,OAAO,MAAM,GAAG,MAAM,YAAY,OAAO,MAAM,GAAG,MAAM;AACjE;AAEO,SAAS,oCACd,OAC4C;AAC5C,MACE,MAAM,eAAe,eACrB,MAAM,cAAc,qCACpB,CAAC,SAAS,MAAM,IAAI,GACpB;AACA,WAAO;AAAA,EACT;AAEA,SACE,kBAAkB,MAAM,MAAM,YAAY,KAC1C,UAAU,MAAM,MAAM,OAAO,KAC7B,UAAU,MAAM,MAAM,MAAM,KAC5B,UAAU,MAAM,MAAM,oBAAoB,KAC1C,UAAU,MAAM,MAAM,wBAAwB;AAElD;AAEO,SAAS,iCACd,UACiC;AACjC,SAAO,OAAO,UAAU;AACtB,QAAI,oCAAoC,KAAK,KAAK,SAAS,eAAe;AACxE,YAAM,SAAS,cAAc,MAAM,MAAM,KAAK;AAC9C;AAAA,IACF;AAEA,UAAM,SAAS,YAAY,KAAK;AAAA,EAClC;AACF;AAEA,eAAe,gBACb,SACA,QACA,WACA,WACA,YACkB;AAClB,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,MAAM,MAAM,OAAO,OAAO;AAAA,IAC9B;AAAA,IACA,QAAQ,OAAO,MAAM;AAAA,IACrB,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,IAChC;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,MAAI,UAAU,SAAS,MAAM,KAAK,CAAC,iBAAiB,KAAK,SAAS,GAAG;AACnE,WAAO;AAAA,EACT;AACA,QAAM,WAAW,IAAI;AAAA,KAClB,UAAU,MAAM,OAAO,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,SAAS,MAAM,EAAE,CAAC;AAAA,EACnE;AAEA,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,GAAG,SAAS,IAAI,UAAU,IAAI,OAAO,EAAE;AAAA,EACxD;AACF;AAEA,SAAS,iBACP,WACA,kBACS;AACT,MAAI,CAAC,QAAQ,KAAK,SAAS,EAAG,QAAO;AACrC,QAAM,cAAc,OAAO,SAAS;AACpC,MAAI,CAAC,OAAO,SAAS,WAAW,EAAG,QAAO;AAC1C,QAAM,SAAS,KAAK,IAAI,KAAK,IAAI,IAAI,WAAW;AAChD,SAAO,UAAU,mBAAmB;AACtC;AAEA,eAAsB,cAIpB,SACA,SACA,SACmB;AACnB,MAAI;AACF,UAAM,UAAU,MAAM,QAAQ,KAAK;AAEnC,QAAI,SAAS,QAAQ;AACnB,YAAM,YAAY,QAAQ,QAAQ,IAAI,qBAAqB,KAAK;AAChE,YAAM,YAAY,QAAQ,QAAQ,IAAI,qBAAqB,KAAK;AAChE,YAAM,aAAa,QAAQ,QAAQ,IAAI,uBAAuB,KAAK;AACnE,YAAM,mBAAmB,QAAQ,oBAAoB;AACrD,YAAM,QACJ,QAAQ,aAAa,UAAU,KAC/B,iBAAiB,WAAW,gBAAgB,KAC3C,MAAM;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACF,UAAI,CAAC,OAAO;AACV,eAAO,IAAI;AAAA,UACT,KAAK,UAAU,EAAE,OAAO,4BAA4B,CAAC;AAAA,UACrD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,QACjE;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ;AAAA,QACN;AAAA,MAEF;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,MAAM,OAAO;AAE/B,QAAI,CAAC,oBAAoB,IAAI,GAAG;AAC9B,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,OAAO,+BAA+B,CAAC;AAAA,QACxD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF;AAEA,UAAM,QAAQ,IAA8B;AAE5C,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,oBAAoB,CAAC;AAAA,MAC9D,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,6BAA6B,KAAK;AAEhD,WAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,wBAAwB,CAAC,GAAG;AAAA,MACtE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAChD,CAAC;AAAA,EACH;AACF;AAEO,SAAS,0BACd,YACA,SACmB;AACnB,SAAO,OAAO,UAA2B;AACvC,QAAI,MAAM,eAAe,YAAY;AACnC,YAAM,IAAI;AAAA,QACR,wBAAwB,UAAU,WAAW,MAAM,UAAU;AAAA,MAC/D;AAAA,IACF;AACA,WAAO,QAAQ,KAAK;AAAA,EACtB;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/webhook.ts","../src/core/webhook/index.ts"],"sourcesContent":["export {\n handleWebhook,\n createTypedWebhookHandler,\n createCommerceEmailWebhookHandler,\n createCustomerAuthWebhookHandler,\n defineCommerceEmailConfig,\n getCommerceNotificationIdempotencyKey,\n isValidWebhookEvent,\n isCommerceNotificationWebhookEvent,\n isCustomerPasswordResetWebhookEvent,\n isOrderChangedWebhookEvent,\n isWebhookCollection,\n isWebhookOperation,\n CUSTOMER_PASSWORD_RESET_OPERATION,\n COMMERCE_NOTIFICATION_EVENT_TYPE,\n COMMERCE_NOTIFICATION_EVENTS,\n COMMERCE_NOTIFICATION_OPERATION,\n ORDER_CHANGED_EVENT_TYPE,\n} from './core/webhook'\nexport type {\n CollectionWebhookOperation,\n CommerceEmailChannel,\n CommerceEmailConfig,\n CommerceEmailEventConfig,\n CommerceEmailEventHandlers,\n CommerceEmailHandlerContext,\n CommerceNotification,\n CommerceNotificationData,\n CommerceNotificationEventName,\n CommerceNotificationSource,\n CommerceNotificationSourceCollection,\n CommerceNotificationWebhookEvent,\n CustomerAuthWebhookEvent,\n CustomerAuthWebhookHandlers,\n CustomerPasswordResetWebhookData,\n CustomerPasswordResetWebhookEvent,\n OrderChangedWebhookEvent,\n WebhookChange,\n WebhookCommerceNotificationChange,\n WebhookEvent,\n WebhookHandler,\n WebhookKnownOperation,\n WebhookOperation,\n WebhookOptions,\n WebhookOrderChange,\n WebhookOrderMoved,\n WebhookOrderScope,\n} from './core/webhook'\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\n\nexport type WebhookOperation = string\n\n/**\n * Semantic event type for manual Admin Panel ordering changes.\n *\n * Order-change webhooks remain `operation: \"update\"` events for compatibility.\n * Do not filter on or emit `operation: \"reorder\"`; use this event type with\n * `isOrderChangedWebhookEvent()` to distinguish ordering from normal content\n * updates.\n */\nexport const ORDER_CHANGED_EVENT_TYPE = 'collection.orderChanged' as const\n\n/** Semantic event type for v1 commerce notification webhooks. */\nexport const COMMERCE_NOTIFICATION_EVENT_TYPE = 'commerce.notification' as const\n\n/** Collection webhook operations emitted for tenant collection writes. */\nexport type CollectionWebhookOperation = 'create' | 'update'\n\n/** Describes the ordered area affected by an order-change webhook. */\nexport type WebhookOrderScope =\n | { kind: 'collection'; collection: string }\n | { kind: 'join'; collection: string; field: string; id: string | number }\n\n/** Identifies the public moved document for the ordered scope. */\nexport type WebhookOrderMoved = {\n collection: string\n id: string | number\n relatedCollection?: string\n relatedId?: string | number\n}\n\n/** Metadata attached to `collection.orderChanged` webhook events. */\nexport type WebhookOrderChange = {\n type: 'order'\n source: 'payload-orderable'\n /**\n * Diagnostic Payload order field name.\n *\n * This may contain hidden implementation field names. Application routing\n * should use `change.scope` and `change.moved` instead.\n */\n orderableFieldName?: string\n previousOrder?: string | null\n nextOrder?: string | null\n scope: WebhookOrderScope\n moved: WebhookOrderMoved\n}\n\n/** Known semantic webhook change metadata. */\nexport type WebhookChange = WebhookOrderChange | WebhookCommerceNotificationChange\n\nexport interface WebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> {\n collection: T\n operation: WebhookOperation\n data: TData\n eventType?: string\n change?: unknown\n timestamp?: string\n deliveryId?: string\n}\n\nexport type WebhookHandler<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = (event: WebhookEvent<T, TData>) => Promise<void> | void\n\nexport interface WebhookOptions {\n secret?: string\n /** Max accepted skew for signed webhook delivery timestamps. Default: 300s. */\n toleranceSeconds?: number\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n if (typeof data !== 'object' || data === null) return false\n const obj = data as Record<string, unknown>\n return (\n typeof obj.collection === 'string' &&\n typeof obj.operation === 'string' &&\n obj.operation.length > 0 &&\n typeof obj.data === 'object' &&\n obj.data !== null\n )\n}\n\n/** Webhook event emitted when manual Admin Panel ordering changes. */\nexport type OrderChangedWebhookEvent<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n> = WebhookEvent<T, TData> & {\n operation: 'update'\n eventType: typeof ORDER_CHANGED_EVENT_TYPE\n change: WebhookOrderChange\n}\n\nexport const COMMERCE_NOTIFICATION_OPERATION = 'notification' as const\n\nexport const COMMERCE_NOTIFICATION_EVENTS = [\n 'orderPaid',\n 'fulfillmentShipped',\n 'orderDelivered',\n 'returnRequested',\n 'returnCompleted',\n] as const\n\nexport type CommerceNotificationEventName =\n (typeof COMMERCE_NOTIFICATION_EVENTS)[number]\n\nexport type CommerceNotificationSourceCollection =\n | 'orders'\n | 'fulfillments'\n | 'returns'\n\nexport type CommerceNotificationSource = {\n collection: CommerceNotificationSourceCollection\n id: string | number\n}\n\nexport type CommerceNotificationData = {\n source?: CommerceNotificationSource\n orderId?: string | number\n orderNumber?: string\n status?: string\n totalAmount?: number\n currency?: string\n fulfillmentId?: string | number\n fulfillmentStatus?: string\n shippedAt?: string\n returnId?: string | number\n returnStatus?: string\n refundAmount?: number\n completedAt?: string\n}\n\nexport type CommerceNotification = {\n event: CommerceNotificationEventName\n intentId: string\n dedupeKey: string\n orderId?: string\n fulfillmentId?: string\n returnId?: string\n}\n\nexport type WebhookCommerceNotificationChange = {\n type: 'notification'\n source: 'commerce-notifications'\n event: CommerceNotificationEventName\n sourceCollection: CommerceNotificationSourceCollection\n sourceId: string | number\n}\n\n/** Webhook event emitted for v1 commerce notification deliveries. */\nexport type CommerceNotificationWebhookEvent = WebhookEvent<\n CommerceNotificationSourceCollection,\n CommerceNotificationData\n> & {\n operation: typeof COMMERCE_NOTIFICATION_OPERATION\n eventType: typeof COMMERCE_NOTIFICATION_EVENT_TYPE\n change?: WebhookCommerceNotificationChange\n notification: CommerceNotification\n}\n\nexport type CommerceEmailChannel = 'webhook' | 'provider'\n\nexport type CommerceEmailEventConfig = {\n enabled: boolean\n channel: CommerceEmailChannel\n template?: string\n}\n\nexport type CommerceEmailConfig = {\n version: 1\n commerceNotifications: Partial<\n Record<CommerceNotificationEventName, CommerceEmailEventConfig>\n >\n}\n\nexport type CommerceEmailHandlerContext = {\n event: CommerceNotificationWebhookEvent\n idempotencyKey: string\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\nexport type CommerceEmailEventHandlers = Partial<\n Record<\n CommerceNotificationEventName,\n (context: CommerceEmailHandlerContext) => MaybePromise<void>\n >\n> & {\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isStringOrNumber(value: unknown): value is string | number {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction isWebhookOrderScope(value: unknown): value is WebhookOrderScope {\n if (!isRecord(value)) return false\n\n if (value.kind === 'collection') {\n return typeof value.collection === 'string'\n }\n\n if (value.kind === 'join') {\n return (\n typeof value.collection === 'string' &&\n typeof value.field === 'string' &&\n isStringOrNumber(value.id)\n )\n }\n\n return false\n}\n\nfunction isWebhookOrderMoved(value: unknown): value is WebhookOrderMoved {\n if (!isRecord(value)) return false\n\n return (\n typeof value.collection === 'string' &&\n isStringOrNumber(value.id) &&\n (value.relatedCollection === undefined ||\n typeof value.relatedCollection === 'string') &&\n (value.relatedId === undefined || isStringOrNumber(value.relatedId))\n )\n}\n\nfunction hasOptionalOrderValue(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return (\n value[key] === undefined ||\n value[key] === null ||\n typeof value[key] === 'string'\n )\n}\n\nfunction isWebhookOrderChange(value: unknown): value is WebhookOrderChange {\n if (!isRecord(value)) return false\n\n return (\n value.type === 'order' &&\n value.source === 'payload-orderable' &&\n (value.orderableFieldName === undefined ||\n typeof value.orderableFieldName === 'string') &&\n hasOptionalOrderValue(value, 'previousOrder') &&\n hasOptionalOrderValue(value, 'nextOrder') &&\n isWebhookOrderScope(value.scope) &&\n isWebhookOrderMoved(value.moved)\n )\n}\n\nfunction isCommerceNotificationEventName(\n value: unknown,\n): value is CommerceNotificationEventName {\n return (\n typeof value === 'string' &&\n (COMMERCE_NOTIFICATION_EVENTS as readonly string[]).includes(value)\n )\n}\n\nfunction isCommerceNotificationSourceCollection(\n value: unknown,\n): value is CommerceNotificationSourceCollection {\n return value === 'orders' || value === 'fulfillments' || value === 'returns'\n}\n\nfunction isCommerceNotificationData(\n value: unknown,\n): value is CommerceNotificationData {\n if (!isRecord(value)) return false\n if (\n value.source !== undefined &&\n (!isRecord(value.source) ||\n !isCommerceNotificationSourceCollection(value.source.collection) ||\n !isStringOrNumber(value.source.id))\n ) {\n return false\n }\n\n return (\n (value.orderId === undefined || isStringOrNumber(value.orderId)) &&\n (value.orderNumber === undefined || typeof value.orderNumber === 'string') &&\n (value.status === undefined || typeof value.status === 'string') &&\n (value.totalAmount === undefined || typeof value.totalAmount === 'number') &&\n (value.currency === undefined || typeof value.currency === 'string') &&\n (value.fulfillmentId === undefined ||\n isStringOrNumber(value.fulfillmentId)) &&\n (value.fulfillmentStatus === undefined ||\n typeof value.fulfillmentStatus === 'string') &&\n (value.shippedAt === undefined || typeof value.shippedAt === 'string') &&\n (value.returnId === undefined || isStringOrNumber(value.returnId)) &&\n (value.returnStatus === undefined ||\n typeof value.returnStatus === 'string') &&\n (value.refundAmount === undefined ||\n typeof value.refundAmount === 'number') &&\n (value.completedAt === undefined || typeof value.completedAt === 'string')\n )\n}\n\nfunction isCommerceNotification(\n value: unknown,\n): value is CommerceNotification {\n if (!isRecord(value)) return false\n return (\n isCommerceNotificationEventName(value.event) &&\n typeof value.intentId === 'string' &&\n value.intentId.length > 0 &&\n typeof value.dedupeKey === 'string' &&\n value.dedupeKey.length > 0 &&\n (value.orderId === undefined || typeof value.orderId === 'string') &&\n (value.fulfillmentId === undefined ||\n typeof value.fulfillmentId === 'string') &&\n (value.returnId === undefined || typeof value.returnId === 'string')\n )\n}\n\nfunction isWebhookCommerceNotificationChange(\n value: unknown,\n): value is WebhookCommerceNotificationChange {\n if (!isRecord(value)) return false\n return (\n value.type === 'notification' &&\n value.source === 'commerce-notifications' &&\n isCommerceNotificationEventName(value.event) &&\n isCommerceNotificationSourceCollection(value.sourceCollection) &&\n isStringOrNumber(value.sourceId)\n )\n}\n\nfunction matchesOptionalId(\n actual: string | number | undefined,\n expected: string | number | undefined,\n): boolean {\n return actual === undefined || expected === undefined || actual === expected\n}\n\n/**\n * Returns true for semantic order-change webhooks emitted as update events.\n *\n * Use this guard with `ORDER_CHANGED_EVENT_TYPE` instead of filtering on\n * `operation: \"reorder\"`. Tenant order-change webhooks intentionally keep\n * `operation: \"update\"` for compatibility with existing webhook handlers.\n */\nexport function isOrderChangedWebhookEvent(\n event: unknown,\n): event is OrderChangedWebhookEvent<string, unknown> {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== 'update' ||\n event.eventType !== ORDER_CHANGED_EVENT_TYPE ||\n !isWebhookOrderChange(event.change)\n ) {\n return false\n }\n\n if (event.collection !== event.change.scope.collection) {\n return false\n }\n\n if (\n event.change.scope.kind === 'collection' &&\n event.change.moved.collection !== event.change.scope.collection\n ) {\n return false\n }\n\n return true\n}\n\n/**\n * Returns true for semantic commerce notification webhooks.\n *\n * Use `notification.intentId` and `notification.dedupeKey` for semantic\n * idempotency. `deliveryId`, when present, identifies a delivery attempt for\n * observability and is not the semantic notification identity.\n */\nexport function isCommerceNotificationWebhookEvent(\n event: unknown,\n): event is CommerceNotificationWebhookEvent {\n if (\n !isValidWebhookEvent(event) ||\n event.operation !== COMMERCE_NOTIFICATION_OPERATION ||\n event.eventType !== COMMERCE_NOTIFICATION_EVENT_TYPE ||\n !isCommerceNotificationData(event.data) ||\n !isCommerceNotification((event as { notification?: unknown }).notification)\n ) {\n return false\n }\n\n const notification = (event as unknown as CommerceNotificationWebhookEvent)\n .notification\n const data = event.data\n const change = event.change\n const sourceCollection = data.source?.collection ?? event.collection\n const sourceId = data.source?.id\n\n if (!isCommerceNotificationSourceCollection(sourceCollection)) return false\n if (data.source !== undefined && event.collection !== data.source.collection) {\n return false\n }\n\n if (change !== undefined) {\n if (!isWebhookCommerceNotificationChange(change)) return false\n if (change.sourceCollection !== sourceCollection) return false\n if (change.event !== notification.event) return false\n if (!matchesOptionalId(change.sourceId, sourceId)) return false\n }\n const changeSourceId = isWebhookCommerceNotificationChange(change)\n ? change.sourceId\n : undefined\n\n if (\n notification.event === 'orderPaid' ||\n notification.event === 'orderDelivered'\n ) {\n return (\n sourceCollection === 'orders' &&\n typeof notification.orderId === 'string' &&\n notification.orderId.length > 0 &&\n matchesOptionalId(data.orderId, sourceId) &&\n matchesOptionalId(notification.orderId, sourceId) &&\n matchesOptionalId(data.orderId, notification.orderId) &&\n matchesOptionalId(changeSourceId, data.orderId ?? notification.orderId)\n )\n }\n\n if (notification.event === 'fulfillmentShipped') {\n return (\n sourceCollection === 'fulfillments' &&\n matchesOptionalId(data.fulfillmentId, sourceId) &&\n typeof notification.fulfillmentId === 'string' &&\n notification.fulfillmentId.length > 0 &&\n matchesOptionalId(notification.fulfillmentId, sourceId) &&\n matchesOptionalId(data.fulfillmentId, notification.fulfillmentId) &&\n matchesOptionalId(changeSourceId, notification.fulfillmentId)\n )\n }\n\n if (\n notification.event === 'returnRequested' ||\n notification.event === 'returnCompleted'\n ) {\n return (\n sourceCollection === 'returns' &&\n matchesOptionalId(data.returnId, sourceId) &&\n typeof notification.returnId === 'string' &&\n notification.returnId.length > 0 &&\n matchesOptionalId(notification.returnId, sourceId) &&\n matchesOptionalId(data.returnId, notification.returnId) &&\n matchesOptionalId(changeSourceId, notification.returnId)\n )\n }\n\n return false\n}\n\nexport function getCommerceNotificationIdempotencyKey(\n event: Pick<CommerceNotificationWebhookEvent, 'notification'>,\n): string {\n return `${event.notification.intentId}:${event.notification.dedupeKey}`\n}\n\nexport function defineCommerceEmailConfig<TConfig extends CommerceEmailConfig>(\n config: TConfig,\n): TConfig {\n return config\n}\n\nexport function createCommerceEmailWebhookHandler(\n handlers: CommerceEmailEventHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (!isCommerceNotificationWebhookEvent(event)) {\n await handlers.unhandled?.(event)\n return\n }\n\n const handler = handlers[event.notification.event]\n if (!handler) {\n await handlers.unhandled?.(event)\n return\n }\n\n await handler({\n event,\n idempotencyKey: getCommerceNotificationIdempotencyKey(event),\n })\n }\n}\n\n/** Narrows a webhook event to a specific collection. */\nexport function isWebhookCollection<TCollection extends string>(\n event: unknown,\n collection: TCollection,\n): event is WebhookEvent<TCollection, unknown> {\n return isValidWebhookEvent(event) && event.collection === collection\n}\n\n/** Narrows a webhook event to a specific operation. */\nexport function isWebhookOperation<TOperation extends string>(\n event: unknown,\n operation: TOperation,\n): event is WebhookEvent<string, unknown> & { operation: TOperation } {\n return isValidWebhookEvent(event) && event.operation === operation\n}\n\nexport const CUSTOMER_PASSWORD_RESET_OPERATION = 'password-reset' as const\n\nexport type WebhookKnownOperation =\n | CollectionWebhookOperation\n | typeof CUSTOMER_PASSWORD_RESET_OPERATION\n | typeof COMMERCE_NOTIFICATION_OPERATION\n\nexport interface CustomerPasswordResetWebhookData {\n customerId: string | number\n email: string\n name: string\n resetPasswordToken: string\n resetPasswordExpiresAt: string\n}\n\nexport type CustomerPasswordResetWebhookEvent = WebhookEvent<\n 'customers',\n CustomerPasswordResetWebhookData\n> & {\n operation: typeof CUSTOMER_PASSWORD_RESET_OPERATION\n}\n\nexport type CustomerAuthWebhookEvent = CustomerPasswordResetWebhookEvent\n\nexport interface CustomerAuthWebhookHandlers {\n passwordReset?: (\n data: CustomerPasswordResetWebhookData,\n event: CustomerPasswordResetWebhookEvent,\n ) => MaybePromise<void>\n unhandled?: (event: WebhookEvent<string, unknown>) => MaybePromise<void>\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\nfunction hasString(value: Record<string, unknown>, key: string): boolean {\n return typeof value[key] === 'string'\n}\n\nfunction hasStringOrNumber(\n value: Record<string, unknown>,\n key: string,\n): boolean {\n return typeof value[key] === 'string' || typeof value[key] === 'number'\n}\n\nexport function isCustomerPasswordResetWebhookEvent(\n event: WebhookEvent<string, unknown>,\n): event is CustomerPasswordResetWebhookEvent {\n if (\n event.collection !== 'customers' ||\n event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION ||\n !isRecord(event.data)\n ) {\n return false\n }\n\n return (\n hasStringOrNumber(event.data, 'customerId') &&\n hasString(event.data, 'email') &&\n hasString(event.data, 'name') &&\n hasString(event.data, 'resetPasswordToken') &&\n hasString(event.data, 'resetPasswordExpiresAt')\n )\n}\n\nexport function createCustomerAuthWebhookHandler(\n handlers: CustomerAuthWebhookHandlers,\n): WebhookHandler<string, unknown> {\n return async (event) => {\n if (isCustomerPasswordResetWebhookEvent(event) && handlers.passwordReset) {\n await handlers.passwordReset(event.data, event)\n return\n }\n\n await handlers.unhandled?.(event)\n }\n}\n\nasync function verifySignature(\n payload: string,\n secret: string,\n signature: string,\n timestamp: string,\n deliveryId: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['verify'],\n )\n // Validate and convert hex signature to Uint8Array\n if (signature.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(signature)) {\n return false\n }\n const sigBytes = new Uint8Array(\n (signature.match(/.{2}/g) ?? []).map((byte) => parseInt(byte, 16)),\n )\n // crypto.subtle.verify performs constant-time comparison internally\n return crypto.subtle.verify(\n 'HMAC',\n key,\n sigBytes,\n encoder.encode(`${timestamp}.${deliveryId}.${payload}`),\n )\n}\n\nfunction timestampIsFresh(\n timestamp: string,\n toleranceSeconds: number,\n): boolean {\n if (!/^\\d+$/.test(timestamp)) return false\n const timestampMs = Number(timestamp)\n if (!Number.isFinite(timestampMs)) return false\n const skewMs = Math.abs(Date.now() - timestampMs)\n return skewMs <= toleranceSeconds * 1000\n}\n\nexport async function handleWebhook<\n T extends Collection | string = Collection,\n TData = T extends Collection ? CollectionType<T> : Record<string, unknown>,\n>(\n request: Request,\n handler: WebhookHandler<T, TData>,\n options?: WebhookOptions,\n): Promise<Response> {\n try {\n const rawBody = await request.text()\n\n if (options?.secret) {\n const signature = request.headers.get('x-webhook-signature') || ''\n const timestamp = request.headers.get('x-webhook-timestamp') || ''\n const deliveryId = request.headers.get('x-webhook-delivery-id') || ''\n const toleranceSeconds = options.toleranceSeconds ?? 300\n const valid =\n Boolean(timestamp && deliveryId) &&\n timestampIsFresh(timestamp, toleranceSeconds) &&\n (await verifySignature(\n rawBody,\n options.secret,\n signature,\n timestamp,\n deliveryId,\n ))\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n } else {\n console.warn(\n '[@01.software/sdk] Webhook signature verification is disabled. ' +\n 'Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification.',\n )\n }\n\n const body = JSON.parse(rawBody)\n\n if (!isValidWebhookEvent(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T, TData>)\n\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n\n return new Response(JSON.stringify({ error: 'Internal server error' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(\n `Expected collection \"${collection}\", got \"${event.collection}\"`,\n )\n }\n return handler(event)\n }\n}\n"],"mappings":"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","names":[]}
|