@dylandepass/helix-product-pipeline 2.2.0 → 2.3.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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/product-index-pipe.js +25 -5
- package/src/steps/utils.js +33 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [2.3.0](https://github.com/adobe-rnd/helix-product-pipeline/compare/v2.2.0...v2.3.0) (2026-02-12)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add limit/offset pagination and deterministic sort to product index ([#71](https://github.com/adobe-rnd/helix-product-pipeline/issues/71)) ([28499dd](https://github.com/adobe-rnd/helix-product-pipeline/commit/28499dd2140c830ed46ecec03bad4cee1fdd1ba5))
|
|
7
|
+
|
|
1
8
|
# [2.2.0](https://github.com/adobe-rnd/helix-product-pipeline/compare/v2.1.0...v2.2.0) (2026-02-04)
|
|
2
9
|
|
|
3
10
|
|
package/package.json
CHANGED
|
@@ -17,22 +17,33 @@ import initConfig from './steps/init-config.js';
|
|
|
17
17
|
import fetchProductBusContent from './steps/fetch-productbus.js';
|
|
18
18
|
import { setLastModified } from './utils/last-modified.js';
|
|
19
19
|
import { set404CacheHeaders } from './steps/set-cache-headers.js';
|
|
20
|
-
import { getIncludes } from './steps/utils.js';
|
|
20
|
+
import { getIncludes, getPaginationParams } from './steps/utils.js';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Returns index as spreadsheet
|
|
23
|
+
* Returns index as spreadsheet with pagination support.
|
|
24
24
|
* @param {SharedTypes.StoredIndex} index
|
|
25
25
|
* @param {Record<string, boolean>} includes
|
|
26
|
+
* @param {{ hasParams?: boolean, limit?: number, offset?: number }} [pagination={}]
|
|
27
|
+
* - Pagination options
|
|
26
28
|
* @returns {{
|
|
27
29
|
* ':type': 'sheet',
|
|
30
|
+
* total: number,
|
|
31
|
+
* offset: number,
|
|
32
|
+
* limit: number,
|
|
28
33
|
* columns: string[],
|
|
29
34
|
* data: Record<string, string>[]
|
|
30
35
|
* }}
|
|
31
36
|
*/
|
|
32
|
-
export function toSpreadsheet(index, includes) {
|
|
37
|
+
export function toSpreadsheet(index, includes, pagination = {}) {
|
|
38
|
+
const {
|
|
39
|
+
limit = pagination.hasParams ? 1000 : Infinity,
|
|
40
|
+
offset = 0,
|
|
41
|
+
} = pagination;
|
|
42
|
+
|
|
33
43
|
const columns = new Set(['sku']);
|
|
34
44
|
|
|
35
45
|
const products = Object.entries(index)
|
|
46
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
36
47
|
.filter(([_, entry]) => includes.all || !entry.filters?.noindex || includes.noindex)
|
|
37
48
|
.reduce((acc, [sluggedSku, entry]) => {
|
|
38
49
|
const product = entry.data;
|
|
@@ -80,10 +91,17 @@ export function toSpreadsheet(index, includes) {
|
|
|
80
91
|
return acc;
|
|
81
92
|
}, []);
|
|
82
93
|
|
|
94
|
+
const total = products.length;
|
|
95
|
+
const len = Math.min(limit, total - offset);
|
|
96
|
+
const paginatedData = products.slice(offset, offset + len);
|
|
97
|
+
|
|
83
98
|
return {
|
|
84
99
|
':type': 'sheet',
|
|
100
|
+
total,
|
|
101
|
+
offset,
|
|
102
|
+
limit: paginatedData.length,
|
|
85
103
|
columns: Array.from(columns),
|
|
86
|
-
data:
|
|
104
|
+
data: paginatedData,
|
|
87
105
|
};
|
|
88
106
|
}
|
|
89
107
|
|
|
@@ -135,7 +153,9 @@ export async function productIndexPipe(state, req) {
|
|
|
135
153
|
|
|
136
154
|
setLastModified(state, res);
|
|
137
155
|
|
|
138
|
-
|
|
156
|
+
const pagination = getPaginationParams(req);
|
|
157
|
+
const spreadsheet = toSpreadsheet(state.content.data, getIncludes(req), pagination);
|
|
158
|
+
res.body = JSON.stringify(spreadsheet, null, 2);
|
|
139
159
|
} catch (e) {
|
|
140
160
|
const errorRes = new PipelineResponse('', {
|
|
141
161
|
/* c8 ignore next 6 */
|
package/src/steps/utils.js
CHANGED
|
@@ -125,3 +125,36 @@ export function getIncludes(req) {
|
|
|
125
125
|
}
|
|
126
126
|
return includes;
|
|
127
127
|
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get pagination params from request URL.
|
|
131
|
+
* @param {PipelineRequest} req
|
|
132
|
+
* @returns {{ hasParams?: boolean, limit?: number, offset?: number }}
|
|
133
|
+
*/
|
|
134
|
+
export function getPaginationParams(req) {
|
|
135
|
+
const { searchParams } = req.url;
|
|
136
|
+
const hasParams = searchParams.has('limit') || searchParams.has('offset');
|
|
137
|
+
if (!hasParams) {
|
|
138
|
+
return {};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const result = { hasParams: true };
|
|
142
|
+
|
|
143
|
+
const limitStr = searchParams.get('limit');
|
|
144
|
+
if (limitStr !== null) {
|
|
145
|
+
const limit = parseInt(limitStr, 10);
|
|
146
|
+
if (!Number.isNaN(limit) && limit >= 0) {
|
|
147
|
+
result.limit = limit;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const offsetStr = searchParams.get('offset');
|
|
152
|
+
if (offsetStr !== null) {
|
|
153
|
+
const offset = parseInt(offsetStr, 10);
|
|
154
|
+
if (!Number.isNaN(offset) && offset >= 0) {
|
|
155
|
+
result.offset = offset;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return result;
|
|
160
|
+
}
|