@theholocron/holocron-plugin-vercel 5.0.0-alpha.28 → 5.0.0-alpha.29

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/README.md CHANGED
@@ -64,11 +64,16 @@ Capability covers:
64
64
  an app) — `defaultFramework` only applies to `ensureProject()`'s
65
65
  Git-linked path.
66
66
  - `getDeployment()` — fetch a deployment by id
67
- - `ensureCustomDomain()` — idempotent add (list → check → add). Adding
68
- a domain new to the Vercel account returns `verified: false` with a
69
- DNS verification challenge (usually a CNAME to a per-project target
70
- Vercel generates — never a fixed well-known host). The returned DNS
71
- record is handed to the configured `dns` provider by `holocron setup`.
67
+ - `ensureCustomDomain()` — idempotent add (list → add-if-missing →
68
+ check DNS routing). Ownership (`verified`) and DNS routing are
69
+ separate: once a team already owns a domain's apex, every new
70
+ subdomain auto-verifies immediately with no fresh challenge, so
71
+ attachment alone can't tell you whether traffic is actually routed
72
+ to Vercel yet. `domains.config()` answers that regardless of
73
+ ownership state, returning a per-project CNAME target — never a
74
+ fixed well-known host — only when DNS isn't already configured. The
75
+ returned DNS record is handed to the configured `dns` provider by
76
+ `holocron setup`.
72
77
 
73
78
  Declare the production domain in the Vercel provider options. On `holocron setup`,
74
79
  the domain is attached to the project and any Vercel verification CNAME is
package/dist/index.d.mts CHANGED
@@ -35,16 +35,23 @@ declare class VercelDeployment implements Deployment {
35
35
  getDeployment(deploymentId: string): Promise<DeploymentRecord>;
36
36
  deployFunction(projectId: string, config: DeployFunctionConfig): Promise<DeployFunctionResult>;
37
37
  /**
38
- * Idempotent — no-op when `hostname` is already on the project,
39
- * matching `Deployment.ensureCustomDomain`'s contract (never break
40
- * on re-runs, per CLAUDE.md's probe-then-act standard). Adding it
41
- * the first time returns `verified: false` for a domain new to this
42
- * Vercel account, plus a `verification` challenge — usually CNAME, a
43
- * unique per-project target Vercel generates (never a fixed
44
- * well-known host, confirmed via Vercel's own docs). Returned as a
45
- * `DnsRecordRequest` — the caller (e.g. `holocron setup`'s
46
- * custom-domain step) hands it straight to `dns.upsertRecord()`,
47
- * same as `Wiki.dnsRecord()` already does for the wiki's own domain.
38
+ * Idempotent — matches `Deployment.ensureCustomDomain`'s contract
39
+ * (never break on re-runs, per CLAUDE.md's probe-then-act standard).
40
+ *
41
+ * Ownership (`domains.add`'s `verified`) and DNS routing are separate
42
+ * concerns: once a team already owns the domain's apex (true for any
43
+ * org with more than one project on the same domain), every new
44
+ * subdomain auto-verifies immediately with no `verification`
45
+ * challenge — re-adding an already-attached domain returns 409, not
46
+ * a fresh one. So attachment alone can't tell us whether traffic is
47
+ * actually routed to Vercel yet. `domains.config()` (Vercel's DNS
48
+ * *configuration* check) answers that regardless of ownership state:
49
+ * `misconfigured` + a `recommendedCNAME`, per-project, never a fixed
50
+ * well-known host — always read it from this response, never
51
+ * hardcode it. Returned as a `DnsRecordRequest` — the caller (e.g.
52
+ * `holocron setup`'s custom-domain step) hands it straight to
53
+ * `dns.upsertRecord()`, same as `Wiki.dnsRecord()` already does for
54
+ * the wiki's own domain.
48
55
  */
49
56
  ensureCustomDomain(projectId: string, hostname: string): Promise<DnsRecordRequest | null>;
50
57
  private getProjectByName;
package/dist/index.mjs CHANGED
@@ -78,30 +78,45 @@ var VercelDeployment = class {
78
78
  };
79
79
  }
