@profullstack/nichedb 0.32.0 → 0.34.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.
- package/package.json +1 -1
- package/src/index.js +147 -1
package/package.json
CHANGED
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.
|
|
18
|
+
export const VERSION = '0.34.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');
|
|
@@ -189,6 +189,40 @@ export const COMMANDS = [
|
|
|
189
189
|
'Population from the world to the ZIP code: an area, its measures and its largest children.',
|
|
190
190
|
options: ['--level country|state|city|zip', '--limit', '--offset', '--json'],
|
|
191
191
|
},
|
|
192
|
+
{
|
|
193
|
+
name: 'tlds',
|
|
194
|
+
usage: 'tlds [<query>] [--registrar <slug>] [--type <t>] [--max-renew <n>] [--trap] [--sort …]',
|
|
195
|
+
summary:
|
|
196
|
+
"Top-level domains with each one's cheapest register, renew and transfer price, renewal first.",
|
|
197
|
+
options: [
|
|
198
|
+
'--registrar <porkbun|dynadot|cloudflare|ovh>',
|
|
199
|
+
'--type <generic|country-code|…>',
|
|
200
|
+
'--max-renew <n>',
|
|
201
|
+
'--max-register <n>',
|
|
202
|
+
'--trap (renews at 2x the first year or more)',
|
|
203
|
+
'--idn / --no-idn',
|
|
204
|
+
'--status <delegated|removed|all>',
|
|
205
|
+
'--sort <renew|register|transfer|ratio|tld|registrars|first_seen>',
|
|
206
|
+
'--order <asc|desc>',
|
|
207
|
+
'--limit',
|
|
208
|
+
'--csv',
|
|
209
|
+
'--json',
|
|
210
|
+
],
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: 'tld',
|
|
214
|
+
usage: 'tld <tld> | tld changes',
|
|
215
|
+
summary:
|
|
216
|
+
'One top-level domain: registry, RDAP server and every registrar price; or what changed in the root.',
|
|
217
|
+
options: ['--json'],
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: 'check',
|
|
221
|
+
usage: 'check <name> [--tlds com,dev,io]',
|
|
222
|
+
summary:
|
|
223
|
+
'Is a domain name registered? Asks the registry over RDAP; a bare word is tried under each ending.',
|
|
224
|
+
options: ['--tlds <list>', '--json'],
|
|
225
|
+
},
|
|
192
226
|
{
|
|
193
227
|
name: 'profiles',
|
|
194
228
|
usage: 'profiles [<query>] [--since <iso>] [--mine]',
|
|
@@ -805,6 +839,118 @@ export async function run(
|
|
|
805
839
|
}
|
|
806
840
|
return 0;
|
|
807
841
|
}
|
|
842
|
+
case 'tlds': {
|
|
843
|
+
const qs = new URLSearchParams();
|
|
844
|
+
const term = rest.join(' ');
|
|
845
|
+
if (term) qs.set('q', term);
|
|
846
|
+
for (const [flag, param] of [
|
|
847
|
+
['registrar', 'registrar'],
|
|
848
|
+
['type', 'type'],
|
|
849
|
+
['maxRenew', 'max_renew'],
|
|
850
|
+
['maxRegister', 'max_register'],
|
|
851
|
+
['status', 'status'],
|
|
852
|
+
['sort', 'sort'],
|
|
853
|
+
['order', 'order'],
|
|
854
|
+
['limit', 'limit'],
|
|
855
|
+
['offset', 'offset'],
|
|
856
|
+
['manager', 'manager'],
|
|
857
|
+
['band', 'band'],
|
|
858
|
+
])
|
|
859
|
+
if (flags[flag] !== undefined && flags[flag] !== true) qs.set(param, flags[flag]);
|
|
860
|
+
if (flags.trap) qs.set('trap', '1');
|
|
861
|
+
if (flags.idn) qs.set('idn', '1');
|
|
862
|
+
if (flags.noIdn) qs.set('idn', '0');
|
|
863
|
+
if (flags.csv) {
|
|
864
|
+
qs.set('format', 'csv');
|
|
865
|
+
const res = await fetchImpl(`${api}/api/v1/tlds?${qs}`);
|
|
866
|
+
out((await res.text()).trimEnd());
|
|
867
|
+
return 0;
|
|
868
|
+
}
|
|
869
|
+
const r = await client.get(`/api/v1/tlds?${qs}`);
|
|
870
|
+
if (json) {
|
|
871
|
+
out(JSON.stringify(r, null, 2));
|
|
872
|
+
return 0;
|
|
873
|
+
}
|
|
874
|
+
const m = (p) =>
|
|
875
|
+
p ? `${p.amount.toFixed(2)} ${p.currency === 'USD' ? '' : p.currency}`.trim() : '-';
|
|
876
|
+
out(
|
|
877
|
+
`${pad('TLD', 22)} ${pad('REGISTER', 10)} ${pad('RENEW', 10)} ${pad('x', 5)} ${pad('TRANSFER', 10)} ${pad('CHEAPEST RENEWAL AT', 22)} REGISTRY`,
|
|
878
|
+
);
|
|
879
|
+
for (const t of r.tlds) {
|
|
880
|
+
out(
|
|
881
|
+
`${pad(`.${t.unicode ?? t.tld}`, 22)} ${pad(m(t.best?.register), 10)} ${pad(m(t.best?.renew), 10)} ${pad(t.renewal_ratio ? `${t.renewal_ratio}x` : '', 5)} ${pad(m(t.best?.transfer), 10)} ${pad(t.best?.renew?.registrar_name ?? '', 22)} ${t.manager ?? ''}`,
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
out(`(${r.tlds.length} of ${r.total}${r.compare_currency ? '; cheapest in USD' : ''})`);
|
|
885
|
+
return 0;
|
|
886
|
+
}
|
|
887
|
+
case 'tld': {
|
|
888
|
+
const [arg] = rest;
|
|
889
|
+
if (!arg) throw new Error('tld <tld> | tld changes');
|
|
890
|
+
if (arg === 'changes') {
|
|
891
|
+
const r = await client.get('/api/v1/tlds/changes');
|
|
892
|
+
if (json) {
|
|
893
|
+
out(JSON.stringify(r.changes, null, 2));
|
|
894
|
+
return 0;
|
|
895
|
+
}
|
|
896
|
+
for (const c of r.changes)
|
|
897
|
+
out(
|
|
898
|
+
`${when(c.at)} ${pad(c.change, 8)} .${pad(c.unicode ?? c.tld, 24)} ${c.list_version ?? ''}`,
|
|
899
|
+
);
|
|
900
|
+
if (!r.changes.length) out('(no changes since tracking began)');
|
|
901
|
+
return 0;
|
|
902
|
+
}
|
|
903
|
+
const t = await client.get(`/api/v1/tlds/${encodeURIComponent(arg.replace(/^\./, ''))}`);
|
|
904
|
+
if (json) {
|
|
905
|
+
out(JSON.stringify(t, null, 2));
|
|
906
|
+
return 0;
|
|
907
|
+
}
|
|
908
|
+
out(`.${t.unicode ?? t.tld}${t.unicode ? ` (${t.tld})` : ''} ${t.status} ${t.type ?? ''}`);
|
|
909
|
+
out(`registry ${t.manager ?? '-'}`);
|
|
910
|
+
out(`rdap ${t.rdap ?? 'none published'}`);
|
|
911
|
+
out('');
|
|
912
|
+
out(
|
|
913
|
+
`${pad('REGISTRAR', 24)} ${pad('CUR', 4)} ${pad('REGISTER', 10)} ${pad('RENEW', 10)} ${pad('TRANSFER', 10)} RESTORE`,
|
|
914
|
+
);
|
|
915
|
+
const f = (v) => (v === null || v === undefined ? '-' : Number(v).toFixed(2));
|
|
916
|
+
for (const p of t.prices)
|
|
917
|
+
out(
|
|
918
|
+
`${pad(p.registrar_name, 24)} ${pad(p.currency, 4)} ${pad(f(p.register), 10)} ${pad(f(p.renew), 10)} ${pad(f(p.transfer), 10)} ${f(p.restore)}`,
|
|
919
|
+
);
|
|
920
|
+
if (!t.prices.length) out('(no registrar read here sells it)');
|
|
921
|
+
out(`\n${t.page}`);
|
|
922
|
+
return 0;
|
|
923
|
+
}
|
|
924
|
+
case 'check': {
|
|
925
|
+
const name = rest.join(',');
|
|
926
|
+
if (!name) throw new Error('check <name> [--tlds com,dev,io]');
|
|
927
|
+
const qs = new URLSearchParams({ name });
|
|
928
|
+
if (flags.tlds && flags.tlds !== true) qs.set('tlds', flags.tlds);
|
|
929
|
+
const r = await client.get(`/api/v1/tlds/check?${qs}`);
|
|
930
|
+
if (json) {
|
|
931
|
+
out(JSON.stringify(r, null, 2));
|
|
932
|
+
return 0;
|
|
933
|
+
}
|
|
934
|
+
const word = {
|
|
935
|
+
registered: 'taken',
|
|
936
|
+
not_registered: 'not registered',
|
|
937
|
+
unknown: 'unknown',
|
|
938
|
+
invalid: 'invalid',
|
|
939
|
+
};
|
|
940
|
+
for (const x of r.results) {
|
|
941
|
+
const detail =
|
|
942
|
+
x.status === 'registered'
|
|
943
|
+
? `${x.registrar ?? ''}${x.expires ? `, expires ${String(x.expires).slice(0, 10)}` : ''}`
|
|
944
|
+
: x.status === 'not_registered'
|
|
945
|
+
? x.cheapest?.register
|
|
946
|
+
? `from ${x.cheapest.register.amount.toFixed(2)} at ${x.cheapest.register.registrar_name}, renews ${x.cheapest.renew?.amount?.toFixed(2) ?? '?'}`
|
|
947
|
+
: ''
|
|
948
|
+
: (x.reason ?? '');
|
|
949
|
+
out(`${pad(x.name, 32)} ${pad(word[x.status] ?? x.status, 15)} ${detail}`);
|
|
950
|
+
}
|
|
951
|
+
if (r.truncated) out('(only the first names were checked)');
|
|
952
|
+
return 0;
|
|
953
|
+
}
|
|
808
954
|
case 'profiles': {
|
|
809
955
|
const term = rest.join(' ');
|
|
810
956
|
const qs = new URLSearchParams();
|