@kizunajs/swift 2.0.0-beta.17 → 2.0.0-beta.19

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/dist/cli.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_generator = require("./generator-E0WQFf92.cjs");
2
+ const require_generator = require("./generator-DBNFuaBB.cjs");
3
3
  let node_fs = require("node:fs");
4
4
  let node_path = require("node:path");
5
5
  let node_util = require("node:util");
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as generateSwiftClient } from "./generator-CxUzLmbK.mjs";
2
+ import { t as generateSwiftClient } from "./generator-CjCPSdEz.mjs";
3
3
  import { mkdirSync, writeFileSync } from "node:fs";
4
4
  import { dirname, resolve } from "node:path";
5
5
  import { parseArgs } from "node:util";
@@ -125,6 +125,7 @@ const objectFields = (schema, registry, hint, shape = readObjectShape(schema) ??
125
125
  wireName: key,
126
126
  type: result.expression,
127
127
  optional: result.optional,
128
+ requiredNullable: result.requiredNullable,
128
129
  description: readMetaDescription(value),
129
130
  isFile: result.isFile,
130
131
  deprecated: deprecation !== void 0,
@@ -236,6 +237,7 @@ const mapUnbrandedType = (schema, registry, hint) => {
236
237
  return {
237
238
  expression: innerResult.expression.endsWith("?") ? innerResult.expression : `${innerResult.expression}?`,
238
239
  optional: true,
240
+ requiredNullable: nullable && !optional,
239
241
  isFile: innerResult.isFile
240
242
  };
241
243
  }
@@ -420,6 +422,7 @@ const sanitizeCaseName = (literal) => {
420
422
  const collectObjectFields = (schema, registry, hint) => {
421
423
  return objectFields(schema, registry, hint);
422
424
  };
425
+ const hasDefault = (field) => field.optional && field.requiredNullable !== true;
423
426
  const objectFieldCount = (schema) => {
424
427
  return Object.keys(readObjectShape(schema) ?? {}).length;
425
428
  };
@@ -696,6 +699,10 @@ const sanitizeEnumCaseName = (value) => {
696
699
  if (!camel) return "_";
697
700
  return /^[0-9]/.test(camel) ? `_${camel}` : camel;
698
701
  };
702
+ const defaultArgument = (field) => {
703
+ if (!hasDefault(field)) return "";
704
+ return " = nil";
705
+ };
699
706
  const optionalize = (type, optional) => {
700
707
  if (!optional) return type;
701
708
  return type.endsWith("?") ? type : `${type}?`;
@@ -710,7 +717,7 @@ const emitNamedFactory = (writer, factoryName, fields, buildExpression) => {
710
717
  }
711
718
  const params = fields.map((field) => {
712
719
  const typeExpression = optionalize(field.type, field.optional);
713
- const defaultPart = field.optional ? " = nil" : "";
720
+ const defaultPart = defaultArgument(field);
714
721
  return `${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
715
722
  });
716
723
  const args = fields.map((field) => `${field.name}: ${escapeKeyword(field.name)}`).join(", ");
@@ -733,7 +740,7 @@ const emitMemberwiseInit = (writer, fields, assignmentTarget = (field) => escape
733
740
  }
734
741
  const params = fields.map((field) => {
735
742
  const typeExpression = optionalize(field.type, field.optional);
736
- const defaultPart = field.optional ? " = nil" : "";
743
+ const defaultPart = defaultArgument(field);
737
744
  return `${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
738
745
  });
739
746
  if (params.length === 1) {
@@ -867,7 +874,9 @@ const emitStruct = (writer, type, context, ownedTypeMap, ownedTypeLookup, regist
867
874
  ...field,
868
875
  type: resolveOwnedType(field.type)
869
876
  }));
870
- const needsCodingKeys = !hasFile && type.fields.some((field) => field.name !== field.wireName || SWIFT_KEYWORDS.has(field.name) || field.deprecated === true);
877
+ const needsEncode = !hasFile && type.fields.some((field) => field.requiredNullable === true);
878
+ const needsCodingKeys = needsEncode || !hasFile && type.fields.some((field) => field.name !== field.wireName || SWIFT_KEYWORDS.has(field.name) || field.deprecated === true);
879
+ const storageName = (field) => field.deprecated ? deprecatedStorageName(field, type.fields) : escapeKeyword(field.name);
871
880
  writer.block(`public struct ${type.name}: ${conformances}`, () => {
872
881
  emitOwnedTypes(writer, lookupName, context, ownedTypeMap, ownedTypeLookup);
873
882
  for (const field of type.fields) {
@@ -890,8 +899,18 @@ const emitStruct = (writer, type, context, ownedTypeMap, ownedTypeLookup, regist
890
899
  else writer.line(`case ${escapeKeyword(field.name)} = ${stringLiteral(field.wireName)}`);
891
900
  });
892
901
  }
902
+ if (needsEncode) {
903
+ writer.blank();
904
+ writer.block("public func encode(to encoder: Encoder) throws", () => {
905
+ writer.line("var container = encoder.container(keyedBy: CodingKeys.self)");
906
+ for (const field of type.fields) {
907
+ const encodeCall = field.optional && field.requiredNullable !== true ? "encodeIfPresent" : "encode";
908
+ writer.line(`try container.${encodeCall}(${storageName(field)}, forKey: .${storageName(field)})`);
909
+ }
910
+ });
911
+ }
893
912
  writer.blank();
894
- emitMemberwiseInit(writer, adjustedFields, (field) => field.deprecated ? deprecatedStorageName(field, type.fields) : escapeKeyword(field.name));
913
+ emitMemberwiseInit(writer, adjustedFields, storageName);
895
914
  });
896
915
  };
897
916
  /**
@@ -929,7 +948,7 @@ const emitDiscriminatedEnum = (writer, type, context, registryName, ownedTypeMap
929
948
  if (!payloadStruct) continue;
930
949
  const isDiscriminator = (field) => field.wireName === type.discriminator || field.name === type.discriminator;
931
950
  const factoryParams = payloadStruct.fields.filter((field) => !isDiscriminator(field)).map((field) => {
932
- const defaultPart = field.optional ? " = nil" : "";
951
+ const defaultPart = defaultArgument(field);
933
952
  const fieldType = (ownedTypeMap && relativeOwnedPath(field.type, ownedTypeMap, lookupName)) ?? resolveType(field.type, void 0, context);
934
953
  return `${escapeKeyword(field.name)}: ${optionalize(fieldType, field.optional)}${defaultPart}`;
935
954
  }).join(", ");
@@ -1322,7 +1341,7 @@ const emitKizunaStreaming = (writer) => {
1322
1341
  writer.line("let retry: Int?");
1323
1342
  });
1324
1343
  writer.blank();
1325
- writer.block("static func open<Failure: KizunaFailure>(_ request: inout URLRequest, session: URLSession, requestMiddleware: (@Sendable (inout URLRequest) async throws -> Void)?, failure: Failure.Type) async throws(Failure) -> (URLSession.AsyncBytes, Int, HTTPURLResponse)", () => {
1344
+ writer.block("static func open<Failure: KizunaFailure>(_ request: inout URLRequest, session: URLSession, requestMiddleware: (@Sendable (inout URLRequest) async throws -> Void)?, responseMiddleware: (@Sendable (URLRequest, Foundation.Data, URLResponse) async -> Void)?, failure: Failure.Type) async throws(Failure) -> (URLSession.AsyncBytes, Int, HTTPURLResponse)", () => {
1326
1345
  writer.line("if let requestMiddleware {");
1327
1346
  writer.line(" do { try await requestMiddleware(&request) }");
1328
1347
  writer.line(" catch is CancellationError { throw Failure.cancelled }");
@@ -1335,6 +1354,7 @@ const emitKizunaStreaming = (writer) => {
1335
1354
  writer.line("catch is CancellationError { throw Failure.cancelled }");
1336
1355
  writer.line("catch let error as URLError where error.code == .cancelled { throw Failure.cancelled }");
1337
1356
  writer.line("catch { throw Failure.requestFailed(error) }");
1357
+ writer.line("if let responseMiddleware { await responseMiddleware(request, Foundation.Data(), response) }");
1338
1358
  writer.line("guard let httpResponse = response as? HTTPURLResponse else { throw Failure.invalidResponse }");
1339
1359
  writer.line("return (bytes, httpResponse.statusCode, httpResponse)");
1340
1360
  });
@@ -1652,13 +1672,13 @@ const methodGroups = (method, context) => {
1652
1672
  varName: "query",
1653
1673
  type: groupTypeRef(operationName, "Query", context),
1654
1674
  factory: "query",
1655
- required: method.query.some((field) => !field.optional)
1675
+ required: method.query.some((field) => !hasDefault(field))
1656
1676
  });
1657
1677
  if (method.headers.length > 0) groups.push({
1658
1678
  varName: "headers",
1659
1679
  type: groupTypeRef(operationName, "Headers", context),
1660
1680
  factory: "headers",
1661
- required: method.headers.some((field) => !field.optional)
1681
+ required: method.headers.some((field) => !hasDefault(field))
1662
1682
  });
1663
1683
  return [...groups.filter((group) => group.required), ...groups.filter((group) => !group.required)];
1664
1684
  };
@@ -1789,7 +1809,7 @@ const emitStreamMethodTail = (writer, method, context, receiver, responseBinding
1789
1809
  const qualifiedResult = `${context.clientName}.${method.operationName}.${method.resultWrapperName}`;
1790
1810
  const hasHeaders = method.resultHeaderFields.length > 0;
1791
1811
  const collect = `let data = try await Kizuna.collect(bytes, failure: ${failure}.self)`;
1792
- writer.line(`let (bytes, statusCode, ${responseBinding}) = try await Kizuna.open(&request, session: ${receiver}session, requestMiddleware: ${receiver}requestMiddleware, failure: ${failure}.self)`);
1812
+ writer.line(`let (bytes, statusCode, ${responseBinding}) = try await Kizuna.open(&request, session: ${receiver}session, requestMiddleware: ${receiver}requestMiddleware, responseMiddleware: ${receiver}responseMiddleware, failure: ${failure}.self)`);
1793
1813
  writer.line("switch statusCode {");
1794
1814
  writer.line(`case ${stream.status}:`);
1795
1815
  writer.indent(() => {
@@ -1874,9 +1894,15 @@ const emitBodyEncoding = (writer, method, context, receiver = "") => {
1874
1894
  writer.line("var multipart = Kizuna.MultipartBuilder()");
1875
1895
  for (const field of body.multipartFields) {
1876
1896
  const flattenedField = body.flattened.find((candidate) => candidate.name === field.name);
1877
- const accessor = `body.${escapeKeyword(field.name)}`;
1878
- if (field.isFile || flattenedField?.isFile === true) writer.line(`multipart.appendFile(name: ${stringLiteral(field.wireName)}, file: ${accessor})`);
1879
- else writer.line(`multipart.appendField(name: ${stringLiteral(field.wireName)}, value: String(describing: ${accessor}))`);
1897
+ const isFile = field.isFile || flattenedField?.isFile === true;
1898
+ const append = (accessor) => {
1899
+ if (isFile) writer.line(`multipart.appendFile(name: ${stringLiteral(field.wireName)}, file: ${accessor})`);
1900
+ else writer.line(`multipart.appendField(name: ${stringLiteral(field.wireName)}, value: String(describing: ${accessor}))`);
1901
+ };
1902
+ if (flattenedField?.optional === true) writer.block(`if let value = body.${escapeKeyword(field.name)}`, () => {
1903
+ append("value");
1904
+ });
1905
+ else append(`body.${escapeKeyword(field.name)}`);
1880
1906
  }
1881
1907
  writer.line("request.httpBody = multipart.finalize()");
1882
1908
  writer.line("request.setValue(multipart.contentType, forHTTPHeaderField: \"Content-Type\")");
@@ -1895,7 +1921,7 @@ const emitClient = (writer, config, partition, context, typesByOperation) => {
1895
1921
  const allMethods = [...flatMethods, ...groups.flatMap((group) => group.methods)];
1896
1922
  const usesMultipart = allMethods.some((method) => method.body?.kind === "multipart");
1897
1923
  const contextFields = context.requestContextFields;
1898
- const contextRequired = contextFields.some((field) => !field.optional);
1924
+ const contextRequired = contextFields.some((field) => !hasDefault(field));
1899
1925
  writer.blank();
1900
1926
  writer.block(`public final class ${clientName}: Sendable`, () => {
1901
1927
  if (contextFields.length > 0) {
@@ -1904,7 +1930,7 @@ const emitClient = (writer, config, partition, context, typesByOperation) => {
1904
1930
  writer.block("public struct RequestContext: Sendable, Equatable", () => {
1905
1931
  for (const field of contextFields) writer.line(`public var ${escapeKeyword(field.name)}: ${field.type}`);
1906
1932
  writer.blank();
1907
- const initParams = contextFields.map((field) => `${escapeKeyword(field.name)}: ${field.type}${field.optional ? " = nil" : ""}`).join(", ");
1933
+ const initParams = contextFields.map((field) => `${escapeKeyword(field.name)}: ${field.type}${defaultArgument(field)}`).join(", ");
1908
1934
  writer.block(`public init(${initParams})`, () => {
1909
1935
  for (const field of contextFields) writer.line(`self.${escapeKeyword(field.name)} = ${escapeKeyword(field.name)}`);
1910
1936
  });
@@ -125,6 +125,7 @@ const objectFields = (schema, registry, hint, shape = (0, kizunajs_generator.rea
125
125
  wireName: key,
126
126
  type: result.expression,
127
127
  optional: result.optional,
128
+ requiredNullable: result.requiredNullable,
128
129
  description: (0, kizunajs_generator.readMetaDescription)(value),
129
130
  isFile: result.isFile,
130
131
  deprecated: deprecation !== void 0,
@@ -236,6 +237,7 @@ const mapUnbrandedType = (schema, registry, hint) => {
236
237
  return {
237
238
  expression: innerResult.expression.endsWith("?") ? innerResult.expression : `${innerResult.expression}?`,
238
239
  optional: true,
240
+ requiredNullable: nullable && !optional,
239
241
  isFile: innerResult.isFile
240
242
  };
241
243
  }
@@ -420,6 +422,7 @@ const sanitizeCaseName = (literal) => {
420
422
  const collectObjectFields = (schema, registry, hint) => {
421
423
  return objectFields(schema, registry, hint);
422
424
  };
425
+ const hasDefault = (field) => field.optional && field.requiredNullable !== true;
423
426
  const objectFieldCount = (schema) => {
424
427
  return Object.keys((0, kizunajs_generator.readObjectShape)(schema) ?? {}).length;
425
428
  };
@@ -696,6 +699,10 @@ const sanitizeEnumCaseName = (value) => {
696
699
  if (!camel) return "_";
697
700
  return /^[0-9]/.test(camel) ? `_${camel}` : camel;
698
701
  };
702
+ const defaultArgument = (field) => {
703
+ if (!hasDefault(field)) return "";
704
+ return " = nil";
705
+ };
699
706
  const optionalize = (type, optional) => {
700
707
  if (!optional) return type;
701
708
  return type.endsWith("?") ? type : `${type}?`;
@@ -710,7 +717,7 @@ const emitNamedFactory = (writer, factoryName, fields, buildExpression) => {
710
717
  }
711
718
  const params = fields.map((field) => {
712
719
  const typeExpression = optionalize(field.type, field.optional);
713
- const defaultPart = field.optional ? " = nil" : "";
720
+ const defaultPart = defaultArgument(field);
714
721
  return `${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
715
722
  });
716
723
  const args = fields.map((field) => `${field.name}: ${escapeKeyword(field.name)}`).join(", ");
@@ -733,7 +740,7 @@ const emitMemberwiseInit = (writer, fields, assignmentTarget = (field) => escape
733
740
  }
734
741
  const params = fields.map((field) => {
735
742
  const typeExpression = optionalize(field.type, field.optional);
736
- const defaultPart = field.optional ? " = nil" : "";
743
+ const defaultPart = defaultArgument(field);
737
744
  return `${escapeKeyword(field.name)}: ${typeExpression}${defaultPart}`;
738
745
  });
739
746
  if (params.length === 1) {
@@ -867,7 +874,9 @@ const emitStruct = (writer, type, context, ownedTypeMap, ownedTypeLookup, regist
867
874
  ...field,
868
875
  type: resolveOwnedType(field.type)
869
876
  }));
870
- const needsCodingKeys = !hasFile && type.fields.some((field) => field.name !== field.wireName || SWIFT_KEYWORDS.has(field.name) || field.deprecated === true);
877
+ const needsEncode = !hasFile && type.fields.some((field) => field.requiredNullable === true);
878
+ const needsCodingKeys = needsEncode || !hasFile && type.fields.some((field) => field.name !== field.wireName || SWIFT_KEYWORDS.has(field.name) || field.deprecated === true);
879
+ const storageName = (field) => field.deprecated ? deprecatedStorageName(field, type.fields) : escapeKeyword(field.name);
871
880
  writer.block(`public struct ${type.name}: ${conformances}`, () => {
872
881
  emitOwnedTypes(writer, lookupName, context, ownedTypeMap, ownedTypeLookup);
873
882
  for (const field of type.fields) {
@@ -890,8 +899,18 @@ const emitStruct = (writer, type, context, ownedTypeMap, ownedTypeLookup, regist
890
899
  else writer.line(`case ${escapeKeyword(field.name)} = ${stringLiteral(field.wireName)}`);
891
900
  });
892
901
  }
902
+ if (needsEncode) {
903
+ writer.blank();
904
+ writer.block("public func encode(to encoder: Encoder) throws", () => {
905
+ writer.line("var container = encoder.container(keyedBy: CodingKeys.self)");
906
+ for (const field of type.fields) {
907
+ const encodeCall = field.optional && field.requiredNullable !== true ? "encodeIfPresent" : "encode";
908
+ writer.line(`try container.${encodeCall}(${storageName(field)}, forKey: .${storageName(field)})`);
909
+ }
910
+ });
911
+ }
893
912
  writer.blank();
894
- emitMemberwiseInit(writer, adjustedFields, (field) => field.deprecated ? deprecatedStorageName(field, type.fields) : escapeKeyword(field.name));
913
+ emitMemberwiseInit(writer, adjustedFields, storageName);
895
914
  });
896
915
  };
897
916
  /**
@@ -929,7 +948,7 @@ const emitDiscriminatedEnum = (writer, type, context, registryName, ownedTypeMap
929
948
  if (!payloadStruct) continue;
930
949
  const isDiscriminator = (field) => field.wireName === type.discriminator || field.name === type.discriminator;
931
950
  const factoryParams = payloadStruct.fields.filter((field) => !isDiscriminator(field)).map((field) => {
932
- const defaultPart = field.optional ? " = nil" : "";
951
+ const defaultPart = defaultArgument(field);
933
952
  const fieldType = (ownedTypeMap && relativeOwnedPath(field.type, ownedTypeMap, lookupName)) ?? resolveType(field.type, void 0, context);
934
953
  return `${escapeKeyword(field.name)}: ${optionalize(fieldType, field.optional)}${defaultPart}`;
935
954
  }).join(", ");
@@ -1322,7 +1341,7 @@ const emitKizunaStreaming = (writer) => {
1322
1341
  writer.line("let retry: Int?");
1323
1342
  });
1324
1343
  writer.blank();
1325
- writer.block("static func open<Failure: KizunaFailure>(_ request: inout URLRequest, session: URLSession, requestMiddleware: (@Sendable (inout URLRequest) async throws -> Void)?, failure: Failure.Type) async throws(Failure) -> (URLSession.AsyncBytes, Int, HTTPURLResponse)", () => {
1344
+ writer.block("static func open<Failure: KizunaFailure>(_ request: inout URLRequest, session: URLSession, requestMiddleware: (@Sendable (inout URLRequest) async throws -> Void)?, responseMiddleware: (@Sendable (URLRequest, Foundation.Data, URLResponse) async -> Void)?, failure: Failure.Type) async throws(Failure) -> (URLSession.AsyncBytes, Int, HTTPURLResponse)", () => {
1326
1345
  writer.line("if let requestMiddleware {");
1327
1346
  writer.line(" do { try await requestMiddleware(&request) }");
1328
1347
  writer.line(" catch is CancellationError { throw Failure.cancelled }");
@@ -1335,6 +1354,7 @@ const emitKizunaStreaming = (writer) => {
1335
1354
  writer.line("catch is CancellationError { throw Failure.cancelled }");
1336
1355
  writer.line("catch let error as URLError where error.code == .cancelled { throw Failure.cancelled }");
1337
1356
  writer.line("catch { throw Failure.requestFailed(error) }");
1357
+ writer.line("if let responseMiddleware { await responseMiddleware(request, Foundation.Data(), response) }");
1338
1358
  writer.line("guard let httpResponse = response as? HTTPURLResponse else { throw Failure.invalidResponse }");
1339
1359
  writer.line("return (bytes, httpResponse.statusCode, httpResponse)");
1340
1360
  });
@@ -1652,13 +1672,13 @@ const methodGroups = (method, context) => {
1652
1672
  varName: "query",
1653
1673
  type: groupTypeRef(operationName, "Query", context),
1654
1674
  factory: "query",
1655
- required: method.query.some((field) => !field.optional)
1675
+ required: method.query.some((field) => !hasDefault(field))
1656
1676
  });
1657
1677
  if (method.headers.length > 0) groups.push({
1658
1678
  varName: "headers",
1659
1679
  type: groupTypeRef(operationName, "Headers", context),
1660
1680
  factory: "headers",
1661
- required: method.headers.some((field) => !field.optional)
1681
+ required: method.headers.some((field) => !hasDefault(field))
1662
1682
  });
1663
1683
  return [...groups.filter((group) => group.required), ...groups.filter((group) => !group.required)];
1664
1684
  };
@@ -1789,7 +1809,7 @@ const emitStreamMethodTail = (writer, method, context, receiver, responseBinding
1789
1809
  const qualifiedResult = `${context.clientName}.${method.operationName}.${method.resultWrapperName}`;
1790
1810
  const hasHeaders = method.resultHeaderFields.length > 0;
1791
1811
  const collect = `let data = try await Kizuna.collect(bytes, failure: ${failure}.self)`;
1792
- writer.line(`let (bytes, statusCode, ${responseBinding}) = try await Kizuna.open(&request, session: ${receiver}session, requestMiddleware: ${receiver}requestMiddleware, failure: ${failure}.self)`);
1812
+ writer.line(`let (bytes, statusCode, ${responseBinding}) = try await Kizuna.open(&request, session: ${receiver}session, requestMiddleware: ${receiver}requestMiddleware, responseMiddleware: ${receiver}responseMiddleware, failure: ${failure}.self)`);
1793
1813
  writer.line("switch statusCode {");
1794
1814
  writer.line(`case ${stream.status}:`);
1795
1815
  writer.indent(() => {
@@ -1874,9 +1894,15 @@ const emitBodyEncoding = (writer, method, context, receiver = "") => {
1874
1894
  writer.line("var multipart = Kizuna.MultipartBuilder()");
1875
1895
  for (const field of body.multipartFields) {
1876
1896
  const flattenedField = body.flattened.find((candidate) => candidate.name === field.name);
1877
- const accessor = `body.${escapeKeyword(field.name)}`;
1878
- if (field.isFile || flattenedField?.isFile === true) writer.line(`multipart.appendFile(name: ${stringLiteral(field.wireName)}, file: ${accessor})`);
1879
- else writer.line(`multipart.appendField(name: ${stringLiteral(field.wireName)}, value: String(describing: ${accessor}))`);
1897
+ const isFile = field.isFile || flattenedField?.isFile === true;
1898
+ const append = (accessor) => {
1899
+ if (isFile) writer.line(`multipart.appendFile(name: ${stringLiteral(field.wireName)}, file: ${accessor})`);
1900
+ else writer.line(`multipart.appendField(name: ${stringLiteral(field.wireName)}, value: String(describing: ${accessor}))`);
1901
+ };
1902
+ if (flattenedField?.optional === true) writer.block(`if let value = body.${escapeKeyword(field.name)}`, () => {
1903
+ append("value");
1904
+ });
1905
+ else append(`body.${escapeKeyword(field.name)}`);
1880
1906
  }
1881
1907
  writer.line("request.httpBody = multipart.finalize()");
1882
1908
  writer.line("request.setValue(multipart.contentType, forHTTPHeaderField: \"Content-Type\")");
@@ -1895,7 +1921,7 @@ const emitClient = (writer, config, partition, context, typesByOperation) => {
1895
1921
  const allMethods = [...flatMethods, ...groups.flatMap((group) => group.methods)];
1896
1922
  const usesMultipart = allMethods.some((method) => method.body?.kind === "multipart");
1897
1923
  const contextFields = context.requestContextFields;
1898
- const contextRequired = contextFields.some((field) => !field.optional);
1924
+ const contextRequired = contextFields.some((field) => !hasDefault(field));
1899
1925
  writer.blank();
1900
1926
  writer.block(`public final class ${clientName}: Sendable`, () => {
1901
1927
  if (contextFields.length > 0) {
@@ -1904,7 +1930,7 @@ const emitClient = (writer, config, partition, context, typesByOperation) => {
1904
1930
  writer.block("public struct RequestContext: Sendable, Equatable", () => {
1905
1931
  for (const field of contextFields) writer.line(`public var ${escapeKeyword(field.name)}: ${field.type}`);
1906
1932
  writer.blank();
1907
- const initParams = contextFields.map((field) => `${escapeKeyword(field.name)}: ${field.type}${field.optional ? " = nil" : ""}`).join(", ");
1933
+ const initParams = contextFields.map((field) => `${escapeKeyword(field.name)}: ${field.type}${defaultArgument(field)}`).join(", ");
1908
1934
  writer.block(`public init(${initParams})`, () => {
1909
1935
  for (const field of contextFields) writer.line(`self.${escapeKeyword(field.name)} = ${escapeKeyword(field.name)}`);
1910
1936
  });
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_generator = require("./generator-E0WQFf92.cjs");
2
+ const require_generator = require("./generator-DBNFuaBB.cjs");
3
3
  let kizunajs_generator = require("kizunajs/generator");
4
4
  let zod = require("zod");
5
5
  //#region src/client-target.ts
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as swiftClientWalk, t as generateSwiftClient } from "./generator-CxUzLmbK.mjs";
1
+ import { n as swiftClientWalk, t as generateSwiftClient } from "./generator-CjCPSdEz.mjs";
2
2
  import { defineClient } from "kizunajs/generator";
3
3
  import { z } from "zod";
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kizunajs/swift",
3
- "version": "2.0.0-beta.17",
3
+ "version": "2.0.0-beta.19",
4
4
  "description": "Swift client generation for Kizuna.js APIs",
5
5
  "keywords": [
6
6
  "kizunajs",
@@ -59,14 +59,14 @@
59
59
  "access": "public"
60
60
  },
61
61
  "dependencies": {
62
- "@kizunajs/cli": "2.0.0-beta.17"
62
+ "@kizunajs/cli": "2.0.0-beta.19"
63
63
  },
64
64
  "peerDependencies": {
65
- "kizunajs": "2.0.0-beta.17",
65
+ "kizunajs": "2.0.0-beta.19",
66
66
  "zod": "^4.0.0"
67
67
  },
68
68
  "devDependencies": {
69
- "kizunajs": "2.0.0-beta.17",
69
+ "kizunajs": "2.0.0-beta.19",
70
70
  "@types/node": "^24",
71
71
  "tsdown": "^0.21.0",
72
72
  "typescript": "^6.0.3",