diff --git a/src/formats/base64.ts b/src/formats/base64.ts new file mode 100644 index 0000000..b1a84f7 --- /dev/null +++ b/src/formats/base64.ts @@ -0,0 +1,13 @@ +export type JSONBase64Format = { + name: "base64"; +}; + +const base64Regex = /^(?:[A-Za-z\d+/]{4})*(?:[A-Za-z\d+/]{3}=|[A-Za-z\d+/]{2}==)?$/; + +export function inferBase64(value: string): JSONBase64Format | undefined { + if (base64Regex.exec(value)) { + return { name: "base64" }; + } + + return undefined; +} diff --git a/src/formats/index.ts b/src/formats/index.ts index bc14475..652d40a 100644 --- a/src/formats/index.ts +++ b/src/formats/index.ts @@ -20,6 +20,7 @@ import { inferFirestoreTimestamp, JSONFirestoreTimestampFormat } from "./firesto import { inferJWT, JSONJWTStringFormat } from "./jwt"; import { inferColor, JSONColorFormat } from "./color"; import { inferCreditCard, JSONCreditCardFormat } from "./creditCard"; +import { inferBase64, JSONBase64Format } from "./base64"; export { JSONHostnameFormat, @@ -63,7 +64,8 @@ export type JSONStringFormat = | JSONSemverFormat | JSONJWTStringFormat | JSONColorFormat - | JSONCreditCardFormat; + | JSONCreditCardFormat + | JSONBase64Format; const formats = [ inferUri, @@ -86,6 +88,7 @@ const formats = [ inferJWT, inferColor, inferCreditCard, + inferBase64, ]; export function inferFormat(value: string): JSONStringFormat | undefined { diff --git a/tests/stringFormats.test.ts b/tests/stringFormats.test.ts index cf339ae..8d2d2f7 100644 --- a/tests/stringFormats.test.ts +++ b/tests/stringFormats.test.ts @@ -824,6 +824,30 @@ describe("credit cards", () => { ); }); +describe("base64", () => { + test.each([ + "Pmo9fEtDfWt7T11T", + "TG1BdGV8cU9BdHdkK3t6Y35WYmVxMiNiQH40Tw==", + "WzBjLiI7VnB2QlRib21denVIbiRj", + "VzFiIXhsOj5bIiU5PWhcSXdBdVslIms=", + "WzBFRFFOSSxjeFt7aiwo", + "fGZydkoqfENQPXt8bDR1Tlx1Kkk6aA==", + "LVwkb29bSiojT21HJU1B", + "cldpOnRUKy85", + "MnhuaVpjU0Zwdz1gZT5iY3ZaUQ==", + "amE3Rmg5OTVTbUAwI1J3NTZwK2lMXHxWR1tkJg==", + ])("%p should be infered as being a base64 string", (value) => { + expect(inferType(value)).toEqual({ + name: "string", + value, + format: { + name: "base64", + }, + }); + }); +}); + + describe("without format", () => { test.each(["46", "2244994945", "1212092628029698048"])( "%p should be inferred as having no format",