@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.
Files changed (4) hide show
  1. package/README.md +16 -0
  2. package/cli.js +43 -0
  3. package/index.js +4 -0
  4. 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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tallpond/cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "The tallpond developer CLI — sign in, register an app, and deploy schema + frontend with one command.",
5
5
  "license": "MIT",
6
6
  "repository": {