@displaydev/cli 0.16.0 → 0.17.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.
@@ -507,6 +507,44 @@ export var ApiClient = /*#__PURE__*/ function() {
507
507
  }).call(this);
508
508
  }
509
509
  },
510
+ {
511
+ key: "setOrgLogo",
512
+ value: /**
513
+ * Upload (or replace) the active org's logo. Multipart `file` field;
514
+ * server validates magic bytes, square aspect, dimensions, and size.
515
+ * Returns the new R2 key + content-addressed version.
516
+ */ function setOrgLogo(params) {
517
+ return _async_to_generator(function() {
518
+ var form, blob;
519
+ return _ts_generator(this, function(_state) {
520
+ form = new FormData();
521
+ blob = new Blob([
522
+ new Uint8Array(params.bytes)
523
+ ], {
524
+ type: params.contentType
525
+ });
526
+ form.append('file', blob, params.filename);
527
+ return [
528
+ 2,
529
+ this.request('POST', '/v1/org/logo', form)
530
+ ];
531
+ });
532
+ }).call(this);
533
+ }
534
+ },
535
+ {
536
+ key: "clearOrgLogo",
537
+ value: /** Clear the active org's logo. Idempotent — 200 even when no logo is set. */ function clearOrgLogo() {
538
+ return _async_to_generator(function() {
539
+ return _ts_generator(this, function(_state) {
540
+ return [
541
+ 2,
542
+ this.request('DELETE', '/v1/org/logo')
543
+ ];
544
+ });
545
+ }).call(this);
546
+ }
547
+ },
510
548
  {
511
549
  key: "find",
512
550
  value: function find(params) {
package/dist/main.js CHANGED
@@ -189,6 +189,7 @@ function _ts_generator(thisArg, body) {
189
189
  }
190
190
  }
191
191
  import { readFile } from 'node:fs/promises';
192
+ import { basename } from 'node:path';
192
193
  import { createInterface } from 'node:readline/promises';
193
194
  import { createRequire } from 'node:module';
194
195
  import { execFileSync } from 'node:child_process';
@@ -1452,6 +1453,170 @@ program.command('set-branding <shortId> <mode>').description('Override display.d
1452
1453
  });
1453
1454
  })();
1454
1455
  });
