@project-ajax/sdk 0.0.34 → 0.0.36

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.
@@ -122,14 +122,40 @@ export declare class ApiClient {
122
122
  /**
123
123
  * List all secrets for a worker (keys only, not values)
124
124
  */
125
- listSecrets(workerId: string): Promise<Result<{
125
+ listSecrets(workerId: string, options?: {
126
+ secretKinds?: Array<"keyValue" | "oauth">;
127
+ }): Promise<Result<{
126
128
  secrets: Array<{
127
129
  spaceId: string;
128
130
  workerId: string;
129
131
  key: string;
130
132
  createdAt: string;
133
+ kind: "keyValue" | "oauth";
131
134
  }>;
132
135
  }, ApiError>>;
136
+ listOauthProviders(): Promise<Result<{
137
+ providers: Array<{
138
+ key: string;
139
+ displayName: string;
140
+ }>;
141
+ }, ApiError>>;
142
+ /**
143
+ * Start the OAuth flow for a provider
144
+ */
145
+ startOauth(args: {
146
+ workerId: string;
147
+ provider: string;
148
+ }): Promise<Result<{
149
+ authorizationUrl: string;
150
+ state: string;
151
+ }, ApiError>>;
152
+ /**
153
+ * Remove an OAuth connection for a worker
154
+ */
155
+ deleteOauthConnection(args: {
156
+ workerId: string;
157
+ provider: string;
158
+ }): Promise<Result<Record<string, never>, ApiError>>;
133
159
  /**
134
160
  * Delete a secret
135
161
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/cli/api/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/cli/api/client.ts"],"names":[],"mappings":"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"}
@@ -160,11 +160,42 @@ class ApiClient {
160
160
  /**
161
161
  * List all secrets for a worker (keys only, not values)
162
162
  */
163
- async listSecrets(workerId) {
163
+ async listSecrets(workerId, options) {
164
164
  return this.fetch("/workersListSecrets", {
165
165
  method: "POST",
166
166
  body: {
167
- workerId
167
+ workerId,
168
+ secretKinds: options?.secretKinds
169
+ }
170
+ });
171
+ }
172
+ async listOauthProviders() {
173
+ return this.fetch("/workersListOauthProviders", {
174
+ method: "POST",
175
+ body: {}
176
+ });
177
+ }
178
+ /**
179
+ * Start the OAuth flow for a provider
180
+ */
181
+ async startOauth(args) {
182
+ return this.fetch("/workersStartOauth", {
183
+ method: "POST",
184
+ body: {
185
+ workerId: args.workerId,
186
+ provider: args.provider
187
+ }
188
+ });
189
+ }
190
+ /**
191
+ * Remove an OAuth connection for a worker
192
+ */
193
+ async deleteOauthConnection(args) {
194
+ return this.fetch("/workersDeleteOauthConnection", {
195
+ method: "POST",
196
+ body: {
197
+ workerId: args.workerId,
198
+ provider: args.provider
168
199
  }
169
200
  });
170
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.impl.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/auth.impl.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,UAAU,UAAU;IACnB,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAqCD,eAAO,MAAM,KAAK,kJAqChB,CAAC;AAEH,eAAO,MAAM,IAAI,yGAEf,CAAC;AAEH,eAAO,MAAM,MAAM,yGAEjB,CAAC"}
1
+ {"version":3,"file":"auth.impl.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/auth.impl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAIhD,UAAU,UAAU;IACnB,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,KAAK,kJAqChB,CAAC;AAEH,eAAO,MAAM,IAAI,yGAEf,CAAC;AAEH,eAAO,MAAM,MAAM,yGAEjB,CAAC"}
@@ -1,31 +1,6 @@
1
- import { exec } from "node:child_process";
2
- import { existsSync } from "node:fs";
3
1
  import { baseUrl } from "../api/client.js";
4
2
  import { buildHandler } from "../handler.js";
5
- async function openUrl(env, url) {
6
- const platform = process.platform;
7
- try {
8
- if (platform === "darwin") {
9
- let notionAppName = null;
10
- if (env === "prod" && existsSync("/Applications/Notion.app")) {
11
- notionAppName = "Notion";
12
- } else if (env === "dev" && existsSync("/Applications/Notion Dev.app")) {
13
- notionAppName = "Notion Dev";
14
- }
15
- if (notionAppName) {
16
- exec(`open -a "${notionAppName}" "${url}"`);
17
- } else {
18
- exec(`open "${url}"`);
19
- }
20
- } else if (platform === "win32") {
21
- exec(`start "" "${url}"`);
22
- } else {
23
- exec(`xdg-open "${url}"`);
24
- }
25
- } catch (error) {
26
- throw new Error(`Failed to open browser: ${error}`);
27
- }
28
- }
3
+ import { openNotionUrl } from "../utils/openNotionUrl.js";
29
4
  const login = buildHandler(async function(flags, token) {
30
5
  const environment = flags.env ?? "prod";
31
6
  if (flags["base-url"]) {
@@ -42,7 +17,7 @@ ${url}
42
17
  this.writer.writeErr("After creating a token, run:");
43
18
  this.writer.writeErr(" npx workers auth login <token>");
44
19
  try {
45
- await openUrl(environment, url);
20
+ await openNotionUrl(environment, url);
46
21
  } catch (_error) {
47
22
  this.writer.writeErr(
48
23
  `Failed to open browser automatically. Please visit:
@@ -0,0 +1,2 @@
1
+ export declare const connectCommands: import("@stricli/core").RouteMap<import("../context.js").LocalContext>;
2
+ //# sourceMappingURL=connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/connect.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,wEA2E1B,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { FormatFlags, GlobalFlags } from "../flags.js";
2
+ export declare const listProviders: (this: import("../context.js").LocalContext, flags: GlobalFlags & FormatFlags) => Promise<void>;
3
+ export declare const addConnection: (this: import("../context.js").LocalContext, flags: GlobalFlags, provider: string) => Promise<void>;
4
+ export declare const listConnections: (this: import("../context.js").LocalContext, flags: GlobalFlags & FormatFlags) => Promise<void>;
5
+ export declare const removeConnection: (this: import("../context.js").LocalContext, flags: GlobalFlags, provider: string) => Promise<void>;
6
+ //# sourceMappingURL=connect.impl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.impl.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/connect.impl.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI5D,eAAO,MAAM,aAAa,iGAuBxB,CAAC;AAEH,eAAO,MAAM,aAAa,qGAuCxB,CAAC;AAEH,eAAO,MAAM,eAAe,iGAiC1B,CAAC;AAEH,eAAO,MAAM,gBAAgB,qGAqB3B,CAAC"}
@@ -0,0 +1,116 @@
1
+ import { Result } from "../api/result.js";
2
+ import { buildAuthedHandler } from "../handler.js";
3
+ import { openNotionUrl } from "../utils/openNotionUrl.js";
4
+ const listProviders = buildAuthedHandler(async function(flags) {
5
+ this.process.stderr.write("Fetching providers...");
6
+ const providersResult = await this.apiClient.listOauthProviders();
7
+ if (Result.isFail(providersResult)) {
8
+ this.process.stderr.write("ERROR\n\n");
9
+ reportApiError(this, providersResult.error, "list providers");
10
+ } else {
11
+ this.process.stderr.write("OK\n\n");
12
+ const providers = providersResult.value.providers;
13
+ if (providers.length === 0) {
14
+ this.writer.writeErr("No OAuth providers are currently available.");
15
+ return;
16
+ }
17
+ this.writer.writeTableOut({
18
+ headers: ["Provider", "Description"],
19
+ rows: providers.map((provider) => [provider.key, provider.displayName]),
20
+ plain: flags.plain
21
+ });
22
+ }
23
+ });
24
+ const addConnection = buildAuthedHandler(async function(_flags, provider) {
25
+ const workerId = requireWorkerId(this);
26
+ this.process.stderr.write(
27
+ `Starting OAuth flow with provider "${provider}"...`
28
+ );
29
+ const startResult = await this.apiClient.startOauth({ workerId, provider });
30
+ if (Result.isFail(startResult)) {
31
+ this.process.stderr.write("ERROR\n\n");
32
+ reportApiError(this, startResult.error, "start OAuth flow");
33
+ return;
34
+ }
35
+ this.process.stderr.write("OK\n\n");
36
+ const { authorizationUrl } = startResult.value;
37
+ this.writer.writeErr("Opening your browser to continue the OAuth flow...");
38
+ try {
39
+ await openNotionUrl(this.config.environment ?? "prod", authorizationUrl);
40
+ } catch (error) {
41
+ this.writer.writeErr(
42
+ `Unable to open the browser automatically (${String(
43
+ error
44
+ )}). Please open the link below manually.`
45
+ );
46
+ }
47
+ this.writer.writeErr("");
48
+ this.writer.writeErr("If the browser did not open, visit:");
49
+ this.writer.writeErr(` ${authorizationUrl}`);
50
+ this.writer.writeErr("");
51
+ this.writer.writeErr(
52
+ "After completing the flow in your browser, return to the CLI."
53
+ );
54
+ });
55
+ const listConnections = buildAuthedHandler(async function(flags) {
56
+ const workerId = requireWorkerId(this);
57
+ this.process.stderr.write("Fetching OAuth connections...");
58
+ const secretsResult = await this.apiClient.listSecrets(workerId, {
59
+ secretKinds: ["oauth"]
60
+ });
61
+ if (Result.isFail(secretsResult)) {
62
+ this.process.stderr.write("ERROR\n\n");
63
+ reportApiError(this, secretsResult.error, "list OAuth connections");
64
+ return;
65
+ }
66
+ this.process.stderr.write("OK\n\n");
67
+ const secrets = secretsResult.value.secrets;
68
+ if (secrets.length === 0) {
69
+ this.writer.writeErr("No OAuth connections found for this worker.");
70
+ return;
71
+ }
72
+ this.writer.writeTableOut({
73
+ headers: ["Env Var", "Created At"],
74
+ rows: secrets.map((secret) => [
75
+ `process.env.${secret.key}`,
76
+ secret.createdAt
77
+ ]),
78
+ plain: flags.plain
79
+ });
80
+ });
81
+ const removeConnection = buildAuthedHandler(async function(_flags, provider) {
82
+ const workerId = requireWorkerId(this);
83
+ this.process.stderr.write(
84
+ `Removing OAuth connection for provider "${provider}"...`
85
+ );
86
+ const result = await this.apiClient.deleteOauthConnection({
87
+ workerId,
88
+ provider
89
+ });
90
+ if (Result.isFail(result)) {
91
+ this.process.stderr.write("ERROR\n\n");
92
+ reportApiError(this, result.error, "remove connection");
93
+ return;
94
+ }
95
+ this.process.stderr.write("OK\n");
96
+ });
97
+ function requireWorkerId(context) {
98
+ const workerId = context.config.workerId;
99
+ if (!workerId) {
100
+ throw new Error(
101
+ "No worker configured. Run 'workers deploy' first to create a worker."
102
+ );
103
+ }
104
+ return workerId;
105
+ }
106
+ function reportApiError(context, error, action) {
107
+ context.writer.writeErr(`\u2717 Failed to ${action}`);
108
+ context.writer.writeErr(`\u2717 ${error.message}`);
109
+ throw new Error(error.message);
110
+ }
111
+ export {
112
+ addConnection,
113
+ listConnections,
114
+ listProviders,
115
+ removeConnection
116
+ };
@@ -0,0 +1,78 @@
1
+ import { buildCommand, buildRouteMap } from "@stricli/core";
2
+ import { formatFlags, globalFlags } from "../flags.js";
3
+ const connectCommands = buildRouteMap({
4
+ docs: {
5
+ brief: "Manage OAuth connections for your worker"
6
+ },
7
+ routes: {
8
+ providers: buildCommand({
9
+ docs: {
10
+ brief: "List available OAuth providers"
11
+ },
12
+ parameters: {
13
+ flags: {
14
+ ...globalFlags,
15
+ ...formatFlags
16
+ }
17
+ },
18
+ loader: () => import("./connect.impl.js").then((m) => m.listProviders)
19
+ }),
20
+ add: buildCommand({
21
+ docs: {
22
+ brief: "Start an OAuth flow for a provider"
23
+ },
24
+ parameters: {
25
+ positional: {
26
+ kind: "tuple",
27
+ parameters: [
28
+ {
29
+ brief: "Provider name (see `providers` command)",
30
+ parse: String,
31
+ placeholder: "provider"
32
+ }
33
+ ]
34
+ },
35
+ flags: {
36
+ ...globalFlags
37
+ }
38
+ },
39
+ loader: () => import("./connect.impl.js").then((m) => m.addConnection)
40
+ }),
41
+ list: buildCommand({
42
+ docs: {
43
+ brief: "List active OAuth connections"
44
+ },
45
+ parameters: {
46
+ flags: {
47
+ ...globalFlags,
48
+ ...formatFlags
49
+ }
50
+ },
51
+ loader: () => import("./connect.impl.js").then((m) => m.listConnections)
52
+ }),
53
+ rm: buildCommand({
54
+ docs: {
55
+ brief: "Remove an OAuth connection"
56
+ },
57
+ parameters: {
58
+ positional: {
59
+ kind: "tuple",
60
+ parameters: [
61
+ {
62
+ brief: "Provider name to remove",
63
+ parse: String,
64
+ placeholder: "provider"
65
+ }
66
+ ]
67
+ },
68
+ flags: {
69
+ ...globalFlags
70
+ }
71
+ },
72
+ loader: () => import("./connect.impl.js").then((m) => m.removeConnection)
73
+ })
74
+ }
75
+ });
76
+ export {
77
+ connectCommands
78
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"secrets.impl.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/secrets.impl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK5D,eAAO,MAAM,UAAU,sGA0BrB,CAAC;AAEH,eAAO,MAAM,WAAW,iGAkCtB,CAAC;AAEH,eAAO,MAAM,YAAY,gGAwBvB,CAAC"}
1
+ {"version":3,"file":"secrets.impl.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/secrets.impl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK5D,eAAO,MAAM,UAAU,sGA0BrB,CAAC;AAEH,eAAO,MAAM,WAAW,iGAwCtB,CAAC;AAEH,eAAO,MAAM,YAAY,gGAwBvB,CAAC"}
@@ -36,12 +36,18 @@ const listSecrets = buildAuthedHandler(async function(flags) {
36
36
  const data = Result.unwrap(result);
37
37
  if (data.secrets.length === 0) {
38
38
  this.writer.writeErr("No secrets for this worker.");
39
+ this.writer.writeErr(
40
+ "To list OAuth connect secrets, use `npx workers connect list`"
41
+ );
39
42
  } else {
40
43
  this.writer.writeTableOut({
41
44
  headers: ["Key", "Created At"],
42
45
  rows: data.secrets.map((secret) => [secret.key, secret.createdAt]),
43
46
  plain: flags.plain
44
47
  });
48
+ this.writer.writeErr(
49
+ "To list OAuth connect secrets, use `npx workers connect list`"
50
+ );
45
51
  }
46
52
  } else {
47
53
  this.process.stderr.write("ERROR\n\n");
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/cli/routes.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,GAAG,0EAgBd,CAAC"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/cli/routes.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,GAAG,0EAgBd,CAAC"}
@@ -3,6 +3,7 @@ import packageJson from "../../package.json" with { type: "json" };
3
3
  import { authCommands } from "./commands/auth.js";
4
4
  import { bundleCommands } from "./commands/bundle.js";
5
5
  import { capabilitiesCommands } from "./commands/capabilities.js";
6
+ import { connectCommands } from "./commands/connect.js";
6
7
  import deploy from "./commands/deploy.js";
7
8
  import exec from "./commands/exec.js";
8
9
  import { runsCommands } from "./commands/runs.js";
@@ -17,6 +18,7 @@ const routes = buildRouteMap({
17
18
  capabilities: capabilitiesCommands,
18
19
  deploy,
19
20
  exec,
21
+ connect: connectCommands,
20
22
  runs: runsCommands,
21
23
  secrets: secretsCommands,
22
24
  bundle: bundleCommands
@@ -0,0 +1,3 @@
1
+ import type { Environment } from "../config.js";
2
+ export declare function openNotionUrl(env: Environment, url: string): Promise<void>;
3
+ //# sourceMappingURL=openNotionUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openNotionUrl.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/openNotionUrl.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,wBAAsB,aAAa,CAClC,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,CAAC,CAmBf"}
@@ -0,0 +1,33 @@
1
+ import { exec } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ async function openNotionUrl(env, url) {
4
+ const platform = process.platform;
5
+ try {
6
+ if (platform === "darwin") {
7
+ const appName = preferredNotionApp(env);
8
+ if (appName) {
9
+ exec(`open -a "${appName}" "${url}"`);
10
+ } else {
11
+ exec(`open "${url}"`);
12
+ }
13
+ } else if (platform === "win32") {
14
+ exec(`start "" "${url}"`);
15
+ } else {
16
+ exec(`xdg-open "${url}"`);
17
+ }
18
+ } catch (error) {
19
+ throw new Error(`Failed to open browser: ${error}`);
20
+ }
21
+ }
22
+ function preferredNotionApp(env) {
23
+ if (env === "prod" && existsSync("/Applications/Notion.app")) {
24
+ return "Notion";
25
+ }
26
+ if (env === "dev" && existsSync("/Applications/Notion Dev.app")) {
27
+ return "Notion Dev";
28
+ }
29
+ return null;
30
+ }
31
+ export {
32
+ openNotionUrl
33
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@project-ajax/sdk",
3
- "version": "0.0.34",
3
+ "version": "0.0.36",
4
4
  "description": "An SDK for building workers for the Project Ajax platform",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -330,7 +330,10 @@ export class ApiClient {
330
330
  /**
331
331
  * List all secrets for a worker (keys only, not values)
332
332
  */
333
- async listSecrets(workerId: string): Promise<
333
+ async listSecrets(
334
+ workerId: string,
335
+ options?: { secretKinds?: Array<"keyValue" | "oauth"> },
336
+ ): Promise<
334
337
  Result<
335
338
  {
336
339
  secrets: Array<{
@@ -338,6 +341,7 @@ export class ApiClient {
338
341
  workerId: string;
339
342
  key: string;
340
343
  createdAt: string;
344
+ kind: "keyValue" | "oauth";
341
345
  }>;
342
346
  },
343
347
  ApiError
@@ -347,6 +351,61 @@ export class ApiClient {
347
351
  method: "POST",
348
352
  body: {
349
353
  workerId,
354
+ secretKinds: options?.secretKinds,
355
+ },
356
+ });
357
+ }
358
+
359
+ async listOauthProviders(): Promise<
360
+ Result<
361
+ {
362
+ providers: Array<{
363
+ key: string;
364
+ displayName: string;
365
+ }>;
366
+ },
367
+ ApiError
368
+ >
369
+ > {
370
+ return this.fetch("/workersListOauthProviders", {
371
+ method: "POST",
372
+ body: {},
373
+ });
374
+ }
375
+
376
+ /**
377
+ * Start the OAuth flow for a provider
378
+ */
379
+ async startOauth(args: { workerId: string; provider: string }): Promise<
380
+ Result<
381
+ {
382
+ authorizationUrl: string;
383
+ state: string;
384
+ },
385
+ ApiError
386
+ >
387
+ > {
388
+ return this.fetch("/workersStartOauth", {
389
+ method: "POST",
390
+ body: {
391
+ workerId: args.workerId,
392
+ provider: args.provider,
393
+ },
394
+ });
395
+ }
396
+
397
+ /**
398
+ * Remove an OAuth connection for a worker
399
+ */
400
+ async deleteOauthConnection(args: {
401
+ workerId: string;
402
+ provider: string;
403
+ }): Promise<Result<Record<string, never>, ApiError>> {
404
+ return this.fetch("/workersDeleteOauthConnection", {
405
+ method: "POST",
406
+ body: {
407
+ workerId: args.workerId,
408
+ provider: args.provider,
350
409
  },
351
410
  });
352
411
  }
@@ -1,49 +1,13 @@
1
- import { exec } from "node:child_process";
2
- import { existsSync } from "node:fs";
3
1
  import { baseUrl } from "../api/client.js";
4
2
  import type { Environment } from "../config.js";
5
3
  import { buildHandler, type HandlerContext } from "../handler.js";
4
+ import { openNotionUrl } from "../utils/openNotionUrl.js";
6
5
 
7
6
  interface LoginFlags {
8
7
  env?: Environment;
9
8
  "base-url"?: string;
10
9
  }
11
10
 
12
- /**
13
- * Open a URL in the user's default browser or Notion app (if app available)
14
- */
15
- async function openUrl(env: Environment, url: string): Promise<void> {
16
- const platform = process.platform;
17
-
18
- try {
19
- if (platform === "darwin") {
20
- // Check if we should try to open Notion app on macOS
21
- let notionAppName: string | null = null;
22
-
23
- if (env === "prod" && existsSync("/Applications/Notion.app")) {
24
- notionAppName = "Notion";
25
- } else if (env === "dev" && existsSync("/Applications/Notion Dev.app")) {
26
- notionAppName = "Notion Dev";
27
- }
28
-
29
- if (notionAppName) {
30
- // Open the app first, then the URL (which will open in the app)
31
- exec(`open -a "${notionAppName}" "${url}"`);
32
- } else {
33
- // Fall back to opening in default browser
34
- exec(`open "${url}"`);
35
- }
36
- } else if (platform === "win32") {
37
- exec(`start "" "${url}"`);
38
- } else {
39
- // Linux and other Unix-like systems
40
- exec(`xdg-open "${url}"`);
41
- }
42
- } catch (error) {
43
- throw new Error(`Failed to open browser: ${error}`);
44
- }
45
- }
46
-
47
11
  export const login = buildHandler(async function (
48
12
  this: HandlerContext,
49
13
  flags: LoginFlags,
@@ -67,7 +31,7 @@ export const login = buildHandler(async function (
67
31
  this.writer.writeErr("\tnpx workers auth login <token>");
68
32
 
69
33
  try {
70
- await openUrl(environment, url);
34
+ await openNotionUrl(environment, url);
71
35
  } catch (_error) {
72
36
  this.writer.writeErr(
73
37
  `Failed to open browser automatically. Please visit:\n ${url}`,
@@ -0,0 +1,149 @@
1
+ import type { ApiError } from "../api/client.js";
2
+ import { Result } from "../api/result.js";
3
+ import type { FormatFlags, GlobalFlags } from "../flags.js";
4
+ import { type AuthedContext, buildAuthedHandler } from "../handler.js";
5
+ import { openNotionUrl } from "../utils/openNotionUrl.js";
6
+
7
+ export const listProviders = buildAuthedHandler(async function (
8
+ flags: FormatFlags,
9
+ ) {
10
+ this.process.stderr.write("Fetching providers...");
11
+ const providersResult = await this.apiClient.listOauthProviders();
12
+
13
+ if (Result.isFail(providersResult)) {
14
+ this.process.stderr.write("ERROR\n\n");
15
+ reportApiError(this, providersResult.error, "list providers");
16
+ } else {
17
+ this.process.stderr.write("OK\n\n");
18
+ const providers = providersResult.value.providers;
19
+ if (providers.length === 0) {
20
+ this.writer.writeErr("No OAuth providers are currently available.");
21
+ return;
22
+ }
23
+
24
+ this.writer.writeTableOut({
25
+ headers: ["Provider", "Description"],
26
+ rows: providers.map((provider) => [provider.key, provider.displayName]),
27
+ plain: flags.plain,
28
+ });
29
+ }
30
+ });
31
+
32
+ export const addConnection = buildAuthedHandler(async function (
33
+ _flags: GlobalFlags,
34
+ provider: string,
35
+ ) {
36
+ const workerId = requireWorkerId(this);
37
+
38
+ this.process.stderr.write(
39
+ `Starting OAuth flow with provider "${provider}"...`,
40
+ );
41
+ const startResult = await this.apiClient.startOauth({ workerId, provider });
42
+
43
+ if (Result.isFail(startResult)) {
44
+ this.process.stderr.write("ERROR\n\n");
45
+ reportApiError(this, startResult.error, "start OAuth flow");
46
+ return;
47
+ }
48
+
49
+ this.process.stderr.write("OK\n\n");
50
+
51
+ const { authorizationUrl } = startResult.value;
52
+
53
+ this.writer.writeErr("Opening your browser to continue the OAuth flow...");
54
+ try {
55
+ await openNotionUrl(this.config.environment ?? "prod", authorizationUrl);
56
+ } catch (error) {
57
+ this.writer.writeErr(
58
+ `Unable to open the browser automatically (${String(
59
+ error,
60
+ )}). Please open the link below manually.`,
61
+ );
62
+ }
63
+
64
+ this.writer.writeErr("");
65
+ this.writer.writeErr("If the browser did not open, visit:");
66
+ this.writer.writeErr(` ${authorizationUrl}`);
67
+ this.writer.writeErr("");
68
+ this.writer.writeErr(
69
+ "After completing the flow in your browser, return to the CLI.",
70
+ );
71
+ });
72
+
73
+ export const listConnections = buildAuthedHandler(async function (
74
+ flags: FormatFlags,
75
+ ) {
76
+ const workerId = requireWorkerId(this);
77
+
78
+ this.process.stderr.write("Fetching OAuth connections...");
79
+ const secretsResult = await this.apiClient.listSecrets(workerId, {
80
+ secretKinds: ["oauth"],
81
+ });
82
+
83
+ if (Result.isFail(secretsResult)) {
84
+ this.process.stderr.write("ERROR\n\n");
85
+ reportApiError(this, secretsResult.error, "list OAuth connections");
86
+ return;
87
+ }
88
+
89
+ this.process.stderr.write("OK\n\n");
90
+
91
+ const secrets = secretsResult.value.secrets;
92
+
93
+ if (secrets.length === 0) {
94
+ this.writer.writeErr("No OAuth connections found for this worker.");
95
+ return;
96
+ }
97
+
98
+ this.writer.writeTableOut({
99
+ headers: ["Env Var", "Created At"],
100
+ rows: secrets.map((secret) => [
101
+ `process.env.${secret.key}`,
102
+ secret.createdAt,
103
+ ]),
104
+ plain: flags.plain,
105
+ });
106
+ });
107
+
108
+ export const removeConnection = buildAuthedHandler(async function (
109
+ _flags: GlobalFlags,
110
+ provider: string,
111
+ ) {
112
+ const workerId = requireWorkerId(this);
113
+
114
+ this.process.stderr.write(
115
+ `Removing OAuth connection for provider "${provider}"...`,
116
+ );
117
+ const result = await this.apiClient.deleteOauthConnection({
118
+ workerId,
119
+ provider,
120
+ });
121
+
122
+ if (Result.isFail(result)) {
123
+ this.process.stderr.write("ERROR\n\n");
124
+ reportApiError(this, result.error, "remove connection");
125
+ return;
126
+ }
127
+
128
+ this.process.stderr.write("OK\n");
129
+ });
130
+
131
+ function requireWorkerId(context: AuthedContext): string {
132
+ const workerId = context.config.workerId;
133
+ if (!workerId) {
134
+ throw new Error(
135
+ "No worker configured. Run 'workers deploy' first to create a worker.",
136
+ );
137
+ }
138
+ return workerId;
139
+ }
140
+
141
+ function reportApiError(
142
+ context: AuthedContext,
143
+ error: ApiError,
144
+ action: string,
145
+ ): never {
146
+ context.writer.writeErr(`✗ Failed to ${action}`);
147
+ context.writer.writeErr(`✗ ${error.message}`);
148
+ throw new Error(error.message);
149
+ }
@@ -0,0 +1,80 @@
1
+ import { buildCommand, buildRouteMap } from "@stricli/core";
2
+
3
+ import { formatFlags, globalFlags } from "../flags.js";
4
+
5
+ export const connectCommands = buildRouteMap({
6
+ docs: {
7
+ brief: "Manage OAuth connections for your worker",
8
+ },
9
+ routes: {
10
+ providers: buildCommand({
11
+ docs: {
12
+ brief: "List available OAuth providers",
13
+ },
14
+ parameters: {
15
+ flags: {
16
+ ...globalFlags,
17
+ ...formatFlags,
18
+ },
19
+ },
20
+ loader: () => import("./connect.impl.js").then((m) => m.listProviders),
21
+ }),
22
+
23
+ add: buildCommand({
24
+ docs: {
25
+ brief: "Start an OAuth flow for a provider",
26
+ },
27
+ parameters: {
28
+ positional: {
29
+ kind: "tuple",
30
+ parameters: [
31
+ {
32
+ brief: "Provider name (see `providers` command)",
33
+ parse: String,
34
+ placeholder: "provider",
35
+ },
36
+ ],
37
+ },
38
+ flags: {
39
+ ...globalFlags,
40
+ },
41
+ },
42
+ loader: () => import("./connect.impl.js").then((m) => m.addConnection),
43
+ }),
44
+
45
+ list: buildCommand({
46
+ docs: {
47
+ brief: "List active OAuth connections",
48
+ },
49
+ parameters: {
50
+ flags: {
51
+ ...globalFlags,
52
+ ...formatFlags,
53
+ },
54
+ },
55
+ loader: () => import("./connect.impl.js").then((m) => m.listConnections),
56
+ }),
57
+
58
+ rm: buildCommand({
59
+ docs: {
60
+ brief: "Remove an OAuth connection",
61
+ },
62
+ parameters: {
63
+ positional: {
64
+ kind: "tuple",
65
+ parameters: [
66
+ {
67
+ brief: "Provider name to remove",
68
+ parse: String,
69
+ placeholder: "provider",
70
+ },
71
+ ],
72
+ },
73
+ flags: {
74
+ ...globalFlags,
75
+ },
76
+ },
77
+ loader: () => import("./connect.impl.js").then((m) => m.removeConnection),
78
+ }),
79
+ },
80
+ });
@@ -52,12 +52,18 @@ export const listSecrets = buildAuthedHandler(async function (
52
52
  const data = Result.unwrap(result);
53
53
  if (data.secrets.length === 0) {
54
54
  this.writer.writeErr("No secrets for this worker.");
55
+ this.writer.writeErr(
56
+ "To list OAuth connect secrets, use `npx workers connect list`",
57
+ );
55
58
  } else {
56
59
  this.writer.writeTableOut({
57
60
  headers: ["Key", "Created At"],
58
61
  rows: data.secrets.map((secret) => [secret.key, secret.createdAt]),
59
62
  plain: flags.plain,
60
63
  });
64
+ this.writer.writeErr(
65
+ "To list OAuth connect secrets, use `npx workers connect list`",
66
+ );
61
67
  }
62
68
  } else {
63
69
  this.process.stderr.write("ERROR\n\n");
package/src/cli/routes.ts CHANGED
@@ -3,6 +3,7 @@ import packageJson from "../../package.json" with { type: "json" };
3
3
  import { authCommands } from "./commands/auth.js";
4
4
  import { bundleCommands } from "./commands/bundle.js";
5
5
  import { capabilitiesCommands } from "./commands/capabilities.js";
6
+ import { connectCommands } from "./commands/connect.js";
6
7
  import deploy from "./commands/deploy.js";
7
8
  import exec from "./commands/exec.js";
8
9
  import { runsCommands } from "./commands/runs.js";
@@ -18,6 +19,7 @@ const routes = buildRouteMap({
18
19
  capabilities: capabilitiesCommands,
19
20
  deploy: deploy,
20
21
  exec: exec,
22
+ connect: connectCommands,
21
23
  runs: runsCommands,
22
24
  secrets: secretsCommands,
23
25
  bundle: bundleCommands,
@@ -0,0 +1,40 @@
1
+ import { exec } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+
4
+ import type { Environment } from "../config.js";
5
+
6
+ export async function openNotionUrl(
7
+ env: Environment,
8
+ url: string,
9
+ ): Promise<void> {
10
+ const platform = process.platform;
11
+
12
+ try {
13
+ if (platform === "darwin") {
14
+ const appName = preferredNotionApp(env);
15
+ if (appName) {
16
+ exec(`open -a "${appName}" "${url}"`);
17
+ } else {
18
+ exec(`open "${url}"`);
19
+ }
20
+ } else if (platform === "win32") {
21
+ exec(`start "" "${url}"`);
22
+ } else {
23
+ exec(`xdg-open "${url}"`);
24
+ }
25
+ } catch (error) {
26
+ throw new Error(`Failed to open browser: ${error}`);
27
+ }
28
+ }
29
+
30
+ function preferredNotionApp(env: Environment): string | null {
31
+ if (env === "prod" && existsSync("/Applications/Notion.app")) {
32
+ return "Notion";
33
+ }
34
+
35
+ if (env === "dev" && existsSync("/Applications/Notion Dev.app")) {
36
+ return "Notion Dev";
37
+ }
38
+
39
+ return null;
40
+ }