@timekast/factory 1.17.1 → 1.17.3
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/commands/provision.js +14 -2
- package/dist/index.js +7 -0
- package/dist/lib/env-file.js +4 -0
- package/dist/lib/vercel-env.js +14 -0
- package/package.json +1 -1
|
@@ -1556,7 +1556,7 @@ async function retireInterimDomain(projectId, token, teamId, state, deps, fetchI
|
|
|
1556
1556
|
// The DEV domain is intentionally never touched (issue §4 — conserved).
|
|
1557
1557
|
}
|
|
1558
1558
|
/**
|
|
1559
|
-
* Update `EMAIL_FROM` + `AUTH_URL`/`NEXTAUTH_URL` to the client domain in the
|
|
1559
|
+
* Update `EMAIL_FROM` + `AUTH_URL`/`NEXTAUTH_URL` + `NEXT_PUBLIC_APP_URL` to the client domain in the
|
|
1560
1560
|
* Vercel env, per-target and idempotently (PROV-006 §4). Lists the existing vars
|
|
1561
1561
|
* once; an `AUTH_URL`/`NEXTAUTH_URL`/`EMAIL_FROM` already set to the target value
|
|
1562
1562
|
* has its PATCH omitted (issue §8 — second run is a no-op). No-echo: only KEY
|
|
@@ -1574,6 +1574,9 @@ async function updateDomainEnv(projectId, token, teamId, domain, deps) {
|
|
|
1574
1574
|
},
|
|
1575
1575
|
{ key: 'AUTH_URL', value: authUrl, target: ['production', 'preview'] },
|
|
1576
1576
|
{ key: 'NEXTAUTH_URL', value: authUrl, target: ['production', 'preview'] },
|
|
1577
|
+
// Keep the public app origin in lockstep with AUTH_URL once a client domain lands
|
|
1578
|
+
// (the substrate set it to the interim domain in buildEnvPlan; this re-points it).
|
|
1579
|
+
{ key: 'NEXT_PUBLIC_APP_URL', value: authUrl, target: ['production', 'preview'] },
|
|
1577
1580
|
];
|
|
1578
1581
|
const existing = await listEnvVars(projectId, token, teamId, deps);
|
|
1579
1582
|
for (const entry of plan) {
|
|
@@ -1599,7 +1602,7 @@ function printClientDomainPlan(domain, interim, route, confirm) {
|
|
|
1599
1602
|
console.log(` … sondea GET /v9/projects/.../domains/${domain} hasta verified:true (o timeout)`);
|
|
1600
1603
|
console.log(` ${confirm ? '-' : '? (requiere --confirm o prompt)'} retira el interino ${interim} ` +
|
|
1601
1604
|
`(el dev ${domain}-dev se conserva)`);
|
|
1602
|
-
console.log(` ↻ EMAIL_FROM=noreply@${mailDomainFor(domain)} · AUTH_URL=https://${domain} · NEXTAUTH_URL=https://${domain}`);
|
|
1605
|
+
console.log(` ↻ EMAIL_FROM=noreply@${mailDomainFor(domain)} · AUTH_URL=https://${domain} · NEXTAUTH_URL=https://${domain} · NEXT_PUBLIC_APP_URL=https://${domain}`);
|
|
1603
1606
|
console.log(` + Resend: POST /domains { name: ${mailDomainFor(domain)} } (subdominio mail, no el apex)`);
|
|
1604
1607
|
console.log('\n(`--dry-run`) No se ejecutó ninguna llamada a API ni se escribió estado.');
|
|
1605
1608
|
}
|
|
@@ -2487,6 +2490,15 @@ export async function runProvision(flags) {
|
|
|
2487
2490
|
await provisionNeon(rootDir, runState);
|
|
2488
2491
|
writeProvisionState(rootDir, runState);
|
|
2489
2492
|
}
|
|
2493
|
+
// 5a.2. Ensure the local E2E creds are in `.env.local` even on a resume/adopt where
|
|
2494
|
+
// the Vercel substrate was already `done` (writeE2eLocalCreds only runs inside
|
|
2495
|
+
// that step's first pass). Idempotent — `setEnvLine` replaces/appends the two
|
|
2496
|
+
// keys — so `pnpm test:e2e` works locally without a manual edit after a re-run.
|
|
2497
|
+
if (!flags.dryRun && runState.neon?.projectId) {
|
|
2498
|
+
if (writeE2eLocalCreds(rootDir, runState.neon.projectId, readNeonApiKey())) {
|
|
2499
|
+
console.log(' + .env.local (NEON_API_KEY · NEON_PROJECT_ID — para `pnpm test:e2e` local)');
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2490
2502
|
// 5b. Client domain (PROV-006) — runs AFTER the services so the Vercel project
|
|
2491
2503
|
// (and the interim domains) already exist. Standalone patch or post-services.
|
|
2492
2504
|
if (hasDomain) {
|
package/dist/index.js
CHANGED
|
@@ -151,6 +151,13 @@ async function main(argv) {
|
|
|
151
151
|
console.log(HELP);
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
|
+
// A `--help`/`-h` flag ANYWHERE (e.g. `factory env push --help`) prints help and
|
|
155
|
+
// NEVER runs the command. A help flag must never trigger a mutation: `env push --help`
|
|
156
|
+
// used to fire a REAL Vercel push, because the check above only inspects the first arg.
|
|
157
|
+
if (rest.includes('--help') || rest.includes('-h')) {
|
|
158
|
+
console.log(HELP);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
154
161
|
// No command at all → interactive TUI menu (LTUI-001). The menu degrades to
|
|
155
162
|
// HELP itself when there's no TTY (CI / pipe), so it never hangs.
|
|
156
163
|
if (command === undefined) {
|
package/dist/lib/env-file.js
CHANGED
|
@@ -25,6 +25,10 @@ export const PROVISION_OWNED = new Set([
|
|
|
25
25
|
'DATABASE_URL_MAIN',
|
|
26
26
|
'AUTH_SECRET',
|
|
27
27
|
'NEXT_PUBLIC_APP_ENV',
|
|
28
|
+
// Per-env app origin: provision sets it to the real domain per environment
|
|
29
|
+
// (prod/preview); `env:push` must NOT re-upload the `localhost:3000` default of
|
|
30
|
+
// `.env.local`, which would break links / OAuth callbacks / the PWA manifest in prod.
|
|
31
|
+
'NEXT_PUBLIC_APP_URL',
|
|
28
32
|
// Provision mints these per-env too (P-1): the MFA key (base64url) + the
|
|
29
33
|
// WebAuthn rpID (the exact host). A shared day-2 push would break passkeys
|
|
30
34
|
// (rpID must match the env's host) or the at-rest TOTP crypto.
|
package/dist/lib/vercel-env.js
CHANGED
|
@@ -470,6 +470,20 @@ export function buildEnvPlan(input) {
|
|
|
470
470
|
// Deployment identity — drives the env-aware PWA manifest (see .env.example).
|
|
471
471
|
{ key: 'NEXT_PUBLIC_APP_ENV', value: 'production', target: ['production'] },
|
|
472
472
|
{ key: 'NEXT_PUBLIC_APP_ENV', value: 'preview', target: ['preview'] },
|
|
473
|
+
// App origin — the EXACT per-env URL (same host as WEBAUTHN_RP_ID), so links,
|
|
474
|
+
// OAuth callbacks and the PWA manifest resolve to the real domain instead of the
|
|
475
|
+
// `localhost:3000` default of `.env.local`. Per-env (PROVISION_OWNED) → `env:push`
|
|
476
|
+
// never overwrites it with a single shared value (P-1 parity with the other hosts).
|
|
477
|
+
{
|
|
478
|
+
key: 'NEXT_PUBLIC_APP_URL',
|
|
479
|
+
value: `https://${input.webauthnRpIdProd}`,
|
|
480
|
+
target: ['production'],
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
key: 'NEXT_PUBLIC_APP_URL',
|
|
484
|
+
value: `https://${input.webauthnRpIdPreview}`,
|
|
485
|
+
target: ['preview'],
|
|
486
|
+
},
|
|
473
487
|
];
|
|
474
488
|
for (const [key, value] of Object.entries(input.shared ?? {})) {
|
|
475
489
|
if (!value)
|