Skip to content

Commit 9f58552

Browse files
committed
feat: docs endpoint
1 parent f9b98ee commit 9f58552

File tree

4 files changed

+238
-10
lines changed

4 files changed

+238
-10
lines changed

api/index.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { VercelResponse as Res } from '@vercel/node'
2-
import { ga } from '../lib/config'
2+
import { docs, ga } from '../lib/config'
33
import { handleAPIError, initRoute, trackAPIRequest } from '../lib/middleware'
44
import type { APIRequest as Req } from '../lib/types'
55

@@ -9,7 +9,8 @@ import type { APIRequest as Req } from '../lib/types'
99
*/
1010

1111
/**
12-
* Root of the Apple Developer Token API.
12+
* Returns the API documentation as a JSON object.
13+
* Documentation follows OpenAPI Specification v3.0.0 standards.
1314
*
1415
* @param req - Incoming request object
1516
* @param res - Server response object
@@ -22,8 +23,8 @@ export default async (req: Req, res: Res): Promise<Res | void> => {
2223
// Send `pageview` hit to Google Analytics
2324
await trackAPIRequest(req)
2425

25-
// Return welcome response
26-
res.json('Apple Developer Token API')
26+
// Return documentation JSON
27+
res.json(docs)
2728
} catch (err) {
2829
return handleAPIError(req, res, err)
2930
}

lib/config/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export { default as axios } from './axios'
77
export * from './constants'
88
export { default as ga } from './google-analytics'
99
export { default as createLogger } from './logger'
10+
export { default as docs } from './openapi.json'
1011
export { default as vercel } from './vercel-env'
1112

1213
/* eslint-disable prettier/prettier */

lib/config/openapi.json

