create-nola-lang 0.1.4 → 0.1.6
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 +10 -0
- package/dist/add.d.ts +11 -3
- package/dist/add.d.ts.map +1 -1
- package/dist/add.js +16 -3
- package/dist/add.js.map +1 -1
- package/dist/agents.d.ts +4 -2
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +18 -22
- package/dist/agents.js.map +1 -1
- package/dist/api.d.ts +129 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +156 -0
- package/dist/api.js.map +1 -0
- package/dist/auth.d.ts +87 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +334 -0
- package/dist/auth.js.map +1 -0
- package/dist/checkout.d.ts +24 -0
- package/dist/checkout.d.ts.map +1 -0
- package/dist/checkout.js +65 -0
- package/dist/checkout.js.map +1 -0
- package/dist/chunk-34XSPT6F.js +2002 -0
- package/dist/{prompter-6BJFVFZL.js → chunk-7IQIRMK6.js} +420 -57
- package/dist/chunk-FPS2V3S4.js +107 -0
- package/dist/cli.d.ts +53 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +107 -0
- package/dist/cli.js.map +1 -0
- package/dist/credentials.d.ts +30 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +98 -0
- package/dist/credentials.js.map +1 -0
- package/dist/examples.d.ts +1 -5
- package/dist/examples.d.ts.map +1 -1
- package/dist/examples.js +4 -17
- package/dist/examples.js.map +1 -1
- package/dist/flow.d.ts +117 -0
- package/dist/flow.d.ts.map +1 -1
- package/dist/flow.js +363 -35
- package/dist/flow.js.map +1 -1
- package/dist/home-config.d.ts +31 -0
- package/dist/home-config.d.ts.map +1 -0
- package/dist/home-config.js +86 -0
- package/dist/home-config.js.map +1 -0
- package/dist/index.d.ts +24 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +140 -5
- package/dist/index.js.map +1 -1
- package/dist/key.d.ts +45 -0
- package/dist/key.d.ts.map +1 -0
- package/dist/key.js +92 -0
- package/dist/key.js.map +1 -0
- package/dist/launch.d.ts +46 -0
- package/dist/launch.d.ts.map +1 -0
- package/dist/launch.js +80 -0
- package/dist/launch.js.map +1 -0
- package/dist/main.js +11 -22
- package/dist/main.js.map +1 -1
- package/dist/node-version.d.ts +22 -0
- package/dist/node-version.d.ts.map +1 -0
- package/dist/node-version.js +60 -0
- package/dist/node-version.js.map +1 -0
- package/dist/open-url.d.ts +20 -0
- package/dist/open-url.d.ts.map +1 -0
- package/dist/open-url.js +51 -0
- package/dist/open-url.js.map +1 -0
- package/dist/palette.d.ts +31 -0
- package/dist/palette.d.ts.map +1 -0
- package/dist/palette.js +36 -0
- package/dist/palette.js.map +1 -0
- package/dist/prompter-LGNUYLB4.js +7 -0
- package/dist/prompter.d.ts.map +1 -1
- package/dist/prompter.js +23 -1
- package/dist/prompter.js.map +1 -1
- package/dist/providers.d.ts +24 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +23 -0
- package/dist/providers.js.map +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +1 -0
- package/dist/registry.js.map +1 -1
- package/dist/scaffold.d.ts +25 -0
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +80 -4
- package/dist/scaffold.js.map +1 -1
- package/dist/skill-install.js +2 -2
- package/dist/skill-install.js.map +1 -1
- package/dist/style.d.ts +16 -0
- package/dist/style.d.ts.map +1 -0
- package/dist/style.js +31 -0
- package/dist/style.js.map +1 -0
- package/dist/trial.d.ts +35 -0
- package/dist/trial.d.ts.map +1 -0
- package/dist/trial.js +90 -0
- package/dist/trial.js.map +1 -0
- package/package.json +6 -4
- package/skills/nola/SKILL.md +4 -2
- package/skills/nola/references/config.md +124 -41
- package/skills/nola/references/patterns.md +1 -1
- package/skills/nola/references/pitfalls.md +6 -6
- package/skills/nola/references/syntax.md +10 -8
- package/templates/_providers/anthropic.config.ts +10 -0
- package/templates/_providers/google.config.ts +10 -0
- package/templates/_providers/nola.config.ts +11 -0
- package/templates/_providers/openai.config.ts +10 -0
- package/templates/empty/_gitignore +3 -0
- package/templates/empty/nola.config.ts +5 -7
- package/templates/empty/package.json +1 -1
- package/templates/empty/src/main.ts +2 -0
- package/templates/starter/README.md +3 -5
- package/templates/starter/_gitignore +2 -1
- package/templates/starter/nola.config.ts +7 -9
- package/templates/starter/nola.replay.jsonl +1 -1
- package/templates/starter/package.json +1 -1
- package/templates/starter/src/main.ts +2 -0
- package/dist/chunk-TRTQSARU.js +0 -34
- package/dist/chunk-VZM5EYBG.js +0 -703
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAqB,KAAK,cAAc,EAAc,MAAM,UAAU,CAAC;AAC/F,OAAO,EAA8B,KAAK,OAAO,EAAgB,MAAM,kBAAkB,CAAC;AAI1F;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,qBAAa,sBAAuB,SAAQ,KAAK;IACtC,IAAI,SAA4B;gBAC7B,OAAO,SAAsD;CAG1E;AAED,wFAAwF;AACxF,qBAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,SAAiB;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+GAA+G;AAC/G,eAAO,MAAM,aAAa,qBAAqB,CAAC;AAChD,8JAA8J;AAC9J,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAC/C,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAsD1C,kFAAkF;AAClF,wBAAgB,QAAQ,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAGlE;AAED,kIAAkI;AAClI,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAY3I;AAmGD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAE3E;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAE/E;AAED,4FAA4F;AAC5F,wBAAsB,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CAYxH;AAED,4EAA4E;AAC5E,wBAAsB,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAWlH;AAED,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC7C,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,mIAAmI;AACnI,wBAAsB,UAAU,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAU/G;AAED,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,0EAA0E;IAC1E,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,uKAAuK;IACvK,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAChC,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD,2HAA2H;AAC3H,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAgClE;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,CAmBrH;AAED,iDAAiD;AACjD,wBAAsB,OAAO,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,GAAG,eAAe,CAAC,CAY7F"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { fetchCapabilities, nolaApiUrl } from "./api.js";
|
|
4
|
+
import { deleteSession, readSession, writeSession } from "./credentials.js";
|
|
5
|
+
import { readHomeConfig } from "./home-config.js";
|
|
6
|
+
import { openBrowser } from "./open-url.js";
|
|
7
|
+
/**
|
|
8
|
+
* Sign-in for the CLI: the Auth0 Authorization Code + PKCE flow (RFC 7636)
|
|
9
|
+
* with a loopback redirect (RFC 8252 §7.3), against the tenant the Nola API
|
|
10
|
+
* names in `GET /v1/capabilities` (platform spec 2026-09-07 §6). The machine's
|
|
11
|
+
* recorded trial account id rides `/authorize` as `ext-nola_account`; the
|
|
12
|
+
* tenant's Action puts it in the access token and the API claims the account.
|
|
13
|
+
* Zero deps — node:http for the one callback, form-encoded POSTs over fetch.
|
|
14
|
+
* Tokens live in `~/.nola/credentials.json` and are never printed.
|
|
15
|
+
*/
|
|
16
|
+
/** The server does not offer sign-in (no `auth` in its capabilities). */
|
|
17
|
+
export class SignInUnavailableError extends Error {
|
|
18
|
+
name = "SignInUnavailableError";
|
|
19
|
+
constructor(message = "Sign-in is not available on this Nola server yet.") {
|
|
20
|
+
super(message);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** The sign-in ran but did not complete (denied, expired, network, malformed reply). */
|
|
24
|
+
export class SignInError extends Error {
|
|
25
|
+
name = "SignInError";
|
|
26
|
+
}
|
|
27
|
+
/** Mirrors core's NOLA_ACCOUNT_PARAM — the /authorize query parameter the tenant's post-login Action reads. */
|
|
28
|
+
export const ACCOUNT_PARAM = "ext-nola_account";
|
|
29
|
+
/** Mirrors core's NOLA_ACCOUNT_CLAIM — the access-token claim the Action sets; the API refuses tokens without it (spec 2026-09-07 account-claim-required). */
|
|
30
|
+
export const ACCOUNT_CLAIM = "nola:account_id";
|
|
31
|
+
/** How long the browser has to come back to the loopback callback. */
|
|
32
|
+
export const SIGN_IN_TIMEOUT_MS = 300_000;
|
|
33
|
+
const SCOPE = "openid profile email offline_access";
|
|
34
|
+
const CALLBACK_PATH = "/callback";
|
|
35
|
+
/** Refresh when the access token has less than this left. */
|
|
36
|
+
const REFRESH_MARGIN_MS = 60_000;
|
|
37
|
+
async function postForm(init, url, form) {
|
|
38
|
+
const doFetch = init.fetch ?? globalThis.fetch;
|
|
39
|
+
let res;
|
|
40
|
+
try {
|
|
41
|
+
res = await doFetch(url, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" },
|
|
44
|
+
body: new URLSearchParams(form).toString(),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
throw new SignInError(`Could not reach the sign-in provider at ${url}: ${err instanceof Error ? err.message : String(err)}`, {
|
|
49
|
+
cause: err,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const text = await res.text();
|
|
53
|
+
let body;
|
|
54
|
+
try {
|
|
55
|
+
body = text === "" ? {} : JSON.parse(text);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
body = {};
|
|
59
|
+
}
|
|
60
|
+
return { ok: res.ok, status: res.status, body: typeof body === "object" && body !== null ? body : {} };
|
|
61
|
+
}
|
|
62
|
+
const str = (v) => (typeof v === "string" && v !== "" ? v : undefined);
|
|
63
|
+
const num = (v, fallback) => (typeof v === "number" && Number.isFinite(v) ? v : fallback);
|
|
64
|
+
function describe(body, fallback) {
|
|
65
|
+
return str(body.error_description) ?? str(body.error) ?? fallback;
|
|
66
|
+
}
|
|
67
|
+
function tokenSetOf(body) {
|
|
68
|
+
const accessToken = str(body.access_token);
|
|
69
|
+
if (!accessToken)
|
|
70
|
+
throw new SignInError("Sign-in did not complete: the provider returned no access token.");
|
|
71
|
+
return {
|
|
72
|
+
accessToken,
|
|
73
|
+
...(str(body.refresh_token) ? { refreshToken: str(body.refresh_token) } : {}),
|
|
74
|
+
expiresIn: num(body.expires_in, 3600),
|
|
75
|
+
...(str(body.id_token) ? { idToken: str(body.id_token) } : {}),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** RFC 7636: a 32-byte random verifier and its S256 challenge, both base64url. */
|
|
79
|
+
export function pkcePair() {
|
|
80
|
+
const verifier = randomBytes(32).toString("base64url");
|
|
81
|
+
return { verifier, challenge: createHash("sha256").update(verifier).digest("base64url") };
|
|
82
|
+
}
|
|
83
|
+
/** The `/authorize` URL: code flow, PKCE S256, our audience and scopes, `state`, and the trial hint when this machine has one. */
|
|
84
|
+
export function authorizeUrl(auth, p) {
|
|
85
|
+
const u = new URL(`${auth.issuer}/authorize`);
|
|
86
|
+
u.searchParams.set("response_type", "code");
|
|
87
|
+
u.searchParams.set("client_id", auth.clientId);
|
|
88
|
+
u.searchParams.set("redirect_uri", p.redirectUri);
|
|
89
|
+
u.searchParams.set("scope", SCOPE);
|
|
90
|
+
u.searchParams.set("audience", auth.audience);
|
|
91
|
+
u.searchParams.set("code_challenge", p.challenge);
|
|
92
|
+
u.searchParams.set("code_challenge_method", "S256");
|
|
93
|
+
u.searchParams.set("state", p.state);
|
|
94
|
+
if (p.accountId)
|
|
95
|
+
u.searchParams.set(ACCOUNT_PARAM, p.accountId);
|
|
96
|
+
return u.href;
|
|
97
|
+
}
|
|
98
|
+
const HTML_ESCAPES = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
|
|
99
|
+
const escapeHtml = (s) => s.replace(/[&<>"']/g, (c) => HTML_ESCAPES[c]);
|
|
100
|
+
const page = (title, body) => `<!doctype html><meta charset="utf-8"><title>${escapeHtml(title)}</title><body style="font:16px system-ui;margin:3rem auto;max-width:32rem"><h1>${escapeHtml(title)}</h1><p>${escapeHtml(body)}</p></body>`;
|
|
101
|
+
/** Bind 127.0.0.1 on the first free port of the list (0 = any, tests only). All busy → SignInError. */
|
|
102
|
+
async function listenOnOneOf(ports, handler) {
|
|
103
|
+
for (const port of ports) {
|
|
104
|
+
const server = createServer(handler);
|
|
105
|
+
const bound = await new Promise((resolve, reject) => {
|
|
106
|
+
server.once("error", (err) => (err.code === "EADDRINUSE" || err.code === "EACCES" ? resolve(undefined) : reject(err)));
|
|
107
|
+
server.listen(port, "127.0.0.1", () => resolve(server.address().port));
|
|
108
|
+
});
|
|
109
|
+
if (bound !== undefined)
|
|
110
|
+
return { server, port: bound };
|
|
111
|
+
}
|
|
112
|
+
throw new SignInError(`Sign-in could not start: ports ${ports.join(", ")} on 127.0.0.1 are in use.`);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The one callback: `run` gets the redirect URI once the listener is up (and
|
|
116
|
+
* opens the browser); the promise is the authorization code, or the
|
|
117
|
+
* user-facing SignInError. The browser tab gets a page either way; the
|
|
118
|
+
* listener closes as soon as the outcome is known or the deadline passes.
|
|
119
|
+
*/
|
|
120
|
+
async function awaitCallback(ports, state, timeoutMs, run) {
|
|
121
|
+
let settle;
|
|
122
|
+
const result = new Promise((resolve, reject) => {
|
|
123
|
+
settle = { resolve, reject };
|
|
124
|
+
});
|
|
125
|
+
// `connection: close`: the browser's socket ends with the page, so closing the server below never waits on keep-alive
|
|
126
|
+
const html = { "content-type": "text/html; charset=utf-8", connection: "close" };
|
|
127
|
+
const { server, port } = await listenOnOneOf(ports, (req, res) => {
|
|
128
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
129
|
+
if (url.pathname !== CALLBACK_PATH) {
|
|
130
|
+
res.writeHead(404, { "content-type": "text/plain", connection: "close" }).end("not found");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (!settle) {
|
|
134
|
+
res.writeHead(410, html).end(page("Nola", "This sign-in already finished. Return to the terminal."));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const { resolve, reject } = settle;
|
|
138
|
+
settle = undefined;
|
|
139
|
+
const q = url.searchParams;
|
|
140
|
+
if (q.get("state") !== state) {
|
|
141
|
+
res.writeHead(400, html).end(page("Sign-in failed", "The browser returned an unexpected state. Return to the terminal and run the command again."));
|
|
142
|
+
reject(new SignInError("Sign-in failed: the browser returned an unexpected state."));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const error = q.get("error");
|
|
146
|
+
if (error) {
|
|
147
|
+
const reason = error === "access_denied" ? "Sign-in was declined in the browser." : `Sign-in failed: ${q.get("error_description") ?? error}`;
|
|
148
|
+
res.writeHead(200, html).end(page("Sign-in failed", `${reason} Return to the terminal.`));
|
|
149
|
+
reject(new SignInError(reason));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const code = q.get("code");
|
|
153
|
+
if (!code) {
|
|
154
|
+
res.writeHead(400, html).end(page("Sign-in failed", "The browser returned no code. Return to the terminal and run the command again."));
|
|
155
|
+
reject(new SignInError("Sign-in failed: the browser returned no authorization code."));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
res.writeHead(200, html).end(page("Signed in to Nola", "You can close this tab and return to the terminal."));
|
|
159
|
+
resolve(code);
|
|
160
|
+
});
|
|
161
|
+
const timer = setTimeout(() => {
|
|
162
|
+
settle?.reject(new SignInError("Sign-in timed out — the browser did not come back within 5 minutes. Run the command again."));
|
|
163
|
+
settle = undefined;
|
|
164
|
+
}, timeoutMs);
|
|
165
|
+
try {
|
|
166
|
+
run(`http://127.0.0.1:${port}${CALLBACK_PATH}`);
|
|
167
|
+
return await result;
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
clearTimeout(timer);
|
|
171
|
+
// stop accepting; drop idle keep-alive sockets (a browser's speculative second connection) but let the page finish sending
|
|
172
|
+
const closed = new Promise((r) => server.close(() => r()));
|
|
173
|
+
server.closeIdleConnections();
|
|
174
|
+
await closed;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** A JWT's payload, decoded and NOT verified — display and sanity checks only; the API is the verifier. */
|
|
178
|
+
function claimsOf(token) {
|
|
179
|
+
const payload = token?.split(".")[1];
|
|
180
|
+
if (!payload)
|
|
181
|
+
return null;
|
|
182
|
+
try {
|
|
183
|
+
const parsed = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
184
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** The `email` claim of an id token's payload — display only, never verified. */
|
|
191
|
+
export function emailFromIdToken(idToken) {
|
|
192
|
+
return str(claimsOf(idToken)?.email) ?? null;
|
|
193
|
+
}
|
|
194
|
+
/** The `nola:account_id` claim of an access token, or null when the tenant's Action did not set one. */
|
|
195
|
+
export function accountIdOfToken(accessToken) {
|
|
196
|
+
return str(claimsOf(accessToken)?.[ACCOUNT_CLAIM]) ?? null;
|
|
197
|
+
}
|
|
198
|
+
/** A refresh; Auth0's rotating refresh tokens return a replacement, which callers store. */
|
|
199
|
+
export async function refreshTokens(auth, refreshToken, init = {}) {
|
|
200
|
+
const { ok, status, body } = await postForm(init, `${auth.issuer}/oauth/token`, {
|
|
201
|
+
grant_type: "refresh_token",
|
|
202
|
+
client_id: auth.clientId,
|
|
203
|
+
refresh_token: refreshToken,
|
|
204
|
+
});
|
|
205
|
+
if (!ok) {
|
|
206
|
+
const err = new SignInError(`Your Nola session could not be refreshed (${status}): ${describe(body, "refresh failed")}`);
|
|
207
|
+
err.status = status;
|
|
208
|
+
throw err;
|
|
209
|
+
}
|
|
210
|
+
return tokenSetOf(body);
|
|
211
|
+
}
|
|
212
|
+
/** Best effort: tell the tenant the refresh token is dead. Never throws. */
|
|
213
|
+
export async function revokeToken(auth, refreshToken, init = {}) {
|
|
214
|
+
const doFetch = init.fetch ?? globalThis.fetch;
|
|
215
|
+
try {
|
|
216
|
+
await doFetch(`${auth.issuer}/oauth/revoke`, {
|
|
217
|
+
method: "POST",
|
|
218
|
+
headers: { "content-type": "application/json" },
|
|
219
|
+
body: JSON.stringify({ client_id: auth.clientId, token: refreshToken }),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// the local session is deleted regardless
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function resolve(opts) {
|
|
227
|
+
const apiUrl = (opts.apiUrl ?? opts.baseUrl ?? nolaApiUrl()).replace(/\/$/, "");
|
|
228
|
+
return { apiUrl, client: { ...(opts.fetch ? { fetch: opts.fetch } : {}), baseUrl: apiUrl } };
|
|
229
|
+
}
|
|
230
|
+
/** The server's sign-in configuration (issuer, client, audience, at least one usable loopback port), or SignInUnavailableError. */
|
|
231
|
+
export async function authConfig(opts = {}) {
|
|
232
|
+
const { client } = resolve(opts);
|
|
233
|
+
const caps = await fetchCapabilities(client);
|
|
234
|
+
const auth = caps.auth;
|
|
235
|
+
const ports = Array.isArray(auth?.redirectPorts) ? auth.redirectPorts.filter((p) => Number.isInteger(p) && p >= 0 && p <= 65535) : [];
|
|
236
|
+
if (!auth || !str(auth.issuer) || !str(auth.clientId) || !str(auth.audience) || ports.length === 0)
|
|
237
|
+
throw new SignInUnavailableError();
|
|
238
|
+
return {
|
|
239
|
+
auth: { issuer: auth.issuer.replace(/\/$/, ""), clientId: auth.clientId, audience: auth.audience, redirectPorts: ports },
|
|
240
|
+
...(caps.consoleUrl ? { consoleUrl: caps.consoleUrl } : {}),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
function sessionOf(tokens, previous) {
|
|
244
|
+
const refreshToken = tokens.refreshToken ?? previous?.refreshToken;
|
|
245
|
+
if (!refreshToken)
|
|
246
|
+
throw new SignInError("Sign-in did not complete: the provider returned no refresh token (offline_access is required).");
|
|
247
|
+
return {
|
|
248
|
+
accessToken: tokens.accessToken,
|
|
249
|
+
refreshToken,
|
|
250
|
+
expiresAt: new Date(Date.now() + tokens.expiresIn * 1000).toISOString(),
|
|
251
|
+
email: emailFromIdToken(tokens.idToken) ?? previous?.email ?? null,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/** The whole PKCE flow: discover, listen, open /authorize, take the callback, exchange, store. Returns the new session. */
|
|
255
|
+
export async function signIn(opts) {
|
|
256
|
+
const { apiUrl, client } = resolve(opts);
|
|
257
|
+
const { auth } = await authConfig(opts);
|
|
258
|
+
const { verifier, challenge } = pkcePair();
|
|
259
|
+
const state = randomBytes(16).toString("base64url");
|
|
260
|
+
const accountId = (await readHomeConfig(opts.home))?.accounts[apiUrl]?.accountId;
|
|
261
|
+
let redirectUri = "";
|
|
262
|
+
const code = await awaitCallback(auth.redirectPorts ?? [], state, opts.timeoutMs ?? SIGN_IN_TIMEOUT_MS, (uri) => {
|
|
263
|
+
redirectUri = uri;
|
|
264
|
+
const url = authorizeUrl(auth, { redirectUri, challenge, state, ...(accountId ? { accountId } : {}) });
|
|
265
|
+
opts.note(`Sign in to Nola: open ${url}`);
|
|
266
|
+
(opts.open ?? openBrowser)(url);
|
|
267
|
+
opts.note("Waiting for the browser…");
|
|
268
|
+
});
|
|
269
|
+
const { ok, status, body } = await postForm(client, `${auth.issuer}/oauth/token`, {
|
|
270
|
+
grant_type: "authorization_code",
|
|
271
|
+
client_id: auth.clientId,
|
|
272
|
+
code,
|
|
273
|
+
code_verifier: verifier,
|
|
274
|
+
redirect_uri: redirectUri,
|
|
275
|
+
});
|
|
276
|
+
if (!ok)
|
|
277
|
+
throw new SignInError(`Sign-in failed (${status}): ${describe(body, "token request failed")}`);
|
|
278
|
+
const session = sessionOf(tokenSetOf(body));
|
|
279
|
+
// account-claim-required: the tenant's Action provisions the account at login and names it in the token; a token without it is useless to the API
|
|
280
|
+
if (!accountIdOfToken(session.accessToken)) {
|
|
281
|
+
throw new SignInError("Sign-in did not return your Nola account — the server's sign-in provider is misconfigured. Nothing was stored.");
|
|
282
|
+
}
|
|
283
|
+
if ((await writeSession(opts.home, apiUrl, session)) === "skipped") {
|
|
284
|
+
opts.note("Could not store the session in ~/.nola/credentials.json — you will be asked to sign in again next time.");
|
|
285
|
+
}
|
|
286
|
+
opts.note(session.email ? `Signed in as ${session.email}.` : "Signed in.");
|
|
287
|
+
return session;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* A usable access token for the API URL, refreshing (and re-storing) when
|
|
291
|
+
* the stored one is within a minute of expiry. undefined = not signed in. A
|
|
292
|
+
* refresh the tenant refuses deletes the session (the user signs in again);
|
|
293
|
+
* a network failure during refresh throws so callers can say so.
|
|
294
|
+
*/
|
|
295
|
+
export async function accessTokenFor(opts = {}) {
|
|
296
|
+
const { apiUrl, client } = resolve(opts);
|
|
297
|
+
const session = await readSession(opts.home, apiUrl);
|
|
298
|
+
if (!session)
|
|
299
|
+
return undefined;
|
|
300
|
+
if (Date.parse(session.expiresAt) - Date.now() > REFRESH_MARGIN_MS)
|
|
301
|
+
return { token: session.accessToken, session };
|
|
302
|
+
const { auth } = await authConfig(opts);
|
|
303
|
+
let tokens;
|
|
304
|
+
try {
|
|
305
|
+
tokens = await refreshTokens(auth, session.refreshToken, client);
|
|
306
|
+
}
|
|
307
|
+
catch (err) {
|
|
308
|
+
if (err instanceof SignInError && typeof err.status === "number") {
|
|
309
|
+
await deleteSession(opts.home, apiUrl);
|
|
310
|
+
return undefined;
|
|
311
|
+
}
|
|
312
|
+
throw err;
|
|
313
|
+
}
|
|
314
|
+
const next = sessionOf(tokens, session);
|
|
315
|
+
await writeSession(opts.home, apiUrl, next);
|
|
316
|
+
return { token: next.accessToken, session: next };
|
|
317
|
+
}
|
|
318
|
+
/** Revoke best-effort and forget the session. */
|
|
319
|
+
export async function signOut(opts = {}) {
|
|
320
|
+
const { apiUrl, client } = resolve(opts);
|
|
321
|
+
const session = await readSession(opts.home, apiUrl);
|
|
322
|
+
if (!session)
|
|
323
|
+
return "not-signed-in";
|
|
324
|
+
try {
|
|
325
|
+
const { auth } = await authConfig(opts);
|
|
326
|
+
await revokeToken(auth, session.refreshToken, client);
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
// unreachable tenant or a server without auth: the local session still goes
|
|
330
|
+
}
|
|
331
|
+
await deleteSession(opts.home, apiUrl);
|
|
332
|
+
return "signed-out";
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The nola-monorepo root when this module runs from inside the dev checkout
|
|
3
|
+
* (both src/ and dist/ sit two levels below the root's packages/ dir), else
|
|
4
|
+
* null. A published copy lives under node_modules and never matches.
|
|
5
|
+
*/
|
|
6
|
+
export declare function checkoutRoot(): Promise<string | null>;
|
|
7
|
+
/**
|
|
8
|
+
* Dev-only switch: the absolute path of a nola-monorepo checkout. When set,
|
|
9
|
+
* the init flow relinks a freshly installed scaffold to that checkout's
|
|
10
|
+
* packages/ (see linkCheckoutPackages). An env var rather than detection so
|
|
11
|
+
* a CLI installed outside the monorepo can be pointed at it while testing.
|
|
12
|
+
*/
|
|
13
|
+
export declare const LINK_CHECKOUT_ENV = "NOLA_LINK_CHECKOUT";
|
|
14
|
+
/** The checkout root NOLA_LINK_CHECKOUT names, or null when unset/blank. */
|
|
15
|
+
export declare function linkCheckoutFromEnv(env?: NodeJS.ProcessEnv): string | null;
|
|
16
|
+
export declare const CHECKOUT_LINKED_PACKAGES: readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* Dev mode only: replace the scaffold's registry copies of the Nola packages
|
|
19
|
+
* with junctions into the checkout's packages/, so a `nola init` run from a
|
|
20
|
+
* linked CLI tests the workspace build instead of the last npm release.
|
|
21
|
+
* Returns the linked package names.
|
|
22
|
+
*/
|
|
23
|
+
export declare function linkCheckoutPackages(dir: string, root: string): Promise<string[]>;
|
|
24
|
+
//# sourceMappingURL=checkout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAU3D;AAaD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,uBAAuB,CAAC;AAEtD,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,GAAG,IAAI,CAGvF;AAED,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAAgC,CAAC;AAEvF;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYvF"}
|
package/dist/checkout.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, readFile, rm, symlink } from "node:fs/promises";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
/**
|
|
6
|
+
* The nola-monorepo root when this module runs from inside the dev checkout
|
|
7
|
+
* (both src/ and dist/ sit two levels below the root's packages/ dir), else
|
|
8
|
+
* null. A published copy lives under node_modules and never matches.
|
|
9
|
+
*/
|
|
10
|
+
export async function checkoutRoot() {
|
|
11
|
+
const repoRoot = fileURLToPath(new URL("../../..", import.meta.url));
|
|
12
|
+
const rootManifest = join(repoRoot, "package.json");
|
|
13
|
+
if (!existsSync(rootManifest))
|
|
14
|
+
return null;
|
|
15
|
+
try {
|
|
16
|
+
const pkg = JSON.parse(await readFile(rootManifest, "utf8"));
|
|
17
|
+
return pkg.name === "nola-monorepo" ? repoRoot : null;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The packages a scaffold depends on directly, as package name → workspace
|
|
25
|
+
* dir. Their internal deps resolve through the junction's real path into the
|
|
26
|
+
* checkout's hoisted node_modules, so nothing else needs linking.
|
|
27
|
+
*/
|
|
28
|
+
const LINKS = [
|
|
29
|
+
["@nola-lang/runtime", "runtime"],
|
|
30
|
+
["@nola-lang/providers", "providers"],
|
|
31
|
+
["nola-lang", "nola-lang"],
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Dev-only switch: the absolute path of a nola-monorepo checkout. When set,
|
|
35
|
+
* the init flow relinks a freshly installed scaffold to that checkout's
|
|
36
|
+
* packages/ (see linkCheckoutPackages). An env var rather than detection so
|
|
37
|
+
* a CLI installed outside the monorepo can be pointed at it while testing.
|
|
38
|
+
*/
|
|
39
|
+
export const LINK_CHECKOUT_ENV = "NOLA_LINK_CHECKOUT";
|
|
40
|
+
/** The checkout root NOLA_LINK_CHECKOUT names, or null when unset/blank. */
|
|
41
|
+
export function linkCheckoutFromEnv(env = process.env) {
|
|
42
|
+
const value = env[LINK_CHECKOUT_ENV]?.trim();
|
|
43
|
+
return value ? value : null;
|
|
44
|
+
}
|
|
45
|
+
export const CHECKOUT_LINKED_PACKAGES = LINKS.map(([name]) => name);
|
|
46
|
+
/**
|
|
47
|
+
* Dev mode only: replace the scaffold's registry copies of the Nola packages
|
|
48
|
+
* with junctions into the checkout's packages/, so a `nola init` run from a
|
|
49
|
+
* linked CLI tests the workspace build instead of the last npm release.
|
|
50
|
+
* Returns the linked package names.
|
|
51
|
+
*/
|
|
52
|
+
export async function linkCheckoutPackages(dir, root) {
|
|
53
|
+
const linked = [];
|
|
54
|
+
for (const [name, pkg] of LINKS) {
|
|
55
|
+
const target = join(root, "packages", pkg);
|
|
56
|
+
const link = join(dir, "node_modules", name);
|
|
57
|
+
await mkdir(dirname(link), { recursive: true });
|
|
58
|
+
// rm lstat's its path: an existing junction is unlinked, never descended.
|
|
59
|
+
await rm(link, { recursive: true, force: true });
|
|
60
|
+
await symlink(target, link, "junction");
|
|
61
|
+
linked.push(name);
|
|
62
|
+
}
|
|
63
|
+
return linked;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=checkout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout.js","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAsB,CAAC;QAClF,OAAO,GAAG,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,KAAK,GAAwD;IACjE,CAAC,oBAAoB,EAAE,SAAS,CAAC;IACjC,CAAC,sBAAsB,EAAE,WAAW,CAAC;IACrC,CAAC,WAAW,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAEtD,4EAA4E;AAC5E,MAAM,UAAU,mBAAmB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACtE,MAAM,KAAK,GAAG,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC;IAC7C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAsB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAW,EAAE,IAAY;IAClE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,0EAA0E;QAC1E,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,MAAM,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|