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.
- package/dist/index.js +35 -20
- 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.
|
|
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(
|
|
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 (
|
|
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({
|
|
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:
|
|
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("\
|
|
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(
|
|
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:
|
|
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.
|
|
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);
|