Skip to content

Commit 4e8416b

Browse files
committed
chore: Updated OpenAPI documentation
1 parent 6a7f72d commit 4e8416b

File tree

6 files changed

+106
-27
lines changed

6 files changed

+106
-27
lines changed

apps/api/src/routes/jobs.ts

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import { Hono } from "hono";
1313
import { describeRoute } from "hono-openapi";
1414
import { resolver } from "hono-openapi/zod";
1515
import { validator } from "shared/hono/middleware";
16-
import { z } from "zod";
1716
import { apiError } from "../errors";
1817
import { auth } from "../middleware";
1918
import { getJob, getJobLogs, getJobs } from "../repositories/jobs";
2019
import { jobSchema, jobsPaginatedSchema } from "../schemas/jobs";
20+
import { z } from "../utils/zod";
2121

2222
const inputSchema = z.discriminatedUnion("type", [
2323
z.object({
@@ -28,16 +28,25 @@ const inputSchema = z.discriminatedUnion("type", [
2828
z.object({
2929
type: z.literal("audio"),
3030
path: z.string(),
31-
language: z.string().optional(),
31+
language: z.string().optional().openapi({
32+
description: "ISO 639 - 3 characters, language",
33+
}),
3234
channels: z.number().optional(),
3335
}),
3436
z.object({
3537
type: z.literal("text"),
3638
path: z.string(),
37-
language: z.string(),
39+
language: z.string().openapi({
40+
description: "ISO 639 - 3 characters, language",
41+
}),
3842
}),
3943
]);
4044

45+
const inputsSchema = z.array(inputSchema).openapi({
46+
description:
47+
"The source media files, optional fields will be extracted from the source if possible.",
48+
});
49+
4150
const streamSchema = z.discriminatedUnion("type", [
4251
z.object({
4352
type: z.literal("video"),
@@ -50,15 +59,24 @@ const streamSchema = z.discriminatedUnion("type", [
5059
type: z.literal("audio"),
5160
codec: z.enum(["aac", "ac3", "eac3"]),
5261
bitrate: z.number().optional(),
53-
language: z.string().optional(),
62+
language: z.string().optional().openapi({
63+
description: "ISO 639 - 3 characters, language",
64+
}),
5465
channels: z.number().optional(),
5566
}),
5667
z.object({
5768
type: z.literal("text"),
58-
language: z.string(),
69+
language: z.string().openapi({
70+
description: "ISO 639 - 3 characters, language",
71+
}),
5972
}),
6073
]);
6174

75+
const streamsSchema = z.array(streamSchema).openapi({
76+
description:
77+
"Output streams, will try to find the best suitable input for the configured output.",
78+
});
79+
6280
export const jobsApp = new Hono()
6381
.use(auth())
6482

@@ -90,13 +108,21 @@ export const jobsApp = new Hono()
90108
validator(
91109
"json",
92110
z.object({
93-
assetId: z.string().uuid().default(randomUUID),
94-
inputs: z.array(inputSchema),
95-
streams: z.array(streamSchema),
111+
assetId: z.string().uuid().default(randomUUID).openapi({
112+
default: "Randomly generated assetId",
113+
description:
114+
"Only provide when re-running this job, leave empty for auto generated id, which is advised.",
115+
}),
116+
inputs: inputsSchema,
117+
streams: streamsSchema,
96118
group: z.string().optional(),
97-
language: z.string().optional(),
119+
language: z.string().optional().openapi({
120+
description: "ISO 639 - 3 characters, language",
121+
}),
98122
concurrency: z.number().default(DEFAULT_CONCURRENCY),
99-
public: z.boolean().default(DEFAULT_PUBLIC),
123+
public: z.boolean().default(DEFAULT_PUBLIC).openapi({
124+
description: "S3 with public-read or private ACL",
125+
}),
100126
}),
101127
),
102128
async (c) => {
@@ -139,10 +165,14 @@ export const jobsApp = new Hono()
139165
validator(
140166
"json",
141167
z.object({
142-
assetId: z.string().uuid().default(randomUUID),
168+
assetId: z.string().uuid().default(randomUUID).openapi({
169+
default: "Randomly generated assetId",
170+
description:
171+
"Only provide when re-running this job, leave empty for auto generated id, which is advised.",
172+
}),
143173
segmentSize: z.number().default(DEFAULT_SEGMENT_SIZE),
144-
inputs: z.array(inputSchema),
145-
streams: z.array(streamSchema),
174+
inputs: inputsSchema,
175+
streams: streamsSchema,
146176
group: z.string().optional(),
147177
}),
148178
),
@@ -187,9 +217,13 @@ export const jobsApp = new Hono()
187217
assetId: z.string().uuid().default(randomUUID),
188218
segmentSize: z.number().default(DEFAULT_SEGMENT_SIZE),
189219
name: z.string().default(DEFAULT_PACKAGE_NAME),
190-
language: z.string().optional(),
220+
language: z.string().optional().openapi({
221+
description: "ISO 639 - 3 characters, language",
222+
}),
191223
concurrency: z.number().default(DEFAULT_CONCURRENCY),
192-
public: z.boolean().default(DEFAULT_PUBLIC),
224+
public: z.boolean().default(DEFAULT_PUBLIC).openapi({
225+
description: "S3 with public-read or private ACL",
226+
}),
193227
}),
194228
),
195229
async (c) => {

apps/api/src/schemas/jobs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const jobSchema: z.ZodType<Job> = baseJobSchema
2626
.openapi({
2727
type: "array",
2828
items: {
29-
$ref: "Job",
29+
$ref: "#/components/schemas/Job",
3030
},
3131
}),
3232
})

apps/api/src/schemas/storage.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export const storageItemSchema = z
1414
])
1515
.openapi({
1616
ref: "StorageItem",
17-
description: "An item in your S3 storage.",
17+
description:
18+
"An item in your S3 storage, typically a folder or a file reference.",
1819
});
1920

2021
export const storageItemsPaginatedSchema = z.object({

apps/stitcher/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ app.get(
2020
description:
2121
"Realtime playlist manipulator. Can be used for ad, bumper or other HLS interstitials insertion on-the-fly. Can apply filters to playlists.",
2222
},
23+
tags: [
24+
{
25+
name: "Sessions",
26+
description: "A session is an individual playout session per viewer.",
27+
},
28+
],
2329
},
2430
}),
2531
);
@@ -34,6 +40,8 @@ app.onError((error, c) => {
3440
);
3541
}
3642

