@intentic/cli 1.18.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/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/access.d.ts +16 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +81 -0
- package/dist/access.js.map +1 -0
- package/dist/adopt-pipelines.d.ts +33 -0
- package/dist/adopt-pipelines.d.ts.map +1 -0
- package/dist/adopt-pipelines.js +97 -0
- package/dist/adopt-pipelines.js.map +1 -0
- package/dist/adopt.d.ts +23 -0
- package/dist/adopt.d.ts.map +1 -0
- package/dist/adopt.js +34 -0
- package/dist/adopt.js.map +1 -0
- package/dist/app.d.ts +3 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +341 -0
- package/dist/app.js.map +1 -0
- package/dist/artifact.d.ts +18 -0
- package/dist/artifact.d.ts.map +1 -0
- package/dist/artifact.js +32 -0
- package/dist/artifact.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/control-plane-sync.d.ts +24 -0
- package/dist/control-plane-sync.d.ts.map +1 -0
- package/dist/control-plane-sync.js +61 -0
- package/dist/control-plane-sync.js.map +1 -0
- package/dist/demo.d.ts +2 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +309 -0
- package/dist/demo.js.map +1 -0
- package/dist/generated-secrets.d.ts +5 -0
- package/dist/generated-secrets.d.ts.map +1 -0
- package/dist/generated-secrets.js +31 -0
- package/dist/generated-secrets.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +5 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +63 -0
- package/dist/init.js.map +1 -0
- package/dist/known-hosts.d.ts +3 -0
- package/dist/known-hosts.d.ts.map +1 -0
- package/dist/known-hosts.js +18 -0
- package/dist/known-hosts.js.map +1 -0
- package/dist/output.d.ts +16 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +50 -0
- package/dist/output.js.map +1 -0
- package/dist/resolve.d.ts +4 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +30 -0
- package/dist/resolve.js.map +1 -0
- package/dist/secrets.d.ts +11 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +53 -0
- package/dist/secrets.js.map +1 -0
- package/package.json +61 -0
package/dist/demo.js
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { cloudflareApi, forgejoApi, sshExecutor } from "@intentic/providers";
|
|
8
|
+
import { deploymentId, deploymentPort } from "@intentic/state-resolver";
|
|
9
|
+
import { readGeneratedSecrets } from "./generated-secrets.js";
|
|
10
|
+
const { utils } = createRequire(import.meta.url)("ssh2");
|
|
11
|
+
const exec = promisify(execFile);
|
|
12
|
+
const repoRoot = fileURLToPath(new URL("../../../", import.meta.url));
|
|
13
|
+
const cliJs = join(repoRoot, "_apps/cli/dist/cli.js");
|
|
14
|
+
const stateDir = join(repoRoot, ".demo");
|
|
15
|
+
const stateFile = join(stateDir, "state.json");
|
|
16
|
+
const CONTAINER = "intentic-demo-host";
|
|
17
|
+
const TUNNEL = "intentic-host";
|
|
18
|
+
const ADMIN = "intentic";
|
|
19
|
+
const APP = "app";
|
|
20
|
+
const ENV = "production";
|
|
21
|
+
const APP_BODY = "intentic-demo-live";
|
|
22
|
+
const appPort = deploymentPort(deploymentId(APP, ENV));
|
|
23
|
+
const zone = process.env["CLOUDFLARE_ZONE"] ?? "intentic.dev";
|
|
24
|
+
const sshPort = Number(process.env["DEMO_SSH_PORT"] ?? "2222");
|
|
25
|
+
const forgejoPort = Number(process.env["DEMO_FORGEJO_PORT"] ?? "3000");
|
|
26
|
+
const komodoPort = Number(process.env["DEMO_KOMODO_PORT"] ?? "9120");
|
|
27
|
+
const GIT_URL = `https://git.${zone}`;
|
|
28
|
+
const KOMODO_URL = `https://deploy.${zone}`;
|
|
29
|
+
const APP_URL = `https://app.${zone}`;
|
|
30
|
+
const log = (message) => {
|
|
31
|
+
process.stdout.write(`${message}\n`);
|
|
32
|
+
};
|
|
33
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
34
|
+
const dohHook = pathToFileURL(join(repoRoot, "_apps/cli/doh-lookup.mjs")).href;
|
|
35
|
+
const cliEnv = {
|
|
36
|
+
...process.env,
|
|
37
|
+
DEMO_DOH_ZONE: zone,
|
|
38
|
+
NODE_OPTIONS: `${process.env["NODE_OPTIONS"] ?? ""} --import=${dohHook}`.trim(),
|
|
39
|
+
};
|
|
40
|
+
const run = (command, args, env = process.env) => new Promise((resolve, reject) => {
|
|
41
|
+
const child = spawn(command, args, { cwd: repoRoot, env, stdio: ["ignore", "inherit", "inherit"] });
|
|
42
|
+
child.on("error", reject);
|
|
43
|
+
child.on("exit", (code) => {
|
|
44
|
+
if (code === 0) {
|
|
45
|
+
resolve();
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
reject(new Error(`${command} ${args.join(" ")} exited ${code}`));
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
const runCli = (...args) => run(process.execPath, [cliJs, ...args], cliEnv);
|
|
53
|
+
const quiet = async (command, args) => {
|
|
54
|
+
try {
|
|
55
|
+
await exec(command, args, { maxBuffer: 16 * 1024 * 1024 });
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const readToken = async () => {
|
|
63
|
+
const fromEnv = process.env["CLOUDFLARE_API_TOKEN"];
|
|
64
|
+
if (fromEnv !== undefined && fromEnv !== "") {
|
|
65
|
+
return fromEnv.replace(/\\/g, "").trim();
|
|
66
|
+
}
|
|
67
|
+
const envText = await readFile(join(repoRoot, "desired-state/.env"), "utf8");
|
|
68
|
+
const match = /^CLOUDFLARE_API_TOKEN=(.*)$/m.exec(envText);
|
|
69
|
+
if (match?.[1] === undefined) {
|
|
70
|
+
throw new Error("CLOUDFLARE_API_TOKEN is not set and was not found in desired-state/.env");
|
|
71
|
+
}
|
|
72
|
+
return match[1].replace(/\\/g, "").trim();
|
|
73
|
+
};
|
|
74
|
+
const deployConfig = () => `import { env } from "@intentic/graph";
|
|
75
|
+
import { defineIntent } from "@intentic/sdk";
|
|
76
|
+
|
|
77
|
+
export const intent = defineIntent((i) => {
|
|
78
|
+
const host = i.have.host("host", {
|
|
79
|
+
address: "127.0.0.1",
|
|
80
|
+
user: "root",
|
|
81
|
+
sshKey: env("HOST_SSH_KEY"),
|
|
82
|
+
port: ${sshPort},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const cf = i.have.cloudflare("cf", {
|
|
86
|
+
apiToken: env("CLOUDFLARE_API_TOKEN"),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
i.want.app(${JSON.stringify(APP)}, {
|
|
90
|
+
on: host,
|
|
91
|
+
expose: cf,
|
|
92
|
+
environments: {
|
|
93
|
+
${ENV}: { domain: ${JSON.stringify(`app.${zone}`)}, branch: "main", env: { PORT: ${JSON.stringify(String(appPort))} } },
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
`;
|
|
98
|
+
const envFile = (privateKey, apiToken) => `HOST_SSH_KEY="${privateKey}"
|
|
99
|
+
CLOUDFLARE_API_TOKEN=${apiToken}
|
|
100
|
+
`;
|
|
101
|
+
const DOCKERFILE = `FROM busybox
|
|
102
|
+
RUN mkdir -p /www && printf '%s' '${APP_BODY}' > /www/index.html
|
|
103
|
+
ENV PORT=8080
|
|
104
|
+
EXPOSE 8080
|
|
105
|
+
CMD ["sh","-c","httpd -f -v -p \${PORT} -h /www"]
|
|
106
|
+
`;
|
|
107
|
+
const ssh = async (command) => {
|
|
108
|
+
const session = await sshExecutor.connect({ address: "127.0.0.1", port: sshPort, user: "root", privateKey });
|
|
109
|
+
try {
|
|
110
|
+
const result = await session.exec(command);
|
|
111
|
+
return `${result.stdout}${result.stderr}`;
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
await session.dispose();
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
let privateKey = "";
|
|
118
|
+
const up = async () => {
|
|
119
|
+
const apiToken = await readToken();
|
|
120
|
+
const keys = utils.generateKeyPairSync("ed25519");
|
|
121
|
+
privateKey = keys.private;
|
|
122
|
+
let forgejoPassword = "";
|
|
123
|
+
let komodoPassword = "";
|
|
124
|
+
log(`▶ building the demo host image (${CONTAINER}) from test/host …`);
|
|
125
|
+
await run("docker", ["build", "-t", CONTAINER, join(repoRoot, "test/host")]);
|
|
126
|
+
log("▶ starting the persistent Docker-in-Docker host …");
|
|
127
|
+
await quiet("docker", ["rm", "-f", CONTAINER]);
|
|
128
|
+
await run("docker", [
|
|
129
|
+
"run",
|
|
130
|
+
"-d",
|
|
131
|
+
"--privileged",
|
|
132
|
+
"--dns",
|
|
133
|
+
"1.1.1.1",
|
|
134
|
+
"--dns",
|
|
135
|
+
"1.0.0.1",
|
|
136
|
+
"--name",
|
|
137
|
+
CONTAINER,
|
|
138
|
+
"-e",
|
|
139
|
+
"DOCKER_TLS_CERTDIR=",
|
|
140
|
+
"-p",
|
|
141
|
+
`${sshPort}:22`,
|
|
142
|
+
"-p",
|
|
143
|
+
`${forgejoPort}:3000`,
|
|
144
|
+
"-p",
|
|
145
|
+
`${komodoPort}:9120`,
|
|
146
|
+
CONTAINER,
|
|
147
|
+
]);
|
|
148
|
+
log("▶ injecting the demo SSH key …");
|
|
149
|
+
for (let i = 0; i < 60 && !(await quiet("docker", ["exec", CONTAINER, "true"])); i++) {
|
|
150
|
+
await sleep(1000);
|
|
151
|
+
}
|
|
152
|
+
await exec("docker", [
|
|
153
|
+
"exec",
|
|
154
|
+
CONTAINER,
|
|
155
|
+
"sh",
|
|
156
|
+
"-c",
|
|
157
|
+
`mkdir -p /root/.ssh && chmod 700 /root/.ssh && printf '%s\\n' '${keys.public}' > /root/.ssh/authorized_keys && chmod 600 /root/.ssh/authorized_keys`,
|
|
158
|
+
]);
|
|
159
|
+
log(`▶ waiting for SSH on 127.0.0.1:${sshPort} …`);
|
|
160
|
+
for (let i = 0;; i++) {
|
|
161
|
+
try {
|
|
162
|
+
await (await sshExecutor.connect({ address: "127.0.0.1", port: sshPort, user: "root", privateKey })).dispose();
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
if (i >= 90) {
|
|
167
|
+
throw new Error(`host SSH never came up: ${String(error)}`);
|
|
168
|
+
}
|
|
169
|
+
await sleep(1000);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const workspace = repoRoot;
|
|
173
|
+
const configPath = join(workspace, "intent", "deploy.config.ts");
|
|
174
|
+
const artifactPath = join(workspace, "desired-state", "desired-state.json");
|
|
175
|
+
await mkdir(stateDir, { recursive: true });
|
|
176
|
+
await writeFile(stateFile, JSON.stringify({
|
|
177
|
+
zone,
|
|
178
|
+
apiToken,
|
|
179
|
+
container: CONTAINER,
|
|
180
|
+
sshPort,
|
|
181
|
+
urls: { git: GIT_URL, komodo: KOMODO_URL, app: APP_URL },
|
|
182
|
+
local: { git: `http://127.0.0.1:${forgejoPort}`, komodo: `http://127.0.0.1:${komodoPort}` },
|
|
183
|
+
}, null, 2));
|
|
184
|
+
log("▶ scaffolding the intent (init --link) …");
|
|
185
|
+
await runCli("init", "--dir", workspace, "--link");
|
|
186
|
+
await writeFile(configPath, deployConfig());
|
|
187
|
+
await writeFile(join(workspace, "desired-state", ".env"), envFile(privateKey, apiToken));
|
|
188
|
+
log("▶ resolve + apply — Forgejo + Komodo + tunnel + the app's CI/CD wiring …");
|
|
189
|
+
await runCli("resolve", "--config", configPath, "--out", artifactPath);
|
|
190
|
+
await runCli("apply", "--artifact", artifactPath, "--maxIterations", "8");
|
|
191
|
+
const secrets = await readGeneratedSecrets(join(workspace, "desired-state"));
|
|
192
|
+
forgejoPassword = secrets["FORGEJO_ADMIN_PASSWORD"] ?? "";
|
|
193
|
+
komodoPassword = secrets["KOMODO_ADMIN_PASSWORD"] ?? "";
|
|
194
|
+
const running = await ssh("docker ps --format '{{.Names}}'");
|
|
195
|
+
for (const name of ["intentic-forgejo", "intentic-forgejo-runner", "komodo-core"]) {
|
|
196
|
+
if (!running.includes(name)) {
|
|
197
|
+
throw new Error(`platform container "${name}" is not running on the host:\n${running}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
log(`✅ platform up — host containers: ${running.split("\n").filter(Boolean).join(", ")}`);
|
|
201
|
+
log("▶ seeding the app repo (intentic/app @ main) with a Dockerfile …");
|
|
202
|
+
let appDeployed = false;
|
|
203
|
+
try {
|
|
204
|
+
await forgejoApi.commitFile({
|
|
205
|
+
baseUrl: `http://127.0.0.1:${forgejoPort}`,
|
|
206
|
+
user: ADMIN,
|
|
207
|
+
password: forgejoPassword,
|
|
208
|
+
owner: ADMIN,
|
|
209
|
+
name: APP,
|
|
210
|
+
branch: "main",
|
|
211
|
+
path: "Dockerfile",
|
|
212
|
+
content: DOCKERFILE,
|
|
213
|
+
message: "seed demo app",
|
|
214
|
+
});
|
|
215
|
+
log(`▶ CI builds + pushes the image and Komodo rolls it out — polling http://127.0.0.1:${appPort} …`);
|
|
216
|
+
const deadline = Date.now() + 5 * 60_000;
|
|
217
|
+
while (!appDeployed && Date.now() < deadline) {
|
|
218
|
+
const hit = (await ssh(`wget -q -T 5 -O- http://127.0.0.1:${appPort} 2>/dev/null || true`)).trim();
|
|
219
|
+
appDeployed = hit.includes(APP_BODY);
|
|
220
|
+
if (!appDeployed) {
|
|
221
|
+
await sleep(2000);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
log(appDeployed
|
|
225
|
+
? `✅ app deployed by CI/CD — serving "${APP_BODY}" on the host`
|
|
226
|
+
: `⚠ app not live yet on :${appPort} (CI/CD may still be running)`);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
log(`⚠ app phase skipped (platform stays up): ${String(error)}`);
|
|
230
|
+
}
|
|
231
|
+
log("");
|
|
232
|
+
log("════════════════════════════════════════════════════════════════════");
|
|
233
|
+
log(" intentic demo is UP and will stay up until you run `pnpm demo:down`");
|
|
234
|
+
log("════════════════════════════════════════════════════════════════════");
|
|
235
|
+
log(" Public (through the Cloudflare tunnel — DNS/edge may take ~1 min):");
|
|
236
|
+
log(` Forgejo : ${GIT_URL}`);
|
|
237
|
+
log(` Komodo : ${KOMODO_URL}`);
|
|
238
|
+
if (appDeployed) {
|
|
239
|
+
log(` App : ${APP_URL}`);
|
|
240
|
+
}
|
|
241
|
+
log(" Local (instant, no DNS needed):");
|
|
242
|
+
log(` Forgejo : http://127.0.0.1:${forgejoPort}`);
|
|
243
|
+
log(` Komodo : http://127.0.0.1:${komodoPort}`);
|
|
244
|
+
log(" Admin login (intentic-generated):");
|
|
245
|
+
log(` user : ${ADMIN}`);
|
|
246
|
+
log(` Forgejo pw: ${forgejoPassword}`);
|
|
247
|
+
log(` Komodo pw : ${komodoPassword}`);
|
|
248
|
+
log(` (saved in ${join(workspace, "desired-state", ".secrets.json")})`);
|
|
249
|
+
log(` SSH into the host: ssh -p ${sshPort} root@127.0.0.1 (key in ${join(workspace, "desired-state", ".env")})`);
|
|
250
|
+
log(" Push the control-plane repos to Forgejo: pnpm intentic adopt (once git DNS is live)");
|
|
251
|
+
log(" Stop (reuses tunnel + DNS, fast re-up) : pnpm demo:down");
|
|
252
|
+
log(" Full teardown (also removes tunnel+DNS): pnpm demo:clear");
|
|
253
|
+
log(" Note: keep this machine + Docker running; the public URLs share the");
|
|
254
|
+
log(" tunnel name 'intentic-host', so don't run the e2e at the same time.");
|
|
255
|
+
log("════════════════════════════════════════════════════════════════════");
|
|
256
|
+
};
|
|
257
|
+
const down = async () => {
|
|
258
|
+
log(`▶ stopping the demo host container (${CONTAINER}) — leaving the Cloudflare tunnel + DNS for a fast re-up …`);
|
|
259
|
+
await quiet("docker", ["rm", "-f", CONTAINER]);
|
|
260
|
+
log("✅ demo stopped. `pnpm demo:up` reconnects in seconds (tunnel + DNS reused); `pnpm demo:clear` tears down Cloudflare too.");
|
|
261
|
+
};
|
|
262
|
+
const clear = async () => {
|
|
263
|
+
const state = await readFile(stateFile, "utf8")
|
|
264
|
+
.then((text) => JSON.parse(text))
|
|
265
|
+
.catch(() => ({}));
|
|
266
|
+
const zoneName = state.zone ?? zone;
|
|
267
|
+
const apiToken = state.apiToken ?? (await readToken());
|
|
268
|
+
log(`▶ removing the demo host container (${CONTAINER}) …`);
|
|
269
|
+
await quiet("docker", ["rm", "-f", CONTAINER]);
|
|
270
|
+
log("▶ deleting the Cloudflare tunnel + DNS records …");
|
|
271
|
+
const cfZone = await cloudflareApi.getZone({ apiToken, zone: zoneName }).catch(() => undefined);
|
|
272
|
+
if (cfZone !== undefined) {
|
|
273
|
+
const tunnel = await cloudflareApi.findTunnel({ accountId: cfZone.accountId, apiToken, name: TUNNEL }).catch(() => undefined);
|
|
274
|
+
if (tunnel !== undefined) {
|
|
275
|
+
await fetch(`https://api.cloudflare.com/client/v4/accounts/${cfZone.accountId}/cfd_tunnel/${tunnel.id}/connections`, {
|
|
276
|
+
method: "DELETE",
|
|
277
|
+
headers: { Authorization: `Bearer ${apiToken}` },
|
|
278
|
+
}).catch(() => { });
|
|
279
|
+
await cloudflareApi
|
|
280
|
+
.deleteTunnel({ accountId: cfZone.accountId, apiToken, tunnelId: tunnel.id })
|
|
281
|
+
.catch((error) => log(` tunnel: ${String(error)}`));
|
|
282
|
+
}
|
|
283
|
+
for (const name of [`git.${zoneName}`, `deploy.${zoneName}`, `app.${zoneName}`]) {
|
|
284
|
+
const record = await cloudflareApi.findDnsRecord({ apiToken, zoneId: cfZone.id, name }).catch(() => undefined);
|
|
285
|
+
if (record !== undefined) {
|
|
286
|
+
await cloudflareApi
|
|
287
|
+
.deleteDnsRecord({ apiToken, zoneId: cfZone.id, recordId: record.id })
|
|
288
|
+
.catch((error) => log(` dns ${name}: ${String(error)}`));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
await rm(stateDir, { recursive: true, force: true }).catch(() => { });
|
|
293
|
+
log("✅ demo cleared — host container, tunnel, and DNS records removed (intent/ + desired-state/ kept).");
|
|
294
|
+
};
|
|
295
|
+
const mode = process.argv[2];
|
|
296
|
+
if (mode === "up") {
|
|
297
|
+
await up();
|
|
298
|
+
}
|
|
299
|
+
else if (mode === "down") {
|
|
300
|
+
await down();
|
|
301
|
+
}
|
|
302
|
+
else if (mode === "clear" || mode === "clean") {
|
|
303
|
+
await clear();
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
log("usage: demo <up|down|clear>");
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=demo.js.map
|
package/dist/demo.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
type MutableEnv = Record<string, string | undefined>;
|
|
2
|
+
export declare const ensureGeneratedSecrets: (dir: string, keys: readonly string[], env: MutableEnv) => Promise<void>;
|
|
3
|
+
export declare const readGeneratedSecrets: (dir: string) => Promise<Record<string, string>>;
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=generated-secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generated-secrets.d.ts","sourceRoot":"","sources":["../src/generated-secrets.ts"],"names":[],"mappings":"AAMA,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAkBrD,eAAO,MAAM,sBAAsB,GAAU,KAAK,MAAM,EAAE,MAAM,SAAS,MAAM,EAAE,EAAE,KAAK,UAAU,KAAG,OAAO,CAAC,IAAI,CAoBhH,CAAC;AAIF,eAAO,MAAM,oBAAoB,GAAI,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAgC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { SECRETS_FILE } from "./artifact.js";
|
|
6
|
+
const generate = () => randomBytes(16).toString("hex");
|
|
7
|
+
const secretsPath = (dir) => join(dir, SECRETS_FILE);
|
|
8
|
+
const readStore = async (path) => existsSync(path) ? JSON.parse(await readFile(path, "utf8")) : {};
|
|
9
|
+
export const ensureGeneratedSecrets = async (dir, keys, env) => {
|
|
10
|
+
if (keys.length === 0) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const path = secretsPath(dir);
|
|
14
|
+
const store = await readStore(path);
|
|
15
|
+
let dirty = false;
|
|
16
|
+
for (const key of keys) {
|
|
17
|
+
if (env[key] !== undefined && env[key] !== "") {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (store[key] === undefined) {
|
|
21
|
+
store[key] = generate();
|
|
22
|
+
dirty = true;
|
|
23
|
+
}
|
|
24
|
+
env[key] = store[key];
|
|
25
|
+
}
|
|
26
|
+
if (dirty) {
|
|
27
|
+
await writeFile(path, `${JSON.stringify(store, undefined, 4)}\n`, { mode: 0o600 });
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export const readGeneratedSecrets = (dir) => readStore(secretsPath(dir));
|
|
31
|
+
//# sourceMappingURL=generated-secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generated-secrets.js","sourceRoot":"","sources":["../src/generated-secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAM7C,MAAM,QAAQ,GAAG,GAAW,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE/D,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAErE,MAAM,SAAS,GAAG,KAAK,EAAE,IAAY,EAAmC,EAAE,CACtE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAA4B,CAAC,CAAC,CAAC,EAAE,CAAC;AASjG,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,GAAW,EAAE,IAAuB,EAAE,GAAe,EAAiB,EAAE;IACjH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO;IACX,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;YAC5C,SAAS;QACb,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC3B,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ,EAAE,CAAC;YACxB,KAAK,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACR,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvF,CAAC;AACL,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAW,EAAmC,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAClH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAClH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AA8EA,eAAO,MAAM,QAAQ,GAAU,KAAK,MAAM,EAAE,SAAS,MAAM,EAAE,MAAM,OAAO,KAAG,OAAO,CAAC;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAc9I,CAAC"}
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { CONFIG_FILE, ENV_FILE, INTENT_DIR, LAST_APPLIED_FILE, SECRETS_FILE, TARGET_DIR } from "./artifact.js";
|
|
7
|
+
const exec = promisify(execFile);
|
|
8
|
+
const STARTER_CONFIG = `import { env } from "@intentic/graph";
|
|
9
|
+
import { defineIntent } from "@intentic/sdk";
|
|
10
|
+
|
|
11
|
+
export const intent = defineIntent((i) => {
|
|
12
|
+
const host = i.have.host("host", {
|
|
13
|
+
address: "203.0.113.10",
|
|
14
|
+
user: "deploy",
|
|
15
|
+
sshKey: env("HOST_SSH_KEY"),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const cf = i.have.cloudflare("cf", {
|
|
19
|
+
apiToken: env("CLOUDFLARE_API_TOKEN"),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
i.want.app("my-app", {
|
|
23
|
+
on: host,
|
|
24
|
+
expose: cf,
|
|
25
|
+
environments: {
|
|
26
|
+
production: { domain: "app.example.com", branch: "main", env: { DATABASE_URL: env("PRODUCTION_DATABASE_URL") } },
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
`;
|
|
31
|
+
const TARGET_GITIGNORE = `${ENV_FILE}\n${SECRETS_FILE}\n${LAST_APPLIED_FILE}\n`;
|
|
32
|
+
const INTENT_GITIGNORE = "node_modules/\n";
|
|
33
|
+
const STARTER_TSCONFIG = `${JSON.stringify({
|
|
34
|
+
compilerOptions: { module: "nodenext", moduleResolution: "nodenext", target: "ES2024", strict: true, skipLibCheck: true, noEmit: true },
|
|
35
|
+
include: [CONFIG_FILE],
|
|
36
|
+
}, undefined, 4)}\n`;
|
|
37
|
+
const LIBS_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..", "_libs");
|
|
38
|
+
const starterPackage = (version, link) => {
|
|
39
|
+
const dependency = (pkg) => (link ? `link:${join(LIBS_DIR, pkg)}` : `~${version}`);
|
|
40
|
+
return `${JSON.stringify({
|
|
41
|
+
name: "intent",
|
|
42
|
+
version: "0.0.0",
|
|
43
|
+
private: true,
|
|
44
|
+
type: "module",
|
|
45
|
+
dependencies: { "@intentic/graph": dependency("graph"), "@intentic/sdk": dependency("sdk") },
|
|
46
|
+
}, undefined, 4)}\n`;
|
|
47
|
+
};
|
|
48
|
+
export const scaffold = async (dir, version, link) => {
|
|
49
|
+
const intentDir = join(dir, INTENT_DIR);
|
|
50
|
+
const targetDir = join(dir, TARGET_DIR);
|
|
51
|
+
await mkdir(intentDir, { recursive: true });
|
|
52
|
+
await mkdir(targetDir, { recursive: true });
|
|
53
|
+
await exec("git", ["init", "-q", intentDir]);
|
|
54
|
+
await exec("git", ["init", "-q", targetDir]);
|
|
55
|
+
await writeFile(join(intentDir, CONFIG_FILE), STARTER_CONFIG);
|
|
56
|
+
await writeFile(join(intentDir, "package.json"), starterPackage(version, link));
|
|
57
|
+
await writeFile(join(intentDir, "tsconfig.json"), STARTER_TSCONFIG);
|
|
58
|
+
await writeFile(join(intentDir, ".gitignore"), INTENT_GITIGNORE);
|
|
59
|
+
await writeFile(join(targetDir, ".gitignore"), TARGET_GITIGNORE);
|
|
60
|
+
await exec("pnpm", ["install", "--ignore-workspace"], { cwd: intentDir });
|
|
61
|
+
return { intentDir, targetDir };
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"known-hosts.d.ts","sourceRoot":"","sources":["../src/known-hosts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,YAanD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { KNOWN_HOSTS_FILE } from "./artifact.js";
|
|
5
|
+
export const createKnownHostsStore = (dir) => {
|
|
6
|
+
const path = join(dir, KNOWN_HOSTS_FILE);
|
|
7
|
+
const id = (host, port) => `${host}:${port}`;
|
|
8
|
+
const read = async () => existsSync(path) ? JSON.parse(await readFile(path, "utf8")) : {};
|
|
9
|
+
return {
|
|
10
|
+
get: async (host, port) => (await read())[id(host, port)],
|
|
11
|
+
set: async (host, port, key) => {
|
|
12
|
+
const store = await read();
|
|
13
|
+
store[id(host, port)] = key;
|
|
14
|
+
await writeFile(path, `${JSON.stringify(store, undefined, 4)}\n`, { mode: 0o600 });
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=known-hosts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"known-hosts.js","sourceRoot":"","sources":["../src/known-hosts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKjD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAW,EAAgB,EAAE;IAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,CAAC,IAAY,EAAE,IAAY,EAAU,EAAE,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACrE,MAAM,IAAI,GAAG,KAAK,IAAqC,EAAE,CACrD,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAA4B,CAAC,CAAC,CAAC,EAAE,CAAC;IACjG,OAAO;QACH,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACzD,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAC;YAC3B,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;YAC5B,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACvF,CAAC;KACJ,CAAC;AACN,CAAC,CAAC"}
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EngineEvent } from "@intentic/engine";
|
|
2
|
+
export type OutputMode = "text" | "json" | "ndjson";
|
|
3
|
+
export declare const outputMode: (env: Readonly<Record<string, string | undefined>>) => OutputMode;
|
|
4
|
+
interface Sink {
|
|
5
|
+
readonly write: (chunk: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface Output {
|
|
8
|
+
readonly mode: OutputMode;
|
|
9
|
+
readonly onEvent: (event: EngineEvent) => void;
|
|
10
|
+
readonly log: (message: string) => void;
|
|
11
|
+
readonly text: (line: string) => void;
|
|
12
|
+
readonly result: (result: Record<string, unknown>) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const createOutput: (sink: Sink, mode: OutputMode) => Output;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKpD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpD,eAAO,MAAM,UAAU,GAAI,KAAK,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,KAAG,UAG9E,CAAC;AAEF,UAAU,IAAI;IACV,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAOD,MAAM,WAAW,MAAM;IACnB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC9D;AAgBD,eAAO,MAAM,YAAY,GAAI,MAAM,IAAI,EAAE,MAAM,UAAU,KAAG,MAsC3D,CAAC"}
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const outputMode = (env) => {
|
|
2
|
+
const value = env["INTENTIC_OUTPUT"];
|
|
3
|
+
return value === "json" || value === "ndjson" ? value : "text";
|
|
4
|
+
};
|
|
5
|
+
const eventText = (event) => {
|
|
6
|
+
if (event.kind === "prune") {
|
|
7
|
+
return event.state === "deleted"
|
|
8
|
+
? `prune: deleted "${event.id}" (type "${event.type}")`
|
|
9
|
+
: `prune: "${event.id}" (type "${event.type}") removed from desired state but its provider has no delete — left in place`;
|
|
10
|
+
}
|
|
11
|
+
if (event.kind === "orphan") {
|
|
12
|
+
return `orphan: "${event.id}" (type "${event.type}") exists but is not in the desired graph — not deleted`;
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
};
|
|
16
|
+
export const createOutput = (sink, mode) => {
|
|
17
|
+
const line = (text) => sink.write(`${text}\n`);
|
|
18
|
+
const jsonLine = (value) => sink.write(`${JSON.stringify(value)}\n`);
|
|
19
|
+
if (mode === "ndjson") {
|
|
20
|
+
return {
|
|
21
|
+
mode,
|
|
22
|
+
onEvent: jsonLine,
|
|
23
|
+
log: (message) => jsonLine({ kind: "log", message }),
|
|
24
|
+
text: () => { },
|
|
25
|
+
result: (result) => jsonLine({ kind: "result", ...result }),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (mode === "json") {
|
|
29
|
+
return {
|
|
30
|
+
mode,
|
|
31
|
+
onEvent: () => { },
|
|
32
|
+
log: () => { },
|
|
33
|
+
text: () => { },
|
|
34
|
+
result: (result) => sink.write(`${JSON.stringify(result, undefined, 4)}\n`),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
mode,
|
|
39
|
+
onEvent: (event) => {
|
|
40
|
+
const text = eventText(event);
|
|
41
|
+
if (text !== undefined) {
|
|
42
|
+
line(text);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
log: line,
|
|
46
|
+
text: line,
|
|
47
|
+
result: () => { },
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAiD,EAAc,EAAE;IACxF,MAAM,KAAK,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACrC,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AACnE,CAAC,CAAC;AAqBF,MAAM,SAAS,GAAG,CAAC,KAAkB,EAAsB,EAAE;IACzD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,KAAK,KAAK,SAAS;YAC5B,CAAC,CAAC,mBAAmB,KAAK,CAAC,EAAE,YAAY,KAAK,CAAC,IAAI,IAAI;YACvD,CAAC,CAAC,WAAW,KAAK,CAAC,EAAE,YAAY,KAAK,CAAC,IAAI,8EAA8E,CAAC;IAClI,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,YAAY,KAAK,CAAC,EAAE,YAAY,KAAK,CAAC,IAAI,yDAAyD,CAAC;IAC/G,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAU,EAAE,IAAgB,EAAU,EAAE;IACjE,MAAM,IAAI,GAAG,CAAC,IAAY,EAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpF,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpB,OAAO;YACH,IAAI;YACJ,OAAO,EAAE,QAAQ;YACjB,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;YACpD,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;SAC9D,CAAC;IACN,CAAC;IAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QAElB,OAAO;YACH,IAAI;YACJ,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;YACjB,GAAG,EAAE,GAAG,EAAE,GAAE,CAAC;YACb,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC;SAC9E,CAAC;IACN,CAAC;IAGD,OAAO;QACH,IAAI;QACJ,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACf,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACrB,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;QACL,CAAC;QACD,GAAG,EAAE,IAAI;QACT,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;KACnB,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { IntentSet } from "@intentic/need-resolver";
|
|
2
|
+
export declare const loadIntent: (configPath: string) => Promise<IntentSet>;
|
|
3
|
+
export declare const discoverZone: (intent: IntentSet, dir: string) => Promise<string | undefined>;
|
|
4
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAQzD,eAAO,MAAM,UAAU,GAAU,YAAY,MAAM,KAAG,OAAO,CAAC,SAAS,CAMtE,CAAC;AAMF,eAAO,MAAM,YAAY,GAAU,QAAQ,SAAS,EAAE,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAmB7F,CAAC"}
|
package/dist/resolve.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
3
|
+
import { cloudflareApi } from "@intentic/providers";
|
|
4
|
+
import { collectDomains, selectZone } from "@intentic/state-resolver";
|
|
5
|
+
import { loadEnvFile } from "./artifact.js";
|
|
6
|
+
export const loadIntent = async (configPath) => {
|
|
7
|
+
const loaded = (await import(pathToFileURL(resolve(configPath)).href));
|
|
8
|
+
if (loaded.intent === undefined) {
|
|
9
|
+
throw new Error(`${configPath} must export "intent" (from defineIntent)`);
|
|
10
|
+
}
|
|
11
|
+
return loaded.intent;
|
|
12
|
+
};
|
|
13
|
+
export const discoverZone = async (intent, dir) => {
|
|
14
|
+
const cloudflare = intent.cloudflare;
|
|
15
|
+
if (cloudflare === undefined || (intent.apps.length === 0 && intent.services.length === 0)) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
loadEnvFile(dir);
|
|
19
|
+
const token = cloudflare.input.apiToken;
|
|
20
|
+
if (token.source !== "env") {
|
|
21
|
+
throw new Error(`cloudflare apiToken must be an env() secret, but it is "${token.source}"`);
|
|
22
|
+
}
|
|
23
|
+
const apiToken = process.env[token.key];
|
|
24
|
+
if (apiToken === undefined || apiToken === "") {
|
|
25
|
+
throw new Error(`set ${token.key} (your Cloudflare API token) before resolve — it is needed to discover your zone and account`);
|
|
26
|
+
}
|
|
27
|
+
const zones = await cloudflareApi.listZones({ apiToken });
|
|
28
|
+
return selectZone(zones.map((zone) => zone.name), collectDomains(intent));
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=resolve.js.map
|