@mondaydotcomorg/z2h-cli 0.1.1 → 0.3.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/dist/commands/build.d.ts +1 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +5 -1
- package/dist/commands/create-workspace.d.ts.map +1 -1
- package/dist/commands/create-workspace.js +1 -0
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +16 -2
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +27 -28
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +29 -0
- package/dist/commands/generate-z2h-token.d.ts +16 -0
- package/dist/commands/generate-z2h-token.d.ts.map +1 -0
- package/dist/commands/generate-z2h-token.js +107 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +28 -0
- package/dist/esm/commands/build.d.ts +1 -0
- package/dist/esm/commands/build.d.ts.map +1 -1
- package/dist/esm/commands/build.mjs +5 -1
- package/dist/esm/commands/create-workspace.d.ts.map +1 -1
- package/dist/esm/commands/create-workspace.mjs +1 -0
- package/dist/esm/commands/create.d.ts.map +1 -1
- package/dist/esm/commands/create.mjs +16 -2
- package/dist/esm/commands/deploy.d.ts.map +1 -1
- package/dist/esm/commands/deploy.mjs +24 -26
- package/dist/esm/commands/dev.d.ts.map +1 -1
- package/dist/esm/commands/dev.mjs +25 -1
- package/dist/esm/commands/generate-z2h-token.d.ts +16 -0
- package/dist/esm/commands/generate-z2h-token.d.ts.map +1 -0
- package/dist/esm/commands/generate-z2h-token.mjs +99 -0
- package/dist/esm/constants.d.ts +8 -0
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.mjs +21 -1
- package/dist/esm/index.mjs +15 -0
- package/dist/esm/shadow/scaffold.d.ts.map +1 -1
- package/dist/esm/shadow/scaffold.mjs +5 -0
- package/dist/esm/templates/app/claude-settings.mjs +15 -2
- package/dist/esm/util/auth/__tests__/auth-store.test.d.ts +2 -0
- package/dist/esm/util/auth/__tests__/auth-store.test.d.ts.map +1 -0
- package/dist/esm/util/auth/__tests__/broker-credential-provider.test.d.ts +2 -0
- package/dist/esm/util/auth/__tests__/broker-credential-provider.test.d.ts.map +1 -0
- package/dist/esm/util/auth/__tests__/loopback-server.test.d.ts +2 -0
- package/dist/esm/util/auth/__tests__/loopback-server.test.d.ts.map +1 -0
- package/dist/esm/util/auth/__tests__/write-auth.test.d.ts +2 -0
- package/dist/esm/util/auth/__tests__/write-auth.test.d.ts.map +1 -0
- package/dist/esm/util/auth/auth-store.d.ts +11 -0
- package/dist/esm/util/auth/auth-store.d.ts.map +1 -0
- package/dist/esm/util/auth/auth-store.mjs +29 -0
- package/dist/esm/util/auth/broker-credential-provider.d.ts +12 -0
- package/dist/esm/util/auth/broker-credential-provider.d.ts.map +1 -0
- package/dist/esm/util/auth/broker-credential-provider.mjs +76 -0
- package/dist/esm/util/auth/loopback-server.d.ts +12 -0
- package/dist/esm/util/auth/loopback-server.d.ts.map +1 -0
- package/dist/esm/util/auth/loopback-server.mjs +87 -0
- package/dist/esm/util/auth/write-auth.d.ts +11 -0
- package/dist/esm/util/auth/write-auth.d.ts.map +1 -0
- package/dist/esm/util/auth/write-auth.mjs +22 -0
- package/dist/esm/util/manifest.d.ts +1 -0
- package/dist/esm/util/manifest.d.ts.map +1 -1
- package/dist/esm/util/manifest.mjs +2 -1
- package/dist/esm/util/s3/client.d.ts +7 -8
- package/dist/esm/util/s3/client.d.ts.map +1 -1
- package/dist/esm/util/s3/client.mjs +15 -30
- package/dist/esm/util/s3/upload.d.ts.map +1 -1
- package/dist/esm/util/s3/upload.mjs +2 -1
- package/dist/index.js +15 -0
- package/dist/shadow/scaffold.d.ts.map +1 -1
- package/dist/shadow/scaffold.js +5 -0
- package/dist/templates/app/claude-settings.js +15 -1
- package/dist/util/auth/__tests__/auth-store.test.d.ts +2 -0
- package/dist/util/auth/__tests__/auth-store.test.d.ts.map +1 -0
- package/dist/util/auth/__tests__/broker-credential-provider.test.d.ts +2 -0
- package/dist/util/auth/__tests__/broker-credential-provider.test.d.ts.map +1 -0
- package/dist/util/auth/__tests__/loopback-server.test.d.ts +2 -0
- package/dist/util/auth/__tests__/loopback-server.test.d.ts.map +1 -0
- package/dist/util/auth/__tests__/write-auth.test.d.ts +2 -0
- package/dist/util/auth/__tests__/write-auth.test.d.ts.map +1 -0
- package/dist/util/auth/auth-store.d.ts +11 -0
- package/dist/util/auth/auth-store.d.ts.map +1 -0
- package/dist/util/auth/auth-store.js +39 -0
- package/dist/util/auth/broker-credential-provider.d.ts +12 -0
- package/dist/util/auth/broker-credential-provider.d.ts.map +1 -0
- package/dist/util/auth/broker-credential-provider.js +80 -0
- package/dist/util/auth/loopback-server.d.ts +12 -0
- package/dist/util/auth/loopback-server.d.ts.map +1 -0
- package/dist/util/auth/loopback-server.js +94 -0
- package/dist/util/auth/write-auth.d.ts +11 -0
- package/dist/util/auth/write-auth.d.ts.map +1 -0
- package/dist/util/auth/write-auth.js +26 -0
- package/dist/util/manifest.d.ts +1 -0
- package/dist/util/manifest.d.ts.map +1 -1
- package/dist/util/manifest.js +5 -4
- package/dist/util/s3/client.d.ts +7 -8
- package/dist/util/s3/client.d.ts.map +1 -1
- package/dist/util/s3/client.js +14 -36
- package/dist/util/s3/upload.d.ts.map +1 -1
- package/dist/util/s3/upload.js +2 -1
- package/package.json +10 -1
- package/src/commands/__tests__/create.test.ts +3 -0
- package/src/commands/build.ts +6 -1
- package/src/commands/create-workspace.ts +1 -0
- package/src/commands/create.ts +19 -2
- package/src/commands/deploy.ts +27 -36
- package/src/commands/dev.ts +26 -1
- package/src/commands/generate-z2h-token.ts +124 -0
- package/src/constants.ts +25 -0
- package/src/index.ts +17 -0
- package/src/shadow/scaffold.ts +5 -0
- package/src/templates/app/claude-settings.json +12 -0
- package/src/templates/workspace/yarnlock +0 -0
- package/src/util/auth/__tests__/auth-store.test.ts +50 -0
- package/src/util/auth/__tests__/broker-credential-provider.test.ts +115 -0
- package/src/util/auth/__tests__/loopback-server.test.ts +85 -0
- package/src/util/auth/__tests__/write-auth.test.ts +79 -0
- package/src/util/auth/auth-store.ts +31 -0
- package/src/util/auth/broker-credential-provider.ts +93 -0
- package/src/util/auth/loopback-server.ts +103 -0
- package/src/util/auth/write-auth.ts +24 -0
- package/src/util/manifest.ts +3 -1
- package/src/util/s3/client.ts +15 -32
- package/src/util/s3/upload.ts +2 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { writeFile, readJson } from 'fs-extra';
|
|
2
4
|
import { watch } from 'chokidar';
|
|
3
5
|
import { execa } from 'execa';
|
|
4
6
|
import { setOutputMode, info, output, warn, errorLog } from '../util/logger.mjs';
|
|
@@ -22,6 +24,28 @@ async function devCommand(opts) {
|
|
|
22
24
|
cwd: ctx.paths.shadowDir,
|
|
23
25
|
stdio: ['inherit', 'pipe', 'inherit'],
|
|
24
26
|
});
|
|
27
|
+
const pidFile = path.join(ctx.paths.shadowDir, 'dev.pid');
|
|
28
|
+
if (server.pid) {
|
|
29
|
+
await writeFile(pidFile, String(server.pid));
|
|
30
|
+
}
|
|
31
|
+
const cleanupPid = () => {
|
|
32
|
+
try {
|
|
33
|
+
fs.unlinkSync(pidFile);
|
|
34
|
+
}
|
|
35
|
+
catch (_) {
|
|
36
|
+
// file already gone — ignore
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
server.on('exit', cleanupPid);
|
|
40
|
+
process.on('exit', cleanupPid);
|
|
41
|
+
process.on('SIGINT', () => {
|
|
42
|
+
server.kill();
|
|
43
|
+
process.exit(0);
|
|
44
|
+
});
|
|
45
|
+
process.on('SIGTERM', () => {
|
|
46
|
+
server.kill();
|
|
47
|
+
process.exit(0);
|
|
48
|
+
});
|
|
25
49
|
let readyPrinted = false;
|
|
26
50
|
server.stdout?.on('data', (chunk) => {
|
|
27
51
|
process.stdout.write(chunk);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const DEFAULT_TOKEN_PAGE_URL = "https://bigbrain.me/bigbrain-vibe/generate-z2h-token";
|
|
2
|
+
export declare const LOOPBACK_TIMEOUT_MS = 120000;
|
|
3
|
+
export interface GenerateZ2HTokenOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Skip browser auto-open AND skip the loopback callback. Prints the URL
|
|
6
|
+
* for the user to open manually, then waits for them to paste the token
|
|
7
|
+
* into the prompt. Use for SSH sessions, CI, or when the loopback can't
|
|
8
|
+
* reach the CLI for any reason.
|
|
9
|
+
*/
|
|
10
|
+
noBrowser?: boolean;
|
|
11
|
+
/** Override the page URL — useful when pointing at staging. */
|
|
12
|
+
url?: string;
|
|
13
|
+
json?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function generateZ2HTokenCommand(opts?: GenerateZ2HTokenOptions): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=generate-z2h-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-z2h-token.d.ts","sourceRoot":"","sources":["../../../src/commands/generate-z2h-token.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,sBAAsB,yDAAyD,CAAC;AAC7F,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAE3C,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAuED,wBAAsB,uBAAuB,CAAC,IAAI,GAAE,uBAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B/F"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import readline from 'node:readline/promises';
|
|
2
|
+
import { stdin, stdout } from 'node:process';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
import { setOutputMode, warn, output, info } from '../util/logger.mjs';
|
|
5
|
+
import { validateJwtPattern, writeZthAuth } from '../util/auth/write-auth.mjs';
|
|
6
|
+
import { startLoopbackServer } from '../util/auth/loopback-server.mjs';
|
|
7
|
+
|
|
8
|
+
const DEFAULT_TOKEN_PAGE_URL = 'https://bigbrain.me/bigbrain-vibe/generate-z2h-token';
|
|
9
|
+
const LOOPBACK_TIMEOUT_MS = 120_000;
|
|
10
|
+
function browserOpenCommand() {
|
|
11
|
+
switch (process.platform) {
|
|
12
|
+
case 'darwin':
|
|
13
|
+
return 'open';
|
|
14
|
+
case 'win32':
|
|
15
|
+
return 'start';
|
|
16
|
+
default:
|
|
17
|
+
return 'xdg-open';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function openInBrowser(url) {
|
|
21
|
+
await execa(browserOpenCommand(), [url], { stdio: 'ignore' });
|
|
22
|
+
}
|
|
23
|
+
async function promptForToken() {
|
|
24
|
+
const rl = readline.createInterface({ input: stdin, output: stdout });
|
|
25
|
+
try {
|
|
26
|
+
const raw = await rl.question('Paste your token here, then press Enter:\n> ');
|
|
27
|
+
return raw.trim();
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
rl.close();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function withQueryParam(url, key, value) {
|
|
34
|
+
const sep = url.includes('?') ? '&' : '?';
|
|
35
|
+
return `${url}${sep}${key}=${encodeURIComponent(value)}`;
|
|
36
|
+
}
|
|
37
|
+
async function runManualFlow(pageUrl) {
|
|
38
|
+
info(`open this URL in your browser to mint a Z2H deploy token:\n` +
|
|
39
|
+
` ${pageUrl}\n\n` +
|
|
40
|
+
`1. Click "Generate token" on the page.\n` +
|
|
41
|
+
`2. Copy the token shown.\n` +
|
|
42
|
+
`3. Paste it below and press Enter.\n`);
|
|
43
|
+
const token = await promptForToken();
|
|
44
|
+
if (!token) {
|
|
45
|
+
throw new Error('No token entered.');
|
|
46
|
+
}
|
|
47
|
+
return token;
|
|
48
|
+
}
|
|
49
|
+
async function runLoopbackFlow(pageUrl) {
|
|
50
|
+
const loopback = await startLoopbackServer();
|
|
51
|
+
const fullUrl = withQueryParam(pageUrl, 'cli_callback', loopback.callbackUrl);
|
|
52
|
+
info('opening your browser to mint a Z2H deploy token');
|
|
53
|
+
info(` ${fullUrl}`);
|
|
54
|
+
try {
|
|
55
|
+
await openInBrowser(fullUrl);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
warn('could not auto-open the browser. please visit the URL above manually.');
|
|
59
|
+
}
|
|
60
|
+
info('waiting for the page to send the token (Ctrl+C to fall back to manual paste)…');
|
|
61
|
+
try {
|
|
62
|
+
return await loopback.waitForToken(LOOPBACK_TIMEOUT_MS);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
loopback.close();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function generateZ2HTokenCommand(opts = {}) {
|
|
72
|
+
if (opts.json) {
|
|
73
|
+
setOutputMode('json');
|
|
74
|
+
}
|
|
75
|
+
const pageUrl = opts.url ?? process.env.Z2H_TOKEN_PAGE_URL ?? DEFAULT_TOKEN_PAGE_URL;
|
|
76
|
+
// --no-browser bypasses both auto-open and the loopback round-trip — the
|
|
77
|
+
// user opens the URL themselves and pastes the token. Useful when the
|
|
78
|
+
// loopback can't be reached (SSH, CI, locked-down browsers).
|
|
79
|
+
let token = null;
|
|
80
|
+
if (!opts.noBrowser) {
|
|
81
|
+
token = await runLoopbackFlow(pageUrl);
|
|
82
|
+
if (!token) {
|
|
83
|
+
warn('loopback flow timed out or was cancelled — falling back to manual paste.');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (!token) {
|
|
87
|
+
token = await runManualFlow(pageUrl);
|
|
88
|
+
}
|
|
89
|
+
if (!validateJwtPattern(token)) {
|
|
90
|
+
throw new Error('That does not look like a JWT (expected three dot-separated segments).');
|
|
91
|
+
}
|
|
92
|
+
const { filePath } = await writeZthAuth({ token });
|
|
93
|
+
output(`[z2h-cli] token saved ✅ ${filePath}`, {
|
|
94
|
+
ok: true,
|
|
95
|
+
filePath,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { DEFAULT_TOKEN_PAGE_URL, LOOPBACK_TIMEOUT_MS, generateZ2HTokenCommand };
|
package/dist/esm/constants.d.ts
CHANGED
|
@@ -9,4 +9,12 @@ export declare const MIN_PORT = 13000;
|
|
|
9
9
|
export declare const MAX_PORT = 19999;
|
|
10
10
|
export declare const GITIGNORE_ENTRIES: string[];
|
|
11
11
|
export declare const YARNRC_LINES: string[];
|
|
12
|
+
export declare const BUCKET_WRITE_NAME = "prod-use1-bigbrain-zth-mf-assets";
|
|
13
|
+
export declare const REGION = "us-east-1";
|
|
14
|
+
export declare const BUCKET_WRITE_URL = "https://prod-use1-bigbrain-zth-mf-assets.s3.us-east-1.amazonaws.com";
|
|
15
|
+
export declare const BUCKET_READ_DNS_NAME = "bigbrain-zth-mf-assets";
|
|
16
|
+
export declare const BUCKET_READ_DNS_URL = "https://bigbrain-zth-mf-assets.bigbrain.me";
|
|
17
|
+
export declare const MANIFEST_KEY = "mf-assets";
|
|
18
|
+
export declare const MANIFEST_READ_URL = "https://bigbrain-zth-mf-assets.bigbrain.me/mf-assets";
|
|
19
|
+
export declare const APP_NAME_PATTERN: RegExp;
|
|
12
20
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,eAAe,SAAS,CAAC;AAGtC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGjD,CAAC;AAQF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAElD,CAAC;AAMF,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAG9B,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAG3C,eAAO,MAAM,YAAY,UAIxB,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,eAAO,MAAM,eAAe,SAAS,CAAC;AAGtC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGjD,CAAC;AAQF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAElD,CAAC;AAMF,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAG9B,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAG3C,eAAO,MAAM,YAAY,UAIxB,CAAC;AAQF,eAAO,MAAM,iBAAiB,qCAAqC,CAAC;AACpE,eAAO,MAAM,MAAM,cAAc,CAAC;AAClC,eAAO,MAAM,gBAAgB,wEAA4D,CAAC;AAE1F,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAC7D,eAAO,MAAM,mBAAmB,+CAAgD,CAAC;AAKjF,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,eAAO,MAAM,iBAAiB,yDAA2C,CAAC;AAM1E,eAAO,MAAM,gBAAgB,QAA2B,CAAC"}
|
package/dist/esm/constants.mjs
CHANGED
|
@@ -32,5 +32,25 @@ const YARNRC_LINES = [
|
|
|
32
32
|
"npmAuthToken: '${NPM_TOKEN}'",
|
|
33
33
|
"npmRegistryServer: 'https://registry.npmjs.org/'",
|
|
34
34
|
];
|
|
35
|
+
// ─────────── Z2H deploy bucket / contract ─────────
|
|
36
|
+
// Source of truth for the bucket layout. The CLI uses these when configuring
|
|
37
|
+
// the S3 client + uploading; bigbrain-zth's STS broker imports them via
|
|
38
|
+
// `@mondaydotcomorg/z2h-cli/constants` to scope the per-deploy session
|
|
39
|
+
// policy to the same bucket + manifest key.
|
|
40
|
+
const BUCKET_WRITE_NAME = 'prod-use1-bigbrain-zth-mf-assets';
|
|
41
|
+
const REGION = 'us-east-1';
|
|
42
|
+
const BUCKET_WRITE_URL = `https://${BUCKET_WRITE_NAME}.s3.${REGION}.amazonaws.com`;
|
|
43
|
+
const BUCKET_READ_DNS_NAME = 'bigbrain-zth-mf-assets';
|
|
44
|
+
const BUCKET_READ_DNS_URL = `https://${BUCKET_READ_DNS_NAME}.bigbrain.me`;
|
|
45
|
+
// No `.json` extension — TridentSkeleton's `mfUrl` API appends `/mf-assets`
|
|
46
|
+
// to the bucket base when fetching, so the manifest must live at this exact
|
|
47
|
+
// key. See microfrontends/mf-bigbrain-zth/.../ZeroToHeroHost.tsx.
|
|
48
|
+
const MANIFEST_KEY = 'mf-assets';
|
|
49
|
+
const MANIFEST_READ_URL = `${BUCKET_READ_DNS_URL}/${MANIFEST_KEY}`;
|
|
50
|
+
// ─────────── App-name slug — backend & CLI both honor this ─────
|
|
51
|
+
// Lowercase kebab-case, must start with a letter, 2-50 chars total. The
|
|
52
|
+
// backend STS broker rejects anything else with 400; the CLI can validate
|
|
53
|
+
// upfront for friendlier errors.
|
|
54
|
+
const APP_NAME_PATTERN = /^[a-z][a-z0-9-]{1,49}$/;
|
|
35
55
|
|
|
36
|
-
export { GITIGNORE_ENTRIES, MAX_PORT, MIN_PORT, SHADOW_DEV_DEPS, SHADOW_DIR_NAME, SHADOW_SCRIPTS, YARNRC_LINES };
|
|
56
|
+
export { APP_NAME_PATTERN, BUCKET_READ_DNS_NAME, BUCKET_READ_DNS_URL, BUCKET_WRITE_NAME, BUCKET_WRITE_URL, GITIGNORE_ENTRIES, MANIFEST_KEY, MANIFEST_READ_URL, MAX_PORT, MIN_PORT, REGION, SHADOW_DEV_DEPS, SHADOW_DIR_NAME, SHADOW_SCRIPTS, YARNRC_LINES };
|
package/dist/esm/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { cleanCommand } from './commands/clean.mjs';
|
|
|
5
5
|
import { deployCommand } from './commands/deploy.mjs';
|
|
6
6
|
import { createWorkspaceCommand } from './commands/create-workspace.mjs';
|
|
7
7
|
import { createCommand } from './commands/create.mjs';
|
|
8
|
+
import { generateZ2HTokenCommand } from './commands/generate-z2h-token.mjs';
|
|
8
9
|
import { errorLog, fail } from './util/logger.mjs';
|
|
9
10
|
|
|
10
11
|
async function main() {
|
|
@@ -88,6 +89,20 @@ async function main() {
|
|
|
88
89
|
fail(`create-workspace failed: ${err.message}`, { command: 'create-workspace' }, 1);
|
|
89
90
|
}
|
|
90
91
|
});
|
|
92
|
+
program
|
|
93
|
+
.command('generate-z2h-token')
|
|
94
|
+
.description('Open the bigbrain.me token page, capture the token via a loopback callback, and persist it to ~/.zth/auth.json')
|
|
95
|
+
.option('--no-browser', "don't auto-open the browser; print the URL and prompt for manual paste")
|
|
96
|
+
.option('--url <url>', 'Override the token page URL (e.g. for staging)')
|
|
97
|
+
.option('--json', 'emit structured JSON on stdout')
|
|
98
|
+
.action(async (opts) => {
|
|
99
|
+
try {
|
|
100
|
+
await generateZ2HTokenCommand(opts);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
fail(`generate-z2h-token failed: ${err.message}`, { command: 'generate-z2h-token' }, 1);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
91
106
|
program
|
|
92
107
|
.command('create <app-name>')
|
|
93
108
|
.description('Scaffold a new Z2H consumer app inside ~/zth-projects/')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/shadow/scaffold.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/shadow/scaffold.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA0G9C;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvG"}
|
|
@@ -3,8 +3,21 @@ var permissions = {
|
|
|
3
3
|
"Skill(z2h:*)"
|
|
4
4
|
]
|
|
5
5
|
};
|
|
6
|
+
var hooks = {
|
|
7
|
+
Stop: [
|
|
8
|
+
{
|
|
9
|
+
hooks: [
|
|
10
|
+
{
|
|
11
|
+
type: "command",
|
|
12
|
+
command: "if [ -f .zth/dev.pid ]; then kill $(cat .zth/dev.pid) 2>/dev/null; rm .zth/dev.pid; fi"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
};
|
|
6
18
|
const claudeSettings = {
|
|
7
|
-
permissions: permissions
|
|
19
|
+
permissions: permissions,
|
|
20
|
+
hooks: hooks
|
|
8
21
|
};
|
|
9
22
|
|
|
10
|
-
export { claudeSettings as default, permissions };
|
|
23
|
+
export { claudeSettings as default, hooks, permissions };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-store.test.d.ts","sourceRoot":"","sources":["../../../../../src/util/auth/__tests__/auth-store.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-credential-provider.test.d.ts","sourceRoot":"","sources":["../../../../../src/util/auth/__tests__/broker-credential-provider.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopback-server.test.d.ts","sourceRoot":"","sources":["../../../../../src/util/auth/__tests__/loopback-server.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-auth.test.d.ts","sourceRoot":"","sources":["../../../../../src/util/auth/__tests__/write-auth.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const Z2H_AUTH_DIR: string;
|
|
2
|
+
export declare const Z2H_AUTH_FILE: string;
|
|
3
|
+
export interface ZthAuth {
|
|
4
|
+
token: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class Z2hAuthMissingError extends Error {
|
|
7
|
+
readonly authFilePath: string;
|
|
8
|
+
constructor(authFilePath: string);
|
|
9
|
+
}
|
|
10
|
+
export declare function readZthAuth(): Promise<ZthAuth>;
|
|
11
|
+
//# sourceMappingURL=auth-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-store.d.ts","sourceRoot":"","sources":["../../../../src/util/auth/auth-store.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,YAAY,QAAkC,CAAC;AAC5D,eAAO,MAAM,aAAa,QAAuC,CAAC;AAElE,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aAChB,YAAY,EAAE,MAAM;gBAApB,YAAY,EAAE,MAAM;CAIjD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CASpD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import { pathExists, readJson } from 'fs-extra';
|
|
4
|
+
|
|
5
|
+
// npm-style convention: per-user config under ~/.zth (mirrors ~/.npmrc, ~/.aws/).
|
|
6
|
+
// Kept out of the workspace dir so accidental `git init` in ~/zth-projects can't
|
|
7
|
+
// stage it.
|
|
8
|
+
const Z2H_AUTH_DIR = path.join(os.homedir(), '.zth');
|
|
9
|
+
const Z2H_AUTH_FILE = path.join(Z2H_AUTH_DIR, 'auth.json');
|
|
10
|
+
class Z2hAuthMissingError extends Error {
|
|
11
|
+
authFilePath;
|
|
12
|
+
constructor(authFilePath) {
|
|
13
|
+
super(`No Z2H deploy token found at ${authFilePath}. Please run 'z2h-cli generate-z2h-token' command.`);
|
|
14
|
+
this.authFilePath = authFilePath;
|
|
15
|
+
this.name = 'Z2hAuthMissingError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function readZthAuth() {
|
|
19
|
+
if (!(await pathExists(Z2H_AUTH_FILE))) {
|
|
20
|
+
throw new Z2hAuthMissingError(Z2H_AUTH_FILE);
|
|
21
|
+
}
|
|
22
|
+
const parsed = (await readJson(Z2H_AUTH_FILE));
|
|
23
|
+
if (!parsed.token) {
|
|
24
|
+
throw new Error(`${Z2H_AUTH_FILE} is missing a "token" string field.`);
|
|
25
|
+
}
|
|
26
|
+
return { token: parsed.token };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { Z2H_AUTH_DIR, Z2H_AUTH_FILE, Z2hAuthMissingError, readZthAuth };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AwsCredentialIdentityProvider } from '@aws-sdk/types';
|
|
2
|
+
export declare const DEFAULT_BROKER_BASE_URL = "https://bigbrain-zth.bigbrain.me";
|
|
3
|
+
export declare const STS_BROKER_PATH = "/z2h-cli/sts/credentials";
|
|
4
|
+
/**
|
|
5
|
+
* AWS SDK credential provider that fetches short-lived deploy credentials
|
|
6
|
+
* from the bigbrain-zth STS broker. Credentials are cached in memory until
|
|
7
|
+
* 5 minutes before expiry; concurrent calls share a single in-flight fetch.
|
|
8
|
+
*/
|
|
9
|
+
export declare function brokerCredentialProvider({ appName }: {
|
|
10
|
+
appName: string;
|
|
11
|
+
}): AwsCredentialIdentityProvider;
|
|
12
|
+
//# sourceMappingURL=broker-credential-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-credential-provider.d.ts","sourceRoot":"","sources":["../../../../src/util/auth/broker-credential-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAyB,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAE3F,eAAO,MAAM,uBAAuB,qCAAqC,CAAC;AAC1E,eAAO,MAAM,eAAe,6BAA6B,CAAC;AA4D1D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,6BAA6B,CAuBxG"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { readZthAuth } from './auth-store.mjs';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_BROKER_BASE_URL = 'https://bigbrain-zth.bigbrain.me';
|
|
4
|
+
const STS_BROKER_PATH = '/z2h-cli/sts/credentials';
|
|
5
|
+
// Refresh the cached credentials this many ms before they expire so the next
|
|
6
|
+
// AWS API call doesn't race the broker round-trip against a hard expiry.
|
|
7
|
+
const REFRESH_BUFFER_MS = 5 * 60 * 1000;
|
|
8
|
+
function brokerBaseUrl() {
|
|
9
|
+
return process.env.Z2H_BROKER_BASE_URL || DEFAULT_BROKER_BASE_URL;
|
|
10
|
+
}
|
|
11
|
+
async function fetchCredentialsOnce(appName) {
|
|
12
|
+
const { token } = await readZthAuth();
|
|
13
|
+
const url = `${brokerBaseUrl()}${STS_BROKER_PATH}`;
|
|
14
|
+
let res;
|
|
15
|
+
try {
|
|
16
|
+
res = await fetch(url, {
|
|
17
|
+
method: 'POST',
|
|
18
|
+
headers: {
|
|
19
|
+
Authorization: `Bearer ${token}`,
|
|
20
|
+
'Content-Type': 'application/json',
|
|
21
|
+
Accept: 'application/json',
|
|
22
|
+
},
|
|
23
|
+
body: JSON.stringify({ appName }),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
28
|
+
throw new Error(`Z2H deploy broker request failed: ${message}`);
|
|
29
|
+
}
|
|
30
|
+
if (res.status === 401 || res.status === 403) {
|
|
31
|
+
throw new Error(`Z2H deploy token rejected by the broker (${res.status}). Refresh user token by running 'z2h-cli generate-z2h-token'.`);
|
|
32
|
+
}
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const text = await res.text();
|
|
35
|
+
throw new Error(`Z2H deploy broker returned ${res.status}: ${text.slice(0, 1024)}`);
|
|
36
|
+
}
|
|
37
|
+
const body = (await res.json());
|
|
38
|
+
if (!body.accessKeyId || !body.secretAccessKey || !body.sessionToken || !body.expiration) {
|
|
39
|
+
throw new Error('Z2H deploy broker response missing required credential fields');
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
accessKeyId: body.accessKeyId,
|
|
43
|
+
secretAccessKey: body.secretAccessKey,
|
|
44
|
+
sessionToken: body.sessionToken,
|
|
45
|
+
expiration: new Date(body.expiration),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* AWS SDK credential provider that fetches short-lived deploy credentials
|
|
50
|
+
* from the bigbrain-zth STS broker. Credentials are cached in memory until
|
|
51
|
+
* 5 minutes before expiry; concurrent calls share a single in-flight fetch.
|
|
52
|
+
*/
|
|
53
|
+
function brokerCredentialProvider({ appName }) {
|
|
54
|
+
let cached;
|
|
55
|
+
let inflight;
|
|
56
|
+
return async () => {
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
if (cached && cached.expiration && cached.expiration.getTime() - now > REFRESH_BUFFER_MS) {
|
|
59
|
+
return cached;
|
|
60
|
+
}
|
|
61
|
+
if (inflight) {
|
|
62
|
+
return inflight;
|
|
63
|
+
}
|
|
64
|
+
inflight = fetchCredentialsOnce(appName)
|
|
65
|
+
.then(creds => {
|
|
66
|
+
cached = creds;
|
|
67
|
+
return creds;
|
|
68
|
+
})
|
|
69
|
+
.finally(() => {
|
|
70
|
+
inflight = undefined;
|
|
71
|
+
});
|
|
72
|
+
return inflight;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { DEFAULT_BROKER_BASE_URL, STS_BROKER_PATH, brokerCredentialProvider };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface LoopbackHandle {
|
|
2
|
+
/** Fully-qualified URL the browser should POST to (e.g. http://127.0.0.1:53811/token). */
|
|
3
|
+
callbackUrl: string;
|
|
4
|
+
/**
|
|
5
|
+
* Resolves with the token once the page POSTs it back. Rejects on timeout
|
|
6
|
+
* or if the server is closed before a token arrives.
|
|
7
|
+
*/
|
|
8
|
+
waitForToken(timeoutMs: number): Promise<string>;
|
|
9
|
+
close(): void;
|
|
10
|
+
}
|
|
11
|
+
export declare function startLoopbackServer(): Promise<LoopbackHandle>;
|
|
12
|
+
//# sourceMappingURL=loopback-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopback-server.d.ts","sourceRoot":"","sources":["../../../../src/util/auth/loopback-server.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,cAAc;IAC7B,0FAA0F;IAC1F,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,cAAc,CAAC,CAkF7D"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import cors from 'cors';
|
|
2
|
+
import express, { json } from 'express';
|
|
3
|
+
|
|
4
|
+
const ALLOWED_ORIGINS = new Set(['https://bigbrain.me', 'https://bigbrainstaging.me']);
|
|
5
|
+
const CALLBACK_PATH = '/token';
|
|
6
|
+
const REQUEST_BODY_LIMIT = '16kb';
|
|
7
|
+
const PREFLIGHT_MAX_AGE_SECONDS = 600;
|
|
8
|
+
function startLoopbackServer() {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
let resolveToken = null;
|
|
11
|
+
let rejectToken = null;
|
|
12
|
+
const app = express();
|
|
13
|
+
// Reflect the origin if it's one of ours; otherwise wildcard. The
|
|
14
|
+
// endpoint is loopback-bound and single-shot, so the CORS surface is
|
|
15
|
+
// moot — we keep allowlist behavior so the test contract stays exact.
|
|
16
|
+
app.use(cors({
|
|
17
|
+
origin: (origin, cb) => {
|
|
18
|
+
if (origin && ALLOWED_ORIGINS.has(origin)) {
|
|
19
|
+
cb(null, origin);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
cb(null, '*');
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
methods: ['POST', 'OPTIONS'],
|
|
26
|
+
allowedHeaders: ['Content-Type'],
|
|
27
|
+
maxAge: PREFLIGHT_MAX_AGE_SECONDS,
|
|
28
|
+
}));
|
|
29
|
+
app.use(json({ limit: REQUEST_BODY_LIMIT }));
|
|
30
|
+
app.post(CALLBACK_PATH, (req, res) => {
|
|
31
|
+
const body = req.body;
|
|
32
|
+
const token = typeof body?.token === 'string' ? body.token.trim() : '';
|
|
33
|
+
if (!token) {
|
|
34
|
+
res.status(400).json({ error: 'missing token' });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// Ack the page so it can transition to "Token sent ✓" and auto-close.
|
|
38
|
+
// The bigbrain.me page never displays this body — it just inspects res.ok.
|
|
39
|
+
res.status(200).json({ ok: true });
|
|
40
|
+
if (resolveToken) {
|
|
41
|
+
const fn = resolveToken;
|
|
42
|
+
resolveToken = null;
|
|
43
|
+
rejectToken = null;
|
|
44
|
+
fn(token);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const server = app.listen(0, '127.0.0.1', () => {
|
|
48
|
+
const address = server.address();
|
|
49
|
+
if (!address || typeof address === 'string') {
|
|
50
|
+
server.close();
|
|
51
|
+
reject(new Error('Failed to determine loopback port'));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
resolve({
|
|
55
|
+
callbackUrl: `http://127.0.0.1:${address.port}${CALLBACK_PATH}`,
|
|
56
|
+
waitForToken(timeoutMs) {
|
|
57
|
+
return new Promise((res, rej) => {
|
|
58
|
+
resolveToken = res;
|
|
59
|
+
rejectToken = rej;
|
|
60
|
+
const timer = setTimeout(() => {
|
|
61
|
+
if (rejectToken) {
|
|
62
|
+
const reject = rejectToken;
|
|
63
|
+
resolveToken = null;
|
|
64
|
+
rejectToken = null;
|
|
65
|
+
reject(new Error('Loopback callback timed out'));
|
|
66
|
+
}
|
|
67
|
+
}, timeoutMs);
|
|
68
|
+
// Don't keep the event loop alive on the timer alone.
|
|
69
|
+
timer.unref?.();
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
close() {
|
|
73
|
+
if (rejectToken) {
|
|
74
|
+
const reject = rejectToken;
|
|
75
|
+
resolveToken = null;
|
|
76
|
+
rejectToken = null;
|
|
77
|
+
reject(new Error('Loopback server closed before token arrived'));
|
|
78
|
+
}
|
|
79
|
+
server.close();
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
server.on('error', reject);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { startLoopbackServer };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ZthAuth } from './auth-store';
|
|
2
|
+
export declare function writeZthAuth(auth: ZthAuth): Promise<{
|
|
3
|
+
filePath: string;
|
|
4
|
+
}>;
|
|
5
|
+
/**
|
|
6
|
+
* Three base64url segments separated by dots — a structural sanity check,
|
|
7
|
+
* not a real verification. Server-side validation happens at the STS broker.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateJwtPattern(token: string): boolean;
|
|
10
|
+
export { Z2H_AUTH_FILE } from './auth-store';
|
|
11
|
+
//# sourceMappingURL=write-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-auth.d.ts","sourceRoot":"","sources":["../../../../src/util/auth/write-auth.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAMzE,wBAAsB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAK/E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { chmod } from 'node:fs/promises';
|
|
2
|
+
import { ensureDir, writeFile } from 'fs-extra';
|
|
3
|
+
import { Z2H_AUTH_DIR, Z2H_AUTH_FILE } from './auth-store.mjs';
|
|
4
|
+
|
|
5
|
+
// 0o600 — owner read/write only. The file holds a long-lived bearer token,
|
|
6
|
+
// so other local users on the machine must not be able to read it.
|
|
7
|
+
const OWNER_READ_WRITE_FILE_MODE = 0o600;
|
|
8
|
+
async function writeZthAuth(auth) {
|
|
9
|
+
await ensureDir(Z2H_AUTH_DIR);
|
|
10
|
+
await writeFile(Z2H_AUTH_FILE, `${JSON.stringify(auth, null, 2)}\n`);
|
|
11
|
+
await chmod(Z2H_AUTH_FILE, OWNER_READ_WRITE_FILE_MODE);
|
|
12
|
+
return { filePath: Z2H_AUTH_FILE };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Three base64url segments separated by dots — a structural sanity check,
|
|
16
|
+
* not a real verification. Server-side validation happens at the STS broker.
|
|
17
|
+
*/
|
|
18
|
+
function validateJwtPattern(token) {
|
|
19
|
+
return /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(token);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { Z2H_AUTH_FILE, validateJwtPattern, writeZthAuth };
|
|
@@ -22,6 +22,7 @@ export interface AssetManifestFile {
|
|
|
22
22
|
export interface ManifestEntry extends AssetManifestFile {
|
|
23
23
|
version: number;
|
|
24
24
|
url: string;
|
|
25
|
+
deployedBy: string;
|
|
25
26
|
}
|
|
26
27
|
export type Manifest = Record<string, ManifestEntry>;
|
|
27
28
|
export declare function readManifest(): Promise<Manifest>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/util/manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/util/manifest.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAErD,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAQtD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,UAI1D;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,QAAQ,CAE3F;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PutObjectCommand } from '@aws-sdk/client-s3';
|
|
2
|
-
import { MANIFEST_READ_URL,
|
|
2
|
+
import { MANIFEST_READ_URL, BUCKET_WRITE_NAME, MANIFEST_KEY } from '../constants.mjs';
|
|
3
|
+
import { getS3Client } from './s3/client.mjs';
|
|
3
4
|
|
|
4
5
|
async function readManifest() {
|
|
5
6
|
// Read via the public CDN endpoint, no AWS auth required.
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { S3Client } from '@aws-sdk/client-s3';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export declare
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Initialize the per-process S3 client with broker-issued credentials scoped
|
|
4
|
+
* to the given app's S3 prefix. Must be called once before any `getS3Client`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function setupS3Client({ appName }: {
|
|
7
|
+
appName: string;
|
|
8
|
+
}): void;
|
|
9
9
|
export declare function getS3Client(): S3Client;
|
|
10
|
-
export declare function assertBucketExists(): Promise<void>;
|
|
11
10
|
//# sourceMappingURL=client.d.ts.map
|