@mohasinac/appkit 3.8.0 → 3.8.2

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,11 +1,9 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
4
3
  import { sortBy } from "@mohasinac/appkit";
5
4
  import React from "react";
6
- import { FilterChipGroup, ListingLayout } from "../../../ui";
5
+ import { ListingLayout } from "../../../ui";
7
6
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
8
- import { ADMIN_CART_OWNERSHIP_TABS } from "../constants/filter-tabs";
9
7
  import { toRecordArray, toRelativeDate, toStringValue, } from "../hooks/useAdminListingData";
10
8
  import { DataListingView } from "./DataListingView";
11
9
  const ADMIN_CARTS_CONFIG = {
@@ -13,7 +11,7 @@ const ADMIN_CARTS_CONFIG = {
13
11
  title: "Carts",
14
12
  searchPlaceholder: "Search by user ID or session",
15
13
  emptyLabel: "No carts found",
16
- filterKeys: ["type"],
14
+ filterKeys: [],
17
15
  defaultSort: sortBy("updatedAt", "DESC"),
18
16
  queryKey: ["admin", "carts", "listing"],
19
17
  endpoint: ADMIN_ENDPOINTS.ADMIN_CARTS,
@@ -36,8 +34,7 @@ const ADMIN_CARTS_CONFIG = {
36
34
  };
37
35
  }),
38
36
  getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
39
- buildFilters: (state) => state.type && state.type !== "All" ? sieveFilter("type", SIEVE_OP.EQ, state.type) : undefined,
40
- renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsx(FilterChipGroup, { label: "Type", tabs: ADMIN_CART_OWNERSHIP_TABS, value: pendingFilters.type ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, type: id })) })),
37
+ buildFilters: () => undefined,
41
38
  };
