@capuchoo/cli 0.7.0 → 0.9.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.
Files changed (106) hide show
  1. package/README.md +231 -22
  2. package/bin/run.js +22 -0
  3. package/dist/cli/members.d.ts +23 -0
  4. package/dist/cli/members.d.ts.map +1 -0
  5. package/dist/cli/members.js +38 -0
  6. package/dist/cli/members.js.map +1 -0
  7. package/dist/cli/menu.d.ts +38 -0
  8. package/dist/cli/menu.d.ts.map +1 -0
  9. package/dist/cli/menu.js +62 -0
  10. package/dist/cli/menu.js.map +1 -0
  11. package/dist/cli/onboarding.d.ts +41 -0
  12. package/dist/cli/onboarding.d.ts.map +1 -0
  13. package/dist/cli/onboarding.js +94 -0
  14. package/dist/cli/onboarding.js.map +1 -0
  15. package/dist/cli/prompts.d.ts +15 -0
  16. package/dist/cli/prompts.d.ts.map +1 -1
  17. package/dist/cli/prompts.js +42 -0
  18. package/dist/cli/prompts.js.map +1 -1
  19. package/dist/cli/team.d.ts +16 -0
  20. package/dist/cli/team.d.ts.map +1 -0
  21. package/dist/cli/team.js +32 -0
  22. package/dist/cli/team.js.map +1 -0
  23. package/dist/commands/app/grant.d.ts +11 -0
  24. package/dist/commands/app/grant.d.ts.map +1 -0
  25. package/dist/commands/app/grant.js +31 -0
  26. package/dist/commands/app/grant.js.map +1 -0
  27. package/dist/commands/app/list.d.ts.map +1 -1
  28. package/dist/commands/app/list.js +2 -1
  29. package/dist/commands/app/list.js.map +1 -1
  30. package/dist/commands/app/revoke.d.ts +13 -0
  31. package/dist/commands/app/revoke.d.ts.map +1 -0
  32. package/dist/commands/app/revoke.js +40 -0
  33. package/dist/commands/app/revoke.js.map +1 -0
  34. package/dist/commands/app/roles.d.ts +7 -0
  35. package/dist/commands/app/roles.d.ts.map +1 -0
  36. package/dist/commands/app/roles.js +30 -0
  37. package/dist/commands/app/roles.js.map +1 -0
  38. package/dist/commands/auth/issue.d.ts +12 -0
  39. package/dist/commands/auth/issue.d.ts.map +1 -0
  40. package/dist/commands/auth/issue.js +52 -0
  41. package/dist/commands/auth/issue.js.map +1 -0
  42. package/dist/commands/auth/keys.d.ts +7 -0
  43. package/dist/commands/auth/keys.d.ts.map +1 -0
  44. package/dist/commands/auth/keys.js +39 -0
  45. package/dist/commands/auth/keys.js.map +1 -0
  46. package/dist/commands/auth/login.d.ts +20 -0
  47. package/dist/commands/auth/login.d.ts.map +1 -1
  48. package/dist/commands/auth/login.js +90 -11
  49. package/dist/commands/auth/login.js.map +1 -1
  50. package/dist/commands/auth/revoke.d.ts +13 -0
  51. package/dist/commands/auth/revoke.d.ts.map +1 -0
  52. package/dist/commands/auth/revoke.js +48 -0
  53. package/dist/commands/auth/revoke.js.map +1 -0
  54. package/dist/commands/auth/whoami.d.ts.map +1 -1
  55. package/dist/commands/auth/whoami.js +2 -1
  56. package/dist/commands/auth/whoami.js.map +1 -1
  57. package/dist/commands/channel/list.d.ts.map +1 -1
  58. package/dist/commands/channel/list.js +2 -1
  59. package/dist/commands/channel/list.js.map +1 -1
  60. package/dist/commands/doctor.d.ts +2 -0
  61. package/dist/commands/doctor.d.ts.map +1 -1
  62. package/dist/commands/doctor.js +86 -13
  63. package/dist/commands/doctor.js.map +1 -1
  64. package/dist/commands/init.d.ts +35 -3
  65. package/dist/commands/init.d.ts.map +1 -1
  66. package/dist/commands/init.js +121 -29
  67. package/dist/commands/init.js.map +1 -1
  68. package/dist/commands/menu.d.ts +42 -0
  69. package/dist/commands/menu.d.ts.map +1 -0
  70. package/dist/commands/menu.js +185 -0
  71. package/dist/commands/menu.js.map +1 -0
  72. package/dist/commands/org/invite.d.ts +14 -0
  73. package/dist/commands/org/invite.d.ts.map +1 -0
  74. package/dist/commands/org/invite.js +52 -0
  75. package/dist/commands/org/invite.js.map +1 -0
  76. package/dist/commands/org/members.d.ts +10 -0
  77. package/dist/commands/org/members.d.ts.map +1 -0
  78. package/dist/commands/org/members.js +49 -0
  79. package/dist/commands/org/members.js.map +1 -0
  80. package/dist/deploy/execute.d.ts.map +1 -1
  81. package/dist/deploy/execute.js +25 -5
  82. package/dist/deploy/execute.js.map +1 -1
  83. package/dist/deploy/signing.d.ts +24 -0
  84. package/dist/deploy/signing.d.ts.map +1 -0
  85. package/dist/deploy/signing.js +57 -0
  86. package/dist/deploy/signing.js.map +1 -0
  87. package/dist/pipeline/android-signing.d.ts +41 -0
  88. package/dist/pipeline/android-signing.d.ts.map +1 -0
  89. package/dist/pipeline/android-signing.js +82 -0
  90. package/dist/pipeline/android-signing.js.map +1 -0
  91. package/dist/pipeline/app-identity.d.ts +35 -0
  92. package/dist/pipeline/app-identity.d.ts.map +1 -0
  93. package/dist/pipeline/app-identity.js +109 -0
  94. package/dist/pipeline/app-identity.js.map +1 -0
  95. package/dist/pipeline/capacitor-support.d.ts +1 -1
  96. package/dist/pipeline/capacitor-support.js +1 -1
  97. package/dist/services/cloud.d.ts +82 -2
  98. package/dist/services/cloud.d.ts.map +1 -1
  99. package/dist/services/cloud.js +85 -4
  100. package/dist/services/cloud.js.map +1 -1
  101. package/dist/utils/http.d.ts +5 -0
  102. package/dist/utils/http.d.ts.map +1 -1
  103. package/dist/utils/http.js +13 -2
  104. package/dist/utils/http.js.map +1 -1
  105. package/oclif.manifest.json +397 -84
  106. package/package.json +5 -5
