@publishq/cli 0.0.5 → 0.0.7
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 +7 -5
- package/dist/index.js +36 -9
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ Output is JSON by default: easy to pipe into `jq` and easy for an AI agent to pa
|
|
|
19
19
|
## Install
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
npm install -g @publishq/cli
|
|
22
|
+
npm install -g @publishq/cli@latest
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
You get two commands: `publishq` and the shorter `pq`. They do the same thing.
|
|
@@ -27,7 +27,7 @@ You get two commands: `publishq` and the shorter `pq`. They do the same thing.
|
|
|
27
27
|
## Quick start
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
# 1. Save your API key (create one under
|
|
30
|
+
# 1. Save your API key (create one under API Keys in the web app)
|
|
31
31
|
pq auth set --key "pq_live_..."
|
|
32
32
|
|
|
33
33
|
# 2. See your connected accounts
|
|
@@ -51,6 +51,8 @@ pq posts create --content "Hello TikTok" --accounts-json '[{"accountId":"<id>","
|
|
|
51
51
|
pq posts update <post-id> [--content "New text"] [--scheduled-at <iso>] \
|
|
52
52
|
[--media-id <id>] [--thumbnail-timestamp <ms>]
|
|
53
53
|
pq posts update <post-id> --media-ids-json '[]' # remove all media
|
|
54
|
+
pq posts update <post-id> --accounts-json '[{"accountId":"<id>","platformSpecificSettings":{"thumbnailMediaId":"<image-media-id>"}}]'
|
|
55
|
+
pq posts update <post-id> --accounts-json '[{"accountId":"<id>","platformSpecificSettings":{"thumbnailMediaId":null}}]' # remove one setting
|
|
54
56
|
pq posts delete <post-id>
|
|
55
57
|
pq posts remove-account <post-id> <account-id>
|
|
56
58
|
```
|
|
@@ -83,7 +85,7 @@ pq media get <media-id>
|
|
|
83
85
|
pq media upload --file ./photo.jpg [--filename custom.jpg]
|
|
84
86
|
```
|
|
85
87
|
|
|
86
|
-
Upload returns a media object whose `id` you can pass to `pq posts create --media-id <id>`.
|
|
88
|
+
Upload returns a media object whose `id` you can pass to `pq posts create --media-id <id>`. Files up to 4 GB are accepted (500 MB on the Free plan).
|
|
87
89
|
|
|
88
90
|
## Scopes
|
|
89
91
|
|
|
@@ -101,8 +103,8 @@ API keys carry scopes that control access. A call missing the required scope ret
|
|
|
101
103
|
|
|
102
104
|
## Related
|
|
103
105
|
|
|
104
|
-
- [`@publishq/sdk`](https://www.npmjs.com/package/@publishq/sdk)
|
|
105
|
-
- [`@publishq/mcp`](https://www.npmjs.com/package/@publishq/mcp)
|
|
106
|
+
- [`@publishq/sdk`](https://www.npmjs.com/package/@publishq/sdk): the TypeScript SDK this CLI is built on.
|
|
107
|
+
- [`@publishq/mcp`](https://www.npmjs.com/package/@publishq/mcp): Model Context Protocol server for Claude Desktop and other AI agents.
|
|
106
108
|
|
|
107
109
|
## License
|
|
108
110
|
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import {
|
|
4
|
+
import { openAsBlob, statSync } from "fs";
|
|
5
5
|
import { basename } from "path";
|
|
6
6
|
import yargs from "yargs";
|
|
7
7
|
import { hideBin } from "yargs/helpers";
|
|
@@ -33,7 +33,7 @@ function getClient() {
|
|
|
33
33
|
const apiKey = getApiKey();
|
|
34
34
|
if (!apiKey) {
|
|
35
35
|
console.error(
|
|
36
|
-
'No API key found. Generate one at https://publishq.com/app/
|
|
36
|
+
'No API key found. Generate one at https://publishq.com/app/api-keys, then run `publishq auth set --key "pq_live_..."` or set PUBLISHQ_API_KEY.'
|
|
37
37
|
);
|
|
38
38
|
process.exit(1);
|
|
39
39
|
}
|
|
@@ -70,6 +70,7 @@ function describeError(error) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
// src/index.ts
|
|
73
|
+
var OPEN_AS_BLOB_MAX_BYTES = 2 ** 32;
|
|
73
74
|
function parseJsonOption(option, value) {
|
|
74
75
|
try {
|
|
75
76
|
return JSON.parse(value);
|
|
@@ -115,18 +116,26 @@ yargs(hideBin(process.argv)).scriptName("publishq").usage("$0 <command> [options
|
|
|
115
116
|
"Create, list, update, and delete posts",
|
|
116
117
|
(y) => y.command(
|
|
117
118
|
["list", "$0"],
|
|
118
|
-
"List posts (paginate with --page and --limit)",
|
|
119
|
+
"List the posts you created through PublishQ (paginate with --page and --limit; imported posts need --include-imported or --only-imported)",
|
|
119
120
|
(yy) => yy.option("page", {
|
|
120
121
|
type: "number",
|
|
121
122
|
describe: "Page number (starts at 1)"
|
|
122
123
|
}).option("limit", {
|
|
123
124
|
type: "number",
|
|
124
125
|
describe: "Page size (max 100)"
|
|
126
|
+
}).option("include-imported", {
|
|
127
|
+
type: "boolean",
|
|
128
|
+
describe: "Also include posts imported from a connected platform (excluded by default)"
|
|
129
|
+
}).option("only-imported", {
|
|
130
|
+
type: "boolean",
|
|
131
|
+
describe: "Return only posts imported from a connected platform"
|
|
125
132
|
}),
|
|
126
133
|
(argv) => {
|
|
127
134
|
const query = {
|
|
128
135
|
...argv.page !== void 0 ? { page: argv.page } : {},
|
|
129
|
-
...argv.limit !== void 0 ? { limit: argv.limit } : {}
|
|
136
|
+
...argv.limit !== void 0 ? { limit: argv.limit } : {},
|
|
137
|
+
...argv.includeImported !== void 0 ? { includeImported: argv.includeImported } : {},
|
|
138
|
+
...argv.onlyImported !== void 0 ? { onlyImported: argv.onlyImported } : {}
|
|
130
139
|
};
|
|
131
140
|
output(
|
|
132
141
|
getClient().posts.list(
|
|
@@ -203,18 +212,26 @@ yargs(hideBin(process.argv)).scriptName("publishq").usage("$0 <command> [options
|
|
|
203
212
|
}).conflicts("media-id", "media-ids-json").option("thumbnail-timestamp", {
|
|
204
213
|
type: "number",
|
|
205
214
|
describe: "New video thumbnail timestamp in milliseconds"
|
|
215
|
+
}).option("accounts-json", {
|
|
216
|
+
type: "string",
|
|
217
|
+
describe: "JSON array of account objects to update or add, with accountId and optional postOverrides/platformSpecificSettings. Only the fields you send change; send a field as null to remove it."
|
|
206
218
|
}),
|
|
207
219
|
(argv) => {
|
|
208
220
|
const mediaIds = argv["media-ids-json"] !== void 0 ? parseJsonOption(
|
|
209
221
|
"--media-ids-json",
|
|
210
222
|
argv["media-ids-json"]
|
|
211
223
|
) : argv["media-id"];
|
|
224
|
+
const accounts = argv["accounts-json"] !== void 0 ? parseJsonOption(
|
|
225
|
+
"--accounts-json",
|
|
226
|
+
argv["accounts-json"]
|
|
227
|
+
) : void 0;
|
|
212
228
|
output(
|
|
213
229
|
getClient().posts.update(argv.id, {
|
|
214
230
|
...argv.content !== void 0 ? { content: argv.content } : {},
|
|
215
231
|
...argv["scheduled-at"] !== void 0 ? { scheduledAt: argv["scheduled-at"] } : {},
|
|
216
232
|
...mediaIds !== void 0 ? { mediaIds } : {},
|
|
217
|
-
...argv["thumbnail-timestamp"] !== void 0 ? { thumbnailTimestamp: argv["thumbnail-timestamp"] } : {}
|
|
233
|
+
...argv["thumbnail-timestamp"] !== void 0 ? { thumbnailTimestamp: argv["thumbnail-timestamp"] } : {},
|
|
234
|
+
...accounts !== void 0 ? { accounts } : {}
|
|
218
235
|
}),
|
|
219
236
|
argv.pretty
|
|
220
237
|
);
|
|
@@ -361,11 +378,21 @@ yargs(hideBin(process.argv)).scriptName("publishq").usage("$0 <command> [options
|
|
|
361
378
|
type: "string",
|
|
362
379
|
describe: "Override the uploaded file name"
|
|
363
380
|
}),
|
|
364
|
-
(argv) => {
|
|
365
|
-
|
|
381
|
+
async (argv) => {
|
|
382
|
+
if (statSync(argv.file).size >= OPEN_AS_BLOB_MAX_BYTES) {
|
|
383
|
+
console.error(
|
|
384
|
+
JSON.stringify({
|
|
385
|
+
error: `${argv.file} is too big to upload: files must be smaller than 4 GB.`
|
|
386
|
+
})
|
|
387
|
+
);
|
|
388
|
+
process.exit(1);
|
|
389
|
+
}
|
|
366
390
|
const name = argv.filename ?? basename(argv.file);
|
|
367
|
-
const file = new File([
|
|
368
|
-
output(
|
|
391
|
+
const file = new File([await openAsBlob(argv.file)], name);
|
|
392
|
+
return output(
|
|
393
|
+
getClient().media.upload({ file }),
|
|
394
|
+
argv.pretty
|
|
395
|
+
);
|
|
369
396
|
}
|
|
370
397
|
).demandCommand(1, "Specify a media subcommand."),
|
|
371
398
|
() => {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@publishq/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "Official command-line interface for the PublishQ API
|
|
5
|
+
"description": "Official command-line interface for the PublishQ API. Schedule and publish across your social platforms.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": "PublishQ",
|
|
8
8
|
"homepage": "https://publishq.com",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"LICENSE"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"
|
|
31
|
-
"
|
|
30
|
+
"@publishq/sdk": "^0.0.3",
|
|
31
|
+
"yargs": "^17.7.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^20",
|