@playdrop/playdrop-cli 0.3.9 → 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/README.md +43 -1
- package/config/client-meta.json +5 -6
- package/dist/catalogue-utils.js +9 -2
- package/dist/catalogue.d.ts +0 -1
- package/dist/catalogue.js +26 -8
- 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 +108 -12
- package/dist/commands/createRemixContent.js +33 -3
- 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 +31 -3
- 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/dist/taskSelection.js +2 -2
- 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 +5 -6
- package/node_modules/@playdrop/config/dist/test/validateClientEnvironment.test.js +13 -0
- package/node_modules/@playdrop/config/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@playdrop/types/dist/api.d.ts +204 -2
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/asset.d.ts +18 -50
- package/node_modules/@playdrop/types/dist/asset.d.ts.map +1 -1
- package/package.json +23 -2
package/dist/commands/init.js
CHANGED
|
@@ -16,7 +16,9 @@ const http_1 = require("../http");
|
|
|
16
16
|
const environment_1 = require("../environment");
|
|
17
17
|
const messages_1 = require("../messages");
|
|
18
18
|
const clientInfo_1 = require("../clientInfo");
|
|
19
|
-
const DEFAULT_CATALOGUE =
|
|
19
|
+
const DEFAULT_CATALOGUE = '{}\n';
|
|
20
|
+
const LEGACY_CATALOGUE_VERSION_KEY = ['schema', 'Version'].join('');
|
|
21
|
+
const ALLOWED_CATALOGUE_TOP_LEVEL_KEYS = new Set(['apps', 'assets', 'assetPacks']);
|
|
20
22
|
function ensureTrailingNewline(content) {
|
|
21
23
|
return content.endsWith('\n') ? content : `${content}\n`;
|
|
22
24
|
}
|
|
@@ -53,7 +55,7 @@ async function resolveUsername(apiBase, token) {
|
|
|
53
55
|
}
|
|
54
56
|
if (unknownError instanceof types_1.ApiError) {
|
|
55
57
|
(0, messages_1.printErrorWithHelp)(`Request failed with status ${unknownError.status}.`, [
|
|
56
|
-
'Run "playdrop
|
|
58
|
+
'Run "playdrop login" to refresh your credentials.',
|
|
57
59
|
'Use "playdrop project init" again after logging in.'
|
|
58
60
|
], { command: 'project init' });
|
|
59
61
|
process.exitCode = 1;
|
|
@@ -100,7 +102,33 @@ function normalizeBootstrapPayload(payload) {
|
|
|
100
102
|
const catalogueRaw = typeof payload.catalogue === 'string' && payload.catalogue.trim().length > 0
|
|
101
103
|
? payload.catalogue
|
|
102
104
|
: DEFAULT_CATALOGUE;
|
|
103
|
-
const
|
|
105
|
+
const catalogueCandidate = ensureTrailingNewline(catalogueRaw.trim() ? catalogueRaw : DEFAULT_CATALOGUE);
|
|
106
|
+
let parsedCatalogue;
|
|
107
|
+
try {
|
|
108
|
+
parsedCatalogue = JSON.parse(catalogueCandidate);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
(0, messages_1.printErrorWithHelp)('Bootstrap payload returned an invalid catalogue.json.', ['Contact the platform team or try again shortly.'], { command: 'project init' });
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
if (!parsedCatalogue || typeof parsedCatalogue !== 'object' || Array.isArray(parsedCatalogue)) {
|
|
116
|
+
(0, messages_1.printErrorWithHelp)('Bootstrap payload returned an invalid catalogue.json.', ['Contact the platform team or try again shortly.'], { command: 'project init' });
|
|
117
|
+
process.exitCode = 1;
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
if (Object.prototype.hasOwnProperty.call(parsedCatalogue, LEGACY_CATALOGUE_VERSION_KEY)) {
|
|
121
|
+
(0, messages_1.printErrorWithHelp)('Bootstrap payload returned a legacy catalogue.json with a top-level version field.', ['Contact the platform team or try again shortly.'], { command: 'project init' });
|
|
122
|
+
process.exitCode = 1;
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
const unsupportedKey = Object.keys(parsedCatalogue).find((key) => !ALLOWED_CATALOGUE_TOP_LEVEL_KEYS.has(key));
|
|
126
|
+
if (unsupportedKey) {
|
|
127
|
+
(0, messages_1.printErrorWithHelp)(`Bootstrap payload returned catalogue.json with unsupported top-level key "${unsupportedKey}".`, ['Contact the platform team or try again shortly.'], { command: 'project init' });
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const catalogue = catalogueCandidate;
|
|
104
132
|
return { readmeUri, agentsUri, catalogue };
|
|
105
133
|
}
|
|
106
134
|
async function downloadBootstrapAsset(webBase, uri, label) {
|
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 {
|
package/dist/commands/whoami.js
CHANGED
|
@@ -10,14 +10,14 @@ const messages_1 = require("../messages");
|
|
|
10
10
|
async function whoami() {
|
|
11
11
|
const cfg = (0, config_1.loadConfig)();
|
|
12
12
|
if (!cfg.token || !cfg.env) {
|
|
13
|
-
(0, messages_1.printLoginRequired)('Checking your Playdrop account status', '
|
|
13
|
+
(0, messages_1.printLoginRequired)('Checking your Playdrop account status', 'whoami');
|
|
14
14
|
process.exitCode = 1;
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
const envConfig = (0, environment_1.resolveEnvironmentConfig)(cfg.env);
|
|
18
18
|
if (!envConfig) {
|
|
19
19
|
const choices = (0, environment_1.formatEnvironmentList)();
|
|
20
|
-
(0, messages_1.printUnknownEnvironment)(cfg.env, choices, '
|
|
20
|
+
(0, messages_1.printUnknownEnvironment)(cfg.env, choices, 'whoami');
|
|
21
21
|
process.exitCode = 1;
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
@@ -36,9 +36,9 @@ async function whoami() {
|
|
|
36
36
|
}
|
|
37
37
|
if (unknownError instanceof types_1.ApiError) {
|
|
38
38
|
(0, messages_1.printErrorWithHelp)(`Request failed with status ${unknownError.status}.`, [
|
|
39
|
-
'Run "playdrop
|
|
40
|
-
'Use "playdrop
|
|
41
|
-
], { command: '
|
|
39
|
+
'Run "playdrop login" to refresh your credentials.',
|
|
40
|
+
'Use "playdrop whoami" again after logging in to confirm your status.',
|
|
41
|
+
], { command: 'whoami' });
|
|
42
42
|
process.exitCode = 1;
|
|
43
43
|
return null;
|
|
44
44
|
}
|
|
@@ -53,7 +53,7 @@ async function whoami() {
|
|
|
53
53
|
if (e instanceof http_1.CLIUnsupportedClientError) {
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
|
-
(0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to check your account.', '
|
|
56
|
+
(0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to check your account.', 'whoami');
|
|
57
57
|
process.exitCode = 1;
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
@@ -62,9 +62,9 @@ async function whoami() {
|
|
|
62
62
|
const username = data.user?.username;
|
|
63
63
|
if (!username) {
|
|
64
64
|
(0, messages_1.printErrorWithHelp)('The Playdrop API returned an unexpected response.', [
|
|
65
|
-
'Retry "playdrop
|
|
66
|
-
'If the problem continues, contact the Playdrop team.'
|
|
67
|
-
], { command: '
|
|
65
|
+
'Retry "playdrop whoami" in a moment.',
|
|
66
|
+
'If the problem continues, contact the Playdrop team.',
|
|
67
|
+
], { command: 'whoami' });
|
|
68
68
|
process.exitCode = 1;
|
|
69
69
|
return;
|
|
70
70
|
}
|
package/dist/index.js
CHANGED
|
@@ -40,9 +40,6 @@ function resolveInitTarget(pathArg) {
|
|
|
40
40
|
}
|
|
41
41
|
function printRemovedCommandHint(command) {
|
|
42
42
|
const replacements = {
|
|
43
|
-
login: 'playdrop auth login',
|
|
44
|
-
whoami: 'playdrop auth whoami',
|
|
45
|
-
logout: 'playdrop auth logout',
|
|
46
43
|
list: 'playdrop browse',
|
|
47
44
|
generate: 'playdrop ai create',
|
|
48
45
|
generations: 'playdrop ai jobs browse',
|
|
@@ -93,29 +90,48 @@ program.on('command:*', (unknownCommands) => {
|
|
|
93
90
|
}
|
|
94
91
|
process.exitCode = 1;
|
|
95
92
|
});
|
|
96
|
-
|
|
93
|
+
function createEnvOption() {
|
|
94
|
+
return new commander_1.Option('--env <env>', 'Environment (dev|local|prod)').default('prod');
|
|
95
|
+
}
|
|
96
|
+
function registerLoginCommand(parent) {
|
|
97
|
+
parent
|
|
98
|
+
.command('login')
|
|
99
|
+
.description('Log in to Playdrop')
|
|
100
|
+
.addOption(createEnvOption())
|
|
101
|
+
.option('--username <username>', 'Username for direct login')
|
|
102
|
+
.option('--password <password>', 'Password for direct login')
|
|
103
|
+
.option('--key <apiKey>', 'API key for direct login')
|
|
104
|
+
.action(async (opts) => {
|
|
105
|
+
await (0, login_1.login)(opts.env, {
|
|
106
|
+
username: opts.username,
|
|
107
|
+
password: opts.password,
|
|
108
|
+
key: opts.key,
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function registerLogoutCommand(parent) {
|
|
113
|
+
parent
|
|
114
|
+
.command('logout')
|
|
115
|
+
.description('Log out of Playdrop')
|
|
116
|
+
.action(() => {
|
|
117
|
+
(0, logout_1.logout)();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function registerWhoamiCommand(parent) {
|
|
121
|
+
parent
|
|
122
|
+
.command('whoami')
|
|
123
|
+
.description('Show the current account')
|
|
124
|
+
.action(async () => {
|
|
125
|
+
await (0, whoami_1.whoami)();
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
registerLoginCommand(program);
|
|
129
|
+
registerLogoutCommand(program);
|
|
130
|
+
registerWhoamiCommand(program);
|
|
97
131
|
const auth = program.command('auth').description('Authentication commands');
|
|
98
|
-
auth
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
.addOption(envOption)
|
|
102
|
-
.option('--username <username>', 'Username for non-interactive login')
|
|
103
|
-
.option('--password <password>', 'Password for non-interactive login')
|
|
104
|
-
.action(async (opts) => {
|
|
105
|
-
await (0, login_1.login)(opts.env, opts.username, opts.password);
|
|
106
|
-
});
|
|
107
|
-
auth
|
|
108
|
-
.command('logout')
|
|
109
|
-
.description('Log out of Playdrop')
|
|
110
|
-
.action(() => {
|
|
111
|
-
(0, logout_1.logout)();
|
|
112
|
-
});
|
|
113
|
-
auth
|
|
114
|
-
.command('whoami')
|
|
115
|
-
.description('Show the current account')
|
|
116
|
-
.action(async () => {
|
|
117
|
-
await (0, whoami_1.whoami)();
|
|
118
|
-
});
|
|
132
|
+
registerLoginCommand(auth);
|
|
133
|
+
registerLogoutCommand(auth);
|
|
134
|
+
registerWhoamiCommand(auth);
|
|
119
135
|
const browseCommand = program.command('browse').description('Browse public content');
|
|
120
136
|
browseCommand
|
|
121
137
|
.option('--kind <kind>', 'app, asset, asset-pack, or all')
|
package/dist/messages.js
CHANGED
|
@@ -28,22 +28,22 @@ function printErrorWithHelp(problem, suggestions, options = {}) {
|
|
|
28
28
|
}
|
|
29
29
|
function printLoginRequired(context, command) {
|
|
30
30
|
printErrorWithHelp(`${context} requires you to be logged in.`, [
|
|
31
|
-
'Run "playdrop
|
|
32
|
-
'Use "playdrop
|
|
31
|
+
'Run "playdrop login" to authenticate.',
|
|
32
|
+
'Use "playdrop whoami" to verify your current status.',
|
|
33
33
|
], { command });
|
|
34
34
|
}
|
|
35
35
|
function printUnknownEnvironment(env, available, command) {
|
|
36
36
|
const listLine = available ? `Available environments: ${available}.` : '';
|
|
37
37
|
const suggestions = [
|
|
38
38
|
listLine,
|
|
39
|
-
'Run "playdrop
|
|
39
|
+
'Run "playdrop login --env <env>" to store a supported environment before retrying.',
|
|
40
40
|
].filter(Boolean);
|
|
41
41
|
printErrorWithHelp(`Environment "${env}" is not supported.`, suggestions, { command });
|
|
42
42
|
}
|
|
43
43
|
function printConfigEnvironmentMissing(command) {
|
|
44
44
|
printErrorWithHelp('No environment is configured yet.', [
|
|
45
|
-
'Run "playdrop
|
|
46
|
-
'Use "playdrop
|
|
45
|
+
'Run "playdrop login" to choose an environment and save your credentials.',
|
|
46
|
+
'Use "playdrop whoami" after logging in to confirm your status.',
|
|
47
47
|
], { command });
|
|
48
48
|
}
|
|
49
49
|
function printNetworkIssue(context, command) {
|
package/dist/taskSelection.js
CHANGED
|
@@ -66,8 +66,8 @@ function selectTasks(pathOrName) {
|
|
|
66
66
|
if (taskList.length === 0) {
|
|
67
67
|
errors.push({
|
|
68
68
|
type: 'no-tasks',
|
|
69
|
-
message: `No
|
|
70
|
-
help: ['Add catalogue.json files
|
|
69
|
+
message: `No publishable entries were found under ${absolute}.`,
|
|
70
|
+
help: ['Add child catalogue.json files or add apps, assets, or assetPacks to the root catalogue.json, then rerun the command.'],
|
|
71
71
|
directory: absolute,
|
|
72
72
|
});
|
|
73
73
|
return { tasks: [], warnings, errors, resolution: 'directory' };
|