hatchkit 0.1.1 → 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 +455 -117
- 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 +504 -66
- 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 +38 -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 +2 -2
package/dist/status.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Shared status collection — what's configured, what's blocked, what's
|
|
3
|
+
* next. Used by the top-level menu, `hatchkit status`, `hatchkit doctor`,
|
|
4
|
+
* and the MCP server.
|
|
5
|
+
*
|
|
6
|
+
* Returns structured data (no chalk, no side-effects). The caller picks
|
|
7
|
+
* a renderer (human/json).
|
|
8
|
+
*/
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
import { getConfig, getConfigPath, getMlServices } from "./config.js";
|
|
11
|
+
import { getCliVersion } from "./utils/version.js";
|
|
12
|
+
export function collectStatus() {
|
|
13
|
+
const config = getConfig();
|
|
14
|
+
const providers = [];
|
|
15
|
+
providers.push({
|
|
16
|
+
key: "github",
|
|
17
|
+
label: "GitHub (gh CLI)",
|
|
18
|
+
configured: config.providers.github.status === "configured",
|
|
19
|
+
configureCommand: "hatchkit setup",
|
|
20
|
+
});
|
|
21
|
+
providers.push({
|
|
22
|
+
key: "coolify",
|
|
23
|
+
label: "Coolify",
|
|
24
|
+
configured: config.providers.coolify?.status === "configured",
|
|
25
|
+
detail: config.providers.coolify?.url,
|
|
26
|
+
configureCommand: "hatchkit config add coolify",
|
|
27
|
+
});
|
|
28
|
+
providers.push({
|
|
29
|
+
key: "hetzner",
|
|
30
|
+
label: "Hetzner Cloud",
|
|
31
|
+
configured: config.providers.hetzner?.status === "configured",
|
|
32
|
+
configureCommand: "hatchkit config add hetzner",
|
|
33
|
+
});
|
|
34
|
+
providers.push({
|
|
35
|
+
key: "dns",
|
|
36
|
+
label: "DNS",
|
|
37
|
+
configured: config.providers.dns?.status === "configured",
|
|
38
|
+
detail: config.providers.dns?.provider,
|
|
39
|
+
configureCommand: "hatchkit config add dns",
|
|
40
|
+
});
|
|
41
|
+
const s3Providers = Object.keys(config.providers.s3);
|
|
42
|
+
providers.push({
|
|
43
|
+
key: "s3",
|
|
44
|
+
label: "S3",
|
|
45
|
+
configured: s3Providers.length > 0,
|
|
46
|
+
detail: s3Providers.length > 0 ? s3Providers.join(", ") : undefined,
|
|
47
|
+
configureCommand: "hatchkit config add s3",
|
|
48
|
+
});
|
|
49
|
+
const gpuProviders = Object.keys(config.providers.gpu);
|
|
50
|
+
providers.push({
|
|
51
|
+
key: "gpu",
|
|
52
|
+
label: "GPU",
|
|
53
|
+
configured: gpuProviders.length > 0,
|
|
54
|
+
detail: gpuProviders.length > 0 ? gpuProviders.join(", ") : undefined,
|
|
55
|
+
configureCommand: "hatchkit config add gpu",
|
|
56
|
+
});
|
|
57
|
+
providers.push({
|
|
58
|
+
key: "glitchtip",
|
|
59
|
+
label: "GlitchTip (errors)",
|
|
60
|
+
configured: !!config.providers.glitchtip && config.providers.glitchtip.status === "configured",
|
|
61
|
+
configureCommand: "hatchkit config add glitchtip",
|
|
62
|
+
});
|
|
63
|
+
providers.push({
|
|
64
|
+
key: "openpanel",
|
|
65
|
+
label: "OpenPanel (analytics)",
|
|
66
|
+
configured: !!config.providers.openpanel && config.providers.openpanel.status === "configured",
|
|
67
|
+
configureCommand: "hatchkit config add openpanel",
|
|
68
|
+
});
|
|
69
|
+
providers.push({
|
|
70
|
+
key: "resend",
|
|
71
|
+
label: "Resend (email)",
|
|
72
|
+
configured: !!config.providers.resend && config.providers.resend.status === "configured",
|
|
73
|
+
configureCommand: "hatchkit config add resend",
|
|
74
|
+
});
|
|
75
|
+
const services = getMlServices();
|
|
76
|
+
const mlServiceList = Object.entries(services).map(([name, entry]) => ({
|
|
77
|
+
name,
|
|
78
|
+
endpoint: entry.endpoint,
|
|
79
|
+
platform: entry.platform,
|
|
80
|
+
}));
|
|
81
|
+
const nextStep = computeNextStep(providers);
|
|
82
|
+
const suggestions = computeSuggestions(providers);
|
|
83
|
+
return {
|
|
84
|
+
version: getCliVersion(),
|
|
85
|
+
configPath: getConfigPath(),
|
|
86
|
+
providers,
|
|
87
|
+
mlServiceCount: mlServiceList.length,
|
|
88
|
+
mlServices: mlServiceList,
|
|
89
|
+
nextStep,
|
|
90
|
+
suggestions,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function computeNextStep(providers) {
|
|
94
|
+
const required = ["github", "coolify", "hetzner", "dns"];
|
|
95
|
+
const firstMissing = providers.find((p) => required.includes(p.key) && !p.configured);
|
|
96
|
+
if (firstMissing) {
|
|
97
|
+
return `Run \`${firstMissing.configureCommand}\` — ${firstMissing.label} is required for full scaffolds.`;
|
|
98
|
+
}
|
|
99
|
+
return "You're set up. Try `hatchkit create` to scaffold a new project.";
|
|
100
|
+
}
|
|
101
|
+
function computeSuggestions(providers) {
|
|
102
|
+
const out = [];
|
|
103
|
+
const has = (k) => providers.find((p) => p.key === k)?.configured;
|
|
104
|
+
if (!has("github") || !has("coolify") || !has("hetzner") || !has("dns")) {
|
|
105
|
+
out.push({
|
|
106
|
+
command: "hatchkit setup",
|
|
107
|
+
why: "first-time onboarding wires up GitHub + Coolify + Hetzner + DNS at once",
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (has("coolify") && has("hetzner") && has("dns")) {
|
|
111
|
+
out.push({ command: "hatchkit create", why: "scaffold and (optionally) deploy a new project" });
|
|
112
|
+
}
|
|
113
|
+
out.push({
|
|
114
|
+
command: "hatchkit doctor",
|
|
115
|
+
why: "health-check every configured provider with contextual fix hints",
|
|
116
|
+
});
|
|
117
|
+
out.push({
|
|
118
|
+
command: "hatchkit add <project>",
|
|
119
|
+
why: "add per-project GlitchTip / OpenPanel / Resend clients",
|
|
120
|
+
});
|
|
121
|
+
out.push({
|
|
122
|
+
command: "hatchkit explain",
|
|
123
|
+
why: "one-page mental model of how the pieces fit together",
|
|
124
|
+
});
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Renderers
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
export function renderStatusHuman(s) {
|
|
131
|
+
const lines = [];
|
|
132
|
+
lines.push(chalk.bold(" Provider Status:"));
|
|
133
|
+
lines.push("");
|
|
134
|
+
for (const p of s.providers) {
|
|
135
|
+
const icon = p.configured ? chalk.green("✓") : chalk.dim("·");
|
|
136
|
+
const detail = p.detail ? chalk.dim(` (${p.detail})`) : "";
|
|
137
|
+
const hint = p.configured ? "" : chalk.dim(` — ${p.configureCommand ?? "not configured"}`);
|
|
138
|
+
lines.push(` ${icon} ${p.label.padEnd(24)}${detail}${hint}`);
|
|
139
|
+
}
|
|
140
|
+
lines.push("");
|
|
141
|
+
lines.push(` ML Services: ${s.mlServiceCount > 0 ? chalk.green(`${s.mlServiceCount} registered`) : chalk.dim("none")}`);
|
|
142
|
+
for (const m of s.mlServices) {
|
|
143
|
+
lines.push(chalk.dim(` ${m.name}: ${m.endpoint} (${m.platform})`));
|
|
144
|
+
}
|
|
145
|
+
lines.push("");
|
|
146
|
+
lines.push(` ${chalk.bold("Next:")} ${s.nextStep}`);
|
|
147
|
+
lines.push(chalk.dim(` Config: ${s.configPath}`));
|
|
148
|
+
lines.push("");
|
|
149
|
+
return lines.join("\n");
|
|
150
|
+
}
|
|
151
|
+
export function renderMenu(s) {
|
|
152
|
+
const lines = [];
|
|
153
|
+
const configured = s.providers.filter((p) => p.configured).length;
|
|
154
|
+
const total = s.providers.length;
|
|
155
|
+
lines.push(` ${chalk.bold("Hatchkit")} — scaffold, deploy, and provision full-stack projects`);
|
|
156
|
+
lines.push(` ${chalk.dim(`${configured}/${total} providers configured`)} ${chalk.dim("·")} ${chalk.dim(s.version ? `v${s.version}` : "")}`);
|
|
157
|
+
lines.push("");
|
|
158
|
+
lines.push(` ${chalk.bold("Next:")} ${s.nextStep}`);
|
|
159
|
+
lines.push("");
|
|
160
|
+
lines.push(chalk.bold(" Suggested commands:"));
|
|
161
|
+
for (const sug of s.suggestions) {
|
|
162
|
+
lines.push(` ${chalk.cyan(sug.command.padEnd(28))} ${chalk.dim(sug.why)}`);
|
|
163
|
+
}
|
|
164
|
+
lines.push("");
|
|
165
|
+
lines.push(chalk.dim(" Run `hatchkit help <command>` for detail, or `hatchkit explain` for the mental model."));
|
|
166
|
+
lines.push("");
|
|
167
|
+
return lines.join("\n");
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,10 +3,16 @@ import type { Express } from "express";
|
|
|
3
3
|
import { config } from "../config.js";
|
|
4
4
|
|
|
5
5
|
export function initSentry(app: Express): void {
|
|
6
|
+
// No DSN = no init. `hatchkit add` writes GLITCHTIP_DSN to
|
|
7
|
+
// .env.production by default; dev doesn't get one (dev error noise
|
|
8
|
+
// pollutes real metrics). Pass `--enable-dev-obs` to opt in.
|
|
6
9
|
if (!config.GLITCHTIP_DSN) return;
|
|
7
10
|
|
|
8
11
|
Sentry.init({
|
|
9
12
|
dsn: config.GLITCHTIP_DSN,
|
|
13
|
+
// `environment` drives GlitchTip's UI filter. DEPLOY_ENV wins so
|
|
14
|
+
// staging deploys tag correctly even when NODE_ENV is "production".
|
|
15
|
+
environment: process.env.DEPLOY_ENV || process.env.NODE_ENV || "development",
|
|
10
16
|
integrations: [
|
|
11
17
|
Sentry.httpIntegration(),
|
|
12
18
|
Sentry.expressIntegration({ app }),
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface CloudflareZone {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
name_servers: string[];
|
|
5
|
+
status: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CloudflareApiOptions {
|
|
8
|
+
token: string;
|
|
9
|
+
/** Optional: filter to one account. Useful if the token spans multiple. */
|
|
10
|
+
accountId?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Cloudflare REST API client. */
|
|
13
|
+
export declare class CloudflareApi {
|
|
14
|
+
private token;
|
|
15
|
+
private accountId?;
|
|
16
|
+
constructor(options: CloudflareApiOptions);
|
|
17
|
+
private request;
|
|
18
|
+
/** Verify the token. "active" means it works. */
|
|
19
|
+
verifyToken(): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* List all zones accessible with this token, optionally filtered to one
|
|
22
|
+
* account. Paginates through the whole result set (CF caps per_page at
|
|
23
|
+
* 50). Safety valve: hard stop at 20 pages (= 1000 zones) to avoid
|
|
24
|
+
* runaway loops if the API misbehaves.
|
|
25
|
+
*/
|
|
26
|
+
listZones(): Promise<CloudflareZone[]>;
|
|
27
|
+
/** Look up a single zone by name. Returns null if not found. */
|
|
28
|
+
getZoneByName(name: string): Promise<CloudflareZone | null>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=cloudflare-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare-api.d.ts","sourceRoot":"","sources":["../../src/utils/cloudflare-api.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiBD,kCAAkC;AAClC,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAC,CAAS;gBAEf,OAAO,EAAE,oBAAoB;YAK3B,OAAO;IAoBrB,iDAAiD;IAC3C,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAKpC;;;;;OAKG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IA2B5C,gEAAgE;IAC1D,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAMlE"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Cloudflare REST API client.
|
|
2
|
+
//
|
|
3
|
+
// Minimal wrapper used by the `hatchkit dns link-to-cloudflare` command
|
|
4
|
+
// to verify a token and list the zones in an account so we can
|
|
5
|
+
// cross-reference them against domains registered at INWX. The DNS record
|
|
6
|
+
// creation itself goes through Terraform (modules/cloudflare-dns) during
|
|
7
|
+
// a normal `hatchkit create` flow — this client is for the standalone
|
|
8
|
+
// migration / reconciliation command.
|
|
9
|
+
//
|
|
10
|
+
// NB: `hatchkit gh-pages` has its own inline Cloudflare DNS helper for
|
|
11
|
+
// record CRUD. That path is separate and doesn't share this class.
|
|
12
|
+
const API_BASE = "https://api.cloudflare.com/client/v4";
|
|
13
|
+
/** Cloudflare REST API client. */
|
|
14
|
+
export class CloudflareApi {
|
|
15
|
+
token;
|
|
16
|
+
accountId;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.token = options.token;
|
|
19
|
+
this.accountId = options.accountId;
|
|
20
|
+
}
|
|
21
|
+
async request(method, path, body) {
|
|
22
|
+
const res = await fetch(`${API_BASE}${path}`, {
|
|
23
|
+
method,
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: `Bearer ${this.token}`,
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
Accept: "application/json",
|
|
28
|
+
},
|
|
29
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
30
|
+
});
|
|
31
|
+
const json = (await res.json().catch(() => null));
|
|
32
|
+
if (!res.ok || !json || !json.success) {
|
|
33
|
+
const errMsg = json?.errors?.map((e) => `${e.code}: ${e.message}`).join("; ") ?? res.statusText;
|
|
34
|
+
throw new Error(`Cloudflare ${method} ${path} failed: ${errMsg}`);
|
|
35
|
+
}
|
|
36
|
+
return json.result;
|
|
37
|
+
}
|
|
38
|
+
/** Verify the token. "active" means it works. */
|
|
39
|
+
async verifyToken() {
|
|
40
|
+
const data = await this.request("GET", "/user/tokens/verify");
|
|
41
|
+
return data.status;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* List all zones accessible with this token, optionally filtered to one
|
|
45
|
+
* account. Paginates through the whole result set (CF caps per_page at
|
|
46
|
+
* 50). Safety valve: hard stop at 20 pages (= 1000 zones) to avoid
|
|
47
|
+
* runaway loops if the API misbehaves.
|
|
48
|
+
*/
|
|
49
|
+
async listZones() {
|
|
50
|
+
const all = [];
|
|
51
|
+
let page = 1;
|
|
52
|
+
while (page <= 20) {
|
|
53
|
+
const query = new URLSearchParams({ per_page: "50", page: String(page) });
|
|
54
|
+
if (this.accountId)
|
|
55
|
+
query.set("account.id", this.accountId);
|
|
56
|
+
const path = `/zones?${query.toString()}`;
|
|
57
|
+
const res = await fetch(`${API_BASE}${path}`, {
|
|
58
|
+
headers: {
|
|
59
|
+
Authorization: `Bearer ${this.token}`,
|
|
60
|
+
Accept: "application/json",
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const json = (await res.json());
|
|
64
|
+
if (!res.ok || !json.success) {
|
|
65
|
+
const errMsg = json?.errors?.map((e) => `${e.code}: ${e.message}`).join("; ") ?? res.statusText;
|
|
66
|
+
throw new Error(`Cloudflare GET /zones failed: ${errMsg}`);
|
|
67
|
+
}
|
|
68
|
+
all.push(...json.result);
|
|
69
|
+
const totalPages = json.result_info?.total_pages ?? 1;
|
|
70
|
+
if (page >= totalPages)
|
|
71
|
+
break;
|
|
72
|
+
page += 1;
|
|
73
|
+
}
|
|
74
|
+
return all;
|
|
75
|
+
}
|
|
76
|
+
/** Look up a single zone by name. Returns null if not found. */
|
|
77
|
+
async getZoneByName(name) {
|
|
78
|
+
const query = new URLSearchParams({ name });
|
|
79
|
+
if (this.accountId)
|
|
80
|
+
query.set("account.id", this.accountId);
|
|
81
|
+
const data = await this.request("GET", `/zones?${query.toString()}`);
|
|
82
|
+
return data[0] ?? null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=cloudflare-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare-api.js","sourceRoot":"","sources":["../../src/utils/cloudflare-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,9 @@ export declare class CoolifyApi {
|
|
|
14
14
|
private token;
|
|
15
15
|
constructor(options: CoolifyApiOptions);
|
|
16
16
|
private request;
|
|
17
|
-
/** Test connection and get Coolify version.
|
|
17
|
+
/** Test connection and get Coolify version. The endpoint returns a
|
|
18
|
+
* plain-text version string on modern Coolify, but older builds
|
|
19
|
+
* wrap it as `{ version: "..." }` — accept either. */
|
|
18
20
|
getVersion(): Promise<string>;
|
|
19
21
|
/** List all servers. */
|
|
20
22
|
listServers(): Promise<CoolifyServer[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coolify-api.d.ts","sourceRoot":"","sources":["../../src/utils/coolify-api.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,+BAA+B;AAC/B,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,EAAE,iBAAiB;YAKxB,OAAO;
|
|
1
|
+
{"version":3,"file":"coolify-api.d.ts","sourceRoot":"","sources":["../../src/utils/coolify-api.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,+BAA+B;AAC/B,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,EAAE,iBAAiB;YAKxB,OAAO;IAiCrB;;2DAEuD;IACjD,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BnC,wBAAwB;IAClB,WAAW,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAkB7C,yBAAyB;IACnB,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAIlE,4BAA4B;IACtB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAIxE,wEAAwE;IAClE,gBAAgB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAI9F;mEAC+D;IACzD,SAAS,CACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAO,GACpC,OAAO,CAAC,IAAI,CAAC;CAYjB;AAED,mEAAmE;AACnE,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/E"}
|
|
@@ -20,12 +20,46 @@ export class CoolifyApi {
|
|
|
20
20
|
const text = await res.text().catch(() => "");
|
|
21
21
|
throw new Error(`Coolify API ${method} ${path} failed: ${res.status} ${res.statusText}${text ? ` — ${text}` : ""}`);
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
const text = await res.text();
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(text);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
const ct = res.headers.get("content-type") ?? "unknown";
|
|
29
|
+
const snippet = text.slice(0, 200).replace(/\s+/g, " ").trim();
|
|
30
|
+
const hint = text.trimStart().startsWith("<")
|
|
31
|
+
? " (got HTML — token may be invalid or URL points to a login page)"
|
|
32
|
+
: "";
|
|
33
|
+
throw new Error(`Coolify API ${method} ${path}: response is not JSON${hint}\n content-type: ${ct}\n body: ${snippet || "(empty)"}`);
|
|
34
|
+
}
|
|
24
35
|
}
|
|
25
|
-
/** Test connection and get Coolify version.
|
|
36
|
+
/** Test connection and get Coolify version. The endpoint returns a
|
|
37
|
+
* plain-text version string on modern Coolify, but older builds
|
|
38
|
+
* wrap it as `{ version: "..." }` — accept either. */
|
|
26
39
|
async getVersion() {
|
|
27
|
-
const
|
|
28
|
-
|
|
40
|
+
const res = await fetch(`${this.url}/api/v1/version`, {
|
|
41
|
+
headers: {
|
|
42
|
+
Authorization: `Bearer ${this.token}`,
|
|
43
|
+
Accept: "application/json, text/plain;q=0.9",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
const text = await res.text().catch(() => "");
|
|
48
|
+
throw new Error(`Coolify API GET /version failed: ${res.status} ${res.statusText}${text ? ` — ${text}` : ""}`);
|
|
49
|
+
}
|
|
50
|
+
const text = (await res.text()).trim();
|
|
51
|
+
try {
|
|
52
|
+
const parsed = JSON.parse(text);
|
|
53
|
+
if (typeof parsed === "string")
|
|
54
|
+
return parsed;
|
|
55
|
+
if (parsed && typeof parsed === "object" && typeof parsed.version === "string") {
|
|
56
|
+
return parsed.version;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Fall through: plain-text version string (e.g. "4.0.0-beta.432")
|
|
61
|
+
}
|
|
62
|
+
return text;
|
|
29
63
|
}
|
|
30
64
|
/** List all servers. */
|
|
31
65
|
async listServers() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coolify-api.js","sourceRoot":"","sources":["../../src/utils/coolify-api.ts"],"names":[],"mappings":"AAYA,+BAA+B;AAC/B,MAAM,OAAO,UAAU;IACb,GAAG,CAAS;IACZ,KAAK,CAAS;IAEtB,YAAY,OAA0B;QACpC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,MAAc,EAAE,IAAY,EAAE,IAAc;QACnE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,UAAU,IAAI,EAAE,EAAE;YACnD,MAAM;YACN,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACrC,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,kBAAkB;aAC3B;YACD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,eAAe,MAAM,IAAI,IAAI,YAAY,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACnG,CAAC;QACJ,CAAC;QAED,OAAO,GAAG,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"coolify-api.js","sourceRoot":"","sources":["../../src/utils/coolify-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface InwxApiOptions {
|
|
2
|
+
username: string;
|
|
3
|
+
password: string;
|
|
4
|
+
/** Use the OTE sandbox instead of production. Set via INWX_SANDBOX=1. */
|
|
5
|
+
sandbox?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** INWX JSON-RPC API client. */
|
|
8
|
+
export declare class InwxApi {
|
|
9
|
+
private url;
|
|
10
|
+
private username;
|
|
11
|
+
private password;
|
|
12
|
+
private cookie;
|
|
13
|
+
constructor(options: InwxApiOptions);
|
|
14
|
+
private request;
|
|
15
|
+
/** Log in and capture the session cookie. Must be called before any
|
|
16
|
+
* other method. Idempotent — safe to call twice. */
|
|
17
|
+
login(): Promise<void>;
|
|
18
|
+
/** Log out and drop the session cookie. */
|
|
19
|
+
logout(): Promise<void>;
|
|
20
|
+
/** Look up a single domain. Returns the record including current
|
|
21
|
+
* nameservers. Throws if the domain isn't registered on this account. */
|
|
22
|
+
getDomainInfo(domain: string): Promise<{
|
|
23
|
+
domain: string;
|
|
24
|
+
ns: string[];
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Update the nameservers delegated at the registrar for `domain`.
|
|
28
|
+
* Replaces the full list — pass all the NS you want, not a diff.
|
|
29
|
+
*
|
|
30
|
+
* INWX's `domain.update` also accepts many other fields (contacts,
|
|
31
|
+
* transferLock, authinfo, ...). We only touch `ns` here so we never
|
|
32
|
+
* accidentally clobber contact info set via the web UI.
|
|
33
|
+
*/
|
|
34
|
+
setDomainNameservers(domain: string, nameservers: string[]): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=inwx-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inwx-api.d.ts","sourceRoot":"","sources":["../../src/utils/inwx-api.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAQD,gCAAgC;AAChC,qBAAa,OAAO;IAClB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAuB;gBAEzB,OAAO,EAAE,cAAc;YAMrB,OAAO;IAsCrB;yDACqD;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5B,2CAA2C;IACrC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7B;8EAC0E;IACpE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAK9E;;;;;;;OAOG;IACG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAQjF"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// INWX JSON-RPC API client.
|
|
2
|
+
//
|
|
3
|
+
// The INWX Terraform provider can create DNS records inside a zone, but it
|
|
4
|
+
// can't change the nameservers that the TLD delegates a domain to. That's
|
|
5
|
+
// a "domain object" operation (domain.update), not a "nameserver object"
|
|
6
|
+
// operation — different part of the INWX API. This client handles the
|
|
7
|
+
// domain-level call so hatchkit can automatically point an INWX-registered
|
|
8
|
+
// domain at Cloudflare's nameservers after the CF zone is ready.
|
|
9
|
+
//
|
|
10
|
+
// API docs: https://www.inwx.com/en/help/apidoc
|
|
11
|
+
// Endpoints: https://api.domrobot.com/jsonrpc/ (OTE sandbox on api.ote)
|
|
12
|
+
//
|
|
13
|
+
// The API is JSON-RPC 2.0 over HTTPS, session-cookie authenticated. Call
|
|
14
|
+
// `account.login` once, capture the PHPSESSID cookie, include it on every
|
|
15
|
+
// follow-up request.
|
|
16
|
+
const PROD_URL = "https://api.domrobot.com/jsonrpc/";
|
|
17
|
+
const OTE_URL = "https://api.ote.domrobot.com/jsonrpc/";
|
|
18
|
+
/** INWX JSON-RPC API client. */
|
|
19
|
+
export class InwxApi {
|
|
20
|
+
url;
|
|
21
|
+
username;
|
|
22
|
+
password;
|
|
23
|
+
cookie = null;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.url = options.sandbox ? OTE_URL : PROD_URL;
|
|
26
|
+
this.username = options.username;
|
|
27
|
+
this.password = options.password;
|
|
28
|
+
}
|
|
29
|
+
async request(method, params) {
|
|
30
|
+
const headers = {
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
Accept: "application/json",
|
|
33
|
+
};
|
|
34
|
+
if (this.cookie)
|
|
35
|
+
headers.Cookie = this.cookie;
|
|
36
|
+
const res = await fetch(this.url, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
headers,
|
|
39
|
+
body: JSON.stringify({ method, params }),
|
|
40
|
+
});
|
|
41
|
+
if (!res.ok) {
|
|
42
|
+
throw new Error(`INWX API ${method} failed: HTTP ${res.status} ${res.statusText}`);
|
|
43
|
+
}
|
|
44
|
+
// Capture the session cookie from the response on login. INWX sets
|
|
45
|
+
// PHPSESSID; we pass it back on every subsequent call.
|
|
46
|
+
const setCookie = res.headers.get("set-cookie");
|
|
47
|
+
if (setCookie) {
|
|
48
|
+
const match = setCookie.match(/(PHPSESSID=[^;]+)/);
|
|
49
|
+
if (match)
|
|
50
|
+
this.cookie = match[1];
|
|
51
|
+
}
|
|
52
|
+
const json = (await res.json());
|
|
53
|
+
// INWX returns HTTP 200 with an error code in the body. 1000 = success,
|
|
54
|
+
// anything else is a failure. The `msg` field is the human-readable
|
|
55
|
+
// error — surface it verbatim so callers can see what went wrong
|
|
56
|
+
// (e.g. "Authentication error" vs "Object does not exist").
|
|
57
|
+
if (json.code !== 1000) {
|
|
58
|
+
throw new Error(`INWX ${method} failed: ${json.code} ${json.msg}`);
|
|
59
|
+
}
|
|
60
|
+
return json.resData;
|
|
61
|
+
}
|
|
62
|
+
/** Log in and capture the session cookie. Must be called before any
|
|
63
|
+
* other method. Idempotent — safe to call twice. */
|
|
64
|
+
async login() {
|
|
65
|
+
await this.request("account.login", {
|
|
66
|
+
user: this.username,
|
|
67
|
+
pass: this.password,
|
|
68
|
+
});
|
|
69
|
+
if (!this.cookie) {
|
|
70
|
+
throw new Error("INWX login succeeded but no session cookie was set");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** Log out and drop the session cookie. */
|
|
74
|
+
async logout() {
|
|
75
|
+
try {
|
|
76
|
+
await this.request("account.logout", {});
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
this.cookie = null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Look up a single domain. Returns the record including current
|
|
83
|
+
* nameservers. Throws if the domain isn't registered on this account. */
|
|
84
|
+
async getDomainInfo(domain) {
|
|
85
|
+
const data = await this.request("domain.info", { domain });
|
|
86
|
+
return data;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Update the nameservers delegated at the registrar for `domain`.
|
|
90
|
+
* Replaces the full list — pass all the NS you want, not a diff.
|
|
91
|
+
*
|
|
92
|
+
* INWX's `domain.update` also accepts many other fields (contacts,
|
|
93
|
+
* transferLock, authinfo, ...). We only touch `ns` here so we never
|
|
94
|
+
* accidentally clobber contact info set via the web UI.
|
|
95
|
+
*/
|
|
96
|
+
async setDomainNameservers(domain, nameservers) {
|
|
97
|
+
if (nameservers.length < 2) {
|
|
98
|
+
// Most registries require ≥2 NS records. Fail loud rather than
|
|
99
|
+
// letting the TLD registry reject it with a less obvious error.
|
|
100
|
+
throw new Error(`At least 2 nameservers required, got ${nameservers.length}`);
|
|
101
|
+
}
|
|
102
|
+
await this.request("domain.update", { domain, ns: nameservers });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=inwx-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inwx-api.js","sourceRoot":"","sources":["../../src/utils/inwx-api.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/secrets.d.ts
CHANGED
|
@@ -5,11 +5,18 @@ export declare const SECRET_KEYS: {
|
|
|
5
5
|
readonly hetznerToken: "hetzner:token";
|
|
6
6
|
readonly dnsInwxPassword: "dns:inwx:password";
|
|
7
7
|
readonly dnsCloudflareToken: "dns:cloudflare:token";
|
|
8
|
+
/** Registrar password when DNS is on Cloudflare but the domain is
|
|
9
|
+
* registered at INWX. Used by the post-apply NS flip in deploy/terraform
|
|
10
|
+
* and by `hatchkit dns link-to-cloudflare`. */
|
|
11
|
+
readonly dnsInwxRegistrarPassword: "dns:inwx-registrar:password";
|
|
8
12
|
readonly s3AccessKey: (provider: string) => string;
|
|
9
13
|
readonly s3SecretKey: (provider: string) => string;
|
|
10
14
|
readonly gpuApiKey: (platform: string) => string;
|
|
11
15
|
readonly glitchtipToken: "glitchtip:auth-token";
|
|
12
|
-
|
|
16
|
+
/** Root-mode OpenPanel client used by the Management API to auto-create
|
|
17
|
+
* per-project clients. Created once in the OpenPanel dashboard. */
|
|
18
|
+
readonly openpanelRootClientId: "openpanel:root-client-id";
|
|
19
|
+
readonly openpanelRootClientSecret: "openpanel:root-client-secret";
|
|
13
20
|
readonly openpanelClientSecret: (name: string) => string;
|
|
14
21
|
readonly resendApiKey: "resend:api-key";
|
|
15
22
|
/** Per-scaffolded-project dotenvx private key for .env.production.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAoBA;mEACmE;AACnE,eAAO,MAAM,WAAW;;;;;
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAoBA;mEACmE;AACnE,eAAO,MAAM,WAAW;;;;;IAKtB;;oDAEgD;;qCAExB,MAAM;qCACN,MAAM;mCACR,MAAM;;IAE5B;wEACoE;;;2CAGtC,MAAM;;IAEpC;;+DAE2D;8CAC1B,MAAM;CAC/B,CAAC;AAEX,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEnE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEhE;AAED,iEAAiE;AACjE,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAGrD"}
|
package/dist/utils/secrets.js
CHANGED
|
@@ -22,11 +22,18 @@ export const SECRET_KEYS = {
|
|
|
22
22
|
hetznerToken: "hetzner:token",
|
|
23
23
|
dnsInwxPassword: "dns:inwx:password",
|
|
24
24
|
dnsCloudflareToken: "dns:cloudflare:token",
|
|
25
|
+
/** Registrar password when DNS is on Cloudflare but the domain is
|
|
26
|
+
* registered at INWX. Used by the post-apply NS flip in deploy/terraform
|
|
27
|
+
* and by `hatchkit dns link-to-cloudflare`. */
|
|
28
|
+
dnsInwxRegistrarPassword: "dns:inwx-registrar:password",
|
|
25
29
|
s3AccessKey: (provider) => `s3:${provider}:access-key`,
|
|
26
30
|
s3SecretKey: (provider) => `s3:${provider}:secret-key`,
|
|
27
31
|
gpuApiKey: (platform) => `gpu:${platform}:api-key`,
|
|
28
32
|
glitchtipToken: "glitchtip:auth-token",
|
|
29
|
-
|
|
33
|
+
/** Root-mode OpenPanel client used by the Management API to auto-create
|
|
34
|
+
* per-project clients. Created once in the OpenPanel dashboard. */
|
|
35
|
+
openpanelRootClientId: "openpanel:root-client-id",
|
|
36
|
+
openpanelRootClientSecret: "openpanel:root-client-secret",
|
|
30
37
|
openpanelClientSecret: (name) => `openpanel:${name}:client-secret`,
|
|
31
38
|
resendApiKey: "resend:api-key",
|
|
32
39
|
/** Per-scaffolded-project dotenvx private key for .env.production.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,iEAAiE;AACjE,uEAAuE;AACvE,sEAAsE;AACtE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,UAAU,CAAC;AAElE;mEACmE;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,YAAY,EAAE,eAAe;IAC7B,YAAY,EAAE,eAAe;IAC7B,eAAe,EAAE,mBAAmB;IACpC,kBAAkB,EAAE,sBAAsB;IAC1C,WAAW,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,MAAM,QAAQ,aAAa;IAC9D,WAAW,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,MAAM,QAAQ,aAAa;IAC9D,SAAS,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,OAAO,QAAQ,UAAU;IAC1D,cAAc,EAAE,sBAAsB;IACtC,
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,iEAAiE;AACjE,uEAAuE;AACvE,sEAAsE;AACtE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,UAAU,CAAC;AAElE;mEACmE;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,YAAY,EAAE,eAAe;IAC7B,YAAY,EAAE,eAAe;IAC7B,eAAe,EAAE,mBAAmB;IACpC,kBAAkB,EAAE,sBAAsB;IAC1C;;oDAEgD;IAChD,wBAAwB,EAAE,6BAA6B;IACvD,WAAW,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,MAAM,QAAQ,aAAa;IAC9D,WAAW,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,MAAM,QAAQ,aAAa;IAC9D,SAAS,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,OAAO,QAAQ,UAAU;IAC1D,cAAc,EAAE,sBAAsB;IACtC;wEACoE;IACpE,qBAAqB,EAAE,0BAA0B;IACjD,yBAAyB,EAAE,8BAA8B;IACzD,qBAAqB,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,aAAa,IAAI,gBAAgB;IAC1E,YAAY,EAAE,gBAAgB;IAC9B;;+DAE2D;IAC3D,iBAAiB,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,WAAW,WAAW,yBAAyB;CACnF,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW;IACzC,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,KAAa;IACxD,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC"}
|