1456
+ // --- set-logo ---
1457
+ program.command('set-logo <file>').description('Upload or replace the org logo (PNG or WebP, square, 32–1024px, ≤256 KB)').action(function(filePath) {
1458
+ return _async_to_generator(function() {
1459
+ var auth, client, bytes, err, msg, lower, contentType, result, err1, _ref, _err_details, upgradeUrl, msg1;
1460
+ return _ts_generator(this, function(_state) {
1461
+ switch(_state.label){
1462
+ case 0:
1463
+ return [
1464
+ 4,
1465
+ resolveAuthOrConfig()
1466
+ ];
1467
+ case 1:
1468
+ auth = _state.sent();
1469
+ client = createClient(auth);
1470
+ _state.label = 2;
1471
+ case 2:
1472
+ _state.trys.push([
1473
+ 2,
1474
+ 4,
1475
+ ,
1476
+ 5
1477
+ ]);
1478
+ return [
1479
+ 4,
1480
+ readFile(filePath)
1481
+ ];
1482
+ case 3:
1483
+ bytes = _state.sent();
1484
+ return [
1485
+ 3,
1486
+ 5
1487
+ ];
1488
+ case 4:
1489
+ err = _state.sent();
1490
+ msg = _instanceof(err, Error) ? err.message : String(err);
1491
+ console.error(msg);
1492
+ process.exit(1);
1493
+ return [
1494
+ 3,
1495
+ 5
1496
+ ];
1497
+ case 5:
1498
+ lower = filePath.toLowerCase();
1499
+ if (lower.endsWith('.png')) {
1500
+ contentType = 'image/png';
1501
+ } else if (lower.endsWith('.webp')) {
1502
+ contentType = 'image/webp';
1503
+ } else {
1504
+ console.error('Logo must be a .png or .webp file.');
1505
+ process.exit(1);
1506
+ }
1507
+ _state.label = 6;
1508
+ case 6:
1509
+ _state.trys.push([
1510
+ 6,
1511
+ 8,
1512
+ ,
1513
+ 9
1514
+ ]);
1515
+ return [
1516
+ 4,
1517
+ client.setOrgLogo({
1518
+ bytes: bytes,
1519
+ contentType: contentType,
1520
+ filename: basename(filePath)
1521
+ })
1522
+ ];
1523
+ case 7:
1524
+ result = _state.sent();
1525
+ console.log("Logo set: ".concat(result.logoContentType, " version=").concat(result.logoVersion));
1526
+ return [
1527
+ 3,
1528
+ 9
1529
+ ];
1530
+ case 8:
1531
+ err1 = _state.sent();
1532
+ if (_instanceof(err1, ApiError) && err1.status === 402) {
1533
+ ;
1534
+ ;
1535
+ upgradeUrl = (_ref = (_err_details = err1.details) === null || _err_details === void 0 ? void 0 : _err_details.upgrade_url) !== null && _ref !== void 0 ? _ref : 'https://app.display.dev/billing';
1536
+ console.error("Error: Setting an org logo requires a paid plan. See ".concat(upgradeUrl));
1537
+ process.exit(1);
1538
+ }
1539
+ if (_instanceof(err1, ApiError) && err1.status === 401) {
1540
+ console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
1541
+ process.exit(1);
1542
+ }
1543
+ if (_instanceof(err1, ApiError) && (err1.status === 400 || err1.status === 403)) {
1544
+ console.error(err1.message);
1545
+ process.exit(1);
1546
+ }
1547
+ msg1 = _instanceof(err1, Error) ? err1.message : String(err1);
1548
+ console.error(msg1);
1549
+ process.exit(1);
1550
+ return [
1551
+ 3,
1552
+ 9
1553
+ ];
1554
+ case 9:
1555
+ return [
1556
+ 2
1557
+ ];
1558
+ }
1559
+ });
1560
+ })();
1561
+ });
1562
+ // --- clear-logo ---
1563
+ program.command('clear-logo').description('Remove the org logo (idempotent — succeeds even if no logo is currently set)').action(function() {
1564
+ return _async_to_generator(function() {
1565
+ var auth, client, err, msg;
1566
+ return _ts_generator(this, function(_state) {
1567
+ switch(_state.label){
1568
+ case 0:
1569
+ return [
1570
+ 4,
1571
+ resolveAuthOrConfig()
1572
+ ];
1573
+ case 1:
1574
+ auth = _state.sent();
1575
+ client = createClient(auth);
1576
+ _state.label = 2;
1577
+ case 2:
1578
+ _state.trys.push([
1579
+ 2,
1580
+ 4,
1581
+ ,
1582
+ 5
1583
+ ]);
1584
+ return [
1585
+ 4,
1586
+ client.clearOrgLogo()
1587
+ ];
1588
+ case 3:
1589
+ _state.sent();
1590
+ console.log('Logo removed.');
1591
+ return [
1592
+ 3,
1593
+ 5
1594
+ ];
1595
+ case 4:
1596
+ err = _state.sent();
1597
+ if (_instanceof(err, ApiError) && err.status === 401) {
1598
+ console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
1599
+ process.exit(1);
1600
+ }
1601
+ if (_instanceof(err, ApiError) && err.status === 403) {
1602
+ console.error(err.message);
1603
+ process.exit(1);
1604
+ }
1605
+ msg = _instanceof(err, Error) ? err.message : String(err);
1606
+ console.error(msg);
1607
+ process.exit(1);
1608
+ return [
1609
+ 3,
1610
+ 5
1611
+ ];
1612
+ case 5:
1613
+ return [
1614
+ 2
1615
+ ];
1616
+ }
1617
+ });
1618
+ })();
1619
+ });
1455
1620
  // --- mcp ---
1456
1621
  program.command('mcp').description('Start MCP server over stdin/stdout').action(function() {
1457
1622
  return _async_to_generator(function() {
@@ -199,7 +199,7 @@ function _ts_generator(thisArg, body) {
199
199
  }
200
200
  }
201
201
  import { readFile } from 'node:fs/promises';
202
- import { resolve } from 'node:path';
202
+ import { basename, resolve } from 'node:path';
203
203
  import { z } from 'zod';
204
204
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
205
205
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
@@ -995,4 +995,138 @@ export function registerTools(server, api) {
995
995
  });
996
996
  })();
