typia 7.2.1 → 7.3.0-dev.20241213
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/LICENSE +21 -21
- package/README.md +148 -148
- package/lib/executable/typia.js +0 -0
- package/lib/programmers/llm/LlmApplicationProgrammer.js +0 -1
- package/lib/programmers/llm/LlmApplicationProgrammer.js.map +1 -1
- package/package.json +3 -3
- package/src/IRandomGenerator.ts +49 -49
- package/src/IReadableURLSearchParams.ts +9 -9
- package/src/IValidation.ts +21 -21
- package/src/executable/TypiaGenerateWizard.ts +83 -83
- package/src/executable/TypiaPatchWizard.ts +45 -45
- package/src/executable/TypiaSetupWizard.ts +179 -179
- package/src/executable/setup/ArgumentParser.ts +42 -42
- package/src/executable/setup/FileRetriever.ts +19 -19
- package/src/executable/setup/PackageManager.ts +87 -87
- package/src/factories/ExpressionFactory.ts +216 -216
- package/src/factories/IdentifierFactory.ts +89 -89
- package/src/factories/JsonMetadataFactory.ts +76 -76
- package/src/factories/LiteralFactory.ts +52 -52
- package/src/factories/MetadataCollection.ts +278 -278
- package/src/factories/MetadataCommentTagFactory.ts +650 -650
- package/src/factories/MetadataFactory.ts +404 -404
- package/src/factories/MetadataTypeTagFactory.ts +411 -411
- package/src/factories/MetadataTypeTagSchemaFactory.ts +82 -82
- package/src/factories/NumericRangeFactory.ts +72 -72
- package/src/factories/ProtobufFactory.ts +875 -875
- package/src/factories/StatementFactory.ts +90 -90
- package/src/factories/TemplateFactory.ts +64 -64
- package/src/factories/TypeFactory.ts +140 -140
- package/src/factories/internal/metadata/IMetadataIteratorProps.ts +17 -17
- package/src/factories/internal/metadata/MetadataHelper.ts +21 -21
- package/src/factories/internal/metadata/emplace_metadata_alias.ts +33 -33
- package/src/factories/internal/metadata/emplace_metadata_array_type.ts +39 -39
- package/src/factories/internal/metadata/emplace_metadata_object.ts +208 -208
- package/src/factories/internal/metadata/emplace_metadata_tuple.ts +57 -57
- package/src/factories/internal/metadata/explore_metadata.ts +31 -31
- package/src/factories/internal/metadata/iterate_metadata.ts +54 -54
- package/src/factories/internal/metadata/iterate_metadata_alias.ts +33 -33
- package/src/factories/internal/metadata/iterate_metadata_array.ts +63 -63
- package/src/factories/internal/metadata/iterate_metadata_atomic.ts +62 -62
- package/src/factories/internal/metadata/iterate_metadata_coalesce.ts +28 -28
- package/src/factories/internal/metadata/iterate_metadata_collection.ts +146 -146
- package/src/factories/internal/metadata/iterate_metadata_comment_tags.ts +32 -32
- package/src/factories/internal/metadata/iterate_metadata_constant.ts +76 -76
- package/src/factories/internal/metadata/iterate_metadata_escape.ts +49 -49
- package/src/factories/internal/metadata/iterate_metadata_function.ts +91 -91
- package/src/factories/internal/metadata/iterate_metadata_intersection.ts +213 -213
- package/src/factories/internal/metadata/iterate_metadata_map.ts +57 -57
- package/src/factories/internal/metadata/iterate_metadata_native.ts +255 -255
- package/src/factories/internal/metadata/iterate_metadata_object.ts +35 -35
- package/src/factories/internal/metadata/iterate_metadata_set.ts +57 -57
- package/src/factories/internal/metadata/iterate_metadata_sort.ts +87 -87
- package/src/factories/internal/metadata/iterate_metadata_template.ts +41 -41
- package/src/factories/internal/metadata/iterate_metadata_tuple.ts +26 -26
- package/src/factories/internal/metadata/iterate_metadata_union.ts +19 -19
- package/src/functional.ts +750 -750
- package/src/http.ts +1047 -1047
- package/src/internal/_IProtobufWriter.ts +18 -18
- package/src/internal/_ProtobufReader.ts +194 -194
- package/src/internal/_ProtobufSizer.ts +145 -145
- package/src/internal/_ProtobufWriter.ts +145 -145
- package/src/internal/_accessExpressionAsString.ts +46 -46
- package/src/internal/_assertGuard.ts +13 -13
- package/src/internal/_functionalTypeGuardErrorFactory.ts +4 -4
- package/src/internal/_httpFormDataReadArray.ts +4 -4
- package/src/internal/_httpFormDataReadBigint.ts +18 -18
- package/src/internal/_httpFormDataReadBlob.ts +10 -10
- package/src/internal/_httpFormDataReadBoolean.ts +16 -16
- package/src/internal/_httpFormDataReadFile.ts +10 -10
- package/src/internal/_httpFormDataReadNumber.ts +15 -15
- package/src/internal/_httpFormDataReadString.ts +10 -10
- package/src/internal/_httpHeaderReadBigint.ts +10 -10
- package/src/internal/_httpHeaderReadBoolean.ts +8 -8
- package/src/internal/_httpHeaderReadNumber.ts +7 -7
- package/src/internal/_httpParameterReadBigint.ts +10 -10
- package/src/internal/_httpParameterReadBoolean.ts +8 -8
- package/src/internal/_httpParameterReadNumber.ts +7 -7
- package/src/internal/_httpParameterReadString.ts +2 -2
- package/src/internal/_httpQueryParseURLSearchParams.ts +12 -12
- package/src/internal/_httpQueryReadArray.ts +4 -4
- package/src/internal/_httpQueryReadBigint.ts +12 -12
- package/src/internal/_httpQueryReadBoolean.ts +14 -14
- package/src/internal/_httpQueryReadNumber.ts +9 -9
- package/src/internal/_httpQueryReadString.ts +4 -4
- package/src/internal/_isBetween.ts +2 -2
- package/src/internal/_isBigintString.ts +8 -8
- package/src/internal/_isFormatByte.ts +7 -7
- package/src/internal/_isFormatDate.ts +3 -3
- package/src/internal/_isFormatDateTime.ts +4 -4
- package/src/internal/_isFormatDuration.ts +4 -4
- package/src/internal/_isFormatEmail.ts +4 -4
- package/src/internal/_isFormatHostname.ts +4 -4
- package/src/internal/_isFormatIdnEmail.ts +4 -4
- package/src/internal/_isFormatIdnHostname.ts +4 -4
- package/src/internal/_isFormatIpv4.ts +4 -4
- package/src/internal/_isFormatIpv6.ts +4 -4
- package/src/internal/_isFormatIri.ts +3 -3
- package/src/internal/_isFormatIriReference.ts +4 -4
- package/src/internal/_isFormatJsonPointer.ts +3 -3
- package/src/internal/_isFormatPassword.ts +1 -1
- package/src/internal/_isFormatRegex.ts +8 -8
- package/src/internal/_isFormatRelativeJsonPointer.ts +4 -4
- package/src/internal/_isFormatTime.ts +4 -4
- package/src/internal/_isFormatUri.ts +6 -6
- package/src/internal/_isFormatUriReference.ts +5 -5
- package/src/internal/_isFormatUriTemplate.ts +4 -4
- package/src/internal/_isFormatUrl.ts +4 -4
- package/src/internal/_isFormatUuid.ts +3 -3
- package/src/internal/_isTypeFloat.ts +5 -5
- package/src/internal/_isTypeInt32.ts +5 -5
- package/src/internal/_isTypeInt64.ts +5 -5
- package/src/internal/_isTypeUint32.ts +5 -5
- package/src/internal/_isTypeUint64.ts +5 -5
- package/src/internal/_isUniqueItems.ts +159 -159
- package/src/internal/_jsonStringifyNumber.ts +12 -12
- package/src/internal/_jsonStringifyRest.ts +3 -3
- package/src/internal/_jsonStringifyString.ts +42 -42
- package/src/internal/_jsonStringifyTail.ts +2 -2
- package/src/internal/_llmApplicationFinalize.ts +20 -20
- package/src/internal/_miscCloneAny.ts +46 -46
- package/src/internal/_notationAny.ts +37 -37
- package/src/internal/_notationCamel.ts +13 -13
- package/src/internal/_notationPascal.ts +8 -8
- package/src/internal/_notationSnake.ts +43 -43
- package/src/internal/_randomArray.ts +21 -21
- package/src/internal/_randomBigint.ts +6 -6
- package/src/internal/_randomBoolean.ts +1 -1
- package/src/internal/_randomFormatByte.ts +3 -3
- package/src/internal/_randomFormatDate.ts +18 -18
- package/src/internal/_randomFormatDatetime.ts +16 -16
- package/src/internal/_randomFormatDuration.ts +27 -27
- package/src/internal/_randomFormatEmail.ts +11 -11
- package/src/internal/_randomFormatHostname.ts +6 -6
- package/src/internal/_randomFormatIdnEmail.ts +3 -3
- package/src/internal/_randomFormatIdnHostname.ts +3 -3
- package/src/internal/_randomFormatIpv4.ts +11 -11
- package/src/internal/_randomFormatIpv6.ts +11 -11
- package/src/internal/_randomFormatIri.ts +3 -3
- package/src/internal/_randomFormatIriReference.ts +3 -3
- package/src/internal/_randomFormatJsonPointer.ts +7 -7
- package/src/internal/_randomFormatPassword.ts +8 -8
- package/src/internal/_randomFormatRegex.ts +4 -4
- package/src/internal/_randomFormatRelativeJsonPointer.ts +8 -8
- package/src/internal/_randomFormatTime.ts +14 -14
- package/src/internal/_randomFormatUri.ts +3 -3
- package/src/internal/_randomFormatUriReference.ts +3 -3
- package/src/internal/_randomFormatUriTemplate.ts +3 -3
- package/src/internal/_randomFormatUrl.ts +11 -11
- package/src/internal/_randomFormatUuid.ts +6 -6
- package/src/internal/_randomInteger.ts +47 -47
- package/src/internal/_randomNumber.ts +74 -74
- package/src/internal/_randomPattern.ts +10 -10
- package/src/internal/_randomPick.ts +9 -9
- package/src/internal/_randomString.ts +24 -24
- package/src/internal/_throwTypeGuardError.ts +5 -5
- package/src/internal/_validateReport.ts +13 -13
- package/src/internal/private/__notationCapitalize.ts +2 -2
- package/src/internal/private/__notationUnsnake.ts +24 -24
- package/src/json.ts +752 -752
- package/src/llm.ts +481 -481
- package/src/misc.ts +658 -658
- package/src/module.ts +937 -937
- package/src/notations.ts +827 -827
- package/src/programmers/AssertProgrammer.ts +454 -454
- package/src/programmers/CheckerProgrammer.ts +1617 -1617
- package/src/programmers/FeatureProgrammer.ts +622 -622
- package/src/programmers/ImportProgrammer.ts +185 -185
- package/src/programmers/IsProgrammer.ts +273 -273
- package/src/programmers/RandomProgrammer.ts +1190 -1190
- package/src/programmers/TypiaProgrammer.ts +174 -174
- package/src/programmers/ValidateProgrammer.ts +439 -439
- package/src/programmers/functional/FunctionalAssertFunctionProgrammer.ts +153 -153
- package/src/programmers/functional/FunctionalAssertParametersProgrammer.ts +125 -125
- package/src/programmers/functional/FunctionalAssertReturnProgrammer.ts +115 -115
- package/src/programmers/functional/FunctionalIsFunctionProgrammer.ts +72 -72
- package/src/programmers/functional/FunctionalIsParametersProgrammer.ts +113 -113
- package/src/programmers/functional/FunctionalIsReturnProgrammer.ts +116 -116
- package/src/programmers/functional/FunctionalValidateFunctionProgrammer.ts +119 -119
- package/src/programmers/functional/FunctionalValidateParametersProgrammer.ts +274 -274
- package/src/programmers/functional/FunctionalValidateReturnProgrammer.ts +135 -135
- package/src/programmers/functional/internal/FunctionalGeneralProgrammer.ts +34 -34
- package/src/programmers/helpers/AtomicPredicator.ts +35 -35
- package/src/programmers/helpers/CloneJoiner.ts +143 -143
- package/src/programmers/helpers/FunctionProgrammer.ts +67 -67
- package/src/programmers/helpers/HttpMetadataUtil.ts +21 -21
- package/src/programmers/helpers/NotationJoiner.ts +144 -144
- package/src/programmers/helpers/OptionPredicator.ts +15 -15
- package/src/programmers/helpers/ProtobufUtil.ts +228 -228
- package/src/programmers/helpers/PruneJoiner.ts +148 -148
- package/src/programmers/helpers/RandomJoiner.ts +168 -168
- package/src/programmers/helpers/StringifyJoinder.ts +115 -115
- package/src/programmers/helpers/StringifyPredicator.ts +13 -13
- package/src/programmers/helpers/UnionExplorer.ts +372 -372
- package/src/programmers/helpers/UnionPredicator.ts +79 -79
- package/src/programmers/helpers/disable_function_programmer_declare.ts +32 -32
- package/src/programmers/http/HttpAssertFormDataProgrammer.ts +99 -99
- package/src/programmers/http/HttpAssertHeadersProgrammer.ts +99 -99
- package/src/programmers/http/HttpAssertQueryProgrammer.ts +105 -105
- package/src/programmers/http/HttpFormDataProgrammer.ts +308 -308
- package/src/programmers/http/HttpHeadersProgrammer.ts +400 -400
- package/src/programmers/http/HttpIsFormDataProgrammer.ts +108 -108
- package/src/programmers/http/HttpIsHeadersProgrammer.ts +108 -108
- package/src/programmers/http/HttpIsQueryProgrammer.ts +114 -114
- package/src/programmers/http/HttpParameterProgrammer.ts +115 -115
- package/src/programmers/http/HttpQueryProgrammer.ts +336 -336
- package/src/programmers/http/HttpValidateFormDataProgrammer.ts +92 -92
- package/src/programmers/http/HttpValidateHeadersProgrammer.ts +92 -92
- package/src/programmers/http/HttpValidateQueryProgrammer.ts +98 -98
- package/src/programmers/internal/check_array_length.ts +47 -47
- package/src/programmers/internal/check_bigint.ts +50 -50
- package/src/programmers/internal/check_dynamic_key.ts +201 -201
- package/src/programmers/internal/check_dynamic_properties.ts +208 -208
- package/src/programmers/internal/check_everything.ts +23 -23
- package/src/programmers/internal/check_native.ts +27 -27
- package/src/programmers/internal/check_number.ts +112 -112
- package/src/programmers/internal/check_object.ts +75 -75
- package/src/programmers/internal/check_string.ts +50 -50
- package/src/programmers/internal/check_template.ts +48 -48
- package/src/programmers/internal/check_union_array_like.ts +335 -335
- package/src/programmers/internal/decode_union_object.ts +116 -116
- package/src/programmers/internal/feature_object_entries.ts +61 -61
- package/src/programmers/internal/json_schema_alias.ts +47 -47
- package/src/programmers/internal/json_schema_array.ts +45 -45
- package/src/programmers/internal/json_schema_bigint.ts +15 -15
- package/src/programmers/internal/json_schema_boolean.ts +15 -15
- package/src/programmers/internal/json_schema_constant.ts +26 -26
- package/src/programmers/internal/json_schema_description.ts +12 -12
- package/src/programmers/internal/json_schema_discriminator.ts +35 -35
- package/src/programmers/internal/json_schema_escaped.ts +82 -82
- package/src/programmers/internal/json_schema_native.ts +33 -33
- package/src/programmers/internal/json_schema_number.ts +15 -15
- package/src/programmers/internal/json_schema_object.ts +158 -158
- package/src/programmers/internal/json_schema_plugin.ts +18 -18
- package/src/programmers/internal/json_schema_station.ts +182 -182
- package/src/programmers/internal/json_schema_string.ts +15 -15
- package/src/programmers/internal/json_schema_template.ts +55 -55
- package/src/programmers/internal/json_schema_title.ts +20 -20
- package/src/programmers/internal/json_schema_tuple.ts +35 -35
- package/src/programmers/internal/metadata_to_pattern.ts +42 -42
- package/src/programmers/internal/postfix_of_tuple.ts +5 -5
- package/src/programmers/internal/prune_object_properties.ts +71 -71
- package/src/programmers/internal/stringify_dynamic_properties.ts +162 -162
- package/src/programmers/internal/stringify_regular_properties.ts +81 -81
- package/src/programmers/internal/template_to_pattern.ts +23 -23
- package/src/programmers/internal/wrap_metadata_rest_tuple.ts +23 -23
- package/src/programmers/json/JsonApplicationProgrammer.ts +279 -279
- package/src/programmers/json/JsonAssertParseProgrammer.ts +113 -113
- package/src/programmers/json/JsonAssertStringifyProgrammer.ts +115 -115
- package/src/programmers/json/JsonIsParseProgrammer.ts +114 -114
- package/src/programmers/json/JsonIsStringifyProgrammer.ts +108 -108
- package/src/programmers/json/JsonSchemasProgrammer.ts +91 -91
- package/src/programmers/json/JsonStringifyProgrammer.ts +1124 -1124
- package/src/programmers/json/JsonValidateParseProgrammer.ts +105 -105
- package/src/programmers/json/JsonValidateStringifyProgrammer.ts +124 -124
- package/src/programmers/llm/LlmApplicationOfValidateProgrammer.ts +81 -81
- package/src/programmers/llm/LlmApplicationProgrammer.ts +277 -278
- package/src/programmers/llm/LlmModelPredicator.ts +127 -127
- package/src/programmers/llm/LlmParametersProgrammer.ts +90 -90
- package/src/programmers/llm/LlmSchemaProgrammer.ts +143 -143
- package/src/programmers/misc/MiscAssertCloneProgrammer.ts +95 -95
- package/src/programmers/misc/MiscAssertPruneProgrammer.ts +116 -116
- package/src/programmers/misc/MiscCloneProgrammer.ts +1032 -1032
- package/src/programmers/misc/MiscIsCloneProgrammer.ts +99 -99
- package/src/programmers/misc/MiscIsPruneProgrammer.ts +97 -97
- package/src/programmers/misc/MiscLiteralsProgrammer.ts +80 -80
- package/src/programmers/misc/MiscPruneProgrammer.ts +728 -728
- package/src/programmers/misc/MiscValidateCloneProgrammer.ts +111 -111
- package/src/programmers/misc/MiscValidatePruneProgrammer.ts +113 -113
- package/src/programmers/notations/NotationAssertGeneralProgrammer.ts +101 -101
- package/src/programmers/notations/NotationGeneralProgrammer.ts +984 -984
- package/src/programmers/notations/NotationIsGeneralProgrammer.ts +105 -105
- package/src/programmers/notations/NotationValidateGeneralProgrammer.ts +119 -119
- package/src/programmers/protobuf/ProtobufAssertDecodeProgrammer.ts +98 -98
- package/src/programmers/protobuf/ProtobufAssertEncodeProgrammer.ts +102 -102
- package/src/programmers/protobuf/ProtobufDecodeProgrammer.ts +654 -654
- package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +945 -945
- package/src/programmers/protobuf/ProtobufIsDecodeProgrammer.ts +109 -109
- package/src/programmers/protobuf/ProtobufIsEncodeProgrammer.ts +98 -98
- package/src/programmers/protobuf/ProtobufMessageProgrammer.ts +179 -179
- package/src/programmers/protobuf/ProtobufValidateDecodeProgrammer.ts +92 -92
- package/src/programmers/protobuf/ProtobufValidateEncodeProgrammer.ts +119 -119
- package/src/protobuf.ts +868 -868
- package/src/reflect.ts +57 -57
- package/src/schemas/json/IJsonApplication.ts +73 -73
- package/src/schemas/json/IJsonSchemaCollection.ts +29 -29
- package/src/schemas/json/__IJsonApplication.ts +63 -63
- package/src/schemas/llm/ILlmApplicationOfValidate.ts +55 -55
- package/src/schemas/llm/ILlmFunctionOfValidate.ts +39 -39
- package/src/schemas/metadata/IMetadata.ts +35 -35
- package/src/schemas/metadata/IMetadataAlias.ts +6 -6
- package/src/schemas/metadata/IMetadataAliasType.ts +12 -12
- package/src/schemas/metadata/IMetadataApplication.ts +7 -7
- package/src/schemas/metadata/IMetadataArray.ts +6 -6
- package/src/schemas/metadata/IMetadataComponents.ts +11 -11
- package/src/schemas/metadata/IMetadataConstantValue.ts +11 -11
- package/src/schemas/metadata/IMetadataDictionary.ts +11 -11
- package/src/schemas/metadata/IMetadataMap.ts +8 -8
- package/src/schemas/metadata/IMetadataNative.ts +6 -6
- package/src/schemas/metadata/IMetadataObject.ts +6 -6
- package/src/schemas/metadata/IMetadataObjectType.ts +13 -13
- package/src/schemas/metadata/IMetadataSet.ts +7 -7
- package/src/schemas/metadata/IMetadataTemplate.ts +7 -7
- package/src/schemas/metadata/IMetadataTuple.ts +6 -6
- package/src/schemas/metadata/IMetadataTypeTag.ts +16 -16
- package/src/schemas/metadata/Metadata.ts +669 -669
- package/src/schemas/metadata/MetadataAlias.ts +46 -46
- package/src/schemas/metadata/MetadataAliasType.ts +63 -63
- package/src/schemas/metadata/MetadataApplication.ts +44 -44
- package/src/schemas/metadata/MetadataArray.ts +49 -49
- package/src/schemas/metadata/MetadataAtomic.ts +87 -87
- package/src/schemas/metadata/MetadataComponents.ts +98 -98
- package/src/schemas/metadata/MetadataConstantValue.ts +62 -62
- package/src/schemas/metadata/MetadataMap.ts +48 -48
- package/src/schemas/metadata/MetadataNative.ts +44 -44
- package/src/schemas/metadata/MetadataObject.ts +48 -48
- package/src/schemas/metadata/MetadataObjectType.ts +149 -149
- package/src/schemas/metadata/MetadataParameter.ts +54 -54
- package/src/schemas/metadata/MetadataProperty.ts +59 -59
- package/src/schemas/metadata/MetadataSet.ts +45 -45
- package/src/schemas/metadata/MetadataTemplate.ts +80 -80
- package/src/schemas/metadata/MetadataTuple.ts +32 -32
- package/src/schemas/protobuf/IProtobufProperty.ts +6 -6
- package/src/schemas/protobuf/IProtobufPropertyType.ts +37 -37
- package/src/schemas/protobuf/IProtobufSchema.ts +50 -50
- package/src/tags/Example.ts +24 -24
- package/src/tags/Examples.ts +16 -16
- package/src/tags/Format.ts +50 -50
- package/src/tags/JsonSchemaPlugin.ts +8 -8
- package/src/tags/Sequence.ts +10 -10
- package/src/tags/TagBase.ts +82 -82
- package/src/tags/Type.ts +32 -32
- package/src/tags/UniqueItems.ts +14 -14
- package/src/tags/index.ts +21 -21
- package/src/transform.ts +35 -35
- package/src/transformers/CallExpressionTransformer.ts +547 -547
- package/src/transformers/FileTransformer.ts +136 -136
- package/src/transformers/IProgrammerProps.ts +11 -11
- package/src/transformers/ITransformOptions.ts +62 -62
- package/src/transformers/ITransformProps.ts +9 -9
- package/src/transformers/ITypiaContext.ts +18 -18
- package/src/transformers/ImportTransformer.ts +81 -81
- package/src/transformers/NodeTransformer.ts +17 -17
- package/src/transformers/TransformerError.ts +60 -60
- package/src/transformers/features/AssertTransformer.ts +24 -24
- package/src/transformers/features/CreateAssertTransformer.ts +24 -24
- package/src/transformers/features/CreateIsTransformer.ts +18 -18
- package/src/transformers/features/CreateRandomTransformer.ts +43 -43
- package/src/transformers/features/CreateValidateTransformer.ts +18 -18
- package/src/transformers/features/IsTransformer.ts +18 -18
- package/src/transformers/features/RandomTransformer.ts +41 -41
- package/src/transformers/features/ValidateTransformer.ts +18 -18
- package/src/transformers/features/functional/FunctionalGenericTransformer.ts +57 -57
- package/src/transformers/features/http/CreateHttpAssertFormDataTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpAssertHeadersTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpAssertQueryTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpFormDataTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpHeadersTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpIsFormDataTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpIsHeadersTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpIsQueryTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpParameterTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpQueryTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpValidateFormDataTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpValidateHeadersTransformer.ts +13 -13
- package/src/transformers/features/http/CreateHttpValidateQueryTransformer.ts +13 -13
- package/src/transformers/features/http/HttpAssertFormDataTransformer.ts +13 -13
- package/src/transformers/features/http/HttpAssertHeadersTransformer.ts +13 -13
- package/src/transformers/features/http/HttpAssertQueryTransformer.ts +13 -13
- package/src/transformers/features/http/HttpFormDataTransformer.ts +13 -13
- package/src/transformers/features/http/HttpHeadersTransformer.ts +13 -13
- package/src/transformers/features/http/HttpIsFormDataTransformer.ts +13 -13
- package/src/transformers/features/http/HttpIsHeadersTransformer.ts +13 -13
- package/src/transformers/features/http/HttpIsQueryTransformer.ts +13 -13
- package/src/transformers/features/http/HttpParameterTransformer.ts +13 -13
- package/src/transformers/features/http/HttpQueryTransformer.ts +13 -13
- package/src/transformers/features/http/HttpValidateFormDataTransformer.ts +13 -13
- package/src/transformers/features/http/HttpValidateHeadersTransformer.ts +13 -13
- package/src/transformers/features/http/HttpValidateQueryTransformer.ts +13 -13
- package/src/transformers/features/json/JsonApplicationTransformer.ts +105 -105
- package/src/transformers/features/json/JsonAssertParseTransformer.ts +13 -13
- package/src/transformers/features/json/JsonAssertStringifyTransformer.ts +13 -13
- package/src/transformers/features/json/JsonCreateAssertParseTransformer.ts +13 -13
- package/src/transformers/features/json/JsonCreateAssertStringifyTransformer.ts +13 -13
- package/src/transformers/features/json/JsonCreateIsParseTransformer.ts +13 -13
- package/src/transformers/features/json/JsonCreateIsStringifyTransformer.ts +13 -13
- package/src/transformers/features/json/JsonCreateStringifyTransformer.ts +13 -13
- package/src/transformers/features/json/JsonCreateValidateParseTransformer.ts +13 -13
- package/src/transformers/features/json/JsonCreateValidateStringifyProgrammer.ts +13 -13
- package/src/transformers/features/json/JsonIsParseTransformer.ts +13 -13
- package/src/transformers/features/json/JsonIsStringifyTransformer.ts +13 -13
- package/src/transformers/features/json/JsonSchemasTransformer.ts +143 -143
- package/src/transformers/features/json/JsonStringifyTransformer.ts +13 -13
- package/src/transformers/features/json/JsonValidateParseTransformer.ts +13 -13
- package/src/transformers/features/json/JsonValidateStringifyTransformer.ts +13 -13
- package/src/transformers/features/llm/LlmApplicationOfValidateTransformer.ts +115 -115
- package/src/transformers/features/llm/LlmApplicationTransformer.ts +113 -113
- package/src/transformers/features/llm/LlmParametersTransformer.ts +89 -89
- package/src/transformers/features/llm/LlmSchemaTransformer.ts +130 -130
- package/src/transformers/features/misc/MiscAssertCloneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscAssertPruneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCloneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCreateAssertCloneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCreateAssertPruneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCreateCloneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCreateIsCloneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCreateIsPruneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCreatePruneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCreateValidateCloneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscCreateValidatePruneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscIsCloneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscIsPruneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscLiteralsTransformer.ts +35 -35
- package/src/transformers/features/misc/MiscPruneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscValidateCloneTransformer.ts +13 -13
- package/src/transformers/features/misc/MiscValidatePruneTransformer.ts +13 -13
- package/src/transformers/features/notations/NotationAssertGeneralTransformer.ts +20 -20
- package/src/transformers/features/notations/NotationCreateAssertGeneralTransformer.ts +20 -20
- package/src/transformers/features/notations/NotationCreateGeneralTransformer.ts +20 -20
- package/src/transformers/features/notations/NotationCreateIsGeneralTransformer.ts +20 -20
- package/src/transformers/features/notations/NotationCreateValidateGeneralTransformer.ts +20 -20
- package/src/transformers/features/notations/NotationGeneralTransformer.ts +18 -18
- package/src/transformers/features/notations/NotationIsGeneralTransformer.ts +20 -20
- package/src/transformers/features/notations/NotationValidateGeneralTransformer.ts +20 -20
- package/src/transformers/features/protobuf/ProtobufAssertDecodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufAssertEncodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufCreateAssertDecodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufCreateAssertEncodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufCreateDecodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufCreateEncodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufCreateIsDecodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufCreateIsEncodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufCreateValidateDecodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufCreateValidateEncodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufDecodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufEncodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufIsDecodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufIsEncodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufMessageTransformer.ts +35 -35
- package/src/transformers/features/protobuf/ProtobufValidateDecodeTransformer.ts +13 -13
- package/src/transformers/features/protobuf/ProtobufValidateEncodeTransformer.ts +13 -13
- package/src/transformers/features/reflect/ReflectMetadataTransformer.ts +69 -69
- package/src/transformers/features/reflect/ReflectNameTransformer.ts +82 -82
- package/src/transformers/internal/GenericTransformer.ts +101 -101
- package/src/utils/MapUtil.ts +14 -14
- package/src/utils/NamingConvention.ts +94 -94
- package/src/utils/ProtobufNameEncoder.ts +32 -32
- package/src/utils/StringUtil.ts +16 -16
|
@@ -1,875 +1,875 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
|
|
3
|
-
import { IMetadataTypeTag } from "../schemas/metadata/IMetadataTypeTag";
|
|
4
|
-
import { Metadata } from "../schemas/metadata/Metadata";
|
|
5
|
-
import { MetadataObjectType } from "../schemas/metadata/MetadataObjectType";
|
|
6
|
-
import { MetadataProperty } from "../schemas/metadata/MetadataProperty";
|
|
7
|
-
import { IProtobufProperty } from "../schemas/protobuf/IProtobufProperty";
|
|
8
|
-
import { IProtobufPropertyType } from "../schemas/protobuf/IProtobufPropertyType";
|
|
9
|
-
import { IProtobufSchema } from "../schemas/protobuf/IProtobufSchema";
|
|
10
|
-
|
|
11
|
-
import { ProtobufUtil } from "../programmers/helpers/ProtobufUtil";
|
|
12
|
-
|
|
13
|
-
import { TransformerError } from "../transformers/TransformerError";
|
|
14
|
-
|
|
15
|
-
import { ProtobufAtomic } from "../typings/ProtobufAtomic";
|
|
16
|
-
import { ValidationPipe } from "../typings/ValidationPipe";
|
|
17
|
-
|
|
18
|
-
import { MetadataCollection } from "./MetadataCollection";
|
|
19
|
-
import { MetadataFactory } from "./MetadataFactory";
|
|
20
|
-
|
|
21
|
-
export namespace ProtobufFactory {
|
|
22
|
-
export interface IProps {
|
|
23
|
-
method: string;
|
|
24
|
-
checker: ts.TypeChecker;
|
|
25
|
-
transformer?: ts.TransformationContext;
|
|
26
|
-
collection: MetadataCollection;
|
|
27
|
-
type: ts.Type;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/* -----------------------------------------------------------
|
|
31
|
-
METADATA COMPOSER
|
|
32
|
-
----------------------------------------------------------- */
|
|
33
|
-
export const metadata = (props: IProps): Metadata => {
|
|
34
|
-
// COMPOSE METADATA WITH INDIVIDUAL VALIDATIONS
|
|
35
|
-
const result: ValidationPipe<Metadata, MetadataFactory.IError> =
|
|
36
|
-
MetadataFactory.analyze({
|
|
37
|
-
...props,
|
|
38
|
-
transformer: props.transformer,
|
|
39
|
-
options: {
|
|
40
|
-
escape: false,
|
|
41
|
-
constant: true,
|
|
42
|
-
absorb: true,
|
|
43
|
-
validate: validate(),
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
if (result.success === false)
|
|
47
|
-
throw TransformerError.from({
|
|
48
|
-
code: `typia.protobuf.${props.method}`,
|
|
49
|
-
errors: result.errors,
|
|
50
|
-
});
|
|
51
|
-
return result.data;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @internal
|
|
56
|
-
*/
|
|
57
|
-
export const emplaceObject = (object: MetadataObjectType): void => {
|
|
58
|
-
for (const p of object.properties) emplaceProperty(p);
|
|
59
|
-
const properties: IProtobufProperty[] = object.properties
|
|
60
|
-
.map((p) => p.of_protobuf_)
|
|
61
|
-
.filter((p) => p !== undefined);
|
|
62
|
-
const unique: Set<number> = new Set(
|
|
63
|
-
properties
|
|
64
|
-
.filter((p) => p !== undefined)
|
|
65
|
-
.filter((p) => p.fixed === true)
|
|
66
|
-
.map((p) => p.union.map((u) => u.index))
|
|
67
|
-
.flat(),
|
|
68
|
-
);
|
|
69
|
-
let index: number = 1;
|
|
70
|
-
properties.forEach((schema) => {
|
|
71
|
-
if (schema.fixed === true)
|
|
72
|
-
index = Math.max(
|
|
73
|
-
index,
|
|
74
|
-
Math.max(...schema.union.map((u) => u.index)) + 1,
|
|
75
|
-
);
|
|
76
|
-
else {
|
|
77
|
-
for (const u of schema.union) {
|
|
78
|
-
while (unique.has(index) === true) ++index;
|
|
79
|
-
u.index = index;
|
|
80
|
-
unique.add(index);
|
|
81
|
-
}
|
|
82
|
-
++index;
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const emplaceProperty = (prop: MetadataProperty): void => {
|
|
88
|
-
const union: IProtobufPropertyType[] = [];
|
|
89
|
-
for (const native of prop.value.natives)
|
|
90
|
-
if (native.name === "Uint8Array")
|
|
91
|
-
union.push({
|
|
92
|
-
type: "bytes",
|
|
93
|
-
index: ProtobufUtil.getSequence(native.tags[0] ?? [])!,
|
|
94
|
-
});
|
|
95
|
-
union.push(...emplaceAtomic(prop.value).values());
|
|
96
|
-
for (const array of prop.value.arrays)
|
|
97
|
-
union.push({
|
|
98
|
-
type: "array",
|
|
99
|
-
array: array.type,
|
|
100
|
-
value: emplaceSchema(
|
|
101
|
-
array.type.value,
|
|
102
|
-
) as IProtobufSchema.IArray["value"],
|
|
103
|
-
index: ProtobufUtil.getSequence(array.tags[0] ?? [])!,
|
|
104
|
-
});
|
|
105
|
-
for (const obj of prop.value.objects)
|
|
106
|
-
if (isDynamicObject(obj.type))
|
|
107
|
-
union.push({
|
|
108
|
-
type: "map",
|
|
109
|
-
map: obj.type,
|
|
110
|
-
key: emplaceSchema(
|
|
111
|
-
obj.type.properties[0]!.key,
|
|
112
|
-
) as IProtobufSchema.IMap["key"],
|
|
113
|
-
value: emplaceSchema(
|
|
114
|
-
obj.type.properties[0]!.value,
|
|
115
|
-
) as IProtobufSchema.IMap["value"],
|
|
116
|
-
index: ProtobufUtil.getSequence(obj.tags[0] ?? [])!,
|
|
117
|
-
});
|
|
118
|
-
else
|
|
119
|
-
union.push({
|
|
120
|
-
type: "object",
|
|
121
|
-
object: obj.type,
|
|
122
|
-
index: ProtobufUtil.getSequence(obj.tags[0] ?? [])!,
|
|
123
|
-
});
|
|
124
|
-
for (const map of prop.value.maps)
|
|
125
|
-
union.push({
|
|
126
|
-
type: "map",
|
|
127
|
-
map,
|
|
128
|
-
key: emplaceSchema(map.key) as IProtobufSchema.IMap["key"],
|
|
129
|
-
value: emplaceSchema(map.value) as IProtobufSchema.IMap["value"],
|
|
130
|
-
index: ProtobufUtil.getSequence(map.tags[0] ?? [])!,
|
|
131
|
-
});
|
|
132
|
-
prop.of_protobuf_ = {
|
|
133
|
-
union,
|
|
134
|
-
fixed: union.every((p) => p.index !== null),
|
|
135
|
-
};
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
const emplaceSchema = (metadata: Metadata): IProtobufSchema => {
|
|
139
|
-
for (const native of metadata.natives)
|
|
140
|
-
if (native.name === "Uint8Array")
|
|
141
|
-
return {
|
|
142
|
-
type: "bytes",
|
|
143
|
-
};
|
|
144
|
-
const atomic = emplaceAtomic(metadata);
|
|
145
|
-
if (atomic.size) return atomic.values().next().value!;
|
|
146
|
-
for (const array of metadata.arrays)
|
|
147
|
-
return {
|
|
148
|
-
type: "array",
|
|
149
|
-
array: array.type,
|
|
150
|
-
value: emplaceSchema(
|
|
151
|
-
array.type.value,
|
|
152
|
-
) as IProtobufSchema.IArray["value"],
|
|
153
|
-
};
|
|
154
|
-
for (const obj of metadata.objects)
|
|
155
|
-
if (isDynamicObject(obj.type))
|
|
156
|
-
return {
|
|
157
|
-
type: "map",
|
|
158
|
-
map: obj.type,
|
|
159
|
-
key: emplaceSchema(
|
|
160
|
-
obj.type.properties[0]!.key,
|
|
161
|
-
) as IProtobufSchema.IMap["key"],
|
|
162
|
-
value: emplaceSchema(
|
|
163
|
-
obj.type.properties[0]!.value,
|
|
164
|
-
) as IProtobufSchema.IMap["value"],
|
|
165
|
-
};
|
|
166
|
-
else
|
|
167
|
-
return {
|
|
168
|
-
type: "object",
|
|
169
|
-
object: obj.type,
|
|
170
|
-
};
|
|
171
|
-
for (const map of metadata.maps)
|
|
172
|
-
return {
|
|
173
|
-
type: "map",
|
|
174
|
-
map,
|
|
175
|
-
key: emplaceSchema(map.key) as IProtobufSchema.IMap["key"],
|
|
176
|
-
value: emplaceSchema(map.value) as IProtobufSchema.IMap["value"],
|
|
177
|
-
};
|
|
178
|
-
throw new Error(
|
|
179
|
-
"Error on ProtobufFactory.emplaceSchema(): any type detected.",
|
|
180
|
-
);
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const emplaceAtomic = (
|
|
184
|
-
meta: Metadata,
|
|
185
|
-
): Map<ProtobufAtomic, IProtobufPropertyType> => {
|
|
186
|
-
const map: Map<ProtobufAtomic, IProtobufPropertyType> = new Map();
|
|
187
|
-
|
|
188
|
-
// CONSTANTS
|
|
189
|
-
for (const c of meta.constants)
|
|
190
|
-
if (c.type === "boolean")
|
|
191
|
-
map.set("bool", {
|
|
192
|
-
type: "bool",
|
|
193
|
-
index: getSequence(c.values[0]?.tags[0] ?? [])!,
|
|
194
|
-
});
|
|
195
|
-
else if (c.type === "bigint") {
|
|
196
|
-
const init: ProtobufAtomic.BigNumeric = getBigintType(
|
|
197
|
-
c.values.map((v) => BigInt(v.value)),
|
|
198
|
-
);
|
|
199
|
-
for (const value of c.values)
|
|
200
|
-
emplaceBigint({
|
|
201
|
-
map,
|
|
202
|
-
tags: value.tags,
|
|
203
|
-
init,
|
|
204
|
-
});
|
|
205
|
-
} else if (c.type === "number") {
|
|
206
|
-
const init: ProtobufAtomic.Numeric = getNumberType(
|
|
207
|
-
c.values.map((v) => v.value) as number[],
|
|
208
|
-
);
|
|
209
|
-
for (const value of c.values)
|
|
210
|
-
emplaceNumber({
|
|
211
|
-
map,
|
|
212
|
-
tags: value.tags,
|
|
213
|
-
init,
|
|
214
|
-
});
|
|
215
|
-
} else if (c.type === "string")
|
|
216
|
-
map.set("string", {
|
|
217
|
-
type: "string",
|
|
218
|
-
index: getSequence(c.values[0]?.tags[0] ?? [])!,
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
// TEMPLATE
|
|
222
|
-
if (meta.templates.length)
|
|
223
|
-
map.set("string", {
|
|
224
|
-
type: "string",
|
|
225
|
-
index: getSequence(meta.templates[0]?.tags[0] ?? [])!,
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
// ATOMICS
|
|
229
|
-
for (const atomic of meta.atomics)
|
|
230
|
-
if (atomic.type === "boolean")
|
|
231
|
-
map.set("bool", {
|
|
232
|
-
type: "bool",
|
|
233
|
-
index: getSequence(atomic.tags[0] ?? [])!,
|
|
234
|
-
});
|
|
235
|
-
else if (atomic.type === "bigint")
|
|
236
|
-
emplaceBigint({
|
|
237
|
-
map,
|
|
238
|
-
tags: atomic.tags,
|
|
239
|
-
init: "int64",
|
|
240
|
-
});
|
|
241
|
-
else if (atomic.type === "number")
|
|
242
|
-
emplaceNumber({
|
|
243
|
-
map,
|
|
244
|
-
tags: atomic.tags,
|
|
245
|
-
init: "double",
|
|
246
|
-
});
|
|
247
|
-
else if (atomic.type === "string")
|
|
248
|
-
map.set("string", {
|
|
249
|
-
type: "string",
|
|
250
|
-
index: getSequence(atomic.tags[0] ?? [])!,
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// SORTING FOR VALIDATION REASON
|
|
254
|
-
return new Map(
|
|
255
|
-
Array.from(map).sort((x, y) => ProtobufUtil.compare(x[0], y[0])),
|
|
256
|
-
);
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const emplaceBigint = (next: {
|
|
260
|
-
map: Map<ProtobufAtomic, IProtobufPropertyType>;
|
|
261
|
-
tags: IMetadataTypeTag[][];
|
|
262
|
-
init: ProtobufAtomic.BigNumeric;
|
|
263
|
-
}): void => {
|
|
264
|
-
if (next.tags.length === 0) {
|
|
265
|
-
next.map.set(next.init, {
|
|
266
|
-
type: "bigint",
|
|
267
|
-
name: next.init,
|
|
268
|
-
index: null!,
|
|
269
|
-
});
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
for (const row of next.tags) {
|
|
273
|
-
const value: ProtobufAtomic.BigNumeric =
|
|
274
|
-
row.find(
|
|
275
|
-
(tag) =>
|
|
276
|
-
tag.kind === "type" &&
|
|
277
|
-
(tag.value === "int64" || tag.value === "uint64"),
|
|
278
|
-
)?.value ?? next.init;
|
|
279
|
-
next.map.set(next.init, {
|
|
280
|
-
type: "bigint",
|
|
281
|
-
name: value,
|
|
282
|
-
index: ProtobufUtil.getSequence(row)!,
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
const emplaceNumber = (next: {
|
|
288
|
-
map: Map<ProtobufAtomic, IProtobufPropertyType>;
|
|
289
|
-
tags: IMetadataTypeTag[][];
|
|
290
|
-
init: ProtobufAtomic.Numeric;
|
|
291
|
-
}): void => {
|
|
292
|
-
if (next.tags.length === 0) {
|
|
293
|
-
next.map.set(next.init, {
|
|
294
|
-
type: "number",
|
|
295
|
-
name: next.init,
|
|
296
|
-
index: null!,
|
|
297
|
-
});
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
for (const row of next.tags) {
|
|
301
|
-
const value: ProtobufAtomic.Numeric =
|
|
302
|
-
row.find(
|
|
303
|
-
(tag) =>
|
|
304
|
-
tag.kind === "type" &&
|
|
305
|
-
(tag.value === "int32" ||
|
|
306
|
-
tag.value === "uint32" ||
|
|
307
|
-
tag.value === "int64" ||
|
|
308
|
-
tag.value === "uint64" ||
|
|
309
|
-
tag.value === "float" ||
|
|
310
|
-
tag.value === "double"),
|
|
311
|
-
)?.value ?? next.init;
|
|
312
|
-
next.map.set(value, {
|
|
313
|
-
type: "number",
|
|
314
|
-
name: value,
|
|
315
|
-
index: ProtobufUtil.getSequence(row)!,
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
const getBigintType = (values: bigint[]): ProtobufAtomic.BigNumeric =>
|
|
321
|
-
values.some((v) => v < 0) ? "int64" : "uint64";
|
|
322
|
-
|
|
323
|
-
const getNumberType = (values: number[]): ProtobufAtomic.Numeric =>
|
|
324
|
-
values.every((v) => Math.floor(v) === v)
|
|
325
|
-
? values.every((v) => -2147483648 <= v && v <= 2147483647)
|
|
326
|
-
? "int32"
|
|
327
|
-
: "int64"
|
|
328
|
-
: "double";
|
|
329
|
-
|
|
330
|
-
const getSequence = (tags: IMetadataTypeTag[]): number | null => {
|
|
331
|
-
const sequence = tags.find(
|
|
332
|
-
(t) =>
|
|
333
|
-
t.kind === "sequence" &&
|
|
334
|
-
typeof (t.schema as any)?.["x-protobuf-sequence"] === "number",
|
|
335
|
-
);
|
|
336
|
-
if (sequence === undefined) return null;
|
|
337
|
-
const value: number = Number(
|
|
338
|
-
(sequence.schema as any)["x-protobuf-sequence"],
|
|
339
|
-
);
|
|
340
|
-
return Number.isNaN(value) ? null : value;
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
/* -----------------------------------------------------------
|
|
344
|
-
VALIDATORS
|
|
345
|
-
----------------------------------------------------------- */
|
|
346
|
-
const validate = () => {
|
|
347
|
-
const visited: WeakSet<MetadataObjectType> = new WeakSet();
|
|
348
|
-
return (meta: Metadata, explore: MetadataFactory.IExplore): string[] => {
|
|
349
|
-
const errors: string[] = [];
|
|
350
|
-
const insert = (msg: string) => errors.push(msg);
|
|
351
|
-
|
|
352
|
-
if (explore.top === true) {
|
|
353
|
-
const onlyObject: boolean =
|
|
354
|
-
meta.size() === 1 &&
|
|
355
|
-
meta.objects.length === 1 &&
|
|
356
|
-
meta.objects[0]!.type.properties.every((p) =>
|
|
357
|
-
p.key.isSoleLiteral(),
|
|
358
|
-
) &&
|
|
359
|
-
meta.isRequired() === true &&
|
|
360
|
-
meta.nullable === false;
|
|
361
|
-
if (onlyObject === false)
|
|
362
|
-
insert("target type must be a sole and static object type");
|
|
363
|
-
}
|
|
364
|
-
for (const obj of meta.objects) {
|
|
365
|
-
if (visited.has(obj.type)) continue;
|
|
366
|
-
visited.add(obj.type);
|
|
367
|
-
validateObject({
|
|
368
|
-
object: obj.type,
|
|
369
|
-
errors,
|
|
370
|
-
});
|
|
371
|
-
try {
|
|
372
|
-
emplaceObject(obj.type);
|
|
373
|
-
} catch {}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
//----
|
|
377
|
-
// NOT SUPPORTED TYPES
|
|
378
|
-
//----
|
|
379
|
-
const noSupport = (msg: string) => insert(`does not support ${msg}`);
|
|
380
|
-
|
|
381
|
-
// PROHIBIT ANY TYPE
|
|
382
|
-
if (meta.any) noSupport("any type");
|
|
383
|
-
// PROHIBIT FUNCTIONAL TYPE
|
|
384
|
-
if (meta.functions.length) noSupport("functional type");
|
|
385
|
-
// PROHIBIT TUPLE TYPE
|
|
386
|
-
if (meta.tuples.length) noSupport("tuple type");
|
|
387
|
-
// PROHIBIT SET TYPE
|
|
388
|
-
if (meta.sets.length) noSupport("Set type");
|
|
389
|
-
// NATIVE TYPE, BUT NOT Uint8Array
|
|
390
|
-
if (meta.natives.length)
|
|
391
|
-
for (const native of meta.natives) {
|
|
392
|
-
if (native.name === "Uint8Array") continue;
|
|
393
|
-
|
|
394
|
-
const instead = BANNED_NATIVE_TYPES.get(native.name);
|
|
395
|
-
if (instead === undefined) noSupport(`${native.name} type`);
|
|
396
|
-
else noSupport(`${native.name} type. Use ${instead} type instead.`);
|
|
397
|
-
}
|
|
398
|
-
//----
|
|
399
|
-
// ATOMIC CASES
|
|
400
|
-
//----
|
|
401
|
-
if (meta.atomics.length) {
|
|
402
|
-
const numbers = ProtobufUtil.getNumbers(meta);
|
|
403
|
-
const bigints = ProtobufUtil.getBigints(meta);
|
|
404
|
-
|
|
405
|
-
for (const type of ["int64", "uint64"])
|
|
406
|
-
if (numbers.has(type) && bigints.has(type))
|
|
407
|
-
insert(
|
|
408
|
-
`tags.Type<"${type}"> cannot be used in both number and bigint types. Recommend to remove from number type`,
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
//----
|
|
412
|
-
// ARRRAY CASES
|
|
413
|
-
//----
|
|
414
|
-
// DO NOT ALLOW MULTI-DIMENTIONAL ARRAY
|
|
415
|
-
if (
|
|
416
|
-
meta.arrays.length &&
|
|
417
|
-
meta.arrays.some((array) => !!array.type.value.arrays.length)
|
|
418
|
-
)
|
|
419
|
-
noSupport("over two dimenstional array type");
|
|
420
|
-
// CHILD OF ARRAY TYPE MUST BE REQUIRED
|
|
421
|
-
if (
|
|
422
|
-
meta.arrays.length &&
|
|
423
|
-
meta.arrays.some(
|
|
424
|
-
(array) =>
|
|
425
|
-
array.type.value.isRequired() === false ||
|
|
426
|
-
array.type.value.nullable === true,
|
|
427
|
-
)
|
|
428
|
-
)
|
|
429
|
-
noSupport("optional type in array");
|
|
430
|
-
// UNION IN ARRAY
|
|
431
|
-
if (
|
|
432
|
-
meta.arrays.length &&
|
|
433
|
-
meta.arrays.some(
|
|
434
|
-
(a) =>
|
|
435
|
-
a.type.value.size() > 1 &&
|
|
436
|
-
a.type.value.constants.length !== 1 &&
|
|
437
|
-
a.type.value.constants[0]?.values.length !== a.type.value.size(),
|
|
438
|
-
)
|
|
439
|
-
)
|
|
440
|
-
noSupport("union type in array");
|
|
441
|
-
// DO DYNAMIC OBJECT IN ARRAY
|
|
442
|
-
if (
|
|
443
|
-
meta.arrays.length &&
|
|
444
|
-
meta.arrays.some(
|
|
445
|
-
(a) =>
|
|
446
|
-
a.type.value.maps.length ||
|
|
447
|
-
(a.type.value.objects.length &&
|
|
448
|
-
a.type.value.objects.some(
|
|
449
|
-
(o) => ProtobufUtil.isStaticObject(o.type) === false,
|
|
450
|
-
)),
|
|
451
|
-
)
|
|
452
|
-
)
|
|
453
|
-
noSupport("dynamic object in array");
|
|
454
|
-
// UNION WITH ARRAY
|
|
455
|
-
if (meta.size() > 1 && meta.arrays.length)
|
|
456
|
-
noSupport("union type with array type");
|
|
457
|
-
//----
|
|
458
|
-
// OBJECT CASES
|
|
459
|
-
//----
|
|
460
|
-
// EMPTY PROPERTY
|
|
461
|
-
if (
|
|
462
|
-
meta.objects.length &&
|
|
463
|
-
meta.objects.some((obj) => obj.type.properties.length === 0)
|
|
464
|
-
)
|
|
465
|
-
noSupport("empty object type");
|
|
466
|
-
// MULTIPLE DYNAMIC KEY TYPED PROPERTIES
|
|
467
|
-
if (
|
|
468
|
-
meta.objects.length &&
|
|
469
|
-
meta.objects.some(
|
|
470
|
-
(obj) =>
|
|
471
|
-
obj.type.properties.filter((p) => !p.key.isSoleLiteral()).length >
|
|
472
|
-
1,
|
|
473
|
-
)
|
|
474
|
-
)
|
|
475
|
-
noSupport(
|
|
476
|
-
"object type with multiple dynamic key typed properties. Keep only one.",
|
|
477
|
-
);
|
|
478
|
-
// STATIC AND DYNAMIC PROPERTIES ARE COMPATIBLE
|
|
479
|
-
if (
|
|
480
|
-
meta.objects.length &&
|
|
481
|
-
meta.objects.some(
|
|
482
|
-
(obj) =>
|
|
483
|
-
obj.type.properties.some((p) => p.key.isSoleLiteral()) &&
|
|
484
|
-
obj.type.properties.some((p) => !p.key.isSoleLiteral()),
|
|
485
|
-
)
|
|
486
|
-
)
|
|
487
|
-
noSupport(
|
|
488
|
-
"object type with mixed static and dynamic key typed properties. Keep statics or dynamic only.",
|
|
489
|
-
);
|
|
490
|
-
// DYNAMIC OBJECT, BUT PROPERTY VALUE TYPE IS ARRAY
|
|
491
|
-
if (
|
|
492
|
-
meta.objects.length &&
|
|
493
|
-
isDynamicObject(meta.objects[0]!.type) &&
|
|
494
|
-
meta.objects[0]!.type.properties.some((p) => !!p.value.arrays.length)
|
|
495
|
-
)
|
|
496
|
-
noSupport("dynamic object with array value type");
|
|
497
|
-
// UNION WITH DYNAMIC OBJECTa
|
|
498
|
-
if (
|
|
499
|
-
meta.size() > 1 &&
|
|
500
|
-
meta.objects.length &&
|
|
501
|
-
isDynamicObject(meta.objects[0]!.type)
|
|
502
|
-
)
|
|
503
|
-
noSupport("union type with dynamic object type");
|
|
504
|
-
// UNION IN DYNAMIC PROPERTY VALUE
|
|
505
|
-
if (
|
|
506
|
-
meta.objects.length &&
|
|
507
|
-
meta.objects.some(
|
|
508
|
-
(obj) =>
|
|
509
|
-
isDynamicObject(obj.type) &&
|
|
510
|
-
obj.type.properties.some((p) => ProtobufUtil.isUnion(p.value)),
|
|
511
|
-
)
|
|
512
|
-
)
|
|
513
|
-
noSupport("union type in dynamic property");
|
|
514
|
-
//----
|
|
515
|
-
// MAP CASES
|
|
516
|
-
//----
|
|
517
|
-
// KEY TYPE IS UNION
|
|
518
|
-
if (
|
|
519
|
-
meta.maps.length &&
|
|
520
|
-
meta.maps.some((m) => ProtobufUtil.isUnion(m.key))
|
|
521
|
-
)
|
|
522
|
-
noSupport("union key typed map");
|
|
523
|
-
// KEY TYPE IS NOT ATOMIC
|
|
524
|
-
if (
|
|
525
|
-
meta.maps.length &&
|
|
526
|
-
meta.maps.some((m) => ProtobufUtil.getAtomics(m.key).size !== 1)
|
|
527
|
-
)
|
|
528
|
-
noSupport("non-atomic key typed map");
|
|
529
|
-
// MAP TYPE, BUT PROPERTY KEY TYPE IS OPTIONAL
|
|
530
|
-
if (
|
|
531
|
-
meta.maps.length &&
|
|
532
|
-
meta.maps.some((m) => m.key.isRequired() === false || m.key.nullable)
|
|
533
|
-
)
|
|
534
|
-
noSupport("optional key typed map");
|
|
535
|
-
// MAP TYPE, BUT VALUE TYPE IS ARRAY
|
|
536
|
-
if (meta.maps.length && meta.maps.some((m) => !!m.value.arrays.length))
|
|
537
|
-
noSupport("map type with array value type");
|
|
538
|
-
// UNION WITH MAP
|
|
539
|
-
if (meta.size() > 1 && meta.maps.length)
|
|
540
|
-
noSupport("union type with map type");
|
|
541
|
-
// UNION IN MAP
|
|
542
|
-
if (
|
|
543
|
-
meta.maps.length &&
|
|
544
|
-
meta.maps.some((m) => ProtobufUtil.isUnion(m.value))
|
|
545
|
-
)
|
|
546
|
-
noSupport("union type in map value type");
|
|
547
|
-
return errors;
|
|
548
|
-
};
|
|
549
|
-
};
|
|
550
|
-
|
|
551
|
-
/* -----------------------------------------------------------
|
|
552
|
-
SEQUENE VALIDATOR
|
|
553
|
-
----------------------------------------------------------- */
|
|
554
|
-
const validateObject = (next: {
|
|
555
|
-
object: MetadataObjectType;
|
|
556
|
-
errors: string[];
|
|
557
|
-
}): void => {
|
|
558
|
-
for (const property of next.object.properties)
|
|
559
|
-
validateProperty({
|
|
560
|
-
metadata: property.value,
|
|
561
|
-
errors: next.errors,
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
const entire: Map<number, string> = new Map();
|
|
565
|
-
const visitProperty = (p: MetadataProperty) => {
|
|
566
|
-
const local: Set<number> = new Set();
|
|
567
|
-
const tagger = (matrix: IMetadataTypeTag[][]): void => {
|
|
568
|
-
matrix.forEach((tags) => {
|
|
569
|
-
const value: number | null = ProtobufUtil.getSequence(tags);
|
|
570
|
-
if (value !== null) local.add(value);
|
|
571
|
-
});
|
|
572
|
-
};
|
|
573
|
-
for (const c of p.value.constants)
|
|
574
|
-
for (const v of c.values) tagger(v.tags);
|
|
575
|
-
for (const a of p.value.atomics) tagger(a.tags);
|
|
576
|
-
for (const t of p.value.templates) tagger(t.tags);
|
|
577
|
-
for (const o of p.value.objects) tagger(o.tags);
|
|
578
|
-
for (const a of p.value.arrays) tagger(a.tags);
|
|
579
|
-
for (const s of local)
|
|
580
|
-
if (entire.has(s))
|
|
581
|
-
next.errors.push(
|
|
582
|
-
`The Sequence<${s}> tag is duplicated in two properties (${JSON.stringify(entire.get(s))} and ${JSON.stringify(p.key.getSoleLiteral())})`,
|
|
583
|
-
);
|
|
584
|
-
else entire.set(s, p.key.getSoleLiteral()!);
|
|
585
|
-
};
|
|
586
|
-
for (const p of next.object.properties) visitProperty(p);
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
const validateProperty = (next: {
|
|
590
|
-
metadata: Metadata;
|
|
591
|
-
errors: string[];
|
|
592
|
-
}): void => {
|
|
593
|
-
let expected: number = 0;
|
|
594
|
-
const sequences: Set<number> = new Set();
|
|
595
|
-
const add = (value: number): boolean => {
|
|
596
|
-
if (sequences.has(value)) return false;
|
|
597
|
-
sequences.add(value);
|
|
598
|
-
++expected;
|
|
599
|
-
return true;
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
for (const validator of [
|
|
603
|
-
validateBooleanSequence,
|
|
604
|
-
validateNumericSequences({
|
|
605
|
-
type: "bigint",
|
|
606
|
-
default: "int64",
|
|
607
|
-
categories: BIGINT_TYPES,
|
|
608
|
-
}),
|
|
609
|
-
validateNumericSequences({
|
|
610
|
-
type: "number",
|
|
611
|
-
default: "double",
|
|
612
|
-
categories: NUMBER_TYPES,
|
|
613
|
-
}),
|
|
614
|
-
validateStringSequence,
|
|
615
|
-
])
|
|
616
|
-
validator({ metadata: next.metadata, errors: next.errors, add });
|
|
617
|
-
for (const array of next.metadata.arrays)
|
|
618
|
-
validateInstanceSequence({
|
|
619
|
-
type: "array",
|
|
620
|
-
tags: array.tags,
|
|
621
|
-
errors: next.errors,
|
|
622
|
-
add,
|
|
623
|
-
});
|
|
624
|
-
for (const object of next.metadata.objects)
|
|
625
|
-
validateInstanceSequence({
|
|
626
|
-
type: "object",
|
|
627
|
-
tags: object.tags,
|
|
628
|
-
errors: next.errors,
|
|
629
|
-
add,
|
|
630
|
-
});
|
|
631
|
-
for (const map of next.metadata.maps)
|
|
632
|
-
validateInstanceSequence({
|
|
633
|
-
type: "map",
|
|
634
|
-
tags: map.tags,
|
|
635
|
-
errors: next.errors,
|
|
636
|
-
add,
|
|
637
|
-
});
|
|
638
|
-
for (const native of next.metadata.natives)
|
|
639
|
-
if (native.name === "Uint8Array")
|
|
640
|
-
validateInstanceSequence({
|
|
641
|
-
type: "Uint8Array",
|
|
642
|
-
tags: native.tags,
|
|
643
|
-
errors: next.errors,
|
|
644
|
-
add,
|
|
645
|
-
});
|
|
646
|
-
};
|
|
647
|
-
|
|
648
|
-
const validateBooleanSequence = (next: {
|
|
649
|
-
metadata: Metadata;
|
|
650
|
-
errors: string[];
|
|
651
|
-
add: (value: number) => boolean;
|
|
652
|
-
}): void => {
|
|
653
|
-
// PREPARE EMPLACER
|
|
654
|
-
const unique: Set<number> = new Set();
|
|
655
|
-
let expected: number = 0;
|
|
656
|
-
let actual: number = 0;
|
|
657
|
-
const emplace = (matrix: IMetadataTypeTag[][]): void => {
|
|
658
|
-
for (const tags of matrix)
|
|
659
|
-
for (const tag of tags) {
|
|
660
|
-
const sequence = ProtobufUtil.getSequence([tag]);
|
|
661
|
-
if (sequence !== null) {
|
|
662
|
-
unique.add(sequence);
|
|
663
|
-
++actual;
|
|
664
|
-
}
|
|
665
|
-
++expected;
|
|
666
|
-
}
|
|
667
|
-
};
|
|
668
|
-
|
|
669
|
-
// GATHER SEQUENCE TAGS
|
|
670
|
-
for (const atomic of next.metadata.atomics)
|
|
671
|
-
if (atomic.type === "boolean") emplace(atomic.tags);
|
|
672
|
-
for (const constant of next.metadata.constants)
|
|
673
|
-
if (constant.type === "boolean")
|
|
674
|
-
for (const value of constant.values) emplace(value.tags);
|
|
675
|
-
|
|
676
|
-
// PREDICATE
|
|
677
|
-
if (unique.size && actual !== expected)
|
|
678
|
-
next.errors.push(
|
|
679
|
-
`The sequence tag must be declared in every union type members`,
|
|
680
|
-
);
|
|
681
|
-
else if (unique.size > 1)
|
|
682
|
-
next.errors.push(
|
|
683
|
-
`The sequence tag value must be the same in boolean type (including literal types)`,
|
|
684
|
-
);
|
|
685
|
-
else if (unique.size === 1) {
|
|
686
|
-
const value: number = unique.values().next().value!;
|
|
687
|
-
if (next.add(value) === false)
|
|
688
|
-
next.errors.push(
|
|
689
|
-
`The sequence tag value ${value} in boolean type is duplicated with other types`,
|
|
690
|
-
);
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
const validateNumericSequences =
|
|
695
|
-
(config: {
|
|
696
|
-
type: "number" | "bigint";
|
|
697
|
-
default: string;
|
|
698
|
-
categories: Set<string>;
|
|
699
|
-
}) =>
|
|
700
|
-
(next: {
|
|
701
|
-
metadata: Metadata;
|
|
702
|
-
errors: string[];
|
|
703
|
-
add: (value: number) => boolean;
|
|
704
|
-
}): void => {
|
|
705
|
-
// FIND TYPE CATEGORIES
|
|
706
|
-
const categories: Set<string> = new Set();
|
|
707
|
-
const getType = (tags: IMetadataTypeTag[]): string => {
|
|
708
|
-
const found: IMetadataTypeTag | undefined = tags.find(
|
|
709
|
-
(t) => t.kind === "type" && config.categories.has(t.value),
|
|
710
|
-
);
|
|
711
|
-
return found?.value ?? config.default;
|
|
712
|
-
};
|
|
713
|
-
const exploreCategory = (matrix: IMetadataTypeTag[][]): void => {
|
|
714
|
-
for (const tags of matrix) categories.add(getType(tags));
|
|
715
|
-
};
|
|
716
|
-
for (const atomic of next.metadata.atomics)
|
|
717
|
-
if (atomic.type === config.type) exploreCategory(atomic.tags);
|
|
718
|
-
for (const constant of next.metadata.constants)
|
|
719
|
-
if (constant.type === config.type)
|
|
720
|
-
for (const value of constant.values) exploreCategory(value.tags);
|
|
721
|
-
|
|
722
|
-
// ITERATE TYPE CATEGORIES
|
|
723
|
-
for (const category of categories) {
|
|
724
|
-
const unique: Set<number> = new Set();
|
|
725
|
-
let expected: number = 0;
|
|
726
|
-
let actual: number = 0;
|
|
727
|
-
const emplace = (tags: IMetadataTypeTag[]): void => {
|
|
728
|
-
const sequence: number | null = ProtobufUtil.getSequence(tags);
|
|
729
|
-
if (sequence !== null) {
|
|
730
|
-
unique.add(sequence);
|
|
731
|
-
++actual;
|
|
732
|
-
}
|
|
733
|
-
++expected;
|
|
734
|
-
};
|
|
735
|
-
|
|
736
|
-
for (const atomic of next.metadata.atomics)
|
|
737
|
-
if (atomic.type === config.type)
|
|
738
|
-
for (const tags of atomic.tags)
|
|
739
|
-
if (getType(tags) === category) emplace(tags);
|
|
740
|
-
for (const constant of next.metadata.constants)
|
|
741
|
-
if (constant.type === config.type)
|
|
742
|
-
for (const value of constant.values)
|
|
743
|
-
for (const tags of value.tags)
|
|
744
|
-
if (getType(tags) === category) emplace(tags);
|
|
745
|
-
|
|
746
|
-
if (unique.size && actual !== expected) {
|
|
747
|
-
next.errors.push(
|
|
748
|
-
`The sequence tag must be declared in every union type members`,
|
|
749
|
-
);
|
|
750
|
-
} else if (unique.size > 1)
|
|
751
|
-
next.errors.push(
|
|
752
|
-
`The sequence tag value must be the same in ${config.type} type (including literal types)`,
|
|
753
|
-
);
|
|
754
|
-
else if (unique.size === 1) {
|
|
755
|
-
const value: number = unique.values().next().value!;
|
|
756
|
-
if (next.add(value) === false)
|
|
757
|
-
next.errors.push(
|
|
758
|
-
`The sequence tag value ${value} in ${config.type} type is duplicated with other types`,
|
|
759
|
-
);
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
};
|
|
763
|
-
|
|
764
|
-
const validateStringSequence = (next: {
|
|
765
|
-
metadata: Metadata;
|
|
766
|
-
errors: string[];
|
|
767
|
-
add: (value: number) => boolean;
|
|
768
|
-
}): void => {
|
|
769
|
-
const unique: Set<number> = new Set();
|
|
770
|
-
let expected: number = 0;
|
|
771
|
-
let actual: number = 0;
|
|
772
|
-
const emplace = (matrix: IMetadataTypeTag[][]): void => {
|
|
773
|
-
for (const tags of matrix)
|
|
774
|
-
for (const tag of tags) {
|
|
775
|
-
const sequence = ProtobufUtil.getSequence([tag]);
|
|
776
|
-
if (sequence !== null) {
|
|
777
|
-
unique.add(sequence);
|
|
778
|
-
++actual;
|
|
779
|
-
}
|
|
780
|
-
++expected;
|
|
781
|
-
}
|
|
782
|
-
};
|
|
783
|
-
for (const atomic of next.metadata.atomics)
|
|
784
|
-
if (atomic.type === "string") emplace(atomic.tags);
|
|
785
|
-
for (const constant of next.metadata.constants)
|
|
786
|
-
if (constant.type === "string")
|
|
787
|
-
for (const value of constant.values) emplace(value.tags);
|
|
788
|
-
for (const template of next.metadata.templates) emplace(template.tags);
|
|
789
|
-
|
|
790
|
-
if (unique.size && actual !== expected)
|
|
791
|
-
next.errors.push(
|
|
792
|
-
`The sequence tag must be declared in every union type members`,
|
|
793
|
-
);
|
|
794
|
-
else if (unique.size > 1)
|
|
795
|
-
next.errors.push(
|
|
796
|
-
`The sequence tag value must be the same in string types including literal and template types`,
|
|
797
|
-
);
|
|
798
|
-
else if (unique.size === 1) {
|
|
799
|
-
const value: number = unique.values().next().value!;
|
|
800
|
-
if (next.add(value) === false)
|
|
801
|
-
next.errors.push(
|
|
802
|
-
`The sequence tag value ${value} in string type is duplicated with other types`,
|
|
803
|
-
);
|
|
804
|
-
}
|
|
805
|
-
};
|
|
806
|
-
|
|
807
|
-
const validateInstanceSequence = (next: {
|
|
808
|
-
type: "array" | "object" | "map" | "Uint8Array";
|
|
809
|
-
tags: IMetadataTypeTag[][];
|
|
810
|
-
errors: string[];
|
|
811
|
-
add: (value: number) => boolean;
|
|
812
|
-
}): void => {
|
|
813
|
-
const unique: Set<number> = new Set();
|
|
814
|
-
let count: number = 0;
|
|
815
|
-
for (const tags of next.tags) {
|
|
816
|
-
const value: number | null = ProtobufUtil.getSequence(tags);
|
|
817
|
-
if (value === null) continue;
|
|
818
|
-
unique.add(value);
|
|
819
|
-
++count;
|
|
820
|
-
}
|
|
821
|
-
if (unique.size && count !== next.tags.length)
|
|
822
|
-
next.errors.push(
|
|
823
|
-
`The sequence tag must be declared in every union type members`,
|
|
824
|
-
);
|
|
825
|
-
else if (unique.size > 1)
|
|
826
|
-
next.errors.push(
|
|
827
|
-
`The sequence tag value must be the same in ${next.type === "array" ? "an array" : "object"} type.`,
|
|
828
|
-
);
|
|
829
|
-
else if (unique.size === 1) {
|
|
830
|
-
const value: number = unique.values().next().value!;
|
|
831
|
-
if (next.add(value) === false)
|
|
832
|
-
next.errors.push(
|
|
833
|
-
`The sequence tag value ${value} in ${next.type} type is duplicated with other types`,
|
|
834
|
-
);
|
|
835
|
-
}
|
|
836
|
-
};
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
const isDynamicObject = (obj: MetadataObjectType): boolean =>
|
|
840
|
-
obj.properties[0]!.key.isSoleLiteral() === false;
|
|
841
|
-
|
|
842
|
-
const BANNED_NATIVE_TYPES: Map<string, string | null> = new Map([
|
|
843
|
-
["Date", "string"],
|
|
844
|
-
["Boolean", "boolean"],
|
|
845
|
-
["BigInt", "bigint"],
|
|
846
|
-
["Number", "number"],
|
|
847
|
-
["String", "string"],
|
|
848
|
-
...[
|
|
849
|
-
"Buffer",
|
|
850
|
-
"Uint8ClampedArray",
|
|
851
|
-
"Uint16Array",
|
|
852
|
-
"Uint32Array",
|
|
853
|
-
"BigUint64Array",
|
|
854
|
-
"Int8Array",
|
|
855
|
-
"Int16Array",
|
|
856
|
-
"Int32Array",
|
|
857
|
-
"BigInt64Array",
|
|
858
|
-
"Float32Array",
|
|
859
|
-
"Float64Array",
|
|
860
|
-
"DataView",
|
|
861
|
-
"ArrayBuffer",
|
|
862
|
-
"SharedArrayBuffer",
|
|
863
|
-
].map((name) => [name, "Uint8Array"] as const),
|
|
864
|
-
["WeakSet", "Array"],
|
|
865
|
-
["WeakMap", "Map"],
|
|
866
|
-
]);
|
|
867
|
-
const NUMBER_TYPES: Set<string> = new Set([
|
|
868
|
-
"int32",
|
|
869
|
-
"uint32",
|
|
870
|
-
"int64",
|
|
871
|
-
"uint64",
|
|
872
|
-
"float",
|
|
873
|
-
"double",
|
|
874
|
-
]);
|
|
875
|
-
const BIGINT_TYPES = new Set(["int64", "uint64"]);
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
import { IMetadataTypeTag } from "../schemas/metadata/IMetadataTypeTag";
|
|
4
|
+
import { Metadata } from "../schemas/metadata/Metadata";
|
|
5
|
+
import { MetadataObjectType } from "../schemas/metadata/MetadataObjectType";
|
|
6
|
+
import { MetadataProperty } from "../schemas/metadata/MetadataProperty";
|
|
7
|
+
import { IProtobufProperty } from "../schemas/protobuf/IProtobufProperty";
|
|
8
|
+
import { IProtobufPropertyType } from "../schemas/protobuf/IProtobufPropertyType";
|
|
9
|
+
import { IProtobufSchema } from "../schemas/protobuf/IProtobufSchema";
|
|
10
|
+
|
|
11
|
+
import { ProtobufUtil } from "../programmers/helpers/ProtobufUtil";
|
|
12
|
+
|
|
13
|
+
import { TransformerError } from "../transformers/TransformerError";
|
|
14
|
+
|
|
15
|
+
import { ProtobufAtomic } from "../typings/ProtobufAtomic";
|
|
16
|
+
import { ValidationPipe } from "../typings/ValidationPipe";
|
|
17
|
+
|
|
18
|
+
import { MetadataCollection } from "./MetadataCollection";
|
|
19
|
+
import { MetadataFactory } from "./MetadataFactory";
|
|
20
|
+
|
|
21
|
+
export namespace ProtobufFactory {
|
|
22
|
+
export interface IProps {
|
|
23
|
+
method: string;
|
|
24
|
+
checker: ts.TypeChecker;
|
|
25
|
+
transformer?: ts.TransformationContext;
|
|
26
|
+
collection: MetadataCollection;
|
|
27
|
+
type: ts.Type;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* -----------------------------------------------------------
|
|
31
|
+
METADATA COMPOSER
|
|
32
|
+
----------------------------------------------------------- */
|
|
33
|
+
export const metadata = (props: IProps): Metadata => {
|
|
34
|
+
// COMPOSE METADATA WITH INDIVIDUAL VALIDATIONS
|
|
35
|
+
const result: ValidationPipe<Metadata, MetadataFactory.IError> =
|
|
36
|
+
MetadataFactory.analyze({
|
|
37
|
+
...props,
|
|
38
|
+
transformer: props.transformer,
|
|
39
|
+
options: {
|
|
40
|
+
escape: false,
|
|
41
|
+
constant: true,
|
|
42
|
+
absorb: true,
|
|
43
|
+
validate: validate(),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
if (result.success === false)
|
|
47
|
+
throw TransformerError.from({
|
|
48
|
+
code: `typia.protobuf.${props.method}`,
|
|
49
|
+
errors: result.errors,
|
|
50
|
+
});
|
|
51
|
+
return result.data;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
export const emplaceObject = (object: MetadataObjectType): void => {
|
|
58
|
+
for (const p of object.properties) emplaceProperty(p);
|
|
59
|
+
const properties: IProtobufProperty[] = object.properties
|
|
60
|
+
.map((p) => p.of_protobuf_)
|
|
61
|
+
.filter((p) => p !== undefined);
|
|
62
|
+
const unique: Set<number> = new Set(
|
|
63
|
+
properties
|
|
64
|
+
.filter((p) => p !== undefined)
|
|
65
|
+
.filter((p) => p.fixed === true)
|
|
66
|
+
.map((p) => p.union.map((u) => u.index))
|
|
67
|
+
.flat(),
|
|
68
|
+
);
|
|
69
|
+
let index: number = 1;
|
|
70
|
+
properties.forEach((schema) => {
|
|
71
|
+
if (schema.fixed === true)
|
|
72
|
+
index = Math.max(
|
|
73
|
+
index,
|
|
74
|
+
Math.max(...schema.union.map((u) => u.index)) + 1,
|
|
75
|
+
);
|
|
76
|
+
else {
|
|
77
|
+
for (const u of schema.union) {
|
|
78
|
+
while (unique.has(index) === true) ++index;
|
|
79
|
+
u.index = index;
|
|
80
|
+
unique.add(index);
|
|
81
|
+
}
|
|
82
|
+
++index;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const emplaceProperty = (prop: MetadataProperty): void => {
|
|
88
|
+
const union: IProtobufPropertyType[] = [];
|
|
89
|
+
for (const native of prop.value.natives)
|
|
90
|
+
if (native.name === "Uint8Array")
|
|
91
|
+
union.push({
|
|
92
|
+
type: "bytes",
|
|
93
|
+
index: ProtobufUtil.getSequence(native.tags[0] ?? [])!,
|
|
94
|
+
});
|
|
95
|
+
union.push(...emplaceAtomic(prop.value).values());
|
|
96
|
+
for (const array of prop.value.arrays)
|
|
97
|
+
union.push({
|
|
98
|
+
type: "array",
|
|
99
|
+
array: array.type,
|
|
100
|
+
value: emplaceSchema(
|
|
101
|
+
array.type.value,
|
|
102
|
+
) as IProtobufSchema.IArray["value"],
|
|
103
|
+
index: ProtobufUtil.getSequence(array.tags[0] ?? [])!,
|
|
104
|
+
});
|
|
105
|
+
for (const obj of prop.value.objects)
|
|
106
|
+
if (isDynamicObject(obj.type))
|
|
107
|
+
union.push({
|
|
108
|
+
type: "map",
|
|
109
|
+
map: obj.type,
|
|
110
|
+
key: emplaceSchema(
|
|
111
|
+
obj.type.properties[0]!.key,
|
|
112
|
+
) as IProtobufSchema.IMap["key"],
|
|
113
|
+
value: emplaceSchema(
|
|
114
|
+
obj.type.properties[0]!.value,
|
|
115
|
+
) as IProtobufSchema.IMap["value"],
|
|
116
|
+
index: ProtobufUtil.getSequence(obj.tags[0] ?? [])!,
|
|
117
|
+
});
|
|
118
|
+
else
|
|
119
|
+
union.push({
|
|
120
|
+
type: "object",
|
|
121
|
+
object: obj.type,
|
|
122
|
+
index: ProtobufUtil.getSequence(obj.tags[0] ?? [])!,
|
|
123
|
+
});
|
|
124
|
+
for (const map of prop.value.maps)
|
|
125
|
+
union.push({
|
|
126
|
+
type: "map",
|
|
127
|
+
map,
|
|
128
|
+
key: emplaceSchema(map.key) as IProtobufSchema.IMap["key"],
|
|
129
|
+
value: emplaceSchema(map.value) as IProtobufSchema.IMap["value"],
|
|
130
|
+
index: ProtobufUtil.getSequence(map.tags[0] ?? [])!,
|
|
131
|
+
});
|
|
132
|
+
prop.of_protobuf_ = {
|
|
133
|
+
union,
|
|
134
|
+
fixed: union.every((p) => p.index !== null),
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const emplaceSchema = (metadata: Metadata): IProtobufSchema => {
|
|
139
|
+
for (const native of metadata.natives)
|
|
140
|
+
if (native.name === "Uint8Array")
|
|
141
|
+
return {
|
|
142
|
+
type: "bytes",
|
|
143
|
+
};
|
|
144
|
+
const atomic = emplaceAtomic(metadata);
|
|
145
|
+
if (atomic.size) return atomic.values().next().value!;
|
|
146
|
+
for (const array of metadata.arrays)
|
|
147
|
+
return {
|
|
148
|
+
type: "array",
|
|
149
|
+
array: array.type,
|
|
150
|
+
value: emplaceSchema(
|
|
151
|
+
array.type.value,
|
|
152
|
+
) as IProtobufSchema.IArray["value"],
|
|
153
|
+
};
|
|
154
|
+
for (const obj of metadata.objects)
|
|
155
|
+
if (isDynamicObject(obj.type))
|
|
156
|
+
return {
|
|
157
|
+
type: "map",
|
|
158
|
+
map: obj.type,
|
|
159
|
+
key: emplaceSchema(
|
|
160
|
+
obj.type.properties[0]!.key,
|
|
161
|
+
) as IProtobufSchema.IMap["key"],
|
|
162
|
+
value: emplaceSchema(
|
|
163
|
+
obj.type.properties[0]!.value,
|
|
164
|
+
) as IProtobufSchema.IMap["value"],
|
|
165
|
+
};
|
|
166
|
+
else
|
|
167
|
+
return {
|
|
168
|
+
type: "object",
|
|
169
|
+
object: obj.type,
|
|
170
|
+
};
|
|
171
|
+
for (const map of metadata.maps)
|
|
172
|
+
return {
|
|
173
|
+
type: "map",
|
|
174
|
+
map,
|
|
175
|
+
key: emplaceSchema(map.key) as IProtobufSchema.IMap["key"],
|
|
176
|
+
value: emplaceSchema(map.value) as IProtobufSchema.IMap["value"],
|
|
177
|
+
};
|
|
178
|
+
throw new Error(
|
|
179
|
+
"Error on ProtobufFactory.emplaceSchema(): any type detected.",
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const emplaceAtomic = (
|
|
184
|
+
meta: Metadata,
|
|
185
|
+
): Map<ProtobufAtomic, IProtobufPropertyType> => {
|
|
186
|
+
const map: Map<ProtobufAtomic, IProtobufPropertyType> = new Map();
|
|
187
|
+
|
|
188
|
+
// CONSTANTS
|
|
189
|
+
for (const c of meta.constants)
|
|
190
|
+
if (c.type === "boolean")
|
|
191
|
+
map.set("bool", {
|
|
192
|
+
type: "bool",
|
|
193
|
+
index: getSequence(c.values[0]?.tags[0] ?? [])!,
|
|
194
|
+
});
|
|
195
|
+
else if (c.type === "bigint") {
|
|
196
|
+
const init: ProtobufAtomic.BigNumeric = getBigintType(
|
|
197
|
+
c.values.map((v) => BigInt(v.value)),
|
|
198
|
+
);
|
|
199
|
+
for (const value of c.values)
|
|
200
|
+
emplaceBigint({
|
|
201
|
+
map,
|
|
202
|
+
tags: value.tags,
|
|
203
|
+
init,
|
|
204
|
+
});
|
|
205
|
+
} else if (c.type === "number") {
|
|
206
|
+
const init: ProtobufAtomic.Numeric = getNumberType(
|
|
207
|
+
c.values.map((v) => v.value) as number[],
|
|
208
|
+
);
|
|
209
|
+
for (const value of c.values)
|
|
210
|
+
emplaceNumber({
|
|
211
|
+
map,
|
|
212
|
+
tags: value.tags,
|
|
213
|
+
init,
|
|
214
|
+
});
|
|
215
|
+
} else if (c.type === "string")
|
|
216
|
+
map.set("string", {
|
|
217
|
+
type: "string",
|
|
218
|
+
index: getSequence(c.values[0]?.tags[0] ?? [])!,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// TEMPLATE
|
|
222
|
+
if (meta.templates.length)
|
|
223
|
+
map.set("string", {
|
|
224
|
+
type: "string",
|
|
225
|
+
index: getSequence(meta.templates[0]?.tags[0] ?? [])!,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// ATOMICS
|
|
229
|
+
for (const atomic of meta.atomics)
|
|
230
|
+
if (atomic.type === "boolean")
|
|
231
|
+
map.set("bool", {
|
|
232
|
+
type: "bool",
|
|
233
|
+
index: getSequence(atomic.tags[0] ?? [])!,
|
|
234
|
+
});
|
|
235
|
+
else if (atomic.type === "bigint")
|
|
236
|
+
emplaceBigint({
|
|
237
|
+
map,
|
|
238
|
+
tags: atomic.tags,
|
|
239
|
+
init: "int64",
|
|
240
|
+
});
|
|
241
|
+
else if (atomic.type === "number")
|
|
242
|
+
emplaceNumber({
|
|
243
|
+
map,
|
|
244
|
+
tags: atomic.tags,
|
|
245
|
+
init: "double",
|
|
246
|
+
});
|
|
247
|
+
else if (atomic.type === "string")
|
|
248
|
+
map.set("string", {
|
|
249
|
+
type: "string",
|
|
250
|
+
index: getSequence(atomic.tags[0] ?? [])!,
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// SORTING FOR VALIDATION REASON
|
|
254
|
+
return new Map(
|
|
255
|
+
Array.from(map).sort((x, y) => ProtobufUtil.compare(x[0], y[0])),
|
|
256
|
+
);
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const emplaceBigint = (next: {
|
|
260
|
+
map: Map<ProtobufAtomic, IProtobufPropertyType>;
|
|
261
|
+
tags: IMetadataTypeTag[][];
|
|
262
|
+
init: ProtobufAtomic.BigNumeric;
|
|
263
|
+
}): void => {
|
|
264
|
+
if (next.tags.length === 0) {
|
|
265
|
+
next.map.set(next.init, {
|
|
266
|
+
type: "bigint",
|
|
267
|
+
name: next.init,
|
|
268
|
+
index: null!,
|
|
269
|
+
});
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
for (const row of next.tags) {
|
|
273
|
+
const value: ProtobufAtomic.BigNumeric =
|
|
274
|
+
row.find(
|
|
275
|
+
(tag) =>
|
|
276
|
+
tag.kind === "type" &&
|
|
277
|
+
(tag.value === "int64" || tag.value === "uint64"),
|
|
278
|
+
)?.value ?? next.init;
|
|
279
|
+
next.map.set(next.init, {
|
|
280
|
+
type: "bigint",
|
|
281
|
+
name: value,
|
|
282
|
+
index: ProtobufUtil.getSequence(row)!,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const emplaceNumber = (next: {
|
|
288
|
+
map: Map<ProtobufAtomic, IProtobufPropertyType>;
|
|
289
|
+
tags: IMetadataTypeTag[][];
|
|
290
|
+
init: ProtobufAtomic.Numeric;
|
|
291
|
+
}): void => {
|
|
292
|
+
if (next.tags.length === 0) {
|
|
293
|
+
next.map.set(next.init, {
|
|
294
|
+
type: "number",
|
|
295
|
+
name: next.init,
|
|
296
|
+
index: null!,
|
|
297
|
+
});
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
for (const row of next.tags) {
|
|
301
|
+
const value: ProtobufAtomic.Numeric =
|
|
302
|
+
row.find(
|
|
303
|
+
(tag) =>
|
|
304
|
+
tag.kind === "type" &&
|
|
305
|
+
(tag.value === "int32" ||
|
|
306
|
+
tag.value === "uint32" ||
|
|
307
|
+
tag.value === "int64" ||
|
|
308
|
+
tag.value === "uint64" ||
|
|
309
|
+
tag.value === "float" ||
|
|
310
|
+
tag.value === "double"),
|
|
311
|
+
)?.value ?? next.init;
|
|
312
|
+
next.map.set(value, {
|
|
313
|
+
type: "number",
|
|
314
|
+
name: value,
|
|
315
|
+
index: ProtobufUtil.getSequence(row)!,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const getBigintType = (values: bigint[]): ProtobufAtomic.BigNumeric =>
|
|
321
|
+
values.some((v) => v < 0) ? "int64" : "uint64";
|
|
322
|
+
|
|
323
|
+
const getNumberType = (values: number[]): ProtobufAtomic.Numeric =>
|
|
324
|
+
values.every((v) => Math.floor(v) === v)
|
|
325
|
+
? values.every((v) => -2147483648 <= v && v <= 2147483647)
|
|
326
|
+
? "int32"
|
|
327
|
+
: "int64"
|
|
328
|
+
: "double";
|
|
329
|
+
|
|
330
|
+
const getSequence = (tags: IMetadataTypeTag[]): number | null => {
|
|
331
|
+
const sequence = tags.find(
|
|
332
|
+
(t) =>
|
|
333
|
+
t.kind === "sequence" &&
|
|
334
|
+
typeof (t.schema as any)?.["x-protobuf-sequence"] === "number",
|
|
335
|
+
);
|
|
336
|
+
if (sequence === undefined) return null;
|
|
337
|
+
const value: number = Number(
|
|
338
|
+
(sequence.schema as any)["x-protobuf-sequence"],
|
|
339
|
+
);
|
|
340
|
+
return Number.isNaN(value) ? null : value;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/* -----------------------------------------------------------
|
|
344
|
+
VALIDATORS
|
|
345
|
+
----------------------------------------------------------- */
|
|
346
|
+
const validate = () => {
|
|
347
|
+
const visited: WeakSet<MetadataObjectType> = new WeakSet();
|
|
348
|
+
return (meta: Metadata, explore: MetadataFactory.IExplore): string[] => {
|
|
349
|
+
const errors: string[] = [];
|
|
350
|
+
const insert = (msg: string) => errors.push(msg);
|
|
351
|
+
|
|
352
|
+
if (explore.top === true) {
|
|
353
|
+
const onlyObject: boolean =
|
|
354
|
+
meta.size() === 1 &&
|
|
355
|
+
meta.objects.length === 1 &&
|
|
356
|
+
meta.objects[0]!.type.properties.every((p) =>
|
|
357
|
+
p.key.isSoleLiteral(),
|
|
358
|
+
) &&
|
|
359
|
+
meta.isRequired() === true &&
|
|
360
|
+
meta.nullable === false;
|
|
361
|
+
if (onlyObject === false)
|
|
362
|
+
insert("target type must be a sole and static object type");
|
|
363
|
+
}
|
|
364
|
+
for (const obj of meta.objects) {
|
|
365
|
+
if (visited.has(obj.type)) continue;
|
|
366
|
+
visited.add(obj.type);
|
|
367
|
+
validateObject({
|
|
368
|
+
object: obj.type,
|
|
369
|
+
errors,
|
|
370
|
+
});
|
|
371
|
+
try {
|
|
372
|
+
emplaceObject(obj.type);
|
|
373
|
+
} catch {}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
//----
|
|
377
|
+
// NOT SUPPORTED TYPES
|
|
378
|
+
//----
|
|
379
|
+
const noSupport = (msg: string) => insert(`does not support ${msg}`);
|
|
380
|
+
|
|
381
|
+
// PROHIBIT ANY TYPE
|
|
382
|
+
if (meta.any) noSupport("any type");
|
|
383
|
+
// PROHIBIT FUNCTIONAL TYPE
|
|
384
|
+
if (meta.functions.length) noSupport("functional type");
|
|
385
|
+
// PROHIBIT TUPLE TYPE
|
|
386
|
+
if (meta.tuples.length) noSupport("tuple type");
|
|
387
|
+
// PROHIBIT SET TYPE
|
|
388
|
+
if (meta.sets.length) noSupport("Set type");
|
|
389
|
+
// NATIVE TYPE, BUT NOT Uint8Array
|
|
390
|
+
if (meta.natives.length)
|
|
391
|
+
for (const native of meta.natives) {
|
|
392
|
+
if (native.name === "Uint8Array") continue;
|
|
393
|
+
|
|
394
|
+
const instead = BANNED_NATIVE_TYPES.get(native.name);
|
|
395
|
+
if (instead === undefined) noSupport(`${native.name} type`);
|
|
396
|
+
else noSupport(`${native.name} type. Use ${instead} type instead.`);
|
|
397
|
+
}
|
|
398
|
+
//----
|
|
399
|
+
// ATOMIC CASES
|
|
400
|
+
//----
|
|
401
|
+
if (meta.atomics.length) {
|
|
402
|
+
const numbers = ProtobufUtil.getNumbers(meta);
|
|
403
|
+
const bigints = ProtobufUtil.getBigints(meta);
|
|
404
|
+
|
|
405
|
+
for (const type of ["int64", "uint64"])
|
|
406
|
+
if (numbers.has(type) && bigints.has(type))
|
|
407
|
+
insert(
|
|
408
|
+
`tags.Type<"${type}"> cannot be used in both number and bigint types. Recommend to remove from number type`,
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
//----
|
|
412
|
+
// ARRRAY CASES
|
|
413
|
+
//----
|
|
414
|
+
// DO NOT ALLOW MULTI-DIMENTIONAL ARRAY
|
|
415
|
+
if (
|
|
416
|
+
meta.arrays.length &&
|
|
417
|
+
meta.arrays.some((array) => !!array.type.value.arrays.length)
|
|
418
|
+
)
|
|
419
|
+
noSupport("over two dimenstional array type");
|
|
420
|
+
// CHILD OF ARRAY TYPE MUST BE REQUIRED
|
|
421
|
+
if (
|
|
422
|
+
meta.arrays.length &&
|
|
423
|
+
meta.arrays.some(
|
|
424
|
+
(array) =>
|
|
425
|
+
array.type.value.isRequired() === false ||
|
|
426
|
+
array.type.value.nullable === true,
|
|
427
|
+
)
|
|
428
|
+
)
|
|
429
|
+
noSupport("optional type in array");
|
|
430
|
+
// UNION IN ARRAY
|
|
431
|
+
if (
|
|
432
|
+
meta.arrays.length &&
|
|
433
|
+
meta.arrays.some(
|
|
434
|
+
(a) =>
|
|
435
|
+
a.type.value.size() > 1 &&
|
|
436
|
+
a.type.value.constants.length !== 1 &&
|
|
437
|
+
a.type.value.constants[0]?.values.length !== a.type.value.size(),
|
|
438
|
+
)
|
|
439
|
+
)
|
|
440
|
+
noSupport("union type in array");
|
|
441
|
+
// DO DYNAMIC OBJECT IN ARRAY
|
|
442
|
+
if (
|
|
443
|
+
meta.arrays.length &&
|
|
444
|
+
meta.arrays.some(
|
|
445
|
+
(a) =>
|
|
446
|
+
a.type.value.maps.length ||
|
|
447
|
+
(a.type.value.objects.length &&
|
|
448
|
+
a.type.value.objects.some(
|
|
449
|
+
(o) => ProtobufUtil.isStaticObject(o.type) === false,
|
|
450
|
+
)),
|
|
451
|
+
)
|
|
452
|
+
)
|
|
453
|
+
noSupport("dynamic object in array");
|
|
454
|
+
// UNION WITH ARRAY
|
|
455
|
+
if (meta.size() > 1 && meta.arrays.length)
|
|
456
|
+
noSupport("union type with array type");
|
|
457
|
+
//----
|
|
458
|
+
// OBJECT CASES
|
|
459
|
+
//----
|
|
460
|
+
// EMPTY PROPERTY
|
|
461
|
+
if (
|
|
462
|
+
meta.objects.length &&
|
|
463
|
+
meta.objects.some((obj) => obj.type.properties.length === 0)
|
|
464
|
+
)
|
|
465
|
+
noSupport("empty object type");
|
|
466
|
+
// MULTIPLE DYNAMIC KEY TYPED PROPERTIES
|
|
467
|
+
if (
|
|
468
|
+
meta.objects.length &&
|
|
469
|
+
meta.objects.some(
|
|
470
|
+
(obj) =>
|
|
471
|
+
obj.type.properties.filter((p) => !p.key.isSoleLiteral()).length >
|
|
472
|
+
1,
|
|
473
|
+
)
|
|
474
|
+
)
|
|
475
|
+
noSupport(
|
|
476
|
+
"object type with multiple dynamic key typed properties. Keep only one.",
|
|
477
|
+
);
|
|
478
|
+
// STATIC AND DYNAMIC PROPERTIES ARE COMPATIBLE
|
|
479
|
+
if (
|
|
480
|
+
meta.objects.length &&
|
|
481
|
+
meta.objects.some(
|
|
482
|
+
(obj) =>
|
|
483
|
+
obj.type.properties.some((p) => p.key.isSoleLiteral()) &&
|
|
484
|
+
obj.type.properties.some((p) => !p.key.isSoleLiteral()),
|
|
485
|
+
)
|
|
486
|
+
)
|
|
487
|
+
noSupport(
|
|
488
|
+
"object type with mixed static and dynamic key typed properties. Keep statics or dynamic only.",
|
|
489
|
+
);
|
|
490
|
+
// DYNAMIC OBJECT, BUT PROPERTY VALUE TYPE IS ARRAY
|
|
491
|
+
if (
|
|
492
|
+
meta.objects.length &&
|
|
493
|
+
isDynamicObject(meta.objects[0]!.type) &&
|
|
494
|
+
meta.objects[0]!.type.properties.some((p) => !!p.value.arrays.length)
|
|
495
|
+
)
|
|
496
|
+
noSupport("dynamic object with array value type");
|
|
497
|
+
// UNION WITH DYNAMIC OBJECTa
|
|
498
|
+
if (
|
|
499
|
+
meta.size() > 1 &&
|
|
500
|
+
meta.objects.length &&
|
|
501
|
+
isDynamicObject(meta.objects[0]!.type)
|
|
502
|
+
)
|
|
503
|
+
noSupport("union type with dynamic object type");
|
|
504
|
+
// UNION IN DYNAMIC PROPERTY VALUE
|
|
505
|
+
if (
|
|
506
|
+
meta.objects.length &&
|
|
507
|
+
meta.objects.some(
|
|
508
|
+
(obj) =>
|
|
509
|
+
isDynamicObject(obj.type) &&
|
|
510
|
+
obj.type.properties.some((p) => ProtobufUtil.isUnion(p.value)),
|
|
511
|
+
)
|
|
512
|
+
)
|
|
513
|
+
noSupport("union type in dynamic property");
|
|
514
|
+
//----
|
|
515
|
+
// MAP CASES
|
|
516
|
+
//----
|
|
517
|
+
// KEY TYPE IS UNION
|
|
518
|
+
if (
|
|
519
|
+
meta.maps.length &&
|
|
520
|
+
meta.maps.some((m) => ProtobufUtil.isUnion(m.key))
|
|
521
|
+
)
|
|
522
|
+
noSupport("union key typed map");
|
|
523
|
+
// KEY TYPE IS NOT ATOMIC
|
|
524
|
+
if (
|
|
525
|
+
meta.maps.length &&
|
|
526
|
+
meta.maps.some((m) => ProtobufUtil.getAtomics(m.key).size !== 1)
|
|
527
|
+
)
|
|
528
|
+
noSupport("non-atomic key typed map");
|
|
529
|
+
// MAP TYPE, BUT PROPERTY KEY TYPE IS OPTIONAL
|
|
530
|
+
if (
|
|
531
|
+
meta.maps.length &&
|
|
532
|
+
meta.maps.some((m) => m.key.isRequired() === false || m.key.nullable)
|
|
533
|
+
)
|
|
534
|
+
noSupport("optional key typed map");
|
|
535
|
+
// MAP TYPE, BUT VALUE TYPE IS ARRAY
|
|
536
|
+
if (meta.maps.length && meta.maps.some((m) => !!m.value.arrays.length))
|
|
537
|
+
noSupport("map type with array value type");
|
|
538
|
+
// UNION WITH MAP
|
|
539
|
+
if (meta.size() > 1 && meta.maps.length)
|
|
540
|
+
noSupport("union type with map type");
|
|
541
|
+
// UNION IN MAP
|
|
542
|
+
if (
|
|
543
|
+
meta.maps.length &&
|
|
544
|
+
meta.maps.some((m) => ProtobufUtil.isUnion(m.value))
|
|
545
|
+
)
|
|
546
|
+
noSupport("union type in map value type");
|
|
547
|
+
return errors;
|
|
548
|
+
};
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
/* -----------------------------------------------------------
|
|
552
|
+
SEQUENE VALIDATOR
|
|
553
|
+
----------------------------------------------------------- */
|
|
554
|
+
const validateObject = (next: {
|
|
555
|
+
object: MetadataObjectType;
|
|
556
|
+
errors: string[];
|
|
557
|
+
}): void => {
|
|
558
|
+
for (const property of next.object.properties)
|
|
559
|
+
validateProperty({
|
|
560
|
+
metadata: property.value,
|
|
561
|
+
errors: next.errors,
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
const entire: Map<number, string> = new Map();
|
|
565
|
+
const visitProperty = (p: MetadataProperty) => {
|
|
566
|
+
const local: Set<number> = new Set();
|
|
567
|
+
const tagger = (matrix: IMetadataTypeTag[][]): void => {
|
|
568
|
+
matrix.forEach((tags) => {
|
|
569
|
+
const value: number | null = ProtobufUtil.getSequence(tags);
|
|
570
|
+
if (value !== null) local.add(value);
|
|
571
|
+
});
|
|
572
|
+
};
|
|
573
|
+
for (const c of p.value.constants)
|
|
574
|
+
for (const v of c.values) tagger(v.tags);
|
|
575
|
+
for (const a of p.value.atomics) tagger(a.tags);
|
|
576
|
+
for (const t of p.value.templates) tagger(t.tags);
|
|
577
|
+
for (const o of p.value.objects) tagger(o.tags);
|
|
578
|
+
for (const a of p.value.arrays) tagger(a.tags);
|
|
579
|
+
for (const s of local)
|
|
580
|
+
if (entire.has(s))
|
|
581
|
+
next.errors.push(
|
|
582
|
+
`The Sequence<${s}> tag is duplicated in two properties (${JSON.stringify(entire.get(s))} and ${JSON.stringify(p.key.getSoleLiteral())})`,
|
|
583
|
+
);
|
|
584
|
+
else entire.set(s, p.key.getSoleLiteral()!);
|
|
585
|
+
};
|
|
586
|
+
for (const p of next.object.properties) visitProperty(p);
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
const validateProperty = (next: {
|
|
590
|
+
metadata: Metadata;
|
|
591
|
+
errors: string[];
|
|
592
|
+
}): void => {
|
|
593
|
+
let expected: number = 0;
|
|
594
|
+
const sequences: Set<number> = new Set();
|
|
595
|
+
const add = (value: number): boolean => {
|
|
596
|
+
if (sequences.has(value)) return false;
|
|
597
|
+
sequences.add(value);
|
|
598
|
+
++expected;
|
|
599
|
+
return true;
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
for (const validator of [
|
|
603
|
+
validateBooleanSequence,
|
|
604
|
+
validateNumericSequences({
|
|
605
|
+
type: "bigint",
|
|
606
|
+
default: "int64",
|
|
607
|
+
categories: BIGINT_TYPES,
|
|
608
|
+
}),
|
|
609
|
+
validateNumericSequences({
|
|
610
|
+
type: "number",
|
|
611
|
+
default: "double",
|
|
612
|
+
categories: NUMBER_TYPES,
|
|
613
|
+
}),
|
|
614
|
+
validateStringSequence,
|
|
615
|
+
])
|
|
616
|
+
validator({ metadata: next.metadata, errors: next.errors, add });
|
|
617
|
+
for (const array of next.metadata.arrays)
|
|
618
|
+
validateInstanceSequence({
|
|
619
|
+
type: "array",
|
|
620
|
+
tags: array.tags,
|
|
621
|
+
errors: next.errors,
|
|
622
|
+
add,
|
|
623
|
+
});
|
|
624
|
+
for (const object of next.metadata.objects)
|
|
625
|
+
validateInstanceSequence({
|
|
626
|
+
type: "object",
|
|
627
|
+
tags: object.tags,
|
|
628
|
+
errors: next.errors,
|
|
629
|
+
add,
|
|
630
|
+
});
|
|
631
|
+
for (const map of next.metadata.maps)
|
|
632
|
+
validateInstanceSequence({
|
|
633
|
+
type: "map",
|
|
634
|
+
tags: map.tags,
|
|
635
|
+
errors: next.errors,
|
|
636
|
+
add,
|
|
637
|
+
});
|
|
638
|
+
for (const native of next.metadata.natives)
|
|
639
|
+
if (native.name === "Uint8Array")
|
|
640
|
+
validateInstanceSequence({
|
|
641
|
+
type: "Uint8Array",
|
|
642
|
+
tags: native.tags,
|
|
643
|
+
errors: next.errors,
|
|
644
|
+
add,
|
|
645
|
+
});
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
const validateBooleanSequence = (next: {
|
|
649
|
+
metadata: Metadata;
|
|
650
|
+
errors: string[];
|
|
651
|
+
add: (value: number) => boolean;
|
|
652
|
+
}): void => {
|
|
653
|
+
// PREPARE EMPLACER
|
|
654
|
+
const unique: Set<number> = new Set();
|
|
655
|
+
let expected: number = 0;
|
|
656
|
+
let actual: number = 0;
|
|
657
|
+
const emplace = (matrix: IMetadataTypeTag[][]): void => {
|
|
658
|
+
for (const tags of matrix)
|
|
659
|
+
for (const tag of tags) {
|
|
660
|
+
const sequence = ProtobufUtil.getSequence([tag]);
|
|
661
|
+
if (sequence !== null) {
|
|
662
|
+
unique.add(sequence);
|
|
663
|
+
++actual;
|
|
664
|
+
}
|
|
665
|
+
++expected;
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
// GATHER SEQUENCE TAGS
|
|
670
|
+
for (const atomic of next.metadata.atomics)
|
|
671
|
+
if (atomic.type === "boolean") emplace(atomic.tags);
|
|
672
|
+
for (const constant of next.metadata.constants)
|
|
673
|
+
if (constant.type === "boolean")
|
|
674
|
+
for (const value of constant.values) emplace(value.tags);
|
|
675
|
+
|
|
676
|
+
// PREDICATE
|
|
677
|
+
if (unique.size && actual !== expected)
|
|
678
|
+
next.errors.push(
|
|
679
|
+
`The sequence tag must be declared in every union type members`,
|
|
680
|
+
);
|
|
681
|
+
else if (unique.size > 1)
|
|
682
|
+
next.errors.push(
|
|
683
|
+
`The sequence tag value must be the same in boolean type (including literal types)`,
|
|
684
|
+
);
|
|
685
|
+
else if (unique.size === 1) {
|
|
686
|
+
const value: number = unique.values().next().value!;
|
|
687
|
+
if (next.add(value) === false)
|
|
688
|
+
next.errors.push(
|
|
689
|
+
`The sequence tag value ${value} in boolean type is duplicated with other types`,
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
const validateNumericSequences =
|
|
695
|
+
(config: {
|
|
696
|
+
type: "number" | "bigint";
|
|
697
|
+
default: string;
|
|
698
|
+
categories: Set<string>;
|
|
699
|
+
}) =>
|
|
700
|
+
(next: {
|
|
701
|
+
metadata: Metadata;
|
|
702
|
+
errors: string[];
|
|
703
|
+
add: (value: number) => boolean;
|
|
704
|
+
}): void => {
|
|
705
|
+
// FIND TYPE CATEGORIES
|
|
706
|
+
const categories: Set<string> = new Set();
|
|
707
|
+
const getType = (tags: IMetadataTypeTag[]): string => {
|
|
708
|
+
const found: IMetadataTypeTag | undefined = tags.find(
|
|
709
|
+
(t) => t.kind === "type" && config.categories.has(t.value),
|
|
710
|
+
);
|
|
711
|
+
return found?.value ?? config.default;
|
|
712
|
+
};
|
|
713
|
+
const exploreCategory = (matrix: IMetadataTypeTag[][]): void => {
|
|
714
|
+
for (const tags of matrix) categories.add(getType(tags));
|
|
715
|
+
};
|
|
716
|
+
for (const atomic of next.metadata.atomics)
|
|
717
|
+
if (atomic.type === config.type) exploreCategory(atomic.tags);
|
|
718
|
+
for (const constant of next.metadata.constants)
|
|
719
|
+
if (constant.type === config.type)
|
|
720
|
+
for (const value of constant.values) exploreCategory(value.tags);
|
|
721
|
+
|
|
722
|
+
// ITERATE TYPE CATEGORIES
|
|
723
|
+
for (const category of categories) {
|
|
724
|
+
const unique: Set<number> = new Set();
|
|
725
|
+
let expected: number = 0;
|
|
726
|
+
let actual: number = 0;
|
|
727
|
+
const emplace = (tags: IMetadataTypeTag[]): void => {
|
|
728
|
+
const sequence: number | null = ProtobufUtil.getSequence(tags);
|
|
729
|
+
if (sequence !== null) {
|
|
730
|
+
unique.add(sequence);
|
|
731
|
+
++actual;
|
|
732
|
+
}
|
|
733
|
+
++expected;
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
for (const atomic of next.metadata.atomics)
|
|
737
|
+
if (atomic.type === config.type)
|
|
738
|
+
for (const tags of atomic.tags)
|
|
739
|
+
if (getType(tags) === category) emplace(tags);
|
|
740
|
+
for (const constant of next.metadata.constants)
|
|
741
|
+
if (constant.type === config.type)
|
|
742
|
+
for (const value of constant.values)
|
|
743
|
+
for (const tags of value.tags)
|
|
744
|
+
if (getType(tags) === category) emplace(tags);
|
|
745
|
+
|
|
746
|
+
if (unique.size && actual !== expected) {
|
|
747
|
+
next.errors.push(
|
|
748
|
+
`The sequence tag must be declared in every union type members`,
|
|
749
|
+
);
|
|
750
|
+
} else if (unique.size > 1)
|
|
751
|
+
next.errors.push(
|
|
752
|
+
`The sequence tag value must be the same in ${config.type} type (including literal types)`,
|
|
753
|
+
);
|
|
754
|
+
else if (unique.size === 1) {
|
|
755
|
+
const value: number = unique.values().next().value!;
|
|
756
|
+
if (next.add(value) === false)
|
|
757
|
+
next.errors.push(
|
|
758
|
+
`The sequence tag value ${value} in ${config.type} type is duplicated with other types`,
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
const validateStringSequence = (next: {
|
|
765
|
+
metadata: Metadata;
|
|
766
|
+
errors: string[];
|
|
767
|
+
add: (value: number) => boolean;
|
|
768
|
+
}): void => {
|
|
769
|
+
const unique: Set<number> = new Set();
|
|
770
|
+
let expected: number = 0;
|
|
771
|
+
let actual: number = 0;
|
|
772
|
+
const emplace = (matrix: IMetadataTypeTag[][]): void => {
|
|
773
|
+
for (const tags of matrix)
|
|
774
|
+
for (const tag of tags) {
|
|
775
|
+
const sequence = ProtobufUtil.getSequence([tag]);
|
|
776
|
+
if (sequence !== null) {
|
|
777
|
+
unique.add(sequence);
|
|
778
|
+
++actual;
|
|
779
|
+
}
|
|
780
|
+
++expected;
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
for (const atomic of next.metadata.atomics)
|
|
784
|
+
if (atomic.type === "string") emplace(atomic.tags);
|
|
785
|
+
for (const constant of next.metadata.constants)
|
|
786
|
+
if (constant.type === "string")
|
|
787
|
+
for (const value of constant.values) emplace(value.tags);
|
|
788
|
+
for (const template of next.metadata.templates) emplace(template.tags);
|
|
789
|
+
|
|
790
|
+
if (unique.size && actual !== expected)
|
|
791
|
+
next.errors.push(
|
|
792
|
+
`The sequence tag must be declared in every union type members`,
|
|
793
|
+
);
|
|
794
|
+
else if (unique.size > 1)
|
|
795
|
+
next.errors.push(
|
|
796
|
+
`The sequence tag value must be the same in string types including literal and template types`,
|
|
797
|
+
);
|
|
798
|
+
else if (unique.size === 1) {
|
|
799
|
+
const value: number = unique.values().next().value!;
|
|
800
|
+
if (next.add(value) === false)
|
|
801
|
+
next.errors.push(
|
|
802
|
+
`The sequence tag value ${value} in string type is duplicated with other types`,
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
const validateInstanceSequence = (next: {
|
|
808
|
+
type: "array" | "object" | "map" | "Uint8Array";
|
|
809
|
+
tags: IMetadataTypeTag[][];
|
|
810
|
+
errors: string[];
|
|
811
|
+
add: (value: number) => boolean;
|
|
812
|
+
}): void => {
|
|
813
|
+
const unique: Set<number> = new Set();
|
|
814
|
+
let count: number = 0;
|
|
815
|
+
for (const tags of next.tags) {
|
|
816
|
+
const value: number | null = ProtobufUtil.getSequence(tags);
|
|
817
|
+
if (value === null) continue;
|
|
818
|
+
unique.add(value);
|
|
819
|
+
++count;
|
|
820
|
+
}
|
|
821
|
+
if (unique.size && count !== next.tags.length)
|
|
822
|
+
next.errors.push(
|
|
823
|
+
`The sequence tag must be declared in every union type members`,
|
|
824
|
+
);
|
|
825
|
+
else if (unique.size > 1)
|
|
826
|
+
next.errors.push(
|
|
827
|
+
`The sequence tag value must be the same in ${next.type === "array" ? "an array" : "object"} type.`,
|
|
828
|
+
);
|
|
829
|
+
else if (unique.size === 1) {
|
|
830
|
+
const value: number = unique.values().next().value!;
|
|
831
|
+
if (next.add(value) === false)
|
|
832
|
+
next.errors.push(
|
|
833
|
+
`The sequence tag value ${value} in ${next.type} type is duplicated with other types`,
|
|
834
|
+
);
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
const isDynamicObject = (obj: MetadataObjectType): boolean =>
|
|
840
|
+
obj.properties[0]!.key.isSoleLiteral() === false;
|
|
841
|
+
|
|
842
|
+
const BANNED_NATIVE_TYPES: Map<string, string | null> = new Map([
|
|
843
|
+
["Date", "string"],
|
|
844
|
+
["Boolean", "boolean"],
|
|
845
|
+
["BigInt", "bigint"],
|
|
846
|
+
["Number", "number"],
|
|
847
|
+
["String", "string"],
|
|
848
|
+
...[
|
|
849
|
+
"Buffer",
|
|
850
|
+
"Uint8ClampedArray",
|
|
851
|
+
"Uint16Array",
|
|
852
|
+
"Uint32Array",
|
|
853
|
+
"BigUint64Array",
|
|
854
|
+
"Int8Array",
|
|
855
|
+
"Int16Array",
|
|
856
|
+
"Int32Array",
|
|
857
|
+
"BigInt64Array",
|
|
858
|
+
"Float32Array",
|
|
859
|
+
"Float64Array",
|
|
860
|
+
"DataView",
|
|
861
|
+
"ArrayBuffer",
|
|
862
|
+
"SharedArrayBuffer",
|
|
863
|
+
].map((name) => [name, "Uint8Array"] as const),
|
|
864
|
+
["WeakSet", "Array"],
|
|
865
|
+
["WeakMap", "Map"],
|
|
866
|
+
]);
|
|
867
|
+
const NUMBER_TYPES: Set<string> = new Set([
|
|
868
|
+
"int32",
|
|
869
|
+
"uint32",
|
|
870
|
+
"int64",
|
|
871
|
+
"uint64",
|
|
872
|
+
"float",
|
|
873
|
+
"double",
|
|
874
|
+
]);
|
|
875
|
+
const BIGINT_TYPES = new Set(["int64", "uint64"]);
|