notipo 1.0.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/config.d.ts +7 -0
- package/dist/config.js +24 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +115 -0
- package/package.json +35 -0
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
export function configPath() {
|
|
5
|
+
return path.join(os.homedir(), ".notipo", "config.json");
|
|
6
|
+
}
|
|
7
|
+
export function readConfig() {
|
|
8
|
+
// Env vars take priority — agents set these
|
|
9
|
+
const url = process.env.NOTIPO_URL;
|
|
10
|
+
const apiKey = process.env.NOTIPO_API_KEY;
|
|
11
|
+
if (url && apiKey)
|
|
12
|
+
return { url, apiKey };
|
|
13
|
+
// Fall back to config file (written by interactive login wrapper)
|
|
14
|
+
const file = configPath();
|
|
15
|
+
if (fs.existsSync(file)) {
|
|
16
|
+
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
17
|
+
}
|
|
18
|
+
throw new Error("No config found. Set NOTIPO_URL and NOTIPO_API_KEY environment variables.");
|
|
19
|
+
}
|
|
20
|
+
export function writeConfig(config) {
|
|
21
|
+
const dir = path.dirname(configPath());
|
|
22
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
23
|
+
fs.writeFileSync(configPath(), JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
24
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readConfig } from "./config.js";
|
|
3
|
+
// ── API client ────────────────────────────────────────────────────────────────
|
|
4
|
+
async function api(config, path, method = "GET", body) {
|
|
5
|
+
const headers = { "X-API-Key": config.apiKey };
|
|
6
|
+
if (body !== undefined)
|
|
7
|
+
headers["Content-Type"] = "application/json";
|
|
8
|
+
const res = await fetch(`${config.url}${path}`, {
|
|
9
|
+
method,
|
|
10
|
+
headers,
|
|
11
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
12
|
+
});
|
|
13
|
+
if (!res.ok) {
|
|
14
|
+
const text = await res.text().catch(() => "");
|
|
15
|
+
let msg = text;
|
|
16
|
+
try {
|
|
17
|
+
msg = JSON.parse(text).message ?? text;
|
|
18
|
+
}
|
|
19
|
+
catch { }
|
|
20
|
+
throw new Error(`${res.status} ${msg || res.statusText}`);
|
|
21
|
+
}
|
|
22
|
+
const json = await res.json();
|
|
23
|
+
// Unwrap Notipo's { data: ... } envelope if present
|
|
24
|
+
if (json !== null && typeof json === "object" && "data" in json) {
|
|
25
|
+
return json.data;
|
|
26
|
+
}
|
|
27
|
+
return json;
|
|
28
|
+
}
|
|
29
|
+
function out(data) {
|
|
30
|
+
console.log(JSON.stringify(data, null, 2));
|
|
31
|
+
}
|
|
32
|
+
function err(message, detail) {
|
|
33
|
+
console.error(JSON.stringify({ error: message, ...(detail ? { detail } : {}) }, null, 2));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// ── Commands ──────────────────────────────────────────────────────────────────
|
|
37
|
+
async function cmdStatus(config) {
|
|
38
|
+
const data = await api(config, "/api/settings");
|
|
39
|
+
out(data);
|
|
40
|
+
}
|
|
41
|
+
async function cmdSync(config) {
|
|
42
|
+
await api(config, "/api/sync-now", "POST");
|
|
43
|
+
out({ ok: true, message: "Sync triggered. Run `notipo jobs` to monitor progress." });
|
|
44
|
+
}
|
|
45
|
+
async function cmdPosts(config) {
|
|
46
|
+
const posts = await api(config, "/api/posts");
|
|
47
|
+
out(posts ?? []);
|
|
48
|
+
}
|
|
49
|
+
async function cmdJobs(config) {
|
|
50
|
+
const jobs = await api(config, "/api/jobs");
|
|
51
|
+
out(jobs ?? []);
|
|
52
|
+
}
|
|
53
|
+
async function cmdPostsDelete(config, id) {
|
|
54
|
+
if (!id)
|
|
55
|
+
err("Missing post ID. Usage: notipo posts delete <id>");
|
|
56
|
+
await api(config, `/api/posts/${id}`, "DELETE");
|
|
57
|
+
out({ ok: true, deleted: id });
|
|
58
|
+
}
|
|
59
|
+
function cmdHelp() {
|
|
60
|
+
out({
|
|
61
|
+
usage: "notipo <command> [args]",
|
|
62
|
+
commands: {
|
|
63
|
+
status: "Show Notion and WordPress connection status",
|
|
64
|
+
sync: "Trigger an immediate Notion poll",
|
|
65
|
+
posts: "List all posts",
|
|
66
|
+
"posts delete <id>": "Delete a post (cleans up WordPress + Notion)",
|
|
67
|
+
jobs: "List recent sync and publish jobs",
|
|
68
|
+
},
|
|
69
|
+
config: {
|
|
70
|
+
env: "NOTIPO_URL and NOTIPO_API_KEY environment variables",
|
|
71
|
+
file: "~/.notipo/config.json (written by `notipo login` if using the interactive wrapper)",
|
|
72
|
+
},
|
|
73
|
+
examples: [
|
|
74
|
+
"NOTIPO_URL=https://notipo.com NOTIPO_API_KEY=ntp_... notipo sync",
|
|
75
|
+
"notipo posts",
|
|
76
|
+
"notipo jobs",
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// ── Entry ─────────────────────────────────────────────────────────────────────
|
|
81
|
+
const [, , cmd, sub, arg] = process.argv;
|
|
82
|
+
if (!cmd || cmd === "help") {
|
|
83
|
+
cmdHelp();
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const config = readConfig();
|
|
88
|
+
if (cmd === "status") {
|
|
89
|
+
await cmdStatus(config);
|
|
90
|
+
}
|
|
91
|
+
else if (cmd === "sync") {
|
|
92
|
+
await cmdSync(config);
|
|
93
|
+
}
|
|
94
|
+
else if (cmd === "posts" && sub === "delete") {
|
|
95
|
+
await cmdPostsDelete(config, arg);
|
|
96
|
+
}
|
|
97
|
+
else if (cmd === "posts") {
|
|
98
|
+
await cmdPosts(config);
|
|
99
|
+
}
|
|
100
|
+
else if (cmd === "jobs") {
|
|
101
|
+
await cmdJobs(config);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
err(`Unknown command: ${cmd}. Run \`notipo help\` for usage.`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
109
|
+
if (msg.includes("No config")) {
|
|
110
|
+
err("Not authenticated. Set NOTIPO_URL and NOTIPO_API_KEY environment variables.");
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
err(msg);
|
|
114
|
+
}
|
|
115
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "notipo",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI for the Notipo publishing API",
|
|
5
|
+
"license": "AGPL-3.0-only",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"notipo": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsc --watch"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"notipo",
|
|
23
|
+
"notion",
|
|
24
|
+
"wordpress",
|
|
25
|
+
"publishing",
|
|
26
|
+
"cli"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/kfuras/notipo.git"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"typescript": "^5.7.3"
|
|
34
|
+
}
|
|
35
|
+
}
|