@codejeet/oadm 0.0.4 → 0.0.6

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
@@ -1,11 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
+ import { createRequire } from 'node:module';
3
4
  import chalk from 'chalk';
4
5
  import { readConfig, writeConfig } from './config.js';
5
6
  import { getJson, postJson } from './http.js';
6
- import pkg from '../package.json' with { type: 'json' };
7
+ const require = createRequire(import.meta.url);
8
+ const pkg = require('../package.json');
7
9
  const program = new Command();
8
- program.name('oadm').description('OADM Inbox CLI').version(pkg.version);
10
+ program
11
+ .name('oadm')
12
+ .description('OADM Inbox CLI')
13
+ .version(pkg.version ?? '0.0.0');
9
14
  program
10
15
  .option('--api <url>', 'API base URL (or set OADM_API_URL)', '')
11
16
  .hook('preAction', (thisCommand) => {
@@ -62,6 +67,7 @@ program
62
67
  .option('--sent', 'Show sent messages (outbox)', false)
63
68
  .option('--all', 'Show both received and sent', false)
64
69
  .option('--since <timestamp>', 'Only messages since timestamp (ISO 8601 or unix)', '')
70
+ .option('--limit <count>', 'Max messages to return (cap 200)', '')
65
71
  .option('--json', 'JSON output', false)
66
72
  .option('--ack', 'Ack returned messages', false)
67
73
  .action(async (opts) => {
@@ -79,6 +85,8 @@ program
79
85
  q.set('all', '1');
80
86
  if (opts.since)
81
87
  q.set('since', opts.since);
88
+ if (opts.limit)
89
+ q.set('limit', String(opts.limit));
82
90
  const data = await getJson(`${cfg.apiUrl}/v1/messages/inbox?${q.toString()}`, cfg.token);
83
91
  if (opts.json) {
84
92
  console.log(JSON.stringify(data, null, 2));
@@ -113,19 +121,17 @@ program
113
121
  await postJson(`${cfg.apiUrl}/v1/messages/ack/${msgId}`, {}, cfg.token);
114
122
  console.log(chalk.green('✓ acked'), msgId);
115
123
  });
116
- // Webhooks
117
124
  program
118
125
  .command('webhook:create')
119
126
  .requiredOption('--url <url>')
127
+ .option('--secret <secret>')
120
128
  .action(async (opts) => {
121
129
  const cfg = readConfig();
122
130
  if (!cfg.token)
123
131
  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);
132
+ const data = await postJson(`${cfg.apiUrl}/v1/webhooks`, { url: opts.url, secret: opts.secret }, cfg.token);
126
133
  console.log(chalk.green('✓ webhook created'), data.webhook.id);
127
- if (data.secret)
128
- console.log('secret:', data.secret);
134
+ console.log('secret:', data.secret);
129
135
  });
130
136
  program
131
137
  .command('webhook:list')
@@ -152,7 +158,7 @@ program
152
158
  const cfg = readConfig();
153
159
  if (!cfg.token)
154
160
  throw new Error('not_logged_in');
155
- await postJson(`${cfg.apiUrl}/v1/webhooks/${webhookId}`, undefined, cfg.token, 'DELETE');
161
+ await postJson(`${cfg.apiUrl}/v1/webhooks/${webhookId}`, {}, cfg.token, 'DELETE');
156
162
  console.log(chalk.green('✓ webhook deleted'), webhookId);
157
163
  });
158
164
  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.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "oadm": "dist/cli.js"
@@ -12,6 +12,7 @@
12
12
  "dev": "tsx src/cli.ts",
13
13
  "build": "tsc -p tsconfig.json",
14
14
  "prepack": "tsc -p tsconfig.json",
15
+ "smoke:version": "pnpm build && node ./scripts/smoke-version.mjs",
15
16
  "typecheck": "tsc -p tsconfig.json --noEmit"
16
17
  },
17
18
  "dependencies": {