notipo 1.0.0 → 1.0.1

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.
Files changed (2) hide show
  1. package/dist/index.js +77 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -50,6 +50,75 @@ async function cmdJobs(config) {
50
50
  const jobs = await api(config, "/api/jobs");
51
51
  out(jobs ?? []);
52
52
  }
53
+ async function cmdPostsCreate(config, args) {
54
+ const get = (flag) => {
55
+ const i = args.indexOf(flag);
56
+ return i !== -1 ? args[i + 1] : undefined;
57
+ };
58
+ const has = (flag) => args.includes(flag);
59
+ const title = get("--title");
60
+ if (!title)
61
+ err("Missing --title. Usage: notipo posts create --title \"My Post\" [options]");
62
+ const body = { title };
63
+ const bodyText = get("--body");
64
+ if (bodyText)
65
+ body.body = bodyText;
66
+ const category = get("--category");
67
+ if (category)
68
+ body.category = category;
69
+ const tags = get("--tags");
70
+ if (tags)
71
+ body.tags = tags.split(",").map((t) => t.trim());
72
+ const seoKeyword = get("--seo-keyword");
73
+ if (seoKeyword)
74
+ body.seoKeyword = seoKeyword;
75
+ const imageTitle = get("--image-title");
76
+ if (imageTitle)
77
+ body.imageTitle = imageTitle;
78
+ const slug = get("--slug");
79
+ if (slug)
80
+ body.slug = slug;
81
+ if (has("--publish"))
82
+ body.publish = true;
83
+ const result = await api(config, "/api/posts/create", "POST", body);
84
+ out(result);
85
+ if (has("--wait")) {
86
+ process.stderr.write("Waiting for job to complete...\n");
87
+ let syncPostId;
88
+ // Phase 1: wait for SYNC_POST to complete
89
+ for (let i = 0; i < 30; i++) {
90
+ await new Promise((r) => setTimeout(r, 3000));
91
+ const jobs = await api(config, "/api/jobs");
92
+ const job = jobs.find((j) => j.pgBossJobId === result.jobId);
93
+ if (job?.status === "FAILED") {
94
+ out(job);
95
+ return;
96
+ }
97
+ if (job?.status === "COMPLETED") {
98
+ syncPostId = job.postId;
99
+ if (!has("--publish")) {
100
+ out(job);
101
+ return;
102
+ }
103
+ break;
104
+ }
105
+ }
106
+ // Phase 2: if --publish, wait for the subsequent PUBLISH_POST job
107
+ if (has("--publish") && syncPostId) {
108
+ process.stderr.write("Waiting for publish to complete...\n");
109
+ for (let i = 0; i < 30; i++) {
110
+ await new Promise((r) => setTimeout(r, 3000));
111
+ const jobs = await api(config, "/api/jobs");
112
+ const job = jobs.find((j) => j.type === "PUBLISH_POST" && j.postId === syncPostId);
113
+ if (job?.status === "COMPLETED" || job?.status === "FAILED") {
114
+ out(job);
115
+ return;
116
+ }
117
+ }
118
+ }
119
+ err("Timed out waiting for job. Run `notipo jobs` to check status.");
120
+ }
121
+ }
53
122
  async function cmdPostsDelete(config, id) {
54
123
  if (!id)
55
124
  err("Missing post ID. Usage: notipo posts delete <id>");
@@ -63,6 +132,8 @@ function cmdHelp() {
63
132
  status: "Show Notion and WordPress connection status",
64
133
  sync: "Trigger an immediate Notion poll",
65
134
  posts: "List all posts",
135
+ "posts create": "Create a post in Notion and sync to WordPress",
136
+ "posts create --title <title> [--body <text>] [--category <cat>] [--tags <a,b>] [--seo-keyword <kw>] [--image-title <title>] [--publish] [--wait]": "",
66
137
  "posts delete <id>": "Delete a post (cleans up WordPress + Notion)",
67
138
  jobs: "List recent sync and publish jobs",
68
139
  },
@@ -71,6 +142,7 @@ function cmdHelp() {
71
142
  file: "~/.notipo/config.json (written by `notipo login` if using the interactive wrapper)",
72
143
  },
73
144
  examples: [
145
+ "notipo posts create --title \"My Post\" --category \"AI\" --publish --wait",
74
146
  "NOTIPO_URL=https://notipo.com NOTIPO_API_KEY=ntp_... notipo sync",
75
147
  "notipo posts",
76
148
  "notipo jobs",
@@ -78,7 +150,7 @@ function cmdHelp() {
78
150
  });
79
151
  }
80
152
  // ── Entry ─────────────────────────────────────────────────────────────────────
81
- const [, , cmd, sub, arg] = process.argv;
153
+ const [, , cmd, sub, ...rest] = process.argv;
82
154
  if (!cmd || cmd === "help") {
83
155
  cmdHelp();
84
156
  process.exit(0);
@@ -91,8 +163,11 @@ try {
91
163
  else if (cmd === "sync") {
92
164
  await cmdSync(config);
93
165
  }
166
+ else if (cmd === "posts" && sub === "create") {
167
+ await cmdPostsCreate(config, rest);
168
+ }
94
169
  else if (cmd === "posts" && sub === "delete") {
95
- await cmdPostsDelete(config, arg);
170
+ await cmdPostsDelete(config, rest[0]);
96
171
  }
97
172
  else if (cmd === "posts") {
98
173
  await cmdPosts(config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notipo",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "CLI for the Notipo publishing API",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",