typia 13.2.0 → 13.3.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/lib/http.d.ts +3 -3
- package/lib/http.js.map +1 -1
- package/lib/http.mjs.map +1 -1
- package/lib/internal/_assertGuard.js +13 -3
- package/lib/internal/_assertGuard.js.map +1 -1
- package/lib/internal/_assertGuard.mjs +4 -2
- package/lib/internal/_assertGuard.mjs.map +1 -1
- package/lib/internal/_isFormatIdnHostname.js +5 -1
- package/lib/internal/_isFormatIdnHostname.js.map +1 -1
- package/lib/internal/_isFormatIdnHostname.mjs +1 -1
- package/lib/internal/_isFormatIdnHostname.mjs.map +1 -1
- package/lib/internal/_isFormatTime.js +19 -2
- package/lib/internal/_isFormatTime.js.map +1 -1
- package/lib/internal/_isFormatTime.mjs +9 -2
- package/lib/internal/_isFormatTime.mjs.map +1 -1
- package/lib/internal/_randomArray.js +37 -4
- package/lib/internal/_randomArray.js.map +1 -1
- package/lib/internal/_randomArray.mjs +16 -3
- package/lib/internal/_randomArray.mjs.map +1 -1
- package/lib/internal/_randomFormatByte.js +15 -12
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +11 -10
- package/lib/internal/_randomFormatByte.mjs.map +1 -1
- package/lib/internal/_randomFormatDatetime.mjs +1 -1
- package/lib/internal/_randomFormatHostname.d.ts +2 -2
- package/lib/internal/_randomFormatHostname.js +2 -2
- package/lib/internal/_randomFormatHostname.mjs +2 -2
- package/lib/internal/_randomFormatHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.js +9 -10
- package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.mjs +3 -4
- package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatRegex.js +4 -4
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +1 -2
- package/lib/internal/_randomFormatRegex.mjs.map +1 -1
- package/lib/internal/_randomFormatTime.js +15 -10
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +6 -3
- package/lib/internal/_randomFormatTime.mjs.map +1 -1
- package/lib/internal/private/__randomComposition.d.ts +8 -0
- package/lib/internal/private/__randomComposition.js +21 -1
- package/lib/internal/private/__randomComposition.js.map +1 -1
- package/lib/internal/private/__randomComposition.mjs +18 -1
- package/lib/internal/private/__randomComposition.mjs.map +1 -1
- package/lib/json.d.ts +2 -2
- package/lib/json.js.map +1 -1
- package/lib/json.mjs.map +1 -1
- package/lib/module.d.ts +28 -13
- package/lib/module.js.map +1 -1
- package/lib/module.mjs.map +1 -1
- package/lib/notations.d.ts +4 -4
- package/lib/notations.js.map +1 -1
- package/lib/notations.mjs.map +1 -1
- package/lib/plain.d.ts +3 -3
- package/lib/plain.js.map +1 -1
- package/lib/plain.mjs.map +1 -1
- package/lib/protobuf.d.ts +2 -2
- package/lib/protobuf.js.map +1 -1
- package/lib/protobuf.mjs.map +1 -1
- package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +17 -4
- package/native/cmd/ttsc-typia/create_assert_error_factory_arity_test.go +309 -0
- package/native/cmd/ttsc-typia/local_function_named_like_typia_operation_transform_test.go +185 -0
- package/native/cmd/ttsc-typia/recursive_conditional_alias_name_transform_test.go +307 -0
- package/native/cmd/ttsc-typia/shadowed_typia_module_declaration_diagnostic_test.go +152 -0
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +1 -3
- package/native/cmd/ttsc-typia/transform_helpers_test.go +92 -26
- package/native/core/factories/FormatCheatSheet.go +2 -2
- package/native/core/factories/MetadataCommentTagFactory.go +26 -11
- package/native/core/factories/factory_utility_coverage_test.go +896 -907
- package/native/core/factories/internal/metadata/MetadataHelper.go +5 -28
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +2 -2
- package/native/core/programmers/RandomProgrammer.go +5 -2
- package/native/core/schemas/metadata/MetadataCollection.go +47 -5
- package/native/transform/CallExpressionTransformer.go +167 -0
- package/package.json +3 -3
- package/src/http.ts +18 -4
- package/src/internal/_assertGuard.ts +13 -2
- package/src/internal/_isFormatIdnHostname.ts +5 -1
- package/src/internal/_isFormatTime.ts +19 -2
- package/src/internal/_randomArray.ts +42 -6
- package/src/internal/_randomFormatByte.ts +17 -12
- package/src/internal/_randomFormatHostname.ts +2 -2
- package/src/internal/_randomFormatIdnHostname.ts +8 -9
- package/src/internal/_randomFormatRegex.ts +4 -6
- package/src/internal/_randomFormatTime.ts +15 -10
- package/src/internal/private/__randomComposition.ts +24 -0
- package/src/json.ts +16 -4
- package/src/module.ts +56 -22
- package/src/notations.ts +16 -4
- package/src/plain.ts +12 -3
- package/src/protobuf.ts +16 -4
|
@@ -3,7 +3,6 @@ package main
|
|
|
3
3
|
import (
|
|
4
4
|
"bytes"
|
|
5
5
|
"os"
|
|
6
|
-
"os/exec"
|
|
7
6
|
"path/filepath"
|
|
8
7
|
"runtime"
|
|
9
8
|
"sort"
|
|
@@ -11,16 +10,81 @@ import (
|
|
|
11
10
|
"testing"
|
|
12
11
|
)
|
|
13
12
|
|
|
13
|
+
// ttscTypiaTestTypecheck requires a fixture project to be free of TypeScript
|
|
14
|
+
// errors, which is what makes an `@ts-expect-error` in a fixture load-bearing.
|
|
15
|
+
//
|
|
16
|
+
// It runs the build command in no-emit mode with the rewrite disabled, so the
|
|
17
|
+
// only diagnostics it can report are the program's own. It used to shell out to
|
|
18
|
+
// `pnpm exec ttsc --noEmit -p tsconfig.json`, which reported nothing and exited
|
|
19
|
+
// 0 for a fixture under `.tmp-ttsc-typia-tests` — `const value: number = "bad"`
|
|
20
|
+
// passed — so every caller was asserting against an oracle that could not fail.
|
|
21
|
+
// `runBuild` is the same program these tests already drive, and
|
|
22
|
+
// build_reports_semantic_diagnostics_test.go pins that it surfaces semantic
|
|
23
|
+
// diagnostics as status 2.
|
|
14
24
|
func ttscTypiaTestTypecheck(t *testing.T, project string) {
|
|
15
25
|
t.Helper()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
out, errText, code := ttscTypiaTestCapture(func() int {
|
|
27
|
+
return runBuild([]string{
|
|
28
|
+
"--cwd", project,
|
|
29
|
+
"--tsconfig", "tsconfig.json",
|
|
30
|
+
"--noEmit",
|
|
31
|
+
"--rewrite-mode", "none",
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
if code != 0 {
|
|
35
|
+
t.Fatalf("fixture typecheck failed: code=%d\nstdout=%s\nstderr=%s", code, out, errText)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ttscTypiaTestWriteFactoryStub installs a typia whose declaration file sits at
|
|
40
|
+
// the path the transformer's identity test accepts, so a fixture that also
|
|
41
|
+
// carries an ambient or augmenting `declare module "typia"` differs from a
|
|
42
|
+
// plain one only in that declaration.
|
|
43
|
+
func ttscTypiaTestWriteFactoryStub(t *testing.T, project string) {
|
|
44
|
+
t.Helper()
|
|
45
|
+
root := filepath.Join(project, "node_modules", "typia")
|
|
46
|
+
lib := filepath.Join(root, "lib")
|
|
47
|
+
if err := os.MkdirAll(lib, 0o755); err != nil {
|
|
48
|
+
t.Fatalf("mkdir typia stub: %v", err)
|
|
19
49
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
50
|
+
files := map[string]string{
|
|
51
|
+
"package.json": `{
|
|
52
|
+
"name": "typia",
|
|
53
|
+
"version": "0.0.0-test",
|
|
54
|
+
"main": "./lib/module.js",
|
|
55
|
+
"types": "./lib/module.d.ts",
|
|
56
|
+
"exports": {
|
|
57
|
+
".": {
|
|
58
|
+
"types": "./lib/module.d.ts",
|
|
59
|
+
"default": "./lib/module.js"
|
|
60
|
+
},
|
|
61
|
+
"./lib/transform": "./lib/transform.js"
|
|
62
|
+
},
|
|
63
|
+
"ttsc": {
|
|
64
|
+
"plugin": { "transform": "typia/lib/transform" }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
`,
|
|
68
|
+
filepath.Join("lib", "module.d.ts"): `declare namespace typia {
|
|
69
|
+
function createAssert<T>(): (input: unknown) => T;
|
|
70
|
+
function createIs<T>(): (input: unknown) => input is T;
|
|
71
|
+
}
|
|
72
|
+
declare const typia: {
|
|
73
|
+
createAssert: typeof typia.createAssert;
|
|
74
|
+
createIs: typeof typia.createIs;
|
|
75
|
+
};
|
|
76
|
+
export default typia;
|
|
77
|
+
export declare function createAssert<T>(): (input: unknown) => T;
|
|
78
|
+
export declare function createIs<T>(): (input: unknown) => input is T;
|
|
79
|
+
`,
|
|
80
|
+
filepath.Join("lib", "module.js"): "exports.createAssert = () => () => undefined;\nexports.createIs = () => () => false;\n",
|
|
81
|
+
filepath.Join("lib", "transform.js"): "module.exports = {};\n",
|
|
82
|
+
filepath.Join("lib", "transform.d.ts"): "export {};\n",
|
|
83
|
+
}
|
|
84
|
+
for name, body := range files {
|
|
85
|
+
if err := os.WriteFile(filepath.Join(root, name), []byte(body), 0o644); err != nil {
|
|
86
|
+
t.Fatalf("write typia stub %s: %v", name, err)
|
|
87
|
+
}
|
|
24
88
|
}
|
|
25
89
|
}
|
|
26
90
|
|
|
@@ -61,14 +125,13 @@ func ttscTypiaTestCapture(run func() int) (string, string, int) {
|
|
|
61
125
|
func ttscTypiaTestWriteCommonRuntimeStubs(t *testing.T, runtimeDir string) {
|
|
62
126
|
t.Helper()
|
|
63
127
|
files := map[string]string{
|
|
64
|
-
"typia-stub.cjs":
|
|
65
|
-
"validate-report-stub.cjs":
|
|
66
|
-
"standard-schema-stub.cjs":
|
|
67
|
-
"assert-guard-stub.cjs":
|
|
68
|
-
"functional-error-stub.cjs":
|
|
69
|
-
"access-expression-stub.cjs":
|
|
70
|
-
"
|
|
71
|
-
"notation-stub.cjs": ttscTypiaTestNotationStub,
|
|
128
|
+
"typia-stub.cjs": "module.exports = {};\n",
|
|
129
|
+
"validate-report-stub.cjs": ttscTypiaTestValidateReportStub,
|
|
130
|
+
"standard-schema-stub.cjs": ttscTypiaTestStandardSchemaStub,
|
|
131
|
+
"assert-guard-stub.cjs": ttscTypiaTestAssertGuardStub,
|
|
132
|
+
"functional-error-stub.cjs": ttscTypiaTestFunctionalErrorStub,
|
|
133
|
+
"access-expression-stub.cjs": ttscTypiaTestAccessExpressionStub,
|
|
134
|
+
"notation-stub.cjs": ttscTypiaTestNotationStub,
|
|
72
135
|
"json-stringify-array-stub.cjs": ttscTypiaTestJsonStringifyArrayStub,
|
|
73
136
|
"json-stringify-property-stub.cjs": ttscTypiaTestJsonStringifyPropertyStub,
|
|
74
137
|
"json-stringify-element-stub.cjs": ttscTypiaTestJsonStringifyElementStub,
|
|
@@ -90,7 +153,6 @@ func ttscTypiaTestRewriteCommonJS(t *testing.T, js string) string {
|
|
|
90
153
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_assertGuard")`, `require("./assert-guard-stub.cjs")`)
|
|
91
154
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_functionalTypeGuardErrorFactory")`, `require("./functional-error-stub.cjs")`)
|
|
92
155
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_accessExpressionAsString")`, `require("./access-expression-stub.cjs")`)
|
|
93
|
-
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_stringLength")`, `require("./string-length-stub.cjs")`)
|
|
94
156
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyArray")`, `require("./json-stringify-array-stub.cjs")`)
|
|
95
157
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyProperty")`, `require("./json-stringify-property-stub.cjs")`)
|
|
96
158
|
runtimeJS = strings.ReplaceAll(runtimeJS, `require("typia/lib/internal/_jsonStringifyElement")`, `require("./json-stringify-element-stub.cjs")`)
|
|
@@ -160,9 +222,20 @@ const ttscTypiaTestValidateReportStub = `module.exports._validateReport = (array
|
|
|
160
222
|
const ttscTypiaTestStandardSchemaStub = `module.exports._createStandardSchema = (validate) => validate;
|
|
161
223
|
`
|
|
162
224
|
|
|
225
|
+
// A double for packages/typia/src/internal/_assertGuard.ts that takes the same
|
|
226
|
+
// branches: `exceptionable === true` and a callable-factory requirement. The
|
|
227
|
+
// generated function's second parameter is caller-supplied, so a pointwise
|
|
228
|
+
// hand-off (`rows.map(assertUser)`) fills it with the element index; testing
|
|
229
|
+
// truthiness here would let this stub report `factory is not a function` for a
|
|
230
|
+
// case the shipped helper handles. The fallback error is deliberately not a
|
|
231
|
+
// TypeGuardError — a stub cannot import typia — so cases assert `props`
|
|
232
|
+
// members rather than the shipped message format.
|
|
163
233
|
const ttscTypiaTestAssertGuardStub = `module.exports._assertGuard = (exceptionable, props, factory) => {
|
|
164
|
-
if (exceptionable) {
|
|
165
|
-
const error =
|
|
234
|
+
if (exceptionable === true) {
|
|
235
|
+
const error =
|
|
236
|
+
typeof factory === "function"
|
|
237
|
+
? factory(props)
|
|
238
|
+
: Object.assign(new Error(props.expected), props);
|
|
166
239
|
throw error;
|
|
167
240
|
}
|
|
168
241
|
return false;
|
|
@@ -217,13 +290,6 @@ const ttscTypiaTestRandomStringStub = `module.exports._randomString = (props) =>
|
|
|
217
290
|
};
|
|
218
291
|
`
|
|
219
292
|
|
|
220
|
-
const ttscTypiaTestStringLengthStub = `module.exports._stringLength = (value) => {
|
|
221
|
-
let count = 0;
|
|
222
|
-
for (const _ of value) ++count;
|
|
223
|
-
return count;
|
|
224
|
-
};
|
|
225
|
-
`
|
|
226
|
-
|
|
227
293
|
const ttscTypiaTestAccessExpressionStub = `const reserved = new Set([
|
|
228
294
|
"break",
|
|
229
295
|
"case",
|
|
@@ -45,7 +45,7 @@ var FormatCheatSheet = map[string]string{
|
|
|
45
45
|
"email": "/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test($input)",
|
|
46
46
|
"hostname": "/^(?=.{1,253}\\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\\.?$/i.test($input)",
|
|
47
47
|
"idn-email": "/^(([^<>()[\\]\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@(([^<>()[\\]\\.,;:\\s@\\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\\"]{2,})$/i.test($input)",
|
|
48
|
-
"idn-hostname": "/^([a-z0-9\\u00a1-\\
|
|
48
|
+
"idn-hostname": "/^(?=.{1,253}\\.?$)[a-z0-9\\u00a1-\\uffff](?:[a-z0-9\\u00a1-\\uffff-]{0,61}[a-z0-9\\u00a1-\\uffff])?(?:\\.[a-z0-9\\u00a1-\\uffff](?:[a-z0-9\\u00a1-\\uffff-]{0,61}[a-z0-9\\u00a1-\\uffff])?)*\\.?$/i.test($input)",
|
|
49
49
|
"iri": `(() => !/[\u0000-\u0020\u007f-\u009f\ud800-\udfff"<>\\^\x60{|}]/u.test($input) && !/%(?![0-9A-Fa-f]{2})/u.test($input) && /^[A-Za-z][A-Za-z0-9+.-]*:/u.test($input))()`,
|
|
50
50
|
"iri-reference": `(() => { if (/[\u0000-\u0020\u007f-\u009f\ud800-\udfff"<>\\^\x60{|}]/u.test($input) || /%(?![0-9A-Fa-f]{2})/u.test($input)) return false; const colon = $input.indexOf(":"); const boundary = $input.search(/[/?#]/u); return colon === -1 || (boundary !== -1 && boundary < colon) || /^[A-Za-z][A-Za-z0-9+.-]*:/u.test($input); })()`,
|
|
51
51
|
"ipv4": "/^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/.test($input)",
|
|
@@ -56,7 +56,7 @@ var FormatCheatSheet = map[string]string{
|
|
|
56
56
|
"url": "/^(?:https?|ftp):\\/\\/(?:[^\\s/?#@]+(?::[^\\s/?#@]*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?=.{1,253}(?::\\d{2,5})?(?:\\/[^\\s]*)?$)(?:[a-z0-9\\u00a1-\\uffff](?:[-a-z0-9\\u00a1-\\uffff]{0,61}[a-z0-9\\u00a1-\\uffff])?\\.)+(?:[a-z\\u00a1-\\uffff](?:[-a-z0-9\\u00a1-\\uffff]{0,61}[a-z0-9\\u00a1-\\uffff])))(?::\\d{2,5})?(?:\\/[^\\s]*)?$/iu.test($input)",
|
|
57
57
|
"date-time": `(() => { const match = /^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])[Tt]((?:[01][0-9]|2[0-3])):([0-5][0-9]):([0-5][0-9]|60)(?:\.[0-9]+)?(?:[Zz]|([+-])((?:[01][0-9]|2[0-3])):([0-5][0-9]))$/.exec($input); if (match === null) return false; const year = Number(match[1]); const month = Number(match[2]); const day = Number(match[3]); if (day > [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1] + (month === 2 && (year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)) ? 1 : 0)) return false; if (match[6] !== "60") return true; const instant = new Date(0); instant.setUTCFullYear(year, month - 1, day); instant.setUTCHours(Number(match[4]), Number(match[5]), 0, 0); const offset = match[7] === undefined ? 0 : (match[7] === "+" ? 1 : -1) * (Number(match[8]) * 60 + Number(match[9])); instant.setUTCMinutes(instant.getUTCMinutes() - offset); return instant.getUTCHours() === 23 && instant.getUTCMinutes() === 59 && ((instant.getUTCMonth() === 5 && instant.getUTCDate() === 30) || (instant.getUTCMonth() === 11 && instant.getUTCDate() === 31)); })()`,
|
|
58
58
|
"date": `(() => { const match = /^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/.exec($input); if (match === null) return false; const year = Number(match[1]); const month = Number(match[2]); const day = Number(match[3]); return day <= [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1] + (month === 2 && (year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)) ? 1 : 0); })()`,
|
|
59
|
-
"time":
|
|
59
|
+
"time": `(() => { const match = /^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(?:\.[0-9]+)?(?:[Zz]|([+-])((?:[01][0-9]|2[0-3])):([0-5][0-9]))$/.exec($input); if (match === null) return false; if (match[3] !== "60") return true; const offset = match[4] === undefined ? 0 : (match[4] === "+" ? 1 : -1) * (Number(match[5]) * 60 + Number(match[6])); const minutes = Number(match[1]) * 60 + Number(match[2]) - offset; return ((minutes % 1440) + 1440) % 1440 === 1439; })()`,
|
|
60
60
|
"duration": "/^P(?!$)((\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+S)?)?|(\\d+W)?)$/.test($input)",
|
|
61
61
|
"json-pointer": "/^(?:\\/(?:[^~/]|~0|~1)*)*$/.test($input)",
|
|
62
62
|
"relative-json-pointer": "/^(?:0|[1-9][0-9]*)(?:#|(?:\\/(?:[^~/]|~0|~1)*)*)$/.test($input)",
|
|
@@ -268,7 +268,7 @@ var metadataCommentTagFactory_PARSER = map[string]metadataCommentTagFactory_pars
|
|
|
268
268
|
Report func(msg string) any
|
|
269
269
|
Value string
|
|
270
270
|
}) metadataCommentTagFactory_TagRecord {
|
|
271
|
-
return metadataCommentTagFactory_numeric(props, "MultipleOf", "multipleOf", "$
|
|
271
|
+
return metadataCommentTagFactory_numeric(props, "MultipleOf", "multipleOf", "$input % "+props.Value+" === 0", "$input % "+props.Value+"n === 0n")
|
|
272
272
|
},
|
|
273
273
|
"format": func(props struct {
|
|
274
274
|
Report func(msg string) any
|
|
@@ -292,8 +292,8 @@ var metadataCommentTagFactory_PARSER = map[string]metadataCommentTagFactory_pars
|
|
|
292
292
|
}) metadataCommentTagFactory_TagRecord {
|
|
293
293
|
value := metadataCommentTagFactory_parse_number(props)
|
|
294
294
|
return metadataCommentTagFactory_TagRecord{"string": {
|
|
295
|
-
{Name: "MinLength<" + props.Value + ">", Target: "string", Kind: "minLength", Value: value, Validate: props.Value + " <= $
|
|
296
|
-
{Name: "MaxLength<" + props.Value + ">", Target: "string", Kind: "maxLength", Value: value, Validate: "$
|
|
295
|
+
{Name: "MinLength<" + props.Value + ">", Target: "string", Kind: "minLength", Value: value, Validate: props.Value + " <= $input.length", Exclusive: metadataCommentTagFactory_exclusive("minLength"), Schema: map[string]any{"minLength": value}},
|
|
296
|
+
{Name: "MaxLength<" + props.Value + ">", Target: "string", Kind: "maxLength", Value: value, Validate: "$input.length <= " + props.Value, Exclusive: metadataCommentTagFactory_exclusive("maxLength"), Schema: map[string]any{"maxLength": value}},
|
|
297
297
|
}}
|
|
298
298
|
},
|
|
299
299
|
"minLength": func(props struct {
|
|
@@ -301,14 +301,14 @@ var metadataCommentTagFactory_PARSER = map[string]metadataCommentTagFactory_pars
|
|
|
301
301
|
Value string
|
|
302
302
|
}) metadataCommentTagFactory_TagRecord {
|
|
303
303
|
value := metadataCommentTagFactory_parse_number(props)
|
|
304
|
-
return metadataCommentTagFactory_TagRecord{"string": {{Name: "MinLength<" + props.Value + ">", Target: "string", Kind: "minLength", Value: value, Validate: props.Value + " <= $
|
|
304
|
+
return metadataCommentTagFactory_TagRecord{"string": {{Name: "MinLength<" + props.Value + ">", Target: "string", Kind: "minLength", Value: value, Validate: props.Value + " <= $input.length", Exclusive: metadataCommentTagFactory_exclusive("minLength"), Schema: map[string]any{"minLength": value}}}}
|
|
305
305
|
},
|
|
306
306
|
"maxLength": func(props struct {
|
|
307
307
|
Report func(msg string) any
|
|
308
308
|
Value string
|
|
309
309
|
}) metadataCommentTagFactory_TagRecord {
|
|
310
310
|
value := metadataCommentTagFactory_parse_number(props)
|
|
311
|
-
return metadataCommentTagFactory_TagRecord{"string": {{Name: "MaxLength<" + props.Value + ">", Target: "string", Kind: "maxLength", Value: value, Validate: "$
|
|
311
|
+
return metadataCommentTagFactory_TagRecord{"string": {{Name: "MaxLength<" + props.Value + ">", Target: "string", Kind: "maxLength", Value: value, Validate: "$input.length <= " + props.Value, Exclusive: metadataCommentTagFactory_exclusive("maxLength"), Schema: map[string]any{"maxLength": value}}}}
|
|
312
312
|
},
|
|
313
313
|
}
|
|
314
314
|
|
|
@@ -407,13 +407,28 @@ func metadataCommentTagFactory_parse_type(props struct {
|
|
|
407
407
|
"number": {{Name: "Type<" + strconv.Quote(value) + ">", Target: "number", Kind: "type", Value: value, Validate: validate, Exclusive: metadataCommentTagFactory_exclusive("type"), Schema: numberSchema}},
|
|
408
408
|
}
|
|
409
409
|
if value == "int64" || value == "uint64" {
|
|
410
|
-
//
|
|
411
|
-
//
|
|
412
|
-
//
|
|
413
|
-
//
|
|
414
|
-
|
|
410
|
+
// Both checks stay inline, spelled exactly as `Type<"int64">` and
|
|
411
|
+
// `Type<"uint64">` declare them, because `@type int64` and
|
|
412
|
+
// `bigint & Type<"int64">` are two spellings of one constraint.
|
|
413
|
+
//
|
|
414
|
+
// That declaration must not name a runtime helper the way the `number` arms
|
|
415
|
+
// above do. A `$importInternal(...)` in a tag template makes the emitted
|
|
416
|
+
// validator import a `typia/lib/internal/*` module, and the declaration
|
|
417
|
+
// lives in `@typia/interface`, which `typia` depends on through a caret
|
|
418
|
+
// range that only floats upward -- so an older `typia` installs a newer
|
|
419
|
+
// `@typia/interface` and emits an import its own runtime never shipped
|
|
420
|
+
// (#2330). `isTypeInt64` and `isTypeUint64` are safe there because
|
|
421
|
+
// `@typia/interface` 13.0.0 already named them and `typia` 13.0.0 already
|
|
422
|
+
// shipped them; a helper introduced later is not, and inside one major
|
|
423
|
+
// there is no range that prevents the pairing.
|
|
424
|
+
//
|
|
425
|
+
// The bound this leaves unenforced is real: int64 accepts any magnitude and
|
|
426
|
+
// uint64 only rejects negatives. #2338 owns restoring it, and only a major
|
|
427
|
+
// can carry it -- an inline exact comparison would name no helper, but
|
|
428
|
+
// tightening an accepted range rejects data that passes today.
|
|
429
|
+
bigintValidate := "BigInt(0) <= $input"
|
|
415
430
|
if value == "int64" {
|
|
416
|
-
bigintValidate = "
|
|
431
|
+
bigintValidate = "true"
|
|
417
432
|
}
|
|
418
433
|
record["bigint"] = []schemametadata.IMetadataTypeTag{
|
|
419
434
|
{Name: "Type<" + strconv.Quote(value) + ">", Target: "bigint", Kind: "type", Value: value, Validate: bigintValidate, Exclusive: metadataCommentTagFactory_exclusive("type"), Schema: bigintSchema},
|