@codejeet/oadm 0.0.4 → 0.0.5

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/cli.js CHANGED
@@ -3,9 +3,8 @@ import { Command } from 'commander';
3
3
  import chalk from 'chalk';
4
4
  import { readConfig, writeConfig } from './config.js';
5
5
  import { getJson, postJson } from './http.js';
6
- import pkg from '../package.json' with { type: 'json' };
7
6
  const program = new Command();
8
- program.name('oadm').description('OADM Inbox CLI').version(pkg.version);
7
+ program.name('oadm').description('OADM Inbox CLI').version('0.0.2');
9
8
  program
10
9
  .option('--api <url>', 'API base URL (or set OADM_API_URL)', '')
11
10
  .hook('preAction', (thisCommand) => {
@@ -62,6 +61,7 @@ program
62
61
  .option('--sent', 'Show sent messages (outbox)', false)
63
62
  .option('--all', 'Show both received and sent', false)
64
63
  .option('--since <timestamp>', 'Only messages since timestamp (ISO 8601 or unix)', '')
64
+ .option('--limit <count>', 'Max messages to return (cap 200)', '')
65
65
  .option('--json', 'JSON output', false)
66
66
  .option('--ack', 'Ack returned messages', false)
67
67
  .action(async (opts) => {
@@ -79,6 +79,8 @@ program
79
79
  q.set('all', '1');
80
80
  if (opts.since)
81
81
  q.set('since', opts.since);
82
+ if (opts.limit)
83
+ q.set('limit', String(opts.limit));
82
84
  const data = await getJson(`${cfg.apiUrl}/v1/messages/inbox?${q.toString()}`, cfg.token);
83
85
  if (opts.json) {
84
86
  console.log(JSON.stringify(data, null, 2));
@@ -113,19 +115,17 @@ program
113
115
  await postJson(`${cfg.apiUrl}/v1/messages/ack/${msgId}`, {}, cfg.token);
114
116
  console.log(chalk.green('✓ acked'), msgId);
115
117
  });
116
- // Webhooks
117
118
  program
118
119
  .command('webhook:create')
119
120
  .requiredOption('--url <url>')
121
+ .option('--secret <secret>')
120
122
  .action(async (opts) => {
121
123
  const cfg = readConfig();
122
124
  if (!cfg.token)
123
125
  throw new Error('not_logged_in');
124
- // Server generates the secret. Do NOT send user secret.
125
- const data = await postJson(`${cfg.apiUrl}/v1/webhooks`, { url: opts.url }, cfg.token);
126
+ const data = await postJson(`${cfg.apiUrl}/v1/webhooks`, { url: opts.url, secret: opts.secret }, cfg.token);
126
127
  console.log(chalk.green('✓ webhook created'), data.webhook.id);
127
- if (data.secret)
128
- console.log('secret:', data.secret);
128
+ console.log('secret:', data.secret);
129
129
  });
130
130
  program
131
131
  .command('webhook:list')
@@ -152,7 +152,7 @@ program
152
152
  const cfg = readConfig();
153
153
  if (!cfg.token)
154
154
  throw new Error('not_logged_in');
155
- await postJson(`${cfg.apiUrl}/v1/webhooks/${webhookId}`, undefined, cfg.token, 'DELETE');
155
+ await postJson(`${cfg.apiUrl}/v1/webhooks/${webhookId}`, {}, cfg.token, 'DELETE');
156
156
  console.log(chalk.green('✓ webhook deleted'), webhookId);
157
157
  });
158
158
  program.parseAsync(process.argv).catch((e) => {
package/dist/config.js CHANGED
@@ -1,28 +1,29 @@
1
- import fs from 'node:fs';
2
1
  import os from 'node:os';
3
2
  import path from 'node:path';
4
- const CONFIG_DIR = path.join(os.homedir(), '.oadm');
5
- const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
3
+ import fs from 'node:fs';
4
+ export function configDir() {
5
+ return path.join(os.homedir(), '.oadm');
6
+ }
7
+ export function configPath() {
8
+ return path.join(configDir(), 'config.json');
9
+ }
6
10
  export function readConfig() {
11
+ const p = configPath();
12
+ if (!fs.existsSync(p)) {
13
+ return { apiUrl: process.env.OADM_API_URL ?? 'http://localhost:3000' };
14
+ }
15
+ const raw = fs.readFileSync(p, 'utf8');
16
+ const cfg = JSON.parse(raw);
17
+ cfg.apiUrl = cfg.apiUrl ?? process.env.OADM_API_URL ?? 'http://localhost:3000';
18
+ return cfg;
19
+ }
20
+ export function writeConfig(cfg) {
21
+ fs.mkdirSync(configDir(), { recursive: true });
22
+ fs.writeFileSync(configPath(), JSON.stringify(cfg, null, 2));
7
23
  try {
8
- const raw = fs.readFileSync(CONFIG_PATH, 'utf8');
9
- const cfg = JSON.parse(raw);
10
- const apiUrl = process.env.OADM_API_URL ??
11
- (typeof cfg.apiUrl === 'string' ? cfg.apiUrl : '') ??
12
- '';
13
- return {
14
- apiUrl: apiUrl || 'https://api-zeta-jet-48.vercel.app',
15
- name: typeof cfg.name === 'string' ? cfg.name : undefined,
16
- token: typeof cfg.token === 'string' ? cfg.token : undefined,
17
- };
24
+ fs.chmodSync(configPath(), 0o600);
18
25
  }
19
26
  catch {
20
- const apiUrl = process.env.OADM_API_URL ?? 'https://api-zeta-jet-48.vercel.app';
21
- return { apiUrl };
27
+ // ignore on platforms that don't support chmod
22
28
  }
23
29
  }
24
- export function writeConfig(cfg) {
25
- if (!fs.existsSync(CONFIG_DIR))
26
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
27
- fs.writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2));
28
- }
package/dist/http.js CHANGED
@@ -1,32 +1,31 @@
1
- import fetch from 'node-fetch';
2
- export async function getJson(url, token) {
3
- const res = await fetch(url, {
4
- method: 'GET',
1
+ export async function postJson(url, body, token, method = 'POST') {
2
+ const r = await fetch(url, {
3
+ method,
5
4
  headers: {
6
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
5
+ 'content-type': 'application/json',
6
+ ...(token ? { authorization: `Bearer ${token}` } : {}),
7
7
  },
8
+ body: JSON.stringify(body),
8
9
  });
9
- if (!res.ok) {
10
- const text = await res.text().catch(() => '');
11
- throw new Error(`http_${res.status}${text ? `: ${text}` : ''}`);
10
+ const text = await r.text();
11
+ const data = text ? JSON.parse(text) : null;
12
+ if (!r.ok) {
13
+ const msg = data?.error ? `${data.error}` : `http_${r.status}`;
14
+ throw new Error(msg);
12
15
  }
13
- return (await res.json());
16
+ return data;
14
17
  }
15
- export async function postJson(url, body, token, method = 'POST') {
16
- const res = await fetch(url, {
17
- method,
18
+ export async function getJson(url, token) {
19
+ const r = await fetch(url, {
18
20
  headers: {
19
- 'Content-Type': 'application/json',
20
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
21
+ ...(token ? { authorization: `Bearer ${token}` } : {}),
21
22
  },
22
- body: body === undefined ? undefined : JSON.stringify(body),
23
23
  });
24
- if (!res.ok) {
25
- const text = await res.text().catch(() => '');
26
- throw new Error(`http_${res.status}${text ? `: ${text}` : ''}`);
24
+ const text = await r.text();
25
+ const data = text ? JSON.parse(text) : null;
26
+ if (!r.ok) {
27
+ const msg = data?.error ? `${data.error}` : `http_${r.status}`;
28
+ throw new Error(msg);
27
29
  }
28
- const ct = res.headers.get('content-type') || '';
29
- if (!ct.includes('application/json'))
30
- return {};
31
- return (await res.json());
30
+ return data;
32
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codejeet/oadm",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "oadm": "dist/cli.js"