Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Pull request

on:
pull_request:
branches:
- main

jobs:

soundness:
name: Soundness
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@0.0.15
with:
format_check_enabled : true
broken_symlink_check_enabled : true
unacceptable_language_check_enabled : true
shell_check_enabled : true
docs_check_enabled : false
api_breakage_check_enabled : false
license_header_check_enabled: false
yamllint_check_enabled : false
python_lint_check_enabled : false

tests:
name: Tests
uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@0.0.15
with:
enable_windows_checks : false
linux_build_command: "swift test --parallel --enable-code-coverage"
linux_swift_versions: '["6.3", "6.4"]'
43 changes: 0 additions & 43 deletions .github/workflows/testing.yml

This file was deleted.

3 changes: 1 addition & 2 deletions .unacceptablelanguageignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
Tests/FeatherOpenAPITests/Petstore/Petstore.swift
Petstore/openapi@3.0.yaml
Petstore/openapi@3.1.yaml
Tests/FeatherOpenAPITests/Petstore/Petstore.swift
10 changes: 5 additions & 5 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 18 additions & 22 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
// swift-tools-version:6.1
// swift-tools-version:6.3
import PackageDescription

// NOTE: https://github.com/swift-server/swift-http-server/blob/main/Package.swift
var defaultSwiftSettings: [SwiftSetting] =
[
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0441-formalize-language-mode-terminology.md
let swiftSettings: [SwiftSetting] = [
.swiftLanguageMode(.v6),
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
.strictMemorySafety(),
.treatAllWarnings(as: .error),
.enableUpcomingFeature("InternalImportsByDefault"),
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("MemberImportVisibility"),
// https://forums.swift.org/t/experimental-support-for-lifetime-dependencies-in-swift-6-2-and-beyond/78638
.enableUpcomingFeature("InferIsolatedConformances"),
.enableUpcomingFeature("NonisolatedNonsendingByDefault"),
.enableUpcomingFeature("ImmutableWeakCaptures"),
.enableExperimentalFeature("SuppressedAssociatedTypes"),
.enableExperimentalFeature("LifetimeDependence"),
.enableExperimentalFeature("Lifetimes"),
// https://github.com/swiftlang/swift/pull/65218
.enableExperimentalFeature("AvailabilityMacro=featherOpenAPI 1.0:macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, visionOS 2.0"),
.enableUpcomingFeature("LifetimeDependence"),
.enableUpcomingFeature("StrictConcurrency"),
]

#if compiler(>=6.2)
defaultSwiftSettings.append(
// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0461-async-function-isolation.md
.enableUpcomingFeature("NonisolatedNonsendingByDefault")
)
#endif

let package = Package(
name: "feather-openapi",
name: "application",
platforms: [
.macOS(.v15),
.iOS(.v18),
Expand All @@ -34,17 +31,16 @@ let package = Package(
.library(name: "FeatherOpenAPI", targets: ["FeatherOpenAPI"]),
],
dependencies: [
.package(url: "https://github.com/mattpolzin/OpenAPIKit", from: "5.0.0"),
.package(url: "https://github.com/jpsim/Yams", from: "6.2.0"),
// [docc-plugin-placeholder]
.package(url: "https://github.com/mattpolzin/OpenAPIKit", from: "7.0.0"),
.package(url: "https://github.com/jpsim/Yams", from: "6.2.0"),
],
targets: [
.target(
name: "FeatherOpenAPI",
dependencies: [
.product(name: "OpenAPIKit30", package: "OpenAPIKit"),
],
swiftSettings: defaultSwiftSettings
swiftSettings: swiftSettings
),
.testTarget(
name: "FeatherOpenAPITests",
Expand All @@ -54,7 +50,7 @@ let package = Package(
.product(name: "OpenAPIKitCompat", package: "OpenAPIKit"),
.target(name: "FeatherOpenAPI"),
],
swiftSettings: defaultSwiftSettings,
swiftSettings: swiftSettings,
),
]
)
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
The FeatherOpenAPI library makes it easy to define OpenAPI specifications using Swift in a type-safe way.

[
![Release: 1.0.0-beta.7](https://img.shields.io/badge/Release-1%2E0%2E0--beta%2E7-F05138)
![Release: 1.0.0-rc.1](https://img.shields.io/badge/Release-1%2E0%2E0--rc%2E1-F05138)
](
https://github.com/feather-framework/feather-openapi/releases/tag/1.0.0-beta.7
https://github.com/feather-framework/feather-openapi/releases/tag/1.0.0-rc.1
)

## Features
Expand All @@ -17,10 +17,11 @@ The FeatherOpenAPI library makes it easy to define OpenAPI specifications using

## Requirements

![Swift 6.1+](https://img.shields.io/badge/Swift-6%2E1%2B-F05138)
![Swift 6.3+](https://img.shields.io/badge/Swift-6%2E3%2B-F05138)
![Platforms: Linux, macOS, iOS, tvOS, watchOS, visionOS](https://img.shields.io/badge/Platforms-Linux_%7C_macOS_%7C_iOS_%7C_tvOS_%7C_watchOS_%7C_visionOS-F05138)

- Swift 6.1+
- Swift 6.3+

- Platforms:
- Linux
- macOS 15+
Expand All @@ -34,7 +35,7 @@ The FeatherOpenAPI library makes it easy to define OpenAPI specifications using
Use Swift Package Manager; add the dependency to your `Package.swift` file:

```swift
.package(url: "https://github.com/feather-framework/feather-openapi", exact: "1.0.0-beta.7"),
.package(url: "https://github.com/feather-framework/feather-openapi", exact: "1.0.0-rc.1"),
```

Then add `FeatherOpenAPI` to your target dependencies:
Expand Down
42 changes: 25 additions & 17 deletions Sources/FeatherOpenAPI/Components/Components.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,33 @@
// Created by Tibor Bödecs on 2026. 01. 23.
//

import OpenAPIKit30
public import OpenAPIKit30

/// Concrete container for reusable OpenAPI components.
public struct Components: ComponentsRepresentable {

/// Schema component map.
public var schemas: OrderedDictionary<SchemaID, OpenAPISchemaRepresentable>
public var schemas:
OrderedDictionary<SchemaID, any OpenAPISchemaRepresentable>
/// Parameter component map.
public var parameters:
OrderedDictionary<ParameterID, OpenAPIParameterRepresentable>
OrderedDictionary<ParameterID, any OpenAPIParameterRepresentable>
/// Example component map.
public var examples:
OrderedDictionary<ExampleID, OpenAPIExampleRepresentable>
OrderedDictionary<ExampleID, any OpenAPIExampleRepresentable>
/// Response component map.
public var responses:
OrderedDictionary<ResponseID, OpenAPIResponseRepresentable>
OrderedDictionary<ResponseID, any OpenAPIResponseRepresentable>
/// Request body component map.
public var requestBodies:
OrderedDictionary<RequestBodyID, OpenAPIRequestBodyRepresentable>
OrderedDictionary<RequestBodyID, any OpenAPIRequestBodyRepresentable>
/// Header component map.
public var headers: OrderedDictionary<HeaderID, OpenAPIHeaderRepresentable>
public var headers:
OrderedDictionary<HeaderID, any OpenAPIHeaderRepresentable>
/// Security requirement list used by components.
public var securityRequirements: [SecurityRequirementRepresentable]
public var securityRequirements: [any SecurityRequirementRepresentable]
/// Link component map.
public var links: OrderedDictionary<LinkID, OpenAPILinkRepresentable>
public var links: OrderedDictionary<LinkID, any OpenAPILinkRepresentable>

/// Creates a components container.
/// - Parameters:
Expand All @@ -42,20 +44,26 @@ public struct Components: ComponentsRepresentable {
/// - securityRequirements: Security requirements.
/// - links: Link component map.
public init(
schemas: OrderedDictionary<SchemaID, OpenAPISchemaRepresentable> = [:],
schemas: OrderedDictionary<SchemaID, any OpenAPISchemaRepresentable> =
[:],
parameters: OrderedDictionary<
ParameterID, OpenAPIParameterRepresentable
ParameterID, any OpenAPIParameterRepresentable
> = [:],
examples: OrderedDictionary<ExampleID, OpenAPIExampleRepresentable> =
examples: OrderedDictionary<
ExampleID, any OpenAPIExampleRepresentable
> =
[:],
responses: OrderedDictionary<ResponseID, OpenAPIResponseRepresentable> =
responses: OrderedDictionary<
ResponseID, any OpenAPIResponseRepresentable
> =
[:],
requestBodies: OrderedDictionary<
RequestBodyID, OpenAPIRequestBodyRepresentable
RequestBodyID, any OpenAPIRequestBodyRepresentable
> = [:],
headers: OrderedDictionary<HeaderID, OpenAPIHeaderRepresentable> = [:],
securityRequirements: [SecurityRequirementRepresentable] = [],
links: OrderedDictionary<LinkID, OpenAPILinkRepresentable> = [:],
headers: OrderedDictionary<HeaderID, any OpenAPIHeaderRepresentable> =
[:],
securityRequirements: [any SecurityRequirementRepresentable] = [],
links: OrderedDictionary<LinkID, any OpenAPILinkRepresentable> = [:],
) {
self.schemas = schemas
self.parameters = parameters
Expand Down
25 changes: 16 additions & 9 deletions Sources/FeatherOpenAPI/Components/ComponentsRepresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,44 @@
// Created by Tibor Bödecs on 2026. 01. 21.
//

import OpenAPIKit30
public import OpenAPIKit30

/// A type that can describe reusable OpenAPI components.
public protocol ComponentsRepresentable:
OpenAPIComponentsRepresentable,
VendorExtensionsProperty
{
/// Schema component map.
var schemas: OrderedDictionary<SchemaID, OpenAPISchemaRepresentable> { get }
var schemas: OrderedDictionary<SchemaID, any OpenAPISchemaRepresentable> {
get
}
/// Parameter component map.
var parameters:
OrderedDictionary<ParameterID, OpenAPIParameterRepresentable>
OrderedDictionary<ParameterID, any OpenAPIParameterRepresentable>
{ get }
/// Example component map.
var examples: OrderedDictionary<ExampleID, OpenAPIExampleRepresentable> {
var examples: OrderedDictionary<ExampleID, any OpenAPIExampleRepresentable>
{
get
}
/// Response component map.
var responses: OrderedDictionary<ResponseID, OpenAPIResponseRepresentable> {
var responses:
OrderedDictionary<ResponseID, any OpenAPIResponseRepresentable>
{
get
}
/// Request body component map.
var requestBodies:
OrderedDictionary<RequestBodyID, OpenAPIRequestBodyRepresentable>
OrderedDictionary<RequestBodyID, any OpenAPIRequestBodyRepresentable>
{ get }
/// Header component map.
var headers: OrderedDictionary<HeaderID, OpenAPIHeaderRepresentable> { get }
var headers: OrderedDictionary<HeaderID, any OpenAPIHeaderRepresentable> {
get
}
/// Security requirements used by the document.
var securityRequirements: [SecurityRequirementRepresentable] { get }
var securityRequirements: [any SecurityRequirementRepresentable] { get }
/// Link component map.
var links: OrderedDictionary<LinkID, OpenAPILinkRepresentable> { get }
var links: OrderedDictionary<LinkID, any OpenAPILinkRepresentable> { get }
// public var callbacks: OrderedDictionary<CallbackID, CallbackRepresentable>

/// Produces the OpenAPI schema components.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Tibor Bödecs on 2026. 01. 23.
//

import OpenAPIKit30
public import OpenAPIKit30

/// A type that can produce OpenAPI components.
public protocol OpenAPIComponentsRepresentable {
Expand Down
6 changes: 3 additions & 3 deletions Sources/FeatherOpenAPI/Contact/ContactRepresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Tibor Bödecs on 2026. 01. 21.
//

import OpenAPIKit30
public import OpenAPIKit30

/// Describes an OpenAPI contact.
public protocol ContactRepresentable:
Expand All @@ -15,7 +15,7 @@ public protocol ContactRepresentable:
/// Contact name.
var name: String? { get }
/// Contact URL.
var url: LocationRepresentable? { get }
var url: (any LocationRepresentable)? { get }
/// Contact email.
var email: String? { get }
}
Expand All @@ -25,7 +25,7 @@ extension ContactRepresentable {
/// Default name is `nil`.
public var name: String? { nil }
/// Default URL is `nil`.
public var url: LocationRepresentable? { nil }
public var url: (any LocationRepresentable)? { nil }
/// Default email is `nil`.
public var email: String? { nil }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Tibor Bödecs on 2026. 01. 23.
//

import OpenAPIKit30
public import OpenAPIKit30

/// A type that can produce OpenAPI contact information.
public protocol OpenAPIContactRepresentable {
Expand Down
Loading
Loading