80
80
  /**
81
- * Idempotent — no-op when `hostname` is already on the project,
82
- * matching `Deployment.ensureCustomDomain`'s contract (never break
83
- * on re-runs, per CLAUDE.md's probe-then-act standard). Adding it
84
- * the first time returns `verified: false` for a domain new to this
85
- * Vercel account, plus a `verification` challenge — usually CNAME, a
86
- * unique per-project target Vercel generates (never a fixed
87
- * well-known host, confirmed via Vercel's own docs). Returned as a
88
- * `DnsRecordRequest` — the caller (e.g. `holocron setup`'s
89
- * custom-domain step) hands it straight to `dns.upsertRecord()`,
90
- * same as `Wiki.dnsRecord()` already does for the wiki's own domain.
81
+ * Idempotent — matches `Deployment.ensureCustomDomain`'s contract
82
+ * (never break on re-runs, per CLAUDE.md's probe-then-act standard).
83
+ *
84
+ * Ownership (`domains.add`'s `verified`) and DNS routing are separate
85
+ * concerns: once a team already owns the domain's apex (true for any
86
+ * org with more than one project on the same domain), every new
87
+ * subdomain auto-verifies immediately with no `verification`
88
+ * challenge — re-adding an already-attached domain returns 409, not
89
+ * a fresh one. So attachment alone can't tell us whether traffic is
90
+ * actually routed to Vercel yet. `domains.config()` (Vercel's DNS
91
+ * *configuration* check) answers that regardless of ownership state:
92
+ * `misconfigured` + a `recommendedCNAME`, per-project, never a fixed
93
+ * well-known host — always read it from this response, never
94
+ * hardcode it. Returned as a `DnsRecordRequest` — the caller (e.g.
95
+ * `holocron setup`'s custom-domain step) hands it straight to
96
+ * `dns.upsertRecord()`, same as `Wiki.dnsRecord()` already does for
97
+ * the wiki's own domain.
91
98
  */
92
99
  async ensureCustomDomain(projectId, hostname) {
93
100
  const { domains: existing } = await this.client().domains.list(projectId);
94
- if (existing.some((d) => d.name === hostname)) return null;
95
- const result = await this.client().domains.add(projectId, hostname);
96
- if (result.verified) return null;
97
- const challenge = result.verification?.find((v) => v.type === "CNAME");
98
- if (!challenge) return null;
101
+ let apexName = existing.find((d) => d.name === hostname)?.apexName;
102
+ if (!apexName) try {
103
+ apexName = (await this.client().domains.add(projectId, hostname)).apexName;
104
+ } catch (err) {
105
+ if (!(err instanceof ProviderApiError && err.status === 409)) throw err;
106
+ const { domains: refreshed } = await this.client().domains.list(projectId);
107
+ apexName = refreshed.find((d) => d.name === hostname)?.apexName;
108
+ }
109
+ if (!apexName) return null;
110
+ const config = await this.client().domains.config(hostname, projectId);
111
+ if (!config.misconfigured) return null;
112
+ const cname = config.recommendedCNAME[0]?.value;
113
+ if (!cname) return null;
99
114
  return {
100
- zone: result.apexName,
115
+ zone: apexName,
101
116
  record: {
102
117
  type: "CNAME",
103
118
  name: hostname,
104
- content: challenge.value
119
+ content: cname
105
120
  }
106
121
  };
107
122
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/holocron-plugin-vercel",
3
- "version": "5.0.0-alpha.28",
3
+ "version": "5.0.0-alpha.29",
4
4
  "description": "Holocron plugin for Vercel. Implements the deployment capability against the Vercel REST API.",
5
5
  "keywords": [
6
6
  "deployment",
@@ -31,10 +31,10 @@
31
31
  ],
32
32
  "devDependencies": {
33
33
  "@theholocron/eslint-config": "^8.0.0",
34
- "@theholocron/http-client": "^1.23.0",
34
+ "@theholocron/http-client": "^1.24.0",
35
35
  "@theholocron/tsconfig": "^8.0.0",
36
36
  "@theholocron/tsdown-config": "^8.0.0",
37
- "@theholocron/vercel-client": "^1.23.0",
37
+ "@theholocron/vercel-client": "^1.24.0",
38
38
  "@theholocron/vitest-config": "^8.0.0",
39
39
  "@types/node": "^26",
40
40
  "@vitest/coverage-v8": "^4.1.11",
@@ -46,11 +46,11 @@
46
46
  "tsx": "4.23.12",
47
47
  "typescript": "^5.9.3",
48
48
  "vitest": "^4.1.11",
49
- "@theholocron/cli": "5.0.0-alpha.28"
49
+ "@theholocron/cli": "5.0.0-alpha.29"
50
50
  },
51
51
  "peerDependencies": {
52
- "@theholocron/vercel-client": "^1.23.0",
53
- "@theholocron/cli": "5.0.0-alpha.28"
52
+ "@theholocron/vercel-client": "^1.24.0",
53
+ "@theholocron/cli": "5.0.0-alpha.29"
54
54
  },
55
55
  "peerDependenciesMeta": {
56
56
  "@theholocron/vercel-client": {}