-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexperiment-schemas.ts
More file actions
124 lines (118 loc) · 4.24 KB
/
experiment-schemas.ts
File metadata and controls
124 lines (118 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import {
getDataDocumentSchema,
getErrorDocumentSchema,
getErrorSchema,
getResourceIdentifierSchema,
mediaType,
} from './jsonapi.ts';
import { ForbiddenErrorResponse, StringOrArrayOfStrings } from './utils.ts';
import { z, type RouteConfig } from './zod-openapi.ts';
// Resource schema
// -----------------------------------------------------------------------------
export const ExperimentResourceIdentifier = getResourceIdentifierSchema(
'experiments',
).openapi('ExperimentResourceIdentifier');
const ExperimentAttributes = z
.strictObject({ name: z.string().min(1).describe('Name of the experiment') })
.openapi('ExperimentAttributes');
// Zod recommend using the spread operator on the shape of a zod object
// instead of using the `extend` method, but we then lose zod-to-openapi's
// ability to generate inherited schemas.
export const ExperimentResource = z
.strictObject({
...ExperimentResourceIdentifier.shape,
attributes: ExperimentAttributes,
})
.openapi('ExperimentResource');
const ExperimentResourceCreate = ExperimentResource.omit({ id: true }).openapi(
'ExperimentResourceCreate',
);
// Query parameters schemas
// -----------------------------------------------------------------------------
const ExperimentQueryFilter = z.strictObject({
'filter[name]': StringOrArrayOfStrings.optional(),
});
// Requests schemas
// -----------------------------------------------------------------------------
const ExperimentPostRequest = getDataDocumentSchema({
data: ExperimentResourceCreate,
}).openapi('ExperimentPostRequest');
// OK Response schemas
// -----------------------------------------------------------------------------
const ExperimentGetResponse = getDataDocumentSchema({
data: ExperimentResource,
}).openapi('ExperimentGetResponse');
const ExperimentGetCollectionResponse = getDataDocumentSchema({
data: z.array(ExperimentResource),
}).openapi('ExperimentGetCollectionResponse');
const ExperimentPostResponse = getDataDocumentSchema({
data: ExperimentResourceIdentifier,
}).openapi('ExperimentPostResponse');
// Error Response schemas
// -----------------------------------------------------------------------------
const ExperimentNotFoundErrorResponse = getErrorDocumentSchema(
getErrorSchema({ code: 'EXPERIMENT_NOT_FOUND', statusText: 'Not Found' }),
).openapi('ExperimentNotFoundErrorResponse');
const ExperimentExistsErrorResponse = getErrorDocumentSchema(
getErrorSchema({ code: 'EXPERIMENT_EXISTS', statusText: 'Conflict' }),
).openapi('ExperimentExistsErrorResponse');
// Route configuration
// -----------------------------------------------------------------------------
export const experimentRoutes = {
'/': {
get: {
description: 'List all experiments',
request: { query: ExperimentQueryFilter },
responses: {
200: {
description: 'List of experiments',
content: { [mediaType]: { schema: ExperimentGetCollectionResponse } },
},
},
},
post: {
description: 'Create a new experiment.',
request: {
body: {
required: true,
content: {
[mediaType]: { schema: ExperimentPostRequest.required() },
},
},
},
responses: {
201: {
description: 'Experiment created successfully',
content: { [mediaType]: { schema: ExperimentPostResponse } },
headers: z.strictObject({ location: z.string() }),
},
403: {
description: 'Forbidden',
content: { [mediaType]: { schema: ForbiddenErrorResponse } },
},
409: {
description: 'Experiment already exists',
content: { [mediaType]: { schema: ExperimentExistsErrorResponse } },
},
},
},
},
'/{id}': {
get: {
description: 'Get a specific experiment by ID',
request: {
params: z.object({ id: z.string().describe('ID of the experiment') }),
},
responses: {
200: {
description: 'Experiment retrieved successfully',
content: { [mediaType]: { schema: ExperimentGetResponse } },
},
404: {
description: 'Experiment not found',
content: { [mediaType]: { schema: ExperimentNotFoundErrorResponse } },
},
},
},
},
} satisfies RouteConfig;