typia 7.0.0-dev.20240930 → 7.0.0-dev.20241001

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.
Files changed (169) hide show
  1. package/lib/index.mjs +25 -25
  2. package/lib/index.mjs.map +1 -1
  3. package/lib/programmers/AssertProgrammer.js +20 -17
  4. package/lib/programmers/AssertProgrammer.js.map +1 -1
  5. package/lib/programmers/CheckerProgrammer.js +274 -216
  6. package/lib/programmers/CheckerProgrammer.js.map +1 -1
  7. package/lib/programmers/FeatureProgrammer.js +16 -8
  8. package/lib/programmers/FeatureProgrammer.js.map +1 -1
  9. package/lib/programmers/IsProgrammer.js +38 -20
  10. package/lib/programmers/IsProgrammer.js.map +1 -1
  11. package/lib/programmers/RandomProgrammer.js +83 -68
  12. package/lib/programmers/RandomProgrammer.js.map +1 -1
  13. package/lib/programmers/TypiaProgrammer.d.ts +2 -2
  14. package/lib/programmers/TypiaProgrammer.js +79 -75
  15. package/lib/programmers/TypiaProgrammer.js.map +1 -1
  16. package/lib/programmers/ValidateProgrammer.js +39 -17
  17. package/lib/programmers/ValidateProgrammer.js.map +1 -1
  18. package/lib/programmers/helpers/CloneJoiner.js +4 -1
  19. package/lib/programmers/helpers/CloneJoiner.js.map +1 -1
  20. package/lib/programmers/helpers/NotationJoiner.d.ts +2 -1
  21. package/lib/programmers/helpers/NotationJoiner.js +34 -33
  22. package/lib/programmers/helpers/NotationJoiner.js.map +1 -1
  23. package/lib/programmers/helpers/PruneJoiner.js +4 -1
  24. package/lib/programmers/helpers/PruneJoiner.js.map +1 -1
  25. package/lib/programmers/helpers/RandomJoiner.d.ts +1 -1
  26. package/lib/programmers/helpers/RandomJoiner.js.map +1 -1
  27. package/lib/programmers/helpers/RandomRanger.js.map +1 -1
  28. package/lib/programmers/helpers/StringifyJoinder.js +4 -1
  29. package/lib/programmers/helpers/StringifyJoinder.js.map +1 -1
  30. package/lib/programmers/helpers/StringifyPredicator.d.ts +1 -1
  31. package/lib/programmers/helpers/StringifyPredicator.js +4 -3
  32. package/lib/programmers/helpers/StringifyPredicator.js.map +1 -1
  33. package/lib/programmers/helpers/UnionExplorer.d.ts +52 -12
  34. package/lib/programmers/helpers/UnionExplorer.js +183 -144
  35. package/lib/programmers/helpers/UnionExplorer.js.map +1 -1
  36. package/lib/programmers/helpers/UnionPredicator.d.ts +1 -1
  37. package/lib/programmers/helpers/UnionPredicator.js +7 -7
  38. package/lib/programmers/http/HttpFormDataProgrammer.js +77 -70
  39. package/lib/programmers/http/HttpFormDataProgrammer.js.map +1 -1
  40. package/lib/programmers/http/HttpHeadersProgrammer.js +69 -68
  41. package/lib/programmers/http/HttpHeadersProgrammer.js.map +1 -1
  42. package/lib/programmers/http/HttpQueryProgrammer.js +69 -62
  43. package/lib/programmers/http/HttpQueryProgrammer.js.map +1 -1
  44. package/lib/programmers/internal/application_escaped.js +4 -4
  45. package/lib/programmers/internal/application_escaped.js.map +1 -1
  46. package/lib/programmers/internal/application_templates.js +8 -2
  47. package/lib/programmers/internal/application_templates.js.map +1 -1
  48. package/lib/programmers/internal/application_union_discriminator.d.ts +1 -1
  49. package/lib/programmers/internal/application_union_discriminator.js +6 -6
  50. package/lib/programmers/internal/application_union_discriminator.js.map +1 -1
  51. package/lib/programmers/internal/application_v30_object.js +6 -3
  52. package/lib/programmers/internal/application_v30_object.js.map +1 -1
  53. package/lib/programmers/internal/application_v31_object.js +4 -1
  54. package/lib/programmers/internal/application_v31_object.js.map +1 -1
  55. package/lib/programmers/internal/check_array_length.js +21 -26
  56. package/lib/programmers/internal/check_array_length.js.map +1 -1
  57. package/lib/programmers/internal/check_bigint.js +18 -26
  58. package/lib/programmers/internal/check_bigint.js.map +1 -1
  59. package/lib/programmers/internal/check_dynamic_key.d.ts +1 -5
  60. package/lib/programmers/internal/check_dynamic_key.js +109 -91
  61. package/lib/programmers/internal/check_dynamic_key.js.map +1 -1
  62. package/lib/programmers/internal/check_dynamic_properties.js +88 -90
  63. package/lib/programmers/internal/check_dynamic_properties.js.map +1 -1
  64. package/lib/programmers/internal/check_native.js +8 -5
  65. package/lib/programmers/internal/check_native.js.map +1 -1
  66. package/lib/programmers/internal/check_number.js +59 -65
  67. package/lib/programmers/internal/check_number.js.map +1 -1
  68. package/lib/programmers/internal/check_object.js +31 -22
  69. package/lib/programmers/internal/check_object.js.map +1 -1
  70. package/lib/programmers/internal/check_string.js +18 -26
  71. package/lib/programmers/internal/check_string.js.map +1 -1
  72. package/lib/programmers/internal/check_template.js +20 -21
  73. package/lib/programmers/internal/check_template.js.map +1 -1
  74. package/lib/programmers/internal/check_union_array_like.js +68 -53
  75. package/lib/programmers/internal/check_union_array_like.js.map +1 -1
  76. package/lib/programmers/internal/decode_union_object.js +59 -49
  77. package/lib/programmers/internal/decode_union_object.js.map +1 -1
  78. package/lib/programmers/internal/feature_object_entries.js +31 -37
  79. package/lib/programmers/internal/feature_object_entries.js.map +1 -1
  80. package/lib/programmers/internal/llm_schema_escaped.js +29 -11
  81. package/lib/programmers/internal/llm_schema_escaped.js.map +1 -1
  82. package/lib/programmers/internal/llm_schema_object.js +4 -1
  83. package/lib/programmers/internal/llm_schema_object.js.map +1 -1
  84. package/lib/programmers/internal/metadata_to_pattern.js +44 -41
  85. package/lib/programmers/internal/metadata_to_pattern.js.map +1 -1
  86. package/lib/programmers/internal/postfix_of_tuple.d.ts +1 -1
  87. package/lib/programmers/internal/postfix_of_tuple.js +3 -0
  88. package/lib/programmers/internal/postfix_of_tuple.js.map +1 -1
  89. package/lib/programmers/internal/prune_object_properties.js +6 -3
  90. package/lib/programmers/internal/prune_object_properties.js.map +1 -1
  91. package/lib/programmers/internal/random_custom.js +8 -14
  92. package/lib/programmers/internal/random_custom.js.map +1 -1
  93. package/lib/programmers/internal/stringify_dynamic_properties.js +4 -1
  94. package/lib/programmers/internal/stringify_dynamic_properties.js.map +1 -1
  95. package/lib/programmers/internal/stringify_regular_properties.js +4 -4
  96. package/lib/programmers/internal/stringify_regular_properties.js.map +1 -1
  97. package/lib/programmers/internal/template_to_pattern.js +10 -5
  98. package/lib/programmers/internal/template_to_pattern.js.map +1 -1
  99. package/lib/programmers/internal/wrap_metadata_rest_tuple.d.ts +1 -2
  100. package/lib/programmers/internal/wrap_metadata_rest_tuple.js +3 -0
  101. package/lib/programmers/internal/wrap_metadata_rest_tuple.js.map +1 -1
  102. package/lib/programmers/json/JsonStringifyProgrammer.js +76 -52
  103. package/lib/programmers/json/JsonStringifyProgrammer.js.map +1 -1
  104. package/lib/programmers/misc/MiscCloneProgrammer.js +143 -115
  105. package/lib/programmers/misc/MiscCloneProgrammer.js.map +1 -1
  106. package/lib/programmers/misc/MiscPruneProgrammer.js +65 -50
  107. package/lib/programmers/misc/MiscPruneProgrammer.js.map +1 -1
  108. package/lib/programmers/notations/NotationGeneralProgrammer.d.ts +4 -1
  109. package/lib/programmers/notations/NotationGeneralProgrammer.js +166 -115
  110. package/lib/programmers/notations/NotationGeneralProgrammer.js.map +1 -1
  111. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js +32 -24
  112. package/lib/programmers/protobuf/ProtobufEncodeProgrammer.js.map +1 -1
  113. package/lib/utils/NamingConvention/NamingConvention.js +41 -47
  114. package/lib/utils/NamingConvention/NamingConvention.js.map +1 -1
  115. package/package.json +1 -1
  116. package/src/programmers/AssertProgrammer.ts +30 -27
  117. package/src/programmers/CheckerProgrammer.ts +279 -248
  118. package/src/programmers/FeatureProgrammer.ts +17 -15
  119. package/src/programmers/IsProgrammer.ts +34 -20
  120. package/src/programmers/RandomProgrammer.ts +18 -9
  121. package/src/programmers/TypiaProgrammer.ts +48 -34
  122. package/src/programmers/ValidateProgrammer.ts +50 -27
  123. package/src/programmers/helpers/CloneJoiner.ts +4 -1
  124. package/src/programmers/helpers/NotationJoiner.ts +85 -83
  125. package/src/programmers/helpers/ProtobufUtil.ts +2 -2
  126. package/src/programmers/helpers/PruneJoiner.ts +4 -1
  127. package/src/programmers/helpers/RandomJoiner.ts +5 -2
  128. package/src/programmers/helpers/RandomRanger.ts +8 -1
  129. package/src/programmers/helpers/StringifyJoinder.ts +4 -1
  130. package/src/programmers/helpers/StringifyPredicator.ts +4 -3
  131. package/src/programmers/helpers/UnionExplorer.ts +279 -202
  132. package/src/programmers/helpers/UnionPredicator.ts +5 -5
  133. package/src/programmers/http/HttpFormDataProgrammer.ts +135 -114
  134. package/src/programmers/http/HttpHeadersProgrammer.ts +145 -120
  135. package/src/programmers/http/HttpQueryProgrammer.ts +137 -116
  136. package/src/programmers/internal/application_escaped.ts +6 -6
  137. package/src/programmers/internal/application_templates.ts +8 -6
  138. package/src/programmers/internal/application_union_discriminator.ts +6 -6
  139. package/src/programmers/internal/application_v30_object.ts +6 -3
  140. package/src/programmers/internal/application_v31_object.ts +4 -1
  141. package/src/programmers/internal/application_v31_tuple.ts +1 -1
  142. package/src/programmers/internal/check_array_length.ts +31 -30
  143. package/src/programmers/internal/check_bigint.ts +31 -31
  144. package/src/programmers/internal/check_dynamic_key.ts +155 -126
  145. package/src/programmers/internal/check_dynamic_properties.ts +152 -154
  146. package/src/programmers/internal/check_native.ts +11 -5
  147. package/src/programmers/internal/check_number.ts +88 -84
  148. package/src/programmers/internal/check_object.ts +45 -31
  149. package/src/programmers/internal/check_string.ts +31 -30
  150. package/src/programmers/internal/check_template.ts +34 -32
  151. package/src/programmers/internal/check_union_array_like.ts +245 -228
  152. package/src/programmers/internal/decode_union_object.ts +92 -75
  153. package/src/programmers/internal/feature_object_entries.ts +43 -46
  154. package/src/programmers/internal/llm_schema_escaped.ts +36 -13
  155. package/src/programmers/internal/llm_schema_object.ts +4 -1
  156. package/src/programmers/internal/metadata_to_pattern.ts +31 -23
  157. package/src/programmers/internal/postfix_of_tuple.ts +3 -0
  158. package/src/programmers/internal/prune_object_properties.ts +6 -3
  159. package/src/programmers/internal/random_custom.ts +24 -23
  160. package/src/programmers/internal/stringify_dynamic_properties.ts +4 -1
  161. package/src/programmers/internal/stringify_regular_properties.ts +7 -7
  162. package/src/programmers/internal/template_to_pattern.ts +12 -4
  163. package/src/programmers/internal/wrap_metadata_rest_tuple.ts +3 -0
  164. package/src/programmers/json/JsonStringifyProgrammer.ts +71 -51
  165. package/src/programmers/misc/MiscCloneProgrammer.ts +156 -132
  166. package/src/programmers/misc/MiscPruneProgrammer.ts +61 -49
  167. package/src/programmers/notations/NotationGeneralProgrammer.ts +193 -144
  168. package/src/programmers/protobuf/ProtobufEncodeProgrammer.ts +25 -21
  169. package/src/utils/NamingConvention/NamingConvention.ts +40 -42
