@getstackrun/sdk 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -8
- package/dist/agent-auth.d.ts +11 -0
- package/dist/agent-auth.d.ts.map +1 -0
- package/dist/agent-auth.js +303 -0
- package/dist/agent-auth.js.map +1 -0
- package/dist/browser-bootstrap.d.ts +18 -0
- package/dist/browser-bootstrap.d.ts.map +1 -0
- package/dist/browser-bootstrap.js +237 -0
- package/dist/browser-bootstrap.js.map +1 -0
- package/dist/client.d.ts +42 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +125 -5
- package/dist/client.js.map +1 -1
- package/dist/credentials-file.d.ts +12 -0
- package/dist/credentials-file.d.ts.map +1 -0
- package/dist/credentials-file.js +37 -0
- package/dist/credentials-file.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,16 +16,30 @@ Requires Node.js 18 or newer. Works in Deno, Bun, and browsers via native `fetch
|
|
|
16
16
|
|
|
17
17
|
## Quick start
|
|
18
18
|
|
|
19
|
+
Sign in once on your machine — the SDK reads credentials from `~/.stack/credentials.json` automatically:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx -y @getstackrun/cli auth login
|
|
23
|
+
```
|
|
24
|
+
|
|
19
25
|
```ts
|
|
20
26
|
import { Stack } from '@getstackrun/sdk';
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
// No constructor args — reads ~/.stack/credentials.json (OAuth refresh token).
|
|
29
|
+
// Falls back to STACK_API_KEY env var or constructor { apiKey } for CI.
|
|
30
|
+
const stack = new Stack();
|
|
23
31
|
|
|
24
|
-
// 1. Register an agent
|
|
32
|
+
// 1. Register an agent (one-time)
|
|
25
33
|
const agent = await stack.agents.register({ name: 'support-bot' });
|
|
26
34
|
|
|
27
|
-
// 2.
|
|
28
|
-
const
|
|
35
|
+
// 2. In your agent runtime, switch to per-agent keypair mode
|
|
36
|
+
const agentStack = new Stack({ agent_id: agent.id });
|
|
37
|
+
// First run: generates an Ed25519 keypair locally + enrolls the public
|
|
38
|
+
// half via /v1/agents/<id>/enroll. Persisted at ~/.stack/agents/<id>.json
|
|
39
|
+
// (mode 0600). Every subsequent call signs a fresh 60-second JWT.
|
|
40
|
+
|
|
41
|
+
// 3. Issue a short-lived scoped passport
|
|
42
|
+
const passport = await agentStack.passports.issue({
|
|
29
43
|
agent_id: agent.id,
|
|
30
44
|
intent: {
|
|
31
45
|
summary: 'Answer one customer ticket',
|
|
@@ -35,8 +49,8 @@ const passport = await stack.passports.issue({
|
|
|
35
49
|
ttl_seconds: 900,
|
|
36
50
|
});
|
|
37
51
|
|
|
38
|
-
//
|
|
39
|
-
await
|
|
52
|
+
// 4. Every outbound call routes through the proxy
|
|
53
|
+
await agentStack.proxy.request({
|
|
40
54
|
service: 'slack',
|
|
41
55
|
method: 'POST',
|
|
42
56
|
url: 'https://slack.com/api/chat.postMessage',
|
|
@@ -44,10 +58,20 @@ await stack.proxy.request({
|
|
|
44
58
|
passport_token: passport.token,
|
|
45
59
|
});
|
|
46
60
|
|
|
47
|
-
//
|
|
48
|
-
await
|
|
61
|
+
// 5. Revoke when done (or let the passport expire)
|
|
62
|
+
await agentStack.passports.revoke(passport.jti, 'mission complete');
|
|
49
63
|
```
|
|
50
64
|
|
|
65
|
+
## Authentication
|
|
66
|
+
|
|
67
|
+
Three sources, resolved in priority order:
|
|
68
|
+
|
|
69
|
+
1. **Explicit `apiKey`** on the constructor or `STACK_API_KEY` env var (legacy `sk_live_*` path, preserved for CI)
|
|
70
|
+
2. **`agent_id`** option (Phase 2) — every request signed with the agent's local keypair
|
|
71
|
+
3. **`~/.stack/credentials.json`** — OAuth refresh token written by `stack-cli auth login`
|
|
72
|
+
|
|
73
|
+
See [/docs/security/stack-auth](https://getstack.run/docs/security/stack-auth) for the full auth model and [/docs/security/agent-keys](https://getstack.run/docs/security/agent-keys) for the per-agent keypair story.
|
|
74
|
+
|
|
51
75
|
## Offline passport verification
|
|
52
76
|
|
|
53
77
|
Downstream services that only need cryptographic validity (no revocation awareness) can verify a passport using the public JWKS — no network round-trip to STACK per request.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token provider for the HttpClient. Returns a fresh agent JWT per call.
|
|
3
|
+
* On first run (no stored key), runs the enrollment flow using the
|
|
4
|
+
* supplied bearerProvider for OAuth fallback authentication.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createAgentTokenProvider(args: {
|
|
7
|
+
agentId: string;
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
bearerProvider: () => Promise<string>;
|
|
10
|
+
}): () => Promise<string>;
|
|
11
|
+
//# sourceMappingURL=agent-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-auth.d.ts","sourceRoot":"","sources":["../src/agent-auth.ts"],"names":[],"mappings":"AAyTA;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACvC,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAWxB"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// Phase 2 — agent-keypair runtime auth.
|
|
2
|
+
//
|
|
3
|
+
// When `new Stack({ agent_id })` is constructed, the SDK enters
|
|
4
|
+
// agent-runtime mode: every API call is signed with a fresh 60-second
|
|
5
|
+
// EdDSA JWT minted on demand from the agent's local privkey.
|
|
6
|
+
//
|
|
7
|
+
// First run flow:
|
|
8
|
+
// 1. Try to read ~/.stack/agents/<agent_id>.json (privkey JWK).
|
|
9
|
+
// 2. If missing, kick off the enrollment dance using the developer's
|
|
10
|
+
// OAuth credentials (the ones written by `stack-cli auth login`):
|
|
11
|
+
// a. POST /v1/agents/<id>/enrollment-challenge
|
|
12
|
+
// b. Generate Ed25519 keypair locally
|
|
13
|
+
// c. Sign the challenge bytes with the new privkey
|
|
14
|
+
// d. POST /v1/agents/<id>/enroll with the public_key JWK +
|
|
15
|
+
// signed_challenge
|
|
16
|
+
// Persist the privkey to disk (mode 0600) and proceed.
|
|
17
|
+
//
|
|
18
|
+
// Subsequent runs hit step 1 only — no enrollment, no browser, no
|
|
19
|
+
// developer interaction.
|
|
20
|
+
//
|
|
21
|
+
// Threat model: the privkey lives on disk just like an OAuth refresh
|
|
22
|
+
// token. Phase 3 (passkey-rooted) closes the laptop-decryption gap.
|
|
23
|
+
// Until then, file-on-disk + chmod 600 is the same posture as `aws cli`.
|
|
24
|
+
import { generateKeyPair, exportJWK, importJWK, SignJWT } from 'jose';
|
|
25
|
+
import { sign as cryptoSign, randomBytes } from 'node:crypto';
|
|
26
|
+
import { shouldRunBrowserBootstrap } from './browser-bootstrap.js';
|
|
27
|
+
const AGENT_KEY_DIR = '.stack/agents';
|
|
28
|
+
const AGENT_JWT_TTL = 60;
|
|
29
|
+
const AGENT_JWT_AUDIENCE = 'stack:agent';
|
|
30
|
+
const AGENT_JWT_ISSUER = 'stack-sdk';
|
|
31
|
+
/**
|
|
32
|
+
* Dashboard origin to which the SDK opens the browser for the
|
|
33
|
+
* approval screen. Mirrors the operator-visible website. Override via
|
|
34
|
+
* STACK_DASHBOARD_URL for self-hosted or test environments.
|
|
35
|
+
*/
|
|
36
|
+
function dashboardUrl(apiBaseUrl) {
|
|
37
|
+
if (process.env['STACK_DASHBOARD_URL'])
|
|
38
|
+
return process.env['STACK_DASHBOARD_URL'];
|
|
39
|
+
// Dev shortcut: api on localhost ⇒ dashboard on :3100.
|
|
40
|
+
if (/^https?:\/\/(127\.0\.0\.1|localhost)/.test(apiBaseUrl)) {
|
|
41
|
+
return 'http://localhost:3100';
|
|
42
|
+
}
|
|
43
|
+
return 'https://getstack.run';
|
|
44
|
+
}
|
|
45
|
+
const ENROLLMENT_AUTH_TIMEOUT_MS = 5 * 60 * 1000; // matches ticket TTL
|
|
46
|
+
async function keyPath(agentId) {
|
|
47
|
+
const { homedir } = await import('node:os');
|
|
48
|
+
const { join } = await import('node:path');
|
|
49
|
+
return join(homedir(), AGENT_KEY_DIR, `${agentId}.json`);
|
|
50
|
+
}
|
|
51
|
+
async function readStoredKey(agentId) {
|
|
52
|
+
try {
|
|
53
|
+
const { readFile } = await import('node:fs/promises');
|
|
54
|
+
const path = await keyPath(agentId);
|
|
55
|
+
const raw = await readFile(path, 'utf8');
|
|
56
|
+
return JSON.parse(raw);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function writeStoredKey(key) {
|
|
63
|
+
const { writeFile, mkdir, chmod } = await import('node:fs/promises');
|
|
64
|
+
const { join, dirname } = await import('node:path');
|
|
65
|
+
const { homedir } = await import('node:os');
|
|
66
|
+
const path = join(homedir(), AGENT_KEY_DIR, `${key.agent_id}.json`);
|
|
67
|
+
await mkdir(dirname(path), { recursive: true });
|
|
68
|
+
await writeFile(path, JSON.stringify(key, null, 2), 'utf8');
|
|
69
|
+
try {
|
|
70
|
+
await chmod(path, 0o600);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
/* Windows / unsupported FS */
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Spawn a one-shot loopback HTTP server on a random free port, open
|
|
78
|
+
* the dashboard /sdk-bootstrap page in the user's browser, and resolve
|
|
79
|
+
* with the enrollment ticket once the user approves (or reject on
|
|
80
|
+
* deny / timeout). Used as the interactive-mode bearer provider in
|
|
81
|
+
* place of the silent OAuth path.
|
|
82
|
+
*
|
|
83
|
+
* The ticket itself is a JWT bound to (operator, member, agent_id,
|
|
84
|
+
* machine_label). Single-use: burned by the API on /enroll success.
|
|
85
|
+
*/
|
|
86
|
+
async function ticketViaBrowserApproval(args) {
|
|
87
|
+
const { createServer } = await import('node:http');
|
|
88
|
+
const { hostname } = await import('node:os');
|
|
89
|
+
const open = (await import('node:child_process')).spawn;
|
|
90
|
+
const state = randomBytes(16).toString('base64url');
|
|
91
|
+
const machine = hostname().slice(0, 80);
|
|
92
|
+
const proc = `${process.argv0 ?? 'node'} ${process.argv[1]?.split(/[/\\]/).pop() ?? ''}`.slice(0, 80);
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
let settled = false;
|
|
95
|
+
const settle = (fn) => {
|
|
96
|
+
if (settled)
|
|
97
|
+
return;
|
|
98
|
+
settled = true;
|
|
99
|
+
try {
|
|
100
|
+
server.close();
|
|
101
|
+
}
|
|
102
|
+
catch { /* */ }
|
|
103
|
+
clearTimeout(timeout);
|
|
104
|
+
fn();
|
|
105
|
+
};
|
|
106
|
+
const server = createServer((req, res) => {
|
|
107
|
+
try {
|
|
108
|
+
const url = new URL(req.url ?? '/', 'http://127.0.0.1');
|
|
109
|
+
if (url.pathname !== '/cb') {
|
|
110
|
+
res.writeHead(404);
|
|
111
|
+
res.end();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const error = url.searchParams.get('error');
|
|
115
|
+
const ticket = url.searchParams.get('ticket');
|
|
116
|
+
const callbackState = url.searchParams.get('state');
|
|
117
|
+
if (callbackState !== state) {
|
|
118
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
119
|
+
res.end('<html><body style="font-family:system-ui;padding:40px"><h1>State mismatch</h1></body></html>');
|
|
120
|
+
settle(() => reject(new Error('enrollment callback state mismatch')));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (error) {
|
|
124
|
+
res.writeHead(403, { 'Content-Type': 'text/html' });
|
|
125
|
+
res.end('<html><body style="font-family:system-ui;padding:40px"><h1>Enrollment denied</h1><p>You can close this tab.</p></body></html>');
|
|
126
|
+
settle(() => reject(new Error(`enrollment ${error}`)));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (!ticket) {
|
|
130
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
131
|
+
res.end('<html><body style="font-family:system-ui;padding:40px"><h1>Missing ticket</h1></body></html>');
|
|
132
|
+
settle(() => reject(new Error('enrollment callback missing ticket')));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
136
|
+
res.end('<html><body style="font-family:system-ui;padding:40px;text-align:center"><h1>Approved</h1><p>You can close this tab and return to your terminal.</p></body></html>');
|
|
137
|
+
settle(() => resolve(ticket));
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
settle(() => reject(e instanceof Error ? e : new Error(String(e))));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
server.listen(0, '127.0.0.1', () => {
|
|
144
|
+
const addr = server.address();
|
|
145
|
+
const port = typeof addr === 'object' && addr ? addr.port : 0;
|
|
146
|
+
if (!port) {
|
|
147
|
+
settle(() => reject(new Error('failed to bind loopback port for enrollment callback')));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const callback = `http://127.0.0.1:${port}/cb`;
|
|
151
|
+
const dash = dashboardUrl(args.apiBaseUrl);
|
|
152
|
+
const url = `${dash}/sdk-bootstrap?` + new URLSearchParams({
|
|
153
|
+
agent_id: args.agentId,
|
|
154
|
+
callback,
|
|
155
|
+
state,
|
|
156
|
+
machine,
|
|
157
|
+
process: proc,
|
|
158
|
+
}).toString();
|
|
159
|
+
process.stderr.write('\n STACK SDK agent enrollment\n');
|
|
160
|
+
process.stderr.write(' ──────────────────────────\n\n');
|
|
161
|
+
process.stderr.write(` Approve in your browser: ${url}\n\n`);
|
|
162
|
+
try {
|
|
163
|
+
const opener = process.platform === 'win32'
|
|
164
|
+
? open('cmd', ['/c', 'start', '', url], { detached: true, stdio: 'ignore' })
|
|
165
|
+
: process.platform === 'darwin'
|
|
166
|
+
? open('open', [url], { detached: true, stdio: 'ignore' })
|
|
167
|
+
: open('xdg-open', [url], { detached: true, stdio: 'ignore' });
|
|
168
|
+
opener.unref?.();
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
/* best-effort */
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
const timeout = setTimeout(() => {
|
|
175
|
+
settle(() => reject(new Error('enrollment approval timed out (5 min). Re-run to try again.')));
|
|
176
|
+
}, ENROLLMENT_AUTH_TIMEOUT_MS);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Run the enrollment dance for `agentId`.
|
|
181
|
+
*
|
|
182
|
+
* Two paths converge on the same /enrollment-challenge + /enroll calls:
|
|
183
|
+
*
|
|
184
|
+
* - **Interactive (TTY + not CI):** open the dashboard /sdk-bootstrap
|
|
185
|
+
* page so the operator explicitly approves enrollment of THIS agent
|
|
186
|
+
* on THIS machine. The dashboard mints a single-use enrollment
|
|
187
|
+
* ticket which the SDK uses as the Bearer.
|
|
188
|
+
*
|
|
189
|
+
* - **Headless / CI:** fall through to the developer's OAuth bearer
|
|
190
|
+
* (or sk_live_* via STACK_API_KEY). No browser, no human-in-the-
|
|
191
|
+
* loop — convenience for CI runners. Same enrollment endpoints.
|
|
192
|
+
*
|
|
193
|
+
* Either way, the privkey is generated locally and never crosses the
|
|
194
|
+
* network. The ticket only authenticates the enrollment dance itself.
|
|
195
|
+
*/
|
|
196
|
+
async function enroll(args) {
|
|
197
|
+
let bearer;
|
|
198
|
+
if (shouldRunBrowserBootstrap()) {
|
|
199
|
+
try {
|
|
200
|
+
bearer = await ticketViaBrowserApproval({ agentId: args.agentId, apiBaseUrl: args.baseUrl });
|
|
201
|
+
}
|
|
202
|
+
catch (e) {
|
|
203
|
+
// Fall back to OAuth-bearer-silent mode — useful when the user
|
|
204
|
+
// explicitly approved but the localhost bind failed (firewall),
|
|
205
|
+
// or when the dashboard rejected because, say, the cookie
|
|
206
|
+
// session expired and they bailed out. Surface the original
|
|
207
|
+
// error so the user knows what happened.
|
|
208
|
+
throw new Error(`Browser approval for SDK agent enrollment failed (${e.message}). ` +
|
|
209
|
+
`Either fix the issue and re-run, or run in CI mode with STACK_API_KEY set ` +
|
|
210
|
+
`to use the silent enrollment path.`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
bearer = await args.bearerProvider();
|
|
215
|
+
}
|
|
216
|
+
// Step 1: request challenge.
|
|
217
|
+
const challengeRes = await fetch(`${args.baseUrl}/v1/agents/${args.agentId}/enrollment-challenge`, {
|
|
218
|
+
method: 'POST',
|
|
219
|
+
headers: {
|
|
220
|
+
Authorization: `Bearer ${bearer}`,
|
|
221
|
+
'Content-Type': 'application/json',
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
if (!challengeRes.ok) {
|
|
225
|
+
const errBody = await challengeRes.json().catch(() => ({}));
|
|
226
|
+
throw new Error(`enrollment-challenge failed: ${errBody.error?.message ?? challengeRes.statusText}`);
|
|
227
|
+
}
|
|
228
|
+
const { challenge_id, challenge } = (await challengeRes.json());
|
|
229
|
+
// Step 2: generate keypair locally.
|
|
230
|
+
const { publicKey, privateKey } = await generateKeyPair('EdDSA', { crv: 'Ed25519', extractable: true });
|
|
231
|
+
const publicJwk = await exportJWK(publicKey);
|
|
232
|
+
const privateJwk = await exportJWK(privateKey);
|
|
233
|
+
// Step 3: sign the challenge bytes with the privkey.
|
|
234
|
+
// Node's `sign(null, ...)` is the Ed25519 entry-point; matches what
|
|
235
|
+
// the API's `crypto.verify(null, ...)` consumes.
|
|
236
|
+
const { createPrivateKey } = await import('node:crypto');
|
|
237
|
+
const privateKeyObject = createPrivateKey({ key: privateJwk, format: 'jwk' });
|
|
238
|
+
const signatureBytes = cryptoSign(null, Buffer.from(challenge, 'utf8'), privateKeyObject);
|
|
239
|
+
const signed_challenge = signatureBytes.toString('base64url');
|
|
240
|
+
// Step 4: POST /enroll.
|
|
241
|
+
const enrollRes = await fetch(`${args.baseUrl}/v1/agents/${args.agentId}/enroll`, {
|
|
242
|
+
method: 'POST',
|
|
243
|
+
headers: {
|
|
244
|
+
Authorization: `Bearer ${bearer}`,
|
|
245
|
+
'Content-Type': 'application/json',
|
|
246
|
+
},
|
|
247
|
+
body: JSON.stringify({
|
|
248
|
+
public_key: { kty: publicJwk.kty, crv: publicJwk.crv, x: publicJwk.x },
|
|
249
|
+
challenge_id,
|
|
250
|
+
signed_challenge,
|
|
251
|
+
}),
|
|
252
|
+
});
|
|
253
|
+
if (!enrollRes.ok) {
|
|
254
|
+
const errBody = await enrollRes.json().catch(() => ({}));
|
|
255
|
+
throw new Error(`enroll failed: ${errBody.error?.message ?? enrollRes.statusText}`);
|
|
256
|
+
}
|
|
257
|
+
const { enrolled_at } = (await enrollRes.json());
|
|
258
|
+
const stored = {
|
|
259
|
+
agent_id: args.agentId,
|
|
260
|
+
publicKey: publicJwk,
|
|
261
|
+
privateKey: privateJwk,
|
|
262
|
+
enrolled_at: new Date(enrolled_at).getTime() / 1000,
|
|
263
|
+
};
|
|
264
|
+
await writeStoredKey(stored);
|
|
265
|
+
return stored;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Mint a fresh agent JWT (60s TTL) signed with the agent's privkey.
|
|
269
|
+
* One JWT per request — no caching. Cheap (≈1ms EdDSA sign) and the
|
|
270
|
+
* jti uniqueness ensures the API's replay-cache stays effective.
|
|
271
|
+
*/
|
|
272
|
+
async function signAgentJwt(stored, agentId) {
|
|
273
|
+
const key = await importJWK(stored.privateKey, 'EdDSA');
|
|
274
|
+
const now = Math.floor(Date.now() / 1000);
|
|
275
|
+
return new SignJWT({})
|
|
276
|
+
.setProtectedHeader({ alg: 'EdDSA' })
|
|
277
|
+
.setIssuer(AGENT_JWT_ISSUER)
|
|
278
|
+
.setSubject(agentId)
|
|
279
|
+
.setAudience(AGENT_JWT_AUDIENCE)
|
|
280
|
+
.setIssuedAt(now)
|
|
281
|
+
.setNotBefore(now)
|
|
282
|
+
.setExpirationTime(now + AGENT_JWT_TTL)
|
|
283
|
+
.setJti(`aj_${now}_${Math.random().toString(36).slice(2, 12)}`)
|
|
284
|
+
.sign(key);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Token provider for the HttpClient. Returns a fresh agent JWT per call.
|
|
288
|
+
* On first run (no stored key), runs the enrollment flow using the
|
|
289
|
+
* supplied bearerProvider for OAuth fallback authentication.
|
|
290
|
+
*/
|
|
291
|
+
export function createAgentTokenProvider(args) {
|
|
292
|
+
let cached = null;
|
|
293
|
+
return async () => {
|
|
294
|
+
if (!cached) {
|
|
295
|
+
cached = await readStoredKey(args.agentId);
|
|
296
|
+
}
|
|
297
|
+
if (!cached) {
|
|
298
|
+
cached = await enroll({ agentId: args.agentId, baseUrl: args.baseUrl, bearerProvider: args.bearerProvider });
|
|
299
|
+
}
|
|
300
|
+
return signAgentJwt(cached, args.agentId);
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=agent-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-auth.js","sourceRoot":"","sources":["../src/agent-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface BootstrapResult {
|
|
2
|
+
access_token: string;
|
|
3
|
+
expires_in: number;
|
|
4
|
+
refresh_token: string;
|
|
5
|
+
client_id: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Decide whether to spawn the browser. Conservative — opt-in by
|
|
9
|
+
* environment, not opt-out.
|
|
10
|
+
*/
|
|
11
|
+
export declare function shouldRunBrowserBootstrap(): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Run the full OAuth Authorization-Code + PKCE flow: DCR a client,
|
|
14
|
+
* mint a PKCE pair, spawn a localhost server, open the browser, wait
|
|
15
|
+
* for the callback, exchange the code for tokens, persist + return.
|
|
16
|
+
*/
|
|
17
|
+
export declare function browserBootstrap(baseUrl: string): Promise<BootstrapResult>;
|
|
18
|
+
//# sourceMappingURL=browser-bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-bootstrap.d.ts","sourceRoot":"","sources":["../src/browser-bootstrap.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAMnD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAkHhF"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// Phase 1 SDK first-run bootstrap (Authorization Code + PKCE with
|
|
2
|
+
// localhost callback).
|
|
3
|
+
//
|
|
4
|
+
// When `new Stack()` is instantiated and there's no apiKey, no
|
|
5
|
+
// STACK_API_KEY env, AND no ~/.stack/credentials.json — instead of
|
|
6
|
+
// throwing NOT_AUTHENTICATED, the SDK can spawn the user's browser
|
|
7
|
+
// and run the full OAuth dance itself. End state: credentials.json
|
|
8
|
+
// is written, the access token is returned, the SDK is usable.
|
|
9
|
+
//
|
|
10
|
+
// Triggered ONLY when:
|
|
11
|
+
// 1. The current process has a TTY (developer at a terminal); AND
|
|
12
|
+
// 2. STACK_AUTH_INTERACTIVE is not 'false' (explicit opt-out for
|
|
13
|
+
// headless dev environments that look like a TTY).
|
|
14
|
+
//
|
|
15
|
+
// In production agent runtimes (Lambda, Vercel, K8s, etc.) there's
|
|
16
|
+
// no TTY — the SDK falls through to the existing NOT_AUTHENTICATED
|
|
17
|
+
// error and the operator must set STACK_API_KEY (or use agent_id
|
|
18
|
+
// mode with credentials seeded another way). The browser-spawn path
|
|
19
|
+
// is strictly a developer convenience.
|
|
20
|
+
import { writeCredentialsFile, credentialsFilePath } from './credentials-file.js';
|
|
21
|
+
const DEFAULT_AUTH_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes — matches the auth-code TTL
|
|
22
|
+
/**
|
|
23
|
+
* Decide whether to spawn the browser. Conservative — opt-in by
|
|
24
|
+
* environment, not opt-out.
|
|
25
|
+
*/
|
|
26
|
+
export function shouldRunBrowserBootstrap() {
|
|
27
|
+
if (typeof process === 'undefined')
|
|
28
|
+
return false;
|
|
29
|
+
if (!process.stdout?.isTTY)
|
|
30
|
+
return false;
|
|
31
|
+
if (process.env['STACK_AUTH_INTERACTIVE'] === 'false')
|
|
32
|
+
return false;
|
|
33
|
+
if (process.env['CI'])
|
|
34
|
+
return false; // belt-and-braces — no spawn in CI
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Run the full OAuth Authorization-Code + PKCE flow: DCR a client,
|
|
39
|
+
* mint a PKCE pair, spawn a localhost server, open the browser, wait
|
|
40
|
+
* for the callback, exchange the code for tokens, persist + return.
|
|
41
|
+
*/
|
|
42
|
+
export async function browserBootstrap(baseUrl) {
|
|
43
|
+
const { createHash, randomBytes } = await import('node:crypto');
|
|
44
|
+
const url = baseUrl.replace(/\/$/, '');
|
|
45
|
+
// 1. DCR a public PKCE client. One per machine — keeps the per-client
|
|
46
|
+
// audit trail clean and avoids a shared client_id across the SDK
|
|
47
|
+
// user base.
|
|
48
|
+
const dcr = await fetch(`${url}/oauth/register`, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: { 'Content-Type': 'application/json' },
|
|
51
|
+
body: JSON.stringify({
|
|
52
|
+
client_name: hostFingerprint(),
|
|
53
|
+
redirect_uris: [`http://127.0.0.1`], // placeholder; the real one is added per-flow with the chosen port
|
|
54
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
55
|
+
software_id: 'getstackrun.sdk-ts.bootstrap',
|
|
56
|
+
}),
|
|
57
|
+
});
|
|
58
|
+
if (!dcr.ok) {
|
|
59
|
+
throw new Error(`STACK SDK: client registration failed (${dcr.status}). Try setting STACK_API_KEY or running \`stack-cli auth login\`.`);
|
|
60
|
+
}
|
|
61
|
+
const { client_id } = (await dcr.json());
|
|
62
|
+
// 2. PKCE pair.
|
|
63
|
+
const verifier = randomBytes(32).toString('base64url');
|
|
64
|
+
const challenge = createHash('sha256').update(verifier).digest('base64url');
|
|
65
|
+
const state = randomBytes(16).toString('base64url');
|
|
66
|
+
// 3. Spawn the localhost callback server FIRST (so we can claim the port
|
|
67
|
+
// before the browser opens), then open the browser to /oauth/authorize.
|
|
68
|
+
const { server, port, codePromise } = await spawnCallbackServer(state);
|
|
69
|
+
// 4. Re-register the client with the actual loopback URI now that we
|
|
70
|
+
// know the port. (DCR is open, the second register supersedes the
|
|
71
|
+
// first for redirect_uri matching.)
|
|
72
|
+
const reRegister = await fetch(`${url}/oauth/register`, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: { 'Content-Type': 'application/json' },
|
|
75
|
+
body: JSON.stringify({
|
|
76
|
+
client_name: hostFingerprint(),
|
|
77
|
+
redirect_uris: [`http://127.0.0.1:${port}/callback`],
|
|
78
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
79
|
+
software_id: 'getstackrun.sdk-ts.bootstrap',
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
82
|
+
if (!reRegister.ok) {
|
|
83
|
+
server.close();
|
|
84
|
+
throw new Error(`STACK SDK: client re-registration with loopback URI failed (${reRegister.status}).`);
|
|
85
|
+
}
|
|
86
|
+
const { client_id: scopedClientId } = (await reRegister.json());
|
|
87
|
+
const authorizeUrl = `${url}/oauth/authorize?` + new URLSearchParams({
|
|
88
|
+
response_type: 'code',
|
|
89
|
+
client_id: scopedClientId,
|
|
90
|
+
redirect_uri: `http://127.0.0.1:${port}/callback`,
|
|
91
|
+
scope: 'passports:read passports:write agents:read agents:write services:read services:connect credentials:read proxy:read proxy:write audit:read',
|
|
92
|
+
resource: 'https://api.getstack.run',
|
|
93
|
+
code_challenge: challenge,
|
|
94
|
+
code_challenge_method: 'S256',
|
|
95
|
+
state,
|
|
96
|
+
}).toString();
|
|
97
|
+
process.stderr.write(`\n STACK SDK first-run sign-in\n`);
|
|
98
|
+
process.stderr.write(` ──────────────────────────\n\n`);
|
|
99
|
+
process.stderr.write(` Opening your browser to approve.\n`);
|
|
100
|
+
process.stderr.write(` If it doesn't open, paste this URL:\n\n ${authorizeUrl}\n\n`);
|
|
101
|
+
await openBrowser(authorizeUrl);
|
|
102
|
+
// 5. Wait for the callback to deliver the code.
|
|
103
|
+
let code;
|
|
104
|
+
try {
|
|
105
|
+
code = await codePromise;
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
server.close();
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
server.close();
|
|
112
|
+
// 6. Exchange the code for tokens.
|
|
113
|
+
const tok = await fetch(`${url}/oauth/token`, {
|
|
114
|
+
method: 'POST',
|
|
115
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
116
|
+
body: new URLSearchParams({
|
|
117
|
+
grant_type: 'authorization_code',
|
|
118
|
+
code,
|
|
119
|
+
redirect_uri: `http://127.0.0.1:${port}/callback`,
|
|
120
|
+
client_id: scopedClientId,
|
|
121
|
+
code_verifier: verifier,
|
|
122
|
+
}),
|
|
123
|
+
});
|
|
124
|
+
if (!tok.ok) {
|
|
125
|
+
const data = await tok.json().catch(() => ({}));
|
|
126
|
+
throw new Error(`STACK SDK: token exchange failed (${tok.status}) ${JSON.stringify(data)}`);
|
|
127
|
+
}
|
|
128
|
+
const { access_token, refresh_token, expires_in } = (await tok.json());
|
|
129
|
+
// 7. Persist for subsequent runs. Same file the CLI writes.
|
|
130
|
+
const stored = {
|
|
131
|
+
client_id: scopedClientId,
|
|
132
|
+
refresh_token,
|
|
133
|
+
issued_at: Math.floor(Date.now() / 1000),
|
|
134
|
+
refresh_expires_at: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60,
|
|
135
|
+
scope: 'passports:read passports:write agents:read agents:write services:read services:connect credentials:read proxy:read proxy:write audit:read',
|
|
136
|
+
};
|
|
137
|
+
await writeCredentialsFile(stored);
|
|
138
|
+
process.stderr.write(` Signed in. Credentials saved to ${await credentialsFilePath()}\n\n`);
|
|
139
|
+
void client_id; // keep linter happy — initial DCR is superseded
|
|
140
|
+
return { access_token, refresh_token, expires_in, client_id: scopedClientId };
|
|
141
|
+
}
|
|
142
|
+
// ─── Helpers ──────────────────────────────────────────────────────────
|
|
143
|
+
function hostFingerprint() {
|
|
144
|
+
// Best-effort label so the operator can recognize the client in their
|
|
145
|
+
// dashboard (when we ship the per-client list view). Falls through to
|
|
146
|
+
// a generic name in environments where os.hostname is locked down.
|
|
147
|
+
try {
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
149
|
+
const os = require('node:os');
|
|
150
|
+
const host = os.hostname?.() ?? 'sdk-host';
|
|
151
|
+
return `STACK SDK on ${host.slice(0, 40)}`;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return 'STACK SDK';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function openBrowser(url) {
|
|
158
|
+
const { spawn } = await import('node:child_process');
|
|
159
|
+
try {
|
|
160
|
+
if (process.platform === 'darwin') {
|
|
161
|
+
spawn('open', [url], { stdio: 'ignore', detached: true }).unref();
|
|
162
|
+
}
|
|
163
|
+
else if (process.platform === 'win32') {
|
|
164
|
+
spawn('cmd', ['/c', 'start', '', url], { stdio: 'ignore', detached: true }).unref();
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
spawn('xdg-open', [url], { stdio: 'ignore', detached: true }).unref();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
/* best-effort — the URL is also printed */
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async function spawnCallbackServer(expectedState) {
|
|
175
|
+
const { createServer } = await import('node:http');
|
|
176
|
+
return new Promise((resolve, reject) => {
|
|
177
|
+
const server = createServer((req, res) => {
|
|
178
|
+
try {
|
|
179
|
+
const parsed = new URL(req.url ?? '/', 'http://127.0.0.1');
|
|
180
|
+
if (parsed.pathname !== '/callback') {
|
|
181
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
182
|
+
res.end('Not found');
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const code = parsed.searchParams.get('code');
|
|
186
|
+
const state = parsed.searchParams.get('state');
|
|
187
|
+
const error = parsed.searchParams.get('error');
|
|
188
|
+
if (error) {
|
|
189
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
190
|
+
res.end(`<html><body style="font-family:system-ui;padding:40px"><h1>Sign-in failed</h1><p>${escape(error)}</p><p>You can close this tab.</p></body></html>`);
|
|
191
|
+
rejectCb(new Error(`OAuth authorize returned error: ${error}`));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (!code || state !== expectedState) {
|
|
195
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
196
|
+
res.end(`<html><body style="font-family:system-ui;padding:40px"><h1>Invalid callback</h1><p>State mismatch or missing code.</p></body></html>`);
|
|
197
|
+
rejectCb(new Error('Invalid callback: state mismatch or missing code'));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
201
|
+
res.end(`<html><body style="font-family:system-ui;padding:40px;text-align:center"><h1>Signed in</h1><p>You can close this tab and return to your terminal.</p></body></html>`);
|
|
202
|
+
resolveCb(code);
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
206
|
+
res.end('Internal error');
|
|
207
|
+
rejectCb(err);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
let resolveCb;
|
|
211
|
+
let rejectCb;
|
|
212
|
+
const codePromise = new Promise((res, rej) => {
|
|
213
|
+
resolveCb = res;
|
|
214
|
+
rejectCb = rej;
|
|
215
|
+
});
|
|
216
|
+
// Bind to a random free port.
|
|
217
|
+
server.listen(0, '127.0.0.1', () => {
|
|
218
|
+
const addr = server.address();
|
|
219
|
+
if (typeof addr === 'object' && addr && typeof addr.port === 'number') {
|
|
220
|
+
// Auth-code + browser flow gets DEFAULT_AUTH_TIMEOUT_MS to complete.
|
|
221
|
+
const timer = setTimeout(() => {
|
|
222
|
+
rejectCb(new Error('Sign-in timed out (5 min). Re-run to try again.'));
|
|
223
|
+
}, DEFAULT_AUTH_TIMEOUT_MS);
|
|
224
|
+
codePromise.finally(() => clearTimeout(timer));
|
|
225
|
+
resolve({ server, port: addr.port, codePromise });
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
reject(new Error('Failed to bind localhost callback server'));
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
server.on('error', reject);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
function escape(s) {
|
|
235
|
+
return s.replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c] ?? c);
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=browser-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-bootstrap.js","sourceRoot":"","sources":["../src/browser-bootstrap.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
export interface ClientOptions {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Long-lived `sk_live_*` operator/member key. When omitted, the SDK
|
|
4
|
+
* falls back to (a) the `STACK_API_KEY` env var, (b) a refresh token
|
|
5
|
+
* stored at `~/.stack/credentials.json` (written by `stack-cli auth
|
|
6
|
+
* login`), exchanged on demand for a 5-minute access token.
|
|
7
|
+
*/
|
|
8
|
+
apiKey?: string;
|
|
3
9
|
baseUrl?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Phase 2 — agent-runtime mode. When set, every request is signed with
|
|
12
|
+
* a fresh 60-second EdDSA JWT minted from the agent's local privkey
|
|
13
|
+
* (~/.stack/agents/<agent_id>.json, mode 0600). On first run, the SDK
|
|
14
|
+
* generates the keypair locally and enrolls the public half via
|
|
15
|
+
* /v1/agents/:id/enroll using the developer's OAuth credentials —
|
|
16
|
+
* the privkey never crosses the network or terminal.
|
|
17
|
+
*/
|
|
18
|
+
agent_id?: string;
|
|
4
19
|
}
|
|
5
20
|
export declare class HttpClient {
|
|
6
|
-
private readonly
|
|
21
|
+
private readonly explicitApiKey;
|
|
7
22
|
private readonly baseUrl;
|
|
8
|
-
|
|
23
|
+
private cachedAccessToken;
|
|
24
|
+
private readonly agentTokenProvider;
|
|
25
|
+
constructor(options?: ClientOptions);
|
|
9
26
|
get<T>(path: string, query?: Record<string, string | undefined>): Promise<T>;
|
|
10
27
|
post<T>(path: string, body?: unknown, options?: {
|
|
11
28
|
headers?: Record<string, string>;
|
|
@@ -18,6 +35,28 @@ export declare class HttpClient {
|
|
|
18
35
|
}): Promise<T>;
|
|
19
36
|
delete<T>(path: string): Promise<T>;
|
|
20
37
|
private buildUrl;
|
|
38
|
+
/**
|
|
39
|
+
* Resolve the bearer token to attach to a request. Three sources, in
|
|
40
|
+
* priority order:
|
|
41
|
+
* 1. Explicit `apiKey` on the constructor or STACK_API_KEY env var
|
|
42
|
+
* (legacy `sk_live_*`, preserved for CI).
|
|
43
|
+
* 2. Cached OAuth access token (5-minute TTL; refresh-rotates).
|
|
44
|
+
* 3. Refresh token in `~/.stack/credentials.json` (written by the
|
|
45
|
+
* CLI's `auth login`) — exchanged for a fresh access token.
|
|
46
|
+
*
|
|
47
|
+
* Throws `StackError('NOT_AUTHENTICATED', ...)` when none of the
|
|
48
|
+
* three resolve.
|
|
49
|
+
*/
|
|
50
|
+
private resolveBearer;
|
|
51
|
+
/**
|
|
52
|
+
* Static-bearer resolution: explicit apiKey → STACK_API_KEY env →
|
|
53
|
+
* ~/.stack/credentials.json refresh-token exchange → first-run
|
|
54
|
+
* browser-spawn bootstrap (interactive only). Does NOT mint agent
|
|
55
|
+
* JWTs — that's `resolveBearer()`'s job. Exposed separately so the
|
|
56
|
+
* agent-token provider can use this same path for the one-time
|
|
57
|
+
* enrollment dance (which itself needs a static bearer to authenticate).
|
|
58
|
+
*/
|
|
59
|
+
private resolveStaticBearer;
|
|
21
60
|
private request;
|
|
22
61
|
}
|
|
23
62
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,iBAAiB,CAAqD;IAC9E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAiC;gBAExD,OAAO,GAAE,aAAkB;IAkBjC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAK5E,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAKjG,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAKlG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAKhG,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAKzC,OAAO,CAAC,QAAQ;IAUhB;;;;;;;;;;;OAWG;YACW,aAAa;IAU3B;;;;;;;OAOG;YACW,mBAAmB;YAgCnB,OAAO;CAkCtB"}
|
package/dist/client.js
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
import { StackError } from './errors.js';
|
|
2
|
+
import { createAgentTokenProvider } from './agent-auth.js';
|
|
3
|
+
import { readCredentialsFile, writeCredentialsFile } from './credentials-file.js';
|
|
4
|
+
import { browserBootstrap, shouldRunBrowserBootstrap } from './browser-bootstrap.js';
|
|
2
5
|
export class HttpClient {
|
|
3
|
-
|
|
6
|
+
explicitApiKey;
|
|
4
7
|
baseUrl;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
cachedAccessToken = null;
|
|
9
|
+
agentTokenProvider;
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.explicitApiKey = options.apiKey ?? process.env['STACK_API_KEY'] ?? undefined;
|
|
12
|
+
this.baseUrl = (options.baseUrl ?? process.env['STACK_API_URL'] ?? 'https://api.getstack.run').replace(/\/$/, '');
|
|
13
|
+
this.agentTokenProvider = options.agent_id
|
|
14
|
+
? createAgentTokenProvider({
|
|
15
|
+
agentId: options.agent_id,
|
|
16
|
+
baseUrl: this.baseUrl,
|
|
17
|
+
// Bearer for the enrollment dance only — once enrolled the
|
|
18
|
+
// agent JWTs sign requests directly. Reuse the OAuth refresh
|
|
19
|
+
// path so the developer doesn't need to ship a separate key
|
|
20
|
+
// to their agent runtime; if neither STACK_API_KEY nor
|
|
21
|
+
// ~/.stack/credentials.json is present, enrollment will fail
|
|
22
|
+
// with a clear error.
|
|
23
|
+
bearerProvider: () => this.resolveStaticBearer(),
|
|
24
|
+
})
|
|
25
|
+
: null;
|
|
8
26
|
}
|
|
9
27
|
async get(path, query) {
|
|
10
28
|
const url = this.buildUrl(path, query);
|
|
@@ -36,9 +54,67 @@ export class HttpClient {
|
|
|
36
54
|
}
|
|
37
55
|
return url.toString();
|
|
38
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the bearer token to attach to a request. Three sources, in
|
|
59
|
+
* priority order:
|
|
60
|
+
* 1. Explicit `apiKey` on the constructor or STACK_API_KEY env var
|
|
61
|
+
* (legacy `sk_live_*`, preserved for CI).
|
|
62
|
+
* 2. Cached OAuth access token (5-minute TTL; refresh-rotates).
|
|
63
|
+
* 3. Refresh token in `~/.stack/credentials.json` (written by the
|
|
64
|
+
* CLI's `auth login`) — exchanged for a fresh access token.
|
|
65
|
+
*
|
|
66
|
+
* Throws `StackError('NOT_AUTHENTICATED', ...)` when none of the
|
|
67
|
+
* three resolve.
|
|
68
|
+
*/
|
|
69
|
+
async resolveBearer() {
|
|
70
|
+
// Phase 2 — agent-runtime mode short-circuits everything. Mint a
|
|
71
|
+
// fresh agent JWT per request; enrollment happens inside the
|
|
72
|
+
// provider on first call.
|
|
73
|
+
if (this.agentTokenProvider) {
|
|
74
|
+
return this.agentTokenProvider();
|
|
75
|
+
}
|
|
76
|
+
return this.resolveStaticBearer();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Static-bearer resolution: explicit apiKey → STACK_API_KEY env →
|
|
80
|
+
* ~/.stack/credentials.json refresh-token exchange → first-run
|
|
81
|
+
* browser-spawn bootstrap (interactive only). Does NOT mint agent
|
|
82
|
+
* JWTs — that's `resolveBearer()`'s job. Exposed separately so the
|
|
83
|
+
* agent-token provider can use this same path for the one-time
|
|
84
|
+
* enrollment dance (which itself needs a static bearer to authenticate).
|
|
85
|
+
*/
|
|
86
|
+
async resolveStaticBearer() {
|
|
87
|
+
if (this.explicitApiKey)
|
|
88
|
+
return this.explicitApiKey;
|
|
89
|
+
// Browser / non-Node runtimes: refresh-from-file is not possible.
|
|
90
|
+
// Fall through to the same NOT_AUTHENTICATED error.
|
|
91
|
+
const isNode = typeof process !== 'undefined' && process.versions?.node;
|
|
92
|
+
if (!isNode)
|
|
93
|
+
throw notAuthenticated();
|
|
94
|
+
const now = Math.floor(Date.now() / 1000);
|
|
95
|
+
if (this.cachedAccessToken && this.cachedAccessToken.expiresAt - 30 > now) {
|
|
96
|
+
// Re-use the cached access token unless within 30s of expiry.
|
|
97
|
+
return this.cachedAccessToken.token;
|
|
98
|
+
}
|
|
99
|
+
const fresh = await refreshAccessTokenFromFile(this.baseUrl);
|
|
100
|
+
if (fresh) {
|
|
101
|
+
this.cachedAccessToken = { token: fresh.access_token, expiresAt: now + (fresh.expires_in ?? 300) };
|
|
102
|
+
return fresh.access_token;
|
|
103
|
+
}
|
|
104
|
+
// Last resort: spawn the browser. Gated by TTY + opt-out env so
|
|
105
|
+
// production agent runtimes (no TTY) don't accidentally try to open
|
|
106
|
+
// a browser.
|
|
107
|
+
if (shouldRunBrowserBootstrap()) {
|
|
108
|
+
const result = await browserBootstrap(this.baseUrl);
|
|
109
|
+
this.cachedAccessToken = { token: result.access_token, expiresAt: now + result.expires_in };
|
|
110
|
+
return result.access_token;
|
|
111
|
+
}
|
|
112
|
+
throw notAuthenticated();
|
|
113
|
+
}
|
|
39
114
|
async request(method, url, body, extraHeaders) {
|
|
115
|
+
const bearer = await this.resolveBearer();
|
|
40
116
|
const headers = {
|
|
41
|
-
'Authorization': `Bearer ${
|
|
117
|
+
'Authorization': `Bearer ${bearer}`,
|
|
42
118
|
'Accept': 'application/json',
|
|
43
119
|
...(extraHeaders ?? {}),
|
|
44
120
|
};
|
|
@@ -67,4 +143,48 @@ export class HttpClient {
|
|
|
67
143
|
return res.json();
|
|
68
144
|
}
|
|
69
145
|
}
|
|
146
|
+
function notAuthenticated() {
|
|
147
|
+
return new StackError('No STACK credentials found. Set STACK_API_KEY, pass { apiKey } to new Stack(), or run `stack-cli auth login`.', 'NOT_AUTHENTICATED', 401, {});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Read `~/.stack/credentials.json` (written by the CLI or by the SDK's
|
|
151
|
+
* own browser-bootstrap), exchange the stored refresh token for a fresh
|
|
152
|
+
* access token, write the rotated refresh back to the file. Returns
|
|
153
|
+
* null when the file is missing or the refresh has been revoked.
|
|
154
|
+
*
|
|
155
|
+
* Lazy-loaded Node-only path. The browser bundle skips this entirely
|
|
156
|
+
* via the isNode check in resolveBearer.
|
|
157
|
+
*/
|
|
158
|
+
async function refreshAccessTokenFromFile(baseUrl) {
|
|
159
|
+
const creds = await readCredentialsFile();
|
|
160
|
+
if (!creds)
|
|
161
|
+
return null;
|
|
162
|
+
const res = await fetch(`${baseUrl}/oauth/token`, {
|
|
163
|
+
method: 'POST',
|
|
164
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
165
|
+
body: new URLSearchParams({
|
|
166
|
+
grant_type: 'refresh_token',
|
|
167
|
+
refresh_token: creds.refresh_token,
|
|
168
|
+
client_id: creds.client_id,
|
|
169
|
+
}),
|
|
170
|
+
});
|
|
171
|
+
if (!res.ok)
|
|
172
|
+
return null;
|
|
173
|
+
const data = (await res.json());
|
|
174
|
+
// Persist the rotated refresh — failure to write means next run pays
|
|
175
|
+
// the round-trip again, but the in-memory access token is still good.
|
|
176
|
+
const next = {
|
|
177
|
+
...creds,
|
|
178
|
+
refresh_token: data.refresh_token,
|
|
179
|
+
issued_at: Math.floor(Date.now() / 1000),
|
|
180
|
+
refresh_expires_at: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60,
|
|
181
|
+
};
|
|
182
|
+
try {
|
|
183
|
+
await writeCredentialsFile(next);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
/* non-fatal */
|
|
187
|
+
}
|
|
188
|
+
return { access_token: data.access_token, expires_in: data.expires_in };
|
|
189
|
+
}
|
|
70
190
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface StoredCredentials {
|
|
2
|
+
client_id: string;
|
|
3
|
+
refresh_token: string;
|
|
4
|
+
issued_at: number;
|
|
5
|
+
refresh_expires_at: number;
|
|
6
|
+
operator_email?: string;
|
|
7
|
+
scope: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function credentialsFilePath(): Promise<string>;
|
|
10
|
+
export declare function readCredentialsFile(): Promise<StoredCredentials | null>;
|
|
11
|
+
export declare function writeCredentialsFile(creds: StoredCredentials): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=credentials-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials-file.d.ts","sourceRoot":"","sources":["../src/credentials-file.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAI3D;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAS7E;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYlF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Shared read/write helpers for ~/.stack/credentials.json.
|
|
2
|
+
//
|
|
3
|
+
// Same file the CLI's `auth login` writes; same file the SDK's
|
|
4
|
+
// browser-bootstrap writes. Read by client.ts on every static-bearer
|
|
5
|
+
// resolve. Centralized here so the on-disk shape stays consistent
|
|
6
|
+
// across all three writers.
|
|
7
|
+
export async function credentialsFilePath() {
|
|
8
|
+
const { homedir } = await import('node:os');
|
|
9
|
+
const { join } = await import('node:path');
|
|
10
|
+
return join(homedir(), '.stack', 'credentials.json');
|
|
11
|
+
}
|
|
12
|
+
export async function readCredentialsFile() {
|
|
13
|
+
try {
|
|
14
|
+
const { readFile } = await import('node:fs/promises');
|
|
15
|
+
const path = await credentialsFilePath();
|
|
16
|
+
const raw = await readFile(path, 'utf8');
|
|
17
|
+
return JSON.parse(raw);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function writeCredentialsFile(creds) {
|
|
24
|
+
const { mkdir, writeFile, chmod } = await import('node:fs/promises');
|
|
25
|
+
const { join, dirname } = await import('node:path');
|
|
26
|
+
const { homedir } = await import('node:os');
|
|
27
|
+
const path = join(homedir(), '.stack', 'credentials.json');
|
|
28
|
+
await mkdir(dirname(path), { recursive: true });
|
|
29
|
+
await writeFile(path, JSON.stringify(creds, null, 2), 'utf8');
|
|
30
|
+
try {
|
|
31
|
+
await chmod(path, 0o600);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
/* Windows / unsupported FS — default ACL on %USERPROFILE%\.stack is user-scoped */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=credentials-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials-file.js","sourceRoot":"","sources":["../src/credentials-file.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,+DAA+D;AAC/D,qEAAqE;AACrE,kEAAkE;AAClE,4BAA4B;AAW5B,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,MAAM,mBAAmB,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAwB;IACjE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACrE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IAC3D,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,mFAAmF;IACrF,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare class Stack {
|
|
|
31
31
|
readonly scan: ScanService;
|
|
32
32
|
readonly audit: AuditService;
|
|
33
33
|
readonly detectorConfig: DetectorConfigService;
|
|
34
|
-
constructor(options
|
|
34
|
+
constructor(options?: ClientOptions);
|
|
35
35
|
}
|
|
36
36
|
export type { ClientOptions } from './client.js';
|
|
37
37
|
export * from './types.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IAEpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC;IAChD,QAAQ,CAAC,aAAa,EAAE,mBAAmB,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,qBAAqB,CAAC;gBAEnC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IAEpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC;IAChD,QAAQ,CAAC,aAAa,EAAE,mBAAmB,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,oBAAoB,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,qBAAqB,CAAC;gBAEnC,OAAO,GAAE,aAAkB;CAkBxC;AAGD,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAK5B,OAAO,EACL,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,MAAM,OAAO,KAAK;IACC,MAAM,CAAa;IAE3B,MAAM,CAAe;IACrB,SAAS,CAAkB;IAC3B,QAAQ,CAAiB;IACzB,WAAW,CAAoB;IAC/B,QAAQ,CAAiB;IACzB,MAAM,CAAe;IACrB,QAAQ,CAAkB;IAC1B,IAAI,CAAc;IAClB,eAAe,CAAwB;IACvC,aAAa,CAAsB;IACnC,cAAc,CAAuB;IACrC,KAAK,CAAe;IACpB,IAAI,CAAc;IAClB,KAAK,CAAe;IACpB,cAAc,CAAwB;IAE/C,YAAY,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|