This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 219
/
index.js
231 lines (213 loc) · 6.27 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/**
* External dependencies
*/
import { addQueryArgs } from '@wordpress/url';
import apiFetch from '@wordpress/api-fetch';
import { getSetting } from '@woocommerce/settings';
import { blocksConfig } from '@woocommerce/block-settings';
/**
* Get product query requests for the Store API.
*
* @param {Object} request A query object with the list of selected products and search term.
* @param {number[]} request.selected Currently selected products.
* @param {string=} request.search Search string.
* @param {(Record<string, unknown>)=} request.queryArgs Query args to pass in.
*/
const getProductsRequests = ( {
selected = [],
search = '',
queryArgs = {},
} ) => {
const isLargeCatalog = blocksConfig.productCount > 100;
const defaultArgs = {
per_page: isLargeCatalog ? 100 : 0,
catalog_visibility: 'any',
search,
orderby: 'title',
order: 'asc',
};
const requests = [
addQueryArgs( '/wc/store/v1/products', {
...defaultArgs,
...queryArgs,
} ),
];
// If we have a large catalog, we might not get all selected products in the first page.
if ( isLargeCatalog && selected.length ) {
requests.push(
addQueryArgs( '/wc/store/v1/products', {
catalog_visibility: 'any',
include: selected,
per_page: 0,
} )
);
}
return requests;
};
const uniqBy = ( array, iteratee ) => {
const seen = new Map();
return array.filter( ( item ) => {
const key = iteratee( item );
if ( ! seen.has( key ) ) {
seen.set( key, item );
return true;
}
return false;
} );
};
/**
* Get a promise that resolves to a list of products from the Store API.
*
* @param {Object} request A query object with the list of selected products and search term.
* @param {number[]} request.selected Currently selected products.
* @param {string=} request.search Search string.
* @param {(Record<string, unknown>)=} request.queryArgs Query args to pass in.
* @return {Promise<unknown>} Promise resolving to a Product list.
* @throws Exception if there is an error.
*/
export const getProducts = ( {
selected = [],
search = '',
queryArgs = {},
} ) => {
const requests = getProductsRequests( { selected, search, queryArgs } );
return Promise.all( requests.map( ( path ) => apiFetch( { path } ) ) )
.then( ( data ) => {
const flatData = data.flat();
const products = uniqBy( flatData, ( item ) => item.id );
const list = products.map( ( product ) => ( {
...product,
parent: 0,
} ) );
return list;
} )
.catch( ( e ) => {
throw e;
} );
};
/**
* Get a promise that resolves to a product object from the Store API.
*
* @param {number} productId Id of the product to retrieve.
*/
export const getProduct = ( productId ) => {
return apiFetch( {
path: `/wc/store/v1/products/${ productId }`,
} );
};
/**
* Get a promise that resolves to a list of attribute objects from the Store API.
*/
export const getAttributes = () => {
return apiFetch( {
path: `wc/store/v1/products/attributes`,
} );
};
/**
* Get a promise that resolves to a list of attribute term objects from the Store API.
*
* @param {number} attribute Id of the attribute to retrieve terms for.
*/
export const getTerms = ( attribute ) => {
return apiFetch( {
path: `wc/store/v1/products/attributes/${ attribute }/terms`,
} );
};
/**
* Get product tag query requests for the Store API.
*
* @param {Object} request A query object with the list of selected products and search term.
* @param {Array} request.selected Currently selected tags.
* @param {string} request.search Search string.
*/
const getProductTagsRequests = ( { selected = [], search } ) => {
const limitTags = getSetting( 'limitTags', false );
const requests = [
addQueryArgs( `wc/store/v1/products/tags`, {
per_page: limitTags ? 100 : 0,
orderby: limitTags ? 'count' : 'name',
order: limitTags ? 'desc' : 'asc',
search,
} ),
];
// If we have a large catalog, we might not get all selected products in the first page.
if ( limitTags && selected.length ) {
requests.push(
addQueryArgs( `wc/store/v1/products/tags`, {
include: selected,
} )
);
}
return requests;
};
/**
* Get a promise that resolves to a list of tags from the Store API.
*
* @param {Object} props A query object with the list of selected products and search term.
* @param {Array} props.selected
* @param {string} props.search
*/
export const getProductTags = ( { selected = [], search } ) => {
const requests = getProductTagsRequests( { selected, search } );
return Promise.all( requests.map( ( path ) => apiFetch( { path } ) ) ).then(
( data ) => {
const flatData = data.flat();
return uniqBy( flatData, ( item ) => item.id );
}
);
};
/**
* Get a promise that resolves to a list of category objects from the Store API.
*
* @param {Object} queryArgs Query args to pass in.
*/
export const getCategories = ( queryArgs ) => {
return apiFetch( {
path: addQueryArgs( `wc/store/v1/products/categories`, {
per_page: 0,
...queryArgs,
} ),
} );
};
/**
* Get a promise that resolves to a category object from the API.
*
* @param {number} categoryId Id of the product to retrieve.
*/
export const getCategory = ( categoryId ) => {
return apiFetch( {
path: `wc/store/v1/products/categories/${ categoryId }`,
} );
};
/**
* Get a promise that resolves to a list of variation objects from the Store API.
*
* @param {number} product Product ID.
*/
export const getProductVariations = ( product ) => {
return apiFetch( {
path: addQueryArgs( `wc/store/v1/products`, {
per_page: 0,
type: 'variation',
parent: product,
} ),
} );
};
/**
* Given a page object and an array of page, format the title.
*
* @param {Object} page Page object.
* @param {Object} page.title Page title object.
* @param {string} page.title.raw Page title.
* @param {string} page.slug Page slug.
* @param {Array} pages Array of all pages.
* @return {string} Formatted page title to display.
*/
export const formatTitle = ( page, pages ) => {
if ( ! page.title.raw ) {
return page.slug;
}
const isUnique =
pages.filter( ( p ) => p.title.raw === page.title.raw ).length === 1;
return page.title.raw + ( ! isUnique ? ` - ${ page.slug }` : '' );
};