| Sources | ||
| Tests | ||
| .gitignore | ||
| Package.swift | ||
| README.md | ||
YAMLMerger
A Swift package for merging multiple YAML files from subdirectories into a single combined file.
How It Works
YAMLMerger recursively scans subdirectories for YAML files and merges them in a predictable order:
- Folders are processed in numerical order (01 → 02 → 03 → ...)
- Within each folder,
__*.yamlfiles are merged first (due to__prefix) - All additional YAML files are then merged in alphabetical order
- The result is a single, properly structured OpenAPI specification file
Directory Structure for OpenAPI Schemas
When using YAMLMerger for OpenAPI specifications, organize your YAML files into the following subdirectories:
Schema/
├── 01_Info/ # OpenAPI info section (version, title, description, etc.)
├── 02_Servers/ # API server URLs and environment configurations
├── 03_Tags/ # Tag definitions for organizing endpoints
├── 04_Paths/ # API endpoint definitions
├── 05_Webhooks/ # Webhook/callback definitions (OpenAPI 3.1+)
├── 06_Components/ # Reusable components (schemas, responses, parameters, etc.)
├── 07_Security/ # Top-level security requirements
└── 08_ExternalDocs/ # External documentation references
Place your distinct YAML files into the corresponding folders:
01_Info/
OpenAPI metadata and general information.
# __info.yaml (header file)
openapi: 3.0.0
info:
# api-info.yaml
title: OpenAPI Generation Demo
version: 1.0.0
description: Demonstration of OpenAPI specification generation using YAMLMerger
02_Servers/
API server URLs and configurations.
# dummyjson-server.yaml
- url: https://dummyjson.com
description: DummyJSON API Server
# local-server.yaml
- url: http://localhost:8080
description: Local development server
03_Tags/
Tag definitions for organizing endpoints.
# tags.yaml
- name: auth
description: Authentication operations
- name: users
description: User management operations
- name: posts
description: Post management operations
- name: products
description: Product catalog operations
04_Paths/
API endpoint definitions (one file per resource).
# auth.yaml
/auth/login:
post:
operationId: loginUser
tags: [auth]
summary: User login
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LoginRequest'
responses:
'200':
description: Successful authentication
# users.yaml
/users:
get:
operationId: getAllUsers
tags: [users]
summary: Get all users
parameters:
- name: limit
in: query
schema:
type: integer
default: 30
responses:
'200':
description: Successful response
post:
operationId: createUser
tags: [users]
summary: Add a new user
security:
- bearerAuth: []
responses:
'201':
description: User created successfully
Try it:
# Auth - Login
curl -X POST https://dummyjson.com/auth/login \
-H 'Content-Type: application/json' \
-d '{"username": "emilys", "password": "emilyspass"}'
# Users - Get all
curl https://dummyjson.com/users?limit=5
# Users - Get single
curl https://dummyjson.com/users/1
# Posts - Get all
curl https://dummyjson.com/posts?limit=5
# Posts - Get single
curl https://dummyjson.com/posts/1
# Products - Get all
curl https://dummyjson.com/products?limit=5
# Products - Get single
curl https://dummyjson.com/products/1
# Carts - Get all
curl https://dummyjson.com/carts?limit=5
# Carts - Get single
curl https://dummyjson.com/carts/1
# Todos - Get all
curl https://dummyjson.com/todos?limit=5
# Todos - Get single
curl https://dummyjson.com/todos/1
# Comments - Get all
curl https://dummyjson.com/comments?limit=5
# Comments - Get single
curl https://dummyjson.com/comments/1
05_Webhooks/
Webhook/callback definitions (OpenAPI 3.1+).
# new-comment.yaml
newComment:
post:
operationId: onNewComment
summary: New comment notification
requestBody:
content:
application/json:
schema:
type: object
properties:
event:
type: string
example: comment.created
timestamp:
type: string
format: date-time
data:
$ref: '#/components/schemas/Comment'
# new-post.yaml
newPost:
post:
operationId: onNewPost
summary: New post notification
requestBody:
content:
application/json:
schema:
type: object
properties:
event:
type: string
example: post.published
data:
$ref: '#/components/schemas/Post'
Test webhook receiver:
# Start a local webhook receiver (requires nc)
nc -l 8080
# In another terminal, simulate a webhook POST
curl -X POST http://localhost:8080/webhook \
-H 'Content-Type: application/json' \
-d '{
"event": "comment.created",
"timestamp": "2025-10-15T10:30:00Z",
"data": {
"id": 1,
"body": "Great post!",
"postId": 1,
"likes": 5,
"user": {
"id": 1,
"username": "emilys",
"fullName": "Emily Johnson"
}
}
}'
06_Components/
Reusable schema definitions (one per file).
# LoginRequest.yaml
LoginRequest:
type: object
required: [username, password]
properties:
username:
type: string
password:
type: string
format: password
# User.yaml
User:
type: object
properties:
id:
type: integer
firstName:
type: string
lastName:
type: string
email:
type: string
format: email
# Post.yaml
Post:
type: object
properties:
id:
type: integer
title:
type: string
body:
type: string
userId:
type: integer
07_Security/
Security schemes and requirements.
# bearer-auth.yaml
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: JWT token obtained from /auth/login endpoint
Try it:
# Get token
TOKEN=$(curl -s -X POST https://dummyjson.com/auth/login \
-H 'Content-Type: application/json' \
-d '{"username": "emilys", "password": "emilyspass"}' \
| grep -o '"accessToken":"[^"]*"' | cut -d'"' -f4)
# Use token to get authenticated user
curl https://dummyjson.com/auth/me \
-H "Authorization: Bearer $TOKEN"
08_ExternalDocs/
Links to external documentation.
# __externalDocs.yaml
externalDocs:
# docs.yaml
description: DummyJSON Documentation
url: https://dummyjson.com/docs
The externalDocs field provides links to additional documentation outside the API spec. It can be used at:
- Global level (as shown above) - links to overall API documentation
- Operation level - links to specific endpoint guides
Tools like Swagger UI render these links prominently for easy access to tutorials, guides, and examples.
Try it:
# View the external documentation
curl https://dummyjson.com/docs
# Or open in browser
open https://dummyjson.com/docs
Usage
import YAMLMerger
let merger = YAMLMerger(
rootDirectory: URL(fileURLWithPath: "/path/to/yaml/files"),
outputFileName: "CombinedSpec.yaml"
)
merger.merge()
Requirements
- Swift 6.1+
- macOS 14.0+ / iOS 17.0+
Installation
Swift Package Manager
Add this package as a dependency in your Package.swift:
dependencies: [
.package(url: "https://github.com/yourusername/YAMLMerger", from: "1.0.0")
]
License
Add your license here.