@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,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
3
5
  var useSWR2 = require('swr');
4
6
 
5
7
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -10,6 +12,110 @@ var __defProp = Object.defineProperty;
10
12
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
13
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
12
14
 
15
+ // src/shared/url.ts
16
+ function resolveBaseUrl(config) {
17
+ return typeof window === "undefined" ? config.serverURL : config.clientURL;
18
+ }
19
+
20
+ // src/auth/types.ts
21
+ var AuthenticationError = class extends Error {
22
+ constructor(message, status) {
23
+ super(message);
24
+ __publicField(this, "status", status);
25
+ this.name = "AuthenticationError";
26
+ }
27
+ };
28
+
29
+ // src/auth/jwt.ts
30
+ async function authenticateJwt(config, credentials) {
31
+ const url = `${resolveBaseUrl(config)}/wp-json/jwt-auth/v1/token`;
32
+ const response = await fetch(url, {
33
+ method: "POST",
34
+ headers: { "Content-Type": "application/json" },
35
+ body: JSON.stringify(credentials),
36
+ cache: "no-store"
37
+ });
38
+ if (!response.ok) {
39
+ throw new AuthenticationError(
40
+ `JWT authentication failed: ${response.statusText}`,
41
+ response.status
42
+ );
43
+ }
44
+ return response.json();
45
+ }
46
+ async function validateJwtToken(config, token) {
47
+ const url = `${resolveBaseUrl(config)}/wp-json/jwt-auth/v1/token/validate`;
48
+ const response = await fetch(url, {
49
+ method: "POST",
50
+ headers: { Authorization: `Bearer ${token}` },
51
+ cache: "no-store"
52
+ });
53
+ return response.ok;
54
+ }
55
+ var AuthContext = react.createContext(null);
56
+ var TOKEN_KEY = "nw_auth_token";
57
+ var USER_KEY = "nw_auth_user";
58
+ function AuthProvider({
59
+ config,
60
+ children
61
+ }) {
62
+ const [user, setUser] = react.useState(null);
63
+ const [isLoading, setIsLoading] = react.useState(true);
64
+ const [error, setError] = react.useState(null);
65
+ const clearStorage = react.useCallback(() => {
66
+ localStorage.removeItem(TOKEN_KEY);
67
+ localStorage.removeItem(USER_KEY);
68
+ }, []);
69
+ react.useEffect(() => {
70
+ const token = localStorage.getItem(TOKEN_KEY);
71
+ const storedUser = localStorage.getItem(USER_KEY);
72
+ if (!token || !storedUser) {
73
+ setIsLoading(false);
74
+ return;
75
+ }
76
+ validateJwtToken(config, token).then((valid) => {
77
+ if (valid) {
78
+ setUser(JSON.parse(storedUser));
79
+ } else {
80
+ clearStorage();
81
+ }
82
+ }).catch(() => clearStorage()).finally(() => setIsLoading(false));
83
+ }, []);
84
+ const login = async (credentials) => {
85
+ setError(null);
86
+ setIsLoading(true);
87
+ try {
88
+ const response = await authenticateJwt(config, credentials);
89
+ const authUser = {
90
+ token: response.token,
91
+ email: response.user_email,
92
+ nicename: response.user_nicename,
93
+ displayName: response.user_display_name
94
+ };
95
+ localStorage.setItem(TOKEN_KEY, response.token);
96
+ localStorage.setItem(USER_KEY, JSON.stringify(authUser));
97
+ setUser(authUser);
98
+ } catch (err) {
99
+ const message = err instanceof Error ? err.message : "Authentication failed";
100
+ setError(message);
101
+ throw err;
102
+ } finally {
103
+ setIsLoading(false);
104
+ }
105
+ };
106
+ const logout = () => {
107
+ clearStorage();
108
+ setUser(null);
109
+ setError(null);
110
+ };
111
+ return /* @__PURE__ */ jsxRuntime.jsx(AuthContext.Provider, { value: { user, isLoggedIn: !!user, isLoading, error, login, logout }, children });
112
+ }
113
+ function useAuth() {
114
+ const ctx = react.useContext(AuthContext);
115
+ if (!ctx) throw new Error("useAuth must be used within an AuthProvider");
116
+ return ctx;
117
+ }
118
+
13
119
  // src/integrations/restApi/core/client/types.ts
