diff --git a/generators/swift/base/package.json b/generators/swift/base/package.json index dbda9dcbdc1f..6c555ddea652 100644 --- a/generators/swift/base/package.json +++ b/generators/swift/base/package.json @@ -37,8 +37,10 @@ "@fern-api/fs-utils": "workspace:*", "@fern-api/swift-codegen": "workspace:*", "@fern-fern/ir-sdk": "^59.7.0", + "@types/lodash-es": "^4.17.12", "@types/node": "18.15.3", "depcheck": "^1.4.7", + "lodash-es": "^4.17.21", "typescript": "5.9.2", "vitest": "^2.1.9" } diff --git a/generators/swift/base/src/AsIs.ts b/generators/swift/base/src/AsIs.ts index 6a1ed103bb92..d4aefbe4ba07 100644 --- a/generators/swift/base/src/AsIs.ts +++ b/generators/swift/base/src/AsIs.ts @@ -2,16 +2,36 @@ import { readFile } from "node:fs/promises"; import { join } from "node:path"; import { entries } from "@fern-api/core-utils"; import { RelativeFilePath } from "@fern-api/fs-utils"; +import { swift } from "@fern-api/swift-codegen"; + +export type AsIsSymbolName = + | "JSONValue" + | "CalendarDate" + | "HTTP" + | "HTTPClient" + | "MultipartFormData" + | "MultipartFormDataConvertible" + | "MultipartFormField" + | "QueryParameter" + | "EncodableValue" + | "Serde" + | "StringKey" + | "APIErrorResponse" + | "ClientConfig" + | "ClientError" + | "FormFile" + | "Nullable" + | "RequestOptions"; /** * Configuration specification for a static Swift file that gets included as-is in the generated SDK. * This serves as the raw configuration that gets transformed into a fully resolved {@link AsIsFileDefinition} * during the build process. */ -interface AsIsFileSpec { +interface AsIsFileSpec { relativePathToDir: string; filenameWithoutExtension: string; - symbolNames?: string[]; + symbols?: { name: SymbolName; shape: swift.TypeSymbolShape }[]; } /** @@ -31,10 +51,9 @@ export interface AsIsFileDefinition { directory: RelativeFilePath; /** - * The names of Swift symbols (classes, structs, enums, protocols, etc.) - * that this file introduces to the project namespace. + * The symbols (classes, structs, enums, protocols, etc.) that this file introduces to the project namespace. */ - symbolNames: string[]; + symbols: { name: string; shape: swift.TypeSymbolShape }[]; /** * Asynchronously loads the contents of the Swift file from disk. @@ -56,32 +75,32 @@ const SourceAsIsFileSpecs = { Http: { relativePathToDir: "Core/Networking", filenameWithoutExtension: "HTTP", - symbolNames: ["HTTP"] + symbols: [{ name: "HTTP", shape: { type: "enum-container" } }] }, HttpClient: { relativePathToDir: "Core/Networking", filenameWithoutExtension: "HTTPClient", - symbolNames: ["HTTPClient"] + symbols: [{ name: "HTTPClient", shape: { type: "class" } }] }, MultipartFormData: { relativePathToDir: "Core/Networking", filenameWithoutExtension: "MultipartFormData", - symbolNames: ["MultipartFormData"] + symbols: [{ name: "MultipartFormData", shape: { type: "class" } }] }, MultipartFormDataConvertible: { relativePathToDir: "Core/Networking", filenameWithoutExtension: "MultipartFormDataConvertible", - symbolNames: ["MultipartFormDataConvertible"] + symbols: [{ name: "MultipartFormDataConvertible", shape: { type: "protocol" } }] }, MultipartFormField: { relativePathToDir: "Core/Networking", filenameWithoutExtension: "MultipartFormField", - symbolNames: ["MultipartFormField"] + symbols: [{ name: "MultipartFormField", shape: { type: "enum-with-associated-values" } }] }, QueryParameter: { relativePathToDir: "Core/Networking", filenameWithoutExtension: "QueryParameter", - symbolNames: ["QueryParameter"] + symbols: [{ name: "QueryParameter", shape: { type: "enum-with-associated-values" } }] }, // Core/Serde DecoderPlusAdditionalProperties: { @@ -91,7 +110,7 @@ const SourceAsIsFileSpecs = { EncodableValue: { relativePathToDir: "Core/Serde", filenameWithoutExtension: "EncodableValue", - symbolNames: ["EncodableValue"] + symbols: [{ name: "EncodableValue", shape: { type: "struct" } }] }, EncoderPlusAdditionalProperties: { relativePathToDir: "Core/Serde", @@ -112,19 +131,19 @@ const SourceAsIsFileSpecs = { Serde: { relativePathToDir: "Core/Serde", filenameWithoutExtension: "Serde", - symbolNames: ["Serde"] + symbols: [{ name: "Serde", shape: { type: "class" } }] }, StringKey: { relativePathToDir: "Core/Serde", filenameWithoutExtension: "StringKey", - symbolNames: ["StringKey"] + symbols: [{ name: "StringKey", shape: { type: "struct" } }] }, // Core CalendarDate: { relativePathToDir: "Core", filenameWithoutExtension: "CalendarDate", - symbolNames: ["CalendarDate"] + symbols: [{ name: "CalendarDate", shape: { type: "struct" } }] }, DataPlusString: { relativePathToDir: "Core", @@ -139,39 +158,39 @@ const SourceAsIsFileSpecs = { APIErrorResponse: { relativePathToDir: "Public", filenameWithoutExtension: "APIErrorResponse", - symbolNames: ["APIErrorResponse"] + symbols: [{ name: "APIErrorResponse", shape: { type: "struct" } }] }, ClientConfig: { relativePathToDir: "Public", filenameWithoutExtension: "ClientConfig", - symbolNames: ["ClientConfig"] + symbols: [{ name: "ClientConfig", shape: { type: "class" } }] }, ClientError: { relativePathToDir: "Public", filenameWithoutExtension: "ClientError", - symbolNames: ["ClientError"] + symbols: [{ name: "ClientError", shape: { type: "enum-with-associated-values" } }] }, FormFile: { relativePathToDir: "Public", filenameWithoutExtension: "FormFile", - symbolNames: ["FormFile"] + symbols: [{ name: "FormFile", shape: { type: "struct" } }] }, JsonValue: { relativePathToDir: "Public", filenameWithoutExtension: "JSONValue", - symbolNames: ["JSONValue"] + symbols: [{ name: "JSONValue", shape: { type: "enum-with-associated-values" } }] }, Nullable: { relativePathToDir: "Public", filenameWithoutExtension: "Nullable", - symbolNames: ["Nullable"] + symbols: [{ name: "Nullable", shape: { type: "enum-with-associated-values" } }] }, RequestOptions: { relativePathToDir: "Public", filenameWithoutExtension: "RequestOptions", - symbolNames: ["RequestOptions"] + symbols: [{ name: "RequestOptions", shape: { type: "struct" } }] } -} satisfies Record; +} satisfies Record>; /** * Union type of all available static file identifiers. @@ -215,11 +234,11 @@ function createSourceAsIsFiles(): SourceAsIsFileDefinitionsById { const result = {} as SourceAsIsFileDefinitionsById; for (const [key, spec] of entries(SourceAsIsFileSpecs)) { - const { relativePathToDir, filenameWithoutExtension, symbolNames } = spec as AsIsFileSpec; + const { relativePathToDir, filenameWithoutExtension, symbols } = spec as AsIsFileSpec; result[key] = { filenameWithoutExtension, directory: RelativeFilePath.of(relativePathToDir), - symbolNames: symbolNames ?? [], + symbols: symbols ?? [], loadContents: () => { const absolutePath = join(__dirname, "asIs", "Sources", filenameWithoutExtension + ".swift"); return readFile(absolutePath, "utf-8"); @@ -235,9 +254,9 @@ const TestAsIsFileSpecs = { WireStub: { relativePathToDir: "Wire/Utilities", filenameWithoutExtension: "WireStub", - symbolNames: ["WireStub"] + symbols: [{ name: "WireStub", shape: { type: "class" } }] } -} satisfies Record; +} satisfies Record>; export type TestAsIsFileId = keyof typeof TestAsIsFileSpecs; @@ -251,11 +270,11 @@ function createTestAsIsFiles(): TestAsIsFileDefinitionsById { const result = {} as TestAsIsFileDefinitionsById; for (const [key, spec] of entries(TestAsIsFileSpecs)) { - const { relativePathToDir, filenameWithoutExtension, symbolNames } = spec as AsIsFileSpec; + const { relativePathToDir, filenameWithoutExtension, symbols } = spec as AsIsFileSpec; result[key] = { filenameWithoutExtension, directory: RelativeFilePath.of(relativePathToDir), - symbolNames: symbolNames ?? [], + symbols: symbols ?? [], loadContents: () => { const absolutePath = join(__dirname, "asIs", "Tests", filenameWithoutExtension + ".swift"); return readFile(absolutePath, "utf-8"); diff --git a/generators/swift/base/src/context/AbstractSwiftGeneratorContext.ts b/generators/swift/base/src/context/AbstractSwiftGeneratorContext.ts index 1403928237c8..fc8b99851a2d 100644 --- a/generators/swift/base/src/context/AbstractSwiftGeneratorContext.ts +++ b/generators/swift/base/src/context/AbstractSwiftGeneratorContext.ts @@ -7,6 +7,7 @@ import { HttpEndpoint, HttpService, IntermediateRepresentation, + ObjectProperty, Package, PrimitiveTypeV1, ServiceId, @@ -18,17 +19,11 @@ import { } from "@fern-fern/ir-sdk/api"; import { AsIsFileDefinition, SourceAsIsFiles, TestAsIsFiles } from "../AsIs"; -import { SourceSymbolRegistry, SwiftProject } from "../project"; -import { TestSymbolRegistry } from "../project/TestSymbolRegistry"; - -/** - * Registry for local type information used by individual generators to resolve type references - * and handle nested type collisions within their specific context. - */ -export interface LocalTypeRegistry { - getSwiftTypeForStringLiteral(literalValue: string): swift.Type; - hasNestedTypeWithName(symbolName: string): boolean; -} +import { SwiftProject } from "../project"; +import { Referencer } from "./Referencer"; +import { registerDiscriminatedUnionVariants } from "./register-discriminated-unions"; +import { registerLiteralEnums, registerLiteralEnumsForObjectProperties } from "./register-literal-enums"; +import { inferCaseNameForTypeReference, registerUndiscriminatedUnionVariants } from "./register-undiscriminated-unions"; export abstract class AbstractSwiftGeneratorContext< CustomConfig extends BaseSwiftCustomConfigSchema @@ -42,48 +37,89 @@ export abstract class AbstractSwiftGeneratorContext< public readonly generatorNotificationService: GeneratorNotificationService ) { super(config, generatorNotificationService); - this.project = this.initProject(ir); + this.project = new SwiftProject({ context: this }); + this.registerProjectSymbols(this.project, ir); } - private initProject(ir: IntermediateRepresentation): SwiftProject { - const project = new SwiftProject({ context: this }); - this.registerSourceSymbols(project.srcSymbolRegistry, ir); - this.registerTestSymbols(project.testSymbolRegistry, project.srcSymbolRegistry); - return project; + private registerProjectSymbols(project: SwiftProject, ir: IntermediateRepresentation) { + this.registerSourceSymbols(project, ir); + this.registerTestSymbols(project); } - /** - * Register symbols in priority order - high-priority symbols first to avoid collisions. - * Root client and environment symbols are registered first as they're most critical, - * followed by schema types and inline request types which are commonly referenced, and - * finally subclient symbols last since they're unlikely to be used directly by end users. - */ - private registerSourceSymbols(symbolRegistry: SourceSymbolRegistry, ir: IntermediateRepresentation) { - symbolRegistry.registerModuleSymbol({ + private registerSourceSymbols(project: SwiftProject, ir: IntermediateRepresentation) { + const { nameRegistry } = project; + nameRegistry.registerSourceModuleSymbol({ configModuleName: this.customConfig.moduleName, - apiNamePascalCase: ir.apiName.pascalCase.unsafeName + apiNamePascalCase: ir.apiName.pascalCase.unsafeName, + asIsSymbols: Object.values(SourceAsIsFiles).flatMap((file) => file.symbols) }); - symbolRegistry.registerRootClientSymbol({ + nameRegistry.registerRootClientSymbol({ configClientClassName: this.customConfig.clientClassName, apiNamePascalCase: ir.apiName.pascalCase.unsafeName }); - symbolRegistry.registerEnvironmentSymbol({ + nameRegistry.registerEnvironmentSymbol({ configEnvironmentEnumName: this.customConfig.environmentEnumName, apiNamePascalCase: ir.apiName.pascalCase.unsafeName }); - Object.entries(ir.types).forEach(([typeId, typeDeclaration]) => { - symbolRegistry.registerSchemaTypeSymbol(typeId, typeDeclaration.name.name.pascalCase.unsafeName); + + // Must first register top-level symbols + const registeredSchemaTypes = Object.entries(ir.types).map(([typeId, typeDeclaration]) => { + const symbolShape: swift.TypeSymbolShape = typeDeclaration.shape._visit({ + alias: () => ({ type: "struct" }), + enum: () => ({ type: "enum-with-raw-values" }), + object: () => ({ type: "struct" }), + union: () => ({ type: "enum-with-associated-values" }), + undiscriminatedUnion: () => ({ type: "enum-with-associated-values" }), + _other: () => ({ type: "other" }) + }); + const schemaTypeSymbol = nameRegistry.registerSchemaTypeSymbol( + typeId, + typeDeclaration.name.name.pascalCase.unsafeName, + symbolShape + ); + return { typeDeclaration, registeredSymbol: schemaTypeSymbol }; }); - symbolRegistry.registerRequestsContainerSymbol(); + + registeredSchemaTypes.forEach(({ typeDeclaration, registeredSymbol }) => { + registerDiscriminatedUnionVariants({ + parentSymbol: registeredSymbol, + registry: nameRegistry, + typeDeclaration, + context: this + }); + registerLiteralEnums({ + parentSymbol: registeredSymbol, + registry: nameRegistry, + typeDeclaration, + context: this + }); + registerUndiscriminatedUnionVariants({ + parentSymbol: registeredSymbol, + registry: nameRegistry, + typeDeclaration, + context: this + }); + }); + + nameRegistry.registerRequestsContainerSymbol(); + Object.entries(ir.services).forEach(([_, service]) => { service.endpoints.forEach((endpoint) => { if (endpoint.requestBody?.type === "inlinedRequestBody") { - symbolRegistry.registerRequestTypeSymbol({ + const requestTypeSymbol = nameRegistry.registerRequestTypeSymbol({ endpointId: endpoint.id, requestNamePascalCase: endpoint.requestBody.name.pascalCase.unsafeName }); + registerLiteralEnumsForObjectProperties({ + parentSymbol: requestTypeSymbol, + registry: nameRegistry, + properties: [ + ...(endpoint.requestBody.extendedProperties ?? []), + ...endpoint.requestBody.properties + ] + }); } else if (endpoint.requestBody?.type === "fileUpload") { - symbolRegistry.registerRequestTypeSymbol({ + nameRegistry.registerRequestTypeSymbol({ endpointId: endpoint.id, requestNamePascalCase: endpoint.requestBody.name.pascalCase.unsafeName }); @@ -91,7 +127,7 @@ export abstract class AbstractSwiftGeneratorContext< }); }); Object.entries(ir.subpackages).forEach(([subpackageId, subpackage]) => { - symbolRegistry.registerSubClientSymbol({ + nameRegistry.registerSubClientSymbol({ subpackageId, fernFilepathPartNamesPascalCase: subpackage.fernFilepath.allParts.map( (name) => name.pascalCase.unsafeName @@ -101,26 +137,36 @@ export abstract class AbstractSwiftGeneratorContext< }); } - private registerTestSymbols(testSymbolRegistry: TestSymbolRegistry, sourceSymbolRegistry: SourceSymbolRegistry) { - sourceSymbolRegistry.getAllSubClientSymbols().forEach((s) => { - testSymbolRegistry.registerWireTestSuiteSymbol(s.name); + private registerTestSymbols(project: SwiftProject) { + const { nameRegistry } = project; + const sourceModuleSymbol = nameRegistry.getRegisteredSourceModuleSymbolOrThrow(); + nameRegistry.registerTestModuleSymbol({ + sourceModuleName: sourceModuleSymbol.name, + asIsSymbols: Object.values(TestAsIsFiles).flatMap((file) => file.symbols) + }); + nameRegistry.getAllSubClientSymbols().forEach((s) => { + nameRegistry.registerWireTestSuiteSymbol(s.name); }); } public get packageName(): string { - return this.project.srcSymbolRegistry.getModuleSymbolOrThrow(); + const symbol = this.project.nameRegistry.getRegisteredSourceModuleSymbolOrThrow(); + return symbol.name; } public get libraryName(): string { - return this.project.srcSymbolRegistry.getModuleSymbolOrThrow(); + const symbol = this.project.nameRegistry.getRegisteredSourceModuleSymbolOrThrow(); + return symbol.name; } - public get srcTargetName(): string { - return this.project.srcSymbolRegistry.getModuleSymbolOrThrow(); + public get sourceTargetName(): string { + const symbol = this.project.nameRegistry.getRegisteredSourceModuleSymbolOrThrow(); + return symbol.name; } public get testTargetName(): string { - return `${this.srcTargetName}Tests`; + const symbol = this.project.nameRegistry.getRegisteredTestModuleSymbolOrThrow(); + return symbol.name; } public get requestsDirectory(): RelativeFilePath { @@ -145,6 +191,18 @@ export abstract class AbstractSwiftGeneratorContext< return typeDeclaration; } + public getPropertiesOfDiscriminatedUnionVariant(typeId: TypeId): ObjectProperty[] { + const typeDeclaration = this.getTypeDeclarationOrThrow(typeId); + return typeDeclaration.shape._visit({ + alias: () => [], + enum: () => [], + object: (otd) => [...(otd.extendedProperties ?? []), ...otd.properties], + union: () => [], + undiscriminatedUnion: () => [], + _other: () => [] + }); + } + public getHttpServiceOrThrow(serviceId: ServiceId): HttpService { const service = this.ir.services[serviceId]; assertDefined(service, `Service with the id '${serviceId}' not found`); @@ -175,64 +233,80 @@ export abstract class AbstractSwiftGeneratorContext< return Object.values(TestAsIsFiles); } - public getSwiftTypeForTypeReference( + public getSwiftTypeReferenceFromSourceModuleScope(typeReference: TypeReference): swift.TypeReference { + const symbol = this.project.nameRegistry.getRegisteredSourceModuleSymbolOrThrow(); + return this.getSwiftTypeReferenceFromScope(typeReference, symbol.id); + } + + public getSwiftTypeReferenceFromTestModuleScope(typeReference: TypeReference): swift.TypeReference { + const symbol = this.project.nameRegistry.getRegisteredTestModuleSymbolOrThrow(); + return this.getSwiftTypeReferenceFromScope(typeReference, symbol.id); + } + + public getSwiftTypeReferenceFromScope( typeReference: TypeReference, - localTypeRegistry?: LocalTypeRegistry - ): swift.Type { + fromSymbol: swift.Symbol | string + ): swift.TypeReference { + const referencer = this.createReferencer(fromSymbol); switch (typeReference.type) { case "container": return typeReference.container._visit({ literal: (literal) => literal._visit({ - boolean: () => swift.Type.jsonValue(), // TODO(kafkas): Implement boolean literals - string: (literalValue) => - localTypeRegistry?.getSwiftTypeForStringLiteral(literalValue) ?? swift.Type.jsonValue(), - _other: () => swift.Type.jsonValue() + boolean: () => referencer.referenceAsIsType("JSONValue"), + string: (literalValue) => { + const symbol = this.project.nameRegistry.getNestedLiteralEnumSymbolOrThrow( + fromSymbol, + literalValue + ); + return referencer.referenceType(symbol); + }, + _other: () => referencer.referenceAsIsType("JSONValue") }), map: (type) => - swift.Type.dictionary( - this.getSwiftTypeForTypeReference(type.keyType, localTypeRegistry), - this.getSwiftTypeForTypeReference(type.valueType, localTypeRegistry) + swift.TypeReference.dictionary( + this.getSwiftTypeReferenceFromScope(type.keyType, fromSymbol), + this.getSwiftTypeReferenceFromScope(type.valueType, fromSymbol) ), - set: () => swift.Type.jsonValue(), // TODO(kafkas): Implement set type - nullable: (ref) => swift.Type.nullable(this.getSwiftTypeForTypeReference(ref, localTypeRegistry)), - optional: (ref) => swift.Type.optional(this.getSwiftTypeForTypeReference(ref, localTypeRegistry)), - list: (ref) => swift.Type.array(this.getSwiftTypeForTypeReference(ref, localTypeRegistry)), - _other: () => swift.Type.jsonValue() + set: () => referencer.referenceAsIsType("JSONValue"), + nullable: (ref) => + swift.TypeReference.nullable(this.getSwiftTypeReferenceFromScope(ref, fromSymbol)), + optional: (ref) => + swift.TypeReference.optional(this.getSwiftTypeReferenceFromScope(ref, fromSymbol)), + list: (ref) => swift.TypeReference.array(this.getSwiftTypeReferenceFromScope(ref, fromSymbol)), + _other: () => referencer.referenceAsIsType("JSONValue") }); case "primitive": return PrimitiveTypeV1._visit(typeReference.primitive.v1, { - string: () => swift.Type.string(), - boolean: () => swift.Type.bool(), - integer: () => swift.Type.int(), - uint: () => swift.Type.uint(), - uint64: () => swift.Type.uint64(), - long: () => swift.Type.int64(), - float: () => swift.Type.float(), - double: () => swift.Type.double(), - bigInteger: () => swift.Type.string(), // TODO(kafkas): We may need to implement our own value type for this - date: () => swift.Type.calendarDate(), - dateTime: () => swift.Type.date(), - base64: () => swift.Type.string(), - uuid: () => swift.Type.uuid(), - _other: () => swift.Type.jsonValue() + string: () => referencer.referenceSwiftType("String"), + boolean: () => referencer.referenceSwiftType("Bool"), + integer: () => referencer.referenceSwiftType("Int"), + uint: () => referencer.referenceSwiftType("UInt"), + uint64: () => referencer.referenceSwiftType("UInt64"), + long: () => referencer.referenceSwiftType("Int64"), + float: () => referencer.referenceSwiftType("Float"), + double: () => referencer.referenceSwiftType("Double"), + bigInteger: () => referencer.referenceSwiftType("String"), + date: () => referencer.referenceAsIsType("CalendarDate"), + dateTime: () => referencer.referenceFoundationType("Date"), + base64: () => referencer.referenceSwiftType("String"), + uuid: () => referencer.referenceFoundationType("UUID"), + _other: () => referencer.referenceAsIsType("JSONValue") }); case "named": { - const symbolName = this.project.srcSymbolRegistry.getSchemaTypeSymbolOrThrow(typeReference.typeId); - const hasNestedTypeWithSameName = localTypeRegistry?.hasNestedTypeWithName?.(symbolName); - return swift.Type.custom( - hasNestedTypeWithSameName ? this.getFullyQualifiedNameForSchemaType(symbolName) : symbolName - ); + const toSymbol = this.project.nameRegistry.getSchemaTypeSymbolOrThrow(typeReference.typeId); + const symbolRef = this.project.nameRegistry.reference({ fromSymbol, toSymbol }); + return swift.TypeReference.symbol(symbolRef); } case "unknown": - return swift.Type.jsonValue(); + return referencer.referenceAsIsType("JSONValue"); default: assertNever(typeReference); } } - public getFullyQualifiedNameForSchemaType(symbolName: string): string { - return `${this.srcTargetName}.${symbolName}`; + public inferCaseNameForTypeReference(parentSymbol: swift.Symbol, typeReference: swift.TypeReference): string { + return inferCaseNameForTypeReference(parentSymbol, typeReference, this.project.nameRegistry); } public getEndpointMethodDetails(endpoint: HttpEndpoint) { @@ -277,4 +351,8 @@ export abstract class AbstractSwiftGeneratorContext< } return { type: "none" }; } + + public createReferencer(fromSymbol: swift.Symbol | string) { + return new Referencer(this.project, fromSymbol); + } } diff --git a/generators/swift/base/src/context/Referencer.ts b/generators/swift/base/src/context/Referencer.ts new file mode 100644 index 000000000000..3cebcfe88076 --- /dev/null +++ b/generators/swift/base/src/context/Referencer.ts @@ -0,0 +1,96 @@ +import { swift } from "@fern-api/swift-codegen"; +import { AsIsSymbolName } from "../AsIs"; +import type { SwiftProject } from "../project"; + +export class Referencer { + private readonly project: SwiftProject; + private readonly fromSymbol: swift.Symbol | string; + + public constructor(project: SwiftProject, fromSymbol: swift.Symbol | string) { + this.project = project; + this.fromSymbol = fromSymbol; + } + + public referenceSwiftType(symbolName: swift.SwiftTypeSymbolName) { + const symbolRef = this.project.nameRegistry.reference({ + fromSymbol: this.fromSymbol, + toSymbol: swift.Symbol.swiftType(symbolName) + }); + return swift.TypeReference.symbol(symbolRef); + } + + public referenceFoundationType(symbolName: swift.FoundationTypeSymbolName) { + const symbolRef = this.project.nameRegistry.reference({ + fromSymbol: this.fromSymbol, + toSymbol: swift.Symbol.foundationType(symbolName) + }); + return swift.TypeReference.symbol(symbolRef); + } + + public referenceAsIsType(symbolName: AsIsSymbolName) { + const symbol = this.project.nameRegistry.getAsIsSymbolOrThrow(symbolName); + const symbolRef = this.project.nameRegistry.reference({ + fromSymbol: this.fromSymbol, + toSymbol: symbol + }); + return swift.TypeReference.symbol(symbolRef); + } + + public referenceType(symbol: swift.Symbol | string) { + const symbolRef = this.project.nameRegistry.reference({ + fromSymbol: this.fromSymbol, + toSymbol: symbol + }); + return swift.TypeReference.symbol(symbolRef); + } + + public resolveToSymbolIfSymbolType(typeReference: swift.TypeReference) { + const reference = typeReference.getReferenceIfSymbolType(); + if (reference === null) { + return null; + } + return this.project.nameRegistry.resolveReference({ + fromSymbol: this.fromSymbol, + reference + }); + } + + public resolvesToTheAsIsType(typeReference: swift.TypeReference, asIsSymbolName: AsIsSymbolName) { + const resolvedSymbol = this.resolveToSymbolIfSymbolType(typeReference); + const registeredSymbol = this.project.nameRegistry.getAsIsSymbolOrThrow(asIsSymbolName); + return resolvedSymbol?.id === registeredSymbol.id; + } + + public resolvesToASwiftType(typeReference: swift.TypeReference) { + const symbol = this.resolveToSymbolIfSymbolType(typeReference); + return symbol?.isSwiftSymbol ?? false; + } + + public resolvesToTheSwiftType(typeReference: swift.TypeReference, swiftSymbolName: swift.SwiftTypeSymbolName) { + const symbol = this.resolveToSymbolIfSymbolType(typeReference); + return symbol?.id === swift.Symbol.swiftType(swiftSymbolName).id; + } + + public resolvesToAFoundationType(typeReference: swift.TypeReference) { + const symbol = this.resolveToSymbolIfSymbolType(typeReference); + return symbol?.isFoundationSymbol ?? false; + } + + public resolvesToTheFoundationType( + typeReference: swift.TypeReference, + foundationSymbolName: swift.FoundationTypeSymbolName + ) { + const symbol = this.resolveToSymbolIfSymbolType(typeReference); + return symbol?.id === swift.Symbol.foundationType(foundationSymbolName).id; + } + + public resolvesToACustomType(typeReference: swift.TypeReference) { + const symbol = this.resolveToSymbolIfSymbolType(typeReference); + return symbol?.isCustomSymbol ?? false; + } + + public resolvesToAnEnumWithRawValues(typeReference: swift.TypeReference) { + const symbol = this.resolveToSymbolIfSymbolType(typeReference); + return symbol?.shape.type === "enum-with-raw-values"; + } +} diff --git a/generators/swift/base/src/context/index.ts b/generators/swift/base/src/context/index.ts index 5bd0ede13a07..e9332f820c6e 100644 --- a/generators/swift/base/src/context/index.ts +++ b/generators/swift/base/src/context/index.ts @@ -1 +1,2 @@ export * from "./AbstractSwiftGeneratorContext"; +export type * from "./Referencer"; diff --git a/generators/swift/base/src/context/register-discriminated-unions.ts b/generators/swift/base/src/context/register-discriminated-unions.ts new file mode 100644 index 000000000000..8d6467bed866 --- /dev/null +++ b/generators/swift/base/src/context/register-discriminated-unions.ts @@ -0,0 +1,42 @@ +import { noop } from "@fern-api/core-utils"; +import { BaseSwiftCustomConfigSchema, EnumWithAssociatedValues, swift } from "@fern-api/swift-codegen"; +import { TypeDeclaration } from "@fern-fern/ir-sdk/api"; +import { NameRegistry } from "../project"; +import type { AbstractSwiftGeneratorContext } from "."; + +export function registerDiscriminatedUnionVariants({ + parentSymbol, + registry, + typeDeclaration +}: { + parentSymbol: swift.Symbol; + registry: NameRegistry; + typeDeclaration: TypeDeclaration; + context: AbstractSwiftGeneratorContext; +}) { + typeDeclaration.shape._visit({ + union: (utd) => { + const variants = utd.types.map((singleUnionType) => { + const symbolName = EnumWithAssociatedValues.sanitizeToPascalCase( + singleUnionType.discriminantValue.name.pascalCase.unsafeName + ); + const caseName = EnumWithAssociatedValues.sanitizeToCamelCase( + singleUnionType.discriminantValue.name.camelCase.unsafeName + ); + return { + swiftType: swift.TypeReference.symbol(symbolName), + caseName: caseName, + symbolName, + discriminantWireValue: singleUnionType.discriminantValue.wireValue, + docsContent: singleUnionType.docs + }; + }); + registry.registerDiscriminatedUnionVariants({ parentSymbol, variants }); + }, + alias: noop, + enum: noop, + object: noop, + undiscriminatedUnion: noop, + _other: noop + }); +} diff --git a/generators/swift/base/src/context/register-literal-enums.ts b/generators/swift/base/src/context/register-literal-enums.ts new file mode 100644 index 000000000000..97a13380904b --- /dev/null +++ b/generators/swift/base/src/context/register-literal-enums.ts @@ -0,0 +1,164 @@ +import { noop } from "@fern-api/core-utils"; +import { BaseSwiftCustomConfigSchema, swift } from "@fern-api/swift-codegen"; +import { ObjectProperty, TypeDeclaration, TypeReference } from "@fern-fern/ir-sdk/api"; + +import { NameRegistry } from "../project"; +import { AbstractSwiftGeneratorContext } from "./AbstractSwiftGeneratorContext"; + +export function registerLiteralEnums({ + parentSymbol, + registry, + typeDeclaration, + context +}: { + parentSymbol: swift.Symbol; + registry: NameRegistry; + typeDeclaration: TypeDeclaration; + context: AbstractSwiftGeneratorContext; +}) { + typeDeclaration.shape._visit({ + object: (otd) => { + const allProperties = [...(otd.extendedProperties ?? []), ...otd.properties]; + registerLiteralEnumsForObjectProperties({ + parentSymbol, + registry, + properties: allProperties + }); + }, + union: (utd) => { + utd.types.forEach((type) => { + const variantSymbol = registry.getDiscriminatedUnionVariantSymbolOrThrow( + parentSymbol, + type.discriminantValue.wireValue + ); + type.shape._visit({ + noProperties: noop, + samePropertiesAsObject: (declaredTypeName) => { + const variantProperties = context.getPropertiesOfDiscriminatedUnionVariant( + declaredTypeName.typeId + ); + variantProperties.forEach((property) => { + registerLiteralEnumsForTypeReference({ + parentSymbol: variantSymbol, + registry, + typeReference: property.valueType + }); + }); + }, + singleProperty: (p) => { + registerLiteralEnumsForTypeReference({ + parentSymbol: variantSymbol, + registry, + typeReference: p.type + }); + }, + _other: noop + }); + }); + }, + undiscriminatedUnion: (utd) => { + utd.members.forEach((member) => { + registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference: member.type + }); + }); + }, + alias: noop, + enum: noop, + _other: noop + }); +} + +export function registerLiteralEnumsForObjectProperties({ + parentSymbol, + registry, + properties +}: { + parentSymbol: swift.Symbol; + registry: NameRegistry; + properties: ObjectProperty[]; +}) { + properties.forEach((property) => { + registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference: property.valueType + }); + }); +} + +export function registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference +}: { + parentSymbol: swift.Symbol; + registry: NameRegistry; + typeReference: TypeReference; +}) { + typeReference._visit({ + container: (ct) => { + ct._visit({ + literal: (literal) => { + literal._visit({ + string: (literalValue) => { + registry.registerNestedLiteralEnumSymbol({ + parentSymbol, + literalValue + }); + }, + _other: noop, + boolean: noop + }); + }, + map: (mt) => { + registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference: mt.keyType + }); + registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference: mt.valueType + }); + }, + list: (lt) => { + registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference: lt + }); + }, + nullable: (typeReference) => { + registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference + }); + }, + optional: (typeReference) => { + registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference + }); + }, + set: (typeReference) => { + registerLiteralEnumsForTypeReference({ + parentSymbol, + registry, + typeReference + }); + }, + _other: noop + }); + }, + named: noop, + primitive: noop, + unknown: noop, + _other: noop + }); +} diff --git a/generators/swift/base/src/context/register-undiscriminated-unions.ts b/generators/swift/base/src/context/register-undiscriminated-unions.ts new file mode 100644 index 000000000000..ccfa975364b0 --- /dev/null +++ b/generators/swift/base/src/context/register-undiscriminated-unions.ts @@ -0,0 +1,116 @@ +import { assertNever, assertNonNull } from "@fern-api/core-utils"; +import { BaseSwiftCustomConfigSchema, swift } from "@fern-api/swift-codegen"; +import { TypeDeclaration } from "@fern-fern/ir-sdk/api"; +import { camelCase, upperFirst } from "lodash-es"; +import { NameRegistry } from "../project"; +import type { AbstractSwiftGeneratorContext } from "."; + +const CASE_LABELS_BY_SWIFT_SYMBOL_NAME: Record = { + String: "string", + Bool: "bool", + Int: "int", + Int64: "int64", + UInt: "uint", + UInt64: "uint64", + Float: "float", + Double: "double", + Void: "void", + Encoder: "encoder", + Decoder: "decoder", + Any: "any" +}; + +const CASE_LABELS_BY_FOUNDATION_SYMBOL_NAME: Record = { + Data: "data", + Date: "date", + URLSession: "urlSession", + UUID: "uuid" +}; + +export function registerUndiscriminatedUnionVariants({ + parentSymbol, + registry, + typeDeclaration, + context +}: { + parentSymbol: swift.Symbol; + registry: NameRegistry; + typeDeclaration: TypeDeclaration; + context: AbstractSwiftGeneratorContext; +}) { + if (typeDeclaration.shape.type === "undiscriminatedUnion") { + const members = typeDeclaration.shape.members.map((member) => { + const swiftType = context.getSwiftTypeReferenceFromScope(member.type, parentSymbol); + return { + swiftType, + caseName: inferCaseNameForTypeReference(parentSymbol, swiftType, registry), + docsContent: member.docs + }; + }); + registry.registerUndiscriminatedUnionVariants({ parentSymbol, variants: members }); + } +} + +export function inferCaseNameForTypeReference( + parentSymbol: swift.Symbol, + typeReference: swift.TypeReference, + registry: NameRegistry +): string { + if (typeReference.variant.type === "symbol") { + const symbolRef = typeReference.variant.symbol; + const symbol = registry.resolveReference({ fromSymbol: parentSymbol, reference: symbolRef }); + assertNonNull(symbol, `Cannot find symbol ${symbolRef} for type reference ${typeReference.variant.type}`); + const symbolName = symbol.name; + if (swift.Symbol.isSwiftSymbol(symbol.id) && swift.Symbol.isSwiftSymbolName(symbolName)) { + return CASE_LABELS_BY_SWIFT_SYMBOL_NAME[symbolName]; + } else if (swift.Symbol.isFoundationSymbol(symbol.id) && swift.Symbol.isFoundationSymbolName(symbolName)) { + return CASE_LABELS_BY_FOUNDATION_SYMBOL_NAME[symbolName]; + } else { + return camelCase(symbolName); + } + } else if (typeReference.variant.type === "generic") { + const argumentTypeCaseNames = typeReference.variant.arguments.map((argument) => + inferCaseNameForTypeReference(parentSymbol, argument, registry) + ); + return `${inferCaseNameForTypeReference(parentSymbol, typeReference.variant.reference, registry)}Of${upperFirst(argumentTypeCaseNames.join("And"))}`; + } else if (typeReference.variant.type === "array") { + const elementTypeCaseName = inferCaseNameForTypeReference( + parentSymbol, + typeReference.variant.elementType, + registry + ); + return `${elementTypeCaseName}Array`; + } else if (typeReference.variant.type === "dictionary") { + const keyTypeCaseName = inferCaseNameForTypeReference(parentSymbol, typeReference.variant.keyType, registry); + const valueTypeCaseName = inferCaseNameForTypeReference( + parentSymbol, + typeReference.variant.valueType, + registry + ); + return `${keyTypeCaseName}To${upperFirst(valueTypeCaseName)}Dictionary`; + } else if (typeReference.variant.type === "optional") { + const valueTypeCaseName = inferCaseNameForTypeReference( + parentSymbol, + typeReference.variant.valueType, + registry + ); + return `optional${upperFirst(valueTypeCaseName)}`; + } else if (typeReference.variant.type === "nullable") { + const valueTypeCaseName = inferCaseNameForTypeReference( + parentSymbol, + typeReference.variant.valueType, + registry + ); + return `nullable${upperFirst(valueTypeCaseName)}`; + } else if (typeReference.variant.type === "tuple") { + const memberTypeCaseNames = typeReference.variant.elements.map((element) => + inferCaseNameForTypeReference(parentSymbol, element, registry) + ); + return `tuple${upperFirst(memberTypeCaseNames.join("And"))}`; + } else if (typeReference.variant.type === "member-access") { + const targetTypeCaseName = inferCaseNameForTypeReference(parentSymbol, typeReference.variant.target, registry); + return `${targetTypeCaseName}${upperFirst(typeReference.variant.memberName)}`; + } else { + assertNever(typeReference.variant); + } +} diff --git a/generators/swift/base/src/project/SourceSymbolRegistry.ts b/generators/swift/base/src/project/SourceSymbolRegistry.ts deleted file mode 100644 index 1fc1fcc6e63c..000000000000 --- a/generators/swift/base/src/project/SourceSymbolRegistry.ts +++ /dev/null @@ -1,306 +0,0 @@ -import { assertDefined, SymbolRegistry, values } from "@fern-api/core-utils"; -import { swift } from "@fern-api/swift-codegen"; - -const SYMBOL_ID_PREFIX = "symbol_id:"; - -export class SourceSymbolRegistry { - private static readonly reservedSymbols = [ - "Swift", - "Foundation", - ...swift.Type.primitiveSymbolNames(), - ...swift.Type.foundationSymbolNames(), - ...values(swift.Protocol) - ]; - - public static create(additionalReservedSymbols?: string[]): SourceSymbolRegistry { - return new SourceSymbolRegistry([ - ...SourceSymbolRegistry.reservedSymbols, - ...(additionalReservedSymbols ?? []) - ]); - } - - private readonly registry: SymbolRegistry; - private readonly requestsRegistry: SymbolRegistry; - - private constructor(reservedSymbolNames: string[]) { - this.registry = new SymbolRegistry({ - reservedSymbolNames - }); - this.requestsRegistry = new SymbolRegistry({ reservedSymbolNames: [] }); - } - - private get moduleSymbolId(): string { - return `${SYMBOL_ID_PREFIX}module`; - } - - private get rootClientSymbolId(): string { - return `${SYMBOL_ID_PREFIX}root_client_class`; - } - - private get environmentSymbolId(): string { - return `${SYMBOL_ID_PREFIX}environment_enum`; - } - - private get requestsContainerSymbolId(): string { - return `${SYMBOL_ID_PREFIX}requests_container`; - } - - private get subClientSymbolIdPrefix(): string { - return `${SYMBOL_ID_PREFIX}subpackage_client_`; - } - - private get schemaTypeSymbolIdPrefix(): string { - return `${SYMBOL_ID_PREFIX}schema_type_`; - } - - private getSubClientSymbolId(subpackageId: string): string { - return `${this.subClientSymbolIdPrefix}${subpackageId}`; - } - - private getSchemaTypeSymbolId(typeId: string): string { - return `${this.schemaTypeSymbolIdPrefix}${typeId}`; - } - - public getModuleSymbolOrThrow(): string { - const symbolName = this.registry.getSymbolNameById(this.moduleSymbolId); - assertDefined(symbolName, "Module symbol not found."); - return symbolName; - } - - public getRootClientSymbolOrThrow(): string { - const symbolName = this.registry.getSymbolNameById(this.rootClientSymbolId); - assertDefined(symbolName, "Root client symbol not found."); - return symbolName; - } - - public getEnvironmentSymbolOrThrow(): string { - const symbolName = this.registry.getSymbolNameById(this.environmentSymbolId); - assertDefined(symbolName, "Environment symbol not found."); - return symbolName; - } - - public getRequestsContainerSymbolOrThrow(): string { - const symbolName = this.registry.getSymbolNameById(this.requestsContainerSymbolId); - assertDefined(symbolName, `Requests container symbol not found`); - return symbolName; - } - - /** - * Retrieves the registered fully qualified inline request type symbol name for a given endpoint and request. - */ - public getFullyQualifiedRequestTypeSymbolOrThrow(endpointId: string, requestNamePascalCase: string): string { - const symbolName = this.getRequestTypeSymbolOrThrow(endpointId, requestNamePascalCase); - const containerSymbolName = this.getRequestsContainerSymbolOrThrow(); - return `${containerSymbolName}.${symbolName}`; - } - - public getRequestTypeSymbolOrThrow(endpointId: string, requestNamePascalCase: string): string { - const symbolId = this.getRequestTypeSymbolId(endpointId, requestNamePascalCase); - const symbolName = this.requestsRegistry.getSymbolNameById(symbolId); - assertDefined(symbolName, `Request symbol not found for request '${requestNamePascalCase}'`); - return symbolName; - } - - public getAllRequestTypeSymbols() { - return this.requestsRegistry.getAllSymbols(); - } - - /** - * Retrieves the registered sub-client symbol name for a given subpackage. - * - * @param subpackageId The unique identifier of the subpackage - * @returns The sub-client symbol name for the specified subpackage - * @throws Error if no sub-client symbol has been registered for the subpackage - */ - public getSubClientSymbolOrThrow(subpackageId: string): string { - const symbolName = this.registry.getSymbolNameById(this.getSubClientSymbolId(subpackageId)); - assertDefined(symbolName, `Subclient symbol not found for subpackage ${subpackageId}`); - return symbolName; - } - - public getAllSubClientSymbols() { - return this.registry.getAllSymbols().filter((symbol) => symbol.id.startsWith(this.subClientSymbolIdPrefix)); - } - - /** - * Retrieves the registered schema type symbol name for a given type ID. - * - * @param typeId The unique identifier of the schema type - * @returns The schema type symbol name for the specified type - * @throws Error if no schema type symbol has been registered for the type ID - */ - public getSchemaTypeSymbolOrThrow(typeId: string): string { - const symbolName = this.registry.getSymbolNameById(this.getSchemaTypeSymbolId(typeId)); - assertDefined(symbolName, `Schema type symbol not found for type ${typeId}`); - return symbolName; - } - - /** - * Registers a unique symbol name for the module. - * Tries preferred name first, then falls back to standard candidates. - * - * @returns The registered unique module symbol name - */ - public registerModuleSymbol({ - configModuleName, - apiNamePascalCase - }: { - configModuleName: string | undefined; - apiNamePascalCase: string; - }): string { - const candidates: [string, ...string[]] = [ - `${apiNamePascalCase}`, - `${apiNamePascalCase}Api`, - `${apiNamePascalCase}Module` - ]; - if (typeof configModuleName === "string") { - candidates.unshift(configModuleName); - } - return this.registry.registerSymbol(this.moduleSymbolId, candidates); - } - - /** - * Registers a unique symbol name for the root client class. - * Tries preferred name first, then falls back to standard candidates. - * - * @returns The registered unique root client symbol name - */ - public registerRootClientSymbol({ - configClientClassName, - apiNamePascalCase - }: { - configClientClassName: string | undefined; - apiNamePascalCase: string; - }): string { - const candidates: [string, ...string[]] = [ - `${apiNamePascalCase}Client`, - `${apiNamePascalCase}ApiClient`, - `${apiNamePascalCase}Service` - ]; - if (typeof configClientClassName === "string") { - candidates.unshift(configClientClassName); - } - return this.registry.registerSymbol(this.rootClientSymbolId, candidates); - } - - /** - * Registers and generates a unique symbol name for the environment enum. - * Tries preferred name first, then falls back to standard candidates. - * - * @returns The generated unique environment symbol name - */ - public registerEnvironmentSymbol({ - configEnvironmentEnumName, - apiNamePascalCase - }: { - configEnvironmentEnumName: string | undefined; - apiNamePascalCase: string; - }): string { - const candidates: [string, ...string[]] = [ - `${apiNamePascalCase}Environment`, - `${apiNamePascalCase}Environ`, - `${apiNamePascalCase}Env` - ]; - if (typeof configEnvironmentEnumName === "string") { - candidates.unshift(configEnvironmentEnumName); - } - return this.registry.registerSymbol(this.environmentSymbolId, candidates); - } - - public registerRequestsContainerSymbol(): string { - return this.registry.registerSymbol(this.requestsContainerSymbolId, [ - "Requests", - "RequestTypes", - "InlineRequests" - ]); - } - - /** - * Registers and generates a unique symbol name for an inline request type. - * Generates different fallback candidates based on whether the request name already ends with "Request". - * - * @param endpointId The unique identifier of the endpoint - * @param requestNamePascalCase The request name in PascalCase - * @returns The generated unique inline request type symbol name - */ - public registerRequestTypeSymbol({ - endpointId, - requestNamePascalCase - }: { - endpointId: string; - requestNamePascalCase: string; - }): string { - const symbolId = this.getRequestTypeSymbolId(endpointId, requestNamePascalCase); - const fallbackCandidates: string[] = [`${requestNamePascalCase}Type`]; - if (requestNamePascalCase.endsWith("Request")) { - fallbackCandidates.push(`${requestNamePascalCase}Body`, `${requestNamePascalCase}BodyType`); - } else { - fallbackCandidates.push( - `${requestNamePascalCase}Request`, - `${requestNamePascalCase}RequestBody`, - `${requestNamePascalCase}RequestBodyType` - ); - } - return this.requestsRegistry.registerSymbol(symbolId, [requestNamePascalCase, ...fallbackCandidates]); - } - - /** - * Registers and generates a unique symbol name for a sub-client class. - * Generates fallback candidates by combining filepath parts with the subpackage name - * to create unique identifiers when simple names collide. - * - * @param subpackageId The unique identifier of the subpackage - * @param fernFilepathPartNamesPascalCase Array of filepath parts in PascalCase - * @param subpackageNamePascalCase The subpackage name in PascalCase - * @returns The generated unique sub-client symbol name - */ - public registerSubClientSymbol({ - subpackageId, - fernFilepathPartNamesPascalCase, - subpackageNamePascalCase - }: { - subpackageId: string; - fernFilepathPartNamesPascalCase: string[]; - subpackageNamePascalCase: string; - }): string { - const reversedParts = fernFilepathPartNamesPascalCase.toReversed(); - reversedParts.shift(); - const fallbackCandidates = reversedParts.map( - (_, partIdx) => - reversedParts - .slice(0, partIdx + 1) - .reverse() - .join("") + - subpackageNamePascalCase + - "Client" - ); - return this.registry.registerSymbol(this.getSubClientSymbolId(subpackageId), [ - `${subpackageNamePascalCase}Client`, - ...fallbackCandidates - ]); - } - - /** - * Registers and generates a unique symbol name for a schema type (struct, enum, union, etc.). - * Tries candidate names in order: {Type}, {Type}Type, {Type}Model, {Type}Schema. - * - * @param typeId The unique identifier of the type - * @param typeDeclarationNamePascalCase The type declaration name in PascalCase - * @returns The generated unique schema type symbol name - */ - public registerSchemaTypeSymbol(typeId: string, typeDeclarationNamePascalCase: string): string { - return this.registry.registerSymbol(this.getSchemaTypeSymbolId(typeId), [ - typeDeclarationNamePascalCase, - `${typeDeclarationNamePascalCase}Type`, - `${typeDeclarationNamePascalCase}Model`, - `${typeDeclarationNamePascalCase}Schema` - ]); - } - - /** - * @returns The symbol ID to use for the requests registry. - */ - private getRequestTypeSymbolId(endpointId: string, requestNamePascalCase: string): string { - return `${endpointId}_${requestNamePascalCase}`; - } -} diff --git a/generators/swift/base/src/project/SwiftProject.ts b/generators/swift/base/src/project/SwiftProject.ts index 71131770f2ff..6cd6af0d2e0b 100644 --- a/generators/swift/base/src/project/SwiftProject.ts +++ b/generators/swift/base/src/project/SwiftProject.ts @@ -2,12 +2,10 @@ import { mkdir } from "node:fs/promises"; import { AbstractProject, File } from "@fern-api/base-generator"; import { AbsoluteFilePath, join, RelativeFilePath } from "@fern-api/fs-utils"; import { BaseSwiftCustomConfigSchema, swift } from "@fern-api/swift-codegen"; -import { SourceAsIsFiles, TestAsIsFiles } from "../AsIs"; import { AbstractSwiftGeneratorContext } from "../context"; -import { FileRegistry } from "./FileRegistry"; -import { SourceSymbolRegistry } from "./SourceSymbolRegistry"; +import { FileRegistry } from "./file-registry"; +import { NameRegistry } from "./name-registry"; import { SwiftFile } from "./SwiftFile"; -import { TestSymbolRegistry } from "./TestSymbolRegistry"; interface FileCandidate { nameCandidateWithoutExtension: string; @@ -23,18 +21,7 @@ export class SwiftProject extends AbstractProject file.symbolNames); - return SourceSymbolRegistry.create(additionalReservedSymbols); - } - - private static createTestSymbolRegistry(): TestSymbolRegistry { - const additionalReservedSymbols = Object.values(TestAsIsFiles).flatMap((file) => file.symbolNames); - return TestSymbolRegistry.create(additionalReservedSymbols); - } + public readonly nameRegistry: NameRegistry; public constructor({ context @@ -42,8 +29,7 @@ export class SwiftProject extends AbstractProject; }) { super(context); - this.srcSymbolRegistry = SwiftProject.createSrcSymbolRegistry(); - this.testSymbolRegistry = SwiftProject.createTestSymbolRegistry(); + this.nameRegistry = NameRegistry.create(); } public get sourcesDirectory(): RelativeFilePath { diff --git a/generators/swift/base/src/project/TestSymbolRegistry.ts b/generators/swift/base/src/project/TestSymbolRegistry.ts deleted file mode 100644 index 3a83a67ab399..000000000000 --- a/generators/swift/base/src/project/TestSymbolRegistry.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { assertDefined, SymbolRegistry, values } from "@fern-api/core-utils"; -import { swift } from "@fern-api/swift-codegen"; - -const SYMBOL_ID_PREFIX = "symbol_id:"; - -export class TestSymbolRegistry { - private static readonly reservedSymbols = [ - "Swift", - "Foundation", - ...swift.Type.primitiveSymbolNames(), - ...swift.Type.foundationSymbolNames(), - ...values(swift.Protocol) - ]; - - public static create(additionalReservedSymbols?: string[]): TestSymbolRegistry { - return new TestSymbolRegistry([...TestSymbolRegistry.reservedSymbols, ...(additionalReservedSymbols ?? [])]); - } - - private readonly registry: SymbolRegistry; - - private constructor(reservedSymbolNames: string[]) { - this.registry = new SymbolRegistry({ - reservedSymbolNames - }); - } - - public getModuleSymbolOrThrow(): string { - const symbolName = this.registry.getSymbolNameById(this.getModuleSymbolId()); - assertDefined(symbolName, "Module symbol not found."); - return symbolName; - } - - public getWireTestSuiteSymbolOrThrow(subclientName: string): string { - const symbolName = this.registry.getSymbolNameById(this.getWireTestSuiteSymbolId(subclientName)); - assertDefined(symbolName, `Wire test suite symbol not found for subclient ${subclientName}`); - return symbolName; - } - - public registerWireTestSuiteSymbol(subclientName: string): string { - return this.registry.registerSymbol(this.getWireTestSuiteSymbolId(subclientName), [ - `${subclientName}WireTests`, - `${subclientName}WireTestSuite` - ]); - } - - private getModuleSymbolId(): string { - return `${SYMBOL_ID_PREFIX}module`; - } - - private getWireTestSuiteSymbolId(subclientName: string): string { - return `${SYMBOL_ID_PREFIX}wire_test_suite_${subclientName}`; - } -} diff --git a/generators/swift/base/src/project/FileRegistry.ts b/generators/swift/base/src/project/file-registry/file-registry.ts similarity index 97% rename from generators/swift/base/src/project/FileRegistry.ts rename to generators/swift/base/src/project/file-registry/file-registry.ts index 59a47c4ddfe6..338f70915d9b 100644 --- a/generators/swift/base/src/project/FileRegistry.ts +++ b/generators/swift/base/src/project/file-registry/file-registry.ts @@ -1,6 +1,6 @@ import { RelativeFilePath } from "@fern-api/fs-utils"; import { swift } from "@fern-api/swift-codegen"; -import { SwiftFile } from "./SwiftFile"; +import { SwiftFile } from "../SwiftFile"; export class FileRegistry { private readonly filesByName: Map = new Map(); diff --git a/generators/swift/base/src/project/file-registry/index.ts b/generators/swift/base/src/project/file-registry/index.ts new file mode 100644 index 000000000000..290ba15bdfdf --- /dev/null +++ b/generators/swift/base/src/project/file-registry/index.ts @@ -0,0 +1 @@ +export * from "./file-registry"; diff --git a/generators/swift/base/src/project/index.ts b/generators/swift/base/src/project/index.ts index 08f2db42e9b2..b2e2d14ff303 100644 --- a/generators/swift/base/src/project/index.ts +++ b/generators/swift/base/src/project/index.ts @@ -1,4 +1,3 @@ -export * from "./SourceSymbolRegistry"; +export * from "./name-registry"; export * from "./SwiftFile"; export * from "./SwiftProject"; -export * from "./TestSymbolRegistry"; diff --git a/generators/swift/base/src/project/name-registry/index.ts b/generators/swift/base/src/project/name-registry/index.ts new file mode 100644 index 000000000000..fd88ec71b720 --- /dev/null +++ b/generators/swift/base/src/project/name-registry/index.ts @@ -0,0 +1 @@ +export * from "./name-registry"; diff --git a/generators/swift/base/src/project/name-registry/name-registry.ts b/generators/swift/base/src/project/name-registry/name-registry.ts new file mode 100644 index 000000000000..d9c96b7b0bd3 --- /dev/null +++ b/generators/swift/base/src/project/name-registry/name-registry.ts @@ -0,0 +1,489 @@ +import { assertDefined, SymbolRegistry as Namespace } from "@fern-api/core-utils"; +import { LiteralEnum, swift } from "@fern-api/swift-codegen"; +import { uniqWith } from "lodash-es"; +import { AsIsSymbolName } from "../../AsIs"; +import { RequestsNamespace } from "./requests-namespace"; +import { SourceModuleNamespace } from "./source-module-namespace"; +import { TestModuleNamespace } from "./test-module-namespace"; + +type UndiscriminatedUnionVariant = { + caseName: string; + swiftType: swift.TypeReference; + docsContent: string | undefined; +}; + +type DiscriminatedUnionVariant = { + caseName: string; + symbolName: string; + discriminantWireValue: string; + docsContent: string | undefined; +}; + +export class NameRegistry { + public static create(): NameRegistry { + return new NameRegistry(); + } + + private readonly symbolRegistry: swift.SymbolRegistry; + private readonly sourceModuleNamespace: SourceModuleNamespace; + private readonly testModuleNamespace: TestModuleNamespace; + private readonly requestsNamespace: RequestsNamespace; + private readonly sourceAsIsSymbolsByName: Map; + private readonly testAsIsSymbolsByName: Map; + private readonly requestTypeSymbols: swift.Symbol[]; + private readonly subClientSymbols: swift.Symbol[]; + private readonly nestedLiteralEnumSymbolsByParentSymbolId: Map>; + private readonly discriminatedUnionVariantsByParentSymbolId: Map; + private readonly undiscriminatedUnionVariantsByParentSymbolId: Map; + + private constructor() { + this.symbolRegistry = swift.SymbolRegistry.create(); + this.sourceModuleNamespace = new SourceModuleNamespace(); + this.testModuleNamespace = new TestModuleNamespace(); + this.requestsNamespace = new RequestsNamespace(); + this.sourceAsIsSymbolsByName = new Map(); + this.testAsIsSymbolsByName = new Map(); + this.requestTypeSymbols = []; + this.subClientSymbols = []; + this.nestedLiteralEnumSymbolsByParentSymbolId = new Map(); + this.discriminatedUnionVariantsByParentSymbolId = new Map(); + this.undiscriminatedUnionVariantsByParentSymbolId = new Map(); + } + + public getAsIsSymbolOrThrow(symbolName: AsIsSymbolName): swift.Symbol { + const symbol = this.sourceAsIsSymbolsByName.get(symbolName); + assertDefined(symbol, `As is symbol not found for name "${symbolName}"`); + return symbol; + } + + /** + * Registers a unique symbol name for the source module. + * Tries preferred name first, then falls back to standard candidates. + */ + public registerSourceModuleSymbol({ + configModuleName, + apiNamePascalCase, + asIsSymbols + }: { + configModuleName: string | undefined; + apiNamePascalCase: string; + asIsSymbols: { name: string; shape: swift.TypeSymbolShape }[]; + }): swift.Symbol { + const candidates: [string, ...string[]] = [ + `${apiNamePascalCase}`, + `${apiNamePascalCase}Api`, + `${apiNamePascalCase}Module` + ]; + if (typeof configModuleName === "string") { + candidates.unshift(configModuleName); + } + const tempNamespace = new Namespace({ reservedSymbolNames: ["Swift", "Foundation"] }); + const moduleSymbolName = tempNamespace.registerSymbol("Module", candidates); + const moduleSymbol = this.symbolRegistry.registerSourceModule(moduleSymbolName); + asIsSymbols.forEach((asIsSymbol) => { + const symbolName = asIsSymbol.name; + this.symbolRegistry.registerSourceModuleType(symbolName, asIsSymbol.shape); + this.sourceModuleNamespace.addAsIsSymbolName(symbolName); + const symbolId = this.symbolRegistry.inferSymbolIdForSourceModuleType(symbolName); + const symbol = swift.Symbol.create(symbolId, symbolName, asIsSymbol.shape); + this.sourceAsIsSymbolsByName.set(symbolName, symbol); + }); + return moduleSymbol; + } + + public getRegisteredSourceModuleSymbolOrThrow(): swift.Symbol { + return this.symbolRegistry.getRegisteredSourceModuleSymbolOrThrow(); + } + + /** + * Registers a unique symbol name for the test module. + * Tries preferred name first, then falls back to standard candidates. + */ + public registerTestModuleSymbol({ + sourceModuleName, + asIsSymbols + }: { + sourceModuleName: string; + asIsSymbols: { name: string; shape: swift.TypeSymbolShape }[]; + }): swift.Symbol { + const candidates: [string, ...string[]] = [ + `${sourceModuleName}Tests`, + `${sourceModuleName}Test`, + `${sourceModuleName}TestsModule` + ]; + const moduleSymbolName = (() => { + const ns = new Namespace(); + ns.registerSymbol("Swift", ["Swift"]); + ns.registerSymbol("Foundation", ["Foundation"]); + ns.registerSymbol(sourceModuleName, [sourceModuleName]); + return ns.registerSymbol(`${sourceModuleName}Tests`, candidates); + })(); + const moduleSymbol = this.symbolRegistry.registerTestModule(moduleSymbolName); + asIsSymbols.forEach((asIsSymbol) => { + const symbolName = asIsSymbol.name; + this.symbolRegistry.registerTestModuleType(symbolName, asIsSymbol.shape); + this.testModuleNamespace.addAsIsSymbol(symbolName); + const symbolId = this.symbolRegistry.inferSymbolIdForTestModuleType(symbolName); + const symbol = swift.Symbol.create(symbolId, symbolName, asIsSymbol.shape); + this.testAsIsSymbolsByName.set(symbolName, symbol); + }); + return moduleSymbol; + } + + public getRegisteredTestModuleSymbolOrThrow(): swift.Symbol { + return this.symbolRegistry.getRegisteredTestModuleSymbolOrThrow(); + } + + /** + * Registers a unique symbol name for the root client class. + * Tries preferred name first, then falls back to standard candidates. + */ + public registerRootClientSymbol({ + configClientClassName, + apiNamePascalCase + }: { + configClientClassName: string | undefined; + apiNamePascalCase: string; + }): swift.Symbol { + const candidates: [string, ...string[]] = [ + `${apiNamePascalCase}Client`, + `${apiNamePascalCase}ApiClient`, + `${apiNamePascalCase}Service` + ]; + if (typeof configClientClassName === "string") { + candidates.unshift(configClientClassName); + } + const symbolName = this.sourceModuleNamespace.addRootClientSymbolName(candidates); + return this.symbolRegistry.registerSourceModuleType(symbolName, { type: "class" }); + } + + public getRootClientSymbolOrThrow(): swift.Symbol { + const symbolName = this.sourceModuleNamespace.getRootClientSymbolNameOrThrow(); + const symbolId = this.symbolRegistry.inferSymbolIdForSourceModuleType(symbolName); + return this.symbolRegistry.getSymbolByIdOrThrow(symbolId); + } + + /** + * Registers and generates a unique symbol name for the environment enum. + * Tries preferred name first, then falls back to standard candidates. + */ + public registerEnvironmentSymbol({ + configEnvironmentEnumName, + apiNamePascalCase + }: { + configEnvironmentEnumName: string | undefined; + apiNamePascalCase: string; + }): swift.Symbol { + const candidates: [string, ...string[]] = [ + `${apiNamePascalCase}Environment`, + `${apiNamePascalCase}Environ`, + `${apiNamePascalCase}Env` + ]; + if (typeof configEnvironmentEnumName === "string") { + candidates.unshift(configEnvironmentEnumName); + } + const symbolName = this.sourceModuleNamespace.addEnvironmentSymbolName(candidates); + return this.symbolRegistry.registerSourceModuleType(symbolName, { type: "enum-with-raw-values" }); + } + + public getEnvironmentSymbolOrThrow(): swift.Symbol { + const symbolName = this.sourceModuleNamespace.getEnvironmentSymbolNameOrThrow(); + const symbolId = this.symbolRegistry.inferSymbolIdForSourceModuleType(symbolName); + return this.symbolRegistry.getSymbolByIdOrThrow(symbolId); + } + + public registerRequestsContainerSymbol(): swift.Symbol { + const symbolName = this.sourceModuleNamespace.addRequestsContainerSymbolName([ + "Requests", + "RequestTypes", + "InlineRequests" + ]); + return this.symbolRegistry.registerSourceModuleType(symbolName, { type: "enum-container" }); + } + + public getRequestsContainerSymbolOrThrow(): swift.Symbol { + const symbolName = this.sourceModuleNamespace.getRequestsContainerSymbolNameOrThrow(); + const symbolId = this.symbolRegistry.inferSymbolIdForSourceModuleType(symbolName); + return this.symbolRegistry.getSymbolByIdOrThrow(symbolId); + } + + /** + * Registers and generates a unique symbol name for an inline request type. + * Generates different fallback candidates based on whether the request name already ends with "Request". + * + * @param endpointId The unique identifier of the endpoint + * @param requestNamePascalCase The request name in PascalCase + */ + public registerRequestTypeSymbol({ + endpointId, + requestNamePascalCase + }: { + endpointId: string; + requestNamePascalCase: string; + }): swift.Symbol { + const fallbackCandidates: string[] = [`${requestNamePascalCase}Type`]; + if (requestNamePascalCase.endsWith("Request")) { + fallbackCandidates.push(`${requestNamePascalCase}Body`, `${requestNamePascalCase}BodyType`); + } else { + fallbackCandidates.push( + `${requestNamePascalCase}Request`, + `${requestNamePascalCase}RequestBody`, + `${requestNamePascalCase}RequestBodyType` + ); + } + const parentSymbol = this.getRequestsContainerSymbolOrThrow(); + const symbolName = this.requestsNamespace.addRequestTypeSymbol(endpointId, requestNamePascalCase, [ + requestNamePascalCase, + ...fallbackCandidates + ]); + const symbol = this.symbolRegistry.registerNestedType({ + parentSymbol, + symbolName, + shape: { type: "struct" } + }); + this.requestTypeSymbols.push(symbol); + return symbol; + } + + public getRequestTypeSymbolOrThrow(endpointId: string, requestNamePascalCase: string): swift.Symbol { + const symbolName = this.requestsNamespace.getRequestTypeNameOrThrow(endpointId, requestNamePascalCase); + const parentSymbol = this.getRequestsContainerSymbolOrThrow(); + const symbolId = this.symbolRegistry.inferSymbolIdForNestedType(parentSymbol.id, symbolName); + return this.symbolRegistry.getSymbolByIdOrThrow(symbolId); + } + + public getAllRequestTypeSymbols(): swift.Symbol[] { + return [...this.requestTypeSymbols]; + } + + /** + * Registers and generates a unique symbol name for a sub-client class. + * Generates fallback candidates by combining filepath parts with the subpackage name + * to create unique identifiers when simple names collide. + * + * @param subpackageId The unique identifier of the subpackage + * @param fernFilepathPartNamesPascalCase Array of filepath parts in PascalCase + * @param subpackageNamePascalCase The subpackage name in PascalCase + */ + public registerSubClientSymbol({ + subpackageId, + fernFilepathPartNamesPascalCase, + subpackageNamePascalCase + }: { + subpackageId: string; + fernFilepathPartNamesPascalCase: string[]; + subpackageNamePascalCase: string; + }): swift.Symbol { + const reversedParts = fernFilepathPartNamesPascalCase.toReversed(); + reversedParts.shift(); + const fallbackCandidates = reversedParts.map( + (_, partIdx) => + reversedParts + .slice(0, partIdx + 1) + .reverse() + .join("") + + subpackageNamePascalCase + + "Client" + ); + const symbolName = this.sourceModuleNamespace.addSubClientSymbolName(subpackageId, [ + `${subpackageNamePascalCase}Client`, + ...fallbackCandidates + ]); + const symbol = this.symbolRegistry.registerSourceModuleType(symbolName, { type: "class" }); + this.subClientSymbols.push(symbol); + return symbol; + } + + public getSubClientSymbolOrThrow(subpackageId: string): swift.Symbol { + const symbolName = this.sourceModuleNamespace.getSubClientSymbolNameOrThrow(subpackageId); + const symbolId = this.symbolRegistry.inferSymbolIdForSourceModuleType(symbolName); + return this.symbolRegistry.getSymbolByIdOrThrow(symbolId); + } + + public getAllSubClientSymbols(): swift.Symbol[] { + return [...this.subClientSymbols]; + } + + /** + * Registers and generates a unique symbol name for a schema type (struct, enum, union, etc.). + * Tries candidate names in order: {Type}, {Type}Type, {Type}Model, {Type}Schema. + * + * @param typeId The unique identifier of the type + * @param typeDeclarationNamePascalCase The type declaration name in PascalCase + */ + public registerSchemaTypeSymbol( + typeId: string, + typeDeclarationNamePascalCase: string, + shape: swift.TypeSymbolShape + ): swift.Symbol { + const symbolName = this.sourceModuleNamespace.addSchemaTypeSymbolName(typeId, [ + typeDeclarationNamePascalCase, + `${typeDeclarationNamePascalCase}Type`, + `${typeDeclarationNamePascalCase}Model`, + `${typeDeclarationNamePascalCase}Schema` + ]); + return this.symbolRegistry.registerSourceModuleType(symbolName, shape); + } + + public getSchemaTypeSymbolOrThrow(typeId: string): swift.Symbol { + const symbolName = this.sourceModuleNamespace.getSchemaTypeSymbolNameOrThrow(typeId); + const symbolId = this.symbolRegistry.inferSymbolIdForSourceModuleType(symbolName); + return this.symbolRegistry.getSymbolByIdOrThrow(symbolId); + } + + public registerNestedLiteralEnumSymbol({ + parentSymbol, + literalValue + }: { + parentSymbol: swift.Symbol | string; + literalValue: string; + }) { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + + const enumsByLiteralValue = + this.nestedLiteralEnumSymbolsByParentSymbolId.get(parentSymbolId) ?? new Map(); + const existingSymbol = enumsByLiteralValue.get(literalValue); + if (existingSymbol) { + return existingSymbol; + } + const literalEnumSymbolsForParent = Array.from(enumsByLiteralValue.values()); + + const symbolName = (() => { + const ns = new Namespace({ reservedSymbolNames: ["CodingKeys"] }); + literalEnumSymbolsForParent.forEach((s) => { + ns.registerSymbol(s.id, [s.name]); + }); + const mainCandidate = LiteralEnum.generateName(literalValue); + return ns.registerSymbol(literalValue, [ + mainCandidate, + `${mainCandidate}Literal`, + `${mainCandidate}Enum`, + `${mainCandidate}StringEnum` + ]); + })(); + + const newSymbol = this.symbolRegistry.registerNestedType({ + parentSymbol, + symbolName, + shape: { type: "enum-with-raw-values" } + }); + enumsByLiteralValue.set(literalValue, newSymbol); + this.nestedLiteralEnumSymbolsByParentSymbolId.set(parentSymbolId, enumsByLiteralValue); + return newSymbol; + } + + public getNestedLiteralEnumSymbolOrThrow(parentSymbol: swift.Symbol | string, literalValue: string): swift.Symbol { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + const enumsByLiteralValue = + this.nestedLiteralEnumSymbolsByParentSymbolId.get(parentSymbolId) ?? new Map(); + const existingSymbol = enumsByLiteralValue.get(literalValue); + assertDefined( + existingSymbol, + `Nested literal enum symbol not found for literal value "${literalValue}" in parent symbol "${parentSymbolId}"` + ); + return existingSymbol; + } + + public getAllNestedLiteralEnumSymbolsOrThrow(parentSymbol: swift.Symbol | string): { + symbol: swift.Symbol; + literalValue: string; + caseLabel: string; + }[] { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + const enumsByLiteralValue = + this.nestedLiteralEnumSymbolsByParentSymbolId.get(parentSymbolId) ?? new Map(); + return Array.from(enumsByLiteralValue.entries()) + .sort(([, symbol1], [, symbol2]) => symbol1.name.localeCompare(symbol2.name)) + .map(([literalValue, symbol]) => ({ + symbol, + literalValue, + caseLabel: LiteralEnum.generateEnumCaseLabel(literalValue) + })); + } + + public registerDiscriminatedUnionVariants({ + parentSymbol, + variants + }: { + parentSymbol: swift.Symbol | string; + variants: DiscriminatedUnionVariant[]; + }) { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + const sortedVariants = [...variants].sort((a, b) => a.caseName.localeCompare(b.caseName)); + this.discriminatedUnionVariantsByParentSymbolId.set(parentSymbolId, sortedVariants); + sortedVariants.forEach((variant) => { + this.symbolRegistry.registerNestedType({ + parentSymbol, + symbolName: variant.symbolName, + shape: { type: "struct" } + }); + }); + return sortedVariants; + } + + public getDiscriminatedUnionVariantSymbolOrThrow( + parentSymbol: swift.Symbol | string, + discriminantWireValue: string + ): swift.Symbol { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + const variants = this.discriminatedUnionVariantsByParentSymbolId.get(parentSymbolId) ?? []; + const variant = variants.find((v) => v.discriminantWireValue === discriminantWireValue); + assertDefined( + variant, + `Discriminated union variant symbol not found for discriminant wire value "${discriminantWireValue}" in parent symbol "${parentSymbolId}"` + ); + const symbolId = this.symbolRegistry.inferSymbolIdForNestedType(parentSymbolId, variant.symbolName); + return swift.Symbol.create(symbolId, variant.symbolName, { type: "struct" }); + } + + public getAllDiscriminatedUnionVariantsOrThrow(parentSymbol: swift.Symbol | string): DiscriminatedUnionVariant[] { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + return this.discriminatedUnionVariantsByParentSymbolId.get(parentSymbolId) ?? []; + } + + public registerUndiscriminatedUnionVariants({ + parentSymbol, + variants + }: { + parentSymbol: swift.Symbol | string; + variants: UndiscriminatedUnionVariant[]; + }) { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + const distinctVariants = uniqWith(variants, (a, b) => a.caseName === b.caseName); + distinctVariants.sort((a, b) => a.caseName.localeCompare(b.caseName)); + this.undiscriminatedUnionVariantsByParentSymbolId.set(parentSymbolId, distinctVariants); + return distinctVariants; + } + + public getAllUndiscriminatedUnionVariantsOrThrow( + parentSymbol: swift.Symbol | string + ): UndiscriminatedUnionVariant[] { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + const variants = this.undiscriminatedUnionVariantsByParentSymbolId.get(parentSymbolId) ?? []; + return variants; + } + + public registerWireTestSuiteSymbol(subclientName: string) { + const symbolName = this.testModuleNamespace.registerWireTestSuiteSymbol(subclientName); + return this.symbolRegistry.registerTestModuleType(symbolName, { type: "struct" }); + } + + public getWireTestSuiteSymbolOrThrow(subclientName: string): swift.Symbol { + const symbolName = this.testModuleNamespace.getWireTestSuiteNameOrThrow(subclientName); + const symbolId = this.symbolRegistry.inferSymbolIdForTestModuleType(symbolName); + return this.symbolRegistry.getSymbolByIdOrThrow(symbolId); + } + + public referenceFromSourceModuleScope(symbol: swift.Symbol | string) { + const moduleSymbol = this.getRegisteredSourceModuleSymbolOrThrow(); + return this.symbolRegistry.reference({ fromSymbol: moduleSymbol, toSymbol: symbol }); + } + + public reference({ fromSymbol, toSymbol }: { fromSymbol: swift.Symbol | string; toSymbol: swift.Symbol | string }) { + return this.symbolRegistry.reference({ fromSymbol, toSymbol }); + } + + public resolveReference({ fromSymbol, reference }: { fromSymbol: swift.Symbol | string; reference: string }) { + return this.symbolRegistry.resolveReference({ fromSymbol, reference }); + } +} diff --git a/generators/swift/base/src/project/name-registry/requests-namespace.ts b/generators/swift/base/src/project/name-registry/requests-namespace.ts new file mode 100644 index 000000000000..190906839048 --- /dev/null +++ b/generators/swift/base/src/project/name-registry/requests-namespace.ts @@ -0,0 +1,27 @@ +import { SymbolRegistry as Namespace } from "@fern-api/core-utils"; + +export class RequestsNamespace { + private readonly namespace: Namespace; + + public constructor() { + this.namespace = new Namespace(); + } + + public getRequestTypeNameOrThrow(endpointId: string, requestNamePascalCase: string) { + const nameId = this.requestTypeNameId(endpointId, requestNamePascalCase); + return this.namespace.getSymbolNameByIdOrThrow(nameId); + } + + public addRequestTypeSymbol( + endpointId: string, + requestNamePascalCase: string, + symbolNameCandidates: [string, ...string[]] + ) { + const nameId = this.requestTypeNameId(endpointId, requestNamePascalCase); + return this.namespace.registerSymbol(nameId, symbolNameCandidates); + } + + private requestTypeNameId(endpointId: string, requestNamePascalCase: string): string { + return `${endpointId}_${requestNamePascalCase}`; + } +} diff --git a/generators/swift/base/src/project/name-registry/source-module-namespace.ts b/generators/swift/base/src/project/name-registry/source-module-namespace.ts new file mode 100644 index 000000000000..880f84f8db61 --- /dev/null +++ b/generators/swift/base/src/project/name-registry/source-module-namespace.ts @@ -0,0 +1,84 @@ +import { SymbolRegistry as Namespace } from "@fern-api/core-utils"; + +export class SourceModuleNamespace { + private readonly namespace: Namespace; + + public constructor() { + this.namespace = new Namespace(); + } + + public addAsIsSymbolName(symbolName: string) { + const nameId = this.asIsSymbolNameId(symbolName); + this.namespace.registerSymbol(nameId, [symbolName]); + } + + private asIsSymbolNameId(symbolName: string): string { + return `AsIs:${symbolName}`; + } + + public addRootClientSymbolName(symbolNameCandidates: [string, ...string[]]) { + const nameId = this.rootClientSymbolNameId(); + return this.namespace.registerSymbol(nameId, symbolNameCandidates); + } + + public getRootClientSymbolNameOrThrow() { + return this.namespace.getSymbolNameByIdOrThrow(this.rootClientSymbolNameId()); + } + + private rootClientSymbolNameId(): string { + return `RootClientClass`; + } + + public addEnvironmentSymbolName(symbolNameCandidates: [string, ...string[]]) { + const nameId = this.environmentSymbolNameId(); + return this.namespace.registerSymbol(nameId, symbolNameCandidates); + } + + public getEnvironmentSymbolNameOrThrow() { + return this.namespace.getSymbolNameByIdOrThrow(this.environmentSymbolNameId()); + } + + private environmentSymbolNameId(): string { + return `EnvironmentEnum`; + } + + public addRequestsContainerSymbolName(symbolNameCandidates: [string, ...string[]]) { + const nameId = this.requestsContainerSymbolNameId(); + return this.namespace.registerSymbol(nameId, symbolNameCandidates); + } + + public getRequestsContainerSymbolNameOrThrow() { + return this.namespace.getSymbolNameByIdOrThrow(this.requestsContainerSymbolNameId()); + } + + private requestsContainerSymbolNameId(): string { + return `RequestsContainer`; + } + + public addSubClientSymbolName(subpackageId: string, symbolNameCandidates: [string, ...string[]]) { + const nameId = this.subClientSymbolNameId(subpackageId); + return this.namespace.registerSymbol(nameId, symbolNameCandidates); + } + + public getSubClientSymbolNameOrThrow(subpackageId: string) { + return this.namespace.getSymbolNameByIdOrThrow(this.subClientSymbolNameId(subpackageId)); + } + + private subClientSymbolNameId(subpackageId: string): string { + return `SubClient:${subpackageId}`; + } + + public addSchemaTypeSymbolName(typeId: string, symbolNameCandidates: [string, ...string[]]) { + const nameId = this.schemaTypeSymbolNameId(typeId); + return this.namespace.registerSymbol(nameId, symbolNameCandidates); + } + + public getSchemaTypeSymbolNameOrThrow(typeId: string) { + const nameId = this.schemaTypeSymbolNameId(typeId); + return this.namespace.getSymbolNameByIdOrThrow(nameId); + } + + private schemaTypeSymbolNameId(typeId: string): string { + return `SchemaType:${typeId}`; + } +} diff --git a/generators/swift/base/src/project/name-registry/test-module-namespace.ts b/generators/swift/base/src/project/name-registry/test-module-namespace.ts new file mode 100644 index 000000000000..542664ee80f0 --- /dev/null +++ b/generators/swift/base/src/project/name-registry/test-module-namespace.ts @@ -0,0 +1,35 @@ +import { SymbolRegistry as Namespace } from "@fern-api/core-utils"; + +export class TestModuleNamespace { + private readonly namespace: Namespace; + + public constructor() { + this.namespace = new Namespace(); + } + + private asIsNameId(symbolName: string): string { + return `AsIs:${symbolName}`; + } + + private wireTestSuiteNameId(typeId: string): string { + return `WireTestSuite:${typeId}`; + } + + // Setters + + public addAsIsSymbol(symbolName: string) { + const nameId = this.asIsNameId(symbolName); + this.namespace.registerSymbol(nameId, [symbolName]); + } + + public registerWireTestSuiteSymbol(subclientName: string): string { + return this.namespace.registerSymbol(this.wireTestSuiteNameId(subclientName), [ + `${subclientName}WireTests`, + `${subclientName}WireTestSuite` + ]); + } + + public getWireTestSuiteNameOrThrow(subclientName: string): string { + return this.namespace.getSymbolNameByIdOrThrow(this.wireTestSuiteNameId(subclientName)); + } +} diff --git a/generators/swift/base/tsconfig.json b/generators/swift/base/tsconfig.json index d41f014ceb3f..c691755a3f8f 100644 --- a/generators/swift/base/tsconfig.json +++ b/generators/swift/base/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "composite": true, "outDir": "lib", - "rootDir": "src" + "rootDir": "src", + "types": ["vitest/globals"] }, "include": ["./src/**/*"], "references": [ diff --git a/generators/swift/base/vitest.config.ts b/generators/swift/base/vitest.config.ts new file mode 100644 index 000000000000..fecc099c58ab --- /dev/null +++ b/generators/swift/base/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../../shared/vitest.config"; diff --git a/generators/swift/codegen/src/ast/ComputedProperty.ts b/generators/swift/codegen/src/ast/ComputedProperty.ts index 46f67e41a978..2a2fbc7da39d 100644 --- a/generators/swift/codegen/src/ast/ComputedProperty.ts +++ b/generators/swift/codegen/src/ast/ComputedProperty.ts @@ -6,13 +6,13 @@ import { AstNode, Writer } from "./core"; import { DocComment } from "./DocComment"; import { Expression } from "./Expression"; import { Statement } from "./Statement"; -import { Type } from "./Type"; +import { TypeReference } from "./TypeReference"; export declare namespace ComputedProperty { interface Args { unsafeName: string; accessLevel?: AccessLevel; - type: Type; + type: TypeReference; body: Expression | CodeBlock; docs?: DocComment; } @@ -21,7 +21,7 @@ export declare namespace ComputedProperty { export class ComputedProperty extends AstNode { public readonly unsafeName: string; public readonly accessLevel?: AccessLevel; - public readonly type: Type; + public readonly type: TypeReference; public readonly body: Expression | CodeBlock; public readonly docs?: DocComment; diff --git a/generators/swift/codegen/src/ast/EnumWithAssociatedValues.ts b/generators/swift/codegen/src/ast/EnumWithAssociatedValues.ts index 9b1c6c90180b..477eb0b28c72 100644 --- a/generators/swift/codegen/src/ast/EnumWithAssociatedValues.ts +++ b/generators/swift/codegen/src/ast/EnumWithAssociatedValues.ts @@ -7,12 +7,12 @@ import { Initializer } from "./Initializer"; import { Method } from "./Method"; import { Protocol } from "./Protocol"; import { Struct } from "./Struct"; -import { Type } from "./Type"; +import { TypeReference } from "./TypeReference"; export declare namespace EnumWithAssociatedValues { interface Case { unsafeName: string; - associatedValue: [Type, ...Type[]]; + associatedValue: [TypeReference, ...TypeReference[]]; docs?: DocComment; } diff --git a/generators/swift/codegen/src/ast/Expression.ts b/generators/swift/codegen/src/ast/Expression.ts index 711591df138e..39f79980a13c 100644 --- a/generators/swift/codegen/src/ast/Expression.ts +++ b/generators/swift/codegen/src/ast/Expression.ts @@ -2,7 +2,7 @@ import { assertNever } from "@fern-api/core-utils"; import { escapeReservedKeyword } from "../syntax"; import { AstNode, Writer } from "./core"; import { FunctionArgument } from "./FunctionArgument"; -import { Type } from "./Type"; +import { TypeReference } from "./TypeReference"; /** * A reference to a variable or constant. @@ -14,7 +14,7 @@ type Reference = { type MemberAccess = { type: "member-access"; - target: Expression | Type; + target: Expression | TypeReference; optionalChain?: true; memberName: string; }; @@ -325,10 +325,10 @@ export class Expression extends AstNode { writer.write(`try! Date("${this.internalExpression.isoString}", strategy: .iso8601)`); break; case "calendar-date-literal": - writer.write(`try! CalendarDate("${this.internalExpression.isoString}")`); + writer.write(`CalendarDate("${this.internalExpression.isoString}")!`); break; case "uuid-literal": - writer.write(`UUID(uuidString: "${this.internalExpression.value}")`); + writer.write(`UUID(uuidString: "${this.internalExpression.value}")!`); break; case "dictionary-literal": this.writeDictionaryLiteral(writer, this.internalExpression); diff --git a/generators/swift/codegen/src/ast/FunctionParameter.ts b/generators/swift/codegen/src/ast/FunctionParameter.ts index 6a5fe7fc4461..e63c7c28c113 100644 --- a/generators/swift/codegen/src/ast/FunctionParameter.ts +++ b/generators/swift/codegen/src/ast/FunctionParameter.ts @@ -1,6 +1,6 @@ import { AstNode, Writer } from "./core"; import { Expression } from "./Expression"; -import { Type } from "./Type"; +import { TypeReference } from "./TypeReference"; export declare namespace FunctionParameter { interface Args { @@ -9,7 +9,7 @@ export declare namespace FunctionParameter { /** Used within the function’s body. */ unsafeName: string; escaping?: true; - type: Type; + type: TypeReference; defaultValue?: Expression; docsContent?: string; } @@ -19,7 +19,7 @@ export class FunctionParameter extends AstNode { public readonly argumentLabel?: string; public readonly unsafeName: string; public readonly escaping?: true; - public readonly type: Type; + public readonly type: TypeReference; public readonly defaultValue?: Expression; public readonly docsContent?: string; diff --git a/generators/swift/codegen/src/ast/Method.ts b/generators/swift/codegen/src/ast/Method.ts index b998fb42eb48..4e9264abcad7 100644 --- a/generators/swift/codegen/src/ast/Method.ts +++ b/generators/swift/codegen/src/ast/Method.ts @@ -6,7 +6,7 @@ import { DocComment } from "./DocComment"; import { Expression } from "./Expression"; import { FunctionArgument } from "./FunctionArgument"; import { FunctionParameter } from "./FunctionParameter"; -import { Type } from "./Type"; +import { TypeReference } from "./TypeReference"; export declare namespace Method { interface Attribute { @@ -22,7 +22,7 @@ export declare namespace Method { parameters?: FunctionParameter[]; async?: true; throws?: true; - returnType: Type; + returnType: TypeReference; body?: CodeBlock; docs?: DocComment; } @@ -36,7 +36,7 @@ export class Method extends AstNode { public readonly parameters: FunctionParameter[]; public readonly async?: true; public readonly throws?: true; - public readonly returnType: Type; + public readonly returnType: TypeReference; public readonly body: CodeBlock; public readonly docs?: DocComment; diff --git a/generators/swift/codegen/src/ast/Property.ts b/generators/swift/codegen/src/ast/Property.ts index f0fca0c5e9dd..0ce5965f68fb 100644 --- a/generators/swift/codegen/src/ast/Property.ts +++ b/generators/swift/codegen/src/ast/Property.ts @@ -4,7 +4,7 @@ import { AstNode, Writer } from "./core"; import { DeclarationType } from "./DeclarationType"; import { DocComment } from "./DocComment"; import { Expression } from "./Expression"; -import { Type } from "./Type"; +import { TypeReference } from "./TypeReference"; export declare namespace Property { interface Args { @@ -12,7 +12,7 @@ export declare namespace Property { accessLevel?: AccessLevel; static_?: boolean; declarationType: DeclarationType; - type: Type; + type: TypeReference; defaultValue?: Expression; docs?: DocComment; } @@ -23,7 +23,7 @@ export class Property extends AstNode { public readonly accessLevel?: AccessLevel; public readonly static_?: boolean; public readonly declarationType: DeclarationType; - public readonly type: Type; + public readonly type: TypeReference; public readonly defaultValue?: Expression; public readonly docs?: DocComment; diff --git a/generators/swift/codegen/src/ast/Statement.ts b/generators/swift/codegen/src/ast/Statement.ts index 332ddfe32d51..5491a030ff09 100644 --- a/generators/swift/codegen/src/ast/Statement.ts +++ b/generators/swift/codegen/src/ast/Statement.ts @@ -8,13 +8,13 @@ import { DocComment } from "./DocComment"; import { Expression } from "./Expression"; import { FunctionParameter } from "./FunctionParameter"; import { Pattern } from "./Pattern"; -import { Type } from "./Type"; +import { TypeReference } from "./TypeReference"; type TypealiasDeclaration = { type: "typealias-declaration"; accessLevel?: AccessLevel; unsafeName: string; - aliasedType: Type; + aliasedType: TypeReference; docs?: DocComment; }; @@ -39,7 +39,7 @@ type FunctionDeclaration = { parameters?: FunctionParameter[]; async?: true; throws?: true; - returnType?: Type; + returnType?: TypeReference; body?: CodeBlock; docs?: DocComment; }; diff --git a/generators/swift/codegen/src/ast/Type.ts b/generators/swift/codegen/src/ast/Type.ts index 5b83ddb4cd6c..12e65c7454ec 100644 --- a/generators/swift/codegen/src/ast/Type.ts +++ b/generators/swift/codegen/src/ast/Type.ts @@ -3,7 +3,7 @@ import { camelCase, lowerFirst, upperFirst } from "lodash-es"; import { AstNode, Writer } from "./core"; -const BuiltinType = { +const SwiftType = { String: { type: "string", symbolName: "String" @@ -40,13 +40,14 @@ const BuiltinType = { type: "void", symbolName: "Void" }, + // TODO(kafkas): Any doesn't seem to be under the Swift scope i.e. Swift.Any is not valid so we probably wanna move this. Any: { type: "any", symbolName: "Any" } } as const; -type BuiltinType = (typeof BuiltinType)[keyof typeof BuiltinType]; +type SwiftType = (typeof SwiftType)[keyof typeof SwiftType]; export const FoundationType = { Data: { @@ -121,7 +122,7 @@ type JsonValue = { }; type InternalType = - | BuiltinType + | SwiftType | FoundationType | Tuple | Array_ @@ -414,52 +415,52 @@ export class Type extends AstNode { } } - public static primitiveSymbolNames(): string[] { - return values(BuiltinType).map((primitive) => primitive.symbolName); + public static primitiveSymbolNames() { + return values(SwiftType).map((primitive) => primitive.symbolName); } - public static foundationSymbolNames(): string[] { + public static foundationSymbolNames() { return values(FoundationType).map((foundation) => foundation.symbolName); } public static string(): Type { - return new this(BuiltinType.String); + return new this(SwiftType.String); } public static bool(): Type { - return new this(BuiltinType.Bool); + return new this(SwiftType.Bool); } public static int(): Type { - return new this(BuiltinType.Int); + return new this(SwiftType.Int); } public static uint(): Type { - return new this(BuiltinType.UInt); + return new this(SwiftType.UInt); } public static uint64(): Type { - return new this(BuiltinType.UInt64); + return new this(SwiftType.UInt64); } public static int64(): Type { - return new this(BuiltinType.Int64); + return new this(SwiftType.Int64); } public static float(): Type { - return new this(BuiltinType.Float); + return new this(SwiftType.Float); } public static double(): Type { - return new this(BuiltinType.Double); + return new this(SwiftType.Double); } public static void(): Type { - return new this(BuiltinType.Void); + return new this(SwiftType.Void); } public static any(): Type { - return new this(BuiltinType.Any); + return new this(SwiftType.Any); } public static data(): Type { diff --git a/generators/swift/codegen/src/ast/TypeReference.ts b/generators/swift/codegen/src/ast/TypeReference.ts new file mode 100644 index 000000000000..4c90f5e07079 --- /dev/null +++ b/generators/swift/codegen/src/ast/TypeReference.ts @@ -0,0 +1,240 @@ +import { assertNever } from "@fern-api/core-utils"; +import { FoundationTypeSymbolName, SwiftTypeSymbolName } from "../symbol"; +import { AstNode, Writer } from "./core"; + +type Symbol = { + type: "symbol"; + symbol: string; +}; + +type Generic = { + type: "generic"; + reference: TypeReference; + arguments: TypeReference[]; +}; + +type Tuple = { + type: "tuple"; + elements: [TypeReference, ...TypeReference[]]; +}; + +type Array_ = { + type: "array"; + elementType: TypeReference; +}; + +type Dictionary = { + type: "dictionary"; + keyType: TypeReference; + valueType: TypeReference; +}; + +type Optional = { + type: "optional"; + valueType: TypeReference; +}; + +type Nullable = { + type: "nullable"; + valueType: TypeReference; +}; + +type MemberAccess = { + type: "member-access"; + target: TypeReference; + memberName: string; +}; + +type TypeReferenceVariant = Symbol | Generic | Tuple | Array_ | Dictionary | Optional | Nullable | MemberAccess; + +export class TypeReference extends AstNode { + public readonly variant: TypeReferenceVariant; + + private constructor(variant: TypeReferenceVariant) { + super(); + this.variant = variant; + } + + public nonOptional(): TypeReference { + return TypeReference.nonOptional(this); + } + + public nonNullable(): TypeReference { + return TypeReference.nonNullable(this); + } + + public getReferenceIfSymbolType(): string | null { + return this.variant.type === "symbol" ? this.variant.symbol : null; + } + + public write(writer: Writer): void { + const { variant } = this; + + switch (variant.type) { + case "symbol": + writer.write(variant.symbol); + break; + case "generic": { + variant.reference.write(writer); + if (variant.arguments.length > 0) { + writer.write("<"); + variant.arguments.forEach((arg, index) => { + arg.write(writer); + if (index < variant.arguments.length - 1) { + writer.write(", "); + } + }); + writer.write(">"); + } + break; + } + case "tuple": + writer.write("("); + variant.elements.forEach((elementType, index) => { + if (index > 0) { + writer.write(", "); + } + elementType.write(writer); + }); + writer.write(")"); + break; + case "array": + writer.write("["); + variant.elementType.write(writer); + writer.write("]"); + break; + case "dictionary": + writer.write("["); + variant.keyType.write(writer); + writer.write(": "); + variant.valueType.write(writer); + writer.write("]"); + break; + case "optional": + variant.valueType.write(writer); + writer.write("?"); + break; + case "nullable": + writer.write("Nullable<"); + variant.valueType.write(writer); + writer.write(">"); + break; + case "member-access": + variant.target.write(writer); + writer.write("."); + writer.write(variant.memberName); + break; + default: + assertNever(variant); + } + } + + public equals(that: TypeReference): boolean { + switch (this.variant.type) { + case "symbol": + return that.variant.type === "symbol" && this.variant.symbol === that.variant.symbol; + case "generic": + return ( + that.variant.type === "generic" && + this.variant.reference.equals(that.variant.reference) && + this.variant.arguments.every( + (arg, index) => + that.variant.type === "generic" && + that.variant.arguments[index] && + arg.equals(that.variant.arguments[index]) + ) + ); + case "tuple": { + return ( + that.variant.type === "tuple" && + this.variant.elements.every( + (arg, index) => + that.variant.type === "tuple" && + that.variant.elements[index] && + arg.equals(that.variant.elements[index]) + ) + ); + } + case "array": + return that.variant.type === "array" && this.variant.elementType.equals(that.variant.elementType); + case "dictionary": + return ( + that.variant.type === "dictionary" && + this.variant.keyType.equals(that.variant.keyType) && + this.variant.valueType.equals(that.variant.valueType) + ); + case "optional": + return that.variant.type == "optional" && this.variant.valueType.equals(that.variant.valueType); + case "nullable": + return that.variant.type === "nullable" && this.variant.valueType.equals(that.variant.valueType); + case "member-access": + return ( + that.variant.type === "member-access" && + this.variant.target.equals(that.variant.target) && + this.variant.memberName === that.variant.memberName + ); + default: + assertNever(this.variant); + } + } + + public static symbol(symbolReference: string): TypeReference { + return new this({ type: "symbol", symbol: symbolReference }); + } + + public static generic(reference: TypeReference, arguments_: TypeReference[]): TypeReference { + return new this({ type: "generic", reference, arguments: arguments_ }); + } + + public static tuple(elements: [TypeReference, ...TypeReference[]]): TypeReference { + return new this({ type: "tuple", elements }); + } + + public static array(elementType: TypeReference): TypeReference { + return new this({ type: "array", elementType }); + } + + public static dictionary(keyType: TypeReference, valueType: TypeReference): TypeReference { + return new this({ type: "dictionary", keyType, valueType }); + } + + public static optional(valueType: TypeReference): TypeReference { + if (valueType.variant.type === "optional") { + return valueType; + } + return new this({ type: "optional", valueType }); + } + + public static nullable(valueType: TypeReference): TypeReference { + if (valueType.variant.type === "nullable") { + return valueType; + } + return new this({ type: "nullable", valueType }); + } + + public static memberAccess(target: TypeReference, memberName: string): TypeReference { + return new this({ type: "member-access", target, memberName }); + } + + // Helpers + + public static nonOptional(valueType: TypeReference): TypeReference { + return valueType.variant.type === "optional" + ? TypeReference.nonOptional(valueType.variant.valueType) + : valueType; + } + + public static nonNullable(valueType: TypeReference): TypeReference { + return valueType.variant.type === "nullable" + ? TypeReference.nonNullable(valueType.variant.valueType) + : valueType; + } + + public static unqualifiedToSwiftType(symbolName: SwiftTypeSymbolName): TypeReference { + return TypeReference.symbol(symbolName); + } + + public static unqualifiedToFoundationType(symbolName: FoundationTypeSymbolName): TypeReference { + return TypeReference.symbol(symbolName); + } +} diff --git a/generators/swift/codegen/src/ast/__test__/enum-with-associated-values/enum-with-associated-values.test.ts b/generators/swift/codegen/src/ast/__test__/enum-with-associated-values/enum-with-associated-values.test.ts index 147a4e6eca3a..84441797dd42 100644 --- a/generators/swift/codegen/src/ast/__test__/enum-with-associated-values/enum-with-associated-values.test.ts +++ b/generators/swift/codegen/src/ast/__test__/enum-with-associated-values/enum-with-associated-values.test.ts @@ -7,8 +7,14 @@ describe("EnumWithAssociatedValues", () => { const enum_ = swift.enumWithAssociatedValues({ name: "NetworkResponse", cases: [ - { unsafeName: "success", associatedValue: [swift.Type.string()] }, - { unsafeName: "error", associatedValue: [swift.Type.int(), swift.Type.string()] } + { unsafeName: "success", associatedValue: [swift.TypeReference.unqualifiedToSwiftType("String")] }, + { + unsafeName: "error", + associatedValue: [ + swift.TypeReference.unqualifiedToSwiftType("Int"), + swift.TypeReference.unqualifiedToSwiftType("String") + ] + } ] }); @@ -26,8 +32,8 @@ describe("EnumWithAssociatedValues", () => { accessLevel: AccessLevel.Public, conformances: [swift.Protocol.Codable, swift.Protocol.Equatable], cases: [ - { unsafeName: "success", associatedValue: [swift.Type.string()] }, - { unsafeName: "failure", associatedValue: [swift.Type.string()] } + { unsafeName: "success", associatedValue: [swift.TypeReference.unqualifiedToSwiftType("String")] }, + { unsafeName: "failure", associatedValue: [swift.TypeReference.unqualifiedToSwiftType("String")] } ] }); @@ -46,9 +52,15 @@ describe("EnumWithAssociatedValues", () => { { unsafeName: "complex", associatedValue: [ - swift.Type.array(swift.Type.string()), - swift.Type.dictionary(swift.Type.string(), swift.Type.int()), - swift.Type.tuple([swift.Type.string(), swift.Type.bool()]) + swift.TypeReference.array(swift.TypeReference.unqualifiedToSwiftType("String")), + swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Int") + ), + swift.TypeReference.tuple([ + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Bool") + ]) ] } ] @@ -65,8 +77,8 @@ describe("EnumWithAssociatedValues", () => { const enum_ = swift.enumWithAssociatedValues({ name: "KeywordEnum", cases: [ - { unsafeName: "class", associatedValue: [swift.Type.string()] }, - { unsafeName: "struct", associatedValue: [swift.Type.int()] } + { unsafeName: "class", associatedValue: [swift.TypeReference.unqualifiedToSwiftType("String")] }, + { unsafeName: "struct", associatedValue: [swift.TypeReference.unqualifiedToSwiftType("Int")] } ] }); @@ -84,14 +96,14 @@ describe("EnumWithAssociatedValues", () => { accessLevel: AccessLevel.Public, conformances: [swift.Protocol.Equatable], cases: [ - { unsafeName: "success", associatedValue: [swift.Type.string()] }, - { unsafeName: "failure", associatedValue: [swift.Type.string()] } + { unsafeName: "success", associatedValue: [swift.TypeReference.unqualifiedToSwiftType("String")] }, + { unsafeName: "failure", associatedValue: [swift.TypeReference.unqualifiedToSwiftType("String")] } ], methods: [ swift.method({ unsafeName: "isSuccess", accessLevel: AccessLevel.Public, - returnType: swift.Type.bool(), + returnType: swift.TypeReference.unqualifiedToSwiftType("Bool"), body: swift.codeBlock((writer) => { writer.writeLine("switch self {"); writer.writeLine("case .success:"); @@ -104,7 +116,7 @@ describe("EnumWithAssociatedValues", () => { swift.method({ unsafeName: "getValue", accessLevel: AccessLevel.Public, - returnType: swift.Type.optional(swift.Type.string()), + returnType: swift.TypeReference.optional(swift.TypeReference.unqualifiedToSwiftType("String")), body: swift.codeBlock((writer) => { writer.writeLine("switch self {"); writer.writeLine("case .success(let value):"); @@ -125,8 +137,14 @@ describe("EnumWithAssociatedValues", () => { name: "NetworkResponse", accessLevel: AccessLevel.Public, cases: [ - { unsafeName: "success", associatedValue: [swift.Type.string()] }, - { unsafeName: "error", associatedValue: [swift.Type.int(), swift.Type.string()] } + { unsafeName: "success", associatedValue: [swift.TypeReference.unqualifiedToSwiftType("String")] }, + { + unsafeName: "error", + associatedValue: [ + swift.TypeReference.unqualifiedToSwiftType("Int"), + swift.TypeReference.unqualifiedToSwiftType("String") + ] + } ], initializers: [ swift.initializer({ @@ -135,7 +153,7 @@ describe("EnumWithAssociatedValues", () => { swift.functionParameter({ argumentLabel: "successValue", unsafeName: "value", - type: swift.Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], body: swift.codeBlock((writer) => { @@ -149,7 +167,10 @@ describe("EnumWithAssociatedValues", () => { swift.functionParameter({ argumentLabel: "from", unsafeName: "dictionary", - type: swift.Type.dictionary(swift.Type.string(), swift.Type.any()) + type: swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Any") + ) }) ], body: swift.codeBlock((writer) => { @@ -175,8 +196,11 @@ describe("EnumWithAssociatedValues", () => { accessLevel: AccessLevel.Public, conformances: [swift.Protocol.Codable], cases: [ - { unsafeName: "success", associatedValue: [swift.Type.custom("Data")] }, - { unsafeName: "error", associatedValue: [swift.Type.custom("ErrorInfo")] } + { + unsafeName: "success", + associatedValue: [swift.TypeReference.unqualifiedToFoundationType("Data")] + }, + { unsafeName: "error", associatedValue: [swift.TypeReference.symbol("ErrorInfo")] } ], nestedTypes: [ swift.struct({ @@ -187,12 +211,12 @@ describe("EnumWithAssociatedValues", () => { swift.property({ unsafeName: "id", declarationType: swift.DeclarationType.Let, - type: swift.Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.property({ unsafeName: "value", declarationType: swift.DeclarationType.Let, - type: swift.Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ] }), @@ -204,12 +228,12 @@ describe("EnumWithAssociatedValues", () => { swift.property({ unsafeName: "code", declarationType: swift.DeclarationType.Let, - type: swift.Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.property({ unsafeName: "message", declarationType: swift.DeclarationType.Let, - type: swift.Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ] }) @@ -225,9 +249,9 @@ describe("EnumWithAssociatedValues", () => { accessLevel: AccessLevel.Public, conformances: [swift.Protocol.Codable, swift.Protocol.Equatable], cases: [ - { unsafeName: "loading", associatedValue: [swift.Type.custom("Progress")] }, - { unsafeName: "loaded", associatedValue: [swift.Type.custom("Content")] }, - { unsafeName: "failed", associatedValue: [swift.Type.custom("ErrorDetails")] } + { unsafeName: "loading", associatedValue: [swift.TypeReference.symbol("Progress")] }, + { unsafeName: "loaded", associatedValue: [swift.TypeReference.symbol("Content")] }, + { unsafeName: "failed", associatedValue: [swift.TypeReference.symbol("ErrorDetails")] } ], initializers: [ swift.initializer({ @@ -236,7 +260,7 @@ describe("EnumWithAssociatedValues", () => { swift.functionParameter({ argumentLabel: "content", unsafeName: "content", - type: swift.Type.custom("Content") + type: swift.TypeReference.symbol("Content") }) ], body: swift.codeBlock((writer) => { @@ -248,7 +272,7 @@ describe("EnumWithAssociatedValues", () => { swift.method({ unsafeName: "isLoading", accessLevel: AccessLevel.Public, - returnType: swift.Type.bool(), + returnType: swift.TypeReference.unqualifiedToSwiftType("Bool"), body: swift.codeBlock((writer) => { writer.writeLine("if case .loading = self { return true }"); writer.writeLine("return false"); @@ -264,7 +288,7 @@ describe("EnumWithAssociatedValues", () => { swift.property({ unsafeName: "percentage", declarationType: swift.DeclarationType.Let, - type: swift.Type.double() + type: swift.TypeReference.unqualifiedToSwiftType("Double") }) ] }) diff --git a/generators/swift/codegen/src/ast/__test__/method.test.ts b/generators/swift/codegen/src/ast/__test__/method.test.ts index d9288024d58c..240723154b74 100644 --- a/generators/swift/codegen/src/ast/__test__/method.test.ts +++ b/generators/swift/codegen/src/ast/__test__/method.test.ts @@ -2,14 +2,13 @@ import { describe, expect, it } from "vitest"; import { swift } from "../.."; import { AccessLevel } from "../AccessLevel"; -import { Type } from "../Type"; describe("Method", () => { describe("write", () => { it("should write basic method with name and return type", () => { const method = swift.method({ unsafeName: "getName", - returnType: Type.string() + returnType: swift.TypeReference.unqualifiedToSwiftType("String") }); expect(method.toString()).toMatchInlineSnapshot(` @@ -22,7 +21,7 @@ describe("Method", () => { const method = swift.method({ unsafeName: "getValue", accessLevel: AccessLevel.Public, - returnType: Type.int() + returnType: swift.TypeReference.unqualifiedToSwiftType("Int") }); expect(method.toString()).toMatchInlineSnapshot(` @@ -35,7 +34,7 @@ describe("Method", () => { const method = swift.method({ unsafeName: "create", static_: true, - returnType: Type.custom("User") + returnType: swift.TypeReference.symbol("User") }); expect(method.toString()).toMatchInlineSnapshot(` @@ -49,7 +48,7 @@ describe("Method", () => { unsafeName: "process", accessLevel: AccessLevel.Private, static_: true, - returnType: Type.bool() + returnType: swift.TypeReference.unqualifiedToSwiftType("Bool") }); expect(method.toString()).toMatchInlineSnapshot(` @@ -64,10 +63,10 @@ describe("Method", () => { parameters: [ swift.functionParameter({ unsafeName: "value", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], - returnType: Type.void() + returnType: swift.TypeReference.unqualifiedToSwiftType("Void") }); expect(method.toString()).toMatchInlineSnapshot(` @@ -82,18 +81,18 @@ describe("Method", () => { parameters: [ swift.functionParameter({ unsafeName: "id", - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.functionParameter({ unsafeName: "name", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.functionParameter({ unsafeName: "email", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], - returnType: Type.bool() + returnType: swift.TypeReference.unqualifiedToSwiftType("Bool") }); expect(method.toString()).toMatchInlineSnapshot( @@ -111,15 +110,15 @@ describe("Method", () => { swift.functionParameter({ argumentLabel: "with", unsafeName: "name", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.functionParameter({ argumentLabel: "email", unsafeName: "emailAddress", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], - returnType: Type.custom("User") + returnType: swift.TypeReference.symbol("User") }); expect(method.toString()).toMatchInlineSnapshot( @@ -136,15 +135,15 @@ describe("Method", () => { parameters: [ swift.functionParameter({ unsafeName: "id", - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.functionParameter({ argumentLabel: "includingDeleted", unsafeName: "deleted", - type: Type.optional(Type.bool()) + type: swift.TypeReference.optional(swift.TypeReference.unqualifiedToSwiftType("Bool")) }) ], - returnType: Type.optional(Type.custom("User")) + returnType: swift.TypeReference.optional(swift.TypeReference.symbol("User")) }); expect(method.toString()).toMatchInlineSnapshot( @@ -162,20 +161,23 @@ describe("Method", () => { parameters: [ swift.functionParameter({ unsafeName: "value", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.functionParameter({ argumentLabel: "with", unsafeName: "options", - type: Type.array(Type.string()) + type: swift.TypeReference.array(swift.TypeReference.unqualifiedToSwiftType("String")) }), swift.functionParameter({ argumentLabel: "timeout", unsafeName: "timeoutValue", - type: Type.optional(Type.double()) + type: swift.TypeReference.optional(swift.TypeReference.unqualifiedToSwiftType("Double")) }) ], - returnType: Type.dictionary(Type.string(), Type.any()) + returnType: swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Any") + ) }); expect(method.toString()).toMatchInlineSnapshot( @@ -189,7 +191,7 @@ describe("Method", () => { it("should write method with reserved keyword name", () => { const method = swift.method({ unsafeName: "class", - returnType: Type.string() + returnType: swift.TypeReference.unqualifiedToSwiftType("String") }); expect(method.toString()).toMatchInlineSnapshot(` @@ -204,15 +206,15 @@ describe("Method", () => { parameters: [ swift.functionParameter({ unsafeName: "enum", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.functionParameter({ argumentLabel: "for", unsafeName: "struct", - type: Type.custom("Config") + type: swift.TypeReference.symbol("Config") }) ], - returnType: Type.string() + returnType: swift.TypeReference.unqualifiedToSwiftType("String") }); expect(method.toString()).toMatchInlineSnapshot( @@ -226,7 +228,15 @@ describe("Method", () => { it("should write method with complex return types", () => { const method = swift.method({ unsafeName: "getComplexData", - returnType: Type.array(Type.dictionary(Type.string(), Type.tuple([Type.int(), Type.bool()]))) + returnType: swift.TypeReference.array( + swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.tuple([ + swift.TypeReference.unqualifiedToSwiftType("Int"), + swift.TypeReference.unqualifiedToSwiftType("Bool") + ]) + ) + ) }); expect(method.toString()).toMatchInlineSnapshot(` @@ -242,10 +252,10 @@ describe("Method", () => { swift.functionParameter({ argumentLabel: "name", unsafeName: "name", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], - returnType: Type.any() + returnType: swift.TypeReference.unqualifiedToSwiftType("Any") }); expect(method.toString()).toMatchInlineSnapshot(` @@ -263,15 +273,17 @@ describe("Method", () => { swift.functionParameter({ argumentLabel: "from", unsafeName: "data", - type: Type.custom("Data") + type: swift.TypeReference.unqualifiedToFoundationType("Data") }), swift.functionParameter({ argumentLabel: "with", unsafeName: "options", - type: Type.optional(Type.array(Type.string())) + type: swift.TypeReference.optional( + swift.TypeReference.array(swift.TypeReference.unqualifiedToSwiftType("String")) + ) }) ], - returnType: Type.string() + returnType: swift.TypeReference.unqualifiedToSwiftType("String") }); expect(method.toString()).toMatchInlineSnapshot( @@ -290,22 +302,22 @@ describe("Method", () => { swift.functionParameter({ argumentLabel: "with", unsafeName: "name", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.functionParameter({ argumentLabel: "email", unsafeName: "emailAddress", - type: Type.optional(Type.string()), + type: swift.TypeReference.optional(swift.TypeReference.unqualifiedToSwiftType("String")), defaultValue: swift.Expression.rawValue("nil") }), swift.functionParameter({ argumentLabel: "isActive", unsafeName: "active", - type: Type.bool(), + type: swift.TypeReference.unqualifiedToSwiftType("Bool"), defaultValue: swift.Expression.rawValue("true") }) ], - returnType: Type.custom("User") + returnType: swift.TypeReference.symbol("User") }); expect(method.toString()).toMatchInlineSnapshot( @@ -319,7 +331,7 @@ describe("Method", () => { it("should write method with body", () => { const method = swift.method({ unsafeName: "getUserName", - returnType: Type.string(), + returnType: swift.TypeReference.unqualifiedToSwiftType("String"), body: swift.CodeBlock.withStatements([ swift.Statement.constantDeclaration({ unsafeName: "name", diff --git a/generators/swift/codegen/src/ast/__test__/property.test.ts b/generators/swift/codegen/src/ast/__test__/property.test.ts index d7497b22a7a0..ce51c4a55263 100644 --- a/generators/swift/codegen/src/ast/__test__/property.test.ts +++ b/generators/swift/codegen/src/ast/__test__/property.test.ts @@ -3,7 +3,6 @@ import { describe, expect, it } from "vitest"; import { swift } from "../.."; import { AccessLevel } from "../AccessLevel"; import { DeclarationType } from "../DeclarationType"; -import { Type } from "../Type"; describe("Property", () => { describe("write", () => { @@ -13,7 +12,7 @@ describe("Property", () => { accessLevel: AccessLevel.Private, static_: true, declarationType: DeclarationType.Let, - type: Type.optional(Type.string()) + type: swift.TypeReference.optional(swift.TypeReference.unqualifiedToSwiftType("String")) }); expect(property.toString()).toBe("private static let fullProperty: String?"); @@ -21,13 +20,28 @@ describe("Property", () => { it("should write property with different types", () => { const testCases = [ - { type: Type.string(), expected: "String" }, - { type: Type.int(), expected: "Int" }, - { type: Type.bool(), expected: "Bool" }, - { type: Type.double(), expected: "Double" }, - { type: Type.array(Type.string()), expected: "[String]" }, - { type: Type.dictionary(Type.string(), Type.int()), expected: "[String: Int]" }, - { type: Type.tuple([Type.string(), Type.int()]), expected: "(String, Int)" } + { type: swift.TypeReference.unqualifiedToSwiftType("String"), expected: "String" }, + { type: swift.TypeReference.unqualifiedToSwiftType("Int"), expected: "Int" }, + { type: swift.TypeReference.unqualifiedToSwiftType("Bool"), expected: "Bool" }, + { type: swift.TypeReference.unqualifiedToSwiftType("Double"), expected: "Double" }, + { + type: swift.TypeReference.array(swift.TypeReference.unqualifiedToSwiftType("String")), + expected: "[String]" + }, + { + type: swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Int") + ), + expected: "[String: Int]" + }, + { + type: swift.TypeReference.tuple([ + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Int") + ]), + expected: "(String, Int)" + } ]; testCases.forEach(({ type, expected }) => { @@ -48,7 +62,7 @@ describe("Property", () => { const property = swift.property({ unsafeName: keyword, declarationType: DeclarationType.Let, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }); expect(property.toString()).toBe(`let \`${keyword}\`: String`); @@ -59,7 +73,7 @@ describe("Property", () => { const property = swift.property({ unsafeName: "myProperty", declarationType: DeclarationType.Let, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }); expect(property.toString()).toBe("let myProperty: String"); @@ -71,7 +85,17 @@ describe("Property", () => { accessLevel: AccessLevel.Public, static_: true, declarationType: DeclarationType.Var, - type: Type.optional(Type.array(Type.dictionary(Type.string(), Type.tuple([Type.int(), Type.bool()])))) + type: swift.TypeReference.optional( + swift.TypeReference.array( + swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.tuple([ + swift.TypeReference.unqualifiedToSwiftType("Int"), + swift.TypeReference.unqualifiedToSwiftType("Bool") + ]) + ) + ) + ) }); expect(property.toString()).toBe("public static var complexProperty: [[String: (Int, Bool)]]?"); @@ -83,7 +107,7 @@ describe("Property", () => { accessLevel: AccessLevel.Private, static_: true, declarationType: DeclarationType.Let, - type: Type.optional(Type.string()) + type: swift.TypeReference.optional(swift.TypeReference.unqualifiedToSwiftType("String")) }); expect(property.toString()).toBe("private static let `class`: String?"); diff --git a/generators/swift/codegen/src/ast/__test__/struct/struct.test.ts b/generators/swift/codegen/src/ast/__test__/struct/struct.test.ts index d3e9dd982f7f..9a3fdfcdf9e6 100644 --- a/generators/swift/codegen/src/ast/__test__/struct/struct.test.ts +++ b/generators/swift/codegen/src/ast/__test__/struct/struct.test.ts @@ -3,7 +3,6 @@ import { describe, expect, it } from "vitest"; import { swift } from "../../.."; import { AccessLevel } from "../../AccessLevel"; import { DeclarationType } from "../../DeclarationType"; -import { Type } from "../../Type"; describe("Struct", () => { describe("write", () => { @@ -12,13 +11,13 @@ describe("Struct", () => { swift.property({ unsafeName: "id", declarationType: DeclarationType.Let, - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.property({ unsafeName: "name", accessLevel: AccessLevel.Public, declarationType: DeclarationType.Let, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ]; @@ -56,18 +55,18 @@ describe("Struct", () => { unsafeName: "staticProperty", static_: true, declarationType: DeclarationType.Let, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.property({ unsafeName: "optionalProperty", declarationType: DeclarationType.Var, - type: Type.optional(Type.int()) + type: swift.TypeReference.optional(swift.TypeReference.unqualifiedToSwiftType("Int")) }), swift.property({ unsafeName: "privateProperty", accessLevel: AccessLevel.Private, declarationType: DeclarationType.Let, - type: Type.array(Type.string()) + type: swift.TypeReference.array(swift.TypeReference.unqualifiedToSwiftType("String")) }) ]; @@ -90,12 +89,12 @@ describe("Struct", () => { swift.property({ unsafeName: "class", declarationType: DeclarationType.Let, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.property({ unsafeName: "enum", declarationType: DeclarationType.Let, - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }) ]; @@ -117,22 +116,33 @@ describe("Struct", () => { swift.property({ unsafeName: "arrayProperty", declarationType: DeclarationType.Let, - type: Type.array(Type.string()) + type: swift.TypeReference.array(swift.TypeReference.unqualifiedToSwiftType("String")) }), swift.property({ unsafeName: "dictProperty", declarationType: DeclarationType.Let, - type: Type.dictionary(Type.string(), Type.int()) + type: swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Int") + ) }), swift.property({ unsafeName: "tupleProperty", declarationType: DeclarationType.Let, - type: Type.tuple([Type.string(), Type.int()]) + type: swift.TypeReference.tuple([ + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Int") + ]) }), swift.property({ unsafeName: "nestedProperty", declarationType: DeclarationType.Let, - type: Type.array(Type.dictionary(Type.string(), Type.int())) + type: swift.TypeReference.array( + swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Int") + ) + ) }) ]; @@ -158,19 +168,19 @@ describe("Struct", () => { accessLevel: AccessLevel.Public, static_: true, declarationType: DeclarationType.Let, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.property({ unsafeName: "privateOptional", accessLevel: AccessLevel.Private, declarationType: DeclarationType.Var, - type: Type.optional(Type.int()) + type: swift.TypeReference.optional(swift.TypeReference.unqualifiedToSwiftType("Int")) }), swift.property({ unsafeName: "fileprivateArray", accessLevel: AccessLevel.Fileprivate, declarationType: DeclarationType.Let, - type: Type.array(Type.double()) + type: swift.TypeReference.array(swift.TypeReference.unqualifiedToSwiftType("Double")) }) ]; @@ -195,12 +205,12 @@ describe("Struct", () => { properties: [ swift.property({ unsafeName: "id", - type: Type.int64(), + type: swift.TypeReference.unqualifiedToSwiftType("Int64"), declarationType: DeclarationType.Let }), swift.property({ unsafeName: "petId", - type: Type.string(), + type: swift.TypeReference.unqualifiedToSwiftType("String"), declarationType: DeclarationType.Let }) ], @@ -225,12 +235,12 @@ describe("Struct", () => { properties: [ swift.property({ unsafeName: "id", - type: Type.int(), + type: swift.TypeReference.unqualifiedToSwiftType("Int"), declarationType: DeclarationType.Let }), swift.property({ unsafeName: "name", - type: Type.string(), + type: swift.TypeReference.unqualifiedToSwiftType("String"), declarationType: DeclarationType.Let }) ], @@ -266,20 +276,20 @@ describe("Struct", () => { swift.property({ unsafeName: "id", declarationType: DeclarationType.Let, - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.property({ unsafeName: "name", accessLevel: AccessLevel.Private, declarationType: DeclarationType.Var, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], methods: [ swift.method({ unsafeName: "getId", accessLevel: AccessLevel.Public, - returnType: Type.int(), + returnType: swift.TypeReference.unqualifiedToSwiftType("Int"), body: swift.codeBlock((writer) => { writer.writeLine("return self.id"); }) @@ -287,7 +297,7 @@ describe("Struct", () => { swift.method({ unsafeName: "getName", accessLevel: AccessLevel.Public, - returnType: Type.string(), + returnType: swift.TypeReference.unqualifiedToSwiftType("String"), body: swift.codeBlock((writer) => { writer.writeLine("return self.name"); }) @@ -300,15 +310,15 @@ describe("Struct", () => { swift.functionParameter({ argumentLabel: "with", unsafeName: "id", - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.functionParameter({ argumentLabel: "name", unsafeName: "name", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], - returnType: Type.custom("User"), + returnType: swift.TypeReference.symbol("User"), body: swift.codeBlock((writer) => { writer.writeLine("return User(id: id, name: name)"); }) @@ -328,12 +338,12 @@ describe("Struct", () => { swift.property({ unsafeName: "id", declarationType: DeclarationType.Let, - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.property({ unsafeName: "name", declarationType: DeclarationType.Let, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], initializers: [ @@ -343,12 +353,12 @@ describe("Struct", () => { swift.functionParameter({ argumentLabel: "id", unsafeName: "id", - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.functionParameter({ argumentLabel: "name", unsafeName: "name", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }) ], body: swift.CodeBlock.withStatements([ @@ -370,17 +380,17 @@ describe("Struct", () => { swift.property({ unsafeName: "id", declarationType: DeclarationType.Let, - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.property({ unsafeName: "name", declarationType: DeclarationType.Let, - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.property({ unsafeName: "price", declarationType: DeclarationType.Let, - type: Type.double() + type: swift.TypeReference.unqualifiedToSwiftType("Double") }) ], initializers: [ @@ -390,17 +400,17 @@ describe("Struct", () => { swift.functionParameter({ argumentLabel: "id", unsafeName: "id", - type: Type.int() + type: swift.TypeReference.unqualifiedToSwiftType("Int") }), swift.functionParameter({ argumentLabel: "name", unsafeName: "name", - type: Type.string() + type: swift.TypeReference.unqualifiedToSwiftType("String") }), swift.functionParameter({ argumentLabel: "price", unsafeName: "price", - type: Type.double() + type: swift.TypeReference.unqualifiedToSwiftType("Double") }) ], body: swift.CodeBlock.withStatements([ @@ -416,7 +426,10 @@ describe("Struct", () => { swift.functionParameter({ argumentLabel: "from", unsafeName: "dictionary", - type: Type.dictionary(Type.string(), Type.any()) + type: swift.TypeReference.dictionary( + swift.TypeReference.unqualifiedToSwiftType("String"), + swift.TypeReference.unqualifiedToSwiftType("Any") + ) }) ], body: swift.codeBlock((writer) => { @@ -443,7 +456,7 @@ describe("Struct", () => { methods: [ swift.method({ unsafeName: "doSomething", - returnType: Type.void(), + returnType: swift.TypeReference.unqualifiedToSwiftType("Void"), body: swift.CodeBlock.withStatements([swift.Statement.raw(`print("doSomething")`)]) }) ] diff --git a/generators/swift/codegen/src/ast/__test__/type-reference.test.ts b/generators/swift/codegen/src/ast/__test__/type-reference.test.ts new file mode 100644 index 000000000000..678b47afc8c5 --- /dev/null +++ b/generators/swift/codegen/src/ast/__test__/type-reference.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from "vitest"; + +import { swift } from "../.."; + +describe("TypeReference", () => { + describe("generic", () => { + it("should write without generic arguments", () => { + const ref = swift.TypeReference.generic(swift.TypeReference.symbol("Symbol1"), []); + expect(ref.toString()).toBe("Symbol1"); + }); + + it("should write with 1 generic argument", () => { + const ref = swift.TypeReference.generic(swift.TypeReference.symbol("Symbol1"), [ + swift.TypeReference.symbol("Symbol2") + ]); + expect(ref.toString()).toBe("Symbol1"); + }); + + it("should write with 2 generic arguments", () => { + const ref = swift.TypeReference.generic(swift.TypeReference.symbol("Symbol1"), [ + swift.TypeReference.symbol("Symbol2"), + swift.TypeReference.symbol("Symbol3") + ]); + expect(ref.toString()).toBe("Symbol1"); + }); + + it("should write with nested generic arguments", () => { + const ref = swift.TypeReference.generic(swift.TypeReference.symbol("Symbol1"), [ + swift.TypeReference.generic(swift.TypeReference.symbol("Symbol2"), [ + swift.TypeReference.symbol("Symbol3") + ]) + ]); + expect(ref.toString()).toBe("Symbol1>"); + }); + }); +}); diff --git a/generators/swift/codegen/src/ast/index.ts b/generators/swift/codegen/src/ast/index.ts index c3437d90a522..68458535fca4 100644 --- a/generators/swift/codegen/src/ast/index.ts +++ b/generators/swift/codegen/src/ast/index.ts @@ -21,3 +21,4 @@ export { Protocol } from "./Protocol"; export { Statement } from "./Statement"; export { Struct } from "./Struct"; export { Type } from "./Type"; +export { TypeReference } from "./TypeReference"; diff --git a/generators/swift/codegen/src/swift.ts b/generators/swift/codegen/src/swift.ts index bf2ec6ebcb2b..9491c0a76e1a 100644 --- a/generators/swift/codegen/src/swift.ts +++ b/generators/swift/codegen/src/swift.ts @@ -72,3 +72,4 @@ export function struct(args: Struct.Args): Struct { } export * from "./ast"; +export * from "./symbol"; diff --git a/generators/swift/codegen/src/symbol/index.ts b/generators/swift/codegen/src/symbol/index.ts new file mode 100644 index 000000000000..592c37dd1237 --- /dev/null +++ b/generators/swift/codegen/src/symbol/index.ts @@ -0,0 +1,2 @@ +export { type FoundationTypeSymbolName, type SwiftTypeSymbolName, Symbol } from "./symbol"; +export { SymbolRegistry, type TypeSymbolShape } from "./symbol-registry"; diff --git a/generators/swift/codegen/src/symbol/symbol-registry/__test__/target-symbol-registry.test.ts b/generators/swift/codegen/src/symbol/symbol-registry/__test__/target-symbol-registry.test.ts new file mode 100644 index 000000000000..126dd7049ea9 --- /dev/null +++ b/generators/swift/codegen/src/symbol/symbol-registry/__test__/target-symbol-registry.test.ts @@ -0,0 +1,325 @@ +import { SymbolRegistry } from "../symbol-registry"; + +describe("SymbolRegistry", () => { + describe("for no name collisions with Swift types", () => { + describe("correctly resolves type reference to Swift type", () => { + it("from module scope", () => { + const registry = SymbolRegistry.create(); + const moduleSymbol = registry.registerSourceModule("Acme"); + + registry.registerSourceModuleType("User", { type: "struct" }); + registry.registerSourceModuleType("Post", { type: "struct" }); + + const ref = registry.reference({ + fromSymbol: moduleSymbol, + toSymbol: "Swift.String" + }); + + expect(ref.toString()).toBe("String"); + }); + + it("from a custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + registry.registerSourceModuleType("Post", { type: "struct" }); + + const ref = registry.reference({ + fromSymbol: userSymbol, + toSymbol: "Swift.String" + }); + + expect(ref.toString()).toBe("String"); + }); + + it("from a nested custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + const postSymbol = registry.registerNestedType({ + parentSymbol: userSymbol, + symbolName: "Post", + shape: { type: "struct" } + }); + + const ref = registry.reference({ + fromSymbol: postSymbol, + toSymbol: "Swift.String" + }); + + expect(ref.toString()).toBe("String"); + }); + }); + }); + + describe("for a top level type name collision with a Swift type", () => { + describe("correctly resolves type reference to custom type", () => { + it("from module scope", () => { + const registry = SymbolRegistry.create(); + const moduleSymbol = registry.registerSourceModule("Acme"); + + registry.registerSourceModuleType("User", { type: "struct" }); + const customStringSymbol = registry.registerSourceModuleType("String", { type: "struct" }); + + const ref = registry.reference({ + fromSymbol: moduleSymbol, + toSymbol: customStringSymbol + }); + + expect(ref.toString()).toBe("String"); + }); + + it("from a custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + const customStringSymbol = registry.registerSourceModuleType("String", { type: "struct" }); + + const ref = registry.reference({ + fromSymbol: userSymbol, + toSymbol: customStringSymbol + }); + + expect(ref.toString()).toBe("String"); + }); + + it("from a nested custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + const postSymbol = registry.registerNestedType({ + parentSymbol: userSymbol, + symbolName: "Post", + shape: { type: "struct" } + }); + + const customStringSymbol = registry.registerSourceModuleType("String", { type: "struct" }); + + const ref = registry.reference({ + fromSymbol: postSymbol, + toSymbol: customStringSymbol + }); + + expect(ref.toString()).toBe("String"); + }); + }); + + describe("correctly resolves type reference to Swift type", () => { + it("from module scope", () => { + const registry = SymbolRegistry.create(); + const moduleSymbol = registry.registerSourceModule("Acme"); + + registry.registerSourceModuleType("User", { type: "struct" }); + registry.registerSourceModuleType("String", { type: "struct" }); + + const ref = registry.reference({ + fromSymbol: moduleSymbol, + toSymbol: "Swift.String" + }); + + expect(ref.toString()).toBe("Swift.String"); + }); + + it("from a custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + registry.registerSourceModuleType("String", { type: "struct" }); + + const ref = registry.reference({ + fromSymbol: userSymbol, + toSymbol: "Swift.String" + }); + + expect(ref.toString()).toBe("Swift.String"); + }); + + it("from a nested custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + registry.registerSourceModuleType("String", { type: "struct" }); + const postSymbol = registry.registerNestedType({ + parentSymbol: userSymbol, + symbolName: "Post", + shape: { type: "struct" } + }); + + const ref = registry.reference({ + fromSymbol: postSymbol, + toSymbol: "Swift.String" + }); + + expect(ref.toString()).toBe("Swift.String"); + }); + }); + }); + + describe("for a nested type name collision with a Foundation type", () => { + describe("correctly resolves type reference to custom type", () => { + it("from module scope", () => { + const registry = SymbolRegistry.create(); + const moduleSymbol = registry.registerSourceModule("Acme"); + registry.registerSourceModuleType("User", { type: "struct" }); + const postSymbol = registry.registerSourceModuleType("Post", { type: "struct" }); + const customDateSymbol = registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Date", + shape: { type: "struct" } + }); + const ref = registry.reference({ + fromSymbol: moduleSymbol, + toSymbol: customDateSymbol + }); + expect(ref.toString()).toBe("Post.Date"); + }); + + it("from a custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + const postSymbol = registry.registerSourceModuleType("Post", { type: "struct" }); + const customDateSymbol = registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Date", + shape: { type: "struct" } + }); + const ref = registry.reference({ + fromSymbol: userSymbol, + toSymbol: customDateSymbol + }); + expect(ref.toString()).toBe("Post.Date"); + }); + + it("from a sibling custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + registry.registerSourceModuleType("User", { type: "struct" }); + const postSymbol = registry.registerSourceModuleType("Post", { type: "struct" }); + const contentSymbol = registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Content", + shape: { type: "struct" } + }); + const customDateSymbol = registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Date", + shape: { type: "struct" } + }); + const ref = registry.reference({ + fromSymbol: contentSymbol, + toSymbol: customDateSymbol + }); + expect(ref.toString()).toBe("Date"); + }); + + it("from a nested custom type in a different scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + const emailSymbolId = registry.registerNestedType({ + parentSymbol: userSymbol, + symbolName: "Email", + shape: { type: "struct" } + }); + const postSymbolId = registry.registerSourceModuleType("Post", { type: "struct" }); + const customDateSymbolId = registry.registerNestedType({ + parentSymbol: postSymbolId, + symbolName: "Date", + shape: { type: "struct" } + }); + const ref = registry.reference({ + fromSymbol: emailSymbolId, + toSymbol: customDateSymbolId + }); + expect(ref.toString()).toBe("Post.Date"); + }); + }); + + describe("correctly resolves type reference to Foundation type", () => { + it("from module scope", () => { + const registry = SymbolRegistry.create(); + const moduleSymbol = registry.registerSourceModule("Acme"); + registry.registerSourceModuleType("User", { type: "struct" }); + const postSymbol = registry.registerSourceModuleType("Post", { type: "struct" }); + registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Date", + shape: { type: "struct" } + }); + const ref = registry.reference({ + fromSymbol: moduleSymbol, + toSymbol: "Foundation.Date" + }); + expect(ref.toString()).toBe("Date"); + }); + + it("from a custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + const postSymbol = registry.registerSourceModuleType("Post", { type: "struct" }); + registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Date", + shape: { type: "struct" } + }); + const ref = registry.reference({ + fromSymbol: userSymbol, + toSymbol: "Foundation.Date" + }); + expect(ref.toString()).toBe("Date"); + }); + + it("from a sibling custom type scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + registry.registerSourceModuleType("User", { type: "struct" }); + const postSymbol = registry.registerSourceModuleType("Post", { type: "struct" }); + const contentSymbol = registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Content", + shape: { type: "struct" } + }); + registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Date", + shape: { type: "struct" } + }); + const ref = registry.reference({ + fromSymbol: contentSymbol, + toSymbol: "Foundation.Date" + }); + expect(ref.toString()).toBe("Foundation.Date"); + }); + + it("from a nested custom type in a different scope", () => { + const registry = SymbolRegistry.create(); + registry.registerSourceModule("Acme"); + const userSymbol = registry.registerSourceModuleType("User", { type: "struct" }); + const emailSymbol = registry.registerNestedType({ + parentSymbol: userSymbol, + symbolName: "Email", + shape: { type: "struct" } + }); + const postSymbol = registry.registerSourceModuleType("Post", { type: "struct" }); + registry.registerNestedType({ + parentSymbol: postSymbol, + symbolName: "Date", + shape: { type: "struct" } + }); + const ref = registry.reference({ + fromSymbol: emailSymbol, + toSymbol: "Foundation.Date" + }); + expect(ref.toString()).toBe("Date"); + }); + }); + }); +}); diff --git a/generators/swift/codegen/src/symbol/symbol-registry/index.ts b/generators/swift/codegen/src/symbol/symbol-registry/index.ts new file mode 100644 index 000000000000..815bee5a1ee1 --- /dev/null +++ b/generators/swift/codegen/src/symbol/symbol-registry/index.ts @@ -0,0 +1,2 @@ +export type { TypeSymbolShape } from "./symbol-graph"; +export * from "./symbol-registry"; diff --git a/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/__test__/symbol-graph.test.ts b/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/__test__/symbol-graph.test.ts new file mode 100644 index 000000000000..672d3b7861c9 --- /dev/null +++ b/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/__test__/symbol-graph.test.ts @@ -0,0 +1,164 @@ +import { SymbolGraph } from "../symbol-graph"; + +describe("SymbolGraph", () => { + function setupGraph() { + const graph = new SymbolGraph(); + // Swift + const swiftModule = graph.createModuleSymbol({ symbolId: "Swift", symbolName: "Swift" }); + const swiftStringType = graph.createTypeSymbol({ + symbolId: "Swift.String", + symbolName: "String", + shape: { type: "system" } + }); + graph.nestSymbol({ parentSymbolId: swiftModule.id, childSymbolId: swiftStringType.id }); + const swiftIntType = graph.createTypeSymbol({ + symbolId: "Swift.Int", + symbolName: "Int", + shape: { type: "system" } + }); + graph.nestSymbol({ parentSymbolId: swiftModule.id, childSymbolId: swiftIntType.id }); + const swiftBoolType = graph.createTypeSymbol({ + symbolId: "Swift.Bool", + symbolName: "Bool", + shape: { type: "system" } + }); + graph.nestSymbol({ parentSymbolId: swiftModule.id, childSymbolId: swiftBoolType.id }); + + // Foundation + const foundationModule = graph.createModuleSymbol({ + symbolId: "Foundation", + symbolName: "Foundation" + }); + const foundationURLType = graph.createTypeSymbol({ + symbolId: "Foundation.URL", + symbolName: "URL", + shape: { type: "system" } + }); + graph.nestSymbol({ parentSymbolId: foundationModule.id, childSymbolId: foundationURLType.id }); + const foundationDateType = graph.createTypeSymbol({ + symbolId: "Foundation.Date", + symbolName: "Date", + shape: { type: "system" } + }); + graph.nestSymbol({ parentSymbolId: foundationModule.id, childSymbolId: foundationDateType.id }); + const foundationDataType = graph.createTypeSymbol({ + symbolId: "Foundation.Data", + symbolName: "Data", + shape: { type: "system" } + }); + graph.nestSymbol({ parentSymbolId: foundationModule.id, childSymbolId: foundationDataType.id }); + + // Client module and types + const clientModule = graph.createModuleSymbol({ symbolId: "Module", symbolName: "Acme" }); + graph.addImportRelation({ clientSymbolId: "Module", importedSymbolId: "Swift" }); + graph.addImportRelation({ clientSymbolId: "Module", importedSymbolId: "Foundation" }); + + const userType = graph.createTypeSymbol({ + symbolId: "Module.User", + symbolName: "User", + shape: { type: "struct" } + }); + graph.nestSymbol({ parentSymbolId: clientModule.id, childSymbolId: userType.id }); + const postType = graph.createTypeSymbol({ + symbolId: "Module.Post", + symbolName: "Post", + shape: { type: "struct" } + }); + graph.nestSymbol({ parentSymbolId: clientModule.id, childSymbolId: postType.id }); + const postDateType = graph.createTypeSymbol({ + symbolId: "Module.Post.Date", + symbolName: "Date", + shape: { type: "struct" } + }); + graph.nestSymbol({ parentSymbolId: postType.id, childSymbolId: postDateType.id }); + const postCommentType = graph.createTypeSymbol({ + symbolId: "Module.Post.Comment", + symbolName: "Comment", + shape: { type: "struct" } + }); + graph.nestSymbol({ parentSymbolId: postType.id, childSymbolId: postCommentType.id }); + + return graph; + } + + it("resolves Foundation.Date from Module.User to 'Date'", () => { + const graph = setupGraph(); + expect( + graph.reference({ + fromSymbolId: "Module.User", + targetSymbolId: "Foundation.Date" + }) + ).toBe("Date"); + }); + + it("resolves Module.Post.Date from Module.Post to 'Date'", () => { + const graph = setupGraph(); + expect( + graph.reference({ + fromSymbolId: "Module.Post", + targetSymbolId: "Module.Post.Date" + }) + ).toBe("Date"); + }); + + it("resolves Foundation.Date from Module.Post to 'Foundation.Date' due to shadow", () => { + const graph = setupGraph(); + expect( + graph.reference({ + fromSymbolId: "Module.Post", + targetSymbolId: "Foundation.Date" + }) + ).toBe("Foundation.Date"); + }); + + it("resolves Foundation.Date from Module.User to 'Foundation.Date' when another import exposes Date", () => { + const graph = setupGraph(); + const otherModule = graph.createModuleSymbol({ symbolId: "Other", symbolName: "Other" }); + const otherDate = graph.createTypeSymbol({ + symbolId: "Other.Date", + symbolName: "Date", + shape: { type: "struct" } + }); + graph.nestSymbol({ parentSymbolId: otherModule.id, childSymbolId: otherDate.id }); + graph.addImportRelation({ clientSymbolId: "Module", importedSymbolId: "Other" }); + expect( + graph.reference({ + fromSymbolId: "Module.User", + targetSymbolId: "Foundation.Date" + }) + ).toBe("Foundation.Date"); + }); + + // New tests for resolveReference(from, reference: string) + it("resolveReference(from, 'Date') resolves to Foundation.Date from Module.User", () => { + const graph = setupGraph(); + const resolved = graph.resolveReference({ fromSymbolId: "Module.User", reference: "Date" }); + expect(resolved?.id).toBe("Foundation.Date"); + }); + + it("resolveReference(from, 'Post.Date') resolves to Module.Post.Date from Module.User", () => { + const graph = setupGraph(); + const resolved = graph.resolveReference({ fromSymbolId: "Module.User", reference: "Post.Date" }); + expect(resolved?.id).toBe("Module.Post.Date"); + }); + + it("resolveReference(from, 'Foundation.Date') resolves to Foundation.Date from Module.User", () => { + const graph = setupGraph(); + const resolved = graph.resolveReference({ fromSymbolId: "Module.User", reference: "Foundation.Date" }); + expect(resolved?.id).toBe("Foundation.Date"); + }); + + it("resolveReference returns null for ambiguous single-segment across imports", () => { + const graph = setupGraph(); + const otherModule = graph.createModuleSymbol({ symbolId: "Other", symbolName: "Other" }); + const otherDate = graph.createTypeSymbol({ + symbolId: "Other.Date", + symbolName: "Date", + shape: { type: "struct" } + }); + graph.nestSymbol({ parentSymbolId: otherModule.id, childSymbolId: otherDate.id }); + graph.addImportRelation({ clientSymbolId: "Module", importedSymbolId: "Other" }); + const resolved = graph.resolveReference({ fromSymbolId: "Module.User", reference: "Date" }); + expect(resolved).toBeNull(); + }); +}); diff --git a/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/index.ts b/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/index.ts new file mode 100644 index 000000000000..d978dc8b3bbe --- /dev/null +++ b/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/index.ts @@ -0,0 +1,2 @@ +export type { ModuleSymbol, Symbol, TypeSymbol, TypeSymbolShape } from "./symbol"; +export { SymbolGraph } from "./symbol-graph"; diff --git a/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/symbol-graph.ts b/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/symbol-graph.ts new file mode 100644 index 000000000000..228e04290b37 --- /dev/null +++ b/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/symbol-graph.ts @@ -0,0 +1,145 @@ +import { assertDefined } from "@fern-api/core-utils"; +import { ModuleSymbol, Symbol, TypeSymbol, TypeSymbolShape } from "./symbol"; + +export class SymbolGraph { + private readonly symbolsById = new Map(); + + public createModuleSymbol({ symbolId, symbolName }: { symbolId: string; symbolName: string }): ModuleSymbol { + this.validateSymbolNotExists(symbolId); + const symbol = new ModuleSymbol(symbolId, symbolName); + this.symbolsById.set(symbolId, symbol); + return symbol; + } + + public createTypeSymbol({ + symbolId, + symbolName, + shape + }: { + symbolId: string; + symbolName: string; + shape: TypeSymbolShape; + }): TypeSymbol { + this.validateSymbolNotExists(symbolId); + const symbol = new TypeSymbol(symbolName, symbolId, shape); + this.symbolsById.set(symbolId, symbol); + return symbol; + } + + public addImportRelation({ + clientSymbolId, + importedSymbolId + }: { + clientSymbolId: string; + importedSymbolId: string; + }): void { + const clientModuleSymbol = this.getSymbolByIdOrThrow(clientSymbolId); + const importedModuleSymbol = this.getSymbolByIdOrThrow(importedSymbolId); + if (clientModuleSymbol.kind !== "module" || importedModuleSymbol.kind !== "module") { + throw new Error( + `Client module '${clientModuleSymbol.id}' and imported module '${importedModuleSymbol.id}' must both be module symbols.` + ); + } + clientModuleSymbol.addImport(importedModuleSymbol); + } + + public nestSymbol({ parentSymbolId, childSymbolId }: { parentSymbolId: string; childSymbolId: string }): void { + const parentSymbol = this.getSymbolByIdOrThrow(parentSymbolId); + const childSymbol = this.getSymbolByIdOrThrow(childSymbolId); + parentSymbol.addChild(childSymbol); + childSymbol.parent = parentSymbol; + } + + public reference({ fromSymbolId, targetSymbolId }: { fromSymbolId: string; targetSymbolId: string }): string { + const from = this.getSymbolByIdOrThrow(fromSymbolId); + const target = this.getSymbolByIdOrThrow(targetSymbolId); + const path = target.qualifiedPath; + for (let k = 1; k <= path.length; k++) { + const parts = path.slice(path.length - k); + const resolved = this.resolvePath(from, parts); + if (resolved?.id === target.id) { + return parts.join("."); + } + } + return target.qualifiedName; + } + + /** + * Resolve a raw reference string (e.g., "Date", "Post.Date", "Foundation.Date") from a given scope. + * Returns the resolved Symbol node or null if it does not resolve unambiguously. + */ + public resolveReference({ fromSymbolId, reference }: { fromSymbolId: string; reference: string }): Symbol | null { + const from = this.getSymbolByIdOrThrow(fromSymbolId); + const parts = reference.split(".").filter((p) => p.length > 0); + return this.resolvePath(from, parts); + } + + private resolvePath(from: Symbol, parts: string[]): Symbol | null { + const [firstPart, ...restParts] = parts; + if (firstPart === undefined) { + return null; + } + const first = this.resolveFirstSegment(from, firstPart); + if (first === null) { + return null; + } + let cur: Symbol | null = first; + for (let i = 0; i < restParts.length; i++) { + const part = restParts[i]; + assertDefined(part); + cur = cur.getChildByName(part) ?? null; + if (cur === null) { + return null; + } + } + return cur; + } + + private resolveFirstSegment(from: Symbol, name: string): Symbol | null { + let cur: Symbol | null = from; + while (cur !== null) { + const child = cur.getChildByName(name); + if (child) { + return child; + } + cur = cur.parent; + } + const moduleSymbol = from.kind === "module" ? from : from.getNearestModuleAncestorOrThrow(); + // Allow explicit module qualifier (e.g., "Acme", "Foundation") + if (moduleSymbol.name === name) { + return moduleSymbol; + } + for (const importedModule of moduleSymbol.imports) { + if (importedModule.name === name) { + return importedModule; + } + } + let resolved: Symbol | null = null; + for (const importedModule of moduleSymbol.imports) { + const hit = importedModule.getChildByName(name); + if (hit) { + if (resolved != null && resolved.id !== hit.id) { + return null; // ambiguous across imports + } + resolved = hit; + } + } + return resolved; + } + + public getSymbolByIdOrThrow(symbolId: string): Symbol { + const symbol = this.symbolsById.get(symbolId); + assertDefined(symbol, `A symbol with the ID '${symbolId}' was not found in the registry.`); + return symbol; + } + + public getSymbolById(symbolId: string): Symbol | null { + return this.symbolsById.get(symbolId) ?? null; + } + + private validateSymbolNotExists(symbolId: string): void { + if (this.symbolsById.has(symbolId)) { + throw new Error(`A symbol with the ID '${symbolId}' already exists in the registry.`); + } + } +} diff --git a/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/symbol.ts b/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/symbol.ts new file mode 100644 index 000000000000..7b025bb30490 --- /dev/null +++ b/generators/swift/codegen/src/symbol/symbol-registry/symbol-graph/symbol.ts @@ -0,0 +1,109 @@ +import { assertNonNull } from "@fern-api/core-utils"; + +abstract class AbstractSymbol { + public readonly id: string; + public readonly name: string; + public abstract qualifiedPath: string[]; + protected childrenByName: Map; + + protected constructor(id: string, name: string) { + this.id = id; + this.name = name; + this.childrenByName = new Map(); + } + + public get children() { + return Array.from(this.childrenByName.values()); + } + + public addChild(child: Symbol) { + if (this.childrenByName.has(child.name)) { + throw new Error(`A child with the name '${child.name}' already exists in module '${this.name}'.`); + } + this.childrenByName.set(child.name, child); + } + + public getChildByName(name: string): Symbol | undefined { + return this.childrenByName.get(name); + } +} + +export class ModuleSymbol extends AbstractSymbol { + public readonly kind = "module"; + public readonly imports: ModuleSymbol[]; + public parent = null; + + public constructor(id: string, name: string) { + super(id, name); + this.imports = []; + } + + public addImport(moduleSymbol: ModuleSymbol) { + this.imports.push(moduleSymbol); + } + + public get qualifiedPath(): string[] { + return [this.name]; + } + + public get qualifiedName(): string { + return this.name; + } +} + +export type TypeSymbolShape = + | { + type: "system"; + } + | { + type: "struct"; + } + | { + type: "class"; + } + | { + type: "enum-container"; + } + | { + type: "enum-with-raw-values"; + } + | { + type: "enum-with-associated-values"; + } + | { + type: "protocol"; + } + | { + type: "other"; + }; + +export class TypeSymbol extends AbstractSymbol { + public readonly kind = "type"; + public readonly shape: TypeSymbolShape; + public parent: Symbol | null; + + public constructor(name: string, id: string, shape: TypeSymbolShape) { + super(id, name); + this.parent = null; + this.shape = shape; + } + + public getNearestModuleAncestorOrThrow(): ModuleSymbol { + let cur: Symbol | null = this.parent; + while (cur !== null && cur.kind !== "module") { + cur = cur.parent; + } + assertNonNull(cur, `No module ancestor found for type symbol '${this.id}'`); + return cur; + } + + public get qualifiedPath(): string[] { + return [...(this.parent?.qualifiedPath ?? []), this.name]; + } + + public get qualifiedName(): string { + return this.qualifiedPath.join("."); + } +} + +export type Symbol = ModuleSymbol | TypeSymbol; diff --git a/generators/swift/codegen/src/symbol/symbol-registry/symbol-registry.ts b/generators/swift/codegen/src/symbol/symbol-registry/symbol-registry.ts new file mode 100644 index 000000000000..e5c04b69ecb9 --- /dev/null +++ b/generators/swift/codegen/src/symbol/symbol-registry/symbol-registry.ts @@ -0,0 +1,199 @@ +import { assertNonNull } from "@fern-api/core-utils"; +import { Symbol } from ".."; +import { ModuleSymbol, SymbolGraph, TypeSymbolShape } from "./symbol-graph"; + +/** + * A symbol registry for a target module used in SDK generation. + * + * This registry manages symbol resolution and references within a Swift module, + * with built-in support for Swift standard library and Foundation framework types. + * It assumes that the Foundation module is imported throughout the target module. + */ +export class SymbolRegistry { + public static create(): SymbolRegistry { + const { graph, swiftSymbol, foundationSymbol } = SymbolRegistry.createGraph(); + return new SymbolRegistry(graph, swiftSymbol, foundationSymbol); + } + + private static createGraph(): { + graph: SymbolGraph; + swiftSymbol: ModuleSymbol; + foundationSymbol: ModuleSymbol; + } { + const graph = new SymbolGraph(); + + const createSwiftNode = () => { + const swiftSymbol = graph.createModuleSymbol({ + symbolId: Symbol.SWIFT_SYMBOL_ID, + symbolName: Symbol.SWIFT_SYMBOL_NAME + }); + Symbol.swiftTypeSymbols.forEach((symbol) => { + const symbolNode = graph.createTypeSymbol({ + symbolId: symbol.id, + symbolName: symbol.name, + shape: { type: "system" } + }); + graph.nestSymbol({ parentSymbolId: swiftSymbol.id, childSymbolId: symbolNode.id }); + }); + return swiftSymbol; + }; + + const createFoundationNode = () => { + const foundationSymbol = graph.createModuleSymbol({ + symbolId: Symbol.FOUNDATION_SYMBOL_ID, + symbolName: Symbol.FOUNDATION_SYMBOL_NAME + }); + Symbol.foundationTypeSymbols.forEach((symbol) => { + const symbolNode = graph.createTypeSymbol({ + symbolId: symbol.id, + symbolName: symbol.name, + shape: { type: "system" } + }); + graph.nestSymbol({ parentSymbolId: foundationSymbol.id, childSymbolId: symbolNode.id }); + }); + return foundationSymbol; + }; + + const swiftSymbol = createSwiftNode(); + const foundationSymbol = createFoundationNode(); + + return { graph, swiftSymbol, foundationSymbol }; + } + + private readonly graph: SymbolGraph; + private readonly swiftSymbol: ModuleSymbol; + private readonly foundationSymbol: ModuleSymbol; + private registeredSourceModule: ModuleSymbol | null; + private registeredTestModule: ModuleSymbol | null; + + private constructor(graph: SymbolGraph, swiftSymbol: ModuleSymbol, foundationSymbol: ModuleSymbol) { + this.graph = graph; + this.swiftSymbol = swiftSymbol; + this.foundationSymbol = foundationSymbol; + this.registeredSourceModule = null; + this.registeredTestModule = null; + } + + public getRegisteredSourceModuleSymbolOrThrow(): Symbol { + assertNonNull(this.registeredSourceModule, "Module symbol not found."); + return Symbol.create(this.registeredSourceModule.id, this.registeredSourceModule.name, { type: "other" }); + } + + public getRegisteredTestModuleSymbolOrThrow(): Symbol { + assertNonNull(this.registeredTestModule, "Module symbol not found."); + return Symbol.create(this.registeredTestModule.id, this.registeredTestModule.name, { type: "other" }); + } + + public getSymbolByIdOrThrow(symbolId: string): Symbol { + const symbol = this.graph.getSymbolById(symbolId); + assertNonNull(symbol, `Symbol with ID '${symbolId}' not found in registry.`); + return Symbol.create(symbol.id, symbol.name, symbol.kind === "type" ? symbol.shape : { type: "other" }); + } + + /** + * Registers a source module symbol. Use this to register a source module only once. + * The import relations between the source module and Swift/Foundation will be automatically added. + * + * @param symbolName - The symbol name. Must not be `"Swift"` or `"Foundation"`. + */ + public registerSourceModule(symbolName: string): Symbol { + const symbolId = symbolName; + const moduleSymbol = this.graph.createModuleSymbol({ symbolId, symbolName }); + moduleSymbol.addImport(this.swiftSymbol); + moduleSymbol.addImport(this.foundationSymbol); + this.registeredSourceModule = moduleSymbol; + return Symbol.create(moduleSymbol.id, moduleSymbol.name, { type: "other" }); + } + + /** + * Registers a test module symbol. Use this to register a test module only once. + * The import relations between the test module, source module and Swift/Foundation will be automatically added. + * + * @param symbolName - The symbol name. Must not be different from `"Swift"`, `"Foundation"` or the name of the source module. + */ + public registerTestModule(symbolName: string): Symbol { + const symbolId = symbolName; + const moduleSymbol = this.graph.createModuleSymbol({ symbolId, symbolName }); + moduleSymbol.addImport(this.swiftSymbol); + moduleSymbol.addImport(this.foundationSymbol); + assertNonNull(this.registeredSourceModule, "Cannot register a test module before registering a source module."); + moduleSymbol.addImport(this.registeredSourceModule); + this.registeredTestModule = moduleSymbol; + return Symbol.create(moduleSymbol.id, moduleSymbol.name, { type: "other" }); + } + + /** + * Registers a top-level source module type symbol. + * + * @param symbolName - The symbol name. + * @param shape - The information about the shape of the type. + */ + public registerSourceModuleType(symbolName: string, shape: TypeSymbolShape): Symbol { + assertNonNull(this.registeredSourceModule, "Cannot register a type before registering a module."); + const symbolId = this.inferSymbolIdForSourceModuleType(symbolName); + const typeSymbol = this.graph.createTypeSymbol({ symbolId, symbolName, shape }); + this.graph.nestSymbol({ parentSymbolId: this.registeredSourceModule.id, childSymbolId: typeSymbol.id }); + return Symbol.create(typeSymbol.id, typeSymbol.name, shape); + } + + /** + * Registers a top-level test module type symbol. + * + * @param symbolName - The symbol name. + * @param shape - The information about the shape of the type. + */ + public registerTestModuleType(symbolName: string, shape: TypeSymbolShape): Symbol { + assertNonNull(this.registeredTestModule, "Cannot register a type before registering a module."); + const symbolId = this.inferSymbolIdForTestModuleType(symbolName); + const typeSymbol = this.graph.createTypeSymbol({ symbolId, symbolName, shape }); + this.graph.nestSymbol({ parentSymbolId: this.registeredTestModule.id, childSymbolId: typeSymbol.id }); + return Symbol.create(typeSymbol.id, typeSymbol.name, shape); + } + + /** + * Registers a nested type symbol. + */ + public registerNestedType({ + parentSymbol, + symbolName, + shape + }: { + parentSymbol: Symbol | string; + symbolName: string; + shape: TypeSymbolShape; + }): Symbol { + const parentSymbolId = typeof parentSymbol === "string" ? parentSymbol : parentSymbol.id; + const symbolId = this.inferSymbolIdForNestedType(parentSymbolId, symbolName); + const typeSymbol = this.graph.createTypeSymbol({ symbolId, symbolName, shape }); + this.graph.nestSymbol({ parentSymbolId, childSymbolId: typeSymbol.id }); + return Symbol.create(typeSymbol.id, typeSymbol.name, shape); + } + + public reference({ fromSymbol, toSymbol }: { fromSymbol: Symbol | string; toSymbol: Symbol | string }) { + const fromSymbolId = typeof fromSymbol === "string" ? fromSymbol : fromSymbol.id; + const toSymbolId = typeof toSymbol === "string" ? toSymbol : toSymbol.id; + return this.graph.reference({ fromSymbolId, targetSymbolId: toSymbolId }); + } + + public resolveReference({ fromSymbol, reference }: { fromSymbol: Symbol | string; reference: string }) { + const fromSymbolId = typeof fromSymbol === "string" ? fromSymbol : fromSymbol.id; + const symbol = this.graph.resolveReference({ fromSymbolId, reference }); + return symbol + ? Symbol.create(symbol.id, symbol.name, symbol.kind === "type" ? symbol.shape : { type: "other" }) + : null; + } + + public inferSymbolIdForSourceModuleType(symbolName: string) { + assertNonNull(this.registeredSourceModule, "Cannot get symbol id for a type before registering a module."); + return `${this.registeredSourceModule.id}.${symbolName}`; + } + + public inferSymbolIdForTestModuleType(symbolName: string) { + assertNonNull(this.registeredTestModule, "Cannot get symbol id for a type before registering a module."); + return `${this.registeredTestModule.id}.${symbolName}`; + } + + public inferSymbolIdForNestedType(parentSymbolId: string, symbolName: string) { + return `${parentSymbolId}.${symbolName}`; + } +} diff --git a/generators/swift/codegen/src/symbol/symbol.ts b/generators/swift/codegen/src/symbol/symbol.ts new file mode 100644 index 000000000000..8de9c036e4c8 --- /dev/null +++ b/generators/swift/codegen/src/symbol/symbol.ts @@ -0,0 +1,107 @@ +import { TypeSymbolShape } from "./symbol-registry"; + +export type SwiftTypeSymbolName = + | "String" + | "Bool" + | "Int" + | "Int64" + | "UInt" + | "UInt64" + | "Float" + | "Double" + | "Void" + | "Encoder" + | "Decoder" + // TODO(kafkas): Any doesn't seem to be under the Swift scope i.e. Swift.Any is not valid so we probably wanna move this. + | "Any"; + +export type FoundationTypeSymbolName = "Data" | "Date" | "URLSession" | "UUID"; + +export class Symbol { + public static readonly SWIFT_SYMBOL_NAME = "Swift"; + public static readonly SWIFT_SYMBOL_ID = Symbol.SWIFT_SYMBOL_NAME; + + private static swiftTypeSymbolsByName: Record = { + String: Symbol.swiftType("String"), + Bool: Symbol.swiftType("Bool"), + Int: Symbol.swiftType("Int"), + Int64: Symbol.swiftType("Int64"), + UInt: Symbol.swiftType("UInt"), + UInt64: Symbol.swiftType("UInt64"), + Float: Symbol.swiftType("Float"), + Double: Symbol.swiftType("Double"), + Void: Symbol.swiftType("Void"), + Encoder: Symbol.swiftType("Encoder"), + Decoder: Symbol.swiftType("Decoder"), + Any: Symbol.swiftType("Any") + }; + public static swiftTypeSymbols = Object.values(Symbol.swiftTypeSymbolsByName); + + public static readonly FOUNDATION_SYMBOL_NAME = "Foundation"; + public static readonly FOUNDATION_SYMBOL_ID = Symbol.FOUNDATION_SYMBOL_NAME; + + private static foundationTypeSymbolsByName: Record = { + Data: Symbol.foundationType("Data"), + Date: Symbol.foundationType("Date"), + URLSession: Symbol.foundationType("URLSession"), + UUID: Symbol.foundationType("UUID") + }; + public static foundationTypeSymbols = Object.values(Symbol.foundationTypeSymbolsByName); + + public static isSwiftSymbol(symbolId: string): boolean { + return Symbol.SWIFT_SYMBOL_ID === symbolId || symbolId.startsWith(`${Symbol.SWIFT_SYMBOL_ID}.`); + } + + public static isSwiftSymbolName(symbolName: string): symbolName is SwiftTypeSymbolName { + return symbolName in Symbol.swiftTypeSymbolsByName; + } + + public static isFoundationSymbol(symbolId: string): boolean { + return Symbol.FOUNDATION_SYMBOL_ID === symbolId || symbolId.startsWith(`${Symbol.FOUNDATION_SYMBOL_ID}.`); + } + + public static isFoundationSymbolName(symbolName: string): symbolName is FoundationTypeSymbolName { + return symbolName in Symbol.foundationTypeSymbolsByName; + } + + /** + * Any non-system symbol. + */ + public static isCustomSymbol(symbolId: string): boolean { + return !Symbol.isSwiftSymbol(symbolId) && !Symbol.isFoundationSymbol(symbolId); + } + + public static create(symbolId: string, symbolName: string, shape: TypeSymbolShape): Symbol { + return new Symbol(symbolId, symbolName, shape); + } + + public static swiftType(symbolName: SwiftTypeSymbolName): Symbol { + return Symbol.create(`${Symbol.SWIFT_SYMBOL_ID}.${symbolName}`, symbolName, { type: "system" }); + } + + public static foundationType(symbolName: FoundationTypeSymbolName): Symbol { + return Symbol.create(`${Symbol.FOUNDATION_SYMBOL_ID}.${symbolName}`, symbolName, { type: "system" }); + } + + public readonly id: string; + public readonly name: string; + public readonly shape: TypeSymbolShape; + + private constructor(id: string, name: string, shape: TypeSymbolShape) { + this.id = id; + this.name = name; + this.shape = shape; + } + + public get isSwiftSymbol(): boolean { + return Symbol.isSwiftSymbol(this.id); + } + + public get isFoundationSymbol(): boolean { + return Symbol.isFoundationSymbol(this.id); + } + + public get isCustomSymbol(): boolean { + return Symbol.isCustomSymbol(this.id); + } +} diff --git a/generators/swift/dynamic-snippets/src/EndpointSnippetGenerator.ts b/generators/swift/dynamic-snippets/src/EndpointSnippetGenerator.ts index fda91f665d50..8b0279fb6b89 100644 --- a/generators/swift/dynamic-snippets/src/EndpointSnippetGenerator.ts +++ b/generators/swift/dynamic-snippets/src/EndpointSnippetGenerator.ts @@ -106,12 +106,13 @@ export class EndpointSnippetGenerator { const authArgs = auth ? this.getRootClientAuthArgs({ auth, snippet }) : []; rootClientArgs.push(...authArgs); rootClientArgs.push(...additionalArgs); + const nonNopRootClientArgs = rootClientArgs.filter((arg) => !arg.value.isNop()); return swift.Statement.constantDeclaration({ unsafeName: CLIENT_CONST_NAME, value: swift.Expression.classInitialization({ unsafeName: this.context.getRootClientClassName(), - arguments_: rootClientArgs, - multiline: rootClientArgs.length > 1 ? true : undefined + arguments_: nonNopRootClientArgs, + multiline: nonNopRootClientArgs.length > 1 ? true : undefined }) }); } @@ -254,14 +255,14 @@ export class EndpointSnippetGenerator { endpoint: FernIr.dynamic.Endpoint; snippet: FernIr.dynamic.EndpointSnippetRequest; }) { - const arguments_ = this.getMethodArguments({ endpoint, snippet }); + const nonNopArguments = this.getMethodArguments({ endpoint, snippet }).filter((arg) => !arg.value.isNop()); return swift.Expression.try( swift.Expression.await( swift.Expression.methodCall({ target: swift.Expression.rawValue(CLIENT_CONST_NAME), methodName: this.getMethodName({ endpoint }), - arguments_, - multiline: arguments_.length > 1 ? true : undefined + arguments_: nonNopArguments, + multiline: nonNopArguments.length > 1 ? true : undefined }) ) ); @@ -430,12 +431,12 @@ export class EndpointSnippetGenerator { : []; this.context.errors.unscope(); - const arguments_ = requestBodyFields; + const nonNopArguments = requestBodyFields.filter((arg) => !arg.value.isNop()); return swift.Expression.contextualMethodCall({ methodName: "init", - arguments_, - multiline: arguments_.length > 1 ? true : undefined + arguments_: nonNopArguments, + multiline: nonNopArguments.length > 1 ? true : undefined }); } diff --git a/generators/swift/dynamic-snippets/src/__test__/__snapshots__/DynamicSnippetsGenerator.test.ts.snap b/generators/swift/dynamic-snippets/src/__test__/__snapshots__/DynamicSnippetsGenerator.test.ts.snap index f11ece1a0913..0e8ca96183e5 100644 --- a/generators/swift/dynamic-snippets/src/__test__/__snapshots__/DynamicSnippetsGenerator.test.ts.snap +++ b/generators/swift/dynamic-snippets/src/__test__/__snapshots__/DynamicSnippetsGenerator.test.ts.snap @@ -151,18 +151,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] )) } @@ -245,18 +243,7 @@ private func main() async throws { .init(data: Data("Second".utf8)) ], maybeFile: .init(data: Data("".utf8)), - maybeFileList: [], - maybeString: , - integer: , - maybeInteger: , - optionalListOfStrings: , - listOfObjects: , - optionalMetadata: , - optionalObjectType: , - optionalID: , - aliasObject: , - listOfAliasObject: , - aliasListOfObject: + maybeFileList: [] )) } diff --git a/generators/swift/dynamic-snippets/src/context/DynamicTypeLiteralMapper.ts b/generators/swift/dynamic-snippets/src/context/DynamicTypeLiteralMapper.ts index de3dcd4945f7..afba7b50c21c 100644 --- a/generators/swift/dynamic-snippets/src/context/DynamicTypeLiteralMapper.ts +++ b/generators/swift/dynamic-snippets/src/context/DynamicTypeLiteralMapper.ts @@ -35,7 +35,6 @@ export class DynamicTypeLiteralMapper { LiteralEnum.generateEnumCaseLabel(args.typeReference.value.value) ); } else if (args.typeReference.value.type === "boolean") { - // TODO(kafkas): Boolean literals are not supported yet return swift.Expression.nop(); } else { assertNever(args.typeReference.value); @@ -58,7 +57,6 @@ export class DynamicTypeLiteralMapper { case "primitive": return this.convertPrimitive({ primitive: args.typeReference.value, value: args.value, as: args.as }); case "set": - // TODO(kafkas): Set is not supported yet return swift.Expression.nop(); case "unknown": return this.convertUnknown(args.value); @@ -329,11 +327,16 @@ export class DynamicTypeLiteralMapper { snippetObject: value }) .map((typeInstance) => { + const expression = this.convert(typeInstance); + if (expression.isNop()) { + return null; + } return swift.functionArgument({ label: sanitizeSelf(typeInstance.name.name.camelCase.unsafeName), value: this.convert(typeInstance) }); - }), + }) + .filter((argument) => argument != null), multiline: true }); } @@ -531,7 +534,6 @@ export class DynamicTypeLiteralMapper { if (bigInt == null) { return swift.Expression.nop(); } - // TODO(kafkas): Bigints are not supported yet return swift.Expression.nop(); } default: diff --git a/generators/swift/dynamic-snippets/src/context/DynamicTypeMapper.ts b/generators/swift/dynamic-snippets/src/context/DynamicTypeMapper.ts index 78b1b7bcf0da..d2bf6b159121 100644 --- a/generators/swift/dynamic-snippets/src/context/DynamicTypeMapper.ts +++ b/generators/swift/dynamic-snippets/src/context/DynamicTypeMapper.ts @@ -44,7 +44,6 @@ export class DynamicTypeMapper { case "primitive": return this.convertPrimitive({ primitive: args.typeReference.value }); case "set": - // TODO(kafkas): Set is not supported yet return swift.Type.jsonValue(); case "unknown": return this.convertUnknown(); @@ -70,7 +69,6 @@ export class DynamicTypeMapper { private convertLiteral({ literal }: { literal: FernIr.dynamic.LiteralType }): swift.Type { switch (literal.type) { case "boolean": - // TODO(kafkas): Boolean literals are not supported yet return swift.Type.bool(); case "string": return swift.Type.custom(pascalCase(literal.value)); @@ -108,7 +106,6 @@ export class DynamicTypeMapper { case "BASE_64": return swift.Type.string(); case "BIG_INTEGER": - // TODO(kafkas): Change when custom type is implemented return swift.Type.string(); default: assertNever(primitive); diff --git a/generators/swift/model/src/alias/AliasGenerator.ts b/generators/swift/model/src/alias/AliasGenerator.ts index a09f379e76b6..4fb2cebb777e 100644 --- a/generators/swift/model/src/alias/AliasGenerator.ts +++ b/generators/swift/model/src/alias/AliasGenerator.ts @@ -33,7 +33,7 @@ export class AliasGenerator { return swift.Statement.typealiasDeclaration({ unsafeName: this.name, accessLevel: swift.AccessLevel.Public, - aliasedType: this.context.getSwiftTypeForTypeReference(this.typeDeclaration.aliasOf), + aliasedType: this.context.getSwiftTypeReferenceFromSourceModuleScope(this.typeDeclaration.aliasOf), docs: this.docsContent ? swift.docComment({ summary: this.docsContent }) : undefined }); } diff --git a/generators/swift/model/src/helpers/struct-generator/LocalContext.ts b/generators/swift/model/src/helpers/struct-generator/LocalContext.ts deleted file mode 100644 index 99e11b1f8b85..000000000000 --- a/generators/swift/model/src/helpers/struct-generator/LocalContext.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { noop } from "@fern-api/core-utils"; -import { LocalTypeRegistry } from "@fern-api/swift-base"; -import { LiteralEnum, swift } from "@fern-api/swift-codegen"; -import { TypeReference } from "@fern-fern/ir-sdk/api"; - -import { LiteralEnumGenerator } from "../../literal"; -import { LocalSymbolRegistry } from "./LocalSymbolRegistry"; -import type { StructGenerator } from "./StructGenerator"; - -export declare namespace LocalContext { - interface AdditionalPropertiesMetadata { - /** - * The name of the property that will be used to store additional properties that are not explicitly defined in the schema. - */ - propertyName: string; - swiftType: swift.Type; - } - - interface Args { - readonly additionalPropertiesMetadata?: AdditionalPropertiesMetadata; - readonly stringLiteralEnums: Map; - readonly symbolRegistry: LocalSymbolRegistry; - } -} - -export class LocalContext implements LocalTypeRegistry { - public readonly additionalPropertiesMetadata?: LocalContext.AdditionalPropertiesMetadata; - public readonly stringLiteralEnums: Map; - public readonly symbolRegistry: LocalSymbolRegistry; - - public static buildForStructGenerator(args: StructGenerator.Args): LocalContext { - const { - constantPropertyDefinitions, - dataPropertyDefinitions, - additionalProperties: hasAdditionalProperties - } = args; - const symbolRegistry = LocalSymbolRegistry.create(); - - const computeAdditionalPropertiesMetadata = () => { - const otherPropertyNames = [ - ...constantPropertyDefinitions.map((p) => p.unsafeName), - ...dataPropertyDefinitions.map((p) => p.unsafeName) - ]; - const otherPropertyNamesSet = new Set(otherPropertyNames); - let propertyName = "additionalProperties"; - while (otherPropertyNamesSet.has(propertyName)) { - propertyName = "_" + propertyName; - } - return { - propertyName, - swiftType: swift.Type.dictionary(swift.Type.string(), swift.Type.jsonValue()) - }; - }; - - const generateStringLiteralEnums = (): Map => { - const enumsByLiteralValue = new Map(); - - const generateStringLiteralEnumsForTypeReference = (typeReference: TypeReference) => { - typeReference._visit({ - container: (container) => { - container._visit({ - literal: (literal) => { - literal._visit({ - string: (literalValue) => { - const enumName = symbolRegistry.registerStringLiteralSymbolIfNotExists( - LiteralEnum.generateName(literalValue), - literalValue - ); - const literalEnumGenerator = new LiteralEnumGenerator({ - name: enumName, - literalValue - }); - enumsByLiteralValue.set(literalValue, literalEnumGenerator.generate()); - }, - boolean: noop, - _other: noop - }); - }, - map: (mapType) => { - generateStringLiteralEnumsForTypeReference(mapType.keyType); - generateStringLiteralEnumsForTypeReference(mapType.valueType); - }, - set: (ref) => { - generateStringLiteralEnumsForTypeReference(ref); - }, - nullable: (ref) => { - generateStringLiteralEnumsForTypeReference(ref); - }, - optional: (ref) => { - generateStringLiteralEnumsForTypeReference(ref); - }, - list: (ref) => { - generateStringLiteralEnumsForTypeReference(ref); - }, - _other: noop - }); - }, - primitive: noop, - unknown: noop, - named: noop, - _other: noop - }); - }; - - for (const def of [...constantPropertyDefinitions, ...dataPropertyDefinitions]) { - if (def.type instanceof swift.Type) { - continue; - } - generateStringLiteralEnumsForTypeReference(def.type); - } - - return enumsByLiteralValue; - }; - - return new LocalContext({ - additionalPropertiesMetadata: hasAdditionalProperties ? computeAdditionalPropertiesMetadata() : undefined, - stringLiteralEnums: generateStringLiteralEnums(), - symbolRegistry - }); - } - - private constructor(args: LocalContext.Args) { - this.additionalPropertiesMetadata = args.additionalPropertiesMetadata; - this.stringLiteralEnums = args.stringLiteralEnums; - this.symbolRegistry = args.symbolRegistry; - } - - public getSwiftTypeForStringLiteral(literalValue: string): swift.Type { - const enumName = this.symbolRegistry.getStringLiteralSymbolOrThrow(literalValue); - return swift.Type.custom(enumName); - } - - public hasNestedTypeWithName(symbolName: string): boolean { - return Array.from(this.stringLiteralEnums.values()).some((enum_) => enum_.name === symbolName); - } -} diff --git a/generators/swift/model/src/helpers/struct-generator/LocalSymbolRegistry.ts b/generators/swift/model/src/helpers/struct-generator/LocalSymbolRegistry.ts deleted file mode 100644 index 0201628adff4..000000000000 --- a/generators/swift/model/src/helpers/struct-generator/LocalSymbolRegistry.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { assertDefined, SymbolRegistry } from "@fern-api/core-utils"; - -export class LocalSymbolRegistry { - private static readonly reservedSymbols = ["CodingKeys"]; - - public static create(): LocalSymbolRegistry { - return new LocalSymbolRegistry(LocalSymbolRegistry.reservedSymbols); - } - - private stringLiteralEnumsRegistry: SymbolRegistry; - - private constructor(reservedSymbolNames: string[]) { - this.stringLiteralEnumsRegistry = new SymbolRegistry({ reservedSymbolNames }); - } - - public getStringLiteralSymbolOrThrow(literalValue: string): string { - const symbol = this.stringLiteralEnumsRegistry.getSymbolNameById(literalValue); - assertDefined(symbol, `String literal symbol not found for literal value "${literalValue}"`); - return symbol; - } - - public registerStringLiteralSymbolIfNotExists(nameCandidatePascalCase: string, literalValue: string): string { - let symbolName = this.stringLiteralEnumsRegistry.getSymbolNameById(literalValue); - if (symbolName != null) { - return symbolName; - } - return this.stringLiteralEnumsRegistry.registerSymbol(literalValue, [ - nameCandidatePascalCase, - `${nameCandidatePascalCase}Literal`, - `${nameCandidatePascalCase}Enum`, - `${nameCandidatePascalCase}LiteralType`, - `${nameCandidatePascalCase}EnumType` - ]); - } -} diff --git a/generators/swift/model/src/helpers/struct-generator/StructGenerator.ts b/generators/swift/model/src/helpers/struct-generator/StructGenerator.ts index 325eecbef501..cba1977df7c9 100644 --- a/generators/swift/model/src/helpers/struct-generator/StructGenerator.ts +++ b/generators/swift/model/src/helpers/struct-generator/StructGenerator.ts @@ -1,14 +1,15 @@ +import { Referencer } from "@fern-api/swift-base"; import { swift } from "@fern-api/swift-codegen"; import { TypeReference } from "@fern-fern/ir-sdk/api"; - +import { LiteralEnumGenerator } from "../../literal"; import { ModelGeneratorContext } from "../../ModelGeneratorContext"; -import { LocalContext } from "./LocalContext"; +import { AdditionalPropertiesMetadata, computeAdditionalPropertiesMetadata } from "./additional-properties"; export declare namespace StructGenerator { interface ConstantPropertyDefinition { unsafeName: string; rawName: string; - type: swift.Type | TypeReference; + type: swift.TypeReference | TypeReference; value: swift.Expression; docsContent?: string; } @@ -21,7 +22,7 @@ export declare namespace StructGenerator { } interface Args { - name: string; + symbol: swift.Symbol; constantPropertyDefinitions: ConstantPropertyDefinition[]; dataPropertyDefinitions: DataPropertyDefinition[]; additionalProperties: boolean; @@ -31,34 +32,36 @@ export declare namespace StructGenerator { } export class StructGenerator { - private readonly name: string; + private readonly symbol: swift.Symbol; private readonly constantPropertyDefinitions: StructGenerator.ConstantPropertyDefinition[]; private readonly dataPropertyDefinitions: StructGenerator.DataPropertyDefinition[]; private readonly docsContent?: string; private readonly generatorContext: ModelGeneratorContext; - private readonly localContext: LocalContext; + private readonly referencer: Referencer; + private readonly additionalPropertiesMetadata: AdditionalPropertiesMetadata | null; public constructor(args: StructGenerator.Args) { - const { name, constantPropertyDefinitions, dataPropertyDefinitions, docsContent, context } = args; - this.name = name; + const { symbol, constantPropertyDefinitions, dataPropertyDefinitions, docsContent, context } = args; + this.referencer = context.createReferencer(symbol); + this.symbol = symbol; this.constantPropertyDefinitions = constantPropertyDefinitions; this.dataPropertyDefinitions = dataPropertyDefinitions; this.docsContent = docsContent; this.generatorContext = context; - this.localContext = LocalContext.buildForStructGenerator(args); + this.additionalPropertiesMetadata = computeAdditionalPropertiesMetadata(args, this.referencer); } public generate(): swift.Struct { const constantProperties = this.generateConstantProperties(); const dataProperties = this.generateDataProperties(); const properties = [...constantProperties, ...dataProperties]; - if (this.localContext.additionalPropertiesMetadata) { + if (this.additionalPropertiesMetadata) { properties.push( swift.property({ - unsafeName: this.localContext.additionalPropertiesMetadata.propertyName, + unsafeName: this.additionalPropertiesMetadata.propertyName, accessLevel: swift.AccessLevel.Public, declarationType: swift.DeclarationType.Let, - type: this.localContext.additionalPropertiesMetadata.swiftType, + type: this.additionalPropertiesMetadata.swiftType, docs: swift.docComment({ summary: "Additional properties that are not explicitly defined in the schema" }) @@ -66,7 +69,7 @@ export class StructGenerator { ); } return swift.struct({ - name: this.name, + name: this.symbol.name, accessLevel: swift.AccessLevel.Public, conformances: [swift.Protocol.Codable, swift.Protocol.Hashable, swift.Protocol.Sendable], properties, @@ -83,7 +86,7 @@ export class StructGenerator { unsafeName: p.unsafeName, accessLevel: swift.AccessLevel.Public, declarationType: swift.DeclarationType.Let, - type: this.getSwiftTypeForProperty(p), + type: this.getSwiftTypeReferenceForProperty(p), defaultValue: p.value, docs: p.docsContent ? swift.docComment({ summary: p.docsContent }) : undefined }) @@ -96,24 +99,24 @@ export class StructGenerator { unsafeName: p.unsafeName, accessLevel: swift.AccessLevel.Public, declarationType: swift.DeclarationType.Let, - type: this.getSwiftTypeForProperty(p), + type: this.getSwiftTypeReferenceForProperty(p), docs: p.docsContent ? swift.docComment({ summary: p.docsContent }) : undefined }) ); } - private getSwiftTypeForProperty( + private getSwiftTypeReferenceForProperty( definition: StructGenerator.ConstantPropertyDefinition | StructGenerator.DataPropertyDefinition ) { - if (definition.type instanceof swift.Type) { + if (definition.type instanceof swift.TypeReference) { return definition.type; } - return this.generatorContext.getSwiftTypeForTypeReference(definition.type, this.localContext); + return this.generatorContext.getSwiftTypeReferenceFromScope(definition.type, this.symbol); } private generateInitializers(dataProperties: swift.Property[]): swift.Initializer[] { const initializers = [this.generatePrimaryInitializer(dataProperties)]; - if (this.localContext.additionalPropertiesMetadata) { + if (this.additionalPropertiesMetadata) { initializers.push(this.generateInitializerForDecoder(dataProperties)); } return initializers; @@ -125,15 +128,15 @@ export class StructGenerator { argumentLabel: p.unsafeName, unsafeName: p.unsafeName, type: p.type, - defaultValue: p.type.isOptional ? swift.Expression.rawValue("nil") : undefined + defaultValue: p.type.variant.type === "optional" ? swift.Expression.rawValue("nil") : undefined }); }); - if (this.localContext.additionalPropertiesMetadata) { + if (this.additionalPropertiesMetadata) { parameters.push( swift.functionParameter({ - argumentLabel: this.localContext.additionalPropertiesMetadata.propertyName, - unsafeName: this.localContext.additionalPropertiesMetadata.propertyName, - type: this.localContext.additionalPropertiesMetadata.swiftType, + argumentLabel: this.additionalPropertiesMetadata.propertyName, + unsafeName: this.additionalPropertiesMetadata.propertyName, + type: this.additionalPropertiesMetadata.swiftType, defaultValue: swift.Expression.contextualMethodCall({ methodName: "init" }) }) ); @@ -141,11 +144,11 @@ export class StructGenerator { const bodyStatements = dataProperties.map((p) => swift.Statement.propertyAssignment(p.unsafeName, swift.Expression.reference(p.unsafeName)) ); - if (this.localContext.additionalPropertiesMetadata) { + if (this.additionalPropertiesMetadata) { bodyStatements.push( swift.Statement.propertyAssignment( - this.localContext.additionalPropertiesMetadata.propertyName, - swift.Expression.reference(this.localContext.additionalPropertiesMetadata.propertyName) + this.additionalPropertiesMetadata.propertyName, + swift.Expression.reference(this.additionalPropertiesMetadata.propertyName) ) ); } @@ -185,17 +188,20 @@ export class StructGenerator { swift.Expression.try( swift.Expression.methodCall({ target: swift.Expression.reference("container"), - methodName: p.type.isOptional - ? p.type.isOptionalNullable - ? "decodeNullableIfPresent" - : "decodeIfPresent" - : "decode", + methodName: + p.type.variant.type === "optional" + ? p.type.variant.valueType.variant.type === "nullable" + ? "decodeNullableIfPresent" + : "decodeIfPresent" + : "decode", arguments_: [ swift.functionArgument({ value: swift.Expression.memberAccess({ - target: p.type.isOptionalNullable - ? p.type.nonOptional().nonNullable() - : p.type.nonOptional(), + target: + p.type.variant.type === "optional" && + p.type.variant.valueType.variant.type === "nullable" + ? p.type.nonOptional().nonNullable() + : p.type.nonOptional(), memberName: "self" }) }), @@ -211,10 +217,10 @@ export class StructGenerator { }); } - if (this.localContext.additionalPropertiesMetadata) { + if (this.additionalPropertiesMetadata) { bodyStatements.push( swift.Statement.propertyAssignment( - this.localContext.additionalPropertiesMetadata.propertyName, + this.additionalPropertiesMetadata.propertyName, swift.Expression.try( swift.Expression.methodCall({ target: swift.Expression.reference("decoder"), @@ -243,7 +249,7 @@ export class StructGenerator { swift.functionParameter({ argumentLabel: "from", unsafeName: "decoder", - type: swift.Type.custom("Decoder") + type: this.referencer.referenceSwiftType("Decoder") }) ], body: swift.CodeBlock.withStatements(bodyStatements) @@ -252,7 +258,7 @@ export class StructGenerator { private generateMethods(constantProperties: swift.Property[], dataProperties: swift.Property[]) { const methods: swift.Method[] = []; - if (this.localContext.additionalPropertiesMetadata) { + if (this.additionalPropertiesMetadata) { methods.push(this.generateEncodeMethod(constantProperties, dataProperties)); } return methods; @@ -279,7 +285,7 @@ export class StructGenerator { ); } - if (this.localContext.additionalPropertiesMetadata) { + if (this.additionalPropertiesMetadata) { bodyStatements.push( swift.Statement.expressionStatement( swift.Expression.try( @@ -290,7 +296,7 @@ export class StructGenerator { swift.functionArgument({ value: swift.Expression.memberAccess({ target: swift.Expression.rawValue("self"), - memberName: this.localContext.additionalPropertiesMetadata.propertyName + memberName: this.additionalPropertiesMetadata.propertyName }) }) ] @@ -306,11 +312,12 @@ export class StructGenerator { swift.Expression.try( swift.Expression.methodCall({ target: swift.Expression.reference("container"), - methodName: p.type.isOptional - ? p.type.isOptionalNullable - ? "encodeNullableIfPresent" - : "encodeIfPresent" - : "encode", + methodName: + p.type.variant.type === "optional" + ? p.type.variant.valueType.variant.type === "nullable" + ? "encodeNullableIfPresent" + : "encodeIfPresent" + : "encode", arguments_: [ swift.functionArgument({ value: swift.Expression.memberAccess({ @@ -336,20 +343,26 @@ export class StructGenerator { swift.functionParameter({ argumentLabel: "to", unsafeName: "encoder", - type: swift.Type.custom("Encoder") + type: this.referencer.referenceSwiftType("Encoder") }) ], throws: true, - returnType: swift.Type.void(), + returnType: this.referencer.referenceSwiftType("Void"), body: swift.CodeBlock.withStatements(bodyStatements) }); } private generateNestedTypes(constantProperties: swift.Property[], dataProperties: swift.Property[]) { const nestedTypes: (swift.Struct | swift.EnumWithRawValues)[] = []; - this.localContext.stringLiteralEnums.forEach((enum_) => { - nestedTypes.push(enum_); - }); + this.generatorContext.project.nameRegistry + .getAllNestedLiteralEnumSymbolsOrThrow(this.symbol) + .forEach(({ symbol, literalValue }) => { + const literalEnumGenerator = new LiteralEnumGenerator({ + name: symbol.name, + literalValue + }); + nestedTypes.push(literalEnumGenerator.generate()); + }); if (constantProperties.length > 0 || dataProperties.length > 0) { nestedTypes.push(this.generateCodingKeysEnum()); } diff --git a/generators/swift/model/src/helpers/struct-generator/additional-properties.ts b/generators/swift/model/src/helpers/struct-generator/additional-properties.ts new file mode 100644 index 000000000000..591c142e1772 --- /dev/null +++ b/generators/swift/model/src/helpers/struct-generator/additional-properties.ts @@ -0,0 +1,40 @@ +import { Referencer } from "@fern-api/swift-base"; +import { swift } from "@fern-api/swift-codegen"; +import { StructGenerator } from "./StructGenerator"; + +export interface AdditionalPropertiesMetadata { + /** + * The name of the property that will be used to store additional properties that are not explicitly defined in the schema. + */ + propertyName: string; + swiftType: swift.TypeReference; +} + +export function computeAdditionalPropertiesMetadata(generatorArgs: StructGenerator.Args, referencer: Referencer) { + const { + constantPropertyDefinitions, + dataPropertyDefinitions, + additionalProperties: hasAdditionalProperties + } = generatorArgs; + + if (!hasAdditionalProperties) { + return null; + } + + const otherPropertyNames = [ + ...constantPropertyDefinitions.map((p) => p.unsafeName), + ...dataPropertyDefinitions.map((p) => p.unsafeName) + ]; + const otherPropertyNamesSet = new Set(otherPropertyNames); + let propertyName = "additionalProperties"; + while (otherPropertyNamesSet.has(propertyName)) { + propertyName = "_" + propertyName; + } + return { + propertyName, + swiftType: swift.TypeReference.dictionary( + referencer.referenceSwiftType("String"), + referencer.referenceAsIsType("JSONValue") + ) + }; +} diff --git a/generators/swift/model/src/helpers/struct-generator/index.ts b/generators/swift/model/src/helpers/struct-generator/index.ts index 3a30228e444f..ec13ee4e1abb 100644 --- a/generators/swift/model/src/helpers/struct-generator/index.ts +++ b/generators/swift/model/src/helpers/struct-generator/index.ts @@ -1,2 +1 @@ -export { LocalContext } from "./LocalContext"; export { StructGenerator } from "./StructGenerator"; diff --git a/generators/swift/model/src/helpers/struct-generator/literal-enums.ts b/generators/swift/model/src/helpers/struct-generator/literal-enums.ts new file mode 100644 index 000000000000..a88b0054561e --- /dev/null +++ b/generators/swift/model/src/helpers/struct-generator/literal-enums.ts @@ -0,0 +1,15 @@ +import { swift } from "@fern-api/swift-codegen"; +import { LiteralEnumGenerator } from "../../literal"; +import { StructGenerator } from "./StructGenerator"; + +export function generateStringLiteralEnums(generatorArgs: StructGenerator.Args): swift.EnumWithRawValues[] { + const { symbol, context } = generatorArgs; + const registeredEnums = context.project.nameRegistry.getAllNestedLiteralEnumSymbolsOrThrow(symbol); + return registeredEnums.map(({ symbol, literalValue }) => { + const literalEnumGenerator = new LiteralEnumGenerator({ + name: symbol.name, + literalValue + }); + return literalEnumGenerator.generate(); + }); +} diff --git a/generators/swift/model/src/object/ObjectGenerator.ts b/generators/swift/model/src/object/ObjectGenerator.ts index fa0ebb0ad4c6..e74a91b48c79 100644 --- a/generators/swift/model/src/object/ObjectGenerator.ts +++ b/generators/swift/model/src/object/ObjectGenerator.ts @@ -6,7 +6,7 @@ import { ModelGeneratorContext } from "../ModelGeneratorContext"; export declare namespace ObjectGenerator { interface Args { - name: string; + symbol: swift.Symbol; properties: (ObjectProperty | InlinedRequestBodyProperty)[]; extendedProperties?: ObjectProperty[]; docsContent?: string; @@ -15,14 +15,14 @@ export declare namespace ObjectGenerator { } export class ObjectGenerator { - private readonly name: string; + private readonly symbol: swift.Symbol; private readonly properties: (ObjectProperty | InlinedRequestBodyProperty)[]; private readonly extendedProperties: ObjectProperty[]; private readonly docsContent?: string; private readonly context: ModelGeneratorContext; - public constructor({ name, properties, extendedProperties, docsContent, context }: ObjectGenerator.Args) { - this.name = name; + public constructor({ symbol, properties, extendedProperties, docsContent, context }: ObjectGenerator.Args) { + this.symbol = symbol; this.properties = properties; this.extendedProperties = extendedProperties ?? []; this.docsContent = docsContent; @@ -35,7 +35,7 @@ export class ObjectGenerator { public generateStructForTypeDeclaration(): swift.Struct { return new StructGenerator({ - name: this.name, + symbol: this.symbol, constantPropertyDefinitions: [], dataPropertyDefinitions: [...this.extendedProperties, ...this.properties].map((p) => ({ unsafeName: sanitizeSelf(p.name.name.camelCase.unsafeName), diff --git a/generators/swift/model/src/object/__test__/object-generator.test.ts b/generators/swift/model/src/object/__test__/object-generator.test.ts index 67980caf1f36..934701bbabb0 100644 --- a/generators/swift/model/src/object/__test__/object-generator.test.ts +++ b/generators/swift/model/src/object/__test__/object-generator.test.ts @@ -29,12 +29,15 @@ function pathToDefinition(testDefinitionName: string) { describe("ObjectGenerator", () => { it("correctly generates nested enums for duplicate string literal values", async () => { const context = await createSampleGeneratorContext(pathToDefinition("duplicate-string-literals")); + const moduleName = "DuplicateStringLiterals"; const objectName = "ObjectWithDuplicateStringLiterals"; - const declaration = getObjectTypeDeclarationOrThrow(context, objectName); + const objectTypeDeclaration = getObjectTypeDeclarationOrThrow(context, objectName); const generator = new ObjectGenerator({ - name: objectName, - properties: declaration.properties, - extendedProperties: declaration.extendedProperties, + symbol: swift.Symbol.create(`${moduleName}.${objectName}`, objectName, { + type: "struct" + }), + properties: objectTypeDeclaration.properties, + extendedProperties: objectTypeDeclaration.extendedProperties, context }); const struct = generator.generate(); @@ -43,12 +46,15 @@ describe("ObjectGenerator", () => { it(`ensures that the special 'CodingKeys' enum does not collide with other string literal enums`, async () => { const context = await createSampleGeneratorContext(pathToDefinition("coding-keys-literal")); + const moduleName = "CodingKeysLiteral"; const objectName = "ObjectWithCodingKeysLiteral"; - const declaration = getObjectTypeDeclarationOrThrow(context, objectName); + const objectTypeDeclaration = getObjectTypeDeclarationOrThrow(context, objectName); const generator = new ObjectGenerator({ - name: objectName, - properties: declaration.properties, - extendedProperties: declaration.extendedProperties, + symbol: swift.Symbol.create(`${moduleName}.${objectName}`, objectName, { + type: "struct" + }), + properties: objectTypeDeclaration.properties, + extendedProperties: objectTypeDeclaration.extendedProperties, context }); const object = generator.generate(); @@ -57,12 +63,15 @@ describe("ObjectGenerator", () => { it(`correctly generates literals in container types`, async () => { const context = await createSampleGeneratorContext(pathToDefinition("literals-in-container-types")); + const moduleName = "LiteralsInContainerTypes"; const objectName = "ObjectWithLiteralsInContainerTypes"; - const declaration = getObjectTypeDeclarationOrThrow(context, objectName); + const objectTypeDeclaration = getObjectTypeDeclarationOrThrow(context, objectName); const generator = new ObjectGenerator({ - name: objectName, - properties: declaration.properties, - extendedProperties: declaration.extendedProperties, + symbol: swift.Symbol.create(`${moduleName}.${objectName}`, objectName, { + type: "struct" + }), + properties: objectTypeDeclaration.properties, + extendedProperties: objectTypeDeclaration.extendedProperties, context }); const object = generator.generate(); @@ -71,14 +80,17 @@ describe("ObjectGenerator", () => { it(`correctly handles name conflicts between nested types and schema types`, async () => { const context = await createSampleGeneratorContext(pathToDefinition("nested-type-collision-with-schema-type")); - + const moduleName = "NestedTypeCollisionWithSchemaType"; const fileComponents: swift.FileComponent[] = []; for (const declaration of Object.values(context.ir.types)) { declaration.shape._visit({ object: (otd) => { + const objectName = declaration.name.name.pascalCase.unsafeName; const generator = new ObjectGenerator({ - name: declaration.name.name.pascalCase.unsafeName, + symbol: swift.Symbol.create(`${moduleName}.${objectName}`, objectName, { + type: "struct" + }), properties: otd.properties, extendedProperties: otd.extendedProperties, context diff --git a/generators/swift/model/src/object/__test__/snapshots/ObjectWithCodingKeysLiteral.swift b/generators/swift/model/src/object/__test__/snapshots/ObjectWithCodingKeysLiteral.swift index 5c3e105d61e8..b375c99f97c2 100644 --- a/generators/swift/model/src/object/__test__/snapshots/ObjectWithCodingKeysLiteral.swift +++ b/generators/swift/model/src/object/__test__/snapshots/ObjectWithCodingKeysLiteral.swift @@ -38,14 +38,14 @@ public struct ObjectWithCodingKeysLiteral: Codable, Hashable, Sendable { try container.encode(self.literalField2, forKey: .literalField2) } - public enum CodingKeysLiteral: String, Codable, Hashable, CaseIterable, Sendable { - case codingKeys = "CodingKeys" - } - public enum CodingKeysEnum: String, Codable, Hashable, CaseIterable, Sendable { case codingKeys } + public enum CodingKeysLiteral: String, Codable, Hashable, CaseIterable, Sendable { + case codingKeys = "CodingKeys" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case field1 diff --git a/generators/swift/model/src/object/__test__/snapshots/ObjectWithDuplicateStringLiterals.swift b/generators/swift/model/src/object/__test__/snapshots/ObjectWithDuplicateStringLiterals.swift index 9869852425a0..4c84761e6db0 100644 --- a/generators/swift/model/src/object/__test__/snapshots/ObjectWithDuplicateStringLiterals.swift +++ b/generators/swift/model/src/object/__test__/snapshots/ObjectWithDuplicateStringLiterals.swift @@ -52,14 +52,14 @@ public struct ObjectWithDuplicateStringLiterals: Codable, Hashable, Sendable { case usa } - public enum UsaLiteral: String, Codable, Hashable, CaseIterable, Sendable { - case usa = "USA" - } - public enum UsaEnum: String, Codable, Hashable, CaseIterable, Sendable { case usa = "Usa" } + public enum UsaLiteral: String, Codable, Hashable, CaseIterable, Sendable { + case usa = "USA" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case field1 diff --git a/generators/swift/model/src/union/DiscriminatedUnionGenerator.ts b/generators/swift/model/src/union/DiscriminatedUnionGenerator.ts index 745805f2ee2a..cdc972f18238 100644 --- a/generators/swift/model/src/union/DiscriminatedUnionGenerator.ts +++ b/generators/swift/model/src/union/DiscriminatedUnionGenerator.ts @@ -1,13 +1,13 @@ import { assertNever, noop } from "@fern-api/core-utils"; -import { EnumWithAssociatedValues, sanitizeSelf, swift } from "@fern-api/swift-codegen"; -import { ObjectProperty, TypeId, UnionTypeDeclaration } from "@fern-fern/ir-sdk/api"; - +import { Referencer } from "@fern-api/swift-base"; +import { sanitizeSelf, swift } from "@fern-api/swift-codegen"; +import { UnionTypeDeclaration } from "@fern-fern/ir-sdk/api"; import { StructGenerator } from "../helpers/struct-generator/StructGenerator"; import { ModelGeneratorContext } from "../ModelGeneratorContext"; export declare namespace DiscriminatedUnionGenerator { interface Args { - name: string; + symbol: swift.Symbol; unionTypeDeclaration: UnionTypeDeclaration; docsContent?: string; context: ModelGeneratorContext; @@ -15,25 +15,31 @@ export declare namespace DiscriminatedUnionGenerator { } export class DiscriminatedUnionGenerator { - private readonly name: string; + private readonly symbol: swift.Symbol; private readonly unionTypeDeclaration: UnionTypeDeclaration; private readonly docsContent?: string; private readonly context: ModelGeneratorContext; + private readonly referencer: Referencer; - public constructor({ name, unionTypeDeclaration, docsContent, context }: DiscriminatedUnionGenerator.Args) { - this.name = name; + public constructor({ symbol, unionTypeDeclaration, docsContent, context }: DiscriminatedUnionGenerator.Args) { + this.symbol = symbol; this.unionTypeDeclaration = unionTypeDeclaration; this.docsContent = docsContent; this.context = context; + this.referencer = context.createReferencer(symbol); } public generate(): swift.EnumWithAssociatedValues { return this.generateEnumForTypeDeclaration(); } + private getAllVariants() { + return this.context.project.nameRegistry.getAllDiscriminatedUnionVariantsOrThrow(this.symbol); + } + private generateEnumForTypeDeclaration(): swift.EnumWithAssociatedValues { return swift.enumWithAssociatedValues({ - name: this.name, + name: this.symbol.name, accessLevel: swift.AccessLevel.Public, conformances: [swift.Protocol.Codable, swift.Protocol.Hashable, swift.Protocol.Sendable], cases: this.generateCasesForTypeDeclaration(), @@ -45,15 +51,11 @@ export class DiscriminatedUnionGenerator { } private generateCasesForTypeDeclaration(): swift.EnumWithAssociatedValues.Case[] { - return this.unionTypeDeclaration.types.map((singleUnionType) => { - const caseName = EnumWithAssociatedValues.sanitizeToCamelCase(singleUnionType.discriminantValue.wireValue); - const structName = EnumWithAssociatedValues.sanitizeToPascalCase( - singleUnionType.discriminantValue.wireValue - ); + return this.getAllVariants().map((variant) => { return { - unsafeName: caseName, - associatedValue: [swift.Type.custom(structName)], - docs: singleUnionType.docs ? swift.docComment({ summary: singleUnionType.docs }) : undefined + unsafeName: variant.caseName, + associatedValue: [swift.TypeReference.symbol(variant.symbolName)], + docs: variant.docsContent ? swift.docComment({ summary: variant.docsContent }) : undefined }; }); } @@ -88,7 +90,7 @@ export class DiscriminatedUnionGenerator { arguments_: [ swift.functionArgument({ value: swift.Expression.memberAccess({ - target: swift.Type.string(), + target: this.referencer.referenceSwiftType("String"), memberName: "self" }) }), @@ -104,24 +106,18 @@ export class DiscriminatedUnionGenerator { }), swift.Statement.switch({ target: swift.Expression.reference("discriminant"), - cases: this.unionTypeDeclaration.types.map((singleUnionType) => { - const caseName = EnumWithAssociatedValues.sanitizeToCamelCase( - singleUnionType.discriminantValue.wireValue - ); - const structName = EnumWithAssociatedValues.sanitizeToPascalCase( - singleUnionType.discriminantValue.wireValue - ); + cases: this.getAllVariants().map((variant) => { return { - pattern: swift.Expression.stringLiteral(singleUnionType.discriminantValue.wireValue), + pattern: swift.Expression.stringLiteral(variant.discriminantWireValue), body: [ swift.Statement.selfAssignment( swift.Expression.contextualMethodCall({ - methodName: caseName, + methodName: variant.caseName, arguments_: [ swift.functionArgument({ value: swift.Expression.try( swift.Expression.structInitialization({ - unsafeName: structName, + unsafeName: variant.symbolName, arguments_: [ swift.functionArgument({ label: "from", @@ -179,7 +175,7 @@ export class DiscriminatedUnionGenerator { swift.functionParameter({ argumentLabel: "from", unsafeName: "decoder", - type: swift.Type.custom("Decoder") + type: this.referencer.referenceSwiftType("Decoder") }) ], body: swift.CodeBlock.withStatements(bodyStatements) @@ -198,21 +194,18 @@ export class DiscriminatedUnionGenerator { swift.functionParameter({ argumentLabel: "to", unsafeName: "encoder", - type: swift.Type.custom("Encoder") + type: this.referencer.referenceSwiftType("Encoder") }) ], throws: true, - returnType: swift.Type.void(), + returnType: this.referencer.referenceSwiftType("Void"), body: swift.CodeBlock.withStatements([ swift.Statement.switch({ target: swift.Expression.rawValue("self"), - cases: this.unionTypeDeclaration.types.map((singleUnionType) => { - const caseName = EnumWithAssociatedValues.sanitizeToCamelCase( - singleUnionType.discriminantValue.wireValue - ); + cases: this.getAllVariants().map((variant) => { return { pattern: swift.Pattern.enumCaseValueBinding({ - caseName: caseName, + caseName: variant.caseName, referenceName: "data", declarationType: swift.DeclarationType.Let }), @@ -243,12 +236,17 @@ export class DiscriminatedUnionGenerator { const variantStructs = this.unionTypeDeclaration.types.map((singleUnionType) => { const constantPropertyDefinitions: StructGenerator.ConstantPropertyDefinition[] = []; const dataPropertyDefinitions: StructGenerator.DataPropertyDefinition[] = []; + const variantSymbol = this.context.project.nameRegistry.getDiscriminatedUnionVariantSymbolOrThrow( + this.symbol, + singleUnionType.discriminantValue.wireValue + ); + const referencer = this.context.createReferencer(variantSymbol); if (singleUnionType.shape.propertiesType === "singleProperty") { constantPropertyDefinitions.push({ unsafeName: sanitizeSelf(this.unionTypeDeclaration.discriminant.name.camelCase.unsafeName), rawName: this.unionTypeDeclaration.discriminant.wireValue, - type: swift.Type.string(), + type: referencer.referenceSwiftType("String"), value: swift.Expression.stringLiteral(singleUnionType.discriminantValue.wireValue) }); dataPropertyDefinitions.push({ @@ -257,11 +255,13 @@ export class DiscriminatedUnionGenerator { type: singleUnionType.shape.type }); } else if (singleUnionType.shape.propertiesType === "samePropertiesAsObject") { - const variantProperties = this.getPropertiesOfVariant(singleUnionType.shape.typeId); + const variantProperties = this.context.getPropertiesOfDiscriminatedUnionVariant( + singleUnionType.shape.typeId + ); constantPropertyDefinitions.push({ unsafeName: sanitizeSelf(this.unionTypeDeclaration.discriminant.name.camelCase.unsafeName), rawName: this.unionTypeDeclaration.discriminant.wireValue, - type: swift.Type.string(), + type: referencer.referenceSwiftType("String"), value: swift.Expression.stringLiteral(singleUnionType.discriminantValue.wireValue) }); dataPropertyDefinitions.push( @@ -279,7 +279,7 @@ export class DiscriminatedUnionGenerator { } return new StructGenerator({ - name: EnumWithAssociatedValues.sanitizeToPascalCase(singleUnionType.discriminantValue.wireValue), + symbol: variantSymbol, constantPropertyDefinitions, dataPropertyDefinitions, additionalProperties: true, @@ -291,18 +291,6 @@ export class DiscriminatedUnionGenerator { return [...variantStructs, this.generateCodingKeysEnum()]; } - private getPropertiesOfVariant(typeId: TypeId): ObjectProperty[] { - const typeDeclaration = this.context.getTypeDeclarationOrThrow(typeId); - return typeDeclaration.shape._visit({ - alias: () => [], - enum: () => [], - object: (otd) => [...(otd.extendedProperties ?? []), ...otd.properties], - union: () => [], - undiscriminatedUnion: () => [], - _other: () => [] - }); - } - private generateCodingKeysEnum(): swift.EnumWithRawValues { return swift.enumWithRawValues({ name: "CodingKeys", diff --git a/generators/swift/model/src/union/UndiscriminatedUnionGenerator.ts b/generators/swift/model/src/union/UndiscriminatedUnionGenerator.ts index be8d59e67f3d..15ee586459cc 100644 --- a/generators/swift/model/src/union/UndiscriminatedUnionGenerator.ts +++ b/generators/swift/model/src/union/UndiscriminatedUnionGenerator.ts @@ -1,12 +1,13 @@ import { assertDefined } from "@fern-api/core-utils"; +import { Referencer } from "@fern-api/swift-base"; import { swift } from "@fern-api/swift-codegen"; import { UndiscriminatedUnionTypeDeclaration } from "@fern-fern/ir-sdk/api"; -import { uniqWith } from "lodash-es"; +import { LiteralEnumGenerator } from "../literal"; import { ModelGeneratorContext } from "../ModelGeneratorContext"; export declare namespace UndiscriminatedUnionGenerator { interface Args { - name: string; + symbol: swift.Symbol; typeDeclaration: UndiscriminatedUnionTypeDeclaration; docsContent?: string; context: ModelGeneratorContext; @@ -14,40 +15,47 @@ export declare namespace UndiscriminatedUnionGenerator { } export class UndiscriminatedUnionGenerator { - private readonly name: string; + private readonly symbol: swift.Symbol; private readonly typeDeclaration: UndiscriminatedUnionTypeDeclaration; private readonly docsContent?: string; private readonly context: ModelGeneratorContext; + private readonly referencer: Referencer; - public constructor({ name, typeDeclaration, docsContent, context }: UndiscriminatedUnionGenerator.Args) { - this.name = name; + public constructor({ symbol, typeDeclaration, docsContent, context }: UndiscriminatedUnionGenerator.Args) { + this.referencer = context.createReferencer(symbol); + this.symbol = symbol; this.typeDeclaration = typeDeclaration; this.docsContent = docsContent; this.context = context; } + private getAllVariants() { + return this.context.project.nameRegistry.getAllUndiscriminatedUnionVariantsOrThrow(this.symbol); + } + public generate(): swift.EnumWithAssociatedValues { return this.generateEnumForTypeDeclaration(); } private generateEnumForTypeDeclaration(): swift.EnumWithAssociatedValues { return swift.enumWithAssociatedValues({ - name: this.name, + name: this.symbol.name, accessLevel: swift.AccessLevel.Public, conformances: [swift.Protocol.Codable, swift.Protocol.Hashable, swift.Protocol.Sendable], cases: this.generateCasesForTypeDeclaration(), initializers: this.generateInitializers(), methods: this.generateMethods(), + nestedTypes: this.generateNestedTypes(), docs: this.docsContent ? swift.docComment({ summary: this.docsContent }) : undefined }); } private generateCasesForTypeDeclaration(): swift.EnumWithAssociatedValues.Case[] { - return this.getDistinctMembers().map((member) => { + return this.getAllVariants().map((variant) => { return { - unsafeName: member.swiftType.toCaseName(), - associatedValue: [member.swiftType], - docs: member.docsContent ? swift.docComment({ summary: member.docsContent }) : undefined + unsafeName: variant.caseName, + associatedValue: [variant.swiftType], + docs: variant.docsContent ? swift.docComment({ summary: variant.docsContent }) : undefined }; }); } @@ -64,7 +72,7 @@ export class UndiscriminatedUnionGenerator { swift.functionParameter({ argumentLabel: "from", unsafeName: "decoder", - type: swift.Type.custom("Decoder") + type: this.referencer.referenceSwiftType("Decoder") }) ], body: swift.CodeBlock.withStatements([ @@ -83,7 +91,7 @@ export class UndiscriminatedUnionGenerator { } private generateIfStatementForDecodingAttempts(): swift.Statement { - const distinctMembers = this.getDistinctMembers(); + const distinctMembers = this.getAllVariants(); const memberDecodeAttempts = distinctMembers.map((member) => { const decodeStatement = swift.Statement.constantDeclaration({ unsafeName: "value", @@ -105,7 +113,7 @@ export class UndiscriminatedUnionGenerator { }); const selfAssignment = swift.Statement.selfAssignment( swift.Expression.contextualMethodCall({ - methodName: member.swiftType.toCaseName(), + methodName: member.caseName, arguments_: [ swift.functionArgument({ value: swift.Expression.reference("value") @@ -126,7 +134,6 @@ export class UndiscriminatedUnionGenerator { }), swift.functionArgument({ label: "debugDescription", - // TODO(kafkas): Add more descriptive error message. We can perhaps try to decode as JSONValue and add the result to the error message. value: swift.Expression.stringLiteral(`Unexpected value.`) }) ], @@ -154,7 +161,7 @@ export class UndiscriminatedUnionGenerator { } private generateEncodeMethod(): swift.Method { - const distinctMembers = this.getDistinctMembers(); + const distinctMembers = this.getAllVariants(); return swift.method({ unsafeName: "encode", accessLevel: swift.AccessLevel.Public, @@ -162,11 +169,11 @@ export class UndiscriminatedUnionGenerator { swift.functionParameter({ argumentLabel: "to", unsafeName: "encoder", - type: swift.Type.custom("Encoder") + type: this.referencer.referenceSwiftType("Encoder") }) ], throws: true, - returnType: swift.Type.void(), + returnType: this.referencer.referenceSwiftType("Void"), body: swift.CodeBlock.withStatements([ swift.Statement.variableDeclaration({ unsafeName: "container", @@ -180,7 +187,7 @@ export class UndiscriminatedUnionGenerator { cases: distinctMembers.map((member) => { return { pattern: swift.Pattern.enumCaseValueBinding({ - caseName: member.swiftType.toCaseName(), + caseName: member.caseName, referenceName: "value", declarationType: swift.DeclarationType.Let }), @@ -206,11 +213,17 @@ export class UndiscriminatedUnionGenerator { }); } - private getDistinctMembers(): { swiftType: swift.Type; docsContent?: string }[] { - const members = this.typeDeclaration.members.map((member) => ({ - docsContent: member.docs, - swiftType: this.context.getSwiftTypeForTypeReference(member.type) - })); - return uniqWith(members, (a, b) => a.swiftType.equals(b.swiftType)); + private generateNestedTypes(): (swift.Struct | swift.EnumWithRawValues)[] { + const nestedTypes: (swift.Struct | swift.EnumWithRawValues)[] = []; + this.context.project.nameRegistry + .getAllNestedLiteralEnumSymbolsOrThrow(this.symbol) + .forEach(({ symbol, literalValue }) => { + const literalEnumGenerator = new LiteralEnumGenerator({ + name: symbol.name, + literalValue + }); + nestedTypes.push(literalEnumGenerator.generate()); + }); + return nestedTypes; } } diff --git a/generators/swift/model/src/union/__test__/discriminated-union-generator.test.ts b/generators/swift/model/src/union/__test__/discriminated-union-generator.test.ts index a8f7f1f71b4d..4b85aa5226de 100644 --- a/generators/swift/model/src/union/__test__/discriminated-union-generator.test.ts +++ b/generators/swift/model/src/union/__test__/discriminated-union-generator.test.ts @@ -1,4 +1,5 @@ import { resolve } from "node:path"; +import { swift } from "@fern-api/swift-codegen"; import { ModelGeneratorContext } from "../../ModelGeneratorContext"; import { createSampleGeneratorContext } from "../../test-utils/createSampleGeneratorContext"; import { DiscriminatedUnionGenerator } from "../DiscriminatedUnionGenerator"; @@ -29,10 +30,13 @@ describe("DiscriminatedUnionGenerator", () => { const context = await createSampleGeneratorContext( pathToDefinition("discriminant-values-with-special-characters") ); + const moduleName = "DiscriminantValuesWithSpecialCharacters"; const unionName = "UnionWithSpecialCharacters"; const declaration = getUnionTypeDeclarationOrThrow(context, unionName); const generator = new DiscriminatedUnionGenerator({ - name: unionName, + symbol: swift.Symbol.create(`${moduleName}.${unionName}`, unionName, { + type: "enum-with-associated-values" + }), unionTypeDeclaration: declaration, context }); diff --git a/generators/swift/model/src/union/__test__/snapshots/UnionWithSpecialCharacters.swift b/generators/swift/model/src/union/__test__/snapshots/UnionWithSpecialCharacters.swift index 5cc372972f84..2cc43ad4c681 100644 --- a/generators/swift/model/src/union/__test__/snapshots/UnionWithSpecialCharacters.swift +++ b/generators/swift/model/src/union/__test__/snapshots/UnionWithSpecialCharacters.swift @@ -1,22 +1,22 @@ public enum UnionWithSpecialCharacters: Codable, Hashable, Sendable { case abc(Abc) + case abcdEfgh(AbcdEfgh) + case camelCase(CamelCase) + case dataPoint(DataPoint) + case kebabCaseValue(KebabCaseValue) + case leadingSpaces(LeadingSpaces) + case mixed123Values456(Mixed123Values456) case oneAbc(OneAbc) - case twelveAbc(TwelveAbc) case oneHundredTwentyThreeAbc(OneHundredTwentyThreeAbc) + case pascalCase(PascalCase) case sevenAgent(SevenAgent) - case abcdEfgh(AbcdEfgh) - case dataPoint(DataPoint) - case userName(UserName) case snakeCaseValue(SnakeCaseValue) - case kebabCaseValue(KebabCaseValue) + case spacesInTheMiddle(SpacesInTheMiddle) case special(Special) - case leadingSpaces(LeadingSpaces) case trailingSpaces(TrailingSpaces) - case spacesInTheMiddle(SpacesInTheMiddle) + case twelveAbc(TwelveAbc) case uppercase(Uppercase) - case camelCase(CamelCase) - case pascalCase(PascalCase) - case mixed123Values456(Mixed123Values456) + case userName(UserName) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -24,40 +24,40 @@ public enum UnionWithSpecialCharacters: Codable, Hashable, Sendable { switch discriminant { case "abc": self = .abc(try Abc(from: decoder)) + case "abcd-efgh": + self = .abcdEfgh(try AbcdEfgh(from: decoder)) + case "camelCase": + self = .camelCase(try CamelCase(from: decoder)) + case "data@point": + self = .dataPoint(try DataPoint(from: decoder)) + case "kebab-case-value": + self = .kebabCaseValue(try KebabCaseValue(from: decoder)) + case " leading-spaces": + self = .leadingSpaces(try LeadingSpaces(from: decoder)) + case "mixed123Values456": + self = .mixed123Values456(try Mixed123Values456(from: decoder)) case "1abc": self = .oneAbc(try OneAbc(from: decoder)) - case "12abc": - self = .twelveAbc(try TwelveAbc(from: decoder)) case "123abc": self = .oneHundredTwentyThreeAbc(try OneHundredTwentyThreeAbc(from: decoder)) + case "PascalCase": + self = .pascalCase(try PascalCase(from: decoder)) case "007agent": self = .sevenAgent(try SevenAgent(from: decoder)) - case "abcd-efgh": - self = .abcdEfgh(try AbcdEfgh(from: decoder)) - case "data@point": - self = .dataPoint(try DataPoint(from: decoder)) - case "user#name": - self = .userName(try UserName(from: decoder)) case "snake_case_value": self = .snakeCaseValue(try SnakeCaseValue(from: decoder)) - case "kebab-case-value": - self = .kebabCaseValue(try KebabCaseValue(from: decoder)) + case "spaces in the middle": + self = .spacesInTheMiddle(try SpacesInTheMiddle(from: decoder)) case "!@#$%special": self = .special(try Special(from: decoder)) - case " leading-spaces": - self = .leadingSpaces(try LeadingSpaces(from: decoder)) case "trailing-spaces ": self = .trailingSpaces(try TrailingSpaces(from: decoder)) - case "spaces in the middle": - self = .spacesInTheMiddle(try SpacesInTheMiddle(from: decoder)) + case "12abc": + self = .twelveAbc(try TwelveAbc(from: decoder)) case "UPPERCASE": self = .uppercase(try Uppercase(from: decoder)) - case "camelCase": - self = .camelCase(try CamelCase(from: decoder)) - case "PascalCase": - self = .pascalCase(try PascalCase(from: decoder)) - case "mixed123Values456": - self = .mixed123Values456(try Mixed123Values456(from: decoder)) + case "user#name": + self = .userName(try UserName(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -72,39 +72,39 @@ public enum UnionWithSpecialCharacters: Codable, Hashable, Sendable { switch self { case .abc(let data): try data.encode(to: encoder) - case .oneAbc(let data): + case .abcdEfgh(let data): try data.encode(to: encoder) - case .twelveAbc(let data): + case .camelCase(let data): try data.encode(to: encoder) - case .oneHundredTwentyThreeAbc(let data): + case .dataPoint(let data): try data.encode(to: encoder) - case .sevenAgent(let data): + case .kebabCaseValue(let data): try data.encode(to: encoder) - case .abcdEfgh(let data): + case .leadingSpaces(let data): try data.encode(to: encoder) - case .dataPoint(let data): + case .mixed123Values456(let data): try data.encode(to: encoder) - case .userName(let data): + case .oneAbc(let data): + try data.encode(to: encoder) + case .oneHundredTwentyThreeAbc(let data): + try data.encode(to: encoder) + case .pascalCase(let data): + try data.encode(to: encoder) + case .sevenAgent(let data): try data.encode(to: encoder) case .snakeCaseValue(let data): try data.encode(to: encoder) - case .kebabCaseValue(let data): + case .spacesInTheMiddle(let data): try data.encode(to: encoder) case .special(let data): try data.encode(to: encoder) - case .leadingSpaces(let data): - try data.encode(to: encoder) case .trailingSpaces(let data): try data.encode(to: encoder) - case .spacesInTheMiddle(let data): + case .twelveAbc(let data): try data.encode(to: encoder) case .uppercase(let data): try data.encode(to: encoder) - case .camelCase(let data): - try data.encode(to: encoder) - case .pascalCase(let data): - try data.encode(to: encoder) - case .mixed123Values456(let data): + case .userName(let data): try data.encode(to: encoder) } } diff --git a/generators/swift/sdk/src/SdkGeneratorCli.ts b/generators/swift/sdk/src/SdkGeneratorCli.ts index 7b348205cf84..bbb7a646079d 100644 --- a/generators/swift/sdk/src/SdkGeneratorCli.ts +++ b/generators/swift/sdk/src/SdkGeneratorCli.ts @@ -170,8 +170,9 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { + const symbol = context.project.nameRegistry.getSubClientSymbolOrThrow(subpackageId); const subclientGenerator = new SubClientGenerator({ - clientName: context.project.srcSymbolRegistry.getSubClientSymbolOrThrow(subpackageId), + symbol, subpackage, sdkGeneratorContext: context }); @@ -186,10 +187,10 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { service.endpoints.forEach((endpoint) => { if (endpoint.requestBody?.type === "inlinedRequestBody") { + const symbol = context.project.nameRegistry.getRequestTypeSymbolOrThrow( + endpoint.id, + endpoint.requestBody.name.pascalCase.unsafeName + ); const generator = new ObjectGenerator({ - name: context.project.srcSymbolRegistry.getRequestTypeSymbolOrThrow( - endpoint.id, - endpoint.requestBody.name.pascalCase.unsafeName - ), + symbol, properties: endpoint.requestBody.properties, extendedProperties: endpoint.requestBody.extendedProperties, docsContent: endpoint.requestBody.docs, @@ -217,15 +219,21 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli p._visit({ @@ -236,7 +244,7 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli p !== null); const struct = swift.struct({ - name: context.project.srcSymbolRegistry.getRequestTypeSymbolOrThrow( - endpoint.id, - endpoint.requestBody.name.pascalCase.unsafeName - ), + name: requestTypeSymbol.name, accessLevel: "public", properties, initializers: [ @@ -285,7 +295,10 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli p !== null); const requestStructExtension = swift.extension({ - name: context.project.srcSymbolRegistry.getFullyQualifiedRequestTypeSymbolOrThrow( - endpoint.id, - endpoint.requestBody.name.pascalCase.unsafeName - ), + name: context.project.nameRegistry.referenceFromSourceModuleScope(requestTypeSymbol.id), conformances: [swift.Protocol.MultipartFormDataConvertible], computedProperties: [ swift.computedProperty({ unsafeName: "multipartFormFields", - type: swift.Type.array(swift.Type.custom("MultipartFormField")), + type: swift.TypeReference.array( + referencerFromRequestType.referenceAsIsType("MultipartFormField") + ), body: swift.Expression.arrayLiteral({ elements: multipartFormFields, multiline: true @@ -388,7 +400,7 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { - const name = context.project.srcSymbolRegistry.getSchemaTypeSymbolOrThrow(typeId); + const symbol = context.project.nameRegistry.getSchemaTypeSymbolOrThrow(typeId); if (atd.aliasOf.type === "container" && atd.aliasOf.container.type === "literal") { // Swift does not support literal aliases, so we need to generate a custom type for them const literalType = atd.aliasOf.container.literal; if (literalType.type === "string") { const generator = new LiteralEnumGenerator({ - name, + name: symbol.name, literalValue: literalType.string, docsContent: typeDeclaration.docs }); @@ -418,16 +430,15 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { + const symbol = context.project.nameRegistry.getSchemaTypeSymbolOrThrow(typeId); const generator = new StringEnumGenerator({ - name: context.project.srcSymbolRegistry.getSchemaTypeSymbolOrThrow(typeId), + name: symbol.name, source: { type: "ir", enumTypeDeclaration: etd }, docsContent: typeDeclaration.docs }); @@ -463,8 +475,9 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { + const symbol = context.project.nameRegistry.getSchemaTypeSymbolOrThrow(typeId); const generator = new ObjectGenerator({ - name: context.project.srcSymbolRegistry.getSchemaTypeSymbolOrThrow(typeId), + symbol, properties: otd.properties, extendedProperties: otd.extendedProperties, docsContent: typeDeclaration.docs, @@ -478,8 +491,9 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { + const symbol = context.project.nameRegistry.getSchemaTypeSymbolOrThrow(typeId); const generator = new UndiscriminatedUnionGenerator({ - name: context.project.srcSymbolRegistry.getSchemaTypeSymbolOrThrow(typeId), + symbol, typeDeclaration: uutd, docsContent: typeDeclaration.docs, context @@ -492,8 +506,9 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { + const symbol = context.project.nameRegistry.getSchemaTypeSymbolOrThrow(typeId); const generator = new DiscriminatedUnionGenerator({ - name: context.project.srcSymbolRegistry.getSchemaTypeSymbolOrThrow(typeId), + symbol, unionTypeDeclaration: utd, docsContent: typeDeclaration.docs, context @@ -511,8 +526,9 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { - const subclientName = context.project.srcSymbolRegistry.getSubClientSymbolOrThrow(subpackageId); - const testSuiteName = context.project.testSymbolRegistry.getWireTestSuiteSymbolOrThrow(subclientName); + const subClientSymbol = context.project.nameRegistry.getSubClientSymbolOrThrow(subpackageId); + const testSuiteSymbol = context.project.nameRegistry.getWireTestSuiteSymbolOrThrow(subClientSymbol.name); const testSuiteGenerator = new WireTestSuiteGenerator({ - suiteName: testSuiteName, - subclientName, + symbol: testSuiteSymbol, + subclientName: subClientSymbol.name, packageOrSubpackage: subpackage, sdkGeneratorContext: context }); @@ -582,7 +599,7 @@ export class SdkGeneratorCLI extends AbstractSwiftGeneratorCli { - const clientName = - this.sdkGeneratorContext.project.srcSymbolRegistry.getSubClientSymbolOrThrow(subpackageId); + const subClientSymbol = + this.sdkGeneratorContext.project.nameRegistry.getSubClientSymbolOrThrow(subpackageId); const property = swift.property({ unsafeName: subpackage.name.camelCase.unsafeName, accessLevel: swift.AccessLevel.Public, declarationType: swift.DeclarationType.Let, - type: swift.Type.custom(clientName) + type: this.referencer.referenceType(subClientSymbol) }); return { property, - clientName + clientName: subClientSymbol.name }; }); } @@ -55,7 +59,7 @@ export class ClientGeneratorContext { unsafeName: name, accessLevel: swift.AccessLevel.Private, declarationType: swift.DeclarationType.Let, - type: swift.Type.custom("HTTPClient") + type: this.referencer.referenceAsIsType("HTTPClient") }), clientName: "HTTPClient" }; diff --git a/generators/swift/sdk/src/generators/client/EndpointMethodGenerator.ts b/generators/swift/sdk/src/generators/client/EndpointMethodGenerator.ts index 2266cc576395..f5cec0e30e81 100644 --- a/generators/swift/sdk/src/generators/client/EndpointMethodGenerator.ts +++ b/generators/swift/sdk/src/generators/client/EndpointMethodGenerator.ts @@ -1,25 +1,33 @@ -import { assertNever } from "@fern-api/core-utils"; +import { assertDefined, assertNever } from "@fern-api/core-utils"; +import { Referencer } from "@fern-api/swift-base"; import { swift } from "@fern-api/swift-codegen"; -import { HttpEndpoint, HttpMethod } from "@fern-fern/ir-sdk/api"; - +import { HttpEndpoint, HttpMethod, TypeReference } from "@fern-fern/ir-sdk/api"; import { SdkGeneratorContext } from "../../SdkGeneratorContext"; import { ClientGeneratorContext } from "./ClientGeneratorContext"; import { formatEndpointPathForSwift } from "./util/format-endpoint-path-for-swift"; -import { getQueryParamCaseName } from "./util/get-query-param-case-name"; import { parseEndpointPath } from "./util/parse-endpoint-path"; export declare namespace EndpointMethodGenerator { interface Args { + parentClassSymbol: swift.Symbol; clientGeneratorContext: ClientGeneratorContext; sdkGeneratorContext: SdkGeneratorContext; } } export class EndpointMethodGenerator { + private readonly parentClassSymbol: swift.Symbol; private readonly clientGeneratorContext: ClientGeneratorContext; private readonly sdkGeneratorContext: SdkGeneratorContext; + private readonly referencer: Referencer; - public constructor({ clientGeneratorContext, sdkGeneratorContext }: EndpointMethodGenerator.Args) { + public constructor({ + parentClassSymbol, + clientGeneratorContext, + sdkGeneratorContext + }: EndpointMethodGenerator.Args) { + this.referencer = sdkGeneratorContext.createReferencer(parentClassSymbol); + this.parentClassSymbol = parentClassSymbol; this.clientGeneratorContext = clientGeneratorContext; this.sdkGeneratorContext = sdkGeneratorContext; } @@ -59,7 +67,7 @@ export class EndpointMethodGenerator { swift.functionParameter({ argumentLabel: pathPart.unsafeNameCamelCase, unsafeName: pathPart.unsafeNameCamelCase, - type: swift.Type.string(), + type: this.referencer.referenceSwiftType("String"), docsContent: pathPart.docs }) ); @@ -67,8 +75,8 @@ export class EndpointMethodGenerator { }); endpoint.headers.forEach((header) => { - const swiftType = this.sdkGeneratorContext.getSwiftTypeForTypeReference(header.valueType); - if (swiftType.nonOptionalType !== "string") { + const swiftType = this.getResolvedSwiftTypeForTypeReference(header.valueType); + if (!this.referencer.resolvesToTheSwiftType(swiftType.nonOptional(), "String")) { return; } params.push( @@ -76,20 +84,23 @@ export class EndpointMethodGenerator { argumentLabel: header.name.name.camelCase.unsafeName, unsafeName: header.name.name.camelCase.unsafeName, type: swiftType, - defaultValue: swiftType.isOptional ? swift.Expression.rawValue("nil") : undefined, + defaultValue: swiftType.variant.type === "optional" ? swift.Expression.rawValue("nil") : undefined, docsContent: header.docs }) ); }); endpoint.queryParameters.forEach((queryParam) => { - const swiftType = this.sdkGeneratorContext.getSwiftTypeForTypeReference(queryParam.valueType); + const swiftType = this.sdkGeneratorContext.getSwiftTypeReferenceFromScope( + queryParam.valueType, + this.parentClassSymbol + ); params.push( swift.functionParameter({ argumentLabel: queryParam.name.name.camelCase.unsafeName, unsafeName: queryParam.name.name.camelCase.unsafeName, type: swiftType, - defaultValue: swiftType.isOptional ? swift.Expression.rawValue("nil") : undefined, + defaultValue: swiftType.variant.type === "optional" ? swift.Expression.rawValue("nil") : undefined, docsContent: queryParam.docs }) ); @@ -101,23 +112,23 @@ export class EndpointMethodGenerator { swift.functionParameter({ argumentLabel: "request", unsafeName: "request", - type: this.sdkGeneratorContext.getSwiftTypeForTypeReference( - endpoint.requestBody.requestBodyType + type: this.sdkGeneratorContext.getSwiftTypeReferenceFromScope( + endpoint.requestBody.requestBodyType, + this.parentClassSymbol ), docsContent: endpoint.requestBody.docs }) ); } else if (endpoint.requestBody.type === "inlinedRequestBody") { - const fullyQualifiedRequestTypeSymbolName = - this.sdkGeneratorContext.project.srcSymbolRegistry.getFullyQualifiedRequestTypeSymbolOrThrow( - endpoint.id, - endpoint.requestBody.name.pascalCase.unsafeName - ); + const requestTypeSymbol = this.sdkGeneratorContext.project.nameRegistry.getRequestTypeSymbolOrThrow( + endpoint.id, + endpoint.requestBody.name.pascalCase.unsafeName + ); params.push( swift.functionParameter({ argumentLabel: "request", unsafeName: "request", - type: swift.Type.custom(fullyQualifiedRequestTypeSymbolName), + type: this.referencer.referenceType(requestTypeSymbol), docsContent: endpoint.requestBody.docs }) ); @@ -126,21 +137,20 @@ export class EndpointMethodGenerator { swift.functionParameter({ argumentLabel: "request", unsafeName: "request", - type: swift.Type.data(), + type: this.referencer.referenceFoundationType("Data"), docsContent: endpoint.requestBody.docs }) ); } else if (endpoint.requestBody.type === "fileUpload") { - const fullyQualifiedRequestTypeSymbolName = - this.sdkGeneratorContext.project.srcSymbolRegistry.getFullyQualifiedRequestTypeSymbolOrThrow( - endpoint.id, - endpoint.requestBody.name.pascalCase.unsafeName - ); + const requestTypeSymbol = this.sdkGeneratorContext.project.nameRegistry.getRequestTypeSymbolOrThrow( + endpoint.id, + endpoint.requestBody.name.pascalCase.unsafeName + ); params.push( swift.functionParameter({ argumentLabel: "request", unsafeName: "request", - type: swift.Type.custom(fullyQualifiedRequestTypeSymbolName), + type: this.referencer.referenceType(requestTypeSymbol), docsContent: endpoint.requestBody.docs }) ); @@ -153,7 +163,7 @@ export class EndpointMethodGenerator { swift.functionParameter({ argumentLabel: "requestOptions", unsafeName: "requestOptions", - type: swift.Type.optional(swift.Type.custom("RequestOptions")), + type: swift.TypeReference.optional(this.referencer.referenceAsIsType("RequestOptions")), defaultValue: swift.Expression.rawValue("nil"), docsContent: "Additional options for configuring the request, such as custom headers or timeout settings." @@ -163,18 +173,19 @@ export class EndpointMethodGenerator { return params; } - private getMethodReturnTypeForEndpoint(endpoint: HttpEndpoint): swift.Type { + private getMethodReturnTypeForEndpoint(endpoint: HttpEndpoint): swift.TypeReference { if (!endpoint.response || !endpoint.response.body) { - return swift.Type.void(); + return this.referencer.referenceSwiftType("Void"); } return endpoint.response.body._visit({ - json: (resp) => this.sdkGeneratorContext.getSwiftTypeForTypeReference(resp.responseBodyType), - fileDownload: () => swift.Type.data(), - text: () => swift.Type.jsonValue(), // TODO(kafkas): Handle text responses - bytes: () => swift.Type.jsonValue(), // TODO(kafkas): Handle bytes responses - streaming: () => swift.Type.jsonValue(), // TODO(kafkas): Handle streaming responses - streamParameter: () => swift.Type.jsonValue(), // TODO(kafkas): Handle stream parameter responses - _other: () => swift.Type.jsonValue() + json: (resp) => + this.sdkGeneratorContext.getSwiftTypeReferenceFromScope(resp.responseBodyType, this.parentClassSymbol), + fileDownload: () => this.referencer.referenceFoundationType("Data"), + text: () => this.referencer.referenceAsIsType("JSONValue"), // TODO(kafkas): Handle text responses + bytes: () => this.referencer.referenceAsIsType("JSONValue"), // TODO(kafkas): Handle bytes responses + streaming: () => this.referencer.referenceAsIsType("JSONValue"), // TODO(kafkas): Handle streaming responses + streamParameter: () => this.referencer.referenceAsIsType("JSONValue"), // TODO(kafkas): Handle stream parameter responses + _other: () => this.referencer.referenceAsIsType("JSONValue") }); } @@ -230,10 +241,10 @@ export class EndpointMethodGenerator { ); } - const validHeaders = endpoint.headers.filter( - (header) => - this.sdkGeneratorContext.getSwiftTypeForTypeReference(header.valueType).nonOptionalType === "string" - ); + const validHeaders = endpoint.headers.filter((header) => { + const swiftType = this.getSwiftTypeForTypeReference(header.valueType); + return this.referencer.resolvesToTheSwiftType(swiftType.nonOptional(), "String"); + }); if (validHeaders.length > 0) { arguments_.push( @@ -259,15 +270,13 @@ export class EndpointMethodGenerator { value: swift.Expression.dictionaryLiteral({ entries: endpoint.queryParameters.map((queryParam) => { const key = swift.Expression.stringLiteral(queryParam.name.name.originalName); - const swiftType = this.sdkGeneratorContext.getSwiftTypeForTypeReference( - queryParam.valueType - ); - if (swiftType.isOptional) { + const swiftType = this.getResolvedSwiftTypeForTypeReference(queryParam.valueType); + if (swiftType.variant.type === "optional") { return [ key, swift.Expression.methodCallWithTrailingClosure({ target: - swiftType.nonOptionalType === "nullable" + swiftType.nonOptional().variant.type === "nullable" ? swift.Expression.memberAccess({ target: swift.Expression.reference( queryParam.name.name.camelCase.unsafeName @@ -278,16 +287,17 @@ export class EndpointMethodGenerator { : swift.Expression.reference(queryParam.name.name.camelCase.unsafeName), methodName: "map", closureBody: swift.Expression.contextualMethodCall({ - methodName: getQueryParamCaseName(swiftType), + methodName: this.inferQueryParamCaseName(swiftType), arguments_: [ swift.functionArgument({ - value: - swiftType.nonOptional().nonNullableType === "custom" - ? swift.Expression.memberAccess({ - target: swift.Expression.reference("$0"), - memberName: "rawValue" - }) - : swift.Expression.reference("$0") + value: this.referencer.resolvesToAnEnumWithRawValues( + swiftType.nonOptional() + ) + ? swift.Expression.memberAccess({ + target: swift.Expression.reference("$0"), + memberName: "rawValue" + }) + : swift.Expression.reference("$0") }) ] }) @@ -296,7 +306,7 @@ export class EndpointMethodGenerator { } else { return [ key, - swiftType.nonOptionalType === "nullable" + swiftType.nonOptional().variant.type === "nullable" ? swift.Expression.methodCallWithTrailingClosure({ target: swift.Expression.memberAccess({ target: swift.Expression.reference( @@ -306,7 +316,7 @@ export class EndpointMethodGenerator { }), methodName: "map", closureBody: swift.Expression.contextualMethodCall({ - methodName: getQueryParamCaseName(swiftType), + methodName: this.inferQueryParamCaseName(swiftType), arguments_: [ swift.functionArgument({ value: swift.Expression.reference("$0") @@ -315,20 +325,21 @@ export class EndpointMethodGenerator { }) }) : swift.Expression.contextualMethodCall({ - methodName: getQueryParamCaseName(swiftType), + methodName: this.inferQueryParamCaseName(swiftType), arguments_: [ swift.functionArgument({ - value: - swiftType.nonOptionalType === "custom" - ? swift.Expression.memberAccess({ - target: swift.Expression.reference( - queryParam.name.name.camelCase.unsafeName - ), - memberName: "rawValue" - }) - : swift.Expression.reference( + value: this.referencer.resolvesToAnEnumWithRawValues( + swiftType.nonOptional() + ) + ? swift.Expression.memberAccess({ + target: swift.Expression.reference( queryParam.name.name.camelCase.unsafeName - ) + ), + memberName: "rawValue" + }) + : swift.Expression.reference( + queryParam.name.name.camelCase.unsafeName + ) }) ] }) @@ -371,7 +382,7 @@ export class EndpointMethodGenerator { const returnType = this.getMethodReturnTypeForEndpoint(endpoint); - if (returnType.type !== "void") { + if (!this.referencer.resolvesToTheSwiftType(returnType, "Void")) { arguments_.push( swift.functionArgument({ label: "responseType", @@ -386,6 +397,22 @@ export class EndpointMethodGenerator { return arguments_; } + private getResolvedSwiftTypeForTypeReference(typeReference: TypeReference): swift.TypeReference { + if (typeReference.type === "named") { + const { typeId } = typeReference; + const typeDeclaration = this.sdkGeneratorContext.ir.types[typeId]; + assertDefined(typeDeclaration, `Type declaration not found for type id: ${typeId}`); + if (typeDeclaration.shape.type === "alias") { + return this.getResolvedSwiftTypeForTypeReference(typeDeclaration.shape.aliasOf); + } + } + return this.getSwiftTypeForTypeReference(typeReference); + } + + private getSwiftTypeForTypeReference(typeReference: TypeReference) { + return this.sdkGeneratorContext.getSwiftTypeReferenceFromScope(typeReference, this.parentClassSymbol); + } + private getEnumCaseNameForHttpMethod(method: HttpMethod): string { switch (method) { case "GET": @@ -404,4 +431,53 @@ export class EndpointMethodGenerator { assertNever(method); } } + + public inferQueryParamCaseName(typeReference: swift.TypeReference): string { + if (typeReference.variant.type === "optional") { + return this.inferQueryParamCaseName(typeReference.nonOptional()); + } + if (typeReference.variant.type === "nullable") { + return this.inferQueryParamCaseName(typeReference.nonNullable()); + } + if (this.referencer.resolvesToTheSwiftType(typeReference, "String")) { + return "string"; + } + if (this.referencer.resolvesToTheSwiftType(typeReference, "Bool")) { + return "bool"; + } + if (this.referencer.resolvesToTheSwiftType(typeReference, "Int")) { + return "int"; + } + if (this.referencer.resolvesToTheSwiftType(typeReference, "UInt")) { + return "uint"; + } + if (this.referencer.resolvesToTheSwiftType(typeReference, "UInt64")) { + return "uint64"; + } + if (this.referencer.resolvesToTheSwiftType(typeReference, "Int64")) { + return "int64"; + } + if (this.referencer.resolvesToTheSwiftType(typeReference, "Float")) { + return "float"; + } + if (this.referencer.resolvesToTheSwiftType(typeReference, "Double")) { + return "double"; + } + if (this.referencer.resolvesToTheFoundationType(typeReference, "Date")) { + return "date"; + } + if (this.referencer.resolvesToTheAsIsType(typeReference, "CalendarDate")) { + return "calendarDate"; + } + if ( + typeReference.variant.type === "array" && + this.referencer.resolvesToTheSwiftType(typeReference.variant.elementType, "String") + ) { + return "stringArray"; + } + if (this.referencer.resolvesToTheFoundationType(typeReference, "UUID")) { + return "uuid"; + } + return "unknown"; + } } diff --git a/generators/swift/sdk/src/generators/client/RootClientGenerator.ts b/generators/swift/sdk/src/generators/client/RootClientGenerator.ts index d5bebc12e9d1..b5e0e7d9ff02 100644 --- a/generators/swift/sdk/src/generators/client/RootClientGenerator.ts +++ b/generators/swift/sdk/src/generators/client/RootClientGenerator.ts @@ -1,14 +1,14 @@ import { assertNever, visitDiscriminatedUnion } from "@fern-api/core-utils"; +import { Referencer } from "@fern-api/swift-base"; import { swift } from "@fern-api/swift-codegen"; import { Package } from "@fern-fern/ir-sdk/api"; - import { SdkGeneratorContext } from "../../SdkGeneratorContext"; import { ClientGeneratorContext } from "./ClientGeneratorContext"; import { EndpointMethodGenerator } from "./EndpointMethodGenerator"; export declare namespace RootClientGenerator { interface Args { - clientName: string; + symbol: swift.Symbol; package_: Package; sdkGeneratorContext: SdkGeneratorContext; } @@ -17,16 +17,19 @@ export declare namespace RootClientGenerator { type BearerTokenParamType = "string" | "async-provider"; export class RootClientGenerator { - private readonly clientName: string; + private readonly symbol: swift.Symbol; private readonly package_: Package; private readonly sdkGeneratorContext: SdkGeneratorContext; private readonly clientGeneratorContext: ClientGeneratorContext; + private readonly referencer: Referencer; - public constructor({ clientName, package_, sdkGeneratorContext }: RootClientGenerator.Args) { - this.clientName = clientName; + public constructor({ symbol, package_, sdkGeneratorContext }: RootClientGenerator.Args) { + this.referencer = sdkGeneratorContext.createReferencer(symbol); + this.symbol = symbol; this.package_ = package_; this.sdkGeneratorContext = sdkGeneratorContext; this.clientGeneratorContext = new ClientGeneratorContext({ + symbol, packageOrSubpackage: package_, sdkGeneratorContext }); @@ -42,7 +45,7 @@ export class RootClientGenerator { return swift.functionParameter({ argumentLabel: "baseURL", unsafeName: "baseURL", - type: swift.Type.string(), + type: this.referencer.referenceSwiftType("String"), defaultValue: this.getDefaultBaseUrl(), docsContent: "The base URL to use for requests from the client. If not provided, the default base URL will be used." @@ -53,7 +56,12 @@ export class RootClientGenerator { return swift.functionParameter({ argumentLabel: "headers", unsafeName: "headers", - type: swift.Type.optional(swift.Type.dictionary(swift.Type.string(), swift.Type.string())), + type: swift.TypeReference.optional( + swift.TypeReference.dictionary( + this.referencer.referenceSwiftType("String"), + this.referencer.referenceSwiftType("String") + ) + ), defaultValue: swift.Expression.nil(), docsContent: "Additional headers to send with each request." }); @@ -63,7 +71,7 @@ export class RootClientGenerator { return swift.functionParameter({ argumentLabel: "timeout", unsafeName: "timeout", - type: swift.Type.optional(swift.Type.int()), + type: swift.TypeReference.optional(this.referencer.referenceSwiftType("Int")), defaultValue: swift.Expression.rawValue("nil"), docsContent: "Request timeout in seconds. Defaults to 60 seconds. Ignored if a custom `urlSession` is provided." @@ -74,7 +82,7 @@ export class RootClientGenerator { return swift.functionParameter({ argumentLabel: "maxRetries", unsafeName: "maxRetries", - type: swift.Type.optional(swift.Type.int()), + type: swift.TypeReference.optional(this.referencer.referenceSwiftType("Int")), defaultValue: swift.Expression.rawValue("nil"), docsContent: "Maximum number of retries for failed requests. Defaults to 2." }); @@ -84,7 +92,7 @@ export class RootClientGenerator { return swift.functionParameter({ argumentLabel: "urlSession", unsafeName: "urlSession", - type: swift.Type.optional(swift.Type.custom("URLSession")), + type: swift.TypeReference.optional(this.referencer.referenceFoundationType("URLSession")), defaultValue: swift.Expression.rawValue("nil"), docsContent: "Custom `URLSession` to use for requests. If not provided, a default session will be created with the specified timeout." @@ -93,7 +101,7 @@ export class RootClientGenerator { public generate() { return swift.class_({ - name: this.clientName, + name: this.symbol.name, final: true, accessLevel: swift.AccessLevel.Public, conformances: [swift.Protocol.Sendable], @@ -141,7 +149,7 @@ export class RootClientGenerator { swift.functionArgument({ label: "headerAuth", value: authSchemes.header - ? authSchemes.header.param.type.isOptional + ? authSchemes.header.param.type.variant.type === "optional" ? swift.Expression.methodCallWithTrailingClosure({ target: swift.Expression.reference(authSchemes.header.param.unsafeName), methodName: "map", @@ -179,7 +187,7 @@ export class RootClientGenerator { swift.functionArgument({ label: "bearerAuth", value: authSchemes.bearer - ? authSchemes.bearer.stringParam.type.isOptional + ? authSchemes.bearer.stringParam.type.variant.type === "optional" ? swift.Expression.methodCallWithTrailingClosure({ target: swift.Expression.reference(authSchemes.bearer.stringParam.unsafeName), methodName: "map", @@ -342,48 +350,59 @@ export class RootClientGenerator { swift.functionParameter({ argumentLabel: "baseURL", unsafeName: "baseURL", - type: swift.Type.string() + type: this.referencer.referenceSwiftType("String") }), swift.functionParameter({ argumentLabel: "headerAuth", unsafeName: "headerAuth", - type: swift.Type.optional(swift.Type.custom("ClientConfig.HeaderAuth")), + type: swift.TypeReference.optional( + swift.TypeReference.memberAccess(this.referencer.referenceAsIsType("ClientConfig"), "HeaderAuth") + ), defaultValue: swift.Expression.nil() }), swift.functionParameter({ argumentLabel: "bearerAuth", unsafeName: "bearerAuth", - type: swift.Type.optional(swift.Type.custom("ClientConfig.BearerAuth")), + type: swift.TypeReference.optional( + swift.TypeReference.memberAccess(this.referencer.referenceAsIsType("ClientConfig"), "BearerAuth") + ), defaultValue: swift.Expression.nil() }), swift.functionParameter({ argumentLabel: "basicAuth", unsafeName: "basicAuth", - type: swift.Type.optional(swift.Type.custom("ClientConfig.BasicAuth")), + type: swift.TypeReference.optional( + swift.TypeReference.memberAccess(this.referencer.referenceAsIsType("ClientConfig"), "BasicAuth") + ), defaultValue: swift.Expression.nil() }), swift.functionParameter({ argumentLabel: "headers", unsafeName: "headers", - type: swift.Type.optional(swift.Type.dictionary(swift.Type.string(), swift.Type.string())), + type: swift.TypeReference.optional( + swift.TypeReference.dictionary( + this.referencer.referenceSwiftType("String"), + this.referencer.referenceSwiftType("String") + ) + ), defaultValue: swift.Expression.nil() }), swift.functionParameter({ argumentLabel: "timeout", unsafeName: "timeout", - type: swift.Type.optional(swift.Type.int()), + type: swift.TypeReference.optional(this.referencer.referenceSwiftType("Int")), defaultValue: swift.Expression.nil() }), swift.functionParameter({ argumentLabel: "maxRetries", unsafeName: "maxRetries", - type: swift.Type.optional(swift.Type.int()), + type: swift.TypeReference.optional(this.referencer.referenceSwiftType("Int")), defaultValue: swift.Expression.nil() }), swift.functionParameter({ argumentLabel: "urlSession", unsafeName: "urlSession", - type: swift.Type.optional(swift.Type.custom("URLSession")), + type: swift.TypeReference.optional(this.referencer.referenceFoundationType("URLSession")), defaultValue: swift.Expression.nil() }) ]; @@ -450,10 +469,13 @@ export class RootClientGenerator { (e, idx) => (defaultEnvId == null ? idx === 0 : e.id === defaultEnvId) ); if (defaultEnvironment != null) { + const environmentSymbol = this.sdkGeneratorContext.project.nameRegistry.getEnvironmentSymbolOrThrow(); + const environmentRef = this.sdkGeneratorContext.project.nameRegistry.reference({ + fromSymbol: this.symbol, + toSymbol: environmentSymbol + }); return swift.Expression.memberAccess({ - target: swift.Expression.reference( - this.sdkGeneratorContext.project.srcSymbolRegistry.getEnvironmentSymbolOrThrow() - ), + target: swift.Expression.reference(environmentRef), memberName: `${defaultEnvironment.name.camelCase.unsafeName}.rawValue` }); } @@ -494,7 +516,9 @@ export class RootClientGenerator { param: swift.functionParameter({ argumentLabel: scheme.name.name.camelCase.unsafeName, unsafeName: scheme.name.name.camelCase.unsafeName, - type: isAuthMandatory ? swift.Type.string() : swift.Type.optional(swift.Type.string()), + type: isAuthMandatory + ? this.referencer.referenceSwiftType("String") + : swift.TypeReference.optional(this.referencer.referenceSwiftType("String")), defaultValue: isAuthMandatory ? undefined : swift.Expression.nil(), docsContent: scheme.docs ?? `The API key to use for authentication.` }), @@ -505,7 +529,9 @@ export class RootClientGenerator { stringParam: swift.functionParameter({ argumentLabel: scheme.token.camelCase.unsafeName, unsafeName: scheme.token.camelCase.unsafeName, - type: isAuthMandatory ? swift.Type.string() : swift.Type.optional(swift.Type.string()), + type: isAuthMandatory + ? this.referencer.referenceSwiftType("String") + : swift.TypeReference.optional(this.referencer.referenceSwiftType("String")), defaultValue: isAuthMandatory ? undefined : swift.Expression.nil(), docsContent: scheme.docs ?? @@ -516,8 +542,16 @@ export class RootClientGenerator { unsafeName: scheme.token.camelCase.unsafeName, escaping: isAuthMandatory ? true : undefined, type: isAuthMandatory - ? swift.Type.custom("ClientConfig.CredentialProvider") - : swift.Type.optional(swift.Type.custom("ClientConfig.CredentialProvider")), + ? swift.TypeReference.memberAccess( + this.referencer.referenceAsIsType("ClientConfig"), + "CredentialProvider" + ) + : swift.TypeReference.optional( + swift.TypeReference.memberAccess( + this.referencer.referenceAsIsType("ClientConfig"), + "CredentialProvider" + ) + ), defaultValue: isAuthMandatory ? undefined : swift.Expression.nil(), docsContent: `An async function that returns the bearer token for authentication. If provided, will be sent as "Bearer {token}" in Authorization header.` }) @@ -527,14 +561,18 @@ export class RootClientGenerator { usernameParam: swift.functionParameter({ argumentLabel: scheme.username.camelCase.unsafeName, unsafeName: scheme.username.camelCase.unsafeName, - type: isAuthMandatory ? swift.Type.string() : swift.Type.optional(swift.Type.string()), + type: isAuthMandatory + ? this.referencer.referenceSwiftType("String") + : swift.TypeReference.optional(this.referencer.referenceSwiftType("String")), defaultValue: isAuthMandatory ? undefined : swift.Expression.nil(), docsContent: `The username to use for authentication.` }), passwordParam: swift.functionParameter({ argumentLabel: scheme.password.camelCase.unsafeName, unsafeName: scheme.password.camelCase.unsafeName, - type: isAuthMandatory ? swift.Type.string() : swift.Type.optional(swift.Type.string()), + type: isAuthMandatory + ? this.referencer.referenceSwiftType("String") + : swift.TypeReference.optional(this.referencer.referenceSwiftType("String")), defaultValue: isAuthMandatory ? undefined : swift.Expression.nil(), docsContent: `The password to use for authentication.` }) @@ -553,6 +591,7 @@ export class RootClientGenerator { private generateMethods(): swift.Method[] { const endpointMethodGenerator = new EndpointMethodGenerator({ + parentClassSymbol: this.symbol, clientGeneratorContext: this.clientGeneratorContext, sdkGeneratorContext: this.sdkGeneratorContext }); diff --git a/generators/swift/sdk/src/generators/client/SubClientGenerator.ts b/generators/swift/sdk/src/generators/client/SubClientGenerator.ts index 3a8200619994..6c8231d7a69c 100644 --- a/generators/swift/sdk/src/generators/client/SubClientGenerator.ts +++ b/generators/swift/sdk/src/generators/client/SubClientGenerator.ts @@ -1,29 +1,32 @@ +import { Referencer } from "@fern-api/swift-base"; import { swift } from "@fern-api/swift-codegen"; import { Subpackage } from "@fern-fern/ir-sdk/api"; - import { SdkGeneratorContext } from "../../SdkGeneratorContext"; import { ClientGeneratorContext } from "./ClientGeneratorContext"; import { EndpointMethodGenerator } from "./EndpointMethodGenerator"; export declare namespace SubClientGenerator { interface Args { - clientName: string; + symbol: swift.Symbol; subpackage: Subpackage; sdkGeneratorContext: SdkGeneratorContext; } } export class SubClientGenerator { - private readonly clientName: string; + private readonly symbol: swift.Symbol; private readonly subpackage: Subpackage; private readonly sdkGeneratorContext: SdkGeneratorContext; private readonly clientGeneratorContext: ClientGeneratorContext; + private readonly referencer: Referencer; - public constructor({ clientName, subpackage, sdkGeneratorContext }: SubClientGenerator.Args) { - this.clientName = clientName; + public constructor({ symbol, subpackage, sdkGeneratorContext }: SubClientGenerator.Args) { + this.referencer = sdkGeneratorContext.createReferencer(symbol); + this.symbol = symbol; this.subpackage = subpackage; this.sdkGeneratorContext = sdkGeneratorContext; this.clientGeneratorContext = new ClientGeneratorContext({ + symbol, packageOrSubpackage: subpackage, sdkGeneratorContext }); @@ -37,7 +40,7 @@ export class SubClientGenerator { public generate(): swift.Class { return swift.class_({ - name: this.clientName, + name: this.symbol.name, final: true, accessLevel: swift.AccessLevel.Public, conformances: [swift.Protocol.Sendable], @@ -56,7 +59,7 @@ export class SubClientGenerator { swift.functionParameter({ argumentLabel: "config", unsafeName: "config", - type: swift.Type.custom("ClientConfig") + type: this.referencer.referenceAsIsType("ClientConfig") }) ], body: swift.CodeBlock.withStatements([ @@ -86,6 +89,7 @@ export class SubClientGenerator { private generateMethods(): swift.Method[] { const endpointMethodGenerator = new EndpointMethodGenerator({ + parentClassSymbol: this.symbol, clientGeneratorContext: this.clientGeneratorContext, sdkGeneratorContext: this.sdkGeneratorContext }); diff --git a/generators/swift/sdk/src/generators/client/util/get-query-param-case-name.ts b/generators/swift/sdk/src/generators/client/util/get-query-param-case-name.ts deleted file mode 100644 index 7c261b214d7c..000000000000 --- a/generators/swift/sdk/src/generators/client/util/get-query-param-case-name.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { assertNever } from "@fern-api/core-utils"; -import { swift } from "@fern-api/swift-codegen"; - -export function getQueryParamCaseName(swiftType: swift.Type): string { - switch (swiftType.type) { - case "optional": - return getQueryParamCaseName(swift.Type.nonOptional(swiftType)); - case "nullable": - return getQueryParamCaseName(swift.Type.nonNullable(swiftType)); - case "custom": - // TODO(kafkas): We are currently assuming that this refers to a string enum. - // Need to handle other cases. - return "string"; - case "string": - return "string"; - case "bool": - return "bool"; - case "int": - return "int"; - case "uint": - return "uint"; - case "uint64": - return "uint64"; - case "int64": - return "int64"; - case "float": - return "float"; - case "double": - return "double"; - case "date": - return "date"; - case "calendar-date": - return "calendarDate"; - case "array": - // TODO(kafkas): We are assuming string array for now. - // Revise this to support more complex query param types. - return "stringArray"; - case "uuid": - return "uuid"; - // TODO(kafkas): The following are currently unsupported. - case "data": - return "data"; - case "tuple": - return "unknown"; - case "dictionary": - return "unknown"; - case "void": - return "unknown"; - case "any": - return "unknown"; - case "existential-any": - return "unknown"; - case "json-value": - return "unknown"; - default: - assertNever(swiftType.type); - } -} diff --git a/generators/swift/sdk/src/generators/manifest/PackageSwiftGenerator.ts b/generators/swift/sdk/src/generators/manifest/PackageSwiftGenerator.ts index 12db539e1f8c..1fbfd7b99132 100644 --- a/generators/swift/sdk/src/generators/manifest/PackageSwiftGenerator.ts +++ b/generators/swift/sdk/src/generators/manifest/PackageSwiftGenerator.ts @@ -25,7 +25,7 @@ export class PackageSwiftGenerator { arguments_: [ swift.functionArgument({ label: "name", - value: swift.Expression.stringLiteral(this.sdkGeneratorContext.srcTargetName) + value: swift.Expression.stringLiteral(this.sdkGeneratorContext.sourceTargetName) }), swift.functionArgument({ label: "path", @@ -48,7 +48,7 @@ export class PackageSwiftGenerator { swift.functionArgument({ label: "dependencies", value: swift.Expression.arrayLiteral({ - elements: [swift.Expression.stringLiteral(this.sdkGeneratorContext.srcTargetName)] + elements: [swift.Expression.stringLiteral(this.sdkGeneratorContext.sourceTargetName)] }) }), swift.functionArgument({ @@ -144,7 +144,7 @@ export class PackageSwiftGenerator { value: swift.Expression.arrayLiteral({ elements: [ swift.Expression.stringLiteral( - this.sdkGeneratorContext.srcTargetName + this.sdkGeneratorContext.sourceTargetName ) ] }) diff --git a/generators/swift/sdk/src/generators/test/WireTestFunctionGenerator.ts b/generators/swift/sdk/src/generators/test/WireTestFunctionGenerator.ts index 790cbedd8a89..6929419aadfe 100644 --- a/generators/swift/sdk/src/generators/test/WireTestFunctionGenerator.ts +++ b/generators/swift/sdk/src/generators/test/WireTestFunctionGenerator.ts @@ -1,4 +1,5 @@ import { assertDefined } from "@fern-api/core-utils"; +import { Referencer } from "@fern-api/swift-base"; import { LiteralEnum, swift } from "@fern-api/swift-codegen"; import { EndpointSnippetGenerator } from "@fern-api/swift-dynamic-snippets"; import { dynamic, ExampleEndpointCall, ExampleTypeReference, HttpEndpoint } from "@fern-fern/ir-sdk/api"; @@ -7,6 +8,7 @@ import { convertDynamicEndpointSnippetRequest } from "../../utils/convertEndpoin export declare namespace WireTestFunctionGenerator { interface Args { + parentSymbol: swift.Symbol; endpoint: HttpEndpoint; endpointSnippetGenerator: EndpointSnippetGenerator; dynamicIr: dynamic.DynamicIntermediateRepresentation; @@ -15,24 +17,28 @@ export declare namespace WireTestFunctionGenerator { } export class WireTestFunctionGenerator { + private readonly parentSymbol: swift.Symbol; private readonly endpoint: HttpEndpoint; private readonly endpointSnippetGenerator: EndpointSnippetGenerator; private readonly dynamicIr: dynamic.DynamicIntermediateRepresentation; private readonly sdkGeneratorContext: SdkGeneratorContext; - private readonly exampleEndpointCallsById: Record; + private readonly referencer: Referencer; public constructor({ + parentSymbol, endpoint, endpointSnippetGenerator, dynamicIr, sdkGeneratorContext }: WireTestFunctionGenerator.Args) { + this.parentSymbol = parentSymbol; this.endpoint = endpoint; this.endpointSnippetGenerator = endpointSnippetGenerator; this.dynamicIr = dynamicIr; this.sdkGeneratorContext = sdkGeneratorContext; this.exampleEndpointCallsById = this.buildExampleEndpointCallsById(endpoint); + this.referencer = this.sdkGeneratorContext.createReferencer(this.parentSymbol); } private get dynamicEndpoint() { @@ -106,7 +112,7 @@ export class WireTestFunctionGenerator { this.generateClientDeclaration(endpointExample), swift.Statement.constantDeclaration({ unsafeName: "expectedResponse", - value: this.generateExampleResponse(exampleTypeRef) + value: this.generateExampleResponse(exampleTypeRef, this.parentSymbol) }), this.generateEndpointMethodCallStatement(endpointExample), swift.Statement.expressionStatement( @@ -130,7 +136,7 @@ export class WireTestFunctionGenerator { unsafeName: `${this.endpoint.name.camelCase.unsafeName}${endpointExampleIdx + 1}`, async: true, throws: true, - returnType: swift.Type.void(), + returnType: this.referencer.referenceSwiftType("Void"), body: swift.CodeBlock.withStatements(statements) }); }) @@ -167,7 +173,10 @@ export class WireTestFunctionGenerator { }); } - private generateExampleResponse(exampleTypeRef: ExampleTypeReference): swift.Expression { + private generateExampleResponse( + exampleTypeRef: ExampleTypeReference, + fromScope: swift.Symbol | string + ): swift.Expression { return exampleTypeRef.shape._visit({ container: (exampleContainer) => exampleContainer._visit({ @@ -194,25 +203,25 @@ export class WireTestFunctionGenerator { map: (mapContainer) => { return swift.Expression.dictionaryLiteral({ entries: mapContainer.map.map((kvPair) => [ - this.generateExampleResponse(kvPair.key), - this.generateExampleResponse(kvPair.value) + this.generateExampleResponse(kvPair.key, fromScope), + this.generateExampleResponse(kvPair.value, fromScope) ]), multiline: true }); }, - set: () => swift.Expression.arrayLiteral({}), // TODO(kafkas): Set is not supported yet + set: () => swift.Expression.arrayLiteral({}), nullable: (nullableContainer) => { if (nullableContainer.nullable == null) { return swift.Expression.enumCaseShorthand("null"); } return swift.Expression.methodCall({ target: swift.Expression.reference( - `Nullable<${this.getSwiftTypeForExampleTypeReference(nullableContainer.nullable).toString()}>` + `Nullable<${this.getSwiftTypeReferenceForExampleTypeReference(nullableContainer.nullable, fromScope).toString()}>` ), methodName: "value", arguments_: [ swift.functionArgument({ - value: this.generateExampleResponse(nullableContainer.nullable) + value: this.generateExampleResponse(nullableContainer.nullable, fromScope) }) ] }); @@ -224,7 +233,7 @@ export class WireTestFunctionGenerator { arguments_: [ swift.functionArgument({ value: swift.Expression.memberAccess({ - target: this.sdkGeneratorContext.getSwiftTypeForTypeReference( + target: this.sdkGeneratorContext.getSwiftTypeReferenceFromTestModuleScope( optionalContainer.valueType ), memberName: "null" @@ -236,14 +245,16 @@ export class WireTestFunctionGenerator { unsafeName: "Optional", arguments_: [ swift.functionArgument({ - value: this.generateExampleResponse(optionalContainer.optional) + value: this.generateExampleResponse(optionalContainer.optional, fromScope) }) ] }); }, list: (listContainer) => { return swift.Expression.arrayLiteral({ - elements: listContainer.list.map((element) => this.generateExampleResponse(element)), + elements: listContainer.list.map((element) => + this.generateExampleResponse(element, fromScope) + ), multiline: true }); }, @@ -259,7 +270,6 @@ export class WireTestFunctionGenerator { long: (value) => swift.Expression.numberLiteral(value), float: (value) => swift.Expression.numberLiteral(value), double: (value) => swift.Expression.numberLiteral(value), - // TODO(kafkas): Bigints are not supported yet bigInteger: (value) => swift.Expression.stringLiteral(value), date: (value) => swift.Expression.calendarDateLiteral(value), datetime: (value) => { @@ -279,18 +289,17 @@ export class WireTestFunctionGenerator { }), named: (exampleNamedType) => { const { typeId } = exampleNamedType.typeName; - const symbolName = - this.sdkGeneratorContext.project.srcSymbolRegistry.getSchemaTypeSymbolOrThrow(typeId); + const symbol = this.sdkGeneratorContext.project.nameRegistry.getSchemaTypeSymbolOrThrow(typeId); return exampleNamedType.shape._visit({ alias: (exampleAliasType) => { - return this.generateExampleResponse(exampleAliasType.value); + return this.generateExampleResponse(exampleAliasType.value, fromScope); }, enum: (exampleEnumType) => { return swift.Expression.enumCaseShorthand(exampleEnumType.value.name.camelCase.unsafeName); }, object: (exampleObjectType) => { return swift.Expression.structInitialization({ - unsafeName: symbolName, + unsafeName: symbol.name, arguments_: exampleObjectType.properties .map((property) => { if ( @@ -300,7 +309,7 @@ export class WireTestFunctionGenerator { ) { return null; } - const exampleResponse = this.generateExampleResponse(property.value); + const exampleResponse = this.generateExampleResponse(property.value, fromScope); return swift.functionArgument({ label: property.name.name.camelCase.unsafeName, value: exampleResponse @@ -338,7 +347,8 @@ export class WireTestFunctionGenerator { return null; } const exampleResponse = this.generateExampleResponse( - property.value + property.value, + fromScope ); return swift.functionArgument({ label: property.name.name.camelCase.unsafeName, @@ -352,7 +362,7 @@ export class WireTestFunctionGenerator { ], multiline: true }), - singleProperty: (exampleTypeRef) => this.generateExampleResponse(exampleTypeRef), + singleProperty: (exampleTypeRef) => this.generateExampleResponse(exampleTypeRef, fromScope), _other: () => swift.Expression.contextualMethodCall({ methodName: @@ -363,13 +373,16 @@ export class WireTestFunctionGenerator { }); }, undiscriminatedUnion: (exampleUnionType) => { - const swiftType = this.getSwiftTypeForExampleTypeReference(exampleUnionType.singleUnionType); + const swiftType = this.getSwiftTypeReferenceForExampleTypeReference( + exampleUnionType.singleUnionType, + fromScope + ); return swift.Expression.methodCall({ - target: swift.Expression.reference(symbolName), - methodName: swiftType.toCaseName(), + target: swift.Expression.reference(symbol.name), + methodName: this.sdkGeneratorContext.inferCaseNameForTypeReference(symbol, swiftType), arguments_: [ swift.functionArgument({ - value: this.generateExampleResponse(exampleUnionType.singleUnionType) + value: this.generateExampleResponse(exampleUnionType.singleUnionType, fromScope) }) ], multiline: true @@ -385,62 +398,79 @@ export class WireTestFunctionGenerator { }); } - private getSwiftTypeForExampleTypeReference(typeReference: ExampleTypeReference): swift.Type { + public getSwiftTypeReferenceForExampleTypeReferenceFromTestModuleScope( + typeReference: ExampleTypeReference + ): swift.TypeReference { + const symbol = this.sdkGeneratorContext.project.nameRegistry.getRegisteredTestModuleSymbolOrThrow(); + return this.getSwiftTypeReferenceForExampleTypeReference(typeReference, symbol); + } + + private getSwiftTypeReferenceForExampleTypeReference( + typeReference: ExampleTypeReference, + fromScope: swift.Symbol | string + ): swift.TypeReference { return typeReference.shape._visit({ container: (exampleContainer) => { return exampleContainer._visit({ - literal: () => { - // TODO(kafkas): Implement this - return swift.Type.jsonValue(); - }, + // TODO(kafkas): Implement this + literal: () => this.referencer.referenceAsIsType("JSONValue"), map: (exampleMapContainer) => - swift.Type.dictionary( - this.sdkGeneratorContext.getSwiftTypeForTypeReference(exampleMapContainer.keyType), - this.sdkGeneratorContext.getSwiftTypeForTypeReference(exampleMapContainer.valueType) + swift.TypeReference.dictionary( + this.sdkGeneratorContext.getSwiftTypeReferenceFromTestModuleScope( + exampleMapContainer.keyType + ), + this.sdkGeneratorContext.getSwiftTypeReferenceFromTestModuleScope( + exampleMapContainer.valueType + ) ), - set: () => swift.Type.jsonValue(), // TODO(kafkas): Set is not supported yet + set: () => this.referencer.referenceAsIsType("JSONValue"), nullable: (exampleNullableContainer) => - swift.Type.nullable( - this.sdkGeneratorContext.getSwiftTypeForTypeReference(exampleNullableContainer.valueType) + swift.TypeReference.nullable( + this.sdkGeneratorContext.getSwiftTypeReferenceFromTestModuleScope( + exampleNullableContainer.valueType + ) ), optional: (exampleOptionalContainer) => - swift.Type.optional( - this.sdkGeneratorContext.getSwiftTypeForTypeReference(exampleOptionalContainer.valueType) + swift.TypeReference.optional( + this.sdkGeneratorContext.getSwiftTypeReferenceFromTestModuleScope( + exampleOptionalContainer.valueType + ) ), list: (exampleListContainer) => - swift.Type.array( - this.sdkGeneratorContext.getSwiftTypeForTypeReference(exampleListContainer.itemType) + swift.TypeReference.array( + this.sdkGeneratorContext.getSwiftTypeReferenceFromTestModuleScope( + exampleListContainer.itemType + ) ), - _other: () => swift.Type.jsonValue() + _other: () => this.referencer.referenceAsIsType("JSONValue") }); }, primitive: (examplePrimitive) => { return examplePrimitive._visit({ - string: () => swift.Type.string(), - boolean: () => swift.Type.bool(), - integer: () => swift.Type.int(), - uint: () => swift.Type.uint(), - uint64: () => swift.Type.uint64(), - long: () => swift.Type.int64(), - float: () => swift.Type.float(), - double: () => swift.Type.double(), - bigInteger: () => swift.Type.string(), // TODO(kafkas): Bigints are not supported yet - date: () => swift.Type.calendarDate(), - datetime: () => swift.Type.date(), - base64: () => swift.Type.string(), - uuid: () => swift.Type.uuid(), - _other: () => swift.Type.jsonValue() + string: () => this.referencer.referenceSwiftType("String"), + boolean: () => this.referencer.referenceSwiftType("Bool"), + integer: () => this.referencer.referenceSwiftType("Int"), + uint: () => this.referencer.referenceSwiftType("UInt"), + uint64: () => this.referencer.referenceSwiftType("UInt64"), + long: () => this.referencer.referenceSwiftType("Int64"), + float: () => this.referencer.referenceSwiftType("Float"), + double: () => this.referencer.referenceSwiftType("Double"), + bigInteger: () => this.referencer.referenceSwiftType("String"), + date: () => this.referencer.referenceAsIsType("CalendarDate"), + datetime: () => this.referencer.referenceFoundationType("Date"), + base64: () => this.referencer.referenceSwiftType("String"), + uuid: () => this.referencer.referenceFoundationType("UUID"), + _other: () => this.referencer.referenceAsIsType("JSONValue") }); }, named: (exampleNamedType) => { - const symbolName = this.sdkGeneratorContext.project.srcSymbolRegistry.getSchemaTypeSymbolOrThrow( + const symbol = this.sdkGeneratorContext.project.nameRegistry.getSchemaTypeSymbolOrThrow( exampleNamedType.typeName.typeId ); - // TODO(kafkas): Handle nested types (inline literals etc.) - return swift.Type.custom(symbolName); + return this.referencer.referenceType(symbol.id); }, - unknown: () => swift.Type.jsonValue(), - _other: () => swift.Type.jsonValue() + unknown: () => this.referencer.referenceAsIsType("JSONValue"), + _other: () => this.referencer.referenceAsIsType("JSONValue") }); } diff --git a/generators/swift/sdk/src/generators/test/WireTestSuiteGenerator.ts b/generators/swift/sdk/src/generators/test/WireTestSuiteGenerator.ts index 4d7a4c413646..96fc13c9b4df 100644 --- a/generators/swift/sdk/src/generators/test/WireTestSuiteGenerator.ts +++ b/generators/swift/sdk/src/generators/test/WireTestSuiteGenerator.ts @@ -7,7 +7,7 @@ import { WireTestFunctionGenerator } from "./WireTestFunctionGenerator"; export declare namespace WireTestSuiteGenerator { interface Args { - suiteName: string; + symbol: swift.Symbol; subclientName: string; packageOrSubpackage: Package | Subpackage; sdkGeneratorContext: SdkGeneratorContext; @@ -15,19 +15,19 @@ export declare namespace WireTestSuiteGenerator { } export class WireTestSuiteGenerator { - private readonly suiteName: string; + private readonly symbol: swift.Symbol; private readonly subclientName: string; private readonly packageOrSubpackage: Package | Subpackage; private readonly sdkGeneratorContext: SdkGeneratorContext; private readonly dynamicIr: dynamic.DynamicIntermediateRepresentation; public constructor({ - suiteName, + symbol, subclientName, packageOrSubpackage, sdkGeneratorContext }: WireTestSuiteGenerator.Args) { - this.suiteName = suiteName; + this.symbol = symbol; this.subclientName = subclientName; this.packageOrSubpackage = packageOrSubpackage; this.sdkGeneratorContext = sdkGeneratorContext; @@ -57,7 +57,7 @@ export class WireTestSuiteGenerator { ] } ], - name: this.suiteName, + name: this.symbol.name, properties: [], methods: this.generateTestFunctions() }); @@ -73,6 +73,7 @@ export class WireTestSuiteGenerator { context: dynamicSnippetsGenerator.context }); return new WireTestFunctionGenerator({ + parentSymbol: this.symbol, endpoint, endpointSnippetGenerator, dynamicIr: this.dynamicIr, diff --git a/generators/swift/sdk/src/readme/ReadmeSnippetBuilder.ts b/generators/swift/sdk/src/readme/ReadmeSnippetBuilder.ts index af3c2ca788e3..0eceef545fac 100644 --- a/generators/swift/sdk/src/readme/ReadmeSnippetBuilder.ts +++ b/generators/swift/sdk/src/readme/ReadmeSnippetBuilder.ts @@ -75,19 +75,22 @@ export class ReadmeSnippetBuilder extends AbstractReadmeSnippetBuilder { } private buildRequestTypesSnippets(): string[] { - const moduleName = this.context.project.srcSymbolRegistry.getModuleSymbolOrThrow(); - const requestContainerName = this.context.project.srcSymbolRegistry.getRequestsContainerSymbolOrThrow(); - const [firstRequestTypeSymbol] = this.context.project.srcSymbolRegistry.getAllRequestTypeSymbols(); + const moduleSymbol = this.context.project.nameRegistry.getRegisteredSourceModuleSymbolOrThrow(); + const [firstRequestTypeSymbol] = this.context.project.nameRegistry.getAllRequestTypeSymbols(); if (firstRequestTypeSymbol == null) { return []; } + const requestTypeRef = this.context.project.nameRegistry.reference({ + fromSymbol: moduleSymbol, + toSymbol: firstRequestTypeSymbol + }); const content = SwiftFile.getRawContents([ - swift.Statement.import(moduleName), + swift.Statement.import(moduleSymbol.name), swift.LineBreak.single(), swift.Statement.constantDeclaration({ unsafeName: "request", value: swift.Expression.structInitialization({ - unsafeName: requestContainerName + "." + firstRequestTypeSymbol.name, + unsafeName: requestTypeRef, arguments_: [ swift.functionArgument({ value: swift.Expression.rawValue("...") @@ -235,16 +238,16 @@ export class ReadmeSnippetBuilder extends AbstractReadmeSnippetBuilder { } private buildCustomNetworkingClientSnippets(): string[] { - const moduleName = this.context.project.srcSymbolRegistry.getModuleSymbolOrThrow(); - const rootClientName = this.context.project.srcSymbolRegistry.getRootClientSymbolOrThrow(); + const moduleSymbol = this.context.project.nameRegistry.getRegisteredSourceModuleSymbolOrThrow(); + const rootClientSymbol = this.context.project.nameRegistry.getRootClientSymbolOrThrow(); const content = SwiftFile.getRawContents([ swift.Statement.import("Foundation"), - swift.Statement.import(moduleName), + swift.Statement.import(moduleSymbol.name), swift.LineBreak.single(), swift.Statement.constantDeclaration({ unsafeName: "client", value: swift.Expression.structInitialization({ - unsafeName: rootClientName, + unsafeName: rootClientSymbol.name, arguments_: [ swift.functionArgument({ value: swift.Expression.rawValue("...") }), swift.functionArgument({ diff --git a/generators/swift/sdk/src/reference/ReferenceConfigAssembler.ts b/generators/swift/sdk/src/reference/ReferenceConfigAssembler.ts index e8cb887a0bf9..61cb689a0ff4 100644 --- a/generators/swift/sdk/src/reference/ReferenceConfigAssembler.ts +++ b/generators/swift/sdk/src/reference/ReferenceConfigAssembler.ts @@ -60,7 +60,9 @@ export class ReferenceConfigAssembler { if (endpointContainer.type === "none") { throw new Error(`Internal error; missing package or subpackage for endpoint ${endpoint.id}`); } + const rootClientSymbol = this.context.project.nameRegistry.getRootClientSymbolOrThrow(); const clientGeneratorContext = new ClientGeneratorContext({ + symbol: rootClientSymbol, packageOrSubpackage: endpointContainer.type === "root-package" ? endpointContainer.package @@ -68,6 +70,7 @@ export class ReferenceConfigAssembler { sdkGeneratorContext: this.context }); const endpointMethodGenerator = new EndpointMethodGenerator({ + parentClassSymbol: rootClientSymbol, clientGeneratorContext, sdkGeneratorContext: this.context }); @@ -120,7 +123,7 @@ export class ReferenceConfigAssembler { parameters: endpointMethod.parameters.map((p) => ({ name: p.unsafeName, type: p.type.toString(), - required: !p.type.isOptional, + required: p.type.variant.type !== "optional", description: p.docsContent })) }; @@ -136,14 +139,14 @@ export class ReferenceConfigAssembler { if (endpointContainer.type === "none") { throw new Error(`Internal error; missing package or subpackage for endpoint ${endpoint.id}`); } else if (endpointContainer.type === "root-package") { - const rootClientName = this.context.project.srcSymbolRegistry.getRootClientSymbolOrThrow(); - return `/${this.context.project.sourcesDirectory}/${rootClientName}.swift`; + const rootClientSymbol = this.context.project.nameRegistry.getRootClientSymbolOrThrow(); + return `/${this.context.project.sourcesDirectory}/${rootClientSymbol.name}.swift`; } else if (endpointContainer.type === "subpackage") { - const subclientName = this.context.project.srcSymbolRegistry.getSubClientSymbolOrThrow( + const subClientSymbol = this.context.project.nameRegistry.getSubClientSymbolOrThrow( endpointContainer.subpackageId ); const fernFilepathDir = this.context.getDirectoryForFernFilepath(endpointContainer.subpackage.fernFilepath); - return `/${this.context.project.sourcesDirectory}/${this.context.resourcesDirectory}/${fernFilepathDir}/${subclientName}.swift`; + return `/${this.context.project.sourcesDirectory}/${this.context.resourcesDirectory}/${fernFilepathDir}/${subClientSymbol.name}.swift`; } else { assertNever(endpointContainer); } diff --git a/generators/swift/sdk/versions.yml b/generators/swift/sdk/versions.yml index 85e405db761d..6eb9ce134da8 100644 --- a/generators/swift/sdk/versions.yml +++ b/generators/swift/sdk/versions.yml @@ -1,5 +1,13 @@ # yaml-language-server: $schema=../../../fern-versions-yml.schema.json +- version: 0.19.0 + changelogEntry: + - type: feat + summary: | + Replaced the flat symbol registry with a graph-backed, scope-aware naming system, delivering deterministic, collision-safe naming and reference resolution. + createdAt: "2025-10-23" + irVersion: 59 + - version: 0.18.2 changelogEntry: - type: fix diff --git a/packages/commons/core-utils/src/SymbolRegistry.ts b/packages/commons/core-utils/src/SymbolRegistry.ts index 4173c5e63872..7325131808a1 100644 --- a/packages/commons/core-utils/src/SymbolRegistry.ts +++ b/packages/commons/core-utils/src/SymbolRegistry.ts @@ -1,5 +1,4 @@ -import { assertDefined } from "./assertDefined"; -import { assertNever } from "./assertNever"; +import { assertDefined, assertNever } from "./assert"; type SymbolId = string; type SymbolName = string; diff --git a/packages/commons/core-utils/src/assert.ts b/packages/commons/core-utils/src/assert.ts new file mode 100644 index 000000000000..4f37eeae08f4 --- /dev/null +++ b/packages/commons/core-utils/src/assert.ts @@ -0,0 +1,30 @@ +/** + * Asserts that a condition is truthy, throwing an exception with the specified message if it is falsy. + */ +export function assert(condition: unknown, message?: string): asserts condition { + if (!condition) { + throw new Error(message ?? "Expected condition to be truthy but got falsy."); + } +} + +export function assertDefined(val: T, message?: string): asserts val is Exclude { + if (val === undefined) { + throw new Error(message ?? "Expected value to be defined but got undefined."); + } +} + +export function assertNonNull(val: T, message?: string): asserts val is Exclude { + if (val === null) { + throw new Error(message ?? "Expected value to be non-null but got null."); + } +} + +export function assertNever(x: never): never { + throw new Error("Unexpected value: " + JSON.stringify(x)); +} + +// biome-ignore lint/suspicious/noEmptyBlockStatements: allow +export function assertNeverNoThrow(_: never): void {} + +// biome-ignore lint/suspicious/noEmptyBlockStatements: allow +export function assertVoidNoThrow(_x: void): void {} diff --git a/packages/commons/core-utils/src/assertDefined.ts b/packages/commons/core-utils/src/assertDefined.ts deleted file mode 100644 index 8fb5b69bbbe1..000000000000 --- a/packages/commons/core-utils/src/assertDefined.ts +++ /dev/null @@ -1,5 +0,0 @@ -export function assertDefined(val: T, message?: string): asserts val is Exclude { - if (val === undefined) { - throw new Error(message ?? "Expected value to be defined but got undefined."); - } -} diff --git a/packages/commons/core-utils/src/assertNever.ts b/packages/commons/core-utils/src/assertNever.ts deleted file mode 100644 index 7732471d022f..000000000000 --- a/packages/commons/core-utils/src/assertNever.ts +++ /dev/null @@ -1,6 +0,0 @@ -export function assertNever(x: never): never { - throw new Error("Unexpected value: " + JSON.stringify(x)); -} - -// biome-ignore lint/suspicious/noEmptyBlockStatements: allow -export function assertNeverNoThrow(_: never): void {} diff --git a/packages/commons/core-utils/src/assertVoidNoThrow.ts b/packages/commons/core-utils/src/assertVoidNoThrow.ts deleted file mode 100644 index f356e8975d04..000000000000 --- a/packages/commons/core-utils/src/assertVoidNoThrow.ts +++ /dev/null @@ -1,2 +0,0 @@ -// biome-ignore lint/suspicious/noEmptyBlockStatements: allow -export function assertVoidNoThrow(_x: void): void {} diff --git a/packages/commons/core-utils/src/index.ts b/packages/commons/core-utils/src/index.ts index 22c834e0a467..0fd75e27739e 100644 --- a/packages/commons/core-utils/src/index.ts +++ b/packages/commons/core-utils/src/index.ts @@ -1,7 +1,5 @@ export { addPrefixToString } from "./addPrefixToString"; -export { assertDefined } from "./assertDefined"; -export { assertNever, assertNeverNoThrow } from "./assertNever"; -export { assertVoidNoThrow } from "./assertVoidNoThrow"; +export { assert, assertDefined, assertNever, assertNeverNoThrow, assertNonNull, assertVoidNoThrow } from "./assert"; export { delay } from "./delay/delay"; export { withMinimumTime } from "./delay/withMinimumTime"; export { EMPTY_ARRAY, EMPTY_OBJECT } from "./empty"; diff --git a/packages/commons/core-utils/src/visitDiscriminatedUnion.ts b/packages/commons/core-utils/src/visitDiscriminatedUnion.ts index 7b619be75440..75e796b05542 100644 --- a/packages/commons/core-utils/src/visitDiscriminatedUnion.ts +++ b/packages/commons/core-utils/src/visitDiscriminatedUnion.ts @@ -1,4 +1,4 @@ -import { assertNever } from "./assertNever"; +import { assertNever } from "./assert"; export type DiscriminatedUnionVisitor, U, Discriminant extends string> = { [D in T[Discriminant]]: (value: Extract>) => U; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb7699f6b8fe..0b1195f36c4b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2125,12 +2125,18 @@ importers: '@fern-fern/ir-sdk': specifier: ^59.7.0 version: 59.7.0 + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 '@types/node': specifier: 18.15.3 version: 18.15.3 depcheck: specifier: ^1.4.7 version: 1.4.7 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 typescript: specifier: 5.9.2 version: 5.9.2 diff --git a/seed/swift-sdk/any-auth/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/any-auth/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/any-auth/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/any-auth/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id" diff --git a/seed/swift-sdk/audiences/Sources/Resources/Foo/FooClient.swift b/seed/swift-sdk/audiences/Sources/Resources/Foo/FooClient.swift index 51f1cf093e86..8451b65093cc 100644 --- a/seed/swift-sdk/audiences/Sources/Resources/Foo/FooClient.swift +++ b/seed/swift-sdk/audiences/Sources/Resources/Foo/FooClient.swift @@ -12,7 +12,7 @@ public final class FooClient: Sendable { method: .post, path: "/", queryParams: [ - "optionalString": .string(optionalString.rawValue) + "optionalString": optionalString.map { .string($0) } ], body: request, requestOptions: requestOptions, diff --git a/seed/swift-sdk/audiences/Tests/Wire/Resources/FolderA/Service/ServiceClientWireTests.swift b/seed/swift-sdk/audiences/Tests/Wire/Resources/FolderA/Service/ServiceClientWireTests.swift index a08bcbdee73f..f6e02ea83248 100644 --- a/seed/swift-sdk/audiences/Tests/Wire/Resources/FolderA/Service/ServiceClientWireTests.swift +++ b/seed/swift-sdk/audiences/Tests/Wire/Resources/FolderA/Service/ServiceClientWireTests.swift @@ -25,7 +25,7 @@ import Audiences let expectedResponse = Response( foo: Optional(Foo( foo: Optional(FolderCFoo( - barProperty: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32") + barProperty: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")! )) )) ) diff --git a/seed/swift-sdk/circular-references-advanced/Sources/Schemas/FieldValue.swift b/seed/swift-sdk/circular-references-advanced/Sources/Schemas/FieldValue.swift index 190c140d7e14..dc6505e2422d 100644 --- a/seed/swift-sdk/circular-references-advanced/Sources/Schemas/FieldValue.swift +++ b/seed/swift-sdk/circular-references-advanced/Sources/Schemas/FieldValue.swift @@ -1,20 +1,20 @@ import Foundation public enum FieldValue: Codable, Hashable, Sendable { - case primitiveValue(PrimitiveValue) - case objectValue(ObjectValue) case containerValue(ContainerValue) + case objectValue(ObjectValue) + case primitiveValue(PrimitiveValue) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "primitive_value": - self = .primitiveValue(try PrimitiveValue(from: decoder)) - case "object_value": - self = .objectValue(try ObjectValue(from: decoder)) case "container_value": self = .containerValue(try ContainerValue(from: decoder)) + case "object_value": + self = .objectValue(try ObjectValue(from: decoder)) + case "primitive_value": + self = .primitiveValue(try PrimitiveValue(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -27,23 +27,23 @@ public enum FieldValue: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .primitiveValue(let data): + case .containerValue(let data): try data.encode(to: encoder) case .objectValue(let data): try data.encode(to: encoder) - case .containerValue(let data): + case .primitiveValue(let data): try data.encode(to: encoder) } } public struct PrimitiveValue: Codable, Hashable, Sendable { public let type: String = "primitive_value" - public let value: PrimitiveValue + public let value: Api.PrimitiveValue /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: PrimitiveValue, + value: Api.PrimitiveValue, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -52,7 +52,7 @@ public enum FieldValue: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(PrimitiveValue.self, forKey: .value) + self.value = try container.decode(Api.PrimitiveValue.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } @@ -99,12 +99,12 @@ public enum FieldValue: Codable, Hashable, Sendable { public struct ContainerValue: Codable, Hashable, Sendable { public let type: String = "container_value" - public let value: ContainerValue + public let value: Api.ContainerValue /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: ContainerValue, + value: Api.ContainerValue, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -113,7 +113,7 @@ public enum FieldValue: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(ContainerValue.self, forKey: .value) + self.value = try container.decode(Api.ContainerValue.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/circular-references/Sources/Schemas/FieldValue.swift b/seed/swift-sdk/circular-references/Sources/Schemas/FieldValue.swift index 190c140d7e14..dc6505e2422d 100644 --- a/seed/swift-sdk/circular-references/Sources/Schemas/FieldValue.swift +++ b/seed/swift-sdk/circular-references/Sources/Schemas/FieldValue.swift @@ -1,20 +1,20 @@ import Foundation public enum FieldValue: Codable, Hashable, Sendable { - case primitiveValue(PrimitiveValue) - case objectValue(ObjectValue) case containerValue(ContainerValue) + case objectValue(ObjectValue) + case primitiveValue(PrimitiveValue) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "primitive_value": - self = .primitiveValue(try PrimitiveValue(from: decoder)) - case "object_value": - self = .objectValue(try ObjectValue(from: decoder)) case "container_value": self = .containerValue(try ContainerValue(from: decoder)) + case "object_value": + self = .objectValue(try ObjectValue(from: decoder)) + case "primitive_value": + self = .primitiveValue(try PrimitiveValue(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -27,23 +27,23 @@ public enum FieldValue: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .primitiveValue(let data): + case .containerValue(let data): try data.encode(to: encoder) case .objectValue(let data): try data.encode(to: encoder) - case .containerValue(let data): + case .primitiveValue(let data): try data.encode(to: encoder) } } public struct PrimitiveValue: Codable, Hashable, Sendable { public let type: String = "primitive_value" - public let value: PrimitiveValue + public let value: Api.PrimitiveValue /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: PrimitiveValue, + value: Api.PrimitiveValue, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -52,7 +52,7 @@ public enum FieldValue: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(PrimitiveValue.self, forKey: .value) + self.value = try container.decode(Api.PrimitiveValue.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } @@ -99,12 +99,12 @@ public enum FieldValue: Codable, Hashable, Sendable { public struct ContainerValue: Codable, Hashable, Sendable { public let type: String = "container_value" - public let value: ContainerValue + public let value: Api.ContainerValue /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: ContainerValue, + value: Api.ContainerValue, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -113,7 +113,7 @@ public enum FieldValue: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(ContainerValue.self, forKey: .value) + self.value = try container.decode(Api.ContainerValue.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/circular-references/Sources/Schemas/JsonLike.swift b/seed/swift-sdk/circular-references/Sources/Schemas/JsonLike.swift index d08324ac9e27..4a5aa0364117 100644 --- a/seed/swift-sdk/circular-references/Sources/Schemas/JsonLike.swift +++ b/seed/swift-sdk/circular-references/Sources/Schemas/JsonLike.swift @@ -1,24 +1,24 @@ import Foundation public enum JsonLike: Codable, Hashable, Sendable { + case bool(Bool) + case int(Int) case jsonLikeArray([JsonLike]) - case stringToJsonLikeDictionary([String: JsonLike]) case string(String) - case int(Int) - case bool(Bool) + case stringToJsonLikeDictionary([String: JsonLike]) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode([JsonLike].self) { + if let value = try? container.decode(Bool.self) { + self = .bool(value) + } else if let value = try? container.decode(Int.self) { + self = .int(value) + } else if let value = try? container.decode([JsonLike].self) { self = .jsonLikeArray(value) - } else if let value = try? container.decode([String: JsonLike].self) { - self = .stringToJsonLikeDictionary(value) } else if let value = try? container.decode(String.self) { self = .string(value) - } else if let value = try? container.decode(Int.self) { - self = .int(value) - } else if let value = try? container.decode(Bool.self) { - self = .bool(value) + } else if let value = try? container.decode([String: JsonLike].self) { + self = .stringToJsonLikeDictionary(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -30,15 +30,15 @@ public enum JsonLike: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .jsonLikeArray(let value): + case .bool(let value): try container.encode(value) - case .stringToJsonLikeDictionary(let value): + case .int(let value): try container.encode(value) - case .string(let value): + case .jsonLikeArray(let value): try container.encode(value) - case .int(let value): + case .string(let value): try container.encode(value) - case .bool(let value): + case .stringToJsonLikeDictionary(let value): try container.encode(value) } } diff --git a/seed/swift-sdk/cross-package-type-names/Sources/Resources/Foo/FooClient.swift b/seed/swift-sdk/cross-package-type-names/Sources/Resources/Foo/FooClient.swift index 51f1cf093e86..8451b65093cc 100644 --- a/seed/swift-sdk/cross-package-type-names/Sources/Resources/Foo/FooClient.swift +++ b/seed/swift-sdk/cross-package-type-names/Sources/Resources/Foo/FooClient.swift @@ -12,7 +12,7 @@ public final class FooClient: Sendable { method: .post, path: "/", queryParams: [ - "optionalString": .string(optionalString.rawValue) + "optionalString": optionalString.map { .string($0) } ], body: request, requestOptions: requestOptions, diff --git a/seed/swift-sdk/cross-package-type-names/Tests/Wire/Resources/FolderA/Service/ServiceClientWireTests.swift b/seed/swift-sdk/cross-package-type-names/Tests/Wire/Resources/FolderA/Service/ServiceClientWireTests.swift index f20334868fe8..a6fa2f163f9c 100644 --- a/seed/swift-sdk/cross-package-type-names/Tests/Wire/Resources/FolderA/Service/ServiceClientWireTests.swift +++ b/seed/swift-sdk/cross-package-type-names/Tests/Wire/Resources/FolderA/Service/ServiceClientWireTests.swift @@ -25,7 +25,7 @@ import CrossPackageTypeNames let expectedResponse = Response( foo: Optional(Foo( foo: Optional(FooType( - barProperty: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32") + barProperty: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")! )) )) ) diff --git a/seed/swift-sdk/cross-package-type-names/Tests/Wire/Resources/FolderD/Service/FolderDServiceClientWireTests.swift b/seed/swift-sdk/cross-package-type-names/Tests/Wire/Resources/FolderD/Service/FolderDServiceClientWireTests.swift index 7a97afa93c87..144830f20b21 100644 --- a/seed/swift-sdk/cross-package-type-names/Tests/Wire/Resources/FolderD/Service/FolderDServiceClientWireTests.swift +++ b/seed/swift-sdk/cross-package-type-names/Tests/Wire/Resources/FolderD/Service/FolderDServiceClientWireTests.swift @@ -25,7 +25,7 @@ import CrossPackageTypeNames let expectedResponse = ResponseType( foo: Optional(Foo( foo: Optional(FooType( - barProperty: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32") + barProperty: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")! )) )) ) diff --git a/seed/swift-sdk/enum/Snippets/Example7.swift b/seed/swift-sdk/enum/Snippets/Example7.swift index 11944cbe6f10..9b007eeec9d4 100644 --- a/seed/swift-sdk/enum/Snippets/Example7.swift +++ b/seed/swift-sdk/enum/Snippets/Example7.swift @@ -4,12 +4,7 @@ import Enum private func main() async throws { let client = EnumClient(baseURL: "https://api.fern.com") - _ = try await client.queryParam.sendList( - operand: , - maybeOperand: , - operandOrColor: , - maybeOperandOrColor: - ) + _ = try await client.queryParam.sendList() } try await main() diff --git a/seed/swift-sdk/enum/Sources/Resources/QueryParam/QueryParamClient.swift b/seed/swift-sdk/enum/Sources/Resources/QueryParam/QueryParamClient.swift index bfe8c192a877..40065ef8c922 100644 --- a/seed/swift-sdk/enum/Sources/Resources/QueryParam/QueryParamClient.swift +++ b/seed/swift-sdk/enum/Sources/Resources/QueryParam/QueryParamClient.swift @@ -12,10 +12,10 @@ public final class QueryParamClient: Sendable { method: .post, path: "/query", queryParams: [ - "operand": .string(operand.rawValue), - "maybeOperand": maybeOperand.map { .string($0.rawValue) }, - "operandOrColor": .string(operandOrColor.rawValue), - "maybeOperandOrColor": maybeOperandOrColor.map { .string($0.rawValue) } + "operand": .unknown(operand.rawValue), + "maybeOperand": maybeOperand.map { .unknown($0.rawValue) }, + "operandOrColor": .unknown(operandOrColor), + "maybeOperandOrColor": maybeOperandOrColor.map { .unknown($0) } ], requestOptions: requestOptions ) @@ -26,10 +26,10 @@ public final class QueryParamClient: Sendable { method: .post, path: "/query-list", queryParams: [ - "operand": .string(operand.rawValue), - "maybeOperand": maybeOperand.map { .string($0.rawValue) }, - "operandOrColor": .string(operandOrColor.rawValue), - "maybeOperandOrColor": maybeOperandOrColor.map { .string($0.rawValue) } + "operand": .unknown(operand.rawValue), + "maybeOperand": maybeOperand.map { .unknown($0.rawValue) }, + "operandOrColor": .unknown(operandOrColor), + "maybeOperandOrColor": maybeOperandOrColor.map { .unknown($0) } ], requestOptions: requestOptions ) diff --git a/seed/swift-sdk/enum/reference.md b/seed/swift-sdk/enum/reference.md index 0086317c2ffa..314ae84db2ff 100644 --- a/seed/swift-sdk/enum/reference.md +++ b/seed/swift-sdk/enum/reference.md @@ -289,12 +289,7 @@ import Enum private func main() async throws { let client = EnumClient() - _ = try await client.queryParam.sendList( - operand: , - maybeOperand: , - operandOrColor: , - maybeOperandOrColor: - ) + _ = try await client.queryParam.sendList() } try await main() diff --git a/seed/swift-sdk/examples/no-custom-config/Snippets/Example17.swift b/seed/swift-sdk/examples/no-custom-config/Snippets/Example17.swift index a2d3fd685dce..fb61c9404484 100644 --- a/seed/swift-sdk/examples/no-custom-config/Snippets/Example17.swift +++ b/seed/swift-sdk/examples/no-custom-config/Snippets/Example17.swift @@ -7,10 +7,7 @@ private func main() async throws { token: "" ) - _ = try await client.service.getMetadata( - shallow: false, - tag: - ) + _ = try await client.service.getMetadata(shallow: false) } try await main() diff --git a/seed/swift-sdk/examples/no-custom-config/Snippets/Example18.swift b/seed/swift-sdk/examples/no-custom-config/Snippets/Example18.swift index 65dec63c5e72..dd9044d09dd8 100644 --- a/seed/swift-sdk/examples/no-custom-config/Snippets/Example18.swift +++ b/seed/swift-sdk/examples/no-custom-config/Snippets/Example18.swift @@ -7,10 +7,7 @@ private func main() async throws { token: "" ) - _ = try await client.service.getMetadata( - shallow: true, - tag: - ) + _ = try await client.service.getMetadata(shallow: true) } try await main() diff --git a/seed/swift-sdk/examples/no-custom-config/Snippets/Example19.swift b/seed/swift-sdk/examples/no-custom-config/Snippets/Example19.swift index 6ad91099b041..6bc984ef3f50 100644 --- a/seed/swift-sdk/examples/no-custom-config/Snippets/Example19.swift +++ b/seed/swift-sdk/examples/no-custom-config/Snippets/Example19.swift @@ -233,8 +233,8 @@ private func main() async throws { ] ), moment: Moment( - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601) ) )) diff --git a/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/BigEntity.swift b/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/BigEntity.swift index dfce7a501b40..f23d9a66b88f 100644 --- a/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/BigEntity.swift +++ b/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/BigEntity.swift @@ -7,7 +7,7 @@ public struct BigEntity: Codable, Hashable, Sendable { public let metadata: MetadataType? public let commonMetadata: Metadata? public let eventInfo: EventInfo? - public let data: DataType? + public let data: Data? public let migration: Migration? public let exception: Exception? public let test: Test? @@ -24,7 +24,7 @@ public struct BigEntity: Codable, Hashable, Sendable { metadata: MetadataType? = nil, commonMetadata: Metadata? = nil, eventInfo: EventInfo? = nil, - data: DataType? = nil, + data: Data? = nil, migration: Migration? = nil, exception: Exception? = nil, test: Test? = nil, @@ -57,7 +57,7 @@ public struct BigEntity: Codable, Hashable, Sendable { self.metadata = try container.decodeIfPresent(MetadataType.self, forKey: .metadata) self.commonMetadata = try container.decodeIfPresent(Metadata.self, forKey: .commonMetadata) self.eventInfo = try container.decodeIfPresent(EventInfo.self, forKey: .eventInfo) - self.data = try container.decodeIfPresent(DataType.self, forKey: .data) + self.data = try container.decodeIfPresent(Data.self, forKey: .data) self.migration = try container.decodeIfPresent(Migration.self, forKey: .migration) self.exception = try container.decodeIfPresent(Exception.self, forKey: .exception) self.test = try container.decodeIfPresent(Test.self, forKey: .test) diff --git a/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/DataType.swift b/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/Data.swift similarity index 79% rename from seed/swift-sdk/examples/no-custom-config/Sources/Schemas/DataType.swift rename to seed/swift-sdk/examples/no-custom-config/Sources/Schemas/Data.swift index 15e55d772d80..c293351af9df 100644 --- a/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/DataType.swift +++ b/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/Data.swift @@ -1,17 +1,17 @@ import Foundation -public enum DataType: Codable, Hashable, Sendable { - case string(String) +public enum Data: Codable, Hashable, Sendable { case base64(Base64) + case string(String) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminant = try container.decode(String.self, forKey: .type) + let discriminant = try container.decode(Swift.String.self, forKey: .type) switch discriminant { - case "string": - self = .string(try String(from: decoder)) case "base64": self = .base64(try Base64(from: decoder)) + case "string": + self = .string(try String(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,22 +24,22 @@ public enum DataType: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .string(let data): - try data.encode(to: encoder) case .base64(let data): try data.encode(to: encoder) + case .string(let data): + try data.encode(to: encoder) } } public struct String: Codable, Hashable, Sendable { - public let type: String = "string" - public let value: String + public let type: Swift.String = "string" + public let value: Swift.String /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( - value: String, - additionalProperties: [String: JSONValue] = .init() + value: Swift.String, + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.value = value self.additionalProperties = additionalProperties @@ -47,7 +47,7 @@ public enum DataType: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(String.self, forKey: .value) + self.value = try container.decode(Swift.String.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } @@ -66,14 +66,14 @@ public enum DataType: Codable, Hashable, Sendable { } public struct Base64: Codable, Hashable, Sendable { - public let type: String = "base64" - public let value: String + public let type: Swift.String = "base64" + public let value: Swift.String /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( - value: String, - additionalProperties: [String: JSONValue] = .init() + value: Swift.String, + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.value = value self.additionalProperties = additionalProperties @@ -81,7 +81,7 @@ public enum DataType: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(String.self, forKey: .value) + self.value = try container.decode(Swift.String.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/EventInfo.swift b/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/EventInfo.swift index 304e82b746fb..9d667d382b59 100644 --- a/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/EventInfo.swift +++ b/seed/swift-sdk/examples/no-custom-config/Sources/Schemas/EventInfo.swift @@ -79,12 +79,12 @@ public enum EventInfo: Codable, Hashable, Sendable { public struct Tag: Codable, Hashable, Sendable { public let type: String = "tag" - public let value: Tag + public let value: Examples.Tag /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: Tag, + value: Examples.Tag, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -93,7 +93,7 @@ public enum EventInfo: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(Tag.self, forKey: .value) + self.value = try container.decode(Examples.Tag.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/examples/no-custom-config/Tests/Wire/Resources/Service/ServiceClient_WireTests.swift b/seed/swift-sdk/examples/no-custom-config/Tests/Wire/Resources/Service/ServiceClient_WireTests.swift index 0696915c1a61..fa913a8a6d9a 100644 --- a/seed/swift-sdk/examples/no-custom-config/Tests/Wire/Resources/Service/ServiceClient_WireTests.swift +++ b/seed/swift-sdk/examples/no-custom-config/Tests/Wire/Resources/Service/ServiceClient_WireTests.swift @@ -217,10 +217,7 @@ import Examples urlSession: stub.urlSession ) let expectedResponse = "..." - let response = try await client.service.getMetadata( - shallow: false, - tag: - ) + let response = try await client.service.getMetadata(shallow: false) try #require(response == expectedResponse) } @@ -248,10 +245,7 @@ import Examples urlSession: stub.urlSession ) let expectedResponse = "string" - let response = try await client.service.getMetadata( - shallow: true, - tag: - ) + let response = try await client.service.getMetadata(shallow: true) try #require(response == expectedResponse) } @@ -534,8 +528,8 @@ import Examples ] ), moment: Moment( - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601) ) )) diff --git a/seed/swift-sdk/examples/no-custom-config/reference.md b/seed/swift-sdk/examples/no-custom-config/reference.md index 5ac5b4927d1f..93b9654f6b60 100644 --- a/seed/swift-sdk/examples/no-custom-config/reference.md +++ b/seed/swift-sdk/examples/no-custom-config/reference.md @@ -533,10 +533,7 @@ import Examples private func main() async throws { let client = ExamplesClient(token: "") - _ = try await client.service.getMetadata( - shallow: false, - tag: - ) + _ = try await client.service.getMetadata(shallow: false) } try await main() @@ -835,8 +832,8 @@ private func main() async throws { ] ), moment: Moment( - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601) ) )) diff --git a/seed/swift-sdk/examples/readme-config/Snippets/Example17.swift b/seed/swift-sdk/examples/readme-config/Snippets/Example17.swift index a2d3fd685dce..fb61c9404484 100644 --- a/seed/swift-sdk/examples/readme-config/Snippets/Example17.swift +++ b/seed/swift-sdk/examples/readme-config/Snippets/Example17.swift @@ -7,10 +7,7 @@ private func main() async throws { token: "" ) - _ = try await client.service.getMetadata( - shallow: false, - tag: - ) + _ = try await client.service.getMetadata(shallow: false) } try await main() diff --git a/seed/swift-sdk/examples/readme-config/Snippets/Example18.swift b/seed/swift-sdk/examples/readme-config/Snippets/Example18.swift index 65dec63c5e72..dd9044d09dd8 100644 --- a/seed/swift-sdk/examples/readme-config/Snippets/Example18.swift +++ b/seed/swift-sdk/examples/readme-config/Snippets/Example18.swift @@ -7,10 +7,7 @@ private func main() async throws { token: "" ) - _ = try await client.service.getMetadata( - shallow: true, - tag: - ) + _ = try await client.service.getMetadata(shallow: true) } try await main() diff --git a/seed/swift-sdk/examples/readme-config/Snippets/Example19.swift b/seed/swift-sdk/examples/readme-config/Snippets/Example19.swift index 6ad91099b041..6bc984ef3f50 100644 --- a/seed/swift-sdk/examples/readme-config/Snippets/Example19.swift +++ b/seed/swift-sdk/examples/readme-config/Snippets/Example19.swift @@ -233,8 +233,8 @@ private func main() async throws { ] ), moment: Moment( - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601) ) )) diff --git a/seed/swift-sdk/examples/readme-config/Sources/Schemas/BigEntity.swift b/seed/swift-sdk/examples/readme-config/Sources/Schemas/BigEntity.swift index dfce7a501b40..f23d9a66b88f 100644 --- a/seed/swift-sdk/examples/readme-config/Sources/Schemas/BigEntity.swift +++ b/seed/swift-sdk/examples/readme-config/Sources/Schemas/BigEntity.swift @@ -7,7 +7,7 @@ public struct BigEntity: Codable, Hashable, Sendable { public let metadata: MetadataType? public let commonMetadata: Metadata? public let eventInfo: EventInfo? - public let data: DataType? + public let data: Data? public let migration: Migration? public let exception: Exception? public let test: Test? @@ -24,7 +24,7 @@ public struct BigEntity: Codable, Hashable, Sendable { metadata: MetadataType? = nil, commonMetadata: Metadata? = nil, eventInfo: EventInfo? = nil, - data: DataType? = nil, + data: Data? = nil, migration: Migration? = nil, exception: Exception? = nil, test: Test? = nil, @@ -57,7 +57,7 @@ public struct BigEntity: Codable, Hashable, Sendable { self.metadata = try container.decodeIfPresent(MetadataType.self, forKey: .metadata) self.commonMetadata = try container.decodeIfPresent(Metadata.self, forKey: .commonMetadata) self.eventInfo = try container.decodeIfPresent(EventInfo.self, forKey: .eventInfo) - self.data = try container.decodeIfPresent(DataType.self, forKey: .data) + self.data = try container.decodeIfPresent(Data.self, forKey: .data) self.migration = try container.decodeIfPresent(Migration.self, forKey: .migration) self.exception = try container.decodeIfPresent(Exception.self, forKey: .exception) self.test = try container.decodeIfPresent(Test.self, forKey: .test) diff --git a/seed/swift-sdk/examples/readme-config/Sources/Schemas/DataType.swift b/seed/swift-sdk/examples/readme-config/Sources/Schemas/Data.swift similarity index 79% rename from seed/swift-sdk/examples/readme-config/Sources/Schemas/DataType.swift rename to seed/swift-sdk/examples/readme-config/Sources/Schemas/Data.swift index 15e55d772d80..c293351af9df 100644 --- a/seed/swift-sdk/examples/readme-config/Sources/Schemas/DataType.swift +++ b/seed/swift-sdk/examples/readme-config/Sources/Schemas/Data.swift @@ -1,17 +1,17 @@ import Foundation -public enum DataType: Codable, Hashable, Sendable { - case string(String) +public enum Data: Codable, Hashable, Sendable { case base64(Base64) + case string(String) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminant = try container.decode(String.self, forKey: .type) + let discriminant = try container.decode(Swift.String.self, forKey: .type) switch discriminant { - case "string": - self = .string(try String(from: decoder)) case "base64": self = .base64(try Base64(from: decoder)) + case "string": + self = .string(try String(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,22 +24,22 @@ public enum DataType: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .string(let data): - try data.encode(to: encoder) case .base64(let data): try data.encode(to: encoder) + case .string(let data): + try data.encode(to: encoder) } } public struct String: Codable, Hashable, Sendable { - public let type: String = "string" - public let value: String + public let type: Swift.String = "string" + public let value: Swift.String /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( - value: String, - additionalProperties: [String: JSONValue] = .init() + value: Swift.String, + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.value = value self.additionalProperties = additionalProperties @@ -47,7 +47,7 @@ public enum DataType: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(String.self, forKey: .value) + self.value = try container.decode(Swift.String.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } @@ -66,14 +66,14 @@ public enum DataType: Codable, Hashable, Sendable { } public struct Base64: Codable, Hashable, Sendable { - public let type: String = "base64" - public let value: String + public let type: Swift.String = "base64" + public let value: Swift.String /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( - value: String, - additionalProperties: [String: JSONValue] = .init() + value: Swift.String, + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.value = value self.additionalProperties = additionalProperties @@ -81,7 +81,7 @@ public enum DataType: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(String.self, forKey: .value) + self.value = try container.decode(Swift.String.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/examples/readme-config/Sources/Schemas/EventInfo.swift b/seed/swift-sdk/examples/readme-config/Sources/Schemas/EventInfo.swift index 304e82b746fb..9d667d382b59 100644 --- a/seed/swift-sdk/examples/readme-config/Sources/Schemas/EventInfo.swift +++ b/seed/swift-sdk/examples/readme-config/Sources/Schemas/EventInfo.swift @@ -79,12 +79,12 @@ public enum EventInfo: Codable, Hashable, Sendable { public struct Tag: Codable, Hashable, Sendable { public let type: String = "tag" - public let value: Tag + public let value: Examples.Tag /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: Tag, + value: Examples.Tag, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -93,7 +93,7 @@ public enum EventInfo: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(Tag.self, forKey: .value) + self.value = try container.decode(Examples.Tag.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/examples/readme-config/Tests/Wire/Resources/Service/ServiceClient_WireTests.swift b/seed/swift-sdk/examples/readme-config/Tests/Wire/Resources/Service/ServiceClient_WireTests.swift index 0696915c1a61..fa913a8a6d9a 100644 --- a/seed/swift-sdk/examples/readme-config/Tests/Wire/Resources/Service/ServiceClient_WireTests.swift +++ b/seed/swift-sdk/examples/readme-config/Tests/Wire/Resources/Service/ServiceClient_WireTests.swift @@ -217,10 +217,7 @@ import Examples urlSession: stub.urlSession ) let expectedResponse = "..." - let response = try await client.service.getMetadata( - shallow: false, - tag: - ) + let response = try await client.service.getMetadata(shallow: false) try #require(response == expectedResponse) } @@ -248,10 +245,7 @@ import Examples urlSession: stub.urlSession ) let expectedResponse = "string" - let response = try await client.service.getMetadata( - shallow: true, - tag: - ) + let response = try await client.service.getMetadata(shallow: true) try #require(response == expectedResponse) } @@ -534,8 +528,8 @@ import Examples ] ), moment: Moment( - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601) ) )) diff --git a/seed/swift-sdk/examples/readme-config/reference.md b/seed/swift-sdk/examples/readme-config/reference.md index 5ac5b4927d1f..93b9654f6b60 100644 --- a/seed/swift-sdk/examples/readme-config/reference.md +++ b/seed/swift-sdk/examples/readme-config/reference.md @@ -533,10 +533,7 @@ import Examples private func main() async throws { let client = ExamplesClient(token: "") - _ = try await client.service.getMetadata( - shallow: false, - tag: - ) + _ = try await client.service.getMetadata(shallow: false) } try await main() @@ -835,8 +832,8 @@ private func main() async throws { ] ), moment: Moment( - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601) ) )) diff --git a/seed/swift-sdk/exhaustive/Snippets/Example13.swift b/seed/swift-sdk/exhaustive/Snippets/Example13.swift index 605578bebabb..4e5cf032291e 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example13.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example13.swift @@ -16,18 +16,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) } diff --git a/seed/swift-sdk/exhaustive/Snippets/Example15.swift b/seed/swift-sdk/exhaustive/Snippets/Example15.swift index c9591ad2034a..f6ffdd20c172 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example15.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example15.swift @@ -14,18 +14,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] )) } diff --git a/seed/swift-sdk/exhaustive/Snippets/Example18.swift b/seed/swift-sdk/exhaustive/Snippets/Example18.swift index 7fbf4beea12e..8b3f173df153 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example18.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example18.swift @@ -16,18 +16,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) )) } diff --git a/seed/swift-sdk/exhaustive/Snippets/Example19.swift b/seed/swift-sdk/exhaustive/Snippets/Example19.swift index 65cbc75e6ebf..2036837ac9ff 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example19.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example19.swift @@ -18,18 +18,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) ) diff --git a/seed/swift-sdk/exhaustive/Snippets/Example2.swift b/seed/swift-sdk/exhaustive/Snippets/Example2.swift index ce640b4abe91..9cdb47ceede8 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example2.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example2.swift @@ -7,7 +7,7 @@ private func main() async throws { token: "" ) - _ = try await client.endpoints.container.getAndReturnSetOfPrimitives(request: ) + _ = try await client.endpoints.container.getAndReturnSetOfPrimitives() } try await main() diff --git a/seed/swift-sdk/exhaustive/Snippets/Example20.swift b/seed/swift-sdk/exhaustive/Snippets/Example20.swift index 22b1cf283612..c00e7a417e48 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example20.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example20.swift @@ -17,18 +17,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ), NestedObjectWithRequiredField( @@ -40,18 +38,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) ]) diff --git a/seed/swift-sdk/exhaustive/Snippets/Example3.swift b/seed/swift-sdk/exhaustive/Snippets/Example3.swift index 5d4966bd4249..630496033792 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example3.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example3.swift @@ -7,7 +7,7 @@ private func main() async throws { token: "" ) - _ = try await client.endpoints.container.getAndReturnSetOfObjects(request: ) + _ = try await client.endpoints.container.getAndReturnSetOfObjects() } try await main() diff --git a/seed/swift-sdk/exhaustive/Snippets/Example35.swift b/seed/swift-sdk/exhaustive/Snippets/Example35.swift index 959beeea8fb6..e85723b0e849 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example35.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example35.swift @@ -7,7 +7,7 @@ private func main() async throws { token: "" ) - _ = try await client.endpoints.primitive.getAndReturnDate(request: try! CalendarDate("2023-01-15")) + _ = try await client.endpoints.primitive.getAndReturnDate(request: CalendarDate("2023-01-15")!) } try await main() diff --git a/seed/swift-sdk/exhaustive/Snippets/Example36.swift b/seed/swift-sdk/exhaustive/Snippets/Example36.swift index bbd5fc7ea4a0..197db759d8ad 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example36.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example36.swift @@ -7,7 +7,7 @@ private func main() async throws { token: "" ) - _ = try await client.endpoints.primitive.getAndReturnUuid(request: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + _ = try await client.endpoints.primitive.getAndReturnUuid(request: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) } try await main() diff --git a/seed/swift-sdk/exhaustive/Snippets/Example44.swift b/seed/swift-sdk/exhaustive/Snippets/Example44.swift index ebc99fa8dd09..d369f169565f 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example44.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example44.swift @@ -17,18 +17,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) )) } diff --git a/seed/swift-sdk/exhaustive/Snippets/Example45.swift b/seed/swift-sdk/exhaustive/Snippets/Example45.swift index ebc99fa8dd09..d369f169565f 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example45.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example45.swift @@ -17,18 +17,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) )) } diff --git a/seed/swift-sdk/exhaustive/Snippets/Example7.swift b/seed/swift-sdk/exhaustive/Snippets/Example7.swift index b93f76f9dbbb..962ba3618ef8 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example7.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example7.swift @@ -14,18 +14,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] )) } diff --git a/seed/swift-sdk/exhaustive/Snippets/Example8.swift b/seed/swift-sdk/exhaustive/Snippets/Example8.swift index 7a6a2f0ceab0..5a3d20e5446a 100644 --- a/seed/swift-sdk/exhaustive/Snippets/Example8.swift +++ b/seed/swift-sdk/exhaustive/Snippets/Example8.swift @@ -14,18 +14,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] )) } diff --git a/seed/swift-sdk/exhaustive/Sources/Schemas/Animal.swift b/seed/swift-sdk/exhaustive/Sources/Schemas/Animal.swift index 43a65b863da2..5cfbb182f23d 100644 --- a/seed/swift-sdk/exhaustive/Sources/Schemas/Animal.swift +++ b/seed/swift-sdk/exhaustive/Sources/Schemas/Animal.swift @@ -1,17 +1,17 @@ import Foundation public enum Animal: Codable, Hashable, Sendable { - case dog(Dog) case cat(Cat) + case dog(Dog) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .animal) switch discriminant { - case "dog": - self = .dog(try Dog(from: decoder)) case "cat": self = .cat(try Cat(from: decoder)) + case "dog": + self = .dog(try Dog(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum Animal: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .dog(let data): - try data.encode(to: encoder) case .cat(let data): try data.encode(to: encoder) + case .dog(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/exhaustive/Sources/Schemas/ErrorType.swift b/seed/swift-sdk/exhaustive/Sources/Schemas/Error.swift similarity index 97% rename from seed/swift-sdk/exhaustive/Sources/Schemas/ErrorType.swift rename to seed/swift-sdk/exhaustive/Sources/Schemas/Error.swift index 7ca242c25525..8e8d8280331b 100644 --- a/seed/swift-sdk/exhaustive/Sources/Schemas/ErrorType.swift +++ b/seed/swift-sdk/exhaustive/Sources/Schemas/Error.swift @@ -1,6 +1,6 @@ import Foundation -public struct ErrorType: Codable, Hashable, Sendable { +public struct Error: Codable, Hashable, Sendable { public let category: ErrorCategory public let code: ErrorCode public let detail: String? diff --git a/seed/swift-sdk/exhaustive/Sources/Schemas/PutResponse.swift b/seed/swift-sdk/exhaustive/Sources/Schemas/PutResponse.swift index c7edc0701d1b..a95be3e06257 100644 --- a/seed/swift-sdk/exhaustive/Sources/Schemas/PutResponse.swift +++ b/seed/swift-sdk/exhaustive/Sources/Schemas/PutResponse.swift @@ -1,12 +1,12 @@ import Foundation public struct PutResponse: Codable, Hashable, Sendable { - public let errors: [ErrorType]? + public let errors: [Error]? /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - errors: [ErrorType]? = nil, + errors: [Error]? = nil, additionalProperties: [String: JSONValue] = .init() ) { self.errors = errors @@ -15,7 +15,7 @@ public struct PutResponse: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.errors = try container.decodeIfPresent([ErrorType].self, forKey: .errors) + self.errors = try container.decodeIfPresent([Error].self, forKey: .errors) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Container/ContainerClientWireTests.swift b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Container/ContainerClientWireTests.swift index 5c8cbf557add..346f1ff93e2f 100644 --- a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Container/ContainerClientWireTests.swift +++ b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Container/ContainerClientWireTests.swift @@ -88,7 +88,7 @@ import Exhaustive urlSession: stub.urlSession ) let expectedResponse = [] - let response = try await client.endpoints.container.getAndReturnSetOfPrimitives(request: ) + let response = try await client.endpoints.container.getAndReturnSetOfPrimitives() try #require(response == expectedResponse) } @@ -111,7 +111,7 @@ import Exhaustive urlSession: stub.urlSession ) let expectedResponse = [] - let response = try await client.endpoints.container.getAndReturnSetOfObjects(request: ) + let response = try await client.endpoints.container.getAndReturnSetOfObjects() try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/HttpMethods/HttpMethodsClientWireTests.swift b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/HttpMethods/HttpMethodsClientWireTests.swift index 95ac96f06cff..c002cba47546 100644 --- a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/HttpMethods/HttpMethodsClientWireTests.swift +++ b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/HttpMethods/HttpMethodsClientWireTests.swift @@ -64,8 +64,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", @@ -125,8 +125,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", @@ -189,8 +189,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", @@ -211,18 +211,16 @@ import Exhaustive double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) try #require(response == expectedResponse) diff --git a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Object/ObjectClientWireTests.swift b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Object/ObjectClientWireTests.swift index 6a5af61529cd..49df645324a7 100644 --- a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Object/ObjectClientWireTests.swift +++ b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Object/ObjectClientWireTests.swift @@ -45,8 +45,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", @@ -65,18 +65,16 @@ import Exhaustive double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] )) try #require(response == expectedResponse) } @@ -190,8 +188,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", @@ -213,18 +211,16 @@ import Exhaustive double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) )) try #require(response == expectedResponse) @@ -277,8 +273,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", @@ -302,18 +298,16 @@ import Exhaustive double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) ) @@ -367,8 +361,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", @@ -391,18 +385,16 @@ import Exhaustive double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ), NestedObjectWithRequiredField( @@ -414,18 +406,16 @@ import Exhaustive double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) ]) diff --git a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Primitive/PrimitiveClientWireTests.swift b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Primitive/PrimitiveClientWireTests.swift index 0744dbc85ed0..34c2fc5f3eee 100644 --- a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Primitive/PrimitiveClientWireTests.swift +++ b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Primitive/PrimitiveClientWireTests.swift @@ -131,8 +131,8 @@ import Exhaustive token: "", urlSession: stub.urlSession ) - let expectedResponse = try! CalendarDate("2023-01-15") - let response = try await client.endpoints.primitive.getAndReturnDate(request: try! CalendarDate("2023-01-15")) + let expectedResponse = CalendarDate("2023-01-15")! + let response = try await client.endpoints.primitive.getAndReturnDate(request: CalendarDate("2023-01-15")!) try #require(response == expectedResponse) } @@ -150,8 +150,8 @@ import Exhaustive token: "", urlSession: stub.urlSession ) - let expectedResponse = UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32") - let response = try await client.endpoints.primitive.getAndReturnUuid(request: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let expectedResponse = UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")! + let response = try await client.endpoints.primitive.getAndReturnUuid(request: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Put/PutClientWireTests.swift b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Put/PutClientWireTests.swift index 749d9aab46ca..0cbba598b347 100644 --- a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Put/PutClientWireTests.swift +++ b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/Endpoints/Put/PutClientWireTests.swift @@ -34,13 +34,13 @@ import Exhaustive ) let expectedResponse = PutResponse( errors: Optional([ - ErrorType( + Error( category: .apiError, code: .internalServerError, detail: Optional("detail"), field: Optional("field") ), - ErrorType( + Error( category: .apiError, code: .internalServerError, detail: Optional("detail"), diff --git a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/InlinedRequests/InlinedRequestsClientWireTests.swift b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/InlinedRequests/InlinedRequestsClientWireTests.swift index 82ad47c39b22..3379783cc82f 100644 --- a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/InlinedRequests/InlinedRequestsClientWireTests.swift +++ b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/InlinedRequests/InlinedRequestsClientWireTests.swift @@ -45,8 +45,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", @@ -68,18 +68,16 @@ import Exhaustive double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) )) try #require(response == expectedResponse) diff --git a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/NoReqBody/NoReqBodyClientWireTests.swift b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/NoReqBody/NoReqBodyClientWireTests.swift index bfe98bb89dff..aa487be5cfd7 100644 --- a/seed/swift-sdk/exhaustive/Tests/Wire/Resources/NoReqBody/NoReqBodyClientWireTests.swift +++ b/seed/swift-sdk/exhaustive/Tests/Wire/Resources/NoReqBody/NoReqBodyClientWireTests.swift @@ -45,8 +45,8 @@ import Exhaustive double: Optional(1.1), bool: Optional(true), datetime: Optional(try! Date("2024-01-15T09:30:00Z", strategy: .iso8601)), - date: Optional(try! CalendarDate("2023-01-15")), - uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")), + date: Optional(CalendarDate("2023-01-15")!), + uuid: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!), base64: Optional("SGVsbG8gd29ybGQh"), list: Optional([ "list", diff --git a/seed/swift-sdk/exhaustive/reference.md b/seed/swift-sdk/exhaustive/reference.md index 7030ca093975..88bb5f985807 100644 --- a/seed/swift-sdk/exhaustive/reference.md +++ b/seed/swift-sdk/exhaustive/reference.md @@ -143,7 +143,7 @@ import Exhaustive private func main() async throws { let client = ExhaustiveClient(token: "") - _ = try await client.endpoints.container.getAndReturnSetOfPrimitives(request: ) + _ = try await client.endpoints.container.getAndReturnSetOfPrimitives() } try await main() @@ -200,7 +200,7 @@ import Exhaustive private func main() async throws { let client = ExhaustiveClient(token: "") - _ = try await client.endpoints.container.getAndReturnSetOfObjects(request: ) + _ = try await client.endpoints.container.getAndReturnSetOfObjects() } try await main() @@ -444,18 +444,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] )) } @@ -520,18 +518,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] )) } @@ -843,18 +839,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) } @@ -986,18 +980,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] )) } @@ -1186,18 +1178,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) )) } @@ -1267,18 +1257,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) ) @@ -1356,18 +1344,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ), NestedObjectWithRequiredField( @@ -1379,18 +1365,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) ) ]) @@ -2428,7 +2412,7 @@ import Exhaustive private func main() async throws { let client = ExhaustiveClient(token: "") - _ = try await client.endpoints.primitive.getAndReturnDate(request: try! CalendarDate("2023-01-15")) + _ = try await client.endpoints.primitive.getAndReturnDate(request: CalendarDate("2023-01-15")!) } try await main() @@ -2485,7 +2469,7 @@ import Exhaustive private func main() async throws { let client = ExhaustiveClient(token: "") - _ = try await client.endpoints.primitive.getAndReturnUuid(request: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + _ = try await client.endpoints.primitive.getAndReturnUuid(request: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) } try await main() @@ -2942,18 +2926,16 @@ private func main() async throws { double: 1.1, bool: true, datetime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), - date: try! CalendarDate("2023-01-15"), - uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + date: CalendarDate("2023-01-15")!, + uuid: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, base64: "SGVsbG8gd29ybGQh", list: [ "list", "list" ], - set: , map: [ 1: "map" - ], - bigint: + ] ) )) } diff --git a/seed/swift-sdk/file-upload-openapi/Snippets/Example0.swift b/seed/swift-sdk/file-upload-openapi/Snippets/Example0.swift index fb52bfc0f507..8f2946f875ae 100644 --- a/seed/swift-sdk/file-upload-openapi/Snippets/Example0.swift +++ b/seed/swift-sdk/file-upload-openapi/Snippets/Example0.swift @@ -5,8 +5,8 @@ private func main() async throws { let client = ApiClient(baseURL: "https://api.fern.com") _ = try await client.fileUploadExample.uploadFile(request: .init( - name: "name", - file: .init(data: Data("".utf8)) + file: .init(data: Data("".utf8)), + name: "name" )) } diff --git a/seed/swift-sdk/file-upload/Snippets/Example1.swift b/seed/swift-sdk/file-upload/Snippets/Example1.swift index 5ff3d17fca04..e4a322de98de 100644 --- a/seed/swift-sdk/file-upload/Snippets/Example1.swift +++ b/seed/swift-sdk/file-upload/Snippets/Example1.swift @@ -4,10 +4,7 @@ import FileUpload private func main() async throws { let client = FileUploadClient(baseURL: "https://api.fern.com") - _ = try await client.service.optionalArgs(request: .init( - imageFile: .init(data: Data("".utf8)), - request: - )) + _ = try await client.service.optionalArgs(request: .init(imageFile: .init(data: Data("".utf8)))) } try await main() diff --git a/seed/swift-sdk/file-upload/Tests/Wire/Resources/Service/ServiceClientWireTests.swift b/seed/swift-sdk/file-upload/Tests/Wire/Resources/Service/ServiceClientWireTests.swift index 09c83c755a6a..b6d595be71a3 100644 --- a/seed/swift-sdk/file-upload/Tests/Wire/Resources/Service/ServiceClientWireTests.swift +++ b/seed/swift-sdk/file-upload/Tests/Wire/Resources/Service/ServiceClientWireTests.swift @@ -17,10 +17,7 @@ import FileUpload urlSession: stub.urlSession ) let expectedResponse = "Foo" - let response = try await client.service.optionalArgs(request: .init( - imageFile: .init(data: Data("".utf8)), - request: - )) + let response = try await client.service.optionalArgs(request: .init(imageFile: .init(data: Data("".utf8)))) try #require(response == expectedResponse) } } \ No newline at end of file diff --git a/seed/swift-sdk/file-upload/reference.md b/seed/swift-sdk/file-upload/reference.md index 7818bc21d0cf..44d2d2cb47a1 100644 --- a/seed/swift-sdk/file-upload/reference.md +++ b/seed/swift-sdk/file-upload/reference.md @@ -76,10 +76,7 @@ import FileUpload private func main() async throws { let client = FileUploadClient() - _ = try await client.service.optionalArgs(request: .init( - imageFile: .init(data: Data("".utf8)), - request: - )) + _ = try await client.service.optionalArgs(request: .init(imageFile: .init(data: Data("".utf8)))) } try await main() diff --git a/seed/swift-sdk/idempotency-headers/Tests/Wire/Resources/Payment/PaymentClientWireTests.swift b/seed/swift-sdk/idempotency-headers/Tests/Wire/Resources/Payment/PaymentClientWireTests.swift index 288866e6a57d..b80bd91783d7 100644 --- a/seed/swift-sdk/idempotency-headers/Tests/Wire/Resources/Payment/PaymentClientWireTests.swift +++ b/seed/swift-sdk/idempotency-headers/Tests/Wire/Resources/Payment/PaymentClientWireTests.swift @@ -17,7 +17,7 @@ import IdempotencyHeaders token: "", urlSession: stub.urlSession ) - let expectedResponse = UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32") + let expectedResponse = UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")! let response = try await client.payment.create(request: .init( amount: 1, currency: .usd diff --git a/seed/swift-sdk/inferred-auth-explicit/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/inferred-auth-explicit/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/inferred-auth-explicit/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/inferred-auth-explicit/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id" diff --git a/seed/swift-sdk/inferred-auth-implicit-no-expiry/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/inferred-auth-implicit-no-expiry/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/inferred-auth-implicit-no-expiry/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/inferred-auth-implicit-no-expiry/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id" diff --git a/seed/swift-sdk/inferred-auth-implicit/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/inferred-auth-implicit/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/inferred-auth-implicit/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/inferred-auth-implicit/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id" diff --git a/seed/swift-sdk/literals-unions/Sources/Schemas/UnionOverLiteral.swift b/seed/swift-sdk/literals-unions/Sources/Schemas/UnionOverLiteral.swift index 8cff228a02a7..b8a5c7c35e01 100644 --- a/seed/swift-sdk/literals-unions/Sources/Schemas/UnionOverLiteral.swift +++ b/seed/swift-sdk/literals-unions/Sources/Schemas/UnionOverLiteral.swift @@ -2,15 +2,15 @@ import Foundation /// An undiscriminated union over a literal. public enum UnionOverLiteral: Codable, Hashable, Sendable { - case string(String) case literalString(LiteralString) + case string(String) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(String.self) { - self = .string(value) - } else if let value = try? container.decode(LiteralString.self) { + if let value = try? container.decode(LiteralString.self) { self = .literalString(value) + } else if let value = try? container.decode(String.self) { + self = .string(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -22,10 +22,10 @@ public enum UnionOverLiteral: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .string(let value): - try container.encode(value) case .literalString(let value): try container.encode(value) + case .string(let value): + try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/mixed-case/Snippets/Example2.swift b/seed/swift-sdk/mixed-case/Snippets/Example2.swift index 7502966ee300..e328d5259166 100644 --- a/seed/swift-sdk/mixed-case/Snippets/Example2.swift +++ b/seed/swift-sdk/mixed-case/Snippets/Example2.swift @@ -6,7 +6,7 @@ private func main() async throws { _ = try await client.service.listResources( pageLimit: 10, - beforeDate: try! CalendarDate("2023-01-01") + beforeDate: CalendarDate("2023-01-01")! ) } diff --git a/seed/swift-sdk/mixed-case/Snippets/Example3.swift b/seed/swift-sdk/mixed-case/Snippets/Example3.swift index e6ef1fc72b4f..df9e8fdd10f8 100644 --- a/seed/swift-sdk/mixed-case/Snippets/Example3.swift +++ b/seed/swift-sdk/mixed-case/Snippets/Example3.swift @@ -6,7 +6,7 @@ private func main() async throws { _ = try await client.service.listResources( pageLimit: 1, - beforeDate: try! CalendarDate("2023-01-15") + beforeDate: CalendarDate("2023-01-15")! ) } diff --git a/seed/swift-sdk/mixed-case/Sources/Schemas/Resource.swift b/seed/swift-sdk/mixed-case/Sources/Schemas/Resource.swift index 4253b5af6421..e80976457e05 100644 --- a/seed/swift-sdk/mixed-case/Sources/Schemas/Resource.swift +++ b/seed/swift-sdk/mixed-case/Sources/Schemas/Resource.swift @@ -1,17 +1,17 @@ import Foundation public enum Resource: Codable, Hashable, Sendable { - case user(User) case organization(Organization) + case user(User) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .resourceType) switch discriminant { - case "user": - self = .user(try User(from: decoder)) case "Organization": self = .organization(try Organization(from: decoder)) + case "user": + self = .user(try User(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum Resource: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .user(let data): - try data.encode(to: encoder) case .organization(let data): try data.encode(to: encoder) + case .user(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/mixed-case/Tests/Wire/Resources/Service/ServiceClientWireTests.swift b/seed/swift-sdk/mixed-case/Tests/Wire/Resources/Service/ServiceClientWireTests.swift index a4afc15aa584..955c06b8dbd5 100644 --- a/seed/swift-sdk/mixed-case/Tests/Wire/Resources/Service/ServiceClientWireTests.swift +++ b/seed/swift-sdk/mixed-case/Tests/Wire/Resources/Service/ServiceClientWireTests.swift @@ -129,7 +129,7 @@ import MixedCase ] let response = try await client.service.listResources( pageLimit: 10, - beforeDate: try! CalendarDate("2023-01-01") + beforeDate: CalendarDate("2023-01-01")! ) try #require(response == expectedResponse) } @@ -200,7 +200,7 @@ import MixedCase ] let response = try await client.service.listResources( pageLimit: 1, - beforeDate: try! CalendarDate("2023-01-15") + beforeDate: CalendarDate("2023-01-15")! ) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/mixed-case/reference.md b/seed/swift-sdk/mixed-case/reference.md index 615fc3e9f3f1..cec999f13e83 100644 --- a/seed/swift-sdk/mixed-case/reference.md +++ b/seed/swift-sdk/mixed-case/reference.md @@ -78,7 +78,7 @@ private func main() async throws { _ = try await client.service.listResources( pageLimit: 10, - beforeDate: try! CalendarDate("2023-01-01") + beforeDate: CalendarDate("2023-01-01")! ) } diff --git a/seed/swift-sdk/mixed-file-directory/Sources/Resources/User/Events/Metadata/MetadataClient.swift b/seed/swift-sdk/mixed-file-directory/Sources/Resources/User/Events/Metadata/MetadataClient.swift index aa10711c70d6..462ebfcda08f 100644 --- a/seed/swift-sdk/mixed-file-directory/Sources/Resources/User/Events/Metadata/MetadataClient.swift +++ b/seed/swift-sdk/mixed-file-directory/Sources/Resources/User/Events/Metadata/MetadataClient.swift @@ -15,7 +15,7 @@ public final class MetadataClient: Sendable { method: .get, path: "/users/events/metadata", queryParams: [ - "id": .string(id.rawValue) + "id": .string(id) ], requestOptions: requestOptions, responseType: Metadata.self diff --git a/seed/swift-sdk/nullable-optional/Sources/Resources/NullableOptional/NullableOptionalClient_.swift b/seed/swift-sdk/nullable-optional/Sources/Resources/NullableOptional/NullableOptionalClient_.swift index 21508b179ad7..8dbc38515d04 100644 --- a/seed/swift-sdk/nullable-optional/Sources/Resources/NullableOptional/NullableOptionalClient_.swift +++ b/seed/swift-sdk/nullable-optional/Sources/Resources/NullableOptional/NullableOptionalClient_.swift @@ -140,9 +140,9 @@ public final class NullableOptionalClient_: Sendable { method: .get, path: "/api/users/filter", queryParams: [ - "role": role.wrappedValue.map { .string($0) }, - "status": status.map { .string($0.rawValue) }, - "secondaryRole": secondaryRole?.wrappedValue.map { .string($0.rawValue) } + "role": role.wrappedValue.map { .unknown($0) }, + "status": status.map { .unknown($0.rawValue) }, + "secondaryRole": secondaryRole?.wrappedValue.map { .unknown($0) } ], requestOptions: requestOptions, responseType: [UserResponse].self diff --git a/seed/swift-sdk/nullable-optional/Sources/Schemas/NotificationMethod.swift b/seed/swift-sdk/nullable-optional/Sources/Schemas/NotificationMethod.swift index afe6d99de484..f4e7e66be8c9 100644 --- a/seed/swift-sdk/nullable-optional/Sources/Schemas/NotificationMethod.swift +++ b/seed/swift-sdk/nullable-optional/Sources/Schemas/NotificationMethod.swift @@ -3,8 +3,8 @@ import Foundation /// Discriminated union for testing nullable unions public enum NotificationMethod: Codable, Hashable, Sendable { case email(Email) - case sms(Sms) case push(Push) + case sms(Sms) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -12,10 +12,10 @@ public enum NotificationMethod: Codable, Hashable, Sendable { switch discriminant { case "email": self = .email(try Email(from: decoder)) - case "sms": - self = .sms(try Sms(from: decoder)) case "push": self = .push(try Push(from: decoder)) + case "sms": + self = .sms(try Sms(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -30,10 +30,10 @@ public enum NotificationMethod: Codable, Hashable, Sendable { switch self { case .email(let data): try data.encode(to: encoder) - case .sms(let data): - try data.encode(to: encoder) case .push(let data): try data.encode(to: encoder) + case .sms(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/nullable-optional/Sources/Schemas/SearchResult.swift b/seed/swift-sdk/nullable-optional/Sources/Schemas/SearchResult.swift index d97e79a9572c..6d928e2bffb5 100644 --- a/seed/swift-sdk/nullable-optional/Sources/Schemas/SearchResult.swift +++ b/seed/swift-sdk/nullable-optional/Sources/Schemas/SearchResult.swift @@ -2,20 +2,20 @@ import Foundation /// Undiscriminated union for testing public enum SearchResult: Codable, Hashable, Sendable { - case user(User) - case organization(Organization) case document(Document) + case organization(Organization) + case user(User) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "user": - self = .user(try User(from: decoder)) - case "organization": - self = .organization(try Organization(from: decoder)) case "document": self = .document(try Document(from: decoder)) + case "organization": + self = .organization(try Organization(from: decoder)) + case "user": + self = .user(try User(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -28,11 +28,11 @@ public enum SearchResult: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .user(let data): + case .document(let data): try data.encode(to: encoder) case .organization(let data): try data.encode(to: encoder) - case .document(let data): + case .user(let data): try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/nullable/Package.swift b/seed/swift-sdk/nullable/Package.swift index 6fa969823646..c44499c6dcc9 100644 --- a/seed/swift-sdk/nullable/Package.swift +++ b/seed/swift-sdk/nullable/Package.swift @@ -3,7 +3,7 @@ import PackageDescription let package = Package( - name: "NullableApi", + name: "Nullable", platforms: [ .iOS(.v15), .macOS(.v12), @@ -12,19 +12,19 @@ let package = Package( ], products: [ .library( - name: "NullableApi", - targets: ["NullableApi"] + name: "Nullable", + targets: ["Nullable"] ) ], dependencies: [], targets: [ .target( - name: "NullableApi", + name: "Nullable", path: "Sources" ), .testTarget( - name: "NullableApiTests", - dependencies: ["NullableApi"], + name: "NullableTests", + dependencies: ["Nullable"], path: "Tests" ) ] diff --git a/seed/swift-sdk/nullable/README.md b/seed/swift-sdk/nullable/README.md index d20fcdeba2f4..30cd4cebc116 100644 --- a/seed/swift-sdk/nullable/README.md +++ b/seed/swift-sdk/nullable/README.md @@ -71,7 +71,7 @@ try await main() The SDK exports all request types as Swift structs. Simply import the SDK module to access them: ```swift -import NullableApi +import Nullable let request = Requests.CreateUserRequest( ... @@ -120,7 +120,7 @@ The SDK allows you to customize the underlying `URLSession` used for HTTP reques ```swift import Foundation -import NullableApi +import Nullable let client = NullableClient( ..., diff --git a/seed/swift-sdk/nullable/Snippets/Example0.swift b/seed/swift-sdk/nullable/Snippets/Example0.swift index 6306f36d0f52..5946f3b7e728 100644 --- a/seed/swift-sdk/nullable/Snippets/Example0.swift +++ b/seed/swift-sdk/nullable/Snippets/Example0.swift @@ -5,10 +5,7 @@ private func main() async throws { let client = NullableClient(baseURL: "https://api.fern.com") _ = try await client.nullable.getUsers( - usernames: , avatar: "avatar", - activated: , - tags: , extra: .value(true) ) } diff --git a/seed/swift-sdk/nullable/Sources/Schemas/WeirdNumber.swift b/seed/swift-sdk/nullable/Sources/Schemas/WeirdNumber.swift index db920a3674eb..e9c8d810c271 100644 --- a/seed/swift-sdk/nullable/Sources/Schemas/WeirdNumber.swift +++ b/seed/swift-sdk/nullable/Sources/Schemas/WeirdNumber.swift @@ -1,21 +1,21 @@ import Foundation public enum WeirdNumber: Codable, Hashable, Sendable { + case double(Double) case int(Int) case nullableFloat(Nullable) case optionalNullableString(Nullable?) - case double(Double) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(Int.self) { + if let value = try? container.decode(Double.self) { + self = .double(value) + } else if let value = try? container.decode(Int.self) { self = .int(value) } else if let value = try? container.decode(Nullable.self) { self = .nullableFloat(value) } else if let value = try? container.decode(Nullable?.self) { self = .optionalNullableString(value) - } else if let value = try? container.decode(Double.self) { - self = .double(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -27,14 +27,14 @@ public enum WeirdNumber: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { + case .double(let value): + try container.encode(value) case .int(let value): try container.encode(value) case .nullableFloat(let value): try container.encode(value) case .optionalNullableString(let value): try container.encode(value) - case .double(let value): - try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/nullable/Tests/Wire/Resources/Nullable/NullableClient_WireTests.swift b/seed/swift-sdk/nullable/Tests/Wire/Resources/Nullable/NullableClient_WireTests.swift index be12d89354e8..fb1c29893e69 100644 --- a/seed/swift-sdk/nullable/Tests/Wire/Resources/Nullable/NullableClient_WireTests.swift +++ b/seed/swift-sdk/nullable/Tests/Wire/Resources/Nullable/NullableClient_WireTests.swift @@ -1,6 +1,6 @@ import Foundation import Testing -import NullableApi +import Nullable @Suite("NullableClient_ Wire Tests") struct NullableClient_WireTests { @Test func getUsers1() async throws -> Void { @@ -148,10 +148,7 @@ import NullableApi ) ] let response = try await client.nullable.getUsers( - usernames: , avatar: "avatar", - activated: , - tags: , extra: .value(true) ) try #require(response == expectedResponse) diff --git a/seed/swift-sdk/nullable/reference.md b/seed/swift-sdk/nullable/reference.md index ac74993280d2..6a0f9cb612f4 100644 --- a/seed/swift-sdk/nullable/reference.md +++ b/seed/swift-sdk/nullable/reference.md @@ -20,10 +20,7 @@ private func main() async throws { let client = NullableClient() _ = try await client.nullable.getUsers( - usernames: , avatar: "avatar", - activated: , - tags: , extra: .value(true) ) } diff --git a/seed/swift-sdk/oauth-client-credentials-custom/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/oauth-client-credentials-custom/Sources/Requests/Requests+GetTokenRequest.swift index 4300b4742194..a890bdab4e91 100644 --- a/seed/swift-sdk/oauth-client-credentials-custom/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/oauth-client-credentials-custom/Sources/Requests/Requests+GetTokenRequest.swift @@ -56,14 +56,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case cid diff --git a/seed/swift-sdk/oauth-client-credentials-environment-variables/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/oauth-client-credentials-environment-variables/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/oauth-client-credentials-environment-variables/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/oauth-client-credentials-environment-variables/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id" diff --git a/seed/swift-sdk/oauth-client-credentials-nested-root/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/oauth-client-credentials-nested-root/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/oauth-client-credentials-nested-root/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/oauth-client-credentials-nested-root/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id" diff --git a/seed/swift-sdk/oauth-client-credentials-with-variables/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/oauth-client-credentials-with-variables/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/oauth-client-credentials-with-variables/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/oauth-client-credentials-with-variables/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id" diff --git a/seed/swift-sdk/oauth-client-credentials/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/oauth-client-credentials/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/oauth-client-credentials/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/oauth-client-credentials/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id" diff --git a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift index a4c92a0a81df..ebc57ce09b4d 100644 --- a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift +++ b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift @@ -14,7 +14,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -51,7 +51,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -66,7 +66,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .double($0) }, "per_page": perPage.map { .double($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -91,7 +91,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponse.self @@ -105,7 +105,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponse.self diff --git a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Resources/Users/UsersClient.swift b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Resources/Users/UsersClient.swift index 6e11a390eda5..3ca317251838 100644 --- a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Resources/Users/UsersClient.swift +++ b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Resources/Users/UsersClient.swift @@ -14,7 +14,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -51,7 +51,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -66,7 +66,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .double($0) }, "per_page": perPage.map { .double($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -91,7 +91,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponseType.self @@ -105,7 +105,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponseType.self diff --git a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Schemas/SearchRequestQuery.swift b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Schemas/SearchRequestQuery.swift index e69f9aa26bd6..d38d0545ed5e 100644 --- a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Schemas/SearchRequestQuery.swift +++ b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Sources/Schemas/SearchRequestQuery.swift @@ -1,15 +1,15 @@ import Foundation public enum SearchRequestQuery: Codable, Hashable, Sendable { - case singleFilterSearchRequest(SingleFilterSearchRequest) case multipleFilterSearchRequest(MultipleFilterSearchRequest) + case singleFilterSearchRequest(SingleFilterSearchRequest) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(SingleFilterSearchRequest.self) { - self = .singleFilterSearchRequest(value) - } else if let value = try? container.decode(MultipleFilterSearchRequest.self) { + if let value = try? container.decode(MultipleFilterSearchRequest.self) { self = .multipleFilterSearchRequest(value) + } else if let value = try? container.decode(SingleFilterSearchRequest.self) { + self = .singleFilterSearchRequest(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -21,10 +21,10 @@ public enum SearchRequestQuery: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .singleFilterSearchRequest(let value): - try container.encode(value) case .multipleFilterSearchRequest(let value): try container.encode(value) + case .singleFilterSearchRequest(let value): + try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift index 5a92a9759a6b..3de84d896365 100644 --- a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift +++ b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift @@ -589,9 +589,9 @@ import Pagination ) ] ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.inlineUsers.inlineUsers.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.inlineUsers.inlineUsers.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } @@ -638,9 +638,9 @@ import Pagination ) ]) ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.inlineUsers.inlineUsers.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.inlineUsers.inlineUsers.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Tests/Wire/Resources/Users/UsersClientWireTests.swift b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Tests/Wire/Resources/Users/UsersClientWireTests.swift index 7d10e72905ae..d8a72f1ef32c 100644 --- a/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Tests/Wire/Resources/Users/UsersClientWireTests.swift +++ b/seed/swift-sdk/pagination/custom-pager-with-exception-handler/Tests/Wire/Resources/Users/UsersClientWireTests.swift @@ -557,9 +557,9 @@ import Pagination ) ] ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.users.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.users.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } @@ -606,9 +606,9 @@ import Pagination ) ]) ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.users.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.users.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/pagination/custom-pager/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift b/seed/swift-sdk/pagination/custom-pager/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift index a4c92a0a81df..ebc57ce09b4d 100644 --- a/seed/swift-sdk/pagination/custom-pager/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift +++ b/seed/swift-sdk/pagination/custom-pager/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift @@ -14,7 +14,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -51,7 +51,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -66,7 +66,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .double($0) }, "per_page": perPage.map { .double($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -91,7 +91,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponse.self @@ -105,7 +105,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponse.self diff --git a/seed/swift-sdk/pagination/custom-pager/Sources/Resources/Users/UsersClient.swift b/seed/swift-sdk/pagination/custom-pager/Sources/Resources/Users/UsersClient.swift index 6e11a390eda5..3ca317251838 100644 --- a/seed/swift-sdk/pagination/custom-pager/Sources/Resources/Users/UsersClient.swift +++ b/seed/swift-sdk/pagination/custom-pager/Sources/Resources/Users/UsersClient.swift @@ -14,7 +14,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -51,7 +51,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -66,7 +66,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .double($0) }, "per_page": perPage.map { .double($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -91,7 +91,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponseType.self @@ -105,7 +105,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponseType.self diff --git a/seed/swift-sdk/pagination/custom-pager/Sources/Schemas/SearchRequestQuery.swift b/seed/swift-sdk/pagination/custom-pager/Sources/Schemas/SearchRequestQuery.swift index e69f9aa26bd6..d38d0545ed5e 100644 --- a/seed/swift-sdk/pagination/custom-pager/Sources/Schemas/SearchRequestQuery.swift +++ b/seed/swift-sdk/pagination/custom-pager/Sources/Schemas/SearchRequestQuery.swift @@ -1,15 +1,15 @@ import Foundation public enum SearchRequestQuery: Codable, Hashable, Sendable { - case singleFilterSearchRequest(SingleFilterSearchRequest) case multipleFilterSearchRequest(MultipleFilterSearchRequest) + case singleFilterSearchRequest(SingleFilterSearchRequest) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(SingleFilterSearchRequest.self) { - self = .singleFilterSearchRequest(value) - } else if let value = try? container.decode(MultipleFilterSearchRequest.self) { + if let value = try? container.decode(MultipleFilterSearchRequest.self) { self = .multipleFilterSearchRequest(value) + } else if let value = try? container.decode(SingleFilterSearchRequest.self) { + self = .singleFilterSearchRequest(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -21,10 +21,10 @@ public enum SearchRequestQuery: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .singleFilterSearchRequest(let value): - try container.encode(value) case .multipleFilterSearchRequest(let value): try container.encode(value) + case .singleFilterSearchRequest(let value): + try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/pagination/custom-pager/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift b/seed/swift-sdk/pagination/custom-pager/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift index 5a92a9759a6b..3de84d896365 100644 --- a/seed/swift-sdk/pagination/custom-pager/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift +++ b/seed/swift-sdk/pagination/custom-pager/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift @@ -589,9 +589,9 @@ import Pagination ) ] ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.inlineUsers.inlineUsers.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.inlineUsers.inlineUsers.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } @@ -638,9 +638,9 @@ import Pagination ) ]) ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.inlineUsers.inlineUsers.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.inlineUsers.inlineUsers.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/pagination/custom-pager/Tests/Wire/Resources/Users/UsersClientWireTests.swift b/seed/swift-sdk/pagination/custom-pager/Tests/Wire/Resources/Users/UsersClientWireTests.swift index 7d10e72905ae..d8a72f1ef32c 100644 --- a/seed/swift-sdk/pagination/custom-pager/Tests/Wire/Resources/Users/UsersClientWireTests.swift +++ b/seed/swift-sdk/pagination/custom-pager/Tests/Wire/Resources/Users/UsersClientWireTests.swift @@ -557,9 +557,9 @@ import Pagination ) ] ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.users.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.users.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } @@ -606,9 +606,9 @@ import Pagination ) ]) ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.users.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.users.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/pagination/no-custom-config/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift b/seed/swift-sdk/pagination/no-custom-config/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift index a4c92a0a81df..ebc57ce09b4d 100644 --- a/seed/swift-sdk/pagination/no-custom-config/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift +++ b/seed/swift-sdk/pagination/no-custom-config/Sources/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClient.swift @@ -14,7 +14,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -51,7 +51,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -66,7 +66,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .double($0) }, "per_page": perPage.map { .double($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -91,7 +91,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponse.self @@ -105,7 +105,7 @@ public final class InlineUsersInlineUsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponse.self diff --git a/seed/swift-sdk/pagination/no-custom-config/Sources/Resources/Users/UsersClient.swift b/seed/swift-sdk/pagination/no-custom-config/Sources/Resources/Users/UsersClient.swift index 6e11a390eda5..3ca317251838 100644 --- a/seed/swift-sdk/pagination/no-custom-config/Sources/Resources/Users/UsersClient.swift +++ b/seed/swift-sdk/pagination/no-custom-config/Sources/Resources/Users/UsersClient.swift @@ -14,7 +14,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -51,7 +51,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "per_page": perPage.map { .int($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -66,7 +66,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .double($0) }, "per_page": perPage.map { .double($0) }, - "order": order.map { .string($0.rawValue) }, + "order": order.map { .unknown($0.rawValue) }, "starting_after": startingAfter.map { .string($0) } ], requestOptions: requestOptions, @@ -91,7 +91,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponseType.self @@ -105,7 +105,7 @@ public final class UsersClient: Sendable { queryParams: [ "page": page.map { .int($0) }, "limit": limit.map { .int($0) }, - "order": order.map { .string($0.rawValue) } + "order": order.map { .unknown($0.rawValue) } ], requestOptions: requestOptions, responseType: ListUsersPaginationResponseType.self diff --git a/seed/swift-sdk/pagination/no-custom-config/Sources/Schemas/SearchRequestQuery.swift b/seed/swift-sdk/pagination/no-custom-config/Sources/Schemas/SearchRequestQuery.swift index e69f9aa26bd6..d38d0545ed5e 100644 --- a/seed/swift-sdk/pagination/no-custom-config/Sources/Schemas/SearchRequestQuery.swift +++ b/seed/swift-sdk/pagination/no-custom-config/Sources/Schemas/SearchRequestQuery.swift @@ -1,15 +1,15 @@ import Foundation public enum SearchRequestQuery: Codable, Hashable, Sendable { - case singleFilterSearchRequest(SingleFilterSearchRequest) case multipleFilterSearchRequest(MultipleFilterSearchRequest) + case singleFilterSearchRequest(SingleFilterSearchRequest) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(SingleFilterSearchRequest.self) { - self = .singleFilterSearchRequest(value) - } else if let value = try? container.decode(MultipleFilterSearchRequest.self) { + if let value = try? container.decode(MultipleFilterSearchRequest.self) { self = .multipleFilterSearchRequest(value) + } else if let value = try? container.decode(SingleFilterSearchRequest.self) { + self = .singleFilterSearchRequest(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -21,10 +21,10 @@ public enum SearchRequestQuery: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .singleFilterSearchRequest(let value): - try container.encode(value) case .multipleFilterSearchRequest(let value): try container.encode(value) + case .singleFilterSearchRequest(let value): + try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/pagination/no-custom-config/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift b/seed/swift-sdk/pagination/no-custom-config/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift index 5a92a9759a6b..3de84d896365 100644 --- a/seed/swift-sdk/pagination/no-custom-config/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift +++ b/seed/swift-sdk/pagination/no-custom-config/Tests/Wire/Resources/InlineUsers/InlineUsers/InlineUsersInlineUsersClientWireTests.swift @@ -589,9 +589,9 @@ import Pagination ) ] ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.inlineUsers.inlineUsers.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.inlineUsers.inlineUsers.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } @@ -638,9 +638,9 @@ import Pagination ) ]) ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.inlineUsers.inlineUsers.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.inlineUsers.inlineUsers.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/pagination/no-custom-config/Tests/Wire/Resources/Users/UsersClientWireTests.swift b/seed/swift-sdk/pagination/no-custom-config/Tests/Wire/Resources/Users/UsersClientWireTests.swift index 7d10e72905ae..d8a72f1ef32c 100644 --- a/seed/swift-sdk/pagination/no-custom-config/Tests/Wire/Resources/Users/UsersClientWireTests.swift +++ b/seed/swift-sdk/pagination/no-custom-config/Tests/Wire/Resources/Users/UsersClientWireTests.swift @@ -557,9 +557,9 @@ import Pagination ) ] ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.users.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.users.listWithExtendedResults(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } @@ -606,9 +606,9 @@ import Pagination ) ]) ), - next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + next: Optional(UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) ) - let response = try await client.users.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")) + let response = try await client.users.listWithExtendedResultsAndOptionalData(cursor: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/property-access/Sources/Schemas/UserOrAdmin.swift b/seed/swift-sdk/property-access/Sources/Schemas/UserOrAdmin.swift index 29a14fc9be2d..3c18ebd67b20 100644 --- a/seed/swift-sdk/property-access/Sources/Schemas/UserOrAdmin.swift +++ b/seed/swift-sdk/property-access/Sources/Schemas/UserOrAdmin.swift @@ -2,15 +2,15 @@ import Foundation /// Example of an undiscriminated union public enum UserOrAdmin: Codable, Hashable, Sendable { - case user(User) case admin(Admin) + case user(User) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(User.self) { - self = .user(value) - } else if let value = try? container.decode(Admin.self) { + if let value = try? container.decode(Admin.self) { self = .admin(value) + } else if let value = try? container.decode(User.self) { + self = .user(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -22,10 +22,10 @@ public enum UserOrAdmin: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .user(let value): - try container.encode(value) case .admin(let value): try container.encode(value) + case .user(let value): + try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/property-access/Sources/Schemas/UserOrAdminDiscriminated.swift b/seed/swift-sdk/property-access/Sources/Schemas/UserOrAdminDiscriminated.swift index 602e220f06d2..eae8bd690adb 100644 --- a/seed/swift-sdk/property-access/Sources/Schemas/UserOrAdminDiscriminated.swift +++ b/seed/swift-sdk/property-access/Sources/Schemas/UserOrAdminDiscriminated.swift @@ -2,20 +2,20 @@ import Foundation /// Example of an discriminated union public enum UserOrAdminDiscriminated: Codable, Hashable, Sendable { - case user(User) case admin(Admin) case empty(Empty) + case user(User) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "user": - self = .user(try User(from: decoder)) case "admin": self = .admin(try Admin(from: decoder)) case "empty": self = .empty(try Empty(from: decoder)) + case "user": + self = .user(try User(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -28,12 +28,12 @@ public enum UserOrAdminDiscriminated: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .user(let data): - try data.encode(to: encoder) case .admin(let data): try data.encode(to: encoder) case .empty(let data): try data.encode(to: encoder) + case .user(let data): + try data.encode(to: encoder) } } @@ -95,12 +95,12 @@ public enum UserOrAdminDiscriminated: Codable, Hashable, Sendable { public struct Admin: Codable, Hashable, Sendable { public let type: String = "admin" - public let admin: Admin + public let admin: PropertyAccess.Admin /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - admin: Admin, + admin: PropertyAccess.Admin, additionalProperties: [String: JSONValue] = .init() ) { self.admin = admin @@ -109,7 +109,7 @@ public enum UserOrAdminDiscriminated: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.admin = try container.decode(Admin.self, forKey: .admin) + self.admin = try container.decode(PropertyAccess.Admin.self, forKey: .admin) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/query-parameters-openapi-as-objects/README.md b/seed/swift-sdk/query-parameters-openapi-as-objects/README.md index b32ace9b47ba..fe1207372fb7 100644 --- a/seed/swift-sdk/query-parameters-openapi-as-objects/README.md +++ b/seed/swift-sdk/query-parameters-openapi-as-objects/README.md @@ -52,7 +52,6 @@ private func main() async throws { "tags" ] ), - userList: , optionalDeadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), keyValue: [ "keyValue": "keyValue" @@ -75,8 +74,6 @@ private func main() async throws { "tags" ] ), - excludeUser: , - filter: , neighbor: SearchRequestNeighbor.user( User( name: "name", diff --git a/seed/swift-sdk/query-parameters-openapi-as-objects/Snippets/Example0.swift b/seed/swift-sdk/query-parameters-openapi-as-objects/Snippets/Example0.swift index a0aefc3c5a06..fc37989326ec 100644 --- a/seed/swift-sdk/query-parameters-openapi-as-objects/Snippets/Example0.swift +++ b/seed/swift-sdk/query-parameters-openapi-as-objects/Snippets/Example0.swift @@ -17,7 +17,6 @@ private func main() async throws { "tags" ] ), - userList: , optionalDeadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), keyValue: [ "keyValue": "keyValue" @@ -40,8 +39,6 @@ private func main() async throws { "tags" ] ), - excludeUser: , - filter: , neighbor: SearchRequestNeighbor.user( User( name: "name", diff --git a/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/ApiClient.swift b/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/ApiClient.swift index f66aef0e45f8..3afe3a121d77 100644 --- a/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/ApiClient.swift +++ b/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/ApiClient.swift @@ -63,17 +63,17 @@ public final class ApiClient: Sendable { "date": .string(date), "deadline": .date(deadline), "bytes": .string(bytes), - "user": .string(user.rawValue), - "userList": userList.map { .string($0.rawValue) }, + "user": .unknown(user), + "userList": userList.map { .unknown($0) }, "optionalDeadline": optionalDeadline.map { .date($0) }, "keyValue": keyValue.map { .unknown($0) }, "optionalString": optionalString.map { .string($0) }, - "nestedUser": nestedUser.map { .string($0.rawValue) }, - "optionalUser": optionalUser.map { .string($0.rawValue) }, - "excludeUser": excludeUser.map { .string($0.rawValue) }, + "nestedUser": nestedUser.map { .unknown($0) }, + "optionalUser": optionalUser.map { .unknown($0) }, + "excludeUser": excludeUser.map { .unknown($0) }, "filter": filter.map { .string($0) }, - "neighbor": neighbor.map { .string($0.rawValue) }, - "neighborRequired": .string(neighborRequired.rawValue) + "neighbor": neighbor.map { .unknown($0) }, + "neighborRequired": .unknown(neighborRequired) ], requestOptions: requestOptions, responseType: SearchResponse.self diff --git a/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/Schemas/SearchRequestNeighbor.swift b/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/Schemas/SearchRequestNeighbor.swift index c95c8344a29f..009a82976fe6 100644 --- a/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/Schemas/SearchRequestNeighbor.swift +++ b/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/Schemas/SearchRequestNeighbor.swift @@ -1,21 +1,21 @@ import Foundation public enum SearchRequestNeighbor: Codable, Hashable, Sendable { - case user(User) + case int(Int) case nestedUser(NestedUser) case string(String) - case int(Int) + case user(User) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(User.self) { - self = .user(value) + if let value = try? container.decode(Int.self) { + self = .int(value) } else if let value = try? container.decode(NestedUser.self) { self = .nestedUser(value) } else if let value = try? container.decode(String.self) { self = .string(value) - } else if let value = try? container.decode(Int.self) { - self = .int(value) + } else if let value = try? container.decode(User.self) { + self = .user(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -27,13 +27,13 @@ public enum SearchRequestNeighbor: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .user(let value): + case .int(let value): try container.encode(value) case .nestedUser(let value): try container.encode(value) case .string(let value): try container.encode(value) - case .int(let value): + case .user(let value): try container.encode(value) } } diff --git a/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/Schemas/SearchRequestNeighborRequired.swift b/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/Schemas/SearchRequestNeighborRequired.swift index 0236eca5725c..bbc8697c7cd0 100644 --- a/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/Schemas/SearchRequestNeighborRequired.swift +++ b/seed/swift-sdk/query-parameters-openapi-as-objects/Sources/Schemas/SearchRequestNeighborRequired.swift @@ -1,21 +1,21 @@ import Foundation public enum SearchRequestNeighborRequired: Codable, Hashable, Sendable { - case user(User) + case int(Int) case nestedUser(NestedUser) case string(String) - case int(Int) + case user(User) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(User.self) { - self = .user(value) + if let value = try? container.decode(Int.self) { + self = .int(value) } else if let value = try? container.decode(NestedUser.self) { self = .nestedUser(value) } else if let value = try? container.decode(String.self) { self = .string(value) - } else if let value = try? container.decode(Int.self) { - self = .int(value) + } else if let value = try? container.decode(User.self) { + self = .user(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -27,13 +27,13 @@ public enum SearchRequestNeighborRequired: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .user(let value): + case .int(let value): try container.encode(value) case .nestedUser(let value): try container.encode(value) case .string(let value): try container.encode(value) - case .int(let value): + case .user(let value): try container.encode(value) } } diff --git a/seed/swift-sdk/query-parameters-openapi-as-objects/reference.md b/seed/swift-sdk/query-parameters-openapi-as-objects/reference.md index 8c0e7ef20d57..7812aee1655c 100644 --- a/seed/swift-sdk/query-parameters-openapi-as-objects/reference.md +++ b/seed/swift-sdk/query-parameters-openapi-as-objects/reference.md @@ -31,7 +31,6 @@ private func main() async throws { "tags" ] ), - userList: , optionalDeadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), keyValue: [ "keyValue": "keyValue" @@ -54,8 +53,6 @@ private func main() async throws { "tags" ] ), - excludeUser: , - filter: , neighbor: SearchRequestNeighbor.user( User( name: "name", diff --git a/seed/swift-sdk/query-parameters-openapi/README.md b/seed/swift-sdk/query-parameters-openapi/README.md index aab9bfea1748..b9f009ee4485 100644 --- a/seed/swift-sdk/query-parameters-openapi/README.md +++ b/seed/swift-sdk/query-parameters-openapi/README.md @@ -52,7 +52,6 @@ private func main() async throws { "tags" ] ), - userList: , optionalDeadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), keyValue: [ "keyValue": "keyValue" @@ -75,8 +74,6 @@ private func main() async throws { "tags" ] ), - excludeUser: , - filter: , neighbor: User( name: "name", tags: [ diff --git a/seed/swift-sdk/query-parameters-openapi/Snippets/Example0.swift b/seed/swift-sdk/query-parameters-openapi/Snippets/Example0.swift index 988781a8e3b2..ace134a70f92 100644 --- a/seed/swift-sdk/query-parameters-openapi/Snippets/Example0.swift +++ b/seed/swift-sdk/query-parameters-openapi/Snippets/Example0.swift @@ -17,7 +17,6 @@ private func main() async throws { "tags" ] ), - userList: , optionalDeadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), keyValue: [ "keyValue": "keyValue" @@ -40,8 +39,6 @@ private func main() async throws { "tags" ] ), - excludeUser: , - filter: , neighbor: User( name: "name", tags: [ diff --git a/seed/swift-sdk/query-parameters-openapi/Sources/ApiClient.swift b/seed/swift-sdk/query-parameters-openapi/Sources/ApiClient.swift index e5d826716bdc..dfc5e1573e23 100644 --- a/seed/swift-sdk/query-parameters-openapi/Sources/ApiClient.swift +++ b/seed/swift-sdk/query-parameters-openapi/Sources/ApiClient.swift @@ -63,17 +63,17 @@ public final class ApiClient: Sendable { "date": .string(date), "deadline": .date(deadline), "bytes": .string(bytes), - "user": .string(user.rawValue), - "userList": userList.map { .string($0.rawValue) }, + "user": .unknown(user), + "userList": userList.map { .unknown($0) }, "optionalDeadline": optionalDeadline.map { .date($0) }, "keyValue": keyValue.map { .unknown($0) }, "optionalString": optionalString.map { .string($0) }, - "nestedUser": nestedUser.map { .string($0.rawValue) }, - "optionalUser": optionalUser.map { .string($0.rawValue) }, - "excludeUser": excludeUser.map { .string($0.rawValue) }, + "nestedUser": nestedUser.map { .unknown($0) }, + "optionalUser": optionalUser.map { .unknown($0) }, + "excludeUser": excludeUser.map { .unknown($0) }, "filter": filter.map { .string($0) }, - "neighbor": neighbor.map { .string($0.rawValue) }, - "neighborRequired": .string(neighborRequired.rawValue) + "neighbor": neighbor.map { .unknown($0) }, + "neighborRequired": .unknown(neighborRequired) ], requestOptions: requestOptions, responseType: SearchResponse.self diff --git a/seed/swift-sdk/query-parameters-openapi/Sources/Schemas/SearchRequestNeighborRequired.swift b/seed/swift-sdk/query-parameters-openapi/Sources/Schemas/SearchRequestNeighborRequired.swift index 0236eca5725c..bbc8697c7cd0 100644 --- a/seed/swift-sdk/query-parameters-openapi/Sources/Schemas/SearchRequestNeighborRequired.swift +++ b/seed/swift-sdk/query-parameters-openapi/Sources/Schemas/SearchRequestNeighborRequired.swift @@ -1,21 +1,21 @@ import Foundation public enum SearchRequestNeighborRequired: Codable, Hashable, Sendable { - case user(User) + case int(Int) case nestedUser(NestedUser) case string(String) - case int(Int) + case user(User) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(User.self) { - self = .user(value) + if let value = try? container.decode(Int.self) { + self = .int(value) } else if let value = try? container.decode(NestedUser.self) { self = .nestedUser(value) } else if let value = try? container.decode(String.self) { self = .string(value) - } else if let value = try? container.decode(Int.self) { - self = .int(value) + } else if let value = try? container.decode(User.self) { + self = .user(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -27,13 +27,13 @@ public enum SearchRequestNeighborRequired: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .user(let value): + case .int(let value): try container.encode(value) case .nestedUser(let value): try container.encode(value) case .string(let value): try container.encode(value) - case .int(let value): + case .user(let value): try container.encode(value) } } diff --git a/seed/swift-sdk/query-parameters-openapi/reference.md b/seed/swift-sdk/query-parameters-openapi/reference.md index 11ec96ad8081..06f57481800b 100644 --- a/seed/swift-sdk/query-parameters-openapi/reference.md +++ b/seed/swift-sdk/query-parameters-openapi/reference.md @@ -31,7 +31,6 @@ private func main() async throws { "tags" ] ), - userList: , optionalDeadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), keyValue: [ "keyValue": "keyValue" @@ -54,8 +53,6 @@ private func main() async throws { "tags" ] ), - excludeUser: , - filter: , neighbor: User( name: "name", tags: [ diff --git a/seed/swift-sdk/query-parameters/README.md b/seed/swift-sdk/query-parameters/README.md index 6cc120464654..5af004413902 100644 --- a/seed/swift-sdk/query-parameters/README.md +++ b/seed/swift-sdk/query-parameters/README.md @@ -41,8 +41,8 @@ private func main() async throws { _ = try await client.user.getUsername( limit: 1, - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, deadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), bytes: "SGVsbG8gd29ybGQh", user: User( @@ -89,9 +89,7 @@ private func main() async throws { "tags", "tags" ] - ), - excludeUser: , - filter: + ) ) } diff --git a/seed/swift-sdk/query-parameters/Snippets/Example0.swift b/seed/swift-sdk/query-parameters/Snippets/Example0.swift index 0fe733ce17dd..895425f5c065 100644 --- a/seed/swift-sdk/query-parameters/Snippets/Example0.swift +++ b/seed/swift-sdk/query-parameters/Snippets/Example0.swift @@ -6,8 +6,8 @@ private func main() async throws { _ = try await client.user.getUsername( limit: 1, - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, deadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), bytes: "SGVsbG8gd29ybGQh", user: User( @@ -54,9 +54,7 @@ private func main() async throws { "tags", "tags" ] - ), - excludeUser: , - filter: + ) ) } diff --git a/seed/swift-sdk/query-parameters/Sources/Resources/User/UserClient.swift b/seed/swift-sdk/query-parameters/Sources/Resources/User/UserClient.swift index 0713cf04ad33..6a132f17c1bc 100644 --- a/seed/swift-sdk/query-parameters/Sources/Resources/User/UserClient.swift +++ b/seed/swift-sdk/query-parameters/Sources/Resources/User/UserClient.swift @@ -17,14 +17,14 @@ public final class UserClient: Sendable { "date": .calendarDate(date), "deadline": .date(deadline), "bytes": .string(bytes), - "user": .string(user.rawValue), - "userList": .stringArray(userList), + "user": .unknown(user), + "userList": .unknown(userList), "optionalDeadline": optionalDeadline.map { .date($0) }, "keyValue": .unknown(keyValue), "optionalString": optionalString.map { .string($0) }, - "nestedUser": .string(nestedUser.rawValue), - "optionalUser": optionalUser.map { .string($0.rawValue) }, - "excludeUser": .string(excludeUser.rawValue), + "nestedUser": .unknown(nestedUser), + "optionalUser": optionalUser.map { .unknown($0) }, + "excludeUser": .unknown(excludeUser), "filter": .string(filter) ], requestOptions: requestOptions, diff --git a/seed/swift-sdk/query-parameters/Tests/Wire/Resources/User/UserClientWireTests.swift b/seed/swift-sdk/query-parameters/Tests/Wire/Resources/User/UserClientWireTests.swift index 1c151746fe51..129da571face 100644 --- a/seed/swift-sdk/query-parameters/Tests/Wire/Resources/User/UserClientWireTests.swift +++ b/seed/swift-sdk/query-parameters/Tests/Wire/Resources/User/UserClientWireTests.swift @@ -31,8 +31,8 @@ import QueryParameters ) let response = try await client.user.getUsername( limit: 1, - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, deadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), bytes: "SGVsbG8gd29ybGQh", user: User( @@ -79,9 +79,7 @@ import QueryParameters "tags", "tags" ] - ), - excludeUser: , - filter: + ) ) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/query-parameters/reference.md b/seed/swift-sdk/query-parameters/reference.md index e59248d68267..1ab33cd681e1 100644 --- a/seed/swift-sdk/query-parameters/reference.md +++ b/seed/swift-sdk/query-parameters/reference.md @@ -21,8 +21,8 @@ private func main() async throws { _ = try await client.user.getUsername( limit: 1, - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, deadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), bytes: "SGVsbG8gd29ybGQh", user: User( @@ -69,9 +69,7 @@ private func main() async throws { "tags", "tags" ] - ), - excludeUser: , - filter: + ) ) } diff --git a/seed/swift-sdk/request-parameters/Snippets/Example4.swift b/seed/swift-sdk/request-parameters/Snippets/Example4.swift index ad27fada048d..359bbafbafda 100644 --- a/seed/swift-sdk/request-parameters/Snippets/Example4.swift +++ b/seed/swift-sdk/request-parameters/Snippets/Example4.swift @@ -6,8 +6,8 @@ private func main() async throws { _ = try await client.user.getUsername( limit: 1, - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, deadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), bytes: "SGVsbG8gd29ybGQh", user: User( @@ -55,10 +55,7 @@ private func main() async throws { "tags" ] ), - excludeUser: , - filter: , - longParam: 1000000, - bigIntParam: + longParam: 1000000 ) } diff --git a/seed/swift-sdk/request-parameters/Sources/Resources/User/UserClient.swift b/seed/swift-sdk/request-parameters/Sources/Resources/User/UserClient.swift index e22f7c56e5e0..2b7378ab5970 100644 --- a/seed/swift-sdk/request-parameters/Sources/Resources/User/UserClient.swift +++ b/seed/swift-sdk/request-parameters/Sources/Resources/User/UserClient.swift @@ -50,14 +50,14 @@ public final class UserClient: Sendable { "date": .calendarDate(date), "deadline": .date(deadline), "bytes": .string(bytes), - "user": .string(user.rawValue), - "userList": .stringArray(userList), + "user": .unknown(user), + "userList": .unknown(userList), "optionalDeadline": optionalDeadline.map { .date($0) }, "keyValue": .unknown(keyValue), "optionalString": optionalString.map { .string($0) }, - "nestedUser": .string(nestedUser.rawValue), - "optionalUser": optionalUser.map { .string($0.rawValue) }, - "excludeUser": .string(excludeUser.rawValue), + "nestedUser": .unknown(nestedUser), + "optionalUser": optionalUser.map { .unknown($0) }, + "excludeUser": .unknown(excludeUser), "filter": .string(filter), "longParam": .int64(longParam), "bigIntParam": .string(bigIntParam) diff --git a/seed/swift-sdk/request-parameters/Tests/Wire/Resources/User/UserClientWireTests.swift b/seed/swift-sdk/request-parameters/Tests/Wire/Resources/User/UserClientWireTests.swift index 0d6fb2b6f58d..758fbd580973 100644 --- a/seed/swift-sdk/request-parameters/Tests/Wire/Resources/User/UserClientWireTests.swift +++ b/seed/swift-sdk/request-parameters/Tests/Wire/Resources/User/UserClientWireTests.swift @@ -31,8 +31,8 @@ import RequestParameters ) let response = try await client.user.getUsername( limit: 1, - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, deadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), bytes: "SGVsbG8gd29ybGQh", user: User( @@ -80,10 +80,7 @@ import RequestParameters "tags" ] ), - excludeUser: , - filter: , - longParam: 1000000, - bigIntParam: + longParam: 1000000 ) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/request-parameters/reference.md b/seed/swift-sdk/request-parameters/reference.md index 623ba0a64fd4..1ca257e3c559 100644 --- a/seed/swift-sdk/request-parameters/reference.md +++ b/seed/swift-sdk/request-parameters/reference.md @@ -230,8 +230,8 @@ private func main() async throws { _ = try await client.user.getUsername( limit: 1, - id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), - date: try! CalendarDate("2023-01-15"), + id: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, + date: CalendarDate("2023-01-15")!, deadline: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), bytes: "SGVsbG8gd29ybGQh", user: User( @@ -279,10 +279,7 @@ private func main() async throws { "tags" ] ), - excludeUser: , - filter: , - longParam: 1000000, - bigIntParam: + longParam: 1000000 ) } diff --git a/seed/swift-sdk/seed.yml b/seed/swift-sdk/seed.yml index f2b7e6c9f070..f3f0f8561fe6 100644 --- a/seed/swift-sdk/seed.yml +++ b/seed/swift-sdk/seed.yml @@ -139,4 +139,3 @@ allowedFailures: - unions - variables - websocket-inferred-auth - - file-upload diff --git a/seed/swift-sdk/streaming/README.md b/seed/swift-sdk/streaming/README.md index 2e98766df6f9..9663c252e42f 100644 --- a/seed/swift-sdk/streaming/README.md +++ b/seed/swift-sdk/streaming/README.md @@ -39,10 +39,7 @@ import Streaming private func main() async throws { let client = StreamingClient() - _ = try await client.dummy.generateStream(request: .init( - stream: , - numEvents: 1 - )) + _ = try await client.dummy.generateStream(request: .init(numEvents: 1)) } try await main() diff --git a/seed/swift-sdk/streaming/Snippets/Example0.swift b/seed/swift-sdk/streaming/Snippets/Example0.swift index 0d1d5ac99ef9..942106ee4877 100644 --- a/seed/swift-sdk/streaming/Snippets/Example0.swift +++ b/seed/swift-sdk/streaming/Snippets/Example0.swift @@ -4,10 +4,7 @@ import Streaming private func main() async throws { let client = StreamingClient(baseURL: "https://api.fern.com") - _ = try await client.dummy.generateStream(request: .init( - stream: , - numEvents: 1 - )) + _ = try await client.dummy.generateStream(request: .init(numEvents: 1)) } try await main() diff --git a/seed/swift-sdk/streaming/Snippets/Example1.swift b/seed/swift-sdk/streaming/Snippets/Example1.swift index 0b3a5a6e696b..22d36ddb29e9 100644 --- a/seed/swift-sdk/streaming/Snippets/Example1.swift +++ b/seed/swift-sdk/streaming/Snippets/Example1.swift @@ -4,10 +4,7 @@ import Streaming private func main() async throws { let client = StreamingClient(baseURL: "https://api.fern.com") - _ = try await client.dummy.generate(request: .init( - stream: , - numEvents: 5 - )) + _ = try await client.dummy.generate(request: .init(numEvents: 5)) } try await main() diff --git a/seed/swift-sdk/streaming/Snippets/Example2.swift b/seed/swift-sdk/streaming/Snippets/Example2.swift index bf333bef2dae..dde9b6c53180 100644 --- a/seed/swift-sdk/streaming/Snippets/Example2.swift +++ b/seed/swift-sdk/streaming/Snippets/Example2.swift @@ -4,10 +4,7 @@ import Streaming private func main() async throws { let client = StreamingClient(baseURL: "https://api.fern.com") - _ = try await client.dummy.generate(request: .init( - stream: , - numEvents: 1 - )) + _ = try await client.dummy.generate(request: .init(numEvents: 1)) } try await main() diff --git a/seed/swift-sdk/streaming/Tests/Wire/Resources/Dummy/DummyClientWireTests.swift b/seed/swift-sdk/streaming/Tests/Wire/Resources/Dummy/DummyClientWireTests.swift index 98467c51cc47..d977cfbbaefe 100644 --- a/seed/swift-sdk/streaming/Tests/Wire/Resources/Dummy/DummyClientWireTests.swift +++ b/seed/swift-sdk/streaming/Tests/Wire/Resources/Dummy/DummyClientWireTests.swift @@ -23,10 +23,7 @@ import Streaming id: "id", name: Optional("name") ) - let response = try await client.dummy.generate(request: .init( - stream: , - numEvents: 5 - )) + let response = try await client.dummy.generate(request: .init(numEvents: 5)) try #require(response == expectedResponse) } @@ -50,10 +47,7 @@ import Streaming id: "id", name: Optional("name") ) - let response = try await client.dummy.generate(request: .init( - stream: , - numEvents: 1 - )) + let response = try await client.dummy.generate(request: .init(numEvents: 1)) try #require(response == expectedResponse) } } \ No newline at end of file diff --git a/seed/swift-sdk/streaming/reference.md b/seed/swift-sdk/streaming/reference.md index 1153459443ba..7a9c4840b3ff 100644 --- a/seed/swift-sdk/streaming/reference.md +++ b/seed/swift-sdk/streaming/reference.md @@ -19,10 +19,7 @@ import Streaming private func main() async throws { let client = StreamingClient() - _ = try await client.dummy.generateStream(request: .init( - stream: , - numEvents: 1 - )) + _ = try await client.dummy.generateStream(request: .init(numEvents: 1)) } try await main() @@ -79,10 +76,7 @@ import Streaming private func main() async throws { let client = StreamingClient() - _ = try await client.dummy.generate(request: .init( - stream: , - numEvents: 5 - )) + _ = try await client.dummy.generate(request: .init(numEvents: 5)) } try await main() diff --git a/seed/swift-sdk/trace/README.md b/seed/swift-sdk/trace/README.md index 6fd8bf9dfb80..26475907a0e1 100644 --- a/seed/swift-sdk/trace/README.md +++ b/seed/swift-sdk/trace/README.md @@ -40,7 +40,7 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.updateTestSubmissionStatus( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: TestSubmissionStatus.stopped( .init( diff --git a/seed/swift-sdk/trace/Snippets/Example1.swift b/seed/swift-sdk/trace/Snippets/Example1.swift index 71d54398c4b1..f597939a90b9 100644 --- a/seed/swift-sdk/trace/Snippets/Example1.swift +++ b/seed/swift-sdk/trace/Snippets/Example1.swift @@ -8,7 +8,7 @@ private func main() async throws { ) _ = try await client.admin.updateTestSubmissionStatus( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: TestSubmissionStatus.stopped( .init( diff --git a/seed/swift-sdk/trace/Snippets/Example13.swift b/seed/swift-sdk/trace/Snippets/Example13.swift index 6ac4fb1e3760..7bd6f4e9e0c0 100644 --- a/seed/swift-sdk/trace/Snippets/Example13.swift +++ b/seed/swift-sdk/trace/Snippets/Example13.swift @@ -11,9 +11,7 @@ private func main() async throws { serviceParam: 1, limit: 1, otherField: "otherField", - multiLineDocs: "multiLineDocs", - optionalMultipleField: , - multipleField: + multiLineDocs: "multiLineDocs" ) } diff --git a/seed/swift-sdk/trace/Snippets/Example2.swift b/seed/swift-sdk/trace/Snippets/Example2.swift index 38e304167ef7..87c3946df6d9 100644 --- a/seed/swift-sdk/trace/Snippets/Example2.swift +++ b/seed/swift-sdk/trace/Snippets/Example2.swift @@ -8,7 +8,7 @@ private func main() async throws { ) _ = try await client.admin.sendTestSubmissionUpdate( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: TestSubmissionUpdate( updateTime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), updateInfo: TestSubmissionUpdateInfo.running( diff --git a/seed/swift-sdk/trace/Snippets/Example3.swift b/seed/swift-sdk/trace/Snippets/Example3.swift index 691f3851bb2a..6b9fb1ac6a22 100644 --- a/seed/swift-sdk/trace/Snippets/Example3.swift +++ b/seed/swift-sdk/trace/Snippets/Example3.swift @@ -8,7 +8,7 @@ private func main() async throws { ) _ = try await client.admin.updateWorkspaceSubmissionStatus( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: WorkspaceSubmissionStatus.stopped( .init( diff --git a/seed/swift-sdk/trace/Snippets/Example4.swift b/seed/swift-sdk/trace/Snippets/Example4.swift index d3ce83b7a503..89a047ba1e0f 100644 --- a/seed/swift-sdk/trace/Snippets/Example4.swift +++ b/seed/swift-sdk/trace/Snippets/Example4.swift @@ -8,7 +8,7 @@ private func main() async throws { ) _ = try await client.admin.sendWorkspaceSubmissionUpdate( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: WorkspaceSubmissionUpdate( updateTime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), updateInfo: WorkspaceSubmissionUpdateInfo.running( diff --git a/seed/swift-sdk/trace/Snippets/Example5.swift b/seed/swift-sdk/trace/Snippets/Example5.swift index 53f80055d7ba..2cec523d8c2d 100644 --- a/seed/swift-sdk/trace/Snippets/Example5.swift +++ b/seed/swift-sdk/trace/Snippets/Example5.swift @@ -8,7 +8,7 @@ private func main() async throws { ) _ = try await client.admin.storeTracedTestCase( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, testCaseId: "testCaseId", request: .init( result: TestCaseResultWithStdout( @@ -33,7 +33,7 @@ private func main() async throws { ), traceResponses: [ TraceResponse( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, returnValue: DebugVariableValue.integerValue( .init( @@ -74,7 +74,7 @@ private func main() async throws { stdout: "stdout" ), TraceResponse( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, returnValue: DebugVariableValue.integerValue( .init( diff --git a/seed/swift-sdk/trace/Snippets/Example6.swift b/seed/swift-sdk/trace/Snippets/Example6.swift index 1a4337029a19..a506d0f79d5c 100644 --- a/seed/swift-sdk/trace/Snippets/Example6.swift +++ b/seed/swift-sdk/trace/Snippets/Example6.swift @@ -8,11 +8,11 @@ private func main() async throws { ) _ = try await client.admin.storeTracedTestCaseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, testCaseId: "testCaseId", request: [ TraceResponseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, file: TracedFile( filename: "filename", @@ -57,7 +57,7 @@ private func main() async throws { stdout: "stdout" ), TraceResponseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, file: TracedFile( filename: "filename", diff --git a/seed/swift-sdk/trace/Snippets/Example7.swift b/seed/swift-sdk/trace/Snippets/Example7.swift index 225d41d6bad6..87fb8768f168 100644 --- a/seed/swift-sdk/trace/Snippets/Example7.swift +++ b/seed/swift-sdk/trace/Snippets/Example7.swift @@ -8,7 +8,7 @@ private func main() async throws { ) _ = try await client.admin.storeTracedWorkspace( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: .init( workspaceRunDetails: WorkspaceRunDetails( exceptionV2: ExceptionV2.generic( @@ -27,7 +27,7 @@ private func main() async throws { ), traceResponses: [ TraceResponse( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, returnValue: DebugVariableValue.integerValue( .init( @@ -68,7 +68,7 @@ private func main() async throws { stdout: "stdout" ), TraceResponse( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, returnValue: DebugVariableValue.integerValue( .init( diff --git a/seed/swift-sdk/trace/Snippets/Example8.swift b/seed/swift-sdk/trace/Snippets/Example8.swift index d100b82191aa..553d9145e317 100644 --- a/seed/swift-sdk/trace/Snippets/Example8.swift +++ b/seed/swift-sdk/trace/Snippets/Example8.swift @@ -8,10 +8,10 @@ private func main() async throws { ) _ = try await client.admin.storeTracedWorkspaceV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: [ TraceResponseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, file: TracedFile( filename: "filename", @@ -56,7 +56,7 @@ private func main() async throws { stdout: "stdout" ), TraceResponseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, file: TracedFile( filename: "filename", diff --git a/seed/swift-sdk/trace/Sources/Schemas/ActualResult.swift b/seed/swift-sdk/trace/Sources/Schemas/ActualResult.swift index 61bfb3e10fe8..98438e434672 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/ActualResult.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/ActualResult.swift @@ -1,20 +1,20 @@ import Foundation public enum ActualResult: Codable, Hashable, Sendable { - case value(Value) case exception(Exception) case exceptionV2(ExceptionV2) + case value(Value) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "value": - self = .value(try Value(from: decoder)) case "exception": self = .exception(try Exception(from: decoder)) case "exceptionV2": self = .exceptionV2(try ExceptionV2(from: decoder)) + case "value": + self = .value(try Value(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -27,12 +27,12 @@ public enum ActualResult: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .value(let data): - try data.encode(to: encoder) case .exception(let data): try data.encode(to: encoder) case .exceptionV2(let data): try data.encode(to: encoder) + case .value(let data): + try data.encode(to: encoder) } } @@ -118,12 +118,12 @@ public enum ActualResult: Codable, Hashable, Sendable { public struct ExceptionV2: Codable, Hashable, Sendable { public let type: String = "exceptionV2" - public let value: ExceptionV2 + public let value: Trace.ExceptionV2 /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: ExceptionV2, + value: Trace.ExceptionV2, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -132,7 +132,7 @@ public enum ActualResult: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(ExceptionV2.self, forKey: .value) + self.value = try container.decode(Trace.ExceptionV2.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/trace/Sources/Schemas/AssertCorrectnessCheck.swift b/seed/swift-sdk/trace/Sources/Schemas/AssertCorrectnessCheck.swift index b53c51d6b1fa..c3610a58b1a0 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/AssertCorrectnessCheck.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/AssertCorrectnessCheck.swift @@ -1,17 +1,17 @@ import Foundation public enum AssertCorrectnessCheck: Codable, Hashable, Sendable { - case deepEquality(DeepEquality) case custom(Custom) + case deepEquality(DeepEquality) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "deepEquality": - self = .deepEquality(try DeepEquality(from: decoder)) case "custom": self = .custom(try Custom(from: decoder)) + case "deepEquality": + self = .deepEquality(try DeepEquality(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum AssertCorrectnessCheck: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .deepEquality(let data): - try data.encode(to: encoder) case .custom(let data): try data.encode(to: encoder) + case .deepEquality(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/AssertCorrectnessCheckType.swift b/seed/swift-sdk/trace/Sources/Schemas/AssertCorrectnessCheckType.swift index 94fe89c4f25b..06a96048fbda 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/AssertCorrectnessCheckType.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/AssertCorrectnessCheckType.swift @@ -1,17 +1,17 @@ import Foundation public enum AssertCorrectnessCheckType: Codable, Hashable, Sendable { - case deepEquality(DeepEquality) case custom(Custom) + case deepEquality(DeepEquality) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "deepEquality": - self = .deepEquality(try DeepEquality(from: decoder)) case "custom": self = .custom(try Custom(from: decoder)) + case "deepEquality": + self = .deepEquality(try DeepEquality(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum AssertCorrectnessCheckType: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .deepEquality(let data): - try data.encode(to: encoder) case .custom(let data): try data.encode(to: encoder) + case .deepEquality(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/CodeExecutionUpdate.swift b/seed/swift-sdk/trace/Sources/Schemas/CodeExecutionUpdate.swift index de465e36756e..afc7cbbf507a 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/CodeExecutionUpdate.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/CodeExecutionUpdate.swift @@ -3,26 +3,26 @@ import Foundation public enum CodeExecutionUpdate: Codable, Hashable, Sendable { /// Statuses if an executor for the session isn't ready (Before RunningResponse). case buildingExecutor(BuildingExecutor) - /// Sent once a test submission is executing. - case running(Running) /// Sent if a submission cannot be run (i.e. Compile Error). case errored(Errored) - /// Sent if a submission is stopped. - case stopped(Stopped) + /// Sent once a submission is graded and fully recorded. + case finished(Finished) /// Graded testcases without trace information. case graded(Graded) /// Graded submission for v2 problems. case gradedV2(GradedV2) - /// Workspace run without trace information. - case workspaceRan(WorkspaceRan) - /// Gives progress about what is being recorded. - case recording(Recording) - /// Graded testcases with trace information. - case recorded(Recorded) /// Sent if an invalid request is sent for a submission. case invalidRequest(InvalidRequest) - /// Sent once a submission is graded and fully recorded. - case finished(Finished) + /// Graded testcases with trace information. + case recorded(Recorded) + /// Gives progress about what is being recorded. + case recording(Recording) + /// Sent once a test submission is executing. + case running(Running) + /// Sent if a submission is stopped. + case stopped(Stopped) + /// Workspace run without trace information. + case workspaceRan(WorkspaceRan) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -30,26 +30,26 @@ public enum CodeExecutionUpdate: Codable, Hashable, Sendable { switch discriminant { case "buildingExecutor": self = .buildingExecutor(try BuildingExecutor(from: decoder)) - case "running": - self = .running(try Running(from: decoder)) case "errored": self = .errored(try Errored(from: decoder)) - case "stopped": - self = .stopped(try Stopped(from: decoder)) + case "finished": + self = .finished(try Finished(from: decoder)) case "graded": self = .graded(try Graded(from: decoder)) case "gradedV2": self = .gradedV2(try GradedV2(from: decoder)) - case "workspaceRan": - self = .workspaceRan(try WorkspaceRan(from: decoder)) - case "recording": - self = .recording(try Recording(from: decoder)) - case "recorded": - self = .recorded(try Recorded(from: decoder)) case "invalidRequest": self = .invalidRequest(try InvalidRequest(from: decoder)) - case "finished": - self = .finished(try Finished(from: decoder)) + case "recorded": + self = .recorded(try Recorded(from: decoder)) + case "recording": + self = .recording(try Recording(from: decoder)) + case "running": + self = .running(try Running(from: decoder)) + case "stopped": + self = .stopped(try Stopped(from: decoder)) + case "workspaceRan": + self = .workspaceRan(try WorkspaceRan(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -64,25 +64,25 @@ public enum CodeExecutionUpdate: Codable, Hashable, Sendable { switch self { case .buildingExecutor(let data): try data.encode(to: encoder) - case .running(let data): - try data.encode(to: encoder) case .errored(let data): try data.encode(to: encoder) - case .stopped(let data): + case .finished(let data): try data.encode(to: encoder) case .graded(let data): try data.encode(to: encoder) case .gradedV2(let data): try data.encode(to: encoder) - case .workspaceRan(let data): + case .invalidRequest(let data): + try data.encode(to: encoder) + case .recorded(let data): try data.encode(to: encoder) case .recording(let data): try data.encode(to: encoder) - case .recorded(let data): + case .running(let data): try data.encode(to: encoder) - case .invalidRequest(let data): + case .stopped(let data): try data.encode(to: encoder) - case .finished(let data): + case .workspaceRan(let data): try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/CreateProblemResponse.swift b/seed/swift-sdk/trace/Sources/Schemas/CreateProblemResponse.swift index 729fa254ac72..76dccd304627 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/CreateProblemResponse.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/CreateProblemResponse.swift @@ -1,17 +1,17 @@ import Foundation public enum CreateProblemResponse: Codable, Hashable, Sendable { - case success(Success) case error(Error) + case success(Success) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "success": - self = .success(try Success(from: decoder)) case "error": self = .error(try Error(from: decoder)) + case "success": + self = .success(try Success(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum CreateProblemResponse: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .success(let data): - try data.encode(to: encoder) case .error(let data): try data.encode(to: encoder) + case .success(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/DebugVariableValue.swift b/seed/swift-sdk/trace/Sources/Schemas/DebugVariableValue.swift index fd09e08bde6b..1030b8c6b750 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/DebugVariableValue.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/DebugVariableValue.swift @@ -1,50 +1,50 @@ import Foundation public enum DebugVariableValue: Codable, Hashable, Sendable { - case integerValue(IntegerValue) + case binaryTreeNodeValue(BinaryTreeNodeValue) case booleanValue(BooleanValue) - case doubleValue(DoubleValue) - case stringValue(StringValue) case charValue(CharValue) - case mapValue(MapValue) + case doubleValue(DoubleValue) + case doublyLinkedListNodeValue(DoublyLinkedListNodeValue) + case genericValue(GenericValue) + case integerValue(IntegerValue) case listValue(ListValue) - case binaryTreeNodeValue(BinaryTreeNodeValue) + case mapValue(MapValue) + case nullValue(NullValue) case singlyLinkedListNodeValue(SinglyLinkedListNodeValue) - case doublyLinkedListNodeValue(DoublyLinkedListNodeValue) + case stringValue(StringValue) case undefinedValue(UndefinedValue) - case nullValue(NullValue) - case genericValue(GenericValue) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "integerValue": - self = .integerValue(try IntegerValue(from: decoder)) + case "binaryTreeNodeValue": + self = .binaryTreeNodeValue(try BinaryTreeNodeValue(from: decoder)) case "booleanValue": self = .booleanValue(try BooleanValue(from: decoder)) - case "doubleValue": - self = .doubleValue(try DoubleValue(from: decoder)) - case "stringValue": - self = .stringValue(try StringValue(from: decoder)) case "charValue": self = .charValue(try CharValue(from: decoder)) - case "mapValue": - self = .mapValue(try MapValue(from: decoder)) + case "doubleValue": + self = .doubleValue(try DoubleValue(from: decoder)) + case "doublyLinkedListNodeValue": + self = .doublyLinkedListNodeValue(try DoublyLinkedListNodeValue(from: decoder)) + case "genericValue": + self = .genericValue(try GenericValue(from: decoder)) + case "integerValue": + self = .integerValue(try IntegerValue(from: decoder)) case "listValue": self = .listValue(try ListValue(from: decoder)) - case "binaryTreeNodeValue": - self = .binaryTreeNodeValue(try BinaryTreeNodeValue(from: decoder)) + case "mapValue": + self = .mapValue(try MapValue(from: decoder)) + case "nullValue": + self = .nullValue(try NullValue(from: decoder)) case "singlyLinkedListNodeValue": self = .singlyLinkedListNodeValue(try SinglyLinkedListNodeValue(from: decoder)) - case "doublyLinkedListNodeValue": - self = .doublyLinkedListNodeValue(try DoublyLinkedListNodeValue(from: decoder)) + case "stringValue": + self = .stringValue(try StringValue(from: decoder)) case "undefinedValue": self = .undefinedValue(try UndefinedValue(from: decoder)) - case "nullValue": - self = .nullValue(try NullValue(from: decoder)) - case "genericValue": - self = .genericValue(try GenericValue(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -57,32 +57,32 @@ public enum DebugVariableValue: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .integerValue(let data): + case .binaryTreeNodeValue(let data): try data.encode(to: encoder) case .booleanValue(let data): try data.encode(to: encoder) + case .charValue(let data): + try data.encode(to: encoder) case .doubleValue(let data): try data.encode(to: encoder) - case .stringValue(let data): + case .doublyLinkedListNodeValue(let data): try data.encode(to: encoder) - case .charValue(let data): + case .genericValue(let data): try data.encode(to: encoder) - case .mapValue(let data): + case .integerValue(let data): try data.encode(to: encoder) case .listValue(let data): try data.encode(to: encoder) - case .binaryTreeNodeValue(let data): + case .mapValue(let data): + try data.encode(to: encoder) + case .nullValue(let data): try data.encode(to: encoder) case .singlyLinkedListNodeValue(let data): try data.encode(to: encoder) - case .doublyLinkedListNodeValue(let data): + case .stringValue(let data): try data.encode(to: encoder) case .undefinedValue(let data): try data.encode(to: encoder) - case .nullValue(let data): - try data.encode(to: encoder) - case .genericValue(let data): - try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/ErrorInfo.swift b/seed/swift-sdk/trace/Sources/Schemas/ErrorInfo.swift index d40924593a5c..2fbdf40fd090 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/ErrorInfo.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/ErrorInfo.swift @@ -2,10 +2,10 @@ import Foundation public enum ErrorInfo: Codable, Hashable, Sendable { case compileError(CompileError) - /// If the submission cannot be executed and throws a runtime error before getting to any of the testcases. - case runtimeError(RuntimeError) /// If the trace backend encounters an unexpected error. case internalError(InternalError) + /// If the submission cannot be executed and throws a runtime error before getting to any of the testcases. + case runtimeError(RuntimeError) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -13,10 +13,10 @@ public enum ErrorInfo: Codable, Hashable, Sendable { switch discriminant { case "compileError": self = .compileError(try CompileError(from: decoder)) - case "runtimeError": - self = .runtimeError(try RuntimeError(from: decoder)) case "internalError": self = .internalError(try InternalError(from: decoder)) + case "runtimeError": + self = .runtimeError(try RuntimeError(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -31,10 +31,10 @@ public enum ErrorInfo: Codable, Hashable, Sendable { switch self { case .compileError(let data): try data.encode(to: encoder) - case .runtimeError(let data): - try data.encode(to: encoder) case .internalError(let data): try data.encode(to: encoder) + case .runtimeError(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/FunctionSignature.swift b/seed/swift-sdk/trace/Sources/Schemas/FunctionSignature.swift index c804c0dc59d9..1dfebb415141 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/FunctionSignature.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/FunctionSignature.swift @@ -1,8 +1,8 @@ import Foundation public enum FunctionSignature: Codable, Hashable, Sendable { - case void(Void) case nonVoid(NonVoid) + case void(Void) /// Useful when specifying custom grading for a testcase where actualResult is defined. case voidThatTakesActualResult(VoidThatTakesActualResult) @@ -10,10 +10,10 @@ public enum FunctionSignature: Codable, Hashable, Sendable { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "void": - self = .void(try Void(from: decoder)) case "nonVoid": self = .nonVoid(try NonVoid(from: decoder)) + case "void": + self = .void(try Void(from: decoder)) case "voidThatTakesActualResult": self = .voidThatTakesActualResult(try VoidThatTakesActualResult(from: decoder)) default: @@ -26,12 +26,12 @@ public enum FunctionSignature: Codable, Hashable, Sendable { } } - public func encode(to encoder: Encoder) throws -> Void { + public func encode(to encoder: Encoder) throws -> Swift.Void { switch self { - case .void(let data): - try data.encode(to: encoder) case .nonVoid(let data): try data.encode(to: encoder) + case .void(let data): + try data.encode(to: encoder) case .voidThatTakesActualResult(let data): try data.encode(to: encoder) } @@ -57,7 +57,7 @@ public enum FunctionSignature: Codable, Hashable, Sendable { self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } - public func encode(to encoder: Encoder) throws -> Void { + public func encode(to encoder: Encoder) throws -> Swift.Void { var container = encoder.container(keyedBy: CodingKeys.self) try encoder.encodeAdditionalProperties(self.additionalProperties) try container.encode(self.type, forKey: .type) @@ -95,7 +95,7 @@ public enum FunctionSignature: Codable, Hashable, Sendable { self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } - public func encode(to encoder: Encoder) throws -> Void { + public func encode(to encoder: Encoder) throws -> Swift.Void { var container = encoder.container(keyedBy: CodingKeys.self) try encoder.encodeAdditionalProperties(self.additionalProperties) try container.encode(self.type, forKey: .type) @@ -136,7 +136,7 @@ public enum FunctionSignature: Codable, Hashable, Sendable { self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } - public func encode(to encoder: Encoder) throws -> Void { + public func encode(to encoder: Encoder) throws -> Swift.Void { var container = encoder.container(keyedBy: CodingKeys.self) try encoder.encodeAdditionalProperties(self.additionalProperties) try container.encode(self.type, forKey: .type) diff --git a/seed/swift-sdk/trace/Sources/Schemas/FunctionSignatureType.swift b/seed/swift-sdk/trace/Sources/Schemas/FunctionSignatureType.swift index 711305a7c532..7173f72e51ef 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/FunctionSignatureType.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/FunctionSignatureType.swift @@ -1,8 +1,8 @@ import Foundation public enum FunctionSignatureType: Codable, Hashable, Sendable { - case void(Void) case nonVoid(NonVoid) + case void(Void) /// Useful when specifying custom grading for a testcase where actualResult is defined. case voidThatTakesActualResult(VoidThatTakesActualResult) @@ -10,10 +10,10 @@ public enum FunctionSignatureType: Codable, Hashable, Sendable { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "void": - self = .void(try Void(from: decoder)) case "nonVoid": self = .nonVoid(try NonVoid(from: decoder)) + case "void": + self = .void(try Void(from: decoder)) case "voidThatTakesActualResult": self = .voidThatTakesActualResult(try VoidThatTakesActualResult(from: decoder)) default: @@ -26,12 +26,12 @@ public enum FunctionSignatureType: Codable, Hashable, Sendable { } } - public func encode(to encoder: Encoder) throws -> Void { + public func encode(to encoder: Encoder) throws -> Swift.Void { switch self { - case .void(let data): - try data.encode(to: encoder) case .nonVoid(let data): try data.encode(to: encoder) + case .void(let data): + try data.encode(to: encoder) case .voidThatTakesActualResult(let data): try data.encode(to: encoder) } @@ -57,7 +57,7 @@ public enum FunctionSignatureType: Codable, Hashable, Sendable { self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } - public func encode(to encoder: Encoder) throws -> Void { + public func encode(to encoder: Encoder) throws -> Swift.Void { var container = encoder.container(keyedBy: CodingKeys.self) try encoder.encodeAdditionalProperties(self.additionalProperties) try container.encode(self.type, forKey: .type) @@ -95,7 +95,7 @@ public enum FunctionSignatureType: Codable, Hashable, Sendable { self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } - public func encode(to encoder: Encoder) throws -> Void { + public func encode(to encoder: Encoder) throws -> Swift.Void { var container = encoder.container(keyedBy: CodingKeys.self) try encoder.encodeAdditionalProperties(self.additionalProperties) try container.encode(self.type, forKey: .type) @@ -136,7 +136,7 @@ public enum FunctionSignatureType: Codable, Hashable, Sendable { self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } - public func encode(to encoder: Encoder) throws -> Void { + public func encode(to encoder: Encoder) throws -> Swift.Void { var container = encoder.container(keyedBy: CodingKeys.self) try encoder.encodeAdditionalProperties(self.additionalProperties) try container.encode(self.type, forKey: .type) diff --git a/seed/swift-sdk/trace/Sources/Schemas/InvalidRequestCause.swift b/seed/swift-sdk/trace/Sources/Schemas/InvalidRequestCause.swift index c8ee525f5174..5417299c0bb4 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/InvalidRequestCause.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/InvalidRequestCause.swift @@ -1,9 +1,9 @@ import Foundation public enum InvalidRequestCause: Codable, Hashable, Sendable { + case customTestCasesUnsupported(CustomTestCasesUnsupported) /// The submission request references a submission id that doesn't exist. case submissionIdNotFound(SubmissionIdNotFound) - case customTestCasesUnsupported(CustomTestCasesUnsupported) /// The submission request was routed to an incorrect language executor. case unexpectedLanguage(UnexpectedLanguage) @@ -11,10 +11,10 @@ public enum InvalidRequestCause: Codable, Hashable, Sendable { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "submissionIdNotFound": - self = .submissionIdNotFound(try SubmissionIdNotFound(from: decoder)) case "customTestCasesUnsupported": self = .customTestCasesUnsupported(try CustomTestCasesUnsupported(from: decoder)) + case "submissionIdNotFound": + self = .submissionIdNotFound(try SubmissionIdNotFound(from: decoder)) case "unexpectedLanguage": self = .unexpectedLanguage(try UnexpectedLanguage(from: decoder)) default: @@ -29,10 +29,10 @@ public enum InvalidRequestCause: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .submissionIdNotFound(let data): - try data.encode(to: encoder) case .customTestCasesUnsupported(let data): try data.encode(to: encoder) + case .submissionIdNotFound(let data): + try data.encode(to: encoder) case .unexpectedLanguage(let data): try data.encode(to: encoder) } diff --git a/seed/swift-sdk/trace/Sources/Schemas/PlaylistIdNotFoundErrorBody.swift b/seed/swift-sdk/trace/Sources/Schemas/PlaylistIdNotFoundErrorBody.swift index 711fd1f03235..025ee06e912b 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/PlaylistIdNotFoundErrorBody.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/PlaylistIdNotFoundErrorBody.swift @@ -28,12 +28,12 @@ public enum PlaylistIdNotFoundErrorBody: Codable, Hashable, Sendable { public struct PlaylistId: Codable, Hashable, Sendable { public let type: String = "playlistId" - public let value: PlaylistId + public let value: Trace.PlaylistId /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: PlaylistId, + value: Trace.PlaylistId, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -42,7 +42,7 @@ public enum PlaylistIdNotFoundErrorBody: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(PlaylistId.self, forKey: .value) + self.value = try container.decode(Trace.PlaylistId.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/trace/Sources/Schemas/ProblemDescriptionBoard.swift b/seed/swift-sdk/trace/Sources/Schemas/ProblemDescriptionBoard.swift index 330b3b90e097..f00bf212be19 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/ProblemDescriptionBoard.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/ProblemDescriptionBoard.swift @@ -2,8 +2,8 @@ import Foundation public enum ProblemDescriptionBoard: Codable, Hashable, Sendable { case html(Html) - case variable(Variable) case testCaseId(TestCaseId) + case variable(Variable) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -11,10 +11,10 @@ public enum ProblemDescriptionBoard: Codable, Hashable, Sendable { switch discriminant { case "html": self = .html(try Html(from: decoder)) - case "variable": - self = .variable(try Variable(from: decoder)) case "testCaseId": self = .testCaseId(try TestCaseId(from: decoder)) + case "variable": + self = .variable(try Variable(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -29,10 +29,10 @@ public enum ProblemDescriptionBoard: Codable, Hashable, Sendable { switch self { case .html(let data): try data.encode(to: encoder) - case .variable(let data): - try data.encode(to: encoder) case .testCaseId(let data): try data.encode(to: encoder) + case .variable(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/SubmissionRequest.swift b/seed/swift-sdk/trace/Sources/Schemas/SubmissionRequest.swift index bd448fde630b..15fa4bb26323 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/SubmissionRequest.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/SubmissionRequest.swift @@ -3,9 +3,9 @@ import Foundation public enum SubmissionRequest: Codable, Hashable, Sendable { case initializeProblemRequest(InitializeProblemRequest) case initializeWorkspaceRequest(InitializeWorkspaceRequest) + case stop(Stop) case submitV2(SubmitV2) case workspaceSubmit(WorkspaceSubmit) - case stop(Stop) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -15,12 +15,12 @@ public enum SubmissionRequest: Codable, Hashable, Sendable { self = .initializeProblemRequest(try InitializeProblemRequest(from: decoder)) case "initializeWorkspaceRequest": self = .initializeWorkspaceRequest(try InitializeWorkspaceRequest(from: decoder)) + case "stop": + self = .stop(try Stop(from: decoder)) case "submitV2": self = .submitV2(try SubmitV2(from: decoder)) case "workspaceSubmit": self = .workspaceSubmit(try WorkspaceSubmit(from: decoder)) - case "stop": - self = .stop(try Stop(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -37,12 +37,12 @@ public enum SubmissionRequest: Codable, Hashable, Sendable { try data.encode(to: encoder) case .initializeWorkspaceRequest(let data): try data.encode(to: encoder) + case .stop(let data): + try data.encode(to: encoder) case .submitV2(let data): try data.encode(to: encoder) case .workspaceSubmit(let data): try data.encode(to: encoder) - case .stop(let data): - try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/SubmissionResponse.swift b/seed/swift-sdk/trace/Sources/Schemas/SubmissionResponse.swift index 743265766b2f..afb0e2f485fa 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/SubmissionResponse.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/SubmissionResponse.swift @@ -1,29 +1,29 @@ import Foundation public enum SubmissionResponse: Codable, Hashable, Sendable { - case serverInitialized(ServerInitialized) + case codeExecutionUpdate(CodeExecutionUpdate) case problemInitialized(ProblemInitialized) - case workspaceInitialized(WorkspaceInitialized) case serverErrored(ServerErrored) - case codeExecutionUpdate(CodeExecutionUpdate) + case serverInitialized(ServerInitialized) case terminated(Terminated) + case workspaceInitialized(WorkspaceInitialized) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "serverInitialized": - self = .serverInitialized(try ServerInitialized(from: decoder)) + case "codeExecutionUpdate": + self = .codeExecutionUpdate(try CodeExecutionUpdate(from: decoder)) case "problemInitialized": self = .problemInitialized(try ProblemInitialized(from: decoder)) - case "workspaceInitialized": - self = .workspaceInitialized(try WorkspaceInitialized(from: decoder)) case "serverErrored": self = .serverErrored(try ServerErrored(from: decoder)) - case "codeExecutionUpdate": - self = .codeExecutionUpdate(try CodeExecutionUpdate(from: decoder)) + case "serverInitialized": + self = .serverInitialized(try ServerInitialized(from: decoder)) case "terminated": self = .terminated(try Terminated(from: decoder)) + case "workspaceInitialized": + self = .workspaceInitialized(try WorkspaceInitialized(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -36,18 +36,18 @@ public enum SubmissionResponse: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .serverInitialized(let data): + case .codeExecutionUpdate(let data): try data.encode(to: encoder) case .problemInitialized(let data): try data.encode(to: encoder) - case .workspaceInitialized(let data): - try data.encode(to: encoder) case .serverErrored(let data): try data.encode(to: encoder) - case .codeExecutionUpdate(let data): + case .serverInitialized(let data): try data.encode(to: encoder) case .terminated(let data): try data.encode(to: encoder) + case .workspaceInitialized(let data): + try data.encode(to: encoder) } } @@ -171,12 +171,12 @@ public enum SubmissionResponse: Codable, Hashable, Sendable { public struct CodeExecutionUpdate: Codable, Hashable, Sendable { public let type: String = "codeExecutionUpdate" - public let value: CodeExecutionUpdate + public let value: Trace.CodeExecutionUpdate /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: CodeExecutionUpdate, + value: Trace.CodeExecutionUpdate, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -185,7 +185,7 @@ public enum SubmissionResponse: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(CodeExecutionUpdate.self, forKey: .value) + self.value = try container.decode(Trace.CodeExecutionUpdate.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/trace/Sources/Schemas/TestCaseFunction.swift b/seed/swift-sdk/trace/Sources/Schemas/TestCaseFunction.swift index 4adfae0cf3af..a7bb9876441d 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/TestCaseFunction.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/TestCaseFunction.swift @@ -1,17 +1,17 @@ import Foundation public enum TestCaseFunction: Codable, Hashable, Sendable { - case withActualResult(WithActualResult) case custom(Custom) + case withActualResult(WithActualResult) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "withActualResult": - self = .withActualResult(try WithActualResult(from: decoder)) case "custom": self = .custom(try Custom(from: decoder)) + case "withActualResult": + self = .withActualResult(try WithActualResult(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum TestCaseFunction: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .withActualResult(let data): - try data.encode(to: encoder) case .custom(let data): try data.encode(to: encoder) + case .withActualResult(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/TestCaseFunctionType.swift b/seed/swift-sdk/trace/Sources/Schemas/TestCaseFunctionType.swift index 64be19cb862f..b80ddc177676 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/TestCaseFunctionType.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/TestCaseFunctionType.swift @@ -1,17 +1,17 @@ import Foundation public enum TestCaseFunctionType: Codable, Hashable, Sendable { - case withActualResult(WithActualResult) case custom(Custom) + case withActualResult(WithActualResult) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "withActualResult": - self = .withActualResult(try WithActualResult(from: decoder)) case "custom": self = .custom(try Custom(from: decoder)) + case "withActualResult": + self = .withActualResult(try WithActualResult(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum TestCaseFunctionType: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .withActualResult(let data): - try data.encode(to: encoder) case .custom(let data): try data.encode(to: encoder) + case .withActualResult(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/TestCaseImplementationReference.swift b/seed/swift-sdk/trace/Sources/Schemas/TestCaseImplementationReference.swift index 817ab5928675..b8f88fe4b977 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/TestCaseImplementationReference.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/TestCaseImplementationReference.swift @@ -1,17 +1,17 @@ import Foundation public enum TestCaseImplementationReference: Codable, Hashable, Sendable { - case templateId(TemplateId) case implementation(Implementation) + case templateId(TemplateId) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "templateId": - self = .templateId(try TemplateId(from: decoder)) case "implementation": self = .implementation(try Implementation(from: decoder)) + case "templateId": + self = .templateId(try TemplateId(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum TestCaseImplementationReference: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .templateId(let data): - try data.encode(to: encoder) case .implementation(let data): try data.encode(to: encoder) + case .templateId(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/TestCaseImplementationReferenceType.swift b/seed/swift-sdk/trace/Sources/Schemas/TestCaseImplementationReferenceType.swift index 4868ae45e946..183e718c7ca3 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/TestCaseImplementationReferenceType.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/TestCaseImplementationReferenceType.swift @@ -1,17 +1,17 @@ import Foundation public enum TestCaseImplementationReferenceType: Codable, Hashable, Sendable { - case templateId(TemplateId) case implementation(Implementation) + case templateId(TemplateId) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "templateId": - self = .templateId(try TemplateId(from: decoder)) case "implementation": self = .implementation(try Implementation(from: decoder)) + case "templateId": + self = .templateId(try TemplateId(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum TestCaseImplementationReferenceType: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .templateId(let data): - try data.encode(to: encoder) case .implementation(let data): try data.encode(to: encoder) + case .templateId(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/TestSubmissionStatus.swift b/seed/swift-sdk/trace/Sources/Schemas/TestSubmissionStatus.swift index eb37b5477e28..0e84f3b85b01 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/TestSubmissionStatus.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/TestSubmissionStatus.swift @@ -1,21 +1,21 @@ import Foundation public enum TestSubmissionStatus: Codable, Hashable, Sendable { - case stopped(Stopped) case errored(Errored) case running(Running) + case stopped(Stopped) case testCaseIdToState(TestCaseIdToState) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "stopped": - self = .stopped(try Stopped(from: decoder)) case "errored": self = .errored(try Errored(from: decoder)) case "running": self = .running(try Running(from: decoder)) + case "stopped": + self = .stopped(try Stopped(from: decoder)) case "testCaseIdToState": self = .testCaseIdToState(try TestCaseIdToState(from: decoder)) default: @@ -30,12 +30,12 @@ public enum TestSubmissionStatus: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .stopped(let data): - try data.encode(to: encoder) case .errored(let data): try data.encode(to: encoder) case .running(let data): try data.encode(to: encoder) + case .stopped(let data): + try data.encode(to: encoder) case .testCaseIdToState(let data): try data.encode(to: encoder) } diff --git a/seed/swift-sdk/trace/Sources/Schemas/TestSubmissionUpdateInfo.swift b/seed/swift-sdk/trace/Sources/Schemas/TestSubmissionUpdateInfo.swift index 30ed393ce5f4..e04d288f4256 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/TestSubmissionUpdateInfo.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/TestSubmissionUpdateInfo.swift @@ -1,29 +1,29 @@ import Foundation public enum TestSubmissionUpdateInfo: Codable, Hashable, Sendable { - case running(Running) - case stopped(Stopped) case errored(Errored) + case finished(Finished) case gradedTestCase(GradedTestCase) case recordedTestCase(RecordedTestCase) - case finished(Finished) + case running(Running) + case stopped(Stopped) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "running": - self = .running(try Running(from: decoder)) - case "stopped": - self = .stopped(try Stopped(from: decoder)) case "errored": self = .errored(try Errored(from: decoder)) + case "finished": + self = .finished(try Finished(from: decoder)) case "gradedTestCase": self = .gradedTestCase(try GradedTestCase(from: decoder)) case "recordedTestCase": self = .recordedTestCase(try RecordedTestCase(from: decoder)) - case "finished": - self = .finished(try Finished(from: decoder)) + case "running": + self = .running(try Running(from: decoder)) + case "stopped": + self = .stopped(try Stopped(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -36,17 +36,17 @@ public enum TestSubmissionUpdateInfo: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .running(let data): - try data.encode(to: encoder) - case .stopped(let data): - try data.encode(to: encoder) case .errored(let data): try data.encode(to: encoder) + case .finished(let data): + try data.encode(to: encoder) case .gradedTestCase(let data): try data.encode(to: encoder) case .recordedTestCase(let data): try data.encode(to: encoder) - case .finished(let data): + case .running(let data): + try data.encode(to: encoder) + case .stopped(let data): try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/VariableType.swift b/seed/swift-sdk/trace/Sources/Schemas/VariableType.swift index 98ab2eb2f0b0..bded0ade5732 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/VariableType.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/VariableType.swift @@ -1,41 +1,41 @@ import Foundation public enum VariableType: Codable, Hashable, Sendable { - case integerType(IntegerType) - case doubleType(DoubleType) + case binaryTreeType(BinaryTreeType) case booleanType(BooleanType) - case stringType(StringType) case charType(CharType) + case doubleType(DoubleType) + case doublyLinkedListType(DoublyLinkedListType) + case integerType(IntegerType) case listType(ListType) case mapType(MapType) - case binaryTreeType(BinaryTreeType) case singlyLinkedListType(SinglyLinkedListType) - case doublyLinkedListType(DoublyLinkedListType) + case stringType(StringType) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "integerType": - self = .integerType(try IntegerType(from: decoder)) - case "doubleType": - self = .doubleType(try DoubleType(from: decoder)) + case "binaryTreeType": + self = .binaryTreeType(try BinaryTreeType(from: decoder)) case "booleanType": self = .booleanType(try BooleanType(from: decoder)) - case "stringType": - self = .stringType(try StringType(from: decoder)) case "charType": self = .charType(try CharType(from: decoder)) + case "doubleType": + self = .doubleType(try DoubleType(from: decoder)) + case "doublyLinkedListType": + self = .doublyLinkedListType(try DoublyLinkedListType(from: decoder)) + case "integerType": + self = .integerType(try IntegerType(from: decoder)) case "listType": self = .listType(try ListType(from: decoder)) case "mapType": self = .mapType(try MapType(from: decoder)) - case "binaryTreeType": - self = .binaryTreeType(try BinaryTreeType(from: decoder)) case "singlyLinkedListType": self = .singlyLinkedListType(try SinglyLinkedListType(from: decoder)) - case "doublyLinkedListType": - self = .doublyLinkedListType(try DoublyLinkedListType(from: decoder)) + case "stringType": + self = .stringType(try StringType(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -48,25 +48,25 @@ public enum VariableType: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .integerType(let data): - try data.encode(to: encoder) - case .doubleType(let data): + case .binaryTreeType(let data): try data.encode(to: encoder) case .booleanType(let data): try data.encode(to: encoder) - case .stringType(let data): - try data.encode(to: encoder) case .charType(let data): try data.encode(to: encoder) + case .doubleType(let data): + try data.encode(to: encoder) + case .doublyLinkedListType(let data): + try data.encode(to: encoder) + case .integerType(let data): + try data.encode(to: encoder) case .listType(let data): try data.encode(to: encoder) case .mapType(let data): try data.encode(to: encoder) - case .binaryTreeType(let data): - try data.encode(to: encoder) case .singlyLinkedListType(let data): try data.encode(to: encoder) - case .doublyLinkedListType(let data): + case .stringType(let data): try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/VariableValue.swift b/seed/swift-sdk/trace/Sources/Schemas/VariableValue.swift index 56a3bb1be6bd..81f2d5a16700 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/VariableValue.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/VariableValue.swift @@ -1,44 +1,44 @@ import Foundation public enum VariableValue: Codable, Hashable, Sendable { - case integerValue(IntegerValue) + case binaryTreeValue(BinaryTreeValue) case booleanValue(BooleanValue) - case doubleValue(DoubleValue) - case stringValue(StringValue) case charValue(CharValue) - case mapValue(MapValue) - case listValue(ListValue) - case binaryTreeValue(BinaryTreeValue) - case singlyLinkedListValue(SinglyLinkedListValue) + case doubleValue(DoubleValue) case doublyLinkedListValue(DoublyLinkedListValue) + case integerValue(IntegerValue) + case listValue(ListValue) + case mapValue(MapValue) case nullValue(NullValue) + case singlyLinkedListValue(SinglyLinkedListValue) + case stringValue(StringValue) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "integerValue": - self = .integerValue(try IntegerValue(from: decoder)) + case "binaryTreeValue": + self = .binaryTreeValue(try BinaryTreeValue(from: decoder)) case "booleanValue": self = .booleanValue(try BooleanValue(from: decoder)) - case "doubleValue": - self = .doubleValue(try DoubleValue(from: decoder)) - case "stringValue": - self = .stringValue(try StringValue(from: decoder)) case "charValue": self = .charValue(try CharValue(from: decoder)) - case "mapValue": - self = .mapValue(try MapValue(from: decoder)) - case "listValue": - self = .listValue(try ListValue(from: decoder)) - case "binaryTreeValue": - self = .binaryTreeValue(try BinaryTreeValue(from: decoder)) - case "singlyLinkedListValue": - self = .singlyLinkedListValue(try SinglyLinkedListValue(from: decoder)) + case "doubleValue": + self = .doubleValue(try DoubleValue(from: decoder)) case "doublyLinkedListValue": self = .doublyLinkedListValue(try DoublyLinkedListValue(from: decoder)) + case "integerValue": + self = .integerValue(try IntegerValue(from: decoder)) + case "listValue": + self = .listValue(try ListValue(from: decoder)) + case "mapValue": + self = .mapValue(try MapValue(from: decoder)) case "nullValue": self = .nullValue(try NullValue(from: decoder)) + case "singlyLinkedListValue": + self = .singlyLinkedListValue(try SinglyLinkedListValue(from: decoder)) + case "stringValue": + self = .stringValue(try StringValue(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -51,27 +51,27 @@ public enum VariableValue: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .integerValue(let data): + case .binaryTreeValue(let data): try data.encode(to: encoder) case .booleanValue(let data): try data.encode(to: encoder) - case .doubleValue(let data): + case .charValue(let data): try data.encode(to: encoder) - case .stringValue(let data): + case .doubleValue(let data): try data.encode(to: encoder) - case .charValue(let data): + case .doublyLinkedListValue(let data): try data.encode(to: encoder) - case .mapValue(let data): + case .integerValue(let data): try data.encode(to: encoder) case .listValue(let data): try data.encode(to: encoder) - case .binaryTreeValue(let data): + case .mapValue(let data): try data.encode(to: encoder) - case .singlyLinkedListValue(let data): + case .nullValue(let data): try data.encode(to: encoder) - case .doublyLinkedListValue(let data): + case .singlyLinkedListValue(let data): try data.encode(to: encoder) - case .nullValue(let data): + case .stringValue(let data): try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Sources/Schemas/WorkspaceSubmissionStatus.swift b/seed/swift-sdk/trace/Sources/Schemas/WorkspaceSubmissionStatus.swift index d064b8dd8383..1f1300669d3b 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/WorkspaceSubmissionStatus.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/WorkspaceSubmissionStatus.swift @@ -1,24 +1,24 @@ import Foundation public enum WorkspaceSubmissionStatus: Codable, Hashable, Sendable { - case stopped(Stopped) case errored(Errored) - case running(Running) case ran(Ran) + case running(Running) + case stopped(Stopped) case traced(Traced) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "stopped": - self = .stopped(try Stopped(from: decoder)) case "errored": self = .errored(try Errored(from: decoder)) - case "running": - self = .running(try Running(from: decoder)) case "ran": self = .ran(try Ran(from: decoder)) + case "running": + self = .running(try Running(from: decoder)) + case "stopped": + self = .stopped(try Stopped(from: decoder)) case "traced": self = .traced(try Traced(from: decoder)) default: @@ -33,13 +33,13 @@ public enum WorkspaceSubmissionStatus: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .stopped(let data): - try data.encode(to: encoder) case .errored(let data): try data.encode(to: encoder) + case .ran(let data): + try data.encode(to: encoder) case .running(let data): try data.encode(to: encoder) - case .ran(let data): + case .stopped(let data): try data.encode(to: encoder) case .traced(let data): try data.encode(to: encoder) diff --git a/seed/swift-sdk/trace/Sources/Schemas/WorkspaceSubmissionUpdateInfo.swift b/seed/swift-sdk/trace/Sources/Schemas/WorkspaceSubmissionUpdateInfo.swift index f84d5e1ec64d..696448c6025e 100644 --- a/seed/swift-sdk/trace/Sources/Schemas/WorkspaceSubmissionUpdateInfo.swift +++ b/seed/swift-sdk/trace/Sources/Schemas/WorkspaceSubmissionUpdateInfo.swift @@ -1,32 +1,32 @@ import Foundation public enum WorkspaceSubmissionUpdateInfo: Codable, Hashable, Sendable { - case running(Running) + case errored(Errored) + case finished(Finished) case ran(Ran) + case running(Running) case stopped(Stopped) case traced(Traced) case tracedV2(TracedV2) - case errored(Errored) - case finished(Finished) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "running": - self = .running(try Running(from: decoder)) + case "errored": + self = .errored(try Errored(from: decoder)) + case "finished": + self = .finished(try Finished(from: decoder)) case "ran": self = .ran(try Ran(from: decoder)) + case "running": + self = .running(try Running(from: decoder)) case "stopped": self = .stopped(try Stopped(from: decoder)) case "traced": self = .traced(try Traced(from: decoder)) case "tracedV2": self = .tracedV2(try TracedV2(from: decoder)) - case "errored": - self = .errored(try Errored(from: decoder)) - case "finished": - self = .finished(try Finished(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -39,20 +39,20 @@ public enum WorkspaceSubmissionUpdateInfo: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .running(let data): + case .errored(let data): + try data.encode(to: encoder) + case .finished(let data): try data.encode(to: encoder) case .ran(let data): try data.encode(to: encoder) + case .running(let data): + try data.encode(to: encoder) case .stopped(let data): try data.encode(to: encoder) case .traced(let data): try data.encode(to: encoder) case .tracedV2(let data): try data.encode(to: encoder) - case .errored(let data): - try data.encode(to: encoder) - case .finished(let data): - try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/trace/Tests/Wire/Resources/Playlist/PlaylistClientWireTests.swift b/seed/swift-sdk/trace/Tests/Wire/Resources/Playlist/PlaylistClientWireTests.swift index d05c2ba296c1..034419e5fd19 100644 --- a/seed/swift-sdk/trace/Tests/Wire/Resources/Playlist/PlaylistClientWireTests.swift +++ b/seed/swift-sdk/trace/Tests/Wire/Resources/Playlist/PlaylistClientWireTests.swift @@ -106,9 +106,7 @@ import Trace serviceParam: 1, limit: 1, otherField: "otherField", - multiLineDocs: "multiLineDocs", - optionalMultipleField: , - multipleField: + multiLineDocs: "multiLineDocs" ) try #require(response == expectedResponse) } diff --git a/seed/swift-sdk/trace/reference.md b/seed/swift-sdk/trace/reference.md index 7d40fbf004d6..bbd473a00511 100644 --- a/seed/swift-sdk/trace/reference.md +++ b/seed/swift-sdk/trace/reference.md @@ -70,7 +70,7 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.updateTestSubmissionStatus( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: TestSubmissionStatus.stopped( .init( @@ -142,7 +142,7 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.sendTestSubmissionUpdate( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: TestSubmissionUpdate( updateTime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), updateInfo: TestSubmissionUpdateInfo.running( @@ -217,7 +217,7 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.updateWorkspaceSubmissionStatus( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: WorkspaceSubmissionStatus.stopped( .init( @@ -289,7 +289,7 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.sendWorkspaceSubmissionUpdate( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: WorkspaceSubmissionUpdate( updateTime: try! Date("2024-01-15T09:30:00Z", strategy: .iso8601), updateInfo: WorkspaceSubmissionUpdateInfo.running( @@ -364,7 +364,7 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.storeTracedTestCase( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, testCaseId: "testCaseId", request: .init( result: TestCaseResultWithStdout( @@ -389,7 +389,7 @@ private func main() async throws { ), traceResponses: [ TraceResponse( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, returnValue: DebugVariableValue.integerValue( .init( @@ -430,7 +430,7 @@ private func main() async throws { stdout: "stdout" ), TraceResponse( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, returnValue: DebugVariableValue.integerValue( .init( @@ -546,11 +546,11 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.storeTracedTestCaseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, testCaseId: "testCaseId", request: [ TraceResponseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, file: TracedFile( filename: "filename", @@ -595,7 +595,7 @@ private func main() async throws { stdout: "stdout" ), TraceResponseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, file: TracedFile( filename: "filename", @@ -714,7 +714,7 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.storeTracedWorkspace( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: .init( workspaceRunDetails: WorkspaceRunDetails( exceptionV2: ExceptionV2.generic( @@ -733,7 +733,7 @@ private func main() async throws { ), traceResponses: [ TraceResponse( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, returnValue: DebugVariableValue.integerValue( .init( @@ -774,7 +774,7 @@ private func main() async throws { stdout: "stdout" ), TraceResponse( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, returnValue: DebugVariableValue.integerValue( .init( @@ -882,10 +882,10 @@ private func main() async throws { let client = TraceClient(token: "") _ = try await client.admin.storeTracedWorkspaceV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, request: [ TraceResponseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, file: TracedFile( filename: "filename", @@ -930,7 +930,7 @@ private func main() async throws { stdout: "stdout" ), TraceResponseV2( - submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32"), + submissionId: UUID(uuidString: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32")!, lineNumber: 1, file: TracedFile( filename: "filename", @@ -1333,9 +1333,7 @@ private func main() async throws { serviceParam: 1, limit: 1, otherField: "otherField", - multiLineDocs: "multiLineDocs", - optionalMultipleField: , - multipleField: + multiLineDocs: "multiLineDocs" ) } diff --git a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/Key.swift b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/Key.swift index 844eea2ba0f2..ba6da34362ee 100644 --- a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/Key.swift +++ b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/Key.swift @@ -1,15 +1,15 @@ import Foundation public enum Key: Codable, Hashable, Sendable { + case `default`(Default) case keyType(KeyType) - case json(JSONValue) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(KeyType.self) { + if let value = try? container.decode(Default.self) { + self = .default(value) + } else if let value = try? container.decode(KeyType.self) { self = .keyType(value) - } else if let value = try? container.decode(JSONValue.self) { - self = .json(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -21,10 +21,14 @@ public enum Key: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .keyType(let value): + case .default(let value): try container.encode(value) - case .json(let value): + case .keyType(let value): try container.encode(value) } } + + public enum Default: String, Codable, Hashable, CaseIterable, Sendable { + case `default` + } } \ No newline at end of file diff --git a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/MetadataUnion.swift b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/MetadataUnion.swift index 0d58770021ce..f2ab538b03cd 100644 --- a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/MetadataUnion.swift +++ b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/MetadataUnion.swift @@ -1,15 +1,15 @@ import Foundation public enum MetadataUnion: Codable, Hashable, Sendable { - case optionalMetadata(OptionalMetadata) case namedMetadata(NamedMetadata) + case optionalMetadata(OptionalMetadata) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(OptionalMetadata.self) { - self = .optionalMetadata(value) - } else if let value = try? container.decode(NamedMetadata.self) { + if let value = try? container.decode(NamedMetadata.self) { self = .namedMetadata(value) + } else if let value = try? container.decode(OptionalMetadata.self) { + self = .optionalMetadata(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -21,10 +21,10 @@ public enum MetadataUnion: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .optionalMetadata(let value): - try container.encode(value) case .namedMetadata(let value): try container.encode(value) + case .optionalMetadata(let value): + try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/MyUnion.swift b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/MyUnion.swift index 112f21a40fd9..1021d3b45f1a 100644 --- a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/MyUnion.swift +++ b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/MyUnion.swift @@ -2,27 +2,27 @@ import Foundation /// Several different types are accepted. public enum MyUnion: Codable, Hashable, Sendable { - case string(String) - case stringArray([String]) case int(Int) case intArray([Int]) case intArrayArray([[Int]]) - case json(JSONValue) + case jsonValue(JSONValue) + case string(String) + case stringArray([String]) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(String.self) { - self = .string(value) - } else if let value = try? container.decode([String].self) { - self = .stringArray(value) - } else if let value = try? container.decode(Int.self) { + if let value = try? container.decode(Int.self) { self = .int(value) } else if let value = try? container.decode([Int].self) { self = .intArray(value) } else if let value = try? container.decode([[Int]].self) { self = .intArrayArray(value) } else if let value = try? container.decode(JSONValue.self) { - self = .json(value) + self = .jsonValue(value) + } else if let value = try? container.decode(String.self) { + self = .string(value) + } else if let value = try? container.decode([String].self) { + self = .stringArray(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -34,17 +34,17 @@ public enum MyUnion: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .string(let value): - try container.encode(value) - case .stringArray(let value): - try container.encode(value) case .int(let value): try container.encode(value) case .intArray(let value): try container.encode(value) case .intArrayArray(let value): try container.encode(value) - case .json(let value): + case .jsonValue(let value): + try container.encode(value) + case .string(let value): + try container.encode(value) + case .stringArray(let value): try container.encode(value) } } diff --git a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionL1.swift b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionL1.swift index 7babe5b79e92..61ebfbb2236f 100644 --- a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionL1.swift +++ b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionL1.swift @@ -3,20 +3,20 @@ import Foundation /// Nested layer 1. public enum NestedUnionL1: Codable, Hashable, Sendable { case int(Int) - case json(JSONValue) - case stringArray([String]) + case jsonValue(JSONValue) case nestedUnionL2(NestedUnionL2) + case stringArray([String]) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() if let value = try? container.decode(Int.self) { self = .int(value) } else if let value = try? container.decode(JSONValue.self) { - self = .json(value) - } else if let value = try? container.decode([String].self) { - self = .stringArray(value) + self = .jsonValue(value) } else if let value = try? container.decode(NestedUnionL2.self) { self = .nestedUnionL2(value) + } else if let value = try? container.decode([String].self) { + self = .stringArray(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -30,12 +30,12 @@ public enum NestedUnionL1: Codable, Hashable, Sendable { switch self { case .int(let value): try container.encode(value) - case .json(let value): - try container.encode(value) - case .stringArray(let value): + case .jsonValue(let value): try container.encode(value) case .nestedUnionL2(let value): try container.encode(value) + case .stringArray(let value): + try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionL2.swift b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionL2.swift index 95f0895e66a9..b6ca32108e43 100644 --- a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionL2.swift +++ b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionL2.swift @@ -3,7 +3,7 @@ import Foundation /// Nested layer 2. public enum NestedUnionL2: Codable, Hashable, Sendable { case bool(Bool) - case json(JSONValue) + case jsonValue(JSONValue) case stringArray([String]) public init(from decoder: Decoder) throws { @@ -11,7 +11,7 @@ public enum NestedUnionL2: Codable, Hashable, Sendable { if let value = try? container.decode(Bool.self) { self = .bool(value) } else if let value = try? container.decode(JSONValue.self) { - self = .json(value) + self = .jsonValue(value) } else if let value = try? container.decode([String].self) { self = .stringArray(value) } else { @@ -27,7 +27,7 @@ public enum NestedUnionL2: Codable, Hashable, Sendable { switch self { case .bool(let value): try container.encode(value) - case .json(let value): + case .jsonValue(let value): try container.encode(value) case .stringArray(let value): try container.encode(value) diff --git a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionRoot.swift b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionRoot.swift index 3e0b31546cfb..1b3a1ade9f72 100644 --- a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionRoot.swift +++ b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/NestedUnionRoot.swift @@ -2,18 +2,18 @@ import Foundation /// Nested union root. public enum NestedUnionRoot: Codable, Hashable, Sendable { + case nestedUnionL1(NestedUnionL1) case string(String) case stringArray([String]) - case nestedUnionL1(NestedUnionL1) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(String.self) { + if let value = try? container.decode(NestedUnionL1.self) { + self = .nestedUnionL1(value) + } else if let value = try? container.decode(String.self) { self = .string(value) } else if let value = try? container.decode([String].self) { self = .stringArray(value) - } else if let value = try? container.decode(NestedUnionL1.self) { - self = .nestedUnionL1(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -25,12 +25,12 @@ public enum NestedUnionRoot: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { + case .nestedUnionL1(let value): + try container.encode(value) case .string(let value): try container.encode(value) case .stringArray(let value): try container.encode(value) - case .nestedUnionL1(let value): - try container.encode(value) } } } \ No newline at end of file diff --git a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/UnionWithDuplicateTypes.swift b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/UnionWithDuplicateTypes.swift index f8880dc4a17c..5b60a28ebb05 100644 --- a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/UnionWithDuplicateTypes.swift +++ b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/UnionWithDuplicateTypes.swift @@ -2,21 +2,21 @@ import Foundation /// Duplicate types. public enum UnionWithDuplicateTypes: Codable, Hashable, Sendable { + case int(Int) + case jsonValue(JSONValue) case string(String) case stringArray([String]) - case int(Int) - case json(JSONValue) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(String.self) { + if let value = try? container.decode(Int.self) { + self = .int(value) + } else if let value = try? container.decode(JSONValue.self) { + self = .jsonValue(value) + } else if let value = try? container.decode(String.self) { self = .string(value) } else if let value = try? container.decode([String].self) { self = .stringArray(value) - } else if let value = try? container.decode(Int.self) { - self = .int(value) - } else if let value = try? container.decode(JSONValue.self) { - self = .json(value) } else { throw DecodingError.dataCorruptedError( in: container, @@ -28,13 +28,13 @@ public enum UnionWithDuplicateTypes: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .string(let value): + case .int(let value): try container.encode(value) - case .stringArray(let value): + case .jsonValue(let value): try container.encode(value) - case .int(let value): + case .string(let value): try container.encode(value) - case .json(let value): + case .stringArray(let value): try container.encode(value) } } diff --git a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/UnionWithIdenticalPrimitives.swift b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/UnionWithIdenticalPrimitives.swift index 9b38e6357d6b..7385fbd9c474 100644 --- a/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/UnionWithIdenticalPrimitives.swift +++ b/seed/swift-sdk/undiscriminated-unions/Sources/Schemas/UnionWithIdenticalPrimitives.swift @@ -2,16 +2,16 @@ import Foundation /// Mix of primitives where some resolve to the same Java type. public enum UnionWithIdenticalPrimitives: Codable, Hashable, Sendable { - case int(Int) case double(Double) + case int(Int) case string(String) public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() - if let value = try? container.decode(Int.self) { - self = .int(value) - } else if let value = try? container.decode(Double.self) { + if let value = try? container.decode(Double.self) { self = .double(value) + } else if let value = try? container.decode(Int.self) { + self = .int(value) } else if let value = try? container.decode(String.self) { self = .string(value) } else { @@ -25,10 +25,10 @@ public enum UnionWithIdenticalPrimitives: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { var container = encoder.singleValueContainer() switch self { - case .int(let value): - try container.encode(value) case .double(let value): try container.encode(value) + case .int(let value): + try container.encode(value) case .string(let value): try container.encode(value) } diff --git a/seed/swift-sdk/undiscriminated-unions/Tests/Wire/Resources/Union/UnionClientWireTests.swift b/seed/swift-sdk/undiscriminated-unions/Tests/Wire/Resources/Union/UnionClientWireTests.swift index b1fa0ff5a2bd..532835d72d50 100644 --- a/seed/swift-sdk/undiscriminated-unions/Tests/Wire/Resources/Union/UnionClientWireTests.swift +++ b/seed/swift-sdk/undiscriminated-unions/Tests/Wire/Resources/Union/UnionClientWireTests.swift @@ -49,7 +49,7 @@ import UndiscriminatedUnions Key.keyType( .value ): "exampleValue", - Key.json( + Key.jsonValue( .default ): "exampleDefault" ] diff --git a/seed/swift-sdk/unions/Sources/Schemas/BigUnion.swift b/seed/swift-sdk/unions/Sources/Schemas/BigUnion.swift index fbc3ea874d3a..504ee1eff4bd 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/BigUnion.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/BigUnion.swift @@ -1,98 +1,98 @@ import Foundation public enum BigUnion: Codable, Hashable, Sendable { - case normalSweet(NormalSweet) - case thankfulFactor(ThankfulFactor) - case jumboEnd(JumboEnd) - case hastyPain(HastyPain) - case mistySnow(MistySnow) - case distinctFailure(DistinctFailure) - case practicalPrinciple(PracticalPrinciple) - case limpingStep(LimpingStep) - case vibrantExcitement(VibrantExcitement) case activeDiamond(ActiveDiamond) - case popularLimit(PopularLimit) - case falseMirror(FalseMirror) - case primaryBlock(PrimaryBlock) - case rotatingRatio(RotatingRatio) + case attractiveScript(AttractiveScript) + case circularCard(CircularCard) case colorfulCover(ColorfulCover) + case diligentDeal(DiligentDeal) case disloyalValue(DisloyalValue) + case distinctFailure(DistinctFailure) + case falseMirror(FalseMirror) + case frozenSleep(FrozenSleep) + case gaseousRoad(GaseousRoad) case gruesomeCoach(GruesomeCoach) - case totalWork(TotalWork) case harmoniousPlay(HarmoniousPlay) - case uniqueStress(UniqueStress) - case unwillingSmoke(UnwillingSmoke) - case frozenSleep(FrozenSleep) - case diligentDeal(DiligentDeal) - case attractiveScript(AttractiveScript) + case hastyPain(HastyPain) case hoarseMouse(HoarseMouse) - case circularCard(CircularCard) + case jumboEnd(JumboEnd) + case limpingStep(LimpingStep) + case mistySnow(MistySnow) + case normalSweet(NormalSweet) + case popularLimit(PopularLimit) case potableBad(PotableBad) + case practicalPrinciple(PracticalPrinciple) + case primaryBlock(PrimaryBlock) + case rotatingRatio(RotatingRatio) + case thankfulFactor(ThankfulFactor) + case totalWork(TotalWork) case triangularRepair(TriangularRepair) - case gaseousRoad(GaseousRoad) + case uniqueStress(UniqueStress) + case unwillingSmoke(UnwillingSmoke) + case vibrantExcitement(VibrantExcitement) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "normalSweet": - self = .normalSweet(try NormalSweet(from: decoder)) - case "thankfulFactor": - self = .thankfulFactor(try ThankfulFactor(from: decoder)) - case "jumboEnd": - self = .jumboEnd(try JumboEnd(from: decoder)) - case "hastyPain": - self = .hastyPain(try HastyPain(from: decoder)) - case "mistySnow": - self = .mistySnow(try MistySnow(from: decoder)) - case "distinctFailure": - self = .distinctFailure(try DistinctFailure(from: decoder)) - case "practicalPrinciple": - self = .practicalPrinciple(try PracticalPrinciple(from: decoder)) - case "limpingStep": - self = .limpingStep(try LimpingStep(from: decoder)) - case "vibrantExcitement": - self = .vibrantExcitement(try VibrantExcitement(from: decoder)) case "activeDiamond": self = .activeDiamond(try ActiveDiamond(from: decoder)) - case "popularLimit": - self = .popularLimit(try PopularLimit(from: decoder)) - case "falseMirror": - self = .falseMirror(try FalseMirror(from: decoder)) - case "primaryBlock": - self = .primaryBlock(try PrimaryBlock(from: decoder)) - case "rotatingRatio": - self = .rotatingRatio(try RotatingRatio(from: decoder)) + case "attractiveScript": + self = .attractiveScript(try AttractiveScript(from: decoder)) + case "circularCard": + self = .circularCard(try CircularCard(from: decoder)) case "colorfulCover": self = .colorfulCover(try ColorfulCover(from: decoder)) + case "diligentDeal": + self = .diligentDeal(try DiligentDeal(from: decoder)) case "disloyalValue": self = .disloyalValue(try DisloyalValue(from: decoder)) + case "distinctFailure": + self = .distinctFailure(try DistinctFailure(from: decoder)) + case "falseMirror": + self = .falseMirror(try FalseMirror(from: decoder)) + case "frozenSleep": + self = .frozenSleep(try FrozenSleep(from: decoder)) + case "gaseousRoad": + self = .gaseousRoad(try GaseousRoad(from: decoder)) case "gruesomeCoach": self = .gruesomeCoach(try GruesomeCoach(from: decoder)) - case "totalWork": - self = .totalWork(try TotalWork(from: decoder)) case "harmoniousPlay": self = .harmoniousPlay(try HarmoniousPlay(from: decoder)) - case "uniqueStress": - self = .uniqueStress(try UniqueStress(from: decoder)) - case "unwillingSmoke": - self = .unwillingSmoke(try UnwillingSmoke(from: decoder)) - case "frozenSleep": - self = .frozenSleep(try FrozenSleep(from: decoder)) - case "diligentDeal": - self = .diligentDeal(try DiligentDeal(from: decoder)) - case "attractiveScript": - self = .attractiveScript(try AttractiveScript(from: decoder)) + case "hastyPain": + self = .hastyPain(try HastyPain(from: decoder)) case "hoarseMouse": self = .hoarseMouse(try HoarseMouse(from: decoder)) - case "circularCard": - self = .circularCard(try CircularCard(from: decoder)) + case "jumboEnd": + self = .jumboEnd(try JumboEnd(from: decoder)) + case "limpingStep": + self = .limpingStep(try LimpingStep(from: decoder)) + case "mistySnow": + self = .mistySnow(try MistySnow(from: decoder)) + case "normalSweet": + self = .normalSweet(try NormalSweet(from: decoder)) + case "popularLimit": + self = .popularLimit(try PopularLimit(from: decoder)) case "potableBad": self = .potableBad(try PotableBad(from: decoder)) + case "practicalPrinciple": + self = .practicalPrinciple(try PracticalPrinciple(from: decoder)) + case "primaryBlock": + self = .primaryBlock(try PrimaryBlock(from: decoder)) + case "rotatingRatio": + self = .rotatingRatio(try RotatingRatio(from: decoder)) + case "thankfulFactor": + self = .thankfulFactor(try ThankfulFactor(from: decoder)) + case "totalWork": + self = .totalWork(try TotalWork(from: decoder)) case "triangularRepair": self = .triangularRepair(try TriangularRepair(from: decoder)) - case "gaseousRoad": - self = .gaseousRoad(try GaseousRoad(from: decoder)) + case "uniqueStress": + self = .uniqueStress(try UniqueStress(from: decoder)) + case "unwillingSmoke": + self = .unwillingSmoke(try UnwillingSmoke(from: decoder)) + case "vibrantExcitement": + self = .vibrantExcitement(try VibrantExcitement(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -105,63 +105,63 @@ public enum BigUnion: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .normalSweet(let data): + case .activeDiamond(let data): try data.encode(to: encoder) - case .thankfulFactor(let data): + case .attractiveScript(let data): try data.encode(to: encoder) - case .jumboEnd(let data): + case .circularCard(let data): try data.encode(to: encoder) - case .hastyPain(let data): + case .colorfulCover(let data): try data.encode(to: encoder) - case .mistySnow(let data): + case .diligentDeal(let data): try data.encode(to: encoder) - case .distinctFailure(let data): + case .disloyalValue(let data): try data.encode(to: encoder) - case .practicalPrinciple(let data): + case .distinctFailure(let data): try data.encode(to: encoder) - case .limpingStep(let data): + case .falseMirror(let data): try data.encode(to: encoder) - case .vibrantExcitement(let data): + case .frozenSleep(let data): try data.encode(to: encoder) - case .activeDiamond(let data): + case .gaseousRoad(let data): try data.encode(to: encoder) - case .popularLimit(let data): + case .gruesomeCoach(let data): try data.encode(to: encoder) - case .falseMirror(let data): + case .harmoniousPlay(let data): try data.encode(to: encoder) - case .primaryBlock(let data): + case .hastyPain(let data): try data.encode(to: encoder) - case .rotatingRatio(let data): + case .hoarseMouse(let data): try data.encode(to: encoder) - case .colorfulCover(let data): + case .jumboEnd(let data): try data.encode(to: encoder) - case .disloyalValue(let data): + case .limpingStep(let data): try data.encode(to: encoder) - case .gruesomeCoach(let data): + case .mistySnow(let data): try data.encode(to: encoder) - case .totalWork(let data): + case .normalSweet(let data): try data.encode(to: encoder) - case .harmoniousPlay(let data): + case .popularLimit(let data): try data.encode(to: encoder) - case .uniqueStress(let data): + case .potableBad(let data): try data.encode(to: encoder) - case .unwillingSmoke(let data): + case .practicalPrinciple(let data): try data.encode(to: encoder) - case .frozenSleep(let data): + case .primaryBlock(let data): try data.encode(to: encoder) - case .diligentDeal(let data): + case .rotatingRatio(let data): try data.encode(to: encoder) - case .attractiveScript(let data): + case .thankfulFactor(let data): try data.encode(to: encoder) - case .hoarseMouse(let data): + case .totalWork(let data): try data.encode(to: encoder) - case .circularCard(let data): + case .triangularRepair(let data): try data.encode(to: encoder) - case .potableBad(let data): + case .uniqueStress(let data): try data.encode(to: encoder) - case .triangularRepair(let data): + case .unwillingSmoke(let data): try data.encode(to: encoder) - case .gaseousRoad(let data): + case .vibrantExcitement(let data): try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/unions/Sources/Schemas/Union.swift b/seed/swift-sdk/unions/Sources/Schemas/Union.swift index 023d08445b6b..1195e4f90c6f 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/Union.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/Union.swift @@ -2,17 +2,17 @@ import Foundation /// This is a simple union. public enum Union: Codable, Hashable, Sendable { - case foo(Foo) case bar(Bar) + case foo(Foo) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "foo": - self = .foo(try Foo(from: decoder)) case "bar": self = .bar(try Bar(from: decoder)) + case "foo": + self = .foo(try Foo(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -25,21 +25,21 @@ public enum Union: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .foo(let data): - try data.encode(to: encoder) case .bar(let data): try data.encode(to: encoder) + case .foo(let data): + try data.encode(to: encoder) } } public struct Foo: Codable, Hashable, Sendable { public let type: String = "foo" - public let foo: Foo + public let foo: Unions.Foo /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - foo: Foo, + foo: Unions.Foo, additionalProperties: [String: JSONValue] = .init() ) { self.foo = foo @@ -48,7 +48,7 @@ public enum Union: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.foo = try container.decode(Foo.self, forKey: .foo) + self.foo = try container.decode(Unions.Foo.self, forKey: .foo) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } @@ -68,12 +68,12 @@ public enum Union: Codable, Hashable, Sendable { public struct Bar: Codable, Hashable, Sendable { public let type: String = "bar" - public let bar: Bar + public let bar: Unions.Bar /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - bar: Bar, + bar: Unions.Bar, additionalProperties: [String: JSONValue] = .init() ) { self.bar = bar @@ -82,7 +82,7 @@ public enum Union: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.bar = try container.decode(Bar.self, forKey: .bar) + self.bar = try container.decode(Unions.Bar.self, forKey: .bar) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithBaseProperties.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithBaseProperties.swift index d526d1a277b0..7731abba9285 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithBaseProperties.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithBaseProperties.swift @@ -1,20 +1,20 @@ import Foundation public enum UnionWithBaseProperties: Codable, Hashable, Sendable { + case foo(Foo) case integer(Integer) case string(String) - case foo(Foo) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminant = try container.decode(String.self, forKey: .type) + let discriminant = try container.decode(Swift.String.self, forKey: .type) switch discriminant { + case "foo": + self = .foo(try Foo(from: decoder)) case "integer": self = .integer(try Integer(from: decoder)) case "string": self = .string(try String(from: decoder)) - case "foo": - self = .foo(try Foo(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -27,24 +27,24 @@ public enum UnionWithBaseProperties: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { + case .foo(let data): + try data.encode(to: encoder) case .integer(let data): try data.encode(to: encoder) case .string(let data): try data.encode(to: encoder) - case .foo(let data): - try data.encode(to: encoder) } } public struct Integer: Codable, Hashable, Sendable { - public let type: String = "integer" + public let type: Swift.String = "integer" public let value: Int /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( value: Int, - additionalProperties: [String: JSONValue] = .init() + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.value = value self.additionalProperties = additionalProperties @@ -71,14 +71,14 @@ public enum UnionWithBaseProperties: Codable, Hashable, Sendable { } public struct String: Codable, Hashable, Sendable { - public let type: String = "string" - public let value: String + public let type: Swift.String = "string" + public let value: Swift.String /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( - value: String, - additionalProperties: [String: JSONValue] = .init() + value: Swift.String, + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.value = value self.additionalProperties = additionalProperties @@ -86,7 +86,7 @@ public enum UnionWithBaseProperties: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(String.self, forKey: .value) + self.value = try container.decode(Swift.String.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } @@ -105,14 +105,14 @@ public enum UnionWithBaseProperties: Codable, Hashable, Sendable { } public struct Foo: Codable, Hashable, Sendable { - public let type: String = "foo" - public let name: String + public let type: Swift.String = "foo" + public let name: Swift.String /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( - name: String, - additionalProperties: [String: JSONValue] = .init() + name: Swift.String, + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.name = name self.additionalProperties = additionalProperties @@ -120,7 +120,7 @@ public enum UnionWithBaseProperties: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.name = try container.decode(String.self, forKey: .name) + self.name = try container.decode(Swift.String.self, forKey: .name) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithDiscriminant.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithDiscriminant.swift index 9603b1488fc4..c960bd99f5e7 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithDiscriminant.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithDiscriminant.swift @@ -1,18 +1,18 @@ import Foundation public enum UnionWithDiscriminant: Codable, Hashable, Sendable { + case bar(Bar) /// This is a Foo field. case foo(Foo) - case bar(Bar) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "foo": - self = .foo(try Foo(from: decoder)) case "bar": self = .bar(try Bar(from: decoder)) + case "foo": + self = .foo(try Foo(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -25,22 +25,22 @@ public enum UnionWithDiscriminant: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .foo(let data): - try data.encode(to: encoder) case .bar(let data): try data.encode(to: encoder) + case .foo(let data): + try data.encode(to: encoder) } } /// This is a Foo field. public struct Foo: Codable, Hashable, Sendable { public let type: String = "foo" - public let foo: Foo + public let foo: Unions.Foo /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - foo: Foo, + foo: Unions.Foo, additionalProperties: [String: JSONValue] = .init() ) { self.foo = foo @@ -49,7 +49,7 @@ public enum UnionWithDiscriminant: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.foo = try container.decode(Foo.self, forKey: .foo) + self.foo = try container.decode(Unions.Foo.self, forKey: .foo) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } @@ -69,12 +69,12 @@ public enum UnionWithDiscriminant: Codable, Hashable, Sendable { public struct Bar: Codable, Hashable, Sendable { public let type: String = "bar" - public let bar: Bar + public let bar: Unions.Bar /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - bar: Bar, + bar: Unions.Bar, additionalProperties: [String: JSONValue] = .init() ) { self.bar = bar @@ -83,7 +83,7 @@ public enum UnionWithDiscriminant: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.bar = try container.decode(Bar.self, forKey: .bar) + self.bar = try container.decode(Unions.Bar.self, forKey: .bar) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithMultipleNoProperties.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithMultipleNoProperties.swift index 6e6a1ee1804b..1284c2a1dce5 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithMultipleNoProperties.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithMultipleNoProperties.swift @@ -1,20 +1,20 @@ import Foundation public enum UnionWithMultipleNoProperties: Codable, Hashable, Sendable { - case foo(Foo) case empty1(Empty1) case empty2(Empty2) + case foo(Foo) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "foo": - self = .foo(try Foo(from: decoder)) case "empty1": self = .empty1(try Empty1(from: decoder)) case "empty2": self = .empty2(try Empty2(from: decoder)) + case "foo": + self = .foo(try Foo(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -27,12 +27,12 @@ public enum UnionWithMultipleNoProperties: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .foo(let data): - try data.encode(to: encoder) case .empty1(let data): try data.encode(to: encoder) case .empty2(let data): try data.encode(to: encoder) + case .foo(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithNoProperties.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithNoProperties.swift index 4ad3108c7797..a7ae1194eb9c 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithNoProperties.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithNoProperties.swift @@ -1,17 +1,17 @@ import Foundation public enum UnionWithNoProperties: Codable, Hashable, Sendable { - case foo(Foo) case empty(Empty) + case foo(Foo) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "foo": - self = .foo(try Foo(from: decoder)) case "empty": self = .empty(try Empty(from: decoder)) + case "foo": + self = .foo(try Foo(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -24,10 +24,10 @@ public enum UnionWithNoProperties: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .foo(let data): - try data.encode(to: encoder) case .empty(let data): try data.encode(to: encoder) + case .foo(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithOptionalTime.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithOptionalTime.swift index 0dacb1291af5..3c2073bc5e57 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithOptionalTime.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithOptionalTime.swift @@ -67,12 +67,12 @@ public enum UnionWithOptionalTime: Codable, Hashable, Sendable { public struct Datetime: Codable, Hashable, Sendable { public let type: String = "datetime" - public let value: Date? + public let value: Foundation.Date? /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: Date? = nil, + value: Foundation.Date? = nil, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -81,7 +81,7 @@ public enum UnionWithOptionalTime: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decodeIfPresent(Date.self, forKey: .value) + self.value = try container.decodeIfPresent(Foundation.Date.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithPrimitive.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithPrimitive.swift index 5cddf09b1553..9e752bcc8970 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithPrimitive.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithPrimitive.swift @@ -6,7 +6,7 @@ public enum UnionWithPrimitive: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let discriminant = try container.decode(String.self, forKey: .type) + let discriminant = try container.decode(Swift.String.self, forKey: .type) switch discriminant { case "integer": self = .integer(try Integer(from: decoder)) @@ -32,14 +32,14 @@ public enum UnionWithPrimitive: Codable, Hashable, Sendable { } public struct Integer: Codable, Hashable, Sendable { - public let type: String = "integer" + public let type: Swift.String = "integer" public let value: Int /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( value: Int, - additionalProperties: [String: JSONValue] = .init() + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.value = value self.additionalProperties = additionalProperties @@ -66,14 +66,14 @@ public enum UnionWithPrimitive: Codable, Hashable, Sendable { } public struct String: Codable, Hashable, Sendable { - public let type: String = "string" - public let value: String + public let type: Swift.String = "string" + public let value: Swift.String /// Additional properties that are not explicitly defined in the schema - public let additionalProperties: [String: JSONValue] + public let additionalProperties: [Swift.String: JSONValue] public init( - value: String, - additionalProperties: [String: JSONValue] = .init() + value: Swift.String, + additionalProperties: [Swift.String: JSONValue] = .init() ) { self.value = value self.additionalProperties = additionalProperties @@ -81,7 +81,7 @@ public enum UnionWithPrimitive: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(String.self, forKey: .value) + self.value = try container.decode(Swift.String.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithSameNumberTypes.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithSameNumberTypes.swift index 7ee66cd18130..261206eab55b 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithSameNumberTypes.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithSameNumberTypes.swift @@ -1,20 +1,20 @@ import Foundation public enum UnionWithSameNumberTypes: Codable, Hashable, Sendable { - case positiveInt(PositiveInt) - case negativeInt(NegativeInt) case anyNumber(AnyNumber) + case negativeInt(NegativeInt) + case positiveInt(PositiveInt) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "positiveInt": - self = .positiveInt(try PositiveInt(from: decoder)) - case "negativeInt": - self = .negativeInt(try NegativeInt(from: decoder)) case "anyNumber": self = .anyNumber(try AnyNumber(from: decoder)) + case "negativeInt": + self = .negativeInt(try NegativeInt(from: decoder)) + case "positiveInt": + self = .positiveInt(try PositiveInt(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -27,11 +27,11 @@ public enum UnionWithSameNumberTypes: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .positiveInt(let data): + case .anyNumber(let data): try data.encode(to: encoder) case .negativeInt(let data): try data.encode(to: encoder) - case .anyNumber(let data): + case .positiveInt(let data): try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithSameStringTypes.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithSameStringTypes.swift index 419eee23ba95..41f87782a132 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithSameStringTypes.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithSameStringTypes.swift @@ -2,8 +2,8 @@ import Foundation public enum UnionWithSameStringTypes: Codable, Hashable, Sendable { case customFormat(CustomFormat) - case regularString(RegularString) case patternString(PatternString) + case regularString(RegularString) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -11,10 +11,10 @@ public enum UnionWithSameStringTypes: Codable, Hashable, Sendable { switch discriminant { case "customFormat": self = .customFormat(try CustomFormat(from: decoder)) - case "regularString": - self = .regularString(try RegularString(from: decoder)) case "patternString": self = .patternString(try PatternString(from: decoder)) + case "regularString": + self = .regularString(try RegularString(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -29,10 +29,10 @@ public enum UnionWithSameStringTypes: Codable, Hashable, Sendable { switch self { case .customFormat(let data): try data.encode(to: encoder) - case .regularString(let data): - try data.encode(to: encoder) case .patternString(let data): try data.encode(to: encoder) + case .regularString(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithTime.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithTime.swift index d3efde6a9f29..d28e238aac59 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithTime.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithTime.swift @@ -1,20 +1,20 @@ import Foundation public enum UnionWithTime: Codable, Hashable, Sendable { - case value(Value) case date(Date) case datetime(Datetime) + case value(Value) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "value": - self = .value(try Value(from: decoder)) case "date": self = .date(try Date(from: decoder)) case "datetime": self = .datetime(try Datetime(from: decoder)) + case "value": + self = .value(try Value(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -27,12 +27,12 @@ public enum UnionWithTime: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .value(let data): - try data.encode(to: encoder) case .date(let data): try data.encode(to: encoder) case .datetime(let data): try data.encode(to: encoder) + case .value(let data): + try data.encode(to: encoder) } } @@ -106,12 +106,12 @@ public enum UnionWithTime: Codable, Hashable, Sendable { public struct Datetime: Codable, Hashable, Sendable { public let type: String = "datetime" - public let value: Date + public let value: Foundation.Date /// Additional properties that are not explicitly defined in the schema public let additionalProperties: [String: JSONValue] public init( - value: Date, + value: Foundation.Date, additionalProperties: [String: JSONValue] = .init() ) { self.value = value @@ -120,7 +120,7 @@ public enum UnionWithTime: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try container.decode(Date.self, forKey: .value) + self.value = try container.decode(Foundation.Date.self, forKey: .value) self.additionalProperties = try decoder.decodeAdditionalProperties(using: CodingKeys.self) } diff --git a/seed/swift-sdk/unions/Sources/Schemas/UnionWithoutKey.swift b/seed/swift-sdk/unions/Sources/Schemas/UnionWithoutKey.swift index 530e2d55bc97..5f5ab88da558 100644 --- a/seed/swift-sdk/unions/Sources/Schemas/UnionWithoutKey.swift +++ b/seed/swift-sdk/unions/Sources/Schemas/UnionWithoutKey.swift @@ -1,18 +1,18 @@ import Foundation public enum UnionWithoutKey: Codable, Hashable, Sendable { - case foo(Foo) /// This is a bar field. case bar(Bar) + case foo(Foo) public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let discriminant = try container.decode(String.self, forKey: .type) switch discriminant { - case "foo": - self = .foo(try Foo(from: decoder)) case "bar": self = .bar(try Bar(from: decoder)) + case "foo": + self = .foo(try Foo(from: decoder)) default: throw DecodingError.dataCorrupted( DecodingError.Context( @@ -25,10 +25,10 @@ public enum UnionWithoutKey: Codable, Hashable, Sendable { public func encode(to encoder: Encoder) throws -> Void { switch self { - case .foo(let data): - try data.encode(to: encoder) case .bar(let data): try data.encode(to: encoder) + case .foo(let data): + try data.encode(to: encoder) } } diff --git a/seed/swift-sdk/validation/Sources/Requests/Requests+CreateRequest.swift b/seed/swift-sdk/validation/Sources/Requests/Requests+CreateRequest.swift index 22d08cacec4e..7cf75653e85d 100644 --- a/seed/swift-sdk/validation/Sources/Requests/Requests+CreateRequest.swift +++ b/seed/swift-sdk/validation/Sources/Requests/Requests+CreateRequest.swift @@ -2,7 +2,7 @@ import Foundation extension Requests { public struct CreateRequest: Codable, Hashable, Sendable { - public let decimal: Double + public let decimal: Swift.Double public let even: Int public let name: String public let shape: Shape @@ -10,7 +10,7 @@ extension Requests { public let additionalProperties: [String: JSONValue] public init( - decimal: Double, + decimal: Swift.Double, even: Int, name: String, shape: Shape, @@ -25,7 +25,7 @@ extension Requests { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.decimal = try container.decode(Double.self, forKey: .decimal) + self.decimal = try container.decode(Swift.Double.self, forKey: .decimal) self.even = try container.decode(Int.self, forKey: .even) self.name = try container.decode(String.self, forKey: .name) self.shape = try container.decode(Shape.self, forKey: .shape) diff --git a/seed/swift-sdk/validation/Sources/Schemas/Double.swift b/seed/swift-sdk/validation/Sources/Schemas/Double.swift new file mode 100644 index 000000000000..b007d55a0f50 --- /dev/null +++ b/seed/swift-sdk/validation/Sources/Schemas/Double.swift @@ -0,0 +1,3 @@ +import Foundation + +public typealias Double = Swift.Double diff --git a/seed/swift-sdk/validation/Sources/Schemas/DoubleType.swift b/seed/swift-sdk/validation/Sources/Schemas/DoubleType.swift deleted file mode 100644 index 673942cd4eb2..000000000000 --- a/seed/swift-sdk/validation/Sources/Schemas/DoubleType.swift +++ /dev/null @@ -1,3 +0,0 @@ -import Foundation - -public typealias DoubleType = Double diff --git a/seed/swift-sdk/validation/Sources/Schemas/Type.swift b/seed/swift-sdk/validation/Sources/Schemas/Type.swift index ee623d2a0ef9..fd719c55faac 100644 --- a/seed/swift-sdk/validation/Sources/Schemas/Type.swift +++ b/seed/swift-sdk/validation/Sources/Schemas/Type.swift @@ -2,7 +2,7 @@ import Foundation /// Defines properties with default values and validation rules. public struct Type: Codable, Hashable, Sendable { - public let decimal: Double + public let decimal: Swift.Double public let even: Int public let name: String public let shape: Shape @@ -10,7 +10,7 @@ public struct Type: Codable, Hashable, Sendable { public let additionalProperties: [String: JSONValue] public init( - decimal: Double, + decimal: Swift.Double, even: Int, name: String, shape: Shape, @@ -25,7 +25,7 @@ public struct Type: Codable, Hashable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.decimal = try container.decode(Double.self, forKey: .decimal) + self.decimal = try container.decode(Swift.Double.self, forKey: .decimal) self.even = try container.decode(Int.self, forKey: .even) self.name = try container.decode(String.self, forKey: .name) self.shape = try container.decode(Shape.self, forKey: .shape) diff --git a/seed/swift-sdk/validation/Sources/ValidationClient.swift b/seed/swift-sdk/validation/Sources/ValidationClient.swift index 563049e2ccfe..be2e87313cbb 100644 --- a/seed/swift-sdk/validation/Sources/ValidationClient.swift +++ b/seed/swift-sdk/validation/Sources/ValidationClient.swift @@ -63,7 +63,7 @@ public final class ValidationClient: Sendable { ) } - public func get(decimal: Double, even: Int, name: String, requestOptions: RequestOptions? = nil) async throws -> Type { + public func get(decimal: Swift.Double, even: Int, name: String, requestOptions: RequestOptions? = nil) async throws -> Type { return try await httpClient.performRequest( method: .get, path: "/", diff --git a/seed/swift-sdk/validation/reference.md b/seed/swift-sdk/validation/reference.md index 5643317104b8..ac447fb7ff78 100644 --- a/seed/swift-sdk/validation/reference.md +++ b/seed/swift-sdk/validation/reference.md @@ -61,7 +61,7 @@ try await main() -
client.get(decimal: Double, even: Int, name: String, requestOptions: RequestOptions?) -> Type +
client.get(decimal: Swift.Double, even: Int, name: String, requestOptions: RequestOptions?) -> Type
@@ -102,7 +102,7 @@ try await main()
-**decimal:** `Double` +**decimal:** `Swift.Double`
diff --git a/seed/swift-sdk/websocket-inferred-auth/Sources/Requests/Requests+GetTokenRequest.swift b/seed/swift-sdk/websocket-inferred-auth/Sources/Requests/Requests+GetTokenRequest.swift index c8a07c8f5fde..cc34aaa7a18a 100644 --- a/seed/swift-sdk/websocket-inferred-auth/Sources/Requests/Requests+GetTokenRequest.swift +++ b/seed/swift-sdk/websocket-inferred-auth/Sources/Requests/Requests+GetTokenRequest.swift @@ -46,14 +46,14 @@ extension Requests { try container.encodeIfPresent(self.scope, forKey: .scope) } - public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { - case httpsApiExampleCom = "https://api.example.com" - } - public enum ClientCredentials: String, Codable, Hashable, CaseIterable, Sendable { case clientCredentials = "client_credentials" } + public enum HttpsApiExampleCom: String, Codable, Hashable, CaseIterable, Sendable { + case httpsApiExampleCom = "https://api.example.com" + } + /// Keys for encoding/decoding struct properties. enum CodingKeys: String, CodingKey, CaseIterable { case clientId = "client_id"