@apicity/x 0.1.0-alpha.0

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/dist/src/x.js ADDED
@@ -0,0 +1,164 @@
1
+ import { XError, } from "./types.js";
2
+ import { XMediaUploadInitializeRequestSchema, XMediaUploadAppendRequestSchema, XTweetCreateRequestSchema, } from "./zod.js";
3
+ import { attachExamples } from "./example.js";
4
+ export function x(opts) {
5
+ const baseURL = opts.baseURL ?? "https://api.x.com";
6
+ const doFetch = opts.fetch ?? fetch;
7
+ const timeout = opts.timeout ?? 30000;
8
+ function attachAbortHandler(signal, controller) {
9
+ if (signal.aborted) {
10
+ controller.abort();
11
+ return;
12
+ }
13
+ signal.addEventListener("abort", () => controller.abort(), { once: true });
14
+ }
15
+ // X v2 errors come in two shapes: `{ errors: [{ message, code, ... }] }`
16
+ // for batched/validation failures, or `{ title, detail, status, type }` for
17
+ // single problems. Surface whichever the server sent so the caller sees the
18
+ // actual reason rather than a generic "X API error: 400".
19
+ function formatErrorMessage(status, body) {
20
+ if (typeof body === "object" && body !== null) {
21
+ const b = body;
22
+ if (Array.isArray(b.errors) && b.errors.length > 0) {
23
+ const first = b.errors[0];
24
+ if (first?.message) {
25
+ return `X API error ${status}: ${first.message}`;
26
+ }
27
+ }
28
+ if (b.detail)
29
+ return `X API error ${status}: ${b.detail}`;
30
+ if (b.title)
31
+ return `X API error ${status}: ${b.title}`;
32
+ }
33
+ return `X API error: ${status}`;
34
+ }
35
+ async function makeJsonRequest(method, path, body, signal) {
36
+ const controller = new AbortController();
37
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
38
+ if (signal) {
39
+ attachAbortHandler(signal, controller);
40
+ }
41
+ try {
42
+ const headers = {
43
+ Authorization: `Bearer ${opts.accessToken}`,
44
+ };
45
+ const init = {
46
+ method,
47
+ headers,
48
+ signal: controller.signal,
49
+ };
50
+ if (body !== undefined) {
51
+ headers["Content-Type"] = "application/json";
52
+ init.body = JSON.stringify(body);
53
+ }
54
+ const res = await doFetch(`${baseURL}${path}`, init);
55
+ clearTimeout(timeoutId);
56
+ if (!res.ok) {
57
+ let resBody = null;
58
+ try {
59
+ resBody = await res.json();
60
+ }
61
+ catch {
62
+ // ignore parse errors
63
+ }
64
+ throw new XError(formatErrorMessage(res.status, resBody), res.status, resBody);
65
+ }
66
+ return (await res.json());
67
+ }
68
+ catch (error) {
69
+ clearTimeout(timeoutId);
70
+ if (error instanceof XError)
71
+ throw error;
72
+ throw new XError(`X request failed: ${error}`, 500);
73
+ }
74
+ }
75
+ async function makeFormRequest(path, form, signal) {
76
+ const controller = new AbortController();
77
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
78
+ if (signal) {
79
+ attachAbortHandler(signal, controller);
80
+ }
81
+ try {
82
+ const res = await doFetch(`${baseURL}${path}`, {
83
+ method: "POST",
84
+ headers: { Authorization: `Bearer ${opts.accessToken}` },
85
+ body: form,
86
+ signal: controller.signal,
87
+ });
88
+ clearTimeout(timeoutId);
89
+ if (!res.ok) {
90
+ let resBody = null;
91
+ try {
92
+ resBody = await res.json();
93
+ }
94
+ catch {
95
+ // ignore parse errors
96
+ }
97
+ throw new XError(formatErrorMessage(res.status, resBody), res.status, resBody);
98
+ }
99
+ return (await res.json());
100
+ }
101
+ catch (error) {
102
+ clearTimeout(timeoutId);
103
+ if (error instanceof XError)
104
+ throw error;
105
+ throw new XError(`X request failed: ${error}`, 500);
106
+ }
107
+ }
108
+ // sig-ok: numeric URL segments (`/2/`) become identifier-safe (`v2`)
109
+ // POST https://api.x.com/2/media/upload/initialize
110
+ // Docs: https://docs.x.com/x-api/media/media-upload-initialize
111
+ const mediaUploadInitialize = Object.assign(async (req, signal) => {
112
+ return makeJsonRequest("POST", "/2/media/upload/initialize", req, signal);
113
+ }, { schema: XMediaUploadInitializeRequestSchema });
114
+ // sig-ok: numeric URL segments (`/2/`) become identifier-safe (`v2`)
115
+ // POST https://api.x.com/2/media/upload/{id}/append
116
+ // Docs: https://docs.x.com/x-api/media/append-media-upload
117
+ const mediaUploadAppend = Object.assign(async (id, req, signal) => {
118
+ const form = new FormData();
119
+ form.append("media", req.media);
120
+ form.append("segment_index", String(req.segment_index));
121
+ return makeFormRequest(`/2/media/upload/${encodeURIComponent(id)}/append`, form, signal);
122
+ }, { schema: XMediaUploadAppendRequestSchema });
123
+ // sig-ok: numeric URL segments (`/2/`) become identifier-safe (`v2`)
124
+ // POST https://api.x.com/2/media/upload/{id}/finalize
125
+ // Docs: https://docs.x.com/x-api/media/finalize-media-upload
126
+ async function mediaUploadFinalize(id, signal) {
127
+ return makeJsonRequest("POST", `/2/media/upload/${encodeURIComponent(id)}/finalize`, undefined, signal);
128
+ }
129
+ // sig-ok: numeric URL segments (`/2/`) become identifier-safe (`v2`)
130
+ // GET https://api.x.com/2/media/upload{query}
131
+ // Docs: https://docs.x.com/x-api/media/get-media-upload-status
132
+ async function mediaUploadStatus(mediaId, signal) {
133
+ const query = `?media_id=${encodeURIComponent(mediaId)}&command=STATUS`;
134
+ return makeJsonRequest("GET", `/2/media/upload${query}`, undefined, signal);
135
+ }
136
+ // sig-ok: numeric URL segments (`/2/`) become identifier-safe (`v2`)
137
+ // POST https://api.x.com/2/tweets
138
+ // Docs: https://docs.x.com/x-api/posts/create-post
139
+ const tweetsCreate = Object.assign(async (req, signal) => {
140
+ return makeJsonRequest("POST", "/2/tweets", req, signal);
141
+ }, { schema: XTweetCreateRequestSchema });
142
+ return attachExamples({
143
+ post: {
144
+ v2: {
145
+ media: {
146
+ upload: {
147
+ initialize: mediaUploadInitialize,
148
+ append: mediaUploadAppend,
149
+ finalize: mediaUploadFinalize,
150
+ },
151
+ },
152
+ tweets: tweetsCreate,
153
+ },
154
+ },
155
+ get: {
156
+ v2: {
157
+ media: {
158
+ upload: mediaUploadStatus,
159
+ },
160
+ },
161
+ },
162
+ });
163
+ }
164
+ //# sourceMappingURL=x.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x.js","sourceRoot":"","sources":["../../src/x.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,327 @@
1
+ import { z } from "zod";
2
+ export declare const XOptionsSchema: z.ZodObject<{
3
+ accessToken: z.ZodString;
4
+ baseURL: z.ZodOptional<z.ZodString>;
5
+ timeout: z.ZodOptional<z.ZodNumber>;
6
+ fetch: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ accessToken: string;
9
+ baseURL?: string | undefined;
10
+ timeout?: number | undefined;
11
+ fetch?: typeof fetch | undefined;
12
+ }, {
13
+ accessToken: string;
14
+ baseURL?: string | undefined;
15
+ timeout?: number | undefined;
16
+ fetch?: typeof fetch | undefined;
17
+ }>;
18
+ export type XOptions = z.infer<typeof XOptionsSchema>;
19
+ export declare const XMediaUploadInitializeRequestSchema: z.ZodObject<{
20
+ media_type: z.ZodOptional<z.ZodEnum<["video/mp4", "video/webm", "video/mp2t", "video/quicktime", "text/srt", "text/vtt", "image/jpeg", "image/gif", "image/bmp", "image/png", "image/webp", "image/pjpeg", "image/tiff", "model/gltf-binary", "model/vnd.usdz+zip"]>>;
21
+ total_bytes: z.ZodOptional<z.ZodNumber>;
22
+ media_category: z.ZodOptional<z.ZodEnum<["amplify_video", "tweet_gif", "tweet_image", "tweet_video", "dm_gif", "dm_image", "dm_video", "subtitles"]>>;
23
+ shared: z.ZodOptional<z.ZodBoolean>;
24
+ additional_owners: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ media_type?: "video/mp4" | "video/webm" | "video/mp2t" | "video/quicktime" | "text/srt" | "text/vtt" | "image/jpeg" | "image/gif" | "image/bmp" | "image/png" | "image/webp" | "image/pjpeg" | "image/tiff" | "model/gltf-binary" | "model/vnd.usdz+zip" | undefined;
27
+ total_bytes?: number | undefined;
28
+ media_category?: "tweet_video" | "amplify_video" | "tweet_gif" | "tweet_image" | "dm_gif" | "dm_image" | "dm_video" | "subtitles" | undefined;
29
+ shared?: boolean | undefined;
30
+ additional_owners?: string[] | undefined;
31
+ }, {
32
+ media_type?: "video/mp4" | "video/webm" | "video/mp2t" | "video/quicktime" | "text/srt" | "text/vtt" | "image/jpeg" | "image/gif" | "image/bmp" | "image/png" | "image/webp" | "image/pjpeg" | "image/tiff" | "model/gltf-binary" | "model/vnd.usdz+zip" | undefined;
33
+ total_bytes?: number | undefined;
34
+ media_category?: "tweet_video" | "amplify_video" | "tweet_gif" | "tweet_image" | "dm_gif" | "dm_image" | "dm_video" | "subtitles" | undefined;
35
+ shared?: boolean | undefined;
36
+ additional_owners?: string[] | undefined;
37
+ }>;
38
+ export type XMediaUploadInitializeRequest = z.infer<typeof XMediaUploadInitializeRequestSchema>;
39
+ export declare const XMediaUploadAppendRequestSchema: z.ZodObject<{
40
+ media: z.ZodType<Blob, z.ZodTypeDef, Blob>;
41
+ segment_index: z.ZodNumber;
42
+ }, "strip", z.ZodTypeAny, {
43
+ media: Blob;
44
+ segment_index: number;
45
+ }, {
46
+ media: Blob;
47
+ segment_index: number;
48
+ }>;
49
+ export type XMediaUploadAppendRequest = z.infer<typeof XMediaUploadAppendRequestSchema>;
50
+ export declare const XTweetCreateRequestSchema: z.ZodObject<{
51
+ text: z.ZodOptional<z.ZodString>;
52
+ card_uri: z.ZodOptional<z.ZodString>;
53
+ community_id: z.ZodOptional<z.ZodString>;
54
+ direct_message_deep_link: z.ZodOptional<z.ZodString>;
55
+ edit_options: z.ZodOptional<z.ZodObject<{
56
+ previous_post_id: z.ZodString;
57
+ }, "strip", z.ZodTypeAny, {
58
+ previous_post_id: string;
59
+ }, {
60
+ previous_post_id: string;
61
+ }>>;
62
+ for_super_followers_only: z.ZodOptional<z.ZodBoolean>;
63
+ geo: z.ZodOptional<z.ZodObject<{
64
+ place_id: z.ZodString;
65
+ }, "strip", z.ZodTypeAny, {
66
+ place_id: string;
67
+ }, {
68
+ place_id: string;
69
+ }>>;
70
+ made_with_ai: z.ZodOptional<z.ZodBoolean>;
71
+ media: z.ZodOptional<z.ZodObject<{
72
+ media_ids: z.ZodArray<z.ZodString, "many">;
73
+ call_to_actions: z.ZodOptional<z.ZodEffects<z.ZodObject<{
74
+ app_install: z.ZodOptional<z.ZodObject<{
75
+ app_store_id: z.ZodOptional<z.ZodString>;
76
+ ipad_app_store_id: z.ZodOptional<z.ZodString>;
77
+ play_store_id: z.ZodOptional<z.ZodString>;
78
+ }, "strip", z.ZodTypeAny, {
79
+ app_store_id?: string | undefined;
80
+ ipad_app_store_id?: string | undefined;
81
+ play_store_id?: string | undefined;
82
+ }, {
83
+ app_store_id?: string | undefined;
84
+ ipad_app_store_id?: string | undefined;
85
+ play_store_id?: string | undefined;
86
+ }>>;
87
+ visit_site: z.ZodOptional<z.ZodObject<{
88
+ url: z.ZodString;
89
+ }, "strip", z.ZodTypeAny, {
90
+ url: string;
91
+ }, {
92
+ url: string;
93
+ }>>;
94
+ watch_now: z.ZodOptional<z.ZodObject<{
95
+ url: z.ZodString;
96
+ }, "strip", z.ZodTypeAny, {
97
+ url: string;
98
+ }, {
99
+ url: string;
100
+ }>>;
101
+ }, "strip", z.ZodTypeAny, {
102
+ app_install?: {
103
+ app_store_id?: string | undefined;
104
+ ipad_app_store_id?: string | undefined;
105
+ play_store_id?: string | undefined;
106
+ } | undefined;
107
+ visit_site?: {
108
+ url: string;
109
+ } | undefined;
110
+ watch_now?: {
111
+ url: string;
112
+ } | undefined;
113
+ }, {
114
+ app_install?: {
115
+ app_store_id?: string | undefined;
116
+ ipad_app_store_id?: string | undefined;
117
+ play_store_id?: string | undefined;
118
+ } | undefined;
119
+ visit_site?: {
120
+ url: string;
121
+ } | undefined;
122
+ watch_now?: {
123
+ url: string;
124
+ } | undefined;
125
+ }>, {
126
+ app_install?: {
127
+ app_store_id?: string | undefined;
128
+ ipad_app_store_id?: string | undefined;
129
+ play_store_id?: string | undefined;
130
+ } | undefined;
131
+ visit_site?: {
132
+ url: string;
133
+ } | undefined;
134
+ watch_now?: {
135
+ url: string;
136
+ } | undefined;
137
+ }, {
138
+ app_install?: {
139
+ app_store_id?: string | undefined;
140
+ ipad_app_store_id?: string | undefined;
141
+ play_store_id?: string | undefined;
142
+ } | undefined;
143
+ visit_site?: {
144
+ url: string;
145
+ } | undefined;
146
+ watch_now?: {
147
+ url: string;
148
+ } | undefined;
149
+ }>>;
150
+ description: z.ZodOptional<z.ZodString>;
151
+ embeddable: z.ZodOptional<z.ZodBoolean>;
152
+ preview_media_id: z.ZodOptional<z.ZodString>;
153
+ tagged_user_ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
154
+ title: z.ZodOptional<z.ZodString>;
155
+ }, "strip", z.ZodTypeAny, {
156
+ media_ids: string[];
157
+ call_to_actions?: {
158
+ app_install?: {
159
+ app_store_id?: string | undefined;
160
+ ipad_app_store_id?: string | undefined;
161
+ play_store_id?: string | undefined;
162
+ } | undefined;
163
+ visit_site?: {
164
+ url: string;
165
+ } | undefined;
166
+ watch_now?: {
167
+ url: string;
168
+ } | undefined;
169
+ } | undefined;
170
+ description?: string | undefined;
171
+ embeddable?: boolean | undefined;
172
+ preview_media_id?: string | undefined;
173
+ tagged_user_ids?: string[] | undefined;
174
+ title?: string | undefined;
175
+ }, {
176
+ media_ids: string[];
177
+ call_to_actions?: {
178
+ app_install?: {
179
+ app_store_id?: string | undefined;
180
+ ipad_app_store_id?: string | undefined;
181
+ play_store_id?: string | undefined;
182
+ } | undefined;
183
+ visit_site?: {
184
+ url: string;
185
+ } | undefined;
186
+ watch_now?: {
187
+ url: string;
188
+ } | undefined;
189
+ } | undefined;
190
+ description?: string | undefined;
191
+ embeddable?: boolean | undefined;
192
+ preview_media_id?: string | undefined;
193
+ tagged_user_ids?: string[] | undefined;
194
+ title?: string | undefined;
195
+ }>>;
196
+ nullcast: z.ZodOptional<z.ZodBoolean>;
197
+ paid_partnership: z.ZodOptional<z.ZodBoolean>;
198
+ poll: z.ZodOptional<z.ZodObject<{
199
+ options: z.ZodArray<z.ZodString, "many">;
200
+ duration_minutes: z.ZodNumber;
201
+ reply_settings: z.ZodOptional<z.ZodEnum<["following", "mentionedUsers", "subscribers", "verified"]>>;
202
+ }, "strip", z.ZodTypeAny, {
203
+ options: string[];
204
+ duration_minutes: number;
205
+ reply_settings?: "following" | "mentionedUsers" | "subscribers" | "verified" | undefined;
206
+ }, {
207
+ options: string[];
208
+ duration_minutes: number;
209
+ reply_settings?: "following" | "mentionedUsers" | "subscribers" | "verified" | undefined;
210
+ }>>;
211
+ quote_tweet_id: z.ZodOptional<z.ZodString>;
212
+ reply: z.ZodOptional<z.ZodObject<{
213
+ in_reply_to_tweet_id: z.ZodString;
214
+ auto_populate_reply_metadata: z.ZodOptional<z.ZodBoolean>;
215
+ exclude_reply_user_ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
216
+ }, "strip", z.ZodTypeAny, {
217
+ in_reply_to_tweet_id: string;
218
+ auto_populate_reply_metadata?: boolean | undefined;
219
+ exclude_reply_user_ids?: string[] | undefined;
220
+ }, {
221
+ in_reply_to_tweet_id: string;
222
+ auto_populate_reply_metadata?: boolean | undefined;
223
+ exclude_reply_user_ids?: string[] | undefined;
224
+ }>>;
225
+ reply_settings: z.ZodOptional<z.ZodEnum<["following", "mentionedUsers", "subscribers", "verified"]>>;
226
+ share_with_followers: z.ZodOptional<z.ZodBoolean>;
227
+ }, "strip", z.ZodTypeAny, {
228
+ media?: {
229
+ media_ids: string[];
230
+ call_to_actions?: {
231
+ app_install?: {
232
+ app_store_id?: string | undefined;
233
+ ipad_app_store_id?: string | undefined;
234
+ play_store_id?: string | undefined;
235
+ } | undefined;
236
+ visit_site?: {
237
+ url: string;
238
+ } | undefined;
239
+ watch_now?: {
240
+ url: string;
241
+ } | undefined;
242
+ } | undefined;
243
+ description?: string | undefined;
244
+ embeddable?: boolean | undefined;
245
+ preview_media_id?: string | undefined;
246
+ tagged_user_ids?: string[] | undefined;
247
+ title?: string | undefined;
248
+ } | undefined;
249
+ reply_settings?: "following" | "mentionedUsers" | "subscribers" | "verified" | undefined;
250
+ text?: string | undefined;
251
+ card_uri?: string | undefined;
252
+ community_id?: string | undefined;
253
+ direct_message_deep_link?: string | undefined;
254
+ edit_options?: {
255
+ previous_post_id: string;
256
+ } | undefined;
257
+ for_super_followers_only?: boolean | undefined;
258
+ geo?: {
259
+ place_id: string;
260
+ } | undefined;
261
+ made_with_ai?: boolean | undefined;
262
+ nullcast?: boolean | undefined;
263
+ paid_partnership?: boolean | undefined;
264
+ poll?: {
265
+ options: string[];
266
+ duration_minutes: number;
267
+ reply_settings?: "following" | "mentionedUsers" | "subscribers" | "verified" | undefined;
268
+ } | undefined;
269
+ quote_tweet_id?: string | undefined;
270
+ reply?: {
271
+ in_reply_to_tweet_id: string;
272
+ auto_populate_reply_metadata?: boolean | undefined;
273
+ exclude_reply_user_ids?: string[] | undefined;
274
+ } | undefined;
275
+ share_with_followers?: boolean | undefined;
276
+ }, {
277
+ media?: {
278
+ media_ids: string[];
279
+ call_to_actions?: {
280
+ app_install?: {
281
+ app_store_id?: string | undefined;
282
+ ipad_app_store_id?: string | undefined;
283
+ play_store_id?: string | undefined;
284
+ } | undefined;
285
+ visit_site?: {
286
+ url: string;
287
+ } | undefined;
288
+ watch_now?: {
289
+ url: string;
290
+ } | undefined;
291
+ } | undefined;
292
+ description?: string | undefined;
293
+ embeddable?: boolean | undefined;
294
+ preview_media_id?: string | undefined;
295
+ tagged_user_ids?: string[] | undefined;
296
+ title?: string | undefined;
297
+ } | undefined;
298
+ reply_settings?: "following" | "mentionedUsers" | "subscribers" | "verified" | undefined;
299
+ text?: string | undefined;
300
+ card_uri?: string | undefined;
301
+ community_id?: string | undefined;
302
+ direct_message_deep_link?: string | undefined;
303
+ edit_options?: {
304
+ previous_post_id: string;
305
+ } | undefined;
306
+ for_super_followers_only?: boolean | undefined;
307
+ geo?: {
308
+ place_id: string;
309
+ } | undefined;
310
+ made_with_ai?: boolean | undefined;
311
+ nullcast?: boolean | undefined;
312
+ paid_partnership?: boolean | undefined;
313
+ poll?: {
314
+ options: string[];
315
+ duration_minutes: number;
316
+ reply_settings?: "following" | "mentionedUsers" | "subscribers" | "verified" | undefined;
317
+ } | undefined;
318
+ quote_tweet_id?: string | undefined;
319
+ reply?: {
320
+ in_reply_to_tweet_id: string;
321
+ auto_populate_reply_metadata?: boolean | undefined;
322
+ exclude_reply_user_ids?: string[] | undefined;
323
+ } | undefined;
324
+ share_with_followers?: boolean | undefined;
325
+ }>;
326
+ export type XTweetCreateRequest = z.infer<typeof XTweetCreateRequestSchema>;
327
+ //# sourceMappingURL=zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;EAKzB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AA8CtD,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;EAM9C,CAAC;AAEH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CACjD,OAAO,mCAAmC,CAC3C,CAAC;AAUF,eAAO,MAAM,+BAA+B;;;;;;;;;EAG1C,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAC7C,OAAO,+BAA+B,CACvC,CAAC;AAqEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
@@ -0,0 +1,145 @@
1
+ import { z } from "zod";
2
+ // ---------------------------------------------------------------------------
3
+ // Provider options
4
+ // ---------------------------------------------------------------------------
5
+ // X requires a user-context OAuth 2.0 access token to post or upload media.
6
+ // App-only Bearer tokens are read-only and rejected by the upload + tweets
7
+ // endpoints. The caller obtains the access token via the PKCE flow externally
8
+ // and supplies it here; this package does not implement the OAuth dance.
9
+ export const XOptionsSchema = z.object({
10
+ accessToken: z.string().min(1),
11
+ baseURL: z.string().optional(),
12
+ timeout: z.number().optional(),
13
+ fetch: z.custom().optional(),
14
+ });
15
+ // ---------------------------------------------------------------------------
16
+ // Shared building blocks
17
+ // ---------------------------------------------------------------------------
18
+ // X v2 represents IDs as numeric strings (≤ 19 digits) to avoid 64-bit
19
+ // precision loss in JS — every id field on this surface uses this pattern.
20
+ const XIdStringSchema = z.string().regex(/^[0-9]{1,19}$/);
21
+ // ---------------------------------------------------------------------------
22
+ // POST /2/media/upload/initialize
23
+ // ---------------------------------------------------------------------------
24
+ const XMediaTypeSchema = z.enum([
25
+ "video/mp4",
26
+ "video/webm",
27
+ "video/mp2t",
28
+ "video/quicktime",
29
+ "text/srt",
30
+ "text/vtt",
31
+ "image/jpeg",
32
+ "image/gif",
33
+ "image/bmp",
34
+ "image/png",
35
+ "image/webp",
36
+ "image/pjpeg",
37
+ "image/tiff",
38
+ "model/gltf-binary",
39
+ "model/vnd.usdz+zip",
40
+ ]);
41
+ const XMediaCategorySchema = z.enum([
42
+ "amplify_video",
43
+ "tweet_gif",
44
+ "tweet_image",
45
+ "tweet_video",
46
+ "dm_gif",
47
+ "dm_image",
48
+ "dm_video",
49
+ "subtitles",
50
+ ]);
51
+ // Both `media_type` and `total_bytes` are documented as optional even though
52
+ // realistic uploads always supply them — match the docs and let the server
53
+ // reject incomplete requests rather than over-constraining at the SDK layer.
54
+ export const XMediaUploadInitializeRequestSchema = z.object({
55
+ media_type: XMediaTypeSchema.optional(),
56
+ total_bytes: z.number().int().min(0).max(17_179_869_184).optional(),
57
+ media_category: XMediaCategorySchema.optional(),
58
+ shared: z.boolean().optional(),
59
+ additional_owners: z.array(XIdStringSchema).optional(),
60
+ });
61
+ // ---------------------------------------------------------------------------
62
+ // POST /2/media/upload/{id}/append
63
+ // ---------------------------------------------------------------------------
64
+ // Body is multipart form-data — `media` is a binary chunk,
65
+ // `segment_index` is the 0-based sequential chunk number (max 999). The
66
+ // schema validates the *typed* request object the user passes; the factory
67
+ // constructs the FormData from it and lets fetch set the boundary header.
68
+ export const XMediaUploadAppendRequestSchema = z.object({
69
+ media: z.custom(),
70
+ segment_index: z.number().int().min(0).max(999),
71
+ });
72
+ // ---------------------------------------------------------------------------
73
+ // POST /2/tweets
74
+ // ---------------------------------------------------------------------------
75
+ // reply_settings allowed values per docs.x.com/x-api/posts/create-post —
76
+ // note `everyone` is NOT in this list (it is the implicit default when the
77
+ // field is omitted, not an enum value the API accepts).
78
+ const XReplySettingsSchema = z.enum([
79
+ "following",
80
+ "mentionedUsers",
81
+ "subscribers",
82
+ "verified",
83
+ ]);
84
+ const XTweetMediaCallToActionsSchema = z
85
+ .object({
86
+ app_install: z
87
+ .object({
88
+ app_store_id: z.string().optional(),
89
+ ipad_app_store_id: z.string().optional(),
90
+ play_store_id: z.string().optional(),
91
+ })
92
+ .optional(),
93
+ visit_site: z.object({ url: z.string() }).optional(),
94
+ watch_now: z.object({ url: z.string() }).optional(),
95
+ })
96
+ .refine((v) => [v.app_install, v.visit_site, v.watch_now].filter((x) => x !== undefined)
97
+ .length === 1, { message: "exactly one of app_install, visit_site, watch_now is allowed" });
98
+ const XTweetMediaSchema = z.object({
99
+ media_ids: z.array(XIdStringSchema).min(1).max(4),
100
+ call_to_actions: XTweetMediaCallToActionsSchema.optional(),
101
+ description: z.string().optional(),
102
+ embeddable: z.boolean().optional(),
103
+ preview_media_id: XIdStringSchema.optional(),
104
+ tagged_user_ids: z.array(XIdStringSchema).max(10).optional(),
105
+ title: z.string().optional(),
106
+ });
107
+ const XTweetReplySchema = z.object({
108
+ in_reply_to_tweet_id: XIdStringSchema,
109
+ auto_populate_reply_metadata: z.boolean().optional(),
110
+ exclude_reply_user_ids: z.array(XIdStringSchema).optional(),
111
+ });
112
+ const XTweetPollSchema = z.object({
113
+ options: z.array(z.string().min(1).max(25)).min(2).max(4),
114
+ duration_minutes: z.number().int().min(5).max(10080),
115
+ reply_settings: XReplySettingsSchema.optional(),
116
+ });
117
+ const XTweetGeoSchema = z.object({
118
+ place_id: z.string(),
119
+ });
120
+ const XTweetEditOptionsSchema = z.object({
121
+ previous_post_id: XIdStringSchema,
122
+ });
123
+ // Either `text` or `media.media_ids` is required by the server. Mutual
124
+ // exclusion between media / poll / quote_tweet_id / card_uri /
125
+ // direct_message_deep_link is also server-enforced — we don't pre-validate
126
+ // either, so error messages match what the API returns directly.
127
+ export const XTweetCreateRequestSchema = z.object({
128
+ text: z.string().optional(),
129
+ card_uri: z.string().optional(),
130
+ community_id: XIdStringSchema.optional(),
131
+ direct_message_deep_link: z.string().optional(),
132
+ edit_options: XTweetEditOptionsSchema.optional(),
133
+ for_super_followers_only: z.boolean().optional(),
134
+ geo: XTweetGeoSchema.optional(),
135
+ made_with_ai: z.boolean().optional(),
136
+ media: XTweetMediaSchema.optional(),
137
+ nullcast: z.boolean().optional(),
138
+ paid_partnership: z.boolean().optional(),
139
+ poll: XTweetPollSchema.optional(),
140
+ quote_tweet_id: XIdStringSchema.optional(),
141
+ reply: XTweetReplySchema.optional(),
142
+ reply_settings: XReplySettingsSchema.optional(),
143
+ share_with_followers: z.boolean().optional(),
144
+ });
145
+ //# sourceMappingURL=zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.js","sourceRoot":"","sources":["../../src/zod.ts"],"names":[],"mappings":"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"}