@@ -0,0 +1,94 @@
1
+ /**
2
+ * The single next action, so the first thing someone sees is a step rather than
3
+ * a list to guess from.
4
+ *
5
+ * Order is by dependency: nothing can be done unsigned, nothing app-specific
6
+ * without an app, nothing published without a channel.
7
+ */
8
+ export function resolveOnboarding(facts) {
9
+ if (!facts.signedIn) {
10
+ return {
11
+ stage: "signed-out",
12
+ next: {
13
+ command: "auth:login",
14
+ label: "Sign in",
15
+ why: "Nothing can reach the backend until this machine has a credential.",
16
+ },
17
+ };
18
+ }
19
+ if (!facts.inAppDirectory) {
20
+ return { stage: "not-an-app", next: null };
21
+ }
22
+ if (!facts.linked) {
23
+ return {
24
+ stage: "unlinked",
25
+ next: {
26
+ command: "setup",
27
+ label: "Set this app up",
28
+ why: "Installs what the app needs and links it to Capuchoo.",
29
+ },
30
+ };
31
+ }
32
+ if (!facts.updaterInstalled) {
33
+ return {
34
+ stage: "incomplete",
35
+ next: {
36
+ command: "setup",
37
+ label: "Finish setting up",
38
+ why: "Linked, but the app cannot check for updates without @capuchoo/updater.",
39
+ },
40
+ };
41
+ }
42
+ // Channels are the only fact that needs the network, so an unknown value must
43
+ // not be reported as a problem.
44
+ if (facts.channels && facts.channels.length === 0) {
45
+ return {
46
+ stage: "no-channels",
47
+ next: {
48
+ command: "channel:create",
49
+ label: "Create a channel",
50
+ why: "There is nowhere to publish to yet.",
51
+ },
52
+ };
53
+ }
54
+ if (facts.channels && !facts.channels.some((channel) => channel.servingBundle)) {
55
+ return {
56
+ stage: "nothing-served",
57
+ next: {
58
+ command: "deploy:ota",
59
+ label: "Publish the first bundle",
60
+ why: "Every channel exists but none is serving anything, so devices get no update.",
61
+ },
62
+ };
63
+ }
64
+ return {
65
+ stage: "ready",
66
+ next: {
67
+ command: "deploy:ota",
68
+ label: "Publish an update",
69
+ why: "Everything is wired up.",
70
+ },
71
+ };
72
+ }
73
+ /** Commands worth hiding in this state, by oclif id. */
74
+ export function hiddenCommands(facts) {
75
+ if (!facts.signedIn) {
76
+ // Signing in is the only useful action, and `config` is how someone points
77
+ // at a different backend before trying.
78
+ return new Set(["auth:logout", "auth:whoami"]);
79
+ }
80
+ return new Set(["auth:login"]);
81
+ }
82
+ /** A label that reads correctly for the current state, or null to keep the default. */
83
+ export function labelFor(command, facts) {
84
+ if (command === "setup" && facts.linked && facts.updaterInstalled)
85
+ return "setup (re-run)";
86
+ if (command === "init" && facts.linked)
87
+ return "init (re-link)";
88
+ return null;
89
+ }
90
+ /** Whether only the next step should be offered, rather than the whole menu. */
91
+ export function isBlocked(state) {
92
+ return state.stage === "signed-out";
93
+ }
94
+ //# sourceMappingURL=onboarding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding.js","sourceRoot":"","sources":["../../src/cli/onboarding.ts"],"names":[],"mappings":"AAkCA;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAsB;IACtD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE;gBACJ,OAAO,EAAE,YAAY;gBACrB,KAAK,EAAE,SAAS;gBAChB,GAAG,EAAE,oEAAoE;aAC1E;SACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO;YACL,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE;gBACJ,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE,iBAAiB;gBACxB,GAAG,EAAE,uDAAuD;aAC7D;SACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC5B,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE;gBACJ,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE,mBAAmB;gBAC1B,GAAG,EAAE,yEAAyE;aAC/E;SACF,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,gCAAgC;IAChC,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO;YACL,KAAK,EAAE,aAAa;YACpB,IAAI,EAAE;gBACJ,OAAO,EAAE,gBAAgB;gBACzB,KAAK,EAAE,kBAAkB;gBACzB,GAAG,EAAE,qCAAqC;aAC3C;SACF,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAC/E,OAAO;YACL,KAAK,EAAE,gBAAgB;YACvB,IAAI,EAAE;gBACJ,OAAO,EAAE,YAAY;gBACrB,KAAK,EAAE,0BAA0B;gBACjC,GAAG,EAAE,8EAA8E;aACpF;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,OAAO;QACd,IAAI,EAAE;YACJ,OAAO,EAAE,YAAY;YACrB,KAAK,EAAE,mBAAmB;YAC1B,GAAG,EAAE,yBAAyB;SAC/B;KACF,CAAC;AACJ,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,cAAc,CAAC,KAAsB;IACnD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpB,2EAA2E;QAC3E,wCAAwC;QACxC,OAAO,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,KAAsB;IAC9D,IAAI,OAAO,KAAK,OAAO,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAO,gBAAgB,CAAC;IAC3F,IAAI,OAAO,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,gBAAgB,CAAC;IAChE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,SAAS,CAAC,KAAsB;IAC9C,OAAO,KAAK,CAAC,KAAK,KAAK,YAAY,CAAC;AACtC,CAAC"}
@@ -27,6 +27,21 @@ export declare function spinner(): {
27
27
  start: (m: string) => void;
28
28
  stop: (m?: string) => void;
29
29
  };
