@playdrop/playdrop-cli 0.3.10 → 0.3.11
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/config/client-meta.json +4 -4
- package/dist/commands/browse.js +1 -1
- package/dist/commands/capture.js +2 -2
- package/dist/commands/comments.js +3 -3
- package/dist/commands/create.js +3 -3
- package/dist/commands/createRemixContent.js +1 -1
- package/dist/commands/creations.js +2 -2
- package/dist/commands/credits.js +2 -2
- package/dist/commands/detail.js +1 -1
- package/dist/commands/dev.js +2 -2
- package/dist/commands/feedback.js +1 -1
- package/dist/commands/generation.js +2 -2
- package/dist/commands/gettingStarted.js +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/login.d.ts +10 -10
- package/dist/commands/login.js +202 -79
- package/dist/commands/logout.js +1 -1
- package/dist/commands/notifications.js +3 -3
- package/dist/commands/versionsBrowse.js +1 -1
- package/dist/commands/whoami.js +9 -9
- package/dist/index.js +41 -25
- package/dist/messages.js +5 -5
- package/node_modules/@playdrop/api-client/dist/client.d.ts +13 -2
- package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/client.js +21 -0
- package/node_modules/@playdrop/api-client/dist/domains/auth.d.ts +10 -1
- package/node_modules/@playdrop/api-client/dist/domains/auth.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/auth.js +94 -0
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts +2 -2
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/payments.js +2 -1
- package/node_modules/@playdrop/api-client/dist/index.d.ts +16 -3
- package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/index.js +37 -4
- package/node_modules/@playdrop/config/client-meta.json +4 -4
- package/node_modules/@playdrop/types/dist/api.d.ts +177 -0
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/package.json +1 -1
package/config/client-meta.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.3.
|
|
2
|
+
"version": "0.3.11",
|
|
3
3
|
"build": 1,
|
|
4
4
|
"platforms": {
|
|
5
5
|
"ios": {
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
},
|
|
27
27
|
"clients": {
|
|
28
28
|
"web": {
|
|
29
|
-
"minimumVersion": "0.3.
|
|
29
|
+
"minimumVersion": "0.3.11",
|
|
30
30
|
"minimumBuild": 1
|
|
31
31
|
},
|
|
32
32
|
"admin": {
|
|
33
|
-
"minimumVersion": "0.3.
|
|
33
|
+
"minimumVersion": "0.3.11",
|
|
34
34
|
"minimumBuild": 1
|
|
35
35
|
},
|
|
36
36
|
"apple": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"minimumBuild": 1
|
|
39
39
|
},
|
|
40
40
|
"cli": {
|
|
41
|
-
"minimumVersion": "0.3.
|
|
41
|
+
"minimumVersion": "0.3.11"
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
package/dist/commands/browse.js
CHANGED
|
@@ -362,7 +362,7 @@ async function browse(options = {}) {
|
|
|
362
362
|
if (apiError.status === 401 || apiError.status === 403) {
|
|
363
363
|
return {
|
|
364
364
|
problem: 'Browsing this content requires you to be logged in.',
|
|
365
|
-
suggestions: ['Run "playdrop
|
|
365
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
366
366
|
};
|
|
367
367
|
}
|
|
368
368
|
return {
|
package/dist/commands/capture.js
CHANGED
|
@@ -326,8 +326,8 @@ async function capture(targetArg, options = {}) {
|
|
|
326
326
|
}
|
|
327
327
|
if (error instanceof types_1.ApiError) {
|
|
328
328
|
(0, messages_1.printErrorWithHelp)(`Could not fetch your account (status ${error.status}).`, [
|
|
329
|
-
'Run "playdrop
|
|
330
|
-
'Use "playdrop
|
|
329
|
+
'Run "playdrop login" to refresh your session and ensure the API is reachable.',
|
|
330
|
+
'Use "playdrop whoami" afterwards to confirm your status.',
|
|
331
331
|
], { command: 'project capture' });
|
|
332
332
|
process.exitCode = 1;
|
|
333
333
|
return;
|
|
@@ -72,7 +72,7 @@ async function browseComments(rawRef, options = {}) {
|
|
|
72
72
|
if (apiError.status === 401 || apiError.status === 403) {
|
|
73
73
|
return {
|
|
74
74
|
problem: `You do not have access to comments for "${ref.ref}".`,
|
|
75
|
-
suggestions: ['Run "playdrop
|
|
75
|
+
suggestions: ['Run "playdrop login" if this is private content you own.'],
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
return {
|
|
@@ -125,7 +125,7 @@ async function addComment(rawRef, options = {}) {
|
|
|
125
125
|
if (apiError.status === 401 || apiError.status === 403) {
|
|
126
126
|
return {
|
|
127
127
|
problem: 'Adding a comment requires you to be logged in.',
|
|
128
|
-
suggestions: ['Run "playdrop
|
|
128
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
if (apiError.status === 404) {
|
|
@@ -166,7 +166,7 @@ async function deleteComment(commentId, options = {}) {
|
|
|
166
166
|
if (apiError.status === 401 || apiError.status === 403) {
|
|
167
167
|
return {
|
|
168
168
|
problem: 'Deleting a comment requires a valid login with permission to manage it.',
|
|
169
|
-
suggestions: ['Run "playdrop
|
|
169
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
170
170
|
};
|
|
171
171
|
}
|
|
172
172
|
if (apiError.status === 404) {
|
package/dist/commands/create.js
CHANGED
|
@@ -877,7 +877,7 @@ async function create(name, options = {}) {
|
|
|
877
877
|
const choices = (0, environment_1.formatEnvironmentList)();
|
|
878
878
|
(0, messages_1.printErrorWithHelp)(`Environment "${envName}" from your Playdrop config is not supported.`, [
|
|
879
879
|
`Available environments: ${choices}.`,
|
|
880
|
-
'Run "playdrop
|
|
880
|
+
'Run "playdrop login --env <env>" to save a supported environment before creating apps.'
|
|
881
881
|
], { command: 'project create app', includeGeneralHelp: false });
|
|
882
882
|
process.exitCode = 1;
|
|
883
883
|
return;
|
|
@@ -1227,7 +1227,7 @@ async function create(name, options = {}) {
|
|
|
1227
1227
|
return;
|
|
1228
1228
|
}
|
|
1229
1229
|
if (error instanceof types_1.ApiError) {
|
|
1230
|
-
(0, messages_1.printErrorWithHelp)(`Failed to resolve your creator account (status ${error.status}).`, ['Run "playdrop
|
|
1230
|
+
(0, messages_1.printErrorWithHelp)(`Failed to resolve your creator account (status ${error.status}).`, ['Run "playdrop login" to refresh your session, then try again.'], { command: 'project create app' });
|
|
1231
1231
|
process.exitCode = 1;
|
|
1232
1232
|
return;
|
|
1233
1233
|
}
|
|
@@ -1237,7 +1237,7 @@ async function create(name, options = {}) {
|
|
|
1237
1237
|
return;
|
|
1238
1238
|
}
|
|
1239
1239
|
if (error instanceof Error && error.message === 'missing_creator_username') {
|
|
1240
|
-
(0, messages_1.printErrorWithHelp)('The API did not return a creator username.', ['Run "playdrop
|
|
1240
|
+
(0, messages_1.printErrorWithHelp)('The API did not return a creator username.', ['Run "playdrop login" again, then retry.'], { command: 'project create app' });
|
|
1241
1241
|
process.exitCode = 1;
|
|
1242
1242
|
return;
|
|
1243
1243
|
}
|
|
@@ -115,7 +115,7 @@ async function createAuthenticatedClient(commandLabel) {
|
|
|
115
115
|
if (!envConfig) {
|
|
116
116
|
(0, messages_1.printErrorWithHelp)(`Environment "${envName}" from your Playdrop config is not supported.`, [
|
|
117
117
|
`Available environments: ${(0, environment_1.formatEnvironmentList)()}.`,
|
|
118
|
-
'Run "playdrop
|
|
118
|
+
'Run "playdrop login --env <env>" to save a supported environment before retrying.',
|
|
119
119
|
], { command: commandLabel, includeGeneralHelp: false });
|
|
120
120
|
process.exitCode = 1;
|
|
121
121
|
throw new Error('unsupported_env');
|
|
@@ -65,7 +65,7 @@ async function resolveCreator(client, rawCreator, command) {
|
|
|
65
65
|
const response = await client.me();
|
|
66
66
|
const username = response.user?.username?.trim();
|
|
67
67
|
if (!username) {
|
|
68
|
-
(0, messages_1.printErrorWithHelp)('Could not resolve your current creator account.', ['Run "playdrop
|
|
68
|
+
(0, messages_1.printErrorWithHelp)('Could not resolve your current creator account.', ['Run "playdrop whoami" to confirm your session, then retry.'], { command });
|
|
69
69
|
process.exitCode = 1;
|
|
70
70
|
return null;
|
|
71
71
|
}
|
|
@@ -283,7 +283,7 @@ async function browseCreations(options = {}) {
|
|
|
283
283
|
const handled = (0, errors_1.handleCommandFailure)(error, 'creations browse', 'Creation lookup', {
|
|
284
284
|
apiMessage: (apiError) => ({
|
|
285
285
|
problem: `Creation lookup failed with status ${apiError.status}.`,
|
|
286
|
-
suggestions: ['Run "playdrop
|
|
286
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
287
287
|
}),
|
|
288
288
|
});
|
|
289
289
|
if (!handled) {
|
package/dist/commands/credits.js
CHANGED
|
@@ -34,7 +34,7 @@ async function showCreditBalance(options = {}) {
|
|
|
34
34
|
const handled = (0, errors_1.handleCommandFailure)(error, 'credits balance', 'Credit balance lookup', {
|
|
35
35
|
apiMessage: (apiError) => ({
|
|
36
36
|
problem: `Credit balance lookup failed with status ${apiError.status}.`,
|
|
37
|
-
suggestions: ['Run "playdrop
|
|
37
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
38
38
|
}),
|
|
39
39
|
});
|
|
40
40
|
if (!handled) {
|
|
@@ -80,7 +80,7 @@ async function browseCreditTransactions(options = {}) {
|
|
|
80
80
|
const handled = (0, errors_1.handleCommandFailure)(error, 'credits transactions', 'Credit transaction lookup', {
|
|
81
81
|
apiMessage: (apiError) => ({
|
|
82
82
|
problem: `Credit transaction lookup failed with status ${apiError.status}.`,
|
|
83
|
-
suggestions: ['Run "playdrop
|
|
83
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
84
84
|
}),
|
|
85
85
|
});
|
|
86
86
|
if (!handled) {
|
package/dist/commands/detail.js
CHANGED
|
@@ -161,7 +161,7 @@ async function detail(rawRef, options = {}) {
|
|
|
161
161
|
if (apiError.status === 401 || apiError.status === 403) {
|
|
162
162
|
return {
|
|
163
163
|
problem: `You do not have access to "${ref.ref}".`,
|
|
164
|
-
suggestions: ['Run "playdrop
|
|
164
|
+
suggestions: ['Run "playdrop login" if this is private content you own.', 'Use "playdrop help detail" for the ref format.'],
|
|
165
165
|
};
|
|
166
166
|
}
|
|
167
167
|
return {
|
package/dist/commands/dev.js
CHANGED
|
@@ -120,8 +120,8 @@ async function dev(targetArg, _port, appOption) {
|
|
|
120
120
|
}
|
|
121
121
|
if (error instanceof types_1.ApiError) {
|
|
122
122
|
(0, messages_1.printErrorWithHelp)(`Could not fetch your account (status ${error.status}).`, [
|
|
123
|
-
'Run "playdrop
|
|
124
|
-
'Use "playdrop
|
|
123
|
+
'Run "playdrop login" to refresh your session and ensure the API is reachable.',
|
|
124
|
+
'Use "playdrop whoami" afterwards to confirm your status.',
|
|
125
125
|
], { command: 'project dev' });
|
|
126
126
|
process.exitCode = 1;
|
|
127
127
|
return;
|
|
@@ -96,7 +96,7 @@ async function sendFeedback(options = {}) {
|
|
|
96
96
|
const handled = (0, errors_1.handleCommandFailure)(error, 'feedback send', 'Feedback send', {
|
|
97
97
|
apiMessage: (apiError) => ({
|
|
98
98
|
problem: `Feedback send failed with status ${apiError.status}.`,
|
|
99
|
-
suggestions: ['Check the provided fields and retry.', 'Run "playdrop
|
|
99
|
+
suggestions: ['Check the provided fields and retry.', 'Run "playdrop login" if your session may be stale.'],
|
|
100
100
|
}),
|
|
101
101
|
});
|
|
102
102
|
if (!handled) {
|
|
@@ -601,7 +601,7 @@ function handleAiFailure(error, command, context) {
|
|
|
601
601
|
if (apiError.status === 401 || apiError.status === 403) {
|
|
602
602
|
return {
|
|
603
603
|
problem: `${context} requires you to be logged in.`,
|
|
604
|
-
suggestions: ['Run "playdrop
|
|
604
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
605
605
|
};
|
|
606
606
|
}
|
|
607
607
|
return {
|
|
@@ -616,7 +616,7 @@ function handleAiFailure(error, command, context) {
|
|
|
616
616
|
const status = typeof error?.status === 'number' ? Number(error.status) : null;
|
|
617
617
|
if (status !== null) {
|
|
618
618
|
if (status === 401 || status === 403) {
|
|
619
|
-
(0, messages_1.printErrorWithHelp)(`${context} requires you to be logged in.`, ['Run "playdrop
|
|
619
|
+
(0, messages_1.printErrorWithHelp)(`${context} requires you to be logged in.`, ['Run "playdrop login" and retry.'], { command });
|
|
620
620
|
}
|
|
621
621
|
else {
|
|
622
622
|
(0, messages_1.printErrorWithHelp)(`${context} failed with status ${status}.`, ['Retry in a moment.'], { command });
|
|
@@ -4,7 +4,7 @@ exports.printGettingStarted = printGettingStarted;
|
|
|
4
4
|
function printGettingStarted() {
|
|
5
5
|
console.log('Start here:\n');
|
|
6
6
|
console.log('1. Log in');
|
|
7
|
-
console.log(' playdrop
|
|
7
|
+
console.log(' playdrop login');
|
|
8
8
|
console.log('');
|
|
9
9
|
console.log('2. Initialize a workspace');
|
|
10
10
|
console.log(' playdrop project init .');
|
package/dist/commands/init.js
CHANGED
|
@@ -55,7 +55,7 @@ async function resolveUsername(apiBase, token) {
|
|
|
55
55
|
}
|
|
56
56
|
if (unknownError instanceof types_1.ApiError) {
|
|
57
57
|
(0, messages_1.printErrorWithHelp)(`Request failed with status ${unknownError.status}.`, [
|
|
58
|
-
'Run "playdrop
|
|
58
|
+
'Run "playdrop login" to refresh your credentials.',
|
|
59
59
|
'Use "playdrop project init" again after logging in.'
|
|
60
60
|
], { command: 'project init' });
|
|
61
61
|
process.exitCode = 1;
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export
|
|
1
|
+
type LoginOptions = {
|
|
2
|
+
username?: string;
|
|
3
|
+
password?: string;
|
|
4
|
+
key?: string;
|
|
5
|
+
};
|
|
6
|
+
type OpenBrowserFn = (url: string) => Promise<boolean>;
|
|
7
|
+
export declare function setOpenBrowserForTests(fn: OpenBrowserFn): void;
|
|
8
|
+
export declare function resetOpenBrowserForTests(): void;
|
|
9
|
+
export declare function login(env: string, options?: LoginOptions): Promise<void>;
|
|
10
|
+
export {};
|
package/dist/commands/login.js
CHANGED
|
@@ -1,118 +1,241 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
3
|
+
exports.setOpenBrowserForTests = setOpenBrowserForTests;
|
|
4
|
+
exports.resetOpenBrowserForTests = resetOpenBrowserForTests;
|
|
7
5
|
exports.login = login;
|
|
8
|
-
const
|
|
9
|
-
const node_stream_1 = require("node:stream");
|
|
10
|
-
const node_process_1 = require("node:process");
|
|
6
|
+
const node_child_process_1 = require("node:child_process");
|
|
11
7
|
const types_1 = require("@playdrop/types");
|
|
12
8
|
const config_1 = require("../config");
|
|
13
9
|
const apiClient_1 = require("../apiClient");
|
|
14
10
|
const http_1 = require("../http");
|
|
15
11
|
const environment_1 = require("../environment");
|
|
16
12
|
const messages_1 = require("../messages");
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
const str = typeof chunk === 'string' ? chunk : chunk?.toString?.();
|
|
29
|
-
if (str && str.includes('\n')) {
|
|
30
|
-
this.target.write('\n');
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
callback();
|
|
13
|
+
function sleep(ms) {
|
|
14
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
|
+
}
|
|
16
|
+
function getBrowserCommand(url) {
|
|
17
|
+
if (process.platform === 'darwin') {
|
|
18
|
+
return { command: 'open', args: [url] };
|
|
19
|
+
}
|
|
20
|
+
if (process.platform === 'win32') {
|
|
21
|
+
return { command: 'cmd', args: ['/c', 'start', '', url] };
|
|
34
22
|
}
|
|
23
|
+
if (process.platform === 'linux') {
|
|
24
|
+
return { command: 'xdg-open', args: [url] };
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
35
27
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
async function defaultOpenBrowser(url) {
|
|
29
|
+
const command = getBrowserCommand(url);
|
|
30
|
+
if (!command) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return await new Promise((resolve) => {
|
|
34
|
+
const child = (0, node_child_process_1.spawn)(command.command, command.args, {
|
|
35
|
+
detached: true,
|
|
36
|
+
stdio: 'ignore',
|
|
37
|
+
});
|
|
38
|
+
child.once('error', () => resolve(false));
|
|
39
|
+
child.once('spawn', () => {
|
|
40
|
+
child.unref();
|
|
41
|
+
resolve(true);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
let openBrowser = defaultOpenBrowser;
|
|
46
|
+
function setOpenBrowserForTests(fn) {
|
|
47
|
+
openBrowser = fn;
|
|
48
|
+
}
|
|
49
|
+
function resetOpenBrowserForTests() {
|
|
50
|
+
openBrowser = defaultOpenBrowser;
|
|
51
|
+
}
|
|
52
|
+
function extractAccessToken(data) {
|
|
53
|
+
return data.accessToken
|
|
54
|
+
?? (typeof data === 'object' && data !== null && 'token' in data ? data.token : undefined);
|
|
55
|
+
}
|
|
56
|
+
function isLoginResponse(data) {
|
|
57
|
+
return typeof data === 'object' && data !== null && 'user' in data;
|
|
58
|
+
}
|
|
59
|
+
function storeLogin(env, data) {
|
|
60
|
+
const token = extractAccessToken(data);
|
|
61
|
+
if (!token) {
|
|
62
|
+
(0, messages_1.printErrorWithHelp)('Login succeeded but no access token was returned.', [
|
|
63
|
+
'Please try again in a moment.',
|
|
64
|
+
'If the issue persists, contact the Playdrop team.',
|
|
65
|
+
], { command: 'login' });
|
|
42
66
|
process.exitCode = 1;
|
|
43
67
|
return;
|
|
44
68
|
}
|
|
45
|
-
|
|
46
|
-
|
|
69
|
+
(0, config_1.saveConfig)({ token, env });
|
|
70
|
+
const username = data.user?.username ?? 'unknown';
|
|
71
|
+
console.log(`Logged in as ${username} on ${env}.`);
|
|
72
|
+
console.log('Next: run "playdrop whoami" to confirm your session.');
|
|
73
|
+
}
|
|
74
|
+
async function loginWithUsernamePassword(env, baseUrl, username, password) {
|
|
75
|
+
const client = (0, apiClient_1.createCliApiClient)({ baseUrl });
|
|
76
|
+
try {
|
|
77
|
+
const data = await client.login({ username, password });
|
|
78
|
+
storeLogin(env, data);
|
|
47
79
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const maskedOutput = new MaskedStdout();
|
|
53
|
-
const rl = promises_1.default.createInterface({ input: node_process_1.stdin, output: maskedOutput, terminal: true });
|
|
54
|
-
if (!username) {
|
|
55
|
-
maskedOutput.muted = false;
|
|
56
|
-
username = (await rl.question('Username: ')).trim();
|
|
80
|
+
catch (unknownError) {
|
|
81
|
+
if (unknownError instanceof types_1.UnsupportedClientError) {
|
|
82
|
+
(0, http_1.handleUnsupportedError)(unknownError, 'Login');
|
|
83
|
+
return;
|
|
57
84
|
}
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
85
|
+
if (unknownError instanceof types_1.ApiError) {
|
|
86
|
+
(0, messages_1.printErrorWithHelp)(`Login failed with status ${unknownError.status}.`, [
|
|
87
|
+
'Verify your username and password, then rerun "playdrop login".',
|
|
88
|
+
'Use "playdrop whoami" after logging in to confirm your status.',
|
|
89
|
+
], { command: 'login' });
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
return;
|
|
62
92
|
}
|
|
63
|
-
|
|
93
|
+
throw unknownError;
|
|
64
94
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
95
|
+
}
|
|
96
|
+
async function loginWithKey(env, baseUrl, apiKey) {
|
|
97
|
+
const client = (0, apiClient_1.createCliApiClient)({ baseUrl });
|
|
98
|
+
try {
|
|
99
|
+
const data = await client.loginWithApiKey({ apiKey });
|
|
100
|
+
storeLogin(env, data);
|
|
101
|
+
}
|
|
102
|
+
catch (unknownError) {
|
|
103
|
+
if (unknownError instanceof types_1.UnsupportedClientError) {
|
|
104
|
+
(0, http_1.handleUnsupportedError)(unknownError, 'Login');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (unknownError instanceof types_1.ApiError) {
|
|
108
|
+
(0, messages_1.printErrorWithHelp)(`Login failed with status ${unknownError.status}.`, [
|
|
109
|
+
'Verify your API key, then rerun "playdrop login --key <api-key>".',
|
|
110
|
+
'Use "playdrop whoami" after logging in to confirm your status.',
|
|
111
|
+
], { command: 'login' });
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
throw unknownError;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function loginInBrowser(env, baseUrl) {
|
|
119
|
+
const client = (0, apiClient_1.createCliApiClient)({ baseUrl });
|
|
120
|
+
let flow;
|
|
121
|
+
try {
|
|
122
|
+
flow = await client.startCliLogin();
|
|
71
123
|
}
|
|
72
|
-
|
|
73
|
-
|
|
124
|
+
catch (unknownError) {
|
|
125
|
+
if (unknownError instanceof types_1.UnsupportedClientError) {
|
|
126
|
+
(0, http_1.handleUnsupportedError)(unknownError, 'Login');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (unknownError instanceof types_1.ApiError) {
|
|
130
|
+
(0, messages_1.printErrorWithHelp)(`Could not start browser login (status ${unknownError.status}).`, [
|
|
131
|
+
'Try again in a moment.',
|
|
132
|
+
'If the problem continues, contact the Playdrop team.',
|
|
133
|
+
], { command: 'login' });
|
|
134
|
+
process.exitCode = 1;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
throw unknownError;
|
|
138
|
+
}
|
|
139
|
+
console.log(`Open this URL to continue: ${flow.loginUrl}`);
|
|
140
|
+
const opened = await openBrowser(flow.loginUrl).catch(() => false);
|
|
141
|
+
if (opened) {
|
|
142
|
+
console.log('Opened the login page in your browser.');
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.log('Open the URL above in your browser to continue.');
|
|
146
|
+
}
|
|
147
|
+
const expiresAtMs = Date.parse(flow.expiresAt);
|
|
148
|
+
const deadlineMs = Number.isFinite(expiresAtMs)
|
|
149
|
+
? expiresAtMs
|
|
150
|
+
: Date.now() + 10 * 60 * 1000;
|
|
151
|
+
const intervalMs = Math.max(250, Number(flow.pollIntervalMs) || 1000);
|
|
152
|
+
while (Date.now() < deadlineMs) {
|
|
74
153
|
try {
|
|
75
|
-
|
|
154
|
+
const result = await client.pollCliLogin({
|
|
155
|
+
requestId: flow.requestId,
|
|
156
|
+
pollToken: flow.pollToken,
|
|
157
|
+
});
|
|
158
|
+
if (!isLoginResponse(result)) {
|
|
159
|
+
await sleep(intervalMs);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
storeLogin(env, result);
|
|
163
|
+
return;
|
|
76
164
|
}
|
|
77
165
|
catch (unknownError) {
|
|
78
166
|
if (unknownError instanceof types_1.UnsupportedClientError) {
|
|
79
167
|
(0, http_1.handleUnsupportedError)(unknownError, 'Login');
|
|
168
|
+
return;
|
|
80
169
|
}
|
|
81
170
|
if (unknownError instanceof types_1.ApiError) {
|
|
82
|
-
(
|
|
83
|
-
'
|
|
84
|
-
|
|
85
|
-
|
|
171
|
+
if (unknownError.status === 410 || unknownError.code === 'cli_login_expired') {
|
|
172
|
+
(0, messages_1.printErrorWithHelp)('Browser login expired before it was approved.', [
|
|
173
|
+
'Rerun "playdrop login" to start a new browser login request.',
|
|
174
|
+
], { command: 'login' });
|
|
175
|
+
process.exitCode = 1;
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
(0, messages_1.printErrorWithHelp)(`Browser login failed with status ${unknownError.status}.`, [
|
|
179
|
+
'Rerun "playdrop login" to try again.',
|
|
180
|
+
], { command: 'login' });
|
|
86
181
|
process.exitCode = 1;
|
|
87
|
-
return
|
|
182
|
+
return;
|
|
88
183
|
}
|
|
89
184
|
throw unknownError;
|
|
90
185
|
}
|
|
91
186
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
(0,
|
|
187
|
+
(0, messages_1.printErrorWithHelp)('Browser login timed out after 10 minutes.', [
|
|
188
|
+
'Rerun "playdrop login" to start a new browser login request.',
|
|
189
|
+
], { command: 'login' });
|
|
190
|
+
process.exitCode = 1;
|
|
191
|
+
}
|
|
192
|
+
async function login(env, options = {}) {
|
|
193
|
+
const envConfig = (0, environment_1.resolveEnvironmentConfig)(env);
|
|
194
|
+
if (!envConfig) {
|
|
195
|
+
const choices = (0, environment_1.formatEnvironmentList)();
|
|
196
|
+
(0, messages_1.printUnknownEnvironment)(env, choices, 'login');
|
|
101
197
|
process.exitCode = 1;
|
|
102
198
|
return;
|
|
103
199
|
}
|
|
104
|
-
if (
|
|
200
|
+
if (envConfig.allowInsecureRequests) {
|
|
201
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
202
|
+
}
|
|
203
|
+
const username = options.username?.trim();
|
|
204
|
+
const password = options.password;
|
|
205
|
+
const apiKey = options.key?.trim();
|
|
206
|
+
if (apiKey && (username || password)) {
|
|
207
|
+
(0, messages_1.printErrorWithHelp)('Choose exactly one login method.', [
|
|
208
|
+
'Use "playdrop login" for browser login.',
|
|
209
|
+
'Use "--username" with "--password" for direct login.',
|
|
210
|
+
'Use "--key" by itself for API key login.',
|
|
211
|
+
], { command: 'login' });
|
|
212
|
+
process.exitCode = 1;
|
|
105
213
|
return;
|
|
106
|
-
|
|
107
|
-
if (!
|
|
108
|
-
(0, messages_1.printErrorWithHelp)('
|
|
109
|
-
'
|
|
110
|
-
'
|
|
111
|
-
], { command: '
|
|
214
|
+
}
|
|
215
|
+
if ((username && !password) || (!username && password)) {
|
|
216
|
+
(0, messages_1.printErrorWithHelp)('Provide both "--username" and "--password" together.', [
|
|
217
|
+
'Rerun "playdrop login --username <username> --password <password>".',
|
|
218
|
+
'Or run "playdrop login" to use browser login instead.',
|
|
219
|
+
], { command: 'login' });
|
|
112
220
|
process.exitCode = 1;
|
|
113
221
|
return;
|
|
114
222
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
223
|
+
try {
|
|
224
|
+
if (apiKey) {
|
|
225
|
+
await loginWithKey(env, envConfig.apiBase, apiKey);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (username && password) {
|
|
229
|
+
await loginWithUsernamePassword(env, envConfig.apiBase, username, password);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
await loginInBrowser(env, envConfig.apiBase);
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
if (error instanceof http_1.CLIUnsupportedClientError) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
(0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to log in.', 'login');
|
|
239
|
+
process.exitCode = 1;
|
|
240
|
+
}
|
|
118
241
|
}
|
package/dist/commands/logout.js
CHANGED
|
@@ -5,5 +5,5 @@ const config_1 = require("../config");
|
|
|
5
5
|
function logout() {
|
|
6
6
|
(0, config_1.clearConfig)();
|
|
7
7
|
console.log('Logged out.');
|
|
8
|
-
console.log('Next: run "playdrop
|
|
8
|
+
console.log('Next: run "playdrop login" when you need a new session.');
|
|
9
9
|
}
|
|
@@ -116,7 +116,7 @@ async function browseNotifications(options = {}) {
|
|
|
116
116
|
const handled = (0, errors_1.handleCommandFailure)(error, 'notifications browse', 'Notification lookup', {
|
|
117
117
|
apiMessage: (apiError) => ({
|
|
118
118
|
problem: `Notification lookup failed with status ${apiError.status}.`,
|
|
119
|
-
suggestions: ['Run "playdrop
|
|
119
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
120
120
|
}),
|
|
121
121
|
});
|
|
122
122
|
if (!handled) {
|
|
@@ -145,7 +145,7 @@ async function readNotification(rawId, options = {}) {
|
|
|
145
145
|
const handled = (0, errors_1.handleCommandFailure)(error, 'notifications read', 'Notification update', {
|
|
146
146
|
apiMessage: (apiError) => ({
|
|
147
147
|
problem: `Notification update failed with status ${apiError.status}.`,
|
|
148
|
-
suggestions: ['Run "playdrop
|
|
148
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
149
149
|
}),
|
|
150
150
|
});
|
|
151
151
|
if (!handled) {
|
|
@@ -168,7 +168,7 @@ async function readAllNotifications(options = {}) {
|
|
|
168
168
|
const handled = (0, errors_1.handleCommandFailure)(error, 'notifications read-all', 'Notification update', {
|
|
169
169
|
apiMessage: (apiError) => ({
|
|
170
170
|
problem: `Notification update failed with status ${apiError.status}.`,
|
|
171
|
-
suggestions: ['Run "playdrop
|
|
171
|
+
suggestions: ['Run "playdrop login" and retry.'],
|
|
172
172
|
}),
|
|
173
173
|
});
|
|
174
174
|
if (!handled) {
|
|
@@ -192,7 +192,7 @@ async function browseVersions(rawRef, options = {}) {
|
|
|
192
192
|
if (apiError.status === 401 || apiError.status === 403) {
|
|
193
193
|
return {
|
|
194
194
|
problem: `You do not have access to version history for "${ref.ref}".`,
|
|
195
|
-
suggestions: ['Run "playdrop
|
|
195
|
+
suggestions: ['Run "playdrop login" if this is private content you own.'],
|
|
196
196
|
};
|
|
197
197
|
}
|
|
198
198
|
return {
|