@szymonpiatek/nextwordpress 0.0.5 → 0.0.7

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,9 +1,115 @@
1
+ import { createContext, useState, useCallback, useEffect, useContext, useReducer } from 'react';
2
+ import { jsx } from 'react/jsx-runtime';
1
3
  import useSWR2 from 'swr';
2
4
 
3
5
  var __defProp = Object.defineProperty;
4
6
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
7
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
8
 
9
+ // src/shared/url.ts
10
+ function resolveBaseUrl(config) {
11
+ return typeof window === "undefined" ? config.serverURL : config.clientURL;
12
+ }
13
+
14
+ // src/auth/types.ts
15
+ var AuthenticationError = class extends Error {
16
+ constructor(message, status) {
17
+ super(message);
18
+ __publicField(this, "status", status);
19
+ this.name = "AuthenticationError";
20
+ }
21
+ };
22
+
23
+ // src/auth/jwt.ts
24
+ async function authenticateJwt(config, credentials) {
25
+ const url = `${resolveBaseUrl(config)}/wp-json/jwt-auth/v1/token`;
26
+ const response = await fetch(url, {
27
+ method: "POST",
28
+ headers: { "Content-Type": "application/json" },
29
+ body: JSON.stringify(credentials),
30
+ cache: "no-store"
31
+ });
32
+ if (!response.ok) {
33
+ throw new AuthenticationError(
34
+ `JWT authentication failed: ${response.statusText}`,
35
+ response.status
36
+ );
37
+ }
38
+ return response.json();
39
+ }
40
+ async function validateJwtToken(config, token) {
41
+ const url = `${resolveBaseUrl(config)}/wp-json/jwt-auth/v1/token/validate`;
42
+ const response = await fetch(url, {
43
+ method: "POST",
44
+ headers: { Authorization: `Bearer ${token}` },
45
+ cache: "no-store"
46
+ });
47
+ return response.ok;
48
+ }
49
+ var AuthContext = createContext(null);
50
+ var TOKEN_KEY = "nw_auth_token";
51
+ var USER_KEY = "nw_auth_user";
52
+ function AuthProvider({
53
+ config,
54
+ children
55
+ }) {
56
+ const [user, setUser] = useState(null);
57
+ const [isLoading, setIsLoading] = useState(true);
58
+ const [error, setError] = useState(null);
59
+ const clearStorage = useCallback(() => {
60
+ localStorage.removeItem(TOKEN_KEY);
61
+ localStorage.removeItem(USER_KEY);
62
+ }, []);
63
+ useEffect(() => {
64
+ const token = localStorage.getItem(TOKEN_KEY);
65
+ const storedUser = localStorage.getItem(USER_KEY);
66
+ if (!token || !storedUser) {
67
+ setIsLoading(false);
68
+ return;
69
+ }
70
+ validateJwtToken(config, token).then((valid) => {
71
+ if (valid) {
72
+ setUser(JSON.parse(storedUser));
73
+ } else {
74
+ clearStorage();
75
+ }
76
+ }).catch(() => clearStorage()).finally(() => setIsLoading(false));
77
+ }, []);
78
+ const login = async (credentials) => {
79
+ setError(null);
80
+ setIsLoading(true);
81
+ try {
82
+ const response = await authenticateJwt(config, credentials);
83
+ const authUser = {
84
+ token: response.token,
85
+ email: response.user_email,
86
+ nicename: response.user_nicename,
87
+ displayName: response.user_display_name
88
+ };
89
+ localStorage.setItem(TOKEN_KEY, response.token);
90
+ localStorage.setItem(USER_KEY, JSON.stringify(authUser));
91
+ setUser(authUser);
92
+ } catch (err) {
93
+ const message = err instanceof Error ? err.message : "Authentication failed";
94
+ setError(message);
95
+ throw err;
96
+ } finally {
97
+ setIsLoading(false);
98
+ }
99
+ };
100
+ const logout = () => {
101
+ clearStorage();
102
+ setUser(null);
103
+ setError(null);
104
+ };
105
+ return /* @__PURE__ */ jsx(AuthContext.Provider, { value: { user, isLoggedIn: !!user, isLoading, error, login, logout }, children });
106
+ }
107
+ function useAuth() {
108
+ const ctx = useContext(AuthContext);
109
+ if (!ctx) throw new Error("useAuth must be used within an AuthProvider");
110
+ return ctx;
111
+ }
112
+
7
113
  // src/integrations/restApi/core/client/types.ts
