@gusnips/one-click-dns 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +151 -2
- package/dist/bounded-fetch-nozW2egX.d.cts +5 -0
- package/dist/bounded-fetch-nozW2egX.d.ts +5 -0
- package/dist/chunk-2T2PEF4H.js +521 -0
- package/dist/chunk-56ZUD4EQ.js +525 -0
- package/dist/chunk-P2O7INDB.js +8 -0
- package/dist/hosts-B0_V4Ned.d.cts +106 -0
- package/dist/hosts-B0_V4Ned.d.ts +106 -0
- package/dist/index.cjs +745 -0
- package/dist/index.d.cts +119 -0
- package/dist/index.d.ts +119 -0
- package/dist/index.js +198 -0
- package/dist/server/index.cjs +1320 -0
- package/dist/server/index.d.cts +145 -0
- package/dist/server/index.d.ts +145 -0
- package/dist/server/index.js +274 -0
- package/dist/writers/index.cjs +555 -0
- package/dist/writers/index.d.cts +64 -0
- package/dist/writers/index.d.ts +64 -0
- package/dist/writers/index.js +17 -0
- package/package.json +93 -4
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,745 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
DNS_HOSTS: () => DNS_HOSTS,
|
|
24
|
+
DNS_HOST_IDS: () => DNS_HOST_IDS,
|
|
25
|
+
cnameTemplate: () => cnameTemplate,
|
|
26
|
+
detectDnsHosts: () => detectDnsHosts,
|
|
27
|
+
dkimTemplate: () => dkimTemplate,
|
|
28
|
+
dmarcTemplate: () => dmarcTemplate,
|
|
29
|
+
dnsRecordRow: () => dnsRecordRow,
|
|
30
|
+
mxTemplate: () => mxTemplate,
|
|
31
|
+
normalizeDnsName: () => normalizeDnsName,
|
|
32
|
+
recordNameInZone: () => recordNameInZone,
|
|
33
|
+
relativeName: () => relativeName,
|
|
34
|
+
spfTemplate: () => spfTemplate,
|
|
35
|
+
templateFileName: () => templateFileName,
|
|
36
|
+
trapOf: () => trapOf,
|
|
37
|
+
verificationTemplate: () => verificationTemplate
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
|
+
|
|
41
|
+
// src/dns-name.ts
|
|
42
|
+
function normalizeDnsName(name) {
|
|
43
|
+
return name.trim().toLowerCase().replace(/\.$/, "");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/hosts.ts
|
|
47
|
+
var DNS_HOST_IDS = [
|
|
48
|
+
"cloudflare",
|
|
49
|
+
"godaddy",
|
|
50
|
+
"namecheap",
|
|
51
|
+
"namecheap-hosting",
|
|
52
|
+
"squarespace",
|
|
53
|
+
"route53",
|
|
54
|
+
"google-cloud-dns",
|
|
55
|
+
"azure-dns",
|
|
56
|
+
"ionos",
|
|
57
|
+
"hostinger",
|
|
58
|
+
"porkbun",
|
|
59
|
+
"name-com",
|
|
60
|
+
"dynadot",
|
|
61
|
+
"namesilo",
|
|
62
|
+
"gandi",
|
|
63
|
+
"ovhcloud",
|
|
64
|
+
"digitalocean",
|
|
65
|
+
"hetzner",
|
|
66
|
+
"vercel",
|
|
67
|
+
"netlify",
|
|
68
|
+
"wix",
|
|
69
|
+
"wordpress-com",
|
|
70
|
+
"cpanel",
|
|
71
|
+
"bluehost",
|
|
72
|
+
"hostgator",
|
|
73
|
+
"hostgator-br",
|
|
74
|
+
"siteground",
|
|
75
|
+
"registro-br",
|
|
76
|
+
"locaweb",
|
|
77
|
+
"kinghost",
|
|
78
|
+
"uol-host",
|
|
79
|
+
"umbler",
|
|
80
|
+
"dnsimple"
|
|
81
|
+
];
|
|
82
|
+
var NO_FIELDS = { name: null, value: null };
|
|
83
|
+
var SHORT = { kind: "shortName" };
|
|
84
|
+
var TRAILING_DOT = { kind: "trailingDot" };
|
|
85
|
+
var QUOTED_TXT = { kind: "quotedTxt" };
|
|
86
|
+
var CPANEL_EDITOR = {
|
|
87
|
+
link: null,
|
|
88
|
+
open: "Zone Editor",
|
|
89
|
+
add: "Add Record",
|
|
90
|
+
save: "Save Record",
|
|
91
|
+
cname: { name: "Name", value: "Record" },
|
|
92
|
+
txt: { name: "Name", value: "Record" },
|
|
93
|
+
root: null,
|
|
94
|
+
traps: []
|
|
95
|
+
};
|
|
96
|
+
var DNS_HOSTS = {
|
|
97
|
+
cloudflare: {
|
|
98
|
+
name: "Cloudflare",
|
|
99
|
+
// Documented: <name>.ns.cloudflare.com, and <color>.foundationdns.{com,net,org}.
|
|
100
|
+
ns: [/^[a-z0-9-]+\.ns\.cloudflare\.com$/, /^[a-z0-9-]+\.foundationdns\.(com|net|org)$/],
|
|
101
|
+
link: "https://dash.cloudflare.com/?to=/:account/:zone/dns/records",
|
|
102
|
+
open: "DNS Records",
|
|
103
|
+
add: "Add record",
|
|
104
|
+
save: "Save",
|
|
105
|
+
cname: { name: "Name", value: "Target" },
|
|
106
|
+
// The dashboard's label for a TXT value is not on a docs page.
|
|
107
|
+
txt: { name: "Name", value: null },
|
|
108
|
+
root: "@",
|
|
109
|
+
traps: [{ kind: "proxyOff", field: "Proxy status", value: "DNS only" }, SHORT]
|
|
110
|
+
},
|
|
111
|
+
godaddy: {
|
|
112
|
+
name: "GoDaddy",
|
|
113
|
+
// Observed: ns<NN>.domaincontrol.com (GoDaddy's docs show only ns1).
|
|
114
|
+
ns: [/^ns\d{1,2}\.domaincontrol\.com$/],
|
|
115
|
+
link: null,
|
|
116
|
+
open: "DNS",
|
|
117
|
+
add: "Add New Record",
|
|
118
|
+
save: "Save",
|
|
119
|
+
cname: { name: "Name", value: "Value" },
|
|
120
|
+
txt: { name: "Name", value: "Value" },
|
|
121
|
+
root: "@",
|
|
122
|
+
traps: [SHORT]
|
|
123
|
+
},
|
|
124
|
+
namecheap: {
|
|
125
|
+
name: "Namecheap",
|
|
126
|
+
// Documented: dns1/2.registrar-servers.com (BasicDNS), pdns1/2 (PremiumDNS),
|
|
127
|
+
// freedns1-5 (FreeDNS).
|
|
128
|
+
ns: [/^(dns|pdns|freedns)\d\.registrar-servers\.com$/],
|
|
129
|
+
link: null,
|
|
130
|
+
open: "Advanced DNS",
|
|
131
|
+
add: "Add New Record",
|
|
132
|
+
save: "Save All Changes",
|
|
133
|
+
cname: { name: "Host", value: "Value" },
|
|
134
|
+
txt: { name: "Host", value: "Value" },
|
|
135
|
+
root: "@",
|
|
136
|
+
traps: [SHORT]
|
|
137
|
+
},
|
|
138
|
+
"namecheap-hosting": {
|
|
139
|
+
name: "Namecheap hosting",
|
|
140
|
+
// Documented: dns1/2.namecheaphosting.com. The records live in cPanel, not Advanced DNS.
|
|
141
|
+
ns: [/^dns\d\.namecheaphosting\.com$/],
|
|
142
|
+
...CPANEL_EDITOR
|
|
143
|
+
},
|
|
144
|
+
squarespace: {
|
|
145
|
+
name: "Squarespace",
|
|
146
|
+
ns: [
|
|
147
|
+
// Documented: Google Cloud DNS nameservers "ending in squarespacedns.com".
|
|
148
|
+
/^[a-z0-9-]+\.squarespacedns\.com$/,
|
|
149
|
+
// Observed, listed so that these names read as ambiguous (domains moved from Google
|
|
150
|
+
// Domains sit on Google's names; older Squarespace domains on NS1's).
|
|
151
|
+
/^ns-cloud-[a-z]\d\.googledomains\.com$/,
|
|
152
|
+
/^dns\d\.p\d{2}\.nsone\.net$/
|
|
153
|
+
],
|
|
154
|
+
link: null,
|
|
155
|
+
open: "DNS Settings",
|
|
156
|
+
add: "Add record",
|
|
157
|
+
save: "Save",
|
|
158
|
+
cname: { name: "Name", value: "Data" },
|
|
159
|
+
txt: { name: "Name", value: "Text" },
|
|
160
|
+
root: "@",
|
|
161
|
+
traps: [SHORT]
|
|
162
|
+
},
|
|
163
|
+
route53: {
|
|
164
|
+
name: "Amazon Route 53",
|
|
165
|
+
// Documented: ns-<n>.awsdns-<nn>.{com,net,org,co.uk}.
|
|
166
|
+
ns: [/^ns-\d+\.awsdns-\d+\.(com|net|org|co\.uk)$/],
|
|
167
|
+
link: "https://console.aws.amazon.com/route53/v2/hostedzones",
|
|
168
|
+
open: "Hosted zones",
|
|
169
|
+
add: "Create record",
|
|
170
|
+
save: "Create records",
|
|
171
|
+
cname: { name: "Record name", value: "Value" },
|
|
172
|
+
txt: { name: "Record name", value: "Value" },
|
|
173
|
+
// "don't enter a value (for example, an @ symbol) in the Name field".
|
|
174
|
+
root: "",
|
|
175
|
+
traps: [SHORT, QUOTED_TXT]
|
|
176
|
+
},
|
|
177
|
+
"google-cloud-dns": {
|
|
178
|
+
name: "Google Cloud DNS",
|
|
179
|
+
// Documented: ns-cloud-<a-d><1-4>.googledomains.com. Squarespace domains moved from
|
|
180
|
+
// Google Domains use the same names, so a set of them is ambiguous.
|
|
181
|
+
ns: [/^ns-cloud-[a-z]\d\.googledomains\.com$/],
|
|
182
|
+
link: null,
|
|
183
|
+
open: null,
|
|
184
|
+
add: "Add standard",
|
|
185
|
+
save: "Create",
|
|
186
|
+
cname: { name: "DNS name", value: null },
|
|
187
|
+
txt: { name: "DNS name", value: null },
|
|
188
|
+
// "To create a resource record at the domain apex, leave the DNS name field blank."
|
|
189
|
+
root: "",
|
|
190
|
+
traps: [SHORT]
|
|
191
|
+
},
|
|
192
|
+
"azure-dns": {
|
|
193
|
+
name: "Azure DNS",
|
|
194
|
+
// Documented: ns<1-4>-<nn>.azure-dns.{com,net,org,info}.
|
|
195
|
+
ns: [/^ns\d-\d+\.azure-dns\.(com|net|org|info)$/],
|
|
196
|
+
link: null,
|
|
197
|
+
open: "Record sets",
|
|
198
|
+
add: "Add",
|
|
199
|
+
save: "Add",
|
|
200
|
+
cname: { name: "Name", value: null },
|
|
201
|
+
txt: { name: "Name", value: null },
|
|
202
|
+
root: "@",
|
|
203
|
+
traps: [SHORT]
|
|
204
|
+
},
|
|
205
|
+
ionos: {
|
|
206
|
+
name: "IONOS",
|
|
207
|
+
// Documented: ns1<ZZZ>.ui-dns.{de,biz,org,com}, ZZZ from 016 to 126.
|
|
208
|
+
ns: [/^ns1\d{3}\.ui-dns\.(de|biz|org|com)$/],
|
|
209
|
+
link: null,
|
|
210
|
+
open: "DNS",
|
|
211
|
+
add: "Add Record",
|
|
212
|
+
save: "Save",
|
|
213
|
+
// The two articles spell the name box differently.
|
|
214
|
+
cname: { name: "Hostname", value: "Point to" },
|
|
215
|
+
txt: { name: "Host name", value: "Value" },
|
|
216
|
+
root: "@",
|
|
217
|
+
traps: [SHORT]
|
|
218
|
+
},
|
|
219
|
+
hostinger: {
|
|
220
|
+
name: "Hostinger",
|
|
221
|
+
// No pattern: ns1/2.dns-parking.com is a search snippet, never confirmed on a page of
|
|
222
|
+
// theirs. The picker reaches Hostinger.
|
|
223
|
+
ns: [],
|
|
224
|
+
link: null,
|
|
225
|
+
open: "DNS Zone Editor",
|
|
226
|
+
add: null,
|
|
227
|
+
save: "Add Record",
|
|
228
|
+
cname: { name: "Name", value: "Points to" },
|
|
229
|
+
txt: { name: "Name", value: "TXT value" },
|
|
230
|
+
root: "@",
|
|
231
|
+
traps: [SHORT, { kind: "oneSpf" }]
|
|
232
|
+
},
|
|
233
|
+
porkbun: {
|
|
234
|
+
name: "Porkbun",
|
|
235
|
+
// Documented: <city>.ns.porkbun.com.
|
|
236
|
+
ns: [/^[a-z]+\.ns\.porkbun\.com$/],
|
|
237
|
+
link: null,
|
|
238
|
+
open: "DNS",
|
|
239
|
+
add: "Add Record",
|
|
240
|
+
save: "Add",
|
|
241
|
+
cname: { name: "Host", value: "Answer" },
|
|
242
|
+
txt: { name: "Host", value: "Answer" },
|
|
243
|
+
// "If you're adding DNS records to your root domain, you will leave this field blank."
|
|
244
|
+
root: "",
|
|
245
|
+
traps: [SHORT]
|
|
246
|
+
},
|
|
247
|
+
"name-com": {
|
|
248
|
+
name: "Name.com",
|
|
249
|
+
// Observed: ns1<abc>.name.com to ns4<abc>.name.com.
|
|
250
|
+
ns: [/^ns[1-4][a-z]{3}\.name\.com$/],
|
|
251
|
+
link: null,
|
|
252
|
+
open: "Manage DNS Records",
|
|
253
|
+
add: null,
|
|
254
|
+
save: "Add Record",
|
|
255
|
+
cname: { name: "Host", value: "Answer" },
|
|
256
|
+
txt: { name: "Host", value: "Answer" },
|
|
257
|
+
root: null,
|
|
258
|
+
traps: [SHORT]
|
|
259
|
+
},
|
|
260
|
+
dynadot: {
|
|
261
|
+
name: "Dynadot",
|
|
262
|
+
// A Dynadot staff answer on its forum: ns1/2.dyna-ns.net.
|
|
263
|
+
ns: [/^ns\d\.dyna-ns\.net$/],
|
|
264
|
+
link: null,
|
|
265
|
+
open: "DNS Settings",
|
|
266
|
+
add: null,
|
|
267
|
+
save: "Save Settings",
|
|
268
|
+
cname: { name: "Subdomain Record", value: "IP Address or Target Host" },
|
|
269
|
+
txt: NO_FIELDS,
|
|
270
|
+
// The zone's own name goes in a separate "Domain Record" section, never as "@".
|
|
271
|
+
root: null,
|
|
272
|
+
traps: [SHORT]
|
|
273
|
+
},
|
|
274
|
+
namesilo: {
|
|
275
|
+
name: "NameSilo",
|
|
276
|
+
// Documented: ns1-3.dnsowl.com.
|
|
277
|
+
ns: [/^ns\d\.dnsowl\.com$/],
|
|
278
|
+
link: null,
|
|
279
|
+
open: null,
|
|
280
|
+
add: null,
|
|
281
|
+
save: "Submit",
|
|
282
|
+
cname: NO_FIELDS,
|
|
283
|
+
txt: NO_FIELDS,
|
|
284
|
+
// "You can leave the hostname blank ... If you do enter an "@", we will convert that".
|
|
285
|
+
root: "",
|
|
286
|
+
traps: []
|
|
287
|
+
},
|
|
288
|
+
gandi: {
|
|
289
|
+
name: "Gandi",
|
|
290
|
+
// Observed: ns-<n>-<a|b|c>.gandi.net.
|
|
291
|
+
ns: [/^ns-\d+-[abc]\.gandi\.net$/],
|
|
292
|
+
link: null,
|
|
293
|
+
open: "DNS Records",
|
|
294
|
+
add: "Add",
|
|
295
|
+
save: null,
|
|
296
|
+
cname: NO_FIELDS,
|
|
297
|
+
txt: NO_FIELDS,
|
|
298
|
+
root: null,
|
|
299
|
+
traps: [SHORT]
|
|
300
|
+
},
|
|
301
|
+
ovhcloud: {
|
|
302
|
+
name: "OVHcloud",
|
|
303
|
+
// Documented: (ns|dns)<nn or nnn>.ovh.net, and (ns|dns)200.anycast.me.
|
|
304
|
+
ns: [/^(ns|dns)\d{2,3}\.ovh\.net$/, /^(ns|dns)200\.anycast\.me$/],
|
|
305
|
+
link: null,
|
|
306
|
+
open: "DNS zone",
|
|
307
|
+
add: "Add an entry",
|
|
308
|
+
save: null,
|
|
309
|
+
cname: { name: "Subdomain", value: "Target" },
|
|
310
|
+
txt: { name: "Subdomain", value: "Target" },
|
|
311
|
+
root: null,
|
|
312
|
+
traps: [SHORT, TRAILING_DOT]
|
|
313
|
+
},
|
|
314
|
+
digitalocean: {
|
|
315
|
+
name: "DigitalOcean",
|
|
316
|
+
// Documented: ns1-3.digitalocean.com.
|
|
317
|
+
ns: [/^ns[1-3]\.digitalocean\.com$/],
|
|
318
|
+
link: null,
|
|
319
|
+
open: "Domains",
|
|
320
|
+
add: "Create a record",
|
|
321
|
+
save: "Create Record",
|
|
322
|
+
cname: { name: "Hostname", value: "Is an alias of" },
|
|
323
|
+
txt: { name: "Hostname", value: "TXT Value" },
|
|
324
|
+
root: "@",
|
|
325
|
+
traps: [SHORT, TRAILING_DOT]
|
|
326
|
+
},
|
|
327
|
+
hetzner: {
|
|
328
|
+
name: "Hetzner",
|
|
329
|
+
ns: [
|
|
330
|
+
// Documented: the primary, secondary (still used by older zones) and konsoleH names.
|
|
331
|
+
/^(hydrogen|oxygen|helium)\.ns\.hetzner\.(com|de)$/,
|
|
332
|
+
/^[a-z0-9]+\.first-ns\.de$/,
|
|
333
|
+
/^[a-z0-9]+\.second-ns\.(de|com)$/,
|
|
334
|
+
/^ns1\.your-server\.de$/
|
|
335
|
+
],
|
|
336
|
+
link: null,
|
|
337
|
+
open: "DNS",
|
|
338
|
+
add: null,
|
|
339
|
+
save: "Add",
|
|
340
|
+
cname: { name: "Name", value: "Alias / Value" },
|
|
341
|
+
txt: { name: "Name", value: null },
|
|
342
|
+
root: "@",
|
|
343
|
+
traps: [SHORT, TRAILING_DOT, QUOTED_TXT]
|
|
344
|
+
},
|
|
345
|
+
vercel: {
|
|
346
|
+
name: "Vercel",
|
|
347
|
+
// Documented: ns1-4.vercel-dns.com (the "alternates" are not named).
|
|
348
|
+
ns: [/^ns[1-4]\.vercel-dns\.com$/],
|
|
349
|
+
link: "https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fdomains",
|
|
350
|
+
open: "Domains",
|
|
351
|
+
add: null,
|
|
352
|
+
save: "Add",
|
|
353
|
+
cname: { name: "Name", value: "Value" },
|
|
354
|
+
txt: { name: "Name", value: "Value" },
|
|
355
|
+
// "Leave Name blank for the root domain."
|
|
356
|
+
root: "",
|
|
357
|
+
traps: [SHORT]
|
|
358
|
+
},
|
|
359
|
+
netlify: {
|
|
360
|
+
name: "Netlify",
|
|
361
|
+
// Documented: "a format similar to dns1.p01.nsone.net". NS1's names are shared with
|
|
362
|
+
// older Squarespace zones, so a set of them is ambiguous.
|
|
363
|
+
ns: [/^dns\d\.p\d{2}\.nsone\.net$/],
|
|
364
|
+
link: null,
|
|
365
|
+
open: "DNS",
|
|
366
|
+
add: "Add new record",
|
|
367
|
+
save: "Save",
|
|
368
|
+
cname: NO_FIELDS,
|
|
369
|
+
txt: NO_FIELDS,
|
|
370
|
+
root: null,
|
|
371
|
+
traps: []
|
|
372
|
+
},
|
|
373
|
+
wix: {
|
|
374
|
+
name: "Wix",
|
|
375
|
+
// Observed: ns<n>.wixdns.net. A domain "connected to Wix via pointing" keeps its old
|
|
376
|
+
// name servers, so it never matches here.
|
|
377
|
+
ns: [/^ns\d+\.wixdns\.net$/],
|
|
378
|
+
link: null,
|
|
379
|
+
open: "Manage DNS Records",
|
|
380
|
+
add: "Add Record",
|
|
381
|
+
save: "Save",
|
|
382
|
+
cname: { name: "Host Name", value: "Value" },
|
|
383
|
+
txt: { name: "Host Name", value: "Value" },
|
|
384
|
+
// "Leave this field blank if you were instructed to add an @ sign."
|
|
385
|
+
root: "",
|
|
386
|
+
traps: []
|
|
387
|
+
},
|
|
388
|
+
"wordpress-com": {
|
|
389
|
+
name: "WordPress.com",
|
|
390
|
+
// Documented: ns1-3.wordpress.com.
|
|
391
|
+
ns: [/^ns[1-3]\.wordpress\.com$/],
|
|
392
|
+
link: "https://wordpress.com/domains/",
|
|
393
|
+
open: "DNS records",
|
|
394
|
+
add: "Add record",
|
|
395
|
+
save: null,
|
|
396
|
+
cname: { name: "Name (host)", value: "Alias of (points to)" },
|
|
397
|
+
txt: { name: "Name", value: "Text" },
|
|
398
|
+
root: "@",
|
|
399
|
+
// The Name box takes the label or the whole name, and ignores quotes around a TXT value.
|
|
400
|
+
traps: []
|
|
401
|
+
},
|
|
402
|
+
cpanel: {
|
|
403
|
+
// Hosting companies run their own name servers, so there is no pattern: the picker
|
|
404
|
+
// reaches it.
|
|
405
|
+
name: "cPanel",
|
|
406
|
+
ns: [],
|
|
407
|
+
...CPANEL_EDITOR
|
|
408
|
+
},
|
|
409
|
+
bluehost: {
|
|
410
|
+
name: "Bluehost",
|
|
411
|
+
// Documented: ns1/2.bluehost.com. Its help is behind a captcha and the menu path was
|
|
412
|
+
// read from a 2024 archive, so no label is quoted.
|
|
413
|
+
ns: [/^ns[12]\.bluehost\.com$/],
|
|
414
|
+
link: null,
|
|
415
|
+
open: null,
|
|
416
|
+
add: null,
|
|
417
|
+
save: null,
|
|
418
|
+
cname: NO_FIELDS,
|
|
419
|
+
txt: NO_FIELDS,
|
|
420
|
+
root: null,
|
|
421
|
+
traps: []
|
|
422
|
+
},
|
|
423
|
+
hostgator: {
|
|
424
|
+
name: "HostGator",
|
|
425
|
+
// Documented: hgns1/2.hostgator.com for new customers, ns<NNNN>.hostgator.com before
|
|
426
|
+
// November 2023.
|
|
427
|
+
ns: [/^hgns\d\.hostgator\.com$/, /^ns\d{4}\.hostgator\.com$/],
|
|
428
|
+
link: null,
|
|
429
|
+
open: "DNS",
|
|
430
|
+
add: "+ ADD RECORD",
|
|
431
|
+
save: "ADD",
|
|
432
|
+
cname: NO_FIELDS,
|
|
433
|
+
txt: NO_FIELDS,
|
|
434
|
+
root: null,
|
|
435
|
+
traps: []
|
|
436
|
+
},
|
|
437
|
+
"hostgator-br": {
|
|
438
|
+
name: "HostGator Brasil",
|
|
439
|
+
// Documented: dns3/4.hostgator.com.br for a registered domain with no plan yet. A plan's
|
|
440
|
+
// names come in its activation email and are not on a page.
|
|
441
|
+
ns: [/^dns[34]\.hostgator\.com\.br$/],
|
|
442
|
+
link: null,
|
|
443
|
+
open: "Editar Zona Avan\xE7ada de DNS",
|
|
444
|
+
add: "Adicionar registro",
|
|
445
|
+
save: "Adicionar",
|
|
446
|
+
// The value box's name changes with the type ("O nome é alterado conforme o Tipo").
|
|
447
|
+
cname: { name: "Nome", value: null },
|
|
448
|
+
txt: { name: "Nome", value: null },
|
|
449
|
+
root: null,
|
|
450
|
+
traps: []
|
|
451
|
+
},
|
|
452
|
+
siteground: {
|
|
453
|
+
name: "SiteGround",
|
|
454
|
+
// Documented: ns1/2.siteground.net.
|
|
455
|
+
ns: [/^ns[12]\.siteground\.net$/],
|
|
456
|
+
link: null,
|
|
457
|
+
open: "DNS Zone Editor",
|
|
458
|
+
add: null,
|
|
459
|
+
save: "Create",
|
|
460
|
+
cname: { name: "Name", value: null },
|
|
461
|
+
txt: { name: "Name", value: null },
|
|
462
|
+
root: null,
|
|
463
|
+
traps: [SHORT]
|
|
464
|
+
},
|
|
465
|
+
"registro-br": {
|
|
466
|
+
name: "Registro.br",
|
|
467
|
+
// Observed: a.auto.dns.br and b.auto.dns.br.
|
|
468
|
+
ns: [/^[ab]\.auto\.dns\.br$/],
|
|
469
|
+
link: null,
|
|
470
|
+
open: "CONFIGURAR ZONA DNS",
|
|
471
|
+
add: null,
|
|
472
|
+
save: null,
|
|
473
|
+
cname: NO_FIELDS,
|
|
474
|
+
txt: NO_FIELDS,
|
|
475
|
+
root: null,
|
|
476
|
+
traps: [{ kind: "advancedMode", mode: "Modo Avan\xE7ado" }]
|
|
477
|
+
},
|
|
478
|
+
locaweb: {
|
|
479
|
+
name: "Locaweb",
|
|
480
|
+
// Documented: ns1-3.locaweb.com.br.
|
|
481
|
+
ns: [/^ns[1-3]\.locaweb\.com\.br$/],
|
|
482
|
+
link: null,
|
|
483
|
+
open: "Editar zona DNS",
|
|
484
|
+
add: "Adicionar entrada",
|
|
485
|
+
save: null,
|
|
486
|
+
cname: { name: "Entrada", value: "Conte\xFAdo" },
|
|
487
|
+
txt: { name: "Entrada", value: "Conte\xFAdo" },
|
|
488
|
+
// "o campo Entrada é preenchido por padrão com apenas um ponto (.)".
|
|
489
|
+
root: ".",
|
|
490
|
+
traps: []
|
|
491
|
+
},
|
|
492
|
+
kinghost: {
|
|
493
|
+
name: "KingHost",
|
|
494
|
+
// Documented: dns1-6.kinghost.com.br.
|
|
495
|
+
ns: [/^dns[1-6]\.kinghost\.com\.br$/],
|
|
496
|
+
link: null,
|
|
497
|
+
open: "Gerenciar DNS",
|
|
498
|
+
add: "+ ADICIONAR DNS",
|
|
499
|
+
save: "ADICIONAR DNS",
|
|
500
|
+
// The form is a screenshot, so the case of "host" and "destino" is unconfirmed.
|
|
501
|
+
cname: NO_FIELDS,
|
|
502
|
+
txt: NO_FIELDS,
|
|
503
|
+
root: "@",
|
|
504
|
+
traps: [{ kind: "secondSave", button: "SALVAR ALTERA\xC7\xD5ES" }]
|
|
505
|
+
},
|
|
506
|
+
"uol-host": {
|
|
507
|
+
name: "UOL Host",
|
|
508
|
+
// Documented: ns1-3.dominios.uol.com.br.
|
|
509
|
+
ns: [/^ns[1-3]\.dominios\.uol\.com\.br$/],
|
|
510
|
+
link: null,
|
|
511
|
+
open: "Administrar DNS",
|
|
512
|
+
add: "Criar nova entrada",
|
|
513
|
+
save: "Salvar entrada",
|
|
514
|
+
cname: { name: "Entrada", value: "Destino" },
|
|
515
|
+
txt: { name: "Entrada", value: "Valor" },
|
|
516
|
+
root: "",
|
|
517
|
+
traps: []
|
|
518
|
+
},
|
|
519
|
+
umbler: {
|
|
520
|
+
name: "Umbler",
|
|
521
|
+
// Documented: ns<NNN>.umbler.{com,in,com.br,co.uk}.
|
|
522
|
+
ns: [/^ns\d{3}\.umbler\.(com|in|com\.br|co\.uk)$/],
|
|
523
|
+
link: null,
|
|
524
|
+
open: "Editor de DNS",
|
|
525
|
+
add: "Adicionar",
|
|
526
|
+
save: "Salvar",
|
|
527
|
+
cname: { name: "Nome", value: "Endere\xE7o" },
|
|
528
|
+
txt: { name: "Nome", value: "Dados" },
|
|
529
|
+
root: "@",
|
|
530
|
+
traps: [SHORT]
|
|
531
|
+
},
|
|
532
|
+
dnsimple: {
|
|
533
|
+
name: "DNSimple",
|
|
534
|
+
// Documented: ns1-4.dnsimple-edge.{com,net,io,org}, and the legacy ns1-4.dnsimple.com.
|
|
535
|
+
ns: [/^ns[1-4]\.dnsimple-edge\.(com|net|io|org)$/, /^ns[1-4]\.dnsimple\.com$/],
|
|
536
|
+
link: null,
|
|
537
|
+
open: "Record editor",
|
|
538
|
+
add: "Add record",
|
|
539
|
+
save: "Add Record",
|
|
540
|
+
cname: { name: "Name", value: "Content" },
|
|
541
|
+
txt: { name: "Name", value: "Content" },
|
|
542
|
+
root: "",
|
|
543
|
+
traps: [SHORT]
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
function trapOf(host, kind) {
|
|
547
|
+
return host.traps.find((trap) => trap.kind === kind);
|
|
548
|
+
}
|
|
549
|
+
function detectDnsHosts(nameservers) {
|
|
550
|
+
const names = nameservers.map(normalizeDnsName).filter(Boolean);
|
|
551
|
+
if (!names.length) return [];
|
|
552
|
+
return DNS_HOST_IDS.filter(
|
|
553
|
+
(id) => names.every((name) => DNS_HOSTS[id].ns.some((pattern) => pattern.test(name)))
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// src/records.ts
|
|
558
|
+
function relativeName(name, zone) {
|
|
559
|
+
if (!zone) return name;
|
|
560
|
+
if (name === zone) return "";
|
|
561
|
+
return name.endsWith(`.${zone}`) ? name.slice(0, -(zone.length + 1)) : name;
|
|
562
|
+
}
|
|
563
|
+
function recordNameInZone(name, zone) {
|
|
564
|
+
if (!zone) return null;
|
|
565
|
+
return relativeName(name, zone) || "@";
|
|
566
|
+
}
|
|
567
|
+
function dnsRecordRow(host, zone, spec) {
|
|
568
|
+
const data = host ? DNS_HOSTS[host] : null;
|
|
569
|
+
const relative = relativeName(spec.name, zone);
|
|
570
|
+
const atRoot = spec.type !== "CNAME" && relative === "";
|
|
571
|
+
const name = atRoot ? data?.root ?? "@" : relative || spec.name;
|
|
572
|
+
if (spec.type === "CNAME" || spec.type === "MX") {
|
|
573
|
+
const target = spec.value && data && trapOf(data, "trailingDot") ? `${spec.value}.` : spec.value;
|
|
574
|
+
if (spec.type === "CNAME")
|
|
575
|
+
return { type: "CNAME", name, value: target, atRoot: false, rootUnsure: false };
|
|
576
|
+
return {
|
|
577
|
+
type: "MX",
|
|
578
|
+
name,
|
|
579
|
+
value: target,
|
|
580
|
+
priority: spec.priority,
|
|
581
|
+
atRoot,
|
|
582
|
+
rootUnsure: atRoot && (!data || data.root === null)
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
return {
|
|
586
|
+
type: "TXT",
|
|
587
|
+
name,
|
|
588
|
+
value: spec.value && data && trapOf(data, "quotedTxt") ? `"${spec.value}"` : spec.value,
|
|
589
|
+
atRoot,
|
|
590
|
+
rootUnsure: atRoot && (!data || data.root === null)
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// src/templates.ts
|
|
595
|
+
var TTL = 3600;
|
|
596
|
+
function template(identity, serviceId, fallback, wording, records, hostRequired) {
|
|
597
|
+
return {
|
|
598
|
+
providerId: identity.providerId,
|
|
599
|
+
providerName: identity.providerName,
|
|
600
|
+
serviceId: wording.serviceId ?? serviceId,
|
|
601
|
+
serviceName: wording.serviceName ?? fallback.serviceName,
|
|
602
|
+
version: wording.version ?? 1,
|
|
603
|
+
logoUrl: identity.logoUrl,
|
|
604
|
+
description: wording.description ?? fallback.description,
|
|
605
|
+
...fallback.variableDescription ? { variableDescription: fallback.variableDescription } : {},
|
|
606
|
+
syncPubKeyDomain: identity.syncPubKeyDomain,
|
|
607
|
+
syncRedirectDomain: identity.syncRedirectDomain,
|
|
608
|
+
...hostRequired ? { hostRequired } : {},
|
|
609
|
+
records
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
function templateFileName(t) {
|
|
613
|
+
return `${t.providerId}.${t.serviceId}.json`.toLowerCase();
|
|
614
|
+
}
|
|
615
|
+
function cnameTemplate(identity, options) {
|
|
616
|
+
return template(
|
|
617
|
+
identity,
|
|
618
|
+
options.serviceId ?? "custom-domain",
|
|
619
|
+
{
|
|
620
|
+
serviceName: "Connect a custom domain",
|
|
621
|
+
description: "Points your subdomain at us. The subdomain is the host parameter.",
|
|
622
|
+
variableDescription: options.variableDescription
|
|
623
|
+
},
|
|
624
|
+
options,
|
|
625
|
+
[{ type: "CNAME", host: "@", pointsTo: options.pointsTo, ttl: TTL }],
|
|
626
|
+
true
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
function dmarcTemplate(identity, options = {}) {
|
|
630
|
+
return template(
|
|
631
|
+
identity,
|
|
632
|
+
"dmarc",
|
|
633
|
+
{
|
|
634
|
+
serviceName: "DMARC record for your sending domain",
|
|
635
|
+
description: "Adds a DMARC record that only monitors (p=none), so mailbox providers can see that your sending domain has a policy. It rejects and quarantines nothing.",
|
|
636
|
+
variableDescription: options.rua ? "%dmarcRua%: the email address that gets the DMARC aggregate reports." : void 0
|
|
637
|
+
},
|
|
638
|
+
options,
|
|
639
|
+
[
|
|
640
|
+
{
|
|
641
|
+
type: "TXT",
|
|
642
|
+
host: "_dmarc",
|
|
643
|
+
data: options.rua ? "v=DMARC1; p=none; rua=mailto:%dmarcRua%" : "v=DMARC1; p=none",
|
|
644
|
+
ttl: TTL,
|
|
645
|
+
txtConflictMatchingMode: "Prefix",
|
|
646
|
+
txtConflictMatchingPrefix: "v=DMARC1",
|
|
647
|
+
essential: "OnApply"
|
|
648
|
+
}
|
|
649
|
+
]
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
function spfTemplate(identity, options = {}) {
|
|
653
|
+
return template(
|
|
654
|
+
identity,
|
|
655
|
+
"spf",
|
|
656
|
+
{
|
|
657
|
+
serviceName: "Allow us to send email for your domain",
|
|
658
|
+
description: "Adds our sending service to your domain's SPF record, next to what is already there.",
|
|
659
|
+
variableDescription: "%include%: the domain to include, such as _spf.example.com."
|
|
660
|
+
},
|
|
661
|
+
options,
|
|
662
|
+
[{ type: "SPFM", host: "@", spfRules: "include:%include%" }]
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
function dkimTemplate(identity, options = {}) {
|
|
666
|
+
const keys = options.keys ?? 2;
|
|
667
|
+
const numbers = Array.from({ length: keys }, (_, index) => index + 1);
|
|
668
|
+
return template(
|
|
669
|
+
identity,
|
|
670
|
+
"dkim",
|
|
671
|
+
{
|
|
672
|
+
serviceName: "Sign your email with our key",
|
|
673
|
+
description: "Adds the CNAME records that let us sign email sent from your domain.",
|
|
674
|
+
variableDescription: numbers.map((n) => `%selector${n}%: the key name, ${n} of ${keys}; %target${n}%: where it points`).join("; ")
|
|
675
|
+
},
|
|
676
|
+
options,
|
|
677
|
+
numbers.map((n) => ({
|
|
678
|
+
type: "CNAME",
|
|
679
|
+
host: `%selector${n}%._domainkey`,
|
|
680
|
+
pointsTo: `%target${n}%`,
|
|
681
|
+
ttl: TTL
|
|
682
|
+
}))
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
function mxTemplate(identity, options) {
|
|
686
|
+
return template(
|
|
687
|
+
identity,
|
|
688
|
+
"mx",
|
|
689
|
+
{
|
|
690
|
+
serviceName: "Receive email for your domain with us",
|
|
691
|
+
description: "Sends the email for your domain to our mail servers."
|
|
692
|
+
},
|
|
693
|
+
options,
|
|
694
|
+
[
|
|
695
|
+
{
|
|
696
|
+
type: "MX",
|
|
697
|
+
host: "@",
|
|
698
|
+
pointsTo: options.pointsTo,
|
|
699
|
+
priority: options.priority ?? 10,
|
|
700
|
+
ttl: TTL
|
|
701
|
+
}
|
|
702
|
+
]
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
function verificationTemplate(identity, options) {
|
|
706
|
+
return template(
|
|
707
|
+
identity,
|
|
708
|
+
"domain-verification",
|
|
709
|
+
{
|
|
710
|
+
serviceName: "Verify your domain",
|
|
711
|
+
description: "Adds the record that shows us you own this domain.",
|
|
712
|
+
variableDescription: "%value%: the verification token we gave you."
|
|
713
|
+
},
|
|
714
|
+
options,
|
|
715
|
+
[
|
|
716
|
+
{
|
|
717
|
+
type: "TXT",
|
|
718
|
+
host: options.host ?? "@",
|
|
719
|
+
data: `${options.prefix}%value%`,
|
|
720
|
+
ttl: TTL,
|
|
721
|
+
txtConflictMatchingMode: "Prefix",
|
|
722
|
+
txtConflictMatchingPrefix: options.prefix,
|
|
723
|
+
essential: "OnApply"
|
|
724
|
+
}
|
|
725
|
+
]
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
729
|
+
0 && (module.exports = {
|
|
730
|
+
DNS_HOSTS,
|
|
731
|
+
DNS_HOST_IDS,
|
|
732
|
+
cnameTemplate,
|
|
733
|
+
detectDnsHosts,
|
|
734
|
+
dkimTemplate,
|
|
735
|
+
dmarcTemplate,
|
|
736
|
+
dnsRecordRow,
|
|
737
|
+
mxTemplate,
|
|
738
|
+
normalizeDnsName,
|
|
739
|
+
recordNameInZone,
|
|
740
|
+
relativeName,
|
|
741
|
+
spfTemplate,
|
|
742
|
+
templateFileName,
|
|
743
|
+
trapOf,
|
|
744
|
+
verificationTemplate
|
|
745
|
+
});
|