@lasso-ai/cli 1.0.7 → 1.0.8
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/README.md +2 -0
- package/dist/cli/host/next-host-entry.js +25 -4
- package/dist/cli/index.js +28 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,6 +211,8 @@ project is served at `http://app.lasso:<port>` or the secure
|
|
|
211
211
|
`*.lasso` domains, loopback-only, single instance).
|
|
212
212
|
- `lasso register [domain]` — register the current directory under a `.lasso`
|
|
213
213
|
domain (reuse, generate, or change one); never duplicates.
|
|
214
|
+
- `lasso unregister [domain]` — remove the current directory’s `.lasso`
|
|
215
|
+
registration, or pass a domain explicitly.
|
|
214
216
|
- `lasso projects` — list registered domains and running state.
|
|
215
217
|
- `lasso daemon install/uninstall` — attach a macOS LaunchAgent (auto-start on
|
|
216
218
|
login) and configure the system DNS resolver so bare `app.lasso` works.
|
|
@@ -25,10 +25,29 @@ function freePort() {
|
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
-
function waitForNext(nextPort, timeoutMs = 60_000) {
|
|
28
|
+
function waitForNext(nextPort, nextProcess, timeoutMs = 60_000) {
|
|
29
29
|
const deadline = Date.now() + timeoutMs;
|
|
30
30
|
return new Promise((resolve, reject) => {
|
|
31
|
+
let settled = false;
|
|
32
|
+
const finish = (error) => {
|
|
33
|
+
if (settled)
|
|
34
|
+
return;
|
|
35
|
+
settled = true;
|
|
36
|
+
clearTimeout(timeout);
|
|
37
|
+
nextProcess.off("exit", onExit);
|
|
38
|
+
if (error)
|
|
39
|
+
reject(error);
|
|
40
|
+
else
|
|
41
|
+
resolve();
|
|
42
|
+
};
|
|
43
|
+
const onExit = (code, signal) => {
|
|
44
|
+
finish(new Error(`Next.js exited before becoming ready${code === null ? ` (${signal || "unknown signal"})` : ` with code ${code}`}.`));
|
|
45
|
+
};
|
|
46
|
+
const timeout = setTimeout(() => finish(new Error(`Next.js did not become ready on port ${nextPort} within ${timeoutMs / 1000}s.`)), timeoutMs);
|
|
47
|
+
nextProcess.once("exit", onExit);
|
|
31
48
|
const check = () => {
|
|
49
|
+
if (settled)
|
|
50
|
+
return;
|
|
32
51
|
const request = node_http_1.default.get({
|
|
33
52
|
hostname: "127.0.0.1",
|
|
34
53
|
port: nextPort,
|
|
@@ -36,11 +55,13 @@ function waitForNext(nextPort, timeoutMs = 60_000) {
|
|
|
36
55
|
headers: { connection: "close" },
|
|
37
56
|
}, (response) => {
|
|
38
57
|
response.resume();
|
|
39
|
-
response.once("end",
|
|
58
|
+
response.once("end", () => finish());
|
|
40
59
|
});
|
|
41
60
|
request.once("error", () => {
|
|
61
|
+
if (settled)
|
|
62
|
+
return;
|
|
42
63
|
if (Date.now() >= deadline) {
|
|
43
|
-
|
|
64
|
+
finish(new Error(`Next.js did not become ready on port ${nextPort} within ${timeoutMs / 1000}s.`));
|
|
44
65
|
return;
|
|
45
66
|
}
|
|
46
67
|
setTimeout(check, 250);
|
|
@@ -92,7 +113,7 @@ void (async () => {
|
|
|
92
113
|
});
|
|
93
114
|
server.on("upgrade", (req, socket, head) => proxy.ws(req, socket, head));
|
|
94
115
|
try {
|
|
95
|
-
await waitForNext(nextPort);
|
|
116
|
+
await waitForNext(nextPort, nextProcess);
|
|
96
117
|
}
|
|
97
118
|
catch (error) {
|
|
98
119
|
bridge.close();
|
package/dist/cli/index.js
CHANGED
|
@@ -270,6 +270,34 @@ program.command("register [domain]")
|
|
|
270
270
|
}
|
|
271
271
|
});
|
|
272
272
|
// prettier-ignore
|
|
273
|
+
program.command("unregister [domain]")
|
|
274
|
+
.description("Remove the current project (or a named project) from Lasso Host")
|
|
275
|
+
.action(async (domainArg) => {
|
|
276
|
+
const cwd = process.cwd();
|
|
277
|
+
const config = (0, project_1.readProjectConfig)(cwd);
|
|
278
|
+
const registered = (0, registry_1.findByDirectory)((0, registry_1.loadRegistry)(), cwd);
|
|
279
|
+
const domain = (domainArg || config?.domain || registered?.domain || "").trim().toLowerCase();
|
|
280
|
+
if (!domain) {
|
|
281
|
+
console.error(chalk_1.default.red("✗") + " No .lasso project is registered for this directory. Pass a domain, for example: lasso unregister app.lasso");
|
|
282
|
+
process.exitCode = 1;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (!(0, registry_1.validateDomain)(domain)) {
|
|
286
|
+
console.error(chalk_1.default.red("✗") + ` "${domain}" is not a valid .lasso domain.`);
|
|
287
|
+
process.exitCode = 1;
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const result = await (0, client_1.unregisterFromHost)(domain, (0, paths_1.hostProxyPort)(projectEnv()));
|
|
291
|
+
if (!result.ok) {
|
|
292
|
+
console.error(chalk_1.default.red("✗") + ` ${result.error}`);
|
|
293
|
+
process.exitCode = 1;
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
console.log(result.removed === false
|
|
297
|
+
? chalk_1.default.dim(`No registration found for ${domain}.`)
|
|
298
|
+
: chalk_1.default.green("✓") + ` Unregistered ${chalk_1.default.cyan(domain)}`);
|
|
299
|
+
});
|
|
300
|
+
// prettier-ignore
|
|
273
301
|
const auth = program.command("auth").description("Sign this machine into your Lasso account (the `lasso auth` OAuth flow)");
|
|
274
302
|
// prettier-ignore
|
|
275
303
|
auth.command("login").description("Sign in with the browser OAuth flow and store a Lasso credential locally").action(async () => {
|
package/package.json
CHANGED