8
114
  var WordPressAPIError = class extends Error {
9
115
  constructor(message, status, endpoint) {
@@ -14,11 +120,6 @@ var WordPressAPIError = class extends Error {
14
120
  }
15
121
  };
16
122
 
17
- // src/shared/url.ts
18
- function resolveBaseUrl(config) {
19
- return typeof window === "undefined" ? config.serverURL : config.clientURL;
20
- }
21
-
22
123
  // src/integrations/restApi/core/client/url.ts
23
124
  function buildUrl(config, path, query) {
24
125
  const base = resolveBaseUrl(config);
@@ -47,7 +148,7 @@ async function doFetch(url, init = {}) {
47
148
  return response;
48
149
  }
49
150
  function createFetcher(config) {
50
- const cacheTtl = 300;
151
+ const cacheTtl = config.cacheTTL ?? 300;
51
152
  async function wpFetch(path, query, tags = ["wordpress"]) {
52
153
  const url = buildUrl(config, path, query);
53
154
  const res = await doFetch(url, {
@@ -250,7 +351,7 @@ function createPostsQueries(fetcher) {
250
351
  };
251
352
  }
252
353
 
253
- // src/hooks/usePosts.ts
354
+ // src/hooks/core/usePosts.ts
254
355
  function usePosts(config, filter, swrOptions) {
255
356
  const key = ["wp-posts", config.clientURL, JSON.stringify(filter ?? null)];
256
357
  return useSWR2(
@@ -313,7 +414,8 @@ function createWooCommerceFetcher(config) {
313
414
  return { ...query, consumer_key: config.consumerKey, consumer_secret: config.consumerSecret };
314
415
  }
315
416
  function buildUrl2(path, query) {
316
- return `${config.serverURL}${path}?${toQueryString(withAuth(query))}`;
417
+ const base = typeof window !== "undefined" && config.clientURL ? config.clientURL : config.serverURL;
418
+ return `${base}${path}?${toQueryString(withAuth(query))}`;
317
419
  }
318
420
  async function wcFetch(path, query, tags = ["woocommerce"], options) {
319
421
  const url = buildUrl2(path, query);
@@ -505,7 +607,7 @@ function createProductsQueries(fetcher) {
505
607
  };
506
608
  }
507
609
 
508
- // src/hooks/useProducts.ts
610
+ // src/hooks/woocommerce/useProducts.ts
509
611
  function useProducts(config, filter, swrOptions) {
510
612
  const key = ["wc-products", config.serverURL, JSON.stringify(filter ?? null)];
511
613
  return useSWR2(
@@ -562,6 +664,258 @@ function useFeaturedProducts(config, limit = 10, swrOptions) {
562
664
  );
563
665
  }
564
666
 
667
+ // src/integrations/restApi/woocommerce/orders/queries.ts
668
+ function createOrdersQueries(fetcher) {
669
+ const { wcFetch, wcFetchGraceful, wcMutate } = fetcher;
670
+ async function createOrder(input) {
671
+ return wcMutate("/wp-json/wc/v3/orders", input, "POST");
672
+ }
673
+ async function getOrderById(id) {
674
+ return wcFetch(`/wp-json/wc/v3/orders/${id}`, void 0, [
675
+ "woocommerce",
676
+ "orders",
677
+ `order-${id}`
678
+ ]);
679
+ }
680
+ async function updateOrder(id, data) {
681
+ return wcMutate(`/wp-json/wc/v3/orders/${id}`, data, "PUT");
682
+ }
683
+ async function getOrdersByCustomer(customerId) {
684
+ return wcFetchGraceful(
685
+ "/wp-json/wc/v3/orders",
686
+ [],
687
+ { customer: customerId, per_page: 100 },
688
+ ["woocommerce", "orders", `orders-customer-${customerId}`]
689
+ );
690
+ }
691
+ async function deleteOrder(id, force = true) {
692
+ return wcMutate(
693
+ `/wp-json/wc/v3/orders/${id}`,
694
+ { force },
695
+ "DELETE"
696
+ );
697
+ }
698
+ return {
699
+ createOrder,
700
+ getOrderById,
701
+ updateOrder,
702
+ getOrdersByCustomer,
703
+ deleteOrder
704
+ };
705
+ }
706
+ var STORAGE_KEY = "nw-cart";
707
+ function isSame(a, b) {
708
+ return a.productId === b.productId && (a.variationId ?? 0) === (b.variationId ?? 0);
709
+ }
710
+ function cartReducer(state, action) {
711
+ switch (action.type) {
712
+ case "LOAD":
713
+ return { items: action.items };
714
+ case "ADD": {
715
+ const existing = state.items.find((i) => isSame(i, action.item));
716
+ if (existing) {
717
+ return {
718
+ items: state.items.map(
719
+ (i) => isSame(i, action.item) ? { ...i, quantity: i.quantity + action.item.quantity } : i
720
+ )
721
+ };
722
+ }
723
+ return { items: [...state.items, action.item] };
724
+ }
725
+ case "REMOVE":
726
+ return { items: state.items.filter((i) => !isSame(i, action)) };
727
+ case "UPDATE":
728
+ if (action.quantity <= 0) {
729
+ return { items: state.items.filter((i) => !isSame(i, action)) };
730
+ }
731
+ return {
732
+ items: state.items.map(
733
+ (i) => isSame(i, action) ? { ...i, quantity: action.quantity } : i
734
+ )
735
+ };
736
+ case "CLEAR":
737
+ return { items: [] };
738
+ }
739
+ }
740
+ var CartContext = createContext(null);
741
+ function CartProvider({ children }) {
742
+ const [state, dispatch] = useReducer(cartReducer, { items: [] });
743
+ useEffect(() => {
744
+ try {
745
+ const stored = localStorage.getItem(STORAGE_KEY);
746
+ if (stored) dispatch({ type: "LOAD", items: JSON.parse(stored) });
747
+ } catch {
748
+ }
749
+ }, []);
750
+ useEffect(() => {
751
+ try {
752
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(state.items));
753
+ } catch {
754
+ }
755
+ }, [state.items]);
756
+ const totalItems = state.items.reduce((sum, i) => sum + i.quantity, 0);
757
+ const subtotal = state.items.reduce((sum, i) => sum + parseFloat(i.price) * i.quantity, 0).toFixed(2);
758
+ function addItem(item, quantity = 1) {
759
+ dispatch({ type: "ADD", item: { ...item, quantity } });
760
+ }
761
+ function removeItem(productId, variationId) {
762
+ dispatch({ type: "REMOVE", productId, variationId });
763
+ }
764
+ function updateQuantity(productId, quantity, variationId) {
765
+ dispatch({ type: "UPDATE", productId, quantity, variationId });
766
+ }
767
+ function clearCart() {
768
+ dispatch({ type: "CLEAR" });
769
+ }
770
+ async function checkout(config, options = {}) {
771
+ if (state.items.length === 0) throw new Error("Cannot checkout with an empty cart");
772
+ const fetcher = createWooCommerceFetcher(config);
773
+ const input = {
774
+ status: "pending",
775
+ line_items: state.items.map((i) => ({
776
+ product_id: i.productId,
777
+ ...i.variationId !== void 0 ? { variation_id: i.variationId } : {},
778
+ quantity: i.quantity
779
+ })),
780
+ ...options.billing ? { billing: options.billing } : {},
781
+ ...options.shipping ? { shipping: options.shipping } : {},
782
+ ...options.paymentMethod ? { payment_method: options.paymentMethod } : {},
783
+ ...options.paymentMethodTitle ? { payment_method_title: options.paymentMethodTitle } : {},
784
+ ...options.customerNote ? { customer_note: options.customerNote } : {},
785
+ ...options.couponCodes ? { coupon_lines: options.couponCodes.map((code) => ({ code })) } : {}
786
+ };
787
+ const order = await createOrdersQueries(fetcher).createOrder(input);
788
+ dispatch({ type: "CLEAR" });
789
+ return order;
790
+ }
791
+ return /* @__PURE__ */ jsx(
792
+ CartContext.Provider,
793
+ {
794
+ value: { items: state.items, totalItems, subtotal, isEmpty: state.items.length === 0, addItem, removeItem, updateQuantity, clearCart, checkout },
795
+ children
796
+ }
797
+ );
798
+ }
799
+ function useCart() {
800
+ const ctx = useContext(CartContext);
801
+ if (!ctx) throw new Error("useCart must be used within a CartProvider");
802
+ return ctx;
803
+ }
804
+
805
+ // src/integrations/restApi/woocommerce/customers/queries.ts
806
+ function createCustomersQueries(fetcher) {
807
+ const { wcFetch, wcFetchGraceful, wcMutate } = fetcher;
808
+ async function getCustomerById(id) {
809
+ return wcFetch(`/wp-json/wc/v3/customers/${id}`, void 0, [
810
+ "woocommerce",
811
+ "customers",
812
+ `customer-${id}`
813
+ ]);
814
+ }
815
+ async function getCustomerByEmail(email) {
816
+ const customers = await wcFetchGraceful(
817
+ "/wp-json/wc/v3/customers",
818
+ [],
819
+ { email },
820
+ ["woocommerce", "customers"]
821
+ );
822
+ return customers[0];
823
+ }
824
+ async function getCustomerByEmailNoCache(email) {
825
+ try {
826
+ const customers = await wcFetch(
827
+ "/wp-json/wc/v3/customers",
828
+ { email },
829
+ ["woocommerce", "customers"],
830
+ { cache: "no-store" }
831
+ );
832
+ return customers[0];
833
+ } catch {
834
+ return void 0;
835
+ }
836
+ }
837
+ async function createCustomer(data) {
838
+ return wcFetch(
839
+ "/wp-json/wc/v3/customers",
840
+ void 0,
841
+ ["woocommerce", "customers"],
842
+ { method: "POST", body: JSON.stringify(data) }
843
+ );
844
+ }
845
+ async function updateCustomer(id, data) {
846
+ return wcMutate(`/wp-json/wc/v3/customers/${id}`, data, "PUT");
847
+ }
848
+ async function deleteCustomer(id, reassign) {
849
+ return wcMutate(
850
+ `/wp-json/wc/v3/customers/${id}`,
851
+ { force: true, ...reassign !== void 0 && { reassign } },
852
+ "DELETE"
853
+ );
854
+ }
855
+ return {
856
+ getCustomerById,
857
+ getCustomerByEmail,
858
+ getCustomerByEmailNoCache,
859
+ createCustomer,
860
+ updateCustomer,
861
+ deleteCustomer
862
+ };
863
+ }
864
+ var CustomerContext = createContext(null);
865
+ function WooCommerceCustomerProvider({
866
+ config,
867
+ children
868
+ }) {
869
+ const { user, isLoggedIn } = useAuth();
870
+ const [customer, setCustomer] = useState(null);
871
+ const [orders, setOrders] = useState([]);
872
+ const [isLoading, setIsLoading] = useState(false);
873
+ const [error, setError] = useState(null);
874
+ const [tick, setTick] = useState(0);
875
+ const fetchData = useCallback(async () => {
876
+ if (!isLoggedIn || !user?.email) {
877
+ setCustomer(null);
878
+ setOrders([]);
879
+ return;
880
+ }
881
+ setIsLoading(true);
882
+ setError(null);
883
+ try {
884
+ const fetcher = createWooCommerceFetcher(config);
885
+ const foundCustomer = await createCustomersQueries(fetcher).getCustomerByEmailNoCache(user.email);
886
+ if (!foundCustomer) {
887
+ setCustomer(null);
888
+ setOrders([]);
889
+ return;
890
+ }
891
+ const customerOrders = await createOrdersQueries(fetcher).getOrdersByCustomer(foundCustomer.id);
892
+ setCustomer(foundCustomer);
893
+ setOrders(customerOrders);
894
+ } catch (err) {
895
+ setError(err instanceof Error ? err.message : "Failed to load customer data");
896
+ } finally {
897
+ setIsLoading(false);
898
+ }
899
+ }, [isLoggedIn, user?.email, config, tick]);
900
+ useEffect(() => {
901
+ void fetchData();
902
+ }, [fetchData]);
903
+ const updateCustomer = async (data) => {
904
+ if (!customer) throw new Error("No customer loaded");
905
+ const fetcher = createWooCommerceFetcher(config);
906
+ const updated = await createCustomersQueries(fetcher).updateCustomer(customer.id, data);
907
+ setCustomer(updated);
908
+ return updated;
909
+ };
910
+ const refetch = () => setTick((t) => t + 1);
911
+ return /* @__PURE__ */ jsx(CustomerContext.Provider, { value: { customer, orders, isLoading, error, updateCustomer, refetch }, children });
912
+ }
913
+ function useCustomer() {
914
+ const ctx = useContext(CustomerContext);
915
+ if (!ctx) throw new Error("useCustomer must be used within a WooCommerceCustomerProvider");
916
+ return ctx;
917
+ }
918
+
565
919
  // src/integrations/wpGraphQL/client/types.ts
566
920
  var WPGraphQLError = class extends Error {
567
921
  constructor(message, status, endpoint, gqlErrors) {
@@ -575,9 +929,9 @@ var WPGraphQLError = class extends Error {
575
929
 
576
930
  // src/integrations/wpGraphQL/client/fetcher.ts
577
931
  var USER_AGENT3 = "NextWordpress WPGraphQL Client";
578
- var CACHE_TTL = 300;
579
932
  function createWPGraphQLFetcher(config) {
580
933
  const url = `${resolveBaseUrl(config)}/graphql`;
934
+ const cacheTTL = config.cacheTTL ?? 300;
581
935
  async function gqlFetch(document, variables, tags = ["wpgraphql"]) {
582
936
  const response = await fetch(url, {
583
937
  method: "POST",
@@ -586,7 +940,7 @@ function createWPGraphQLFetcher(config) {
586
940
  "User-Agent": USER_AGENT3
587
941
  },
588
942
  body: JSON.stringify({ query: document, variables }),
589
- next: { tags, revalidate: CACHE_TTL }
943
+ next: { tags, revalidate: cacheTTL }
590
944
  });
591
945
  if (!response.ok) {
592
946
  throw new WPGraphQLError(
@@ -815,7 +1169,7 @@ function createPostsQueries2(fetcher) {
815
1169
  };
816
1170
  }
817
1171
 
818
- // src/hooks/useWPGraphQL.ts
1172
+ // src/hooks/wpgraphql/useWPGraphQL.ts
819
1173
  function useWPGraphQL(config, query, variables, tags, swrOptions) {
820
1174
  const key = ["wpgraphql", config.clientURL, query, JSON.stringify(variables ?? null)];
821
1175
  return useSWR2(
@@ -850,6 +1204,6 @@ function useGQLPostBySlug(config, slug, swrOptions) {
850
1204
  );
851
1205
  }
852
1206
 
853
- export { useFeaturedProducts, useGQLPostBySlug, useGQLPosts, usePost, usePostBySlug, usePosts, usePostsPaginated, useProduct, useProductBySlug, useProducts, useProductsPaginated, useWPGraphQL };
1207
+ export { AuthProvider, CartProvider, WooCommerceCustomerProvider, cartReducer, useAuth, useCart, useCustomer, useFeaturedProducts, useGQLPostBySlug, useGQLPosts, usePost, usePostBySlug, usePosts, usePostsPaginated, useProduct, useProductBySlug, useProducts, useProductsPaginated, useWPGraphQL };
854
1208
  //# sourceMappingURL=index.js.map
855
1209
  //# sourceMappingURL=index.js.map