hatchkit 0.1.2 → 0.1.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/completion.d.ts +2 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +207 -0
- package/dist/completion.js.map +1 -0
- package/dist/config.d.ts +33 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +439 -127
- package/dist/config.js.map +1 -1
- package/dist/deploy/keys.d.ts +6 -2
- package/dist/deploy/keys.d.ts.map +1 -1
- package/dist/deploy/keys.js +16 -2
- package/dist/deploy/keys.js.map +1 -1
- package/dist/deploy/pages.d.ts +2 -0
- package/dist/deploy/pages.d.ts.map +1 -0
- package/dist/deploy/pages.js +537 -0
- package/dist/deploy/pages.js.map +1 -0
- package/dist/deploy/rename-domain.d.ts +55 -0
- package/dist/deploy/rename-domain.d.ts.map +1 -0
- package/dist/deploy/rename-domain.js +290 -0
- package/dist/deploy/rename-domain.js.map +1 -0
- package/dist/deploy/terraform.d.ts.map +1 -1
- package/dist/deploy/terraform.js +90 -0
- package/dist/deploy/terraform.js.map +1 -1
- package/dist/dns.d.ts +7 -0
- package/dist/dns.d.ts.map +1 -0
- package/dist/dns.js +124 -0
- package/dist/dns.js.map +1 -0
- package/dist/doctor.d.ts +13 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +368 -0
- package/dist/doctor.js.map +1 -0
- package/dist/explain.d.ts +4 -0
- package/dist/explain.d.ts.map +1 -0
- package/dist/explain.js +173 -0
- package/dist/explain.js.map +1 -0
- package/dist/index.js +477 -46
- package/dist/index.js.map +1 -1
- package/dist/provision/glitchtip.d.ts +3 -0
- package/dist/provision/glitchtip.d.ts.map +1 -1
- package/dist/provision/glitchtip.js +18 -0
- package/dist/provision/glitchtip.js.map +1 -1
- package/dist/provision/index.d.ts +26 -0
- package/dist/provision/index.d.ts.map +1 -1
- package/dist/provision/index.js +435 -60
- package/dist/provision/index.js.map +1 -1
- package/dist/provision/openpanel.d.ts +7 -0
- package/dist/provision/openpanel.d.ts.map +1 -1
- package/dist/provision/openpanel.js +113 -48
- package/dist/provision/openpanel.js.map +1 -1
- package/dist/provision/resend.d.ts +23 -1
- package/dist/provision/resend.d.ts.map +1 -1
- package/dist/provision/resend.js +62 -1
- package/dist/provision/resend.js.map +1 -1
- package/dist/provision/write-env.d.ts +31 -0
- package/dist/provision/write-env.d.ts.map +1 -0
- package/dist/provision/write-env.js +94 -0
- package/dist/provision/write-env.js.map +1 -0
- package/dist/scaffold/infra.d.ts.map +1 -1
- package/dist/scaffold/infra.js +18 -1
- package/dist/scaffold/infra.js.map +1 -1
- package/dist/status.d.ts +30 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +169 -0
- package/dist/status.js.map +1 -0
- package/dist/templates/addons/analytics/sentry.ts.hbs +6 -0
- package/dist/utils/cloudflare-api.d.ts +30 -0
- package/dist/utils/cloudflare-api.d.ts.map +1 -0
- package/dist/utils/cloudflare-api.js +85 -0
- package/dist/utils/cloudflare-api.js.map +1 -0
- package/dist/utils/coolify-api.d.ts +3 -1
- package/dist/utils/coolify-api.d.ts.map +1 -1
- package/dist/utils/coolify-api.js +29 -4
- package/dist/utils/coolify-api.js.map +1 -1
- package/dist/utils/inwx-api.d.ts +36 -0
- package/dist/utils/inwx-api.d.ts.map +1 -0
- package/dist/utils/inwx-api.js +105 -0
- package/dist/utils/inwx-api.js.map +1 -0
- package/dist/utils/secrets.d.ts +8 -1
- package/dist/utils/secrets.d.ts.map +1 -1
- package/dist/utils/secrets.js +8 -1
- package/dist/utils/secrets.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,66 +1,131 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* OpenPanel provisioning —
|
|
3
|
-
*
|
|
2
|
+
* OpenPanel provisioning — uses the Management API (authenticated with a
|
|
3
|
+
* root-mode client) to create a project + a write client for <clientName>.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Auth model: custom headers `openpanel-client-id` / `openpanel-client-secret`,
|
|
6
|
+
* NOT Authorization: Bearer. See https://openpanel.dev/docs/api/authentication.
|
|
7
|
+
*
|
|
8
|
+
* Endpoint shapes (from the OpenPanel source):
|
|
9
|
+
* POST {apiUrl}/manage/projects body: { name } ->
|
|
10
|
+
* { data: { id, ..., client: { id, secret } } }
|
|
11
|
+
* POST {apiUrl}/manage/clients body: { name, projectId, type: "write" } ->
|
|
12
|
+
* { data: { id, secret, ... } }
|
|
13
|
+
* DELETE {apiUrl}/manage/projects/{projectId}
|
|
14
|
+
*
|
|
15
|
+
* Per-project ids + secrets are cached in the keychain so re-runs are
|
|
16
|
+
* idempotent and `delete` can target the exact upstream project.
|
|
9
17
|
*/
|
|
10
|
-
import { input, password as passwordPrompt } from "@inquirer/prompts";
|
|
11
18
|
import { ensureOpenpanel } from "../config.js";
|
|
12
|
-
import { SECRET_KEYS, getSecret, setSecret } from "../utils/secrets.js";
|
|
19
|
+
import { SECRET_KEYS, deleteSecret, getSecret, setSecret } from "../utils/secrets.js";
|
|
20
|
+
/** Extra cache slot for the upstream project id, used by `deleteOpenpanelClient`
|
|
21
|
+
* — separate from the client id slot so we can target the right row. */
|
|
22
|
+
const projectIdKey = (clientName) => SECRET_KEYS.openpanelClientSecret(`${clientName}:project-id`);
|
|
23
|
+
const clientIdKey = (clientName) => SECRET_KEYS.openpanelClientSecret(`${clientName}:id`);
|
|
24
|
+
function buildHeaders(rootClientId, rootClientSecret) {
|
|
25
|
+
return {
|
|
26
|
+
"openpanel-client-id": rootClientId,
|
|
27
|
+
"openpanel-client-secret": rootClientSecret,
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
Accept: "application/json",
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function resolveManageBase(url, apiUrl) {
|
|
33
|
+
return `${(apiUrl ?? url).replace(/\/$/, "")}/manage`;
|
|
34
|
+
}
|
|
13
35
|
export async function provisionOpenpanelClient(clientName) {
|
|
14
36
|
const cfg = await ensureOpenpanel();
|
|
15
|
-
const { url,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
// Reuse a previously-provisioned client for the same name if one
|
|
20
|
-
// exists — lets you re-run the command without creating duplicates.
|
|
37
|
+
const { url, apiUrl, rootClientId, rootClientSecret } = cfg;
|
|
38
|
+
const manageBase = resolveManageBase(url, apiUrl);
|
|
39
|
+
// Reuse a previously-provisioned client so re-runs don't mint duplicates.
|
|
21
40
|
const cachedSecret = await getSecret(SECRET_KEYS.openpanelClientSecret(clientName));
|
|
22
|
-
const
|
|
23
|
-
const cachedId = await getSecret(cachedIdKey);
|
|
41
|
+
const cachedId = await getSecret(clientIdKey(clientName));
|
|
24
42
|
if (cachedSecret && cachedId) {
|
|
25
|
-
return {
|
|
43
|
+
return {
|
|
44
|
+
projectName: clientName,
|
|
45
|
+
clientId: cachedId,
|
|
46
|
+
clientSecret: cachedSecret,
|
|
47
|
+
apiUrl: manageBase,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const headers = buildHeaders(rootClientId, rootClientSecret);
|
|
51
|
+
// Step 1: create the project. The API authenticates the organization
|
|
52
|
+
// from the root client's auth — don't send organizationSlug.
|
|
53
|
+
const projectRes = await fetch(`${manageBase}/projects`, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers,
|
|
56
|
+
body: JSON.stringify({ name: clientName }),
|
|
57
|
+
});
|
|
58
|
+
if (!projectRes.ok) {
|
|
59
|
+
const text = await projectRes.text().catch(() => "");
|
|
60
|
+
throw new Error(`OpenPanel create project failed: ${projectRes.status} ${projectRes.statusText}${text ? ` — ${text}` : ""}`);
|
|
61
|
+
}
|
|
62
|
+
const projectBody = (await projectRes.json());
|
|
63
|
+
const project = projectBody.data;
|
|
64
|
+
const projectId = project?.id;
|
|
65
|
+
let clientId = project?.client?.id;
|
|
66
|
+
let clientSecret = project?.client?.secret;
|
|
67
|
+
if (!projectId) {
|
|
68
|
+
throw new Error(`OpenPanel: project created but response lacked a project id (got ${JSON.stringify(projectBody).slice(0, 300)}).`);
|
|
26
69
|
}
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const res = await fetch(`${url}/api/client`, {
|
|
70
|
+
// Step 2 (fallback): some self-hosted configurations disable the
|
|
71
|
+
// default-client on project creation. Mint one explicitly so the env
|
|
72
|
+
// block always has real credentials.
|
|
73
|
+
if (!clientId || !clientSecret) {
|
|
74
|
+
const clientRes = await fetch(`${manageBase}/clients`, {
|
|
33
75
|
method: "POST",
|
|
34
|
-
headers
|
|
35
|
-
|
|
36
|
-
"Content-Type": "application/json",
|
|
37
|
-
},
|
|
38
|
-
body: JSON.stringify({
|
|
39
|
-
organizationSlug,
|
|
40
|
-
project: { name: clientName },
|
|
41
|
-
client: { name: clientName, type: "write" },
|
|
42
|
-
}),
|
|
76
|
+
headers,
|
|
77
|
+
body: JSON.stringify({ name: clientName, type: "write", projectId }),
|
|
43
78
|
});
|
|
44
|
-
if (
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
clientId = body.clientId;
|
|
48
|
-
clientSecret = body.clientSecret;
|
|
49
|
-
}
|
|
79
|
+
if (!clientRes.ok) {
|
|
80
|
+
const text = await clientRes.text().catch(() => "");
|
|
81
|
+
throw new Error(`OpenPanel create client failed: ${clientRes.status} ${clientRes.statusText}${text ? ` — ${text}` : ""}`);
|
|
50
82
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
83
|
+
const clientBody = (await clientRes.json());
|
|
84
|
+
clientId = clientBody.data?.id;
|
|
85
|
+
clientSecret = clientBody.data?.secret;
|
|
54
86
|
}
|
|
55
87
|
if (!clientId || !clientSecret) {
|
|
56
|
-
|
|
57
|
-
` Open ${url}/${organizationSlug} → create a project named "${clientName}" →\n` +
|
|
58
|
-
` add a write client, then paste the credentials below.`);
|
|
59
|
-
clientId = await input({ message: `OpenPanel clientId for ${clientName}:` });
|
|
60
|
-
clientSecret = await passwordPrompt({ message: `OpenPanel clientSecret for ${clientName}:` });
|
|
88
|
+
throw new Error("OpenPanel: client created but response lacked id/secret.");
|
|
61
89
|
}
|
|
62
90
|
await setSecret(SECRET_KEYS.openpanelClientSecret(clientName), clientSecret);
|
|
63
|
-
await setSecret(
|
|
64
|
-
|
|
91
|
+
await setSecret(clientIdKey(clientName), clientId);
|
|
92
|
+
await setSecret(projectIdKey(clientName), projectId);
|
|
93
|
+
return { projectName: clientName, clientId, clientSecret, apiUrl: manageBase };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Delete an OpenPanel project created by `provisionOpenpanelClient`.
|
|
97
|
+
* Also wipes the cached id + secret from the keychain so a future
|
|
98
|
+
* provision round won't hand back stale creds.
|
|
99
|
+
*/
|
|
100
|
+
export async function deleteOpenpanelClient(clientName) {
|
|
101
|
+
const cfg = await ensureOpenpanel();
|
|
102
|
+
const { url, apiUrl, rootClientId, rootClientSecret } = cfg;
|
|
103
|
+
const cachedProjectId = await getSecret(projectIdKey(clientName));
|
|
104
|
+
const manageBase = resolveManageBase(url, apiUrl);
|
|
105
|
+
const headers = buildHeaders(rootClientId, rootClientSecret);
|
|
106
|
+
// With no cached project id there's nothing to target — OpenPanel
|
|
107
|
+
// projects are keyed by id (not name), so bail out quietly and let
|
|
108
|
+
// the caller move on.
|
|
109
|
+
if (!cachedProjectId) {
|
|
110
|
+
await deleteSecret(SECRET_KEYS.openpanelClientSecret(clientName));
|
|
111
|
+
await deleteSecret(clientIdKey(clientName));
|
|
112
|
+
return "not-found";
|
|
113
|
+
}
|
|
114
|
+
const res = await fetch(`${manageBase}/projects/${cachedProjectId}`, {
|
|
115
|
+
method: "DELETE",
|
|
116
|
+
headers,
|
|
117
|
+
});
|
|
118
|
+
// Always clear cached creds — if the upstream project is gone (or
|
|
119
|
+
// already-gone), the local secrets have no reason to linger.
|
|
120
|
+
await deleteSecret(SECRET_KEYS.openpanelClientSecret(clientName));
|
|
121
|
+
await deleteSecret(clientIdKey(clientName));
|
|
122
|
+
await deleteSecret(projectIdKey(clientName));
|
|
123
|
+
if (res.status === 404)
|
|
124
|
+
return "not-found";
|
|
125
|
+
if (!res.ok) {
|
|
126
|
+
const text = await res.text().catch(() => "");
|
|
127
|
+
throw new Error(`OpenPanel delete project failed: ${res.status} ${res.statusText}${text ? ` — ${text}` : ""}`);
|
|
128
|
+
}
|
|
129
|
+
return "deleted";
|
|
65
130
|
}
|
|
66
131
|
//# sourceMappingURL=openpanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openpanel.js","sourceRoot":"","sources":["../../src/provision/openpanel.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"openpanel.js","sourceRoot":"","sources":["../../src/provision/openpanel.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,10 +7,32 @@ export interface ResendClient {
|
|
|
7
7
|
raw: string;
|
|
8
8
|
}
|
|
9
9
|
export declare function provisionResendClient(clientName: string, domainId?: string): Promise<ResendClient>;
|
|
10
|
-
/** List
|
|
10
|
+
/** List Resend domains so the caller can pick one. */
|
|
11
11
|
export declare function listResendDomains(): Promise<Array<{
|
|
12
12
|
id: string;
|
|
13
13
|
name: string;
|
|
14
14
|
status: string;
|
|
15
15
|
}>>;
|
|
16
|
+
/** Create a new Resend sending domain. `name` must be a bare domain
|
|
17
|
+
* (no scheme, no path) — e.g. "playtiao.com" or "mail.playtiao.com".
|
|
18
|
+
* Newly created domains start unverified; DNS records must be added
|
|
19
|
+
* before keys scoped to it can send. */
|
|
20
|
+
export declare function createResendDomain(name: string): Promise<{
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
status: string;
|
|
24
|
+
}>;
|
|
25
|
+
export type DeleteResult = "deleted" | "not-found";
|
|
26
|
+
/**
|
|
27
|
+
* Delete the Resend API key named `clientName`.
|
|
28
|
+
*
|
|
29
|
+
* Resend's create response only gives us the token, not the key's id,
|
|
30
|
+
* and we don't persist the id locally. So: list keys, find the one with
|
|
31
|
+
* the matching name, DELETE /api-keys/:id. If zero match, treat as
|
|
32
|
+
* already-gone; if more than one matches (rare — same name re-used),
|
|
33
|
+
* delete them all so the undo is total.
|
|
34
|
+
*/
|
|
35
|
+
export declare function deleteResendClient(clientName: string): Promise<DeleteResult>;
|
|
36
|
+
/** Normalize user-pasted domain input: strip scheme, path, whitespace. */
|
|
37
|
+
export declare function normalizeDomainInput(raw: string): string;
|
|
16
38
|
//# sourceMappingURL=resend.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resend.d.ts","sourceRoot":"","sources":["../../src/provision/resend.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;+DAC2D;IAC3D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CAsBvB;AAED
|
|
1
|
+
{"version":3,"file":"resend.d.ts","sourceRoot":"","sources":["../../src/provision/resend.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;+DAC2D;IAC3D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CAsBvB;AAED,sDAAsD;AACtD,wBAAsB,iBAAiB,IAAI,OAAO,CAChD,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CACpD,CAQA;AAED;;;yCAGyC;AACzC,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAevD;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;AAEnD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAyBlF;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMxD"}
|
package/dist/provision/resend.js
CHANGED
|
@@ -29,7 +29,7 @@ export async function provisionResendClient(clientName, domainId) {
|
|
|
29
29
|
const data = (await res.json());
|
|
30
30
|
return { keyName: clientName, apiKey: data.token, domainId, raw: data.token };
|
|
31
31
|
}
|
|
32
|
-
/** List
|
|
32
|
+
/** List Resend domains so the caller can pick one. */
|
|
33
33
|
export async function listResendDomains() {
|
|
34
34
|
const cfg = await ensureResend();
|
|
35
35
|
const res = await fetch("https://api.resend.com/domains", {
|
|
@@ -40,4 +40,65 @@ export async function listResendDomains() {
|
|
|
40
40
|
const body = (await res.json());
|
|
41
41
|
return body.data ?? [];
|
|
42
42
|
}
|
|
43
|
+
/** Create a new Resend sending domain. `name` must be a bare domain
|
|
44
|
+
* (no scheme, no path) — e.g. "playtiao.com" or "mail.playtiao.com".
|
|
45
|
+
* Newly created domains start unverified; DNS records must be added
|
|
46
|
+
* before keys scoped to it can send. */
|
|
47
|
+
export async function createResendDomain(name) {
|
|
48
|
+
const cfg = await ensureResend();
|
|
49
|
+
const res = await fetch("https://api.resend.com/domains", {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: {
|
|
52
|
+
Authorization: `Bearer ${cfg.apiKey}`,
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
},
|
|
55
|
+
body: JSON.stringify({ name }),
|
|
56
|
+
});
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
throw new Error(`Resend create domain failed: HTTP ${res.status} ${await res.text()}`);
|
|
59
|
+
}
|
|
60
|
+
const data = (await res.json());
|
|
61
|
+
return { id: data.id, name: data.name, status: data.status ?? "not_started" };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Delete the Resend API key named `clientName`.
|
|
65
|
+
*
|
|
66
|
+
* Resend's create response only gives us the token, not the key's id,
|
|
67
|
+
* and we don't persist the id locally. So: list keys, find the one with
|
|
68
|
+
* the matching name, DELETE /api-keys/:id. If zero match, treat as
|
|
69
|
+
* already-gone; if more than one matches (rare — same name re-used),
|
|
70
|
+
* delete them all so the undo is total.
|
|
71
|
+
*/
|
|
72
|
+
export async function deleteResendClient(clientName) {
|
|
73
|
+
const cfg = await ensureResend();
|
|
74
|
+
const auth = { Authorization: `Bearer ${cfg.apiKey}` };
|
|
75
|
+
const listRes = await fetch("https://api.resend.com/api-keys", { headers: auth });
|
|
76
|
+
if (!listRes.ok) {
|
|
77
|
+
throw new Error(`Resend list keys failed: HTTP ${listRes.status}`);
|
|
78
|
+
}
|
|
79
|
+
const body = (await listRes.json());
|
|
80
|
+
const matches = (body.data ?? []).filter((k) => k.name === clientName);
|
|
81
|
+
if (matches.length === 0)
|
|
82
|
+
return "not-found";
|
|
83
|
+
for (const key of matches) {
|
|
84
|
+
const delRes = await fetch(`https://api.resend.com/api-keys/${key.id}`, {
|
|
85
|
+
method: "DELETE",
|
|
86
|
+
headers: auth,
|
|
87
|
+
});
|
|
88
|
+
if (delRes.status === 404)
|
|
89
|
+
continue;
|
|
90
|
+
if (!delRes.ok) {
|
|
91
|
+
throw new Error(`Resend delete key ${key.id} failed: HTTP ${delRes.status} ${await delRes.text()}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return "deleted";
|
|
95
|
+
}
|
|
96
|
+
/** Normalize user-pasted domain input: strip scheme, path, whitespace. */
|
|
97
|
+
export function normalizeDomainInput(raw) {
|
|
98
|
+
let s = raw.trim().toLowerCase();
|
|
99
|
+
s = s.replace(/^https?:\/\//, "");
|
|
100
|
+
s = s.replace(/\/.*$/, "");
|
|
101
|
+
s = s.replace(/^www\./, "");
|
|
102
|
+
return s;
|
|
103
|
+
}
|
|
43
104
|
//# sourceMappingURL=resend.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resend.js","sourceRoot":"","sources":["../../src/provision/resend.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAW5C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAkB,EAClB,QAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC;IAEjC,MAAM,IAAI,GAA4B;QACpC,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,gBAAgB;KAC7B,CAAC;IACF,IAAI,QAAQ;QAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,iCAAiC,EAAE;QACzD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE;YACrC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkC,CAAC;IACjE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AAChF,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"resend.js","sourceRoot":"","sources":["../../src/provision/resend.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAW5C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAkB,EAClB,QAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC;IAEjC,MAAM,IAAI,GAA4B;QACpC,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,gBAAgB;KAC7B,CAAC;IACF,IAAI,QAAQ;QAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,iCAAiC,EAAE;QACzD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE;YACrC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkC,CAAC;IACjE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AAChF,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,iBAAiB;IAGrC,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gCAAgC,EAAE;QACxD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,EAAE;KACnD,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkE,CAAC;IACjG,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;yCAGyC;AACzC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY;IAEZ,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gCAAgC,EAAE;QACxD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE;YACrC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;KAC/B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkD,CAAC;IACjF,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC;AAChF,CAAC;AAID;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAkB;IACzD,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,EAAE,aAAa,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;IAEvD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,iCAAiC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAmD,CAAC;IACtF,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACvE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAE7C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,mCAAmC,GAAG,CAAC,EAAE,EAAE,EAAE;YACtE,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG;YAAE,SAAS;QACpC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,qBAAqB,GAAG,CAAC,EAAE,iBAAiB,MAAM,CAAC,MAAM,IAAI,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CACnF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC5B,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** One `KEY=VALUE` pair parsed out of a provisioned env block. */
|
|
2
|
+
export interface EnvPair {
|
|
3
|
+
key: string;
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
6
|
+
export interface WriteResult {
|
|
7
|
+
devPath: string;
|
|
8
|
+
prodPath: string;
|
|
9
|
+
devWrittenKeys: string[];
|
|
10
|
+
prodEncryptedKeys: string[];
|
|
11
|
+
}
|
|
12
|
+
/** Parse a list of `KEY=VALUE` lines into structured pairs. Blank
|
|
13
|
+
* lines and comments are ignored, which matches the format the
|
|
14
|
+
* provision orchestrator emits today. */
|
|
15
|
+
export declare function parseEnvLines(lines: string[]): EnvPair[];
|
|
16
|
+
/** Resolve where `.env.{development,production}` should live. The
|
|
17
|
+
* starter keeps them under `packages/server/`; other layouts (a
|
|
18
|
+
* hand-maintained project root, a monorepo not from the starter) are
|
|
19
|
+
* also accepted. */
|
|
20
|
+
export declare function resolveEnvTarget(projectDir: string): {
|
|
21
|
+
baseDir: string;
|
|
22
|
+
layout: "starter" | "root";
|
|
23
|
+
};
|
|
24
|
+
/** Upsert plain-text KEY=VALUE entries into `.env.development`. If the
|
|
25
|
+
* file already has a line for a given key, we replace it in place so
|
|
26
|
+
* re-runs don't duplicate entries. */
|
|
27
|
+
export declare function writeDevEnv(envPath: string, pairs: EnvPair[]): string[];
|
|
28
|
+
/** Encrypt each KEY into `.env.production` via dotenvx. First call
|
|
29
|
+
* generates the keypair and writes `.env.keys`. */
|
|
30
|
+
export declare function writeProdEnv(envPath: string, pairs: EnvPair[]): string[];
|
|
31
|
+
//# sourceMappingURL=write-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-env.d.ts","sourceRoot":"","sources":["../../src/provision/write-env.ts"],"names":[],"mappings":"AAmBA,kEAAkE;AAClE,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;0CAE0C;AAC1C,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAUxD;AAED;;;qBAGqB;AACrB,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC;CAC5B,CAMA;AAED;;uCAEuC;AACvC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAqBvE;AAED;oDACoD;AACpD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAQxE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* write-env — write provisioned credentials directly into a project's
|
|
3
|
+
* `.env.development` (plain) and `.env.production` (dotenvx-encrypted).
|
|
4
|
+
*
|
|
5
|
+
* Motivation: printing env blocks to stdout leaks secret values into
|
|
6
|
+
* the user's terminal scrollback / shell history / any process log
|
|
7
|
+
* capturing the CLI. Writing straight into the project repo means:
|
|
8
|
+
* · dev values land in a gitignored `.env.development`
|
|
9
|
+
* · prod values land in a commit-safe encrypted `.env.production`
|
|
10
|
+
* · nothing with a live secret crosses stdout
|
|
11
|
+
*
|
|
12
|
+
* The starter lays env files under `packages/server/`; we detect that
|
|
13
|
+
* layout first and fall back to the project root otherwise.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { dirname, join } from "node:path";
|
|
17
|
+
import { set as dotenvxSet } from "@dotenvx/dotenvx";
|
|
18
|
+
/** Parse a list of `KEY=VALUE` lines into structured pairs. Blank
|
|
19
|
+
* lines and comments are ignored, which matches the format the
|
|
20
|
+
* provision orchestrator emits today. */
|
|
21
|
+
export function parseEnvLines(lines) {
|
|
22
|
+
const out = [];
|
|
23
|
+
for (const raw of lines) {
|
|
24
|
+
const line = raw.trim();
|
|
25
|
+
if (!line || line.startsWith("#"))
|
|
26
|
+
continue;
|
|
27
|
+
const eq = line.indexOf("=");
|
|
28
|
+
if (eq < 0)
|
|
29
|
+
continue;
|
|
30
|
+
out.push({ key: line.slice(0, eq).trim(), value: line.slice(eq + 1) });
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
/** Resolve where `.env.{development,production}` should live. The
|
|
35
|
+
* starter keeps them under `packages/server/`; other layouts (a
|
|
36
|
+
* hand-maintained project root, a monorepo not from the starter) are
|
|
37
|
+
* also accepted. */
|
|
38
|
+
export function resolveEnvTarget(projectDir) {
|
|
39
|
+
const starterDir = join(projectDir, "packages/server");
|
|
40
|
+
if (existsSync(starterDir)) {
|
|
41
|
+
return { baseDir: starterDir, layout: "starter" };
|
|
42
|
+
}
|
|
43
|
+
return { baseDir: projectDir, layout: "root" };
|
|
44
|
+
}
|
|
45
|
+
/** Upsert plain-text KEY=VALUE entries into `.env.development`. If the
|
|
46
|
+
* file already has a line for a given key, we replace it in place so
|
|
47
|
+
* re-runs don't duplicate entries. */
|
|
48
|
+
export function writeDevEnv(envPath, pairs) {
|
|
49
|
+
ensureParent(envPath);
|
|
50
|
+
const existing = existsSync(envPath) ? readFileSync(envPath, "utf-8") : "";
|
|
51
|
+
const lines = existing === "" ? [] : existing.split("\n");
|
|
52
|
+
const wroteKeys = [];
|
|
53
|
+
for (const { key, value } of pairs) {
|
|
54
|
+
const idx = lines.findIndex((l) => l.startsWith(`${key}=`));
|
|
55
|
+
const line = `${key}=${serializeDevValue(value)}`;
|
|
56
|
+
if (idx >= 0) {
|
|
57
|
+
lines[idx] = line;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
lines.push(line);
|
|
61
|
+
}
|
|
62
|
+
wroteKeys.push(key);
|
|
63
|
+
}
|
|
64
|
+
// Trim trailing newlines then re-add exactly one so diffs stay clean.
|
|
65
|
+
while (lines.length > 0 && lines[lines.length - 1] === "")
|
|
66
|
+
lines.pop();
|
|
67
|
+
writeFileSync(envPath, `${lines.join("\n")}\n`, { mode: 0o600 });
|
|
68
|
+
return wroteKeys;
|
|
69
|
+
}
|
|
70
|
+
/** Encrypt each KEY into `.env.production` via dotenvx. First call
|
|
71
|
+
* generates the keypair and writes `.env.keys`. */
|
|
72
|
+
export function writeProdEnv(envPath, pairs) {
|
|
73
|
+
ensureParent(envPath);
|
|
74
|
+
const encrypted = [];
|
|
75
|
+
for (const { key, value } of pairs) {
|
|
76
|
+
dotenvxSet(key, value, { path: envPath, encrypt: true });
|
|
77
|
+
encrypted.push(key);
|
|
78
|
+
}
|
|
79
|
+
return encrypted;
|
|
80
|
+
}
|
|
81
|
+
function ensureParent(filePath) {
|
|
82
|
+
const parent = dirname(filePath);
|
|
83
|
+
if (!existsSync(parent))
|
|
84
|
+
mkdirSync(parent, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
/** Quote a dev-env value if it contains whitespace or shell-special
|
|
87
|
+
* characters. Plain alphanumerics / common URL/token shapes stay
|
|
88
|
+
* unquoted so the file reads naturally. */
|
|
89
|
+
function serializeDevValue(value) {
|
|
90
|
+
if (/^[A-Za-z0-9_\-./:=+@]*$/.test(value))
|
|
91
|
+
return value;
|
|
92
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=write-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-env.js","sourceRoot":"","sources":["../../src/provision/write-env.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infra.d.ts","sourceRoot":"","sources":["../../src/scaffold/infra.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"infra.d.ts","sourceRoot":"","sources":["../../src/scaffold/infra.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA8C5D;AAED,mDAAmD;AACnD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,MAAM,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1E,MAAM,CAqBR;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gCAAgC;AAChC,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,oBAAyB,GACjC,IAAI,CA0CN"}
|
package/dist/scaffold/infra.js
CHANGED
|
@@ -19,6 +19,13 @@ export function generateTfvars(config) {
|
|
|
19
19
|
addSubdomain(config.subdomain, "Web app + API paths");
|
|
20
20
|
addSubdomain(`api.${config.subdomain}`, "REST API");
|
|
21
21
|
addSubdomain("admin", "Coolify dashboard");
|
|
22
|
+
// The stack-level dns_provider defaults to "inwx" for backward compat,
|
|
23
|
+
// but the user's CLI config is the source of truth — emit whichever
|
|
24
|
+
// provider they configured. "manual" maps to "inwx" because the stack
|
|
25
|
+
// only accepts "inwx" | "cloudflare"; manual DNS skips Terraform DNS
|
|
26
|
+
// entirely and is handled upstream.
|
|
27
|
+
const cfgProvider = getConfig().providers.dns?.provider ?? "inwx";
|
|
28
|
+
const stackDnsProvider = cfgProvider === "cloudflare" ? "cloudflare" : "inwx";
|
|
22
29
|
if (config.deployTarget === "new") {
|
|
23
30
|
return renderString(TFVARS_TEMPLATE, {
|
|
24
31
|
name: config.name,
|
|
@@ -26,6 +33,8 @@ export function generateTfvars(config) {
|
|
|
26
33
|
serverLocation: config.serverLocation || "nbg1",
|
|
27
34
|
domain: config.baseDomain,
|
|
28
35
|
subdomains,
|
|
36
|
+
dnsProvider: stackDnsProvider,
|
|
37
|
+
cloudflareProxied: true,
|
|
29
38
|
s3Enabled: config.features.includes("s3") && config.s3Provider !== "existing",
|
|
30
39
|
s3BucketName: `${config.name}-assets`,
|
|
31
40
|
s3Location: config.serverLocation || "nbg1",
|
|
@@ -35,6 +44,8 @@ export function generateTfvars(config) {
|
|
|
35
44
|
return renderString(DNS_ONLY_TFVARS_TEMPLATE, {
|
|
36
45
|
domain: config.baseDomain,
|
|
37
46
|
subdomains,
|
|
47
|
+
dnsProvider: stackDnsProvider,
|
|
48
|
+
cloudflareProxied: true,
|
|
38
49
|
targetIpv4: config.serverIp || "",
|
|
39
50
|
targetIpv6: "",
|
|
40
51
|
});
|
|
@@ -127,6 +138,9 @@ server_location = "{{serverLocation}}"
|
|
|
127
138
|
ssh_key_name = "deploy-key"
|
|
128
139
|
ssh_public_key = "ssh-ed25519 CHANGE_ME"
|
|
129
140
|
|
|
141
|
+
dns_provider = "{{dnsProvider}}"
|
|
142
|
+
cloudflare_proxied = {{cloudflareProxied}}
|
|
143
|
+
|
|
130
144
|
domain = "{{domain}}"
|
|
131
145
|
subdomains = {
|
|
132
146
|
{{#each subdomains}}
|
|
@@ -146,7 +160,10 @@ s3_location = "{{s3Location}}"
|
|
|
146
160
|
s3_enabled = false
|
|
147
161
|
{{/if}}
|
|
148
162
|
`;
|
|
149
|
-
const DNS_ONLY_TFVARS_TEMPLATE = `
|
|
163
|
+
const DNS_ONLY_TFVARS_TEMPLATE = `dns_provider = "{{dnsProvider}}"
|
|
164
|
+
cloudflare_proxied = {{cloudflareProxied}}
|
|
165
|
+
|
|
166
|
+
domain = "{{domain}}"
|
|
150
167
|
subdomains = {
|
|
151
168
|
{{#each subdomains}}
|
|
152
169
|
"{{@key}}" = "{{this}}"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infra.js","sourceRoot":"","sources":["../../src/scaffold/infra.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"infra.js","sourceRoot":"","sources":["../../src/scaffold/infra.ts"],"names":[],"mappings":"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"}
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface ProviderSnapshot {
|
|
2
|
+
key: string;
|
|
3
|
+
label: string;
|
|
4
|
+
configured: boolean;
|
|
5
|
+
detail?: string;
|
|
6
|
+
/** If not configured, how to configure it. */
|
|
7
|
+
configureCommand?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface StatusSnapshot {
|
|
10
|
+
version: string;
|
|
11
|
+
configPath: string;
|
|
12
|
+
providers: ProviderSnapshot[];
|
|
13
|
+
mlServiceCount: number;
|
|
14
|
+
mlServices: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
endpoint: string;
|
|
17
|
+
platform: string;
|
|
18
|
+
}>;
|
|
19
|
+
/** One-line next-best-step based on what's missing. */
|
|
20
|
+
nextStep: string;
|
|
21
|
+
/** Ordered suggestions for discoverability in the menu. */
|
|
22
|
+
suggestions: Array<{
|
|
23
|
+
command: string;
|
|
24
|
+
why: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
export declare function collectStatus(): StatusSnapshot;
|
|
28
|
+
export declare function renderStatusHuman(s: StatusSnapshot): string;
|
|
29
|
+
export declare function renderMenu(s: StatusSnapshot): string;
|
|
30
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,WAAW,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtD;AAED,wBAAgB,aAAa,IAAI,cAAc,CAuF9C;AA6CD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAwB3D;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAyBpD"}
|