@project-ajax/sdk 0.0.55 → 0.0.57

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 (48) hide show
  1. package/dist/cli/api/client.d.ts +2 -2
  2. package/dist/cli/api/client.d.ts.map +1 -1
  3. package/dist/cli/commands/auth.impl.d.ts.map +1 -1
  4. package/dist/cli/commands/auth.impl.js +13 -9
  5. package/dist/cli/commands/bundle.impl.js +2 -2
  6. package/dist/cli/commands/capabilities.impl.js +4 -4
  7. package/dist/cli/commands/connect.impl.js +13 -13
  8. package/dist/cli/commands/deploy.impl.d.ts.map +1 -1
  9. package/dist/cli/commands/deploy.impl.js +10 -16
  10. package/dist/cli/commands/env.impl.d.ts.map +1 -1
  11. package/dist/cli/commands/env.impl.js +7 -10
  12. package/dist/cli/commands/exec.impl.d.ts.map +1 -1
  13. package/dist/cli/commands/exec.impl.js +14 -16
  14. package/dist/cli/commands/runs.impl.js +7 -7
  15. package/dist/cli/commands/secrets.impl.js +12 -12
  16. package/dist/cli/commands/utils/testing.d.ts +2 -11
  17. package/dist/cli/commands/utils/testing.d.ts.map +1 -1
  18. package/dist/cli/commands/utils/testing.js +4 -4
  19. package/dist/cli/config.d.ts.map +1 -1
  20. package/dist/cli/config.js +3 -6
  21. package/dist/cli/context.d.ts +2 -2
  22. package/dist/cli/context.d.ts.map +1 -1
  23. package/dist/cli/context.js +3 -3
  24. package/dist/cli/deploy.js +11 -11
  25. package/dist/cli/handler.js +2 -2
  26. package/dist/cli/{writer.d.ts → io.d.ts} +10 -3
  27. package/dist/cli/io.d.ts.map +1 -0
  28. package/dist/cli/{writer.js → io.js} +24 -2
  29. package/package.json +3 -3
  30. package/src/cli/api/client.ts +3 -3
  31. package/src/cli/commands/auth.impl.test.ts +4 -2
  32. package/src/cli/commands/auth.impl.ts +17 -9
  33. package/src/cli/commands/bundle.impl.ts +2 -2
  34. package/src/cli/commands/capabilities.impl.ts +4 -4
  35. package/src/cli/commands/connect.impl.ts +13 -13
  36. package/src/cli/commands/deploy.impl.test.ts +9 -14
  37. package/src/cli/commands/deploy.impl.ts +11 -16
  38. package/src/cli/commands/env.impl.ts +7 -11
  39. package/src/cli/commands/exec.impl.ts +14 -16
  40. package/src/cli/commands/runs.impl.ts +7 -7
  41. package/src/cli/commands/secrets.impl.ts +12 -12
  42. package/src/cli/commands/utils/testing.ts +5 -4
  43. package/src/cli/config.ts +2 -5
  44. package/src/cli/context.ts +3 -3
  45. package/src/cli/deploy.ts +11 -11
  46. package/src/cli/handler.ts +2 -2
  47. package/src/cli/{writer.ts → io.ts} +34 -2
  48. package/dist/cli/writer.d.ts.map +0 -1
