greybull 0.2.3 → 0.2.4

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 +35 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -94,7 +94,7 @@ var ApiError = class extends Error {
94
94
  this.status = status;
95
95
  }
96
96
  };
97
- var VERSION = "0.2.3";
97
+ var VERSION = "0.2.4";
98
98
  function buildRequest(opts) {
99
99
  const url = new URL(opts.apiUrl.replace(/\/+$/, "") + opts.path);
100
100
  if (opts.query) {
@@ -148,6 +148,17 @@ async function apiRequest(opts) {
148
148
  }
149
149
 
150
150
  // src/output.ts
151
+ var COLOR = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
152
+ function paint(code, s) {
153
+ return COLOR ? `\x1B[${code}m${s}\x1B[0m` : s;
154
+ }
155
+ var color = {
156
+ red: (s) => paint("31", s),
157
+ green: (s) => paint("32", s),
158
+ yellow: (s) => paint("33", s),
159
+ bold: (s) => paint("1", s),
160
+ dim: (s) => paint("2", s)
161
+ };
151
162
  function formatTable(headers, rows, opts = {}) {
152
163
  if (rows.length === 0) return "(none)";
153
164
  const max = opts.max ?? [];
@@ -175,7 +186,7 @@ Run 'greybull login' to authenticate (or set GREYBULL_API_KEY).`;
175
186
  Your API key is missing a required scope \u2014 create one with DNS/domain permissions at ${opts.apiUrl}/api-settings.`;
176
187
  }
177
188
  }
178
- process.stderr.write(`Error: ${message}
189
+ process.stderr.write(`${color.red(color.bold("Error:"))} ${color.red(message)}
179
190
  `);
180
191
  process.exit(1);
181
192
  }
@@ -478,7 +489,7 @@ function renderZoneFile(zone, records) {
478
489
  "; -*- mode: dns -*-",
479
490
  `; Zone: ${zone}`,
480
491
  "; Edit records below, then save and close your editor to apply.",
481
- "; Format: NAME TTL TYPE CONTENT (use @ for the zone apex)",
492
+ "; Format: NAME [TTL] TYPE CONTENT (@ = apex; TTL optional, default 3600)",
482
493
  "; TXT values keep their quotes; MX/SRV keep priority in CONTENT.",
483
494
  "; SOA and the apex NS records are managed for you and not shown.",
484
495
  ";"
@@ -494,12 +505,17 @@ function parseZoneFile(text) {
494
505
  for (let i = 0; i < lines.length; i++) {
495
506
  const trimmed = lines[i].trim();
496
507
  if (!trimmed || trimmed.startsWith(";")) continue;
497
- const m = trimmed.match(/^(\S+)\s+(\d+)\s+(?:IN\s+)?([A-Za-z][A-Za-z0-9]*)\s+(.+)$/i);
508
+ const m = trimmed.match(/^(\S+)\s+(?:(\d+)\s+)?(?:IN\s+)?([A-Za-z][A-Za-z0-9]*)\s+(.+)$/i);
498
509
  if (!m) {
499
- throw new Error(`line ${i + 1}: could not parse "${trimmed}" (expected: NAME TTL TYPE CONTENT)`);
510
+ throw new Error(`line ${i + 1}: could not parse "${trimmed}" (expected: NAME [TTL] TYPE CONTENT)`);
500
511
  }
501
512
  const [, name, ttlStr, typeRaw, content] = m;
502
- recs.push({ name, type: typeRaw.toUpperCase(), content: content.trim(), ttl: parseInt(ttlStr) });
513
+ recs.push({
514
+ name,
515
+ type: typeRaw.toUpperCase(),
516
+ content: content.trim(),
517
+ ttl: ttlStr ? parseInt(ttlStr) : 3600
518
+ });
503
519
  }
504
520
  return recs;
505
521
  }
@@ -577,9 +593,9 @@ async function editCmd(ctx2, zone) {
577
593
  try {
578
594
  records = parseZoneFile(edited);
579
595
  } catch (err) {
580
- process.stdout.write(`
581
- Error parsing the zone: ${err.message}
582
- `);
596
+ process.stdout.write(
597
+ "\n" + color.red(color.bold("Error parsing the zone: ") + err.message) + "\n"
598
+ );
583
599
  const c2 = await prompt(
584
600
  "Options are: (e)dit your changes, (r)etry with original zone, (a)bort? [e] ",
585
601
  ["e", "r", "a"],
@@ -594,11 +610,9 @@ Error parsing the zone: ${err.message}
594
610
  if (added.length === 0 && removed.length === 0) {
595
611
  return void process.stdout.write("No changes.\n");
596
612
  }
597
- process.stdout.write("\nChanges to apply:\n");
598
- removed.forEach((l) => process.stdout.write(` - ${l}
599
- `));
600
- added.forEach((l) => process.stdout.write(` + ${l}
601
- `));
613
+ process.stdout.write("\n" + color.bold("Changes to apply:") + "\n");
614
+ removed.forEach((l) => process.stdout.write(color.red(` - ${l}`) + "\n"));
615
+ added.forEach((l) => process.stdout.write(color.green(` + ${l}`) + "\n"));
602
616
  process.stdout.write("\n");
603
617
  const c = await prompt(
604
618
  "(a)pply these changes, (e)dit again, (r)etry with original zone, (q)uit? [a] ",
@@ -622,14 +636,15 @@ Error parsing the zone: ${err.message}
622
636
  path: `/api/v1/dns/zones/${encodeURIComponent(zone)}`,
623
637
  body: { records }
624
638
  });
625
- process.stdout.write(`Applied. ${zone} now has ${put.data.applied} record(s).
626
- `);
639
+ process.stdout.write(
640
+ color.green(`Applied. ${zone} now has ${put.data.applied} record(s).`) + "\n"
641
+ );
627
642
  return;
628
643
  } catch (err) {
629
644
  if (err instanceof ApiError && (err.status === 422 || err.status === 400)) {
630
- process.stdout.write(`
631
- The DNS server rejected the zone: ${err.message}
632
- `);
645
+ process.stdout.write(
646
+ "\n" + color.red(color.bold("The DNS server rejected the zone: ") + err.message) + "\n"
647
+ );
633
648
  const c2 = await prompt(
634
649
  "Options are: (e)dit your changes, (r)etry with original zone, (a)bort? [e] ",
635
650
  ["e", "r", "a"],
@@ -684,7 +699,7 @@ async function domainsCheckCmd(ctx2, query, opts) {
684
699
 
685
700
  // src/index.ts
686
701
  var program = new Command();
687
- program.name("greybull").description("Manage Greybull DNS records and domains from the command line").version("0.2.3").option("--json", "output raw JSON", false).option("--api-url <url>", "portal base URL (or set GREYBULL_API_URL)");
702
+ program.name("greybull").description("Manage Greybull DNS records and domains from the command line").version("0.2.4").option("--json", "output raw JSON", false).option("--api-url <url>", "portal base URL (or set GREYBULL_API_URL)");
688
703
  function ctx(requireAuth = true) {
689
704
  const opts = program.opts();
690
705
  const apiUrl = resolveApiUrl(opts.apiUrl);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "greybull",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Command-line tool for the Greybull portal — manage DNS records and domains",
5
5
  "type": "module",
6
6
  "bin": {