typia 13.1.19 → 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/executable/FileSystemIdentity.d.ts +23 -0
- package/lib/executable/FileSystemIdentity.js +30 -0
- package/lib/executable/FileSystemIdentity.js.map +1 -1
- package/lib/executable/FileSystemIdentity.mjs +4 -0
- package/lib/executable/FileSystemIdentity.mjs.map +1 -1
- package/lib/executable/TypiaGenerateWizard.js +15 -9
- package/lib/executable/TypiaGenerateWizard.js.map +1 -1
- package/lib/executable/TypiaGenerateWizard.mjs +11 -7
- package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
- package/lib/http.d.ts +3 -3
- package/lib/http.js.map +1 -1
- package/lib/http.mjs.map +1 -1
- package/lib/internal/_ProtobufReader.d.ts +18 -3
- package/lib/internal/_ProtobufReader.js +39 -11
- package/lib/internal/_ProtobufReader.js.map +1 -1
- package/lib/internal/_ProtobufReader.mjs +37 -10
- package/lib/internal/_ProtobufReader.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/_jsonStringifyArray.d.ts +1 -0
- package/lib/internal/_jsonStringifyArray.js +48 -0
- package/lib/internal/_jsonStringifyArray.js.map +1 -0
- package/lib/internal/_jsonStringifyArray.mjs +40 -0
- package/lib/internal/_jsonStringifyArray.mjs.map +1 -0
- package/lib/internal/_jsonStringifyElement.d.ts +1 -0
- package/lib/internal/_jsonStringifyElement.js +23 -0
- package/lib/internal/_jsonStringifyElement.js.map +1 -0
- package/lib/internal/_jsonStringifyElement.mjs +23 -0
- package/lib/internal/_jsonStringifyElement.mjs.map +1 -0
- package/lib/internal/_jsonStringifyProperty.d.ts +1 -0
- package/lib/internal/_jsonStringifyProperty.js +31 -0
- package/lib/internal/_jsonStringifyProperty.js.map +1 -0
- package/lib/internal/_jsonStringifyProperty.mjs +31 -0
- package/lib/internal/_jsonStringifyProperty.mjs.map +1 -0
- package/lib/internal/_llmApplicationFinalize.js +1 -1
- package/lib/internal/_llmApplicationFinalize.js.map +1 -1
- package/lib/internal/_llmApplicationFinalize.mjs +1 -1
- package/lib/internal/_llmApplicationFinalize.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 +28 -2
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +22 -3
- package/lib/internal/_randomFormatByte.mjs.map +1 -1
- package/lib/internal/_randomFormatDate.d.ts +3 -6
- package/lib/internal/_randomFormatDate.js +2 -10
- package/lib/internal/_randomFormatDate.js.map +1 -1
- package/lib/internal/_randomFormatDate.mjs +2 -6
- package/lib/internal/_randomFormatDate.mjs.map +1 -1
- package/lib/internal/_randomFormatDatetime.d.ts +3 -6
- package/lib/internal/_randomFormatDatetime.js +25 -8
- package/lib/internal/_randomFormatDatetime.js.map +1 -1
- package/lib/internal/_randomFormatDatetime.mjs +17 -7
- package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
- package/lib/internal/_randomFormatDuration.js +23 -15
- package/lib/internal/_randomFormatDuration.js.map +1 -1
- package/lib/internal/_randomFormatDuration.mjs +23 -15
- package/lib/internal/_randomFormatDuration.mjs.map +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/_randomFormatIpv4.js +31 -1
- package/lib/internal/_randomFormatIpv4.js.map +1 -1
- package/lib/internal/_randomFormatIpv4.mjs +23 -2
- package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv6.js +57 -1
- package/lib/internal/_randomFormatIpv6.js.map +1 -1
- package/lib/internal/_randomFormatIpv6.mjs +45 -2
- package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.js +14 -2
- package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.mjs +13 -3
- package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatRegex.js +15 -2
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +14 -3
- package/lib/internal/_randomFormatRegex.mjs.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.js +19 -5
- package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs +21 -6
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatTime.js +38 -7
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +40 -5
- package/lib/internal/_randomFormatTime.mjs.map +1 -1
- package/lib/internal/_randomPattern.js.map +1 -1
- package/lib/internal/_randomPattern.mjs.map +1 -1
- package/lib/internal/_randomStringLength.d.ts +41 -10
- package/lib/internal/_randomStringLength.js +49 -13
- package/lib/internal/_randomStringLength.js.map +1 -1
- package/lib/internal/_randomStringLength.mjs +48 -13
- package/lib/internal/_randomStringLength.mjs.map +1 -1
- package/lib/internal/private/__notationRename.js.map +1 -1
- package/lib/internal/private/__notationRename.mjs.map +1 -1
- package/lib/internal/private/__randomComposition.d.ts +31 -0
- package/lib/internal/private/__randomComposition.js +68 -0
- package/lib/internal/private/__randomComposition.js.map +1 -0
- package/lib/internal/private/__randomComposition.mjs +71 -0
- package/lib/internal/private/__randomComposition.mjs.map +1 -0
- package/lib/internal/private/__randomEpoch.d.ts +19 -0
- package/lib/internal/private/__randomEpoch.js +31 -0
- package/lib/internal/private/__randomEpoch.js.map +1 -0
- package/lib/internal/private/__randomEpoch.mjs +28 -0
- package/lib/internal/private/__randomEpoch.mjs.map +1 -0
- 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/build.go +3 -0
- package/native/cmd/ttsc-typia/callable_interface_function_semantics_transform_test.go +331 -0
- package/native/cmd/ttsc-typia/callable_type_literal_boundaries_transform_test.go +1184 -0
- package/native/cmd/ttsc-typia/compare_functional_union_membership_transform_test.go +434 -0
- package/native/cmd/ttsc-typia/compare_template_literal_union_transform_test.go +241 -0
- package/native/cmd/ttsc-typia/create_assert_error_factory_arity_test.go +309 -0
- package/native/cmd/ttsc-typia/default_library_spoof_native_identity_transform_test.go +216 -0
- package/native/cmd/ttsc-typia/json_schema_dynamic_key_determinism_transform_test.go +246 -0
- package/native/cmd/ttsc-typia/json_stringify_contextual_undefined_transform_test.go +556 -0
- package/native/cmd/ttsc-typia/lib_replacement_native_identity_transform_test.go +277 -0
- package/native/cmd/ttsc-typia/local_function_named_like_typia_operation_transform_test.go +185 -0
- package/native/cmd/ttsc-typia/native_named_intersection_union_transform_test.go +390 -0
- package/native/cmd/ttsc-typia/node_buffer_native_exports_is_transform_test.go +526 -0
- package/native/cmd/ttsc-typia/package_declaration_native_identity_is_transform_test.go +293 -0
- package/native/cmd/ttsc-typia/protobuf_diagnostic_code_transform_test.go +167 -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/symbol_index_domain_transform_test.go +316 -0
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +1 -3
- package/native/cmd/ttsc-typia/transform.go +23 -0
- package/native/cmd/ttsc-typia/transform_helpers_test.go +166 -25
- package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
- package/native/core/factories/FormatCheatSheet.go +2 -2
- package/native/core/factories/MetadataCommentTagFactory.go +26 -11
- package/native/core/factories/ProtobufFactory.go +6 -1
- package/native/core/factories/factory_utility_coverage_test.go +896 -907
- package/native/core/factories/internal/metadata/MetadataHelper.go +190 -58
- package/native/core/factories/internal/metadata/emplace_metadata_object.go +25 -0
- package/native/core/factories/internal/metadata/iterate_metadata_function.go +1 -1
- package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +103 -23
- package/native/core/factories/internal/metadata/iterate_metadata_map.go +3 -7
- package/native/core/factories/internal/metadata/iterate_metadata_native.go +32 -14
- package/native/core/factories/internal/metadata/iterate_metadata_set.go +3 -7
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +2 -2
- package/native/core/programmers/RandomProgrammer.go +5 -2
- package/native/core/programmers/compare/CompareEqualProgrammer.go +27 -13
- package/native/core/programmers/helpers/FunctionProgrammer.go +6 -13
- package/native/core/programmers/helpers/StringifyJoinder.go +129 -50
- package/native/core/programmers/helpers/joiner_branch_coverage_test.go +116 -120
- package/native/core/programmers/iterate/iterate_check_coverage_test.go +76 -158
- package/native/core/programmers/iterate/iterate_utility_coverage_test.go +231 -270
- package/native/core/programmers/iterate/json_schema_object.go +49 -7
- package/native/core/programmers/iterate/json_schema_pattern_property_order_test.go +44 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader.go +34 -1
- package/native/core/programmers/iterate/template_runtime_pattern.go +11 -0
- package/native/core/programmers/json/JsonStringifyProgrammer.go +47 -6
- package/native/core/programmers/llm/LlmApplicationProgrammer.go +9 -1
- package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +1 -1
- package/native/core/schemas/metadata/MetadataCollection.go +47 -14
- package/native/core/schemas/metadata/MetadataDefaultLibrary.go +81 -0
- package/native/core/schemas/metadata/MetadataObjectType.go +7 -18
- package/native/go.mod +4 -4
- package/native/transform/CallExpressionTransformer.go +167 -0
- package/native/transform/features/protobuf/ProtobufMessageTransformer.go +1 -1
- package/package.json +3 -7
- package/src/executable/FileSystemIdentity.ts +33 -0
- package/src/executable/TypiaGenerateWizard.ts +18 -12
- package/src/http.ts +18 -4
- package/src/internal/_ProtobufReader.ts +40 -11
- package/src/internal/_assertGuard.ts +13 -2
- package/src/internal/_isFormatIdnHostname.ts +5 -1
- package/src/internal/_isFormatTime.ts +19 -2
- package/src/internal/_jsonStringifyArray.ts +50 -0
- package/src/internal/_jsonStringifyElement.ts +19 -0
- package/src/internal/_jsonStringifyProperty.ts +30 -0
- package/src/internal/_llmApplicationFinalize.ts +6 -1
- package/src/internal/_randomArray.ts +42 -6
- package/src/internal/_randomFormatByte.ts +36 -4
- package/src/internal/_randomFormatDate.ts +4 -20
- package/src/internal/_randomFormatDatetime.ts +34 -20
- package/src/internal/_randomFormatDuration.ts +19 -4
- package/src/internal/_randomFormatHostname.ts +2 -2
- package/src/internal/_randomFormatIdnHostname.ts +8 -9
- package/src/internal/_randomFormatIpv4.ts +43 -3
- package/src/internal/_randomFormatIpv6.ts +67 -3
- package/src/internal/_randomFormatJsonPointer.ts +23 -3
- package/src/internal/_randomFormatRegex.ts +22 -6
- package/src/internal/_randomFormatRelativeJsonPointer.ts +23 -10
- package/src/internal/_randomFormatTime.ts +50 -12
- package/src/internal/_randomPattern.ts +4 -1
- package/src/internal/_randomStringLength.ts +61 -17
- package/src/internal/private/__notationRename.ts +1 -4
- package/src/internal/private/__randomComposition.ts +74 -0
- package/src/internal/private/__randomEpoch.ts +34 -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
- package/native/adapter/visit.go +0 -173
- package/native/adapter/visit_property_chain_edges_test.go +0 -129
- package/native/core/programmers/helpers/disable_function_programmer_declare.go +0 -10
- package/native/core/programmers/iterate/check_union_array_like.go +0 -422
- package/native/core/programmers/iterate/prune_object_properties.go +0 -105
- package/native/core/programmers/iterate/stringify_dynamic_properties.go +0 -219
- package/native/core/programmers/iterate/stringify_native.go +0 -14
- package/native/core/programmers/iterate/stringify_regular_properties.go +0 -112
- package/native/core/schemas/metadata/MetadataApplication.go +0 -41
|
@@ -20,7 +20,7 @@ func (protobufMessageTransformerNamespace) Transform(props nativetransform.ITran
|
|
|
20
20
|
typ := props.Context.Checker.GetTypeFromTypeNode(props.Expression.TypeArguments.Nodes[0])
|
|
21
21
|
if typ != nil && typ.IsTypeParameter() {
|
|
22
22
|
panic(nativetransform.NewTransformerError(nativetransform.TransformerError_IProps{
|
|
23
|
-
Code: "
|
|
23
|
+
Code: "typia.protobuf.message",
|
|
24
24
|
Message: "non-specified generic argument.",
|
|
25
25
|
}))
|
|
26
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typia",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.3.0",
|
|
4
4
|
"description": "Superfast runtime validators with only one line",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -50,17 +50,13 @@
|
|
|
50
50
|
"inquirer": "^8.2.5",
|
|
51
51
|
"randexp": "^0.5.3",
|
|
52
52
|
"tinyglobby": "^0.2.12",
|
|
53
|
-
"@typia/interface": "^13.
|
|
54
|
-
"@typia/utils": "^13.
|
|
53
|
+
"@typia/interface": "^13.3.0",
|
|
54
|
+
"@typia/utils": "^13.3.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@ttsc/unplugin": ">=0.19.2",
|
|
58
57
|
"ttsc": ">=0.19.2"
|
|
59
58
|
},
|
|
60
59
|
"peerDependenciesMeta": {
|
|
61
|
-
"@ttsc/unplugin": {
|
|
62
|
-
"optional": true
|
|
63
|
-
},
|
|
64
60
|
"ttsc": {
|
|
65
61
|
"optional": true
|
|
66
62
|
}
|
|
@@ -147,6 +147,39 @@ export namespace FileSystemIdentity {
|
|
|
147
147
|
);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Builds the key that decides whether two paths are the same filesystem
|
|
152
|
+
* object.
|
|
153
|
+
*
|
|
154
|
+
* The identity is read from `fs.BigIntStats` rather than `fs.Stats`, because
|
|
155
|
+
* `fs.Stats.ino` is a JavaScript number. An NTFS file ID is `(sequenceNumber
|
|
156
|
+
* << 48) | mftRecordIndex` and routinely exceeds `Number.MAX_SAFE_INTEGER` —
|
|
157
|
+
* in a 4000-directory probe, 1879 of them did — where the spacing between
|
|
158
|
+
* representable doubles is 8 or more. Two entries sharing a sequence number
|
|
159
|
+
* with MFT record indices within that spacing round to one double. The
|
|
160
|
+
* traversal callers would then treat a distinct directory or file as already
|
|
161
|
+
* visited and skip it with no diagnostic, and the overwrite guard would
|
|
162
|
+
* refuse a legitimate output (samchon/typia#2269).
|
|
163
|
+
*
|
|
164
|
+
* A filesystem that reports no inode at all keeps the canonical path
|
|
165
|
+
* fallback, which is the only identity available there.
|
|
166
|
+
*
|
|
167
|
+
* @param stat Stats read with `{ bigint: true }`.
|
|
168
|
+
* @param realpath Canonical path of the same object.
|
|
169
|
+
* @returns Key that is equal for two paths only when they are one object.
|
|
170
|
+
*/
|
|
171
|
+
export function identityKey(
|
|
172
|
+
stat: Pick<fs.BigIntStats, "dev" | "ino">,
|
|
173
|
+
realpath: string,
|
|
174
|
+
): string {
|
|
175
|
+
// `BigInt(0)` rather than `0n`: this package compiles at ES2016, where a
|
|
176
|
+
// BigInt literal is a syntax error, while the constructor and the `bigint`
|
|
177
|
+
// type are fine.
|
|
178
|
+
return stat.ino === BigInt(0)
|
|
179
|
+
? `path:${path.normalize(realpath)}`
|
|
180
|
+
: `inode:${stat.dev}:${stat.ino}`;
|
|
181
|
+
}
|
|
182
|
+
|
|
150
183
|
function alternateCase(name: string): string | undefined {
|
|
151
184
|
let changed: boolean = false;
|
|
152
185
|
let output: string = "";
|
|
@@ -453,7 +453,7 @@ export namespace TypiaGenerateWizard {
|
|
|
453
453
|
for (const entry of entries) {
|
|
454
454
|
inputs.add(
|
|
455
455
|
fileIdentityKey(
|
|
456
|
-
await fs.promises.stat(entry.file),
|
|
456
|
+
await fs.promises.stat(entry.file, { bigint: true }),
|
|
457
457
|
await fs.promises.realpath(entry.file),
|
|
458
458
|
),
|
|
459
459
|
);
|
|
@@ -461,9 +461,9 @@ export namespace TypiaGenerateWizard {
|
|
|
461
461
|
}
|
|
462
462
|
|
|
463
463
|
for (const entry of files.values()) {
|
|
464
|
-
let stat: fs.
|
|
464
|
+
let stat: fs.BigIntStats;
|
|
465
465
|
try {
|
|
466
|
-
stat = await fs.promises.lstat(entry.target);
|
|
466
|
+
stat = await fs.promises.lstat(entry.target, { bigint: true });
|
|
467
467
|
} catch (exp) {
|
|
468
468
|
if (isMissingFileError(exp)) {
|
|
469
469
|
continue;
|
|
@@ -486,7 +486,7 @@ export namespace TypiaGenerateWizard {
|
|
|
486
486
|
`Error on TypiaGenerateWizard.generate(): output file would overwrite input file through a physical file alias: ${entry.target}`,
|
|
487
487
|
);
|
|
488
488
|
}
|
|
489
|
-
if (stat.nlink > 1) {
|
|
489
|
+
if (stat.nlink > BigInt(1)) {
|
|
490
490
|
throw new URIError(
|
|
491
491
|
`Error on TypiaGenerateWizard.generate(): output file has multiple hard links: ${entry.target}`,
|
|
492
492
|
);
|
|
@@ -874,7 +874,9 @@ export namespace TypiaGenerateWizard {
|
|
|
874
874
|
real: currentReal,
|
|
875
875
|
});
|
|
876
876
|
|
|
877
|
-
const currentStat: fs.
|
|
877
|
+
const currentStat: fs.BigIntStats = await fs.promises.stat(props.from, {
|
|
878
|
+
bigint: true,
|
|
879
|
+
});
|
|
878
880
|
const directoryIdentity: string = fileIdentityKey(currentStat, currentReal);
|
|
879
881
|
if (props.visitedDirectories.has(directoryIdentity)) {
|
|
880
882
|
const lexicalStat: fs.Stats = await fs.promises.lstat(props.from);
|
|
@@ -907,14 +909,16 @@ export namespace TypiaGenerateWizard {
|
|
|
907
909
|
entries.sort((x, y) => {
|
|
908
910
|
const linkOrder: number =
|
|
909
911
|
Number(x.stat.isSymbolicLink()) - Number(y.stat.isSymbolicLink());
|
|
910
|
-
return linkOrder !== 0
|
|
912
|
+
return linkOrder !== 0
|
|
913
|
+
? linkOrder
|
|
914
|
+
: Buffer.compare(Buffer.from(x.name), Buffer.from(y.name));
|
|
911
915
|
});
|
|
912
916
|
|
|
913
917
|
for (const entry of entries) {
|
|
914
|
-
let stat: fs.
|
|
918
|
+
let stat: fs.BigIntStats;
|
|
915
919
|
let real: string;
|
|
916
920
|
try {
|
|
917
|
-
stat = await fs.promises.stat(entry.file);
|
|
921
|
+
stat = await fs.promises.stat(entry.file, { bigint: true });
|
|
918
922
|
real = await fs.promises.realpath(entry.file);
|
|
919
923
|
} catch (error) {
|
|
920
924
|
throw new URIError(
|
|
@@ -1086,10 +1090,12 @@ export namespace TypiaGenerateWizard {
|
|
|
1086
1090
|
);
|
|
1087
1091
|
}
|
|
1088
1092
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
+
/**
|
|
1094
|
+
* Delegates to {@link FileSystemIdentity.identityKey}, which owns the rule and
|
|
1095
|
+
* carries the reasoning for reading the identity as a `bigint`.
|
|
1096
|
+
*/
|
|
1097
|
+
function fileIdentityKey(stat: fs.BigIntStats, realpath: string): string {
|
|
1098
|
+
return FileSystemIdentity.identityKey(stat, realpath);
|
|
1093
1099
|
}
|
|
1094
1100
|
|
|
1095
1101
|
function formatDiagnostics(diagnostics: ITtscCompilerDiagnostic[]): string {
|
package/src/http.ts
CHANGED
|
@@ -550,10 +550,16 @@ export function createAssertFormData(
|
|
|
550
550
|
*/
|
|
551
551
|
export function createAssertFormData<T extends object>(
|
|
552
552
|
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
553
|
-
): (
|
|
553
|
+
): (
|
|
554
|
+
input: FormData,
|
|
555
|
+
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
556
|
+
) => T;
|
|
554
557
|
|
|
555
558
|
/** @internal */
|
|
556
|
-
export function createAssertFormData<T>(): (
|
|
559
|
+
export function createAssertFormData<T>(): (
|
|
560
|
+
input: FormData,
|
|
561
|
+
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
562
|
+
) => T {
|
|
557
563
|
NoTransformConfigurationError("http.createAssertFormData");
|
|
558
564
|
}
|
|
559
565
|
|
|
@@ -652,11 +658,15 @@ export function createAssertQuery(
|
|
|
652
658
|
*/
|
|
653
659
|
export function createAssertQuery<T extends object>(
|
|
654
660
|
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
655
|
-
): (
|
|
661
|
+
): (
|
|
662
|
+
input: string | IReadableURLSearchParams,
|
|
663
|
+
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
664
|
+
) => T;
|
|
656
665
|
|
|
657
666
|
/** @internal */
|
|
658
667
|
export function createAssertQuery<T>(): (
|
|
659
668
|
input: string | IReadableURLSearchParams,
|
|
669
|
+
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
660
670
|
) => T {
|
|
661
671
|
NoTransformConfigurationError("http.createAssertQuery");
|
|
662
672
|
}
|
|
@@ -758,11 +768,15 @@ export function createAssertHeaders(
|
|
|
758
768
|
*/
|
|
759
769
|
export function createAssertHeaders<T extends object>(
|
|
760
770
|
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
761
|
-
): (
|
|
771
|
+
): (
|
|
772
|
+
input: Record<string, string | string[] | undefined>,
|
|
773
|
+
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
774
|
+
) => T;
|
|
762
775
|
|
|
763
776
|
/** @internal */
|
|
764
777
|
export function createAssertHeaders<T>(): (
|
|
765
778
|
input: Record<string, string | string[] | undefined>,
|
|
779
|
+
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
|
|
766
780
|
) => T {
|
|
767
781
|
NoTransformConfigurationError("http.createAssertHeaders");
|
|
768
782
|
}
|
|
@@ -110,15 +110,19 @@ export class _ProtobufReader {
|
|
|
110
110
|
* Advance by exactly one varint, which carries no length prefix.
|
|
111
111
|
*
|
|
112
112
|
* A varint terminates at its first byte without the continuation bit, and may
|
|
113
|
-
* occupy no more than {@link VARINT_MAX_BYTES}.
|
|
114
|
-
*
|
|
115
|
-
*
|
|
113
|
+
* occupy no more than {@link VARINT_MAX_BYTES}. Its tenth byte is bounded
|
|
114
|
+
* twice over, by {@link lastVarintByte}: it may neither continue into an
|
|
115
|
+
* eleventh byte nor carry payload above bit 63. Skipping is where that is
|
|
116
|
+
* easiest to get wrong, because this path discards the bytes it reads and so
|
|
117
|
+
* never notices a value it could not have represented. Relaxing either bound
|
|
118
|
+
* here would accept a varint that `varint32` and `varint64` reject, making
|
|
119
|
+
* the limit depend on which method happens to consume the value.
|
|
116
120
|
*/
|
|
117
121
|
public skipVarint(): void {
|
|
118
122
|
this.atomic(() => {
|
|
119
|
-
for (let i: number =
|
|
123
|
+
for (let i: number = 1; i < VARINT_MAX_BYTES; ++i)
|
|
120
124
|
if ((this.u8() & 0x80) === 0) return;
|
|
121
|
-
|
|
125
|
+
this.lastVarintByte();
|
|
122
126
|
});
|
|
123
127
|
}
|
|
124
128
|
|
|
@@ -172,8 +176,7 @@ export class _ProtobufReader {
|
|
|
172
176
|
if (this.u8() < 0x80) return value;
|
|
173
177
|
if (this.u8() < 0x80) return value;
|
|
174
178
|
if (this.u8() < 0x80) return value;
|
|
175
|
-
|
|
176
|
-
|
|
179
|
+
this.lastVarintByte();
|
|
177
180
|
return value;
|
|
178
181
|
}
|
|
179
182
|
|
|
@@ -208,10 +211,28 @@ export class _ProtobufReader {
|
|
|
208
211
|
value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(56);
|
|
209
212
|
if (loaded < BigInt(0x80)) return value;
|
|
210
213
|
|
|
211
|
-
value |= (this.
|
|
214
|
+
value |= BigInt(this.lastVarintByte()) << BigInt(63);
|
|
212
215
|
return BigInt.asUintN(64, value);
|
|
213
216
|
}
|
|
214
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Read the only byte whose varint payload is limited to bit 63.
|
|
220
|
+
*
|
|
221
|
+
* Two distinct faults meet on this byte, and each is named for what it is. A
|
|
222
|
+
* continuation bit means the varint would occupy an eleventh byte, which no
|
|
223
|
+
* 64-bit value can reach. Any other payload bit means the varint terminates
|
|
224
|
+
* within its ten bytes but carries a value bit above 63. Reporting the second
|
|
225
|
+
* as a length fault would tell the caller something untrue about a payload
|
|
226
|
+
* that is exactly ten bytes long.
|
|
227
|
+
*/
|
|
228
|
+
private lastVarintByte(): number {
|
|
229
|
+
const loaded: number = this.u8();
|
|
230
|
+
if ((loaded & 0x80) !== 0)
|
|
231
|
+
throw error(`varint exceeds ${VARINT_MAX_BYTES} bytes.`);
|
|
232
|
+
if (loaded > 0x01) throw error(`varint exceeds ${VARINT_MAX_BITS} bits.`);
|
|
233
|
+
return loaded;
|
|
234
|
+
}
|
|
235
|
+
|
|
215
236
|
private u8(): number {
|
|
216
237
|
return this.view.getUint8(this.take(1));
|
|
217
238
|
}
|
|
@@ -262,12 +283,20 @@ const error = (message: string): Error =>
|
|
|
262
283
|
/**
|
|
263
284
|
* The most bytes a varint may occupy: a 64-bit value in seven-bit groups.
|
|
264
285
|
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* holds it by.
|
|
286
|
+
* Every path reads no further than its tenth byte and accepts only bit 63 from
|
|
287
|
+
* that byte. This constant keeps the loop-driven skip path on the same limit.
|
|
268
288
|
*/
|
|
269
289
|
const VARINT_MAX_BYTES = 10;
|
|
270
290
|
|
|
291
|
+
/**
|
|
292
|
+
* The widest value a varint may carry: the 64-bit Protocol Buffer wire domain.
|
|
293
|
+
*
|
|
294
|
+
* The tenth byte reaches only bit 63, so a payload bit above it belongs to no
|
|
295
|
+
* representable value. This names the overflow fault apart from the length
|
|
296
|
+
* one.
|
|
297
|
+
*/
|
|
298
|
+
const VARINT_MAX_BITS = 64;
|
|
299
|
+
|
|
271
300
|
const utf8 = new Singleton(
|
|
272
301
|
() => new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }),
|
|
273
302
|
);
|
|
@@ -6,8 +6,19 @@ export const _assertGuard = (
|
|
|
6
6
|
factory?: (props: TypeGuardError.IProps) => Error,
|
|
7
7
|
): false => {
|
|
8
8
|
if (exceptionable === true) {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// `factory` arrives from the generated function's second parameter, which
|
|
10
|
+
// a pointwise hand-off fills with something that is not a factory at all:
|
|
11
|
+
// `rows.map(assertUser)` passes the element index. A truthiness test then
|
|
12
|
+
// called a number and reported `factory is not a function`, hiding the
|
|
13
|
+
// real assertion failure — and only for indices other than 0. Require a
|
|
14
|
+
// callable, and fall back to TypeGuardError for everything else.
|
|
15
|
+
//
|
|
16
|
+
// A create-time factory is the default of that same parameter, so a
|
|
17
|
+
// non-callable argument has already overridden it by the time this runs
|
|
18
|
+
// and cannot be recovered here. TypeGuardError still names the property
|
|
19
|
+
// that failed, which `factory is not a function` never did.
|
|
20
|
+
if (typeof factory === "function") throw factory(props);
|
|
21
|
+
throw new TypeGuardError(props);
|
|
11
22
|
}
|
|
12
23
|
return false;
|
|
13
24
|
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export const _isFormatIdnHostname = (str: string): boolean => PATTERN.test(str);
|
|
2
2
|
|
|
3
|
+
// The ASCII `hostname` structure with the label character class extended by the
|
|
4
|
+
// non-ASCII range: every valid host name is a valid IDN host name, so this must
|
|
5
|
+
// accept a single label, a one-to-63-character label in any position, and a
|
|
6
|
+
// name up to 253 characters, exactly as `_isFormatHostname` does (issue #2317).
|
|
3
7
|
const PATTERN =
|
|
4
|
-
/^([a-z0-9\u00a1-\
|
|
8
|
+
/^(?=.{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;
|
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
export const _isFormatTime = (str: string): boolean =>
|
|
1
|
+
export const _isFormatTime = (str: string): boolean => {
|
|
2
|
+
const match: RegExpExecArray | null = PATTERN.exec(str);
|
|
3
|
+
if (match === null) return false;
|
|
4
|
+
if (match[3] !== "60") return true;
|
|
5
|
+
|
|
6
|
+
// RFC 3339 admits `:60` only where a leap second is inserted, which is
|
|
7
|
+
// always 23:59:60 UTC. `date-time` decides that from the instant it can
|
|
8
|
+
// build; a clock carries no date, so it shifts itself by its own offset and
|
|
9
|
+
// asks the same question, wrapping the result back into the day.
|
|
10
|
+
const offset: number =
|
|
11
|
+
match[4] === undefined
|
|
12
|
+
? 0
|
|
13
|
+
: (match[4] === "+" ? 1 : -1) *
|
|
14
|
+
(Number(match[5]) * 60 + Number(match[6]));
|
|
15
|
+
const minutes: number = Number(match[1]) * 60 + Number(match[2]) - offset;
|
|
16
|
+
return ((minutes % DAY) + DAY) % DAY === DAY - 1;
|
|
17
|
+
};
|
|
2
18
|
|
|
3
19
|
const PATTERN =
|
|
4
|
-
/^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]
|
|
20
|
+
/^([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]))$/;
|
|
21
|
+
const DAY = 24 * 60;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializes the elements of an array the way ECMAScript `JSON.stringify` does.
|
|
3
|
+
*
|
|
4
|
+
* `SerializeJSONArray` walks index `0` to `LengthOfArrayLike(value) - 1` and
|
|
5
|
+
* writes `null` wherever the element serializes to `undefined`. Neither
|
|
6
|
+
* `Array.prototype.map` nor `Array.prototype.join` reproduces that:
|
|
7
|
+
*
|
|
8
|
+
* - `map` never visits a hole and leaves one behind, and `join` renders a hole as
|
|
9
|
+
* empty text, so a sparse array joined into malformed text such as `[,1]`. A
|
|
10
|
+
* hole exists at runtime whatever the element type declares, so this is not
|
|
11
|
+
* an `any` concern.
|
|
12
|
+
* - `join` renders a mapped `undefined` as empty text too, which is what an `any`
|
|
13
|
+
* or `unknown` element holding a function, a symbol, or a `toJSON` that
|
|
14
|
+
* returns nothing serializes to.
|
|
15
|
+
*
|
|
16
|
+
* The length is converted with `ToLength` and read once, which is both what
|
|
17
|
+
* `JSON.stringify` does and what `Array.prototype.every` - the traversal
|
|
18
|
+
* typia's own array checkers emit - does, so the checker and the serializer
|
|
19
|
+
* walk one index range rather than two that merely usually coincide.
|
|
20
|
+
*
|
|
21
|
+
* @param elements Array being serialized.
|
|
22
|
+
* @param mapper Serializer of one element, emitted by the transform.
|
|
23
|
+
* @returns Comma separated element text, without the enclosing brackets.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export const _jsonStringifyArray = <T>(
|
|
27
|
+
elements: ArrayLike<T>,
|
|
28
|
+
mapper: (elem: T, index: number) => string,
|
|
29
|
+
): string => {
|
|
30
|
+
const length: number = Math.min(
|
|
31
|
+
Math.max(Math.trunc(elements.length) || 0, 0),
|
|
32
|
+
Number.MAX_SAFE_INTEGER,
|
|
33
|
+
);
|
|
34
|
+
let output: string = "";
|
|
35
|
+
for (let i: number = 0; i < length; ++i) {
|
|
36
|
+
const elem: T | undefined = elements[i];
|
|
37
|
+
// A hole and an explicit `undefined` are answered without calling the
|
|
38
|
+
// mapper, because the mapper is the element type's own serializer and a
|
|
39
|
+
// typed one has no answer for a missing value. Everything else is answered
|
|
40
|
+
// from the mapper's *result*: an element that is present but serializes to
|
|
41
|
+
// nothing — a function, a symbol, or a `toJSON` returning nothing in an
|
|
42
|
+
// `any` slot — is `null` in an array position, exactly as
|
|
43
|
+
// SerializeJSONArray specifies, and testing the input instead would let its
|
|
44
|
+
// text become the literal `undefined`.
|
|
45
|
+
const text: string | undefined =
|
|
46
|
+
elem === undefined ? undefined : mapper(elem, i);
|
|
47
|
+
output += (i === 0 ? "" : ",") + (text === undefined ? "null" : text);
|
|
48
|
+
}
|
|
49
|
+
return output;
|
|
50
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writes one array or tuple element the way ECMAScript `JSON.stringify` writes
|
|
3
|
+
* it.
|
|
4
|
+
*
|
|
5
|
+
* `SerializeJSONArray` writes `null` wherever an element serializes to
|
|
6
|
+
* `undefined`, because an array position cannot be omitted without shifting
|
|
7
|
+
* every element after it. A present value with no serialization — a function, a
|
|
8
|
+
* symbol, or a `toJSON` returning nothing — is therefore `null`, not the
|
|
9
|
+
* literal text `undefined` and not an empty slot.
|
|
10
|
+
*
|
|
11
|
+
* This is the fixed-position counterpart of `_jsonStringifyArray`, which
|
|
12
|
+
* answers the same question while walking an array's own index range.
|
|
13
|
+
*
|
|
14
|
+
* @param text Serialized element value, or `undefined` when it has none.
|
|
15
|
+
* @returns Element text, or `null` when the element has no serialization.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export const _jsonStringifyElement = (text: string | undefined): string =>
|
|
19
|
+
text === undefined ? "null" : text;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writes one object member the way ECMAScript `JSON.stringify` writes it.
|
|
3
|
+
*
|
|
4
|
+
* `SerializeJSONObject` serializes each member first and drops the member
|
|
5
|
+
* entirely when that result is `undefined`. Deciding omission from the _input_
|
|
6
|
+
* instead cannot reach the same answer: a symbol and a `toJSON` returning
|
|
7
|
+
* nothing are both present, non-`undefined`, non-function values whose
|
|
8
|
+
* serialization is `undefined`, so the member's text became the literal
|
|
9
|
+
* `"k":undefined` — output that is not JSON at all.
|
|
10
|
+
*
|
|
11
|
+
* The serialized text is passed in already evaluated, so the member's value is
|
|
12
|
+
* serialized exactly once. Testing the input and then serializing would
|
|
13
|
+
* evaluate a `toJSON` twice, and a `toJSON` is free to answer differently each
|
|
14
|
+
* call.
|
|
15
|
+
*
|
|
16
|
+
* The trailing separator belongs to the member because a dropped member must
|
|
17
|
+
* take its comma with it; `_jsonStringifyTail` removes the one that is left
|
|
18
|
+
* behind when the last written member is the one that dropped.
|
|
19
|
+
*
|
|
20
|
+
* @param head Quoted key and colon, emitted by the transform.
|
|
21
|
+
* @param text Serialized member value, or `undefined` when it has none.
|
|
22
|
+
* @param tail Separator following this member, empty for the last one.
|
|
23
|
+
* @returns Member text, or an empty string when the member is omitted.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export const _jsonStringifyProperty = (
|
|
27
|
+
head: string,
|
|
28
|
+
text: string | undefined,
|
|
29
|
+
tail: string,
|
|
30
|
+
): string => (text === undefined ? "" : head + text + tail);
|
|
@@ -7,7 +7,12 @@ export const _llmApplicationFinalize = <Class extends object = any>(
|
|
|
7
7
|
): ILlmApplication<Class> => ({
|
|
8
8
|
...app,
|
|
9
9
|
config: {
|
|
10
|
-
|
|
10
|
+
// The schema configuration comes from the emitted application, which is
|
|
11
|
+
// where the `Config` generic was resolved. Rebuilding it from the
|
|
12
|
+
// converter's defaults reported `strict: false` for a strict build, and
|
|
13
|
+
// `@typia/mcp` then inverted a strict output schema without strict, which
|
|
14
|
+
// drops every constraint it carries as a description tag (issue #2293).
|
|
15
|
+
...LlmSchemaConverter.getConfig(app.config),
|
|
11
16
|
validate: config?.validate ?? null,
|
|
12
17
|
},
|
|
13
18
|
functions: app.functions.map((func) => ({
|
|
@@ -7,6 +7,16 @@ const DEFAULT_MIN_ITEMS = 1;
|
|
|
7
7
|
const DEFAULT_RANGE = 5;
|
|
8
8
|
const DEFAULT_RECURSIVE_RANGE = 2;
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Consecutive duplicates that end a unique draw once its floor is satisfied.
|
|
12
|
+
*
|
|
13
|
+
* The worst case a domain can still hide is one value left among a handful:
|
|
14
|
+
* with one of four remaining, sixty-four misses in a row is a `0.75 ** 64`
|
|
15
|
+
* event, about one in a hundred million. Below the floor this limit does not
|
|
16
|
+
* apply at all, so it can never fail a request the domain could satisfy.
|
|
17
|
+
*/
|
|
18
|
+
const STALE_LIMIT = 64;
|
|
19
|
+
|
|
10
20
|
export const _randomArray = <T>(
|
|
11
21
|
props: Omit<OpenApi.IJsonSchema.IArray, "items"> & {
|
|
12
22
|
element: (index: number, count: number) => T;
|
|
@@ -28,16 +38,42 @@ export const _randomArray = <T>(
|
|
|
28
38
|
});
|
|
29
39
|
if (props.uniqueItems !== true)
|
|
30
40
|
return new Array(count).fill(null).map((_, i) => props.element(i, count));
|
|
41
|
+
// How many distinct values the element can take is not knowable from here --
|
|
42
|
+
// `element` is a closure over whatever the transform emitted, from `boolean`
|
|
43
|
+
// to a recursive object -- so the count above is a preference, not a
|
|
44
|
+
// contract. Draw until the budget says the domain has nothing new left, then
|
|
45
|
+
// keep what was reached.
|
|
46
|
+
//
|
|
47
|
+
// Failing on that budget instead is what made `Array<boolean> &
|
|
48
|
+
// UniqueItems` throw on two draws in three: `[true, false]` satisfies the
|
|
49
|
+
// declaration at every count, and a count of five is unreachable for a
|
|
50
|
+
// domain of two however many times it is redrawn. Only a result below the
|
|
51
|
+
// floor is a real failure, which is still the honest outcome for a window
|
|
52
|
+
// like `MinItems<3>` over a domain of two.
|
|
53
|
+
//
|
|
54
|
+
// Below the floor the whole budget is spent, because stopping early there
|
|
55
|
+
// would fail a request the domain can still satisfy. Above it every further
|
|
56
|
+
// attempt is only buying length, so a run of `STALE_LIMIT` duplicates is
|
|
57
|
+
// taken as the domain saying it has nothing left. Without that, each nesting
|
|
58
|
+
// level of a small-domain unique array multiplies the full budget into the
|
|
59
|
+
// level above it.
|
|
31
60
|
const elements: T[] = [];
|
|
32
61
|
const maximumAttempts: number = count * 100 + 1000;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
62
|
+
let stale: number = 0;
|
|
63
|
+
for (
|
|
64
|
+
let attempts = 0;
|
|
65
|
+
elements.length !== count && attempts !== maximumAttempts;
|
|
66
|
+
attempts++
|
|
67
|
+
) {
|
|
38
68
|
const candidate: T = props.element(elements.length, count);
|
|
39
|
-
if (elements.every((element) => _isUniqueItems([element, candidate])))
|
|
69
|
+
if (elements.every((element) => _isUniqueItems([element, candidate]))) {
|
|
40
70
|
elements.push(candidate);
|
|
71
|
+
stale = 0;
|
|
72
|
+
} else if (elements.length >= minimum && ++stale === STALE_LIMIT) break;
|
|
41
73
|
}
|
|
74
|
+
if (elements.length < minimum)
|
|
75
|
+
throw new Error(
|
|
76
|
+
"Unable to generate enough unique items; the element domain may be too small.",
|
|
77
|
+
);
|
|
42
78
|
return elements;
|
|
43
79
|
};
|
|
@@ -1,6 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _randomInteger } from "./_randomInteger";
|
|
2
|
+
import {
|
|
3
|
+
_ILengthProps,
|
|
4
|
+
_RANDOM_LENGTH_ERROR,
|
|
5
|
+
_randomLengthPick,
|
|
6
|
+
_randomLengthWindow,
|
|
7
|
+
} from "./_randomStringLength";
|
|
8
|
+
import { __randomBase64 } from "./private/__randomComposition";
|
|
2
9
|
|
|
3
|
-
export const _randomFormatByte = (props?: _ILengthProps): string =>
|
|
4
|
-
|
|
10
|
+
export const _randomFormatByte = (props?: _ILengthProps): string => {
|
|
11
|
+
// Base64 encodes three bytes as four characters, so a valid length is always
|
|
12
|
+
// a multiple of four; an unconstrained draw spends between four and twelve
|
|
13
|
+
// groups, and a constrained one raises the window to the first multiple it
|
|
14
|
+
// contains and steps by four from there.
|
|
15
|
+
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
16
|
+
return __randomBase64(
|
|
17
|
+
4 *
|
|
18
|
+
_randomInteger({
|
|
19
|
+
type: "integer",
|
|
20
|
+
minimum: DEFAULT_GROUP_MIN,
|
|
21
|
+
maximum: DEFAULT_GROUP_MAX,
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
const window = _randomLengthWindow(props, { minimum: 0, spread: 16 });
|
|
25
|
+
const low: number = Math.ceil(window.low / 4) * 4;
|
|
26
|
+
if (low > window.high) throw new Error(_RANDOM_LENGTH_ERROR);
|
|
27
|
+
const length: number =
|
|
28
|
+
low +
|
|
29
|
+
4 *
|
|
30
|
+
_randomLengthPick({
|
|
31
|
+
low: 0,
|
|
32
|
+
high: Math.floor((window.high - low) / 4),
|
|
33
|
+
});
|
|
34
|
+
return __randomBase64(length);
|
|
35
|
+
};
|
|
5
36
|
|
|
6
|
-
const
|
|
37
|
+
const DEFAULT_GROUP_MIN = 4;
|
|
38
|
+
const DEFAULT_GROUP_MAX = 12;
|
|
@@ -1,23 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { _ILengthProps, _randomFormatLength } from "./_randomStringLength";
|
|
2
|
+
import { __IEpochProps, __randomEpoch } from "./private/__randomEpoch";
|
|
3
3
|
|
|
4
|
-
export const _randomFormatDate = (props?:
|
|
5
|
-
minimum?: number;
|
|
6
|
-
maximum?: number;
|
|
7
|
-
minLength?: number;
|
|
8
|
-
maxLength?: number;
|
|
9
|
-
}) =>
|
|
4
|
+
export const _randomFormatDate = (props?: __IEpochProps & _ILengthProps) =>
|
|
10
5
|
_randomFormatLength(props, () =>
|
|
11
|
-
new Date(
|
|
12
|
-
_randomInteger({
|
|
13
|
-
type: "integer",
|
|
14
|
-
minimum: props?.minimum ?? 0,
|
|
15
|
-
maximum:
|
|
16
|
-
(props?.maximum ?? props?.minimum === undefined)
|
|
17
|
-
? Date.now()
|
|
18
|
-
: props.minimum + 365 * 24 * 60 * 60 * 1_000,
|
|
19
|
-
}),
|
|
20
|
-
)
|
|
21
|
-
.toISOString()
|
|
22
|
-
.substring(0, 10),
|
|
6
|
+
new Date(__randomEpoch(props)).toISOString().substring(0, 10),
|
|
23
7
|
);
|