@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.
- package/dist/cli/api/client.d.ts +27 -1
- package/dist/cli/api/client.d.ts.map +1 -1
- package/dist/cli/api/client.js +33 -2
- package/dist/cli/commands/auth.impl.d.ts.map +1 -1
- package/dist/cli/commands/auth.impl.js +2 -27
- package/dist/cli/commands/connect.d.ts +2 -0
- package/dist/cli/commands/connect.d.ts.map +1 -0
- package/dist/cli/commands/connect.impl.d.ts +6 -0
- package/dist/cli/commands/connect.impl.d.ts.map +1 -0
- package/dist/cli/commands/connect.impl.js +116 -0
- package/dist/cli/commands/connect.js +78 -0
- package/dist/cli/commands/secrets.impl.d.ts.map +1 -1
- package/dist/cli/commands/secrets.impl.js +6 -0
- package/dist/cli/routes.d.ts.map +1 -1
- package/dist/cli/routes.js +2 -0
- package/dist/cli/utils/openNotionUrl.d.ts +3 -0
- package/dist/cli/utils/openNotionUrl.d.ts.map +1 -0
- package/dist/cli/utils/openNotionUrl.js +33 -0
- package/package.json +1 -1
- package/src/cli/api/client.ts +60 -1
- package/src/cli/commands/auth.impl.ts +2 -38
- package/src/cli/commands/connect.impl.ts +149 -0
- package/src/cli/commands/connect.ts +80 -0
- package/src/cli/commands/secrets.impl.ts +6 -0
- package/src/cli/routes.ts +2 -0
- package/src/cli/utils/openNotionUrl.ts +40 -0
package/dist/cli/api/client.d.ts
CHANGED
|
@@ -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
|
|
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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"}
|
package/dist/cli/api/client.js
CHANGED
|
@@ -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":"
|
|
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
|
-
|
|
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
|
|
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 @@
|
|
|
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,
|
|
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");
|
package/dist/cli/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/cli/routes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/cli/routes.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,GAAG,0EAgBd,CAAC"}
|
package/dist/cli/routes.js
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";
|
|
@@ -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 @@
|
|
|
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
package/src/cli/api/client.ts
CHANGED
|
@@ -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(
|
|
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
|
|
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
|
+
}
|