@cardelli/ambit 0.1.0 → 0.1.1
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/esm/lib/cli.d.ts.map +1 -1
- package/esm/lib/cli.js +7 -11
- package/esm/lib/command.d.ts.map +1 -1
- package/esm/lib/command.js +45 -40
- package/esm/src/cli/commands/create.js +15 -3
- package/esm/src/cli/commands/deploy.js +15 -6
- package/esm/src/cli/commands/destroy.js +19 -7
- package/esm/src/cli/commands/doctor.js +7 -7
- package/esm/src/cli/commands/list.js +13 -6
- package/esm/src/cli/commands/status.js +100 -94
- package/esm/src/credentials.d.ts +13 -4
- package/esm/src/credentials.d.ts.map +1 -1
- package/esm/src/credentials.js +26 -9
- package/esm/src/guard.d.ts +6 -0
- package/esm/src/guard.d.ts.map +1 -1
- package/esm/src/guard.js +183 -0
- package/esm/src/providers/fly.d.ts +10 -0
- package/esm/src/providers/fly.d.ts.map +1 -1
- package/esm/src/providers/fly.js +31 -4
- package/package.json +4 -1
package/esm/lib/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/lib/cli.ts"],"names":[],"mappings":"AAKA,OAAO,sBAAsB,CAAC;AAiB9B,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,MAAkC,CAAC;AACvE,eAAO,MAAM,GAAG,GAAI,MAAM,MAAM,KAAG,MAAiC,CAAC;AACrE,eAAO,MAAM,GAAG,GAAI,MAAM,MAAM,KAAG,MAAiC,CAAC;AACrE,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,KAAG,MAAmC,CAAC;AACzE,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,KAAG,MAAoC,CAAC;AAC3E,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,MAAkC,CAAC;AACvE,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,MAAkC,CAAC;AAMvE,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,KAAG,IAE1C,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,KAAG,IAE5C,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,IAE3C,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,KAAG,IAE5C,CAAC;AAMF,eAAO,MAAM,GAAG,GAAI,SAAS,MAAM,KAAG,KAGrC,CAAC;AAQF,qBAAa,OAAO;IAClB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAM;IAErB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAe5B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,IAAI,IAAI,IAAI;IASZ,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK9B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAI5B;AAMD,eAAO,MAAM,MAAM,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CAW5D,CAAC;AAEF,eAAO,MAAM,OAAO,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,OAAO,CAG9D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CAIhE,CAAC;AAMF,eAAO,MAAM,UAAU,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,OAAO,CAO9D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OAO7C,CAAC;AAMF,eAAO,MAAM,YAAY,QAAO,MAG/B,CAAC;AAEF,eAAO,MAAM,aAAa,QAAO,MAEhC,CAAC;AAEF,eAAO,MAAM,eAAe,QAAa,OAAO,CAAC,IAAI,CAOpD,CAAC;AAMF,eAAO,MAAM,QAAQ,GAAI,SAAQ,MAAU,KAAG,MAO7C,CAAC;AAMF,eAAO,MAAM,aAAa,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/lib/cli.ts"],"names":[],"mappings":"AAKA,OAAO,sBAAsB,CAAC;AAiB9B,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,MAAkC,CAAC;AACvE,eAAO,MAAM,GAAG,GAAI,MAAM,MAAM,KAAG,MAAiC,CAAC;AACrE,eAAO,MAAM,GAAG,GAAI,MAAM,MAAM,KAAG,MAAiC,CAAC;AACrE,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,KAAG,MAAmC,CAAC;AACzE,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,KAAG,MAAoC,CAAC;AAC3E,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,MAAkC,CAAC;AACvE,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,KAAG,MAAkC,CAAC;AAMvE,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,KAAG,IAE1C,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,KAAG,IAE5C,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,IAE3C,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,KAAG,IAE5C,CAAC;AAMF,eAAO,MAAM,GAAG,GAAI,SAAS,MAAM,KAAG,KAGrC,CAAC;AAQF,qBAAa,OAAO;IAClB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAM;IAErB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAe5B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,IAAI,IAAI,IAAI;IASZ,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK9B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAI5B;AAMD,eAAO,MAAM,MAAM,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CAW5D,CAAC;AAEF,eAAO,MAAM,OAAO,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,OAAO,CAG9D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CAIhE,CAAC;AAMF,eAAO,MAAM,UAAU,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,OAAO,CAO9D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OAO7C,CAAC;AAMF,eAAO,MAAM,YAAY,QAAO,MAG/B,CAAC;AAEF,eAAO,MAAM,aAAa,QAAO,MAEhC,CAAC;AAEF,eAAO,MAAM,eAAe,QAAa,OAAO,CAAC,IAAI,CAOpD,CAAC;AAMF,eAAO,MAAM,QAAQ,GAAI,SAAQ,MAAU,KAAG,MAO7C,CAAC;AAMF,eAAO,MAAM,aAAa,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,OAAO,CASpE,CAAC"}
|
package/esm/lib/cli.js
CHANGED
|
@@ -161,16 +161,12 @@ export const randomId = (length = 6) => {
|
|
|
161
161
|
// Command Exists Check
|
|
162
162
|
// =============================================================================
|
|
163
163
|
export const commandExists = async (command) => {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
stderr: "null",
|
|
164
|
+
const { spawn } = await import("node:child_process");
|
|
165
|
+
return new Promise((resolve) => {
|
|
166
|
+
const child = spawn("which", [command], {
|
|
167
|
+
stdio: "ignore",
|
|
169
168
|
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
catch {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
169
|
+
child.on("error", () => resolve(false));
|
|
170
|
+
child.on("close", (code) => resolve(code === 0));
|
|
171
|
+
});
|
|
176
172
|
};
|
package/esm/lib/command.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/lib/command.ts"],"names":[],"mappings":"AAGA,OAAO,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/lib/command.ts"],"names":[],"mappings":"AAGA,OAAO,sBAAsB,CAAC;AAU9B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD;;GAEG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,MAAM,EAAE,EACd,UAAU;IACR,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;CACtC,KACA,OAAO,CAAC,aAAa,CAwCvB,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,cAAc,GAAU,CAAC,EACpC,MAAM,MAAM,EAAE,EACd,UAAU;IACR,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,KACA,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAmBxD,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,MAAM,MAAM,EAAE,EACd,UAAU;IACR,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,KACA,OAAO,CAAC,aAAa,CAavB,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,QAAQ,GACnB,OAAO,MAAM,EACb,MAAM,MAAM,EAAE,EACd,UAAU;IACR,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,KACA,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAM9C,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EAAE,EACd,UAAU;IACR,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,KACA,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAkB5C,CAAC"}
|
package/esm/lib/command.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Shell Command Helpers
|
|
3
3
|
// =============================================================================
|
|
4
4
|
import "../_dnt.polyfills.js";
|
|
5
|
-
import
|
|
5
|
+
import { spawn } from "node:child_process";
|
|
6
6
|
import { Spinner } from "./cli.js";
|
|
7
7
|
// =============================================================================
|
|
8
8
|
// Run Command
|
|
@@ -10,34 +10,41 @@ import { Spinner } from "./cli.js";
|
|
|
10
10
|
/**
|
|
11
11
|
* Run a command and capture output.
|
|
12
12
|
*/
|
|
13
|
-
export const runCommand =
|
|
13
|
+
export const runCommand = (args, options) => {
|
|
14
14
|
const [cmd, ...cmdArgs] = args;
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
args: cmdArgs,
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
const child = spawn(cmd, cmdArgs, {
|
|
18
17
|
cwd: options?.cwd,
|
|
19
|
-
env: options?.env,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
env: options?.env ? { ...process.env, ...options.env } : undefined,
|
|
19
|
+
stdio: [
|
|
20
|
+
options?.stdin === "inherit" ? "inherit" : "ignore",
|
|
21
|
+
"pipe",
|
|
22
|
+
"pipe",
|
|
23
|
+
],
|
|
23
24
|
});
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
25
|
+
const stdout = [];
|
|
26
|
+
const stderr = [];
|
|
27
|
+
child.stdout.setEncoding("utf8");
|
|
28
|
+
child.stderr.setEncoding("utf8");
|
|
29
|
+
child.stdout.on("data", (chunk) => stdout.push(chunk));
|
|
30
|
+
child.stderr.on("data", (chunk) => stderr.push(chunk));
|
|
31
|
+
child.on("error", (error) => {
|
|
32
|
+
resolve({
|
|
33
|
+
success: false,
|
|
34
|
+
code: -1,
|
|
35
|
+
stdout: "",
|
|
36
|
+
stderr: error.message,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
child.on("close", (code) => {
|
|
40
|
+
resolve({
|
|
41
|
+
success: code === 0,
|
|
42
|
+
code: code ?? 1,
|
|
43
|
+
stdout: stdout.join(""),
|
|
44
|
+
stderr: stderr.join(""),
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
41
48
|
};
|
|
42
49
|
// =============================================================================
|
|
43
50
|
// Run Command with JSON Output
|
|
@@ -101,21 +108,19 @@ export const runQuiet = async (label, args, options) => {
|
|
|
101
108
|
/**
|
|
102
109
|
* Run a command interactively (inherits stdio).
|
|
103
110
|
*/
|
|
104
|
-
export const runInteractive =
|
|
111
|
+
export const runInteractive = (args, options) => {
|
|
105
112
|
const [cmd, ...cmdArgs] = args;
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
args: cmdArgs,
|
|
113
|
+
return new Promise((resolve) => {
|
|
114
|
+
const child = spawn(cmd, cmdArgs, {
|
|
109
115
|
cwd: options?.cwd,
|
|
110
|
-
env: options?.env,
|
|
111
|
-
|
|
112
|
-
stdout: "inherit",
|
|
113
|
-
stderr: "inherit",
|
|
116
|
+
env: options?.env ? { ...process.env, ...options.env } : undefined,
|
|
117
|
+
stdio: "inherit",
|
|
114
118
|
});
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
child.on("error", () => {
|
|
120
|
+
resolve({ success: false, code: -1 });
|
|
121
|
+
});
|
|
122
|
+
child.on("close", (code) => {
|
|
123
|
+
resolve({ success: (code ?? 1) === 0, code: code ?? 1 });
|
|
124
|
+
});
|
|
125
|
+
});
|
|
121
126
|
};
|
|
@@ -6,7 +6,8 @@ import { bold, randomId, readSecret } from "../../../lib/cli.js";
|
|
|
6
6
|
import { createOutput } from "../../../lib/output.js";
|
|
7
7
|
import { registerCommand } from "../mod.js";
|
|
8
8
|
import { extractSubnet, getRouterTag } from "../../schemas/config.js";
|
|
9
|
-
import {
|
|
9
|
+
import { isPublicTld } from "../../guard.js";
|
|
10
|
+
import { createFlyProvider, FlyDeployError, getRouterAppName } from "../../providers/fly.js";
|
|
10
11
|
import { createTailscaleProvider, enableAcceptRoutes, isAcceptRoutesEnabled, isTailscaleInstalled, waitForDevice, } from "../../providers/tailscale.js";
|
|
11
12
|
import { getCredentialStore } from "../../credentials.js";
|
|
12
13
|
import { resolveOrg } from "../../resolve.js";
|
|
@@ -53,6 +54,9 @@ ${bold("EXAMPLES")}
|
|
|
53
54
|
if (!network) {
|
|
54
55
|
return out.die("Network Name Required. Usage: ambit create <network>");
|
|
55
56
|
}
|
|
57
|
+
if (isPublicTld(network)) {
|
|
58
|
+
return out.die(`"${network}" Is a Public TLD and Cannot Be Used as a Network Name`);
|
|
59
|
+
}
|
|
56
60
|
const tag = args.tag || getRouterTag(network);
|
|
57
61
|
const selfApprove = args["self-approve"] ?? false;
|
|
58
62
|
out.blank()
|
|
@@ -164,7 +168,16 @@ ${bold("EXAMPLES")}
|
|
|
164
168
|
out.ok("Set Router Secrets");
|
|
165
169
|
const dockerDir = new URL("../../docker/router", globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url).pathname;
|
|
166
170
|
out.blank().dim("Deploying Router...");
|
|
167
|
-
|
|
171
|
+
try {
|
|
172
|
+
await fly.routerDeploy(routerAppName, dockerDir, { region });
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
if (e instanceof FlyDeployError) {
|
|
176
|
+
out.dim(` ${e.detail}`);
|
|
177
|
+
return out.die(e.message);
|
|
178
|
+
}
|
|
179
|
+
throw e;
|
|
180
|
+
}
|
|
168
181
|
out.ok("Router Deployed");
|
|
169
182
|
out.blank();
|
|
170
183
|
const joinSpinner = out.spinner("Waiting for Router to Join Tailnet");
|
|
@@ -243,7 +256,6 @@ ${bold("EXAMPLES")}
|
|
|
243
256
|
.dim("Control their access:")
|
|
244
257
|
.dim(" https://login.tailscale.com/admin/acls/visual/general-access-rules")
|
|
245
258
|
.blank();
|
|
246
|
-
// Print recommended ACL policy
|
|
247
259
|
if (subnet && selfApprove) {
|
|
248
260
|
out.header("Recommended Tailscale ACL Policy:")
|
|
249
261
|
.blank()
|
|
@@ -6,7 +6,7 @@ import { parseArgs } from "../../../deps/jsr.io/@std/cli/1.0.27/mod.js";
|
|
|
6
6
|
import { bold, confirm, fileExists } from "../../../lib/cli.js";
|
|
7
7
|
import { createOutput } from "../../../lib/output.js";
|
|
8
8
|
import { registerCommand } from "../mod.js";
|
|
9
|
-
import { createFlyProvider } from "../../providers/fly.js";
|
|
9
|
+
import { createFlyProvider, FlyDeployError } from "../../providers/fly.js";
|
|
10
10
|
import { findRouterApp } from "../../discovery.js";
|
|
11
11
|
import { resolveOrg } from "../../resolve.js";
|
|
12
12
|
import { assertNotRouter, auditDeploy, scanFlyToml } from "../../guard.js";
|
|
@@ -172,11 +172,20 @@ ${bold("EXAMPLES")}
|
|
|
172
172
|
// ==========================================================================
|
|
173
173
|
out.header("Step 5: Deploy").blank();
|
|
174
174
|
out.dim("Deploying with --no-public-ips --flycast ...");
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
175
|
+
try {
|
|
176
|
+
await fly.deploySafe(app, {
|
|
177
|
+
image: args.image,
|
|
178
|
+
config: configPath,
|
|
179
|
+
region: args.region,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
if (e instanceof FlyDeployError) {
|
|
184
|
+
out.dim(` ${e.detail}`);
|
|
185
|
+
return out.die(e.message);
|
|
186
|
+
}
|
|
187
|
+
throw e;
|
|
188
|
+
}
|
|
180
189
|
out.ok("Deploy Succeeded");
|
|
181
190
|
out.blank();
|
|
182
191
|
// ==========================================================================
|
|
@@ -6,7 +6,8 @@ import { bold, confirm } from "../../../lib/cli.js";
|
|
|
6
6
|
import { createOutput } from "../../../lib/output.js";
|
|
7
7
|
import { registerCommand } from "../mod.js";
|
|
8
8
|
import { createFlyProvider } from "../../providers/fly.js";
|
|
9
|
-
import {
|
|
9
|
+
import { createTailscaleProvider } from "../../providers/tailscale.js";
|
|
10
|
+
import { checkDependencies } from "../../credentials.js";
|
|
10
11
|
import { findRouterApp } from "../../discovery.js";
|
|
11
12
|
import { resolveOrg } from "../../resolve.js";
|
|
12
13
|
// =============================================================================
|
|
@@ -37,12 +38,17 @@ ${bold("OPTIONS")}
|
|
|
37
38
|
if (!args.network) {
|
|
38
39
|
return out.die("--network Is Required");
|
|
39
40
|
}
|
|
41
|
+
// =========================================================================
|
|
42
|
+
// Prerequisites
|
|
43
|
+
// =========================================================================
|
|
44
|
+
const { tailscaleKey } = await checkDependencies(out);
|
|
40
45
|
const fly = createFlyProvider();
|
|
41
|
-
await fly.ensureInstalled();
|
|
42
46
|
await fly.ensureAuth({ interactive: !args.json });
|
|
43
|
-
const tailscale =
|
|
47
|
+
const tailscale = createTailscaleProvider("-", tailscaleKey);
|
|
44
48
|
const org = await resolveOrg(fly, args, out);
|
|
45
|
-
//
|
|
49
|
+
// =========================================================================
|
|
50
|
+
// Discover Router
|
|
51
|
+
// =========================================================================
|
|
46
52
|
const spinner = out.spinner("Discovering Router");
|
|
47
53
|
const app = await findRouterApp(fly, org, args.network);
|
|
48
54
|
if (!app) {
|
|
@@ -50,13 +56,15 @@ ${bold("OPTIONS")}
|
|
|
50
56
|
return out.die(`No Router Found for Network '${args.network}'`);
|
|
51
57
|
}
|
|
52
58
|
spinner.success(`Found Router: ${app.appName}`);
|
|
53
|
-
// Get tailscale device to read the actual tag
|
|
54
59
|
let tsDevice = null;
|
|
55
60
|
try {
|
|
56
61
|
tsDevice = await tailscale.getDeviceByHostname(app.appName);
|
|
57
62
|
}
|
|
58
63
|
catch { /* device may not exist */ }
|
|
59
64
|
const tag = tsDevice?.tags?.[0] ?? null;
|
|
65
|
+
// =========================================================================
|
|
66
|
+
// Confirm
|
|
67
|
+
// =========================================================================
|
|
60
68
|
out.blank()
|
|
61
69
|
.header("ambit Destroy")
|
|
62
70
|
.blank()
|
|
@@ -72,7 +80,9 @@ ${bold("OPTIONS")}
|
|
|
72
80
|
}
|
|
73
81
|
out.blank();
|
|
74
82
|
}
|
|
75
|
-
//
|
|
83
|
+
// =========================================================================
|
|
84
|
+
// Tear Down
|
|
85
|
+
// =========================================================================
|
|
76
86
|
const dnsSpinner = out.spinner("Clearing Split DNS");
|
|
77
87
|
try {
|
|
78
88
|
await tailscale.clearSplitDns(app.network);
|
|
@@ -95,7 +105,6 @@ ${bold("OPTIONS")}
|
|
|
95
105
|
catch {
|
|
96
106
|
deviceSpinner.fail("Could Not Remove Tailscale Device");
|
|
97
107
|
}
|
|
98
|
-
// 3. Destroy Fly app
|
|
99
108
|
const appSpinner = out.spinner("Destroying Fly App");
|
|
100
109
|
try {
|
|
101
110
|
await fly.deleteApp(app.appName);
|
|
@@ -104,6 +113,9 @@ ${bold("OPTIONS")}
|
|
|
104
113
|
catch {
|
|
105
114
|
appSpinner.fail("Could Not Destroy Fly App");
|
|
106
115
|
}
|
|
116
|
+
// =========================================================================
|
|
117
|
+
// Done
|
|
118
|
+
// =========================================================================
|
|
107
119
|
out.done({ destroyed: true, appName: app.appName });
|
|
108
120
|
out.ok("Router Destroyed");
|
|
109
121
|
if (tag) {
|
|
@@ -7,8 +7,8 @@ import { createOutput } from "../../../lib/output.js";
|
|
|
7
7
|
import { runCommand } from "../../../lib/command.js";
|
|
8
8
|
import { registerCommand } from "../mod.js";
|
|
9
9
|
import { createFlyProvider } from "../../providers/fly.js";
|
|
10
|
-
import { isAcceptRoutesEnabled, isTailscaleInstalled, } from "../../providers/tailscale.js";
|
|
11
|
-
import {
|
|
10
|
+
import { createTailscaleProvider, isAcceptRoutesEnabled, isTailscaleInstalled, } from "../../providers/tailscale.js";
|
|
11
|
+
import { checkDependencies } from "../../credentials.js";
|
|
12
12
|
import { findRouterApp, getRouterMachineInfo, getRouterTailscaleInfo, listRouterApps, } from "../../discovery.js";
|
|
13
13
|
import { resolveOrg } from "../../resolve.js";
|
|
14
14
|
// =============================================================================
|
|
@@ -54,15 +54,15 @@ ${bold("CHECKS")}
|
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
56
|
// =========================================================================
|
|
57
|
-
// Prerequisites
|
|
57
|
+
// Prerequisites
|
|
58
58
|
// =========================================================================
|
|
59
|
+
const { tailscaleKey } = await checkDependencies(out);
|
|
59
60
|
const fly = createFlyProvider();
|
|
60
|
-
await fly.ensureInstalled();
|
|
61
61
|
await fly.ensureAuth({ interactive: !args.json });
|
|
62
|
-
const tailscale =
|
|
62
|
+
const tailscale = createTailscaleProvider("-", tailscaleKey);
|
|
63
63
|
const org = await resolveOrg(fly, args, out);
|
|
64
64
|
// =========================================================================
|
|
65
|
-
// Local
|
|
65
|
+
// Local Checks
|
|
66
66
|
// =========================================================================
|
|
67
67
|
report("Tailscale Installed", await isTailscaleInstalled(), "Install from https://tailscale.com/download");
|
|
68
68
|
const tsStatus = await runCommand(["tailscale", "status", "--json"]);
|
|
@@ -77,7 +77,7 @@ ${bold("CHECKS")}
|
|
|
77
77
|
report("Tailscale Connected", tsConnected, "Run: tailscale up");
|
|
78
78
|
report("Accept Routes Enabled", await isAcceptRoutesEnabled(), "Run: sudo tailscale set --accept-routes");
|
|
79
79
|
// =========================================================================
|
|
80
|
-
// Router
|
|
80
|
+
// Router Checks
|
|
81
81
|
// =========================================================================
|
|
82
82
|
if (args.network) {
|
|
83
83
|
const app = await findRouterApp(fly, org, args.network);
|
|
@@ -7,7 +7,8 @@ import { bold } from "../../../lib/cli.js";
|
|
|
7
7
|
import { createOutput } from "../../../lib/output.js";
|
|
8
8
|
import { registerCommand } from "../mod.js";
|
|
9
9
|
import { createFlyProvider } from "../../providers/fly.js";
|
|
10
|
-
import {
|
|
10
|
+
import { createTailscaleProvider } from "../../providers/tailscale.js";
|
|
11
|
+
import { checkDependencies } from "../../credentials.js";
|
|
11
12
|
import { getRouterMachineInfo, getRouterTailscaleInfo, listRouterApps, } from "../../discovery.js";
|
|
12
13
|
import { resolveOrg } from "../../resolve.js";
|
|
13
14
|
// =============================================================================
|
|
@@ -32,12 +33,17 @@ ${bold("OPTIONS")}
|
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
34
35
|
const out = createOutput(args.json);
|
|
36
|
+
// =========================================================================
|
|
37
|
+
// Prerequisites
|
|
38
|
+
// =========================================================================
|
|
39
|
+
const { tailscaleKey } = await checkDependencies(out);
|
|
35
40
|
const fly = createFlyProvider();
|
|
36
|
-
await fly.ensureInstalled();
|
|
37
41
|
await fly.ensureAuth({ interactive: !args.json });
|
|
38
|
-
const tailscale =
|
|
42
|
+
const tailscale = createTailscaleProvider("-", tailscaleKey);
|
|
39
43
|
const org = await resolveOrg(fly, args, out);
|
|
40
|
-
//
|
|
44
|
+
// =========================================================================
|
|
45
|
+
// Discover Routers
|
|
46
|
+
// =========================================================================
|
|
41
47
|
const spinner = out.spinner("Discovering Routers");
|
|
42
48
|
const routerApps = await listRouterApps(fly, org);
|
|
43
49
|
spinner.success(`Found ${routerApps.length} Router${routerApps.length !== 1 ? "s" : ""}`);
|
|
@@ -50,14 +56,15 @@ ${bold("OPTIONS")}
|
|
|
50
56
|
out.print();
|
|
51
57
|
return;
|
|
52
58
|
}
|
|
53
|
-
// 2. Get machine + tailscale state for each
|
|
54
59
|
const routers = [];
|
|
55
60
|
for (const app of routerApps) {
|
|
56
61
|
const machine = await getRouterMachineInfo(fly, app.appName);
|
|
57
62
|
const ts = await getRouterTailscaleInfo(tailscale, app.appName);
|
|
58
63
|
routers.push({ ...app, machine, tailscale: ts });
|
|
59
64
|
}
|
|
60
|
-
//
|
|
65
|
+
// =========================================================================
|
|
66
|
+
// Render
|
|
67
|
+
// =========================================================================
|
|
61
68
|
out.blank().header("Routers").blank();
|
|
62
69
|
const rows = routers.map((r) => {
|
|
63
70
|
const tsStatus = r.tailscale
|
|
@@ -7,7 +7,8 @@ import { bold } from "../../../lib/cli.js";
|
|
|
7
7
|
import { createOutput } from "../../../lib/output.js";
|
|
8
8
|
import { registerCommand } from "../mod.js";
|
|
9
9
|
import { createFlyProvider } from "../../providers/fly.js";
|
|
10
|
-
import {
|
|
10
|
+
import { createTailscaleProvider, } from "../../providers/tailscale.js";
|
|
11
|
+
import { checkDependencies } from "../../credentials.js";
|
|
11
12
|
import { findRouterApp, getRouterMachineInfo, getRouterTailscaleInfo, listRouterApps, } from "../../discovery.js";
|
|
12
13
|
import { resolveOrg } from "../../resolve.js";
|
|
13
14
|
// =============================================================================
|
|
@@ -36,106 +37,111 @@ ${bold("EXAMPLES")}
|
|
|
36
37
|
`);
|
|
37
38
|
return;
|
|
38
39
|
}
|
|
40
|
+
// =========================================================================
|
|
41
|
+
// Prerequisites
|
|
42
|
+
// =========================================================================
|
|
43
|
+
const { tailscaleKey } = await checkDependencies(createOutput(args.json));
|
|
39
44
|
const fly = createFlyProvider();
|
|
40
|
-
await fly.ensureInstalled();
|
|
41
45
|
await fly.ensureAuth({ interactive: !args.json });
|
|
46
|
+
const tailscale = createTailscaleProvider("-", tailscaleKey);
|
|
47
|
+
// =========================================================================
|
|
48
|
+
// Status
|
|
49
|
+
// =========================================================================
|
|
42
50
|
if (args.network) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
out.blank();
|
|
85
|
-
out.done({
|
|
86
|
-
network: app.network,
|
|
87
|
-
router: app,
|
|
88
|
-
machine,
|
|
89
|
-
tag,
|
|
90
|
-
tailscale: ts,
|
|
91
|
-
});
|
|
92
|
-
out.print();
|
|
51
|
+
await showNetworkStatus(fly, tailscale, args);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
await showAllStatus(fly, tailscale, args);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// Single Router Detailed View
|
|
59
|
+
// =============================================================================
|
|
60
|
+
const showNetworkStatus = async (fly, tailscale, args) => {
|
|
61
|
+
const out = createOutput(args.json);
|
|
62
|
+
const org = await resolveOrg(fly, args, out);
|
|
63
|
+
const app = await findRouterApp(fly, org, args.network);
|
|
64
|
+
if (!app) {
|
|
65
|
+
return out.die(`No Router Found for Network '${args.network}'`);
|
|
66
|
+
}
|
|
67
|
+
const machine = await getRouterMachineInfo(fly, app.appName);
|
|
68
|
+
const ts = await getRouterTailscaleInfo(tailscale, app.appName);
|
|
69
|
+
const tag = ts?.tags?.[0] ?? null;
|
|
70
|
+
out.blank()
|
|
71
|
+
.header("ambit Status")
|
|
72
|
+
.blank()
|
|
73
|
+
.text(` Network: ${bold(app.network)}`)
|
|
74
|
+
.text(` TLD: *.${app.network}`)
|
|
75
|
+
.text(` Tag: ${tag ?? "unknown"}`)
|
|
76
|
+
.blank()
|
|
77
|
+
.text(` Router App: ${app.appName}`)
|
|
78
|
+
.text(` Region: ${machine?.region ?? "unknown"}`)
|
|
79
|
+
.text(` Machine State: ${machine?.state ?? "unknown"}`)
|
|
80
|
+
.text(` Private IP: ${machine?.privateIp ?? "unknown"}`)
|
|
81
|
+
.text(` SOCKS Proxy: ${machine?.privateIp
|
|
82
|
+
? `socks5://[${machine.privateIp}]:1080`
|
|
83
|
+
: "unknown"}`);
|
|
84
|
+
if (machine?.subnet) {
|
|
85
|
+
out.text(` Subnet: ${machine.subnet}`);
|
|
86
|
+
}
|
|
87
|
+
out.blank();
|
|
88
|
+
if (ts) {
|
|
89
|
+
out.text(` Tailscale IP: ${ts.ip}`)
|
|
90
|
+
.text(` Online: ${ts.online ? "yes" : "no"}`);
|
|
93
91
|
}
|
|
94
92
|
else {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
out.blank().header("Router Status").blank();
|
|
123
|
-
const rows = routers.map((r) => {
|
|
124
|
-
const tsStatus = r.tailscale
|
|
125
|
-
? r.tailscale.online ? "online" : "offline"
|
|
126
|
-
: "not found";
|
|
127
|
-
return [r.network, r.appName, r.machine?.state ?? "unknown", tsStatus];
|
|
128
|
-
});
|
|
129
|
-
const table = new Table()
|
|
130
|
-
.header(["Network", "App", "State", "Tailscale"])
|
|
131
|
-
.body(rows)
|
|
132
|
-
.indent(2)
|
|
133
|
-
.padding(2);
|
|
134
|
-
out.text(table.toString());
|
|
135
|
-
out.blank();
|
|
136
|
-
out.done({ routers });
|
|
93
|
+
out.text(" Tailscale: Not Found in Tailnet");
|
|
94
|
+
}
|
|
95
|
+
out.blank();
|
|
96
|
+
out.done({
|
|
97
|
+
network: app.network,
|
|
98
|
+
router: app,
|
|
99
|
+
machine,
|
|
100
|
+
tag,
|
|
101
|
+
tailscale: ts,
|
|
102
|
+
});
|
|
103
|
+
out.print();
|
|
104
|
+
};
|
|
105
|
+
// =============================================================================
|
|
106
|
+
// Summary Table of All Routers
|
|
107
|
+
// =============================================================================
|
|
108
|
+
const showAllStatus = async (fly, tailscale, args) => {
|
|
109
|
+
const out = createOutput(args.json);
|
|
110
|
+
const org = await resolveOrg(fly, args, out);
|
|
111
|
+
const spinner = out.spinner("Discovering Routers");
|
|
112
|
+
const routerApps = await listRouterApps(fly, org);
|
|
113
|
+
spinner.success(`Found ${routerApps.length} Router${routerApps.length !== 1 ? "s" : ""}`);
|
|
114
|
+
if (routerApps.length === 0) {
|
|
115
|
+
out.blank()
|
|
116
|
+
.text("No Routers Found.")
|
|
117
|
+
.dim(" Create one with: ambit create <network>")
|
|
118
|
+
.blank();
|
|
119
|
+
out.done({ routers: [] });
|
|
137
120
|
out.print();
|
|
121
|
+
return;
|
|
138
122
|
}
|
|
123
|
+
const routers = [];
|
|
124
|
+
for (const app of routerApps) {
|
|
125
|
+
const machine = await getRouterMachineInfo(fly, app.appName);
|
|
126
|
+
const ts = await getRouterTailscaleInfo(tailscale, app.appName);
|
|
127
|
+
routers.push({ ...app, machine, tailscale: ts });
|
|
128
|
+
}
|
|
129
|
+
out.blank().header("Router Status").blank();
|
|
130
|
+
const rows = routers.map((r) => {
|
|
131
|
+
const tsStatus = r.tailscale
|
|
132
|
+
? r.tailscale.online ? "online" : "offline"
|
|
133
|
+
: "not found";
|
|
134
|
+
return [r.network, r.appName, r.machine?.state ?? "unknown", tsStatus];
|
|
135
|
+
});
|
|
136
|
+
const table = new Table()
|
|
137
|
+
.header(["Network", "App", "State", "Tailscale"])
|
|
138
|
+
.body(rows)
|
|
139
|
+
.indent(2)
|
|
140
|
+
.padding(2);
|
|
141
|
+
out.text(table.toString());
|
|
142
|
+
out.blank();
|
|
143
|
+
out.done({ routers });
|
|
144
|
+
out.print();
|
|
139
145
|
};
|
|
140
146
|
// =============================================================================
|
|
141
147
|
// Register Command
|
package/esm/src/credentials.d.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import "../_dnt.polyfills.js";
|
|
2
|
-
import { type TailscaleProvider } from "./providers/tailscale.js";
|
|
3
2
|
export interface CredentialStore {
|
|
4
3
|
getTailscaleApiKey(): Promise<string | null>;
|
|
5
4
|
setTailscaleApiKey(key: string): Promise<void>;
|
|
6
5
|
}
|
|
7
6
|
export declare const createConfigCredentialStore: () => CredentialStore;
|
|
8
7
|
export declare const getCredentialStore: () => CredentialStore;
|
|
9
|
-
/**
|
|
10
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Verify that flyctl CLI and Tailscale API key are both available.
|
|
10
|
+
* Reports ALL missing dependencies before dying, so the user can
|
|
11
|
+
* fix everything in one pass instead of hitting errors one at a time.
|
|
12
|
+
*
|
|
13
|
+
* Returns the validated Tailscale API key for explicit injection into
|
|
14
|
+
* the provider created by the caller.
|
|
15
|
+
*/
|
|
16
|
+
export declare const checkDependencies: (out: {
|
|
17
|
+
err(msg: string): unknown;
|
|
11
18
|
die(msg: string): never;
|
|
12
|
-
}) => Promise<
|
|
19
|
+
}) => Promise<{
|
|
20
|
+
tailscaleKey: string;
|
|
21
|
+
}>;
|
|
13
22
|
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/src/credentials.ts"],"names":[],"mappings":"AAGA,OAAO,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/src/credentials.ts"],"names":[],"mappings":"AAGA,OAAO,sBAAsB,CAAC;AAqB9B,MAAM,WAAW,eAAe;IAC9B,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAQD,eAAO,MAAM,2BAA2B,QAAO,eA0B9C,CAAC;AAMF,eAAO,MAAM,kBAAkB,QAAO,eAgBrC,CAAC;AAMF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC5B,KAAK;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,KAC1D,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAyBlC,CAAC"}
|
package/esm/src/credentials.js
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
import "../_dnt.polyfills.js";
|
|
5
5
|
import * as dntShim from "../_dnt.shims.js";
|
|
6
6
|
import { z } from "../deps/jsr.io/@zod/zod/4.3.6/src/index.js";
|
|
7
|
-
import { ensureConfigDir, fileExists } from "../lib/cli.js";
|
|
7
|
+
import { commandExists, ensureConfigDir, fileExists } from "../lib/cli.js";
|
|
8
8
|
import { getConfigDir } from "./schemas/config.js";
|
|
9
|
-
import { createTailscaleProvider, } from "./providers/tailscale.js";
|
|
10
9
|
// =============================================================================
|
|
11
10
|
// Schema
|
|
12
11
|
// =============================================================================
|
|
@@ -59,14 +58,32 @@ export const getCredentialStore = () => {
|
|
|
59
58
|
};
|
|
60
59
|
};
|
|
61
60
|
// =============================================================================
|
|
62
|
-
//
|
|
61
|
+
// Check Dependencies (batch validation)
|
|
63
62
|
// =============================================================================
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Verify that flyctl CLI and Tailscale API key are both available.
|
|
65
|
+
* Reports ALL missing dependencies before dying, so the user can
|
|
66
|
+
* fix everything in one pass instead of hitting errors one at a time.
|
|
67
|
+
*
|
|
68
|
+
* Returns the validated Tailscale API key for explicit injection into
|
|
69
|
+
* the provider created by the caller.
|
|
70
|
+
*/
|
|
71
|
+
export const checkDependencies = async (out) => {
|
|
72
|
+
const errors = [];
|
|
73
|
+
if (!(await commandExists("fly"))) {
|
|
74
|
+
errors.push("Flyctl Not Found. Install from https://fly.io/docs/flyctl/install/");
|
|
75
|
+
}
|
|
76
|
+
const key = await getCredentialStore().getTailscaleApiKey();
|
|
68
77
|
if (!key) {
|
|
69
|
-
|
|
78
|
+
errors.push("Tailscale API Key Required. Run 'ambit create' or set TAILSCALE_API_KEY");
|
|
79
|
+
}
|
|
80
|
+
if (errors.length === 1) {
|
|
81
|
+
return out.die(errors[0]);
|
|
82
|
+
}
|
|
83
|
+
if (errors.length > 1) {
|
|
84
|
+
for (const e of errors)
|
|
85
|
+
out.err(e);
|
|
86
|
+
return out.die("Missing Prerequisites");
|
|
70
87
|
}
|
|
71
|
-
return
|
|
88
|
+
return { tailscaleKey: key };
|
|
72
89
|
};
|
package/esm/src/guard.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import "../_dnt.polyfills.js";
|
|
1
2
|
import type { FlyProvider } from "./providers/fly.js";
|
|
3
|
+
/**
|
|
4
|
+
* Returns true if the given name is a public TLD (case-insensitive).
|
|
5
|
+
* Used to prevent creating networks that would shadow real DNS.
|
|
6
|
+
*/
|
|
7
|
+
export declare const isPublicTld: (name: string) => boolean;
|
|
2
8
|
export interface PreflightResult {
|
|
3
9
|
scanned: boolean;
|
|
4
10
|
errors: string[];
|
package/esm/src/guard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/src/guard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/src/guard.ts"],"names":[],"mappings":"AAWA,OAAO,sBAAsB,CAAC;AAI9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAqLtD;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,OACN,CAAC;AAMtC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAOjD;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAwDhE;AAMD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,iBAAiB,CAAC,CAwF5B"}
|
package/esm/src/guard.js
CHANGED
|
@@ -9,8 +9,191 @@
|
|
|
9
9
|
// - auditDeploy: post-deploy check that releases public IPs and reports
|
|
10
10
|
//
|
|
11
11
|
// =============================================================================
|
|
12
|
+
import "../_dnt.polyfills.js";
|
|
12
13
|
import { parse as parseToml } from "../deps/jsr.io/@std/toml/1.0.11/mod.js";
|
|
13
14
|
// =============================================================================
|
|
15
|
+
// Public TLD Blocklist (source: https://data.iana.org/TLD/tlds-alpha-by-domain.txt)
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// deno-fmt-ignore
|
|
18
|
+
const PUBLIC_TLDS = new Set([
|
|
19
|
+
"aaa", "aarp", "abb", "abbott", "abbvie", "abc", "able", "abogado", "abudhabi", "ac",
|
|
20
|
+
"academy", "accenture", "accountant", "accountants", "aco", "actor", "ad", "ads",
|
|
21
|
+
"adult", "ae", "aeg", "aero", "aetna", "af", "afl", "africa", "ag", "agakhan", "agency",
|
|
22
|
+
"ai", "aig", "airbus", "airforce", "airtel", "akdn", "al", "alibaba", "alipay",
|
|
23
|
+
"allfinanz", "allstate", "ally", "alsace", "alstom", "am", "amazon", "americanexpress",
|
|
24
|
+
"americanfamily", "amex", "amfam", "amica", "amsterdam", "analytics", "android",
|
|
25
|
+
"anquan", "anz", "ao", "aol", "apartments", "app", "apple", "aq", "aquarelle", "ar",
|
|
26
|
+
"arab", "aramco", "archi", "army", "arpa", "art", "arte", "as", "asda", "asia",
|
|
27
|
+
"associates", "at", "athleta", "attorney", "au", "auction", "audi", "audible", "audio",
|
|
28
|
+
"auspost", "author", "auto", "autos", "aw", "aws", "ax", "axa", "az", "azure", "ba",
|
|
29
|
+
"baby", "baidu", "banamex", "band", "bank", "bar", "barcelona", "barclaycard",
|
|
30
|
+
"barclays", "barefoot", "bargains", "baseball", "basketball", "bauhaus", "bayern",
|
|
31
|
+
"bb", "bbc", "bbt", "bbva", "bcg", "bcn", "bd", "be", "beats", "beauty", "beer",
|
|
32
|
+
"berlin", "best", "bestbuy", "bet", "bf", "bg", "bh", "bharti", "bi", "bible", "bid",
|
|
33
|
+
"bike", "bing", "bingo", "bio", "biz", "bj", "black", "blackfriday", "blockbuster",
|
|
34
|
+
"blog", "bloomberg", "blue", "bm", "bms", "bmw", "bn", "bnpparibas", "bo", "boats",
|
|
35
|
+
"boehringer", "bofa", "bom", "bond", "boo", "book", "booking", "bosch", "bostik",
|
|
36
|
+
"boston", "bot", "boutique", "box", "br", "bradesco", "bridgestone", "broadway",
|
|
37
|
+
"broker", "brother", "brussels", "bs", "bt", "build", "builders", "business", "buy",
|
|
38
|
+
"buzz", "bv", "bw", "by", "bz", "bzh", "ca", "cab", "cafe", "cal", "call",
|
|
39
|
+
"calvinklein", "cam", "camera", "camp", "canon", "capetown", "capital", "capitalone",
|
|
40
|
+
"car", "caravan", "cards", "care", "career", "careers", "cars", "casa", "case", "cash",
|
|
41
|
+
"casino", "cat", "catering", "catholic", "cba", "cbn", "cbre", "cc", "cd", "center",
|
|
42
|
+
"ceo", "cern", "cf", "cfa", "cfd", "cg", "ch", "chanel", "channel", "charity", "chase",
|
|
43
|
+
"chat", "cheap", "chintai", "christmas", "chrome", "church", "ci", "cipriani",
|
|
44
|
+
"circle", "cisco", "citadel", "citi", "citic", "city", "ck", "cl", "claims",
|
|
45
|
+
"cleaning", "click", "clinic", "clinique", "clothing", "cloud", "club", "clubmed",
|
|
46
|
+
"cm", "cn", "co", "coach", "codes", "coffee", "college", "cologne", "com", "commbank",
|
|
47
|
+
"community", "company", "compare", "computer", "comsec", "condos", "construction",
|
|
48
|
+
"consulting", "contact", "contractors", "cooking", "cool", "coop", "corsica",
|
|
49
|
+
"country", "coupon", "coupons", "courses", "cpa", "cr", "credit", "creditcard",
|
|
50
|
+
"creditunion", "cricket", "crown", "crs", "cruise", "cruises", "cu", "cuisinella",
|
|
51
|
+
"cv", "cw", "cx", "cy", "cymru", "cyou", "cz", "dad", "dance", "data", "date",
|
|
52
|
+
"dating", "datsun", "day", "dclk", "dds", "de", "deal", "dealer", "deals", "degree",
|
|
53
|
+
"delivery", "dell", "deloitte", "delta", "democrat", "dental", "dentist", "desi",
|
|
54
|
+
"design", "dev", "dhl", "diamonds", "diet", "digital", "direct", "directory",
|
|
55
|
+
"discount", "discover", "dish", "diy", "dj", "dk", "dm", "dnp", "do", "docs", "doctor",
|
|
56
|
+
"dog", "domains", "dot", "download", "drive", "dtv", "dubai", "dupont", "durban",
|
|
57
|
+
"dvag", "dvr", "dz", "earth", "eat", "ec", "eco", "edeka", "edu", "education", "ee",
|
|
58
|
+
"eg", "email", "emerck", "energy", "engineer", "engineering", "enterprises", "epson",
|
|
59
|
+
"equipment", "er", "ericsson", "erni", "es", "esq", "estate", "et", "eu", "eurovision",
|
|
60
|
+
"eus", "events", "exchange", "expert", "exposed", "express", "extraspace", "fage",
|
|
61
|
+
"fail", "fairwinds", "faith", "family", "fan", "fans", "farm", "farmers", "fashion",
|
|
62
|
+
"fast", "fedex", "feedback", "ferrari", "ferrero", "fi", "fidelity", "fido", "film",
|
|
63
|
+
"final", "finance", "financial", "fire", "firestone", "firmdale", "fish", "fishing",
|
|
64
|
+
"fit", "fitness", "fj", "fk", "flickr", "flights", "flir", "florist", "flowers", "fly",
|
|
65
|
+
"fm", "fo", "foo", "food", "football", "ford", "forex", "forsale", "forum",
|
|
66
|
+
"foundation", "fox", "fr", "free", "fresenius", "frl", "frogans", "frontier", "ftr",
|
|
67
|
+
"fujitsu", "fun", "fund", "furniture", "futbol", "fyi", "ga", "gal", "gallery",
|
|
68
|
+
"gallo", "gallup", "game", "games", "gap", "garden", "gay", "gb", "gbiz", "gd", "gdn",
|
|
69
|
+
"ge", "gea", "gent", "genting", "george", "gf", "gg", "ggee", "gh", "gi", "gift",
|
|
70
|
+
"gifts", "gives", "giving", "gl", "glass", "gle", "global", "globo", "gm", "gmail",
|
|
71
|
+
"gmbh", "gmo", "gmx", "gn", "godaddy", "gold", "goldpoint", "golf", "goodyear",
|
|
72
|
+
"goog", "google", "gop", "got", "gov", "gp", "gq", "gr", "grainger", "graphics",
|
|
73
|
+
"gratis", "green", "gripe", "grocery", "group", "gs", "gt", "gu", "gucci", "guge",
|
|
74
|
+
"guide", "guitars", "guru", "gw", "gy", "hair", "hamburg", "hangout", "haus", "hbo",
|
|
75
|
+
"hdfc", "hdfcbank", "health", "healthcare", "help", "helsinki", "here", "hermes",
|
|
76
|
+
"hiphop", "hisamitsu", "hitachi", "hiv", "hk", "hkt", "hm", "hn", "hockey",
|
|
77
|
+
"holdings", "holiday", "homedepot", "homegoods", "homes", "homesense", "honda",
|
|
78
|
+
"horse", "hospital", "host", "hosting", "hot", "hotels", "hotmail", "house", "how",
|
|
79
|
+
"hr", "hsbc", "ht", "hu", "hughes", "hyatt", "hyundai", "ibm", "icbc", "ice", "icu",
|
|
80
|
+
"id", "ie", "ieee", "ifm", "ikano", "il", "im", "imamat", "imdb", "immo", "immobilien",
|
|
81
|
+
"in", "inc", "industries", "infiniti", "info", "ing", "ink", "institute", "insurance",
|
|
82
|
+
"insure", "int", "international", "intuit", "investments", "io", "ipiranga", "iq",
|
|
83
|
+
"ir", "irish", "is", "ismaili", "ist", "istanbul", "it", "itau", "itv", "jaguar",
|
|
84
|
+
"java", "jcb", "je", "jeep", "jetzt", "jewelry", "jio", "jll", "jm", "jmp", "jnj", "jo",
|
|
85
|
+
"jobs", "joburg", "jot", "joy", "jp", "jpmorgan", "jprs", "juegos", "juniper",
|
|
86
|
+
"kaufen", "kddi", "ke", "kerryhotels", "kerryproperties", "kfh", "kg", "kh", "ki",
|
|
87
|
+
"kia", "kids", "kim", "kindle", "kitchen", "kiwi", "km", "kn", "koeln", "komatsu",
|
|
88
|
+
"kosher", "kp", "kpmg", "kpn", "kr", "krd", "kred", "kuokgroup", "kw", "ky", "kyoto",
|
|
89
|
+
"kz", "la", "lacaixa", "lamborghini", "lamer", "land", "landrover", "lanxess",
|
|
90
|
+
"lasalle", "lat", "latino", "latrobe", "law", "lawyer", "lb", "lc", "lds", "lease",
|
|
91
|
+
"leclerc", "lefrak", "legal", "lego", "lexus", "lgbt", "li", "lidl", "life",
|
|
92
|
+
"lifeinsurance", "lifestyle", "lighting", "like", "lilly", "limited", "limo",
|
|
93
|
+
"lincoln", "link", "live", "living", "lk", "llc", "llp", "loan", "loans", "locker",
|
|
94
|
+
"locus", "lol", "london", "lotte", "lotto", "love", "lpl", "lplfinancial", "lr", "ls",
|
|
95
|
+
"lt", "ltd", "ltda", "lu", "lundbeck", "luxe", "luxury", "lv", "ly", "ma", "madrid",
|
|
96
|
+
"maif", "maison", "makeup", "man", "management", "mango", "map", "market",
|
|
97
|
+
"marketing", "markets", "marriott", "marshalls", "mattel", "mba", "mc", "mckinsey",
|
|
98
|
+
"md", "me", "med", "media", "meet", "melbourne", "meme", "memorial", "men", "menu",
|
|
99
|
+
"merckmsd", "mg", "mh", "miami", "microsoft", "mil", "mini", "mint", "mit",
|
|
100
|
+
"mitsubishi", "mk", "ml", "mlb", "mls", "mm", "mma", "mn", "mo", "mobi", "mobile",
|
|
101
|
+
"moda", "moe", "moi", "mom", "monash", "money", "monster", "mormon", "mortgage",
|
|
102
|
+
"moscow", "moto", "motorcycles", "mov", "movie", "mp", "mq", "mr", "ms", "msd", "mt",
|
|
103
|
+
"mtn", "mtr", "mu", "museum", "music", "mv", "mw", "mx", "my", "mz", "na", "nab",
|
|
104
|
+
"nagoya", "name", "navy", "nba", "nc", "ne", "nec", "net", "netbank", "netflix",
|
|
105
|
+
"network", "neustar", "new", "news", "next", "nextdirect", "nexus", "nf", "nfl", "ng",
|
|
106
|
+
"ngo", "nhk", "ni", "nico", "nike", "nikon", "ninja", "nissan", "nissay", "nl", "no",
|
|
107
|
+
"nokia", "norton", "now", "nowruz", "nowtv", "np", "nr", "nra", "nrw", "ntt", "nu",
|
|
108
|
+
"nyc", "nz", "obi", "observer", "office", "okinawa", "olayan", "olayangroup", "ollo",
|
|
109
|
+
"om", "omega", "one", "ong", "onl", "online", "ooo", "open", "oracle", "orange", "org",
|
|
110
|
+
"organic", "origins", "osaka", "otsuka", "ott", "ovh", "pa", "page", "panasonic",
|
|
111
|
+
"paris", "pars", "partners", "parts", "party", "pay", "pccw", "pe", "pet", "pf",
|
|
112
|
+
"pfizer", "pg", "ph", "pharmacy", "phd", "philips", "phone", "photo", "photography",
|
|
113
|
+
"photos", "physio", "pics", "pictet", "pictures", "pid", "pin", "ping", "pink",
|
|
114
|
+
"pioneer", "pizza", "pk", "pl", "place", "play", "playstation", "plumbing", "plus",
|
|
115
|
+
"pm", "pn", "pnc", "pohl", "poker", "politie", "porn", "post", "pr", "praxi", "press",
|
|
116
|
+
"prime", "pro", "prod", "productions", "prof", "progressive", "promo", "properties",
|
|
117
|
+
"property", "protection", "pru", "prudential", "ps", "pt", "pub", "pw", "pwc", "py",
|
|
118
|
+
"qa", "qpon", "quebec", "quest", "racing", "radio", "re", "read", "realestate",
|
|
119
|
+
"realtor", "realty", "recipes", "red", "redumbrella", "rehab", "reise", "reisen",
|
|
120
|
+
"reit", "reliance", "ren", "rent", "rentals", "repair", "report", "republican",
|
|
121
|
+
"rest", "restaurant", "review", "reviews", "rexroth", "rich", "richardli", "ricoh",
|
|
122
|
+
"ril", "rio", "rip", "ro", "rocks", "rodeo", "rogers", "room", "rs", "rsvp", "ru",
|
|
123
|
+
"rugby", "ruhr", "run", "rw", "rwe", "ryukyu", "sa", "saarland", "safe", "safety",
|
|
124
|
+
"sakura", "sale", "salon", "samsclub", "samsung", "sandvik", "sandvikcoromant",
|
|
125
|
+
"sanofi", "sap", "sarl", "sas", "save", "saxo", "sb", "sbi", "sbs", "sc", "scb",
|
|
126
|
+
"schaeffler", "schmidt", "scholarships", "school", "schule", "schwarz", "science",
|
|
127
|
+
"scot", "sd", "se", "search", "seat", "secure", "security", "seek", "select", "sener",
|
|
128
|
+
"services", "seven", "sew", "sex", "sexy", "sfr", "sg", "sh", "shangrila", "sharp",
|
|
129
|
+
"shell", "shia", "shiksha", "shoes", "shop", "shopping", "shouji", "show", "si",
|
|
130
|
+
"silk", "sina", "singles", "site", "sj", "sk", "ski", "skin", "sky", "skype", "sl",
|
|
131
|
+
"sling", "sm", "smart", "smile", "sn", "sncf", "so", "soccer", "social", "softbank",
|
|
132
|
+
"software", "sohu", "solar", "solutions", "song", "sony", "soy", "spa", "space",
|
|
133
|
+
"sport", "spot", "sr", "srl", "ss", "st", "stada", "staples", "star", "statebank",
|
|
134
|
+
"statefarm", "stc", "stcgroup", "stockholm", "storage", "store", "stream", "studio",
|
|
135
|
+
"study", "style", "su", "sucks", "supplies", "supply", "support", "surf", "surgery",
|
|
136
|
+
"suzuki", "sv", "swatch", "swiss", "sx", "sy", "sydney", "systems", "sz", "tab",
|
|
137
|
+
"taipei", "talk", "taobao", "target", "tatamotors", "tatar", "tattoo", "tax", "taxi",
|
|
138
|
+
"tc", "tci", "td", "tdk", "team", "tech", "technology", "tel", "temasek", "tennis",
|
|
139
|
+
"teva", "tf", "tg", "th", "thd", "theater", "theatre", "tiaa", "tickets", "tienda",
|
|
140
|
+
"tips", "tires", "tirol", "tj", "tjmaxx", "tjx", "tk", "tkmaxx", "tl", "tm", "tmall",
|
|
141
|
+
"tn", "to", "today", "tokyo", "tools", "top", "toray", "toshiba", "total", "tours",
|
|
142
|
+
"town", "toyota", "toys", "tr", "trade", "trading", "training", "travel", "travelers",
|
|
143
|
+
"travelersinsurance", "trust", "trv", "tt", "tube", "tui", "tunes", "tushu", "tv",
|
|
144
|
+
"tvs", "tw", "tz", "ua", "ubank", "ubs", "ug", "uk", "unicom", "university", "uno",
|
|
145
|
+
"uol", "ups", "us", "uy", "uz", "va", "vacations", "vana", "vanguard", "vc", "ve",
|
|
146
|
+
"vegas", "ventures", "verisign", "versicherung", "vet", "vg", "vi", "viajes", "video",
|
|
147
|
+
"vig", "viking", "villas", "vin", "vip", "virgin", "visa", "vision", "viva", "vivo",
|
|
148
|
+
"vlaanderen", "vn", "vodka", "volvo", "vote", "voting", "voto", "voyage", "vu",
|
|
149
|
+
"wales", "walmart", "walter", "wang", "wanggou", "watch", "watches", "weather",
|
|
150
|
+
"weatherchannel", "webcam", "weber", "website", "wed", "wedding", "weibo", "weir",
|
|
151
|
+
"wf", "whoswho", "wien", "wiki", "williamhill", "win", "windows", "wine", "winners",
|
|
152
|
+
"wme", "woodside", "work", "works", "world", "wow", "ws", "wtc", "wtf", "xbox",
|
|
153
|
+
"xerox", "xihuan", "xin", "xn--11b4c3d", "xn--1ck2e1b", "xn--1qqw23a",
|
|
154
|
+
"xn--2scrj9c", "xn--30rr7y", "xn--3bst00m", "xn--3ds443g", "xn--3e0b707e",
|
|
155
|
+
"xn--3hcrj9c", "xn--3pxu8k", "xn--42c2d9a", "xn--45br5cyl", "xn--45brj9c",
|
|
156
|
+
"xn--45q11c", "xn--4dbrk0ce", "xn--4gbrim", "xn--54b7fta0cc", "xn--55qw42g",
|
|
157
|
+
"xn--55qx5d", "xn--5su34j936bgsg", "xn--5tzm5g", "xn--6frz82g",
|
|
158
|
+
"xn--6qq986b3xl", "xn--80adxhks", "xn--80ao21a", "xn--80aqecdr1a",
|
|
159
|
+
"xn--80asehdb", "xn--80aswg", "xn--8y0a063a", "xn--90a3ac", "xn--90ae",
|
|
160
|
+
"xn--90ais", "xn--9dbq2a", "xn--9et52u", "xn--9krt00a", "xn--b4w605ferd",
|
|
161
|
+
"xn--bck1b9a5dre4c", "xn--c1avg", "xn--c2br7g", "xn--cck2b3b",
|
|
162
|
+
"xn--cckwcxetd", "xn--cg4bki", "xn--clchc0ea0b2g2a9gcd", "xn--czr694b",
|
|
163
|
+
"xn--czrs0t", "xn--czru2d", "xn--d1acj3b", "xn--d1alf", "xn--e1a4c",
|
|
164
|
+
"xn--eckvdtc9d", "xn--efvy88h", "xn--fct429k", "xn--fhbei", "xn--fiq228c5hs",
|
|
165
|
+
"xn--fiq64b", "xn--fiqs8s", "xn--fiqz9s", "xn--fjq720a", "xn--flw351e",
|
|
166
|
+
"xn--fpcrj9c3d", "xn--fzc2c9e2c", "xn--fzys8d69uvgm", "xn--g2xx48c",
|
|
167
|
+
"xn--gckr3f0f", "xn--gecrj9c", "xn--gk3at1e", "xn--h2breg3eve", "xn--h2brj9c",
|
|
168
|
+
"xn--h2brj9c8c", "xn--hxt814e", "xn--i1b6b1a6a2e", "xn--imr513n",
|
|
169
|
+
"xn--io0a7i", "xn--j1aef", "xn--j1amh", "xn--j6w193g", "xn--jlq480n2rg",
|
|
170
|
+
"xn--jvr189m", "xn--kcrx77d1x4a", "xn--kprw13d", "xn--kpry57d", "xn--kput3i",
|
|
171
|
+
"xn--l1acc", "xn--lgbbat1ad8j", "xn--mgb9awbf", "xn--mgba3a3ejt",
|
|
172
|
+
"xn--mgba3a4f16a", "xn--mgba7c0bbn0a", "xn--mgbaam7a8h", "xn--mgbab2bd",
|
|
173
|
+
"xn--mgbah1a3hjkrd", "xn--mgbai9azgqp6j", "xn--mgbayh7gpa", "xn--mgbbh1a",
|
|
174
|
+
"xn--mgbbh1a71e", "xn--mgbc0a9azcg", "xn--mgbca7dzdo", "xn--mgbcpq6gpa1a",
|
|
175
|
+
"xn--mgberp4a5d4ar", "xn--mgbgu82a", "xn--mgbi4ecexp", "xn--mgbpl2fh",
|
|
176
|
+
"xn--mgbt3dhd", "xn--mgbtx2b", "xn--mgbx4cd0ab", "xn--mix891f",
|
|
177
|
+
"xn--mk1bu44c", "xn--mxtq1m", "xn--ngbc5azd", "xn--ngbe9e0a", "xn--ngbrx",
|
|
178
|
+
"xn--node", "xn--nqv7f", "xn--nqv7fs00ema", "xn--nyqy26a", "xn--o3cw4h",
|
|
179
|
+
"xn--ogbpf8fl", "xn--otu796d", "xn--p1acf", "xn--p1ai", "xn--pgbs0dh",
|
|
180
|
+
"xn--pssy2u", "xn--q7ce6a", "xn--q9jyb4c", "xn--qcka1pmc", "xn--qxa6a",
|
|
181
|
+
"xn--qxam", "xn--rhqv96g", "xn--rovu88b", "xn--rvc1e0am3e", "xn--s9brj9c",
|
|
182
|
+
"xn--ses554g", "xn--t60b56a", "xn--tckwe", "xn--tiq49xqyj", "xn--unup4y",
|
|
183
|
+
"xn--vermgensberater-ctb", "xn--vermgensberatung-pwb", "xn--vhquv",
|
|
184
|
+
"xn--vuq861b", "xn--w4r85el8fhu5dnra", "xn--w4rs40l", "xn--wgbh1c",
|
|
185
|
+
"xn--wgbl6a", "xn--xhq521b", "xn--xkc2al3hye2a", "xn--xkc2dl3a5ee0h",
|
|
186
|
+
"xn--y9a3aq", "xn--yfro4i67o", "xn--ygbi2ammx", "xn--zfr164b", "xxx", "xyz",
|
|
187
|
+
"yachts", "yahoo", "yamaxun", "yandex", "ye", "yodobashi", "yoga", "yokohama", "you",
|
|
188
|
+
"youtube", "yt", "yun", "za", "zappos", "zara", "zero", "zip", "zm", "zone", "zuerich",
|
|
189
|
+
"zw",
|
|
190
|
+
]);
|
|
191
|
+
/**
|
|
192
|
+
* Returns true if the given name is a public TLD (case-insensitive).
|
|
193
|
+
* Used to prevent creating networks that would shadow real DNS.
|
|
194
|
+
*/
|
|
195
|
+
export const isPublicTld = (name) => PUBLIC_TLDS.has(name.toLowerCase());
|
|
196
|
+
// =============================================================================
|
|
14
197
|
// assertNotRouter
|
|
15
198
|
// =============================================================================
|
|
16
199
|
/**
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import "../../_dnt.polyfills.js";
|
|
2
2
|
import { type FlyApp, type FlyAppInfo, type FlyIp, type FlyMachine } from "../schemas/fly.js";
|
|
3
|
+
/**
|
|
4
|
+
* Thrown when a `fly deploy` command fails. Carries the raw stderr so callers
|
|
5
|
+
* can surface it through `out` (respecting JSON mode) instead of printing
|
|
6
|
+
* directly.
|
|
7
|
+
*/
|
|
8
|
+
export declare class FlyDeployError extends Error {
|
|
9
|
+
/** Last meaningful line from flyctl stderr. */
|
|
10
|
+
readonly detail: string;
|
|
11
|
+
constructor(app: string, stderr: string);
|
|
12
|
+
}
|
|
3
13
|
export type MachineSize = "shared-cpu-1x" | "shared-cpu-2x" | "shared-cpu-4x";
|
|
4
14
|
export interface MachineConfig {
|
|
5
15
|
size: MachineSize;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fly.d.ts","sourceRoot":"","sources":["../../../src/src/providers/fly.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"fly.d.ts","sourceRoot":"","sources":["../../../src/src/providers/fly.ts"],"names":[],"mappings":"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"}
|
package/esm/src/providers/fly.js
CHANGED
|
@@ -12,6 +12,35 @@ import { fileExists } from "../../lib/cli.js";
|
|
|
12
12
|
// Constants
|
|
13
13
|
// =============================================================================
|
|
14
14
|
const ROUTER_APP_PREFIX = "ambit-";
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Deploy Error
|
|
17
|
+
// =============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Thrown when a `fly deploy` command fails. Carries the raw stderr so callers
|
|
20
|
+
* can surface it through `out` (respecting JSON mode) instead of printing
|
|
21
|
+
* directly.
|
|
22
|
+
*/
|
|
23
|
+
export class FlyDeployError extends Error {
|
|
24
|
+
/** Last meaningful line from flyctl stderr. */
|
|
25
|
+
detail;
|
|
26
|
+
constructor(app, stderr) {
|
|
27
|
+
const detail = extractErrorDetail(stderr);
|
|
28
|
+
super(`Deploy Failed for '${app}'`);
|
|
29
|
+
this.name = "FlyDeployError";
|
|
30
|
+
this.detail = detail;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Pull the last non-empty, non-decoration line from fly stderr.
|
|
35
|
+
* Fly often prints progress lines then the actual error at the end.
|
|
36
|
+
*/
|
|
37
|
+
const extractErrorDetail = (stderr) => {
|
|
38
|
+
const lines = stderr
|
|
39
|
+
.split("\n")
|
|
40
|
+
.map((l) => l.replace(/\x1b\[[0-9;]*m/g, "").trim())
|
|
41
|
+
.filter((l) => l.length > 0 && !l.startsWith("-->") && l !== "Error");
|
|
42
|
+
return lines[lines.length - 1] ?? "unknown error";
|
|
43
|
+
};
|
|
15
44
|
export const getSizeConfig = (size) => {
|
|
16
45
|
switch (size) {
|
|
17
46
|
case "shared-cpu-1x":
|
|
@@ -226,8 +255,7 @@ export const createFlyProvider = () => {
|
|
|
226
255
|
}
|
|
227
256
|
const result = await runCommand(args);
|
|
228
257
|
if (!result.success) {
|
|
229
|
-
|
|
230
|
-
return die(`Deploy Failed for '${app}'`);
|
|
258
|
+
throw new FlyDeployError(app, result.stderr);
|
|
231
259
|
}
|
|
232
260
|
},
|
|
233
261
|
async listIps(app) {
|
|
@@ -306,8 +334,7 @@ export const createFlyProvider = () => {
|
|
|
306
334
|
}
|
|
307
335
|
const result = await runCommand(args);
|
|
308
336
|
if (!result.success) {
|
|
309
|
-
|
|
310
|
-
return die(`Deploy Failed for '${app}'`);
|
|
337
|
+
throw new FlyDeployError(app, result.stderr);
|
|
311
338
|
}
|
|
312
339
|
},
|
|
313
340
|
async listCerts(app) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardelli/ambit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Tailscale subnet router manager for Fly.io custom networks",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"module": "./esm/src/providers/fly.js",
|
|
@@ -38,6 +38,9 @@
|
|
|
38
38
|
"./src/discovery": {
|
|
39
39
|
"import": "./esm/src/discovery.js"
|
|
40
40
|
},
|
|
41
|
+
"./src/guard": {
|
|
42
|
+
"import": "./esm/src/guard.js"
|
|
43
|
+
},
|
|
41
44
|
"./src/resolve": {
|
|
42
45
|
"import": "./esm/src/resolve.js"
|
|
43
46
|
}
|