typia 13.1.19 → 13.2.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/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/_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/_randomFormatByte.js +24 -1
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +20 -2
- 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/_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 +14 -1
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +14 -2
- 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 +33 -7
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +37 -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 +23 -0
- package/lib/internal/private/__randomComposition.js +48 -0
- package/lib/internal/private/__randomComposition.js.map +1 -0
- package/lib/internal/private/__randomComposition.mjs +54 -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/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/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/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/symbol_index_domain_transform_test.go +316 -0
- package/native/cmd/ttsc-typia/transform.go +23 -0
- package/native/cmd/ttsc-typia/transform_helpers_test.go +77 -2
- package/native/cmd/ttsc-typia/user_global_native_identity_transform_test.go +484 -0
- package/native/core/factories/ProtobufFactory.go +6 -1
- package/native/core/factories/internal/metadata/MetadataHelper.go +185 -30
- 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/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 +0 -9
- 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/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/internal/_ProtobufReader.ts +40 -11
- 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/_randomFormatByte.ts +30 -3
- package/src/internal/_randomFormatDate.ts +4 -20
- package/src/internal/_randomFormatDatetime.ts +34 -20
- package/src/internal/_randomFormatDuration.ts +19 -4
- 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 +21 -3
- package/src/internal/_randomFormatRelativeJsonPointer.ts +23 -10
- package/src/internal/_randomFormatTime.ts +45 -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 +50 -0
- package/src/internal/private/__randomEpoch.ts +34 -0
- 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
|
@@ -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) => ({
|
|
@@ -1,6 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _randomString } from "./_randomString";
|
|
2
|
+
import {
|
|
3
|
+
_ILengthProps,
|
|
4
|
+
_RANDOM_LENGTH_ERROR,
|
|
5
|
+
_randomLengthPick,
|
|
6
|
+
_randomLengthWindow,
|
|
7
|
+
} from "./_randomStringLength";
|
|
2
8
|
|
|
3
|
-
export const _randomFormatByte = (props?: _ILengthProps): string =>
|
|
4
|
-
|
|
9
|
+
export const _randomFormatByte = (props?: _ILengthProps): string => {
|
|
10
|
+
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
11
|
+
return FIXED;
|
|
12
|
+
// Base64 encodes three bytes as four characters, so a valid length is always
|
|
13
|
+
// a multiple of four; the window is raised to the first multiple it contains
|
|
14
|
+
// and the draw steps by four from there. Every character `_randomString`
|
|
15
|
+
// emits is in the base64 alphabet, so the result needs no padding.
|
|
16
|
+
const window = _randomLengthWindow(props, { minimum: 0, spread: 16 });
|
|
17
|
+
const low: number = Math.ceil(window.low / 4) * 4;
|
|
18
|
+
if (low > window.high) throw new Error(_RANDOM_LENGTH_ERROR);
|
|
19
|
+
const length: number =
|
|
20
|
+
low +
|
|
21
|
+
4 *
|
|
22
|
+
_randomLengthPick({
|
|
23
|
+
low: 0,
|
|
24
|
+
high: Math.floor((window.high - low) / 4),
|
|
25
|
+
});
|
|
26
|
+
return _randomString({
|
|
27
|
+
type: "string",
|
|
28
|
+
minLength: length,
|
|
29
|
+
maxLength: length,
|
|
30
|
+
});
|
|
31
|
+
};
|
|
5
32
|
|
|
6
33
|
const FIXED = "vt7ekz4lIoNTTS9sDQYdWKharxIFAR54+z/umIxSgUM=";
|
|
@@ -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
|
);
|
|
@@ -1,21 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
_ILengthProps,
|
|
3
|
+
_RANDOM_LENGTH_ERROR,
|
|
4
|
+
_randomLengthPick,
|
|
5
|
+
_randomLengthWindow,
|
|
6
|
+
} from "./_randomStringLength";
|
|
7
|
+
import { __randomDigits } from "./private/__randomComposition";
|
|
8
|
+
import { __IEpochProps, __randomEpoch } from "./private/__randomEpoch";
|
|
3
9
|
|
|
4
|
-
export const _randomFormatDatetime = (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
maxLength
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
)
|
|
10
|
+
export const _randomFormatDatetime = (
|
|
11
|
+
props?: __IEpochProps & _ILengthProps,
|
|
12
|
+
) => {
|
|
13
|
+
const instant = (): string => new Date(__randomEpoch(props)).toISOString();
|
|
14
|
+
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
15
|
+
return instant();
|
|
16
|
+
// `YYYY-MM-DDTHH:MM:SS` plus `Z` is the shortest instant, and a fractional
|
|
17
|
+
// second grows it one digit at a time. Because that fraction needs both a dot
|
|
18
|
+
// and at least one digit, 21 is the single length between the two forms that
|
|
19
|
+
// no instant can have.
|
|
20
|
+
const window = _randomLengthWindow(props, {
|
|
21
|
+
minimum: SECONDS + 1,
|
|
22
|
+
spread: 8,
|
|
23
|
+
});
|
|
24
|
+
let length: number = _randomLengthPick(window);
|
|
25
|
+
if (length === SECONDS + 2)
|
|
26
|
+
length = window.high >= SECONDS + 3 ? SECONDS + 3 : SECONDS + 1;
|
|
27
|
+
if (length < window.low || length > window.high)
|
|
28
|
+
throw new Error(_RANDOM_LENGTH_ERROR);
|
|
29
|
+
const base: string = instant().substring(0, SECONDS);
|
|
30
|
+
return length === SECONDS + 1
|
|
31
|
+
? `${base}Z`
|
|
32
|
+
: `${base}.${__randomDigits(length - SECONDS - 2)}Z`;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const SECONDS = "0000-00-00T00:00:00".length;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { _randomInteger } from "./_randomInteger";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
_ILengthProps,
|
|
4
|
+
_randomLengthPick,
|
|
5
|
+
_randomLengthWindow,
|
|
6
|
+
} from "./_randomStringLength";
|
|
7
|
+
import { __randomNumeric } from "./private/__randomComposition";
|
|
3
8
|
|
|
4
|
-
export const _randomFormatDuration = (props?: _ILengthProps): string =>
|
|
5
|
-
|
|
9
|
+
export const _randomFormatDuration = (props?: _ILengthProps): string => {
|
|
10
|
+
if (props?.minLength === undefined && props?.maxLength === undefined) {
|
|
6
11
|
const period: string = durate([
|
|
7
12
|
["Y", random(0, 100)],
|
|
8
13
|
["M", random(0, 12)],
|
|
@@ -15,7 +20,17 @@ export const _randomFormatDuration = (props?: _ILengthProps): string =>
|
|
|
15
20
|
]);
|
|
16
21
|
if (period.length + time.length === 0) return "PT0S";
|
|
17
22
|
return `P${period}${time.length ? "T" : ""}${time}`;
|
|
18
|
-
}
|
|
23
|
+
}
|
|
24
|
+
// A single designator carries an unbounded digit count, so `P<n>Y` expresses
|
|
25
|
+
// every length from three upward and `P1Y` is the shortest duration there is.
|
|
26
|
+
const length: number = _randomLengthPick(
|
|
27
|
+
_randomLengthWindow(props, { minimum: MINIMUM, spread: 6 }),
|
|
28
|
+
);
|
|
29
|
+
return `P${__randomNumeric(length - MINIMUM + 1)}Y`;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const MINIMUM = "P1Y".length;
|
|
33
|
+
|
|
19
34
|
const durate = (elements: [string, number][]) =>
|
|
20
35
|
elements
|
|
21
36
|
.filter(([_unit, value]) => value !== 0)
|
|
@@ -1,8 +1,37 @@
|
|
|
1
1
|
import { _randomInteger } from "./_randomInteger";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
_ILengthProps,
|
|
4
|
+
_randomLengthPick,
|
|
5
|
+
_randomLengthWindow,
|
|
6
|
+
} from "./_randomStringLength";
|
|
7
|
+
import { __randomComposition } from "./private/__randomComposition";
|
|
3
8
|
|
|
4
|
-
export const _randomFormatIpv4 = (props?: _ILengthProps): string =>
|
|
5
|
-
|
|
9
|
+
export const _randomFormatIpv4 = (props?: _ILengthProps): string => {
|
|
10
|
+
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
11
|
+
return new Array(4).fill(0).map(random).join(".");
|
|
12
|
+
// Three dots plus four octets of one to three digits: `0.0.0.0` is the
|
|
13
|
+
// shortest address and `255.255.255.255` the longest, and every length
|
|
14
|
+
// between them is reached by choosing how many digits each octet spends.
|
|
15
|
+
const length: number = _randomLengthPick(
|
|
16
|
+
_randomLengthWindow(props, {
|
|
17
|
+
minimum: 4 * DIGITS_MIN + DOTS,
|
|
18
|
+
maximum: 4 * DIGITS_MAX + DOTS,
|
|
19
|
+
spread: 8,
|
|
20
|
+
}),
|
|
21
|
+
);
|
|
22
|
+
return __randomComposition({
|
|
23
|
+
total: length - DOTS,
|
|
24
|
+
count: 4,
|
|
25
|
+
minimum: DIGITS_MIN,
|
|
26
|
+
maximum: DIGITS_MAX,
|
|
27
|
+
})
|
|
28
|
+
.map(octet)
|
|
29
|
+
.join(".");
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const DOTS = 3;
|
|
33
|
+
const DIGITS_MIN = 1;
|
|
34
|
+
const DIGITS_MAX = 3;
|
|
6
35
|
|
|
7
36
|
const random = () =>
|
|
8
37
|
_randomInteger({
|
|
@@ -10,3 +39,14 @@ const random = () =>
|
|
|
10
39
|
minimum: 0,
|
|
11
40
|
maximum: 255,
|
|
12
41
|
});
|
|
42
|
+
|
|
43
|
+
// An octet is bounded by 255, so a three-digit one starts at 100 and stops
|
|
44
|
+
// there rather than at 999.
|
|
45
|
+
const octet = (digits: number): string =>
|
|
46
|
+
String(
|
|
47
|
+
_randomInteger({
|
|
48
|
+
type: "integer",
|
|
49
|
+
minimum: digits === 1 ? 0 : Math.pow(10, digits - 1),
|
|
50
|
+
maximum: digits === 3 ? 255 : Math.pow(10, digits) - 1,
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
@@ -1,8 +1,61 @@
|
|
|
1
|
+
import { _randomFormatIpv4 } from "./_randomFormatIpv4";
|
|
1
2
|
import { _randomInteger } from "./_randomInteger";
|
|
2
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
_ILengthProps,
|
|
5
|
+
_randomLengthPick,
|
|
6
|
+
_randomLengthWindow,
|
|
7
|
+
} from "./_randomStringLength";
|
|
8
|
+
import { __randomComposition } from "./private/__randomComposition";
|
|
3
9
|
|
|
4
|
-
export const _randomFormatIpv6 = (props?: _ILengthProps): string =>
|
|
5
|
-
|
|
10
|
+
export const _randomFormatIpv6 = (props?: _ILengthProps): string => {
|
|
11
|
+
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
12
|
+
return new Array(GROUPS).fill(0).map(random).join(":");
|
|
13
|
+
const length: number = _randomLengthPick(
|
|
14
|
+
_randomLengthWindow(props, {
|
|
15
|
+
minimum: SHORTEST,
|
|
16
|
+
maximum: LONGEST,
|
|
17
|
+
spread: 12,
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
// `::` alone is the all-zero address, and the three forms below cover every
|
|
21
|
+
// length between it and the padded IPv4-suffixed address: a compressed prefix
|
|
22
|
+
// for the short ones, eight groups of one to four hexadecimal digits for the
|
|
23
|
+
// middle, and six groups plus a dotted-quad tail for the long ones.
|
|
24
|
+
if (length === SHORTEST) return "::";
|
|
25
|
+
if (length < GROUPS * DIGITS_MIN + COLONS) {
|
|
26
|
+
// `::` plus `count` groups spends one colon between each pair.
|
|
27
|
+
const count: number = Math.ceil((length - 1) / (DIGITS_MAX + 1));
|
|
28
|
+
return `::${compose(length - 1 - count, count)}`;
|
|
29
|
+
}
|
|
30
|
+
if (length <= GROUPS * DIGITS_MAX + COLONS)
|
|
31
|
+
return compose(length - COLONS, GROUPS);
|
|
32
|
+
// The dotted-quad tail is drawn at its longest so the six leading groups keep
|
|
33
|
+
// a composable number of digits.
|
|
34
|
+
const tail: string = _randomFormatIpv4({
|
|
35
|
+
minLength: IPV4_MAX,
|
|
36
|
+
maxLength: IPV4_MAX,
|
|
37
|
+
});
|
|
38
|
+
return `${compose(length - IPV4_MAX - EMBEDDED, EMBEDDED)}:${tail}`;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const GROUPS = 8;
|
|
42
|
+
const COLONS = GROUPS - 1;
|
|
43
|
+
const DIGITS_MIN = 1;
|
|
44
|
+
const DIGITS_MAX = 4;
|
|
45
|
+
const EMBEDDED = 6; // groups preceding a dotted-quad tail
|
|
46
|
+
const IPV4_MAX = "255.255.255.255".length;
|
|
47
|
+
const SHORTEST = "::".length;
|
|
48
|
+
const LONGEST = EMBEDDED * DIGITS_MAX + EMBEDDED + IPV4_MAX;
|
|
49
|
+
|
|
50
|
+
const compose = (digits: number, count: number): string =>
|
|
51
|
+
__randomComposition({
|
|
52
|
+
total: digits,
|
|
53
|
+
count,
|
|
54
|
+
minimum: DIGITS_MIN,
|
|
55
|
+
maximum: DIGITS_MAX,
|
|
56
|
+
})
|
|
57
|
+
.map(group)
|
|
58
|
+
.join(":");
|
|
6
59
|
|
|
7
60
|
const random = () =>
|
|
8
61
|
_randomInteger({
|
|
@@ -10,3 +63,14 @@ const random = () =>
|
|
|
10
63
|
minimum: 0,
|
|
11
64
|
maximum: 65_535,
|
|
12
65
|
}).toString(16);
|
|
66
|
+
|
|
67
|
+
const group = (digits: number): string => {
|
|
68
|
+
let text: string = "";
|
|
69
|
+
for (let i: number = 0; i < digits; ++i)
|
|
70
|
+
text += _randomInteger({
|
|
71
|
+
type: "integer",
|
|
72
|
+
minimum: 0,
|
|
73
|
+
maximum: 15,
|
|
74
|
+
}).toString(16);
|
|
75
|
+
return text;
|
|
76
|
+
};
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
import { _randomString } from "./_randomString";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
_ILengthProps,
|
|
4
|
+
_randomLengthPick,
|
|
5
|
+
_randomLengthWindow,
|
|
6
|
+
_randomSegmentLength,
|
|
7
|
+
} from "./_randomStringLength";
|
|
3
8
|
|
|
4
9
|
export const _randomFormatJsonPointer = (props?: _ILengthProps): string => {
|
|
5
10
|
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
6
|
-
return
|
|
11
|
+
return `${PREFIX}${random()}`;
|
|
7
12
|
// The `/components/schemas/` prefix (20 chars) is fixed; the reference token
|
|
8
13
|
// after it grows or shrinks to hit the requested length.
|
|
9
|
-
|
|
14
|
+
if (props.maxLength === undefined || props.maxLength >= PREFIX.length)
|
|
15
|
+
return `${PREFIX}${_randomSegmentLength(props, PREFIX.length, 10, 0)}`;
|
|
16
|
+
// Below that prefix a pointer still exists: the empty pointer addresses the
|
|
17
|
+
// whole document, and one `/`-prefixed token addresses a member of it.
|
|
18
|
+
const length: number = _randomLengthPick(
|
|
19
|
+
_randomLengthWindow(props, { minimum: 0, spread: 6 }),
|
|
20
|
+
);
|
|
21
|
+
return length === 0
|
|
22
|
+
? ""
|
|
23
|
+
: `/${_randomString({
|
|
24
|
+
type: "string",
|
|
25
|
+
minLength: length - 1,
|
|
26
|
+
maxLength: length - 1,
|
|
27
|
+
})}`;
|
|
10
28
|
};
|
|
11
29
|
|
|
30
|
+
const PREFIX = "/components/schemas/";
|
|
31
|
+
|
|
12
32
|
const random = () =>
|
|
13
33
|
_randomString({ type: "string", minLength: 10, maxLength: 10 });
|
|
@@ -1,7 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _randomString } from "./_randomString";
|
|
2
|
+
import {
|
|
3
|
+
_ILengthProps,
|
|
4
|
+
_randomLengthPick,
|
|
5
|
+
_randomLengthWindow,
|
|
6
|
+
} from "./_randomStringLength";
|
|
2
7
|
|
|
3
|
-
export const _randomFormatRegex = (props?: _ILengthProps): string =>
|
|
4
|
-
|
|
8
|
+
export const _randomFormatRegex = (props?: _ILengthProps): string => {
|
|
9
|
+
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
10
|
+
return FIXED;
|
|
11
|
+
// Every character `_randomString` emits is a literal in regular expression
|
|
12
|
+
// syntax, so a source of any length — including the empty source `new
|
|
13
|
+
// RegExp("")` accepts — compiles.
|
|
14
|
+
const length: number = _randomLengthPick(
|
|
15
|
+
_randomLengthWindow(props, { minimum: 0, spread: 16 }),
|
|
16
|
+
);
|
|
17
|
+
return _randomString({
|
|
18
|
+
type: "string",
|
|
19
|
+
minLength: length,
|
|
20
|
+
maxLength: length,
|
|
21
|
+
});
|
|
22
|
+
};
|
|
5
23
|
|
|
6
24
|
const FIXED =
|
|
7
25
|
"/^(?:(?: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)$/";
|
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
import { _randomInteger } from "./_randomInteger";
|
|
2
|
-
import {
|
|
2
|
+
import { _randomString } from "./_randomString";
|
|
3
|
+
import {
|
|
4
|
+
_ILengthProps,
|
|
5
|
+
_randomLengthPick,
|
|
6
|
+
_randomLengthWindow,
|
|
7
|
+
} from "./_randomStringLength";
|
|
8
|
+
import { __randomNumeric } from "./private/__randomComposition";
|
|
3
9
|
|
|
4
10
|
export const _randomFormatRelativeJsonPointer = (
|
|
5
11
|
props?: _ILengthProps,
|
|
6
|
-
): string =>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
})}#`,
|
|
12
|
+
): string => {
|
|
13
|
+
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
14
|
+
return `${_randomInteger({ type: "integer", minimum: 0, maximum: 10 })}#`;
|
|
15
|
+
// The leading non-negative integer stands alone as a pointer, so a single
|
|
16
|
+
// digit is the shortest form; `#` names the key and a `/`-prefixed token names
|
|
17
|
+
// a member, which absorbs any remaining length.
|
|
18
|
+
const length: number = _randomLengthPick(
|
|
19
|
+
_randomLengthWindow(props, { minimum: 1, spread: 6 }),
|
|
15
20
|
);
|
|
21
|
+
if (length === 1) return __randomNumeric(1);
|
|
22
|
+
if (length === 2) return `${__randomNumeric(1)}#`;
|
|
23
|
+
return `${__randomNumeric(1)}/${_randomString({
|
|
24
|
+
type: "string",
|
|
25
|
+
minLength: length - 2,
|
|
26
|
+
maxLength: length - 2,
|
|
27
|
+
})}`;
|
|
28
|
+
};
|
|
@@ -1,17 +1,50 @@
|
|
|
1
1
|
import { _randomInteger } from "./_randomInteger";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
_ILengthProps,
|
|
4
|
+
_RANDOM_LENGTH_ERROR,
|
|
5
|
+
_randomLengthPick,
|
|
6
|
+
_randomLengthWindow,
|
|
7
|
+
} from "./_randomStringLength";
|
|
8
|
+
import { __randomDigits } from "./private/__randomComposition";
|
|
3
9
|
|
|
4
|
-
export const _randomFormatTime = (props?: _ILengthProps): string =>
|
|
5
|
-
|
|
10
|
+
export const _randomFormatTime = (props?: _ILengthProps): string => {
|
|
11
|
+
const clock = (): string =>
|
|
6
12
|
new Date(
|
|
7
|
-
_randomInteger({
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
_randomInteger({ type: "integer", minimum: 0, maximum: DAY }),
|
|
14
|
+
).toISOString();
|
|
15
|
+
if (props?.minLength === undefined && props?.maxLength === undefined)
|
|
16
|
+
return clock().substring(11);
|
|
17
|
+
// `HH:MM:SS` carries a mandatory offset — one character as `Z`, six as
|
|
18
|
+
// `+HH:MM` — and an optional fraction of one to nine digits between them.
|
|
19
|
+
// Together they express 9 and every length from 11 through 24; 10 is the one
|
|
20
|
+
// gap, because a fraction needs both a dot and a digit.
|
|
21
|
+
const window = _randomLengthWindow(props, {
|
|
22
|
+
minimum: CLOCK + 1,
|
|
23
|
+
maximum: CLOCK + 1 + FRACTION_MAX + OFFSET,
|
|
24
|
+
spread: 6,
|
|
25
|
+
});
|
|
26
|
+
let length: number = _randomLengthPick(window);
|
|
27
|
+
if (length === CLOCK + 2)
|
|
28
|
+
length = window.high >= CLOCK + 3 ? CLOCK + 3 : CLOCK + 1;
|
|
29
|
+
if (length < window.low || length > window.high)
|
|
30
|
+
throw new Error(_RANDOM_LENGTH_ERROR);
|
|
31
|
+
const base: string = clock().substring(11, 11 + CLOCK);
|
|
32
|
+
if (length === CLOCK + 1) return `${base}Z`;
|
|
33
|
+
// Nine fraction digits cap the `Z` form at 19 characters, so anything longer
|
|
34
|
+
// spends the extra five on a numeric offset instead.
|
|
35
|
+
return length <= CLOCK + 2 + FRACTION_MAX
|
|
36
|
+
? `${base}.${__randomDigits(length - CLOCK - 2)}Z`
|
|
37
|
+
: `${base}.${__randomDigits(length - CLOCK - 1 - OFFSET)}${offset()}`;
|
|
38
|
+
};
|
|
16
39
|
|
|
17
40
|
const DAY = 86_400_000;
|
|
41
|
+
const CLOCK = "00:00:00".length;
|
|
42
|
+
const OFFSET = "+00:00".length;
|
|
43
|
+
const FRACTION_MAX = 9;
|
|
44
|
+
|
|
45
|
+
const offset = (): string =>
|
|
46
|
+
`${_randomInteger({ type: "integer", minimum: 0, maximum: 1 }) === 0 ? "+" : "-"}${pad(
|
|
47
|
+
_randomInteger({ type: "integer", minimum: 0, maximum: 23 }),
|
|
48
|
+
)}:${pad(_randomInteger({ type: "integer", minimum: 0, maximum: 59 }))}`;
|
|
49
|
+
|
|
50
|
+
const pad = (value: number): string => String(value).padStart(2, "0");
|
|
@@ -2,7 +2,10 @@ import RandExp from "randexp";
|
|
|
2
2
|
|
|
3
3
|
import { _ILengthProps } from "./_randomStringLength";
|
|
4
4
|
|
|
5
|
-
export const _randomPattern = (
|
|
5
|
+
export const _randomPattern = (
|
|
6
|
+
regex: RegExp,
|
|
7
|
+
props?: _ILengthProps,
|
|
8
|
+
): string => {
|
|
6
9
|
const r: RandExp = new RandExp(regex);
|
|
7
10
|
const min: number | undefined = props?.minLength;
|
|
8
11
|
const max: number | undefined = props?.maxLength;
|