@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,33 @@
1
+ export class CliError extends Error {
2
+ kind;
3
+ status;
4
+ hint;
5
+ details;
6
+ constructor(kind, message, options = {}) {
7
+ super(message);
8
+ this.name = 'CliError';
9
+ this.kind = kind;
10
+ this.status = options.status;
11
+ this.hint = options.hint;
12
+ this.details = options.details;
13
+ }
14
+ }
15
+ export function isCliError(value) {
16
+ return value instanceof CliError;
17
+ }
18
+ /**
19
+ * Exit codes: 1 for a refused or failed command, 2 when Bridge could not be
20
+ * reached or could not answer, 3 when the CLI is not set up (no issuer, not
21
+ * signed in, a setting that is wrong).
22
+ */
23
+ export function exitCodeOf(error) {
24
+ if (!isCliError(error))
25
+ return 1;
26
+ if (error.kind === 'unavailable' || error.kind === 'network')
27
+ return 2;
28
+ if (error.kind === 'misconfigured' || error.kind === 'not-signed-in' || error.kind === 'session-ended')
29
+ return 3;
30
+ return 1;
31
+ }
32
+ export const SIGN_IN_AGAIN = 'Sign in again with `bridge auth login` (or `bridge auth login --password`).';
33
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AA6BA,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAe;IACnB,MAAM,CAAqB;IAC3B,IAAI,CAAqB;IACzB,OAAO,CAAU;IAE1B,YAAY,IAAkB,EAAE,OAAe,EAAE,UAA2B,EAAE;QAC5E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACjC,CAAC;CACF;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,KAAK,YAAY,QAAQ,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IACvE,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe;QAAE,OAAO,CAAC,CAAC;IACjH,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,6EAA6E,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { CliError } from './errors.js';
2
+ export type Fetch = (input: string, init?: RequestInit) => Promise<Response>;
3
+ export interface HttpRequest {
4
+ readonly method: string;
5
+ readonly url: string;
6
+ readonly headers?: Readonly<Record<string, string>>;
7
+ /** Sent as JSON. */
8
+ readonly body?: unknown;
9
+ }
10
+ export interface HttpResponse<T = unknown> {
11
+ readonly status: number;
12
+ readonly headers: Headers;
13
+ readonly body: T;
14
+ }
15
+ /**
16
+ * One call to Bridge: JSON in, JSON out. A redirect is never followed, so a
17
+ * token is never sent anywhere but the address the issuer listed. Anything
18
+ * but a 2xx becomes a {@link CliError}.
19
+ */
20
+ export declare function call<T = unknown>(fetchFn: Fetch, request: HttpRequest): Promise<HttpResponse<T>>;
21
+ /** What Bridge said, read from any of the shapes its answers take, as one error. */
22
+ export declare function errorFrom(status: number, body: unknown, headers?: Headers): CliError;
23
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/core/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAoC,MAAM,aAAa,CAAC;AAEzE,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE7E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,oBAAoB;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;CAClB;AAID;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CA4BtG;AAqED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAkBpF"}
@@ -0,0 +1,153 @@
1
+ import { CliError, SIGN_IN_AGAIN } from './errors.js';
2
+ const TIMEOUT_MS = 30_000;
3
+ /**
4
+ * One call to Bridge: JSON in, JSON out. A redirect is never followed, so a
5
+ * token is never sent anywhere but the address the issuer listed. Anything
6
+ * but a 2xx becomes a {@link CliError}.
7
+ */
8
+ export async function call(fetchFn, request) {
9
+ const headers = { accept: 'application/json', ...request.headers };
10
+ let body;
11
+ if (request.body !== undefined) {
12
+ headers['content-type'] = 'application/json';
13
+ body = JSON.stringify(request.body);
14
+ }
15
+ let response;
16
+ try {
17
+ response = await fetchFn(request.url, {
18
+ method: request.method,
19
+ headers,
20
+ body,
21
+ redirect: 'manual',
22
+ signal: AbortSignal.timeout(TIMEOUT_MS),
23
+ });
24
+ }
25
+ catch (error) {
26
+ const reason = error instanceof Error ? error.message : String(error);
27
+ throw new CliError('network', `Could not reach ${new URL(request.url).host}: ${reason}`);
28
+ }
29
+ const parsed = await readBody(response);
30
+ if (response.status >= 300 && response.status < 400) {
31
+ throw new CliError('misconfigured', `Bridge answered ${request.method} ${pathOf(request.url)} with a redirect, which the CLI never follows.`, {
32
+ status: response.status,
33
+ });
34
+ }
35
+ if (!response.ok)
36
+ throw errorFrom(response.status, parsed, response.headers);
37
+ return { status: response.status, headers: response.headers, body: parsed };
38
+ }
39
+ async function readBody(response) {
40
+ const text = await response.text();
41
+ if (text === '')
42
+ return null;
43
+ const type = response.headers.get('content-type') ?? '';
44
+ if (type.includes('json')) {
45
+ try {
46
+ return JSON.parse(text);
47
+ }
48
+ catch {
49
+ return text;
50
+ }
51
+ }
52
+ return text;
53
+ }
54
+ function pathOf(url) {
55
+ try {
56
+ return new URL(url).pathname;
57
+ }
58
+ catch {
59
+ return url;
60
+ }
61
+ }
62
+ /** The kinds of Bridge's RFC 9457 problems (`urn:bridge:problem:<kind>`), as CLI errors. */
63
+ const PROBLEM_KINDS = {
64
+ 'identity-recheck': 'reauthenticate',
65
+ 'privilege-missing': 'forbidden',
66
+ 'entitlement-missing': 'plan-required',
67
+ 'credential-missing': 'not-signed-in',
68
+ 'credential-refused': 'session-ended',
69
+ 'rate-limited': 'rate-limited',
70
+ unavailable: 'unavailable',
71
+ conflict: 'conflict',
72
+ };
73
+ /** OAuth and sign-in errors (`{ error: "…" }`), as CLI errors. */
74
+ const OAUTH_KINDS = {
75
+ wrong_credentials: 'wrong-credentials',
76
+ invalid_grant: 'session-ended',
77
+ flow_expired: 'flow-expired',
78
+ invalid_link: 'invalid',
79
+ wrong_device: 'invalid',
80
+ invalid_request: 'invalid',
81
+ invalid_client: 'misconfigured',
82
+ unsupported_grant_type: 'misconfigured',
83
+ access_denied: 'forbidden',
84
+ not_found: 'not-found',
85
+ conflict: 'conflict',
86
+ temporarily_unavailable: 'unavailable',
87
+ };
88
+ function kindOfStatus(status) {
89
+ if (status === 401)
90
+ return 'not-signed-in';
91
+ if (status === 402)
92
+ return 'plan-required';
93
+ if (status === 403)
94
+ return 'forbidden';
95
+ if (status === 404)
96
+ return 'not-found';
97
+ if (status === 409 || status === 412 || status === 428)
98
+ return 'conflict';
99
+ if (status === 429)
100
+ return 'rate-limited';
101
+ if (status >= 500)
102
+ return 'unavailable';
103
+ return 'invalid';
104
+ }
105
+ function text(value) {
106
+ if (typeof value === 'string' && value.trim() !== '')
107
+ return value.trim();
108
+ if (Array.isArray(value) && value.every((each) => typeof each === 'string'))
109
+ return value.join(' ');
110
+ return undefined;
111
+ }
112
+ /** What Bridge said, read from any of the shapes its answers take, as one error. */
113
+ export function errorFrom(status, body, headers) {
114
+ const fields = typeof body === 'object' && body !== null && !Array.isArray(body) ? body : {};
115
+ let kind = kindOfStatus(status);
116
+ let message;
117
+ const type = typeof fields['type'] === 'string' ? fields['type'] : '';
118
+ if (type.startsWith('urn:bridge:problem:')) {
119
+ kind = PROBLEM_KINDS[type.slice('urn:bridge:problem:'.length)] ?? kind;
120
+ message = text(fields['detail']) ?? text(fields['title']);
121
+ }
122
+ else if (typeof fields['error'] === 'string' && OAUTH_KINDS[fields['error']] !== undefined) {
123
+ kind = OAUTH_KINDS[fields['error']];
124
+ message = text(fields['error_description']) ?? fields['error'].replace(/_/g, ' ');
125
+ }
126
+ else {
127
+ message = text(fields['message']) ?? text(fields['detail']) ?? text(fields['title']) ?? text(body);
128
+ }
129
+ const hint = hintFor(kind, fields, headers);
130
+ return new CliError(kind, message ?? `Bridge answered ${String(status)}.`, { status, hint, details: body ?? undefined });
131
+ }
132
+ function hintFor(kind, fields, headers) {
133
+ switch (kind) {
134
+ case 'reauthenticate': {
135
+ const maxAge = typeof fields['maxAge'] === 'number' ? ` within ${String(Math.round(fields['maxAge'] / 60))} minutes of signing in` : '';
136
+ return `This needs a recent sign-in. Sign in again with \`bridge auth login\`, then run it again${maxAge}.`;
137
+ }
138
+ case 'not-signed-in':
139
+ case 'session-ended':
140
+ return SIGN_IN_AGAIN;
141
+ case 'rate-limited': {
142
+ const after = headers?.get('retry-after');
143
+ return after ? `Try again in ${after} seconds.` : 'Try again in a moment.';
144
+ }
145
+ case 'unavailable':
146
+ return 'Bridge could not answer right now. Try again in a moment.';
147
+ case 'forbidden':
148
+ return typeof fields['privilege'] === 'string' ? `This needs the privilege ${fields['privilege']}.` : undefined;
149
+ default:
150
+ return undefined;
151
+ }
152
+ }
153
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/core/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function ensurePrivateDir(dir: string): Promise<void>;
2
+ /** The file's text, or null when there is none. A file others could read is tightened to 0600 first. */
3
+ export declare function readPrivateFile(dir: string, name: string): Promise<string | null>;
4
+ export declare function writePrivateFile(dir: string, name: string, content: string): Promise<void>;
5
+ export declare function removePrivateFile(dir: string, name: string): Promise<void>;
6
+ //# sourceMappingURL=private-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-files.d.ts","sourceRoot":"","sources":["../../src/core/private-files.ts"],"names":[],"mappings":"AAsBA,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOjE;AAaD,wGAAwG;AACxG,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBvF;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhG;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF"}
@@ -0,0 +1,96 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { constants } from 'node:fs';
3
+ import { chmod, lstat, mkdir, open, rename, unlink } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import { CliError } from './errors.js';
6
+ /**
7
+ * Files only their owner may read: the session and the settings.
8
+ *
9
+ * - The directory is made 0700, and an existing one must be a real
10
+ * directory (not a symlink) that this user owns; it is tightened to 0700.
11
+ * - A file is written to a temporary file with a random name in the same
12
+ * directory, created with O_EXCL (which never follows a symlink) and mode
13
+ * 0600, then renamed over the file.
14
+ * - A file that is a symlink is refused, for reading and for writing.
15
+ */
16
+ const POSIX = process.platform !== 'win32';
17
+ function refuse(message) {
18
+ return new CliError('misconfigured', message, { hint: 'Point BRIDGE_CONFIG_DIR at a directory only you can write to.' });
19
+ }
20
+ export async function ensurePrivateDir(dir) {
21
+ await mkdir(dir, { recursive: true, mode: 0o700 });
22
+ const info = await lstat(dir);
23
+ if (info.isSymbolicLink() || !info.isDirectory())
24
+ throw refuse(`${dir} is not a directory of its own (it is a symlink or a file).`);
25
+ if (!POSIX)
26
+ return;
27
+ if (typeof process.getuid === 'function' && info.uid !== process.getuid())
28
+ throw refuse(`${dir} belongs to another user.`);
29
+ if ((info.mode & 0o077) !== 0)
30
+ await chmod(dir, 0o700);
31
+ }
32
+ async function notALink(path) {
33
+ try {
34
+ const info = await lstat(path);
35
+ if (info.isSymbolicLink())
36
+ throw refuse(`${path} is a symlink; the CLI does not follow it.`);
37
+ return true;
38
+ }
39
+ catch (error) {
40
+ if (error.code === 'ENOENT')
41
+ return false;
42
+ throw error;
43
+ }
44
+ }
45
+ /** The file's text, or null when there is none. A file others could read is tightened to 0600 first. */
46
+ export async function readPrivateFile(dir, name) {
47
+ const path = join(dir, name);
48
+ if (!(await notALink(path)))
49
+ return null;
50
+ const flags = constants.O_RDONLY | (POSIX ? constants.O_NOFOLLOW : 0);
51
+ let handle;
52
+ try {
53
+ handle = await open(path, flags);
54
+ }
55
+ catch (error) {
56
+ if (error.code === 'ENOENT')
57
+ return null;
58
+ throw error;
59
+ }
60
+ try {
61
+ if (POSIX && ((await handle.stat()).mode & 0o077) !== 0)
62
+ await handle.chmod(0o600);
63
+ return await handle.readFile('utf8');
64
+ }
65
+ finally {
66
+ await handle.close();
67
+ }
68
+ }
69
+ export async function writePrivateFile(dir, name, content) {
70
+ await ensurePrivateDir(dir);
71
+ const path = join(dir, name);
72
+ await notALink(path);
73
+ const temp = join(dir, `.${name}.${randomBytes(8).toString('hex')}.tmp`);
74
+ const handle = await open(temp, 'wx', 0o600);
75
+ try {
76
+ await handle.writeFile(content, 'utf8');
77
+ // The umask may have narrowed or widened the mode; it is 0600 whatever it is.
78
+ if (POSIX)
79
+ await handle.chmod(0o600);
80
+ await handle.sync();
81
+ }
82
+ catch (error) {
83
+ await handle.close();
84
+ await unlink(temp).catch(() => undefined);
85
+ throw error;
86
+ }
87
+ await handle.close();
88
+ await rename(temp, path);
89
+ }
90
+ export async function removePrivateFile(dir, name) {
91
+ await unlink(join(dir, name)).catch((error) => {
92
+ if (error.code !== 'ENOENT')
93
+ throw error;
94
+ });
95
+ }
96
+ //# sourceMappingURL=private-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-files.js","sourceRoot":"","sources":["../../src/core/private-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Every Bridge endpoint the CLI calls, pinned to version 2 of Bridge's API.
3
+ *
4
+ * A route names its microservice and its path under that microservice's
5
+ * base; the base comes from the issuer's metadata (`bridge_endpoints["2"]`),
6
+ * so the CLI is given only the issuer. The contract test checks every route
7
+ * here against a pinned copy of the API's contract, so a route the server
8
+ * does not promise at version 2 fails the build.
9
+ *
10
+ * `auth` says which credential the route takes:
11
+ * - `person`: the signed-in developer's token, from the Bridge App. The
12
+ * `/apps/{appId}/…` routes act on one of the developer's apps.
13
+ * - `app-key`: an app key of the app, in `x-api-key`. Used where version 2
14
+ * has no route for the developer: roles, privileges, members, invites
15
+ * into the app's workspaces, and a pasted Stripe key.
16
+ * - `none`: before sign-in (the issuer's own endpoints).
17
+ */
18
+ export declare const API_VERSION = 2;
19
+ export type Service = 'app-registry' | 'identity-access' | 'billing' | 'flags' | 'accounts';
20
+ export type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
21
+ export type Auth = 'person' | 'app-key' | 'none';
22
+ export interface Route {
23
+ readonly method: Method;
24
+ readonly service: Service;
25
+ readonly path: string;
26
+ readonly auth: Auth;
27
+ /** App-key routes that act in one workspace send it in `Bridge-Workspace`. */
28
+ readonly workspace?: true;
29
+ }
30
+ export declare const ROUTES: {
31
+ readonly signIn: Route;
32
+ readonly token: Route;
33
+ readonly revoke: Route;
34
+ readonly signOut: Route;
35
+ readonly me: Route;
36
+ readonly appsList: Route;
37
+ readonly appsCreate: Route;
38
+ readonly appsGet: Route;
39
+ readonly appsUpdate: Route;
40
+ readonly appsDelete: Route;
41
+ readonly keysList: Route;
42
+ readonly keysCreate: Route;
43
+ readonly keysRevoke: Route;
44
+ readonly plansList: Route;
45
+ readonly plansCreate: Route;
46
+ readonly plansGet: Route;
47
+ readonly plansReplace: Route;
48
+ readonly plansUpdate: Route;
49
+ readonly plansDelete: Route;
50
+ readonly plansArchive: Route;
51
+ readonly plansDeletionPreview: Route;
52
+ readonly productsList: Route;
53
+ readonly productsCreate: Route;
54
+ readonly productsGet: Route;
55
+ readonly productsUpdate: Route;
56
+ readonly productsDelete: Route;
57
+ readonly productsArchive: Route;
58
+ readonly metricsList: Route;
59
+ readonly metricsPut: Route;
60
+ readonly metricsDelete: Route;
61
+ readonly taxesList: Route;
62
+ readonly taxesPut: Route;
63
+ readonly taxesDelete: Route;
64
+ readonly billingSettingsGet: Route;
65
+ readonly billingSettingsUpdate: Route;
66
+ readonly connectionGet: Route;
67
+ readonly connectionDelete: Route;
68
+ readonly connectionPasteKey: Route;
69
+ readonly flagsList: Route;
70
+ readonly flagsCreate: Route;
71
+ readonly flagsGet: Route;
72
+ readonly flagsUpdate: Route;
73
+ readonly flagsDelete: Route;
74
+ readonly flagsKill: Route;
75
+ readonly flagsRestore: Route;
76
+ readonly segmentsList: Route;
77
+ readonly rolesList: Route;
78
+ readonly rolesCreate: Route;
79
+ readonly rolesUpdate: Route;
80
+ readonly rolesDelete: Route;
81
+ readonly privilegesList: Route;
82
+ readonly privilegesCreate: Route;
83
+ readonly privilegesUpdate: Route;
84
+ readonly privilegesDelete: Route;
85
+ readonly workspacesList: Route;
86
+ readonly membersList: Route;
87
+ readonly membersGet: Route;
88
+ readonly membersUpdate: Route;
89
+ readonly membersRemove: Route;
90
+ readonly invitesList: Route;
91
+ readonly invitesSend: Route;
92
+ readonly invitesRevoke: Route;
93
+ readonly appInvitesList: Route;
94
+ readonly appInvitesSend: Route;
95
+ readonly appInvitesRevoke: Route;
96
+ };
97
+ export type RouteName = keyof typeof ROUTES;
98
+ /** The route as the API's contract writes it: `/v2/<microservice><path>`, with `{appId}` for an app. */
99
+ export declare function contractPath(route: Route): string;
100
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/core/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B,MAAM,MAAM,OAAO,GAAG,cAAc,GAAG,iBAAiB,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAC5F,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AACjE,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;CAC3B;AAKD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgFuB,CAAC;AAE3C,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,MAAM,CAAC;AAE5C,wGAAwG;AACxG,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEjD"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Every Bridge endpoint the CLI calls, pinned to version 2 of Bridge's API.
3
+ *
4
+ * A route names its microservice and its path under that microservice's
5
+ * base; the base comes from the issuer's metadata (`bridge_endpoints["2"]`),
6
+ * so the CLI is given only the issuer. The contract test checks every route
7
+ * here against a pinned copy of the API's contract, so a route the server
8
+ * does not promise at version 2 fails the build.
9
+ *
10
+ * `auth` says which credential the route takes:
11
+ * - `person`: the signed-in developer's token, from the Bridge App. The
12
+ * `/apps/{appId}/…` routes act on one of the developer's apps.
13
+ * - `app-key`: an app key of the app, in `x-api-key`. Used where version 2
14
+ * has no route for the developer: roles, privileges, members, invites
15
+ * into the app's workspaces, and a pasted Stripe key.
16
+ * - `none`: before sign-in (the issuer's own endpoints).
17
+ */
18
+ export const API_VERSION = 2;
19
+ const r = (method, service, path, auth, workspace) => workspace ? { method, service, path, auth, workspace } : { method, service, path, auth };
20
+ export const ROUTES = {
21
+ // The issuer's own endpoints: sign-in, tokens, sign-out.
22
+ signIn: r('POST', 'identity-access', '/apps/{issuerApp}/sign-in', 'none'),
23
+ token: r('POST', 'identity-access', '/apps/{issuerApp}/token', 'none'),
24
+ revoke: r('POST', 'identity-access', '/apps/{issuerApp}/revoke', 'none'),
25
+ signOut: r('POST', 'identity-access', '/sign-out', 'person'),
26
+ me: r('GET', 'accounts', '/me', 'person'),
27
+ // Apps and their addresses.
28
+ appsList: r('GET', 'app-registry', '/apps', 'person'),
29
+ appsCreate: r('POST', 'app-registry', '/apps', 'person'),
30
+ appsGet: r('GET', 'app-registry', '/apps/{appId}', 'person'),
31
+ appsUpdate: r('PATCH', 'app-registry', '/apps/{appId}', 'person'),
32
+ appsDelete: r('DELETE', 'app-registry', '/apps/{appId}', 'person'),
33
+ // App keys.
34
+ keysList: r('GET', 'identity-access', '/apps/{appId}/keys', 'person'),
35
+ keysCreate: r('POST', 'identity-access', '/apps/{appId}/keys', 'person'),
36
+ keysRevoke: r('DELETE', 'identity-access', '/apps/{appId}/keys/{keyId}', 'person'),
37
+ // Billing: plans, products, metrics, taxes, settings, the payment connection.
38
+ plansList: r('GET', 'billing', '/apps/{appId}/plans', 'person'),
39
+ plansCreate: r('POST', 'billing', '/apps/{appId}/plans', 'person'),
40
+ plansGet: r('GET', 'billing', '/apps/{appId}/plans/{key}', 'person'),
41
+ plansReplace: r('PUT', 'billing', '/apps/{appId}/plans/{key}', 'person'),
42
+ plansUpdate: r('PATCH', 'billing', '/apps/{appId}/plans/{key}', 'person'),
43
+ plansDelete: r('DELETE', 'billing', '/apps/{appId}/plans/{key}', 'person'),
44
+ plansArchive: r('POST', 'billing', '/apps/{appId}/plans/{key}/archive', 'person'),
45
+ plansDeletionPreview: r('GET', 'billing', '/apps/{appId}/plans/{key}/deletion-preview', 'person'),
46
+ productsList: r('GET', 'billing', '/apps/{appId}/products', 'person'),
47
+ productsCreate: r('POST', 'billing', '/apps/{appId}/products', 'person'),
48
+ productsGet: r('GET', 'billing', '/apps/{appId}/products/{key}', 'person'),
49
+ productsUpdate: r('PATCH', 'billing', '/apps/{appId}/products/{key}', 'person'),
50
+ productsDelete: r('DELETE', 'billing', '/apps/{appId}/products/{key}', 'person'),
51
+ productsArchive: r('POST', 'billing', '/apps/{appId}/products/{key}/archive', 'person'),
52
+ metricsList: r('GET', 'billing', '/apps/{appId}/metrics', 'person'),
53
+ metricsPut: r('PUT', 'billing', '/apps/{appId}/metrics/{key}', 'person'),
54
+ metricsDelete: r('DELETE', 'billing', '/apps/{appId}/metrics/{key}', 'person'),
55
+ taxesList: r('GET', 'billing', '/apps/{appId}/taxes', 'person'),
56
+ taxesPut: r('PUT', 'billing', '/apps/{appId}/taxes/{country}', 'person'),
57
+ taxesDelete: r('DELETE', 'billing', '/apps/{appId}/taxes/{country}', 'person'),
58
+ billingSettingsGet: r('GET', 'billing', '/apps/{appId}/settings', 'person'),
59
+ billingSettingsUpdate: r('PATCH', 'billing', '/apps/{appId}/settings', 'person'),
60
+ connectionGet: r('GET', 'billing', '/apps/{appId}/connection', 'person'),
61
+ connectionDelete: r('DELETE', 'billing', '/apps/{appId}/connection', 'person'),
62
+ connectionPasteKey: r('POST', 'billing', '/connection', 'app-key'),
63
+ // Flags and their rules.
64
+ flagsList: r('GET', 'flags', '/apps/{appId}/flags', 'person'),
65
+ flagsCreate: r('POST', 'flags', '/apps/{appId}/flags', 'person'),
66
+ flagsGet: r('GET', 'flags', '/apps/{appId}/flags/{key}', 'person'),
67
+ flagsUpdate: r('PATCH', 'flags', '/apps/{appId}/flags/{key}', 'person'),
68
+ flagsDelete: r('DELETE', 'flags', '/apps/{appId}/flags/{key}', 'person'),
69
+ flagsKill: r('POST', 'flags', '/apps/{appId}/flags/{key}/kill', 'person'),
70
+ flagsRestore: r('POST', 'flags', '/apps/{appId}/flags/{key}/restore', 'person'),
71
+ segmentsList: r('GET', 'flags', '/apps/{appId}/segments', 'person'),
72
+ // Roles and privileges, members and workspaces of the app (app-key routes).
73
+ rolesList: r('GET', 'accounts', '/roles', 'app-key'),
74
+ rolesCreate: r('POST', 'accounts', '/roles', 'app-key'),
75
+ rolesUpdate: r('PATCH', 'accounts', '/roles/{roleId}', 'app-key'),
76
+ rolesDelete: r('DELETE', 'accounts', '/roles/{roleId}', 'app-key'),
77
+ privilegesList: r('GET', 'accounts', '/privileges', 'app-key'),
78
+ privilegesCreate: r('POST', 'accounts', '/privileges', 'app-key'),
79
+ privilegesUpdate: r('PATCH', 'accounts', '/privileges/{privilegeId}', 'app-key'),
80
+ privilegesDelete: r('DELETE', 'accounts', '/privileges/{privilegeId}', 'app-key'),
81
+ workspacesList: r('GET', 'accounts', '/workspaces', 'app-key'),
82
+ membersList: r('GET', 'accounts', '/members', 'app-key', true),
83
+ membersGet: r('GET', 'accounts', '/members/{memberId}', 'app-key', true),
84
+ membersUpdate: r('PATCH', 'accounts', '/members/{memberId}', 'app-key', true),
85
+ membersRemove: r('DELETE', 'accounts', '/members/{memberId}', 'app-key', true),
86
+ // Invites into the developer's own workspace on Bridge, the one their token is for.
87
+ invitesList: r('GET', 'accounts', '/invites', 'person'),
88
+ invitesSend: r('POST', 'accounts', '/invites', 'person'),
89
+ invitesRevoke: r('DELETE', 'accounts', '/invites/{inviteId}', 'person'),
90
+ // Invites into one of the app's workspaces (app-key routes).
91
+ appInvitesList: r('GET', 'accounts', '/invites', 'app-key', true),
92
+ appInvitesSend: r('POST', 'accounts', '/invites', 'app-key', true),
93
+ appInvitesRevoke: r('DELETE', 'accounts', '/invites/{inviteId}', 'app-key', true),
94
+ };
95
+ /** The route as the API's contract writes it: `/v2/<microservice><path>`, with `{appId}` for an app. */
96
+ export function contractPath(route) {
97
+ return `/v${String(API_VERSION)}/${route.service}${route.path.replace('{issuerApp}', '{appId}')}`;
98
+ }
99
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/core/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export declare function isLocalHost(hostname: string): boolean;
2
+ /**
3
+ * An address Bridge is reached at: https, or http only on this machine.
4
+ * No user name or password in it. Returns null for anything else.
5
+ */
6
+ export declare function secureUrl(value: unknown): URL | null;
7
+ /**
8
+ * The issuer, checked and normalized: https (http only on this machine), no
9
+ * query or fragment, no trailing slash. The issuer is the one address the
10
+ * CLI is given; every endpoint comes from its metadata.
11
+ */
12
+ export declare function normalizeIssuer(value: string): string;
13
+ /** Fills `{name}` placeholders with URL-encoded values. */
14
+ export declare function fillPath(path: string, params?: Readonly<Record<string, string>>): string;
15
+ //# sourceMappingURL=urls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../src/core/urls.ts"],"names":[],"mappings":"AAKA,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,GAAG,IAAI,CAYpD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED,2DAA2D;AAC3D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAAG,MAAM,CAM5F"}
@@ -0,0 +1,55 @@
1
+ import { CliError } from './errors.js';
2
+ /** The hosts plain http is allowed on: this machine only, for local development. */
3
+ const LOCAL_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]']);
4
+ export function isLocalHost(hostname) {
5
+ return LOCAL_HOSTS.has(hostname);
6
+ }
7
+ /**
8
+ * An address Bridge is reached at: https, or http only on this machine.
9
+ * No user name or password in it. Returns null for anything else.
10
+ */
11
+ export function secureUrl(value) {
12
+ if (typeof value !== 'string' || value === '')
13
+ return null;
14
+ let url;
15
+ try {
16
+ url = new URL(value);
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ if (url.username !== '' || url.password !== '')
22
+ return null;
23
+ if (url.protocol === 'https:')
24
+ return url;
25
+ if (url.protocol === 'http:' && isLocalHost(url.hostname))
26
+ return url;
27
+ return null;
28
+ }
29
+ /**
30
+ * The issuer, checked and normalized: https (http only on this machine), no
31
+ * query or fragment, no trailing slash. The issuer is the one address the
32
+ * CLI is given; every endpoint comes from its metadata.
33
+ */
34
+ export function normalizeIssuer(value) {
35
+ const url = secureUrl(value.trim());
36
+ if (url === null) {
37
+ throw new CliError('misconfigured', `The issuer must be an https address (http only on localhost): ${value}`, {
38
+ hint: 'Pass the Bridge App\'s issuer, for example `--issuer https://api.example.com/identity-access/apps/<app-id>`.',
39
+ });
40
+ }
41
+ if (url.search !== '' || url.hash !== '') {
42
+ throw new CliError('misconfigured', `The issuer has no query or fragment: ${value}`);
43
+ }
44
+ return url.toString().replace(/\/+$/, '');
45
+ }
46
+ /** Fills `{name}` placeholders with URL-encoded values. */
47
+ export function fillPath(path, params = {}) {
48
+ return path.replace(/\{([A-Za-z]+)\}/g, (_, name) => {
49
+ const value = params[name];
50
+ if (value === undefined || value === '')
51
+ throw new CliError('invalid', `Missing ${name}.`);
52
+ return encodeURIComponent(value);
53
+ });
54
+ }
55
+ //# sourceMappingURL=urls.js.map