14
120
  var WordPressAPIError = class extends Error {
15
121
  constructor(message, status, endpoint) {
@@ -20,11 +126,6 @@ var WordPressAPIError = class extends Error {
20
126
  }
21
127
  };
22
128
 
23
- // src/shared/url.ts
24
- function resolveBaseUrl(config) {
25
- return typeof window === "undefined" ? config.serverURL : config.clientURL;
26
- }
27
-
28
129
  // src/integrations/restApi/core/client/url.ts
29
130
  function buildUrl(config, path, query) {
30
131
  const base = resolveBaseUrl(config);
@@ -53,7 +154,7 @@ async function doFetch(url, init = {}) {
53
154
  return response;
54
155
  }
55
156
  function createFetcher(config) {
56
- const cacheTtl = 300;
157
+ const cacheTtl = config.cacheTTL ?? 300;
57
158
  async function wpFetch(path, query, tags = ["wordpress"]) {
58
159
  const url = buildUrl(config, path, query);
59
160
  const res = await doFetch(url, {
@@ -256,7 +357,7 @@ function createPostsQueries(fetcher) {
256
357
  };
257
358
  }
258
359
 
259
- // src/hooks/usePosts.ts
360
+ // src/hooks/core/usePosts.ts
260
361
  function usePosts(config, filter, swrOptions) {
261
362
  const key = ["wp-posts", config.clientURL, JSON.stringify(filter ?? null)];
262
363
  return useSWR2__default.default(
@@ -319,7 +420,8 @@ function createWooCommerceFetcher(config) {
319
420
  return { ...query, consumer_key: config.consumerKey, consumer_secret: config.consumerSecret };
320
421
  }
321
422
  function buildUrl2(path, query) {
322
- return `${config.serverURL}${path}?${toQueryString(withAuth(query))}`;
423
+ const base = typeof window !== "undefined" && config.clientURL ? config.clientURL : config.serverURL;
424
+ return `${base}${path}?${toQueryString(withAuth(query))}`;
323
425
  }
324
426
  async function wcFetch(path, query, tags = ["woocommerce"], options) {
325
427
  const url = buildUrl2(path, query);
@@ -511,7 +613,7 @@ function createProductsQueries(fetcher) {
511
613
  };
512
614
  }
513
615
 
514
- // src/hooks/useProducts.ts
616
+ // src/hooks/woocommerce/useProducts.ts
515
617
  function useProducts(config, filter, swrOptions) {
516
618
  const key = ["wc-products", config.serverURL, JSON.stringify(filter ?? null)];
517
619
  return useSWR2__default.default(
@@ -568,6 +670,258 @@ function useFeaturedProducts(config, limit = 10, swrOptions) {
568
670
  );
569
671
  }
570
672
 
673
+ // src/integrations/restApi/woocommerce/orders/queries.ts
674
+ function createOrdersQueries(fetcher) {
675
+ const { wcFetch, wcFetchGraceful, wcMutate } = fetcher;
676
+ async function createOrder(input) {
677
+ return wcMutate("/wp-json/wc/v3/orders", input, "POST");
678
+ }
679
+ async function getOrderById(id) {
680
+ return wcFetch(`/wp-json/wc/v3/orders/${id}`, void 0, [
681
+ "woocommerce",
682
+ "orders",
683
+ `order-${id}`
684
+ ]);
685
+ }
686
+ async function updateOrder(id, data) {
687
+ return wcMutate(`/wp-json/wc/v3/orders/${id}`, data, "PUT");
688
+ }
689
+ async function getOrdersByCustomer(customerId) {
690
+ return wcFetchGraceful(
691
+ "/wp-json/wc/v3/orders",
692
+ [],
693
+ { customer: customerId, per_page: 100 },
694
+ ["woocommerce", "orders", `orders-customer-${customerId}`]
695
+ );
696
+ }
697
+ async function deleteOrder(id, force = true) {
698
+ return wcMutate(
699
+ `/wp-json/wc/v3/orders/${id}`,
700
+ { force },
701
+ "DELETE"
702
+ );
703
+ }
704
+ return {
705
+ createOrder,
706
+ getOrderById,
707
+ updateOrder,
708
+ getOrdersByCustomer,
709
+ deleteOrder
710
+ };
711
+ }
712
+ var STORAGE_KEY = "nw-cart";
713
+ function isSame(a, b) {
714
+ return a.productId === b.productId && (a.variationId ?? 0) === (b.variationId ?? 0);
715
+ }
716
+ function cartReducer(state, action) {
717
+ switch (action.type) {
718
+ case "LOAD":
719
+ return { items: action.items };
720
+ case "ADD": {
721
+ const existing = state.items.find((i) => isSame(i, action.item));
722
+ if (existing) {
723
+ return {
724
+ items: state.items.map(
725
+ (i) => isSame(i, action.item) ? { ...i, quantity: i.quantity + action.item.quantity } : i
726
+ )
727
+ };
728
+ }
729
+ return { items: [...state.items, action.item] };
730
+ }
731
+ case "REMOVE":
732
+ return { items: state.items.filter((i) => !isSame(i, action)) };
733
+ case "UPDATE":
734
+ if (action.quantity <= 0) {
735
+ return { items: state.items.filter((i) => !isSame(i, action)) };
736
+ }
737
+ return {
738
+ items: state.items.map(
739
+ (i) => isSame(i, action) ? { ...i, quantity: action.quantity } : i
740
+ )
741
+ };
742
+ case "CLEAR":
743
+ return { items: [] };
744
+ }
745
+ }
746
+ var CartContext = react.createContext(null);
747
+ function CartProvider({ children }) {
748
+ const [state, dispatch] = react.useReducer(cartReducer, { items: [] });
749
+ react.useEffect(() => {
750
+ try {
751
+ const stored = localStorage.getItem(STORAGE_KEY);
752
+ if (stored) dispatch({ type: "LOAD", items: JSON.parse(stored) });
753
+ } catch {
754
+ }
755
+ }, []);
756
+ react.useEffect(() => {
757
+ try {
758
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(state.items));
759
+ } catch {
760
+ }
761
+ }, [state.items]);
762
+ const totalItems = state.items.reduce((sum, i) => sum + i.quantity, 0);
763
+ const subtotal = state.items.reduce((sum, i) => sum + parseFloat(i.price) * i.quantity, 0).toFixed(2);
764
+ function addItem(item, quantity = 1) {
765
+ dispatch({ type: "ADD", item: { ...item, quantity } });
766
+ }
767
+ function removeItem(productId, variationId) {
768
+ dispatch({ type: "REMOVE", productId, variationId });
769
+ }
770
+ function updateQuantity(productId, quantity, variationId) {
771
+ dispatch({ type: "UPDATE", productId, quantity, variationId });
772
+ }
773
+ function clearCart() {
774
+ dispatch({ type: "CLEAR" });
775
+ }
776
+ async function checkout(config, options = {}) {
777
+ if (state.items.length === 0) throw new Error("Cannot checkout with an empty cart");
778
+ const fetcher = createWooCommerceFetcher(config);
779
+ const input = {
780
+ status: "pending",
781
+ line_items: state.items.map((i) => ({
782
+ product_id: i.productId,
783
+ ...i.variationId !== void 0 ? { variation_id: i.variationId } : {},
784
+ quantity: i.quantity
785
+ })),
786
+ ...options.billing ? { billing: options.billing } : {},
787
+ ...options.shipping ? { shipping: options.shipping } : {},
788
+ ...options.paymentMethod ? { payment_method: options.paymentMethod } : {},
789
+ ...options.paymentMethodTitle ? { payment_method_title: options.paymentMethodTitle } : {},
790
+ ...options.customerNote ? { customer_note: options.customerNote } : {},
791
+ ...options.couponCodes ? { coupon_lines: options.couponCodes.map((code) => ({ code })) } : {}
792
+ };
793
+ const order = await createOrdersQueries(fetcher).createOrder(input);
794
+ dispatch({ type: "CLEAR" });
795
+ return order;
796
+ }
797
+ return /* @__PURE__ */ jsxRuntime.jsx(
798
+ CartContext.Provider,
799
+ {
800
+ value: { items: state.items, totalItems, subtotal, isEmpty: state.items.length === 0, addItem, removeItem, updateQuantity, clearCart, checkout },
801
+ children
802
+ }
803
+ );
804
+ }
805
+ function useCart() {
806
+ const ctx = react.useContext(CartContext);
807
+ if (!ctx) throw new Error("useCart must be used within a CartProvider");
808
+ return ctx;
809
+ }
810
+
811
+ // src/integrations/restApi/woocommerce/customers/queries.ts
812
+ function createCustomersQueries(fetcher) {
813
+ const { wcFetch, wcFetchGraceful, wcMutate } = fetcher;
814
+ async function getCustomerById(id) {
815
+ return wcFetch(`/wp-json/wc/v3/customers/${id}`, void 0, [
816
+ "woocommerce",
817
+ "customers",
818
+ `customer-${id}`
819
+ ]);
820
+ }
821
+ async function getCustomerByEmail(email) {
822
+ const customers = await wcFetchGraceful(
823
+ "/wp-json/wc/v3/customers",
824
+ [],
825
+ { email },
826
+ ["woocommerce", "customers"]
827
+ );
828
+ return customers[0];
829
+ }
830
+ async function getCustomerByEmailNoCache(email) {
831
+ try {
832
+ const customers = await wcFetch(
833
+ "/wp-json/wc/v3/customers",
834
+ { email },
835
+ ["woocommerce", "customers"],
836
+ { cache: "no-store" }
837
+ );
838
+ return customers[0];
839
+ } catch {
840
+ return void 0;
841
+ }
842
+ }
843
+ async function createCustomer(data) {
844
+ return wcFetch(
845
+ "/wp-json/wc/v3/customers",
846
+ void 0,
847
+ ["woocommerce", "customers"],
848
+ { method: "POST", body: JSON.stringify(data) }
849
+ );
850
+ }
851
+ async function updateCustomer(id, data) {
852
+ return wcMutate(`/wp-json/wc/v3/customers/${id}`, data, "PUT");
853
+ }
854
+ async function deleteCustomer(id, reassign) {
855
+ return wcMutate(
856
+ `/wp-json/wc/v3/customers/${id}`,
857
+ { force: true, ...reassign !== void 0 && { reassign } },
858
+ "DELETE"
859
+ );
860
+ }
861
+ return {
862
+ getCustomerById,
863
+ getCustomerByEmail,
864
+ getCustomerByEmailNoCache,
865
+ createCustomer,
866
+ updateCustomer,
867
+ deleteCustomer
868
+ };
869
+ }
870
+ var CustomerContext = react.createContext(null);
871
+ function WooCommerceCustomerProvider({
872
+ config,
873
+ children
874
+ }) {
875
+ const { user, isLoggedIn } = useAuth();
876
+ const [customer, setCustomer] = react.useState(null);
877
+ const [orders, setOrders] = react.useState([]);
878
+ const [isLoading, setIsLoading] = react.useState(false);
879
+ const [error, setError] = react.useState(null);
880
+ const [tick, setTick] = react.useState(0);
881
+ const fetchData = react.useCallback(async () => {
882
+ if (!isLoggedIn || !user?.email) {
883
+ setCustomer(null);
884
+ setOrders([]);
885
+ return;
886
+ }
887
+ setIsLoading(true);
888
+ setError(null);
889
+ try {
890
+ const fetcher = createWooCommerceFetcher(config);
891
+ const foundCustomer = await createCustomersQueries(fetcher).getCustomerByEmailNoCache(user.email);
892
+ if (!foundCustomer) {
893
+ setCustomer(null);
894
+ setOrders([]);
895
+ return;
896
+ }
897
+ const customerOrders = await createOrdersQueries(fetcher).getOrdersByCustomer(foundCustomer.id);
898
+ setCustomer(foundCustomer);
899
+ setOrders(customerOrders);
900
+ } catch (err) {
901
+ setError(err instanceof Error ? err.message : "Failed to load customer data");
902
+ } finally {
903
+ setIsLoading(false);
904
+ }
905
+ }, [isLoggedIn, user?.email, config, tick]);
906
+ react.useEffect(() => {
907
+ void fetchData();
908
+ }, [fetchData]);
909
+ const updateCustomer = async (data) => {
910
+ if (!customer) throw new Error("No customer loaded");
911
+ const fetcher = createWooCommerceFetcher(config);
912
+ const updated = await createCustomersQueries(fetcher).updateCustomer(customer.id, data);
913
+ setCustomer(updated);
914
+ return updated;
915
+ };
916
+ const refetch = () => setTick((t) => t + 1);
917
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomerContext.Provider, { value: { customer, orders, isLoading, error, updateCustomer, refetch }, children });
918
+ }
919
+ function useCustomer() {
920
+ const ctx = react.useContext(CustomerContext);
921
+ if (!ctx) throw new Error("useCustomer must be used within a WooCommerceCustomerProvider");
922
+ return ctx;
923
+ }
924
+
571
925
  // src/integrations/wpGraphQL/client/types.ts
572
926
  var WPGraphQLError = class extends Error {
573
927
  constructor(message, status, endpoint, gqlErrors) {
@@ -581,9 +935,9 @@ var WPGraphQLError = class extends Error {
581
935
 
582
936
  // src/integrations/wpGraphQL/client/fetcher.ts
583
937
  var USER_AGENT3 = "NextWordpress WPGraphQL Client";
584
- var CACHE_TTL = 300;
585
938
  function createWPGraphQLFetcher(config) {
586
939
  const url = `${resolveBaseUrl(config)}/graphql`;
940
+ const cacheTTL = config.cacheTTL ?? 300;
587
941
  async function gqlFetch(document, variables, tags = ["wpgraphql"]) {
588
942
  const response = await fetch(url, {
589
943
  method: "POST",
@@ -592,7 +946,7 @@ function createWPGraphQLFetcher(config) {
592
946
  "User-Agent": USER_AGENT3
593
947
  },
594
948
  body: JSON.stringify({ query: document, variables }),
595
- next: { tags, revalidate: CACHE_TTL }
949
+ next: { tags, revalidate: cacheTTL }
596
950
  });
597
951
  if (!response.ok) {
598
952
  throw new WPGraphQLError(
@@ -821,7 +1175,7 @@ function createPostsQueries2(fetcher) {
821
1175
  };
822
1176
  }
823
1177
 
824
- // src/hooks/useWPGraphQL.ts
1178
+ // src/hooks/wpgraphql/useWPGraphQL.ts
825
1179
  function useWPGraphQL(config, query, variables, tags, swrOptions) {
826
1180
  const key = ["wpgraphql", config.clientURL, query, JSON.stringify(variables ?? null)];
827
1181
  return useSWR2__default.default(
@@ -856,6 +1210,13 @@ function useGQLPostBySlug(config, slug, swrOptions) {
856
1210
  );
857
1211
  }
858
1212
 
1213
+ exports.AuthProvider = AuthProvider;
1214
+ exports.CartProvider = CartProvider;
1215
+ exports.WooCommerceCustomerProvider = WooCommerceCustomerProvider;
1216
+ exports.cartReducer = cartReducer;
1217
+ exports.useAuth = useAuth;
1218
+ exports.useCart = useCart;
1219
+ exports.useCustomer = useCustomer;
859
1220
  exports.useFeaturedProducts = useFeaturedProducts;
860
1221
  exports.useGQLPostBySlug = useGQLPostBySlug;
861
1222
  exports.useGQLPosts = useGQLPosts;