@nebulr-group/bridge-cli 0.6.6 → 1.0.0-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.
Files changed (293) hide show
  1. package/README.md +98 -458
  2. package/dist/api/accounts.d.ts +105 -0
  3. package/dist/api/accounts.d.ts.map +1 -0
  4. package/dist/api/accounts.js +58 -0
  5. package/dist/api/accounts.js.map +1 -0
  6. package/dist/api/apps.d.ts +50 -0
  7. package/dist/api/apps.d.ts.map +1 -0
  8. package/dist/api/apps.js +62 -0
  9. package/dist/api/apps.js.map +1 -0
  10. package/dist/api/billing.d.ts +131 -0
  11. package/dist/api/billing.d.ts.map +1 -0
  12. package/dist/api/billing.js +42 -0
  13. package/dist/api/billing.js.map +1 -0
  14. package/dist/api/flags.d.ts +73 -0
  15. package/dist/api/flags.d.ts.map +1 -0
  16. package/dist/api/flags.js +108 -0
  17. package/dist/api/flags.js.map +1 -0
  18. package/dist/api/keys.d.ts +48 -0
  19. package/dist/api/keys.d.ts.map +1 -0
  20. package/dist/api/keys.js +87 -0
  21. package/dist/api/keys.js.map +1 -0
  22. package/dist/auth/browser-open.d.ts +21 -4
  23. package/dist/auth/browser-open.d.ts.map +1 -1
  24. package/dist/auth/browser-open.js +45 -65
  25. package/dist/auth/browser-open.js.map +1 -1
  26. package/dist/auth/lock.d.ts +8 -0
  27. package/dist/auth/lock.d.ts.map +1 -0
  28. package/dist/auth/lock.js +43 -0
  29. package/dist/auth/lock.js.map +1 -0
  30. package/dist/auth/loopback.d.ts +8 -12
  31. package/dist/auth/loopback.d.ts.map +1 -1
  32. package/dist/auth/loopback.js +40 -45
  33. package/dist/auth/loopback.js.map +1 -1
  34. package/dist/auth/session.d.ts +61 -0
  35. package/dist/auth/session.d.ts.map +1 -0
  36. package/dist/auth/session.js +142 -0
  37. package/dist/auth/session.js.map +1 -0
  38. package/dist/auth/sign-in.d.ts +67 -0
  39. package/dist/auth/sign-in.d.ts.map +1 -0
  40. package/dist/auth/sign-in.js +113 -0
  41. package/dist/auth/sign-in.js.map +1 -0
  42. package/dist/auth/store.d.ts +89 -0
  43. package/dist/auth/store.d.ts.map +1 -0
  44. package/dist/auth/store.js +214 -0
  45. package/dist/auth/store.js.map +1 -0
  46. package/dist/bin.js +0 -2
  47. package/dist/bin.js.map +1 -1
  48. package/dist/cli.d.ts +1 -2
  49. package/dist/cli.d.ts.map +1 -1
  50. package/dist/cli.js +13 -17
  51. package/dist/cli.js.map +1 -1
  52. package/dist/client.d.ts +31 -0
  53. package/dist/client.d.ts.map +1 -0
  54. package/dist/client.js +67 -0
  55. package/dist/client.js.map +1 -0
  56. package/dist/commands/accounts.command.d.ts +4 -0
  57. package/dist/commands/accounts.command.d.ts.map +1 -0
  58. package/dist/commands/accounts.command.js +166 -0
  59. package/dist/commands/accounts.command.js.map +1 -0
  60. package/dist/commands/app.command.d.ts +3 -2
  61. package/dist/commands/app.command.d.ts.map +1 -1
  62. package/dist/commands/app.command.js +132 -233
  63. package/dist/commands/app.command.js.map +1 -1
  64. package/dist/commands/auth.command.d.ts +2 -12
  65. package/dist/commands/auth.command.d.ts.map +1 -1
  66. package/dist/commands/auth.command.js +147 -20
  67. package/dist/commands/auth.command.js.map +1 -1
  68. package/dist/commands/billing.command.d.ts +4 -0
  69. package/dist/commands/billing.command.d.ts.map +1 -0
  70. package/dist/commands/billing.command.js +185 -0
  71. package/dist/commands/billing.command.js.map +1 -0
  72. package/dist/commands/check.command.d.ts +2 -1
  73. package/dist/commands/check.command.d.ts.map +1 -1
  74. package/dist/commands/check.command.js +11 -14
  75. package/dist/commands/check.command.js.map +1 -1
  76. package/dist/commands/context.d.ts +58 -0
  77. package/dist/commands/context.d.ts.map +1 -0
  78. package/dist/commands/context.js +78 -0
  79. package/dist/commands/context.js.map +1 -0
  80. package/dist/commands/flag.command.d.ts +3 -62
  81. package/dist/commands/flag.command.d.ts.map +1 -1
  82. package/dist/commands/flag.command.js +181 -864
  83. package/dist/commands/flag.command.js.map +1 -1
  84. package/dist/commands/key.command.d.ts +4 -0
  85. package/dist/commands/key.command.d.ts.map +1 -0
  86. package/dist/commands/key.command.js +44 -0
  87. package/dist/commands/key.command.js.map +1 -0
  88. package/dist/commands/plan.command.d.ts +3 -203
  89. package/dist/commands/plan.command.d.ts.map +1 -1
  90. package/dist/commands/plan.command.js +200 -759
  91. package/dist/commands/plan.command.js.map +1 -1
  92. package/dist/config.d.ts +19 -101
  93. package/dist/config.d.ts.map +1 -1
  94. package/dist/config.js +51 -364
  95. package/dist/config.js.map +1 -1
  96. package/dist/core/discovery.d.ts +27 -0
  97. package/dist/core/discovery.d.ts.map +1 -0
  98. package/dist/core/discovery.js +97 -0
  99. package/dist/core/discovery.js.map +1 -0
  100. package/dist/core/errors.d.ts +26 -0
  101. package/dist/core/errors.d.ts.map +1 -0
  102. package/dist/core/errors.js +33 -0
  103. package/dist/core/errors.js.map +1 -0
  104. package/dist/core/http.d.ts +23 -0
  105. package/dist/core/http.d.ts.map +1 -0
  106. package/dist/core/http.js +153 -0
  107. package/dist/core/http.js.map +1 -0
  108. package/dist/core/private-files.d.ts +6 -0
  109. package/dist/core/private-files.d.ts.map +1 -0
  110. package/dist/core/private-files.js +96 -0
  111. package/dist/core/private-files.js.map +1 -0
  112. package/dist/core/routes.d.ts +100 -0
  113. package/dist/core/routes.d.ts.map +1 -0
  114. package/dist/core/routes.js +99 -0
  115. package/dist/core/routes.js.map +1 -0
  116. package/dist/core/urls.d.ts +15 -0
  117. package/dist/core/urls.d.ts.map +1 -0
  118. package/dist/core/urls.js +55 -0
  119. package/dist/core/urls.js.map +1 -0
  120. package/dist/gate-rules.d.ts +1 -2
  121. package/dist/gate-rules.d.ts.map +1 -1
  122. package/dist/gate-rules.js +4 -5
  123. package/dist/gate-rules.js.map +1 -1
  124. package/dist/index.d.ts +24 -3
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +18 -3
  127. package/dist/index.js.map +1 -1
  128. package/dist/io.d.ts +21 -0
  129. package/dist/io.d.ts.map +1 -0
  130. package/dist/io.js +59 -0
  131. package/dist/io.js.map +1 -0
  132. package/dist/money.d.ts +42 -0
  133. package/dist/money.d.ts.map +1 -0
  134. package/dist/money.js +112 -0
  135. package/dist/money.js.map +1 -0
  136. package/dist/program.d.ts +5 -24
  137. package/dist/program.d.ts.map +1 -1
  138. package/dist/program.js +25 -113
  139. package/dist/program.js.map +1 -1
  140. package/package.json +7 -8
  141. package/dist/auth/api-client.d.ts +0 -50
  142. package/dist/auth/api-client.d.ts.map +0 -1
  143. package/dist/auth/api-client.js +0 -109
  144. package/dist/auth/api-client.js.map +0 -1
  145. package/dist/auth/relative-time.d.ts +0 -2
  146. package/dist/auth/relative-time.d.ts.map +0 -1
  147. package/dist/auth/relative-time.js +0 -27
  148. package/dist/auth/relative-time.js.map +0 -1
  149. package/dist/auth/scopes.d.ts +0 -30
  150. package/dist/auth/scopes.d.ts.map +0 -1
  151. package/dist/auth/scopes.js +0 -39
  152. package/dist/auth/scopes.js.map +0 -1
  153. package/dist/auth/workspace-client.d.ts +0 -70
  154. package/dist/auth/workspace-client.d.ts.map +0 -1
  155. package/dist/auth/workspace-client.js +0 -105
  156. package/dist/auth/workspace-client.js.map +0 -1
  157. package/dist/commands/auth/config.command.d.ts +0 -8
  158. package/dist/commands/auth/config.command.d.ts.map +0 -1
  159. package/dist/commands/auth/config.command.js +0 -60
  160. package/dist/commands/auth/config.command.js.map +0 -1
  161. package/dist/commands/auth/login.command.d.ts +0 -46
  162. package/dist/commands/auth/login.command.d.ts.map +0 -1
  163. package/dist/commands/auth/login.command.js +0 -166
  164. package/dist/commands/auth/login.command.js.map +0 -1
  165. package/dist/commands/auth/logout.command.d.ts +0 -21
  166. package/dist/commands/auth/logout.command.d.ts.map +0 -1
  167. package/dist/commands/auth/logout.command.js +0 -97
  168. package/dist/commands/auth/logout.command.js.map +0 -1
  169. package/dist/commands/auth/methods.command.d.ts +0 -68
  170. package/dist/commands/auth/methods.command.d.ts.map +0 -1
  171. package/dist/commands/auth/methods.command.js +0 -91
  172. package/dist/commands/auth/methods.command.js.map +0 -1
  173. package/dist/commands/auth/status.command.d.ts +0 -18
  174. package/dist/commands/auth/status.command.d.ts.map +0 -1
  175. package/dist/commands/auth/status.command.js +0 -104
  176. package/dist/commands/auth/status.command.js.map +0 -1
  177. package/dist/commands/auth/use.command.d.ts +0 -17
  178. package/dist/commands/auth/use.command.d.ts.map +0 -1
  179. package/dist/commands/auth/use.command.js +0 -47
  180. package/dist/commands/auth/use.command.js.map +0 -1
  181. package/dist/commands/branding.command.d.ts +0 -3
  182. package/dist/commands/branding.command.d.ts.map +0 -1
  183. package/dist/commands/branding.command.js +0 -42
  184. package/dist/commands/branding.command.js.map +0 -1
  185. package/dist/commands/event.command.d.ts +0 -3
  186. package/dist/commands/event.command.d.ts.map +0 -1
  187. package/dist/commands/event.command.js +0 -27
  188. package/dist/commands/event.command.js.map +0 -1
  189. package/dist/commands/flag-init.command.d.ts +0 -13
  190. package/dist/commands/flag-init.command.d.ts.map +0 -1
  191. package/dist/commands/flag-init.command.js +0 -463
  192. package/dist/commands/flag-init.command.js.map +0 -1
  193. package/dist/commands/guide.command.d.ts +0 -61
  194. package/dist/commands/guide.command.d.ts.map +0 -1
  195. package/dist/commands/guide.command.js +0 -655
  196. package/dist/commands/guide.command.js.map +0 -1
  197. package/dist/commands/info.command.d.ts +0 -3
  198. package/dist/commands/info.command.d.ts.map +0 -1
  199. package/dist/commands/info.command.js +0 -70
  200. package/dist/commands/info.command.js.map +0 -1
  201. package/dist/commands/integration.command.d.ts +0 -35
  202. package/dist/commands/integration.command.d.ts.map +0 -1
  203. package/dist/commands/integration.command.js +0 -290
  204. package/dist/commands/integration.command.js.map +0 -1
  205. package/dist/commands/journeys.d.ts +0 -43
  206. package/dist/commands/journeys.d.ts.map +0 -1
  207. package/dist/commands/journeys.js +0 -221
  208. package/dist/commands/journeys.js.map +0 -1
  209. package/dist/commands/ops.command.d.ts +0 -17
  210. package/dist/commands/ops.command.d.ts.map +0 -1
  211. package/dist/commands/ops.command.js +0 -129
  212. package/dist/commands/ops.command.js.map +0 -1
  213. package/dist/commands/privilege.command.d.ts +0 -16
  214. package/dist/commands/privilege.command.d.ts.map +0 -1
  215. package/dist/commands/privilege.command.js +0 -86
  216. package/dist/commands/privilege.command.js.map +0 -1
  217. package/dist/commands/role.command.d.ts +0 -3
  218. package/dist/commands/role.command.d.ts.map +0 -1
  219. package/dist/commands/role.command.js +0 -101
  220. package/dist/commands/role.command.js.map +0 -1
  221. package/dist/commands/runtime-dir.d.ts +0 -16
  222. package/dist/commands/runtime-dir.d.ts.map +0 -1
  223. package/dist/commands/runtime-dir.js +0 -18
  224. package/dist/commands/runtime-dir.js.map +0 -1
  225. package/dist/commands/setup.command.d.ts +0 -63
  226. package/dist/commands/setup.command.d.ts.map +0 -1
  227. package/dist/commands/setup.command.js +0 -148
  228. package/dist/commands/setup.command.js.map +0 -1
  229. package/dist/commands/stripe.command.d.ts +0 -29
  230. package/dist/commands/stripe.command.d.ts.map +0 -1
  231. package/dist/commands/stripe.command.js +0 -99
  232. package/dist/commands/stripe.command.js.map +0 -1
  233. package/dist/commands/tenant.command.d.ts +0 -3
  234. package/dist/commands/tenant.command.d.ts.map +0 -1
  235. package/dist/commands/tenant.command.js +0 -135
  236. package/dist/commands/tenant.command.js.map +0 -1
  237. package/dist/commands/token.command.d.ts +0 -3
  238. package/dist/commands/token.command.d.ts.map +0 -1
  239. package/dist/commands/token.command.js +0 -54
  240. package/dist/commands/token.command.js.map +0 -1
  241. package/dist/commands/user.command.d.ts +0 -3
  242. package/dist/commands/user.command.d.ts.map +0 -1
  243. package/dist/commands/user.command.js +0 -117
  244. package/dist/commands/user.command.js.map +0 -1
  245. package/dist/credentials.d.ts +0 -141
  246. package/dist/credentials.d.ts.map +0 -1
  247. package/dist/credentials.js +0 -348
  248. package/dist/credentials.js.map +0 -1
  249. package/dist/flag-coherence.d.ts +0 -42
  250. package/dist/flag-coherence.d.ts.map +0 -1
  251. package/dist/flag-coherence.js +0 -103
  252. package/dist/flag-coherence.js.map +0 -1
  253. package/dist/output.d.ts +0 -17
  254. package/dist/output.d.ts.map +0 -1
  255. package/dist/output.js +0 -107
  256. package/dist/output.js.map +0 -1
  257. package/dist/preview.d.ts +0 -9
  258. package/dist/preview.d.ts.map +0 -1
  259. package/dist/preview.js +0 -63
  260. package/dist/preview.js.map +0 -1
  261. package/dist/product-decisions.d.ts +0 -40
  262. package/dist/product-decisions.d.ts.map +0 -1
  263. package/dist/product-decisions.js +0 -52
  264. package/dist/product-decisions.js.map +0 -1
  265. package/dist/prompt-urls.d.ts +0 -31
  266. package/dist/prompt-urls.d.ts.map +0 -1
  267. package/dist/prompt-urls.js +0 -35
  268. package/dist/prompt-urls.js.map +0 -1
  269. package/dist/prompts/auth-master-integration-prompt.md +0 -255
  270. package/dist/prompts/billing/master.md +0 -332
  271. package/dist/prompts/decisions/feature-control.md +0 -131
  272. package/dist/prompts/decisions/going-live.md +0 -60
  273. package/dist/prompts/decisions/login.md +0 -71
  274. package/dist/prompts/decisions/look-and-feel.md +0 -68
  275. package/dist/prompts/decisions/payments.md +0 -97
  276. package/dist/prompts/decisions/roles.md +0 -78
  277. package/dist/prompts/decisions/teams.md +0 -61
  278. package/dist/prompts/fit-together.md +0 -97
  279. package/dist/prompts/flags/master.md +0 -220
  280. package/dist/prompts/guide-coverage.json +0 -17
  281. package/dist/prompts/integration-success.md +0 -106
  282. package/dist/prompts/mcp-tools.json +0 -90
  283. package/dist/prompts/mechanisms.md +0 -304
  284. package/dist/prompts/orientation.md +0 -42
  285. package/dist/prompts/product-decisions.json +0 -338
  286. package/dist/resolve.d.ts +0 -110
  287. package/dist/resolve.d.ts.map +0 -1
  288. package/dist/resolve.js +0 -260
  289. package/dist/resolve.js.map +0 -1
  290. package/dist/shape.d.ts +0 -25
  291. package/dist/shape.d.ts.map +0 -1
  292. package/dist/shape.js +0 -74
  293. package/dist/shape.js.map +0 -1
