Skip to content

Commit

Permalink
Merge pull request #1233 from samchon/feature/pattern
Browse files Browse the repository at this point in the history
Fix #1232: enhance `tags.Pattern` type by type level JSON stringify.
  • Loading branch information
samchon authored Aug 20, 2024
2 parents 0bc883f + d95e79b commit 0771e23
Show file tree
Hide file tree
Showing 21 changed files with 64 additions and 54 deletions.
2 changes: 1 addition & 1 deletion benchmark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@
"suppress-warnings": "^1.0.2",
"tstl": "^3.0.0",
"uuid": "^9.0.1",
"typia": "../typia-6.8.0.tgz"
"typia": "../typia-6.9.0.tgz"
}
}
2 changes: 1 addition & 1 deletion debug/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"dependencies": {
"tstl": "^3.0.0",
"typia": "../typia-6.8.0-dev.20240811.tgz",
"typia": "../typia-6.8.0.tgz",
"uuid": "^10.0.0"
}
}
19 changes: 0 additions & 19 deletions debug/src/bigint.ts

This file was deleted.

6 changes: 6 additions & 0 deletions debug/src/pattern.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import typia, { tags } from "typia";

typia.createIs<
string &
tags.Pattern<"^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$">
>();
2 changes: 1 addition & 1 deletion errors/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
"typescript": "^5.3.2"
},
"dependencies": {
"typia": "../typia-6.8.0.tgz"
"typia": "../typia-6.9.0.tgz"
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typia",
"version": "6.8.0",
"version": "6.9.0",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -67,7 +67,7 @@
},
"homepage": "https://typia.io",
"dependencies": {
"@samchon/openapi": "^0.4.5",
"@samchon/openapi": "^0.4.6",
"commander": "^10.0.0",
"comment-json": "^4.2.3",
"inquirer": "^8.2.5",
Expand Down
4 changes: 2 additions & 2 deletions packages/typescript-json/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typescript-json",
"version": "6.8.0",
"version": "6.9.0",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -63,7 +63,7 @@
},
"homepage": "https://typia.io",
"dependencies": {
"typia": "6.8.0"
"typia": "6.9.0"
},
"peerDependencies": {
"typescript": ">=4.8.0 <5.6.0"
Expand Down
2 changes: 1 addition & 1 deletion src/factories/MetadataCommentTagFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ const PARSER: Record<
target: "string",
kind: "pattern",
value: Value,
validate: `RegExp(/${Value}/).test($input)`,
validate: `RegExp(${JSON.stringify(Value)}).test($input)`,
exclusive: ["format"],
schema: {
pattern: Value,
Expand Down
6 changes: 5 additions & 1 deletion src/programmers/RandomProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,11 @@ export namespace RandomProgrammer {
return ts.factory.createCallExpression(
COALESCE(importer)("pattern"),
undefined,
[ts.factory.createIdentifier(`/${t.value}/`)],
[
ts.factory.createIdentifier(
`RegExp(${JSON.stringify(t.value)})`,
),
],
);

const tail = RandomRanger.length(COALESCE(importer))({
Expand Down
21 changes: 20 additions & 1 deletion src/tags/Pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,28 @@ export type Pattern<Value extends string> = TagBase<{
target: "string";
kind: "pattern";
value: Value;
validate: `/${Value}/.test($input)`;
validate: `RegExp("${Serialize<Value>}").test($input)`;
exclusive: ["format", "pattern"];
schema: {
pattern: Value;
};
}>;

/// reference: https://github.com/type-challenges/type-challenges/issues/22394#issuecomment-1397158205
type Serialize<T extends string, Output extends string = ""> = string extends T
? never
: T extends ""
? Output
: T extends `${infer P}${infer R}`
? Serialize<R, `${Output}${P extends keyof Escaper ? Escaper[P] : P}`>
: never;

type Escaper = {
'"': '\\"';
"\\": "\\\\";
"\b": "\\b";
"\f": "\\f";
"\n": "\\n";
"\r": "\\r";
"\t": "\\t";
};
2 changes: 1 addition & 1 deletion test-esm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@
"typescript": "^5.4.5"
},
"dependencies": {
"typia": "../typia-6.8.0.tgz"
"typia": "../typia-6.9.0.tgz"
}
}
4 changes: 2 additions & 2 deletions test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"scripts": {
"build": "rimraf bin && tsc",
"build_run": "npm run build",
"generate": "rimraf generated && rimraf bin-generated && node --max-old-space-size=8000 node_modules/typia/lib/executable/typia generate --input src --output generated --project tsconfig.generated.json && rimraf generated/features/functional* && rimraf generated/features/issues && node --max-old-space-size=8000 node_modules/typescript/bin/tsc --project tsconfig.generated.json",
"generate": "rimraf generated && rimraf bin-generated && typia generate --input src --output generated --project tsconfig.generated.json && rimraf generated/features/functional* && rimraf generated/features/issues && node --max-old-space-size=8000 node_modules/typescript/bin/tsc --project tsconfig.generated.json",
"prepare": "ts-patch install",
"prettier": "prettier ./src/**/*.ts --write",
"setup": "node build/setup.js",
Expand Down Expand Up @@ -52,6 +52,6 @@
"suppress-warnings": "^1.0.2",
"tstl": "^3.0.0",
"uuid": "^9.0.1",
"typia": "../typia-6.8.0.tgz"
"typia": "../typia-6.9.0.tgz"
}
}
2 changes: 1 addition & 1 deletion test/schemas/json/v3_0/CommentTagPattern.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"email": {
"type": "string",
"pattern": "^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$"
"pattern": "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
},
"ipv4": {
"type": "string",
Expand Down
2 changes: 1 addition & 1 deletion test/schemas/json/v3_0/TypeTagPattern.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"email": {
"type": "string",
"pattern": "^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$"
"pattern": "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
},
"ipv4": {
"type": "string",
Expand Down
2 changes: 1 addition & 1 deletion test/schemas/json/v3_1/CommentTagPattern.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"email": {
"type": "string",
"pattern": "^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$"
"pattern": "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
},
"ipv4": {
"type": "string",
Expand Down
2 changes: 1 addition & 1 deletion test/schemas/json/v3_1/TypeTagPattern.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"email": {
"type": "string",
"pattern": "^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$"
"pattern": "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
},
"ipv4": {
"type": "string",
Expand Down
16 changes: 8 additions & 8 deletions test/schemas/reflect/metadata/CommentTagPattern.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"name": "Pattern<\"[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[4][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$\">",
"kind": "pattern",
"value": "[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[4][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$",
"validate": "RegExp(/[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[4][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$/).test($input)",
"validate": "RegExp(\"[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[4][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$\").test($input)",
"exclusive": [
"format"
],
Expand Down Expand Up @@ -151,15 +151,15 @@
[
{
"target": "string",
"name": "Pattern<\"^(([^<>()[\\\\]\\\\.,;:\\\\s@\\\\\\\"]+(\\\\.[^<>()[\\\\]\\\\.,;:\\\\s@\\\\\\\"]+)*)|(\\\\\\\".+\\\\\\\"))@(([^<>()[\\\\]\\\\.,;:\\\\s@\\\\\\\"]+\\\\.)+[^<>()[\\\\]\\\\.,;:\\\\s@\\\\\\\"]{2,})$\">",
"name": "Pattern<\"^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$\">",
"kind": "pattern",
"value": "^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$",
"validate": "RegExp(/^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$/).test($input)",
"value": "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",
"validate": "RegExp(\"^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$\").test($input)",
"exclusive": [
"format"
],
"schema": {
"pattern": "^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$"
"pattern": "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
}
}
]
Expand All @@ -184,7 +184,7 @@
"name": "pattern",
"text": [
{
"text": "^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$",
"text": "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",
"kind": "text"
}
]
Expand Down Expand Up @@ -236,7 +236,7 @@
"name": "Pattern<\"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$\">",
"kind": "pattern",
"value": "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$",
"validate": "RegExp(/(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/).test($input)",
"validate": "RegExp(\"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$\").test($input)",
"exclusive": [
"format"
],
Expand Down Expand Up @@ -318,7 +318,7 @@
"name": "Pattern<\"(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$\">",
"kind": "pattern",
"value": "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$",
"validate": "RegExp(/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/).test($input)",
"validate": "RegExp(\"(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$\").test($input)",
"exclusive": [
"format"
],
Expand Down
Loading

0 comments on commit 0771e23

Please sign in to comment.