@@ -51,7 +51,10 @@ export namespace HttpFormDataProgrammer {
51
51
 
52
52
  // DO TRANSFORM
53
53
  const object: MetadataObject = result.data.objects[0]!;
54
- const statements: ts.Statement[] = decode_object(props.importer)(object);
54
+ const statements: ts.Statement[] = decode_object({
55
+ importer: props.importer,
56
+ object,
57
+ });
55
58
  return {
56
59
  functions: {},
57
60
  statements: [],
@@ -154,126 +157,144 @@ export namespace HttpFormDataProgrammer {
154
157
  return errors;
155
158
  };
156
159
 
157
- const decode_object =
158
- (importer: FunctionImporter) =>
159
- (object: MetadataObject): ts.Statement[] => {
160
- // const input: ts.Identifier = ts.factory.createIdentifier("input");
161
- const output: ts.Identifier = ts.factory.createIdentifier("output");
162
- return [
163
- StatementFactory.constant(
164
- "output",
165
- ts.factory.createObjectLiteralExpression(
166
- object.properties.map((prop) =>
167
- decode_regular_property(importer)(prop),
168
- ),
169
- true,
160
+ const decode_object = (props: {
161
+ importer: FunctionImporter;
162
+ object: MetadataObject;
163
+ }): ts.Statement[] => {
164
+ // const input: ts.Identifier = ts.factory.createIdentifier("input");
165
+ const output: ts.Identifier = ts.factory.createIdentifier("output");
166
+ return [
167
+ StatementFactory.constant(
168
+ "output",
169
+ ts.factory.createObjectLiteralExpression(
170
+ props.object.properties.map((p) =>
171
+ decode_regular_property({
172
+ importer: props.importer,
173
+ property: p,
174
+ }),
170
175
  ),
176
+ true,
171
177
  ),
172
- ts.factory.createReturnStatement(
173
- ts.factory.createAsExpression(output, TypeFactory.keyword("any")),
174
- ),
175
- ];
176
- };
178
+ ),
179
+ ts.factory.createReturnStatement(
180
+ ts.factory.createAsExpression(output, TypeFactory.keyword("any")),
181
+ ),
182
+ ];
183
+ };
177
184
 
178
- const decode_regular_property =
179
- (importer: FunctionImporter) =>
180
- (property: MetadataProperty): ts.PropertyAssignment => {
181
- const key: string = property.key.constants[0]!.values[0]!.value as string;
182
- const value: Metadata = property.value;
185
+ const decode_regular_property = (props: {
186
+ importer: FunctionImporter;
187
+ property: MetadataProperty;
188
+ }): ts.PropertyAssignment => {
189
+ const key: string = props.property.key.constants[0]!.values[0]!
190
+ .value as string;
191
+ const value: Metadata = props.property.value;
183
192
 
184
- const [type, isArray]: [Atomic.Literal | "blob" | "file", boolean] = value
185
- .atomics.length
186
- ? [value.atomics[0]!.type, false]
187
- : value.constants.length
188
- ? [value.constants[0]!.type, false]
189
- : value.templates.length
190
- ? ["string", false]
191
- : value.natives.includes("Blob")
192
- ? ["blob", false]
193
- : value.natives.includes("File")
194
- ? ["file", false]
195
- : (() => {
196
- const meta =
197
- value.arrays[0]?.type.value ??
198
- value.tuples[0]!.type.elements[0]!;
199
- return meta.atomics.length
200
- ? [meta.atomics[0]!.type, true]
201
- : meta.templates.length
202
- ? ["string", true]
203
- : meta.natives.includes("Blob")
204
- ? ["blob", true]
205
- : meta.natives.includes("File")
206
- ? ["file", true]
207
- : [meta.constants[0]!.type, true];
208
- })();
209
- return ts.factory.createPropertyAssignment(
210
- Escaper.variable(key) ? key : ts.factory.createStringLiteral(key),
211
- isArray
212
- ? decode_array(importer)(value)(
213
- ts.factory.createCallExpression(
214
- IdentifierFactory.access(
215
- ts.factory.createCallExpression(
216
- ts.factory.createIdentifier("input.getAll"),
217
- undefined,
218
- [ts.factory.createStringLiteral(key)],
219
- ),
220
- )("map"),
221
- undefined,
222
- [
223
- ts.factory.createArrowFunction(
224
- undefined,
225
- undefined,
226
- [IdentifierFactory.parameter("elem")],
227
- undefined,
228
- undefined,
229
- decode_value(importer)(type)(false)(
230
- ts.factory.createIdentifier("elem"),
231
- ),
232
- ),
233
- ],
234
- ),
235
- )
236
- : decode_value(importer)(type)(
237
- value.nullable === false && value.isRequired() === false,
238
- )(
239
- ts.factory.createCallExpression(
240
- ts.factory.createIdentifier("input.get"),
241
- undefined,
242
- [ts.factory.createStringLiteral(key)],
243
- ),
193
+ const [type, isArray]: [Atomic.Literal | "blob" | "file", boolean] = value
194
+ .atomics.length
195
+ ? [value.atomics[0]!.type, false]
196
+ : value.constants.length
197
+ ? [value.constants[0]!.type, false]
198
+ : value.templates.length
199
+ ? ["string", false]
200
+ : value.natives.includes("Blob")
201
+ ? ["blob", false]
202
+ : value.natives.includes("File")
203
+ ? ["file", false]
204
+ : (() => {
205
+ const meta =
206
+ value.arrays[0]?.type.value ??
207
+ value.tuples[0]!.type.elements[0]!;
208
+ return meta.atomics.length
209
+ ? [meta.atomics[0]!.type, true]
210
+ : meta.templates.length
211
+ ? ["string", true]
212
+ : meta.natives.includes("Blob")
213
+ ? ["blob", true]
214
+ : meta.natives.includes("File")
215
+ ? ["file", true]
216
+ : [meta.constants[0]!.type, true];
217
+ })();
218
+ return ts.factory.createPropertyAssignment(
219
+ Escaper.variable(key) ? key : ts.factory.createStringLiteral(key),
220
+ isArray
221
+ ? decode_array({
222
+ importer: props.importer,
223
+ metadata: value,
224
+ input: ts.factory.createCallExpression(
225
+ IdentifierFactory.access(
226
+ ts.factory.createCallExpression(
227
+ ts.factory.createIdentifier("input.getAll"),
228
+ undefined,
229
+ [ts.factory.createStringLiteral(key)],
230
+ ),
231
+ )("map"),
232
+ undefined,
233
+ [
234
+ ts.factory.createArrowFunction(
235
+ undefined,
236
+ undefined,
237
+ [IdentifierFactory.parameter("elem")],
238
+ undefined,
239
+ undefined,
240
+ decode_value({
241
+ importer: props.importer,
242
+ type,
243
+ coalesce: false,
244
+ input: ts.factory.createIdentifier("elem"),
245
+ }),
246
+ ),
247
+ ],
244
248
  ),
245
- );
246
- };
249
+ })
250
+ : decode_value({
251
+ importer: props.importer,
252
+ type,
253
+ coalesce: value.nullable === false && value.isRequired() === false,
254
+ input: ts.factory.createCallExpression(
255
+ ts.factory.createIdentifier("input.get"),
256
+ undefined,
257
+ [ts.factory.createStringLiteral(key)],
258
+ ),
259
+ }),
260
+ );
261
+ };
247
262
 
248
- const decode_value =
249
- (importer: FunctionImporter) =>
250
- (type: Atomic.Literal | "blob" | "file") =>
251
- (onlyUndefindable: boolean) =>
252
- (value: ts.Expression) => {
253
- const call = ts.factory.createCallExpression(
254
- importer.use(type),
255
- undefined,
256
- [value],
257
- );
258
- return onlyUndefindable
259
- ? ts.factory.createBinaryExpression(
260
- call,
261
- ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
262
- ts.factory.createIdentifier("undefined"),
263
- )
264
- : call;
265
- };
263
+ const decode_value = (props: {
264
+ importer: FunctionImporter;
265
+ type: Atomic.Literal | "blob" | "file";
266
+ coalesce: boolean;
267
+ input: ts.Expression;
268
+ }) => {
269
+ const call = ts.factory.createCallExpression(
270
+ props.importer.use(props.type),
271
+ undefined,
272
+ [props.input],
273
+ );
274
+ return props.coalesce
275
+ ? ts.factory.createBinaryExpression(
276
+ call,
277
+ ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
278
+ ts.factory.createIdentifier("undefined"),
279
+ )
280
+ : call;
281
+ };
266
282
 
267
- const decode_array =
268
- (importer: FunctionImporter) =>
269
- (value: Metadata) =>
270
- (expression: ts.Expression): ts.Expression =>
271
- value.nullable || value.isRequired() === false
272
- ? ts.factory.createCallExpression(importer.use("array"), undefined, [
273
- expression,
274
- value.nullable
283
+ const decode_array = (props: {
284
+ importer: FunctionImporter;
285
+ metadata: Metadata;
286
+ input: ts.Expression;
287
+ }): ts.Expression =>
288
+ props.metadata.nullable || props.metadata.isRequired() === false
289
+ ? ts.factory.createCallExpression(
290
+ props.importer.use("array"),
291
+ undefined,
292
+ [
293
+ props.input,
294
+ props.metadata.nullable
275
295
  ? ts.factory.createNull()
276
296
  : ts.factory.createIdentifier("undefined"),
277
- ])
278
- : expression;
297
+ ],
298
+ )
299
+ : props.input;
279
300
  }
@@ -55,7 +55,10 @@ export namespace HttpHeadersProgrammer {
55
55
 
56
56
  // DO TRANSFORM
57
57
  const object: MetadataObject = result.data.objects[0]!;
58
- const statements: ts.Statement[] = decode_object(props.importer)(object);
58
+ const statements: ts.Statement[] = decode_object({
59
+ importer: props.importer,
60
+ object,
61
+ });
59
62
  return {
60
63
  functions: {},
61
64
  statements: [],
@@ -195,135 +198,157 @@ export namespace HttpHeadersProgrammer {
195
198
  return errors;
196
199
  };
197
200
 
198
- const decode_object =
199
- (importer: FunctionImporter) =>
200
- (object: MetadataObject): ts.Statement[] => {
201
- const output: ts.Identifier = ts.factory.createIdentifier("output");
202
- const optionals: string[] = [];
203
- return [
204
- StatementFactory.constant(
205
- "output",
206
- ts.factory.createObjectLiteralExpression(
207
- object.properties.map((prop) => {
208
- if (
209
- !prop.value.isRequired() &&
210
- prop.value.arrays.length + prop.value.tuples.length > 0
211
- )
212
- optionals.push(
213
- prop.key.constants[0]!.values[0]!.value as string,
214
- );
215
- return decode_regular_property(importer)(prop);
216
- }),
217
- true,
218
- ),
219
- ),
220
- ...optionals.map((key) => {
221
- const access = IdentifierFactory.access(output)(key);
222
- return ts.factory.createIfStatement(
223
- ts.factory.createStrictEquality(
224
- ExpressionFactory.number(0),
225
- IdentifierFactory.access(access)("length"),
226
- ),
227
- ts.factory.createExpressionStatement(
228
- ts.factory.createDeleteExpression(access),
229
- ),
230
- );
231
- }),
232
- ts.factory.createReturnStatement(
233
- ts.factory.createAsExpression(output, TypeFactory.keyword("any")),
201
+ const decode_object = (props: {
202
+ importer: FunctionImporter;
203
+ object: MetadataObject;
204
+ }): ts.Statement[] => {
205
+ const output: ts.Identifier = ts.factory.createIdentifier("output");
206
+ const optionals: string[] = [];
207
+ return [
208
+ StatementFactory.constant(
209
+ "output",
210
+ ts.factory.createObjectLiteralExpression(
211
+ props.object.properties.map((p) => {
212
+ if (
213
+ !p.value.isRequired() &&
214
+ p.value.arrays.length + p.value.tuples.length > 0
215
+ )
216
+ optionals.push(p.key.constants[0]!.values[0]!.value as string);
217
+ return decode_regular_property({
218
+ importer: props.importer,
219
+ property: p,
220
+ });
221
+ }),
222
+ true,
234
223
  ),
235
- ];
236
- };
224
+ ),
225
+ ...optionals.map((key) => {
226
+ const access = IdentifierFactory.access(output)(key);
227
+ return ts.factory.createIfStatement(
228
+ ts.factory.createStrictEquality(
229
+ ExpressionFactory.number(0),
230
+ IdentifierFactory.access(access)("length"),
231
+ ),
232
+ ts.factory.createExpressionStatement(
233
+ ts.factory.createDeleteExpression(access),
234
+ ),
235
+ );
236
+ }),
237
+ ts.factory.createReturnStatement(
238
+ ts.factory.createAsExpression(output, TypeFactory.keyword("any")),
239
+ ),
240
+ ];
241
+ };
237
242
 
238
- const decode_regular_property =
239
- (importer: FunctionImporter) =>
240
- (property: MetadataProperty): ts.PropertyAssignment => {
241
- const key: string = property.key.constants[0]!.values[0]!.value as string;
242
- const value: Metadata = property.value;
243
+ const decode_regular_property = (props: {
244
+ importer: FunctionImporter;
245
+ property: MetadataProperty;
246
+ }): ts.PropertyAssignment => {
247
+ const key: string = props.property.key.constants[0]!.values[0]!
248
+ .value as string;
249
+ const value: Metadata = props.property.value;
243
250
 
244
- const [type, isArray]: [Atomic.Literal, boolean] = value.atomics.length
245
- ? [value.atomics[0]!.type, false]
246
- : value.constants.length
247
- ? [value.constants[0]!.type, false]
248
- : value.templates.length
249
- ? ["string", false]
250
- : (() => {
251
- const meta: Metadata =
252
- value.arrays[0]?.type.value ??
253
- value.tuples[0]!.type.elements[0]!;
254
- return meta.atomics.length
255
- ? [meta.atomics[0]!.type, true]
256
- : meta.templates.length
257
- ? ["string", true]
258
- : [meta.constants[0]!.type, true];
259
- })();
260
- const accessor = IdentifierFactory.access(
261
- ts.factory.createIdentifier("input"),
262
- )(key.toLowerCase());
251
+ const [type, isArray]: [Atomic.Literal, boolean] = value.atomics.length
252
+ ? [value.atomics[0]!.type, false]
253
+ : value.constants.length
254
+ ? [value.constants[0]!.type, false]
255
+ : value.templates.length
256
+ ? ["string", false]
257
+ : (() => {
258
+ const meta: Metadata =
259
+ value.arrays[0]?.type.value ??
260
+ value.tuples[0]!.type.elements[0]!;
261
+ return meta.atomics.length
262
+ ? [meta.atomics[0]!.type, true]
263
+ : meta.templates.length
264
+ ? ["string", true]
265
+ : [meta.constants[0]!.type, true];
266
+ })();
267
+ const input = IdentifierFactory.access(
268
+ ts.factory.createIdentifier("input"),
269
+ )(key.toLowerCase());
263
270
 
264
- return ts.factory.createPropertyAssignment(
265
- Escaper.variable(key) ? key : ts.factory.createStringLiteral(key),
266
- isArray
267
- ? key === "set-cookie"
268
- ? accessor
269
- : decode_array(importer)(type)(key)(value)(accessor)
270
- : decode_value(importer)(type)(accessor),
271
- );
272
- };
271
+ return ts.factory.createPropertyAssignment(
272
+ Escaper.variable(key) ? key : ts.factory.createStringLiteral(key),
273
+ isArray
274
+ ? key === "set-cookie"
275
+ ? input
276
+ : decode_array({
277
+ importer: props.importer,
278
+ type,
279
+ key,
280
+ value,
281
+ input,
282
+ })
283
+ : decode_value({
284
+ importer: props.importer,
285
+ type,
286
+ input,
287
+ }),
288
+ );
289
+ };
273
290
 
274
- const decode_value =
275
- (importer: FunctionImporter) =>
276
- (type: Atomic.Literal) =>
277
- (value: ts.Expression) =>
278
- type === "string"
279
- ? value
280
- : ts.factory.createCallExpression(importer.use(type), undefined, [
281
- value,
282
- ]);
291
+ const decode_value = (props: {
292
+ importer: FunctionImporter;
293
+ type: Atomic.Literal;
294
+ input: ts.Expression;
295
+ }) =>
296
+ props.type === "string"
297
+ ? props.input
298
+ : ts.factory.createCallExpression(
299
+ props.importer.use(props.type),
300
+ undefined,
301
+ [props.input],
302
+ );
283
303
 
284
- const decode_array =
285
- (importer: FunctionImporter) =>
286
- (type: Atomic.Literal) =>
287
- (key: string) =>
288
- (value: Metadata) =>
289
- (accessor: ts.Expression) => {
290
- const split: ts.CallChain = ts.factory.createCallChain(
291
- ts.factory.createPropertyAccessChain(
292
- ts.factory.createCallChain(
293
- ts.factory.createPropertyAccessChain(
294
- accessor,
295
- ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
296
- ts.factory.createIdentifier("split"),
297
- ),
298
- undefined,
299
- undefined,
300
- [ts.factory.createStringLiteral(key === "cookie" ? "; " : ", ")],
304
+ const decode_array = (props: {
305
+ importer: FunctionImporter;
306
+ type: Atomic.Literal;
307
+ key: string;
308
+ value: Metadata;
309
+ input: ts.Expression;
310
+ }) => {
311
+ const split: ts.CallChain = ts.factory.createCallChain(
312
+ ts.factory.createPropertyAccessChain(
313
+ ts.factory.createCallChain(
314
+ ts.factory.createPropertyAccessChain(
315
+ props.input,
316
+ ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
317
+ ts.factory.createIdentifier("split"),
301
318
  ),
302
- ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
303
- ts.factory.createIdentifier("map"),
304
- ),
305
- undefined,
306
- undefined,
307
- [importer.use(type)],
308
- );
309
- return ts.factory.createConditionalExpression(
310
- ExpressionFactory.isArray(accessor),
311
- undefined,
312
- ts.factory.createCallExpression(
313
- IdentifierFactory.access(accessor)("map"),
314
319
  undefined,
315
- [importer.use(type)],
320
+ undefined,
321
+ [
322
+ ts.factory.createStringLiteral(
323
+ props.key === "cookie" ? "; " : ", ",
324
+ ),
325
+ ],
316
326
  ),
327
+ ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
328
+ ts.factory.createIdentifier("map"),
329
+ ),
330
+ undefined,
331
+ undefined,
332
+ [props.importer.use(props.type)],
333
+ );
334
+ return ts.factory.createConditionalExpression(
335
+ ExpressionFactory.isArray(props.input),
336
+ undefined,
337
+ ts.factory.createCallExpression(
338
+ IdentifierFactory.access(props.input)("map"),
317
339
  undefined,
318
- value.isRequired() === false
319
- ? split
320
- : ts.factory.createBinaryExpression(
321
- split,
322
- ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
323
- ts.factory.createArrayLiteralExpression([], false),
324
- ),
325
- );
326
- };
340
+ [props.importer.use(props.type)],
341
+ ),
342
+ undefined,
343
+ props.value.isRequired() === false
344
+ ? split
345
+ : ts.factory.createBinaryExpression(
346
+ split,
347
+ ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
348
+ ts.factory.createArrayLiteralExpression([], false),
349
+ ),
350
+ );
351
+ };
327
352
  }
328
353
 
329
354
  const SINGULAR: Set<string> = new Set([