@@ -0,0 +1,166 @@
1
+ import { appInvites, invites, members, privileges, roles, workspaces } from '../api/accounts.js';
2
+ import { withAppKey } from '../api/keys.js';
3
+ import { CliError, isCliError } from '../core/errors.js';
4
+ import { action, collect } from './context.js';
5
+ /**
6
+ * Roles, privileges, workspaces and members: version 2 offers these routes
7
+ * to the app's own server only, so each command runs with an app key:
8
+ * `BRIDGE_APP_KEY`, or a one-day key the CLI makes and revokes at once.
9
+ */
10
+ async function asApp(ctx, needs, fn) {
11
+ const { c, appId } = await ctx.forApp();
12
+ return withAppKey(c, appId, needs, ctx.env, (key) => fn(c, key), { warn: (message) => ctx.io.info(message) });
13
+ }
14
+ const KEY_NOTE = ' Runs with BRIDGE_APP_KEY, or a short-lived key the CLI makes (needs a recent sign-in).';
15
+ /**
16
+ * An invite Bridge would not send because the app has no email-links
17
+ * address: say where to add one. For the developer's own workspace there is
18
+ * nothing to add here, and Bridge's message stands.
19
+ */
20
+ function withEmailLinksHint(error, appWorkspace) {
21
+ if (appWorkspace && isCliError(error) && error.kind === 'conflict' && /email-links/i.test(error.message)) {
22
+ throw new CliError('conflict', error.message, {
23
+ status: error.status,
24
+ details: error.details,
25
+ hint: "Add the page that opens your app's email links: `bridge app address add <url> --use email-links`.",
26
+ });
27
+ }
28
+ throw error;
29
+ }
30
+ function roleFields(opts) {
31
+ return {
32
+ ...(opts.name === undefined ? {} : { name: opts.name }),
33
+ ...(opts.description === undefined ? {} : { description: opts.description }),
34
+ ...(opts.privilege === undefined ? {} : { privileges: opts.privilege }),
35
+ ...(opts.default === undefined ? {} : { isDefault: opts.default }),
36
+ };
37
+ }
38
+ export function registerAccountCommands(program, deps) {
39
+ const role = program.command('role').description(`The app's roles and the privileges each holds.${KEY_NOTE}`);
40
+ role.command('list').action(action(deps, async (ctx) => {
41
+ ctx.io.result(await asApp(ctx, [], (c, key) => roles.list(c, key)));
42
+ }));
43
+ role
44
+ .command('create <key>')
45
+ .requiredOption('--name <name>', 'The role\'s name')
46
+ .option('--description <text>', 'What the role is for')
47
+ .option('--privilege <privilege>', 'A privilege it holds; repeat for several', collect)
48
+ .option('--default', 'New members get this role')
49
+ .action(action(deps, async (ctx, key, opts) => {
50
+ ctx.io.result(await asApp(ctx, [], (c, appKey) => roles.create(c, appKey, { ...roleFields(opts), key, name: opts.name })));
51
+ }));
52
+ role
53
+ .command('update <role>')
54
+ .description('Change a role, by its key or id. --privilege replaces the role\'s privileges')
55
+ .option('--name <name>', 'The role\'s name')
56
+ .option('--description <text>', 'What the role is for')
57
+ .option('--privilege <privilege>', 'A privilege it holds; repeat for several', collect)
58
+ .option('--default', 'New members get this role')
59
+ .action(action(deps, async (ctx, which, opts) => {
60
+ const fields = roleFields(opts);
61
+ if (Object.keys(fields).length === 0)
62
+ throw new CliError('invalid', 'Nothing to change.');
63
+ ctx.io.result(await asApp(ctx, [], (c, key) => roles.update(c, key, which, fields)));
64
+ }));
65
+ role.command('delete <role>').action(action(deps, async (ctx, which) => {
66
+ ctx.io.result(await asApp(ctx, ['ROLE_DELETE'], (c, key) => roles.remove(c, key, which)));
67
+ }));
68
+ const privilege = program.command('privilege').description(`The app's privileges, which roles hold.${KEY_NOTE}`);
69
+ privilege.command('list').action(action(deps, async (ctx) => {
70
+ ctx.io.result(await asApp(ctx, [], (c, key) => privileges.list(c, key)));
71
+ }));
72
+ privilege
73
+ .command('create <key>')
74
+ .option('--description <text>', 'What it allows')
75
+ .action(action(deps, async (ctx, key, opts) => {
76
+ ctx.io.result(await asApp(ctx, [], (c, appKey) => privileges.create(c, appKey, { key, ...(opts.description === undefined ? {} : { description: opts.description }) })));
77
+ }));
78
+ privilege
79
+ .command('update <privilege>')
80
+ .option('--new-key <key>', 'Rename it')
81
+ .option('--description <text>', 'What it allows')
82
+ .action(action(deps, async (ctx, which, opts) => {
83
+ const fields = { ...(opts.newKey === undefined ? {} : { key: opts.newKey }), ...(opts.description === undefined ? {} : { description: opts.description }) };
84
+ if (Object.keys(fields).length === 0)
85
+ throw new CliError('invalid', 'Nothing to change.');
86
+ ctx.io.result(await asApp(ctx, [], (c, key) => privileges.update(c, key, which, fields)));
87
+ }));
88
+ privilege.command('delete <privilege>').action(action(deps, async (ctx, which) => {
89
+ ctx.io.result(await asApp(ctx, ['ROLE_DELETE'], (c, key) => privileges.remove(c, key, which)));
90
+ }));
91
+ const workspace = program.command('workspace').description(`The app's workspaces (its customers' teams).${KEY_NOTE}`);
92
+ workspace
93
+ .command('list')
94
+ .option('--search <text>', 'Only workspaces whose name has this')
95
+ .option('--limit <n>', 'At most this many')
96
+ .option('--after <cursor>', 'The page after this cursor')
97
+ .action(action(deps, async (ctx, opts) => {
98
+ ctx.io.result(await asApp(ctx, [], (c, key) => workspaces.list(c, key, opts)));
99
+ }));
100
+ const member = program.command('member').description(`The members of one of the app's workspaces.${KEY_NOTE}`);
101
+ const withWorkspace = (cmd) => cmd.requiredOption('--workspace <id>', 'The workspace (`bridge workspace list` shows them)');
102
+ withWorkspace(member.command('list'))
103
+ .option('--search <text>', 'Only members whose name or email has this')
104
+ .option('--limit <n>', 'At most this many')
105
+ .option('--after <cursor>', 'The page after this cursor')
106
+ .action(action(deps, async (ctx, opts) => {
107
+ const { workspace: ws, ...query } = opts;
108
+ ctx.io.result(await asApp(ctx, ['USER_READ'], (c, key) => members.list(c, key, ws, query)));
109
+ }));
110
+ withWorkspace(member.command('get <member>')).action(action(deps, async (ctx, id, opts) => {
111
+ ctx.io.result(await asApp(ctx, ['USER_READ'], (c, key) => members.get(c, key, opts.workspace, id)));
112
+ }));
113
+ withWorkspace(member.command('update <member>'))
114
+ .option('--role <role>', 'Give the member this role')
115
+ .option('--disable', 'Stop the member from signing in to this workspace')
116
+ .option('--enable', 'Let the member sign in again')
117
+ .action(action(deps, async (ctx, id, opts) => {
118
+ if (opts.disable && opts.enable)
119
+ throw new CliError('invalid', '--disable or --enable, not both.');
120
+ const fields = { ...(opts.role === undefined ? {} : { role: opts.role }), ...(opts.disable ? { enabled: false } : opts.enable ? { enabled: true } : {}) };
121
+ if (Object.keys(fields).length === 0)
122
+ throw new CliError('invalid', 'Nothing to change: give --role, --disable or --enable.');
123
+ ctx.io.result(await asApp(ctx, ['USER_WRITE'], (c, key) => members.update(c, key, opts.workspace, id, fields)));
124
+ }));
125
+ withWorkspace(member.command('remove <member>'))
126
+ .requiredOption('--yes', 'Confirm')
127
+ .action(action(deps, async (ctx, id, opts) => {
128
+ ctx.io.result(await asApp(ctx, ['USER_WRITE'], (c, key) => members.remove(c, key, opts.workspace, id)));
129
+ }));
130
+ const invite = program
131
+ .command('invite')
132
+ .description("Invites by email. Without --workspace, into your own workspace on Bridge (the one you signed in to), with your sign-in. " +
133
+ "With --workspace, into one of the app's workspaces, with BRIDGE_APP_KEY or a short-lived key the CLI makes (needs a recent sign-in).");
134
+ const inWorkspace = (cmd) => cmd.option('--workspace <id>', "One of the app's workspaces (`bridge workspace list` shows them); leave out for your own");
135
+ inWorkspace(invite.command('list').description('The open invites')).action(action(deps, async (ctx, opts) => {
136
+ const ws = opts.workspace;
137
+ if (ws === undefined)
138
+ ctx.io.result(await invites.list(await ctx.client()));
139
+ else
140
+ ctx.io.result(await asApp(ctx, ['USER_READ'], (c, key) => appInvites.list(c, key, ws)));
141
+ }));
142
+ inWorkspace(invite
143
+ .command('send <email>')
144
+ .description('Email an invite. Sending again to the same address sends a new link, and the old one stops working. An invite lasts 30 days')
145
+ .option('--role <role>', "The role they join with; left out, the workspace's default")).action(action(deps, async (ctx, email, opts) => {
146
+ const fields = { email, ...(opts.role === undefined ? {} : { role: opts.role }) };
147
+ const ws = opts.workspace;
148
+ try {
149
+ if (ws === undefined)
150
+ ctx.io.result(await invites.send(await ctx.client(), fields));
151
+ else
152
+ ctx.io.result(await asApp(ctx, ['USER_WRITE'], (c, key) => appInvites.send(c, key, ws, fields)));
153
+ }
154
+ catch (error) {
155
+ withEmailLinksHint(error, ws !== undefined);
156
+ }
157
+ }));
158
+ inWorkspace(invite.command('revoke <invite>').description('Revoke an invite by its id: its link stops working')).action(action(deps, async (ctx, id, opts) => {
159
+ const ws = opts.workspace;
160
+ if (ws === undefined)
161
+ ctx.io.result(await invites.revoke(await ctx.client(), id));
162
+ else
163
+ ctx.io.result(await asApp(ctx, ['USER_WRITE'], (c, key) => appInvites.revoke(c, key, ws, id)));
164
+ }));
165
+ }
166
+ //# sourceMappingURL=accounts.command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.command.js","sourceRoot":"","sources":["../../src/commands/accounts.command.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
- import { Command } from 'commander';
2
- export declare function registerAppCommands(program: Command): void;
1
+ import type { Command } from 'commander';
2
+ import { type Deps } from './context.js';
3
+ export declare function registerAppCommands(program: Command, deps: Deps): void;
3
4
  //# sourceMappingURL=app.command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.command.d.ts","sourceRoot":"","sources":["../../src/commands/app.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmH1D"}
