@displaydev/cli 0.6.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 +228 -4
- package/dist/config.js +220 -0
- package/dist/main-helpers.js +687 -0
- package/dist/main.js +572 -340
- package/dist/mcp-server.js +296 -117
- 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,49 +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() {
|
|
175
|
+
function resolveAuthOrConfig() {
|
|
153
176
|
return _async_to_generator(function() {
|
|
154
|
-
var
|
|
177
|
+
var auth;
|
|
155
178
|
return _ts_generator(this, function(_state) {
|
|
156
179
|
switch(_state.label){
|
|
157
180
|
case 0:
|
|
158
|
-
_state.trys.push([
|
|
159
|
-
0,
|
|
160
|
-
2,
|
|
161
|
-
,
|
|
162
|
-
3
|
|
163
|
-
]);
|
|
164
181
|
return [
|
|
165
182
|
4,
|
|
166
|
-
|
|
183
|
+
resolveAuthOrConfigOptional()
|
|
167
184
|
];
|
|
168
185
|
case 1:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
null
|
|
179
|
-
];
|
|
180
|
-
case 3:
|
|
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);
|
|
181
195
|
return [
|
|
182
196
|
2
|
|
183
197
|
];
|
|
@@ -185,97 +199,34 @@ function loadConfig() {
|
|
|
185
199
|
});
|
|
186
200
|
})();
|
|
187
201
|
}
|
|
188
|
-
|
|
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() {
|
|
189
207
|
return _async_to_generator(function() {
|
|
190
|
-
var
|
|
208
|
+
var config;
|
|
191
209
|
return _ts_generator(this, function(_state) {
|
|
192
210
|
switch(_state.label){
|
|
193
211
|
case 0:
|
|
194
|
-
return [
|
|
195
|
-
4,
|
|
196
|
-
mkdir(CONFIG_DIR, {
|
|
197
|
-
recursive: true
|
|
198
|
-
})
|
|
199
|
-
];
|
|
200
|
-
case 1:
|
|
201
|
-
_state.sent();
|
|
202
|
-
tmpPath = "".concat(CONFIG_PATH, ".tmp");
|
|
203
|
-
return [
|
|
204
|
-
4,
|
|
205
|
-
writeFile(tmpPath, "".concat(JSON.stringify(config, null, 2), "\n"), {
|
|
206
|
-
mode: 384
|
|
207
|
-
})
|
|
208
|
-
];
|
|
209
|
-
case 2:
|
|
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();
|
|
223
|
-
return [
|
|
224
|
-
2
|
|
225
|
-
];
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
})();
|
|
229
|
-
}
|
|
230
|
-
function resolveAuth() {
|
|
231
|
-
var apiKey = process.env.DISPLAYDEV_API_KEY;
|
|
232
|
-
if (apiKey) {
|
|
233
|
-
var _process_env_DISPLAYDEV_API_URL;
|
|
234
|
-
return {
|
|
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() {
|
|
242
|
-
return _async_to_generator(function() {
|
|
243
|
-
var env, config, _config_apiUrl;
|
|
244
|
-
return _ts_generator(this, function(_state) {
|
|
245
|
-
switch(_state.label){
|
|
246
|
-
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,82 +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
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
var normalized = raw.toLowerCase();
|
|
300
|
-
if (!SHOW_BRANDING_VALUES.has(normalized)) {
|
|
301
|
-
console.error("Invalid --show-branding: ".concat(raw, ". Use show, hide, or inherit."));
|
|
302
|
-
process.exit(1);
|
|
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;
|
|
303
250
|
}
|
|
304
|
-
return normalized;
|
|
305
251
|
}
|
|
306
252
|
// --- publish ---
|
|
307
|
-
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) {
|
|
308
258
|
return _async_to_generator(function() {
|
|
309
|
-
var showBranding, 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;
|
|
310
260
|
return _ts_generator(this, function(_state) {
|
|
311
261
|
switch(_state.label){
|
|
312
262
|
case 0:
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
+
}
|
|
316
287
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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;
|
|
320
309
|
}
|
|
321
|
-
if (
|
|
322
|
-
|
|
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).');
|
|
323
340
|
process.exit(1);
|
|
324
341
|
}
|
|
325
|
-
if (
|
|
326
|
-
console.error(
|
|
327
|
-
process.exit(
|
|
342
|
+
if (_instanceof(err, ApiError) && err.status === 404) {
|
|
343
|
+
console.error("Artifact not found: ".concat(opts.id));
|
|
344
|
+
process.exit(4);
|
|
328
345
|
}
|
|
329
|
-
|
|
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:
|
|
330
354
|
return [
|
|
331
355
|
4,
|
|
332
|
-
|
|
356
|
+
readStreamToString(process.stdin)
|
|
333
357
|
];
|
|
334
|
-
case
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
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';
|
|
342
366
|
return [
|
|
343
367
|
4,
|
|
344
368
|
readFile(filePath, 'utf-8')
|
|
345
369
|
];
|
|
346
|
-
case
|
|
370
|
+
case 8:
|
|
347
371
|
content = _state.sent();
|
|
348
|
-
|
|
349
|
-
|
|
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) {
|
|
350
440
|
visibility = 'public';
|
|
351
441
|
} else if (opts.company) {
|
|
352
442
|
visibility = 'company';
|
|
353
443
|
}
|
|
354
|
-
share
|
|
355
|
-
|
|
356
|
-
|
|
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:
|
|
357
451
|
_state.trys.push([
|
|
358
|
-
|
|
359
|
-
|
|
452
|
+
15,
|
|
453
|
+
20,
|
|
360
454
|
,
|
|
361
|
-
|
|
455
|
+
21
|
|
362
456
|
]);
|
|
363
457
|
if (!opts.id) return [
|
|
364
458
|
3,
|
|
365
|
-
|
|
459
|
+
17
|
|
366
460
|
];
|
|
367
461
|
return [
|
|
368
462
|
4,
|
|
@@ -377,13 +471,13 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
|
|
|
377
471
|
showBranding: showBranding
|
|
378
472
|
})
|
|
379
473
|
];
|
|
380
|
-
case
|
|
474
|
+
case 16:
|
|
381
475
|
result = _state.sent();
|
|
382
476
|
return [
|
|
383
477
|
3,
|
|
384
|
-
|
|
478
|
+
19
|
|
385
479
|
];
|
|
386
|
-
case
|
|
480
|
+
case 17:
|
|
387
481
|
return [
|
|
388
482
|
4,
|
|
389
483
|
client.publish({
|
|
@@ -396,28 +490,34 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
|
|
|
396
490
|
showBranding: showBranding
|
|
397
491
|
})
|
|
398
492
|
];
|
|
399
|
-
case
|
|
493
|
+
case 18:
|
|
400
494
|
result = _state.sent();
|
|
401
|
-
_state.label =
|
|
402
|
-
case
|
|
495
|
+
_state.label = 19;
|
|
496
|
+
case 19:
|
|
403
497
|
return [
|
|
404
498
|
3,
|
|
405
|
-
|
|
499
|
+
21
|
|
406
500
|
];
|
|
407
|
-
case
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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') {
|
|
411
511
|
console.error('Error: Hiding display.dev branding requires a paid plan. See https://display.dev/billing');
|
|
412
512
|
} else {
|
|
413
|
-
console.error(
|
|
513
|
+
console.error(msg2);
|
|
414
514
|
}
|
|
415
515
|
process.exit(1);
|
|
416
516
|
return [
|
|
417
517
|
3,
|
|
418
|
-
|
|
518
|
+
21
|
|
419
519
|
];
|
|
420
|
-
case
|
|
520
|
+
case 21:
|
|
421
521
|
console.log(result.url);
|
|
422
522
|
verb = opts.id ? 'Updated' : 'Published';
|
|
423
523
|
console.log("".concat(verb, " ").concat(result.name, " (").concat(result.shortId, ") v").concat(result.version));
|
|
@@ -428,6 +528,96 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
|
|
|
428
528
|
});
|
|
429
529
|
})();
|
|
430
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
|
+
});
|
|
431
621
|
// --- find ---
|
|
432
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) {
|
|
433
623
|
return parseInt(v, 10);
|
|
@@ -531,6 +721,76 @@ program.command('get <shortId>').description('Get artifact details').option('--i
|
|
|
531
721
|
});
|
|
532
722
|
})();
|
|
533
723
|
});
|
|
724
|
+
// --- export ---
|
|
725
|
+
program.command('export <shortId>').description('Print the published source bytes to stdout. Pin a version with @<n>.').action(function(shortIdArg) {
|
|
726
|
+
return _async_to_generator(function() {
|
|
727
|
+
var parsed, auth, client, result, err, msg;
|
|
728
|
+
return _ts_generator(this, function(_state) {
|
|
729
|
+
switch(_state.label){
|
|
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
|
+
}
|
|
736
|
+
return [
|
|
737
|
+
4,
|
|
738
|
+
resolveAuthOrConfig()
|
|
739
|
+
];
|
|
740
|
+
case 1:
|
|
741
|
+
auth = _state.sent();
|
|
742
|
+
client = createClient(auth);
|
|
743
|
+
_state.label = 2;
|
|
744
|
+
case 2:
|
|
745
|
+
_state.trys.push([
|
|
746
|
+
2,
|
|
747
|
+
4,
|
|
748
|
+
,
|
|
749
|
+
5
|
|
750
|
+
]);
|
|
751
|
+
return [
|
|
752
|
+
4,
|
|
753
|
+
client.exportSource(parsed.shortId, parsed.version)
|
|
754
|
+
];
|
|
755
|
+
case 3:
|
|
756
|
+
result = _state.sent();
|
|
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);
|
|
787
|
+
return [
|
|
788
|
+
2
|
|
789
|
+
];
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
})();
|
|
793
|
+
});
|
|
534
794
|
// --- delete ---
|
|
535
795
|
program.command('delete <shortId>').description('Delete an artifact permanently').option('--confirm', 'Confirm deletion').action(function(shortId, opts) {
|
|
536
796
|
return _async_to_generator(function() {
|
|
@@ -564,6 +824,9 @@ program.command('delete <shortId>').description('Delete an artifact permanently'
|
|
|
564
824
|
})();
|
|
565
825
|
});
|
|
566
826
|
function openBrowser(url) {
|
|
827
|
+
if (process.env.DISPLAYDEV_SKIP_BROWSER) {
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
567
830
|
try {
|
|
568
831
|
var os = platform();
|
|
569
832
|
if (os === 'darwin') {
|
|
@@ -587,15 +850,10 @@ function openBrowser(url) {
|
|
|
587
850
|
// URL is already printed — user can open it manually
|
|
588
851
|
}
|
|
589
852
|
}
|
|
590
|
-
function sleep(ms) {
|
|
591
|
-
return new Promise(function(resolve) {
|
|
592
|
-
return setTimeout(resolve, ms);
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
853
|
// --- login ---
|
|
596
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) {
|
|
597
855
|
return _async_to_generator(function() {
|
|
598
|
-
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;
|
|
599
857
|
return _ts_generator(this, function(_state) {
|
|
600
858
|
switch(_state.label){
|
|
601
859
|
case 0:
|
|
@@ -623,7 +881,7 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
623
881
|
});
|
|
624
882
|
if (!(opts.apiKey !== undefined)) return [
|
|
625
883
|
3,
|
|
626
|
-
|
|
884
|
+
11
|
|
627
885
|
];
|
|
628
886
|
if (!(typeof opts.apiKey === 'string')) return [
|
|
629
887
|
3,
|
|
@@ -632,54 +890,46 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
632
890
|
key = opts.apiKey;
|
|
633
891
|
return [
|
|
634
892
|
3,
|
|
635
|
-
|
|
893
|
+
8
|
|
636
894
|
];
|
|
637
895
|
case 1:
|
|
638
896
|
if (!process.stdin.isTTY) return [
|
|
639
897
|
3,
|
|
640
|
-
|
|
898
|
+
6
|
|
641
899
|
];
|
|
642
|
-
//
|
|
900
|
+
// Raw-mode input suppresses terminal echo.
|
|
643
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
|
+
]);
|
|
644
910
|
return [
|
|
645
911
|
4,
|
|
646
|
-
|
|
647
|
-
var input = '';
|
|
648
|
-
process.stdin.setRawMode(true);
|
|
649
|
-
process.stdin.resume();
|
|
650
|
-
process.stdin.setEncoding('utf8');
|
|
651
|
-
var cleanup = function cleanup() {
|
|
652
|
-
process.stdin.setRawMode(false);
|
|
653
|
-
process.stdin.pause();
|
|
654
|
-
process.stdin.removeListener('data', onData);
|
|
655
|
-
};
|
|
656
|
-
var onData = function onData(ch) {
|
|
657
|
-
if (ch === '\r' || ch === '\n') {
|
|
658
|
-
cleanup();
|
|
659
|
-
process.stdout.write('\n');
|
|
660
|
-
resolve(input);
|
|
661
|
-
} else if (ch === '\u0003') {
|
|
662
|
-
cleanup();
|
|
663
|
-
process.stdout.write('\n');
|
|
664
|
-
process.exit(1);
|
|
665
|
-
} else if (ch === '\u007F' || ch === '\b') {
|
|
666
|
-
if (input.length > 0) {
|
|
667
|
-
input = input.slice(0, -1);
|
|
668
|
-
}
|
|
669
|
-
} else {
|
|
670
|
-
input += ch;
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
|
-
process.stdin.on('data', onData);
|
|
674
|
-
})
|
|
912
|
+
readApiKeyFromTty(process.stdin, process.stdout)
|
|
675
913
|
];
|
|
676
|
-
case
|
|
914
|
+
case 3:
|
|
677
915
|
key = _state.sent();
|
|
678
916
|
return [
|
|
679
917
|
3,
|
|
680
918
|
5
|
|
681
919
|
];
|
|
682
|
-
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:
|
|
683
933
|
// Non-TTY: read from stdin (piped input)
|
|
684
934
|
rl = createInterface({
|
|
685
935
|
input: process.stdin,
|
|
@@ -689,11 +939,11 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
689
939
|
4,
|
|
690
940
|
rl.question('API key: ')
|
|
691
941
|
];
|
|
692
|
-
case
|
|
942
|
+
case 7:
|
|
693
943
|
key = _state.sent();
|
|
694
944
|
rl.close();
|
|
695
|
-
_state.label =
|
|
696
|
-
case
|
|
945
|
+
_state.label = 8;
|
|
946
|
+
case 8:
|
|
697
947
|
key = key.trim();
|
|
698
948
|
if (!key) {
|
|
699
949
|
console.error('API key cannot be empty.');
|
|
@@ -703,7 +953,7 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
703
953
|
4,
|
|
704
954
|
client.validateApiKey(key)
|
|
705
955
|
];
|
|
706
|
-
case
|
|
956
|
+
case 9:
|
|
707
957
|
validation = _state.sent();
|
|
708
958
|
if (validation === 'invalid') {
|
|
709
959
|
emitErr('Invalid API key. Check the key and try again.', {
|
|
@@ -722,7 +972,7 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
722
972
|
apiUrl: apiUrl
|
|
723
973
|
})
|
|
724
974
|
];
|
|
725
|
-
case
|
|
975
|
+
case 10:
|
|
726
976
|
_state.sent();
|
|
727
977
|
emit('Authenticated.', {
|
|
728
978
|
status: 'authenticated',
|
|
@@ -731,12 +981,12 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
731
981
|
return [
|
|
732
982
|
2
|
|
733
983
|
];
|
|
734
|
-
case
|
|
984
|
+
case 11:
|
|
735
985
|
// --- Mode 1 & 2: Email-based login ---
|
|
736
986
|
email = opts.email;
|
|
737
987
|
if (!!email) return [
|
|
738
988
|
3,
|
|
739
|
-
|
|
989
|
+
13
|
|
740
990
|
];
|
|
741
991
|
if (!process.stdin.isTTY) {
|
|
742
992
|
console.error('Email is required. Use --email <email> for non-interactive mode.');
|
|
@@ -750,67 +1000,67 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
750
1000
|
4,
|
|
751
1001
|
rl1.question('Email: ')
|
|
752
1002
|
];
|
|
753
|
-
case
|
|
1003
|
+
case 12:
|
|
754
1004
|
email = _state.sent();
|
|
755
1005
|
rl1.close();
|
|
756
|
-
_state.label =
|
|
757
|
-
case
|
|
1006
|
+
_state.label = 13;
|
|
1007
|
+
case 13:
|
|
758
1008
|
email = email.trim();
|
|
759
1009
|
// Check auth method
|
|
760
1010
|
method = 'otp';
|
|
761
|
-
_state.label =
|
|
762
|
-
case
|
|
1011
|
+
_state.label = 14;
|
|
1012
|
+
case 14:
|
|
763
1013
|
_state.trys.push([
|
|
764
|
-
|
|
765
|
-
|
|
1014
|
+
14,
|
|
1015
|
+
16,
|
|
766
1016
|
,
|
|
767
|
-
|
|
1017
|
+
17
|
|
768
1018
|
]);
|
|
769
1019
|
return [
|
|
770
1020
|
4,
|
|
771
1021
|
client.authCheck(email)
|
|
772
1022
|
];
|
|
773
|
-
case
|
|
1023
|
+
case 15:
|
|
774
1024
|
check = _state.sent();
|
|
775
1025
|
method = check.method;
|
|
776
1026
|
return [
|
|
777
1027
|
3,
|
|
778
|
-
|
|
1028
|
+
17
|
|
779
1029
|
];
|
|
780
|
-
case
|
|
781
|
-
|
|
1030
|
+
case 16:
|
|
1031
|
+
unused1 = _state.sent();
|
|
782
1032
|
return [
|
|
783
1033
|
3,
|
|
784
|
-
|
|
1034
|
+
17
|
|
785
1035
|
];
|
|
786
|
-
case
|
|
1036
|
+
case 17:
|
|
787
1037
|
if (!(method === 'otp')) return [
|
|
788
1038
|
3,
|
|
789
|
-
|
|
1039
|
+
30
|
|
790
1040
|
];
|
|
791
1041
|
if (!!opts.code) return [
|
|
792
1042
|
3,
|
|
793
|
-
|
|
1043
|
+
22
|
|
794
1044
|
];
|
|
795
|
-
_state.label =
|
|
796
|
-
case
|
|
1045
|
+
_state.label = 18;
|
|
1046
|
+
case 18:
|
|
797
1047
|
_state.trys.push([
|
|
798
|
-
|
|
799
|
-
|
|
1048
|
+
18,
|
|
1049
|
+
20,
|
|
800
1050
|
,
|
|
801
|
-
|
|
1051
|
+
21
|
|
802
1052
|
]);
|
|
803
1053
|
return [
|
|
804
1054
|
4,
|
|
805
1055
|
client.sendOtp(email)
|
|
806
1056
|
];
|
|
807
|
-
case
|
|
1057
|
+
case 19:
|
|
808
1058
|
_state.sent();
|
|
809
1059
|
return [
|
|
810
1060
|
3,
|
|
811
|
-
|
|
1061
|
+
21
|
|
812
1062
|
];
|
|
813
|
-
case
|
|
1063
|
+
case 20:
|
|
814
1064
|
err = _state.sent();
|
|
815
1065
|
msg = _instanceof(err, Error) ? err.message : 'Something went wrong';
|
|
816
1066
|
if (msg.includes('requires SSO')) {
|
|
@@ -827,9 +1077,9 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
827
1077
|
process.exit(1);
|
|
828
1078
|
return [
|
|
829
1079
|
3,
|
|
830
|
-
|
|
1080
|
+
21
|
|
831
1081
|
];
|
|
832
|
-
case
|
|
1082
|
+
case 21:
|
|
833
1083
|
if (!process.stdin.isTTY) {
|
|
834
1084
|
// Non-interactive: exit after sending. The caller (typically an
|
|
835
1085
|
// agent) will collect the OTP from the user and re-invoke with --code.
|
|
@@ -859,18 +1109,18 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
859
1109
|
if (!opts.json) {
|
|
860
1110
|
console.log("Code sent to ".concat(email));
|
|
861
1111
|
}
|
|
862
|
-
_state.label =
|
|
863
|
-
case
|
|
1112
|
+
_state.label = 22;
|
|
1113
|
+
case 22:
|
|
864
1114
|
if (!opts.code) return [
|
|
865
1115
|
3,
|
|
866
|
-
|
|
1116
|
+
23
|
|
867
1117
|
];
|
|
868
1118
|
code = opts.code;
|
|
869
1119
|
return [
|
|
870
1120
|
3,
|
|
871
|
-
|
|
1121
|
+
25
|
|
872
1122
|
];
|
|
873
|
-
case
|
|
1123
|
+
case 23:
|
|
874
1124
|
rl2 = createInterface({
|
|
875
1125
|
input: process.stdin,
|
|
876
1126
|
output: process.stdout
|
|
@@ -879,22 +1129,22 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
879
1129
|
4,
|
|
880
1130
|
rl2.question('Enter the 6-digit code: ')
|
|
881
1131
|
];
|
|
882
|
-
case
|
|
1132
|
+
case 24:
|
|
883
1133
|
code = _state.sent();
|
|
884
1134
|
rl2.close();
|
|
885
|
-
_state.label =
|
|
886
|
-
case
|
|
1135
|
+
_state.label = 25;
|
|
1136
|
+
case 25:
|
|
887
1137
|
_state.trys.push([
|
|
888
|
-
22,
|
|
889
1138
|
25,
|
|
1139
|
+
28,
|
|
890
1140
|
,
|
|
891
|
-
|
|
1141
|
+
29
|
|
892
1142
|
]);
|
|
893
1143
|
return [
|
|
894
1144
|
4,
|
|
895
1145
|
client.verifyOtp(email, code.trim())
|
|
896
1146
|
];
|
|
897
|
-
case
|
|
1147
|
+
case 26:
|
|
898
1148
|
result = _state.sent();
|
|
899
1149
|
return [
|
|
900
1150
|
4,
|
|
@@ -903,7 +1153,7 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
903
1153
|
apiUrl: apiUrl
|
|
904
1154
|
})
|
|
905
1155
|
];
|
|
906
|
-
case
|
|
1156
|
+
case 27:
|
|
907
1157
|
_state.sent();
|
|
908
1158
|
emit("Logged in as ".concat(email), {
|
|
909
1159
|
status: 'authenticated',
|
|
@@ -912,10 +1162,10 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
912
1162
|
});
|
|
913
1163
|
return [
|
|
914
1164
|
3,
|
|
915
|
-
|
|
1165
|
+
29
|
|
916
1166
|
];
|
|
917
|
-
case
|
|
918
|
-
|
|
1167
|
+
case 28:
|
|
1168
|
+
unused2 = _state.sent();
|
|
919
1169
|
emitErr('Invalid or expired code. Try again.', {
|
|
920
1170
|
status: 'error',
|
|
921
1171
|
error: 'invalid_or_expired_code'
|
|
@@ -923,142 +1173,98 @@ program.command('login').description('Authenticate with display.dev').option('--
|
|
|
923
1173
|
process.exit(1);
|
|
924
1174
|
return [
|
|
925
1175
|
3,
|
|
926
|
-
|
|
1176
|
+
29
|
|
927
1177
|
];
|
|
928
|
-
case
|
|
1178
|
+
case 29:
|
|
929
1179
|
return [
|
|
930
1180
|
3,
|
|
931
|
-
|
|
1181
|
+
39
|
|
932
1182
|
];
|
|
933
|
-
case
|
|
1183
|
+
case 30:
|
|
934
1184
|
// --- Mode 2: SSO device flow ---
|
|
935
1185
|
console.log('Your organization requires SSO. Opening browser...');
|
|
936
|
-
_state.label =
|
|
937
|
-
case
|
|
1186
|
+
_state.label = 31;
|
|
1187
|
+
case 31:
|
|
938
1188
|
_state.trys.push([
|
|
939
|
-
|
|
940
|
-
|
|
1189
|
+
31,
|
|
1190
|
+
33,
|
|
941
1191
|
,
|
|
942
|
-
|
|
1192
|
+
34
|
|
943
1193
|
]);
|
|
944
1194
|
return [
|
|
945
1195
|
4,
|
|
946
1196
|
client.requestDeviceCode('dsp-cli')
|
|
947
1197
|
];
|
|
948
|
-
case
|
|
1198
|
+
case 32:
|
|
949
1199
|
deviceResult = _state.sent();
|
|
950
1200
|
return [
|
|
951
1201
|
3,
|
|
952
|
-
|
|
1202
|
+
34
|
|
953
1203
|
];
|
|
954
|
-
case
|
|
955
|
-
|
|
1204
|
+
case 33:
|
|
1205
|
+
unused3 = _state.sent();
|
|
956
1206
|
console.error('Something went wrong. Check your connection and try again.');
|
|
957
1207
|
process.exit(1);
|
|
958
1208
|
return [
|
|
959
1209
|
3,
|
|
960
|
-
|
|
1210
|
+
34
|
|
961
1211
|
];
|
|
962
|
-
case
|
|
963
|
-
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;
|
|
964
1214
|
console.log();
|
|
965
1215
|
console.log(" ".concat(verification_uri_complete));
|
|
966
1216
|
console.log();
|
|
967
1217
|
openBrowser(verification_uri_complete);
|
|
968
|
-
// Poll for token
|
|
969
|
-
interval = (initialInterval || 5) * 1000;
|
|
970
1218
|
process.stdout.write('Waiting for authentication...');
|
|
971
|
-
_state.label =
|
|
972
|
-
case
|
|
973
|
-
if (!true) return [
|
|
974
|
-
3,
|
|
975
|
-
40
|
|
976
|
-
];
|
|
977
|
-
return [
|
|
978
|
-
4,
|
|
979
|
-
sleep(interval)
|
|
980
|
-
];
|
|
981
|
-
case 33:
|
|
982
|
-
_state.sent();
|
|
983
|
-
tokenResult = void 0;
|
|
984
|
-
_state.label = 34;
|
|
985
|
-
case 34:
|
|
1219
|
+
_state.label = 35;
|
|
1220
|
+
case 35:
|
|
986
1221
|
_state.trys.push([
|
|
987
|
-
|
|
988
|
-
|
|
1222
|
+
35,
|
|
1223
|
+
38,
|
|
989
1224
|
,
|
|
990
|
-
|
|
1225
|
+
39
|
|
991
1226
|
]);
|
|
992
1227
|
return [
|
|
993
1228
|
4,
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
return [
|
|
999
|
-
3,
|
|
1000
|
-
37
|
|
1229
|
+
pollDeviceToken(client, device_code, 'dsp-cli', {
|
|
1230
|
+
intervalMs: (initialInterval || 5) * 1000,
|
|
1231
|
+
expiresAt: Date.now() + (expires_in || 600) * 1000
|
|
1232
|
+
})
|
|
1001
1233
|
];
|
|
1002
1234
|
case 36:
|
|
1003
|
-
|
|
1004
|
-
// Transient network error — retry on next interval
|
|
1005
|
-
return [
|
|
1006
|
-
3,
|
|
1007
|
-
32
|
|
1008
|
-
];
|
|
1009
|
-
case 37:
|
|
1010
|
-
if (!('access_token' in tokenResult)) return [
|
|
1011
|
-
3,
|
|
1012
|
-
39
|
|
1013
|
-
];
|
|
1235
|
+
token = _state.sent();
|
|
1014
1236
|
console.log(' done');
|
|
1015
1237
|
return [
|
|
1016
1238
|
4,
|
|
1017
1239
|
saveConfig({
|
|
1018
|
-
token:
|
|
1240
|
+
token: token,
|
|
1019
1241
|
apiUrl: apiUrl
|
|
1020
1242
|
})
|
|
1021
1243
|
];
|
|
1022
|
-
case
|
|
1244
|
+
case 37:
|
|
1023
1245
|
_state.sent();
|
|
1024
1246
|
console.log("Logged in as ".concat(email));
|
|
1025
1247
|
return [
|
|
1026
1248
|
2
|
|
1027
1249
|
];
|
|
1028
|
-
case
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
3,
|
|
1033
|
-
32
|
|
1034
|
-
];
|
|
1035
|
-
}
|
|
1036
|
-
if (_$err.error === 'slow_down') {
|
|
1037
|
-
interval += 5000;
|
|
1038
|
-
return [
|
|
1039
|
-
3,
|
|
1040
|
-
32
|
|
1041
|
-
];
|
|
1042
|
-
}
|
|
1043
|
-
if (_$err.error === 'access_denied') {
|
|
1044
|
-
console.log();
|
|
1250
|
+
case 38:
|
|
1251
|
+
err1 = _state.sent();
|
|
1252
|
+
console.log();
|
|
1253
|
+
if (_instanceof(err1, DeviceCodeDeniedError)) {
|
|
1045
1254
|
console.error('Authentication denied. Run dsp login to try again.');
|
|
1046
|
-
|
|
1047
|
-
}
|
|
1048
|
-
if (_$err.error === 'expired_token') {
|
|
1049
|
-
console.log();
|
|
1255
|
+
} else if (_instanceof(err1, DeviceCodeExpiredError)) {
|
|
1050
1256
|
console.error('Code expired. Run dsp login to try again.');
|
|
1051
|
-
|
|
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.');
|
|
1052
1261
|
}
|
|
1053
|
-
// Unknown error
|
|
1054
|
-
console.log();
|
|
1055
|
-
console.error(_$err.error_description || 'Authentication failed. Run dsp login to try again.');
|
|
1056
1262
|
process.exit(1);
|
|
1057
1263
|
return [
|
|
1058
1264
|
3,
|
|
1059
|
-
|
|
1265
|
+
39
|
|
1060
1266
|
];
|
|
1061
|
-
case
|
|
1267
|
+
case 39:
|
|
1062
1268
|
return [
|
|
1063
1269
|
2
|
|
1064
1270
|
];
|
|
@@ -1073,7 +1279,7 @@ program.command('branding <shortId> <mode>').description('Override display.dev b
|
|
|
1073
1279
|
return _ts_generator(this, function(_state) {
|
|
1074
1280
|
switch(_state.label){
|
|
1075
1281
|
case 0:
|
|
1076
|
-
mode =
|
|
1282
|
+
mode = parseShowBrandingOrExit(modeRaw);
|
|
1077
1283
|
if (!mode) {
|
|
1078
1284
|
console.error('mode is required');
|
|
1079
1285
|
process.exit(1);
|
|
@@ -1107,7 +1313,7 @@ program.command('branding <shortId> <mode>').description('Override display.dev b
|
|
|
1107
1313
|
case 4:
|
|
1108
1314
|
err = _state.sent();
|
|
1109
1315
|
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
1110
|
-
if (
|
|
1316
|
+
if (classifyBrandingError(msg) === 'paid-plan') {
|
|
1111
1317
|
console.error('Error: Hiding display.dev branding requires a paid plan. See https://display.dev/billing');
|
|
1112
1318
|
} else {
|
|
1113
1319
|
console.error(msg);
|
|
@@ -1128,16 +1334,20 @@ program.command('branding <shortId> <mode>').description('Override display.dev b
|
|
|
1128
1334
|
// --- mcp ---
|
|
1129
1335
|
program.command('mcp').description('Start MCP server over stdin/stdout').action(function() {
|
|
1130
1336
|
return _async_to_generator(function() {
|
|
1131
|
-
var auth, client;
|
|
1337
|
+
var auth, client, publicClient;
|
|
1132
1338
|
return _ts_generator(this, function(_state) {
|
|
1133
1339
|
switch(_state.label){
|
|
1134
1340
|
case 0:
|
|
1135
1341
|
return [
|
|
1136
1342
|
4,
|
|
1137
|
-
|
|
1343
|
+
resolveAuthOrConfigOptional()
|
|
1138
1344
|
];
|
|
1139
1345
|
case 1:
|
|
1140
1346
|
auth = _state.sent();
|
|
1347
|
+
if (!auth) return [
|
|
1348
|
+
3,
|
|
1349
|
+
3
|
|
1350
|
+
];
|
|
1141
1351
|
client = new ApiClient({
|
|
1142
1352
|
baseUrl: auth.apiUrl,
|
|
1143
1353
|
apiKey: auth.apiKey,
|
|
@@ -1152,6 +1362,28 @@ program.command('mcp').description('Start MCP server over stdin/stdout').action(
|
|
|
1152
1362
|
return [
|
|
1153
1363
|
2
|
|
1154
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
|
+
];
|
|
1155
1387
|
}
|
|
1156
1388
|
});
|
|
1157
1389
|
})();
|