@publishq/sdk 0.0.1 → 0.0.2
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/README.md +3 -3
- package/dist/index.cjs +245 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +578 -13
- package/dist/index.d.ts +578 -13
- package/dist/index.js +234 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ for (const account of data?.accounts ?? []) {
|
|
|
40
40
|
## Authentication
|
|
41
41
|
|
|
42
42
|
Pass your API key (starts with `pq_live_`). Create one in the PublishQ web app
|
|
43
|
-
under **
|
|
43
|
+
under **API Keys** and select the scopes you need.
|
|
44
44
|
|
|
45
45
|
```ts
|
|
46
46
|
const publishq = new PublishQ({ apiKey: 'pq_live_...' });
|
|
@@ -95,7 +95,7 @@ await publishq.workspaces.get('<workspace-id>');
|
|
|
95
95
|
### Media
|
|
96
96
|
|
|
97
97
|
```ts
|
|
98
|
-
// Upload a file, then attach the returned media id to a post via `mediaIds
|
|
98
|
+
// Upload a file of up to 4 GB, then attach the returned media id to a post via `mediaIds`.
|
|
99
99
|
const { data: media } = await publishq.media.upload({ file });
|
|
100
100
|
await publishq.media.list({ mediaTypes: ['IMAGE'] });
|
|
101
101
|
await publishq.media.get('<media-id>');
|
|
@@ -114,7 +114,7 @@ returns `403`.
|
|
|
114
114
|
| `workspaces:read` | `workspaces.list`, `workspaces.get` |
|
|
115
115
|
| `workspaces:write` | `workspaces.create` |
|
|
116
116
|
| `media:read` | `media.list`, `media.get` |
|
|
117
|
-
| `media:write` | `media.upload`
|
|
117
|
+
| `media:write` | `media.upload`, `media.createUpload`, `media.completeUpload` |
|
|
118
118
|
|
|
119
119
|
## Configuration
|
|
120
120
|
|
package/dist/index.cjs
CHANGED
|
@@ -34,14 +34,21 @@ __export(index_exports, {
|
|
|
34
34
|
Media2: () => Media,
|
|
35
35
|
Posts: () => Posts,
|
|
36
36
|
PublishQ: () => PublishQ,
|
|
37
|
+
STORAGE_UPLOAD_THRESHOLD_BYTES: () => STORAGE_UPLOAD_THRESHOLD_BYTES,
|
|
37
38
|
Workspaces: () => Workspaces,
|
|
38
39
|
default: () => index_default,
|
|
40
|
+
withInferredContentType: () => withInferredContentType,
|
|
39
41
|
zAccount: () => zAccount,
|
|
40
42
|
zAccountsResponse: () => zAccountsResponse,
|
|
41
43
|
zApiError: () => zApiError,
|
|
42
44
|
zApiErrorCode: () => zApiErrorCode,
|
|
43
45
|
zApiKeyScope: () => zApiKeyScope,
|
|
44
46
|
zBlueskyPlatformSpecificSettings: () => zBlueskyPlatformSpecificSettings,
|
|
47
|
+
zCompleteMediaUploadPath: () => zCompleteMediaUploadPath,
|
|
48
|
+
zCompleteMediaUploadResponse: () => zCompleteMediaUploadResponse,
|
|
49
|
+
zCreateMediaUploadBody: () => zCreateMediaUploadBody,
|
|
50
|
+
zCreateMediaUploadRequest: () => zCreateMediaUploadRequest,
|
|
51
|
+
zCreateMediaUploadResponse: () => zCreateMediaUploadResponse,
|
|
45
52
|
zCreatePostAccount: () => zCreatePostAccount,
|
|
46
53
|
zCreatePostBody: () => zCreatePostBody,
|
|
47
54
|
zCreatePostRequest: () => zCreatePostRequest,
|
|
@@ -74,13 +81,17 @@ __export(index_exports, {
|
|
|
74
81
|
zMediaListResponse: () => zMediaListResponse,
|
|
75
82
|
zMediaSource: () => zMediaSource,
|
|
76
83
|
zMediaType: () => zMediaType,
|
|
84
|
+
zMediaUpload: () => zMediaUpload,
|
|
77
85
|
zPagination: () => zPagination,
|
|
78
86
|
zPlatformSpecificSettings: () => zPlatformSpecificSettings,
|
|
79
87
|
zPost: () => zPost,
|
|
80
88
|
zPostAccount: () => zPostAccount,
|
|
89
|
+
zPostAnalytics: () => zPostAnalytics,
|
|
81
90
|
zPostOverrides: () => zPostOverrides,
|
|
91
|
+
zPostSource: () => zPostSource,
|
|
82
92
|
zPostStatus: () => zPostStatus,
|
|
83
93
|
zPostsResponse: () => zPostsResponse,
|
|
94
|
+
zPublishFailure: () => zPublishFailure,
|
|
84
95
|
zRemovePostAccountPath: () => zRemovePostAccountPath,
|
|
85
96
|
zRemovePostAccountResponse: () => zRemovePostAccountResponse,
|
|
86
97
|
zSocialPlatform: () => zSocialPlatform,
|
|
@@ -920,7 +931,7 @@ var Posts = class {
|
|
|
920
931
|
/**
|
|
921
932
|
* List posts
|
|
922
933
|
*
|
|
923
|
-
* Returns a paginated list of posts.
|
|
934
|
+
* Returns a paginated list of the posts you created through PublishQ. Posts imported from a connected platform are excluded by default; pass includeImported=true to get both, or onlyImported=true for only the imported ones.
|
|
924
935
|
*/
|
|
925
936
|
static listPosts(options) {
|
|
926
937
|
return (options?.client ?? client).get({
|
|
@@ -1082,7 +1093,7 @@ var Media = class {
|
|
|
1082
1093
|
/**
|
|
1083
1094
|
* Upload media
|
|
1084
1095
|
*
|
|
1085
|
-
* Upload
|
|
1096
|
+
* Upload a file smaller than 100 MB in a single request. It is the simplest way to upload: one call returns a media ID you can attach to posts. For bigger files, use Create media upload.
|
|
1086
1097
|
*/
|
|
1087
1098
|
static uploadMedia(options) {
|
|
1088
1099
|
return (options.client ?? client).post({
|
|
@@ -1108,6 +1119,39 @@ var Media = class {
|
|
|
1108
1119
|
...options
|
|
1109
1120
|
});
|
|
1110
1121
|
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Create media upload
|
|
1124
|
+
*
|
|
1125
|
+
* Upload a file of up to 4 GB (500 MB on the Free plan) straight to storage:
|
|
1126
|
+
*
|
|
1127
|
+
* 1. Call this endpoint with `filename`, `contentType` and `fileSize`. You get back an `id` and an `uploadUrl`.
|
|
1128
|
+
* 2. `PUT` the file to `uploadUrl` with the same `Content-Type` header. Storage answers `200`, or `403` if the file is not exactly `fileSize` bytes.
|
|
1129
|
+
* 3. Optional: call Complete media upload to add the file to your media library now.
|
|
1130
|
+
* 4. Put the `id` in `mediaIds` when you create or update a post.
|
|
1131
|
+
*/
|
|
1132
|
+
static createMediaUpload(options) {
|
|
1133
|
+
return (options.client ?? client).post({
|
|
1134
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1135
|
+
url: "/media/uploads",
|
|
1136
|
+
...options,
|
|
1137
|
+
headers: {
|
|
1138
|
+
"Content-Type": "application/json",
|
|
1139
|
+
...options.headers
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Complete media upload
|
|
1145
|
+
*
|
|
1146
|
+
* Optional. Adds a file uploaded through Create media upload to your media library now and returns it. Without this call the file is added the first time you use its id in a post, and an upload nobody completes or uses within 1 day expires.
|
|
1147
|
+
*/
|
|
1148
|
+
static completeMediaUpload(options) {
|
|
1149
|
+
return (options.client ?? client).post({
|
|
1150
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1151
|
+
url: "/media/uploads/{id}/complete",
|
|
1152
|
+
...options
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1111
1155
|
};
|
|
1112
1156
|
|
|
1113
1157
|
// src/generated/zod.gen.ts
|
|
@@ -1127,6 +1171,7 @@ var zApiErrorCode = z.enum([
|
|
|
1127
1171
|
"post_not_editable",
|
|
1128
1172
|
"media_not_found",
|
|
1129
1173
|
"media_in_use",
|
|
1174
|
+
"media_upload_incomplete",
|
|
1130
1175
|
"storage_limit_exceeded",
|
|
1131
1176
|
"free_media_limit_exceeded",
|
|
1132
1177
|
"free_pending_media_limit_exceeded",
|
|
@@ -1137,6 +1182,9 @@ var zApiErrorCode = z.enum([
|
|
|
1137
1182
|
"invalid_file_extension",
|
|
1138
1183
|
"social_accounts_not_found",
|
|
1139
1184
|
"social_accounts_expired",
|
|
1185
|
+
"social_account_limit_exceeded",
|
|
1186
|
+
"platform_temporarily_unavailable",
|
|
1187
|
+
"platform_permission_missing",
|
|
1140
1188
|
"platform_validation_failed",
|
|
1141
1189
|
"posting_limits_exceeded",
|
|
1142
1190
|
"scheduled_at_required",
|
|
@@ -1146,10 +1194,12 @@ var zApiErrorCode = z.enum([
|
|
|
1146
1194
|
"workspace_not_found",
|
|
1147
1195
|
"workspace_forbidden",
|
|
1148
1196
|
"workspace_owner_required",
|
|
1197
|
+
"workspace_limit_exceeded",
|
|
1149
1198
|
"workspace_account_not_found",
|
|
1150
1199
|
"workspace_account_conflict",
|
|
1151
1200
|
"workspace_member_not_found",
|
|
1152
1201
|
"workspace_member_conflict",
|
|
1202
|
+
"team_member_limit_exceeded",
|
|
1153
1203
|
"workspace_invitation_invalid",
|
|
1154
1204
|
"workspace_invitation_expired"
|
|
1155
1205
|
]);
|
|
@@ -1358,6 +1408,56 @@ var zTwitterPlatformSpecificSettings = z.object({
|
|
|
1358
1408
|
}).register(z.globalRegistry, {
|
|
1359
1409
|
description: "X (Twitter) specific post settings. All fields are optional."
|
|
1360
1410
|
});
|
|
1411
|
+
var zPostSource = z.enum(["PUBLISHQ", "IMPORTED"]).register(z.globalRegistry, {
|
|
1412
|
+
description: "Where the post came from. PUBLISHQ: created in PublishQ. IMPORTED: published directly on the platform and discovered during an analytics sync, so the post history stays complete."
|
|
1413
|
+
});
|
|
1414
|
+
var zPostAnalytics = z.object({
|
|
1415
|
+
views: z.int().check(z.gte(0)).register(z.globalRegistry, {
|
|
1416
|
+
description: "Views the platform reports for this post."
|
|
1417
|
+
}),
|
|
1418
|
+
likes: z.int().check(z.gte(0)).register(z.globalRegistry, {
|
|
1419
|
+
description: "Likes the platform reports for this post."
|
|
1420
|
+
}),
|
|
1421
|
+
comments: z.int().check(z.gte(0)).register(z.globalRegistry, {
|
|
1422
|
+
description: "Comments the platform reports for this post."
|
|
1423
|
+
}),
|
|
1424
|
+
shares: z.int().check(z.gte(0)).register(z.globalRegistry, {
|
|
1425
|
+
description: "Shares the platform reports for this post. 0 on platforms that do not disclose it (including YouTube)."
|
|
1426
|
+
}),
|
|
1427
|
+
extraMetrics: z.record(z.string(), z.int().check(z.gte(0))).register(z.globalRegistry, {
|
|
1428
|
+
description: "Metrics only this platform reports, keyed by metric name \u2014 Bluesky bookmarks, for example. Every metric the platform reports is always present, 0 included, so no key has to be guessed. Empty on platforms that expose nothing beyond the fields above, and a metric that already has its own field is never repeated here."
|
|
1429
|
+
}),
|
|
1430
|
+
syncedAt: z.iso.datetime().register(z.globalRegistry, {
|
|
1431
|
+
description: "When these numbers were last recorded. Metrics are refreshed in the background roughly once a day, and only stored when they change."
|
|
1432
|
+
})
|
|
1433
|
+
});
|
|
1434
|
+
var zPublishFailure = z.object({
|
|
1435
|
+
kind: z.enum([
|
|
1436
|
+
"RECONNECT",
|
|
1437
|
+
"MEDIA",
|
|
1438
|
+
"ACCOUNT_STATE",
|
|
1439
|
+
"TRANSIENT",
|
|
1440
|
+
"MAYBE_PUBLISHED",
|
|
1441
|
+
"UNKNOWN"
|
|
1442
|
+
]).register(z.globalRegistry, {
|
|
1443
|
+
description: "What kind of action this failure needs. `RECONNECT`: the account has to be reconnected. `MEDIA`: the platform refused the attached file. `ACCOUNT_STATE`: the platform is blocking this account, so the fix is on the platform. `TRANSIENT`: the platform was unavailable and the same request can succeed unchanged. `MAYBE_PUBLISHED`: the platform reported an error for a post that may have gone out anyway. `UNKNOWN`: unrecognised, so read `errorMessage`."
|
|
1444
|
+
}),
|
|
1445
|
+
title: z.string().register(z.globalRegistry, {
|
|
1446
|
+
description: "Short label for this failure."
|
|
1447
|
+
}),
|
|
1448
|
+
whatHappened: z.string().register(z.globalRegistry, {
|
|
1449
|
+
description: "One sentence about what the platform did."
|
|
1450
|
+
}),
|
|
1451
|
+
whatToDo: z.string().register(z.globalRegistry, {
|
|
1452
|
+
description: "One sentence naming the next action."
|
|
1453
|
+
}),
|
|
1454
|
+
canRetry: z.boolean().register(z.globalRegistry, {
|
|
1455
|
+
description: "Whether retrying can succeed. False when the platform is blocking the account, since the same request will be refused the same way."
|
|
1456
|
+
}),
|
|
1457
|
+
checkPlatformFirst: z.boolean().register(z.globalRegistry, {
|
|
1458
|
+
description: "Whether the post may already be live. A publish is not idempotent and no platform accepts a deduplication key, so when this is true a retry can create a second copy: check the profile before retrying."
|
|
1459
|
+
})
|
|
1460
|
+
});
|
|
1361
1461
|
var zSocialPlatform = z.enum([
|
|
1362
1462
|
"TWITTER",
|
|
1363
1463
|
"INSTAGRAM",
|
|
@@ -1382,8 +1482,8 @@ var zPostOverrides = z.object({
|
|
|
1382
1482
|
thumbnailTimestamp: z.optional(z.int().check(z.gte(0)).register(z.globalRegistry, {
|
|
1383
1483
|
description: "Video thumbnail timestamp in milliseconds. Applies to Instagram and TikTok."
|
|
1384
1484
|
})),
|
|
1385
|
-
mediaIds: z.optional(z.array(z.uuid()).register(z.globalRegistry, {
|
|
1386
|
-
description: "Replacement media for this account. Completely replaces the post-level media."
|
|
1485
|
+
mediaIds: z.optional(z.array(z.uuid()).check(z.maxLength(35)).register(z.globalRegistry, {
|
|
1486
|
+
description: "Replacement media for this account. Completely replaces the post-level media. Up to 35."
|
|
1387
1487
|
}))
|
|
1388
1488
|
});
|
|
1389
1489
|
var zPlatformSpecificSettings = z.union([
|
|
@@ -1575,6 +1675,12 @@ var zPostAccount = z.object({
|
|
|
1575
1675
|
errorMessage: z.optional(z.string().register(z.globalRegistry, {
|
|
1576
1676
|
description: "Error message from the platform if publishing failed for this account."
|
|
1577
1677
|
})),
|
|
1678
|
+
failure: z.optional(z.intersection(zPublishFailure, z.unknown().register(z.globalRegistry, {
|
|
1679
|
+
description: "The same failure read as an action: what happened and the one thing to do about it. Present whenever status is FAILED, including when the platform gave no reason. The wording is what the app and the failure email show, so a client does not have to interpret `errorMessage` itself."
|
|
1680
|
+
}))),
|
|
1681
|
+
analytics: z.optional(z.intersection(zPostAnalytics, z.unknown().register(z.globalRegistry, {
|
|
1682
|
+
description: "Latest metrics recorded for this delivery. Present only for published posts on platforms with analytics support, once a background sync has run."
|
|
1683
|
+
}))),
|
|
1578
1684
|
postOverrides: z.optional(zPostOverrides),
|
|
1579
1685
|
platformSpecificSettings: z.optional(zPlatformSpecificSettings)
|
|
1580
1686
|
});
|
|
@@ -1586,6 +1692,7 @@ var zPost = z.object({
|
|
|
1586
1692
|
description: "The shared text content of the post."
|
|
1587
1693
|
}),
|
|
1588
1694
|
status: zPostStatus,
|
|
1695
|
+
source: zPostSource,
|
|
1589
1696
|
errorMessage: z.optional(z.string().register(z.globalRegistry, {
|
|
1590
1697
|
description: "Human-readable error summary when one or more accounts failed."
|
|
1591
1698
|
})),
|
|
@@ -1627,8 +1734,8 @@ var zCreatePostRequest = z.object({
|
|
|
1627
1734
|
content: z._default(z.optional(z.string().register(z.globalRegistry, {
|
|
1628
1735
|
description: "The text content of the post, shared across all accounts unless overridden. Optional when media is attached (platform-dependent)."
|
|
1629
1736
|
})), ""),
|
|
1630
|
-
mediaIds: z.optional(z.array(z.uuid()).register(z.globalRegistry, {
|
|
1631
|
-
description: "Media to attach to the post. Shared across all accounts unless an account provides its own mediaIds in postOverrides."
|
|
1737
|
+
mediaIds: z.optional(z.array(z.uuid()).check(z.maxLength(35)).register(z.globalRegistry, {
|
|
1738
|
+
description: "Media to attach to the post, up to 35. Shared across all accounts unless an account provides its own mediaIds in postOverrides. Accepts IDs from Upload media and from Create media upload."
|
|
1632
1739
|
})),
|
|
1633
1740
|
thumbnailTimestamp: z.optional(z.int().check(z.gte(0)).register(z.globalRegistry, {
|
|
1634
1741
|
description: "Default video thumbnail timestamp in milliseconds for Instagram and TikTok. Can be overridden per account."
|
|
@@ -1637,7 +1744,7 @@ var zCreatePostRequest = z.object({
|
|
|
1637
1744
|
description: "Accounts to post to. Each entry can optionally include content overrides and platform-specific settings."
|
|
1638
1745
|
}),
|
|
1639
1746
|
scheduledAt: z.optional(z.iso.datetime().register(z.globalRegistry, {
|
|
1640
|
-
description: "Schedule the post for a future date. If omitted and publishNow is false or absent, the post is saved as a draft."
|
|
1747
|
+
description: "Schedule the post for a future date. If omitted and publishNow is false or absent, the post is saved as a draft. Accepts UTC (2026-04-01T12:00:00Z) or an explicit UTC offset (2026-04-01T14:00:00+02:00); a time without zone information is rejected."
|
|
1641
1748
|
})),
|
|
1642
1749
|
publishNow: z.optional(z.boolean().register(z.globalRegistry, {
|
|
1643
1750
|
description: "Publish immediately. Cannot be combined with scheduledAt."
|
|
@@ -1650,10 +1757,10 @@ var zUpdatePostRequest = z.object({
|
|
|
1650
1757
|
description: "New shared text content for the post."
|
|
1651
1758
|
})),
|
|
1652
1759
|
scheduledAt: z.optional(z.iso.datetime().register(z.globalRegistry, {
|
|
1653
|
-
description: "New scheduled date for the post. Must be at least 1 minute in the future."
|
|
1760
|
+
description: "New scheduled date for the post. Must be at least 1 minute in the future. Accepts UTC (2026-04-15T14:00:00Z) or an explicit UTC offset (2026-04-15T16:00:00+02:00); a time without zone information is rejected."
|
|
1654
1761
|
})),
|
|
1655
|
-
mediaIds: z.optional(z.array(z.uuid()).register(z.globalRegistry, {
|
|
1656
|
-
description: "Full replacement for the post media. If omitted, the existing media stays unchanged. If provided, it replaces the current media across all accounts in the post. Send an empty array to remove all media from the post."
|
|
1762
|
+
mediaIds: z.optional(z.array(z.uuid()).check(z.maxLength(35)).register(z.globalRegistry, {
|
|
1763
|
+
description: "Full replacement for the post media, up to 35. If omitted, the existing media stays unchanged. If provided, it replaces the current media across all accounts in the post. Send an empty array to remove all media from the post."
|
|
1657
1764
|
})),
|
|
1658
1765
|
thumbnailTimestamp: z.optional(z.int().check(z.gte(0)).register(z.globalRegistry, {
|
|
1659
1766
|
description: "New video thumbnail timestamp in milliseconds for Instagram and TikTok media. Does not change which media files are attached. Combine with mediaIds if you want to replace media and set the new thumbnail timestamp in the same request."
|
|
@@ -1762,6 +1869,28 @@ var zMediaListResponse = z.object({
|
|
|
1762
1869
|
var zUploadMediaRequest = z.object({
|
|
1763
1870
|
file: z.string()
|
|
1764
1871
|
});
|
|
1872
|
+
var zCreateMediaUploadRequest = z.object({
|
|
1873
|
+
filename: z.string().check(z.minLength(1), z.maxLength(1024)).register(z.globalRegistry, {
|
|
1874
|
+
description: "Name of the file you are uploading."
|
|
1875
|
+
}),
|
|
1876
|
+
contentType: z.string().check(z.minLength(1)).register(z.globalRegistry, {
|
|
1877
|
+
description: "Content type of the file. One of: image/jpeg, image/png, image/gif, image/webp, video/mp4, video/webm, video/quicktime, video/x-msvideo."
|
|
1878
|
+
}),
|
|
1879
|
+
fileSize: z.int().check(z.gt(0)).register(z.globalRegistry, {
|
|
1880
|
+
description: "Exact size of the file in bytes. Your plan's file size limit and your storage are checked before you upload, and storage refuses a file of any other size. Each platform's own size limits are checked when you attach the media to a post."
|
|
1881
|
+
})
|
|
1882
|
+
});
|
|
1883
|
+
var zMediaUpload = z.object({
|
|
1884
|
+
id: z.uuid().register(z.globalRegistry, {
|
|
1885
|
+
description: "Media ID of the file. Attach it to posts through mediaIds once the file is uploaded."
|
|
1886
|
+
}),
|
|
1887
|
+
uploadUrl: z.url().register(z.globalRegistry, {
|
|
1888
|
+
description: "Signed storage URL. PUT the file to it with the same Content-Type. It goes to storage, not to the PublishQ API, so send no Authorization header."
|
|
1889
|
+
}),
|
|
1890
|
+
expiresAt: z.iso.datetime().register(z.globalRegistry, {
|
|
1891
|
+
description: "When uploadUrl stops accepting the file, 1 hour after it is created."
|
|
1892
|
+
})
|
|
1893
|
+
});
|
|
1765
1894
|
var zTikTokCreatorInfoResponse = z.object({
|
|
1766
1895
|
privacyLevelOptions: z.array(z.string()).register(z.globalRegistry, {
|
|
1767
1896
|
description: "Privacy levels available for this account. Use one of these values as `privacyLevel` in `platformSpecificSettings`."
|
|
@@ -1794,7 +1923,13 @@ var zListPostsQuery = z.object({
|
|
|
1794
1923
|
})), 1),
|
|
1795
1924
|
limit: z._default(z.optional(z.int().check(z.gt(0), z.lte(100)).register(z.globalRegistry, {
|
|
1796
1925
|
description: "Page size. Max 100."
|
|
1797
|
-
})), 20)
|
|
1926
|
+
})), 20),
|
|
1927
|
+
includeImported: z._default(z.optional(z.boolean().register(z.globalRegistry, {
|
|
1928
|
+
description: "Also return posts imported from a connected platform (posts with source IMPORTED). Defaults to false: only posts created through PublishQ are returned."
|
|
1929
|
+
})), false),
|
|
1930
|
+
onlyImported: z._default(z.optional(z.boolean().register(z.globalRegistry, {
|
|
1931
|
+
description: "Return ONLY posts imported from a connected platform. Cannot be combined with includeImported."
|
|
1932
|
+
})), false)
|
|
1798
1933
|
});
|
|
1799
1934
|
var zListPostsResponse = zPostsResponse;
|
|
1800
1935
|
var zCreatePostBody = zCreatePostRequest;
|
|
@@ -1865,6 +2000,12 @@ var zGetMediaPath = z.object({
|
|
|
1865
2000
|
id: z.uuid()
|
|
1866
2001
|
});
|
|
1867
2002
|
var zGetMediaResponse = zMedia;
|
|
2003
|
+
var zCreateMediaUploadBody = zCreateMediaUploadRequest;
|
|
2004
|
+
var zCreateMediaUploadResponse = zMediaUpload;
|
|
2005
|
+
var zCompleteMediaUploadPath = z.object({
|
|
2006
|
+
id: z.uuid()
|
|
2007
|
+
});
|
|
2008
|
+
var zCompleteMediaUploadResponse = zMedia;
|
|
1868
2009
|
|
|
1869
2010
|
// src/index.ts
|
|
1870
2011
|
var rawErrorBodies = /* @__PURE__ */ new WeakMap();
|
|
@@ -1966,12 +2107,92 @@ function createWorkspacesNamespace(client2) {
|
|
|
1966
2107
|
get: (id) => preserveApiError(Workspaces.getWorkspace({ client: client2, path: { id } }))
|
|
1967
2108
|
};
|
|
1968
2109
|
}
|
|
2110
|
+
var UPLOAD_MIME_TYPE_BY_EXTENSION = {
|
|
2111
|
+
jpg: "image/jpeg",
|
|
2112
|
+
jpeg: "image/jpeg",
|
|
2113
|
+
png: "image/png",
|
|
2114
|
+
gif: "image/gif",
|
|
2115
|
+
webp: "image/webp",
|
|
2116
|
+
mp4: "video/mp4",
|
|
2117
|
+
webm: "video/webm",
|
|
2118
|
+
mov: "video/quicktime",
|
|
2119
|
+
avi: "video/x-msvideo"
|
|
2120
|
+
};
|
|
2121
|
+
function isUninformativeType(type) {
|
|
2122
|
+
return type === "" || type === "application/octet-stream";
|
|
2123
|
+
}
|
|
2124
|
+
function withInferredContentType(file) {
|
|
2125
|
+
const name = "name" in file ? file.name : void 0;
|
|
2126
|
+
if (!name || !isUninformativeType(file.type)) return file;
|
|
2127
|
+
const extension = name.split(".").pop()?.toLowerCase();
|
|
2128
|
+
const type = extension ? UPLOAD_MIME_TYPE_BY_EXTENSION[extension] : void 0;
|
|
2129
|
+
if (!type) return file;
|
|
2130
|
+
return new File([file], name, { type });
|
|
2131
|
+
}
|
|
2132
|
+
var STORAGE_UPLOAD_THRESHOLD_BYTES = 90 * 1024 * 1024;
|
|
2133
|
+
async function uploadThroughStorage(client2, file) {
|
|
2134
|
+
const created = await preserveApiError(
|
|
2135
|
+
Media.createMediaUpload({
|
|
2136
|
+
client: client2,
|
|
2137
|
+
body: {
|
|
2138
|
+
filename: "name" in file && file.name ? file.name : "upload",
|
|
2139
|
+
contentType: file.type,
|
|
2140
|
+
fileSize: file.size
|
|
2141
|
+
}
|
|
2142
|
+
})
|
|
2143
|
+
);
|
|
2144
|
+
if (!created.data) return created;
|
|
2145
|
+
const response = await fetch(created.data.uploadUrl, {
|
|
2146
|
+
method: "PUT",
|
|
2147
|
+
headers: { "Content-Type": file.type },
|
|
2148
|
+
body: file
|
|
2149
|
+
});
|
|
2150
|
+
if (!response.ok) {
|
|
2151
|
+
return {
|
|
2152
|
+
data: void 0,
|
|
2153
|
+
error: {
|
|
2154
|
+
error: {
|
|
2155
|
+
status: response.status,
|
|
2156
|
+
message: "Storage refused the file upload",
|
|
2157
|
+
mediaId: created.data.id,
|
|
2158
|
+
storageResponse: await response.text()
|
|
2159
|
+
}
|
|
2160
|
+
},
|
|
2161
|
+
request: new Request(created.data.uploadUrl, { method: "PUT" }),
|
|
2162
|
+
response
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
return preserveApiError(
|
|
2166
|
+
Media.completeMediaUpload({ client: client2, path: { id: created.data.id } })
|
|
2167
|
+
);
|
|
2168
|
+
}
|
|
1969
2169
|
function createMediaNamespace(client2) {
|
|
1970
2170
|
return {
|
|
1971
2171
|
/** List your uploaded and generated media files. Filter by id, type, source. Wraps `Media.listMedia`. */
|
|
1972
2172
|
list: (query) => preserveApiError(Media.listMedia({ client: client2, query })),
|
|
1973
|
-
/**
|
|
1974
|
-
|
|
2173
|
+
/**
|
|
2174
|
+
* Upload one media file and get back a media ID to attach to posts. Wraps
|
|
2175
|
+
* `Media.uploadMedia`, or for files over `STORAGE_UPLOAD_THRESHOLD_BYTES`
|
|
2176
|
+
* runs `createUpload`, sends the file to storage and returns the finished
|
|
2177
|
+
* media from `completeUpload`. Both return the same `Media` object.
|
|
2178
|
+
*
|
|
2179
|
+
* The file's content type is filled in from its name when it has none, so a
|
|
2180
|
+
* file read off disk with `new File([buffer], 'photo.jpg')` is not sent as
|
|
2181
|
+
* `application/octet-stream` and refused. See `withInferredContentType`.
|
|
2182
|
+
*/
|
|
2183
|
+
upload: (body) => {
|
|
2184
|
+
const file = withInferredContentType(body.file);
|
|
2185
|
+
if (file.size > STORAGE_UPLOAD_THRESHOLD_BYTES) {
|
|
2186
|
+
return uploadThroughStorage(client2, file);
|
|
2187
|
+
}
|
|
2188
|
+
return preserveApiError(
|
|
2189
|
+
Media.uploadMedia({ client: client2, body: { ...body, file } })
|
|
2190
|
+
);
|
|
2191
|
+
},
|
|
2192
|
+
/** Get a storage upload URL for a file of up to 4 GB. Send the file there, then use the returned media ID in posts. Wraps `Media.createMediaUpload`. */
|
|
2193
|
+
createUpload: (body) => preserveApiError(Media.createMediaUpload({ client: client2, body })),
|
|
2194
|
+
/** Add a file sent to a `createUpload` URL to the media library now and return it. Optional: using the ID in a post does the same. Wraps `Media.completeMediaUpload`. */
|
|
2195
|
+
completeUpload: (id) => preserveApiError(Media.completeMediaUpload({ client: client2, path: { id } })),
|
|
1975
2196
|
/** Get one media file by ID. Wraps `Media.getMedia`. */
|
|
1976
2197
|
get: (id) => preserveApiError(Media.getMedia({ client: client2, path: { id } }))
|
|
1977
2198
|
};
|
|
@@ -1983,13 +2204,20 @@ var index_default = PublishQ;
|
|
|
1983
2204
|
Media2,
|
|
1984
2205
|
Posts,
|
|
1985
2206
|
PublishQ,
|
|
2207
|
+
STORAGE_UPLOAD_THRESHOLD_BYTES,
|
|
1986
2208
|
Workspaces,
|
|
2209
|
+
withInferredContentType,
|
|
1987
2210
|
zAccount,
|
|
1988
2211
|
zAccountsResponse,
|
|
1989
2212
|
zApiError,
|
|
1990
2213
|
zApiErrorCode,
|
|
1991
2214
|
zApiKeyScope,
|
|
1992
2215
|
zBlueskyPlatformSpecificSettings,
|
|
2216
|
+
zCompleteMediaUploadPath,
|
|
2217
|
+
zCompleteMediaUploadResponse,
|
|
2218
|
+
zCreateMediaUploadBody,
|
|
2219
|
+
zCreateMediaUploadRequest,
|
|
2220
|
+
zCreateMediaUploadResponse,
|
|
1993
2221
|
zCreatePostAccount,
|
|
1994
2222
|
zCreatePostBody,
|
|
1995
2223
|
zCreatePostRequest,
|
|
@@ -2022,13 +2250,17 @@ var index_default = PublishQ;
|
|
|
2022
2250
|
zMediaListResponse,
|
|
2023
2251
|
zMediaSource,
|
|
2024
2252
|
zMediaType,
|
|
2253
|
+
zMediaUpload,
|
|
2025
2254
|
zPagination,
|
|
2026
2255
|
zPlatformSpecificSettings,
|
|
2027
2256
|
zPost,
|
|
2028
2257
|
zPostAccount,
|
|
2258
|
+
zPostAnalytics,
|
|
2029
2259
|
zPostOverrides,
|
|
2260
|
+
zPostSource,
|
|
2030
2261
|
zPostStatus,
|
|
2031
2262
|
zPostsResponse,
|
|
2263
|
+
zPublishFailure,
|
|
2032
2264
|
zRemovePostAccountPath,
|
|
2033
2265
|
zRemovePostAccountResponse,
|
|
2034
2266
|
zSocialPlatform,
|