1
+ {"version":3,"file":"app.command.d.ts","sourceRoot":"","sources":["../../src/commands/app.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EAAmB,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AA6B1D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAoJtE"}
@@ -1,239 +1,138 @@
1
- import { ConfigError, getManagementClient, resolveSelectedCredential, resetManagementClient } from '../config.js';
2
- import { outputSuccess, outputError } from '../output.js';
3
- import { updateCredential } from '../credentials.js';
4
- import { createWorkspaceClient, resolveAppSelector, } from '../auth/workspace-client.js';
5
- export function registerAppCommands(program) {
6
- const app = program.command('app').description('Manage app configuration');
7
- // TBP-769 — one login, every app of the workspace (MCP parity).
8
- app.command('list')
9
- .description('List the apps your login covers, marking the home app and the current one')
10
- .action(async () => {
11
- try {
12
- outputSuccess(await runAppList());
13
- }
14
- catch (err) {
15
- outputError(err);
16
- }
17
- });
18
- app.command('use <id|name>')
19
- .description('Make another app of your workspace login the default for every command (local, no re-login)')
20
- .action(async (selector) => {
21
- try {
22
- outputSuccess(await runAppUse(selector));
23
- }
24
- catch (err) {
25
- outputError(err);
26
- }
27
- });
28
- app.command('create')
29
- .description('Create a new app in your workspace')
30
- .requiredOption('--name <name>', 'App name')
31
- .option('--callback-url <url>', 'OAuth callback URL to register on the new app')
32
- .option('--use', 'Also make the new app the current one (like `bridge app use`)')
33
- .action(async (opts) => {
34
- try {
35
- outputSuccess(await runAppCreate(opts));
36
- }
37
- catch (err) {
38
- outputError(err);
39
- }
40
- });
41
- app.command('get')
42
- .description('Get current app configuration')
43
- .action(async () => {
44
- try {
45
- outputSuccess(await getManagementClient().app.get());
46
- }
47
- catch (err) {
48
- outputError(err);
49
- }
50
- });
51
- app.command('update')
52
- .description('Update app settings')
53
- .option('--name <name>', 'App name')
54
- .option('--api-url <url>', 'API URL')
55
- .option('--ui-url <url>', "Your app's base URL. Links in Bridge emails (invites, password resets, payment notices) open here when your backend calls the API without an Origin header. Must also be listed in --allowed-origins")
56
- .option('--webhook-url <url>', 'Webhook URL')
57
- .option('--tenant-self-signup <bool>', 'Allow tenant self-signup', parseBool)
58
- .option('--mfa-enabled <bool>', 'Enable MFA', parseBool)
59
- .option('--passkeys-enabled <bool>', 'Enable passkeys', parseBool)
60
- .option('--magic-link-enabled <bool>', 'Enable magic links', parseBool)
61
- .option('--payments-auto-redirect <bool>', 'Force new users to pick a plan before entering the app (billing paywall)', parseBool)
62
- .option('--redirect-uris <uris>', 'Comma-separated list of allowed OAuth callback URIs', parseList)
63
- .option('--allowed-origins <origins>', 'Comma-separated list of allowed CORS origins', parseList)
64
- .option('--default-callback-uri <uri>', 'Default OAuth callback URI')
65
- .action(async (opts) => {
66
- try {
67
- const data = stripUndefined({
68
- name: opts.name,
69
- apiUrl: opts.apiUrl,
70
- uiUrl: opts.uiUrl,
71
- webhookUrl: opts.webhookUrl,
72
- tenantSelfSignup: opts.tenantSelfSignup,
73
- mfaEnabled: opts.mfaEnabled,
74
- passkeysEnabled: opts.passkeysEnabled,
75
- magicLinkEnabled: opts.magicLinkEnabled,
76
- paymentsAutoRedirect: opts.paymentsAutoRedirect,
77
- redirectUris: opts.redirectUris,
78
- allowedOrigins: opts.allowedOrigins,
79
- defaultCallbackUri: opts.defaultCallbackUri,
80
- });
81
- outputSuccess(await getManagementClient().app.update(data));
82
- }
83
- catch (err) {
84
- outputError(err);
85
- }
86
- });
87
- const redirectUris = app
88
- .command('redirect-uris')
89
- .description('Manage allowed OAuth callback URIs without replacing the whole list');
90
- redirectUris.command('list')
91
- .description('List registered redirect URIs')
92
- .action(async () => {
93
- try {
94
- const current = await getManagementClient().app.get();
95
- outputSuccess({ redirectUris: current.redirectUris ?? [] });
96
- }
97
- catch (err) {
98
- outputError(err);
99
- }
100
- });
101
- redirectUris.command('add <url>')
102
- .description('Register a redirect URI (existing entries are kept)')
103
- .action(async (url) => {
104
- try {
105
- validateRedirectUri(url);
106
- const client = getManagementClient();
107
- const current = (await client.app.get()).redirectUris ?? [];
108
- if (current.includes(url)) {
109
- outputSuccess({ added: false, message: `Already registered: ${url}`, redirectUris: current });
110
- return;
111
- }
112
- const next = [...current, url];
113
- await client.app.update({ redirectUris: next });
114
- outputSuccess({ added: true, redirectUris: next });
115
- }
116
- catch (err) {
117
- outputError(err);
118
- }
119
- });
120
- redirectUris.command('remove <url>')
121
- .description('Remove a registered redirect URI')
122
- .action(async (url) => {
123
- try {
124
- const client = getManagementClient();
125
- const current = (await client.app.get()).redirectUris ?? [];
126
- if (!current.includes(url)) {
127
- throw new Error(`Redirect URI not registered: ${url}. Registered URIs: ${current.length ? current.join(', ') : '(none)'}`);
128
- }
129
- const next = current.filter((u) => u !== url);
130
- await client.app.update({ redirectUris: next });
131
- outputSuccess({ removed: true, redirectUris: next });
132
- }
133
- catch (err) {
134
- outputError(err);
135
- }
136
- });
137
- }
138
- /** The stored login these commands work with; BRIDGE_API_KEY cannot list apps. */
139
- function loginContext() {
140
- const selected = resolveSelectedCredential();
141
- if (!selected.creds || !selected.key) {
142
- throw Object.assign(new ConfigError('App selection needs a login from `bridge auth login`; BRIDGE_API_KEY is bound to one app.'), { hint: 'Run `bridge auth login` (it covers every app of the workspace by default).' });
1
+ import { ADDRESS_USES, apps, checkUses } from '../api/apps.js';
2
+ import { CliError } from '../core/errors.js';
3
+ import { action, collect } from './context.js';
4
+ /** The profile fields given; "none" clears one. */
5
+ function profile(opts) {
6
+ const fields = {};
7
+ for (const name of ['logo', 'website', 'privacyPolicy', 'termsOfService']) {
8
+ const value = opts[name];
9
+ if (value !== undefined)
10
+ fields[name] = value === 'none' ? null : value;
143
11
  }
144
- return { key: selected.key, creds: selected.creds, baseUrl: selected.baseUrl };
12
+ return { ...(opts.name === undefined ? {} : { name: opts.name }), ...fields };
145
13
  }
146
- function workspaceClient(ctx) {
147
- return createWorkspaceClient({ baseUrl: ctx.baseUrl, loginToken: ctx.creds.apiKey });
148
- }
149
- /** Current = the locally chosen app of this login, else its home app. */
150
- function currentAppId(creds) {
151
- return creds.appAccess === 'workspace' && creds.currentApp ? creds.currentApp.id : creds.app.id;
152
- }
153
- /** Learn the login's scope from the server (credentials from before TBP-769 lack it). */
154
- function rememberScope(key, creds, scope) {
155
- const appAccess = scope === 'workspace' ? 'workspace' : 'app';
156
- return creds.appAccess === appAccess ? creds : updateCredential(key, { appAccess });
157
- }
158
- async function runAppList() {
159
- const ctx = loginContext();
160
- const res = await workspaceClient(ctx).listApps();
161
- const creds = rememberScope(ctx.key, ctx.creds, res.scope);
162
- const current = currentAppId(creds);
163
- return {
164
- scope: res.scope,
165
- homeAppId: res.homeAppId,
166
- currentAppId: current,
167
- apps: res.apps.map((a) => ({ id: a.id, name: a.name, home: a.home, current: a.id === current })),
168
- };
169
- }
170
- async function runAppUse(selector) {
171
- const ctx = loginContext();
172
- const home = ctx.creds.app;
173
- const lower = selector.trim().toLowerCase();
174
- let target;
175
- if (selector.trim() === home.id || lower === home.name.toLowerCase()) {
176
- target = home;
177
- }
178
- else {
179
- const res = await workspaceClient(ctx).listApps();
180
- rememberScope(ctx.key, ctx.creds, res.scope);
181
- if (res.scope !== 'workspace') {
182
- throw Object.assign(new ConfigError(`This login covers only the app ${home.name} (${home.id}), so it cannot switch to "${selector}".`), {
183
- code: 'APP_NOT_IN_CONNECTION',
184
- hint: 'Run `bridge auth login` again and choose "Every app in <workspace>" on the consent ' +
185
- 'screen; one login then covers every app and `bridge app use` switches between them.',
14
+ const withProfileOptions = (cmd) => cmd
15
+ .option('--logo <url>', 'Logo address ("none" clears it)')
16
+ .option('--website <url>', 'Website ("none" clears it)')
17
+ .option('--privacy-policy <url>', 'Privacy policy ("none" clears it)')
18
+ .option('--terms-of-service <url>', 'Terms of service ("none" clears it)');
19
+ const USES = `one of ${ADDRESS_USES.join(', ')}; repeat for several`;
20
+ export function registerAppCommands(program, deps) {
21
+ const app = program.command('app').description('Your apps: create them, choose the one commands act on, set their addresses');
22
+ app
23
+ .command('list')
24
+ .description('The apps of your workspace')
25
+ .action(action(deps, async (ctx) => {
26
+ const c = await ctx.client();
27
+ const current = (await ctx.settings()).apps?.[await ctx.issuer()];
28
+ ctx.io.result((await apps.list(c)).map((each) => ({ ...each, current: each.id === current })));
29
+ }));
30
+ withProfileOptions(app
31
+ .command('create')
32
+ .description('Create an app, and choose it for the commands that follow')
33
+ .requiredOption('--name <name>', 'The app\'s name')
34
+ .option('--sign-in-return <url>', 'An address sign-in may return to; repeat for several', collect)
35
+ .option('--email-links <url>', 'The page email links (sign-up, password reset, invites) open', collect)
36
+ .option('--browser-origin <origin>', 'An origin whose pages may call Bridge from the browser; repeat for several', collect)
37
+ .option('--no-use', 'Create it without choosing it')).action(action(deps, async (ctx, opts) => {
38
+ const c = await ctx.client();
39
+ const byUrl = new Map();
40
+ const add = (urls, use) => urls?.forEach((url) => byUrl.set(url, (byUrl.get(url) ?? new Set()).add(use)));
41
+ add(opts.signInReturn, 'sign-in-return');
42
+ add(opts.emailLinks, 'email-links');
43
+ add(opts.browserOrigin, 'browser-origin');
44
+ const addresses = [...byUrl].map(([url, uses]) => ({ url, uses: checkUses([...uses]) }));
45
+ const made = await apps.create(c, {
46
+ ...profile(opts),
47
+ name: opts.name,
48
+ ...(addresses.length === 0 ? {} : { addresses }),
49
+ ...(opts.signInReturn?.[0] === undefined ? {} : { defaultReturn: opts.signInReturn[0] }),
50
+ });
51
+ if (opts.use !== false) {
52
+ const issuer = await ctx.issuer();
53
+ await ctx.config.update((settings) => {
54
+ settings.apps = { ...settings.apps, [issuer]: made.id };
186
55
  });
187
- }
188
- target = resolveAppSelector(selector, res.apps);
189
- }
190
- const isHome = target.id === home.id;
191
- updateCredential(ctx.key, { currentApp: isHome ? undefined : { id: target.id, name: target.name } });
192
- resetManagementClient();
193
- return {
194
- currentApp: { id: target.id, name: target.name, home: isHome },
195
- message: isHome
196
- ? `Now using the home app ${target.name} (${target.id}).`
197
- : `Now using ${target.name} (${target.id}). Commands act on it until \`bridge app use\` again; \`--app\` overrides it for one command.`,
198
- };
199
- }
200
- async function runAppCreate(opts) {
201
- const ctx = loginContext();
202
- const res = await workspaceClient(ctx).createApp({
203
- name: opts.name,
204
- ...(opts.callbackUrl ? { callbackUrl: opts.callbackUrl } : {}),
205
- });
206
- let current = false;
207
- if (opts.use) {
208
- // A create that succeeded proves the login spans the workspace.
209
- updateCredential(ctx.key, {
210
- appAccess: 'workspace',
211
- currentApp: res.app.id === ctx.creds.app.id ? undefined : { id: res.app.id, name: res.app.name },
56
+ ctx.io.info(`Created ${made.name} (${made.id}); commands now act on it.`);
57
+ }
58
+ ctx.io.result(made);
59
+ }));
60
+ app
61
+ .command('use <id>')
62
+ .description('Choose the app the commands act on')
63
+ .action(action(deps, async (ctx, id) => {
64
+ const c = await ctx.client();
65
+ const found = await apps.get(c, id);
66
+ const issuer = await ctx.issuer();
67
+ await ctx.config.update((settings) => {
68
+ settings.apps = { ...settings.apps, [issuer]: found.id };
212
69
  });
213
- resetManagementClient();
214
- current = true;
215
- }
216
- return { app: res.app, current };
217
- }
218
- function validateRedirectUri(value) {
219
- let parsed;
220
- try {
221
- parsed = new URL(value);
222
- }
223
- catch {
224
- throw new Error(`Invalid redirect URI: "${value}" is not an absolute URL (expected e.g. https://app.example.com/auth/oauth-callback).`);
225
- }
226
- if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
227
- throw new Error(`Invalid redirect URI: "${value}" must use http or https.`);
228
- }
229
- }
230
- function parseBool(val) {
231
- return val === 'true';
232
- }
233
- function parseList(val) {
234
- return val.split(',').map((s) => s.trim()).filter(Boolean);
235
- }
236
- function stripUndefined(obj) {
237
- return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined));
70
+ ctx.io.info(`Commands now act on ${found.name} (${found.id}).`);
71
+ ctx.io.result({ id: found.id, name: found.name });
72
+ }));
73
+ app
74
+ .command('get')
75
+ .description('The app: its addresses, profile and how its tokens are checked')
76
+ .action(action(deps, async (ctx) => {
77
+ const { c, appId } = await ctx.forApp();
78
+ ctx.io.result(await apps.get(c, appId));
79
+ }));
80
+ withProfileOptions(app.command('update').description('Rename the app or change its public profile').option('--name <name>', 'The app\'s name')).action(action(deps, async (ctx, opts) => {
81
+ const fields = profile(opts);
82
+ if (Object.keys(fields).length === 0)
83
+ throw new CliError('invalid', 'Nothing to change: give --name, --logo, --website, --privacy-policy or --terms-of-service.');
84
+ const { c, appId } = await ctx.forApp();
85
+ ctx.io.result(await apps.update(c, appId, fields));
86
+ }));
87
+ app
88
+ .command('delete')
89
+ .description('Delete the app. Its keys, plans and flags go with it')
90
+ .requiredOption('--yes', 'Confirm the deletion')
91
+ .action(action(deps, async (ctx) => {
92
+ const { c, appId } = await ctx.forApp();
93
+ const issuer = await ctx.issuer();
94
+ const answer = await apps.remove(c, appId);
95
+ await ctx.config.update((settings) => {
96
+ if (settings.apps?.[issuer] === appId)
97
+ delete settings.apps[issuer];
98
+ });
99
+ ctx.io.result(answer ?? { deleted: appId });
100
+ }));
101
+ app
102
+ .command('default-return <url>')
103
+ .description('The sign-in return used when a sign-in names none ("none" clears it). It must be one of the app\'s sign-in returns')
104
+ .action(action(deps, async (ctx, url) => {
105
+ const { c, appId } = await ctx.forApp();
106
+ ctx.io.result(await apps.update(c, appId, { defaultReturn: url === 'none' ? null : url }));
107
+ }));
108
+ const address = app.command('address').description('The app\'s addresses: sign-in returns, email links, browser origins, sign-out and checkout returns');
109
+ address
110
+ .command('list')
111
+ .description('Every address of the app and what it is used for')
112
+ .action(action(deps, async (ctx) => {
113
+ const { c, appId } = await ctx.forApp();
114
+ const found = await apps.get(c, appId);
115
+ ctx.io.result({ addresses: found.addresses ?? [], defaultReturn: found.defaultReturn });
116
+ }));
117
+ address
118
+ .command('add <url>')
119
+ .description('Add an address, or add uses to one the app has')
120
+ .requiredOption('--use <use>', USES, collect)
121
+ .action(action(deps, async (ctx, url, opts) => {
122
+ const uses = checkUses(opts.use);
123
+ const { c, appId } = await ctx.forApp();
124
+ const changed = await apps.addAddress(c, appId, url, uses);
125
+ ctx.io.result({ addresses: changed.addresses, defaultReturn: changed.defaultReturn });
126
+ }));
127
+ address
128
+ .command('remove <url>')
129
+ .description('Remove an address, or only some of its uses')
130
+ .option('--use <use>', `Only this use (${USES})`, collect)
131
+ .action(action(deps, async (ctx, url, opts) => {
132
+ const uses = opts.use === undefined ? [] : checkUses(opts.use);
133
+ const { c, appId } = await ctx.forApp();
134
+ const changed = await apps.removeAddress(c, appId, url, uses);
135
+ ctx.io.result({ addresses: changed.addresses, defaultReturn: changed.defaultReturn });
136
+ }));
238
137
  }
239
138
  //# sourceMappingURL=app.command.js.map