30
+ /**
31
+ * Runs work, and shows a spinner only once it has been slow enough to worry about.
32
+ *
33
+ * The backend is on a host that sleeps when idle, so the first request of a
34
+ * session can take fifteen seconds to come back. Every command opened with an
35
+ * unannounced `whoami()`, so `capuchoo doctor` and `capuchoo deploy native` sat
36
+ * with a blank terminal for that whole time and looked broken - the user
37
+ * reported the CLI itself as laggy, which it is not: `--version` returns in
38
+ * 190ms.
39
+ *
40
+ * Deliberately delayed rather than always-on. A warm backend answers in well
41
+ * under the threshold and stays silent, so the spinner only ever appears when
42
+ * there is genuinely something to wait for.
43
+ */
44
+ export declare function whileWaiting<T>(message: string, work: Promise<T>): Promise<T>;
30
45
  export declare function selectOne<T>(question: string, choices: Choice<T>[], flag: string): Promise<T>;
31
46
  export declare function confirm(question: string, options?: {
32
47
  default?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"AAoBA,qBAAa,eAAgB,SAAQ,KAAK;;CAKzC;AAED,8EAA8E;AAC9E,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAI3C;AAED,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAOD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,eAAO,MAAM,GAAG;oBACE,MAAM;oBACN,MAAM;oBACN,MAAM;qBACL,MAAM;uBACJ,MAAM;uBACN,MAAM;CAC1B,CAAC;AAEF,mEAAmE;AACnE,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED,wBAAgB,OAAO,IAAI;IAAE,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAMpF;AAED,wBAAsB,SAAS,CAAC,CAAC,EAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EACpB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAED,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GACA,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAcjE"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"AAoBA,qBAAa,eAAgB,SAAQ,KAAK;;CAKzC;AAED,8EAA8E;AAC9E,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAI3C;AAED,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAOD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,eAAO,MAAM,GAAG;oBACE,MAAM;oBACN,MAAM;oBACN,MAAM;qBACL,MAAM;uBACJ,MAAM;uBACN,MAAM;CAC1B,CAAC;AAEF,mEAAmE;AACnE,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED,wBAAgB,OAAO,IAAI;IAAE,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAMpF;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAqBnF;AAED,wBAAsB,SAAS,CAAC,CAAC,EAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EACpB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAED,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GACA,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAcjE"}
@@ -61,6 +61,48 @@ export function spinner() {
61
61
  stop: (message) => instance.stop(message),
62
62
  };
63
63
  }