@@ -19,9 +19,9 @@ export const listRuns = buildAuthedHandler(async function (flags: FormatFlags) {
19
19
 
20
20
  const data = Result.unwrap(result);
21
21
  if (data.runs.length === 0) {
22
- this.writer.writeErr("No runs found for this worker.");
22
+ this.io.writeErr("No runs found for this worker.");
23
23
  } else {
24
- this.writer.writeTableOut({
24
+ this.io.writeTableOut({
25
25
  headers: ["Run ID", "Name", "Started At", "Ended At", "Exit Code"],
26
26
  rows: data.runs.map((run) => [
27
27
  run.runId,
@@ -38,10 +38,10 @@ export const listRuns = buildAuthedHandler(async function (flags: FormatFlags) {
38
38
 
39
39
  // If it's a validation error, show the clean debug message
40
40
  if (result.error.validationError) {
41
- this.writer.writeErr(`✗ ${result.error.validationError.debugMessage}`);
41
+ this.io.writeErr(`✗ ${result.error.validationError.debugMessage}`);
42
42
  throw new Error(result.error.validationError.debugMessage);
43
43
  } else {
44
- this.writer.writeErr(`✗ ${result.error.message}`);
44
+ this.io.writeErr(`✗ ${result.error.message}`);
45
45
  throw new Error(result.error.message);
46
46
  }
47
47
  }
@@ -71,16 +71,16 @@ export const getRunLogs = buildAuthedHandler(async function (
71
71
 
72
72
  const data = Result.unwrap(result);
73
73
  // Output logs directly to stdout (primary output)
74
- this.writer.writeOut(data.logs);
74
+ this.io.writeOut(data.logs);
75
75
  } else {
76
76
  this.process.stderr.write("ERROR\n\n");
77
77
 
78
78
  // If it's a validation error, show the clean debug message
79
79
  if (result.error.validationError) {
80
- this.writer.writeErr(`✗ ${result.error.validationError.debugMessage}`);
80
+ this.io.writeErr(`✗ ${result.error.validationError.debugMessage}`);
81
81
  throw new Error(result.error.validationError.debugMessage);
82
82
  } else {
83
- this.writer.writeErr(`✗ ${result.error.message}`);
83
+ this.io.writeErr(`✗ ${result.error.message}`);
84
84
  throw new Error(result.error.message);
85
85
  }
86
86
  }
@@ -17,17 +17,17 @@ export const setSecrets = buildAuthedHandler(async function (
17
17
  );
18
18
  }
19
19
 
20
- this.writer.writeErr(`Setting ${pluralize(secrets.length, "secret")}...`);
20
+ this.io.writeErr(`Setting ${pluralize(secrets.length, "secret")}...`);
21
21
 
22
22
  const result = await this.apiClient.upsertSecrets(workerId, secrets);
23
23
 
24
24
  if (Result.isSuccess(result)) {
25
25
  for (const secret of Result.unwrap(result).secrets) {
26
- this.writer.writeErr(`Set secret "${secret.key}"`);
26
+ this.io.writeErr(`Set secret "${secret.key}"`);
27
27
  }
28
28
  } else {
29
- this.writer.writeErr(`✗ Failed to set secrets`);
30
- this.writer.writeErr(`✗ ${result.error.message}`);
29
+ this.io.writeErr(`✗ Failed to set secrets`);
30
+ this.io.writeErr(`✗ ${result.error.message}`);
31
31
  throw new Error(result.error.message);
32
32
  }
33
33
  });
@@ -51,25 +51,25 @@ export const listSecrets = buildAuthedHandler(async function (
51
51
 
52
52
  const data = Result.unwrap(result);
53
53
  if (data.secrets.length === 0) {
54
- this.writer.writeErr("No secrets for this worker.");
55
- this.writer.writeErr(
54
+ this.io.writeErr("No secrets for this worker.");
55
+ this.io.writeErr(
56
56
  "To list OAuth connect secrets, use `npx workers connect list`",
57
57
  );
58
58
  } else {
59
- this.writer.writeTableOut({
59
+ this.io.writeTableOut({
60
60
  headers: ["Key", "Created At"],
61
61
  rows: data.secrets.map((secret) => [secret.key, secret.createdAt]),
62
62
  plain: flags.plain,
63
63
  });
64
- this.writer.writeErr(
64
+ this.io.writeErr(
65
65
  "To list OAuth connect secrets, use `npx workers connect list`",
66
66
  );
67
67
  }
68
68
  } else {
69
69
  this.process.stderr.write("ERROR\n\n");
70
70
 
71
- this.writer.writeErr(`✗ Failed to list secrets`);
72
- this.writer.writeErr(`✗ ${result.error.message}`);
71
+ this.io.writeErr(`✗ Failed to list secrets`);
72
+ this.io.writeErr(`✗ ${result.error.message}`);
73
73
  throw new Error(result.error.message);
74
74
  }
75
75
  });
@@ -94,8 +94,8 @@ export const removeSecret = buildAuthedHandler(async function (
94
94
  } else {
95
95
  this.process.stderr.write("ERROR\n\n");
96
96
 
97
- this.writer.writeErr(`✗ Failed to remove secret "${key}"`);
98
- this.writer.writeErr(`✗ ${result.error.message}`);
97
+ this.io.writeErr(`✗ Failed to remove secret "${key}"`);
98
+ this.io.writeErr(`✗ ${result.error.message}`);
99
99
  throw new Error(result.error.message);
100
100
  }
101
101
  });
@@ -4,8 +4,9 @@ import * as os from "node:os";
4
4
  import { tmpdir } from "node:os";
5
5
  import * as path from "node:path";
6
6
  import { Config, type ConfigMap } from "../../config.js";
7
+ import type { LocalContext } from "../../context.js";
7
8
  import type { GlobalFlags } from "../../flags.js";
8
- import { Writer } from "../../writer.js";
9
+ import { IO } from "../../io.js";
9
10
 
10
11
  export const tmpDirectories: string[] = [];
11
12
 
@@ -36,13 +37,13 @@ export async function createAndLoadConfig({
36
37
  return [map, configFilePath];
37
38
  }
38
39
 
39
- export function createBaseContext() {
40
+ export function createBaseContext(): LocalContext {
40
41
  return {
41
- writer: new Writer({ debugEnabled: false }),
42
- process,
43
42
  fs,
43
+ io: new IO({ debugEnabled: false }),
44
44
  os,
45
45
  path,
46
+ process,
46
47
  };
47
48
  }
48
49
 
package/src/cli/config.ts CHANGED
@@ -141,9 +141,8 @@ export class Config {
141
141
  partialConfig.workerId = opts.flags["worker-id"];
142
142
  }
143
143
 
144
- partialConfig.baseUrl ??= baseUrlForEnvironment(
145
- partialConfig.environment ?? "prod",
146
- );
144
+ partialConfig.environment ??= "prod";
145
+ partialConfig.baseUrl ??= baseUrlForEnvironment(partialConfig.environment);
147
146
 
148
147
  const environment = partialConfig.environment;
149
148
  if (!environment) {
@@ -194,8 +193,6 @@ export class Config {
194
193
  configFile = {
195
194
  token: null,
196
195
  workerId: null,
197
- environment: "prod",
198
- baseUrl: baseUrlForEnvironment("prod"),
199
196
  };
200
197
  } else {
201
198
  throw error;
@@ -3,24 +3,24 @@ import * as os from "node:os";
3
3
  import * as path from "node:path";
4
4
  import type { StricliAutoCompleteContext } from "@stricli/auto-complete";
5
5
  import type { CommandContext } from "@stricli/core";
6
- import { Writer } from "./writer.js";
6
+ import { IO } from "./io.js";
7
7
 
8
8
  export interface LocalContext
9
9
  extends CommandContext,
10
10
  StricliAutoCompleteContext {
11
11
  readonly fs: typeof fs;
12
+ readonly io: IO;
12
13
  readonly os: typeof os;
13
14
  readonly path: typeof path;
14
15
  readonly process: NodeJS.Process;
15
- readonly writer: Writer;
16
16
  }
17
17
 
18
18
  export function buildContext(process: NodeJS.Process): LocalContext {
19
19
  return {
20
20
  fs,
21
+ io: new IO({ debugEnabled: false }),
21
22
  os,
22
23
  path,
23
24
  process,
24
- writer: new Writer({ debugEnabled: false }),
25
25
  };
26
26
  }
package/src/cli/deploy.ts CHANGED
@@ -53,7 +53,7 @@ export async function deployWorker(
53
53
 
54
54
  // Resolve absolute path
55
55
  const absPath = path.resolve(process.cwd(), workerPath);
56
- context.writer.debug(`Deploying worker from: ${absPath}`);
56
+ context.io.debug(`Deploying worker from: ${absPath}`);
57
57
 
58
58
  // Create API client
59
59
  const client = context.apiClient;
@@ -63,7 +63,7 @@ export async function deployWorker(
63
63
  let workerId: string;
64
64
 
65
65
  if ("workerId" in options) {
66
- context.writer.writeErr(`Updating worker...`);
66
+ context.io.writeErr(`Updating worker...`);
67
67
 
68
68
  workerId = options.workerId;
69
69
 
@@ -73,13 +73,13 @@ export async function deployWorker(
73
73
  uploadUrl = res.url;
74
74
  uploadFields = res.fields;
75
75
  } else {
76
- context.writer.writeErr(
76
+ context.io.writeErr(
77
77
  "Failed to generate pre-signed upload URL for worker bundle:",
78
78
  );
79
79
  throw new Error(updateResult.error.message);
80
80
  }
81
81
  } else {
82
- context.writer.writeErr(`Creating worker...`);
82
+ context.io.writeErr(`Creating worker...`);
83
83
 
84
84
  const createResult = await client.createWorker(options.name);
85
85
  if (Result.isSuccess(createResult)) {
@@ -93,20 +93,20 @@ export async function deployWorker(
93
93
  }
94
94
  }
95
95
 
96
- context.writer.debug(`Generated upload URL: ${uploadUrl}`);
96
+ context.io.debug(`Generated upload URL: ${uploadUrl}`);
97
97
 
98
98
  // Build the worker bundle
99
- context.writer.writeErr("Building worker bundle...");
99
+ context.io.writeErr("Building worker bundle...");
100
100
  const archivePath = await buildWorkerBundle(context, absPath);
101
- context.writer.debug(`Created bundle at: ${archivePath}`);
101
+ context.io.debug(`Created bundle at: ${archivePath}`);
102
102
 
103
103
  // Upload the bundle
104
- context.writer.writeErr("Uploading bundle...");
104
+ context.io.writeErr("Uploading bundle...");
105
105
  await uploadBundle(uploadUrl, uploadFields, archivePath);
106
- context.writer.debug("Upload complete");
106
+ context.io.debug("Upload complete");
107
107
 
108
108
  // Fetch and save capabilities
109
- context.writer.writeErr("Fetching and saving worker capabilities...");
109
+ context.io.writeErr("Fetching and saving worker capabilities...");
110
110
  const capabilitiesResult = await client.fetchAndSaveCapabilities(workerId);
111
111
 
112
112
  if (Result.isSuccess(capabilitiesResult)) {
@@ -141,7 +141,7 @@ async function buildWorkerBundle(
141
141
  platform: "node",
142
142
  });
143
143
 
144
- context.writer.debug(`Built bundle to: ${outdir}`);
144
+ context.io.debug(`Built bundle to: ${outdir}`);
145
145
 
146
146
  // Create tar.gz archive
147
147
  const archiveDir = fs.mkdtempSync("/tmp/workers-archive-");
@@ -35,7 +35,7 @@ export function buildHandler<const FLAGS, const ARGS extends BaseArgs = []>(
35
35
  flags,
36
36
  });
37
37
 
38
- this.writer.debugEnabled = flags.debug;
38
+ this.io.debugEnabled = flags.debug;
39
39
 
40
40
  await handler.call({ ...this, config }, flags, ...args);
41
41
  };
@@ -61,7 +61,7 @@ export function buildAuthedHandler<
61
61
  environment,
62
62
  baseUrl: this.config.baseUrl,
63
63
  cellId,
64
- writer: this.writer,
64
+ writer: this.io,
65
65
  });
66
66
  return handler.call({ ...this, apiClient: client }, flags, ...args);
67
67
  });
@@ -1,3 +1,4 @@
1
+ import * as prompts from "@inquirer/prompts";
1
2
  import { createTable, type TableCell, type TableItem } from "@visulima/tabular";
2
3
 
3
4
  export interface WriterOptions {
@@ -10,10 +11,14 @@ export interface TableOptions {
10
11
  plain: boolean;
11
12
  }
12
13
 
14
+ type WithSafety<T> = T & {
15
+ noTTY: string;
16
+ };
17
+
13
18
  /**
14
- * A writer writes messages to standard out and standard error.
19
+ * IO manages safe, consistent, input and output patterns for the CLI.
15
20
  */
16
- export class Writer {
21
+ export class IO {
17
22
  debugEnabled: boolean;
18
23
 
19
24
  constructor(options: WriterOptions) {
@@ -74,6 +79,33 @@ export class Writer {
74
79
  this.writeErr(content);
75
80
  }
76
81
 
82
+ confirm(config: WithSafety<Parameters<typeof prompts.confirm>[0]>) {
83
+ if (!process.stdin.isTTY) {
84
+ this.writeErr(config.noTTY);
85
+ process.exit(1);
86
+ }
87
+
88
+ return prompts.confirm(config).catch(this.#handlePromptExit.bind(this));
89
+ }
90
+
91
+ input(config: WithSafety<Parameters<typeof prompts.input>[0]>) {
92
+ if (!process.stdin.isTTY) {
93
+ this.writeErr(config.noTTY);
94
+ process.exit(1);
95
+ }
96
+
97
+ return prompts.input(config).catch(this.#handlePromptExit.bind(this));
98
+ }
99
+
100
+ #handlePromptExit(err: unknown) {
101
+ if (err instanceof Error && err.name === "ExitPromptError") {
102
+ this.writeErr("👋 Prompt cancelled. Goodbye!");
103
+ process.exit(1);
104
+ }
105
+
106
+ throw err;
107
+ }
108
+
77
109
  #buildTable(tableConfig: TableOptions) {
78
110
  if (tableConfig.plain) {
79
111
  return tableConfig.rows
@@ -1 +0,0 @@
1
- {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/cli/writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,SAAS,EAAkB,MAAM,mBAAmB,CAAC;AAEhF,MAAM,WAAW,aAAa;IAC7B,YAAY,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,EAAE,CAAC;IACrC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,qBAAa,MAAM;;IAClB,YAAY,EAAE,OAAO,CAAC;gBAEV,OAAO,EAAE,aAAa;IAIlC;;;;OAIG;IACH,KAAK,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,GAAG,CAAC;IAW7C;;;;OAIG;IACH,QAAQ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAIzD;;;;OAIG;IACH,QAAQ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAIzD;;;;OAIG;IACH,aAAa,CAAC,WAAW,EAAE,YAAY;IAKvC;;;;OAIG;IACH,aAAa,CAAC,WAAW,EAAE,YAAY;CAqBvC"}