@theholocron/holocron-plugin-vercel 5.0.0-alpha.26 → 5.0.0-alpha.28
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 +17 -1
- package/dist/index.d.mts +19 -1
- package/dist/index.mjs +31 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -64,9 +64,25 @@ 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`.
|
|
72
|
+
|
|
73
|
+
Declare the production domain in the Vercel provider options. On `holocron setup`,
|
|
74
|
+
the domain is attached to the project and any Vercel verification CNAME is
|
|
75
|
+
upserted through the configured DNS provider:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
providers: {
|
|
79
|
+
deployment: ["vercel", { teamId: "team_…", domain: "sentinel.example.com" }],
|
|
80
|
+
dns: "cloudflare",
|
|
81
|
+
}
|
|
82
|
+
```
|
|
67
83
|
|
|
68
84
|
Out of scope for alpha.0 (file a follow-up if needed):
|
|
69
85
|
|
|
70
|
-
- Domain
|
|
86
|
+
- Domain removal (`removeDomain`)
|
|
71
87
|
- Deletion (`deleteProject`)
|
|
72
88
|
- Marketplace integrations (e.g. `vercel install neon` for vault-managed databases)
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthError, DeployFunctionConfig, DeployFunctionResult, Deployment, DeploymentProject, DeploymentProjectSettings, DeploymentRecord, DeploymentTarget, DeploymentTrigger, ResolveTokenInput } from "@theholocron/cli";
|
|
1
|
+
import { AuthError, DeployFunctionConfig, DeployFunctionResult, Deployment, DeploymentProject, DeploymentProjectSettings, DeploymentRecord, DeploymentTarget, DeploymentTrigger, DnsRecordRequest, ResolveTokenInput } from "@theholocron/cli";
|
|
2
2
|
import { VercelClient, VercelClient as VercelClient$1, VercelClientOptions, createVercelClient } from "@theholocron/vercel-client";
|
|
3
3
|
//#region src/auth.d.ts
|
|
4
4
|
declare const resolveToken: (input?: ResolveTokenInput) => string;
|
|
@@ -7,11 +7,14 @@ declare const resolveToken: (input?: ResolveTokenInput) => string;
|
|
|
7
7
|
interface DeploymentOptions {
|
|
8
8
|
/** Optional framework hint passed to project creates. Defaults to "nextjs". */
|
|
9
9
|
defaultFramework?: string;
|
|
10
|
+
/** Custom domain that `holocron setup` should attach to this project. */
|
|
11
|
+
domain?: string;
|
|
10
12
|
}
|
|
11
13
|
declare class VercelDeployment implements Deployment {
|
|
12
14
|
private readonly client;
|
|
13
15
|
readonly key: "deployment";
|
|
14
16
|
readonly providerName = "vercel";
|
|
17
|
+
readonly domain?: string;
|
|
15
18
|
private readonly defaultFramework;
|
|
16
19
|
constructor(client: () => VercelClient$1, opts?: DeploymentOptions);
|
|
17
20
|
listProjects(): Promise<DeploymentProject[]>;
|
|
@@ -31,6 +34,19 @@ declare class VercelDeployment implements Deployment {
|
|
|
31
34
|
}): Promise<DeploymentRecord>;
|
|
32
35
|
getDeployment(deploymentId: string): Promise<DeploymentRecord>;
|
|
33
36
|
deployFunction(projectId: string, config: DeployFunctionConfig): Promise<DeployFunctionResult>;
|
|
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.
|
|
48
|
+
*/
|
|
49
|
+
ensureCustomDomain(projectId: string, hostname: string): Promise<DnsRecordRequest | null>;
|
|
34
50
|
private getProjectByName;
|
|
35
51
|
}
|
|
36
52
|
//#endregion
|
|
@@ -61,6 +77,8 @@ interface VercelPluginOptions extends ResolveTokenInput {
|
|
|
61
77
|
teamId?: string;
|
|
62
78
|
/** Default framework slug for new project creates. Defaults to "nextjs". */
|
|
63
79
|
defaultFramework?: string;
|
|
80
|
+
/** Custom domain that `holocron setup` should attach to the Vercel project. */
|
|
81
|
+
domain?: string;
|
|
64
82
|
/** Override base URL for tests. */
|
|
65
83
|
baseUrl?: string;
|
|
66
84
|
/** Override `fetch` for tests. */
|
package/dist/index.mjs
CHANGED
|
@@ -13,10 +13,12 @@ var VercelDeployment = class {
|
|
|
13
13
|
client;
|
|
14
14
|
key = "deployment";
|
|
15
15
|
providerName = "vercel";
|
|
16
|
+
domain;
|
|
16
17
|
defaultFramework;
|
|
17
18
|
constructor(client, opts = {}) {
|
|
18
19
|
this.client = client;
|
|
19
20
|
this.defaultFramework = opts.defaultFramework ?? "nextjs";
|
|
21
|
+
this.domain = opts.domain;
|
|
20
22
|
}
|
|
21
23
|
async listProjects() {
|
|
22
24
|
const { projects } = await this.client().projects.list();
|
|
@@ -75,6 +77,34 @@ var VercelDeployment = class {
|
|
|
75
77
|
url: raw.url
|
|
76
78
|
};
|
|
77
79
|
}
|
|
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.
|
|
91
|
+
*/
|
|
92
|
+
async ensureCustomDomain(projectId, hostname) {
|
|
93
|
+
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;
|
|
99
|
+
return {
|
|
100
|
+
zone: result.apexName,
|
|
101
|
+
record: {
|
|
102
|
+
type: "CNAME",
|
|
103
|
+
name: hostname,
|
|
104
|
+
content: challenge.value
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
78
108
|
async getProjectByName(name) {
|
|
79
109
|
try {
|
|
80
110
|
return mapProject(await this.client().projects.get(name));
|
|
@@ -157,6 +187,7 @@ function createContext(options = {}) {
|
|
|
157
187
|
function deployment(ctx) {
|
|
158
188
|
const opts = {};
|
|
159
189
|
if (ctx.options.defaultFramework !== void 0) opts.defaultFramework = ctx.options.defaultFramework;
|
|
190
|
+
if (ctx.options.domain !== void 0) opts.domain = ctx.options.domain;
|
|
160
191
|
return new VercelDeployment(ctx.client, opts);
|
|
161
192
|
}
|
|
162
193
|
function createPlugin(options = {}) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-vercel",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.28",
|
|
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.
|
|
34
|
+
"@theholocron/http-client": "^1.23.0",
|
|
35
35
|
"@theholocron/tsconfig": "^8.0.0",
|
|
36
36
|
"@theholocron/tsdown-config": "^8.0.0",
|
|
37
|
-
"@theholocron/vercel-client": "^1.
|
|
37
|
+
"@theholocron/vercel-client": "^1.23.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.
|
|
49
|
+
"@theholocron/cli": "5.0.0-alpha.28"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@theholocron/vercel-client": "^1.
|
|
53
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
52
|
+
"@theholocron/vercel-client": "^1.23.0",
|
|
53
|
+
"@theholocron/cli": "5.0.0-alpha.28"
|
|
54
54
|
},
|
|
55
55
|
"peerDependenciesMeta": {
|
|
56
56
|
"@theholocron/vercel-client": {}
|