42
39
  export function AdminCartsView({ children, ...props }) {
43
40
  if (React.Children.count(children) > 0) {
@@ -69,7 +69,7 @@ export function SellerArtView({ onCreateClick, onEditClick, onDelete, onBulkDele
69
69
  sortOptions: [
70
70
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
71
71
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
72
- { value: "productTitle", label: "Name A–Z" },
72
+ { value: "title", label: "Name A–Z" },
73
73
  { value: sortBy("price", "ASC"), label: "Price: Low–High" },
74
74
  { value: sortBy("price", "DESC"), label: "Price: High–Low" },
75
75
  ],
@@ -39,12 +39,12 @@ export function SellerAuctionsView({ children, onEditClick, onDelete, onBulkDele
39
39
  searchPlaceholder: "Search auctions by product name",
40
40
  emptyLabel: "No auctions found",
41
41
  filterKeys: ["status"],
42
- defaultSort: sortBy("endsAt", "ASC"),
42
+ defaultSort: sortBy("auctionEndDate", "ASC"),
43
43
  queryKey: ["seller", "auctions", "listing"],
44
44
  endpoint: SELLER_ENDPOINTS.AUCTIONS,
45
45
  sortOptions: [
46
- { value: "endsAt", label: "Ending soon" },
47
- { value: sortBy("endsAt", "DESC"), label: "Ending latest" },
46
+ { value: "auctionEndDate", label: "Ending soon" },
47
+ { value: sortBy("auctionEndDate", "DESC"), label: "Ending latest" },
48
48
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
49
49
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
50
50
  ],
@@ -70,7 +70,7 @@ export function SellerClassifiedView({ onCreateClick, onEditClick, onDelete, onB
70
70
  sortOptions: [
71
71
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
72
72
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
73
- { value: "productTitle", label: "Name A–Z" },
73
+ { value: "title", label: "Name A–Z" },
74
74
  { value: sortBy("price", "ASC"), label: "Price: Low–High" },
75
75
  { value: sortBy("price", "DESC"), label: "Price: High–Low" },
76
76
  ],
@@ -75,7 +75,7 @@ export function SellerDigitalCodesView({ onCreateClick, onEditClick, onDelete, o
75
75
  sortOptions: [
76
76
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
77
77
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
78
- { value: "productTitle", label: "Name A–Z" },
78
+ { value: "title", label: "Name A–Z" },
79
79
  { value: sortBy("price", "ASC"), label: "Price: Low–High" },
80
80
  ],
81
81
  columns: COLUMNS,
@@ -74,7 +74,7 @@ export function SellerLiveView({ onCreateClick, onEditClick, onDelete, onBulkDel
74
74
  sortOptions: [
75
75
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
76
76
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
77
- { value: "productTitle", label: "Name A–Z" },
77
+ { value: "title", label: "Name A–Z" },
78
78
  { value: sortBy("price", "ASC"), label: "Price: Low–High" },
79
79
  { value: sortBy("price", "DESC"), label: "Price: High–Low" },
80
80
  ],
@@ -88,7 +88,7 @@ export function SellerPreOrdersView({ children, onDelete, ...props }) {
88
88
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
89
89
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
90
90
  { value: "title", label: "Title A–Z" },
91
- { value: "preorderAvailableDate", label: "Delivery Soon" },
91
+ { value: "preOrderDeliveryDate", label: "Delivery Soon" },
92
92
  ],
93
93
  columns: PRE_ORDER_COLUMNS,
94
94
  mapRows: (response) => toRecordArray(response.products).map((item, index) => {
@@ -99,8 +99,8 @@ export function SellerPreOrdersView({ children, onDelete, ...props }) {
99
99
  secondary: toStringValue(item.condition, ""),
100
100
  status: toStringValue(item.status, "draft"),
101
101
  price: priceRaw ? toRupees(priceRaw) : "—",
102
- deliveryDate: item.preorderAvailableDate
103
- ? toRelativeDate(item.preorderAvailableDate)
102
+ deliveryDate: item.preOrderDeliveryDate
103
+ ? toRelativeDate(item.preOrderDeliveryDate)
104
104
  : "TBA",
105
105
  updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
106
106
  imageUrl: toStringValue(item.mainImage ?? item.images?.[0], undefined),
@@ -85,7 +85,7 @@ export function SellerPrizeDrawsView({ children, onDelete, ...props }) {
85
85
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
86
86
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
87
87
  { value: "title", label: "Title A–Z" },
88
- { value: "prizeDrawEndDate", label: "Draw Date Soon" },
88
+ { value: "prizeRevealWindowEnd", label: "Draw Date Soon" },
89
89
  ],
90
90
  columns: PRIZE_DRAW_COLUMNS,
91
91
  mapRows: (response) => toRecordArray(response.products).map((item, index) => {
@@ -96,8 +96,8 @@ export function SellerPrizeDrawsView({ children, onDelete, ...props }) {
96
96
  secondary: toStringValue(item.condition, ""),
97
97
  status: toStringValue(item.status, "draft"),
98
98
  entryFee: priceRaw ? toRupees(priceRaw) : "Free",
99
- drawDate: item.prizeDrawEndDate
100
- ? toRelativeDate(item.prizeDrawEndDate)
99
+ drawDate: item.prizeRevealWindowEnd
100
+ ? toRelativeDate(item.prizeRevealWindowEnd)
101
101
  : "TBA",
102
102
  updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
103
103
  imageUrl: toStringValue(item.mainImage ?? item.images?.[0], undefined),
@@ -69,7 +69,7 @@ export function SellerStickersView({ onCreateClick, onEditClick, onDelete, onBul
69
69
  sortOptions: [
70
70
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
71
71
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
72
- { value: "productTitle", label: "Name A–Z" },
72
+ { value: "title", label: "Name A–Z" },
73
73
  { value: sortBy("price", "ASC"), label: "Price: Low–High" },
74
74
  { value: sortBy("price", "DESC"), label: "Price: High–Low" },
75
75
  ],
package/dist/index.d.ts CHANGED
@@ -444,10 +444,8 @@ export { BID_PII_FIELDS } from "./security/index";
444
444
  export { CHAT_PII_FIELDS } from "./security/index";
445
445
  export { Can } from "./security/index";
446
446
  export { DEFAULT_ROLES } from "./security/index";
447
- export { ENC_PREFIX } from "./security/index";
448
447
  export { EVENT_ENTRY_PII_FIELDS } from "./security/index";
449
448
  export { LOTTERY_ENTRY_PII_FIELDS } from "./security/index";
450
- export { HMAC_PREFIX } from "./security/index";
451
449
  export { NEWSLETTER_PII_FIELDS } from "./security/index";
452
450
  export { NEWSLETTER_PII_INDEX_MAP } from "./security/index";
453
451
  export { OFFER_PII_FIELDS } from "./security/index";
@@ -461,7 +459,6 @@ export { TOKEN_PII_FIELDS } from "./security/index";
461
459
  export { TOKEN_PII_INDEX_MAP } from "./security/index";
462
460
  export { USER_PII_FIELDS } from "./security/index";
463
461
  export { USER_PII_INDEX_MAP } from "./security/index";
464
- export { addPiiIndices } from "./security/index";
465
462
  export { applyRateLimit } from "./security/index";
466
463
  export { buildCSP } from "./security/index";
467
464
  export { canChangeRole } from "./security/index";
@@ -470,42 +467,19 @@ export { createRbacHook } from "./security/index";
470
467
  export { createRbacMiddleware } from "./security/index";
471
468
  export { createRequirePermission } from "./security/index";
472
469
  export { createRequirePermissionSync } from "./security/index";
473
- export { decryptPayoutBankAccount } from "./security/index";
474
- export { decryptPayoutDetails } from "./security/index";
475
- export { decryptPii } from "./security/index";
476
- export { decryptPiiFields } from "./security/index";
477
470
  export { decryptSecret } from "./security/index";
478
- export { decryptShippingAddress } from "./security/index";
479
- export { decryptShippingConfig } from "./security/index";
480
- export { decryptValue } from "./security/index";
481
- export { encryptPayoutBankAccount } from "./security/index";
482
- export { encryptPayoutDetails } from "./security/index";
483
- export { encryptPii } from "./security/index";
484
- export { encryptPiiFields } from "./security/index";
485
471
  export { encryptSecret } from "./security/index";
486
- export { encryptShippingAddress } from "./security/index";
487
- export { encryptShippingConfig } from "./security/index";
488
- export { encryptValue } from "./security/index";
489
472
  export { generateNonce } from "./security/index";
490
- export { getPiiConfigError } from "./security/index";
491
473
  export { getRoleLevel } from "./security/index";
492
474
  export { hasAllPermissions } from "./security/index";
493
475
  export { hasAnyPermission } from "./security/index";
494
476
  export { hasPermission } from "./security/index";
495
- export { hmacBlindIndex } from "./security/index";
496
- export { isPiiEncrypted } from "./security/index";
497
477
  export { isSecretEncrypted } from "./security/index";
498
- export { maskEmail } from "./security/index";
499
- export { maskName } from "./security/index";
500
- export { maskOfferForSeller } from "./security/index";
501
- export { maskPublicBid } from "./security/index";
502
- export { maskPublicEventEntry } from "./security/index";
503
- export { maskPublicReview } from "./security/index";
504
478
  export { maskSecret } from "./security/index";
505
- export { piiBlindIndex } from "./security/index";
506
479
  export { rateLimit } from "./security/index";
507
480
  export { rateLimitByIdentifier } from "./security/index";
508
481
  export { redactPii, safeDisplayName, safeDisplayEmail } from "./security/index";
482
+ export { isPiiEncrypted, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./security/index";
509
483
  export { requireActiveAccount } from "./security/index";
510
484
  export { requireAuth } from "./security/index";
511
485
  export { requireEmailVerified } from "./security/index";
package/dist/index.js CHANGED
@@ -782,17 +782,11 @@ export { Can } from "./security/index";
782
782
  // DEFAULT_ROLES - Constant used across modules.
783
783
  export { DEFAULT_ROLES } from "./security/index";
784
784
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
785
- // ENC_PREFIX - Constant used across modules.
786
- export { ENC_PREFIX } from "./security/index";
787
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
788
785
  // EVENT_ENTRY_PII_FIELDS - Constant used across modules.
789
786
  export { EVENT_ENTRY_PII_FIELDS } from "./security/index";
790
787
  // LOTTERY_ENTRY_PII_FIELDS - PII fields for lottery entries.
791
788
  export { LOTTERY_ENTRY_PII_FIELDS } from "./security/index";
792
789
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
793
- // HMAC_PREFIX - Constant used across modules.
794
- export { HMAC_PREFIX } from "./security/index";
795
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
796
790
  // NEWSLETTER_PII_FIELDS - Constant used across modules.
797
791
  export { NEWSLETTER_PII_FIELDS } from "./security/index";
798
792
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
@@ -832,9 +826,6 @@ export { USER_PII_FIELDS } from "./security/index";
832
826
  // USER_PII_INDEX_MAP - Constant used across modules.
833
827
  export { USER_PII_INDEX_MAP } from "./security/index";
834
828
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
835
- // addPiiIndices - Helper for add pii indices.
836
- export { addPiiIndices } from "./security/index";
837
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
838
829
  // applyRateLimit - Helper for apply rate limit.
839
830
  export { applyRateLimit } from "./security/index";
840
831
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
@@ -859,60 +850,15 @@ export { createRequirePermission } from "./security/index";
859
850
  // createRequirePermissionSync - Helper for create require permission sync.
860
851
  export { createRequirePermissionSync } from "./security/index";
861
852
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
862
- // decryptPayoutBankAccount - Helper for decrypt payout bank account.
863
- export { decryptPayoutBankAccount } from "./security/index";
864
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
865
- // decryptPayoutDetails - Helper for decrypt payout details.
866
- export { decryptPayoutDetails } from "./security/index";
867
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
868
- // decryptPii - Helper for decrypt pii.
869
- export { decryptPii } from "./security/index";
870
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
871
- // decryptPiiFields - Helper for decrypt pii fields.
872
- export { decryptPiiFields } from "./security/index";
873
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
874
853
  // decryptSecret - Helper for decrypt secret.
875
854
  export { decryptSecret } from "./security/index";
876
855
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
877
- // decryptShippingAddress - Helper for decrypt shipping address.
878
- export { decryptShippingAddress } from "./security/index";
879
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
880
- // decryptShippingConfig - Helper for decrypt shipping config.
881
- export { decryptShippingConfig } from "./security/index";
882
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
883
- // decryptValue - Helper for decrypt value.
884
- export { decryptValue } from "./security/index";
885
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
886
- // encryptPayoutBankAccount - Helper for encrypt payout bank account.
887
- export { encryptPayoutBankAccount } from "./security/index";
888
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
889
- // encryptPayoutDetails - Helper for encrypt payout details.
890
- export { encryptPayoutDetails } from "./security/index";
891
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
892
- // encryptPii - Helper for encrypt pii.
893
- export { encryptPii } from "./security/index";
894
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
895
- // encryptPiiFields - Helper for encrypt pii fields.
896
- export { encryptPiiFields } from "./security/index";
897
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
898
856
  // encryptSecret - Helper for encrypt secret.
899
857
  export { encryptSecret } from "./security/index";
900
858
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
901
- // encryptShippingAddress - Helper for encrypt shipping address.
902
- export { encryptShippingAddress } from "./security/index";
903
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
904
- // encryptShippingConfig - Helper for encrypt shipping config.
905
- export { encryptShippingConfig } from "./security/index";
906
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
907
- // encryptValue - Helper for encrypt value.
908
- export { encryptValue } from "./security/index";
909
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
910
859
  // generateNonce - Helper for generate nonce.
911
860
  export { generateNonce } from "./security/index";
912
861
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
913
- // getPiiConfigError - Helper for get pii config error.
914
- export { getPiiConfigError } from "./security/index";
915
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
916
862
  // getRoleLevel - Helper for get role level.
917
863
  export { getRoleLevel } from "./security/index";
918
864
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
@@ -925,39 +871,12 @@ export { hasAnyPermission } from "./security/index";
925
871
  // hasPermission - Model for has permission.
926
872
  export { hasPermission } from "./security/index";
927
873
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
928
- // hmacBlindIndex - Shared export for hmac blind index.
929
- export { hmacBlindIndex } from "./security/index";
930
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
931
- // isPiiEncrypted - Shared export for is pii encrypted.
932
- export { isPiiEncrypted } from "./security/index";
933
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
934
874
  // isSecretEncrypted - Shared export for is secret encrypted.
935
875
  export { isSecretEncrypted } from "./security/index";
936
876
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
937
- // maskEmail - Helper for mask email.
938
- export { maskEmail } from "./security/index";
939
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
940
- // maskName - Helper for mask name.
941
- export { maskName } from "./security/index";
942
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
943
- // maskOfferForSeller - Helper for mask offer for seller.
944
- export { maskOfferForSeller } from "./security/index";
945
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
946
- // maskPublicBid - Helper for mask public bid.
947
- export { maskPublicBid } from "./security/index";
948
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
949
- // maskPublicEventEntry - Helper for mask public event entry.
950
- export { maskPublicEventEntry } from "./security/index";
951
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
952
- // maskPublicReview - Helper for mask public review.
953
- export { maskPublicReview } from "./security/index";
954
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
955
877
  // maskSecret - Helper for mask secret.
956
878
  export { maskSecret } from "./security/index";
957
879
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
958
- // piiBlindIndex - Shared export for pii blind index.
959
- export { piiBlindIndex } from "./security/index";
960
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
961
880
  // rateLimit - Shared export for rate limit.
962
881
  export { rateLimit } from "./security/index";
963
882
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
@@ -966,6 +885,8 @@ export { rateLimitByIdentifier } from "./security/index";
966
885
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
967
886
  // redactPii - Shared export for redact pii.
968
887
  export { redactPii, safeDisplayName, safeDisplayEmail } from "./security/index";
888
+ // [CLIENT-SSR]-Runs in both SSR and browser â€" pure display-masking helpers, no crypto dependency.
889
+ export { isPiiEncrypted, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./security/index";
969
890
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
970
891
  // requireActiveAccount - Shared export for require active account.
971
892
  export { requireActiveAccount } from "./security/index";
@@ -4,7 +4,8 @@ export type { RateLimitConfig, RateLimitResult } from "./rate-limit";
4
4
  export { requireAuth, requireRole, requireOwnership, requireEmailVerified, requireActiveAccount, canChangeRole, getRoleLevel, } from "./authorization";
5
5
  export type { UserRole } from "./authorization";
6
6
  export { redactPii, safeDisplayName, safeDisplayEmail, maskIp } from "./pii-redact";
7
- export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, isPiiEncrypted, piiBlindIndex, addPiiIndices, getPiiConfigError, encryptShippingAddress, decryptShippingAddress, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, encryptPayoutBankAccount, decryptPayoutBankAccount, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-encrypt";
7
+ export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, piiBlindIndex, addPiiIndices, getPiiConfigError, encryptShippingAddress, decryptShippingAddress, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, encryptPayoutBankAccount, decryptPayoutBankAccount, } from "./pii-encrypt";
8
+ export { isPiiEncrypted, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-mask";
8
9
  export { USER_PII_FIELDS, USER_PII_INDEX_MAP, ADDRESS_PII_FIELDS, ORDER_PII_FIELDS, PAYOUT_PII_FIELDS, PAYOUT_PII_INDEX_MAP, BID_PII_FIELDS, NEWSLETTER_PII_FIELDS, NEWSLETTER_PII_INDEX_MAP, TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, REVIEW_PII_FIELDS, REVIEW_PII_INDEX_MAP, OFFER_PII_FIELDS, CHAT_PII_FIELDS, EVENT_ENTRY_PII_FIELDS, LOTTERY_ENTRY_PII_FIELDS, PAYMENT_METHOD_PII_FIELDS, } from "./pii-schemas";
9
10
  export { encryptSecret, decryptSecret, isSecretEncrypted, maskSecret, } from "./settings-encryption";
10
11
  export type { Permission, RoleDefinition, RbacConfig, ResolvedUser, RbacHookReturn, } from "./rbac";
@@ -2,7 +2,11 @@ export { generateNonce, buildCSP } from "./csp";
2
2
  export { rateLimit, applyRateLimit, rateLimitByIdentifier, RateLimitPresets, clearRateLimitStore, } from "./rate-limit";
3
3
  export { requireAuth, requireRole, requireOwnership, requireEmailVerified, requireActiveAccount, canChangeRole, getRoleLevel, } from "./authorization";
4
4
  export { redactPii, safeDisplayName, safeDisplayEmail, maskIp } from "./pii-redact";
5
- export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, isPiiEncrypted, piiBlindIndex, addPiiIndices, getPiiConfigError, encryptShippingAddress, decryptShippingAddress, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, encryptPayoutBankAccount, decryptPayoutBankAccount, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-encrypt";
5
+ export { encryptValue, decryptValue, hmacBlindIndex, encryptPiiFields, decryptPiiFields, encryptPii, decryptPii, piiBlindIndex, addPiiIndices, getPiiConfigError, encryptShippingAddress, decryptShippingAddress, encryptPayoutDetails, decryptPayoutDetails, encryptShippingConfig, decryptShippingConfig, encryptPayoutBankAccount, decryptPayoutBankAccount, } from "./pii-encrypt";
6
+ // Crypto-free display-masking helpers -- sourced from pii-mask.ts (not
7
+ // pii-encrypt.ts) so this barrel stays safe to re-export from the
8
+ // universal client+server index.ts. See pii-mask.ts's header comment.
9
+ export { isPiiEncrypted, maskName, maskEmail, maskPublicReview, maskPublicBid, maskPublicEventEntry, maskOfferForSeller, ENC_PREFIX, HMAC_PREFIX, } from "./pii-mask";
6
10
  export { USER_PII_FIELDS, USER_PII_INDEX_MAP, ADDRESS_PII_FIELDS, ORDER_PII_FIELDS, PAYOUT_PII_FIELDS, PAYOUT_PII_INDEX_MAP, BID_PII_FIELDS, NEWSLETTER_PII_FIELDS, NEWSLETTER_PII_INDEX_MAP, TOKEN_PII_FIELDS, TOKEN_PII_INDEX_MAP, REVIEW_PII_FIELDS, REVIEW_PII_INDEX_MAP, OFFER_PII_FIELDS, CHAT_PII_FIELDS, EVENT_ENTRY_PII_FIELDS, LOTTERY_ENTRY_PII_FIELDS, PAYMENT_METHOD_PII_FIELDS, } from "./pii-schemas";
7
11
  export { encryptSecret, decryptSecret, isSecretEncrypted, maskSecret, } from "./settings-encryption";
8
12
  export { DEFAULT_ROLES, resolvePermissions, hasPermission, hasAllPermissions, hasAnyPermission, createRbacHook, Can, createRequirePermission, createRequirePermissionSync, createRbacMiddleware, } from "./rbac";
@@ -9,8 +9,8 @@
9
9
  * Ciphertext format: "enc:v1:<iv_b64>:<ciphertext_b64>:<authtag_b64>"
10
10
  * Blind index format: "hmac-sha256:<sha256_hex>"
11
11
  */
12
- export declare const ENC_PREFIX = "enc:v1:";
13
- export declare const HMAC_PREFIX = "hmac-sha256:";
12
+ import { ENC_PREFIX, HMAC_PREFIX, isPiiEncrypted } from "./pii-mask";
13
+ export { ENC_PREFIX, HMAC_PREFIX, isPiiEncrypted };
14
14
  export declare function getPiiConfigError(): string | null;
15
15
  /** Encrypt a plaintext string with AES-256-GCM. */
16
16
  export declare function encryptValue(plaintext: string): string;
@@ -36,8 +36,6 @@ export declare function decryptPiiFields<T extends object>(doc: T, piiFields: st
36
36
  export declare function encryptPii(plaintext: string | null | undefined): string | null | undefined;
37
37
  /** Alias for decryptValue — decrypts a PII ciphertext. */
38
38
  export declare function decryptPii(ciphertext: string | null | undefined): string | null | undefined;
39
- /** Check if a value is encrypted by our PII system. */
40
- export declare function isPiiEncrypted(value: string): boolean;
41
39
  /** Alias for hmacBlindIndex. */
42
40
  export declare function piiBlindIndex(plaintext: string): string;
43
41
  /**
@@ -80,52 +78,3 @@ export declare function encryptPayoutBankAccount<T extends object>(bank: T | und
80
78
  * Decrypt PII on a payout bankAccount sub-object from the payouts collection.
81
79
  */
82
80
  export declare function decryptPayoutBankAccount<T extends object>(bank: T | undefined | null): T | undefined | null;
83
- /**
84
- * Mask a person's name for public display.
85
- * Each word is reduced to its first letter followed by "***".
86
- *
87
- * "John Doe" → "J*** D***"
88
- * "Alice" → "A***"
89
- *
90
- * If the value is still an encrypted blob (e.g. PII_ENCRYPTION_KEY not set),
91
- * returns "Anonymous" so encrypted ciphertext never leaks to the UI.
92
- */
93
- export declare function maskName(name: string | null | undefined): string;
94
- /**
95
- * Mask an email address for public display.
96
- * "john.doe@example.com" → "j***@***.com"
97
- */
98
- export declare function maskEmail(email: string | null | undefined): string;
99
- /**
100
- * Return a copy of a review document with PII fields masked for public display.
101
- * Admin/owner endpoints should NOT call this — use the raw document instead.
102
- */
103
- export declare function maskPublicReview<T extends {
104
- userName: string;
105
- }>(review: T): T;
106
- /**
107
- * Return a copy of a bid document with PII masked for public display
108
- * (auction product page).
109
- */
110
- export declare function maskPublicBid<T extends {
111
- userName: string;
112
- }>(bid: T): T;
113
- /**
114
- * Return a copy of an event-entry document with PII masked for the leaderboard.
115
- * ipAddress and userEmail are never sent to the client;
116
- * only userDisplayName needs masking for a public leaderboard view.
117
- */
118
- export declare function maskPublicEventEntry<T extends {
119
- userDisplayName?: string;
120
- userEmail?: string;
121
- ipAddress?: string;
122
- }>(entry: T): Omit<T, "userEmail" | "ipAddress">;
123
- /**
124
- * Return a copy of an offer document with buyer PII masked for the seller view.
125
- * The seller needs to know an offer was made and its amount, but the buyer's
126
- * full name and email should remain private until the order is confirmed.
127
- */
128
- export declare function maskOfferForSeller<T extends {
129
- buyerName: string;
130
- buyerEmail: string;
131
- }>(offer: T): T;
@@ -9,22 +9,26 @@
9
9
  * Ciphertext format: "enc:v1:<iv_b64>:<ciphertext_b64>:<authtag_b64>"
10
10
  * Blind index format: "hmac-sha256:<sha256_hex>"
11
11
  */
12
- import { createRequire } from "node:module";
13
- // crypto is a Node.js built-in. Use require() to keep it out of the static
14
- // import graph so Next.js Edge bundler does not warn about this file. A bare
15
- // top-level `require(...)` call only works when the compiled dist output is
16
- // loaded via CommonJS (or a bundler that polyfills `require`) — under a
17
- // plain Node ESM `import()` (e.g. appkit/scripts/seed-cli.mjs and any other
18
- // standalone script importing @mohasinac/appkit directly), there is no
19
- // ambient `require` global, so that call threw `ReferenceError: require is
20
- // not defined`. createRequire(import.meta.url) works in both: it's still a
21
- // runtime function call a bundler's static analysis won't follow into the
22
- // client graph, but it resolves correctly under Node's own ESM loader too.
23
- const nodeRequire = createRequire(import.meta.url);
24
- function nodeCrypto() { return nodeRequire("crypto"); }
12
+ import { ENC_PREFIX, HMAC_PREFIX, isPiiEncrypted } from "./pii-mask";
13
+ // Re-exported for backward-compat with existing direct imports of these
14
+ // symbols from this file the actual crypto-free definitions live in
15
+ // pii-mask.ts (see that file's header comment for why the split exists).
16
+ export { ENC_PREFIX, HMAC_PREFIX, isPiiEncrypted };
17
+ // crypto is a Node.js built-in. A bare, non-static `require(...)` call
18
+ // (never a top-level `import ... from "node:module"`/"crypto") is
19
+ // deliberate: bundlers targeting the browser (Turbopack in particular)
20
+ // statically resolve every top-level import in a module's chain before any
21
+ // tree-shaking pass, and hard-fail immediately on an unresolvable Node
22
+ // builtin even if the symbol using it is never actually consumed
23
+ // client-side. A bare `require` reference inside a function body is a
24
+ // runtime lookup, not a static import, so it's invisible to that pass.
25
+ // This only works where an ambient `require` global exists: Next.js's own
26
+ // server bundle (webpack/Turbopack) provides one automatically; the one
27
+ // place that doesn't is a standalone pure-ESM script importing
28
+ // @mohasinac/appkit directly (appkit/scripts/seed-cli.mjs), which sets
29
+ // `globalThis.require` itself before importing appkit — see that file.
30
+ function nodeCrypto() { return require("crypto"); }
25
31
  const ALGO = "aes-256-gcm";
26
- export const ENC_PREFIX = "enc:v1:";
27
- export const HMAC_PREFIX = "hmac-sha256:";
28
32
  function normalizePiiSecretValue(raw) {
29
33
  return (raw ?? "").replace(/(?:\\r|\\n|\r|\n)+$/g, "").trim();
30
34
  }
@@ -139,10 +143,6 @@ export function decryptPii(ciphertext) {
139
143
  return ciphertext;
140
144
  return decryptValue(ciphertext);
141
145
  }
142
- /** Check if a value is encrypted by our PII system. */
143
- export function isPiiEncrypted(value) {
144
- return typeof value === "string" && value.startsWith(ENC_PREFIX);
145
- }
146
146
  /** Alias for hmacBlindIndex. */
147
147
  export function piiBlindIndex(plaintext) {
148
148
  return hmacBlindIndex(plaintext);
@@ -278,84 +278,3 @@ export function decryptPayoutBankAccount(bank) {
278
278
  return bank;
279
279
  return decryptPiiFields({ ...bank }, []);
280
280
  }
281
- // --- Public display masking -------------------------------------------------
282
- /**
283
- * Mask a person's name for public display.
284
- * Each word is reduced to its first letter followed by "***".
285
- *
286
- * "John Doe" → "J*** D***"
287
- * "Alice" → "A***"
288
- *
289
- * If the value is still an encrypted blob (e.g. PII_ENCRYPTION_KEY not set),
290
- * returns "Anonymous" so encrypted ciphertext never leaks to the UI.
291
- */
292
- export function maskName(name) {
293
- if (!name || typeof name !== "string")
294
- return "Anonymous";
295
- if (isPiiEncrypted(name))
296
- return "Anonymous";
297
- return name
298
- .trim()
299
- .split(/\s+/)
300
- .filter(Boolean)
301
- .map((word) => word[0] + "***")
302
- .join(" ");
303
- }
304
- /**
305
- * Mask an email address for public display.
306
- * "john.doe@example.com" → "j***@***.com"
307
- */
308
- export function maskEmail(email) {
309
- if (!email || typeof email !== "string")
310
- return "***@***.***";
311
- if (isPiiEncrypted(email))
312
- return "***@***.***";
313
- const atIdx = email.indexOf("@");
314
- if (atIdx < 0)
315
- return "***";
316
- const local = email.slice(0, atIdx);
317
- const domain = email.slice(atIdx + 1);
318
- const dotIdx = domain.lastIndexOf(".");
319
- const domainMasked = dotIdx > 0 ? "***" + domain.slice(dotIdx) : "***";
320
- return (local[0] ?? "*") + "***@" + domainMasked;
321
- }
322
- /**
323
- * Return a copy of a review document with PII fields masked for public display.
324
- * Admin/owner endpoints should NOT call this — use the raw document instead.
325
- */
326
- export function maskPublicReview(review) {
327
- return { ...review, userName: maskName(review.userName) };
328
- }
329
- /**
330
- * Return a copy of a bid document with PII masked for public display
331
- * (auction product page).
332
- */
333
- export function maskPublicBid(bid) {
334
- return { ...bid };
335
- }
336
- /**
337
- * Return a copy of an event-entry document with PII masked for the leaderboard.
338
- * ipAddress and userEmail are never sent to the client;
339
- * only userDisplayName needs masking for a public leaderboard view.
340
- */
341
- export function maskPublicEventEntry(entry) {
342
- const { userEmail: _e, ipAddress: _ip, ...rest } = entry;
343
- return {
344
- ...rest,
345
- ...(rest.userDisplayName !== undefined
346
- ? { userDisplayName: maskName(rest.userDisplayName) }
347
- : {}),
348
- };
349
- }
350
- /**
351
- * Return a copy of an offer document with buyer PII masked for the seller view.
352
- * The seller needs to know an offer was made and its amount, but the buyer's
353
- * full name and email should remain private until the order is confirmed.
354
- */
355
- export function maskOfferForSeller(offer) {
356
- return {
357
- ...offer,
358
- buyerName: maskName(offer.buyerName),
359
- buyerEmail: maskEmail(offer.buyerEmail),
360
- };
361
- }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * PII display-masking helpers — pure string manipulation, zero runtime
3
+ * dependencies. Split out from pii-encrypt.ts so these can be exported
4
+ * from the universal client+server barrel (index.ts): pii-encrypt.ts has
5
+ * a top-level `import { createRequire } from "node:module"` (needed for
6
+ * the AES-256-GCM/HMAC functions to work under both Next.js's bundler and
7
+ * a pure-ESM standalone script context) that poisons the whole module for
8
+ * client bundling — Turbopack statically resolves every export in a file
9
+ * before tree-shaking, so re-exporting even one crypto-free symbol from
10
+ * pii-encrypt.ts still pulls `node:module` into the client graph and hard
11
+ * fails the browser build. This file has no such import and is safe
12
+ * anywhere `ReviewModal`/`ReviewDetailShell`/`ReviewsList` (client
13
+ * components displaying masked reviewer names) can reach it.
14
+ */
15
+ export declare const ENC_PREFIX = "enc:v1:";
16
+ export declare const HMAC_PREFIX = "hmac-sha256:";
17
+ /** Check if a value is encrypted by our PII system. */
18
+ export declare function isPiiEncrypted(value: string): boolean;
19
+ /**
20
+ * Mask a person's name for public display.
21
+ * Each word is reduced to its first letter followed by "***".
22
+ *
23
+ * "John Doe" → "J*** D***"
24
+ * "Alice" → "A***"
25
+ *
26
+ * If the value is still an encrypted blob (e.g. PII_ENCRYPTION_KEY not set),
27
+ * returns "Anonymous" so encrypted ciphertext never leaks to the UI.
28
+ */
29
+ export declare function maskName(name: string | null | undefined): string;
30
+ /**
31
+ * Mask an email address for public display.
32
+ * "john.doe@example.com" → "j***@***.com"
33
+ */
34
+ export declare function maskEmail(email: string | null | undefined): string;
35
+ /**
36
+ * Return a copy of a review document with PII fields masked for public display.
37
+ * Admin/owner endpoints should NOT call this — use the raw document instead.
38
+ */
39
+ export declare function maskPublicReview<T extends {
40
+ userName: string;
41
+ }>(review: T): T;
42
+ /**
43
+ * Return a copy of a bid document with PII masked for public display
44
+ * (auction product page).
45
+ */
46
+ export declare function maskPublicBid<T extends {
47
+ userName: string;
48
+ }>(bid: T): T;
49
+ /**
50
+ * Return a copy of an event-entry document with PII masked for the leaderboard.
51
+ * ipAddress and userEmail are never sent to the client;
52
+ * only userDisplayName needs masking for a public leaderboard view.
53
+ */
54
+ export declare function maskPublicEventEntry<T extends {
55
+ userDisplayName?: string;
56
+ userEmail?: string;
57
+ ipAddress?: string;
58
+ }>(entry: T): Omit<T, "userEmail" | "ipAddress">;
59
+ /**
60
+ * Return a copy of an offer document with buyer PII masked for the seller view.
61
+ * The seller needs to know an offer was made and its amount, but the buyer's
62
+ * full name and email should remain private until the order is confirmed.
63
+ */
64
+ export declare function maskOfferForSeller<T extends {
65
+ buyerName: string;
66
+ buyerEmail: string;
67
+ }>(offer: T): T;
@@ -0,0 +1,100 @@
1
+ /**
2
+ * PII display-masking helpers — pure string manipulation, zero runtime
3
+ * dependencies. Split out from pii-encrypt.ts so these can be exported
4
+ * from the universal client+server barrel (index.ts): pii-encrypt.ts has
5
+ * a top-level `import { createRequire } from "node:module"` (needed for
6
+ * the AES-256-GCM/HMAC functions to work under both Next.js's bundler and
7
+ * a pure-ESM standalone script context) that poisons the whole module for
8
+ * client bundling — Turbopack statically resolves every export in a file
9
+ * before tree-shaking, so re-exporting even one crypto-free symbol from
10
+ * pii-encrypt.ts still pulls `node:module` into the client graph and hard
11
+ * fails the browser build. This file has no such import and is safe
12
+ * anywhere `ReviewModal`/`ReviewDetailShell`/`ReviewsList` (client
13
+ * components displaying masked reviewer names) can reach it.
14
+ */
15
+ export const ENC_PREFIX = "enc:v1:";
16
+ export const HMAC_PREFIX = "hmac-sha256:";
17
+ /** Check if a value is encrypted by our PII system. */
18
+ export function isPiiEncrypted(value) {
19
+ return typeof value === "string" && value.startsWith(ENC_PREFIX);
20
+ }
21
+ /**
22
+ * Mask a person's name for public display.
23
+ * Each word is reduced to its first letter followed by "***".
24
+ *
25
+ * "John Doe" → "J*** D***"
26
+ * "Alice" → "A***"
27
+ *
28
+ * If the value is still an encrypted blob (e.g. PII_ENCRYPTION_KEY not set),
29
+ * returns "Anonymous" so encrypted ciphertext never leaks to the UI.
30
+ */
31
+ export function maskName(name) {
32
+ if (!name || typeof name !== "string")
33
+ return "Anonymous";
34
+ if (isPiiEncrypted(name))
35
+ return "Anonymous";
36
+ return name
37
+ .trim()
38
+ .split(/\s+/)
39
+ .filter(Boolean)
40
+ .map((word) => word[0] + "***")
41
+ .join(" ");
42
+ }
43
+ /**
44
+ * Mask an email address for public display.
45
+ * "john.doe@example.com" → "j***@***.com"
46
+ */
47
+ export function maskEmail(email) {
48
+ if (!email || typeof email !== "string")
49
+ return "***@***.***";
50
+ if (isPiiEncrypted(email))
51
+ return "***@***.***";
52
+ const atIdx = email.indexOf("@");
53
+ if (atIdx < 0)
54
+ return "***";
55
+ const local = email.slice(0, atIdx);
56
+ const domain = email.slice(atIdx + 1);
57
+ const dotIdx = domain.lastIndexOf(".");
58
+ const domainMasked = dotIdx > 0 ? "***" + domain.slice(dotIdx) : "***";
59
+ return (local[0] ?? "*") + "***@" + domainMasked;
60
+ }
61
+ /**
62
+ * Return a copy of a review document with PII fields masked for public display.
63
+ * Admin/owner endpoints should NOT call this — use the raw document instead.
64
+ */
65
+ export function maskPublicReview(review) {
66
+ return { ...review, userName: maskName(review.userName) };
67
+ }
68
+ /**
69
+ * Return a copy of a bid document with PII masked for public display
70
+ * (auction product page).
71
+ */
72
+ export function maskPublicBid(bid) {
73
+ return { ...bid };
74
+ }
75
+ /**
76
+ * Return a copy of an event-entry document with PII masked for the leaderboard.
77
+ * ipAddress and userEmail are never sent to the client;
78
+ * only userDisplayName needs masking for a public leaderboard view.
79
+ */
80
+ export function maskPublicEventEntry(entry) {
81
+ const { userEmail: _e, ipAddress: _ip, ...rest } = entry;
82
+ return {
83
+ ...rest,
84
+ ...(rest.userDisplayName !== undefined
85
+ ? { userDisplayName: maskName(rest.userDisplayName) }
86
+ : {}),
87
+ };
88
+ }
89
+ /**
90
+ * Return a copy of an offer document with buyer PII masked for the seller view.
91
+ * The seller needs to know an offer was made and its amount, but the buyer's
92
+ * full name and email should remain private until the order is confirmed.
93
+ */
94
+ export function maskOfferForSeller(offer) {
95
+ return {
96
+ ...offer,
97
+ buyerName: maskName(offer.buyerName),
98
+ buyerEmail: maskEmail(offer.buyerEmail),
99
+ };
100
+ }
package/dist/server.d.ts CHANGED
@@ -454,6 +454,32 @@ export { applyRateLimit } from "./security/index";
454
454
  export { rateLimitByIdentifier } from "./security/index";
455
455
  export { RateLimitPresets } from "./security/index";
456
456
  export { maskPublicEventEntry } from "./security/index";
457
+ export { encryptValue } from "./security/index";
458
+ export { decryptValue } from "./security/index";
459
+ export { hmacBlindIndex } from "./security/index";
460
+ export { encryptPiiFields } from "./security/index";
461
+ export { decryptPiiFields } from "./security/index";
462
+ export { encryptPii } from "./security/index";
463
+ export { decryptPii } from "./security/index";
464
+ export { isPiiEncrypted } from "./security/index";
465
+ export { piiBlindIndex } from "./security/index";
466
+ export { addPiiIndices } from "./security/index";
467
+ export { getPiiConfigError } from "./security/index";
468
+ export { encryptShippingAddress } from "./security/index";
469
+ export { decryptShippingAddress } from "./security/index";
470
+ export { encryptPayoutDetails } from "./security/index";
471
+ export { decryptPayoutDetails } from "./security/index";
472
+ export { encryptShippingConfig } from "./security/index";
473
+ export { decryptShippingConfig } from "./security/index";
474
+ export { encryptPayoutBankAccount } from "./security/index";
475
+ export { decryptPayoutBankAccount } from "./security/index";
476
+ export { maskName } from "./security/index";
477
+ export { maskEmail } from "./security/index";
478
+ export { maskPublicReview } from "./security/index";
479
+ export { maskPublicBid } from "./security/index";
480
+ export { maskOfferForSeller } from "./security/index";
481
+ export { ENC_PREFIX } from "./security/index";
482
+ export { HMAC_PREFIX } from "./security/index";
457
483
  export { createInstrumentation } from "./instrumentation/index";
458
484
  export { SEO_CONFIG } from "./seo/index";
459
485
  export { createSeoConfig } from "./seo/index";
package/dist/server.js CHANGED
@@ -1312,6 +1312,33 @@ export { rateLimitByIdentifier } from "./security/index";
1312
1312
  export { RateLimitPresets } from "./security/index";
1313
1313
  // maskPublicEventEntry - Redact PII from event entries before public exposure.
1314
1314
  export { maskPublicEventEntry } from "./security/index";
1315
+ // PII encryption/masking (server-only -- crypto module via node:module, must never leak into a client bundle; see appkit Export Rules in CLAUDE.md)
1316
+ export { encryptValue } from "./security/index";
1317
+ export { decryptValue } from "./security/index";
1318
+ export { hmacBlindIndex } from "./security/index";
1319
+ export { encryptPiiFields } from "./security/index";
1320
+ export { decryptPiiFields } from "./security/index";
1321
+ export { encryptPii } from "./security/index";
1322
+ export { decryptPii } from "./security/index";
1323
+ export { isPiiEncrypted } from "./security/index";
1324
+ export { piiBlindIndex } from "./security/index";
1325
+ export { addPiiIndices } from "./security/index";
1326
+ export { getPiiConfigError } from "./security/index";
1327
+ export { encryptShippingAddress } from "./security/index";
1328
+ export { decryptShippingAddress } from "./security/index";
1329
+ export { encryptPayoutDetails } from "./security/index";
1330
+ export { decryptPayoutDetails } from "./security/index";
1331
+ export { encryptShippingConfig } from "./security/index";
1332
+ export { decryptShippingConfig } from "./security/index";
1333
+ export { encryptPayoutBankAccount } from "./security/index";
1334
+ export { decryptPayoutBankAccount } from "./security/index";
1335
+ export { maskName } from "./security/index";
1336
+ export { maskEmail } from "./security/index";
1337
+ export { maskPublicReview } from "./security/index";
1338
+ export { maskPublicBid } from "./security/index";
1339
+ export { maskOfferForSeller } from "./security/index";
1340
+ export { ENC_PREFIX } from "./security/index";
1341
+ export { HMAC_PREFIX } from "./security/index";
1315
1342
  // -- Instrumentation ---------------------------------------------------------
1316
1343
  // createInstrumentation - Factory for Next.js instrumentation hooks.
1317
1344
  export { createInstrumentation } from "./instrumentation/index";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "3.8.0",
3
+ "version": "3.8.2",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -117,6 +117,15 @@ if (ACTION === "load" && !PII_KEY_PRESENT) {
117
117
  // firebase-admin init
118
118
  // ---------------------------------------------------------------------------
119
119
  const require = createRequire(import.meta.url);
120
+ // appkit's pii-encrypt.ts calls a bare `require("crypto")` at runtime (not a
121
+ // static import — deliberately, so bundlers like Turbopack never see a
122
+ // node:module dependency and refuse to build the client bundle). A bare
123
+ // `require` identifier resolves via the global scope in Node ESM, so it must
124
+ // exist as a global before the dynamic `import("@mohasinac/appkit")` below
125
+ // ever triggers that code path. Only this standalone-script environment
126
+ // needs it — Next.js's own server bundle (webpack/Turbopack) provides an
127
+ // ambient `require` automatically.
128
+ globalThis.require = require;
120
129
  const admin = require("firebase-admin");
121
130
 
122
131
  function parsePrivateKey(raw) {