blogwright 0.1.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/LICENSE +24 -0
- package/README.md +12 -0
- package/agent/Dockerfile +20 -0
- package/agent/agent-manifest.json +3 -0
- package/agent/server.js +7935 -0
- package/dist/adapters/fetch-ping.d.ts +9 -0
- package/dist/adapters/fetch-ping.js +26 -0
- package/dist/adapters/fetch-ping.js.map +1 -0
- package/dist/adapters/process-vcs.d.ts +12 -0
- package/dist/adapters/process-vcs.js +49 -0
- package/dist/adapters/process-vcs.js.map +1 -0
- package/dist/agent-package.d.ts +19 -0
- package/dist/agent-package.js +49 -0
- package/dist/agent-package.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +14 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +249 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +31 -0
- package/dist/commands.js +269 -0
- package/dist/commands.js.map +1 -0
- package/dist/context.d.ts +50 -0
- package/dist/context.js +77 -0
- package/dist/context.js.map +1 -0
- package/dist/deploy.d.ts +57 -0
- package/dist/deploy.js +247 -0
- package/dist/deploy.js.map +1 -0
- package/dist/graph.d.ts +20 -0
- package/dist/graph.js +73 -0
- package/dist/graph.js.map +1 -0
- package/dist/init.d.ts +4 -0
- package/dist/init.js +92 -0
- package/dist/init.js.map +1 -0
- package/dist/logger.d.ts +18 -0
- package/dist/logger.js +34 -0
- package/dist/logger.js.map +1 -0
- package/dist/microvms.d.ts +15 -0
- package/dist/microvms.js +56 -0
- package/dist/microvms.js.map +1 -0
- package/dist/nodes.d.ts +34 -0
- package/dist/nodes.js +858 -0
- package/dist/nodes.js.map +1 -0
- package/dist/ports.d.ts +25 -0
- package/dist/ports.js +7 -0
- package/dist/ports.js.map +1 -0
- package/dist/render.d.ts +33 -0
- package/dist/render.js +81 -0
- package/dist/render.js.map +1 -0
- package/dist/repo.d.ts +25 -0
- package/dist/repo.js +75 -0
- package/dist/repo.js.map +1 -0
- package/dist/rkey.d.ts +6 -0
- package/dist/rkey.js +7 -0
- package/dist/rkey.js.map +1 -0
- package/dist/seo.d.ts +15 -0
- package/dist/seo.js +30 -0
- package/dist/seo.js.map +1 -0
- package/dist/test-support.d.ts +44 -0
- package/dist/test-support.js +120 -0
- package/dist/test-support.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch adapter for the PingBuilder port: opens a connection to the builder
|
|
3
|
+
* MicroVM's proxy endpoint to wake the resumed agent's event loop. Errors never
|
|
4
|
+
* cross the port — the ping is best-effort by contract, and the agent's HTTP/1
|
|
5
|
+
* server may not even parse the request.
|
|
6
|
+
*/
|
|
7
|
+
import type { PingBuilder } from '../ports.js';
|
|
8
|
+
/** Build the fetch-backed ping. `fetchImpl` is injectable for tests. */
|
|
9
|
+
export declare function createFetchPing(fetchImpl?: typeof fetch): PingBuilder;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch adapter for the PingBuilder port: opens a connection to the builder
|
|
3
|
+
* MicroVM's proxy endpoint to wake the resumed agent's event loop. Errors never
|
|
4
|
+
* cross the port — the ping is best-effort by contract, and the agent's HTTP/1
|
|
5
|
+
* server may not even parse the request.
|
|
6
|
+
*/
|
|
7
|
+
/** A nudge only needs the connection to land; never hold a poll cycle longer than this. */
|
|
8
|
+
const PING_TIMEOUT_MS = 2500;
|
|
9
|
+
/** Build the fetch-backed ping. `fetchImpl` is injectable for tests. */
|
|
10
|
+
export function createFetchPing(fetchImpl = fetch) {
|
|
11
|
+
return async (endpoint, token) => {
|
|
12
|
+
try {
|
|
13
|
+
const res = await fetchImpl(`https://${endpoint}/status`, {
|
|
14
|
+
headers: { 'X-aws-proxy-auth': token, 'X-aws-proxy-port': '8080' },
|
|
15
|
+
signal: AbortSignal.timeout(PING_TIMEOUT_MS),
|
|
16
|
+
});
|
|
17
|
+
// Release the connection — an unread body pins an undici socket per
|
|
18
|
+
// poll cycle until GC.
|
|
19
|
+
await res.body?.cancel();
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
/* expected — the point is the wake-up, not the response */
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=fetch-ping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-ping.js","sourceRoot":"","sources":["../../src/adapters/fetch-ping.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,2FAA2F;AAC3F,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,wEAAwE;AACxE,MAAM,UAAU,eAAe,CAAC,YAA0B,KAAK;IAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,WAAW,QAAQ,SAAS,EAAE;gBACxD,OAAO,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE;gBAClE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC;aAC7C,CAAC,CAAC;YACH,oEAAoE;YACpE,uBAAuB;YACvB,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,2DAA2D;QAC7D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process adapter for the Vcs port: shells out to jj/git. The only module
|
|
3
|
+
* outside the build-agent that may import node:child_process; failures are
|
|
4
|
+
* translated with the command and directory before they cross the port.
|
|
5
|
+
*/
|
|
6
|
+
import type { Vcs } from '../ports.js';
|
|
7
|
+
/**
|
|
8
|
+
* Build the jj/git process adapter. The revision hash prefers jj's git commit
|
|
9
|
+
* id (jj auto-commits the working copy), falling back to git HEAD; listings
|
|
10
|
+
* honor .gitignore — tracked files plus untracked files that are not ignored.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createProcessVcs(): Vcs;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process adapter for the Vcs port: shells out to jj/git. The only module
|
|
3
|
+
* outside the build-agent that may import node:child_process; failures are
|
|
4
|
+
* translated with the command and directory before they cross the port.
|
|
5
|
+
*/
|
|
6
|
+
import { execFile } from 'node:child_process';
|
|
7
|
+
import { promisify } from 'node:util';
|
|
8
|
+
const run = promisify(execFile);
|
|
9
|
+
/** `git ls-files -z` output can exceed the 1 MiB default buffer on large repos. */
|
|
10
|
+
const MAX_OUTPUT_BYTES = 64 * 1024 * 1024;
|
|
11
|
+
async function runVcsCommand(cwd, command, args) {
|
|
12
|
+
try {
|
|
13
|
+
const { stdout } = await run(command, args, { cwd, maxBuffer: MAX_OUTPUT_BYTES });
|
|
14
|
+
return stdout;
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
throw new Error(`${command} ${args.join(' ')} failed in ${cwd}: ${err.message}`, {
|
|
18
|
+
cause: err,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Build the jj/git process adapter. The revision hash prefers jj's git commit
|
|
24
|
+
* id (jj auto-commits the working copy), falling back to git HEAD; listings
|
|
25
|
+
* honor .gitignore — tracked files plus untracked files that are not ignored.
|
|
26
|
+
*/
|
|
27
|
+
export function createProcessVcs() {
|
|
28
|
+
return {
|
|
29
|
+
async revisionHash(cwd) {
|
|
30
|
+
try {
|
|
31
|
+
const jjArgs = ['log', '--no-graph', '-r', '@', '-T', 'commit_id.short()'];
|
|
32
|
+
const hash = (await runVcsCommand(cwd, 'jj', jjArgs)).trim();
|
|
33
|
+
if (hash)
|
|
34
|
+
return hash;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
/* jj unavailable or not a jj repo — fall through to git */
|
|
38
|
+
}
|
|
39
|
+
return (await runVcsCommand(cwd, 'git', ['rev-parse', '--short', 'HEAD'])).trim();
|
|
40
|
+
},
|
|
41
|
+
async listFiles(cwd) {
|
|
42
|
+
// -z gives NUL-separated, un-quoted paths (correct for names with spaces/unicode).
|
|
43
|
+
const args = ['ls-files', '-z', '--cached', '--others', '--exclude-standard'];
|
|
44
|
+
const stdout = await runVcsCommand(cwd, 'git', args);
|
|
45
|
+
return stdout.split('\0').filter(Boolean);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=process-vcs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-vcs.js","sourceRoot":"","sources":["../../src/adapters/process-vcs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEhC,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE1C,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,OAAe,EAAE,IAAc;IACvE,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAClF,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,KAAM,GAAa,CAAC,OAAO,EAAE,EAAE;YAC1F,KAAK,EAAE,GAAG;SACX,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,KAAK,CAAC,YAAY,CAAC,GAAW;YAC5B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,CAAC,CAAC;gBAC3E,MAAM,IAAI,GAAG,CAAC,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC7D,IAAI,IAAI;oBAAE,OAAO,IAAI,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,2DAA2D;YAC7D,CAAC;YACD,OAAO,CAAC,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpF,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,GAAW;YACzB,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YACrD,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Packages the build-agent artifacts (Dockerfile, bundled server.js,
|
|
3
|
+
* agent-manifest.json) into a reproducible zip and uploads it to S3. Reads the
|
|
4
|
+
* artifacts through the FileSystem port from the composition-root-resolved
|
|
5
|
+
* `ctx.agentDir`; this module touches no Node API directly.
|
|
6
|
+
*/
|
|
7
|
+
import type { OpsContext } from './context.js';
|
|
8
|
+
/**
|
|
9
|
+
* Package the build-agent (Dockerfile + bundled server) into a zip and upload it to
|
|
10
|
+
* `build/agent/agent-<hash>.zip`. `<hash>` is the reproducible source hash stamped
|
|
11
|
+
* into agent-manifest.json when the agent was bundled — a hash of the agent's
|
|
12
|
+
* *source*, not the bundle, because bundle bytes vary by build platform/toolchain
|
|
13
|
+
* while source bytes are identical everywhere. The MicroVM image is then built from
|
|
14
|
+
* this artifact and keyed by the same hash, so identical source never rebuilds.
|
|
15
|
+
*/
|
|
16
|
+
export declare function packageAndUploadAgent(ctx: OpsContext): Promise<{
|
|
17
|
+
key: string;
|
|
18
|
+
hash: string;
|
|
19
|
+
}>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Packages the build-agent artifacts (Dockerfile, bundled server.js,
|
|
3
|
+
* agent-manifest.json) into a reproducible zip and uploads it to S3. Reads the
|
|
4
|
+
* artifacts through the FileSystem port from the composition-root-resolved
|
|
5
|
+
* `ctx.agentDir`; this module touches no Node API directly.
|
|
6
|
+
*/
|
|
7
|
+
import { zipSync } from 'fflate';
|
|
8
|
+
const IMAGE_PACKAGE_JSON = JSON.stringify({
|
|
9
|
+
name: 'site-builder',
|
|
10
|
+
private: true,
|
|
11
|
+
type: 'module',
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Package the build-agent (Dockerfile + bundled server) into a zip and upload it to
|
|
15
|
+
* `build/agent/agent-<hash>.zip`. `<hash>` is the reproducible source hash stamped
|
|
16
|
+
* into agent-manifest.json when the agent was bundled — a hash of the agent's
|
|
17
|
+
* *source*, not the bundle, because bundle bytes vary by build platform/toolchain
|
|
18
|
+
* while source bytes are identical everywhere. The MicroVM image is then built from
|
|
19
|
+
* this artifact and keyed by the same hash, so identical source never rebuilds.
|
|
20
|
+
*/
|
|
21
|
+
export async function packageAndUploadAgent(ctx) {
|
|
22
|
+
const dir = ctx.agentDir;
|
|
23
|
+
const { fs } = ctx.ports;
|
|
24
|
+
let dockerfile;
|
|
25
|
+
let server;
|
|
26
|
+
let manifest;
|
|
27
|
+
try {
|
|
28
|
+
dockerfile = await fs.readBytes(`${dir}/Dockerfile`);
|
|
29
|
+
server = await fs.readBytes(`${dir}/server.js`);
|
|
30
|
+
manifest = JSON.parse(await fs.readText(`${dir}/agent-manifest.json`));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error(`build-agent artifacts not found in ${dir}. Run "pnpm --filter blogwright build" first.`);
|
|
34
|
+
}
|
|
35
|
+
const hash = manifest.hash;
|
|
36
|
+
if (!hash || !/^[0-9a-f]{12}$/.test(hash)) {
|
|
37
|
+
throw new Error(`agent-manifest.json in ${dir} has no valid hash — rebuild the agent`);
|
|
38
|
+
}
|
|
39
|
+
const entries = {
|
|
40
|
+
Dockerfile: dockerfile,
|
|
41
|
+
'server.js': server,
|
|
42
|
+
'package.json': new TextEncoder().encode(IMAGE_PACKAGE_JSON),
|
|
43
|
+
};
|
|
44
|
+
const zip = zipSync(entries, { level: 6, mtime: new Date('1980-01-01T00:00:00Z') });
|
|
45
|
+
const key = `build/agent/agent-${hash}.zip`;
|
|
46
|
+
await ctx.clients.s3.putObject(ctx.names.bucket, key, zip, 'application/zip');
|
|
47
|
+
return { key, hash };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=agent-package.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-package.js","sourceRoot":"","sources":["../src/agent-package.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAiB,MAAM,QAAQ,CAAC;AAIhD,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC;IACxC,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,QAAQ;CACf,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAe;IAEf,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;IACzB,MAAM,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC;IACzB,IAAI,UAAsB,CAAC;IAC3B,IAAI,MAAkB,CAAC;IACvB,IAAI,QAA2B,CAAC;IAChC,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,GAAG,aAAa,CAAC,CAAC;QACrD,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,GAAG,YAAY,CAAC,CAAC;QAChD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,GAAG,sBAAsB,CAAC,CAAC,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,sCAAsC,GAAG,+CAA+C,CACzF,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,IAAI,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,wCAAwC,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,OAAO,GAAa;QACxB,UAAU,EAAE,UAAU;QACtB,WAAW,EAAE,MAAM;QACnB,cAAc,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC;KAC7D,CAAC;IACF,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IACpF,MAAM,GAAG,GAAG,qBAAqB,IAAI,MAAM,CAAC;IAE5C,MAAM,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAC9E,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACvB,CAAC"}
|
package/dist/bin.d.ts
ADDED
package/dist/bin.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createNodeTerminal } from 'blogwright-core';
|
|
3
|
+
import { main } from './cli.js';
|
|
4
|
+
import { createLogger } from './logger.js';
|
|
5
|
+
const makeTerminal = (opts) => createNodeTerminal(opts);
|
|
6
|
+
main(process.argv.slice(2), makeTerminal)
|
|
7
|
+
.then((code) => {
|
|
8
|
+
process.exitCode = code;
|
|
9
|
+
})
|
|
10
|
+
.catch((err) => {
|
|
11
|
+
createLogger(makeTerminal({ plain: true })).error(err instanceof Error ? err.message : String(err));
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,YAAY,GAAG,CAAC,IAAwB,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAE5E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;KACtC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtB,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAC/C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;IACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Terminal } from 'blogwright-core';
|
|
2
|
+
/** Builds the Terminal after flag parsing, so --plain shapes the whole session. */
|
|
3
|
+
export type TerminalFactory = (opts: {
|
|
4
|
+
plain: boolean;
|
|
5
|
+
}) => Terminal;
|
|
6
|
+
export declare function main(argv: string[], makeTerminal: TerminalFactory): Promise<number>;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
import { createNodeFileSystem } from 'blogwright-core';
|
|
3
|
+
import * as pds from 'blogwright-pds';
|
|
4
|
+
import * as commands from './commands.js';
|
|
5
|
+
import { createContext } from './context.js';
|
|
6
|
+
import { initSite } from './init.js';
|
|
7
|
+
import { createLogger } from './logger.js';
|
|
8
|
+
const USAGE = `blogwright — full operations for a blog site on AWS (S3 + CloudFront, MicroVM builds)
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
blogwright <command> [env] [options]
|
|
12
|
+
|
|
13
|
+
Commands:
|
|
14
|
+
init First-run wizard: writes config/production.jsonc
|
|
15
|
+
bootstrap [env] Create/reconcile the infrastructure graph
|
|
16
|
+
deploy [env] Zip the repo, build in a MicroVM, publish to site/
|
|
17
|
+
rollback <hash> [env] Re-deploy an existing build by hash
|
|
18
|
+
delete [env] Empty the live site/ prefix
|
|
19
|
+
destroy [env] --yes Tear down all infrastructure
|
|
20
|
+
history [env] List deployment history
|
|
21
|
+
logs <hash> [env] Show CloudWatch build logs for a hash
|
|
22
|
+
status [env] Show planned graph vs. live state
|
|
23
|
+
|
|
24
|
+
preview bootstrap Provision the shared preview stack
|
|
25
|
+
preview deploy <id> Build + publish a PR preview (id like pr-42)
|
|
26
|
+
preview destroy <id> Remove one PR preview
|
|
27
|
+
preview list List active previews
|
|
28
|
+
preview teardown --yes Tear down the whole preview stack
|
|
29
|
+
|
|
30
|
+
pds keygen Generate the OAuth client key: private JWK into
|
|
31
|
+
Secrets Manager, public documents into public/oauth/
|
|
32
|
+
(commit + release those before pds login)
|
|
33
|
+
pds login --identifier <handle-or-did>
|
|
34
|
+
Interactive OAuth bootstrap: prints an authorize URL,
|
|
35
|
+
then expects the pasted /oauth/callback redirect URL;
|
|
36
|
+
the session is stored in Secrets Manager and refreshed
|
|
37
|
+
automatically on every sync
|
|
38
|
+
pds secret status Show secret metadata (never the value)
|
|
39
|
+
pds secret delete --yes Delete the secret (logs out and discards the key)
|
|
40
|
+
pds init Create/update the standard.site publication record and
|
|
41
|
+
write the site verification files (commit them)
|
|
42
|
+
pds sync Reconcile site.standard.document records with the
|
|
43
|
+
content collection (production only; also runs after
|
|
44
|
+
every successful production deploy)
|
|
45
|
+
|
|
46
|
+
Options:
|
|
47
|
+
--env <name> Environment (default: production; also accepted positionally)
|
|
48
|
+
--domain <fqdn> Custom domain (ACM cert + CloudFront alias)
|
|
49
|
+
--config <path> Path to a JSONC config file
|
|
50
|
+
--endpoint <url> AWS endpoint override (e.g. http://localhost:4566 for floci)
|
|
51
|
+
--id <preview> Preview id for preview deploy/destroy (also accepted positionally)
|
|
52
|
+
--plain Minimal machine-friendly output (no colour, no live status,
|
|
53
|
+
no prompts) — for CI systems and agents; also automatic when
|
|
54
|
+
output is piped. NO_COLOR disables colour only.
|
|
55
|
+
--yes Confirm destructive operations
|
|
56
|
+
--help Show this help
|
|
57
|
+
`;
|
|
58
|
+
const HASH_COMMANDS = new Set(['rollback', 'logs']);
|
|
59
|
+
const KNOWN_COMMANDS = new Set([
|
|
60
|
+
'bootstrap',
|
|
61
|
+
'deploy',
|
|
62
|
+
'rollback',
|
|
63
|
+
'delete',
|
|
64
|
+
'destroy',
|
|
65
|
+
'history',
|
|
66
|
+
'logs',
|
|
67
|
+
'status',
|
|
68
|
+
]);
|
|
69
|
+
export async function main(argv, makeTerminal) {
|
|
70
|
+
const { values, positionals } = parseArgs({
|
|
71
|
+
args: argv,
|
|
72
|
+
allowPositionals: true,
|
|
73
|
+
options: {
|
|
74
|
+
env: { type: 'string' },
|
|
75
|
+
domain: { type: 'string' },
|
|
76
|
+
config: { type: 'string' },
|
|
77
|
+
endpoint: { type: 'string' },
|
|
78
|
+
hash: { type: 'string' },
|
|
79
|
+
id: { type: 'string' },
|
|
80
|
+
identifier: { type: 'string' },
|
|
81
|
+
plain: { type: 'boolean', default: false },
|
|
82
|
+
yes: { type: 'boolean', default: false },
|
|
83
|
+
help: { type: 'boolean', default: false },
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
const terminal = makeTerminal({ plain: values.plain });
|
|
87
|
+
const logger = createLogger(terminal);
|
|
88
|
+
const command = positionals[0];
|
|
89
|
+
if (!command || values.help) {
|
|
90
|
+
logger.info(USAGE);
|
|
91
|
+
// Asking for help is success; invoking with no command at all is not.
|
|
92
|
+
return values.help || command ? 0 : 1;
|
|
93
|
+
}
|
|
94
|
+
if (command === 'init') {
|
|
95
|
+
// Runs before any context exists — there is no config to load yet.
|
|
96
|
+
return initSite(createNodeFileSystem(), terminal, logger);
|
|
97
|
+
}
|
|
98
|
+
if (command === 'preview') {
|
|
99
|
+
return runPreview(positionals, values, terminal, logger);
|
|
100
|
+
}
|
|
101
|
+
if (command === 'pds') {
|
|
102
|
+
return runPds(positionals, values, terminal, logger);
|
|
103
|
+
}
|
|
104
|
+
if (!KNOWN_COMMANDS.has(command)) {
|
|
105
|
+
logger.error(`unknown command: ${command}`);
|
|
106
|
+
logger.info(USAGE);
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
// Positional layout: rollback/logs take <hash> first, then optional env.
|
|
110
|
+
let hash;
|
|
111
|
+
let envPositional;
|
|
112
|
+
if (HASH_COMMANDS.has(command)) {
|
|
113
|
+
hash = values.hash ?? positionals[1];
|
|
114
|
+
envPositional = positionals[2];
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
envPositional = positionals[1];
|
|
118
|
+
}
|
|
119
|
+
const env = values.env ?? envPositional ?? 'production';
|
|
120
|
+
const ctx = await createContext({
|
|
121
|
+
env,
|
|
122
|
+
configPath: values.config,
|
|
123
|
+
domain: values.domain,
|
|
124
|
+
endpointOverride: values.endpoint,
|
|
125
|
+
ports: { terminal },
|
|
126
|
+
});
|
|
127
|
+
switch (command) {
|
|
128
|
+
case 'bootstrap':
|
|
129
|
+
await commands.bootstrap(ctx);
|
|
130
|
+
break;
|
|
131
|
+
case 'deploy':
|
|
132
|
+
await commands.deploy(ctx);
|
|
133
|
+
break;
|
|
134
|
+
case 'rollback':
|
|
135
|
+
if (!hash)
|
|
136
|
+
throw new Error('rollback requires a <hash>');
|
|
137
|
+
await commands.rollback(ctx, hash);
|
|
138
|
+
break;
|
|
139
|
+
case 'delete':
|
|
140
|
+
await commands.deleteSite(ctx);
|
|
141
|
+
break;
|
|
142
|
+
case 'destroy':
|
|
143
|
+
await commands.destroy(ctx, { yes: values.yes });
|
|
144
|
+
break;
|
|
145
|
+
case 'history':
|
|
146
|
+
await commands.history(ctx);
|
|
147
|
+
break;
|
|
148
|
+
case 'logs':
|
|
149
|
+
if (!hash)
|
|
150
|
+
throw new Error('logs requires a <hash>');
|
|
151
|
+
await commands.logs(ctx, hash);
|
|
152
|
+
break;
|
|
153
|
+
case 'status':
|
|
154
|
+
await commands.status(ctx);
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
logger.error(`unknown command: ${command}`);
|
|
158
|
+
logger.info(USAGE);
|
|
159
|
+
return 1;
|
|
160
|
+
}
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
/** Handle `blogwright pds <action> [env]` (and `pds secret <action> [env]`). */
|
|
164
|
+
async function runPds(positionals, values, terminal, logger) {
|
|
165
|
+
// `pds secret set production` — the secret sub-action shifts positionals by one.
|
|
166
|
+
const secret = positionals[1] === 'secret';
|
|
167
|
+
const action = secret ? `secret ${positionals[2] ?? ''}`.trim() : positionals[1];
|
|
168
|
+
const envPositional = positionals[secret ? 3 : 2];
|
|
169
|
+
const known = new Set(['keygen', 'login', 'init', 'sync', 'secret status', 'secret delete']);
|
|
170
|
+
if (!action || !known.has(action)) {
|
|
171
|
+
logger.error(`unknown pds action: ${action ?? '(none)'}`);
|
|
172
|
+
logger.info(USAGE);
|
|
173
|
+
return 1;
|
|
174
|
+
}
|
|
175
|
+
const ctx = await createContext({
|
|
176
|
+
env: values.env ?? envPositional ?? 'production',
|
|
177
|
+
configPath: values.config,
|
|
178
|
+
domain: values.domain,
|
|
179
|
+
endpointOverride: values.endpoint,
|
|
180
|
+
ports: { terminal },
|
|
181
|
+
});
|
|
182
|
+
switch (action) {
|
|
183
|
+
case 'keygen':
|
|
184
|
+
await pds.keygen(ctx);
|
|
185
|
+
break;
|
|
186
|
+
case 'login':
|
|
187
|
+
await pds.login(ctx, { identifier: values.identifier });
|
|
188
|
+
break;
|
|
189
|
+
case 'secret status':
|
|
190
|
+
await pds.secretStatus(ctx);
|
|
191
|
+
break;
|
|
192
|
+
case 'secret delete':
|
|
193
|
+
await pds.secretDelete(ctx, { yes: values.yes });
|
|
194
|
+
break;
|
|
195
|
+
case 'init':
|
|
196
|
+
await pds.init(ctx);
|
|
197
|
+
break;
|
|
198
|
+
case 'sync':
|
|
199
|
+
await pds.sync(ctx);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
return 0;
|
|
203
|
+
}
|
|
204
|
+
/** Handle `blogwright preview <action> [id]` (always the shared `preview` stack). */
|
|
205
|
+
const PREVIEW_ACTIONS = new Set(['bootstrap', 'deploy', 'destroy', 'list', 'teardown']);
|
|
206
|
+
async function runPreview(positionals, values, terminal, logger) {
|
|
207
|
+
const action = positionals[1];
|
|
208
|
+
const id = values.id ?? positionals[2];
|
|
209
|
+
if (!action || !PREVIEW_ACTIONS.has(action)) {
|
|
210
|
+
logger.error(`unknown preview action: ${action ?? '(none)'}`);
|
|
211
|
+
logger.info(USAGE);
|
|
212
|
+
return 1;
|
|
213
|
+
}
|
|
214
|
+
const ctx = await createContext({
|
|
215
|
+
env: 'preview',
|
|
216
|
+
preview: true,
|
|
217
|
+
configPath: values.config,
|
|
218
|
+
domain: values.domain,
|
|
219
|
+
endpointOverride: values.endpoint,
|
|
220
|
+
ports: { terminal },
|
|
221
|
+
});
|
|
222
|
+
switch (action) {
|
|
223
|
+
case 'bootstrap':
|
|
224
|
+
await commands.previewBootstrap(ctx);
|
|
225
|
+
break;
|
|
226
|
+
case 'deploy':
|
|
227
|
+
if (!id)
|
|
228
|
+
throw new Error('preview deploy requires an <id> (e.g. pr-42)');
|
|
229
|
+
await commands.previewDeploy(ctx, id);
|
|
230
|
+
break;
|
|
231
|
+
case 'destroy':
|
|
232
|
+
if (!id)
|
|
233
|
+
throw new Error('preview destroy requires an <id>');
|
|
234
|
+
await commands.previewDestroy(ctx, id);
|
|
235
|
+
break;
|
|
236
|
+
case 'list':
|
|
237
|
+
await commands.previewList(ctx);
|
|
238
|
+
break;
|
|
239
|
+
case 'teardown':
|
|
240
|
+
await commands.previewTeardown(ctx, { yes: values.yes });
|
|
241
|
+
break;
|
|
242
|
+
default:
|
|
243
|
+
logger.error(`unknown preview action: ${action ?? '(none)'}`);
|
|
244
|
+
logger.info(USAGE);
|
|
245
|
+
return 1;
|
|
246
|
+
}
|
|
247
|
+
return 0;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { OpsContext } from './context.js';
|
|
2
|
+
/** Create the full infrastructure graph. */
|
|
3
|
+
export declare function bootstrap(ctx: OpsContext): Promise<void>;
|
|
4
|
+
/** Destroy the full infrastructure graph. */
|
|
5
|
+
export declare function destroy(ctx: OpsContext, opts: {
|
|
6
|
+
yes: boolean;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
/** Zip the repo, upload it, run the builder MicroVM, and invalidate the cache. */
|
|
9
|
+
export declare function deploy(ctx: OpsContext): Promise<void>;
|
|
10
|
+
/** Re-run the builder against an existing source zip for the given hash. */
|
|
11
|
+
export declare function rollback(ctx: OpsContext, hash: string): Promise<void>;
|
|
12
|
+
/** Provision the shared preview stack (one CloudFront distribution + host router + OIDC role). */
|
|
13
|
+
export declare function previewBootstrap(ctx: OpsContext): Promise<void>;
|
|
14
|
+
/** Build the current repo and publish it to this PR's preview prefix. Prints the URL. */
|
|
15
|
+
export declare function previewDeploy(ctx: OpsContext, id: string): Promise<string>;
|
|
16
|
+
/** Remove one PR's preview (delete its prefix). No invalidation — previews aren't cached. */
|
|
17
|
+
export declare function previewDestroy(ctx: OpsContext, id: string): Promise<void>;
|
|
18
|
+
/** List active previews (by prefix). */
|
|
19
|
+
export declare function previewList(ctx: OpsContext): Promise<void>;
|
|
20
|
+
/** Tear down the entire shared preview stack. */
|
|
21
|
+
export declare function previewTeardown(ctx: OpsContext, opts: {
|
|
22
|
+
yes: boolean;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
/** Empty the live site/ prefix (leaves infra and build history intact). */
|
|
25
|
+
export declare function deleteSite(ctx: OpsContext): Promise<void>;
|
|
26
|
+
/** List deployment history from build manifests. */
|
|
27
|
+
export declare function history(ctx: OpsContext): Promise<void>;
|
|
28
|
+
/** Show CloudWatch build logs for a given hash. */
|
|
29
|
+
export declare function logs(ctx: OpsContext, hash: string): Promise<void>;
|
|
30
|
+
/** Show the planned graph against live state (drift view). */
|
|
31
|
+
export declare function status(ctx: OpsContext): Promise<void>;
|