@malloydata/malloyyo 0.2.39 → 0.2.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +64 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2881,7 +2881,7 @@ function clearCreds(url6) {
|
|
|
2881
2881
|
}
|
|
2882
2882
|
|
|
2883
2883
|
// package.json
|
|
2884
|
-
var version = "0.2.
|
|
2884
|
+
var version = "0.2.40";
|
|
2885
2885
|
|
|
2886
2886
|
// src/http.ts
|
|
2887
2887
|
var USER_AGENT = `malloyyo/${version}`;
|
|
@@ -2928,15 +2928,34 @@ async function registerClient(registrationEndpoint, redirectUri) {
|
|
|
2928
2928
|
if (!res.ok) throw new Error(`client registration failed: ${res.status} ${await res.text()}`);
|
|
2929
2929
|
return (await res.json()).client_id;
|
|
2930
2930
|
}
|
|
2931
|
+
function browserless(platform = process.platform, env = process.env) {
|
|
2932
|
+
if (platform === "darwin" || platform === "win32") return false;
|
|
2933
|
+
return !env.DISPLAY && !env.WAYLAND_DISPLAY;
|
|
2934
|
+
}
|
|
2931
2935
|
function openBrowser(url6) {
|
|
2932
2936
|
const [cmd, args] = process.platform === "darwin" ? ["open", [url6]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url6]] : ["xdg-open", [url6]];
|
|
2933
2937
|
try {
|
|
2934
|
-
spawn(cmd, args, { stdio: "ignore", detached: true })
|
|
2938
|
+
const child = spawn(cmd, args, { stdio: "ignore", detached: true });
|
|
2939
|
+
child.on("error", () => {
|
|
2940
|
+
});
|
|
2941
|
+
child.unref();
|
|
2935
2942
|
} catch {
|
|
2936
2943
|
}
|
|
2937
2944
|
}
|
|
2945
|
+
function listenTarget(env = process.env) {
|
|
2946
|
+
const raw = env.MALLOYYO_OAUTH_PORT;
|
|
2947
|
+
let port = 0;
|
|
2948
|
+
if (raw !== void 0 && raw !== "") {
|
|
2949
|
+
port = Number(raw);
|
|
2950
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
2951
|
+
throw new Error(`MALLOYYO_OAUTH_PORT must be a port number between 1 and 65535, got "${raw}"`);
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
return { host: env.MALLOYYO_OAUTH_HOST || "127.0.0.1", port };
|
|
2955
|
+
}
|
|
2938
2956
|
function awaitRedirect(state) {
|
|
2939
|
-
return new Promise((resolveServer) => {
|
|
2957
|
+
return new Promise((resolveServer, rejectServer) => {
|
|
2958
|
+
const { host, port: wanted } = listenTarget();
|
|
2940
2959
|
let resolveCode;
|
|
2941
2960
|
let rejectCode;
|
|
2942
2961
|
const code = new Promise((res, rej) => {
|
|
@@ -2961,13 +2980,33 @@ function awaitRedirect(state) {
|
|
|
2961
2980
|
if (ok) resolveCode(got);
|
|
2962
2981
|
else rejectCode(new Error(err ?? "state mismatch or missing code"));
|
|
2963
2982
|
});
|
|
2964
|
-
|
|
2983
|
+
let listening = false;
|
|
2984
|
+
server.on("error", (err) => {
|
|
2985
|
+
clearTimeout(timer);
|
|
2986
|
+
const detail = err.code === "EADDRINUSE" ? `${host}:${wanted} is already in use \u2014 set MALLOYYO_OAUTH_PORT to a free port` : err.message;
|
|
2987
|
+
const failure = new Error(`could not start the sign-in listener: ${detail}`);
|
|
2988
|
+
rejectCode(failure);
|
|
2989
|
+
if (!listening) {
|
|
2990
|
+
void code.catch(() => {
|
|
2991
|
+
});
|
|
2992
|
+
rejectServer(failure);
|
|
2993
|
+
}
|
|
2994
|
+
});
|
|
2995
|
+
server.listen(wanted, host, () => {
|
|
2996
|
+
listening = true;
|
|
2965
2997
|
const port = server.address().port;
|
|
2966
|
-
resolveServer({
|
|
2998
|
+
resolveServer({
|
|
2999
|
+
port,
|
|
3000
|
+
code,
|
|
3001
|
+
close: () => {
|
|
3002
|
+
clearTimeout(timer);
|
|
3003
|
+
server.close();
|
|
3004
|
+
}
|
|
3005
|
+
});
|
|
2967
3006
|
});
|
|
2968
3007
|
});
|
|
2969
3008
|
}
|
|
2970
|
-
async function login(baseUrl) {
|
|
3009
|
+
async function login(baseUrl, opts = {}) {
|
|
2971
3010
|
const ep = await discover(baseUrl);
|
|
2972
3011
|
const { verifier, challenge } = pkce();
|
|
2973
3012
|
const state = crypto.randomBytes(16).toString("base64url");
|
|
@@ -2985,11 +3024,24 @@ async function login(baseUrl) {
|
|
|
2985
3024
|
scope: "mcp",
|
|
2986
3025
|
state
|
|
2987
3026
|
}).toString();
|
|
2988
|
-
|
|
2989
|
-
|
|
3027
|
+
if (opts.noBrowser || browserless()) {
|
|
3028
|
+
console.log(`Visit this URL to sign in:
|
|
3029
|
+
|
|
2990
3030
|
${authUrl.toString()}
|
|
2991
3031
|
`);
|
|
2992
|
-
|
|
3032
|
+
if (!process.env.MALLOYYO_OAUTH_PORT) {
|
|
3033
|
+
console.log(
|
|
3034
|
+
"Note: sign-in redirects back to this machine on a random port.\n In a container, set MALLOYYO_OAUTH_PORT and MALLOYYO_OAUTH_HOST=0.0.0.0,\n and publish that port, so the browser can reach the redirect.\n"
|
|
3035
|
+
);
|
|
3036
|
+
}
|
|
3037
|
+
console.log("Waiting for sign-in to complete\u2026");
|
|
3038
|
+
} else {
|
|
3039
|
+
console.log("Opening your browser to sign in\u2026");
|
|
3040
|
+
console.log(`If it doesn't open, visit:
|
|
3041
|
+
${authUrl.toString()}
|
|
3042
|
+
`);
|
|
3043
|
+
openBrowser(authUrl.toString());
|
|
3044
|
+
}
|
|
2993
3045
|
const authCode = await code;
|
|
2994
3046
|
const res = await apiFetch(ep.token_endpoint, {
|
|
2995
3047
|
method: "POST",
|
|
@@ -5389,9 +5441,9 @@ async function status(target, opts) {
|
|
|
5389
5441
|
console.log(` version ${s.version ?? "?"}` + (git?.sha ? ` ${git.branch}@${shortSha(git.sha)}` : ""));
|
|
5390
5442
|
console.log(` ${s.compileError ? `\u2717 ${s.compileError}` : `\u2713 compiled ${s.compiledAt ?? ""}`}`);
|
|
5391
5443
|
}
|
|
5392
|
-
async function loginCmd(target) {
|
|
5444
|
+
async function loginCmd(target, opts) {
|
|
5393
5445
|
const inst = resolveInstance(resolve3("."), target);
|
|
5394
|
-
await login(inst.url);
|
|
5446
|
+
await login(inst.url, { noBrowser: opts.browser === false });
|
|
5395
5447
|
console.log(`\u2713 logged in to ${inst.name} (${inst.url})`);
|
|
5396
5448
|
}
|
|
5397
5449
|
async function logoutCmd(target) {
|
|
@@ -5400,7 +5452,7 @@ async function logoutCmd(target) {
|
|
|
5400
5452
|
}
|
|
5401
5453
|
var program = new Command();
|
|
5402
5454
|
program.name("malloyyo").description("Publish Malloy models to a Malloyyo instance").version(version);
|
|
5403
|
-
program.command("login").argument("[target]", "target name or instance URL (optional if the config has one target)").description("sign in to an instance in your browser (stores a token)").action(loginCmd);
|
|
5455
|
+
program.command("login").argument("[target]", "target name or instance URL (optional if the config has one target)").option("--no-browser", "print the sign-in URL instead of launching a browser").description("sign in to an instance in your browser (stores a token)").action(loginCmd);
|
|
5404
5456
|
program.command("logout").argument("[target]", "target name or instance URL (optional if the config has one target)").description("forget the stored token for an instance").action(logoutCmd);
|
|
5405
5457
|
program.command("publish").argument(
|
|
5406
5458
|
"[target]",
|