@displaydev/cli 0.5.0 → 0.7.0
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 +32 -0
- package/dist/api-client.js +274 -4
- package/dist/config.js +220 -0
- package/dist/main-helpers.js +687 -0
- package/dist/main.js +653 -317
- package/dist/mcp-server.js +395 -75
- package/package.json +3 -2
package/dist/main.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
function _array_like_to_array(arr, len) {
|
|
3
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
4
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
5
|
+
return arr2;
|
|
6
|
+
}
|
|
7
|
+
function _array_without_holes(arr) {
|
|
8
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
9
|
+
}
|
|
2
10
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
3
11
|
try {
|
|
4
12
|
var info = gen[key](arg);
|
|
@@ -36,6 +44,23 @@ function _instanceof(left, right) {
|
|
|
36
44
|
return left instanceof right;
|
|
37
45
|
}
|
|
38
46
|
}
|
|
47
|
+
function _iterable_to_array(iter) {
|
|
48
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
49
|
+
}
|
|
50
|
+
function _non_iterable_spread() {
|
|
51
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
52
|
+
}
|
|
53
|
+
function _to_consumable_array(arr) {
|
|
54
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
55
|
+
}
|
|
56
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
57
|
+
if (!o) return;
|
|
58
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
59
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
60
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
61
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
62
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
63
|
+
}
|
|
39
64
|
function _ts_generator(thisArg, body) {
|
|
40
65
|
var f, y, t, _ = {
|
|
41
66
|
label: 0,
|
|
@@ -135,91 +160,38 @@ function _ts_generator(thisArg, body) {
|
|
|
135
160
|
};
|
|
136
161
|
}
|
|
137
162
|
}
|
|
138
|
-
import { readFile
|
|
163
|
+
import { readFile } from 'node:fs/promises';
|
|
139
164
|
import { createInterface } from 'node:readline/promises';
|
|
140
165
|
import { createRequire } from 'node:module';
|
|
141
166
|
import { execFileSync } from 'node:child_process';
|
|
142
|
-
import {
|
|
143
|
-
import { join, extname } from 'node:path';
|
|
167
|
+
import { platform } from 'node:os';
|
|
144
168
|
import { Command } from 'commander';
|
|
145
|
-
import { ApiClient } from './api-client.js';
|
|
169
|
+
import { ApiClient, ApiError } from './api-client.js';
|
|
170
|
+
import { loadConfig, saveConfig } from './config.js';
|
|
146
171
|
import { startMcpServer } from './mcp-server.js';
|
|
172
|
+
import { DEFAULT_API_URL, DeviceCodeDeniedError, DeviceCodeExpiredError, DeviceCodeFailedError, InvalidFlagError, PublishArgsError, classifyBrandingError, parseShortIdAndVersion, parseShowBrandingFlag, pollDeviceToken, readApiKeyFromTty, readStreamToString, resolveAuth as resolveAuthFromEnvAndConfig, validatePublishArgs } from './main-helpers.js';
|
|
147
173
|
var require = createRequire(import.meta.url);
|
|
148
174
|
var version = require('../package.json').version;
|
|
149
|
-
|
|
150
|
-
var CONFIG_DIR = join(homedir(), '.displaydev');
|
|
151
|
-
var CONFIG_PATH = join(CONFIG_DIR, 'config.json');
|
|
152
|
-
function loadConfig() {
|
|
153
|
-
return _async_to_generator(function() {
|
|
154
|
-
var raw, unused;
|
|
155
|
-
return _ts_generator(this, function(_state) {
|
|
156
|
-
switch(_state.label){
|
|
157
|
-
case 0:
|
|
158
|
-
_state.trys.push([
|
|
159
|
-
0,
|
|
160
|
-
2,
|
|
161
|
-
,
|
|
162
|
-
3
|
|
163
|
-
]);
|
|
164
|
-
return [
|
|
165
|
-
4,
|
|
166
|
-
readFile(CONFIG_PATH, 'utf-8')
|
|
167
|
-
];
|
|
168
|
-
case 1:
|
|
169
|
-
raw = _state.sent();
|
|
170
|
-
return [
|
|
171
|
-
2,
|
|
172
|
-
JSON.parse(raw)
|
|
173
|
-
];
|
|
174
|
-
case 2:
|
|
175
|
-
unused = _state.sent();
|
|
176
|
-
return [
|
|
177
|
-
2,
|
|
178
|
-
null
|
|
179
|
-
];
|
|
180
|
-
case 3:
|
|
181
|
-
return [
|
|
182
|
-
2
|
|
183
|
-
];
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
})();
|
|
187
|
-
}
|
|
188
|
-
function saveConfig(config) {
|
|
175
|
+
function resolveAuthOrConfig() {
|
|
189
176
|
return _async_to_generator(function() {
|
|
190
|
-
var
|
|
177
|
+
var auth;
|
|
191
178
|
return _ts_generator(this, function(_state) {
|
|
192
179
|
switch(_state.label){
|
|
193
180
|
case 0:
|
|
194
181
|
return [
|
|
195
182
|
4,
|
|
196
|
-
|
|
197
|
-
recursive: true
|
|
198
|
-
})
|
|
183
|
+
resolveAuthOrConfigOptional()
|
|
199
184
|
];
|
|
200
185
|
case 1:
|
|
201
|
-
_state.sent();
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
_state.sent();
|
|
211
|
-
return [
|
|
212
|
-
4,
|
|
213
|
-
rename(tmpPath, CONFIG_PATH)
|
|
214
|
-
];
|
|
215
|
-
case 3:
|
|
216
|
-
_state.sent();
|
|
217
|
-
return [
|
|
218
|
-
4,
|
|
219
|
-
chmod(CONFIG_PATH, 384)
|
|
220
|
-
];
|
|
221
|
-
case 4:
|
|
222
|
-
_state.sent();
|
|
186
|
+
auth = _state.sent();
|
|
187
|
+
if (auth) {
|
|
188
|
+
return [
|
|
189
|
+
2,
|
|
190
|
+
auth
|
|
191
|
+
];
|
|
192
|
+
}
|
|
193
|
+
console.error('Not authenticated. Set DISPLAYDEV_API_KEY or run: dsp login');
|
|
194
|
+
process.exit(1);
|
|
223
195
|
return [
|
|
224
196
|
2
|
|
225
197
|
];
|
|
@@ -227,55 +199,34 @@ function saveConfig(config) {
|
|
|
227
199
|
});
|
|
228
200
|
})();
|
|
229
201
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
apiKey: apiKey,
|
|
236
|
-
apiUrl: (_process_env_DISPLAYDEV_API_URL = process.env.DISPLAYDEV_API_URL) !== null && _process_env_DISPLAYDEV_API_URL !== void 0 ? _process_env_DISPLAYDEV_API_URL : DEFAULT_API_URL
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
function resolveAuthOrConfig() {
|
|
202
|
+
/**
|
|
203
|
+
* Like `resolveAuthOrConfig()` but returns null instead of exiting when
|
|
204
|
+
* no credential is present. Used by flows that have a fallback (public
|
|
205
|
+
* publish) or a different behaviour without auth (MCP public-only tools).
|
|
206
|
+
*/ function resolveAuthOrConfigOptional() {
|
|
242
207
|
return _async_to_generator(function() {
|
|
243
|
-
var
|
|
208
|
+
var config;
|
|
244
209
|
return _ts_generator(this, function(_state) {
|
|
245
210
|
switch(_state.label){
|
|
246
211
|
case 0:
|
|
247
|
-
env = resolveAuth();
|
|
248
|
-
if (env) {
|
|
249
|
-
return [
|
|
250
|
-
2,
|
|
251
|
-
env
|
|
252
|
-
];
|
|
253
|
-
}
|
|
254
212
|
return [
|
|
255
213
|
4,
|
|
256
214
|
loadConfig()
|
|
257
215
|
];
|
|
258
216
|
case 1:
|
|
259
217
|
config = _state.sent();
|
|
260
|
-
if (config === null || config === void 0 ? void 0 : config.token) {
|
|
261
|
-
;
|
|
262
|
-
return [
|
|
263
|
-
2,
|
|
264
|
-
{
|
|
265
|
-
apiKey: config.token,
|
|
266
|
-
apiUrl: (_config_apiUrl = config.apiUrl) !== null && _config_apiUrl !== void 0 ? _config_apiUrl : DEFAULT_API_URL
|
|
267
|
-
}
|
|
268
|
-
];
|
|
269
|
-
}
|
|
270
|
-
console.error('Not authenticated. Set DISPLAYDEV_API_KEY or run: dsp login');
|
|
271
|
-
process.exit(1);
|
|
272
218
|
return [
|
|
273
|
-
2
|
|
219
|
+
2,
|
|
220
|
+
resolveAuthFromEnvAndConfig(process.env, config)
|
|
274
221
|
];
|
|
275
222
|
}
|
|
276
223
|
});
|
|
277
224
|
})();
|
|
278
225
|
}
|
|
226
|
+
function resolvePublicApiUrl() {
|
|
227
|
+
var _process_env_DISPLAYDEV_API_URL;
|
|
228
|
+
return (_process_env_DISPLAYDEV_API_URL = process.env.DISPLAYDEV_API_URL) !== null && _process_env_DISPLAYDEV_API_URL !== void 0 ? _process_env_DISPLAYDEV_API_URL : DEFAULT_API_URL;
|
|
229
|
+
}
|
|
279
230
|
function createClient(auth) {
|
|
280
231
|
return new ApiClient({
|
|
281
232
|
baseUrl: auth.apiUrl,
|
|
@@ -287,57 +238,225 @@ var program = new Command().name('dsp').description('display.dev CLI — publish
|
|
|
287
238
|
function collectEmails(value, prev) {
|
|
288
239
|
return prev.concat(value);
|
|
289
240
|
}
|
|
241
|
+
function parseShowBrandingOrExit(raw) {
|
|
242
|
+
try {
|
|
243
|
+
return parseShowBrandingFlag(raw);
|
|
244
|
+
} catch (err) {
|
|
245
|
+
if (_instanceof(err, InvalidFlagError)) {
|
|
246
|
+
console.error("Invalid ".concat(err.flag, ": ").concat(err.value, ". Use show, hide, or inherit."));
|
|
247
|
+
process.exit(1);
|
|
248
|
+
}
|
|
249
|
+
throw err;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
290
252
|
// --- publish ---
|
|
291
|
-
program.command('publish <path>').description('Publish an HTML or Markdown file').option('--name <name>', 'Artifact display name').option('--id <shortId>', 'Update existing artifact (new version)').option('--public', 'Make artifact publicly accessible').option('--company', 'Restrict artifact to company auth (
|
|
253
|
+
program.command('publish <path>').description('Publish an HTML or Markdown file. Use "-" to read from stdin (requires --id).').option('--name <name>', 'Artifact display name').option('--id <shortId>', 'Update existing artifact (new version)').option('--public', 'Make artifact publicly accessible (alias for --visibility public)').option('--company', 'Restrict artifact to company auth (alias for --visibility company)').option('--visibility <level>', 'public | company | private. "private" requires the Teams plan.').option('--share <email>', 'Add an email to sharedWith (repeatable; alias for --share-with)', collectEmails, []).option('--share-with <emails>', 'Comma-separated email list for sharedWith', function(val) {
|
|
254
|
+
return val.split(',').map(function(e) {
|
|
255
|
+
return e.trim();
|
|
256
|
+
}).filter(Boolean);
|
|
257
|
+
}).option('--clear-shares', 'Remove all sharedWith entries (update only)').option('--theme <theme>', 'Markdown theme (default: github)').option('--show-branding <mode>', 'display.dev bar override: show, hide, or inherit (paid plans only)').action(function(filePath, opts) {
|
|
292
258
|
return _async_to_generator(function() {
|
|
293
|
-
var auth,
|
|
259
|
+
var _opts_shareWith, showBranding, auth, fromStdin, format, content, inferClient, detail, err, msg, publicClient, publicResult, err1, msg1, client, visibility, mergedShare, share, result, err2, msg2, verb;
|
|
294
260
|
return _ts_generator(this, function(_state) {
|
|
295
261
|
switch(_state.label){
|
|
296
262
|
case 0:
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
263
|
+
showBranding = parseShowBrandingOrExit(opts.showBranding);
|
|
264
|
+
return [
|
|
265
|
+
4,
|
|
266
|
+
resolveAuthOrConfigOptional()
|
|
267
|
+
];
|
|
268
|
+
case 1:
|
|
269
|
+
auth = _state.sent();
|
|
270
|
+
fromStdin = filePath === '-';
|
|
271
|
+
if (fromStdin) {
|
|
272
|
+
// stdin path is for re-publishing existing artifacts (`dsp export | dsp
|
|
273
|
+
// publish --id <id> -`). Path-specific gates run first so the user gets
|
|
274
|
+
// a clear error before we touch the network or stdin.
|
|
275
|
+
if (!auth) {
|
|
276
|
+
console.error('Reading from stdin (-) requires auth. Run: dsp login');
|
|
277
|
+
process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
if (!opts.id) {
|
|
280
|
+
console.error('Reading from stdin (-) requires --id <shortId>.');
|
|
281
|
+
process.exit(2);
|
|
282
|
+
}
|
|
283
|
+
if (process.stdin.isTTY) {
|
|
284
|
+
console.error('cannot read source from a TTY; pipe a file or use a path');
|
|
285
|
+
process.exit(2);
|
|
286
|
+
}
|
|
300
287
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
288
|
+
try {
|
|
289
|
+
validatePublishArgs({
|
|
290
|
+
name: opts.name,
|
|
291
|
+
id: opts.id,
|
|
292
|
+
public: opts.public,
|
|
293
|
+
company: opts.company,
|
|
294
|
+
visibility: opts.visibility,
|
|
295
|
+
share: opts.share,
|
|
296
|
+
shareWith: opts.shareWith,
|
|
297
|
+
clearShares: opts.clearShares,
|
|
298
|
+
showBranding: opts.showBranding,
|
|
299
|
+
filePath: filePath,
|
|
300
|
+
authenticated: auth !== null,
|
|
301
|
+
fromStdin: fromStdin
|
|
302
|
+
});
|
|
303
|
+
} catch (err) {
|
|
304
|
+
if (_instanceof(err, PublishArgsError)) {
|
|
305
|
+
console.error(err.message);
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
308
|
+
throw err;
|
|
304
309
|
}
|
|
305
|
-
if (
|
|
306
|
-
|
|
310
|
+
if (!fromStdin) return [
|
|
311
|
+
3,
|
|
312
|
+
7
|
|
313
|
+
];
|
|
314
|
+
// The artifact's format is fixed at create — infer it via GET so the
|
|
315
|
+
// round-trip preserves it without making the caller pass --format.
|
|
316
|
+
inferClient = createClient(auth);
|
|
317
|
+
_state.label = 2;
|
|
318
|
+
case 2:
|
|
319
|
+
_state.trys.push([
|
|
320
|
+
2,
|
|
321
|
+
4,
|
|
322
|
+
,
|
|
323
|
+
5
|
|
324
|
+
]);
|
|
325
|
+
return [
|
|
326
|
+
4,
|
|
327
|
+
inferClient.get(opts.id)
|
|
328
|
+
];
|
|
329
|
+
case 3:
|
|
330
|
+
detail = _state.sent();
|
|
331
|
+
format = detail.format === 'md' ? 'md' : 'html';
|
|
332
|
+
return [
|
|
333
|
+
3,
|
|
334
|
+
5
|
|
335
|
+
];
|
|
336
|
+
case 4:
|
|
337
|
+
err = _state.sent();
|
|
338
|
+
if (_instanceof(err, ApiError) && (err.status === 401 || err.status === 403)) {
|
|
339
|
+
console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
|
|
307
340
|
process.exit(1);
|
|
308
341
|
}
|
|
309
|
-
if (
|
|
310
|
-
console.error(
|
|
311
|
-
process.exit(
|
|
342
|
+
if (_instanceof(err, ApiError) && err.status === 404) {
|
|
343
|
+
console.error("Artifact not found: ".concat(opts.id));
|
|
344
|
+
process.exit(4);
|
|
312
345
|
}
|
|
346
|
+
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
347
|
+
console.error(msg);
|
|
348
|
+
process.exit(1);
|
|
349
|
+
return [
|
|
350
|
+
3,
|
|
351
|
+
5
|
|
352
|
+
];
|
|
353
|
+
case 5:
|
|
313
354
|
return [
|
|
314
355
|
4,
|
|
315
|
-
|
|
356
|
+
readStreamToString(process.stdin)
|
|
316
357
|
];
|
|
317
|
-
case
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
358
|
+
case 6:
|
|
359
|
+
content = _state.sent();
|
|
360
|
+
return [
|
|
361
|
+
3,
|
|
362
|
+
9
|
|
363
|
+
];
|
|
364
|
+
case 7:
|
|
365
|
+
format = filePath.toLowerCase().endsWith('.md') ? 'md' : 'html';
|
|
325
366
|
return [
|
|
326
367
|
4,
|
|
327
368
|
readFile(filePath, 'utf-8')
|
|
328
369
|
];
|
|
329
|
-
case
|
|
370
|
+
case 8:
|
|
330
371
|
content = _state.sent();
|
|
331
|
-
|
|
332
|
-
|
|
372
|
+
_state.label = 9;
|
|
373
|
+
case 9:
|
|
374
|
+
if (!!auth) return [
|
|
375
|
+
3,
|
|
376
|
+
14
|
|
377
|
+
];
|
|
378
|
+
publicClient = new ApiClient({
|
|
379
|
+
baseUrl: resolvePublicApiUrl(),
|
|
380
|
+
apiKey: '',
|
|
381
|
+
clientType: 'cli'
|
|
382
|
+
});
|
|
383
|
+
_state.label = 10;
|
|
384
|
+
case 10:
|
|
385
|
+
_state.trys.push([
|
|
386
|
+
10,
|
|
387
|
+
12,
|
|
388
|
+
,
|
|
389
|
+
13
|
|
390
|
+
]);
|
|
391
|
+
return [
|
|
392
|
+
4,
|
|
393
|
+
publicClient.publishPublic({
|
|
394
|
+
content: content,
|
|
395
|
+
name: opts.name,
|
|
396
|
+
format: format
|
|
397
|
+
})
|
|
398
|
+
];
|
|
399
|
+
case 11:
|
|
400
|
+
publicResult = _state.sent();
|
|
401
|
+
return [
|
|
402
|
+
3,
|
|
403
|
+
13
|
|
404
|
+
];
|
|
405
|
+
case 12:
|
|
406
|
+
err1 = _state.sent();
|
|
407
|
+
msg1 = _instanceof(err1, Error) ? err1.message : String(err1);
|
|
408
|
+
console.error(msg1);
|
|
409
|
+
process.exit(1);
|
|
410
|
+
return [
|
|
411
|
+
3,
|
|
412
|
+
13
|
|
413
|
+
];
|
|
414
|
+
case 13:
|
|
415
|
+
// Full response as JSON on stdout so `dsp publish … | jq -r .previewUrl`
|
|
416
|
+
// works alongside the human-readable block on stderr.
|
|
417
|
+
console.log(JSON.stringify(publicResult));
|
|
418
|
+
process.stderr.write([
|
|
419
|
+
'',
|
|
420
|
+
"Published anonymously — nobody owns this artifact yet.",
|
|
421
|
+
" Preview: ".concat(publicResult.previewUrl),
|
|
422
|
+
" Claim: ".concat(publicResult.claimUrl),
|
|
423
|
+
" Expires: ".concat(publicResult.expiresAt),
|
|
424
|
+
"Sign in at the claim URL to move it into your display.dev organization.",
|
|
425
|
+
''
|
|
426
|
+
].join('\n'));
|
|
427
|
+
return [
|
|
428
|
+
2
|
|
429
|
+
];
|
|
430
|
+
case 14:
|
|
431
|
+
// --- Authenticated path — `--id` is update, otherwise create. ---
|
|
432
|
+
client = createClient(auth);
|
|
433
|
+
if (opts.visibility) {
|
|
434
|
+
if (opts.visibility !== 'public' && opts.visibility !== 'company' && opts.visibility !== 'private') {
|
|
435
|
+
console.error("Invalid --visibility: ".concat(opts.visibility, ". Use public, company, or private."));
|
|
436
|
+
process.exit(1);
|
|
437
|
+
}
|
|
438
|
+
visibility = opts.visibility;
|
|
439
|
+
} else if (opts.public) {
|
|
333
440
|
visibility = 'public';
|
|
334
441
|
} else if (opts.company) {
|
|
335
442
|
visibility = 'company';
|
|
336
443
|
}
|
|
337
|
-
share
|
|
444
|
+
// --share-with (csv) and --share (repeatable) both contribute to the
|
|
445
|
+
// sharedWith list. Concatenating rather than making them mutually
|
|
446
|
+
// exclusive keeps CLI composition simple for scripts that want to mix.
|
|
447
|
+
mergedShare = _to_consumable_array((_opts_shareWith = opts.shareWith) !== null && _opts_shareWith !== void 0 ? _opts_shareWith : []).concat(_to_consumable_array(opts.share));
|
|
448
|
+
share = mergedShare.length > 0 ? mergedShare : undefined;
|
|
449
|
+
_state.label = 15;
|
|
450
|
+
case 15:
|
|
451
|
+
_state.trys.push([
|
|
452
|
+
15,
|
|
453
|
+
20,
|
|
454
|
+
,
|
|
455
|
+
21
|
|
456
|
+
]);
|
|
338
457
|
if (!opts.id) return [
|
|
339
458
|
3,
|
|
340
|
-
|
|
459
|
+
17
|
|
341
460
|
];
|
|
342
461
|
return [
|
|
343
462
|
4,
|
|
@@ -348,16 +467,17 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
|
|
|
348
467
|
theme: opts.theme,
|
|
349
468
|
share: share,
|
|
350
469
|
clearShares: opts.clearShares,
|
|
351
|
-
visibility: visibility
|
|
470
|
+
visibility: visibility,
|
|
471
|
+
showBranding: showBranding
|
|
352
472
|
})
|
|
353
473
|
];
|
|
354
|
-
case
|
|
474
|
+
case 16:
|
|
355
475
|
result = _state.sent();
|
|
356
476
|
return [
|
|
357
477
|
3,
|
|
358
|
-
|
|
478
|
+
19
|
|
359
479
|
];
|
|
360
|
-
case
|
|
480
|
+
case 17:
|
|
361
481
|
return [
|
|
362
482
|
4,
|
|
363
483
|
client.publish({
|
|
@@ -366,13 +486,38 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
|
|
|
366
486
|
format: format,
|
|
367
487
|
theme: opts.theme,
|
|
368
488
|
share: share,
|
|
369
|
-
visibility: visibility
|
|
489
|
+
visibility: visibility,
|
|
490
|
+
showBranding: showBranding
|
|
370
491
|
})
|
|
371
492
|
];
|
|
372
|
-
case
|
|
493
|
+
case 18:
|
|
373
494
|
result = _state.sent();
|
|
374
|
-
_state.label =
|
|
375
|
-
case
|
|
495
|
+
_state.label = 19;
|
|
496
|
+
case 19:
|
|
497
|
+
return [
|
|
498
|
+
3,
|
|
499
|
+
21
|
|
500
|
+
];
|
|
501
|
+
case 20:
|
|
502
|
+
err2 = _state.sent();
|
|
503
|
+
// Fail closed on an expired / revoked credential: do NOT fall through
|
|
504
|
+
// to the public endpoint, since the user intended a workspace publish.
|
|
505
|
+
if (_instanceof(err2, ApiError) && (err2.status === 401 || err2.status === 403)) {
|
|
506
|
+
console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
|
|
507
|
+
process.exit(1);
|
|
508
|
+
}
|
|
509
|
+
msg2 = _instanceof(err2, Error) ? err2.message : String(err2);
|
|
510
|
+
if (classifyBrandingError(msg2) === 'paid-plan') {
|
|
511
|
+
console.error('Error: Hiding display.dev branding requires a paid plan. See https://display.dev/billing');
|
|
512
|
+
} else {
|
|
513
|
+
console.error(msg2);
|
|
514
|
+
}
|
|
515
|
+
process.exit(1);
|
|
516
|
+
return [
|
|
517
|
+
3,
|
|
518
|
+
21
|
|
519
|
+
];
|
|
520
|
+
case 21:
|
|
376
521
|
console.log(result.url);
|
|
377
522
|
verb = opts.id ? 'Updated' : 'Published';
|
|
378
523
|
console.log("".concat(verb, " ").concat(result.name, " (").concat(result.shortId, ") v").concat(result.version));
|
|
@@ -383,6 +528,96 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
|
|
|
383
528
|
});
|
|
384
529
|
})();
|
|
385
530
|
});
|
|
531
|
+
// --- share ---
|
|
532
|
+
program.command('share <shortId>').description('Change an artifact\'s visibility and/or add/remove shared-with emails.').option('--visibility <level>', 'public | company | private. "private" requires the Teams plan.').option('--add-users <emails>', 'Comma-separated emails to add to sharedWith', function(val) {
|
|
533
|
+
return val.split(',').map(function(e) {
|
|
534
|
+
return e.trim();
|
|
535
|
+
}).filter(Boolean);
|
|
536
|
+
}).option('--remove-users <emails>', 'Comma-separated emails to remove from sharedWith', function(val) {
|
|
537
|
+
return val.split(',').map(function(e) {
|
|
538
|
+
return e.trim();
|
|
539
|
+
}).filter(Boolean);
|
|
540
|
+
}).action(function(shortId, opts) {
|
|
541
|
+
return _async_to_generator(function() {
|
|
542
|
+
var auth, client, result, err, msg;
|
|
543
|
+
return _ts_generator(this, function(_state) {
|
|
544
|
+
switch(_state.label){
|
|
545
|
+
case 0:
|
|
546
|
+
if (opts.visibility === undefined && (!opts.addUsers || opts.addUsers.length === 0) && (!opts.removeUsers || opts.removeUsers.length === 0)) {
|
|
547
|
+
console.error('Provide at least one of --visibility, --add-users, --remove-users.');
|
|
548
|
+
process.exit(1);
|
|
549
|
+
}
|
|
550
|
+
if (opts.visibility !== undefined && opts.visibility !== 'public' && opts.visibility !== 'company' && opts.visibility !== 'private') {
|
|
551
|
+
console.error("Invalid --visibility: ".concat(opts.visibility, ". Use public, company, or private."));
|
|
552
|
+
process.exit(1);
|
|
553
|
+
}
|
|
554
|
+
return [
|
|
555
|
+
4,
|
|
556
|
+
resolveAuthOrConfig()
|
|
557
|
+
];
|
|
558
|
+
case 1:
|
|
559
|
+
auth = _state.sent();
|
|
560
|
+
client = createClient(auth);
|
|
561
|
+
_state.label = 2;
|
|
562
|
+
case 2:
|
|
563
|
+
_state.trys.push([
|
|
564
|
+
2,
|
|
565
|
+
4,
|
|
566
|
+
,
|
|
567
|
+
5
|
|
568
|
+
]);
|
|
569
|
+
return [
|
|
570
|
+
4,
|
|
571
|
+
client.share(shortId, {
|
|
572
|
+
visibility: opts.visibility,
|
|
573
|
+
addUsers: opts.addUsers,
|
|
574
|
+
removeUsers: opts.removeUsers
|
|
575
|
+
})
|
|
576
|
+
];
|
|
577
|
+
case 3:
|
|
578
|
+
result = _state.sent();
|
|
579
|
+
console.log(JSON.stringify(result, null, 2));
|
|
580
|
+
return [
|
|
581
|
+
3,
|
|
582
|
+
5
|
|
583
|
+
];
|
|
584
|
+
case 4:
|
|
585
|
+
err = _state.sent();
|
|
586
|
+
if (_instanceof(err, ApiError) && err.status === 402) {
|
|
587
|
+
console.error('Error: Private visibility requires the Teams plan. Upgrade at https://display.dev/pricing');
|
|
588
|
+
process.exit(1);
|
|
589
|
+
}
|
|
590
|
+
if (_instanceof(err, ApiError) && err.status === 404) {
|
|
591
|
+
console.error("Artifact not found: ".concat(shortId));
|
|
592
|
+
process.exit(4);
|
|
593
|
+
}
|
|
594
|
+
if (_instanceof(err, ApiError) && err.status === 401) {
|
|
595
|
+
// 401 is always "credential expired / revoked" — sessions + api keys
|
|
596
|
+
// both return it on an invalid secret. 403 is authorization ("you're
|
|
597
|
+
// signed in but not allowed"), which we surface with the API's own
|
|
598
|
+
// message below.
|
|
599
|
+
console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
|
|
600
|
+
process.exit(1);
|
|
601
|
+
}
|
|
602
|
+
if (_instanceof(err, ApiError) && (err.status === 400 || err.status === 403)) {
|
|
603
|
+
console.error(err.message);
|
|
604
|
+
process.exit(1);
|
|
605
|
+
}
|
|
606
|
+
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
607
|
+
console.error(msg);
|
|
608
|
+
process.exit(1);
|
|
609
|
+
return [
|
|
610
|
+
3,
|
|
611
|
+
5
|
|
612
|
+
];
|
|
613
|
+
case 5:
|
|
614
|
+
return [
|
|
615
|
+
2
|
|
616
|
+
];
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
})();
|
|
620
|
+
});
|
|
386
621
|
// --- find ---
|
|
387
622
|
program.command('find [query]').description('Search for artifacts').option('--by <email>', 'Filter by publisher email').option('--mine', 'Show only artifacts you published').option('--since <date>', 'Filter by date (ISO format)').option('--sort <col>', 'Sort column: updated_at, view_count, name', 'updated_at').option('--dir <direction>', 'Sort direction: asc or desc').option('--limit <n>', 'Max rows to fetch (1-100)', function(v) {
|
|
388
623
|
return parseInt(v, 10);
|
|
@@ -458,13 +693,46 @@ program.command('find [query]').description('Search for artifacts').option('--by
|
|
|
458
693
|
});
|
|
459
694
|
})();
|
|
460
695
|
});
|
|
461
|
-
// --- get ---
|
|
462
|
-
program.command('get <shortId>').description('Get artifact details').option('--include <field>', 'Include additional data (repeatable, e.g. versions)', collectEmails, []).action(function(shortId, opts) {
|
|
696
|
+
// --- get ---
|
|
697
|
+
program.command('get <shortId>').description('Get artifact details').option('--include <field>', 'Include additional data (repeatable, e.g. versions)', collectEmails, []).action(function(shortId, opts) {
|
|
698
|
+
return _async_to_generator(function() {
|
|
699
|
+
var auth, client, result;
|
|
700
|
+
return _ts_generator(this, function(_state) {
|
|
701
|
+
switch(_state.label){
|
|
702
|
+
case 0:
|
|
703
|
+
return [
|
|
704
|
+
4,
|
|
705
|
+
resolveAuthOrConfig()
|
|
706
|
+
];
|
|
707
|
+
case 1:
|
|
708
|
+
auth = _state.sent();
|
|
709
|
+
client = createClient(auth);
|
|
710
|
+
return [
|
|
711
|
+
4,
|
|
712
|
+
client.get(shortId, opts.include.length > 0 ? opts.include : undefined)
|
|
713
|
+
];
|
|
714
|
+
case 2:
|
|
715
|
+
result = _state.sent();
|
|
716
|
+
console.log(JSON.stringify(result, null, 2));
|
|
717
|
+
return [
|
|
718
|
+
2
|
|
719
|
+
];
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
})();
|
|
723
|
+
});
|
|
724
|
+
// --- export ---
|
|
725
|
+
program.command('export <shortId>').description('Print the published source bytes to stdout. Pin a version with @<n>.').action(function(shortIdArg) {
|
|
463
726
|
return _async_to_generator(function() {
|
|
464
|
-
var auth, client, result;
|
|
727
|
+
var parsed, auth, client, result, err, msg;
|
|
465
728
|
return _ts_generator(this, function(_state) {
|
|
466
729
|
switch(_state.label){
|
|
467
730
|
case 0:
|
|
731
|
+
parsed = parseShortIdAndVersion(shortIdArg);
|
|
732
|
+
if (!parsed) {
|
|
733
|
+
console.error('Invalid argument. Expected <shortId> or <shortId>@<version> (version must be a positive integer).');
|
|
734
|
+
process.exit(2);
|
|
735
|
+
}
|
|
468
736
|
return [
|
|
469
737
|
4,
|
|
470
738
|
resolveAuthOrConfig()
|
|
@@ -472,13 +740,50 @@ program.command('get <shortId>').description('Get artifact details').option('--i
|
|
|
472
740
|
case 1:
|
|
473
741
|
auth = _state.sent();
|
|
474
742
|
client = createClient(auth);
|
|
743
|
+
_state.label = 2;
|
|
744
|
+
case 2:
|
|
745
|
+
_state.trys.push([
|
|
746
|
+
2,
|
|
747
|
+
4,
|
|
748
|
+
,
|
|
749
|
+
5
|
|
750
|
+
]);
|
|
475
751
|
return [
|
|
476
752
|
4,
|
|
477
|
-
client.
|
|
753
|
+
client.exportSource(parsed.shortId, parsed.version)
|
|
478
754
|
];
|
|
479
|
-
case
|
|
755
|
+
case 3:
|
|
480
756
|
result = _state.sent();
|
|
481
|
-
|
|
757
|
+
return [
|
|
758
|
+
3,
|
|
759
|
+
5
|
|
760
|
+
];
|
|
761
|
+
case 4:
|
|
762
|
+
err = _state.sent();
|
|
763
|
+
if (_instanceof(err, ApiError)) {
|
|
764
|
+
if (err.status === 404) {
|
|
765
|
+
console.error('Artifact not found');
|
|
766
|
+
process.exit(4);
|
|
767
|
+
}
|
|
768
|
+
if (err.status === 403) {
|
|
769
|
+
console.error('Forbidden');
|
|
770
|
+
process.exit(4);
|
|
771
|
+
}
|
|
772
|
+
if (err.status === 401) {
|
|
773
|
+
console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
|
|
774
|
+
process.exit(1);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
778
|
+
console.error(msg);
|
|
779
|
+
process.exit(1);
|
|
780
|
+
return [
|
|
781
|
+
3,
|
|
782
|
+
5
|
|
783
|
+
];
|
|
784
|
+
case 5:
|
|
785
|
+
// Binary-clean: write Buffer directly, no console.log (which appends \n).
|
|
786
|
+
process.stdout.write(result.data);
|
|
482
787
|
return [
|
|
483
788
|
2
|
|
484
789
|
];
|
|
@@ -519,6 +824,9 @@ program.command('delete <shortId>').description('Delete an artifact permanently'
|
|
|
519
824
|
})();
|
|
520
825
|
});
|
|
521
826
|
function openBrowser(url) {
|
|
827
|
+
if (process.env.DISPLAYDEV_SKIP_BROWSER) {
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
522
830
|
try {
|
|
523
831
|
var os = platform();
|
|
524
832
|
if (os === 'darwin') {
|
|
@@ -542,15 +850,10 @@ function openBrowser(url) {
|
|
|
542
850
|
// URL is already printed — user can open it manually
|
|
543
851
|
}
|
|
544
852
|
}
|
|
545
|
-
function sleep(ms) {
|
|
546
|
-
return new Promise(function(resolve) {
|
|
547
|
-
return setTimeout(resolve, ms);
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
853
|
// --- login ---
|
|
551
854
|
program.command('login').description('Authenticate with display.dev').option('--email <email>', 'Email address').option('--code <code>', 'OTP code (verify step; pair with --email)').option('--api-key [key]', 'Authenticate with an API key').option('--json', 'Machine-readable output (structured status, no prose)').action(function(opts) {
|
|
552
855
|
return _async_to_generator(function() {
|
|
553
|
-
var _process_env_DISPLAYDEV_API_URL, emit, emitErr, apiUrl, client, key, rl, validation, email, rl1, method, check,
|
|
856
|
+
var _process_env_DISPLAYDEV_API_URL, emit, emitErr, apiUrl, client, key, unused, rl, validation, email, rl1, method, check, unused1, err, msg, code, rl2, result, unused2, deviceResult, unused3, device_code, verification_uri_complete, initialInterval, expires_in, token, err1;
|
|
554
857
|
return _ts_generator(this, function(_state) {
|
|
555
858
|
switch(_state.label){
|
|
556
859
|
case 0:
|
|
@@ -578,7 +881,7 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
578
881
|
});
|
|
579
882
|
if (!(opts.apiKey !== undefined)) return [
|
|
580
883
|
3,
|
|
581
|
-
|
|
884
|
+
11
|
|
582
885
|
];
|
|
583
886
|
if (!(typeof opts.apiKey === 'string')) return [
|
|
584
887
|
3,
|
|
@@ -587,54 +890,46 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
587
890
|
key = opts.apiKey;
|
|
588
891
|
return [
|
|
589
892
|
3,
|
|
590
|
-
|
|
893
|
+
8
|
|
591
894
|
];
|
|
592
895
|
case 1:
|
|
593
896
|
if (!process.stdin.isTTY) return [
|
|
594
897
|
3,
|
|
595
|
-
|
|
898
|
+
6
|
|
596
899
|
];
|
|
597
|
-
//
|
|
900
|
+
// Raw-mode input suppresses terminal echo.
|
|
598
901
|
process.stdout.write('API key: ');
|
|
902
|
+
_state.label = 2;
|
|
903
|
+
case 2:
|
|
904
|
+
_state.trys.push([
|
|
905
|
+
2,
|
|
906
|
+
4,
|
|
907
|
+
,
|
|
908
|
+
5
|
|
909
|
+
]);
|
|
599
910
|
return [
|
|
600
911
|
4,
|
|
601
|
-
|
|
602
|
-
var input = '';
|
|
603
|
-
process.stdin.setRawMode(true);
|
|
604
|
-
process.stdin.resume();
|
|
605
|
-
process.stdin.setEncoding('utf8');
|
|
606
|
-
var cleanup = function cleanup() {
|
|
607
|
-
process.stdin.setRawMode(false);
|
|
608
|
-
process.stdin.pause();
|
|
609
|
-
process.stdin.removeListener('data', onData);
|
|
610
|
-
};
|
|
611
|
-
var onData = function onData(ch) {
|
|
612
|
-
if (ch === '\r' || ch === '\n') {
|
|
613
|
-
cleanup();
|
|
614
|
-
process.stdout.write('\n');
|
|
615
|
-
resolve(input);
|
|
616
|
-
} else if (ch === '\u0003') {
|
|
617
|
-
cleanup();
|
|
618
|
-
process.stdout.write('\n');
|
|
619
|
-
process.exit(1);
|
|
620
|
-
} else if (ch === '\u007F' || ch === '\b') {
|
|
621
|
-
if (input.length > 0) {
|
|
622
|
-
input = input.slice(0, -1);
|
|
623
|
-
}
|
|
624
|
-
} else {
|
|
625
|
-
input += ch;
|
|
626
|
-
}
|
|
627
|
-
};
|
|
628
|
-
process.stdin.on('data', onData);
|
|
629
|
-
})
|
|
912
|
+
readApiKeyFromTty(process.stdin, process.stdout)
|
|
630
913
|
];
|
|
631
|
-
case
|
|
914
|
+
case 3:
|
|
632
915
|
key = _state.sent();
|
|
633
916
|
return [
|
|
634
917
|
3,
|
|
635
918
|
5
|
|
636
919
|
];
|
|
637
|
-
case
|
|
920
|
+
case 4:
|
|
921
|
+
unused = _state.sent();
|
|
922
|
+
process.exit(1);
|
|
923
|
+
return [
|
|
924
|
+
3,
|
|
925
|
+
5
|
|
926
|
+
];
|
|
927
|
+
case 5:
|
|
928
|
+
return [
|
|
929
|
+
3,
|
|
930
|
+
8
|
|
931
|
+
];
|
|
932
|
+
case 6:
|
|
638
933
|
// Non-TTY: read from stdin (piped input)
|
|
639
934
|
rl = createInterface({
|
|
640
935
|
input: process.stdin,
|
|
@@ -644,11 +939,11 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
644
939
|
4,
|
|
645
940
|
rl.question('API key: ')
|
|
646
941
|
];
|
|
647
|
-
case
|
|
942
|
+
case 7:
|
|
648
943
|
key = _state.sent();
|
|
649
944
|
rl.close();
|
|
650
|
-
_state.label =
|
|
651
|
-
case
|
|
945
|
+
_state.label = 8;
|
|
946
|
+
case 8:
|
|
652
947
|
key = key.trim();
|
|
653
948
|
if (!key) {
|
|
654
949
|
console.error('API key cannot be empty.');
|
|
@@ -658,7 +953,7 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
658
953
|
4,
|
|
659
954
|
client.validateApiKey(key)
|
|
660
955
|
];
|
|
661
|
-
case
|
|
956
|
+
case 9:
|
|
662
957
|
validation = _state.sent();
|
|
663
958
|
if (validation === 'invalid') {
|
|
664
959
|
emitErr('Invalid API key. Check the key and try again.', {
|
|
@@ -677,7 +972,7 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
677
972
|
apiUrl: apiUrl
|
|
678
973
|
})
|
|
679
974
|
];
|
|
680
|
-
case
|
|
975
|
+
case 10:
|
|
681
976
|
_state.sent();
|
|
682
977
|
emit('Authenticated.', {
|
|
683
978
|
status: 'authenticated',
|
|
@@ -686,12 +981,12 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
686
981
|
return [
|
|
687
982
|
2
|
|
688
983
|
];
|
|
689
|
-
case
|
|
984
|
+
case 11:
|
|
690
985
|
// --- Mode 1 & 2: Email-based login ---
|
|
691
986
|
email = opts.email;
|
|
692
987
|
if (!!email) return [
|
|
693
988
|
3,
|
|
694
|
-
|
|
989
|
+
13
|
|
695
990
|
];
|
|
696
991
|
if (!process.stdin.isTTY) {
|
|
697
992
|
console.error('Email is required. Use --email <email> for non-interactive mode.');
|
|
@@ -705,67 +1000,67 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
705
1000
|
4,
|
|
706
1001
|
rl1.question('Email: ')
|
|
707
1002
|
];
|
|
708
|
-
case
|
|
1003
|
+
case 12:
|
|
709
1004
|
email = _state.sent();
|
|
710
1005
|
rl1.close();
|
|
711
|
-
_state.label =
|
|
712
|
-
case
|
|
1006
|
+
_state.label = 13;
|
|
1007
|
+
case 13:
|
|
713
1008
|
email = email.trim();
|
|
714
1009
|
// Check auth method
|
|
715
1010
|
method = 'otp';
|
|
716
|
-
_state.label =
|
|
717
|
-
case
|
|
1011
|
+
_state.label = 14;
|
|
1012
|
+
case 14:
|
|
718
1013
|
_state.trys.push([
|
|
719
|
-
|
|
720
|
-
|
|
1014
|
+
14,
|
|
1015
|
+
16,
|
|
721
1016
|
,
|
|
722
|
-
|
|
1017
|
+
17
|
|
723
1018
|
]);
|
|
724
1019
|
return [
|
|
725
1020
|
4,
|
|
726
1021
|
client.authCheck(email)
|
|
727
1022
|
];
|
|
728
|
-
case
|
|
1023
|
+
case 15:
|
|
729
1024
|
check = _state.sent();
|
|
730
1025
|
method = check.method;
|
|
731
1026
|
return [
|
|
732
1027
|
3,
|
|
733
|
-
|
|
1028
|
+
17
|
|
734
1029
|
];
|
|
735
|
-
case
|
|
736
|
-
|
|
1030
|
+
case 16:
|
|
1031
|
+
unused1 = _state.sent();
|
|
737
1032
|
return [
|
|
738
1033
|
3,
|
|
739
|
-
|
|
1034
|
+
17
|
|
740
1035
|
];
|
|
741
|
-
case
|
|
1036
|
+
case 17:
|
|
742
1037
|
if (!(method === 'otp')) return [
|
|
743
1038
|
3,
|
|
744
|
-
|
|
1039
|
+
30
|
|
745
1040
|
];
|
|
746
1041
|
if (!!opts.code) return [
|
|
747
1042
|
3,
|
|
748
|
-
|
|
1043
|
+
22
|
|
749
1044
|
];
|
|
750
|
-
_state.label =
|
|
751
|
-
case
|
|
1045
|
+
_state.label = 18;
|
|
1046
|
+
case 18:
|
|
752
1047
|
_state.trys.push([
|
|
753
|
-
|
|
754
|
-
|
|
1048
|
+
18,
|
|
1049
|
+
20,
|
|
755
1050
|
,
|
|
756
|
-
|
|
1051
|
+
21
|
|
757
1052
|
]);
|
|
758
1053
|
return [
|
|
759
1054
|
4,
|
|
760
1055
|
client.sendOtp(email)
|
|
761
1056
|
];
|
|
762
|
-
case
|
|
1057
|
+
case 19:
|
|
763
1058
|
_state.sent();
|
|
764
1059
|
return [
|
|
765
1060
|
3,
|
|
766
|
-
|
|
1061
|
+
21
|
|
767
1062
|
];
|
|
768
|
-
case
|
|
1063
|
+
case 20:
|
|
769
1064
|
err = _state.sent();
|
|
770
1065
|
msg = _instanceof(err, Error) ? err.message : 'Something went wrong';
|
|
771
1066
|
if (msg.includes('requires SSO')) {
|
|
@@ -782,9 +1077,9 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
782
1077
|
process.exit(1);
|
|
783
1078
|
return [
|
|
784
1079
|
3,
|
|
785
|
-
|
|
1080
|
+
21
|
|
786
1081
|
];
|
|
787
|
-
case
|
|
1082
|
+
case 21:
|
|
788
1083
|
if (!process.stdin.isTTY) {
|
|
789
1084
|
// Non-interactive: exit after sending. The caller (typically an
|
|
790
1085
|
// agent) will collect the OTP from the user and re-invoke with --code.
|
|
@@ -814,18 +1109,18 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
814
1109
|
if (!opts.json) {
|
|
815
1110
|
console.log("Code sent to ".concat(email));
|
|
816
1111
|
}
|
|
817
|
-
_state.label =
|
|
818
|
-
case
|
|
1112
|
+
_state.label = 22;
|
|
1113
|
+
case 22:
|
|
819
1114
|
if (!opts.code) return [
|
|
820
1115
|
3,
|
|
821
|
-
|
|
1116
|
+
23
|
|
822
1117
|
];
|
|
823
1118
|
code = opts.code;
|
|
824
1119
|
return [
|
|
825
1120
|
3,
|
|
826
|
-
|
|
1121
|
+
25
|
|
827
1122
|
];
|
|
828
|
-
case
|
|
1123
|
+
case 23:
|
|
829
1124
|
rl2 = createInterface({
|
|
830
1125
|
input: process.stdin,
|
|
831
1126
|
output: process.stdout
|
|
@@ -834,22 +1129,22 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
834
1129
|
4,
|
|
835
1130
|
rl2.question('Enter the 6-digit code: ')
|
|
836
1131
|
];
|
|
837
|
-
case
|
|
1132
|
+
case 24:
|
|
838
1133
|
code = _state.sent();
|
|
839
1134
|
rl2.close();
|
|
840
|
-
_state.label =
|
|
841
|
-
case
|
|
1135
|
+
_state.label = 25;
|
|
1136
|
+
case 25:
|
|
842
1137
|
_state.trys.push([
|
|
843
|
-
22,
|
|
844
1138
|
25,
|
|
1139
|
+
28,
|
|
845
1140
|
,
|
|
846
|
-
|
|
1141
|
+
29
|
|
847
1142
|
]);
|
|
848
1143
|
return [
|
|
849
1144
|
4,
|
|
850
1145
|
client.verifyOtp(email, code.trim())
|
|
851
1146
|
];
|
|
852
|
-
case
|
|
1147
|
+
case 26:
|
|
853
1148
|
result = _state.sent();
|
|
854
1149
|
return [
|
|
855
1150
|
4,
|
|
@@ -858,7 +1153,7 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
858
1153
|
apiUrl: apiUrl
|
|
859
1154
|
})
|
|
860
1155
|
];
|
|
861
|
-
case
|
|
1156
|
+
case 27:
|
|
862
1157
|
_state.sent();
|
|
863
1158
|
emit("Logged in as ".concat(email), {
|
|
864
1159
|
status: 'authenticated',
|
|
@@ -867,10 +1162,10 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
867
1162
|
});
|
|
868
1163
|
return [
|
|
869
1164
|
3,
|
|
870
|
-
|
|
1165
|
+
29
|
|
871
1166
|
];
|
|
872
|
-
case
|
|
873
|
-
|
|
1167
|
+
case 28:
|
|
1168
|
+
unused2 = _state.sent();
|
|
874
1169
|
emitErr('Invalid or expired code. Try again.', {
|
|
875
1170
|
status: 'error',
|
|
876
1171
|
error: 'invalid_or_expired_code'
|
|
@@ -878,142 +1173,157 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
878
1173
|
process.exit(1);
|
|
879
1174
|
return [
|
|
880
1175
|
3,
|
|
881
|
-
|
|
1176
|
+
29
|
|
882
1177
|
];
|
|
883
|
-
case
|
|
1178
|
+
case 29:
|
|
884
1179
|
return [
|
|
885
1180
|
3,
|
|
886
|
-
|
|
1181
|
+
39
|
|
887
1182
|
];
|
|
888
|
-
case
|
|
1183
|
+
case 30:
|
|
889
1184
|
// --- Mode 2: SSO device flow ---
|
|
890
1185
|
console.log('Your organization requires SSO. Opening browser...');
|
|
891
|
-
_state.label =
|
|
892
|
-
case
|
|
1186
|
+
_state.label = 31;
|
|
1187
|
+
case 31:
|
|
893
1188
|
_state.trys.push([
|
|
894
|
-
|
|
895
|
-
|
|
1189
|
+
31,
|
|
1190
|
+
33,
|
|
896
1191
|
,
|
|
897
|
-
|
|
1192
|
+
34
|
|
898
1193
|
]);
|
|
899
1194
|
return [
|
|
900
1195
|
4,
|
|
901
1196
|
client.requestDeviceCode('dsp-cli')
|
|
902
1197
|
];
|
|
903
|
-
case
|
|
1198
|
+
case 32:
|
|
904
1199
|
deviceResult = _state.sent();
|
|
905
1200
|
return [
|
|
906
1201
|
3,
|
|
907
|
-
|
|
1202
|
+
34
|
|
908
1203
|
];
|
|
909
|
-
case
|
|
910
|
-
|
|
1204
|
+
case 33:
|
|
1205
|
+
unused3 = _state.sent();
|
|
911
1206
|
console.error('Something went wrong. Check your connection and try again.');
|
|
912
1207
|
process.exit(1);
|
|
913
1208
|
return [
|
|
914
1209
|
3,
|
|
915
|
-
|
|
1210
|
+
34
|
|
916
1211
|
];
|
|
917
|
-
case
|
|
918
|
-
device_code = deviceResult.device_code, verification_uri_complete = deviceResult.verification_uri_complete, initialInterval = deviceResult.interval;
|
|
1212
|
+
case 34:
|
|
1213
|
+
device_code = deviceResult.device_code, verification_uri_complete = deviceResult.verification_uri_complete, initialInterval = deviceResult.interval, expires_in = deviceResult.expires_in;
|
|
919
1214
|
console.log();
|
|
920
1215
|
console.log(" ".concat(verification_uri_complete));
|
|
921
1216
|
console.log();
|
|
922
1217
|
openBrowser(verification_uri_complete);
|
|
923
|
-
// Poll for token
|
|
924
|
-
interval = (initialInterval || 5) * 1000;
|
|
925
1218
|
process.stdout.write('Waiting for authentication...');
|
|
926
|
-
_state.label =
|
|
927
|
-
case
|
|
928
|
-
if (!true) return [
|
|
929
|
-
3,
|
|
930
|
-
40
|
|
931
|
-
];
|
|
932
|
-
return [
|
|
933
|
-
4,
|
|
934
|
-
sleep(interval)
|
|
935
|
-
];
|
|
936
|
-
case 33:
|
|
937
|
-
_state.sent();
|
|
938
|
-
tokenResult = void 0;
|
|
939
|
-
_state.label = 34;
|
|
940
|
-
case 34:
|
|
1219
|
+
_state.label = 35;
|
|
1220
|
+
case 35:
|
|
941
1221
|
_state.trys.push([
|
|
942
|
-
|
|
943
|
-
|
|
1222
|
+
35,
|
|
1223
|
+
38,
|
|
944
1224
|
,
|
|
945
|
-
|
|
1225
|
+
39
|
|
946
1226
|
]);
|
|
947
1227
|
return [
|
|
948
1228
|
4,
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
return [
|
|
954
|
-
3,
|
|
955
|
-
37
|
|
1229
|
+
pollDeviceToken(client, device_code, 'dsp-cli', {
|
|
1230
|
+
intervalMs: (initialInterval || 5) * 1000,
|
|
1231
|
+
expiresAt: Date.now() + (expires_in || 600) * 1000
|
|
1232
|
+
})
|
|
956
1233
|
];
|
|
957
1234
|
case 36:
|
|
958
|
-
|
|
959
|
-
// Transient network error — retry on next interval
|
|
960
|
-
return [
|
|
961
|
-
3,
|
|
962
|
-
32
|
|
963
|
-
];
|
|
964
|
-
case 37:
|
|
965
|
-
if (!('access_token' in tokenResult)) return [
|
|
966
|
-
3,
|
|
967
|
-
39
|
|
968
|
-
];
|
|
1235
|
+
token = _state.sent();
|
|
969
1236
|
console.log(' done');
|
|
970
1237
|
return [
|
|
971
1238
|
4,
|
|
972
1239
|
saveConfig({
|
|
973
|
-
token:
|
|
1240
|
+
token: token,
|
|
974
1241
|
apiUrl: apiUrl
|
|
975
1242
|
})
|
|
976
1243
|
];
|
|
977
|
-
case
|
|
1244
|
+
case 37:
|
|
978
1245
|
_state.sent();
|
|
979
1246
|
console.log("Logged in as ".concat(email));
|
|
980
1247
|
return [
|
|
981
1248
|
2
|
|
982
1249
|
];
|
|
983
|
-
case
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
3,
|
|
988
|
-
32
|
|
989
|
-
];
|
|
990
|
-
}
|
|
991
|
-
if (_$err.error === 'slow_down') {
|
|
992
|
-
interval += 5000;
|
|
993
|
-
return [
|
|
994
|
-
3,
|
|
995
|
-
32
|
|
996
|
-
];
|
|
997
|
-
}
|
|
998
|
-
if (_$err.error === 'access_denied') {
|
|
999
|
-
console.log();
|
|
1250
|
+
case 38:
|
|
1251
|
+
err1 = _state.sent();
|
|
1252
|
+
console.log();
|
|
1253
|
+
if (_instanceof(err1, DeviceCodeDeniedError)) {
|
|
1000
1254
|
console.error('Authentication denied. Run dsp login to try again.');
|
|
1001
|
-
|
|
1002
|
-
}
|
|
1003
|
-
if (_$err.error === 'expired_token') {
|
|
1004
|
-
console.log();
|
|
1255
|
+
} else if (_instanceof(err1, DeviceCodeExpiredError)) {
|
|
1005
1256
|
console.error('Code expired. Run dsp login to try again.');
|
|
1257
|
+
} else if (_instanceof(err1, DeviceCodeFailedError)) {
|
|
1258
|
+
console.error(err1.message || 'Authentication failed. Run dsp login to try again.');
|
|
1259
|
+
} else {
|
|
1260
|
+
console.error('Authentication failed. Run dsp login to try again.');
|
|
1261
|
+
}
|
|
1262
|
+
process.exit(1);
|
|
1263
|
+
return [
|
|
1264
|
+
3,
|
|
1265
|
+
39
|
|
1266
|
+
];
|
|
1267
|
+
case 39:
|
|
1268
|
+
return [
|
|
1269
|
+
2
|
|
1270
|
+
];
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1273
|
+
})();
|
|
1274
|
+
});
|
|
1275
|
+
// --- branding ---
|
|
1276
|
+
program.command('branding <shortId> <mode>').description('Override display.dev branding for an existing artifact without re-publishing (show|hide|inherit)').action(function(shortId, modeRaw) {
|
|
1277
|
+
return _async_to_generator(function() {
|
|
1278
|
+
var mode, auth, client, result, err, msg;
|
|
1279
|
+
return _ts_generator(this, function(_state) {
|
|
1280
|
+
switch(_state.label){
|
|
1281
|
+
case 0:
|
|
1282
|
+
mode = parseShowBrandingOrExit(modeRaw);
|
|
1283
|
+
if (!mode) {
|
|
1284
|
+
console.error('mode is required');
|
|
1006
1285
|
process.exit(1);
|
|
1007
1286
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1287
|
+
return [
|
|
1288
|
+
4,
|
|
1289
|
+
resolveAuthOrConfig()
|
|
1290
|
+
];
|
|
1291
|
+
case 1:
|
|
1292
|
+
auth = _state.sent();
|
|
1293
|
+
client = createClient(auth);
|
|
1294
|
+
_state.label = 2;
|
|
1295
|
+
case 2:
|
|
1296
|
+
_state.trys.push([
|
|
1297
|
+
2,
|
|
1298
|
+
4,
|
|
1299
|
+
,
|
|
1300
|
+
5
|
|
1301
|
+
]);
|
|
1302
|
+
return [
|
|
1303
|
+
4,
|
|
1304
|
+
client.setArtifactBranding(shortId, mode)
|
|
1305
|
+
];
|
|
1306
|
+
case 3:
|
|
1307
|
+
result = _state.sent();
|
|
1308
|
+
console.log("".concat(result.shortId, " branding=").concat(result.showBranding === null ? 'inherit' : result.showBranding ? 'show' : 'hide'));
|
|
1309
|
+
return [
|
|
1310
|
+
3,
|
|
1311
|
+
5
|
|
1312
|
+
];
|
|
1313
|
+
case 4:
|
|
1314
|
+
err = _state.sent();
|
|
1315
|
+
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
1316
|
+
if (classifyBrandingError(msg) === 'paid-plan') {
|
|
1317
|
+
console.error('Error: Hiding display.dev branding requires a paid plan. See https://display.dev/billing');
|
|
1318
|
+
} else {
|
|
1319
|
+
console.error(msg);
|
|
1320
|
+
}
|
|
1011
1321
|
process.exit(1);
|
|
1012
1322
|
return [
|
|
1013
1323
|
3,
|
|
1014
|
-
|
|
1324
|
+
5
|
|
1015
1325
|
];
|
|
1016
|
-
case
|
|
1326
|
+
case 5:
|
|
1017
1327
|
return [
|
|
1018
1328
|
2
|
|
1019
1329
|
];
|
|
@@ -1024,16 +1334,20 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
1024
1334
|
// --- mcp ---
|
|
1025
1335
|
program.command('mcp').description('Start MCP server over stdin/stdout').action(function() {
|
|
1026
1336
|
return _async_to_generator(function() {
|
|
1027
|
-
var auth, client;
|
|
1337
|
+
var auth, client, publicClient;
|
|
1028
1338
|
return _ts_generator(this, function(_state) {
|
|
1029
1339
|
switch(_state.label){
|
|
1030
1340
|
case 0:
|
|
1031
1341
|
return [
|
|
1032
1342
|
4,
|
|
1033
|
-
|
|
1343
|
+
resolveAuthOrConfigOptional()
|
|
1034
1344
|
];
|
|
1035
1345
|
case 1:
|
|
1036
1346
|
auth = _state.sent();
|
|
1347
|
+
if (!auth) return [
|
|
1348
|
+
3,
|
|
1349
|
+
3
|
|
1350
|
+
];
|
|
1037
1351
|
client = new ApiClient({
|
|
1038
1352
|
baseUrl: auth.apiUrl,
|
|
1039
1353
|
apiKey: auth.apiKey,
|
|
@@ -1048,6 +1362,28 @@ program.command('mcp').description('Start MCP server over stdin/stdout').action(
|
|
|
1048
1362
|
return [
|
|
1049
1363
|
2
|
|
1050
1364
|
];
|
|
1365
|
+
case 3:
|
|
1366
|
+
// Unauthenticated: expose only `publish`, which maps to the public
|
|
1367
|
+
// claimable endpoint and returns a claim URL the user visits to own
|
|
1368
|
+
// the artifact. Workspace-bound tools are not registered — they have
|
|
1369
|
+
// no meaningful behaviour without auth and listing them would invite
|
|
1370
|
+
// agents to call them and error out.
|
|
1371
|
+
publicClient = new ApiClient({
|
|
1372
|
+
baseUrl: resolvePublicApiUrl(),
|
|
1373
|
+
apiKey: '',
|
|
1374
|
+
clientType: 'mcp-stdio'
|
|
1375
|
+
});
|
|
1376
|
+
return [
|
|
1377
|
+
4,
|
|
1378
|
+
startMcpServer(publicClient, {
|
|
1379
|
+
mode: 'public'
|
|
1380
|
+
})
|
|
1381
|
+
];
|
|
1382
|
+
case 4:
|
|
1383
|
+
_state.sent();
|
|
1384
|
+
return [
|
|
1385
|
+
2
|
|
1386
|
+
];
|
|
1051
1387
|
}
|
|
1052
1388
|
});
|
|
1053
1389
|
})();
|