+231
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
{
2+
"openapi": "3.0.0",
3+
"info": {
4+
"title": "Apple Developer Token API",
5+
"description": "The Apple Developer Token (ADT) API is a single serverless endpoint that can be used to generate developer tokens suitable for use with the Apple Music API.",
6+
"termsOfService": "",
7+
"contact": {
8+
"name": "GitHub",
9+
"url": "https://github.com/flex-development/adt-api"
10+
},
11+
"license": {
12+
"name": "License - BSD 3 Clause",
13+
"url": "https://spdx.org/licenses/BSD-3-Clause.html"
14+
},
15+
"version": "1.0.0"
16+
},
17+
"servers": [
18+
{
19+
"description": "Production",
20+
"url": "https://adt-api.flexdevelopment.vercel.app"
21+
},
22+
{
23+
"description": "Next",
24+
"url": "https://adt-api-git-next-flexdevelopment.vercel.app"
25+
}
26+
],
27+
"tags": [],
28+
"paths": {
29+
"/token": {
30+
"post": {
31+
"summary": "Create an Apple Developer token",
32+
"description": "Generates a JSON Web Token (JWT) suitable for use with the Apple Music API.",
33+
"operationId": "token-post",
34+
"parameters": [
35+
{
36+
"name": "expiresIn",
37+
"in": "query",
38+
"description": "Expiration time of registered claim key in seconds. Must not exceed `15777000` (6 months in seconds)",
39+
"schema": {
40+
"type": "integer"
41+
}
42+
},
43+
{
44+
"name": "team",
45+
"in": "query",
46+
"description": "Apple Team ID",
47+
"required": true,
48+
"schema": {
49+
"type": "string"
50+
}
51+
}
52+
],
53+
"responses": {
54+
"201": {
55+
"description": "Created",
56+
"content": {
57+
"application/json": {
58+
"schema": {
59+
"$ref": "#/components/schemas/AppleDeveloperToken"
60+
}
61+
}
62+
}
63+
},
64+
"400": {
65+
"description": "BadRequest",
66+
"content": {
67+
"application/json": {
68+
"schema": {
69+
"$ref": "#/components/schemas/BadRequest"
70+
}
71+
}
72+
}
73+
},
74+
"401": {
75+
"description": "NotAuthenticated",
76+
"content": {
77+
"application/json": {
78+
"schema": {
79+
"$ref": "#/components/schemas/NotAuthenticated"
80+
}
81+
}
82+
}
83+
},
84+
"500": {
85+
"description": "GeneralError",
86+
"content": {
87+
"application/json": {
88+
"schema": {
89+
"$ref": "#/components/schemas/GeneralError"
90+
}
91+
}
92+
}
93+
}
94+
},
95+
"security": [
96+
"BasicAuth"
97+
]
98+
}
99+
}
100+
},
101+
"components": {
102+
"schemas": {
103+
"AppleDeveloperToken": {
104+
"type": "string"
105+
},
106+
"BadRequest": {
107+
"type": "object",
108+
"properties": {
109+
"className": {
110+
"type": "string",
111+
"example": "bad-request"
112+
},
113+
"code": {
114+
"type": "integer",
115+
"example": 400
116+
},
117+
"data": {
118+
"type": "object",
119+
"example": {}
120+
},
121+
"errors": {
122+
"type": "object",
123+
"example": {}
124+
},
125+
"message": {
126+
"type": "string"
127+
},
128+
"name": {
129+
"type": "string",
130+
"example": "BadRequest"
131+
}
132+
}
133+
},
134+
"GeneralError": {
135+
"type": "object",
136+
"properties": {
137+
"className": {
138+
"type": "string",
139+
"example": "general-error"
140+
},
141+
"code": {
142+
"type": "integer",
143+
"example": 500
144+
},
145+
"data": {
146+
"type": "object",
147+
"example": {}
148+
},
149+
"errors": {
150+
"type": "object",
151+
"example": {}
152+
},
153+
"message": {
154+
"type": "string"
155+
},
156+
"name": {
157+
"type": "string",
158+
"example": "GeneralError"
159+
}
160+
}
161+
},
162+
"NotAuthenticated": {
163+
"type": "object",
164+
"properties": {
165+
"className": {
166+
"type": "string",
167+
"example": "not-authenticated"
168+
},
169+
"code": {
170+
"type": "integer",
171+
"example": 401
172+
},
173+
"data": {
174+
"type": "object",
175+
"example": {}
176+
},
177+
"errors": {
178+
"type": "object",
179+
"example": {}
180+
},
181+
"message": {
182+
"type": "string"
183+
},
184+
"name": {
185+
"type": "string",
186+
"example": "NotAuthenticated"
187+
}
188+
}
189+
},
190+
"NotImplemented": {
191+
"type": "object",
192+
"properties": {
193+
"className": {
194+
"type": "string",
195+
"example": "not-implemented"
196+
},
197+
"code": {
198+
"type": "integer",
199+
"example": 501
200+
},
201+
"data": {
202+
"type": "object",
203+
"example": {}
204+
},
205+
"errors": {
206+
"type": "object",
207+
"example": {}
208+
},
209+
"message": {
210+
"type": "string"
211+
},
212+
"name": {
213+
"type": "string",
214+
"example": "NotImplemented"
215+
}
216+
}
217+
}
218+
},
219+
"securitySchemes": {
220+
"BasicAuth": {
221+
"description": "Musickit identifier and private key",
222+
"type": "http",
223+
"scheme": "basic"
224+
}
225+
}
226+
},
227+
"externalDocs": {
228+
"description": "Apple Developer Docs - Getting Keys and Creating Tokens",
229+
"url": "https://developer.apple.com/documentation/applemusicapi/getting_keys_and_creating_tokens"
230+
}
231+
}

vercel.json

+1-6
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
"silent": false
66
},
77
"functions": {
8-
"api/index.ts": {
9-
"includeFiles": "../public/**",
8+
"api/*.ts": {
109
"maxDuration": 10,
1110
"memory": 3008
1211
}
@@ -47,10 +46,6 @@
4746
{
4847
"key": "Access-Control-Allow-Origin",
4948
"value": "*"
50-
},
51-
{
52-
"key": "Cache-Control",
53-
"value": "s-maxage=1, stale-while-revalidate"
5449
}
5550
]
5651
}

0 commit comments

Comments
 (0)