@nebulr-group/bridge-cli 0.6.5 → 1.0.0-alpha.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 (293) hide show
  1. package/README.md +93 -460
  2. package/dist/api/accounts.d.ts +69 -0
  3. package/dist/api/accounts.d.ts.map +1 -0
  4. package/dist/api/accounts.js +42 -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 +116 -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 +94 -0
  113. package/dist/core/routes.d.ts.map +1 -0
  114. package/dist/core/routes.js +91 -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 +23 -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 -298
  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
@@ -1 +0,0 @@
1
- {"version":3,"file":"use.command.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/use.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAc1D"}
@@ -1,47 +0,0 @@
1
- import { CredentialSelectorError, findCredential, isExpired, listCredentials, setActiveCredential, } from '../../credentials.js';
2
- import { resetManagementClient } from '../../config.js';
3
- export function registerAuthUseCommand(auth) {
4
- auth
5
- .command('use <profile>')
6
- .description('Switch the default app to another stored credential (no re-login)')
7
- .action((profile) => {
8
- try {
9
- runUse(profile);
10
- process.exitCode = 0;
11
- }
12
- catch (err) {
13
- const msg = err instanceof Error ? err.message : String(err);
14
- process.stderr.write(`bridge auth use: ${msg}\n`);
15
- process.exitCode = 1;
16
- }
17
- });
18
- }
19
- function runUse(profile) {
20
- const stdout = process.stdout;
21
- let entry;
22
- try {
23
- entry = findCredential(profile);
24
- }
25
- catch (err) {
26
- if (err instanceof CredentialSelectorError)
27
- throw new Error(err.message);
28
- throw err;
29
- }
30
- setActiveCredential(entry.key);
31
- resetManagementClient();
32
- const name = entry.creds.label ?? entry.creds.app.name;
33
- stdout.write(`Now using ${name} — ${entry.creds.app.name} (${entry.creds.app.id})\n`);
34
- stdout.write(` baseUrl=${entry.creds.baseUrl}\n`);
35
- // Switching TO an expired credential is allowed — it is the user's stated
36
- // intent, and refusing would leave them unable to make it the default before
37
- // re-authenticating it. But it must not be a surprise at the next command.
38
- if (isExpired(entry.creds)) {
39
- stdout.write(` WARNING: this credential expired ${entry.creds.expiresAt}. ` +
40
- 'Run `bridge auth login` to refresh it.\n');
41
- }
42
- const others = listCredentials().filter((e) => e.key !== entry.key);
43
- if (others.length > 0) {
44
- stdout.write(` also stored: ${others.map((e) => e.creds.label ?? e.creds.app.name).join(', ')}\n`);
45
- }
46
- }
47
- //# sourceMappingURL=use.command.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use.command.js","sourceRoot":"","sources":["../../../src/commands/auth/use.command.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,SAAS,EACT,eAAe,EACf,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,UAAU,sBAAsB,CAAC,IAAa;IAClD,IAAI;SACD,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,mEAAmE,CAAC;SAChF,MAAM,CAAC,CAAC,OAAe,EAAE,EAAE;QAC1B,IAAI,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;YAClD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,MAAM,CAAC,OAAe;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE9B,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,uBAAuB;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzE,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,qBAAqB,EAAE,CAAC;IAExB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;IACvD,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IACtF,MAAM,CAAC,KAAK,CAAC,aAAa,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IAEnD,0EAA0E;IAC1E,6EAA6E;IAC7E,2EAA2E;IAC3E,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CACV,sCAAsC,KAAK,CAAC,KAAK,CAAC,SAAS,IAAI;YAC7D,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;IACpE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,KAAK,CACV,kBAAkB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACtF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerBrandingCommands(program: Command): void;
3
- //# sourceMappingURL=branding.command.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"branding.command.d.ts","sourceRoot":"","sources":["../../src/commands/branding.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmC/D"}
@@ -1,42 +0,0 @@
1
- import { getManagementClient } from '../config.js';
2
- import { outputSuccess, outputError } from '../output.js';
3
- export function registerBrandingCommands(program) {
4
- const branding = program.command('branding').description('Manage branding');
5
- branding.command('get')
6
- .description('Get current branding configuration')
7
- .action(async () => {
8
- try {
9
- outputSuccess(await getManagementClient().branding.get());
10
- }
11
- catch (err) {
12
- outputError(err);
13
- }
14
- });
15
- branding.command('update')
16
- .description('Update branding')
17
- .option('--bg-color <color>', 'Background color')
18
- .option('--text-color <color>', 'Text color')
19
- .option('--link-color <color>', 'Link color')
20
- .option('--primary-btn-bg <color>', 'Primary button background')
21
- .option('--primary-btn-text <color>', 'Primary button text')
22
- .option('--font-family <font>', 'Font family')
23
- .option('--border-radius <radius>', 'Border radius')
24
- .action(async (opts) => {
25
- try {
26
- const data = Object.fromEntries(Object.entries({
27
- bgColor: opts.bgColor,
28
- textColor: opts.textColor,
29
- linkColor: opts.linkColor,
30
- primaryButtonBgColor: opts.primaryBtnBg,
31
- primaryButtonTextColor: opts.primaryBtnText,
32
- fontFamily: opts.fontFamily,
33
- borderRadius: opts.borderRadius,
34
- }).filter(([, v]) => v !== undefined));
35
- outputSuccess(await getManagementClient().branding.update(data));
36
- }
37
- catch (err) {
38
- outputError(err);
39
- }
40
- });
41
- }
42
- //# sourceMappingURL=branding.command.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"branding.command.js","sourceRoot":"","sources":["../../src/commands/branding.command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAE5E,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC;SACpB,WAAW,CAAC,oCAAoC,CAAC;SACjD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YAAC,aAAa,CAAC,MAAM,mBAAmB,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QAAC,CAAC;QAClE,OAAO,GAAG,EAAE,CAAC;YAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEL,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;SACvB,WAAW,CAAC,iBAAiB,CAAC;SAC9B,MAAM,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;SAChD,MAAM,CAAC,sBAAsB,EAAE,YAAY,CAAC;SAC5C,MAAM,CAAC,sBAAsB,EAAE,YAAY,CAAC;SAC5C,MAAM,CAAC,0BAA0B,EAAE,2BAA2B,CAAC;SAC/D,MAAM,CAAC,4BAA4B,EAAE,qBAAqB,CAAC;SAC3D,MAAM,CAAC,sBAAsB,EAAE,aAAa,CAAC;SAC7C,MAAM,CAAC,0BAA0B,EAAE,eAAe,CAAC;SACnD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAC7B,MAAM,CAAC,OAAO,CAAC;gBACb,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,oBAAoB,EAAE,IAAI,CAAC,YAAY;gBACvC,sBAAsB,EAAE,IAAI,CAAC,cAAc;gBAC3C,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;aAChC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CACtC,CAAC;YACF,aAAa,CAAC,MAAM,mBAAmB,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAW,CAAC,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerEventCommands(program: Command): void;
3
- //# sourceMappingURL=event.command.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event.command.d.ts","sourceRoot":"","sources":["../../src/commands/event.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqB5D"}
@@ -1,27 +0,0 @@
1
- import { getManagementClient } from '../config.js';
2
- import { outputSuccess, outputError } from '../output.js';
3
- export function registerEventCommands(program) {
4
- const event = program.command('event').description('Query event log');
5
- event.command('list')
6
- .description('Query events')
7
- .option('--type <type>', 'Event type filter')
8
- .option('--tenant-id <id>', 'Filter by tenant')
9
- .option('--user-id <id>', 'Filter by user')
10
- .option('--since <duration>', 'Time filter (e.g., "24h", "7d", ISO date)')
11
- .option('--limit <n>', 'Max results', parseInt)
12
- .action(async (opts) => {
13
- try {
14
- outputSuccess(await getManagementClient().events.query({
15
- type: opts.type,
16
- tenantId: opts.tenantId,
17
- userId: opts.userId,
18
- since: opts.since,
19
- limit: opts.limit,
20
- }));
21
- }
22
- catch (err) {
23
- outputError(err);
24
- }
25
- });
26
- }
27
- //# sourceMappingURL=event.command.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event.command.js","sourceRoot":"","sources":["../../src/commands/event.command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAEtE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;SAClB,WAAW,CAAC,cAAc,CAAC;SAC3B,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC;SAC5C,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;SAC9C,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;SAC1C,MAAM,CAAC,oBAAoB,EAAE,2CAA2C,CAAC;SACzE,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,CAAC;SAC9C,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,aAAa,CAAC,MAAM,mBAAmB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;gBACrD,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,13 +0,0 @@
1
- import { Command } from 'commander';
2
- export type FlagsFramework = 'svelte' | 'react' | 'nextjs' | 'angular' | 'nestjs' | 'express' | 'unknown';
3
- export declare function registerFlagInitCommand(flagParent: Command): void;
4
- export declare function detectFramework(cwd: string): Promise<FlagsFramework>;
5
- interface SnippetCtx {
6
- appId: string;
7
- baseUrl: string;
8
- }
9
- export declare function renderSnippet(framework: FlagsFramework, ctx: SnippetCtx): string;
10
- /** Probe whether a path exists (used by tests). */
11
- export declare function pathExists(path: string): Promise<boolean>;
12
- export {};
13
- //# sourceMappingURL=flag-init.command.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"flag-init.command.d.ts","sourceRoot":"","sources":["../../src/commands/flag-init.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,MAAM,MAAM,cAAc,GACtB,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,SAAS,GACT,SAAS,CAAC;AAEd,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI,CAkEjE;AAID,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAwB1E;AAID,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CA8ThF;AAuCD,mDAAmD;AACnD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D"}
@@ -1,463 +0,0 @@
1
- // TBP-198 — Flags-only integration scaffold.
2
- //
3
- // `bridge flag init` (alias for the eventual `bridge init --flags-only`).
4
- // Detects the project framework from package.json and prints:
5
- // - The framework's REAL flag-reading setup snippet
6
- // - A `bridge-flags.config.json` next to package.json with appId + baseUrl
7
- // + suggested provider config
8
- //
9
- // TBP-206 — every snippet below MUST correspond to a symbol that actually
10
- // exists in the named package at an import specifier that actually resolves.
11
- // The previous revision invented `createBridgeFlags()` middleware for express,
12
- // `BridgeFlagsProvider` for react/nextjs and `provideBridgeFlags` for angular,
13
- // and pointed every framework at a `/flags` subpath — several of which are not
14
- // declared in the package's `exports` map. Agents followed the scaffold and
15
- // wrote code that could not resolve, let alone run. If you change a snippet,
16
- // re-verify it against the package source first.
17
- //
18
- // The command is deliberately NON-destructive: it never overwrites source
19
- // files. The "scaffold" is text output (snippet + config file) for the agent
20
- // or the developer to apply.
21
- import { readFile, writeFile, access } from 'node:fs/promises';
22
- import { join } from 'node:path';
23
- import { getManagementClient, getResolvedBaseUrl } from '../config.js';
24
- import { outputSuccess, outputError } from '../output.js';
25
- export function registerFlagInitCommand(flagParent) {
26
- flagParent
27
- .command('init')
28
- .description('Scaffold a flags-only Bridge integration (no auth setup) — detects framework, prints setup snippet, writes bridge-flags.config.json')
29
- .option('--framework <name>', 'Override framework detection: svelte | react | nextjs | angular | nestjs | express')
30
- .option('--cwd <path>', 'Project directory (defaults to current)', process.cwd())
31
- .option('--no-config', 'Skip writing bridge-flags.config.json')
32
- .option('--base-url <url>', 'Override the base URL written to config')
33
- .option('--force', 'Overwrite an existing bridge-flags.config.json')
34
- .action(async (opts) => {
35
- try {
36
- const cwd = opts.cwd;
37
- const framework = opts.framework ?? (await detectFramework(cwd));
38
- const client = getManagementClient();
39
- const app = (await client.app.get());
40
- const appId = app.id ?? '';
41
- const appName = app.name ?? '';
42
- // The environment the app was just read from, so the project is wired
43
- // to the same one (TBP-708).
44
- const baseUrl = opts.baseUrl ?? getResolvedBaseUrl();
45
- const snippet = renderSnippet(framework, { appId, baseUrl });
46
- let configPath;
47
- if (opts.config !== false) {
48
- configPath = join(cwd, 'bridge-flags.config.json');
49
- // Never clobber a config someone may have edited (TBP-706).
50
- if (!opts.force && (await pathExists(configPath))) {
51
- throw new Error(`${configPath} already exists. Pass --force to overwrite it, or --no-config to leave it and only print the setup.`);
52
- }
53
- await writeFile(configPath, JSON.stringify({
54
- appId,
55
- appName,
56
- baseUrl,
57
- framework,
58
- provider: suggestedProviderConfig(framework),
59
- }, null, 2) + '\n', 'utf8');
60
- }
61
- outputSuccess({
62
- framework,
63
- app: { id: appId, name: appName },
64
- baseUrl,
65
- configFile: configPath,
66
- nextSteps: nextStepsFor(framework),
67
- snippet,
68
- });
69
- }
70
- catch (err) {
71
- outputError(err);
72
- }
73
- });
74
- }
75
- // ── Framework detection ─────────────────────────────────────────────────────
76
- export async function detectFramework(cwd) {
77
- const pkgPath = join(cwd, 'package.json');
78
- let pkgRaw;
79
- try {
80
- pkgRaw = await readFile(pkgPath, 'utf8');
81
- }
82
- catch {
83
- return 'unknown';
84
- }
85
- let pkg;
86
- try {
87
- pkg = JSON.parse(pkgRaw);
88
- }
89
- catch {
90
- return 'unknown';
91
- }
92
- const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
93
- // Order matters: Next.js + React is detected as Next.js.
94
- if ('next' in deps)
95
- return 'nextjs';
96
- if ('@sveltejs/kit' in deps || 'svelte' in deps)
97
- return 'svelte';
98
- if ('@nestjs/core' in deps)
99
- return 'nestjs';
100
- if ('@angular/core' in deps)
101
- return 'angular';
102
- if ('react' in deps)
103
- return 'react';
104
- if ('express' in deps)
105
- return 'express';
106
- return 'unknown';
107
- }
108
- export function renderSnippet(framework, ctx) {
109
- // Import specifiers that actually resolve for each framework (TBP-206).
110
- //
111
- // svelte / react — declare "./flags" in their package.json `exports` map.
112
- // nextjs — has NO "./flags" and NO "." key; FF 2.0 is folded into
113
- // "./client", server-side flags live under "./server".
114
- // angular — ships a single ng-packagr entry point; everything comes
115
- // from the bare specifier.
116
- // nestjs — declares "./flags" since 0.6.0 (TBP-613). Before that
117
- // it had no `exports` map, so `<pkg>/flags` fell back to
118
- // legacy resolution and 404'd, and this scaffolder
119
- // emitted `<pkg>/dist/flags` instead. Reaching into the
120
- // build directory was never right — it froze the dist
121
- // layout into a public contract — and generating it here
122
- // is how the wrong path spread. Requires >= 0.6.0.
123
- // express — no `exports` map and no flags entry point; the flag
124
- // surface is on the bare specifier.
125
- const pkgFor = {
126
- svelte: '@nebulr-group/bridge-svelte/flags',
127
- react: '@nebulr-group/bridge-react/flags',
128
- nextjs: '@nebulr-group/bridge-nextjs/client',
129
- angular: '@nebulr-group/bridge-angular',
130
- nestjs: '@nebulr-group/bridge-nestjs/flags',
131
- express: '@nebulr-group/bridge-express',
132
- };
133
- if (framework === 'unknown') {
134
- return [
135
- `# Bridge Flags — generic setup`,
136
- ``,
137
- `Couldn't auto-detect your framework. Use the core SDK directly:`,
138
- ``,
139
- '```ts',
140
- `import { BridgeFlags } from '@nebulr-group/bridge-auth-core';`,
141
- ``,
142
- `// 'backend' refuses to bucket rollout flags without an identity;`,
143
- `// use 'frontend' in a browser runtime.`,
144
- `export const bridge = new BridgeFlags({ mode: 'backend' });`,
145
- ``,
146
- `// Load the rule set for your app, for local evaluation (the framework SDKs do this`,
147
- `// for you). To have Bridge evaluate for a signed-in user instead, see the`,
148
- `// bulkEvaluate endpoint in \`bridge guide custom\`.`,
149
- `const res = await fetch(`,
150
- ` '${ctx.baseUrl}/admin/flags-internal/flags-cache/${ctx.appId}',`,
151
- `);`,
152
- `bridge.hydrate(await res.json());`,
153
- ``,
154
- `bridge.setContext({ identity: 'user-id', attributes: { /* plan, role, ... */ } });`,
155
- ``,
156
- `// Read a flag — T is inferred from defaultValue (boolean | string | number | json).`,
157
- `// Returns FlagEvalResult<T> = { value, passed }, NOT a bare value.`,
158
- `const { value: newDashboard } = bridge.flag('new-dashboard', false);`,
159
- '```',
160
- ].join('\n');
161
- }
162
- const pkg = pkgFor[framework];
163
- // Per-framework idiomatic snippet.
164
- switch (framework) {
165
- case 'svelte':
166
- return [
167
- '# Bridge Flags — SvelteKit (flags-only)',
168
- '',
169
- `1. Install:`,
170
- ' ```bash',
171
- ' bun add @nebulr-group/bridge-svelte',
172
- ' ```',
173
- '',
174
- '2. Configure + mount the runtime once — `src/routes/+layout.svelte`:',
175
- ' ```svelte',
176
- ' <script lang="ts">',
177
- ` import { BridgeProvider, bridgeConfig } from '@nebulr-group/bridge-svelte';`,
178
- '',
179
- ' bridgeConfig.initConfig({',
180
- ` appId: '${ctx.appId}',`,
181
- ` apiBaseUrl: '${ctx.baseUrl}',`,
182
- ' });',
183
- '',
184
- ' let { children } = $props();',
185
- ' </script>',
186
- '',
187
- ' <BridgeProvider>{@render children()}</BridgeProvider>',
188
- ' ```',
189
- '',
190
- '3. Read a flag in any component under the provider:',
191
- ' ```svelte',
192
- ' <script lang="ts">',
193
- ` import { useFlag } from '${pkg}';`,
194
- '',
195
- ' // Sync rune. Returns { value, passed } — NOT a bare value.',
196
- ' // T is inferred from the default: boolean | string | number | json.',
197
- ` const newDashboard = useFlag('new-dashboard', false);`,
198
- ' </script>',
199
- '',
200
- ' {#if newDashboard.value}<V2 />{:else}<V1 />{/if}',
201
- ' ```',
202
- '',
203
- ' Or declaratively:',
204
- ' ```svelte',
205
- ` import { FeatureFlag } from '${pkg}';`,
206
- ' <FeatureFlag flag="new-dashboard">…</FeatureFlag>',
207
- ' ```',
208
- ].join('\n');
209
- case 'react':
210
- return [
211
- '# Bridge Flags — React (flags-only)',
212
- '',
213
- `1. Install:`,
214
- ' ```bash',
215
- ' bun add @nebulr-group/bridge-react',
216
- ' ```',
217
- '',
218
- '2. In `src/main.tsx` — flags ride on the core Bridge runtime, so mount',
219
- ' `<BridgeProvider>` (there is no separate flags provider):',
220
- ' ```tsx',
221
- ` import { BridgeProvider } from '@nebulr-group/bridge-react';`,
222
- '',
223
- ` <BridgeProvider config={{ appId: '${ctx.appId}', apiBaseUrl: '${ctx.baseUrl}' }}>`,
224
- ' <App />',
225
- ' </BridgeProvider>',
226
- ' ```',
227
- ' (`VITE_BRIDGE_APP_ID` / `VITE_BRIDGE_API_BASE_URL` override the props.)',
228
- '',
229
- '3. Use the hook in any component:',
230
- ' ```tsx',
231
- ` import { useFlag } from '${pkg}';`,
232
- '',
233
- ' function NewDashboard() {',
234
- ' // Sync. Returns { value, passed } — destructure `value`.',
235
- ` const { value: enabled } = useFlag('new-dashboard', false);`,
236
- ' return enabled ? <V2 /> : <V1 />;',
237
- ' }',
238
- ' ```',
239
- ].join('\n');
240
- case 'nextjs':
241
- return [
242
- '# Bridge Flags — Next.js (flags-only)',
243
- '',
244
- `1. Install:`,
245
- ' ```bash',
246
- ' bun add @nebulr-group/bridge-nextjs',
247
- ' ```',
248
- '',
249
- '2. Client side — `app/providers.tsx`. FF 2.0 is folded into the',
250
- ' `./client` entry point; there is no `/flags` subpath and no separate',
251
- ' flags provider:',
252
- ' ```tsx',
253
- ` "use client";`,
254
- ` import { BridgeProvider } from '${pkg}';`,
255
- '',
256
- ' export function Providers({ children }: { children: React.ReactNode }) {',
257
- ' return (',
258
- ` <BridgeProvider config={{ appId: '${ctx.appId}', apiBaseUrl: '${ctx.baseUrl}' }}>`,
259
- ' {children}',
260
- ' </BridgeProvider>',
261
- ' );',
262
- ' }',
263
- ' ```',
264
- '',
265
- ' Then in any client component:',
266
- ' ```tsx',
267
- ` import { useFlag } from '${pkg}';`,
268
- ` const { value: enabled } = useFlag('new-dashboard', false);`,
269
- ' ```',
270
- '',
271
- '3. Server side — Server Component / Route Handler / middleware. The',
272
- ' server flag surface is a singleton, and every read is async and takes',
273
- ' the `NextRequest` (that is where identity comes from):',
274
- ' ```ts',
275
- ` import { FeatureFlagServer } from '@nebulr-group/bridge-nextjs/server';`,
276
- '',
277
- ' // Once at boot:',
278
- ' FeatureFlagServer.getInstance().init({',
279
- ` appId: '${ctx.appId}',`,
280
- ` apiBaseUrl: '${ctx.baseUrl}',`,
281
- ' });',
282
- '',
283
- ' // Per request — evaluated locally in-process, no round trip per flag:',
284
- ` const enabled = await FeatureFlagServer.getInstance().flagServer('new-dashboard', false, request);`,
285
- ' ```',
286
- ].join('\n');
287
- case 'angular':
288
- return [
289
- '# Bridge Flags — Angular (flags-only)',
290
- '',
291
- `1. Install:`,
292
- ' ```bash',
293
- ' bun add @nebulr-group/bridge-angular',
294
- ' ```',
295
- '',
296
- '2. In `app.config.ts` — one provider covers auth + flags (the package',
297
- ' ships a single entry point, so import from the bare specifier):',
298
- ' ```ts',
299
- ` import { provideBridge } from '${pkg}';`,
300
- '',
301
- ' export const appConfig: ApplicationConfig = {',
302
- ' providers: [',
303
- ' provideBridge({',
304
- ` appId: '${ctx.appId}',`,
305
- ` apiBaseUrl: '${ctx.baseUrl}',`,
306
- ' }),',
307
- ' ],',
308
- ' };',
309
- ' ```',
310
- '',
311
- '3. Inject `BridgeService` — `flag()` returns a Signal of { value, passed }:',
312
- ' ```ts',
313
- ` import { BridgeService } from '${pkg}';`,
314
- '',
315
- ' private bridge = inject(BridgeService);',
316
- '',
317
- ` newDashboard = this.bridge.flag('new-dashboard', false);`,
318
- ' // template: {{ newDashboard().value }}',
319
- '',
320
- ' // One-shot, non-reactive read:',
321
- ` // const { value } = this.bridge.evaluate('new-dashboard', false);`,
322
- ' ```',
323
- ].join('\n');
324
- case 'nestjs':
325
- return [
326
- '# Bridge Flags — NestJS (flags-only, backend mode)',
327
- '',
328
- `1. Install:`,
329
- ' ```bash',
330
- ' bun add @nebulr-group/bridge-nestjs',
331
- ' ```',
332
- '',
333
- '2. Import the module in `app.module.ts` (requires bridge-nestjs >= 0.6.0):',
334
- ' ```ts',
335
- ` import { BridgeFlagsModule } from '${pkg}';`,
336
- '',
337
- ' @Module({',
338
- ' imports: [',
339
- ' BridgeFlagsModule.forRoot({',
340
- ` apiBaseUrl: '${ctx.baseUrl}',`,
341
- ` appId: '${ctx.appId}',`,
342
- ` apiKey: process.env.BRIDGE_API_KEY!, // a Bridge API token, never the app id`,
343
- ` mode: 'backend',`,
344
- ' }),',
345
- ' ],',
346
- ' })',
347
- ' export class AppModule {}',
348
- ' ```',
349
- '',
350
- '3. Inject in any service / controller:',
351
- ' ```ts',
352
- ` import { BridgeFlagsService } from '${pkg}';`,
353
- '',
354
- ' constructor(private flags: BridgeFlagsService) {}',
355
- '',
356
- ' handleRequest(req) {',
357
- ' // Sync, evaluated locally in-process. Returns T directly.',
358
- ` const enabled = this.flags.flag('new-checkout', false, {`,
359
- ' identity: req.bridgeUser?.id,',
360
- ' attributes: { plan: req.bridgeUser?.plan },',
361
- ' });',
362
- ' }',
363
- ' ```',
364
- ].join('\n');
365
- case 'express':
366
- return [
367
- '# Bridge Flags — Express',
368
- '',
369
- ' NOTE: express does not have a standalone flags runtime. Flags are',
370
- ' part of the auth middleware, are boolean-only, require a user JWT,',
371
- ' and are evaluated remotely by the Bridge API (see TBP-516).',
372
- '',
373
- `1. Install:`,
374
- ' ```bash',
375
- ' bun add @nebulr-group/bridge-express',
376
- ' ```',
377
- '',
378
- '2. At app bootstrap:',
379
- ' ```ts',
380
- ` import { createBridge } from '${pkg}';`,
381
- '',
382
- ' const bridge = createBridge({',
383
- ` appId: '${ctx.appId}',`,
384
- ` apiBaseUrl: '${ctx.baseUrl}',`,
385
- ' guard: { defaultAccess: \'protected\' },',
386
- ' });',
387
- '',
388
- ' app.use(bridge.auth());',
389
- ' ```',
390
- '',
391
- '3. Gate a route on a flag — `featureFlag` accepts',
392
- ' `string | { any: string[] } | { all: string[] }`; a miss is a 403:',
393
- ' ```ts',
394
- ` app.get('/beta', bridge.protect({ featureFlag: 'new-home' }), (req, res) => {`,
395
- ` res.send('v2');`,
396
- ' });',
397
- '',
398
- ' // Or centrally, via guard.rules:',
399
- ` // { path: '/beta/**', privilege: 'AUTHENTICATED', featureFlag: { any: ['new-home', 'beta'] } }`,
400
- ' ```',
401
- '',
402
- '4. Read a flag inside a handler:',
403
- ' ```ts',
404
- ` import { BridgeConfigService, FeatureFlagService } from '${pkg}';`,
405
- '',
406
- ' const flags = new FeatureFlagService(',
407
- ` new BridgeConfigService({ appId: '${ctx.appId}', apiBaseUrl: '${ctx.baseUrl}' }),`,
408
- ' );',
409
- '',
410
- ` app.get('/', bridge.protect(), async (req, res) => {`,
411
- ' // Boolean only. Async — remote evaluation, cached 5 min per token.',
412
- ` const enabled = await flags.isEnabled('new-home', req.bridgeAccessToken!);`,
413
- ` res.send(enabled ? 'v2' : 'v1');`,
414
- ' });',
415
- ' ```',
416
- ].join('\n');
417
- }
418
- }
419
- // ── Provider config + next-steps blurbs ─────────────────────────────────────
420
- function suggestedProviderConfig(framework) {
421
- // Keys mirror the real option names on the framework's flags runtime
422
- // (`createBridgeFlags` / `BridgeFlagsModule.forRoot`) — `mode` is
423
- // `'frontend' | 'backend'`, `telemetry` is a partial TelemetryBatcherConfig.
424
- if (framework === 'express') {
425
- // express has no BridgeFlags runtime — nothing to configure. Flags are
426
- // enforced through `bridge.protect({ featureFlag })` and evaluated remotely
427
- // by the Bridge API. See TBP-516.
428
- return {
429
- runtime: 'none',
430
- note: 'bridge-express evaluates flags remotely inside the auth middleware; there is no local flags provider to configure.',
431
- };
432
- }
433
- if (framework === 'nestjs') {
434
- return { mode: 'backend', telemetry: { enabled: true, flushIntervalMs: 5000 } };
435
- }
436
- return { mode: 'frontend', telemetry: { enabled: true, flushIntervalMs: 5000 } };
437
- }
438
- function nextStepsFor(framework) {
439
- const base = [
440
- 'Apply the printed snippet to the file noted above.',
441
- 'Run `bridge guide flags' + (framework !== 'unknown' ? ` --framework ${framework}` : '') + '` for the full integration prompt.',
442
- 'Create your first flag: `bridge flag create --key hello-flag --state on --value-type boolean --on-value true --off-value false`',
443
- 'Eval it locally: `bridge flag eval hello-flag --identity demo-user`',
444
- ];
445
- if (framework === 'unknown') {
446
- return [
447
- 'Could not auto-detect your framework — pass --framework <name> to scope the snippet.',
448
- ...base,
449
- ];
450
- }
451
- return base;
452
- }
453
- /** Probe whether a path exists (used by tests). */
454
- export async function pathExists(path) {
455
- try {
456
- await access(path);
457
- return true;
458
- }
459
- catch {
460
- return false;
461
- }
462
- }
463
- //# sourceMappingURL=flag-init.command.js.map