@tokenoftrust/cli 3.11.0 → 3.12.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/commands/go-live.mjs +68 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.12.0",
|
|
4
4
|
"description": "Token of Trust developer CLI — clone a tenant store, run it locally with save→reload, and submit it for preview. Installs the `tot` command.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Token of Trust",
|
package/src/commands/go-live.mjs
CHANGED
|
@@ -242,12 +242,13 @@ export async function pollRunTerminal(http, { attempts = 8, delayMs = 2000, slee
|
|
|
242
242
|
* live DNS.
|
|
243
243
|
*
|
|
244
244
|
* @param {{ get:(path:string)=>Promise<any>, post:(path:string,body:any)=>Promise<any> }} http
|
|
245
|
-
* @param {{ appDomain:string, action:"connect"|"rollback", rehearsal:boolean, noOpen?:boolean
|
|
245
|
+
* @param {{ appDomain:string, action:"connect"|"rollback", rehearsal:boolean, noOpen?:boolean,
|
|
246
|
+
* dnsSetup?: { domainConnectDeclared?: boolean, ciRoleCanChangeZone?: boolean, nameserversAtRegistrar?: boolean } }} params
|
|
246
247
|
* @param {{ interactive?:()=>boolean, confirm?:(q:string,d:boolean)=>Promise<boolean>,
|
|
247
248
|
* poll?:typeof pollRunTerminal, openUrl?:(u:string)=>boolean, progress?:boolean }} [deps]
|
|
248
249
|
* @returns {Promise<number>} process exit code
|
|
249
250
|
*/
|
|
250
|
-
export async function runGoLive(http, { appDomain, action, rehearsal, noOpen }, deps = {}) {
|
|
251
|
+
export async function runGoLive(http, { appDomain, action, rehearsal, noOpen, dnsSetup }, deps = {}) {
|
|
251
252
|
const interactive = deps.interactive || isInteractive;
|
|
252
253
|
const confirm = deps.confirm || promptYesNo;
|
|
253
254
|
const poll = deps.poll || pollRunTerminal;
|
|
@@ -340,17 +341,80 @@ export async function runGoLive(http, { appDomain, action, rehearsal, noOpen },
|
|
|
340
341
|
} finally {
|
|
341
342
|
progress?.stop();
|
|
342
343
|
}
|
|
343
|
-
return reportGoLive({
|
|
344
|
+
return reportGoLive({
|
|
345
|
+
status, dispatch, action, rehearsal, domain, noOpen, openUrl: deps.openUrl, dnsSetup,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Which Connect apex setup a rehearsal measured. Pure — no DNS lookup.
|
|
351
|
+
* Writable only when `domainConnect` is declared, CI's role can change that
|
|
352
|
+
* Route53 zone, and the public nameservers are not still the registrar's.
|
|
353
|
+
* A registrar-held zone is not writable until the merchant delegates NS.
|
|
354
|
+
* There is no registrar API. `null` when this command was not given a measurement.
|
|
355
|
+
* @param {{ domainConnectDeclared?: boolean, ciRoleCanChangeZone?: boolean, nameserversAtRegistrar?: boolean } | null | undefined} measured
|
|
356
|
+
* @returns {{ id: "no-domain-connect"|"registrar-held"|"platform-route53-zone", writable: boolean, detail: string } | null}
|
|
357
|
+
*/
|
|
358
|
+
export function connectApexDnsSetup(measured) {
|
|
359
|
+
if (!measured || typeof measured !== "object") return null;
|
|
360
|
+
const declared = measured.domainConnectDeclared === true;
|
|
361
|
+
const roleCanWrite = measured.ciRoleCanChangeZone === true;
|
|
362
|
+
const registrarHeld = measured.nameserversAtRegistrar === true;
|
|
363
|
+
if (!declared) {
|
|
364
|
+
return {
|
|
365
|
+
id: "no-domain-connect",
|
|
366
|
+
writable: false,
|
|
367
|
+
detail:
|
|
368
|
+
"Connect apex cannot write this zone. CI refuses a tenant whose www-distributions entry declares no domainConnect. No registrar API.",
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
if (registrarHeld) {
|
|
372
|
+
return {
|
|
373
|
+
id: "registrar-held",
|
|
374
|
+
writable: false,
|
|
375
|
+
detail:
|
|
376
|
+
"Connect apex cannot write this zone while nameservers are still the registrar's. The merchant's first step is to delegate NS at the registrar to the declared platform zone. Lead time is the registry NS TTL, 172800 seconds (48 hours), not the ~60 second in-zone ALIAS change. No registrar API.",
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
if (!roleCanWrite) {
|
|
380
|
+
return {
|
|
381
|
+
id: "platform-route53-zone",
|
|
382
|
+
writable: false,
|
|
383
|
+
detail:
|
|
384
|
+
"domainConnect is declared, but CI's role cannot change that Route53 zone, so Connect apex cannot write it. No registrar API.",
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
return {
|
|
388
|
+
id: "platform-route53-zone",
|
|
389
|
+
writable: true,
|
|
390
|
+
detail:
|
|
391
|
+
"Connect apex can write this zone: domainConnect is declared and CI's role can change that Route53 zone. Records upserted: apex and www A and AAAA ALIAS only. Mail and every other name stay. In-zone propagation is about 60 seconds.",
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/** Lines a successful rehearsal prints so the operator can see which setup applies. */
|
|
396
|
+
function rehearsalSetupLines(dnsSetup) {
|
|
397
|
+
const measured = connectApexDnsSetup(dnsSetup);
|
|
398
|
+
if (measured) {
|
|
399
|
+
return [` This rehearsal measured setup: ${measured.id}. ${measured.detail}`, " DNS was not changed."];
|
|
400
|
+
}
|
|
401
|
+
return [
|
|
402
|
+
" This rehearsal did not measure a per-tenant setup. Which setup applies:",
|
|
403
|
+
" platform-route53-zone — writable only when the tenant declares domainConnect and CI's role can change that Route53 zone. Records upserted: apex and www A and AAAA ALIAS only.",
|
|
404
|
+
" registrar-held — not writable while nameservers are still the registrar's. The merchant delegates NS at the registrar to the declared platform zone first. Lead time is the registry NS TTL, 172800 seconds (48 hours), not the ~60 second in-zone ALIAS change. No registrar API.",
|
|
405
|
+
" no-domain-connect — CI refuses the tenant. Connect apex cannot write a zone.",
|
|
406
|
+
];
|
|
344
407
|
}
|
|
345
408
|
|
|
346
409
|
/** Report the go-live outcome honestly + always surface the one-line revert. */
|
|
347
|
-
function reportGoLive({ status, dispatch, action, rehearsal, domain, noOpen, openUrl }) {
|
|
410
|
+
export function reportGoLive({ status, dispatch, action, rehearsal, domain, noOpen, openUrl, dnsSetup }) {
|
|
348
411
|
const runUrl = status?.runUrl || null;
|
|
349
412
|
const revertHint = " Revert (one line): tot go-live --rollback";
|
|
350
413
|
|
|
351
414
|
if (status?.status === "succeeded") {
|
|
352
415
|
if (rehearsal) {
|
|
353
416
|
console.log(`\n ✓ rehearsal succeeded for ${domain} — DNS state unchanged (dry run).`);
|
|
417
|
+
for (const line of rehearsalSetupLines(dnsSetup)) console.log(line);
|
|
354
418
|
} else if (action === "rollback") {
|
|
355
419
|
console.log(`\n ✓ rolled the apex DNS back for ${domain} to the captured prior records.`);
|
|
356
420
|
} else {
|