@appcircle/codepush-cli 0.0.1 → 0.0.3-alpha.1

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 CHANGED
@@ -58,11 +58,6 @@ appcircle-code-push login <optional: server-url> <optional: auth-url>
58
58
 
59
59
  This will launch a browser, asking you to authenticate with either your GitHub or Microsoft account. This will generate an access key that you need to copy/paste into the CLI (it will prompt you for it). You are now successfully authenticated and can safely close your browser window.
60
60
 
61
- If at any time you want to determine if you're already logged in, you can run the following command to display the e-mail address associated with your current authentication session, which identity providers your account is linked to (e.g. GitHub):
62
-
63
- ```shell
64
- appcircle-code-push whoami
65
- ```
66
61
 
67
62
  When you login from the CLI, your access key is persisted to disk for the duration of your session so that you don't have to login every time you attempt to access your account. In order to end your session and delete this access key, simply run the following command:
68
63
 
@@ -145,56 +140,6 @@ you can run the following command:
145
140
  appcircle-code-push app ls
146
141
  ```
147
142
 
148
- ### App Collaboration
149
-
150
- If you will be working with other developers on the same CodePush app, you can add them as collaborators using the following command:
151
-
152
- ```shell
153
- appcircle-code-push collaborator add <appName> <collaboratorEmail>
154
- ```
155
-
156
- _NOTE: This expects the developer to have already [registered](#account-creation) with CodePush using the specified e-mail address, so ensure that they have done that before attempting to share the app with them._
157
-
158
- Once added, all collaborators will immediately have the following permissions with regards to the newly shared app:
159
-
160
- 1. View the app, its collaborators, [deployments](#deployment-management) and [release history](#viewing-release-history)
161
- 1. [Release](#releasing-updates) updates to any of the app's deployments
162
- 1. [Promote](#promoting-updates) an update between any of the app's deployments
163
- 1. [Rollback](#rolling-back-undesired-updates) any of the app's deployments
164
- 1. [Patch](#updating-existing-releases) any releases within any of the app's deployments
165
-
166
- Inversely, that means that an app collaborator cannot do any of the following:
167
-
168
- 1. Rename or delete the app
169
- 1. Transfer ownership of the app
170
- 1. Create, rename or delete new deployments within the app
171
- 1. Clear a deployment's release history
172
- 1. Add or remove collaborators from the app (\*)
173
-
174
- _NOTE: A developer can remove him/herself as a collaborator from an app that was shared with them._
175
-
176
- Over time, if someone is no longer working on an app with you, you can remove them as a collaborator using the following command:
177
-
178
- ```shell
179
- appcircle-code-push collaborator rm <appName> <collaboratorEmail>
180
- ```
181
-
182
- If at any time you want to list all collaborators that have been added to an app, you can simply run the following command:
183
-
184
- ```shell
185
- appcircle-code-push collaborator ls <appName>
186
- ```
187
-
188
- Finally, if at some point, you (as the app owner) will no longer be working on the app, and you want to transfer it to another developer (or a client), you can run the following command:
189
-
190
- ```shell
191
- appcircle-code-push app transfer <appName> <newOwnerEmail>
192
- ```
193
-
194
- _NOTE: Just like with the `appcircle-code-push collaborator add` command, this expects that the new owner has already registered with CodePush using the specified e-mail address._
195
-
196
- Once confirmed, the specified developer becomes the app's owner and immediately receives the permissions associated with that role. Besides the transfer of ownership, nothing else about the app is modified (e.g. deployments, release history, collaborators). This means that you will still be a collaborator of the app, and therefore, if you want to remove yourself, you simply need to run the `appcircle-code-push collaborator rm` command after successfully transferring ownership.
197
-
198
143
  ### Deployment Management
199
144
 
200
145
  From the CodePush perspective, an app is simply a named grouping for one or more things called "deployments". While the app represents a conceptual "namespace" or "scope" for a platform-specific version of an app (e.g. the iOS port of Foo app), its deployments represent the actual target for releasing updates (for developers) and synchronizing updates (for end-users). Deployments allow you to have multiple "environments" for each app in-flight at any given time, and help model the reality that apps typically move from a dev's personal environment to a testing/QA/staging environment, before finally making their way into production.
@@ -133,6 +133,11 @@ function appList(command) {
133
133
  printAppList(command.format, retrievedApps);
134
134
  });
135
135
  }
136
+ function appDeploymentKeyList(command) {
137
+ return exports.sdk.getDeploymentKeys(command.appName).then((retrievedKeys) => {
138
+ printAppDeploymentKeyList(retrievedKeys);
139
+ });
140
+ }
136
141
  function appRemove(command) {
137
142
  return (0, exports.confirm)("Are you sure you want to remove this app? Note that its deployment keys will be PERMANENTLY unrecoverable.").then((wasConfirmed) => {
138
143
  if (wasConfirmed) {
@@ -368,18 +373,12 @@ function execute(command) {
368
373
  return appAdd(command);
369
374
  case cli.CommandType.appList:
370
375
  return appList(command);
376
+ case cli.CommandType.appDeploymentKeyList:
377
+ return appDeploymentKeyList(command);
371
378
  case cli.CommandType.appRemove:
372
379
  return appRemove(command);
373
380
  case cli.CommandType.appRename:
374
381
  return appRename(command);
375
- case cli.CommandType.appTransfer:
376
- return appTransfer(command);
377
- case cli.CommandType.collaboratorAdd:
378
- return addCollaborator(command);
379
- case cli.CommandType.collaboratorList:
380
- return listCollaborators(command);
381
- case cli.CommandType.collaboratorRemove:
382
- return removeCollaborator(command);
383
382
  case cli.CommandType.debug:
384
383
  return (0, debug_1.default)(command);
385
384
  case cli.CommandType.deploymentAdd:
@@ -416,8 +415,6 @@ function execute(command) {
416
415
  return sessionList(command);
417
416
  case cli.CommandType.sessionRemove:
418
417
  return sessionRemove(command);
419
- case cli.CommandType.whoami:
420
- return whoami(command);
421
418
  default:
422
419
  // We should never see this message as invalid commands should be caught by the argument parser.
423
420
  throw new Error("Invalid command: " + JSON.stringify(command));
@@ -524,6 +521,15 @@ function printAppList(format, apps) {
524
521
  });
525
522
  }
526
523
  }
524
+ function printAppDeploymentKeyList(deploymentKeys) {
525
+ const headers = ["Name", "Deployment Key"];
526
+ printTable(headers, (dataSource) => {
527
+ deploymentKeys.forEach((deploymentKey, index) => {
528
+ const row = [deploymentKey.name, wordwrap(50)(deploymentKey.deploymentKey)];
529
+ dataSource.push(row);
530
+ });
531
+ });
532
+ }
527
533
  function getCollaboratorDisplayName(email, collaboratorProperties) {
528
534
  return collaboratorProperties.permission === AccountManager.AppPermission.OWNER ? email + chalk.magenta(" (Owner)") : email;
529
535
  }
@@ -1254,6 +1260,7 @@ function throwForInvalidOutputFormat(format) {
1254
1260
  throw new Error("Invalid format: " + format + ".");
1255
1261
  }
1256
1262
  }
1263
+ // DEPRECATED
1257
1264
  function whoami(command) {
1258
1265
  return exports.sdk.getAccountInfo().then((account) => {
1259
1266
  const accountInfo = `${account.email} (${account.linkedProviders.join(", ")})`;
@@ -120,6 +120,14 @@ function appRemove(commandName, yargs) {
120
120
  .example("app " + commandName + " MyApp", 'Removes app "MyApp"');
121
121
  addCommonConfiguration(yargs);
122
122
  }
123
+ function appDeploymentKeyList(commandName, yargs) {
124
+ isValidCommand = true;
125
+ yargs
126
+ .usage(USAGE_PREFIX + " app " + commandName + " <appName>")
127
+ .demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
128
+ .example("app " + commandName + " MyApp", 'Lists the deployment keys for app "MyApp" in tabular format');
129
+ addCommonConfiguration(yargs);
130
+ }
123
131
  function listCollaborators(commandName, yargs) {
124
132
  isValidCommand = true;
125
133
  yargs
@@ -268,6 +276,7 @@ yargs
268
276
  })
269
277
  .command("list", "Lists the apps associated with your account", (yargs) => appList("list", yargs))
270
278
  .command("ls", "Lists the apps associated with your account", (yargs) => appList("ls", yargs))
279
+ .command("deployment-keys", "Lists the deployment keys for app", (yargs) => appDeploymentKeyList("deployment-keys", yargs))
271
280
  .command("transfer", "Transfer the ownership of an app to another account", (yargs) => {
272
281
  isValidCommand = true;
273
282
  yargs
@@ -278,26 +287,6 @@ yargs
278
287
  })
279
288
  .check((argv, aliases) => isValidCommand); // Report unrecognized, non-hyphenated command category.
280
289
  addCommonConfiguration(yargs);
281
- })
282
- .command("collaborator", "View and manage app collaborators", (yargs) => {
283
- isValidCommandCategory = true;
284
- yargs
285
- .usage(USAGE_PREFIX + " collaborator <command>")
286
- .demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments.
287
- .command("add", "Add a new collaborator to an app", (yargs) => {
288
- isValidCommand = true;
289
- yargs
290
- .usage(USAGE_PREFIX + " collaborator add <appName> <email>")
291
- .demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
292
- .example("collaborator add MyApp foo@bar.com", 'Adds foo@bar.com as a collaborator to app "MyApp"');
293
- addCommonConfiguration(yargs);
294
- })
295
- .command("remove", "Remove a collaborator from an app", (yargs) => removeCollaborator("remove", yargs))
296
- .command("rm", "Remove a collaborator from an app", (yargs) => removeCollaborator("rm", yargs))
297
- .command("list", "List the collaborators for an app", (yargs) => listCollaborators("list", yargs))
298
- .command("ls", "List the collaborators for an app", (yargs) => listCollaborators("ls", yargs))
299
- .check((argv, aliases) => isValidCommand); // Report unrecognized, non-hyphenated command category.
300
- addCommonConfiguration(yargs);
301
290
  })
302
291
  .command("debug", "View the CodePush debug logs for a running app", (yargs) => {
303
292
  isValidCommandCategory = true;
@@ -761,15 +750,6 @@ yargs
761
750
  .command("ls", "List the current login sessions associated with your account", (yargs) => sessionList("ls", yargs))
762
751
  .check((argv, aliases) => isValidCommand); // Report unrecognized, non-hyphenated command category.
763
752
  addCommonConfiguration(yargs);
764
- })
765
- .command("whoami", "Display the account info for the current login session", (yargs) => {
766
- isValidCommandCategory = true;
767
- isValidCommand = true;
768
- yargs
769
- .usage(USAGE_PREFIX + " whoami")
770
- .demand(/*count*/ 0, /*max*/ 0)
771
- .example("whoami", "Display the account info for the current login session");
772
- addCommonConfiguration(yargs);
773
753
  })
774
754
  .alias("v", "version")
775
755
  .version(packageJson.version)
@@ -841,6 +821,10 @@ function createCommand() {
841
821
  cmd = { type: cli.CommandType.appList };
842
822
  cmd.format = argv["format"];
843
823
  break;
824
+ case "deployment-keys":
825
+ cmd = { type: cli.CommandType.appDeploymentKeyList };
826
+ cmd.appName = arg2;
827
+ break;
844
828
  case "remove":
845
829
  case "rm":
846
830
  if (arg2) {
@@ -856,41 +840,6 @@ function createCommand() {
856
840
  appRenameCommand.newAppName = arg3;
857
841
  }
858
842
  break;
859
- case "transfer":
860
- if (arg2 && arg3) {
861
- cmd = { type: cli.CommandType.appTransfer };
862
- const appTransferCommand = cmd;
863
- appTransferCommand.appName = arg2;
864
- appTransferCommand.email = arg3;
865
- }
866
- break;
867
- }
868
- break;
869
- case "collaborator":
870
- switch (arg1) {
871
- case "add":
872
- if (arg2 && arg3) {
873
- cmd = { type: cli.CommandType.collaboratorAdd };
874
- cmd.appName = arg2;
875
- cmd.email = arg3;
876
- }
877
- break;
878
- case "list":
879
- case "ls":
880
- if (arg2) {
881
- cmd = { type: cli.CommandType.collaboratorList };
882
- cmd.appName = arg2;
883
- cmd.format = argv["format"];
884
- }
885
- break;
886
- case "remove":
887
- case "rm":
888
- if (arg2 && arg3) {
889
- cmd = { type: cli.CommandType.collaboratorRemove };
890
- cmd.appName = arg2;
891
- cmd.email = arg3;
892
- }
893
- break;
894
843
  }
895
844
  break;
896
845
  case "debug":
@@ -1083,9 +1032,6 @@ function createCommand() {
1083
1032
  break;
1084
1033
  }
1085
1034
  break;
1086
- case "whoami":
1087
- cmd = { type: cli.CommandType.whoami };
1088
- break;
1089
1035
  }
1090
1036
  return cmd;
1091
1037
  }
@@ -190,6 +190,9 @@ class AccountManager {
190
190
  getApp(appName) {
191
191
  return this.get(urlEncode([`/apps/${appName}`])).then((res) => res.body.app);
192
192
  }
193
+ getDeploymentKeys(appName) {
194
+ return this.get(urlEncode([`/apps/${appName}/deployment-keys`])).then((res) => res.body);
195
+ }
193
196
  addApp(appName) {
194
197
  const app = { name: appName };
195
198
  return this.post(urlEncode(["/apps"]), JSON.stringify(app), /*expectResponseBody=*/ false).then(() => app);
@@ -11,30 +11,26 @@ var CommandType;
11
11
  CommandType[CommandType["accessKeyRemove"] = 3] = "accessKeyRemove";
12
12
  CommandType[CommandType["appAdd"] = 4] = "appAdd";
13
13
  CommandType[CommandType["appList"] = 5] = "appList";
14
- CommandType[CommandType["appRemove"] = 6] = "appRemove";
15
- CommandType[CommandType["appRename"] = 7] = "appRename";
16
- CommandType[CommandType["appTransfer"] = 8] = "appTransfer";
17
- CommandType[CommandType["collaboratorAdd"] = 9] = "collaboratorAdd";
18
- CommandType[CommandType["collaboratorList"] = 10] = "collaboratorList";
19
- CommandType[CommandType["collaboratorRemove"] = 11] = "collaboratorRemove";
20
- CommandType[CommandType["debug"] = 12] = "debug";
21
- CommandType[CommandType["deploymentAdd"] = 13] = "deploymentAdd";
22
- CommandType[CommandType["deploymentHistory"] = 14] = "deploymentHistory";
23
- CommandType[CommandType["deploymentHistoryClear"] = 15] = "deploymentHistoryClear";
24
- CommandType[CommandType["deploymentList"] = 16] = "deploymentList";
25
- CommandType[CommandType["deploymentMetrics"] = 17] = "deploymentMetrics";
26
- CommandType[CommandType["deploymentRemove"] = 18] = "deploymentRemove";
27
- CommandType[CommandType["deploymentRename"] = 19] = "deploymentRename";
28
- CommandType[CommandType["link"] = 20] = "link";
29
- CommandType[CommandType["login"] = 21] = "login";
30
- CommandType[CommandType["logout"] = 22] = "logout";
31
- CommandType[CommandType["patch"] = 23] = "patch";
32
- CommandType[CommandType["promote"] = 24] = "promote";
33
- CommandType[CommandType["register"] = 25] = "register";
34
- CommandType[CommandType["release"] = 26] = "release";
35
- CommandType[CommandType["releaseReact"] = 27] = "releaseReact";
36
- CommandType[CommandType["rollback"] = 28] = "rollback";
37
- CommandType[CommandType["sessionList"] = 29] = "sessionList";
38
- CommandType[CommandType["sessionRemove"] = 30] = "sessionRemove";
39
- CommandType[CommandType["whoami"] = 31] = "whoami";
14
+ CommandType[CommandType["appDeploymentKeyList"] = 6] = "appDeploymentKeyList";
15
+ CommandType[CommandType["appRemove"] = 7] = "appRemove";
16
+ CommandType[CommandType["appRename"] = 8] = "appRename";
17
+ CommandType[CommandType["debug"] = 9] = "debug";
18
+ CommandType[CommandType["deploymentAdd"] = 10] = "deploymentAdd";
19
+ CommandType[CommandType["deploymentHistory"] = 11] = "deploymentHistory";
20
+ CommandType[CommandType["deploymentHistoryClear"] = 12] = "deploymentHistoryClear";
21
+ CommandType[CommandType["deploymentList"] = 13] = "deploymentList";
22
+ CommandType[CommandType["deploymentMetrics"] = 14] = "deploymentMetrics";
23
+ CommandType[CommandType["deploymentRemove"] = 15] = "deploymentRemove";
24
+ CommandType[CommandType["deploymentRename"] = 16] = "deploymentRename";
25
+ CommandType[CommandType["link"] = 17] = "link";
26
+ CommandType[CommandType["login"] = 18] = "login";
27
+ CommandType[CommandType["logout"] = 19] = "logout";
28
+ CommandType[CommandType["patch"] = 20] = "patch";
29
+ CommandType[CommandType["promote"] = 21] = "promote";
30
+ CommandType[CommandType["register"] = 22] = "register";
31
+ CommandType[CommandType["release"] = 23] = "release";
32
+ CommandType[CommandType["releaseReact"] = 24] = "releaseReact";
33
+ CommandType[CommandType["rollback"] = 25] = "rollback";
34
+ CommandType[CommandType["sessionList"] = 26] = "sessionList";
35
+ CommandType[CommandType["sessionRemove"] = 27] = "sessionRemove";
40
36
  })(CommandType || (exports.CommandType = CommandType = {}));
package/bin/test/cli.js CHANGED
@@ -482,68 +482,6 @@ describe("CLI", () => {
482
482
  done();
483
483
  });
484
484
  });
485
- it("appTransfer transfers app", (done) => {
486
- var command = {
487
- type: cli.CommandType.appTransfer,
488
- appName: "a",
489
- email: "b@b.com",
490
- };
491
- var transferApp = sandbox.spy(cmdexec.sdk, "transferApp");
492
- cmdexec.execute(command).done(() => {
493
- sinon.assert.calledOnce(transferApp);
494
- sinon.assert.calledOnce(log);
495
- sinon.assert.calledWithExactly(log, 'Successfully transferred the ownership of app "a" to the account with email "b@b.com".');
496
- done();
497
- });
498
- });
499
- it("collaboratorAdd adds collaborator", (done) => {
500
- var command = {
501
- type: cli.CommandType.collaboratorAdd,
502
- appName: "a",
503
- email: "b@b.com",
504
- };
505
- var addCollaborator = sandbox.spy(cmdexec.sdk, "addCollaborator");
506
- cmdexec.execute(command).done(() => {
507
- sinon.assert.calledOnce(addCollaborator);
508
- sinon.assert.calledOnce(log);
509
- sinon.assert.calledWithExactly(log, 'Successfully added "b@b.com" as a collaborator to the app "a".');
510
- done();
511
- });
512
- });
513
- it("collaboratorList lists collaborators email and properties", (done) => {
514
- var command = {
515
- type: cli.CommandType.collaboratorList,
516
- appName: "a",
517
- format: "json",
518
- };
519
- cmdexec.execute(command).done(() => {
520
- sinon.assert.calledOnce(log);
521
- assert.equal(log.args[0].length, 1);
522
- var actual = log.args[0][0];
523
- var expected = {
524
- collaborators: {
525
- "a@a.com": { permission: "Owner", isCurrentAccount: true },
526
- "b@b.com": { permission: "Collaborator", isCurrentAccount: false },
527
- },
528
- };
529
- assertJsonDescribesObject(actual, expected);
530
- done();
531
- });
532
- });
533
- it("collaboratorRemove removes collaborator", (done) => {
534
- var command = {
535
- type: cli.CommandType.collaboratorRemove,
536
- appName: "a",
537
- email: "b@b.com",
538
- };
539
- var removeCollaborator = sandbox.spy(cmdexec.sdk, "removeCollaborator");
540
- cmdexec.execute(command).done(() => {
541
- sinon.assert.calledOnce(removeCollaborator);
542
- sinon.assert.calledOnce(log);
543
- sinon.assert.calledWithExactly(log, 'Successfully removed "b@b.com" as a collaborator from the app "a".');
544
- done();
545
- });
546
- });
547
485
  it("deploymentAdd reports new app name and ID", (done) => {
548
486
  var command = {
549
487
  type: cli.CommandType.deploymentAdd,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appcircle/codepush-cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.3-alpha.1",
4
4
  "description": "Management CLI for the CodePush service",
5
5
  "main": "./script/cli.js",
6
6
  "scripts": {
@@ -49,6 +49,7 @@ import {
49
49
  isBinaryOrZip,
50
50
  fileExists
51
51
  } from "./utils/file-utils";
52
+ import { DeploymentKey } from "./types/rest-definitions";
52
53
 
53
54
  const configFilePath: string = path.join(process.env.LOCALAPPDATA || process.env.HOME, ".code-push.config");
54
55
  const emailValidator = require("email-validator");
@@ -196,6 +197,12 @@ function appList(command: cli.IAppListCommand): Promise<void> {
196
197
  });
197
198
  }
198
199
 
200
+ function appDeploymentKeyList(command: cli.IAppDeploymentKeysCommand): Promise<void> {
201
+ return sdk.getDeploymentKeys(command.appName).then((retrievedKeys: DeploymentKey[]): void => {
202
+ printAppDeploymentKeyList(retrievedKeys);
203
+ });
204
+ }
205
+
199
206
  function appRemove(command: cli.IAppRemoveCommand): Promise<void> {
200
207
  return confirm("Are you sure you want to remove this app? Note that its deployment keys will be PERMANENTLY unrecoverable.").then(
201
208
  (wasConfirmed: boolean): Promise<void> => {
@@ -481,6 +488,9 @@ export function execute(command: cli.ICommand) {
481
488
 
482
489
  case cli.CommandType.appList:
483
490
  return appList(<cli.IAppListCommand>command);
491
+
492
+ case cli.CommandType.appDeploymentKeyList:
493
+ return appDeploymentKeyList(<cli.IAppDeploymentKeysCommand>command);
484
494
 
485
495
  case cli.CommandType.appRemove:
486
496
  return appRemove(<cli.IAppRemoveCommand>command);
@@ -488,18 +498,6 @@ export function execute(command: cli.ICommand) {
488
498
  case cli.CommandType.appRename:
489
499
  return appRename(<cli.IAppRenameCommand>command);
490
500
 
491
- case cli.CommandType.appTransfer:
492
- return appTransfer(<cli.IAppTransferCommand>command);
493
-
494
- case cli.CommandType.collaboratorAdd:
495
- return addCollaborator(<cli.ICollaboratorAddCommand>command);
496
-
497
- case cli.CommandType.collaboratorList:
498
- return listCollaborators(<cli.ICollaboratorListCommand>command);
499
-
500
- case cli.CommandType.collaboratorRemove:
501
- return removeCollaborator(<cli.ICollaboratorRemoveCommand>command);
502
-
503
501
  case cli.CommandType.debug:
504
502
  return debugCommand(<cli.IDebugCommand>command);
505
503
 
@@ -554,9 +552,6 @@ export function execute(command: cli.ICommand) {
554
552
  case cli.CommandType.sessionRemove:
555
553
  return sessionRemove(<cli.ISessionRemoveCommand>command);
556
554
 
557
- case cli.CommandType.whoami:
558
- return whoami(command);
559
-
560
555
  default:
561
556
  // We should never see this message as invalid commands should be caught by the argument parser.
562
557
  throw new Error("Invalid command: " + JSON.stringify(command));
@@ -671,6 +666,16 @@ function printAppList(format: string, apps: App[]): void {
671
666
  }
672
667
  }
673
668
 
669
+ function printAppDeploymentKeyList(deploymentKeys: DeploymentKey[]): void {
670
+ const headers = ["Name", "Deployment Key"];
671
+ printTable(headers, (dataSource: any[]): void => {
672
+ deploymentKeys.forEach((deploymentKey: DeploymentKey, index: number): void => {
673
+ const row = [deploymentKey.name, wordwrap(50)(deploymentKey.deploymentKey)];
674
+ dataSource.push(row);
675
+ });
676
+ });
677
+ }
678
+
674
679
  function getCollaboratorDisplayName(email: string, collaboratorProperties: CollaboratorProperties): string {
675
680
  return collaboratorProperties.permission === AccountManager.AppPermission.OWNER ? email + chalk.magenta(" (Owner)") : email;
676
681
  }
@@ -1570,6 +1575,7 @@ function throwForInvalidOutputFormat(format: string): void {
1570
1575
  }
1571
1576
  }
1572
1577
 
1578
+ // DEPRECATED
1573
1579
  function whoami(command: cli.ICommand): Promise<void> {
1574
1580
  return sdk.getAccountInfo().then((account): void => {
1575
1581
  const accountInfo = `${account.email} (${account.linkedProviders.join(", ")})`;
@@ -146,6 +146,16 @@ function appRemove(commandName: string, yargs: yargs.Argv): void {
146
146
  addCommonConfiguration(yargs);
147
147
  }
148
148
 
149
+ function appDeploymentKeyList(commandName: string, yargs: yargs.Argv): void {
150
+ isValidCommand = true;
151
+ yargs
152
+ .usage(USAGE_PREFIX + " app " + commandName + " <appName>")
153
+ .demand(/*count*/ 1, /*max*/ 1) // Require exactly one non-option arguments
154
+ .example("app " + commandName + " MyApp", 'Lists the deployment keys for app "MyApp" in tabular format');
155
+
156
+ addCommonConfiguration(yargs);
157
+ }
158
+
149
159
  function listCollaborators(commandName: string, yargs: yargs.Argv): void {
150
160
  isValidCommand = true;
151
161
  yargs
@@ -321,6 +331,7 @@ yargs
321
331
  })
322
332
  .command("list", "Lists the apps associated with your account", (yargs: yargs.Argv) => appList("list", yargs))
323
333
  .command("ls", "Lists the apps associated with your account", (yargs: yargs.Argv) => appList("ls", yargs))
334
+ .command("deployment-keys","Lists the deployment keys for app", (yargs:yargs.Argv) => appDeploymentKeyList("deployment-keys", yargs))
324
335
  .command("transfer", "Transfer the ownership of an app to another account", (yargs: yargs.Argv) => {
325
336
  isValidCommand = true;
326
337
  yargs
@@ -334,28 +345,6 @@ yargs
334
345
 
335
346
  addCommonConfiguration(yargs);
336
347
  })
337
- .command("collaborator", "View and manage app collaborators", (yargs: yargs.Argv) => {
338
- isValidCommandCategory = true;
339
- yargs
340
- .usage(USAGE_PREFIX + " collaborator <command>")
341
- .demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments.
342
- .command("add", "Add a new collaborator to an app", (yargs: yargs.Argv): void => {
343
- isValidCommand = true;
344
- yargs
345
- .usage(USAGE_PREFIX + " collaborator add <appName> <email>")
346
- .demand(/*count*/ 2, /*max*/ 2) // Require exactly two non-option arguments
347
- .example("collaborator add MyApp foo@bar.com", 'Adds foo@bar.com as a collaborator to app "MyApp"');
348
-
349
- addCommonConfiguration(yargs);
350
- })
351
- .command("remove", "Remove a collaborator from an app", (yargs: yargs.Argv) => removeCollaborator("remove", yargs))
352
- .command("rm", "Remove a collaborator from an app", (yargs: yargs.Argv) => removeCollaborator("rm", yargs))
353
- .command("list", "List the collaborators for an app", (yargs: yargs.Argv) => listCollaborators("list", yargs))
354
- .command("ls", "List the collaborators for an app", (yargs: yargs.Argv) => listCollaborators("ls", yargs))
355
- .check((argv: any, aliases: { [aliases: string]: string }): any => isValidCommand); // Report unrecognized, non-hyphenated command category.
356
-
357
- addCommonConfiguration(yargs);
358
- })
359
348
  .command("debug", "View the CodePush debug logs for a running app", (yargs: yargs.Argv) => {
360
349
  isValidCommandCategory = true;
361
350
  isValidCommand = true;
@@ -890,15 +879,6 @@ yargs
890
879
 
891
880
  addCommonConfiguration(yargs);
892
881
  })
893
- .command("whoami", "Display the account info for the current login session", (yargs: yargs.Argv) => {
894
- isValidCommandCategory = true;
895
- isValidCommand = true;
896
- yargs
897
- .usage(USAGE_PREFIX + " whoami")
898
- .demand(/*count*/ 0, /*max*/ 0)
899
- .example("whoami", "Display the account info for the current login session");
900
- addCommonConfiguration(yargs);
901
- })
902
882
  .alias("v", "version")
903
883
  .version(packageJson.version)
904
884
  .wrap(/*columnLimit*/ null)
@@ -984,7 +964,10 @@ export function createCommand(): cli.ICommand {
984
964
 
985
965
  (<cli.IAppListCommand>cmd).format = argv["format"] as any;
986
966
  break;
987
-
967
+ case "deployment-keys":
968
+ cmd = {type : cli.CommandType.appDeploymentKeyList};
969
+ (<cli.IAppDeploymentKeysCommand>cmd).appName = arg2;
970
+ break;
988
971
  case "remove":
989
972
  case "rm":
990
973
  if (arg2) {
@@ -1004,50 +987,6 @@ export function createCommand(): cli.ICommand {
1004
987
  appRenameCommand.newAppName = arg3;
1005
988
  }
1006
989
  break;
1007
-
1008
- case "transfer":
1009
- if (arg2 && arg3) {
1010
- cmd = { type: cli.CommandType.appTransfer };
1011
-
1012
- const appTransferCommand = <cli.IAppTransferCommand>cmd;
1013
-
1014
- appTransferCommand.appName = arg2;
1015
- appTransferCommand.email = arg3;
1016
- }
1017
- break;
1018
- }
1019
- break;
1020
-
1021
- case "collaborator":
1022
- switch (arg1) {
1023
- case "add":
1024
- if (arg2 && arg3) {
1025
- cmd = { type: cli.CommandType.collaboratorAdd };
1026
-
1027
- (<cli.ICollaboratorAddCommand>cmd).appName = arg2;
1028
- (<cli.ICollaboratorAddCommand>cmd).email = arg3;
1029
- }
1030
- break;
1031
-
1032
- case "list":
1033
- case "ls":
1034
- if (arg2) {
1035
- cmd = { type: cli.CommandType.collaboratorList };
1036
-
1037
- (<cli.ICollaboratorListCommand>cmd).appName = arg2;
1038
- (<cli.ICollaboratorListCommand>cmd).format = argv["format"] as any;
1039
- }
1040
- break;
1041
-
1042
- case "remove":
1043
- case "rm":
1044
- if (arg2 && arg3) {
1045
- cmd = { type: cli.CommandType.collaboratorRemove };
1046
-
1047
- (<cli.ICollaboratorRemoveCommand>cmd).appName = arg2;
1048
- (<cli.ICollaboratorAddCommand>cmd).email = arg3;
1049
- }
1050
- break;
1051
990
  }
1052
991
  break;
1053
992
 
@@ -1290,10 +1229,6 @@ export function createCommand(): cli.ICommand {
1290
1229
  break;
1291
1230
  }
1292
1231
  break;
1293
-
1294
- case "whoami":
1295
- cmd = { type: cli.CommandType.whoami };
1296
- break;
1297
1232
  }
1298
1233
 
1299
1234
  return cmd;
@@ -28,6 +28,7 @@ import {
28
28
  ServerAccessKey,
29
29
  Session,
30
30
  } from "./types";
31
+ import { DeploymentKey } from "./types/rest-definitions";
31
32
 
32
33
  const packageJson = require("../../package.json");
33
34
 
@@ -268,6 +269,10 @@ class AccountManager {
268
269
  return this.get(urlEncode([`/apps/${appName}`])).then((res: JsonResponse) => res.body.app);
269
270
  }
270
271
 
272
+ public getDeploymentKeys(appName: string): Promise<DeploymentKey[]> {
273
+ return this.get(urlEncode([`/apps/${appName}/deployment-keys`])).then((res: JsonResponse) => res.body);
274
+ }
275
+
271
276
  public addApp(appName: string): Promise<App> {
272
277
  const app: App = { name: appName };
273
278
  return this.post(urlEncode(["/apps"]), JSON.stringify(app), /*expectResponseBody=*/ false).then(() => app);
@@ -10,12 +10,9 @@ export enum CommandType {
10
10
  accessKeyRemove,
11
11
  appAdd,
12
12
  appList,
13
+ appDeploymentKeyList,
13
14
  appRemove,
14
15
  appRename,
15
- appTransfer,
16
- collaboratorAdd,
17
- collaboratorList,
18
- collaboratorRemove,
19
16
  debug,
20
17
  deploymentAdd,
21
18
  deploymentHistory,
@@ -34,8 +31,7 @@ export enum CommandType {
34
31
  releaseReact,
35
32
  rollback,
36
33
  sessionList,
37
- sessionRemove,
38
- whoami,
34
+ sessionRemove
39
35
  }
40
36
 
41
37
  export interface ICommand {
@@ -75,6 +71,10 @@ export interface IAppRemoveCommand extends ICommand {
75
71
  appName: string;
76
72
  }
77
73
 
74
+ export interface IAppDeploymentKeysCommand extends ICommand {
75
+ appName: string;
76
+ }
77
+
78
78
  export interface IAppRenameCommand extends ICommand {
79
79
  currentAppName: string;
80
80
  newAppName: string;
@@ -126,6 +126,12 @@ export interface Deployment {
126
126
  /*generated*/ package?: Package;
127
127
  }
128
128
 
129
+ /*out*/
130
+ export interface DeploymentKey {
131
+ /*generated key*/ deploymentKey?: string;
132
+ /*key*/ name: string;
133
+ }
134
+
129
135
  /*out*/
130
136
  export interface BlobInfo {
131
137
  size: number;
package/test/cli.ts CHANGED
@@ -579,83 +579,6 @@ describe("CLI", () => {
579
579
  });
580
580
  });
581
581
 
582
- it("appTransfer transfers app", (done: Mocha.Done): void => {
583
- var command: cli.IAppTransferCommand = {
584
- type: cli.CommandType.appTransfer,
585
- appName: "a",
586
- email: "b@b.com",
587
- };
588
-
589
- var transferApp: sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "transferApp");
590
-
591
- cmdexec.execute(command).done((): void => {
592
- sinon.assert.calledOnce(transferApp);
593
- sinon.assert.calledOnce(log);
594
- sinon.assert.calledWithExactly(log, 'Successfully transferred the ownership of app "a" to the account with email "b@b.com".');
595
-
596
- done();
597
- });
598
- });
599
-
600
- it("collaboratorAdd adds collaborator", (done: Mocha.Done): void => {
601
- var command: cli.ICollaboratorAddCommand = {
602
- type: cli.CommandType.collaboratorAdd,
603
- appName: "a",
604
- email: "b@b.com",
605
- };
606
-
607
- var addCollaborator: sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "addCollaborator");
608
-
609
- cmdexec.execute(command).done((): void => {
610
- sinon.assert.calledOnce(addCollaborator);
611
- sinon.assert.calledOnce(log);
612
- sinon.assert.calledWithExactly(log, 'Successfully added "b@b.com" as a collaborator to the app "a".');
613
-
614
- done();
615
- });
616
- });
617
-
618
- it("collaboratorList lists collaborators email and properties", (done: Mocha.Done): void => {
619
- var command: cli.ICollaboratorListCommand = {
620
- type: cli.CommandType.collaboratorList,
621
- appName: "a",
622
- format: "json",
623
- };
624
-
625
- cmdexec.execute(command).done((): void => {
626
- sinon.assert.calledOnce(log);
627
- assert.equal(log.args[0].length, 1);
628
-
629
- var actual: string = log.args[0][0];
630
- var expected = {
631
- collaborators: {
632
- "a@a.com": { permission: "Owner", isCurrentAccount: true },
633
- "b@b.com": { permission: "Collaborator", isCurrentAccount: false },
634
- },
635
- };
636
-
637
- assertJsonDescribesObject(actual, expected);
638
- done();
639
- });
640
- });
641
-
642
- it("collaboratorRemove removes collaborator", (done: Mocha.Done): void => {
643
- var command: cli.ICollaboratorRemoveCommand = {
644
- type: cli.CommandType.collaboratorRemove,
645
- appName: "a",
646
- email: "b@b.com",
647
- };
648
-
649
- var removeCollaborator: sinon.SinonSpy = sandbox.spy(cmdexec.sdk, "removeCollaborator");
650
-
651
- cmdexec.execute(command).done((): void => {
652
- sinon.assert.calledOnce(removeCollaborator);
653
- sinon.assert.calledOnce(log);
654
- sinon.assert.calledWithExactly(log, 'Successfully removed "b@b.com" as a collaborator from the app "a".');
655
-
656
- done();
657
- });
658
- });
659
582
 
660
583
  it("deploymentAdd reports new app name and ID", (done: Mocha.Done): void => {
661
584
  var command: cli.IDeploymentAddCommand = {