@scayle/storefront-nuxt 7.44.1 → 7.46.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 +35 -0
- package/dist/module.json +1 -1
- package/dist/runtime/composables/core/useFormatHelpers.d.ts +14 -0
- package/dist/runtime/composables/core/useFormatHelpers.mjs +27 -0
- package/package.json +12 -12
- package/dist/runtime/server/middleware/bootstrap.test.d.ts +0 -6
- package/dist/runtime/server/middleware/bootstrap.test.mjs +0 -277
- package/dist/runtime/server/middleware/redirects.test.d.ts +0 -1
- package/dist/runtime/server/middleware/redirects.test.mjs +0 -66
- package/dist/runtime/utils/price.d.ts +0 -11
- package/dist/runtime/utils/price.mjs +0 -32
- package/dist/runtime/utils/price.test.d.ts +0 -1
- package/dist/runtime/utils/price.test.mjs +0 -83
- package/dist/runtime/utils/route.test.d.ts +0 -1
- package/dist/runtime/utils/route.test.mjs +0 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @scayle/storefront-nuxt
|
|
2
2
|
|
|
3
|
+
## 7.46.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Use new password change API when oauth is enabled
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Locale is optional in formatCurrency
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
- @scayle/storefront-core@7.32.0
|
|
14
|
+
|
|
15
|
+
## 7.45.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- Migrate currency formatters to a composable
|
|
20
|
+
|
|
21
|
+
Because the currency formatter functions depend on the `useCurrentShop` composable, they must also be initialized through a composable. Additionally, because `formatPrice` was the same as `toCurrency` except that it excluded the symbol, the two functions have been merged into `formatCurrency`. If you don't want the currency symbol to be displayed, set the `style` option to `decimal`. These changes requires a small migration step.
|
|
22
|
+
|
|
23
|
+
Before:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
toCurrency(100, { currency: 'EUR' })
|
|
27
|
+
formatPrice(100, { currencyFractionDigits: 2 })
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
After:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
const { formatCurrency } = useFormatHelpers()
|
|
34
|
+
formatCurrency(100, { currency: 'EUR' })
|
|
35
|
+
formatCurrency(100, { style: 'decimal', currencyFractionDigits: 2 })
|
|
36
|
+
```
|
|
37
|
+
|
|
3
38
|
## 7.44.1
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
package/dist/module.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type FormatCurrencyOptions = {
|
|
2
|
+
locale?: string;
|
|
3
|
+
currencyFractionDigits?: number;
|
|
4
|
+
style?: 'currency';
|
|
5
|
+
currency: string;
|
|
6
|
+
} | {
|
|
7
|
+
locale?: string;
|
|
8
|
+
currencyFractionDigits?: number;
|
|
9
|
+
style: 'decimal';
|
|
10
|
+
};
|
|
11
|
+
export default function useFormatHelpers(): {
|
|
12
|
+
formatCurrency: (value: number, options?: FormatCurrencyOptions) => string;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getDefaultFractionDigits } from "@scayle/storefront-core";
|
|
2
|
+
import { useCurrentShop } from "./useCurrentShop.mjs";
|
|
3
|
+
export default function useFormatHelpers() {
|
|
4
|
+
const currentShop = useCurrentShop();
|
|
5
|
+
const formatCurrency = (value, options) => {
|
|
6
|
+
const {
|
|
7
|
+
locale = currentShop.value.locale,
|
|
8
|
+
currencyFractionDigits = currentShop.value.currencyFractionDigits
|
|
9
|
+
} = options || {};
|
|
10
|
+
const currency = options?.style !== "decimal" ? options?.currency ?? currentShop.value.currency : void 0;
|
|
11
|
+
const minimumFractionDigits = options?.style !== "decimal" ? getDefaultFractionDigits(
|
|
12
|
+
locale,
|
|
13
|
+
options?.currency ?? currentShop.value.currency
|
|
14
|
+
) : currencyFractionDigits;
|
|
15
|
+
return (value / 100).toLocaleString(locale, {
|
|
16
|
+
style: options?.style ?? "currency",
|
|
17
|
+
...currencyFractionDigits && {
|
|
18
|
+
minimumFractionDigits: minimumFractionDigits !== void 0 ? Math.min(minimumFractionDigits, currencyFractionDigits) : currencyFractionDigits
|
|
19
|
+
},
|
|
20
|
+
maximumFractionDigits: currencyFractionDigits,
|
|
21
|
+
currency
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
formatCurrency
|
|
26
|
+
};
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/storefront-nuxt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.
|
|
4
|
+
"version": "7.46.0",
|
|
5
5
|
"description": "Nuxt integration for the SCAYLE Commerce Engine and Storefront API",
|
|
6
6
|
"author": "SCAYLE Commerce Engine",
|
|
7
7
|
"license": "MIT",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@nuxt/kit": "3.8.2",
|
|
64
64
|
"@scayle/h3-session": "0.3.4",
|
|
65
|
-
"@scayle/storefront-core": "7.
|
|
65
|
+
"@scayle/storefront-core": "7.32.0",
|
|
66
66
|
"@scayle/unstorage-compression-driver": "0.1.1",
|
|
67
67
|
"@vueuse/core": "10.7.0",
|
|
68
68
|
"consola": "3.2.3",
|
|
@@ -101,16 +101,16 @@
|
|
|
101
101
|
"vue": ">=3.3.0"
|
|
102
102
|
},
|
|
103
103
|
"resolutions": {
|
|
104
|
-
"@vue/compiler-core": "3.3.
|
|
105
|
-
"@vue/shared": "3.3.
|
|
106
|
-
"@vue/compiler-dom": "3.3.
|
|
107
|
-
"@vue/compiler-sfc": "3.3.
|
|
108
|
-
"@vue/compiler-ssr": "3.3.
|
|
109
|
-
"@vue/reactivity-transform": "3.3.
|
|
110
|
-
"@vue/reactivity": "3.3.
|
|
111
|
-
"@vue/runtime-core": "3.3.
|
|
112
|
-
"@vue/runtime-dom": "3.3.
|
|
113
|
-
"@vue/server-renderer": "3.3.
|
|
104
|
+
"@vue/compiler-core": "3.3.12",
|
|
105
|
+
"@vue/shared": "3.3.12",
|
|
106
|
+
"@vue/compiler-dom": "3.3.12",
|
|
107
|
+
"@vue/compiler-sfc": "3.3.12",
|
|
108
|
+
"@vue/compiler-ssr": "3.3.12",
|
|
109
|
+
"@vue/reactivity-transform": "3.3.12",
|
|
110
|
+
"@vue/reactivity": "3.3.12",
|
|
111
|
+
"@vue/runtime-core": "3.3.12",
|
|
112
|
+
"@vue/runtime-dom": "3.3.12",
|
|
113
|
+
"@vue/server-renderer": "3.3.12"
|
|
114
114
|
},
|
|
115
115
|
"volta": {
|
|
116
116
|
"node": "20.10.0"
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { createRequest, createResponse } from "node-mocks-http";
|
|
3
|
-
import { createEvent } from "h3";
|
|
4
|
-
import { getCurrentShopForRequest, getPublicShopData } from "./bootstrap.utils.mjs";
|
|
5
|
-
const DOMAIN_DE = "de.scayle.example";
|
|
6
|
-
const DOMAIN_AT = "at.scayle.example";
|
|
7
|
-
const DOMAIN_US = "us.scayle.example";
|
|
8
|
-
const CHECKOUT_HOST = "https://checkout.scayle.cloud";
|
|
9
|
-
const baseShop = {
|
|
10
|
-
appKeys: {
|
|
11
|
-
wishlistKey: "wishlist_{shopId}_{userId}",
|
|
12
|
-
basketKey: "basket_{shopId}_{userId}",
|
|
13
|
-
hashAlgorithm: "sha256"
|
|
14
|
-
},
|
|
15
|
-
auth: {
|
|
16
|
-
resetPasswordUrl: ""
|
|
17
|
-
},
|
|
18
|
-
domain: "demo.test",
|
|
19
|
-
paymentProviders: [],
|
|
20
|
-
checkout: {
|
|
21
|
-
host: CHECKOUT_HOST,
|
|
22
|
-
token: "",
|
|
23
|
-
secret: "",
|
|
24
|
-
user: ""
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
describe("getCurrentShopForRequest", () => {
|
|
28
|
-
it("respects the x-shop-id header", () => {
|
|
29
|
-
const req = createRequest({
|
|
30
|
-
url: "/api/getProducts",
|
|
31
|
-
headers: {
|
|
32
|
-
"x-shop-id": "1002"
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
const moduleOptions = {
|
|
36
|
-
shopSelector: "domain",
|
|
37
|
-
stores: {
|
|
38
|
-
DE_DE: {
|
|
39
|
-
...baseShop,
|
|
40
|
-
shopId: 1001,
|
|
41
|
-
domain: DOMAIN_DE,
|
|
42
|
-
locale: "de-DE",
|
|
43
|
-
currency: "EUR"
|
|
44
|
-
},
|
|
45
|
-
DE_AT: {
|
|
46
|
-
...baseShop,
|
|
47
|
-
shopId: 1002,
|
|
48
|
-
domain: DOMAIN_AT,
|
|
49
|
-
locale: "de-AT",
|
|
50
|
-
currency: "EUR"
|
|
51
|
-
},
|
|
52
|
-
DE_US: {
|
|
53
|
-
...baseShop,
|
|
54
|
-
shopId: 1003,
|
|
55
|
-
domain: DOMAIN_US,
|
|
56
|
-
locale: "en-US",
|
|
57
|
-
currency: "USD"
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
const shop = getCurrentShopForRequest(
|
|
62
|
-
createEvent(req, createResponse()),
|
|
63
|
-
moduleOptions
|
|
64
|
-
);
|
|
65
|
-
expect(shop.shopId).to.eq(1002);
|
|
66
|
-
});
|
|
67
|
-
it("falls back to the path when shopSelector = path", () => {
|
|
68
|
-
const moduleOptions = {
|
|
69
|
-
shopSelector: "path",
|
|
70
|
-
stores: {
|
|
71
|
-
DE_DE: {
|
|
72
|
-
...baseShop,
|
|
73
|
-
shopId: 1001,
|
|
74
|
-
path: "de",
|
|
75
|
-
locale: "de-DE",
|
|
76
|
-
currency: "EUR"
|
|
77
|
-
},
|
|
78
|
-
DE_AT: {
|
|
79
|
-
...baseShop,
|
|
80
|
-
shopId: 1002,
|
|
81
|
-
path: "at",
|
|
82
|
-
locale: "de-AT",
|
|
83
|
-
currency: "EUR"
|
|
84
|
-
},
|
|
85
|
-
EN_US: {
|
|
86
|
-
...baseShop,
|
|
87
|
-
shopId: 1003,
|
|
88
|
-
path: "foobar",
|
|
89
|
-
locale: "en-US",
|
|
90
|
-
currency: "USD"
|
|
91
|
-
},
|
|
92
|
-
DE_CH: {
|
|
93
|
-
...baseShop,
|
|
94
|
-
shopId: 1004,
|
|
95
|
-
path: "de-ch",
|
|
96
|
-
locale: "de-CH",
|
|
97
|
-
currency: "CHF"
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
expect(
|
|
102
|
-
getCurrentShopForRequest(
|
|
103
|
-
createEvent(
|
|
104
|
-
createRequest({
|
|
105
|
-
url: "https://de.scayle.example/foobar/men/shirts"
|
|
106
|
-
}),
|
|
107
|
-
createResponse()
|
|
108
|
-
),
|
|
109
|
-
moduleOptions
|
|
110
|
-
).shopId
|
|
111
|
-
).to.eq(1003);
|
|
112
|
-
expect(
|
|
113
|
-
getCurrentShopForRequest(
|
|
114
|
-
createEvent(
|
|
115
|
-
createRequest({
|
|
116
|
-
url: "/foobar/men/shirts"
|
|
117
|
-
}),
|
|
118
|
-
createResponse()
|
|
119
|
-
),
|
|
120
|
-
moduleOptions
|
|
121
|
-
).shopId
|
|
122
|
-
).to.eq(1003);
|
|
123
|
-
expect(
|
|
124
|
-
getCurrentShopForRequest(
|
|
125
|
-
createEvent(
|
|
126
|
-
createRequest({
|
|
127
|
-
url: "https://de.scayle.example/at/men/shirts"
|
|
128
|
-
}),
|
|
129
|
-
createResponse()
|
|
130
|
-
),
|
|
131
|
-
moduleOptions
|
|
132
|
-
).shopId
|
|
133
|
-
).to.eq(1002);
|
|
134
|
-
expect(
|
|
135
|
-
getCurrentShopForRequest(
|
|
136
|
-
createEvent(
|
|
137
|
-
createRequest({
|
|
138
|
-
url: "https://de.scayle.example/de-ch/men/shirts"
|
|
139
|
-
}),
|
|
140
|
-
createResponse()
|
|
141
|
-
),
|
|
142
|
-
moduleOptions
|
|
143
|
-
).shopId
|
|
144
|
-
).to.eq(1004);
|
|
145
|
-
});
|
|
146
|
-
it("falls back to the domain when shopSelector = domain", () => {
|
|
147
|
-
const req = createRequest({
|
|
148
|
-
url: "https://de.scayle.example/at/frauen"
|
|
149
|
-
});
|
|
150
|
-
const moduleOptions = {
|
|
151
|
-
shopSelector: "domain",
|
|
152
|
-
stores: {
|
|
153
|
-
DE_DE: {
|
|
154
|
-
...baseShop,
|
|
155
|
-
shopId: 1001,
|
|
156
|
-
domain: DOMAIN_DE,
|
|
157
|
-
locale: "de-DE",
|
|
158
|
-
currency: "EUR"
|
|
159
|
-
},
|
|
160
|
-
DE_AT: {
|
|
161
|
-
...baseShop,
|
|
162
|
-
shopId: 1002,
|
|
163
|
-
domain: DOMAIN_AT,
|
|
164
|
-
locale: "de-AT",
|
|
165
|
-
currency: "EUR"
|
|
166
|
-
},
|
|
167
|
-
EN_US: {
|
|
168
|
-
...baseShop,
|
|
169
|
-
shopId: 1003,
|
|
170
|
-
domain: DOMAIN_US,
|
|
171
|
-
locale: "en-US",
|
|
172
|
-
currency: "USD"
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
const shop = getCurrentShopForRequest(
|
|
177
|
-
createEvent(req, createResponse()),
|
|
178
|
-
moduleOptions
|
|
179
|
-
);
|
|
180
|
-
expect(shop.shopId).to.eq(1001);
|
|
181
|
-
});
|
|
182
|
-
it("falls back to the first shop when there is no match", () => {
|
|
183
|
-
const req = createRequest({
|
|
184
|
-
url: "https://de.scayle.example/foobar/men/shirts",
|
|
185
|
-
headers: {
|
|
186
|
-
"x-shop-id": "1005"
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
const moduleOptions = {
|
|
190
|
-
shopSelector: "domain",
|
|
191
|
-
stores: {
|
|
192
|
-
DE_DE: {
|
|
193
|
-
...baseShop,
|
|
194
|
-
shopId: 1001,
|
|
195
|
-
domain: DOMAIN_DE,
|
|
196
|
-
locale: "de-DE",
|
|
197
|
-
currency: "EUR"
|
|
198
|
-
},
|
|
199
|
-
DE_AT: {
|
|
200
|
-
...baseShop,
|
|
201
|
-
shopId: 1002,
|
|
202
|
-
domain: DOMAIN_AT,
|
|
203
|
-
locale: "de-AT",
|
|
204
|
-
currency: "EUR"
|
|
205
|
-
},
|
|
206
|
-
EN_US: {
|
|
207
|
-
...baseShop,
|
|
208
|
-
shopId: 1003,
|
|
209
|
-
domain: DOMAIN_US,
|
|
210
|
-
locale: "en-US",
|
|
211
|
-
currency: "USD"
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
const shop = getCurrentShopForRequest(
|
|
216
|
-
createEvent(req, createResponse()),
|
|
217
|
-
moduleOptions
|
|
218
|
-
);
|
|
219
|
-
expect(shop.shopId).to.eq(1001);
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
describe("getPublicShopData", () => {
|
|
223
|
-
it("excludes checkout secrets from the public shop data", () => {
|
|
224
|
-
const shopConfig = {
|
|
225
|
-
...baseShop,
|
|
226
|
-
shopId: 1003,
|
|
227
|
-
domain: DOMAIN_US,
|
|
228
|
-
path: "en",
|
|
229
|
-
locale: "en-US",
|
|
230
|
-
currency: "USD"
|
|
231
|
-
};
|
|
232
|
-
expect(getPublicShopData(shopConfig, 1003, "/api")).to.eql({
|
|
233
|
-
shopId: 1003,
|
|
234
|
-
domain: DOMAIN_US,
|
|
235
|
-
path: "en",
|
|
236
|
-
locale: "en-US",
|
|
237
|
-
currency: "USD",
|
|
238
|
-
isActive: true,
|
|
239
|
-
checkout: {
|
|
240
|
-
host: CHECKOUT_HOST
|
|
241
|
-
},
|
|
242
|
-
apiBasePath: "/api"
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
it("includes additional shop data for keys in storefront.publicShopData", () => {
|
|
246
|
-
const shopConfig = {
|
|
247
|
-
...baseShop,
|
|
248
|
-
shopId: 1003,
|
|
249
|
-
domain: DOMAIN_US,
|
|
250
|
-
path: "en",
|
|
251
|
-
locale: "en-US",
|
|
252
|
-
currency: "USD",
|
|
253
|
-
paymentProviders: ["visa", "klarna"],
|
|
254
|
-
checkout: {
|
|
255
|
-
host: CHECKOUT_HOST,
|
|
256
|
-
token: "",
|
|
257
|
-
secret: "",
|
|
258
|
-
user: ""
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
expect(
|
|
262
|
-
getPublicShopData(shopConfig, 1003, "/api", ["paymentProviders"])
|
|
263
|
-
).to.eql({
|
|
264
|
-
shopId: 1003,
|
|
265
|
-
domain: DOMAIN_US,
|
|
266
|
-
path: "en",
|
|
267
|
-
locale: "en-US",
|
|
268
|
-
currency: "USD",
|
|
269
|
-
paymentProviders: ["visa", "klarna"],
|
|
270
|
-
isActive: true,
|
|
271
|
-
checkout: {
|
|
272
|
-
host: CHECKOUT_HOST
|
|
273
|
-
},
|
|
274
|
-
apiBasePath: "/api"
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { getRedirectLookupUrls, getTargetLocation } from "./redirects.utils.mjs";
|
|
3
|
-
describe("redirects module", () => {
|
|
4
|
-
describe("getRedirectLookupUrls", () => {
|
|
5
|
-
it("returns the relative and absolute URL", () => {
|
|
6
|
-
expect(
|
|
7
|
-
getRedirectLookupUrls(
|
|
8
|
-
new URL("https://demo.example/de/frauen/kleidung"),
|
|
9
|
-
/* @__PURE__ */ new Set()
|
|
10
|
-
)
|
|
11
|
-
).to.eql({
|
|
12
|
-
relativeSourceUrl: "/de/frauen/kleidung",
|
|
13
|
-
absoluteSourceUrl: "https://demo.example/de/frauen/kleidung"
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
it("strips trailing slashes", () => {
|
|
17
|
-
expect(
|
|
18
|
-
getRedirectLookupUrls(new URL("https://demo.example/men/"), /* @__PURE__ */ new Set())
|
|
19
|
-
).to.eql({
|
|
20
|
-
relativeSourceUrl: "/men",
|
|
21
|
-
absoluteSourceUrl: "https://demo.example/men"
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
it("strips query params", () => {
|
|
25
|
-
expect(
|
|
26
|
-
getRedirectLookupUrls(
|
|
27
|
-
new URL("https://demo.example/products?p=20&term=foo"),
|
|
28
|
-
/* @__PURE__ */ new Set()
|
|
29
|
-
)
|
|
30
|
-
).to.eql({
|
|
31
|
-
relativeSourceUrl: "/products",
|
|
32
|
-
absoluteSourceUrl: "https://demo.example/products"
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
it("does not strip whitelisted query params", () => {
|
|
36
|
-
expect(
|
|
37
|
-
getRedirectLookupUrls(
|
|
38
|
-
new URL("https://demo.example/test/page/?foo=1&bar=10"),
|
|
39
|
-
/* @__PURE__ */ new Set(["bar"])
|
|
40
|
-
)
|
|
41
|
-
).to.eql({
|
|
42
|
-
relativeSourceUrl: "/test/page?bar=10",
|
|
43
|
-
absoluteSourceUrl: "https://demo.example/test/page?bar=10"
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
describe("getTargetLocation", () => {
|
|
48
|
-
it("uses the source as the base for relative URLs", () => {
|
|
49
|
-
expect(
|
|
50
|
-
getTargetLocation(
|
|
51
|
-
new URL("http://demo.test/source/location"),
|
|
52
|
-
"/target"
|
|
53
|
-
)
|
|
54
|
-
).to.eq("http://demo.test/target");
|
|
55
|
-
});
|
|
56
|
-
it("copies non-whitelisted query params from source", () => {
|
|
57
|
-
expect(
|
|
58
|
-
getTargetLocation(
|
|
59
|
-
new URL("http://demo.test/source?foo=10&bar=20"),
|
|
60
|
-
"/redirect",
|
|
61
|
-
/* @__PURE__ */ new Set(["foo"])
|
|
62
|
-
)
|
|
63
|
-
).to.eq("http://demo.test/redirect?bar=20");
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
type BaseOptions = {
|
|
2
|
-
locale: string;
|
|
3
|
-
currencyFractionDigits?: number;
|
|
4
|
-
};
|
|
5
|
-
type FormatOptions = BaseOptions;
|
|
6
|
-
type ToCurrencyOptions = BaseOptions & {
|
|
7
|
-
currency: string;
|
|
8
|
-
};
|
|
9
|
-
export declare const toCurrency: (value: number, options?: ToCurrencyOptions) => string;
|
|
10
|
-
export declare const formatPrice: (value: number, formatOptions?: FormatOptions) => string;
|
|
11
|
-
export {};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { getDefaultFractionDigits } from "@scayle/storefront-core";
|
|
2
|
-
import { useCurrentShop } from "../composables/core/useCurrentShop.mjs";
|
|
3
|
-
export const toCurrency = (value, options) => {
|
|
4
|
-
const currentShop = useCurrentShop();
|
|
5
|
-
const {
|
|
6
|
-
locale = currentShop.value.locale,
|
|
7
|
-
currency = currentShop.value.currency,
|
|
8
|
-
currencyFractionDigits = currentShop.value.currencyFractionDigits
|
|
9
|
-
} = options || {};
|
|
10
|
-
const minimumFractionDigits = getDefaultFractionDigits(locale, currency);
|
|
11
|
-
return (value / 100).toLocaleString(locale, {
|
|
12
|
-
style: "currency",
|
|
13
|
-
...currencyFractionDigits && {
|
|
14
|
-
minimumFractionDigits: Math.min(
|
|
15
|
-
minimumFractionDigits,
|
|
16
|
-
currencyFractionDigits
|
|
17
|
-
)
|
|
18
|
-
},
|
|
19
|
-
maximumFractionDigits: currencyFractionDigits,
|
|
20
|
-
currency
|
|
21
|
-
});
|
|
22
|
-
};
|
|
23
|
-
export const formatPrice = (value, formatOptions) => {
|
|
24
|
-
const currentShop = useCurrentShop();
|
|
25
|
-
const {
|
|
26
|
-
locale = currentShop.value.locale,
|
|
27
|
-
currencyFractionDigits = currentShop.value.currencyFractionDigits
|
|
28
|
-
} = formatOptions || {};
|
|
29
|
-
return (value / 100).toLocaleString(locale, {
|
|
30
|
-
minimumFractionDigits: currencyFractionDigits
|
|
31
|
-
});
|
|
32
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { ref } from "vue";
|
|
3
|
-
import { toCurrency, formatPrice } from "./price.mjs";
|
|
4
|
-
describe("Price utils", () => {
|
|
5
|
-
vi.mock("../composables/core/useCurrentShop", () => ({
|
|
6
|
-
useCurrentShop: () => ref({
|
|
7
|
-
locale: "de-DE",
|
|
8
|
-
currency: "EUR",
|
|
9
|
-
currencyFractionDigits: 2
|
|
10
|
-
})
|
|
11
|
-
}));
|
|
12
|
-
describe("toCurrency", () => {
|
|
13
|
-
it("should return value with EUR currency", () => {
|
|
14
|
-
const options = {
|
|
15
|
-
locale: "de-DE",
|
|
16
|
-
currency: "EUR",
|
|
17
|
-
currencyFractionDigits: 2
|
|
18
|
-
};
|
|
19
|
-
const currency = toCurrency(200, options);
|
|
20
|
-
expect(currency).be.eq("2,00\xA0\u20AC");
|
|
21
|
-
});
|
|
22
|
-
it("should return value with EUR currency with default options", () => {
|
|
23
|
-
const currency = toCurrency(200);
|
|
24
|
-
expect(currency).be.eq("2,00\xA0\u20AC");
|
|
25
|
-
});
|
|
26
|
-
it("should return value with EUR currency with default options", () => {
|
|
27
|
-
const currency = toCurrency(200);
|
|
28
|
-
expect(currency).be.eq("2,00\xA0\u20AC");
|
|
29
|
-
});
|
|
30
|
-
it("should return value with USD currency", () => {
|
|
31
|
-
const options = {
|
|
32
|
-
locale: "de-DE",
|
|
33
|
-
currency: "USD",
|
|
34
|
-
currencyFractionDigits: 2
|
|
35
|
-
};
|
|
36
|
-
const currency = toCurrency(200, options);
|
|
37
|
-
expect(currency).be.eq("2,00\xA0$");
|
|
38
|
-
});
|
|
39
|
-
it("should return value with one fraction digit", () => {
|
|
40
|
-
const options = {
|
|
41
|
-
locale: "de-DE",
|
|
42
|
-
currency: "USD",
|
|
43
|
-
currencyFractionDigits: 1
|
|
44
|
-
};
|
|
45
|
-
const currency = toCurrency(200, options);
|
|
46
|
-
expect(currency).be.eq("2,0\xA0$");
|
|
47
|
-
});
|
|
48
|
-
it("should return value with two fraction digits if no fraction digits set", () => {
|
|
49
|
-
const options = {
|
|
50
|
-
locale: "de-DE",
|
|
51
|
-
currency: "USD"
|
|
52
|
-
};
|
|
53
|
-
const currency = toCurrency(200, options);
|
|
54
|
-
expect(currency).be.eq("2,00\xA0$");
|
|
55
|
-
});
|
|
56
|
-
it("should return value properly formatted for en-US locale", () => {
|
|
57
|
-
const options = {
|
|
58
|
-
locale: "en-US",
|
|
59
|
-
currency: "USD"
|
|
60
|
-
};
|
|
61
|
-
const currency = toCurrency(200, options);
|
|
62
|
-
expect(currency).be.eq("$2.00");
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
describe("formatPrice", () => {
|
|
66
|
-
it("should return formatted price with two fraction digits", () => {
|
|
67
|
-
const options = {
|
|
68
|
-
locale: "en-US",
|
|
69
|
-
currencyFractionDigits: 2
|
|
70
|
-
};
|
|
71
|
-
const price = formatPrice(200, options);
|
|
72
|
-
expect(price).be.eq("2.00");
|
|
73
|
-
});
|
|
74
|
-
it("should return formatted price with one fraction digits", () => {
|
|
75
|
-
const options = {
|
|
76
|
-
locale: "en-US",
|
|
77
|
-
currencyFractionDigits: 1
|
|
78
|
-
};
|
|
79
|
-
const price = formatPrice(200, options);
|
|
80
|
-
expect(price).be.eq("2.0");
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { getCurrentPage } from "./route.mjs";
|
|
3
|
-
describe("getCurrentPage", () => {
|
|
4
|
-
it("should return parsed current page", () => {
|
|
5
|
-
const page = getCurrentPage({ page: "20" });
|
|
6
|
-
expect(page).be.equal(20);
|
|
7
|
-
});
|
|
8
|
-
it("should return undefined if page does not exist inside the query", () => {
|
|
9
|
-
const page = getCurrentPage({});
|
|
10
|
-
expect(page).be.equal(void 0);
|
|
11
|
-
});
|
|
12
|
-
it("should return undefined if page is not a string", () => {
|
|
13
|
-
expect(getCurrentPage({ page: ["1", "2"] })).toBe(void 0);
|
|
14
|
-
});
|
|
15
|
-
});
|