997
997
  });
998
+ server.tool('set_logo', 'Upload or replace the org logo (paid tiers only). Used as the favicon on every artifact the org publishes. Stdio variant reads bytes from a local file path.', {
999
+ file_path: z.string().describe('Path to a local PNG or WebP file. Square, 32×32 to 1024×1024, ≤256 KB.'),
1000
+ content_type: z.enum([
1001
+ 'image/png',
1002
+ 'image/webp'
1003
+ ]).optional().describe('Optional declared MIME type; inferred from the file extension when omitted.')
1004
+ }, function(args) {
1005
+ return _async_to_generator(function() {
1006
+ var bytes, err, contentType, lower, result, err1;
1007
+ return _ts_generator(this, function(_state) {
1008
+ switch(_state.label){
1009
+ case 0:
1010
+ _state.trys.push([
1011
+ 0,
1012
+ 2,
1013
+ ,
1014
+ 3
1015
+ ]);
1016
+ return [
1017
+ 4,
1018
+ readFile(resolve(args.file_path))
1019
+ ];
1020
+ case 1:
1021
+ bytes = _state.sent();
1022
+ return [
1023
+ 3,
1024
+ 3
1025
+ ];
1026
+ case 2:
1027
+ err = _state.sent();
1028
+ return [
1029
+ 2,
1030
+ errorResponse(err)
1031
+ ];
1032
+ case 3:
1033
+ contentType = args.content_type;
1034
+ if (!contentType) {
1035
+ lower = args.file_path.toLowerCase();
1036
+ if (lower.endsWith('.png')) {
1037
+ contentType = 'image/png';
1038
+ } else if (lower.endsWith('.webp')) {
1039
+ contentType = 'image/webp';
1040
+ } else {
1041
+ return [
1042
+ 2,
1043
+ {
1044
+ content: [
1045
+ {
1046
+ type: 'text',
1047
+ text: JSON.stringify({
1048
+ error: 'invalid_input',
1049
+ message: 'Unable to infer content_type from file extension; pass content_type explicitly.'
1050
+ })
1051
+ }
1052
+ ],
1053
+ isError: true
1054
+ }
1055
+ ];
1056
+ }
1057
+ }
1058
+ _state.label = 4;
1059
+ case 4:
1060
+ _state.trys.push([
1061
+ 4,
1062
+ 6,
1063
+ ,
1064
+ 7
1065
+ ]);
1066
+ return [
1067
+ 4,
1068
+ api.setOrgLogo({
1069
+ bytes: bytes,
1070
+ contentType: contentType,
1071
+ filename: basename(args.file_path)
1072
+ })
1073
+ ];
1074
+ case 5:
1075
+ result = _state.sent();
1076
+ return [
1077
+ 2,
1078
+ okResponse(result)
1079
+ ];
1080
+ case 6:
1081
+ err1 = _state.sent();
1082
+ return [
1083
+ 2,
1084
+ errorResponse(err1)
1085
+ ];
1086
+ case 7:
1087
+ return [
1088
+ 2
1089
+ ];
1090
+ }
1091
+ });
1092
+ })();
1093
+ });
1094
+ server.tool('clear_logo', 'Remove the org logo. Idempotent — succeeds even when no logo is currently set.', {}, function() {
1095
+ return _async_to_generator(function() {
1096
+ var err;
1097
+ return _ts_generator(this, function(_state) {
1098
+ switch(_state.label){
1099
+ case 0:
1100
+ _state.trys.push([
1101
+ 0,
1102
+ 2,
1103
+ ,
1104
+ 3
1105
+ ]);
1106
+ return [
1107
+ 4,
1108
+ api.clearOrgLogo()
1109
+ ];
1110
+ case 1:
1111
+ _state.sent();
1112
+ return [
1113
+ 2,
1114
+ okResponse({
1115
+ success: true
1116
+ })
1117
+ ];
1118
+ case 2:
1119
+ err = _state.sent();
1120
+ return [
1121
+ 2,
1122
+ errorResponse(err)
1123
+ ];
1124
+ case 3:
1125
+ return [
1126
+ 2
1127
+ ];
1128
+ }
1129
+ });
1130
+ })();
1131
+ });
998
1132
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@displaydev/cli",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "dsp": "dist/main.js"