an.era 0.3.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/dist/chunk-BN_g-Awi.js +18 -0
- package/dist/index.d.ts +328173 -0
- package/dist/index.js +1233 -0
- package/package.json +42 -0
- package/readme.md +3 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1233 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-BN_g-Awi.js";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
|
|
4
|
+
//#region src/openapi/components/schemas.ts
|
|
5
|
+
const ErrorSchema = v.required(v.partial(v.object({
|
|
6
|
+
error: v.pipe(v.string(), v.metadata({ description: "Error message" }), v.examples(["Not Found"])),
|
|
7
|
+
code: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "HTTP status code" }), v.examples([404])),
|
|
8
|
+
details: v.pipe(v.object({ message: v.pipe(v.string(), v.metadata({ description: "Detailed error message" }), v.examples(["The resource you are looking for does not exist."])) }), v.metadata({ description: "Additional error details" }))
|
|
9
|
+
})), ["error", "code"]);
|
|
10
|
+
const RateLimitErrorSchema = v.pipe(v.required(v.object({ error: v.required(v.partial(v.object({
|
|
11
|
+
type: v.pipe(v.string(), v.metadata({ description: "Error type identifier" }), v.examples(["rate_limit_exceeded"])),
|
|
12
|
+
message: v.pipe(v.string(), v.metadata({ description: "Human-readable error message" }), v.examples(["Rate limit of 30 requests per minute exceeded for guest tier. Try again later."])),
|
|
13
|
+
tier: v.pipe(v.picklist([
|
|
14
|
+
"guest",
|
|
15
|
+
"free",
|
|
16
|
+
"premium",
|
|
17
|
+
"supporter"
|
|
18
|
+
]), v.metadata({ description: "User's current tier" }), v.examples(["guest"])),
|
|
19
|
+
limit: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Request limit per minute for this tier" }), v.examples([30])),
|
|
20
|
+
limit_window: v.pipe(v.string(), v.metadata({ description: "Time window for rate limits" }), v.examples(["1 minute"])),
|
|
21
|
+
retry_after: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Suggested seconds to wait before retrying" }), v.examples([65])),
|
|
22
|
+
current_status: v.object({
|
|
23
|
+
tier: v.pipe(v.string(), v.examples(["guest"])),
|
|
24
|
+
limits: v.pipe(v.record(v.string(), v.union([v.number()])), v.examples([{
|
|
25
|
+
"guest": 30,
|
|
26
|
+
"free": 120,
|
|
27
|
+
"premium": 300,
|
|
28
|
+
"supporter": 600
|
|
29
|
+
}])),
|
|
30
|
+
upgrade_path: v.object({
|
|
31
|
+
current: v.pipe(v.string(), v.examples(["Guest (30 req/min)"])),
|
|
32
|
+
recommended: v.pipe(v.string(), v.examples(["Free Account (120 req/min)"])),
|
|
33
|
+
benefits: v.pipe(v.array(v.string()), v.examples([[
|
|
34
|
+
"4x higher rate limit",
|
|
35
|
+
"Persistent authentication",
|
|
36
|
+
"API access"
|
|
37
|
+
]])),
|
|
38
|
+
action: v.pipe(v.string(), v.examples(["Sign up at https://are.na/signup"]))
|
|
39
|
+
})
|
|
40
|
+
}),
|
|
41
|
+
suggestions: v.pipe(v.array(v.string()), v.metadata({ description: "Tier-specific optimization suggestions" }), v.examples([[
|
|
42
|
+
"Sign up for a free account to get 120 requests per minute",
|
|
43
|
+
"Implement exponential backoff with jitter",
|
|
44
|
+
"Cache responses when possible to reduce API calls",
|
|
45
|
+
"Consider batch requests if available"
|
|
46
|
+
]])),
|
|
47
|
+
headers_note: v.pipe(v.string(), v.metadata({ description: "Information about header usage" }), v.examples(["Check 'X-RateLimit-*' headers on successful requests for current usage"]))
|
|
48
|
+
})), [
|
|
49
|
+
"type",
|
|
50
|
+
"message",
|
|
51
|
+
"tier",
|
|
52
|
+
"limit",
|
|
53
|
+
"retry_after",
|
|
54
|
+
"suggestions"
|
|
55
|
+
]) }), ["error"]), v.metadata({ description: "Rate limit exceeded error response with upgrade information and suggestions" }));
|
|
56
|
+
const LinkSchema = v.pipe(v.required(v.object({ href: v.pipe(v.string(), v.metadata({ description: "The URL of the linked resource" }), v.examples(["https://api.are.na/v3/blocks/12345"])) }), ["href"]), v.metadata({ description: "A hypermedia link containing the URL of a linked resource.\nThe relationship type is expressed by the key in the parent _links object.\n" }));
|
|
57
|
+
const MarkdownContentSchema = v.pipe(v.required(v.object({
|
|
58
|
+
markdown: v.pipe(v.string(), v.metadata({ description: "Original markdown value" }), v.examples(["This is **only** a [test](https://example.com)."])),
|
|
59
|
+
html: v.pipe(v.string(), v.metadata({ description: "HTML rendering of the markdown" }), v.examples(["<p>This is <strong>only</strong> a <a href=\"https://example.com\" target=\"_blank\" rel=\"nofollow noopener\">test</a>.</p>"])),
|
|
60
|
+
plain: v.pipe(v.string(), v.metadata({ description: "Plain text rendering of the markdown" }), v.examples(["This is only a test (https://example.com)."]))
|
|
61
|
+
}), [
|
|
62
|
+
"markdown",
|
|
63
|
+
"html",
|
|
64
|
+
"plain"
|
|
65
|
+
]), v.metadata({ description: "Markdown content with multiple renderings" }));
|
|
66
|
+
const EmbeddedUserSchema = v.pipe(v.required(v.object({
|
|
67
|
+
id: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Unique identifier for the user" }), v.examples([12345])),
|
|
68
|
+
type: v.pipe(v.picklist(["User"]), v.metadata({ description: "User type" }), v.examples(["User"])),
|
|
69
|
+
name: v.pipe(v.string(), v.metadata({ description: "User's display name" }), v.examples(["John Doe"])),
|
|
70
|
+
slug: v.pipe(v.string(), v.metadata({ description: "URL-safe identifier (use this in API paths)" }), v.examples(["john-doe"])),
|
|
71
|
+
avatar: v.pipe(v.union([
|
|
72
|
+
v.string(),
|
|
73
|
+
v.null(),
|
|
74
|
+
v.undefined()
|
|
75
|
+
]), v.metadata({ description: "URL to user's avatar image" }), v.examples(["https://d2w9rnfcy7mm78.cloudfront.net/12345/avatar.jpg"])),
|
|
76
|
+
initials: v.pipe(v.string(), v.metadata({ description: "User's initials" }), v.examples(["JD"]))
|
|
77
|
+
}), [
|
|
78
|
+
"id",
|
|
79
|
+
"type",
|
|
80
|
+
"name",
|
|
81
|
+
"slug",
|
|
82
|
+
"avatar",
|
|
83
|
+
"initials"
|
|
84
|
+
]), v.metadata({ description: "Embedded user representation (used when user is nested in other resources)" }));
|
|
85
|
+
const EmbeddedGroupSchema = v.pipe(v.required(v.object({
|
|
86
|
+
id: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Unique identifier for the group" }), v.examples([67890])),
|
|
87
|
+
type: v.pipe(v.picklist(["Group"]), v.metadata({ description: "Group type" }), v.examples(["Group"])),
|
|
88
|
+
name: v.pipe(v.string(), v.metadata({ description: "Group's name" }), v.examples(["Design Team"])),
|
|
89
|
+
slug: v.pipe(v.string(), v.metadata({ description: "Group's URL slug" }), v.examples(["design-team-abc123"])),
|
|
90
|
+
avatar: v.pipe(v.union([
|
|
91
|
+
v.string(),
|
|
92
|
+
v.null(),
|
|
93
|
+
v.undefined()
|
|
94
|
+
]), v.metadata({ description: "URL to group's avatar image" }), v.examples(["https://d2w9rnfcy7mm78.cloudfront.net/groups/67890/avatar.jpg"])),
|
|
95
|
+
initials: v.pipe(v.string(), v.metadata({ description: "Group's initials" }), v.examples(["DT"]))
|
|
96
|
+
}), [
|
|
97
|
+
"id",
|
|
98
|
+
"type",
|
|
99
|
+
"name",
|
|
100
|
+
"slug",
|
|
101
|
+
"avatar",
|
|
102
|
+
"initials"
|
|
103
|
+
]), v.metadata({ description: "Embedded group representation (used when group is nested in other resources)" }));
|
|
104
|
+
const UserCountsSchema = v.pipe(v.required(v.object({
|
|
105
|
+
channels: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of channels owned by the user" }), v.examples([24])),
|
|
106
|
+
followers: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of followers" }), v.examples([156])),
|
|
107
|
+
following: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of users being followed" }), v.examples([89]))
|
|
108
|
+
}), [
|
|
109
|
+
"channels",
|
|
110
|
+
"followers",
|
|
111
|
+
"following"
|
|
112
|
+
]), v.metadata({ description: "Counts of various items for the user" }));
|
|
113
|
+
const GroupCountsSchema = v.pipe(v.required(v.object({
|
|
114
|
+
channels: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of channels owned by the group" }), v.examples([12])),
|
|
115
|
+
users: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of users in the group" }), v.examples([5]))
|
|
116
|
+
}), ["channels", "users"]), v.metadata({ description: "Counts of various items for the group" }));
|
|
117
|
+
const ContentTypeFilterSchema = v.pipe(v.picklist([
|
|
118
|
+
"Text",
|
|
119
|
+
"Image",
|
|
120
|
+
"Link",
|
|
121
|
+
"Attachment",
|
|
122
|
+
"Embed",
|
|
123
|
+
"Channel",
|
|
124
|
+
"Block"
|
|
125
|
+
]), v.metadata({ description: "Filter for content types (blocks and channels)" }));
|
|
126
|
+
const SearchTypeFilterSchema = v.pipe(v.picklist([
|
|
127
|
+
"All",
|
|
128
|
+
"Text",
|
|
129
|
+
"Image",
|
|
130
|
+
"Link",
|
|
131
|
+
"Attachment",
|
|
132
|
+
"Embed",
|
|
133
|
+
"Channel",
|
|
134
|
+
"Block",
|
|
135
|
+
"User",
|
|
136
|
+
"Group"
|
|
137
|
+
]), v.metadata({ description: "Filter for searchable content types (includes all content types plus users and groups)" }));
|
|
138
|
+
const FileExtensionSchema = v.pipe(v.picklist([
|
|
139
|
+
"aac",
|
|
140
|
+
"ai",
|
|
141
|
+
"aiff",
|
|
142
|
+
"avi",
|
|
143
|
+
"avif",
|
|
144
|
+
"bmp",
|
|
145
|
+
"csv",
|
|
146
|
+
"doc",
|
|
147
|
+
"docx",
|
|
148
|
+
"eps",
|
|
149
|
+
"epub",
|
|
150
|
+
"fla",
|
|
151
|
+
"gif",
|
|
152
|
+
"h264",
|
|
153
|
+
"heic",
|
|
154
|
+
"heif",
|
|
155
|
+
"ind",
|
|
156
|
+
"indd",
|
|
157
|
+
"jpeg",
|
|
158
|
+
"jpg",
|
|
159
|
+
"key",
|
|
160
|
+
"kml",
|
|
161
|
+
"kmz",
|
|
162
|
+
"latex",
|
|
163
|
+
"m4a",
|
|
164
|
+
"ma",
|
|
165
|
+
"mb",
|
|
166
|
+
"mid",
|
|
167
|
+
"midi",
|
|
168
|
+
"mov",
|
|
169
|
+
"mp3",
|
|
170
|
+
"mp4",
|
|
171
|
+
"mp4v",
|
|
172
|
+
"mpeg",
|
|
173
|
+
"mpg",
|
|
174
|
+
"mpg4",
|
|
175
|
+
"numbers",
|
|
176
|
+
"oga",
|
|
177
|
+
"ogg",
|
|
178
|
+
"ogv",
|
|
179
|
+
"otf",
|
|
180
|
+
"pages",
|
|
181
|
+
"pdf",
|
|
182
|
+
"pgp",
|
|
183
|
+
"png",
|
|
184
|
+
"ppt",
|
|
185
|
+
"pptx",
|
|
186
|
+
"psd",
|
|
187
|
+
"svg",
|
|
188
|
+
"swa",
|
|
189
|
+
"swf",
|
|
190
|
+
"tex",
|
|
191
|
+
"texi",
|
|
192
|
+
"texinfo",
|
|
193
|
+
"tfm",
|
|
194
|
+
"tif",
|
|
195
|
+
"tiff",
|
|
196
|
+
"torrent",
|
|
197
|
+
"ttc",
|
|
198
|
+
"ttf",
|
|
199
|
+
"txt",
|
|
200
|
+
"wav",
|
|
201
|
+
"webm",
|
|
202
|
+
"webp",
|
|
203
|
+
"wma",
|
|
204
|
+
"xls",
|
|
205
|
+
"xlsx",
|
|
206
|
+
"xlt"
|
|
207
|
+
]), v.metadata({ description: "Supported file extensions for filtering" }));
|
|
208
|
+
const ConnectionSortSchema = v.pipe(v.picklist(["created_at_desc", "created_at_asc"]), v.metadata({ description: "Sort order for connection lists (channels containing a block/channel, followers)" }));
|
|
209
|
+
const ChannelContentSortSchema = v.pipe(v.picklist([
|
|
210
|
+
"position_asc",
|
|
211
|
+
"position_desc",
|
|
212
|
+
"created_at_asc",
|
|
213
|
+
"created_at_desc",
|
|
214
|
+
"updated_at_asc",
|
|
215
|
+
"updated_at_desc"
|
|
216
|
+
]), v.metadata({ description: "Sort order for channel contents (includes position for manual ordering)" }));
|
|
217
|
+
const ContentSortSchema = v.pipe(v.picklist([
|
|
218
|
+
"created_at_asc",
|
|
219
|
+
"created_at_desc",
|
|
220
|
+
"updated_at_asc",
|
|
221
|
+
"updated_at_desc"
|
|
222
|
+
]), v.metadata({ description: "Sort order for user/group content lists" }));
|
|
223
|
+
const BlockProviderSchema = v.required(v.object({
|
|
224
|
+
name: v.pipe(v.string(), v.metadata({ description: "Provider name (from parsed URI host)" }), v.examples(["Example.com"])),
|
|
225
|
+
url: v.pipe(v.string(), v.metadata({ description: "Provider URL (from parsed URI scheme and host)" }), v.examples(["https://example.com"]))
|
|
226
|
+
}), ["name", "url"]);
|
|
227
|
+
const ImageVersionSchema = v.pipe(v.required(v.partial(v.object({
|
|
228
|
+
src: v.pipe(v.string(), v.metadata({ description: "Default image URL (1x resolution)" }), v.examples(["https://d2w9rnfcy7mm78.cloudfront.net/12345/display_image.jpg"])),
|
|
229
|
+
src_1x: v.pipe(v.string(), v.metadata({ description: "1x resolution image URL" }), v.examples(["https://d2w9rnfcy7mm78.cloudfront.net/12345/display_image.jpg"])),
|
|
230
|
+
src_2x: v.pipe(v.string(), v.metadata({ description: "2x resolution image URL for high DPI displays" }), v.examples(["https://d2w9rnfcy7mm78.cloudfront.net/12345/display_image@2x.jpg"])),
|
|
231
|
+
width: v.pipe(v.union([
|
|
232
|
+
v.pipe(v.number(), v.integer()),
|
|
233
|
+
v.null(),
|
|
234
|
+
v.undefined()
|
|
235
|
+
]), v.metadata({ description: "Width of the resized image in pixels" }), v.examples([640])),
|
|
236
|
+
height: v.pipe(v.union([
|
|
237
|
+
v.pipe(v.number(), v.integer()),
|
|
238
|
+
v.null(),
|
|
239
|
+
v.undefined()
|
|
240
|
+
]), v.metadata({ description: "Height of the resized image in pixels" }), v.examples([480]))
|
|
241
|
+
})), [
|
|
242
|
+
"src",
|
|
243
|
+
"src_1x",
|
|
244
|
+
"src_2x"
|
|
245
|
+
]), v.metadata({ description: "A resized/processed version of an image with multiple resolution URLs" }));
|
|
246
|
+
const BlockEmbedSchema = v.object({
|
|
247
|
+
url: v.pipe(v.union([
|
|
248
|
+
v.string(),
|
|
249
|
+
v.null(),
|
|
250
|
+
v.undefined()
|
|
251
|
+
]), v.metadata({ description: "Embed URL" }), v.examples(["https://www.youtube.com/embed/abc123"])),
|
|
252
|
+
type: v.pipe(v.union([
|
|
253
|
+
v.string(),
|
|
254
|
+
v.null(),
|
|
255
|
+
v.undefined()
|
|
256
|
+
]), v.metadata({ description: "Embed type" }), v.examples(["youtube"])),
|
|
257
|
+
title: v.pipe(v.union([
|
|
258
|
+
v.string(),
|
|
259
|
+
v.null(),
|
|
260
|
+
v.undefined()
|
|
261
|
+
]), v.metadata({ description: "Embed title" }), v.examples(["Video Title"])),
|
|
262
|
+
author_name: v.pipe(v.union([
|
|
263
|
+
v.string(),
|
|
264
|
+
v.null(),
|
|
265
|
+
v.undefined()
|
|
266
|
+
]), v.metadata({ description: "Author name" }), v.examples(["Author Name"])),
|
|
267
|
+
author_url: v.pipe(v.union([
|
|
268
|
+
v.string(),
|
|
269
|
+
v.null(),
|
|
270
|
+
v.undefined()
|
|
271
|
+
]), v.metadata({ description: "Author URL" }), v.examples(["https://example.com/author"])),
|
|
272
|
+
source_url: v.pipe(v.union([
|
|
273
|
+
v.string(),
|
|
274
|
+
v.null(),
|
|
275
|
+
v.undefined()
|
|
276
|
+
]), v.metadata({ description: "Embed source URL" }), v.examples(["https://www.youtube.com/watch?v=abc123"])),
|
|
277
|
+
width: v.pipe(v.union([
|
|
278
|
+
v.pipe(v.number(), v.integer()),
|
|
279
|
+
v.null(),
|
|
280
|
+
v.undefined()
|
|
281
|
+
]), v.metadata({ description: "Embed width" }), v.examples([640])),
|
|
282
|
+
height: v.pipe(v.union([
|
|
283
|
+
v.pipe(v.number(), v.integer()),
|
|
284
|
+
v.null(),
|
|
285
|
+
v.undefined()
|
|
286
|
+
]), v.metadata({ description: "Embed height" }), v.examples([480])),
|
|
287
|
+
html: v.pipe(v.union([
|
|
288
|
+
v.string(),
|
|
289
|
+
v.null(),
|
|
290
|
+
v.undefined()
|
|
291
|
+
]), v.metadata({ description: "Embed HTML" }), v.examples(["<iframe src='...'></iframe>"])),
|
|
292
|
+
thumbnail_url: v.pipe(v.union([
|
|
293
|
+
v.string(),
|
|
294
|
+
v.null(),
|
|
295
|
+
v.undefined()
|
|
296
|
+
]), v.metadata({ description: "Thumbnail URL" }), v.examples(["https://example.com/thumbnail.jpg"]))
|
|
297
|
+
});
|
|
298
|
+
const BlockAttachmentSchema = v.required(v.partial(v.object({
|
|
299
|
+
filename: v.pipe(v.union([
|
|
300
|
+
v.string(),
|
|
301
|
+
v.null(),
|
|
302
|
+
v.undefined()
|
|
303
|
+
]), v.metadata({ description: "Attachment filename" }), v.examples(["document.pdf"])),
|
|
304
|
+
content_type: v.pipe(v.union([
|
|
305
|
+
v.string(),
|
|
306
|
+
v.null(),
|
|
307
|
+
v.undefined()
|
|
308
|
+
]), v.metadata({ description: "Attachment content type" }), v.examples(["application/pdf"])),
|
|
309
|
+
file_size: v.pipe(v.union([
|
|
310
|
+
v.pipe(v.number(), v.integer()),
|
|
311
|
+
v.null(),
|
|
312
|
+
v.undefined()
|
|
313
|
+
]), v.metadata({ description: "File size in bytes" }), v.examples([2048e3])),
|
|
314
|
+
file_extension: v.pipe(v.union([
|
|
315
|
+
v.string(),
|
|
316
|
+
v.null(),
|
|
317
|
+
v.undefined()
|
|
318
|
+
]), v.metadata({ description: "File extension" }), v.examples(["pdf"])),
|
|
319
|
+
updated_at: v.pipe(v.union([
|
|
320
|
+
v.string(),
|
|
321
|
+
v.null(),
|
|
322
|
+
v.undefined()
|
|
323
|
+
]), v.metadata({ description: "When the attachment was last updated" })),
|
|
324
|
+
url: v.pipe(v.string(), v.metadata({ description: "Attachment download URL" }), v.examples(["https://attachments.are.na/12345/document.pdf"]))
|
|
325
|
+
})), ["url"]);
|
|
326
|
+
const ChannelCountsSchema = v.pipe(v.required(v.object({
|
|
327
|
+
blocks: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of blocks in the channel" }), v.examples([42])),
|
|
328
|
+
channels: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of channels connected to this channel" }), v.examples([8])),
|
|
329
|
+
contents: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Total number of contents (blocks + channels)" }), v.examples([50])),
|
|
330
|
+
collaborators: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of collaborators on the channel" }), v.examples([3]))
|
|
331
|
+
}), [
|
|
332
|
+
"blocks",
|
|
333
|
+
"channels",
|
|
334
|
+
"contents",
|
|
335
|
+
"collaborators"
|
|
336
|
+
]), v.metadata({ description: "Counts of various items in the channel" }));
|
|
337
|
+
const PaginationMetaWithCountSchema = v.pipe(v.required(v.partial(v.object({
|
|
338
|
+
current_page: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Current page number" }), v.examples([1])),
|
|
339
|
+
next_page: v.pipe(v.union([
|
|
340
|
+
v.pipe(v.number(), v.integer()),
|
|
341
|
+
v.null(),
|
|
342
|
+
v.undefined()
|
|
343
|
+
]), v.metadata({ description: "Next page number (null if last page)" }), v.examples([2])),
|
|
344
|
+
prev_page: v.pipe(v.union([
|
|
345
|
+
v.pipe(v.number(), v.integer()),
|
|
346
|
+
v.null(),
|
|
347
|
+
v.undefined()
|
|
348
|
+
]), v.metadata({ description: "Previous page number (null if first page)" })),
|
|
349
|
+
per_page: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of items per page" }), v.examples([25])),
|
|
350
|
+
total_pages: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Total number of pages available" }), v.examples([5])),
|
|
351
|
+
total_count: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Total number of items available" }), v.examples([120])),
|
|
352
|
+
has_more_pages: v.pipe(v.boolean(), v.metadata({ description: "Whether there are more pages available" }), v.examples([true]))
|
|
353
|
+
})), [
|
|
354
|
+
"current_page",
|
|
355
|
+
"per_page",
|
|
356
|
+
"total_pages",
|
|
357
|
+
"total_count",
|
|
358
|
+
"has_more_pages"
|
|
359
|
+
]), v.metadata({ description: "Pagination metadata when total counts are available" }));
|
|
360
|
+
const PaginationMetaWithoutCountSchema = v.pipe(v.required(v.partial(v.object({
|
|
361
|
+
current_page: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Current page number" }), v.examples([1])),
|
|
362
|
+
next_page: v.pipe(v.union([
|
|
363
|
+
v.pipe(v.number(), v.integer()),
|
|
364
|
+
v.null(),
|
|
365
|
+
v.undefined()
|
|
366
|
+
]), v.metadata({ description: "Next page number (null if last page)" }), v.examples([2])),
|
|
367
|
+
prev_page: v.pipe(v.union([
|
|
368
|
+
v.pipe(v.number(), v.integer()),
|
|
369
|
+
v.null(),
|
|
370
|
+
v.undefined()
|
|
371
|
+
]), v.metadata({ description: "Previous page number (null if first page)" })),
|
|
372
|
+
per_page: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of items per page" }), v.examples([25])),
|
|
373
|
+
has_more_pages: v.pipe(v.boolean(), v.metadata({ description: "Whether there are more pages available" }), v.examples([true]))
|
|
374
|
+
})), [
|
|
375
|
+
"current_page",
|
|
376
|
+
"per_page",
|
|
377
|
+
"has_more_pages"
|
|
378
|
+
]), v.metadata({ description: "Pagination metadata when total counts are not available" }));
|
|
379
|
+
const PingResponseSchema = v.pipe(v.required(v.object({ status: v.pipe(v.picklist(["ok"]), v.examples(["ok"])) }), ["status"]), v.metadata({ description: "Health check response" }));
|
|
380
|
+
const LinksSchema = v.pipe(v.required(v.object({ self: v.intersect([LinkSchema, v.pipe(v.any(), v.metadata({ description: "Link to the current resource (always present)" }))]) }), ["self"]), v.metadata({ description: "HATEOAS links for navigation and discovery.\nFollows HAL (Hypertext Application Language) format where link relationships \nare expressed as object keys (e.g., \"self\", \"user\", \"channels\").\n" }));
|
|
381
|
+
const ConnectionContextSchema = v.pipe(v.required(v.object({
|
|
382
|
+
id: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Unique identifier for the connection" }), v.examples([98765])),
|
|
383
|
+
position: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Position of the item within the channel (for manual ordering)" }), v.examples([1])),
|
|
384
|
+
pinned: v.pipe(v.boolean(), v.metadata({ description: "Whether the item is pinned to the top of the channel" }), v.examples([false])),
|
|
385
|
+
connected_at: v.pipe(v.string(), v.metadata({ description: "When the item was connected to the channel" }), v.examples(["2023-01-15T10:30:00Z"])),
|
|
386
|
+
connected_by: v.pipe(v.union([
|
|
387
|
+
EmbeddedUserSchema,
|
|
388
|
+
v.null(),
|
|
389
|
+
v.undefined()
|
|
390
|
+
]), v.metadata({ description: "User who connected this item to the channel" }))
|
|
391
|
+
}), [
|
|
392
|
+
"id",
|
|
393
|
+
"position",
|
|
394
|
+
"pinned",
|
|
395
|
+
"connected_at",
|
|
396
|
+
"connected_by"
|
|
397
|
+
]), v.metadata({ description: "Connection metadata that describes how an item is connected to a channel.\nThis is only present when the item is returned as part of a channel's contents.\n" }));
|
|
398
|
+
const ChannelOwnerSchema = v.pipe(v.union([EmbeddedUserSchema, EmbeddedGroupSchema]), v.metadata({ description: "Channel owner (User or Group)" }));
|
|
399
|
+
const BlockSourceSchema = v.required(v.partial(v.object({
|
|
400
|
+
url: v.pipe(v.string(), v.metadata({ description: "Source URL" }), v.examples(["https://example.com/article"])),
|
|
401
|
+
title: v.pipe(v.union([
|
|
402
|
+
v.string(),
|
|
403
|
+
v.null(),
|
|
404
|
+
v.undefined()
|
|
405
|
+
]), v.metadata({ description: "Source title" }), v.examples(["Original Article Title"])),
|
|
406
|
+
provider: v.union([
|
|
407
|
+
BlockProviderSchema,
|
|
408
|
+
v.null(),
|
|
409
|
+
v.undefined()
|
|
410
|
+
])
|
|
411
|
+
})), ["url"]);
|
|
412
|
+
const BlockImageSchema = v.required(v.partial(v.object({
|
|
413
|
+
alt_text: v.pipe(v.union([
|
|
414
|
+
v.string(),
|
|
415
|
+
v.null(),
|
|
416
|
+
v.undefined()
|
|
417
|
+
]), v.metadata({ description: "Alternative text associated with the image" }), v.examples(["Scanned collage of magazine cutouts"])),
|
|
418
|
+
blurhash: v.pipe(v.union([
|
|
419
|
+
v.string(),
|
|
420
|
+
v.null(),
|
|
421
|
+
v.undefined()
|
|
422
|
+
]), v.metadata({ description: "BlurHash representation of the image for progressive loading" }), v.examples(["LEHV6nWB2yk8pyo0adR*.7kCMdnj"])),
|
|
423
|
+
width: v.pipe(v.union([
|
|
424
|
+
v.pipe(v.number(), v.integer()),
|
|
425
|
+
v.null(),
|
|
426
|
+
v.undefined()
|
|
427
|
+
]), v.metadata({ description: "Original image width in pixels" }), v.examples([1920])),
|
|
428
|
+
height: v.pipe(v.union([
|
|
429
|
+
v.pipe(v.number(), v.integer()),
|
|
430
|
+
v.null(),
|
|
431
|
+
v.undefined()
|
|
432
|
+
]), v.metadata({ description: "Original image height in pixels" }), v.examples([1080])),
|
|
433
|
+
aspect_ratio: v.pipe(v.union([
|
|
434
|
+
v.number(),
|
|
435
|
+
v.null(),
|
|
436
|
+
v.undefined()
|
|
437
|
+
]), v.metadata({ description: "Image aspect ratio (width / height)" }), v.examples([1.7778])),
|
|
438
|
+
content_type: v.pipe(v.string(), v.metadata({ description: "Image content type" }), v.examples(["image/jpeg"])),
|
|
439
|
+
filename: v.pipe(v.string(), v.metadata({ description: "Image filename" }), v.examples(["image.jpg"])),
|
|
440
|
+
file_size: v.pipe(v.union([
|
|
441
|
+
v.pipe(v.number(), v.integer()),
|
|
442
|
+
v.null(),
|
|
443
|
+
v.undefined()
|
|
444
|
+
]), v.metadata({ description: "File size in bytes" }), v.examples([1024e3])),
|
|
445
|
+
updated_at: v.pipe(v.string(), v.metadata({ description: "When the image was last updated" }), v.examples(["2023-01-15T14:45:00Z"])),
|
|
446
|
+
small: v.intersect([ImageVersionSchema, v.pipe(v.any(), v.metadata({ description: "Small image version (thumb)" }))]),
|
|
447
|
+
medium: v.intersect([ImageVersionSchema, v.pipe(v.any(), v.metadata({ description: "Medium image version (display)" }))]),
|
|
448
|
+
large: v.intersect([ImageVersionSchema, v.pipe(v.any(), v.metadata({ description: "Large image version" }))]),
|
|
449
|
+
square: v.intersect([ImageVersionSchema, v.pipe(v.any(), v.metadata({ description: "Square cropped image version" }))])
|
|
450
|
+
})), [
|
|
451
|
+
"small",
|
|
452
|
+
"medium",
|
|
453
|
+
"large",
|
|
454
|
+
"square"
|
|
455
|
+
]);
|
|
456
|
+
const PaginatedResponseWithCountBaseSchema = v.pipe(v.required(v.partial(v.object({ meta: PaginationMetaWithCountSchema })), ["meta"]), v.metadata({ description: "Base schema for paginated responses with total count (use allOf to extend with specific data type)" }));
|
|
457
|
+
const PaginationMetaSchema = v.pipe(v.union([PaginationMetaWithCountSchema, PaginationMetaWithoutCountSchema]), v.metadata({ description: "Pagination metadata union matching pagination behavior with and without total counts" }));
|
|
458
|
+
const UserSchema = v.pipe(v.intersect([EmbeddedUserSchema, v.required(v.partial(v.object({
|
|
459
|
+
created_at: v.pipe(v.string(), v.metadata({ description: "When the user was created" }), v.examples(["2023-01-15T10:30:00Z"])),
|
|
460
|
+
updated_at: v.pipe(v.string(), v.metadata({ description: "When the user was last updated" }), v.examples(["2023-06-20T14:45:00Z"])),
|
|
461
|
+
bio: v.pipe(v.union([
|
|
462
|
+
MarkdownContentSchema,
|
|
463
|
+
v.null(),
|
|
464
|
+
v.undefined()
|
|
465
|
+
]), v.metadata({ description: "User biography with markdown, HTML, and plain text renderings" })),
|
|
466
|
+
counts: UserCountsSchema,
|
|
467
|
+
_links: v.intersect([LinksSchema, v.pipe(v.any(), v.metadata({ description: "HATEOAS links for navigation" }))])
|
|
468
|
+
})), [
|
|
469
|
+
"created_at",
|
|
470
|
+
"updated_at",
|
|
471
|
+
"counts",
|
|
472
|
+
"_links"
|
|
473
|
+
])]), v.metadata({ description: "Full user representation" }));
|
|
474
|
+
const GroupSchema = v.pipe(v.intersect([EmbeddedGroupSchema, v.required(v.partial(v.object({
|
|
475
|
+
bio: v.pipe(v.union([
|
|
476
|
+
MarkdownContentSchema,
|
|
477
|
+
v.null(),
|
|
478
|
+
v.undefined()
|
|
479
|
+
]), v.metadata({ description: "Group biography with markdown, HTML, and plain text renderings" })),
|
|
480
|
+
created_at: v.pipe(v.string(), v.metadata({ description: "When the group was created" }), v.examples(["2023-01-15T10:30:00Z"])),
|
|
481
|
+
updated_at: v.pipe(v.string(), v.metadata({ description: "When the group was last updated" }), v.examples(["2023-06-20T14:45:00Z"])),
|
|
482
|
+
user: v.intersect([EmbeddedUserSchema, v.pipe(v.any(), v.metadata({ description: "User who owns/created the group" }))]),
|
|
483
|
+
counts: GroupCountsSchema,
|
|
484
|
+
_links: v.intersect([LinksSchema, v.pipe(v.any(), v.metadata({ description: "HATEOAS links for navigation" }))])
|
|
485
|
+
})), [
|
|
486
|
+
"created_at",
|
|
487
|
+
"updated_at",
|
|
488
|
+
"user",
|
|
489
|
+
"counts",
|
|
490
|
+
"_links"
|
|
491
|
+
])]), v.metadata({ description: "Full group representation" }));
|
|
492
|
+
const CommentSchema = v.pipe(v.required(v.partial(v.object({
|
|
493
|
+
id: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Unique identifier for the comment" }), v.examples([12345])),
|
|
494
|
+
type: v.pipe(v.picklist(["Comment"]), v.metadata({ description: "Comment type" }), v.examples(["Comment"])),
|
|
495
|
+
body: v.pipe(v.union([
|
|
496
|
+
MarkdownContentSchema,
|
|
497
|
+
v.null(),
|
|
498
|
+
v.undefined()
|
|
499
|
+
]), v.metadata({ description: "Comment body with markdown, HTML, and plain text renderings" })),
|
|
500
|
+
created_at: v.pipe(v.string(), v.metadata({ description: "When the comment was created" }), v.examples(["2023-01-15T10:30:00Z"])),
|
|
501
|
+
updated_at: v.pipe(v.string(), v.metadata({ description: "When the comment was last updated" }), v.examples(["2023-01-15T14:45:00Z"])),
|
|
502
|
+
user: EmbeddedUserSchema,
|
|
503
|
+
_links: v.intersect([LinksSchema, v.pipe(v.any(), v.metadata({ description: "HATEOAS links for navigation" }))])
|
|
504
|
+
})), [
|
|
505
|
+
"id",
|
|
506
|
+
"type",
|
|
507
|
+
"created_at",
|
|
508
|
+
"updated_at",
|
|
509
|
+
"user",
|
|
510
|
+
"_links"
|
|
511
|
+
]), v.metadata({ description: "A comment on a block" }));
|
|
512
|
+
const ChannelSchema = v.required(v.partial(v.object({
|
|
513
|
+
id: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Unique identifier for the channel" }), v.examples([12345])),
|
|
514
|
+
type: v.pipe(v.picklist(["Channel"]), v.metadata({ description: "Channel type" }), v.examples(["Channel"])),
|
|
515
|
+
slug: v.pipe(v.string(), v.metadata({ description: "Channel URL slug" }), v.examples(["my-collection-abc123"])),
|
|
516
|
+
title: v.pipe(v.string(), v.metadata({ description: "Channel title" }), v.examples(["My Collection"])),
|
|
517
|
+
description: v.pipe(v.union([
|
|
518
|
+
MarkdownContentSchema,
|
|
519
|
+
v.null(),
|
|
520
|
+
v.undefined()
|
|
521
|
+
]), v.metadata({ description: "Channel description with multiple renderings" })),
|
|
522
|
+
state: v.pipe(v.picklist(["available", "deleted"]), v.metadata({ description: "Lifecycle state of the channel:\n- `available`: Channel is active and accessible\n- `deleted`: Channel has been soft-deleted\n" }), v.examples(["available"])),
|
|
523
|
+
visibility: v.pipe(v.picklist([
|
|
524
|
+
"public",
|
|
525
|
+
"private",
|
|
526
|
+
"closed"
|
|
527
|
+
]), v.metadata({ description: "Visibility level of the channel:\n- `public`: Anyone can view and connect to the channel\n- `private`: Only the owner and collaborators can view\n- `closed`: Anyone can view, but only collaborators can add content\n" }), v.examples(["public"])),
|
|
528
|
+
created_at: v.pipe(v.string(), v.metadata({ description: "When the channel was created" }), v.examples(["2023-01-15T10:30:00Z"])),
|
|
529
|
+
updated_at: v.pipe(v.string(), v.metadata({ description: "When the channel was last updated" }), v.examples(["2023-01-15T14:45:00Z"])),
|
|
530
|
+
owner: ChannelOwnerSchema,
|
|
531
|
+
counts: ChannelCountsSchema,
|
|
532
|
+
_links: v.intersect([LinksSchema, v.pipe(v.any(), v.metadata({ description: "HATEOAS links for navigation" }))]),
|
|
533
|
+
connection: v.pipe(v.union([
|
|
534
|
+
ConnectionContextSchema,
|
|
535
|
+
v.null(),
|
|
536
|
+
v.undefined()
|
|
537
|
+
]), v.metadata({ description: "Connection context (only present when channel is returned as part of another channel's contents).\nContains position, pinned status, and information about who connected the channel.\n" }))
|
|
538
|
+
})), [
|
|
539
|
+
"id",
|
|
540
|
+
"type",
|
|
541
|
+
"slug",
|
|
542
|
+
"title",
|
|
543
|
+
"state",
|
|
544
|
+
"visibility",
|
|
545
|
+
"created_at",
|
|
546
|
+
"updated_at",
|
|
547
|
+
"owner",
|
|
548
|
+
"counts",
|
|
549
|
+
"_links"
|
|
550
|
+
]);
|
|
551
|
+
const BaseBlockPropertiesSchema = v.pipe(v.required(v.partial(v.object({
|
|
552
|
+
id: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Unique identifier for the block" }), v.examples([12345])),
|
|
553
|
+
base_type: v.pipe(v.picklist(["Block"]), v.metadata({ description: "Base type of the block (always \"Block\")" }), v.examples(["Block"])),
|
|
554
|
+
title: v.pipe(v.union([
|
|
555
|
+
v.string(),
|
|
556
|
+
v.null(),
|
|
557
|
+
v.undefined()
|
|
558
|
+
]), v.metadata({ description: "Block title" }), v.examples(["Interesting Article"])),
|
|
559
|
+
description: v.pipe(v.union([
|
|
560
|
+
MarkdownContentSchema,
|
|
561
|
+
v.null(),
|
|
562
|
+
v.undefined()
|
|
563
|
+
]), v.metadata({ description: "Block description with multiple renderings" })),
|
|
564
|
+
state: v.pipe(v.picklist([
|
|
565
|
+
"available",
|
|
566
|
+
"pending",
|
|
567
|
+
"failed",
|
|
568
|
+
"processing"
|
|
569
|
+
]), v.metadata({ description: "Processing state of the block:\n- `available`: Block is ready and fully processed\n- `pending`: Block is queued for processing\n- `processing`: Block is currently being processed (e.g., image thumbnails, metadata extraction)\n- `failed`: Block processing failed (may still be viewable but incomplete)\n" }), v.examples(["available"])),
|
|
570
|
+
visibility: v.pipe(v.picklist([
|
|
571
|
+
"public",
|
|
572
|
+
"private",
|
|
573
|
+
"orphan"
|
|
574
|
+
]), v.metadata({ description: "Visibility level of the block:\n- `public`: Visible to everyone\n- `private`: Only visible to the owner\n- `orphan`: Block exists but is not connected to any channel\n" }), v.examples(["public"])),
|
|
575
|
+
comment_count: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Number of comments on the block" }), v.examples([5])),
|
|
576
|
+
created_at: v.pipe(v.string(), v.metadata({ description: "When the block was created" }), v.examples(["2023-01-15T10:30:00Z"])),
|
|
577
|
+
updated_at: v.pipe(v.string(), v.metadata({ description: "When the block was last updated" }), v.examples(["2023-01-15T14:45:00Z"])),
|
|
578
|
+
user: EmbeddedUserSchema,
|
|
579
|
+
source: v.pipe(v.union([
|
|
580
|
+
BlockSourceSchema,
|
|
581
|
+
v.null(),
|
|
582
|
+
v.undefined()
|
|
583
|
+
]), v.metadata({ description: "Source URL and metadata (if block was created from a URL)" })),
|
|
584
|
+
_links: v.intersect([LinksSchema, v.pipe(v.any(), v.metadata({ description: "HATEOAS links for navigation" }))]),
|
|
585
|
+
connection: v.pipe(v.union([
|
|
586
|
+
ConnectionContextSchema,
|
|
587
|
+
v.null(),
|
|
588
|
+
v.undefined()
|
|
589
|
+
]), v.metadata({ description: "Connection context (only present when block is returned as part of channel contents).\nContains position, pinned status, and information about who connected the block.\n" }))
|
|
590
|
+
})), [
|
|
591
|
+
"id",
|
|
592
|
+
"base_type",
|
|
593
|
+
"state",
|
|
594
|
+
"visibility",
|
|
595
|
+
"comment_count",
|
|
596
|
+
"created_at",
|
|
597
|
+
"updated_at",
|
|
598
|
+
"user",
|
|
599
|
+
"_links"
|
|
600
|
+
]), v.metadata({ description: "Common properties shared by all block types" }));
|
|
601
|
+
const PaginatedResponseBaseSchema = v.pipe(v.required(v.partial(v.object({ meta: PaginationMetaSchema })), ["meta"]), v.metadata({ description: "Base schema for all paginated responses (use allOf to extend with specific data type)" }));
|
|
602
|
+
const UserListSchema = v.pipe(v.required(v.object({ data: v.pipe(v.array(UserSchema), v.metadata({ description: "Array of users" })) }), ["data"]), v.metadata({ description: "Data payload containing an array of users" }));
|
|
603
|
+
const CommentListSchema = v.pipe(v.required(v.object({ data: v.pipe(v.array(CommentSchema), v.metadata({ description: "Array of comments" })) }), ["data"]), v.metadata({ description: "Data payload containing an array of comments" }));
|
|
604
|
+
const ChannelListSchema = v.pipe(v.required(v.object({ data: v.pipe(v.array(ChannelSchema), v.metadata({ description: "Array of channels" })) }), ["data"]), v.metadata({ description: "Data payload containing an array of channels" }));
|
|
605
|
+
const FollowableListSchema = v.pipe(v.required(v.object({ data: v.pipe(v.array(v.union([
|
|
606
|
+
UserSchema,
|
|
607
|
+
ChannelSchema,
|
|
608
|
+
GroupSchema
|
|
609
|
+
])), v.metadata({ description: "Array of users, channels, and/or groups" })) }), ["data"]), v.metadata({ description: "Data payload containing followable items (users, channels, and groups)" }));
|
|
610
|
+
const TextBlockSchema = v.pipe(v.intersect([BaseBlockPropertiesSchema, v.required(v.object({
|
|
611
|
+
type: v.pipe(v.picklist(["Text"]), v.metadata({ description: "Block type (always \"Text\" for TextBlock)" })),
|
|
612
|
+
content: MarkdownContentSchema
|
|
613
|
+
}), ["type", "content"])]), v.metadata({ description: "A text block containing markdown content" }));
|
|
614
|
+
const ImageBlockSchema = v.pipe(v.intersect([BaseBlockPropertiesSchema, v.required(v.object({
|
|
615
|
+
type: v.pipe(v.picklist(["Image"]), v.metadata({ description: "Block type (always \"Image\" for ImageBlock)" })),
|
|
616
|
+
image: BlockImageSchema
|
|
617
|
+
}), ["type", "image"])]), v.metadata({ description: "An image block containing an uploaded or scraped image" }));
|
|
618
|
+
const LinkBlockSchema = v.pipe(v.intersect([BaseBlockPropertiesSchema, v.required(v.partial(v.object({
|
|
619
|
+
type: v.pipe(v.picklist(["Link"]), v.metadata({ description: "Block type (always \"Link\" for LinkBlock)" })),
|
|
620
|
+
image: v.pipe(v.union([
|
|
621
|
+
BlockImageSchema,
|
|
622
|
+
v.null(),
|
|
623
|
+
v.undefined()
|
|
624
|
+
]), v.metadata({ description: "Preview image (if available)" })),
|
|
625
|
+
content: v.pipe(v.union([
|
|
626
|
+
MarkdownContentSchema,
|
|
627
|
+
v.null(),
|
|
628
|
+
v.undefined()
|
|
629
|
+
]), v.metadata({ description: "Extracted text content from the link" }))
|
|
630
|
+
})), ["type"])]), v.metadata({ description: "A link block representing a URL with optional preview" }));
|
|
631
|
+
const AttachmentBlockSchema = v.pipe(v.intersect([BaseBlockPropertiesSchema, v.required(v.partial(v.object({
|
|
632
|
+
type: v.pipe(v.picklist(["Attachment"]), v.metadata({ description: "Block type (always \"Attachment\" for AttachmentBlock)" })),
|
|
633
|
+
attachment: BlockAttachmentSchema,
|
|
634
|
+
image: v.pipe(v.union([
|
|
635
|
+
BlockImageSchema,
|
|
636
|
+
v.null(),
|
|
637
|
+
v.undefined()
|
|
638
|
+
]), v.metadata({ description: "Preview image (for PDFs and other previewable files)" }))
|
|
639
|
+
})), ["type", "attachment"])]), v.metadata({ description: "An attachment block containing an uploaded file" }));
|
|
640
|
+
const EmbedBlockSchema = v.pipe(v.intersect([BaseBlockPropertiesSchema, v.required(v.partial(v.object({
|
|
641
|
+
type: v.pipe(v.picklist(["Embed"]), v.metadata({ description: "Block type (always \"Embed\" for EmbedBlock)" })),
|
|
642
|
+
embed: BlockEmbedSchema,
|
|
643
|
+
image: v.pipe(v.union([
|
|
644
|
+
BlockImageSchema,
|
|
645
|
+
v.null(),
|
|
646
|
+
v.undefined()
|
|
647
|
+
]), v.metadata({ description: "Thumbnail image (if available)" }))
|
|
648
|
+
})), ["type", "embed"])]), v.metadata({ description: "An embed block containing embedded media (video, audio, etc.)" }));
|
|
649
|
+
const UserListResponseSchema = v.pipe(v.intersect([UserListSchema, PaginatedResponseWithCountBaseSchema]), v.metadata({ description: "Paginated list of users with total count" }));
|
|
650
|
+
const CommentListResponseSchema = v.pipe(v.intersect([CommentListSchema, PaginatedResponseWithCountBaseSchema]), v.metadata({ description: "Paginated list of comments with total count" }));
|
|
651
|
+
const ChannelListResponseSchema = v.pipe(v.intersect([ChannelListSchema, PaginatedResponseWithCountBaseSchema]), v.metadata({ description: "Paginated list of channels with total count" }));
|
|
652
|
+
const FollowableListResponseSchema = v.pipe(v.intersect([FollowableListSchema, PaginatedResponseWithCountBaseSchema]), v.metadata({ description: "Paginated list of followable items (users, channels, and groups) with total count" }));
|
|
653
|
+
const BlockSchema = v.pipe(v.union([
|
|
654
|
+
TextBlockSchema,
|
|
655
|
+
ImageBlockSchema,
|
|
656
|
+
LinkBlockSchema,
|
|
657
|
+
AttachmentBlockSchema,
|
|
658
|
+
EmbedBlockSchema
|
|
659
|
+
]), v.metadata({ description: "A block is a piece of content on Are.na. Blocks come in different types,\neach with its own set of fields. Use the `type` field to determine which\nfields are available.\n" }));
|
|
660
|
+
const ConnectableListSchema = v.pipe(v.required(v.object({ data: v.pipe(v.array(v.union([
|
|
661
|
+
TextBlockSchema,
|
|
662
|
+
ImageBlockSchema,
|
|
663
|
+
LinkBlockSchema,
|
|
664
|
+
AttachmentBlockSchema,
|
|
665
|
+
EmbedBlockSchema,
|
|
666
|
+
ChannelSchema
|
|
667
|
+
])), v.metadata({ description: "Array of blocks and channels" })) }), ["data"]), v.metadata({ description: "Data payload containing mixed content that can be connected to channels (blocks and channels)" }));
|
|
668
|
+
const EverythingListSchema = v.pipe(v.required(v.object({ data: v.pipe(v.array(v.union([
|
|
669
|
+
TextBlockSchema,
|
|
670
|
+
ImageBlockSchema,
|
|
671
|
+
LinkBlockSchema,
|
|
672
|
+
AttachmentBlockSchema,
|
|
673
|
+
EmbedBlockSchema,
|
|
674
|
+
ChannelSchema,
|
|
675
|
+
UserSchema,
|
|
676
|
+
GroupSchema
|
|
677
|
+
])), v.metadata({ description: "Array of results (blocks, channels, users, or groups)" })) }), ["data"]), v.metadata({ description: "Data payload containing all content types" }));
|
|
678
|
+
const ConnectableListResponseSchema = v.pipe(v.intersect([ConnectableListSchema, PaginatedResponseBaseSchema]), v.metadata({ description: "Paginated list of connectable content (blocks and channels)" }));
|
|
679
|
+
const EverythingListResponseSchema = v.pipe(v.intersect([EverythingListSchema, PaginatedResponseWithCountBaseSchema]), v.metadata({ description: "Paginated list of all content types with total count" }));
|
|
680
|
+
|
|
681
|
+
//#endregion
|
|
682
|
+
//#region src/openapi/components/responses.ts
|
|
683
|
+
const UnauthorizedResponse = { "application/json": ErrorSchema };
|
|
684
|
+
const NotFoundResponse = { "application/json": ErrorSchema };
|
|
685
|
+
const ValidationErrorResponse = { "application/json": ErrorSchema };
|
|
686
|
+
const ForbiddenResponse = { "application/json": ErrorSchema };
|
|
687
|
+
const RateLimitResponse = { "application/json": RateLimitErrorSchema };
|
|
688
|
+
|
|
689
|
+
//#endregion
|
|
690
|
+
//#region src/openapi/components/parameters.ts
|
|
691
|
+
const PageParamSchema = v.pipe(v.pipe(v.number(), v.integer()), v.examples([1]));
|
|
692
|
+
const PerParamSchema = v.pipe(v.pipe(v.number(), v.integer()), v.examples([24]));
|
|
693
|
+
const IdParamSchema = v.pipe(v.number(), v.integer());
|
|
694
|
+
const SlugOrIdParamSchema = v.string();
|
|
695
|
+
const ConnectionSortParamSchema = ConnectionSortSchema;
|
|
696
|
+
const ContentSortParamSchema = ContentSortSchema;
|
|
697
|
+
const ChannelContentSortParamSchema = ChannelContentSortSchema;
|
|
698
|
+
const ContentTypeFilterParamSchema = ContentTypeFilterSchema;
|
|
699
|
+
|
|
700
|
+
//#endregion
|
|
701
|
+
//#region src/openapi/paths.ts
|
|
702
|
+
var paths_exports = /* @__PURE__ */ __exportAll({
|
|
703
|
+
Authentication: () => Authentication,
|
|
704
|
+
Blocks: () => Blocks,
|
|
705
|
+
Channels: () => Channels,
|
|
706
|
+
Groups: () => Groups,
|
|
707
|
+
Search: () => Search,
|
|
708
|
+
System: () => System,
|
|
709
|
+
Users: () => Users
|
|
710
|
+
});
|
|
711
|
+
const Authentication = { createOAuthToken: {
|
|
712
|
+
method: "post",
|
|
713
|
+
path: "/v3/oauth/token",
|
|
714
|
+
parameters: {},
|
|
715
|
+
body: {
|
|
716
|
+
required: true,
|
|
717
|
+
content: { "application/x-www-form-urlencoded": v.required(v.partial(v.object({
|
|
718
|
+
grant_type: v.pipe(v.picklist(["authorization_code", "client_credentials"]), v.metadata({ description: "The OAuth 2.0 grant type" })),
|
|
719
|
+
client_id: v.pipe(v.string(), v.metadata({ description: "Your application's client ID (required for all grant types)" })),
|
|
720
|
+
client_secret: v.pipe(v.string(), v.metadata({ description: "Your application's client secret (required for confidential clients, omit for PKCE)" })),
|
|
721
|
+
code: v.pipe(v.string(), v.metadata({ description: "Authorization code (required for authorization_code grant)" })),
|
|
722
|
+
redirect_uri: v.pipe(v.string(), v.metadata({ description: "Redirect URI used in authorization request (required for authorization_code grant)" })),
|
|
723
|
+
code_verifier: v.pipe(v.string(), v.metadata({ description: "PKCE code verifier (required when authorization used code_challenge).\nMust be 43-128 characters from [A-Z], [a-z], [0-9], \"-\", \".\", \"_\", \"~\".\n" }))
|
|
724
|
+
})), ["grant_type"]) }
|
|
725
|
+
},
|
|
726
|
+
responses: {
|
|
727
|
+
"200": { "application/json": v.pipe(v.required(v.object({
|
|
728
|
+
access_token: v.pipe(v.string(), v.metadata({ description: "The access token to use for API requests" })),
|
|
729
|
+
token_type: v.pipe(v.picklist(["Bearer"]), v.metadata({ description: "Token type (always \"Bearer\")" })),
|
|
730
|
+
scope: v.pipe(v.string(), v.metadata({ description: "Granted scopes (space-separated)" }), v.examples(["write"])),
|
|
731
|
+
created_at: v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Unix timestamp when the token was created" }))
|
|
732
|
+
}), [
|
|
733
|
+
"access_token",
|
|
734
|
+
"token_type",
|
|
735
|
+
"scope",
|
|
736
|
+
"created_at"
|
|
737
|
+
]), v.metadata({ description: "Access token granted" })) },
|
|
738
|
+
"400": { "application/json": v.pipe(v.object({
|
|
739
|
+
error: v.picklist([
|
|
740
|
+
"invalid_request",
|
|
741
|
+
"invalid_client",
|
|
742
|
+
"invalid_grant",
|
|
743
|
+
"unauthorized_client",
|
|
744
|
+
"unsupported_grant_type"
|
|
745
|
+
]),
|
|
746
|
+
error_description: v.string()
|
|
747
|
+
}), v.metadata({ description: "Invalid request" })) },
|
|
748
|
+
"401": { "application/json": v.pipe(v.object({
|
|
749
|
+
error: v.pipe(v.string(), v.examples(["invalid_client"])),
|
|
750
|
+
error_description: v.pipe(v.string(), v.examples(["Client authentication failed due to unknown client or invalid credentials."]))
|
|
751
|
+
}), v.metadata({ description: "Invalid client credentials" })) }
|
|
752
|
+
}
|
|
753
|
+
} };
|
|
754
|
+
const System = {
|
|
755
|
+
getOpenapiSpec: {
|
|
756
|
+
method: "get",
|
|
757
|
+
path: "/v3/openapi",
|
|
758
|
+
parameters: {},
|
|
759
|
+
responses: {
|
|
760
|
+
"200": { "application/yaml": v.pipe(v.string(), v.metadata({ description: "OpenAPI specification in YAML format" })) },
|
|
761
|
+
"404": NotFoundResponse
|
|
762
|
+
}
|
|
763
|
+
},
|
|
764
|
+
getOpenapiSpecJson: {
|
|
765
|
+
method: "get",
|
|
766
|
+
path: "/v3/openapi.json",
|
|
767
|
+
parameters: {},
|
|
768
|
+
responses: {
|
|
769
|
+
"200": { "application/json": v.pipe(v.record(v.string(), v.union([])), v.metadata({ description: "OpenAPI specification in JSON format" })) },
|
|
770
|
+
"404": NotFoundResponse
|
|
771
|
+
}
|
|
772
|
+
},
|
|
773
|
+
getPing: {
|
|
774
|
+
method: "get",
|
|
775
|
+
path: "/v3/ping",
|
|
776
|
+
parameters: {},
|
|
777
|
+
responses: {
|
|
778
|
+
"200": { "application/json": PingResponseSchema },
|
|
779
|
+
"429": RateLimitResponse
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
const Blocks = { id: {
|
|
784
|
+
$parameters: { id: IdParamSchema },
|
|
785
|
+
getBlock: {
|
|
786
|
+
method: "get",
|
|
787
|
+
path: "/v3/blocks/{id}",
|
|
788
|
+
parameters: { path: { id: IdParamSchema } },
|
|
789
|
+
responses: {
|
|
790
|
+
"200": { "application/json": BlockSchema },
|
|
791
|
+
"401": UnauthorizedResponse,
|
|
792
|
+
"403": ForbiddenResponse,
|
|
793
|
+
"404": NotFoundResponse,
|
|
794
|
+
"429": RateLimitResponse
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
getBlockConnections: {
|
|
798
|
+
method: "get",
|
|
799
|
+
path: "/v3/blocks/{id}/connections",
|
|
800
|
+
parameters: {
|
|
801
|
+
path: { id: IdParamSchema },
|
|
802
|
+
query: {
|
|
803
|
+
page: v.nullish(PageParamSchema),
|
|
804
|
+
per: v.nullish(PerParamSchema),
|
|
805
|
+
sort: v.nullish(ConnectionSortParamSchema),
|
|
806
|
+
filter: v.nullish(v.pipe(v.picklist([
|
|
807
|
+
"ALL",
|
|
808
|
+
"OWN",
|
|
809
|
+
"EXCLUDE_OWN"
|
|
810
|
+
]), v.metadata({ description: "Filter connections by ownership:\n- `ALL`: All accessible connections (default)\n- `OWN`: Only connections created by the current user\n- `EXCLUDE_OWN`: All connections except those created by the current user\n" }), v.examples(["ALL"])))
|
|
811
|
+
}
|
|
812
|
+
},
|
|
813
|
+
responses: {
|
|
814
|
+
"200": { "application/json": ChannelListResponseSchema },
|
|
815
|
+
"401": UnauthorizedResponse,
|
|
816
|
+
"403": ForbiddenResponse,
|
|
817
|
+
"404": NotFoundResponse,
|
|
818
|
+
"429": RateLimitResponse
|
|
819
|
+
}
|
|
820
|
+
},
|
|
821
|
+
getBlockComments: {
|
|
822
|
+
method: "get",
|
|
823
|
+
path: "/v3/blocks/{id}/comments",
|
|
824
|
+
parameters: {
|
|
825
|
+
path: { id: IdParamSchema },
|
|
826
|
+
query: {
|
|
827
|
+
page: v.nullish(PageParamSchema),
|
|
828
|
+
per: v.nullish(PerParamSchema),
|
|
829
|
+
sort: v.nullish(ConnectionSortParamSchema)
|
|
830
|
+
}
|
|
831
|
+
},
|
|
832
|
+
responses: {
|
|
833
|
+
"200": { "application/json": CommentListResponseSchema },
|
|
834
|
+
"401": UnauthorizedResponse,
|
|
835
|
+
"403": ForbiddenResponse,
|
|
836
|
+
"404": NotFoundResponse,
|
|
837
|
+
"429": RateLimitResponse
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
} };
|
|
841
|
+
const Channels = { id: {
|
|
842
|
+
$parameters: { id: SlugOrIdParamSchema },
|
|
843
|
+
getChannel: {
|
|
844
|
+
method: "get",
|
|
845
|
+
path: "/v3/channels/{id}",
|
|
846
|
+
parameters: { path: { id: SlugOrIdParamSchema } },
|
|
847
|
+
responses: {
|
|
848
|
+
"200": { "application/json": ChannelSchema },
|
|
849
|
+
"401": UnauthorizedResponse,
|
|
850
|
+
"403": ForbiddenResponse,
|
|
851
|
+
"404": NotFoundResponse,
|
|
852
|
+
"429": RateLimitResponse
|
|
853
|
+
}
|
|
854
|
+
},
|
|
855
|
+
getChannelContents: {
|
|
856
|
+
method: "get",
|
|
857
|
+
path: "/v3/channels/{id}/contents",
|
|
858
|
+
parameters: {
|
|
859
|
+
path: { id: SlugOrIdParamSchema },
|
|
860
|
+
query: {
|
|
861
|
+
page: v.nullish(PageParamSchema),
|
|
862
|
+
per: v.nullish(PerParamSchema),
|
|
863
|
+
sort: v.nullish(ChannelContentSortParamSchema),
|
|
864
|
+
user_id: v.nullish(v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Filter by user who added the content" }), v.examples([12345])))
|
|
865
|
+
}
|
|
866
|
+
},
|
|
867
|
+
responses: {
|
|
868
|
+
"200": { "application/json": ConnectableListResponseSchema },
|
|
869
|
+
"401": UnauthorizedResponse,
|
|
870
|
+
"403": ForbiddenResponse,
|
|
871
|
+
"404": NotFoundResponse,
|
|
872
|
+
"429": RateLimitResponse
|
|
873
|
+
}
|
|
874
|
+
},
|
|
875
|
+
getChannelConnections: {
|
|
876
|
+
method: "get",
|
|
877
|
+
path: "/v3/channels/{id}/connections",
|
|
878
|
+
parameters: {
|
|
879
|
+
path: { id: SlugOrIdParamSchema },
|
|
880
|
+
query: {
|
|
881
|
+
page: v.nullish(PageParamSchema),
|
|
882
|
+
per: v.nullish(PerParamSchema),
|
|
883
|
+
sort: v.nullish(ConnectionSortParamSchema)
|
|
884
|
+
}
|
|
885
|
+
},
|
|
886
|
+
responses: {
|
|
887
|
+
"200": { "application/json": ChannelListResponseSchema },
|
|
888
|
+
"401": UnauthorizedResponse,
|
|
889
|
+
"403": ForbiddenResponse,
|
|
890
|
+
"404": NotFoundResponse,
|
|
891
|
+
"429": RateLimitResponse
|
|
892
|
+
}
|
|
893
|
+
},
|
|
894
|
+
getChannelFollowers: {
|
|
895
|
+
method: "get",
|
|
896
|
+
path: "/v3/channels/{id}/followers",
|
|
897
|
+
parameters: {
|
|
898
|
+
path: { id: SlugOrIdParamSchema },
|
|
899
|
+
query: {
|
|
900
|
+
page: v.nullish(PageParamSchema),
|
|
901
|
+
per: v.nullish(PerParamSchema),
|
|
902
|
+
sort: v.nullish(ConnectionSortParamSchema)
|
|
903
|
+
}
|
|
904
|
+
},
|
|
905
|
+
responses: {
|
|
906
|
+
"200": { "application/json": UserListResponseSchema },
|
|
907
|
+
"401": UnauthorizedResponse,
|
|
908
|
+
"403": ForbiddenResponse,
|
|
909
|
+
"404": NotFoundResponse,
|
|
910
|
+
"429": RateLimitResponse
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
} };
|
|
914
|
+
const Users = {
|
|
915
|
+
getCurrentUser: {
|
|
916
|
+
method: "get",
|
|
917
|
+
path: "/v3/me",
|
|
918
|
+
parameters: {},
|
|
919
|
+
responses: {
|
|
920
|
+
"200": { "application/json": UserSchema },
|
|
921
|
+
"401": UnauthorizedResponse,
|
|
922
|
+
"429": RateLimitResponse
|
|
923
|
+
}
|
|
924
|
+
},
|
|
925
|
+
id: {
|
|
926
|
+
$parameters: { id: SlugOrIdParamSchema },
|
|
927
|
+
getUser: {
|
|
928
|
+
method: "get",
|
|
929
|
+
path: "/v3/users/{id}",
|
|
930
|
+
parameters: { path: { id: SlugOrIdParamSchema } },
|
|
931
|
+
responses: {
|
|
932
|
+
"200": { "application/json": UserSchema },
|
|
933
|
+
"401": UnauthorizedResponse,
|
|
934
|
+
"403": ForbiddenResponse,
|
|
935
|
+
"404": NotFoundResponse,
|
|
936
|
+
"429": RateLimitResponse
|
|
937
|
+
}
|
|
938
|
+
},
|
|
939
|
+
getUserContents: {
|
|
940
|
+
method: "get",
|
|
941
|
+
path: "/v3/users/{id}/contents",
|
|
942
|
+
parameters: {
|
|
943
|
+
path: { id: SlugOrIdParamSchema },
|
|
944
|
+
query: {
|
|
945
|
+
page: v.nullish(PageParamSchema),
|
|
946
|
+
per: v.nullish(PerParamSchema),
|
|
947
|
+
sort: v.nullish(ContentSortParamSchema),
|
|
948
|
+
type: v.nullish(ContentTypeFilterParamSchema)
|
|
949
|
+
}
|
|
950
|
+
},
|
|
951
|
+
responses: {
|
|
952
|
+
"200": { "application/json": ConnectableListResponseSchema },
|
|
953
|
+
"401": UnauthorizedResponse,
|
|
954
|
+
"403": ForbiddenResponse,
|
|
955
|
+
"404": NotFoundResponse,
|
|
956
|
+
"429": RateLimitResponse
|
|
957
|
+
}
|
|
958
|
+
},
|
|
959
|
+
getUserFollowers: {
|
|
960
|
+
method: "get",
|
|
961
|
+
path: "/v3/users/{id}/followers",
|
|
962
|
+
parameters: {
|
|
963
|
+
path: { id: SlugOrIdParamSchema },
|
|
964
|
+
query: {
|
|
965
|
+
page: v.nullish(PageParamSchema),
|
|
966
|
+
per: v.nullish(PerParamSchema),
|
|
967
|
+
sort: v.nullish(ConnectionSortParamSchema)
|
|
968
|
+
}
|
|
969
|
+
},
|
|
970
|
+
responses: {
|
|
971
|
+
"200": { "application/json": UserListResponseSchema },
|
|
972
|
+
"401": UnauthorizedResponse,
|
|
973
|
+
"403": ForbiddenResponse,
|
|
974
|
+
"404": NotFoundResponse,
|
|
975
|
+
"429": RateLimitResponse
|
|
976
|
+
}
|
|
977
|
+
},
|
|
978
|
+
getUserFollowing: {
|
|
979
|
+
method: "get",
|
|
980
|
+
path: "/v3/users/{id}/following",
|
|
981
|
+
parameters: {
|
|
982
|
+
path: { id: SlugOrIdParamSchema },
|
|
983
|
+
query: {
|
|
984
|
+
page: v.nullish(PageParamSchema),
|
|
985
|
+
per: v.nullish(PerParamSchema),
|
|
986
|
+
sort: v.nullish(ConnectionSortParamSchema),
|
|
987
|
+
type: v.nullish(v.pipe(v.picklist([
|
|
988
|
+
"User",
|
|
989
|
+
"Channel",
|
|
990
|
+
"Group"
|
|
991
|
+
]), v.metadata({ description: "Filter by followable type" }), v.examples(["Channel"])))
|
|
992
|
+
}
|
|
993
|
+
},
|
|
994
|
+
responses: {
|
|
995
|
+
"200": { "application/json": FollowableListResponseSchema },
|
|
996
|
+
"401": UnauthorizedResponse,
|
|
997
|
+
"403": ForbiddenResponse,
|
|
998
|
+
"404": NotFoundResponse,
|
|
999
|
+
"429": RateLimitResponse
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
const Groups = { id: {
|
|
1005
|
+
$parameters: { id: SlugOrIdParamSchema },
|
|
1006
|
+
getGroup: {
|
|
1007
|
+
method: "get",
|
|
1008
|
+
path: "/v3/groups/{id}",
|
|
1009
|
+
parameters: { path: { id: SlugOrIdParamSchema } },
|
|
1010
|
+
responses: {
|
|
1011
|
+
"200": { "application/json": GroupSchema },
|
|
1012
|
+
"401": UnauthorizedResponse,
|
|
1013
|
+
"403": ForbiddenResponse,
|
|
1014
|
+
"404": NotFoundResponse,
|
|
1015
|
+
"429": RateLimitResponse
|
|
1016
|
+
}
|
|
1017
|
+
},
|
|
1018
|
+
getGroupContents: {
|
|
1019
|
+
method: "get",
|
|
1020
|
+
path: "/v3/groups/{id}/contents",
|
|
1021
|
+
parameters: {
|
|
1022
|
+
path: { id: SlugOrIdParamSchema },
|
|
1023
|
+
query: {
|
|
1024
|
+
page: v.nullish(PageParamSchema),
|
|
1025
|
+
per: v.nullish(PerParamSchema),
|
|
1026
|
+
sort: v.nullish(ContentSortParamSchema),
|
|
1027
|
+
type: v.nullish(ContentTypeFilterParamSchema)
|
|
1028
|
+
}
|
|
1029
|
+
},
|
|
1030
|
+
responses: {
|
|
1031
|
+
"200": { "application/json": ConnectableListResponseSchema },
|
|
1032
|
+
"401": UnauthorizedResponse,
|
|
1033
|
+
"403": ForbiddenResponse,
|
|
1034
|
+
"404": NotFoundResponse,
|
|
1035
|
+
"429": RateLimitResponse
|
|
1036
|
+
}
|
|
1037
|
+
},
|
|
1038
|
+
getGroupFollowers: {
|
|
1039
|
+
method: "get",
|
|
1040
|
+
path: "/v3/groups/{id}/followers",
|
|
1041
|
+
parameters: {
|
|
1042
|
+
path: { id: SlugOrIdParamSchema },
|
|
1043
|
+
query: {
|
|
1044
|
+
page: v.nullish(PageParamSchema),
|
|
1045
|
+
per: v.nullish(PerParamSchema),
|
|
1046
|
+
sort: v.nullish(ConnectionSortParamSchema)
|
|
1047
|
+
}
|
|
1048
|
+
},
|
|
1049
|
+
responses: {
|
|
1050
|
+
"200": { "application/json": UserListResponseSchema },
|
|
1051
|
+
"401": UnauthorizedResponse,
|
|
1052
|
+
"403": ForbiddenResponse,
|
|
1053
|
+
"404": NotFoundResponse,
|
|
1054
|
+
"429": RateLimitResponse
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
} };
|
|
1058
|
+
const Search = { search: {
|
|
1059
|
+
method: "get",
|
|
1060
|
+
path: "/v3/search",
|
|
1061
|
+
parameters: { query: {
|
|
1062
|
+
q: v.nullish(v.pipe(v.string(), v.metadata({ description: "Search query. Use `*` to match everything (useful with filters).\n" }), v.examples(["design"]))),
|
|
1063
|
+
type: v.nullish(v.pipe(v.array(SearchTypeFilterSchema), v.metadata({ description: "Content types to search (comma-separated).\nBlock subtypes: Text, Image, Link, Attachment, Embed.\nOther: Channel, User, Group, Block (all block types).\n" }), v.examples([["Image", "Link"]]))),
|
|
1064
|
+
scope: v.nullish(v.pipe(v.string(), v.metadata({ description: "Where to search:\n- `all` - Everything (default)\n- `my` - Current user's content\n- `following` - Content from followed users/channels\n- `user:ID` - Specific user's content\n- `group:ID` - Specific group's content\n- `channel:ID` - Specific channel's content\n" }), v.examples(["channel:12345"]))),
|
|
1065
|
+
in: v.nullish(v.pipe(v.array(v.picklist([
|
|
1066
|
+
"name",
|
|
1067
|
+
"description",
|
|
1068
|
+
"content",
|
|
1069
|
+
"domain",
|
|
1070
|
+
"url"
|
|
1071
|
+
])), v.metadata({ description: "Fields to search within (comma-separated).\nOptions: name, description, content, domain, url.\nDefaults to all fields.\n" }), v.examples([["name", "description"]]))),
|
|
1072
|
+
ext: v.nullish(v.pipe(v.array(FileExtensionSchema), v.metadata({ description: "Filter by file extensions (comma-separated)" }), v.examples([["pdf", "jpg"]]))),
|
|
1073
|
+
sort: v.nullish(v.pipe(v.picklist([
|
|
1074
|
+
"score_desc",
|
|
1075
|
+
"created_at_desc",
|
|
1076
|
+
"created_at_asc",
|
|
1077
|
+
"updated_at_desc",
|
|
1078
|
+
"updated_at_asc",
|
|
1079
|
+
"name_asc",
|
|
1080
|
+
"name_desc",
|
|
1081
|
+
"connections_count_desc",
|
|
1082
|
+
"random"
|
|
1083
|
+
]), v.metadata({ description: "Sort order. Options:\n- `score_desc` (default) - Relevance\n- `created_at_desc`, `created_at_asc`\n- `updated_at_desc`, `updated_at_asc`\n- `name_asc`, `name_desc`\n- `connections_count_desc`\n- `random` (use with `seed` for reproducibility)\n" }), v.examples(["created_at_desc"]))),
|
|
1084
|
+
after: v.nullish(v.pipe(v.string(), v.metadata({ description: "Only return results updated after this date (ISO 8601)" }), v.examples(["2024-01-01T00:00:00Z"]))),
|
|
1085
|
+
seed: v.nullish(v.pipe(v.pipe(v.number(), v.integer()), v.metadata({ description: "Random seed for reproducible results (use with `sort=random`)" }), v.examples([1234567890]))),
|
|
1086
|
+
page: v.nullish(PageParamSchema),
|
|
1087
|
+
per: v.nullish(PerParamSchema)
|
|
1088
|
+
} },
|
|
1089
|
+
responses: {
|
|
1090
|
+
"200": { "application/json": EverythingListResponseSchema },
|
|
1091
|
+
"400": ValidationErrorResponse,
|
|
1092
|
+
"401": UnauthorizedResponse,
|
|
1093
|
+
"403": { "application/json": ErrorSchema },
|
|
1094
|
+
"429": RateLimitResponse
|
|
1095
|
+
}
|
|
1096
|
+
} };
|
|
1097
|
+
|
|
1098
|
+
//#endregion
|
|
1099
|
+
//#region src/util.ts
|
|
1100
|
+
function findKeyWithSingleOccurrence(obj, targetKey) {
|
|
1101
|
+
let foundKey = null;
|
|
1102
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
1103
|
+
if (typeof value !== "object" || value === null) continue;
|
|
1104
|
+
let count = 0;
|
|
1105
|
+
for (const childKey of Object.keys(value)) if (childKey === targetKey) {
|
|
1106
|
+
count++;
|
|
1107
|
+
if (count > 1) break;
|
|
1108
|
+
}
|
|
1109
|
+
if (count === 1) {
|
|
1110
|
+
if (foundKey !== null) return null;
|
|
1111
|
+
foundKey = key;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
return foundKey;
|
|
1115
|
+
}
|
|
1116
|
+
function removeCommonPrefix(obj, defaultKey) {
|
|
1117
|
+
const keys = Object.keys(obj);
|
|
1118
|
+
if (keys.length === 0) return {};
|
|
1119
|
+
const findCommonPrefix = (strings) => {
|
|
1120
|
+
if (strings.length === 0) return "";
|
|
1121
|
+
if (strings.length === 1) return strings[0];
|
|
1122
|
+
let prefix = "";
|
|
1123
|
+
const first = strings[0];
|
|
1124
|
+
for (let i = 0; i < first.length; i++) {
|
|
1125
|
+
const char = first[i];
|
|
1126
|
+
if (strings.every((s) => s[i] === char)) prefix += char;
|
|
1127
|
+
else break;
|
|
1128
|
+
}
|
|
1129
|
+
return prefix;
|
|
1130
|
+
};
|
|
1131
|
+
const commonPrefix = findCommonPrefix(keys);
|
|
1132
|
+
const result = {};
|
|
1133
|
+
for (const key of keys) {
|
|
1134
|
+
let newKey = key.slice(commonPrefix.length);
|
|
1135
|
+
if (newKey === "") newKey = defaultKey !== void 0 ? defaultKey : key;
|
|
1136
|
+
else newKey = newKey.charAt(0).toLowerCase() + newKey.slice(1);
|
|
1137
|
+
result[newKey] = obj[key];
|
|
1138
|
+
}
|
|
1139
|
+
return result;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
//#endregion
|
|
1143
|
+
//#region node_modules/.bun/form-urlencoded@6.1.6/node_modules/form-urlencoded/form-urlencoded.mjs
|
|
1144
|
+
var form_urlencoded_default = (data, opts = {}) => {
|
|
1145
|
+
const { sorted, ignorenull, ignoreEmptyArray, useDot, skipIndex, skipBracket, whitespace = "+" } = opts;
|
|
1146
|
+
const encode = (value) => String(value).replace(/[^ !'()~*]/gu, encodeURIComponent).replace(/ /g, whitespace).replace(/[!'()~*]/g, (ch) => `%${ch.charCodeAt().toString(16).slice(-2).toUpperCase()}`);
|
|
1147
|
+
const keys = (obj, keyarr = Object.keys(obj)) => sorted ? keyarr.sort() : keyarr;
|
|
1148
|
+
const filterjoin = (arr) => arr.filter((e) => e).join("&");
|
|
1149
|
+
const objnest = (name, obj) => filterjoin(keys(obj).map((key) => useDot ? nest(`${name}.${key}`, obj[key]) : nest(`${name}[${key}]`, obj[key])));
|
|
1150
|
+
const arrnest = (name, arr, brackets = skipBracket ? "" : "[]") => arr.length ? filterjoin(arr.map((elem, index) => skipIndex ? nest(name + brackets, elem) : nest(name + "[" + index + "]", elem))) : ignoreEmptyArray ? null : encode(name + brackets);
|
|
1151
|
+
const setnest = (name, set) => filterjoin(Array.from(set).map((elem) => nest(name, elem)));
|
|
1152
|
+
const nest = (name, value, type = typeof value, f = null) => {
|
|
1153
|
+
if (value === f) f = ignorenull ? f : encode(name) + "=" + f;
|
|
1154
|
+
else if (/string|number|boolean/.test(type)) f = encode(name) + "=" + encode(value);
|
|
1155
|
+
else if (Array.isArray(value)) f = arrnest(name, value);
|
|
1156
|
+
else if (value instanceof Set) f = setnest(name, value);
|
|
1157
|
+
else if (type === "object") f = objnest(name, value);
|
|
1158
|
+
return f;
|
|
1159
|
+
};
|
|
1160
|
+
return data && filterjoin(keys(data).map((key) => nest(key, data[key])));
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
//#endregion
|
|
1164
|
+
//#region src/api/index.ts
|
|
1165
|
+
const getMethodArgKind = (method) => "query" in method.parameters ? "query" : method.body != null && "content" in method.body ? "body" : null;
|
|
1166
|
+
const createApi = ({ accessToken, baseUrl, ...init } = { baseUrl: "https://api.are.na" }) => {
|
|
1167
|
+
const createFetch = (baseUrl, baseInit) => (url, init = {}, modifyUrl = (u) => u) => global.fetch(modifyUrl(new URL(url.toString(), baseUrl)), Object.assign({}, baseInit, init));
|
|
1168
|
+
if (accessToken) {
|
|
1169
|
+
init.headers ??= {};
|
|
1170
|
+
init.headers = new Headers(init.headers);
|
|
1171
|
+
init.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
1172
|
+
}
|
|
1173
|
+
const fetch = createFetch(new URL(baseUrl), init);
|
|
1174
|
+
return Object.fromEntries(Object.entries(paths_exports).map(([group, value]) => {
|
|
1175
|
+
const singleKey = findKeyWithSingleOccurrence(value, "$parameters");
|
|
1176
|
+
const makeMethod = (method) => {
|
|
1177
|
+
const argKind = getMethodArgKind(method);
|
|
1178
|
+
const localFetch = (init = {}, modifyUrl = (u) => u) => fetch(method.path, Object.assign({}, { method: method.method }, init ?? {}), modifyUrl ?? ((u) => u));
|
|
1179
|
+
return async (arg) => {
|
|
1180
|
+
const res = await localFetch(argKind === "body" && arg != null ? (() => {
|
|
1181
|
+
const content = method.body?.content;
|
|
1182
|
+
let contentType;
|
|
1183
|
+
let body;
|
|
1184
|
+
for (const media in content) {
|
|
1185
|
+
const schema = content[media];
|
|
1186
|
+
if (schema == null) continue;
|
|
1187
|
+
const maybeBody = v.safeParse(schema, arg);
|
|
1188
|
+
if (maybeBody.success) {
|
|
1189
|
+
contentType = media;
|
|
1190
|
+
body = maybeBody.output;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
if (!contentType) return {};
|
|
1194
|
+
return {
|
|
1195
|
+
headers: { "Content-Type": contentType },
|
|
1196
|
+
body: contentType.endsWith("x-www-form-urlencoded") ? form_urlencoded_default(body) : body
|
|
1197
|
+
};
|
|
1198
|
+
})() : void 0, argKind === "query" && arg != null ? (() => {
|
|
1199
|
+
const nextQuery = Object.fromEntries(Object.entries(arg).map(([key, value]) => [key, method.parameters["query"]?.[key] ? v.parse(method.parameters["query"]?.[key], value) : value]));
|
|
1200
|
+
return (u) => {
|
|
1201
|
+
for (const key in nextQuery) {
|
|
1202
|
+
const value = nextQuery[key];
|
|
1203
|
+
if (value == null) continue;
|
|
1204
|
+
u.searchParams.set(key, value);
|
|
1205
|
+
}
|
|
1206
|
+
return u;
|
|
1207
|
+
};
|
|
1208
|
+
})() : void 0);
|
|
1209
|
+
const statusCodeResponseData = method.responses[res.status] ?? {};
|
|
1210
|
+
const contentTypeResponseData = res.headers.has("content-type") ? statusCodeResponseData?.[res.headers.get("content-type")?.split(";").at(0)] : null;
|
|
1211
|
+
const result = await (Object.keys(statusCodeResponseData).includes("application/json") ? res.json() : res.text());
|
|
1212
|
+
return contentTypeResponseData != null ? v.parse(contentTypeResponseData, result) : result;
|
|
1213
|
+
};
|
|
1214
|
+
};
|
|
1215
|
+
const makeMethods = (value, parameters = {
|
|
1216
|
+
path: {},
|
|
1217
|
+
query: {}
|
|
1218
|
+
}) => {
|
|
1219
|
+
const replacePathPart = Object.fromEntries(Object.entries(parameters.path ?? {}).map(([key, value]) => [`{${key}}`, value]));
|
|
1220
|
+
return Object.fromEntries(Object.entries(Object.keys(value).length > 1 ? removeCommonPrefix(value, "self") : value).map(([key, value]) => [key, makeMethod(Object.assign({}, value, { path: value.path.split("/").map((p) => replacePathPart[p] ?? p).join("/") }))]));
|
|
1221
|
+
};
|
|
1222
|
+
return [group.toLowerCase(), singleKey ? Object.assign((param) => {
|
|
1223
|
+
const { $parameters, ...methods } = paths_exports[group][singleKey];
|
|
1224
|
+
return makeMethods(methods, { path: { [`${Object.keys($parameters).at(0)}`]: `${param}` } });
|
|
1225
|
+
}, makeMethods(Object.fromEntries(Object.entries(value).filter(([key]) => key !== singleKey)))) : (() => {
|
|
1226
|
+
const keys = Object.keys(value);
|
|
1227
|
+
return keys.length === 1 && keys.map((k) => k.toLowerCase()).includes(group.toLowerCase());
|
|
1228
|
+
})() ? makeMethod(value[group.toLowerCase()]) : makeMethods(value)];
|
|
1229
|
+
}));
|
|
1230
|
+
};
|
|
1231
|
+
|
|
1232
|
+
//#endregion
|
|
1233
|
+
export { createApi as createArena };
|