@fast-simon/shopify-hydrogen 1.0.6 → 1.0.7-beta.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/dist/esnext/@types/editor.d.ts +0 -2
- package/dist/esnext/services/categories_navigation.d.ts +2 -23
- package/dist/esnext/services/categories_navigation.js +5 -7
- package/package.json +4 -8
- package/dist/esnext/services/__tests__/categories_navigation.test.d.ts +0 -1
- package/dist/esnext/services/__tests__/categories_navigation.test.js +0 -90
|
@@ -25,22 +25,6 @@ export interface CategoryNavigationServerResponseAll {
|
|
|
25
25
|
personalization_recency_limit?: number;
|
|
26
26
|
personalized_products?: number[];
|
|
27
27
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Optional personalization context for category navigation requests. When provided, the
|
|
30
|
-
* present keys are forwarded to the API. When omitted, the request URL is byte-identical
|
|
31
|
-
* to prior versions of this SDK.
|
|
32
|
-
*
|
|
33
|
-
* - `st` — session token
|
|
34
|
-
* - `sp` — recent-products (comma-joined IDs)
|
|
35
|
-
* - `spv` — personalization vector
|
|
36
|
-
* - `ps` — personalization segment (`"new"` | `"returning"`)
|
|
37
|
-
*/
|
|
38
|
-
export interface PersonalizationContext {
|
|
39
|
-
st?: string;
|
|
40
|
-
sp?: string;
|
|
41
|
-
spv?: string;
|
|
42
|
-
ps?: 'new' | 'returning';
|
|
43
|
-
}
|
|
44
28
|
interface CategoryNavigationProps {
|
|
45
29
|
categoryID: string;
|
|
46
30
|
page?: number;
|
|
@@ -52,18 +36,13 @@ interface CategoryNavigationProps {
|
|
|
52
36
|
searchWithinResultsQuery?: string;
|
|
53
37
|
storeID: number;
|
|
54
38
|
UUID: string;
|
|
55
|
-
/**
|
|
56
|
-
* Optional personalization context for this request. When omitted, the emitted URL is
|
|
57
|
-
* unchanged from earlier SDK versions.
|
|
58
|
-
*/
|
|
59
|
-
personalization?: PersonalizationContext;
|
|
60
39
|
}
|
|
61
40
|
interface CategoryNavigationResponse {
|
|
62
41
|
data: CategoryNavigationServerResponseAll;
|
|
63
42
|
getFacetsOnly?: () => ServerFacet[];
|
|
64
43
|
}
|
|
65
44
|
export declare const CategoriesNavigation: {
|
|
66
|
-
get: ({ categoryID, page, sortBy, facets, narrow, productsPerPage, withProductAttributes, searchWithinResultsQuery, storeID, UUID,
|
|
67
|
-
getFacetsOnly: ({ categoryID, page, sortBy, narrow, productsPerPage, searchWithinResultsQuery, storeID, UUID
|
|
45
|
+
get: ({ categoryID, page, sortBy, facets, narrow, productsPerPage, withProductAttributes, searchWithinResultsQuery, storeID, UUID, }: CategoryNavigationProps) => CategoryNavigationResponse;
|
|
46
|
+
getFacetsOnly: ({ categoryID, page, sortBy, narrow, productsPerPage, searchWithinResultsQuery, storeID, UUID }: CategoryNavigationProps) => ServerFacet[];
|
|
68
47
|
};
|
|
69
48
|
export {};
|
|
@@ -2,7 +2,7 @@ import { CacheShort, fetchSync } from "@shopify/hydrogen";
|
|
|
2
2
|
import { Narrow as NarrowUtil } from "@fast-simon/utilities";
|
|
3
3
|
const ENDPOINT = "https://api.fastsimon.com";
|
|
4
4
|
export const CategoriesNavigation = {
|
|
5
|
-
get: ({ categoryID, page = 1, sortBy = "relevency", facets = true, narrow, productsPerPage, withProductAttributes = true, searchWithinResultsQuery, storeID, UUID,
|
|
5
|
+
get: ({ categoryID, page = 1, sortBy = "relevency", facets = true, narrow, productsPerPage, withProductAttributes = true, searchWithinResultsQuery, storeID, UUID, }) => {
|
|
6
6
|
const narrowParm = narrow ? NarrowUtil.toServerNarrow(narrow) : undefined;
|
|
7
7
|
const params = {
|
|
8
8
|
category_id: categoryID,
|
|
@@ -14,8 +14,7 @@ export const CategoriesNavigation = {
|
|
|
14
14
|
with_product_attributes: withProductAttributes ? withProductAttributes : undefined,
|
|
15
15
|
search_within_search: searchWithinResultsQuery ? searchWithinResultsQuery : undefined,
|
|
16
16
|
UUID: UUID,
|
|
17
|
-
store_id: storeID
|
|
18
|
-
...(personalization ?? {})
|
|
17
|
+
store_id: storeID
|
|
19
18
|
};
|
|
20
19
|
const url = `${ENDPOINT}/categories_navigation?${Object.keys(params).filter(key => params[key] !== undefined).map(key => key + '=' + params[key]).join('&')}`;
|
|
21
20
|
const data = fetchSync(url, {
|
|
@@ -25,11 +24,11 @@ export const CategoriesNavigation = {
|
|
|
25
24
|
return {
|
|
26
25
|
data: data,
|
|
27
26
|
getFacetsOnly: (facets && !data.facets_completed) ? () => {
|
|
28
|
-
return CategoriesNavigation.getFacetsOnly({ categoryID, page, sortBy, narrow, productsPerPage, searchWithinResultsQuery, UUID, storeID
|
|
27
|
+
return CategoriesNavigation.getFacetsOnly({ categoryID, page, sortBy, narrow, productsPerPage, searchWithinResultsQuery, UUID, storeID });
|
|
29
28
|
} : undefined
|
|
30
29
|
};
|
|
31
30
|
},
|
|
32
|
-
getFacetsOnly: ({ categoryID, page = 1, sortBy = "relevency", narrow, productsPerPage, searchWithinResultsQuery, storeID, UUID
|
|
31
|
+
getFacetsOnly: ({ categoryID, page = 1, sortBy = "relevency", narrow, productsPerPage, searchWithinResultsQuery, storeID, UUID }) => {
|
|
33
32
|
const narrowParm = narrow ? NarrowUtil.toServerNarrow(narrow) : undefined;
|
|
34
33
|
const params = {
|
|
35
34
|
category_id: categoryID,
|
|
@@ -40,8 +39,7 @@ export const CategoriesNavigation = {
|
|
|
40
39
|
narrow: JSON.stringify(narrowParm),
|
|
41
40
|
search_within_search: searchWithinResultsQuery ? searchWithinResultsQuery : undefined,
|
|
42
41
|
UUID: UUID,
|
|
43
|
-
store_id: storeID
|
|
44
|
-
...(personalization ?? {})
|
|
42
|
+
store_id: storeID
|
|
45
43
|
};
|
|
46
44
|
const url = `${ENDPOINT}/categories_navigation?${Object.keys(params).filter(key => params[key] !== undefined).map(key => key + '=' + params[key]).join('&')}`;
|
|
47
45
|
const data = fetchSync(url, {
|
package/package.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fast-simon/shopify-hydrogen",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7-beta.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npm run build:plugin:cjs && npm run build:esm",
|
|
7
7
|
"build:plugin:cjs": "tsc --p tsconfig.plugin.cjs.json",
|
|
8
|
-
"build:esm": "tsc --p tsconfig.esm.json"
|
|
9
|
-
"test": "vitest run",
|
|
10
|
-
"test:watch": "vitest"
|
|
8
|
+
"build:esm": "tsc --p tsconfig.esm.json"
|
|
11
9
|
},
|
|
12
10
|
"author": "",
|
|
13
11
|
"license": "ISC",
|
|
@@ -17,7 +15,7 @@
|
|
|
17
15
|
"devDependencies": {
|
|
18
16
|
"@shopify/hydrogen": "^1.2.0",
|
|
19
17
|
"@types/react": "^18.0.16",
|
|
20
|
-
"@types/node": "
|
|
18
|
+
"@types/node": "17.0.35",
|
|
21
19
|
"@types/react-dom": "^18.0.5",
|
|
22
20
|
"rollup": "^2.77.2",
|
|
23
21
|
"rollup-plugin-dts": "^4.2.2",
|
|
@@ -25,9 +23,7 @@
|
|
|
25
23
|
"vite": "^2.9.14",
|
|
26
24
|
"type-fest": "^2.13.0",
|
|
27
25
|
"@vitejs/plugin-react": "^1.3.0",
|
|
28
|
-
"copyfiles": "2.4.1"
|
|
29
|
-
"vitest": "^3.0.0",
|
|
30
|
-
"jsdom": "^26.0.0"
|
|
26
|
+
"copyfiles": "2.4.1"
|
|
31
27
|
},
|
|
32
28
|
"main": "dist/esnext/index.js",
|
|
33
29
|
"files": [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
-
vi.mock('@shopify/hydrogen', () => ({
|
|
3
|
-
CacheShort: () => ({ cacheStrategy: 'short' }),
|
|
4
|
-
fetchSync: (url) => {
|
|
5
|
-
lastRequestedUrl = url;
|
|
6
|
-
return { json: () => ({ facets: [], facets_completed: true, items: [] }) };
|
|
7
|
-
},
|
|
8
|
-
}));
|
|
9
|
-
let lastRequestedUrl = '';
|
|
10
|
-
import { CategoriesNavigation } from '../categories_navigation';
|
|
11
|
-
const baseProps = {
|
|
12
|
-
categoryID: '42',
|
|
13
|
-
storeID: 1,
|
|
14
|
-
UUID: 'abc',
|
|
15
|
-
};
|
|
16
|
-
describe('legacy hydrogen categories_navigation — personalization', () => {
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
lastRequestedUrl = '';
|
|
19
|
-
});
|
|
20
|
-
it('omits personalization keys when the prop is absent (backwards-compat)', () => {
|
|
21
|
-
CategoriesNavigation.get({ ...baseProps });
|
|
22
|
-
expect(lastRequestedUrl).not.toMatch(/[?&]ps=/);
|
|
23
|
-
expect(lastRequestedUrl).not.toMatch(/[?&]st=/);
|
|
24
|
-
expect(lastRequestedUrl).not.toMatch(/[?&]sp=/);
|
|
25
|
-
expect(lastRequestedUrl).not.toMatch(/[?&]spv=/);
|
|
26
|
-
});
|
|
27
|
-
it('emits full personalization context', () => {
|
|
28
|
-
CategoriesNavigation.get({
|
|
29
|
-
...baseProps,
|
|
30
|
-
personalization: { st: 'tok', sp: '1,2', spv: 'vec', ps: 'new' },
|
|
31
|
-
});
|
|
32
|
-
expect(lastRequestedUrl).toMatch(/[?&]ps=new(&|$)/);
|
|
33
|
-
expect(lastRequestedUrl).toMatch(/[?&]st=tok(&|$)/);
|
|
34
|
-
expect(lastRequestedUrl).toMatch(/[?&]sp=1,2(&|$)/);
|
|
35
|
-
expect(lastRequestedUrl).toMatch(/[?&]spv=vec(&|$)/);
|
|
36
|
-
});
|
|
37
|
-
it('emits only provided partial context keys', () => {
|
|
38
|
-
CategoriesNavigation.get({
|
|
39
|
-
...baseProps,
|
|
40
|
-
personalization: { ps: 'returning' },
|
|
41
|
-
});
|
|
42
|
-
expect(lastRequestedUrl).toMatch(/[?&]ps=returning(&|$)/);
|
|
43
|
-
expect(lastRequestedUrl).not.toMatch(/[?&]st=/);
|
|
44
|
-
expect(lastRequestedUrl).not.toMatch(/[?&]sp=/);
|
|
45
|
-
expect(lastRequestedUrl).not.toMatch(/[?&]spv=/);
|
|
46
|
-
});
|
|
47
|
-
it('empty personalization object emits no personalization keys', () => {
|
|
48
|
-
CategoriesNavigation.get({
|
|
49
|
-
...baseProps,
|
|
50
|
-
personalization: {},
|
|
51
|
-
});
|
|
52
|
-
expect(lastRequestedUrl).not.toMatch(/[?&]ps=/);
|
|
53
|
-
});
|
|
54
|
-
it('getFacetsOnly emits personalization keys too', () => {
|
|
55
|
-
CategoriesNavigation.getFacetsOnly({
|
|
56
|
-
...baseProps,
|
|
57
|
-
personalization: { ps: 'returning' },
|
|
58
|
-
});
|
|
59
|
-
expect(lastRequestedUrl).toMatch(/[?&]ps=returning(&|$)/);
|
|
60
|
-
expect(lastRequestedUrl).toMatch(/\/categories_navigation\?/);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
describe('legacy hydrogen categories_navigation — regression (byte-identical without opt-in)', () => {
|
|
64
|
-
beforeEach(() => {
|
|
65
|
-
lastRequestedUrl = '';
|
|
66
|
-
});
|
|
67
|
-
it('URL is unchanged when personalization is omitted vs undefined', () => {
|
|
68
|
-
CategoriesNavigation.get({ ...baseProps });
|
|
69
|
-
const urlA = lastRequestedUrl;
|
|
70
|
-
lastRequestedUrl = '';
|
|
71
|
-
CategoriesNavigation.get({ ...baseProps, personalization: undefined });
|
|
72
|
-
expect(lastRequestedUrl).toBe(urlA);
|
|
73
|
-
});
|
|
74
|
-
it('preserves the historical narrow=undefined quirk when narrow is not provided', () => {
|
|
75
|
-
CategoriesNavigation.get({ ...baseProps });
|
|
76
|
-
expect(lastRequestedUrl).toMatch(/[?&]narrow=undefined/);
|
|
77
|
-
});
|
|
78
|
-
it('appends personalization keys after core params', () => {
|
|
79
|
-
CategoriesNavigation.get({
|
|
80
|
-
...baseProps,
|
|
81
|
-
personalization: { ps: 'new' },
|
|
82
|
-
});
|
|
83
|
-
const params = new URL(lastRequestedUrl).searchParams;
|
|
84
|
-
const keys = [...params.keys()];
|
|
85
|
-
const idxCategory = keys.indexOf('category_id');
|
|
86
|
-
const idxPs = keys.indexOf('ps');
|
|
87
|
-
expect(idxCategory).toBeGreaterThanOrEqual(0);
|
|
88
|
-
expect(idxPs).toBeGreaterThan(idxCategory);
|
|
89
|
-
});
|
|
90
|
-
});
|