64
+ /**
65
+ * How long a call may take before silence starts to look like a hang.
66
+ *
67
+ * Under this, a spinner would appear and vanish within a frame, which reads as a
68
+ * glitch rather than progress.
69
+ */
70
+ const LOOKS_STUCK_AFTER_MS = 400;
71
+ /**
72
+ * Runs work, and shows a spinner only once it has been slow enough to worry about.
73
+ *
74
+ * The backend is on a host that sleeps when idle, so the first request of a
75
+ * session can take fifteen seconds to come back. Every command opened with an
76
+ * unannounced `whoami()`, so `capuchoo doctor` and `capuchoo deploy native` sat
77
+ * with a blank terminal for that whole time and looked broken - the user
78
+ * reported the CLI itself as laggy, which it is not: `--version` returns in
79
+ * 190ms.
80
+ *
81
+ * Deliberately delayed rather than always-on. A warm backend answers in well
82
+ * under the threshold and stays silent, so the spinner only ever appears when
83
+ * there is genuinely something to wait for.
84
+ */
85
+ export async function whileWaiting(message, work) {
86
+ if (!isInteractive())
87
+ return work;
88
+ // Held on an object rather than in a plain `let`: control-flow analysis cannot
89
+ // see an assignment made inside a timer callback, so a `let` stays narrowed to
90
+ // its initialiser and the guard below becomes a type error.
91
+ const shown = {};
92
+ const timer = setTimeout(() => {
93
+ shown.spinner = spinner();
94
+ shown.spinner.start(message);
95
+ }, LOOKS_STUCK_AFTER_MS);
96
+ try {
97
+ return await work;
98
+ }
99
+ finally {
100
+ clearTimeout(timer);
101
+ // stop() on a spinner that never started throws, hence the guard rather
102
+ // than an unconditional call.
103
+ shown.spinner?.stop();
104
+ }
105
+ }
64
106
  export async function selectOne(question, choices, flag) {
65
107
  if (choices.length === 0)
66
108
  throw new Error(`Nothing to choose from for: ${question}`);
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Command } from "@oclif/core";
2
+ import type { ResolvedProjectConfig } from "@capuchoo/core";
3
+ import { CloudClient } from "../services/cloud.js";
4
+ export declare const APP_ROLES: readonly ["admin", "developer", "tester", "viewer"];
5
+ export declare const ORG_ROLES: readonly ["owner", "admin", "member"];
6
+ /** Roles that may ship code, mirroring PUBLISH_ROLES on the server. */
7
+ export declare const PUBLISH_ROLES: readonly string[];
8
+ export interface LinkedApp {
9
+ cloud: CloudClient;
10
+ project: ResolvedProjectConfig;
11
+ }
12
+ /** Credentials plus a linked app, or a clear error naming the missing half. */
13
+ export declare function requireLinkedApp(command: Command): LinkedApp;
14
+ /** Credentials only, for commands that are not about one app. */
15
+ export declare function requireCloud(command: Command): CloudClient;
16
+ //# sourceMappingURL=team.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.d.ts","sourceRoot":"","sources":["../../src/cli/team.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,eAAO,MAAM,SAAS,qDAAsD,CAAC;AAC7E,eAAO,MAAM,SAAS,uCAAwC,CAAC;AAE/D,uEAAuE;AACvE,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAA2B,CAAC;AAEvE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,qBAAqB,CAAC;CAChC;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAe5D;AAED,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAO1D"}
@@ -0,0 +1,32 @@
1
+ import chalk from "chalk";
2
+ import { normaliseProjectConfig } from "@capuchoo/core";
3
+ import { CloudClient } from "../services/cloud.js";
4
+ import { readProjectConfig, resolveCredentials } from "../utils/config.js";
5
+ export const APP_ROLES = ["admin", "developer", "tester", "viewer"];
6
+ export const ORG_ROLES = ["owner", "admin", "member"];
7
+ /** Roles that may ship code, mirroring PUBLISH_ROLES on the server. */
8
+ export const PUBLISH_ROLES = ["admin", "developer"];
9
+ /** Credentials plus a linked app, or a clear error naming the missing half. */
10
+ export function requireLinkedApp(command) {
11
+ const credentials = resolveCredentials();
12
+ if (!credentials) {
13
+ command.error(`Not signed in. Run ${chalk.cyan("capuchoo auth login")}.`);
14
+ }
15
+ const raw = readProjectConfig(process.cwd());
16
+ if (!raw) {
17
+ command.error(`This directory is not linked to an app. Run ${chalk.cyan("capuchoo init")}.`);
18
+ }
19
+ return {
20
+ cloud: new CloudClient(credentials.endpoint, credentials.apiKey),
21
+ project: normaliseProjectConfig(raw),
22
+ };
23
+ }
24
+ /** Credentials only, for commands that are not about one app. */
25
+ export function requireCloud(command) {
26
+ const credentials = resolveCredentials();
27
+ if (!credentials) {
28
+ command.error(`Not signed in. Run ${chalk.cyan("capuchoo auth login")}.`);
29
+ }
30
+ return new CloudClient(credentials.endpoint, credentials.apiKey);
31
+ }
32
+ //# sourceMappingURL=team.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.js","sourceRoot":"","sources":["../../src/cli/team.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAC7E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAC;AAE/D,uEAAuE;AACvE,MAAM,CAAC,MAAM,aAAa,GAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAOvE,+EAA+E;AAC/E,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;IACzC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,sBAAsB,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,GAAG,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,+CAA+C,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC/F,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC;QAChE,OAAO,EAAE,sBAAsB,CAAC,GAAG,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;IACzC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,sBAAsB,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class AppGrant extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ email: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ role: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=grant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../../src/commands/app/grant.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,OAAgB,WAAW,SAAqC;IAEhE,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,IAAI;;;MAOlB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkB3B"}
@@ -0,0 +1,31 @@
1
+ import { Args } from "@oclif/core";
2
+ import chalk from "chalk";
3
+ import { BaseCommand } from "../../base-command.js";
4
+ import { whileWaiting } from "../../cli/prompts.js";
5
+ import { APP_ROLES, requireLinkedApp } from "../../cli/team.js";
6
+ export default class AppGrant extends BaseCommand {
7
+ static description = "Give someone a role on this app";
8
+ static examples = [
9
+ "<%= config.bin %> app grant dev@company.com developer",
10
+ "<%= config.bin %> app grant qa@company.com tester",
11
+ ];
12
+ static args = {
13
+ email: Args.string({ description: "Account to grant", required: true }),
14
+ role: Args.string({
15
+ description: `One of ${APP_ROLES.join(", ")}`,
16
+ required: true,
17
+ options: [...APP_ROLES],
18
+ }),
19
+ };
20
+ async run() {
21
+ const { args } = await this.parse(AppGrant);
22
+ const { cloud, project } = requireLinkedApp(this);
23
+ await whileWaiting("Granting...", cloud.grantAppRole(project.cloudAppId, args.email.trim(), args.role));
24
+ const publishes = args.role === "admin" || args.role === "developer";
25
+ this.log("");
26
+ this.log(` ${chalk.green("Granted")} ${args.email} is now ${chalk.bold(args.role)}`);
27
+ this.log(chalk.dim(publishes ? " They can publish releases." : " They cannot publish releases."));
28
+ this.log("");
29
+ }
30
+ }
31
+ //# sourceMappingURL=grant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grant.js","sourceRoot":"","sources":["../../../src/commands/app/grant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGhE,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,MAAM,CAAU,WAAW,GAAG,iCAAiC,CAAC;IAEhE,MAAM,CAAU,QAAQ,GAAG;QACzB,uDAAuD;QACvD,mDAAmD;KACpD,CAAC;IAEF,MAAM,CAAU,IAAI,GAAG;QACrB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACvE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAChB,WAAW,EAAE,UAAU,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC7C,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC;SACxB,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,YAAY,CAChB,aAAa,EACb,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,IAAe,CAAC,CAChF,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC;QAErE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtF,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAC1F,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/app/list.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,OAAgB,WAAW,SAA0C;IAErE,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkC3B"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/app/list.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,OAAgB,WAAW,SAA0C;IAErE,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkC3B"}
@@ -1,5 +1,6 @@
1
1
  import { Flags } from "@oclif/core";
