@tallpond/cli 0.0.4 → 0.0.5
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 +16 -0
- package/cli.js +43 -0
- package/index.js +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,6 +83,22 @@ scanned, and handlers can import from them freely (everything is bundled). A
|
|
|
83
83
|
top-level file without a default export is skipped with a warning rather than
|
|
84
84
|
deployed.
|
|
85
85
|
|
|
86
|
+
## `tallpond test-session [--user name]`
|
|
87
|
+
|
|
88
|
+
End-to-end testing without a browser: mints a bearer token for a synthetic
|
|
89
|
+
test user of your app. Test users have no wallet — their usage bills your own
|
|
90
|
+
balance directly (bounded by your per-app budget), and tokens expire after
|
|
91
|
+
24h. The token alone goes to stdout:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
ALICE=$(tallpond test-session --user alice)
|
|
95
|
+
curl -H "Authorization: Bearer $ALICE" https://api.tallpond.com/v1/users/me
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
It authenticates on every user-facing route — tables, resources, functions,
|
|
99
|
+
files, AI — as that user, metering normally. Mint two names for multi-user
|
|
100
|
+
flows.
|
|
101
|
+
|
|
86
102
|
Full command reference: <https://tallpond.com> → docs → CLI.
|
|
87
103
|
|
|
88
104
|
## License
|
package/cli.js
CHANGED
|
@@ -306,6 +306,9 @@ function deployFunctionsAsDev(gatewayUrl, token, appId, bundle, fetcher = fetch)
|
|
|
306
306
|
bundle
|
|
307
307
|
);
|
|
308
308
|
}
|
|
309
|
+
function createTestSession(gatewayUrl, token, appId, name, fetcher = fetch) {
|
|
310
|
+
return request(fetcher, gatewayUrl, token, "POST", `dev/apps/${appId}/test-users`, { name });
|
|
311
|
+
}
|
|
309
312
|
function collectBundleFiles(dir) {
|
|
310
313
|
const out = [];
|
|
311
314
|
const walk = (d) => {
|
|
@@ -512,6 +515,7 @@ Usage:
|
|
|
512
515
|
tallpond apps list List your apps
|
|
513
516
|
tallpond deploy [schemaFile] Deploy the app: schema + functions/ + built bundle
|
|
514
517
|
tallpond typegen [schemaFile] Generate row types (--out tallpond-env.d.ts)
|
|
518
|
+
tallpond test-session Mint a bearer token for a synthetic test user
|
|
515
519
|
tallpond help Show this help
|
|
516
520
|
|
|
517
521
|
Common flags:
|
|
@@ -525,6 +529,10 @@ deploy flags:
|
|
|
525
529
|
--no-bundle deploy the schema only
|
|
526
530
|
schemaFile defaults to ./.tallpond.schema.ts (skipped if absent)
|
|
527
531
|
|
|
532
|
+
test-session flags:
|
|
533
|
+
--user <name> which test user (default "default"; same name = same user)
|
|
534
|
+
--json print the full response as JSON instead of just the token
|
|
535
|
+
|
|
528
536
|
Platform/CI escape hatch (bypasses login; uses the shared deploy token):
|
|
529
537
|
--app-id <id> --deployment-id <id> --token <token>
|
|
530
538
|
[env TALLPOND_APP_ID, TALLPOND_DEPLOYMENT_ID, TALLPOND_DEPLOY_TOKEN]
|
|
@@ -543,6 +551,7 @@ async function main(argv) {
|
|
|
543
551
|
if (command === "create") return await runAppsCreate(argv.slice(1));
|
|
544
552
|
if (command === "deploy") return await runDeploy(argv.slice(1));
|
|
545
553
|
if (command === "typegen") return await runTypegen(argv.slice(1));
|
|
554
|
+
if (command === "test-session") return await runTestSession(argv.slice(1));
|
|
546
555
|
} catch (e) {
|
|
547
556
|
if (e instanceof DevApiError) {
|
|
548
557
|
if (e.status === 401) {
|
|
@@ -820,6 +829,40 @@ ${renderBlockedChanges(result.changes)}
|
|
|
820
829
|
}
|
|
821
830
|
return 1;
|
|
822
831
|
}
|
|
832
|
+
async function runTestSession(args) {
|
|
833
|
+
const { values } = parseArgs({
|
|
834
|
+
args,
|
|
835
|
+
allowPositionals: false,
|
|
836
|
+
options: {
|
|
837
|
+
"gateway-url": { type: "string" },
|
|
838
|
+
user: { type: "string" },
|
|
839
|
+
json: { type: "boolean" }
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
const project = readProjectConfig();
|
|
843
|
+
if (!project) {
|
|
844
|
+
process.stderr.write(`error: no ${PROJECT_CONFIG_FILE} here \u2014 run \`tallpond apps create <name>\` first
|
|
845
|
+
`);
|
|
846
|
+
return 1;
|
|
847
|
+
}
|
|
848
|
+
const gatewayUrl = resolveGatewayUrl(values["gateway-url"] ?? project.gatewayUrl);
|
|
849
|
+
const token = requireToken(gatewayUrl);
|
|
850
|
+
const session = await createTestSession(gatewayUrl, token, project.appId, values.user ?? "default");
|
|
851
|
+
if (values.json) {
|
|
852
|
+
process.stdout.write(`${JSON.stringify(session, null, 2)}
|
|
853
|
+
`);
|
|
854
|
+
return 0;
|
|
855
|
+
}
|
|
856
|
+
process.stderr.write(
|
|
857
|
+
`test user ${session.user_id} \u2014 usage bills your own balance (token expires ${session.expires_at})
|
|
858
|
+
use it as a bearer token, e.g.
|
|
859
|
+
curl -H "Authorization: Bearer <token>" ${gatewayUrl}/v1/users/me
|
|
860
|
+
`
|
|
861
|
+
);
|
|
862
|
+
process.stdout.write(`${session.token}
|
|
863
|
+
`);
|
|
864
|
+
return 0;
|
|
865
|
+
}
|
|
823
866
|
async function runTypegen(args) {
|
|
824
867
|
const { values, positionals } = parseArgs({
|
|
825
868
|
args,
|
package/index.js
CHANGED
|
@@ -241,6 +241,9 @@ function deployFunctionsAsDev(gatewayUrl, token, appId, bundle, fetcher = fetch)
|
|
|
241
241
|
bundle
|
|
242
242
|
);
|
|
243
243
|
}
|
|
244
|
+
function createTestSession(gatewayUrl, token, appId, name, fetcher = fetch) {
|
|
245
|
+
return request(fetcher, gatewayUrl, token, "POST", `dev/apps/${appId}/test-users`, { name });
|
|
246
|
+
}
|
|
244
247
|
function collectBundleFiles(dir) {
|
|
245
248
|
const out = [];
|
|
246
249
|
const walk = (d) => {
|
|
@@ -340,6 +343,7 @@ export {
|
|
|
340
343
|
PROJECT_CONFIG_FILE,
|
|
341
344
|
collectBundleFiles,
|
|
342
345
|
createApp,
|
|
346
|
+
createTestSession,
|
|
343
347
|
deploy,
|
|
344
348
|
deployFunctionsAsDev,
|
|
345
349
|
deploySchemaAsDev,
|