Validate product and collection handles to be URL safe (#7310)
* fix: allow URL safe characters for product handle Fixes: CORE-2072
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import { isValidHandle } from "../validate-handle"
|
||||
|
||||
describe("normalizeHandle", function () {
|
||||
it("should generate URL friendly handles", function () {
|
||||
const expectations = [
|
||||
{
|
||||
input: "the-fan-boy's-club",
|
||||
isValid: false,
|
||||
},
|
||||
{
|
||||
input: "@t-the-sky",
|
||||
isValid: false,
|
||||
},
|
||||
{
|
||||
input: "nouvelles-annees",
|
||||
isValid: true,
|
||||
},
|
||||
{
|
||||
input: "@t-the-sky",
|
||||
isValid: false,
|
||||
},
|
||||
{
|
||||
input: "user.product",
|
||||
isValid: false,
|
||||
},
|
||||
{
|
||||
input: 'sky"bar',
|
||||
isValid: false,
|
||||
},
|
||||
]
|
||||
|
||||
expectations.forEach((expectation) => {
|
||||
expect(isValidHandle(expectation.input)).toEqual(expectation.isValid)
|
||||
})
|
||||
})
|
||||
})
|
||||
44
packages/core/utils/src/common/__tests__/to-handle.spec.ts
Normal file
44
packages/core/utils/src/common/__tests__/to-handle.spec.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { toHandle } from "../to-handle"
|
||||
|
||||
describe("normalizeHandle", function () {
|
||||
it("should generate URL friendly handles", function () {
|
||||
const expectations = [
|
||||
{
|
||||
input: "The fan boy's club",
|
||||
output: "the-fan-boys-club",
|
||||
},
|
||||
{
|
||||
input: "nouvelles années",
|
||||
output: "nouvelles-annees",
|
||||
},
|
||||
{
|
||||
input: "25% OFF",
|
||||
output: "25-off",
|
||||
},
|
||||
{
|
||||
input: "25% de réduction",
|
||||
output: "25-de-reduction",
|
||||
},
|
||||
{
|
||||
input: "-first-product",
|
||||
output: "-first-product",
|
||||
},
|
||||
{
|
||||
input: "user.product",
|
||||
output: "userproduct",
|
||||
},
|
||||
{
|
||||
input: "_first-product",
|
||||
output: "-first-product",
|
||||
},
|
||||
{
|
||||
input: "_HELLO_WORLD",
|
||||
output: "-hello-world",
|
||||
},
|
||||
]
|
||||
|
||||
expectations.forEach((expectation) => {
|
||||
expect(toHandle(expectation.input)).toEqual(expectation.output)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -58,3 +58,5 @@ export * from "./transaction"
|
||||
export * from "./trim-zeros"
|
||||
export * from "./upper-case-first"
|
||||
export * from "./wrap-handler"
|
||||
export * from "./to-handle"
|
||||
export * from "./validate-handle"
|
||||
|
||||
18
packages/core/utils/src/common/to-handle.ts
Normal file
18
packages/core/utils/src/common/to-handle.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { kebabCase } from "./to-kebab-case"
|
||||
|
||||
/**
|
||||
* Helper method to create a to be URL friendly "handle" from
|
||||
* a string value.
|
||||
*
|
||||
* - Works by converting the value to lowercase
|
||||
* - Splits and remove accents from characters
|
||||
* - Removes all unallowed characters like a '"%$ and so on.
|
||||
*/
|
||||
export const toHandle = (value: string): string => {
|
||||
return kebabCase(
|
||||
value
|
||||
.toLowerCase()
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
).replace(/[^a-z0-9A-Z-_]/g, "")
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export const kebabCase = (string) =>
|
||||
export const kebabCase = (string: string): string =>
|
||||
string
|
||||
.replace(/([a-z])([A-Z])/g, "$1-$2")
|
||||
.replace(/[\s_]+/g, "-")
|
||||
|
||||
9
packages/core/utils/src/common/validate-handle.ts
Normal file
9
packages/core/utils/src/common/validate-handle.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { kebabCase } from "./to-kebab-case"
|
||||
|
||||
/**
|
||||
* Helper method to validate entity "handle" to be URL
|
||||
* friendly.
|
||||
*/
|
||||
export const isValidHandle = (value: string): boolean => {
|
||||
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value)
|
||||
}
|
||||
Reference in New Issue
Block a user