2
2
  import chalk from "chalk";
3
+ import { whileWaiting } from "../../cli/prompts.js";
3
4
  import { BaseCommand } from "../../base-command.js";
4
5
  import { CloudClient } from "../../services/cloud.js";
5
6
  import { readProjectConfig, resolveCredentials } from "../../utils/config.js";
@@ -15,7 +16,7 @@ export default class AppList extends BaseCommand {
15
16
  this.error(`Not authenticated. Run ${chalk.cyan("capuchoo auth login")}.`);
16
17
  }
17
18
  const cloud = new CloudClient(credentials.endpoint, credentials.apiKey);
18
- const apps = await cloud.apps();
19
+ const apps = await whileWaiting("Reading apps...", cloud.apps());
19
20
  if (flags.json) {
20
21
  this.log(JSON.stringify(apps, null, 2));
21
22
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/app/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,MAAM,CAAU,WAAW,GAAG,sCAAsC,CAAC;IAErE,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;KAChF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE5C,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,0BAA0B,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEhC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,6CAA6C,CAAC,GAAG,IAAI,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QAED,4EAA4E;QAC5E,yEAAyE;QACzE,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,UAAU,CAAC;QAE5D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/app/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,MAAM,CAAU,WAAW,GAAG,sCAAsC,CAAC;IAErE,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;KAChF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE5C,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,0BAA0B,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,iBAAiB,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAEjE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,6CAA6C,CAAC,GAAG,IAAI,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QAED,4EAA4E;QAC5E,yEAAyE;QACzE,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,UAAU,CAAC;QAE5D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class AppRevoke extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ email: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=revoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revoke.d.ts","sourceRoot":"","sources":["../../../src/commands/app/revoke.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,WAAW,SAAuC;IAElE,OAAgB,QAAQ,WAAoD;IAE5E,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B3B"}
@@ -0,0 +1,40 @@
1
+ import { Args, Flags } from "@oclif/core";
2
+ import chalk from "chalk";
3
+ import { BaseCommand } from "../../base-command.js";
4
+ import { resolveByEmail } from "../../cli/members.js";
5
+ import { confirm, isInteractive, whileWaiting } from "../../cli/prompts.js";
6
+ import { requireLinkedApp } from "../../cli/team.js";
7
+ export default class AppRevoke extends BaseCommand {
8
+ static description = "Remove someone's role on this app";
9
+ static examples = ["<%= config.bin %> app revoke dev@company.com"];
10
+ static args = {
11
+ email: Args.string({ description: "Account to revoke", required: true }),
12
+ };
13
+ static flags = {
14
+ yes: Flags.boolean({ char: "y", default: false, description: "Skip the confirmation" }),
15
+ };
16
+ async run() {
17
+ const { args, flags } = await this.parse(AppRevoke);
18
+ const { cloud, project } = requireLinkedApp(this);
19
+ const members = await whileWaiting("Reading permissions...", cloud.appPermissions(project.cloudAppId));
20
+ const found = resolveByEmail(members, args.email);
21
+ if (!found.ok)
22
+ this.error(found.problem);
23
+ if (!flags.yes) {
24
+ if (!isInteractive()) {
25
+ this.error(`Refusing to revoke ${args.email} unattended. Pass --yes.`);
26
+ }
27
+ const proceed = await confirm(`Revoke ${args.email} on ${project.appName}?`, {
28
+ default: false,
29
+ });
30
+ if (!proceed)
31
+ return;
32
+ }
33
+ await whileWaiting("Revoking...", cloud.revokeAppRole(project.cloudAppId, found.userId));
34
+ this.log("");
35
+ this.log(` ${chalk.green("Revoked")} ${args.email}`);
36
+ this.log(chalk.dim(" Organisation owners and admins keep access - remove them from the org instead."));
37
+ this.log("");
38
+ }
39
+ }
40
+ //# sourceMappingURL=revoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revoke.js","sourceRoot":"","sources":["../../../src/commands/app/revoke.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,MAAM,CAAU,WAAW,GAAG,mCAAmC,CAAC;IAElE,MAAM,CAAU,QAAQ,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAE5E,MAAM,CAAU,IAAI,GAAG;QACrB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KACzE,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC;KACxF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,MAAM,YAAY,CAChC,wBAAwB,EACxB,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CACzC,CAAC;QAEF,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,KAAK,0BAA0B,CAAC,CAAC;YACzE,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,IAAI,CAAC,KAAK,OAAO,OAAO,CAAC,OAAO,GAAG,EAAE;gBAC3E,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YACH,IAAI,CAAC,OAAO;gBAAE,OAAO;QACvB,CAAC;QAED,MAAM,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,MAAO,CAAC,CAAC,CAAC;QAE1F,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAC9F,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class AppRoles extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=roles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../../src/commands/app/roles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,OAAgB,WAAW,SAAsC;IAEjE,OAAgB,QAAQ,WAAmC;IAErD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA8B3B"}
@@ -0,0 +1,30 @@
1
+ import chalk from "chalk";
2
+ import { BaseCommand } from "../../base-command.js";
3
+ import { membershipRows } from "../../cli/members.js";
4
+ import { whileWaiting } from "../../cli/prompts.js";
5
+ import { requireLinkedApp } from "../../cli/team.js";
6
+ export default class AppRoles extends BaseCommand {
7
+ static description = "Show who can do what on this app";
8
+ static examples = ["<%= config.bin %> app roles"];
9
+ async run() {
10
+ const { cloud, project } = requireLinkedApp(this);
11
+ const members = await whileWaiting("Reading permissions...", cloud.appPermissions(project.cloudAppId));
12
+ this.log("");
13
+ this.log(` ${chalk.bold(project.appName)} ${chalk.dim(`(${project.appId})`)}`);
14
+ this.log("");
15
+ if (members.length === 0) {
16
+ this.log(chalk.dim(" No direct grants. Organisation owners and admins still have access."));
17
+ this.log("");
18
+ return;
19
+ }
20
+ const width = Math.max(...membershipRows(members).map((row) => row.email.length));
21
+ for (const row of membershipRows(members)) {
22
+ const canPublish = row.role === "admin" || row.role === "developer";
23
+ this.log(` ${row.email.padEnd(width)} ${canPublish ? chalk.green(row.role) : chalk.dim(row.role)}`);
24
+ }
25
+ this.log("");
26
+ this.log(chalk.dim(" Green roles may publish. Grant with: capuchoo app grant <email> <role>"));
27
+ this.log("");
28
+ }
29
+ }
30
+ //# sourceMappingURL=roles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.js","sourceRoot":"","sources":["../../../src/commands/app/roles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,MAAM,CAAU,WAAW,GAAG,kCAAkC,CAAC;IAEjE,MAAM,CAAU,QAAQ,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3D,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,MAAM,YAAY,CAChC,wBAAwB,EACxB,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CACzC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;QAChF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEb,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC,CAAC;YAC7F,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAClF,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC;YACpE,IAAI,CAAC,GAAG,CACN,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC5F,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC,CAAC;QAChG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class AuthIssue extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ role: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ "this-app": import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=issue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/issue.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,WAAW;IAChD,OAAgB,WAAW,SAAmE;IAE9F,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;;;MAUnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B3B"}
@@ -0,0 +1,52 @@
1
+ import { APP_ROLE_ORDER, describeCap } from "@capuchoo/core";
2
+ import { Flags } from "@oclif/core";
3
+ import chalk from "chalk";
4
+ import { hostname } from "node:os";
5
+ import { BaseCommand } from "../../base-command.js";
6
+ import { whileWaiting } from "../../cli/prompts.js";
7
+ import { requireCloud } from "../../cli/team.js";
8
+ import { readProjectConfig } from "../../utils/config.js";
9
+ export default class AuthIssue extends BaseCommand {
10
+ static description = "Create an API key, optionally limited to one app and one role";
11
+ static examples = [
12
+ "<%= config.bin %> auth issue --name ci --role developer --this-app",
13
+ "<%= config.bin %> auth issue --name readonly --role viewer",
14
+ ];
15
+ static flags = {
16
+ name: Flags.string({ description: "Label shown in capuchoo auth keys" }),
17
+ role: Flags.string({
18
+ description: `Ceiling on what the key may do: ${APP_ROLE_ORDER.join(", ")}`,
19
+ options: [...APP_ROLE_ORDER],
20
+ }),
21
+ "this-app": Flags.boolean({
22
+ default: false,
23
+ description: "Restrict the key to the app this directory is linked to",
24
+ }),
25
+ };
26
+ async run() {
27
+ const { flags } = await this.parse(AuthIssue);
28
+ const cloud = requireCloud(this);
29
+ let appId;
30
+ if (flags["this-app"]) {
31
+ const project = readProjectConfig(process.cwd());
32
+ if (!project) {
33
+ this.error("--this-app needs a linked directory. Run capuchoo init, or drop the flag.");
34
+ }
35
+ appId = project.cloudAppId;
36
+ }
37
+ const name = flags.name?.trim() || `capuchoo-cli ${hostname()}`;
38
+ const role = flags.role;
39
+ const { key } = await whileWaiting("Creating...", cloud.createApiKey({ name, appId, role }));
40
+ this.log("");
41
+ this.log(` ${chalk.bold(name)}`);
42
+ this.log(` scope ${appId ? chalk.yellow("this app only") : chalk.dim("all apps")}`);
43
+ this.log(` role ${role ? chalk.yellow(describeCap(role)) : chalk.dim(describeCap(null))}`);
44
+ this.log("");
45
+ // Shown once, because only its hash is stored.
46
+ this.log(` ${key}`);
47
+ this.log("");
48
+ this.log(chalk.yellow(" Copy it now - it is not stored and cannot be shown again."));
49
+ this.log("");
50
+ }
51
+ }
52
+ //# sourceMappingURL=issue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.js","sourceRoot":"","sources":["../../../src/commands/auth/issue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { BaseCommand } from "../../base-command.js";
2
+ export default class AuthKeys extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/keys.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKpD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,OAAgB,WAAW,SAAuC;IAElE,OAAgB,QAAQ,WAAmC;IAErD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAsC3B"}
@@ -0,0 +1,39 @@
1
+ import { describeCap, isAppRole } from "@capuchoo/core";
2
+ import chalk from "chalk";
3
+ import { BaseCommand } from "../../base-command.js";
4
+ import { whileWaiting } from "../../cli/prompts.js";
5
+ import { requireCloud } from "../../cli/team.js";
6
+ import { resolveCredentials } from "../../utils/config.js";
7
+ export default class AuthKeys extends BaseCommand {
8
+ static description = "List the API keys on this account";
9
+ static examples = ["<%= config.bin %> auth keys"];
10
+ async run() {
11
+ const cloud = requireCloud(this);
12
+ const current = resolveCredentials();
13
+ const keys = await whileWaiting("Reading keys...", cloud.apiKeys());
14
+ this.log("");
15
+ if (keys.length === 0) {
16
+ this.log(chalk.dim(" No keys."));
17
+ this.log("");
18
+ return;
19
+ }
20
+ for (const key of keys) {
21
+ // A key is shown once, at creation, so the prefix is the only way to tell
22
+ // which stored credential a row corresponds to.
23
+ const mine = key.key_prefix ? current?.apiKey.startsWith(key.key_prefix) : false;
24
+ const scope = key.app_id ? chalk.yellow("one app") : chalk.dim("all apps");
25
+ this.log(` ${chalk.bold(key.name)} ${chalk.dim(key.key_prefix ?? "")}` +
26
+ `${mine ? chalk.green(" (this machine)") : ""}`);
27
+ const cap = isAppRole(key.role)
28
+ ? chalk.yellow(describeCap(key.role))
29
+ : chalk.dim(describeCap(null));
30
+ this.log(` ${scope} ${cap}`);
31
+ this.log(` ${chalk.dim(`id ${key.id}`)}`);
32
+ }
33
+ this.log("");
34
+ this.log(chalk.dim(" Revoke one with: capuchoo auth revoke <id>"));
35
+ this.log(chalk.dim(" Issue a limited one with: capuchoo auth issue --role developer --this-app"));
36
+ this.log("");
37
+ }
38
+ }
39
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/commands/auth/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,WAAW;IAC/C,MAAM,CAAU,WAAW,GAAG,mCAAmC,CAAC;IAElE,MAAM,CAAU,QAAQ,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3D,KAAK,CAAC,GAAG;QACP,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;QAErC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,iBAAiB,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAEpE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEb,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,0EAA0E;YAC1E,gDAAgD;YAChD,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACjF,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAE3E,IAAI,CAAC,GAAG,CACN,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE;gBAC5D,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,CAAC;YACF,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;gBAC7B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,GAAG,CACN,KAAK,CAAC,GAAG,CAAC,6EAA6E,CAAC,CACzF,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC"}