From 4a074f22ba75efa12dd4614a5d6d2c6d821a242f Mon Sep 17 00:00:00 2001 From: benjaminLeongSK Date: Mon, 13 Apr 2026 16:24:04 +0800 Subject: [PATCH 1/2] [CCUBE-1813][BL] Create special character rule htmlsafe --- src/custom-rules/apply-custom-rules.ts | 2 ++ src/custom-rules/html-safe.ts | 11 +++++++++++ src/schema-generator/types.ts | 1 + 3 files changed, 14 insertions(+) create mode 100644 src/custom-rules/html-safe.ts diff --git a/src/custom-rules/apply-custom-rules.ts b/src/custom-rules/apply-custom-rules.ts index 831d274..03d5ada 100644 --- a/src/custom-rules/apply-custom-rules.ts +++ b/src/custom-rules/apply-custom-rules.ts @@ -1,5 +1,6 @@ import { equalsField, notEqualsField } from "./equals-field"; import { excludes } from "./excludes"; +import { htmlSafe } from "./html-safe"; import { includes } from "./includes"; import { uen } from "./uen"; import { uinfin } from "./uinfin"; @@ -34,4 +35,5 @@ export const applyCustomRules = () => { notEqualsField(); withinDays(); beyondDays(); + htmlSafe(); }; diff --git a/src/custom-rules/html-safe.ts b/src/custom-rules/html-safe.ts new file mode 100644 index 0000000..3b870cf --- /dev/null +++ b/src/custom-rules/html-safe.ts @@ -0,0 +1,11 @@ +import isEmpty from "lodash/isEmpty"; +import { addRule } from "../schema-generator"; + +// Myinfo name fields allow letters, spaces, and only these special characters: , ( ) / . @ - ' +const HTML_SAFE_REGEX = /^[A-Za-z\s,()/.@'-]+$/; + +export const htmlSafe = () => + addRule("string", "htmlSafe", (value: string, htmlSafe: boolean) => { + if (isEmpty(value) || !htmlSafe) return true; + return HTML_SAFE_REGEX.test(value); + }); diff --git a/src/schema-generator/types.ts b/src/schema-generator/types.ts index 128dc20..4d1be34 100644 --- a/src/schema-generator/types.ts +++ b/src/schema-generator/types.ts @@ -85,6 +85,7 @@ interface IRule { equalsField?: string | undefined; notEqualsField?: string | undefined; whitespace?: boolean | IWhitespaceRule | undefined; + htmlSafe?: boolean | undefined; /** * @deprecated Use `whitespace` rule instead. */ From baaf6cd0a0bce7baada8c724bb4d4de2d4bfbacf Mon Sep 17 00:00:00 2001 From: benjaminLeongSK Date: Mon, 13 Apr 2026 16:24:19 +0800 Subject: [PATCH 2/2] [CCUBE-1813][BL] Added test cases --- src/__tests__/custom-rules/custom-rules.spec.ts | 8 +++++--- src/__tests__/schema-generator/yup-helper.spec.ts | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/__tests__/custom-rules/custom-rules.spec.ts b/src/__tests__/custom-rules/custom-rules.spec.ts index ef43c5b..42643e5 100644 --- a/src/__tests__/custom-rules/custom-rules.spec.ts +++ b/src/__tests__/custom-rules/custom-rules.spec.ts @@ -30,6 +30,7 @@ describe("custom-rules", () => { ${"string"} | ${"notEquals"} | ${"text-field"} | ${{ notEquals: "hello" }} | ${"hi"} | ${"hello"} ${"string"} | ${"equalsField"} | ${"text-field"} | ${{ equalsField: "field1" }} | ${"hello"} | ${"help"} ${"string"} | ${"equalsField (empty)"} | ${"text-field"} | ${{ equalsField: "field1" }} | ${undefined} | ${"help"} + ${"string"} | ${"htmlSafe"} | ${"text-field"} | ${{ htmlSafe: true }} | ${"O'CONNOR"} | ${"TAN&LEE"} ${"string"} | ${"notMatches"} | ${"text-field"} | ${{ notMatches: "/^(hello)/" }} | ${"hi"} | ${"hello"} ${"string"} | ${"noWhitespaceOnly"} | ${"text-field"} | ${{ noWhitespaceOnly: true }} | ${" . "} | ${" "} ${"string"} | ${"whitespace"} | ${"text-field"} | ${{ whitespace: true }} | ${""} | ${" "} @@ -202,9 +203,10 @@ describe("custom-rules", () => { }); it.each` - type | config | valid | invalid - ${"uinfin"} | ${{ uinfin: true }} | ${["S1111111D", "T8017681Z", "F4769209K", "G5825195Q", "M1234567K"]} | ${["S1234567A"]} - ${"uen"} | ${{ uen: true }} | ${["200012345A", "12345678A", "T09LL0001B"]} | ${["1234A567A", "T09L10001B"]} + type | config | valid | invalid + ${"uinfin"} | ${{ uinfin: true }} | ${["S1111111D", "T8017681Z", "F4769209K", "G5825195Q", "M1234567K"]} | ${["S1234567A"]} + ${"uen"} | ${{ uen: true }} | ${["200012345A", "12345678A", "T09LL0001B"]} | ${["1234A567A", "T09L10001B"]} + ${"htmlSafe"} | ${{ htmlSafe: true }} | ${["TAN AH KOW", "O'CONNOR", "A/B TEST", "LEE (ALIAS)", "A.B. @ C"]} | ${["