Skip to content
Open
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
2 changes: 1 addition & 1 deletion Package.resolved

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

16 changes: 8 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/jpsim/Yams.git", from: "5.0.6"),
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"),
.package(url: "https://github.com/apple/swift-docc-symbolkit.git", from: "1.0.0"),
.package(url: "https://github.com/swiftlang/swift-docc-symbolkit.git", from: "1.0.0"),
.package(url: "https://github.com/mattpolzin/OpenAPIKit.git", from: "3.0.0"),
],
targets: [
Expand Down Expand Up @@ -52,8 +52,8 @@ let package = Package(
.target(
name: "Integration",
dependencies: [
"OpenAPI",
"DocC",
"OpenAPI",
"DocC",
"Core",
.product(name: "SymbolKit", package: "swift-docc-symbolkit")
],
Expand All @@ -63,8 +63,8 @@ let package = Package(
.target(
name: "OpenAPItoSymbolGraph",
dependencies: [
"OpenAPI",
"DocC",
"OpenAPI",
"DocC",
"Integration",
"Core",
.product(name: "SymbolKit", package: "swift-docc-symbolkit")
Expand Down Expand Up @@ -98,9 +98,9 @@ let package = Package(
.testTarget(
name: "OpenAPItoSymbolGraphTests",
dependencies: [
"OpenAPI",
"DocC",
"Integration",
"OpenAPI",
"DocC",
"Integration",
"OpenAPItoSymbolGraph",
"Core",
"CLI",
Expand Down
157 changes: 157 additions & 0 deletions RegistryAPI.docc/Extensions/PackageMetadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# ``RegistryAPI/PackageMetadata``

A comprehensive representation of metadata for a Swift package.

## Overview

The `PackageMetadata` structure contains all descriptive information about a Swift package, including details about the package's author, license, and available versions.

```swift
// Example: Fetching and using package metadata
let url = URL(string: "https://registry.example.com/mona/LinkedList")!
let (data, _) = try await URLSession.shared.data(from: url)
let metadata = try JSONDecoder().decode(PackageMetadata.self, from: data)

// Use metadata properties
print("Package name: \(metadata.name)")
print("Latest version: \(metadata.latestVersion)")
print("Available versions: \(metadata.versions.joined(separator: ", "))")
```

Package metadata provides a complete picture of a package, including:

- Basic information like name, version, and description
- Author and organization information
- License details
- Repository location
- Available versions

## Topics

### Essential Properties

- ``name``
- ``description``
- ``version``
- ``latestVersion``

### Author Information

- ``author``
- ``PackageAuthor``
- ``organization``
- ``PackageOrganization``

### Package Versions

- ``versions``
- ``listedVersions``
- ``ListedRelease``

### Package Resources

- ``repository``
- ``license``
- ``readmeURL``
- ``keywords``

## Structure

```json
{
"name": "LinkedList",
"description": "A linked list implementation for Swift",
"keywords": ["data-structure", "list", "collection"],
"version": "1.1.1",
"author": {
"name": "J. Appleseed",
"email": "japplseed@example.com",
"url": "https://example.com/japplseed"
},
"organization": {
"name": "Example Organization",
"url": "https://example.com",
"description": "Organization that maintains the package"
},
"license": {
"name": "MIT",
"url": "https://opensource.org/licenses/MIT"
},
"repository": {
"type": "git",
"url": "https://github.com/mona/LinkedList.git"
},
"readmeURL": "https://registry.example.com/mona/LinkedList/1.1.1/README.md",
"latestVersion": "1.1.1",
"versions": ["1.0.0", "1.0.1", "1.1.0", "1.1.1"]
}
```

## Accessing Metadata

You can retrieve package metadata using the package identifier endpoint:

```swift
func fetchPackageMetadata(scope: String, name: String) async throws -> PackageMetadata {
let url = URL(string: "https://registry.example.com/\(scope)/\(name)")!

var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Accept")

let (data, response) = try await URLSession.shared.data(for: request)

guard let httpResponse = response as? HTTPURLResponse,
(200..<300).contains(httpResponse.statusCode) else {
throw FetchError.invalidResponse
}

return try JSONDecoder().decode(PackageMetadata.self, from: data)
}
```

## Required and Optional Fields

The following fields are required in every package metadata response:

- `name`: Package name
- `version`: Current version
- `description`: Brief description of the package
- `license`: License information

All other fields are optional and may not be present in all responses.

## Handling Missing Fields

When working with package metadata, it's important to handle optional fields gracefully:

```swift
// Example: Handling optional fields
func displayPackageInfo(_ metadata: PackageMetadata) {
// Required fields
print("Package: \(metadata.name)")
print("Description: \(metadata.description)")

// Optional fields
if let author = metadata.author {
print("Author: \(author.name)")
if let email = author.email {
print("Contact: \(email)")
}
}

if let org = metadata.organization {
print("Organization: \(org.name)")
}

// Keywords
if let keywords = metadata.keywords, !keywords.isEmpty {
print("Keywords: \(keywords.joined(separator: ", "))")
}
}
```

## See Also

- ``RegistryAPI/__scope___name_``
- ``RegistryAPI/ReleaseResource``
- ``RegistryAPI/ListedRelease``
65 changes: 62 additions & 3 deletions RegistryAPI.docc/RegistryAPI.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,66 @@
# RegistryAPI
# ``RegistryAPI``

Swift Package Registry API documentation.
@Metadata {
@DisplayName("Registry API")
@TitleHeading("Swift Package Registry API")
@DocumentationExtension(mergeBehavior: append)
}

Interact with Swift packages through a standardized API for publishing, discovering, and retrieving packages.

## Overview

This documentation provides details about the Swift Package Registry API endpoints and schemas, generated from the OpenAPI specification.
The Swift Package Registry API provides a robust interface for package management that follows open standards. Using this API, you can:

- **Discover** packages through search and metadata
- **Retrieve** package releases including source code and manifests
- **Publish** your own packages for others to use
- **Authenticate** to access private packages or perform privileged operations

![A diagram showing the workflow of package discovery, retrieval and publishing](registry_workflow.png)

The API follows RESTful principles with well-defined endpoints for each resource type. All requests and responses use standard HTTP methods and status codes, with JSON-formatted data.

```swift
// Example: Retrieve package metadata
let url = URL(string: "https://registry.example.com/mona/LinkedList")!
let (data, response) = try await URLSession.shared.data(from: url)
let metadata = try JSONDecoder().decode(PackageMetadata.self, from: data)

print("Package: \(metadata.name)")
print("Latest version: \(metadata.latestVersion)")
print("Available versions: \(metadata.versions.joined(separator: ", "))")
```

## Topics

### API Endpoints

- <doc:GettingStarted>
- ``_identifiers``
- ``_login``
- ``__scope___name_``
- ``__scope___name___version_``
- ``__scope___name___version_.zip``
- ``__scope___name___version__package.swift``

### Data Models

- ``PackageMetadata``
- ``ReleaseResource``
- ``ProblemDetails``
- ``Identifier``
- ``Identifiers``
- ``Releases``
- ``ReleaseMetadata``
- ``ReleaseSignature``
- ``PublishResponse``

### Guides

- <doc:Authentication>
- <doc:Publishing>
- <doc:ErrorCodes>
- <doc:RateLimiting>
- <doc:Security>
- <doc:Performance>
81 changes: 81 additions & 0 deletions RegistryAPI.docc/Resources/VersionEndpoint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# ``RegistryAPI/__scope___name___version_``

Interact with a specific version of a Swift package.

## Overview

This endpoint provides access to a specific version of a package in the registry. It supports both retrieving metadata about a version and publishing new versions.

## Getting Version Information

Retrieve information about a specific version of a package:

```http
GET /{scope}/{name}/{version}
```

### Response

On success, returns a `200 OK` response with a `ReleaseResource` object in the response body:

```json
{
"id": "mona/LinkedList/1.1.1",
"version": "1.1.1",
"resources": [
{
"name": "source-archive",
"type": "application/zip",
"checksum": "a2ac54cf25fbc1ad0028f03f0aa4b96833b83bb05a14e510892bb27dea4dc812",
"signing": {
"signatureBase64Encoded": "ZXhhbXBsZSBzaWduYXR1cmU=",
"signatureFormat": "cms-1.0.0"
}
}
],
"metadata": {
"author": {
"name": "J. Appleseed"
},
"description": "A linked list implementation for Swift",
"licenseURL": "https://opensource.org/licenses/MIT"
}
}
```

## Publishing a New Version

To publish a new version of a package:

```http
PUT /{scope}/{name}/{version}
Content-Type: application/octet-stream
X-Swift-Package-Signature: sha256=[Base64 encoded signature]
```

The request body should contain the package archive in ZIP format.

### Response Codes

When publishing a package version, the registry may respond with:

| Status Code | Description |
|-------------|-------------|
| 201 Created | Version published successfully |
| 202 Accepted | Version accepted for processing |
| 400 Bad Request | Invalid request format |
| 401 Unauthorized | Authentication required |
| 403 Forbidden | Insufficient permissions |
| 409 Conflict | Version already exists |
| 413 Payload Too Large | Package size exceeds limits |
| 422 Unprocessable Entity | Package validation failed |

## Availability

The endpoint is available for both public and private packages. Private packages require authentication.

## See Also

- ``RegistryAPI/__scope___name_``
- ``RegistryAPI/__scope___name___version_.zip``
- ``RegistryAPI/ReleaseResource``
Loading