43+
console.error(error);
44+
3745
return c.json(
3846
{
3947
message:

apps/stitcher/src/routes/sessions.ts

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { Hono } from "hono";
22
import { describeRoute } from "hono-openapi";
33
import { resolver } from "hono-openapi/zod";
44
import { validator } from "shared/hono/middleware";
5-
import { z } from "zod";
65
import { getAppContext } from "../app-context";
76
import { filterQuerySchema } from "../filters";
87
import { createMasterUrl, createOpaqueMasterUrl } from "../playlist";
98
import { createSession, getSession } from "../session";
9+
import { z } from "../utils/zod";
1010

1111
export const sessionsApp = new Hono()
1212
/**
@@ -35,44 +35,78 @@ export const sessionsApp = new Hono()
3535
validator(
3636
"json",
3737
z.object({
38-
uri: z.string(),
38+
uri: z.string().openapi({
39+
description: "The HLS master playlist source.",
40+
examples: ["UUID", "asset://UUID", "https://master.m3u8"],
41+
}),
3942
interstitials: z
4043
.array(
4144
z.object({
42-
time: z.union([z.number(), z.string()]),
43-
duration: z.number().optional(),
45+
time: z.union([
46+
z.number().openapi({
47+
description: "Relative to the media time",
48+
}),
49+
z.string().openapi({
50+
description: "Absolute time, must be an ISO 8601 string",
51+
}),
52+
]),
53+
duration: z.number().optional().openapi({
54+
description:
55+
"For ad replacement purposes, the interstitial will be treated as a range instead of a point when provided.",
56+
}),
4457
delay: z.number().optional(),
4558
assets: z
4659
.array(
4760
z.object({
4861
uri: z.string(),
4962
}),
5063
)
51-
.optional(),
64+
.optional()
65+
.openapi({
66+
description: "Manually define one or more assets.",
67+
}),
5268
vast: z
5369
.object({
5470
url: z.string(),
5571
})
56-
.optional(),
72+
.optional()
73+
.openapi({
74+
description:
75+
"Provide a VAST url for ad insertion, will resolve to assets.",
76+
}),
5777
}),
5878
)
59-
.default([]),
79+
.default([])
80+
.openapi({
81+
description: "Manually defined interstitials at given times.",
82+
}),
6083
filter: z
6184
.object({
6285
resolution: z.string().optional(),
6386
audioLanguage: z.string().optional(),
6487
})
65-
.optional(),
88+
.optional()
89+
.openapi({
90+
description: "Applies filters to the playout.",
91+
}),
6692
vmap: z
6793
.object({
6894
url: z.string(),
6995
})
70-
.optional(),
96+
.optional()
97+
.openapi({
98+
description:
99+
"Add interstitials based on the ads defined in the VMAP.",
100+
}),
71101
vast: z
72102
.object({
73103
url: z.string().optional(),
74104
})
75-
.optional(),
105+
.optional()
106+
.openapi({
107+
description:
108+
"Generic VAST configuration, typically used for live where ad signaling is used to replace linear breaks.",
109+
}),
76110
expiry: z.number().default(60 * 60 * 12),
77111
}),
78112
),

apps/stitcher/src/utils/zod.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import "zod-openapi/extend";
2+
export * from "zod";

0 commit comments

Comments
 (0)