@infracraft/pulumi 1.19.0 → 1.20.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/dist/vercel/domain.cjs +39 -11
- package/dist/vercel/domain.cjs.map +1 -1
- package/dist/vercel/domain.d.cts +14 -8
- package/dist/vercel/domain.d.cts.map +1 -1
- package/dist/vercel/domain.d.mts +14 -8
- package/dist/vercel/domain.d.mts.map +1 -1
- package/dist/vercel/domain.mjs +40 -11
- package/dist/vercel/domain.mjs.map +1 -1
- package/dist/vercel/index.cjs +0 -1
- package/dist/vercel/index.d.cts +2 -2
- package/dist/vercel/index.d.mts +2 -2
- package/dist/vercel/index.mjs +2 -2
- package/package.json +1 -1
package/dist/vercel/domain.cjs
CHANGED
|
@@ -6,10 +6,29 @@ _pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
|
|
|
6
6
|
//#region src/vercel/domain.ts
|
|
7
7
|
const VERCEL_API_URL = "https://api.vercel.com";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Fallback CNAME target, used only when Vercel's domain-config endpoint returns no
|
|
10
|
+
* recommendation (see {@link fetchCnameTarget}). Not the primary source of truth —
|
|
11
|
+
* `VercelDomain.cnameTarget` queries Vercel's per-domain recommendation dynamically,
|
|
12
|
+
* since the actual target can vary by account/domain.
|
|
10
13
|
* https://vercel.com/docs/domains/working-with-domains/add-a-domain
|
|
11
14
|
*/
|
|
12
|
-
const
|
|
15
|
+
const VERCEL_CNAME_TARGET_FALLBACK = "cname.vercel-dns.com";
|
|
16
|
+
/**
|
|
17
|
+
* Fetches Vercel's recommended CNAME target for a domain from its DNS config endpoint.
|
|
18
|
+
* Falls back to {@link VERCEL_CNAME_TARGET_FALLBACK} if Vercel returns no recommendation
|
|
19
|
+
* (logged, since that's an unusual state worth noticing rather than silently accepting).
|
|
20
|
+
*/
|
|
21
|
+
async function fetchCnameTarget(token, teamId, name) {
|
|
22
|
+
const response = await fetch(`${VERCEL_API_URL}/v6/domains/${encodeURIComponent(name)}/config?teamId=${teamId}`, { headers: { Authorization: `Bearer ${token}` } });
|
|
23
|
+
if (!response.ok) throw new Error(`Vercel API error fetching domain config for "${name}" (${response.status}): ${await response.text()}`);
|
|
24
|
+
const { recommendedCNAME = [] } = await response.json();
|
|
25
|
+
const preferred = [...recommendedCNAME].sort((a, b) => a.rank - b.rank)[0];
|
|
26
|
+
if (!preferred) {
|
|
27
|
+
_pulumi_pulumi.log.info(`Vercel returned no recommended CNAME for "${name}" — falling back to "${VERCEL_CNAME_TARGET_FALLBACK}"`);
|
|
28
|
+
return VERCEL_CNAME_TARGET_FALLBACK;
|
|
29
|
+
}
|
|
30
|
+
return preferred.value;
|
|
31
|
+
}
|
|
13
32
|
/**
|
|
14
33
|
* Fetches a project domain by name. Returns `null` if not attached (404).
|
|
15
34
|
*/
|
|
@@ -34,7 +53,8 @@ var VercelDomainResourceProvider = class {
|
|
|
34
53
|
_pulumi_pulumi.log.info(`Adopted existing Vercel domain "${inputs.name}" on project ${inputs.projectId}`);
|
|
35
54
|
const outs = {
|
|
36
55
|
...inputs,
|
|
37
|
-
verified: existing.verified
|
|
56
|
+
verified: existing.verified,
|
|
57
|
+
cnameTarget: await fetchCnameTarget(inputs.token, inputs.teamId, inputs.name)
|
|
38
58
|
};
|
|
39
59
|
return {
|
|
40
60
|
id: `${inputs.projectId}/${inputs.name}`,
|
|
@@ -53,7 +73,8 @@ var VercelDomainResourceProvider = class {
|
|
|
53
73
|
const created = await response.json();
|
|
54
74
|
const outs = {
|
|
55
75
|
...inputs,
|
|
56
|
-
verified: created.verified
|
|
76
|
+
verified: created.verified,
|
|
77
|
+
cnameTarget: await fetchCnameTarget(inputs.token, inputs.teamId, inputs.name)
|
|
57
78
|
};
|
|
58
79
|
return {
|
|
59
80
|
id: `${inputs.projectId}/${inputs.name}`,
|
|
@@ -67,15 +88,17 @@ var VercelDomainResourceProvider = class {
|
|
|
67
88
|
id: `${props.projectId}/${props.name}`,
|
|
68
89
|
props: {
|
|
69
90
|
...props,
|
|
70
|
-
verified: domain.verified
|
|
91
|
+
verified: domain.verified,
|
|
92
|
+
cnameTarget: await fetchCnameTarget(props.token, props.teamId, props.name)
|
|
71
93
|
}
|
|
72
94
|
};
|
|
73
95
|
}
|
|
74
96
|
/** All fields replace (see `diff`) — this is never actually invoked. */
|
|
75
|
-
async update(_id,
|
|
97
|
+
async update(_id, olds, news) {
|
|
76
98
|
return { outs: {
|
|
77
99
|
...news,
|
|
78
|
-
verified: false
|
|
100
|
+
verified: false,
|
|
101
|
+
cnameTarget: olds.cnameTarget
|
|
79
102
|
} };
|
|
80
103
|
}
|
|
81
104
|
async delete(_id, props) {
|
|
@@ -111,7 +134,8 @@ var VercelDomainResource = class extends _pulumi_pulumi.dynamic.Resource {
|
|
|
111
134
|
constructor(name, args, opts) {
|
|
112
135
|
super(new VercelDomainResourceProvider(), name, {
|
|
113
136
|
...args,
|
|
114
|
-
verified: void 0
|
|
137
|
+
verified: void 0,
|
|
138
|
+
cnameTarget: void 0
|
|
115
139
|
}, opts);
|
|
116
140
|
}
|
|
117
141
|
};
|
|
@@ -120,7 +144,10 @@ var VercelDomainResource = class extends _pulumi_pulumi.dynamic.Resource {
|
|
|
120
144
|
*
|
|
121
145
|
* @example
|
|
122
146
|
* ```typescript
|
|
123
|
-
* new VercelDomain("aura-domain", { name: "app.example.com" }, { provider, project });
|
|
147
|
+
* const domain = new VercelDomain("aura-domain", { name: "app.example.com" }, { provider, project });
|
|
148
|
+
*
|
|
149
|
+
* // Point app.example.com's DNS CNAME at this value.
|
|
150
|
+
* const cnameTarget = domain.cnameTarget;
|
|
124
151
|
* ```
|
|
125
152
|
*/
|
|
126
153
|
var VercelDomain = class extends _pulumi_pulumi.ComponentResource {
|
|
@@ -135,15 +162,16 @@ var VercelDomain = class extends _pulumi_pulumi.ComponentResource {
|
|
|
135
162
|
}, { parent: this });
|
|
136
163
|
this.verified = resource.verified;
|
|
137
164
|
this.name = resource.name;
|
|
165
|
+
this.cnameTarget = resource.cnameTarget;
|
|
138
166
|
this.registerOutputs({
|
|
139
167
|
verified: this.verified,
|
|
140
|
-
name: this.name
|
|
168
|
+
name: this.name,
|
|
169
|
+
cnameTarget: this.cnameTarget
|
|
141
170
|
});
|
|
142
171
|
}
|
|
143
172
|
};
|
|
144
173
|
|
|
145
174
|
//#endregion
|
|
146
|
-
exports.VERCEL_CNAME_TARGET = VERCEL_CNAME_TARGET;
|
|
147
175
|
exports.VercelDomain = VercelDomain;
|
|
148
176
|
exports.VercelDomainResourceProvider = VercelDomainResourceProvider;
|
|
149
177
|
//# sourceMappingURL=domain.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain.cjs","names":["pulumi"],"sources":["../../src/vercel/domain.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport type { VercelProject } from \"./project\";\nimport type { VercelProvider } from \"./provider\";\n\nconst VERCEL_API_URL = \"https://api.vercel.com\";\n\n/**\n * Vercel's documented CNAME target for attaching a subdomain to a project.\n * https://vercel.com/docs/domains/working-with-domains/add-a-domain\n */\nexport const VERCEL_CNAME_TARGET = \"cname.vercel-dns.com\";\n\n/** Resolved inputs for the Vercel domain dynamic provider. */\nexport interface VercelDomainInputs {\n\t/** Vercel API bearer token. */\n\ttoken: string;\n\n\t/** Vercel team/org ID. */\n\tteamId: string;\n\n\t/** Vercel project ID to attach the domain to. */\n\tprojectId: string;\n\n\t/** Domain name (e.g. `\"app.example.com\"`). */\n\tname: string;\n}\n\n/** Persisted state for the Vercel domain, extending inputs with verification status. */\ninterface VercelDomainOutputs extends VercelDomainInputs {\n\t/** `true` once the domain's DNS has been verified by Vercel. */\n\tverified: boolean;\n}\n\n/** Vercel API response shape for a project domain. */\ninterface VercelDomainResponse {\n\tname: string;\n\tprojectId: string;\n\tverified: boolean;\n}\n\n/**\n * Fetches a project domain by name. Returns `null` if not attached (404).\n */\nasync function fetchDomain(\n\ttoken: string,\n\tteamId: string,\n\tprojectId: string,\n\tname: string,\n): Promise<VercelDomainResponse | null> {\n\tconst response = await fetch(\n\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(name)}?teamId=${teamId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\tif (response.status === 404) {\n\t\treturn null;\n\t}\n\n\tif (!response.ok) {\n\t\tthrow new Error(\n\t\t\t`Vercel API error fetching domain \"${name}\" (${response.status}): ${await response.text()}`,\n\t\t);\n\t}\n\n\treturn (await response.json()) as VercelDomainResponse;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for a Vercel project domain.\n *\n * On `create()`, calls `GET /v9/projects/{projectId}/domains/{name}`. If found, adopts\n * the existing attachment. If 404, attaches it via `POST /v10/projects/{projectId}/domains`.\n *\n * @internal Exported only for unit testing; not part of the public API surface.\n */\nexport class VercelDomainResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst existing = await fetchDomain(\n\t\t\tinputs.token,\n\t\t\tinputs.teamId,\n\t\t\tinputs.projectId,\n\t\t\tinputs.name,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopted existing Vercel domain \"${inputs.name}\" on project ${inputs.projectId}`,\n\t\t\t);\n\n\t\t\tconst outs: VercelDomainOutputs = {\n\t\t\t\t...inputs,\n\t\t\t\tverified: existing.verified,\n\t\t\t};\n\n\t\t\treturn { id: `${inputs.projectId}/${inputs.name}`, outs };\n\t\t}\n\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v10/projects/${encodeURIComponent(inputs.projectId)}/domains?teamId=${inputs.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${inputs.token}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ name: inputs.name }),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error creating domain \"${inputs.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tconst created = (await response.json()) as VercelDomainResponse;\n\n\t\tconst outs: VercelDomainOutputs = { ...inputs, verified: created.verified };\n\n\t\treturn { id: `${inputs.projectId}/${inputs.name}`, outs };\n\t}\n\n\tasync read(\n\t\t_id: string,\n\t\tprops: VercelDomainOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst domain = await fetchDomain(\n\t\t\tprops.token,\n\t\t\tprops.teamId,\n\t\t\tprops.projectId,\n\t\t\tprops.name,\n\t\t);\n\n\t\tif (!domain) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel domain \"${props.name}\" not found on project ${props.projectId}`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: `${props.projectId}/${props.name}`,\n\t\t\tprops: { ...props, verified: domain.verified },\n\t\t};\n\t}\n\n\t/** All fields replace (see `diff`) — this is never actually invoked. */\n\tasync update(\n\t\t_id: string,\n\t\t_olds: VercelDomainOutputs,\n\t\tnews: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\treturn { outs: { ...news, verified: false } };\n\t}\n\n\tasync delete(_id: string, props: VercelDomainOutputs): Promise<void> {\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(props.projectId)}/domains/${encodeURIComponent(props.name)}?teamId=${props.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\theaders: { Authorization: `Bearer ${props.token}` },\n\t\t\t},\n\t\t);\n\n\t\tif (response.status === 404) {\n\t\t\tpulumi.log.warn(\n\t\t\t\t`Vercel domain \"${props.name}\" already gone from project ${props.projectId}`,\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error deleting domain \"${props.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tpulumi.log.info(\n\t\t\t`Deleted Vercel domain \"${props.name}\" from project ${props.projectId}`,\n\t\t);\n\t}\n\n\t/**\n\t * A domain can only be attached to one project, so every field change replaces\n\t * rather than updates.\n\t */\n\tasync diff(\n\t\t_id: string,\n\t\tolds: VercelDomainOutputs,\n\t\tnews: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\n\t\tif (olds.projectId !== news.projectId) {\n\t\t\treplaces.push(\"projectId\");\n\t\t}\n\n\t\tif (olds.teamId !== news.teamId) {\n\t\t\treplaces.push(\"teamId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass VercelDomainResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly verified: pulumi.Output<boolean>;\n\tpublic declare readonly name: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tteamId: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew VercelDomainResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, verified: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for VercelDomain — replaces Pulumi's native `provider` field. */\ntype VercelDomainOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n\n\t/** Vercel project to attach the domain to. */\n\tproject: VercelProject;\n};\n\n/** Args for VercelDomain. */\nexport interface VercelDomainArgs {\n\t/** Domain name (e.g. `\"app.example.com\"`). */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Attaches a custom domain to a Vercel project, with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * new VercelDomain(\"aura-domain\", { name: \"app.example.com\" }, { provider, project });\n * ```\n */\nexport class VercelDomain extends pulumi.ComponentResource {\n\t/** `true` once the domain's DNS has been verified by Vercel. */\n\tpublic readonly verified: pulumi.Output<boolean>;\n\n\t/** The attached domain name. */\n\tpublic readonly name: pulumi.Output<string>;\n\n\tconstructor(name: string, args: VercelDomainArgs, opts: VercelDomainOptions) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Domain\", name, {}, pulumiOpts);\n\n\t\tconst resource = new VercelDomainResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tteamId: provider.teamId,\n\t\t\t\tprojectId: project.id,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.verified = resource.verified;\n\t\tthis.name = resource.name;\n\n\t\tthis.registerOutputs({ verified: this.verified, name: this.name });\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"domain.cjs","names":["pulumi"],"sources":["../../src/vercel/domain.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport type { VercelProject } from \"./project\";\nimport type { VercelProvider } from \"./provider\";\n\nconst VERCEL_API_URL = \"https://api.vercel.com\";\n\n/**\n * Fallback CNAME target, used only when Vercel's domain-config endpoint returns no\n * recommendation (see {@link fetchCnameTarget}). Not the primary source of truth —\n * `VercelDomain.cnameTarget` queries Vercel's per-domain recommendation dynamically,\n * since the actual target can vary by account/domain.\n * https://vercel.com/docs/domains/working-with-domains/add-a-domain\n */\nconst VERCEL_CNAME_TARGET_FALLBACK = \"cname.vercel-dns.com\";\n\n/** Resolved inputs for the Vercel domain dynamic provider. */\nexport interface VercelDomainInputs {\n\t/** Vercel API bearer token. */\n\ttoken: string;\n\n\t/** Vercel team/org ID. */\n\tteamId: string;\n\n\t/** Vercel project ID to attach the domain to. */\n\tprojectId: string;\n\n\t/** Domain name (e.g. `\"app.example.com\"`). */\n\tname: string;\n}\n\n/** Persisted state for the Vercel domain, extending inputs with verification status. */\ninterface VercelDomainOutputs extends VercelDomainInputs {\n\t/** `true` once the domain's DNS has been verified by Vercel. */\n\tverified: boolean;\n\n\t/** The value to CNAME `name` to, per Vercel's own per-domain recommendation. */\n\tcnameTarget: string;\n}\n\n/** Vercel API response shape for a project domain. */\ninterface VercelDomainResponse {\n\tname: string;\n\tprojectId: string;\n\tverified: boolean;\n}\n\n/** A single ranked CNAME recommendation from `GET /v6/domains/{domain}/config`. */\ninterface VercelRecommendedCname {\n\trank: number;\n\tvalue: string;\n}\n\n/**\n * Fetches Vercel's recommended CNAME target for a domain from its DNS config endpoint.\n * Falls back to {@link VERCEL_CNAME_TARGET_FALLBACK} if Vercel returns no recommendation\n * (logged, since that's an unusual state worth noticing rather than silently accepting).\n */\nasync function fetchCnameTarget(\n\ttoken: string,\n\tteamId: string,\n\tname: string,\n): Promise<string> {\n\tconst response = await fetch(\n\t\t`${VERCEL_API_URL}/v6/domains/${encodeURIComponent(name)}/config?teamId=${teamId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\tif (!response.ok) {\n\t\tthrow new Error(\n\t\t\t`Vercel API error fetching domain config for \"${name}\" (${response.status}): ${await response.text()}`,\n\t\t);\n\t}\n\n\tconst { recommendedCNAME = [] } = (await response.json()) as {\n\t\trecommendedCNAME?: VercelRecommendedCname[];\n\t};\n\n\tconst preferred = [...recommendedCNAME].sort((a, b) => a.rank - b.rank)[0];\n\n\tif (!preferred) {\n\t\tpulumi.log.info(\n\t\t\t`Vercel returned no recommended CNAME for \"${name}\" — falling back to \"${VERCEL_CNAME_TARGET_FALLBACK}\"`,\n\t\t);\n\n\t\treturn VERCEL_CNAME_TARGET_FALLBACK;\n\t}\n\n\treturn preferred.value;\n}\n\n/**\n * Fetches a project domain by name. Returns `null` if not attached (404).\n */\nasync function fetchDomain(\n\ttoken: string,\n\tteamId: string,\n\tprojectId: string,\n\tname: string,\n): Promise<VercelDomainResponse | null> {\n\tconst response = await fetch(\n\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(name)}?teamId=${teamId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\tif (response.status === 404) {\n\t\treturn null;\n\t}\n\n\tif (!response.ok) {\n\t\tthrow new Error(\n\t\t\t`Vercel API error fetching domain \"${name}\" (${response.status}): ${await response.text()}`,\n\t\t);\n\t}\n\n\treturn (await response.json()) as VercelDomainResponse;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for a Vercel project domain.\n *\n * On `create()`, calls `GET /v9/projects/{projectId}/domains/{name}`. If found, adopts\n * the existing attachment. If 404, attaches it via `POST /v10/projects/{projectId}/domains`.\n *\n * @internal Exported only for unit testing; not part of the public API surface.\n */\nexport class VercelDomainResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst existing = await fetchDomain(\n\t\t\tinputs.token,\n\t\t\tinputs.teamId,\n\t\t\tinputs.projectId,\n\t\t\tinputs.name,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopted existing Vercel domain \"${inputs.name}\" on project ${inputs.projectId}`,\n\t\t\t);\n\n\t\t\tconst outs: VercelDomainOutputs = {\n\t\t\t\t...inputs,\n\t\t\t\tverified: existing.verified,\n\t\t\t\tcnameTarget: await fetchCnameTarget(\n\t\t\t\t\tinputs.token,\n\t\t\t\t\tinputs.teamId,\n\t\t\t\t\tinputs.name,\n\t\t\t\t),\n\t\t\t};\n\n\t\t\treturn { id: `${inputs.projectId}/${inputs.name}`, outs };\n\t\t}\n\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v10/projects/${encodeURIComponent(inputs.projectId)}/domains?teamId=${inputs.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${inputs.token}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ name: inputs.name }),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error creating domain \"${inputs.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tconst created = (await response.json()) as VercelDomainResponse;\n\n\t\tconst outs: VercelDomainOutputs = {\n\t\t\t...inputs,\n\t\t\tverified: created.verified,\n\t\t\tcnameTarget: await fetchCnameTarget(\n\t\t\t\tinputs.token,\n\t\t\t\tinputs.teamId,\n\t\t\t\tinputs.name,\n\t\t\t),\n\t\t};\n\n\t\treturn { id: `${inputs.projectId}/${inputs.name}`, outs };\n\t}\n\n\tasync read(\n\t\t_id: string,\n\t\tprops: VercelDomainOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst domain = await fetchDomain(\n\t\t\tprops.token,\n\t\t\tprops.teamId,\n\t\t\tprops.projectId,\n\t\t\tprops.name,\n\t\t);\n\n\t\tif (!domain) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel domain \"${props.name}\" not found on project ${props.projectId}`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: `${props.projectId}/${props.name}`,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tverified: domain.verified,\n\t\t\t\tcnameTarget: await fetchCnameTarget(\n\t\t\t\t\tprops.token,\n\t\t\t\t\tprops.teamId,\n\t\t\t\t\tprops.name,\n\t\t\t\t),\n\t\t\t},\n\t\t};\n\t}\n\n\t/** All fields replace (see `diff`) — this is never actually invoked. */\n\tasync update(\n\t\t_id: string,\n\t\tolds: VercelDomainOutputs,\n\t\tnews: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\treturn {\n\t\t\touts: { ...news, verified: false, cnameTarget: olds.cnameTarget },\n\t\t};\n\t}\n\n\tasync delete(_id: string, props: VercelDomainOutputs): Promise<void> {\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(props.projectId)}/domains/${encodeURIComponent(props.name)}?teamId=${props.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\theaders: { Authorization: `Bearer ${props.token}` },\n\t\t\t},\n\t\t);\n\n\t\tif (response.status === 404) {\n\t\t\tpulumi.log.warn(\n\t\t\t\t`Vercel domain \"${props.name}\" already gone from project ${props.projectId}`,\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error deleting domain \"${props.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tpulumi.log.info(\n\t\t\t`Deleted Vercel domain \"${props.name}\" from project ${props.projectId}`,\n\t\t);\n\t}\n\n\t/**\n\t * A domain can only be attached to one project, so every field change replaces\n\t * rather than updates.\n\t */\n\tasync diff(\n\t\t_id: string,\n\t\tolds: VercelDomainOutputs,\n\t\tnews: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\n\t\tif (olds.projectId !== news.projectId) {\n\t\t\treplaces.push(\"projectId\");\n\t\t}\n\n\t\tif (olds.teamId !== news.teamId) {\n\t\t\treplaces.push(\"teamId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass VercelDomainResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly verified: pulumi.Output<boolean>;\n\tpublic declare readonly name: pulumi.Output<string>;\n\tpublic declare readonly cnameTarget: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tteamId: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew VercelDomainResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, verified: undefined, cnameTarget: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for VercelDomain — replaces Pulumi's native `provider` field. */\ntype VercelDomainOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n\n\t/** Vercel project to attach the domain to. */\n\tproject: VercelProject;\n};\n\n/** Args for VercelDomain. */\nexport interface VercelDomainArgs {\n\t/** Domain name (e.g. `\"app.example.com\"`). */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Attaches a custom domain to a Vercel project, with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const domain = new VercelDomain(\"aura-domain\", { name: \"app.example.com\" }, { provider, project });\n *\n * // Point app.example.com's DNS CNAME at this value.\n * const cnameTarget = domain.cnameTarget;\n * ```\n */\nexport class VercelDomain extends pulumi.ComponentResource {\n\t/** `true` once the domain's DNS has been verified by Vercel. */\n\tpublic readonly verified: pulumi.Output<boolean>;\n\n\t/** The attached domain name. */\n\tpublic readonly name: pulumi.Output<string>;\n\n\t/**\n\t * The value to CNAME `name` to — Vercel's own recommendation for this specific\n\t * domain, fetched fresh from its DNS config endpoint (falls back to a static default\n\t * only if Vercel returns no recommendation).\n\t */\n\tpublic readonly cnameTarget: pulumi.Output<string>;\n\n\tconstructor(name: string, args: VercelDomainArgs, opts: VercelDomainOptions) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Domain\", name, {}, pulumiOpts);\n\n\t\tconst resource = new VercelDomainResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tteamId: provider.teamId,\n\t\t\t\tprojectId: project.id,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.verified = resource.verified;\n\t\tthis.name = resource.name;\n\t\tthis.cnameTarget = resource.cnameTarget;\n\n\t\tthis.registerOutputs({\n\t\t\tverified: this.verified,\n\t\t\tname: this.name,\n\t\t\tcnameTarget: this.cnameTarget,\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;AAIA,MAAM,iBAAiB;;;;;;;;AASvB,MAAM,+BAA+B;;;;;;AA4CrC,eAAe,iBACd,OACA,QACA,MACkB;CAClB,MAAM,WAAW,MAAM,MACtB,GAAG,eAAe,cAAc,mBAAmB,IAAI,EAAE,iBAAiB,UAC1E,EAAE,SAAS,EAAE,eAAe,UAAU,QAAQ,EAAE,CACjD;CAEA,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MACT,gDAAgD,KAAK,KAAK,SAAS,OAAO,KAAK,MAAM,SAAS,KAAK,GACpG;CAGD,MAAM,EAAE,mBAAmB,CAAC,MAAO,MAAM,SAAS,KAAK;CAIvD,MAAM,YAAY,CAAC,GAAG,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;CAExE,IAAI,CAAC,WAAW;EACf,eAAO,IAAI,KACV,6CAA6C,KAAK,uBAAuB,6BAA6B,EACvG;EAEA,OAAO;CACR;CAEA,OAAO,UAAU;AAClB;;;;AAKA,eAAe,YACd,OACA,QACA,WACA,MACuC;CACvC,MAAM,WAAW,MAAM,MACtB,GAAG,eAAe,eAAe,mBAAmB,SAAS,EAAE,WAAW,mBAAmB,IAAI,EAAE,UAAU,UAC7G,EAAE,SAAS,EAAE,eAAe,UAAU,QAAQ,EAAE,CACjD;CAEA,IAAI,SAAS,WAAW,KACvB,OAAO;CAGR,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MACT,qCAAqC,KAAK,KAAK,SAAS,OAAO,KAAK,MAAM,SAAS,KAAK,GACzF;CAGD,OAAQ,MAAM,SAAS,KAAK;AAC7B;;;;;;;;;AAUA,IAAa,+BAAb,MAEA;CACC,MAAM,OACL,QACuC;EACvC,MAAM,WAAW,MAAM,YACtB,OAAO,OACP,OAAO,QACP,OAAO,WACP,OAAO,IACR;EAEA,IAAI,UAAU;GACb,eAAO,IAAI,KACV,mCAAmC,OAAO,KAAK,eAAe,OAAO,WACtE;GAEA,MAAM,OAA4B;IACjC,GAAG;IACH,UAAU,SAAS;IACnB,aAAa,MAAM,iBAClB,OAAO,OACP,OAAO,QACP,OAAO,IACR;GACD;GAEA,OAAO;IAAE,IAAI,GAAG,OAAO,UAAU,GAAG,OAAO;IAAQ;GAAK;EACzD;EAEA,MAAM,WAAW,MAAM,MACtB,GAAG,eAAe,gBAAgB,mBAAmB,OAAO,SAAS,EAAE,kBAAkB,OAAO,UAChG;GACC,QAAQ;GACR,SAAS;IACR,eAAe,UAAU,OAAO;IAChC,gBAAgB;GACjB;GACA,MAAM,KAAK,UAAU,EAAE,MAAM,OAAO,KAAK,CAAC;EAC3C,CACD;EAEA,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MACT,qCAAqC,OAAO,KAAK,KAAK,SAAS,OAAO,KAAK,MAAM,SAAS,KAAK,GAChG;EAGD,MAAM,UAAW,MAAM,SAAS,KAAK;EAErC,MAAM,OAA4B;GACjC,GAAG;GACH,UAAU,QAAQ;GAClB,aAAa,MAAM,iBAClB,OAAO,OACP,OAAO,QACP,OAAO,IACR;EACD;EAEA,OAAO;GAAE,IAAI,GAAG,OAAO,UAAU,GAAG,OAAO;GAAQ;EAAK;CACzD;CAEA,MAAM,KACL,KACA,OACqC;EACrC,MAAM,SAAS,MAAM,YACpB,MAAM,OACN,MAAM,QACN,MAAM,WACN,MAAM,IACP;EAEA,IAAI,CAAC,QACJ,MAAM,IAAI,MACT,kBAAkB,MAAM,KAAK,yBAAyB,MAAM,WAC7D;EAGD,OAAO;GACN,IAAI,GAAG,MAAM,UAAU,GAAG,MAAM;GAChC,OAAO;IACN,GAAG;IACH,UAAU,OAAO;IACjB,aAAa,MAAM,iBAClB,MAAM,OACN,MAAM,QACN,MAAM,IACP;GACD;EACD;CACD;;CAGA,MAAM,OACL,KACA,MACA,MACuC;EACvC,OAAO,EACN,MAAM;GAAE,GAAG;GAAM,UAAU;GAAO,aAAa,KAAK;EAAY,EACjE;CACD;CAEA,MAAM,OAAO,KAAa,OAA2C;EACpE,MAAM,WAAW,MAAM,MACtB,GAAG,eAAe,eAAe,mBAAmB,MAAM,SAAS,EAAE,WAAW,mBAAmB,MAAM,IAAI,EAAE,UAAU,MAAM,UAC/H;GACC,QAAQ;GACR,SAAS,EAAE,eAAe,UAAU,MAAM,QAAQ;EACnD,CACD;EAEA,IAAI,SAAS,WAAW,KAAK;GAC5B,eAAO,IAAI,KACV,kBAAkB,MAAM,KAAK,8BAA8B,MAAM,WAClE;GAEA;EACD;EAEA,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MACT,qCAAqC,MAAM,KAAK,KAAK,SAAS,OAAO,KAAK,MAAM,SAAS,KAAK,GAC/F;EAGD,eAAO,IAAI,KACV,0BAA0B,MAAM,KAAK,iBAAiB,MAAM,WAC7D;CACD;;;;;CAMA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,SAAS,KAAK,MACtB,SAAS,KAAK,MAAM;EAGrB,IAAI,KAAK,cAAc,KAAK,WAC3B,SAAS,KAAK,WAAW;EAG1B,IAAI,KAAK,WAAW,KAAK,QACxB,SAAS,KAAK,QAAQ;EAGvB,OAAO;GACN,SAAS,SAAS,SAAS;GAC3B;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,uBAAN,cAAmCA,eAAO,QAAQ,SAAS;CAK1D,YACC,MACA,MAMA,MACC;EACD,MACC,IAAI,6BAA6B,GACjC,MACA;GAAE,GAAG;GAAM,UAAU;GAAW,aAAa;EAAU,GACvD,IACD;CACD;AACD;;;;;;;;;;;;AA4BA,IAAa,eAAb,cAAkCA,eAAO,kBAAkB;CAc1D,YAAY,MAAc,MAAwB,MAA2B;EAC5E,MAAM,EAAE,UAAU,SAAS,GAAG,eAAe;EAE7C,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAEtD,MAAM,WAAW,IAAI,qBACpB,GAAG,KAAK,YACR;GACC,OAAO,SAAS;GAChB,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,GAAG;EACJ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,WAAW,SAAS;EACzB,KAAK,OAAO,SAAS;EACrB,KAAK,cAAc,SAAS;EAE5B,KAAK,gBAAgB;GACpB,UAAU,KAAK;GACf,MAAM,KAAK;GACX,aAAa,KAAK;EACnB,CAAC;CACF;AACD"}
|
package/dist/vercel/domain.d.cts
CHANGED
|
@@ -4,11 +4,6 @@ import { VercelProject } from "./project.cjs";
|
|
|
4
4
|
import * as pulumi from "@pulumi/pulumi";
|
|
5
5
|
|
|
6
6
|
//#region src/vercel/domain.d.ts
|
|
7
|
-
/**
|
|
8
|
-
* Vercel's documented CNAME target for attaching a subdomain to a project.
|
|
9
|
-
* https://vercel.com/docs/domains/working-with-domains/add-a-domain
|
|
10
|
-
*/
|
|
11
|
-
declare const VERCEL_CNAME_TARGET = "cname.vercel-dns.com";
|
|
12
7
|
/** Resolved inputs for the Vercel domain dynamic provider. */
|
|
13
8
|
interface VercelDomainInputs {
|
|
14
9
|
/** Vercel API bearer token. */
|
|
@@ -24,6 +19,8 @@ interface VercelDomainInputs {
|
|
|
24
19
|
interface VercelDomainOutputs extends VercelDomainInputs {
|
|
25
20
|
/** `true` once the domain's DNS has been verified by Vercel. */
|
|
26
21
|
verified: boolean;
|
|
22
|
+
/** The value to CNAME `name` to, per Vercel's own per-domain recommendation. */
|
|
23
|
+
cnameTarget: string;
|
|
27
24
|
}
|
|
28
25
|
/**
|
|
29
26
|
* Dynamic provider implementing adopt-or-create for a Vercel project domain.
|
|
@@ -37,7 +34,7 @@ declare class VercelDomainResourceProvider implements pulumi.dynamic.ResourcePro
|
|
|
37
34
|
create(inputs: VercelDomainInputs): Promise<pulumi.dynamic.CreateResult>;
|
|
38
35
|
read(_id: string, props: VercelDomainOutputs): Promise<pulumi.dynamic.ReadResult>;
|
|
39
36
|
/** All fields replace (see `diff`) — this is never actually invoked. */
|
|
40
|
-
update(_id: string,
|
|
37
|
+
update(_id: string, olds: VercelDomainOutputs, news: VercelDomainInputs): Promise<pulumi.dynamic.UpdateResult>;
|
|
41
38
|
delete(_id: string, props: VercelDomainOutputs): Promise<void>;
|
|
42
39
|
/**
|
|
43
40
|
* A domain can only be attached to one project, so every field change replaces
|
|
@@ -60,7 +57,10 @@ interface VercelDomainArgs {
|
|
|
60
57
|
*
|
|
61
58
|
* @example
|
|
62
59
|
* ```typescript
|
|
63
|
-
* new VercelDomain("aura-domain", { name: "app.example.com" }, { provider, project });
|
|
60
|
+
* const domain = new VercelDomain("aura-domain", { name: "app.example.com" }, { provider, project });
|
|
61
|
+
*
|
|
62
|
+
* // Point app.example.com's DNS CNAME at this value.
|
|
63
|
+
* const cnameTarget = domain.cnameTarget;
|
|
64
64
|
* ```
|
|
65
65
|
*/
|
|
66
66
|
declare class VercelDomain extends pulumi.ComponentResource {
|
|
@@ -68,8 +68,14 @@ declare class VercelDomain extends pulumi.ComponentResource {
|
|
|
68
68
|
readonly verified: pulumi.Output<boolean>;
|
|
69
69
|
/** The attached domain name. */
|
|
70
70
|
readonly name: pulumi.Output<string>;
|
|
71
|
+
/**
|
|
72
|
+
* The value to CNAME `name` to — Vercel's own recommendation for this specific
|
|
73
|
+
* domain, fetched fresh from its DNS config endpoint (falls back to a static default
|
|
74
|
+
* only if Vercel returns no recommendation).
|
|
75
|
+
*/
|
|
76
|
+
readonly cnameTarget: pulumi.Output<string>;
|
|
71
77
|
constructor(name: string, args: VercelDomainArgs, opts: VercelDomainOptions);
|
|
72
78
|
}
|
|
73
79
|
//#endregion
|
|
74
|
-
export {
|
|
80
|
+
export { VercelDomain, VercelDomainArgs, VercelDomainInputs, VercelDomainResourceProvider };
|
|
75
81
|
//# sourceMappingURL=domain.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain.d.cts","names":[],"sources":["../../src/vercel/domain.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"domain.d.cts","names":[],"sources":["../../src/vercel/domain.ts"],"mappings":";;;;;;;UAgBiB,kBAAA;;EAEhB,KAAA;EAFkC;EAKlC,MAAA;EALkC;EAQlC,SAAA;EAHA;EAMA,IAAA;AAAA;;UAIS,mBAAA,SAA4B,kBAAkB;EAA9C;EAET,QAAA;;EAGA,WAAA;AAAA;;;;AAAW;AAyFZ;;;;cAAa,4BAAA,YACD,MAAA,CAAO,OAAA,CAAQ,gBAAA;EAEpB,MAAA,CACL,MAAA,EAAQ,kBAAA,GACN,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,YAAA;EA2DpB,IAAA,CACL,GAAA,UACA,KAAA,EAAO,mBAAA,GACL,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,UAAA;EAAf;EA6BL,MAAA,CACL,GAAA,UACA,IAAA,EAAM,mBAAA,EACN,IAAA,EAAM,kBAAA,GACJ,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,YAAA;EAMpB,MAAA,CAAO,GAAA,UAAa,KAAA,EAAO,mBAAA,GAAsB,OAAA;EAPhD;;;;EAuCD,IAAA,CACL,GAAA,UACA,IAAA,EAAM,mBAAA,EACN,IAAA,EAAM,kBAAA,GACJ,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,UAAA;AAAA;;KAiDtB,mBAAA,GAAsB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAjDnC,qCAmDH,QAAA,EAAU,cAAA,EAhMgC;EAmM1C,OAAA,EAAS,aAAA;AAAA;;UAIO,gBAAA;EArMV;EAuMN,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;;;;;cAcN,YAAA,SAAqB,MAAA,CAAO,iBAAA;EAxHlC;EAAA,SA0HU,QAAA,EAAU,MAAA,CAAO,MAAA;EAxH1B;EAAA,SA2HS,IAAA,EAAM,MAAA,CAAO,MAAA;EA1HtB;;;;;EAAA,SAiIS,WAAA,EAAa,MAAA,CAAO,MAAA;cAExB,IAAA,UAAc,IAAA,EAAM,gBAAA,EAAkB,IAAA,EAAM,mBAAA;AAAA"}
|
package/dist/vercel/domain.d.mts
CHANGED
|
@@ -4,11 +4,6 @@ import { VercelProject } from "./project.mjs";
|
|
|
4
4
|
import * as pulumi from "@pulumi/pulumi";
|
|
5
5
|
|
|
6
6
|
//#region src/vercel/domain.d.ts
|
|
7
|
-
/**
|
|
8
|
-
* Vercel's documented CNAME target for attaching a subdomain to a project.
|
|
9
|
-
* https://vercel.com/docs/domains/working-with-domains/add-a-domain
|
|
10
|
-
*/
|
|
11
|
-
declare const VERCEL_CNAME_TARGET = "cname.vercel-dns.com";
|
|
12
7
|
/** Resolved inputs for the Vercel domain dynamic provider. */
|
|
13
8
|
interface VercelDomainInputs {
|
|
14
9
|
/** Vercel API bearer token. */
|
|
@@ -24,6 +19,8 @@ interface VercelDomainInputs {
|
|
|
24
19
|
interface VercelDomainOutputs extends VercelDomainInputs {
|
|
25
20
|
/** `true` once the domain's DNS has been verified by Vercel. */
|
|
26
21
|
verified: boolean;
|
|
22
|
+
/** The value to CNAME `name` to, per Vercel's own per-domain recommendation. */
|
|
23
|
+
cnameTarget: string;
|
|
27
24
|
}
|
|
28
25
|
/**
|
|
29
26
|
* Dynamic provider implementing adopt-or-create for a Vercel project domain.
|
|
@@ -37,7 +34,7 @@ declare class VercelDomainResourceProvider implements pulumi.dynamic.ResourcePro
|
|
|
37
34
|
create(inputs: VercelDomainInputs): Promise<pulumi.dynamic.CreateResult>;
|
|
38
35
|
read(_id: string, props: VercelDomainOutputs): Promise<pulumi.dynamic.ReadResult>;
|
|
39
36
|
/** All fields replace (see `diff`) — this is never actually invoked. */
|
|
40
|
-
update(_id: string,
|
|
37
|
+
update(_id: string, olds: VercelDomainOutputs, news: VercelDomainInputs): Promise<pulumi.dynamic.UpdateResult>;
|
|
41
38
|
delete(_id: string, props: VercelDomainOutputs): Promise<void>;
|
|
42
39
|
/**
|
|
43
40
|
* A domain can only be attached to one project, so every field change replaces
|
|
@@ -60,7 +57,10 @@ interface VercelDomainArgs {
|
|
|
60
57
|
*
|
|
61
58
|
* @example
|
|
62
59
|
* ```typescript
|
|
63
|
-
* new VercelDomain("aura-domain", { name: "app.example.com" }, { provider, project });
|
|
60
|
+
* const domain = new VercelDomain("aura-domain", { name: "app.example.com" }, { provider, project });
|
|
61
|
+
*
|
|
62
|
+
* // Point app.example.com's DNS CNAME at this value.
|
|
63
|
+
* const cnameTarget = domain.cnameTarget;
|
|
64
64
|
* ```
|
|
65
65
|
*/
|
|
66
66
|
declare class VercelDomain extends pulumi.ComponentResource {
|
|
@@ -68,8 +68,14 @@ declare class VercelDomain extends pulumi.ComponentResource {
|
|
|
68
68
|
readonly verified: pulumi.Output<boolean>;
|
|
69
69
|
/** The attached domain name. */
|
|
70
70
|
readonly name: pulumi.Output<string>;
|
|
71
|
+
/**
|
|
72
|
+
* The value to CNAME `name` to — Vercel's own recommendation for this specific
|
|
73
|
+
* domain, fetched fresh from its DNS config endpoint (falls back to a static default
|
|
74
|
+
* only if Vercel returns no recommendation).
|
|
75
|
+
*/
|
|
76
|
+
readonly cnameTarget: pulumi.Output<string>;
|
|
71
77
|
constructor(name: string, args: VercelDomainArgs, opts: VercelDomainOptions);
|
|
72
78
|
}
|
|
73
79
|
//#endregion
|
|
74
|
-
export {
|
|
80
|
+
export { VercelDomain, VercelDomainArgs, VercelDomainInputs, VercelDomainResourceProvider };
|
|
75
81
|
//# sourceMappingURL=domain.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain.d.mts","names":[],"sources":["../../src/vercel/domain.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"domain.d.mts","names":[],"sources":["../../src/vercel/domain.ts"],"mappings":";;;;;;;UAgBiB,kBAAA;;EAEhB,KAAA;EAFkC;EAKlC,MAAA;EALkC;EAQlC,SAAA;EAHA;EAMA,IAAA;AAAA;;UAIS,mBAAA,SAA4B,kBAAkB;EAA9C;EAET,QAAA;;EAGA,WAAA;AAAA;;;;AAAW;AAyFZ;;;;cAAa,4BAAA,YACD,MAAA,CAAO,OAAA,CAAQ,gBAAA;EAEpB,MAAA,CACL,MAAA,EAAQ,kBAAA,GACN,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,YAAA;EA2DpB,IAAA,CACL,GAAA,UACA,KAAA,EAAO,mBAAA,GACL,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,UAAA;EAAf;EA6BL,MAAA,CACL,GAAA,UACA,IAAA,EAAM,mBAAA,EACN,IAAA,EAAM,kBAAA,GACJ,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,YAAA;EAMpB,MAAA,CAAO,GAAA,UAAa,KAAA,EAAO,mBAAA,GAAsB,OAAA;EAPhD;;;;EAuCD,IAAA,CACL,GAAA,UACA,IAAA,EAAM,mBAAA,EACN,IAAA,EAAM,kBAAA,GACJ,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,UAAA;AAAA;;KAiDtB,mBAAA,GAAsB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAjDnC,qCAmDH,QAAA,EAAU,cAAA,EAhMgC;EAmM1C,OAAA,EAAS,aAAA;AAAA;;UAIO,gBAAA;EArMV;EAuMN,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;;;;;cAcN,YAAA,SAAqB,MAAA,CAAO,iBAAA;EAxHlC;EAAA,SA0HU,QAAA,EAAU,MAAA,CAAO,MAAA;EAxH1B;EAAA,SA2HS,IAAA,EAAM,MAAA,CAAO,MAAA;EA1HtB;;;;;EAAA,SAiIS,WAAA,EAAa,MAAA,CAAO,MAAA;cAExB,IAAA,UAAc,IAAA,EAAM,gBAAA,EAAkB,IAAA,EAAM,mBAAA;AAAA"}
|
package/dist/vercel/domain.mjs
CHANGED
|
@@ -4,10 +4,29 @@ import * as pulumi from "@pulumi/pulumi";
|
|
|
4
4
|
//#region src/vercel/domain.ts
|
|
5
5
|
const VERCEL_API_URL = "https://api.vercel.com";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Fallback CNAME target, used only when Vercel's domain-config endpoint returns no
|
|
8
|
+
* recommendation (see {@link fetchCnameTarget}). Not the primary source of truth —
|
|
9
|
+
* `VercelDomain.cnameTarget` queries Vercel's per-domain recommendation dynamically,
|
|
10
|
+
* since the actual target can vary by account/domain.
|
|
8
11
|
* https://vercel.com/docs/domains/working-with-domains/add-a-domain
|
|
9
12
|
*/
|
|
10
|
-
const
|
|
13
|
+
const VERCEL_CNAME_TARGET_FALLBACK = "cname.vercel-dns.com";
|
|
14
|
+
/**
|
|
15
|
+
* Fetches Vercel's recommended CNAME target for a domain from its DNS config endpoint.
|
|
16
|
+
* Falls back to {@link VERCEL_CNAME_TARGET_FALLBACK} if Vercel returns no recommendation
|
|
17
|
+
* (logged, since that's an unusual state worth noticing rather than silently accepting).
|
|
18
|
+
*/
|
|
19
|
+
async function fetchCnameTarget(token, teamId, name) {
|
|
20
|
+
const response = await fetch(`${VERCEL_API_URL}/v6/domains/${encodeURIComponent(name)}/config?teamId=${teamId}`, { headers: { Authorization: `Bearer ${token}` } });
|
|
21
|
+
if (!response.ok) throw new Error(`Vercel API error fetching domain config for "${name}" (${response.status}): ${await response.text()}`);
|
|
22
|
+
const { recommendedCNAME = [] } = await response.json();
|
|
23
|
+
const preferred = [...recommendedCNAME].sort((a, b) => a.rank - b.rank)[0];
|
|
24
|
+
if (!preferred) {
|
|
25
|
+
pulumi.log.info(`Vercel returned no recommended CNAME for "${name}" — falling back to "${VERCEL_CNAME_TARGET_FALLBACK}"`);
|
|
26
|
+
return VERCEL_CNAME_TARGET_FALLBACK;
|
|
27
|
+
}
|
|
28
|
+
return preferred.value;
|
|
29
|
+
}
|
|
11
30
|
/**
|
|
12
31
|
* Fetches a project domain by name. Returns `null` if not attached (404).
|
|
13
32
|
*/
|
|
@@ -32,7 +51,8 @@ var VercelDomainResourceProvider = class {
|
|
|
32
51
|
pulumi.log.info(`Adopted existing Vercel domain "${inputs.name}" on project ${inputs.projectId}`);
|
|
33
52
|
const outs = {
|
|
34
53
|
...inputs,
|
|
35
|
-
verified: existing.verified
|
|
54
|
+
verified: existing.verified,
|
|
55
|
+
cnameTarget: await fetchCnameTarget(inputs.token, inputs.teamId, inputs.name)
|
|
36
56
|
};
|
|
37
57
|
return {
|
|
38
58
|
id: `${inputs.projectId}/${inputs.name}`,
|
|
@@ -51,7 +71,8 @@ var VercelDomainResourceProvider = class {
|
|
|
51
71
|
const created = await response.json();
|
|
52
72
|
const outs = {
|
|
53
73
|
...inputs,
|
|
54
|
-
verified: created.verified
|
|
74
|
+
verified: created.verified,
|
|
75
|
+
cnameTarget: await fetchCnameTarget(inputs.token, inputs.teamId, inputs.name)
|
|
55
76
|
};
|
|
56
77
|
return {
|
|
57
78
|
id: `${inputs.projectId}/${inputs.name}`,
|
|
@@ -65,15 +86,17 @@ var VercelDomainResourceProvider = class {
|
|
|
65
86
|
id: `${props.projectId}/${props.name}`,
|
|
66
87
|
props: {
|
|
67
88
|
...props,
|
|
68
|
-
verified: domain.verified
|
|
89
|
+
verified: domain.verified,
|
|
90
|
+
cnameTarget: await fetchCnameTarget(props.token, props.teamId, props.name)
|
|
69
91
|
}
|
|
70
92
|
};
|
|
71
93
|
}
|
|
72
94
|
/** All fields replace (see `diff`) — this is never actually invoked. */
|
|
73
|
-
async update(_id,
|
|
95
|
+
async update(_id, olds, news) {
|
|
74
96
|
return { outs: {
|
|
75
97
|
...news,
|
|
76
|
-
verified: false
|
|
98
|
+
verified: false,
|
|
99
|
+
cnameTarget: olds.cnameTarget
|
|
77
100
|
} };
|
|
78
101
|
}
|
|
79
102
|
async delete(_id, props) {
|
|
@@ -109,7 +132,8 @@ var VercelDomainResource = class extends pulumi.dynamic.Resource {
|
|
|
109
132
|
constructor(name, args, opts) {
|
|
110
133
|
super(new VercelDomainResourceProvider(), name, {
|
|
111
134
|
...args,
|
|
112
|
-
verified: void 0
|
|
135
|
+
verified: void 0,
|
|
136
|
+
cnameTarget: void 0
|
|
113
137
|
}, opts);
|
|
114
138
|
}
|
|
115
139
|
};
|
|
@@ -118,7 +142,10 @@ var VercelDomainResource = class extends pulumi.dynamic.Resource {
|
|
|
118
142
|
*
|
|
119
143
|
* @example
|
|
120
144
|
* ```typescript
|
|
121
|
-
* new VercelDomain("aura-domain", { name: "app.example.com" }, { provider, project });
|
|
145
|
+
* const domain = new VercelDomain("aura-domain", { name: "app.example.com" }, { provider, project });
|
|
146
|
+
*
|
|
147
|
+
* // Point app.example.com's DNS CNAME at this value.
|
|
148
|
+
* const cnameTarget = domain.cnameTarget;
|
|
122
149
|
* ```
|
|
123
150
|
*/
|
|
124
151
|
var VercelDomain = class extends pulumi.ComponentResource {
|
|
@@ -133,13 +160,15 @@ var VercelDomain = class extends pulumi.ComponentResource {
|
|
|
133
160
|
}, { parent: this });
|
|
134
161
|
this.verified = resource.verified;
|
|
135
162
|
this.name = resource.name;
|
|
163
|
+
this.cnameTarget = resource.cnameTarget;
|
|
136
164
|
this.registerOutputs({
|
|
137
165
|
verified: this.verified,
|
|
138
|
-
name: this.name
|
|
166
|
+
name: this.name,
|
|
167
|
+
cnameTarget: this.cnameTarget
|
|
139
168
|
});
|
|
140
169
|
}
|
|
141
170
|
};
|
|
142
171
|
|
|
143
172
|
//#endregion
|
|
144
|
-
export {
|
|
173
|
+
export { VercelDomain, VercelDomainResourceProvider };
|
|
145
174
|
//# sourceMappingURL=domain.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain.mjs","names":[],"sources":["../../src/vercel/domain.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport type { VercelProject } from \"./project\";\nimport type { VercelProvider } from \"./provider\";\n\nconst VERCEL_API_URL = \"https://api.vercel.com\";\n\n/**\n * Vercel's documented CNAME target for attaching a subdomain to a project.\n * https://vercel.com/docs/domains/working-with-domains/add-a-domain\n */\nexport const VERCEL_CNAME_TARGET = \"cname.vercel-dns.com\";\n\n/** Resolved inputs for the Vercel domain dynamic provider. */\nexport interface VercelDomainInputs {\n\t/** Vercel API bearer token. */\n\ttoken: string;\n\n\t/** Vercel team/org ID. */\n\tteamId: string;\n\n\t/** Vercel project ID to attach the domain to. */\n\tprojectId: string;\n\n\t/** Domain name (e.g. `\"app.example.com\"`). */\n\tname: string;\n}\n\n/** Persisted state for the Vercel domain, extending inputs with verification status. */\ninterface VercelDomainOutputs extends VercelDomainInputs {\n\t/** `true` once the domain's DNS has been verified by Vercel. */\n\tverified: boolean;\n}\n\n/** Vercel API response shape for a project domain. */\ninterface VercelDomainResponse {\n\tname: string;\n\tprojectId: string;\n\tverified: boolean;\n}\n\n/**\n * Fetches a project domain by name. Returns `null` if not attached (404).\n */\nasync function fetchDomain(\n\ttoken: string,\n\tteamId: string,\n\tprojectId: string,\n\tname: string,\n): Promise<VercelDomainResponse | null> {\n\tconst response = await fetch(\n\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(name)}?teamId=${teamId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\tif (response.status === 404) {\n\t\treturn null;\n\t}\n\n\tif (!response.ok) {\n\t\tthrow new Error(\n\t\t\t`Vercel API error fetching domain \"${name}\" (${response.status}): ${await response.text()}`,\n\t\t);\n\t}\n\n\treturn (await response.json()) as VercelDomainResponse;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for a Vercel project domain.\n *\n * On `create()`, calls `GET /v9/projects/{projectId}/domains/{name}`. If found, adopts\n * the existing attachment. If 404, attaches it via `POST /v10/projects/{projectId}/domains`.\n *\n * @internal Exported only for unit testing; not part of the public API surface.\n */\nexport class VercelDomainResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst existing = await fetchDomain(\n\t\t\tinputs.token,\n\t\t\tinputs.teamId,\n\t\t\tinputs.projectId,\n\t\t\tinputs.name,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopted existing Vercel domain \"${inputs.name}\" on project ${inputs.projectId}`,\n\t\t\t);\n\n\t\t\tconst outs: VercelDomainOutputs = {\n\t\t\t\t...inputs,\n\t\t\t\tverified: existing.verified,\n\t\t\t};\n\n\t\t\treturn { id: `${inputs.projectId}/${inputs.name}`, outs };\n\t\t}\n\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v10/projects/${encodeURIComponent(inputs.projectId)}/domains?teamId=${inputs.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${inputs.token}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ name: inputs.name }),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error creating domain \"${inputs.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tconst created = (await response.json()) as VercelDomainResponse;\n\n\t\tconst outs: VercelDomainOutputs = { ...inputs, verified: created.verified };\n\n\t\treturn { id: `${inputs.projectId}/${inputs.name}`, outs };\n\t}\n\n\tasync read(\n\t\t_id: string,\n\t\tprops: VercelDomainOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst domain = await fetchDomain(\n\t\t\tprops.token,\n\t\t\tprops.teamId,\n\t\t\tprops.projectId,\n\t\t\tprops.name,\n\t\t);\n\n\t\tif (!domain) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel domain \"${props.name}\" not found on project ${props.projectId}`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: `${props.projectId}/${props.name}`,\n\t\t\tprops: { ...props, verified: domain.verified },\n\t\t};\n\t}\n\n\t/** All fields replace (see `diff`) — this is never actually invoked. */\n\tasync update(\n\t\t_id: string,\n\t\t_olds: VercelDomainOutputs,\n\t\tnews: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\treturn { outs: { ...news, verified: false } };\n\t}\n\n\tasync delete(_id: string, props: VercelDomainOutputs): Promise<void> {\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(props.projectId)}/domains/${encodeURIComponent(props.name)}?teamId=${props.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\theaders: { Authorization: `Bearer ${props.token}` },\n\t\t\t},\n\t\t);\n\n\t\tif (response.status === 404) {\n\t\t\tpulumi.log.warn(\n\t\t\t\t`Vercel domain \"${props.name}\" already gone from project ${props.projectId}`,\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error deleting domain \"${props.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tpulumi.log.info(\n\t\t\t`Deleted Vercel domain \"${props.name}\" from project ${props.projectId}`,\n\t\t);\n\t}\n\n\t/**\n\t * A domain can only be attached to one project, so every field change replaces\n\t * rather than updates.\n\t */\n\tasync diff(\n\t\t_id: string,\n\t\tolds: VercelDomainOutputs,\n\t\tnews: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\n\t\tif (olds.projectId !== news.projectId) {\n\t\t\treplaces.push(\"projectId\");\n\t\t}\n\n\t\tif (olds.teamId !== news.teamId) {\n\t\t\treplaces.push(\"teamId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass VercelDomainResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly verified: pulumi.Output<boolean>;\n\tpublic declare readonly name: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tteamId: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew VercelDomainResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, verified: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for VercelDomain — replaces Pulumi's native `provider` field. */\ntype VercelDomainOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n\n\t/** Vercel project to attach the domain to. */\n\tproject: VercelProject;\n};\n\n/** Args for VercelDomain. */\nexport interface VercelDomainArgs {\n\t/** Domain name (e.g. `\"app.example.com\"`). */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Attaches a custom domain to a Vercel project, with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * new VercelDomain(\"aura-domain\", { name: \"app.example.com\" }, { provider, project });\n * ```\n */\nexport class VercelDomain extends pulumi.ComponentResource {\n\t/** `true` once the domain's DNS has been verified by Vercel. */\n\tpublic readonly verified: pulumi.Output<boolean>;\n\n\t/** The attached domain name. */\n\tpublic readonly name: pulumi.Output<string>;\n\n\tconstructor(name: string, args: VercelDomainArgs, opts: VercelDomainOptions) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Domain\", name, {}, pulumiOpts);\n\n\t\tconst resource = new VercelDomainResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tteamId: provider.teamId,\n\t\t\t\tprojectId: project.id,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.verified = resource.verified;\n\t\tthis.name = resource.name;\n\n\t\tthis.registerOutputs({ verified: this.verified, name: this.name });\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"domain.mjs","names":[],"sources":["../../src/vercel/domain.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport type { VercelProject } from \"./project\";\nimport type { VercelProvider } from \"./provider\";\n\nconst VERCEL_API_URL = \"https://api.vercel.com\";\n\n/**\n * Fallback CNAME target, used only when Vercel's domain-config endpoint returns no\n * recommendation (see {@link fetchCnameTarget}). Not the primary source of truth —\n * `VercelDomain.cnameTarget` queries Vercel's per-domain recommendation dynamically,\n * since the actual target can vary by account/domain.\n * https://vercel.com/docs/domains/working-with-domains/add-a-domain\n */\nconst VERCEL_CNAME_TARGET_FALLBACK = \"cname.vercel-dns.com\";\n\n/** Resolved inputs for the Vercel domain dynamic provider. */\nexport interface VercelDomainInputs {\n\t/** Vercel API bearer token. */\n\ttoken: string;\n\n\t/** Vercel team/org ID. */\n\tteamId: string;\n\n\t/** Vercel project ID to attach the domain to. */\n\tprojectId: string;\n\n\t/** Domain name (e.g. `\"app.example.com\"`). */\n\tname: string;\n}\n\n/** Persisted state for the Vercel domain, extending inputs with verification status. */\ninterface VercelDomainOutputs extends VercelDomainInputs {\n\t/** `true` once the domain's DNS has been verified by Vercel. */\n\tverified: boolean;\n\n\t/** The value to CNAME `name` to, per Vercel's own per-domain recommendation. */\n\tcnameTarget: string;\n}\n\n/** Vercel API response shape for a project domain. */\ninterface VercelDomainResponse {\n\tname: string;\n\tprojectId: string;\n\tverified: boolean;\n}\n\n/** A single ranked CNAME recommendation from `GET /v6/domains/{domain}/config`. */\ninterface VercelRecommendedCname {\n\trank: number;\n\tvalue: string;\n}\n\n/**\n * Fetches Vercel's recommended CNAME target for a domain from its DNS config endpoint.\n * Falls back to {@link VERCEL_CNAME_TARGET_FALLBACK} if Vercel returns no recommendation\n * (logged, since that's an unusual state worth noticing rather than silently accepting).\n */\nasync function fetchCnameTarget(\n\ttoken: string,\n\tteamId: string,\n\tname: string,\n): Promise<string> {\n\tconst response = await fetch(\n\t\t`${VERCEL_API_URL}/v6/domains/${encodeURIComponent(name)}/config?teamId=${teamId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\tif (!response.ok) {\n\t\tthrow new Error(\n\t\t\t`Vercel API error fetching domain config for \"${name}\" (${response.status}): ${await response.text()}`,\n\t\t);\n\t}\n\n\tconst { recommendedCNAME = [] } = (await response.json()) as {\n\t\trecommendedCNAME?: VercelRecommendedCname[];\n\t};\n\n\tconst preferred = [...recommendedCNAME].sort((a, b) => a.rank - b.rank)[0];\n\n\tif (!preferred) {\n\t\tpulumi.log.info(\n\t\t\t`Vercel returned no recommended CNAME for \"${name}\" — falling back to \"${VERCEL_CNAME_TARGET_FALLBACK}\"`,\n\t\t);\n\n\t\treturn VERCEL_CNAME_TARGET_FALLBACK;\n\t}\n\n\treturn preferred.value;\n}\n\n/**\n * Fetches a project domain by name. Returns `null` if not attached (404).\n */\nasync function fetchDomain(\n\ttoken: string,\n\tteamId: string,\n\tprojectId: string,\n\tname: string,\n): Promise<VercelDomainResponse | null> {\n\tconst response = await fetch(\n\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(projectId)}/domains/${encodeURIComponent(name)}?teamId=${teamId}`,\n\t\t{ headers: { Authorization: `Bearer ${token}` } },\n\t);\n\n\tif (response.status === 404) {\n\t\treturn null;\n\t}\n\n\tif (!response.ok) {\n\t\tthrow new Error(\n\t\t\t`Vercel API error fetching domain \"${name}\" (${response.status}): ${await response.text()}`,\n\t\t);\n\t}\n\n\treturn (await response.json()) as VercelDomainResponse;\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for a Vercel project domain.\n *\n * On `create()`, calls `GET /v9/projects/{projectId}/domains/{name}`. If found, adopts\n * the existing attachment. If 404, attaches it via `POST /v10/projects/{projectId}/domains`.\n *\n * @internal Exported only for unit testing; not part of the public API surface.\n */\nexport class VercelDomainResourceProvider\n\timplements pulumi.dynamic.ResourceProvider\n{\n\tasync create(\n\t\tinputs: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst existing = await fetchDomain(\n\t\t\tinputs.token,\n\t\t\tinputs.teamId,\n\t\t\tinputs.projectId,\n\t\t\tinputs.name,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopted existing Vercel domain \"${inputs.name}\" on project ${inputs.projectId}`,\n\t\t\t);\n\n\t\t\tconst outs: VercelDomainOutputs = {\n\t\t\t\t...inputs,\n\t\t\t\tverified: existing.verified,\n\t\t\t\tcnameTarget: await fetchCnameTarget(\n\t\t\t\t\tinputs.token,\n\t\t\t\t\tinputs.teamId,\n\t\t\t\t\tinputs.name,\n\t\t\t\t),\n\t\t\t};\n\n\t\t\treturn { id: `${inputs.projectId}/${inputs.name}`, outs };\n\t\t}\n\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v10/projects/${encodeURIComponent(inputs.projectId)}/domains?teamId=${inputs.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${inputs.token}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ name: inputs.name }),\n\t\t\t},\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error creating domain \"${inputs.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tconst created = (await response.json()) as VercelDomainResponse;\n\n\t\tconst outs: VercelDomainOutputs = {\n\t\t\t...inputs,\n\t\t\tverified: created.verified,\n\t\t\tcnameTarget: await fetchCnameTarget(\n\t\t\t\tinputs.token,\n\t\t\t\tinputs.teamId,\n\t\t\t\tinputs.name,\n\t\t\t),\n\t\t};\n\n\t\treturn { id: `${inputs.projectId}/${inputs.name}`, outs };\n\t}\n\n\tasync read(\n\t\t_id: string,\n\t\tprops: VercelDomainOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst domain = await fetchDomain(\n\t\t\tprops.token,\n\t\t\tprops.teamId,\n\t\t\tprops.projectId,\n\t\t\tprops.name,\n\t\t);\n\n\t\tif (!domain) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel domain \"${props.name}\" not found on project ${props.projectId}`,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: `${props.projectId}/${props.name}`,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tverified: domain.verified,\n\t\t\t\tcnameTarget: await fetchCnameTarget(\n\t\t\t\t\tprops.token,\n\t\t\t\t\tprops.teamId,\n\t\t\t\t\tprops.name,\n\t\t\t\t),\n\t\t\t},\n\t\t};\n\t}\n\n\t/** All fields replace (see `diff`) — this is never actually invoked. */\n\tasync update(\n\t\t_id: string,\n\t\tolds: VercelDomainOutputs,\n\t\tnews: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\treturn {\n\t\t\touts: { ...news, verified: false, cnameTarget: olds.cnameTarget },\n\t\t};\n\t}\n\n\tasync delete(_id: string, props: VercelDomainOutputs): Promise<void> {\n\t\tconst response = await fetch(\n\t\t\t`${VERCEL_API_URL}/v9/projects/${encodeURIComponent(props.projectId)}/domains/${encodeURIComponent(props.name)}?teamId=${props.teamId}`,\n\t\t\t{\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\theaders: { Authorization: `Bearer ${props.token}` },\n\t\t\t},\n\t\t);\n\n\t\tif (response.status === 404) {\n\t\t\tpulumi.log.warn(\n\t\t\t\t`Vercel domain \"${props.name}\" already gone from project ${props.projectId}`,\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vercel API error deleting domain \"${props.name}\" (${response.status}): ${await response.text()}`,\n\t\t\t);\n\t\t}\n\n\t\tpulumi.log.info(\n\t\t\t`Deleted Vercel domain \"${props.name}\" from project ${props.projectId}`,\n\t\t);\n\t}\n\n\t/**\n\t * A domain can only be attached to one project, so every field change replaces\n\t * rather than updates.\n\t */\n\tasync diff(\n\t\t_id: string,\n\t\tolds: VercelDomainOutputs,\n\t\tnews: VercelDomainInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\n\t\tif (olds.projectId !== news.projectId) {\n\t\t\treplaces.push(\"projectId\");\n\t\t}\n\n\t\tif (olds.teamId !== news.teamId) {\n\t\t\treplaces.push(\"teamId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass VercelDomainResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly verified: pulumi.Output<boolean>;\n\tpublic declare readonly name: pulumi.Output<string>;\n\tpublic declare readonly cnameTarget: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\ttoken: pulumi.Input<string>;\n\t\t\tteamId: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew VercelDomainResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, verified: undefined, cnameTarget: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for VercelDomain — replaces Pulumi's native `provider` field. */\ntype VercelDomainOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Vercel authentication context. */\n\tprovider: VercelProvider;\n\n\t/** Vercel project to attach the domain to. */\n\tproject: VercelProject;\n};\n\n/** Args for VercelDomain. */\nexport interface VercelDomainArgs {\n\t/** Domain name (e.g. `\"app.example.com\"`). */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Attaches a custom domain to a Vercel project, with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const domain = new VercelDomain(\"aura-domain\", { name: \"app.example.com\" }, { provider, project });\n *\n * // Point app.example.com's DNS CNAME at this value.\n * const cnameTarget = domain.cnameTarget;\n * ```\n */\nexport class VercelDomain extends pulumi.ComponentResource {\n\t/** `true` once the domain's DNS has been verified by Vercel. */\n\tpublic readonly verified: pulumi.Output<boolean>;\n\n\t/** The attached domain name. */\n\tpublic readonly name: pulumi.Output<string>;\n\n\t/**\n\t * The value to CNAME `name` to — Vercel's own recommendation for this specific\n\t * domain, fetched fresh from its DNS config endpoint (falls back to a static default\n\t * only if Vercel returns no recommendation).\n\t */\n\tpublic readonly cnameTarget: pulumi.Output<string>;\n\n\tconstructor(name: string, args: VercelDomainArgs, opts: VercelDomainOptions) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:vercel:Domain\", name, {}, pulumiOpts);\n\n\t\tconst resource = new VercelDomainResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\ttoken: provider.token,\n\t\t\t\tteamId: provider.teamId,\n\t\t\t\tprojectId: project.id,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.verified = resource.verified;\n\t\tthis.name = resource.name;\n\t\tthis.cnameTarget = resource.cnameTarget;\n\n\t\tthis.registerOutputs({\n\t\t\tverified: this.verified,\n\t\t\tname: this.name,\n\t\t\tcnameTarget: this.cnameTarget,\n\t\t});\n\t}\n}\n"],"mappings":"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"}
|
package/dist/vercel/index.cjs
CHANGED
|
@@ -8,7 +8,6 @@ const require_vercel_provider = require('./provider.cjs');
|
|
|
8
8
|
const require_vercel_resource_connection = require('./resource-connection.cjs');
|
|
9
9
|
const require_vercel_variable = require('./variable.cjs');
|
|
10
10
|
|
|
11
|
-
exports.VERCEL_CNAME_TARGET = require_vercel_domain.VERCEL_CNAME_TARGET;
|
|
12
11
|
exports.VERCEL_FRAMEWORKS = require_vercel_project.VERCEL_FRAMEWORKS;
|
|
13
12
|
exports.VercelDeploy = require_vercel_deploy.VercelDeploy;
|
|
14
13
|
exports.VercelDomain = require_vercel_domain.VercelDomain;
|
package/dist/vercel/index.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { VercelProvider, VercelProviderArgs } from "./provider.cjs";
|
|
2
2
|
import { VERCEL_FRAMEWORKS, VercelFramework, VercelProject, VercelProjectArgs } from "./project.cjs";
|
|
3
3
|
import { VercelDeploy, VercelDeployArgs } from "./deploy.cjs";
|
|
4
|
-
import {
|
|
4
|
+
import { VercelDomain, VercelDomainArgs } from "./domain.cjs";
|
|
5
5
|
import { VercelIntegration, VercelIntegrationArgs } from "./integration.cjs";
|
|
6
6
|
import { VercelMarketplaceResource, VercelMarketplaceResourceArgs } from "./marketplace-resource.cjs";
|
|
7
7
|
import { VercelResourceConnection, VercelResourceConnectionArgs } from "./resource-connection.cjs";
|
|
8
8
|
import { VercelVariable, VercelVariableArgs } from "./variable.cjs";
|
|
9
|
-
export {
|
|
9
|
+
export { VERCEL_FRAMEWORKS, VercelDeploy, type VercelDeployArgs, VercelDomain, type VercelDomainArgs, type VercelFramework, VercelIntegration, type VercelIntegrationArgs, VercelMarketplaceResource, type VercelMarketplaceResourceArgs, VercelProject, type VercelProjectArgs, VercelProvider, type VercelProviderArgs, VercelResourceConnection, type VercelResourceConnectionArgs, VercelVariable, type VercelVariableArgs };
|
package/dist/vercel/index.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { VercelProvider, VercelProviderArgs } from "./provider.mjs";
|
|
2
2
|
import { VERCEL_FRAMEWORKS, VercelFramework, VercelProject, VercelProjectArgs } from "./project.mjs";
|
|
3
3
|
import { VercelDeploy, VercelDeployArgs } from "./deploy.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { VercelDomain, VercelDomainArgs } from "./domain.mjs";
|
|
5
5
|
import { VercelIntegration, VercelIntegrationArgs } from "./integration.mjs";
|
|
6
6
|
import { VercelMarketplaceResource, VercelMarketplaceResourceArgs } from "./marketplace-resource.mjs";
|
|
7
7
|
import { VercelResourceConnection, VercelResourceConnectionArgs } from "./resource-connection.mjs";
|
|
8
8
|
import { VercelVariable, VercelVariableArgs } from "./variable.mjs";
|
|
9
|
-
export {
|
|
9
|
+
export { VERCEL_FRAMEWORKS, VercelDeploy, type VercelDeployArgs, VercelDomain, type VercelDomainArgs, type VercelFramework, VercelIntegration, type VercelIntegrationArgs, VercelMarketplaceResource, type VercelMarketplaceResourceArgs, VercelProject, type VercelProjectArgs, VercelProvider, type VercelProviderArgs, VercelResourceConnection, type VercelResourceConnectionArgs, VercelVariable, type VercelVariableArgs };
|
package/dist/vercel/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VercelDeploy } from "./deploy.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { VercelDomain } from "./domain.mjs";
|
|
3
3
|
import { VercelIntegration } from "./integration.mjs";
|
|
4
4
|
import { VercelMarketplaceResource } from "./marketplace-resource.mjs";
|
|
5
5
|
import { VERCEL_FRAMEWORKS, VercelProject } from "./project.mjs";
|
|
@@ -7,4 +7,4 @@ import { VercelProvider } from "./provider.mjs";
|
|
|
7
7
|
import { VercelResourceConnection } from "./resource-connection.mjs";
|
|
8
8
|
import { VercelVariable } from "./variable.mjs";
|
|
9
9
|
|
|
10
|
-
export {
|
|
10
|
+
export { VERCEL_FRAMEWORKS, VercelDeploy, VercelDomain, VercelIntegration, VercelMarketplaceResource, VercelProject, VercelProvider, VercelResourceConnection, VercelVariable };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infracraft/pulumi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Native Pulumi providers for Railway, Neon, Vercel, and Fly.io with adopt-or-create semantics and deploy orchestration. No Terraform bridge.",
|