@profullstack/nichedb 0.63.0 → 0.64.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +37 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@profullstack/nichedb",
3
- "version": "0.63.0",
3
+ "version": "0.64.0",
4
4
  "description": "CLI and MCP bridge for NicheDB: browse collections, manage sources and feeds, search items, from any deployment",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -15,7 +15,7 @@ import { homedir, tmpdir } from 'node:os';
15
15
  import { join } from 'node:path';
16
16
  import { createInterface } from 'node:readline';
17
17
 
18
- export const VERSION = '0.63.0';
18
+ export const VERSION = '0.64.0';
19
19
  const GEO_FLAGS = ['lat', 'long', 'radius', 'unit', 'bbox', 'sort', 'offset'];
20
20
  const DEFAULT_API = process.env.NICHEDB_API ?? 'https://nichedb.dev';
21
21
  const CONFIG_DIR = join(process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config'), 'nichedb');
@@ -259,6 +259,13 @@ export const COMMANDS = [
259
259
  'A train run (Amtrak, VIA Rail, Finland): where it is, its next stop and how late; or a European station.',
260
260
  options: ['--json'],
261
261
  },
262
+ {
263
+ name: 'transit',
264
+ usage: 'transit [<city> [<station id>]] [--json]',
265
+ summary:
266
+ 'Public transit: the cities, a city’s lines and alerts, or a station’s next arrivals and timetable.',
267
+ options: ['--json'],
268
+ },
262
269
  {
263
270
  name: 'ship',
264
271
  usage: 'ship <MMSI | IMO | name> [--json]',
@@ -1246,6 +1253,35 @@ export async function run(
1246
1253
  if (r.record?.url) out(r.record.url);
1247
1254
  return 0;
1248
1255
  }
1256
+ case 'transit': {
1257
+ const [city, station] = rest;
1258
+ const path = ['/api/v1/transit', city, station]
1259
+ .filter(Boolean)
1260
+ .map((p, i) => (i ? encodeURIComponent(p) : p))
1261
+ .join('/');
1262
+ const r = await client.get(path);
1263
+ if (json) {
1264
+ out(JSON.stringify(r, null, 2));
1265
+ return 0;
1266
+ }
1267
+ if (r.cities)
1268
+ for (const c of r.cities) out(`${pad(c.slug, 14)} ${c.name}: ${c.system} (${c.live})`);
1269
+ else if (r.arrivals) {
1270
+ out(`${r.station.name}: ${r.station.lines.join(', ')}`);
1271
+ if (!r.arrivals.length) out(' no live arrivals');
1272
+ for (const a of r.arrivals.slice(0, 15))
1273
+ out(
1274
+ ` ${pad(String(a.inMinutes === 0 ? 'now' : `${a.inMinutes} min`), 8)} ${pad(a.line ?? a.route ?? '', 14)} ${a.toward ?? ''}`,
1275
+ );
1276
+ } else {
1277
+ out(`${r.name}: ${r.system}`);
1278
+ out(
1279
+ ` ${r.lines.length} lines, ${r.stations.length} stations, ${r.alerts.length} alerts in force`,
1280
+ );
1281
+ for (const a of r.alerts.slice(0, 10)) out(` ! ${a.title}`);
1282
+ }
1283
+ return 0;
1284
+ }
1249
1285
  case 'business': {
1250
1286
  const qs = new URLSearchParams();
1251
1287
  const name = rest.join(' ');