@nebulr-group/bridge-cli 0.6.6 → 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.
- package/README.md +93 -460
- package/dist/api/accounts.d.ts +69 -0
- package/dist/api/accounts.d.ts.map +1 -0
- package/dist/api/accounts.js +42 -0
- package/dist/api/accounts.js.map +1 -0
- package/dist/api/apps.d.ts +50 -0
- package/dist/api/apps.d.ts.map +1 -0
- package/dist/api/apps.js +62 -0
- package/dist/api/apps.js.map +1 -0
- package/dist/api/billing.d.ts +131 -0
- package/dist/api/billing.d.ts.map +1 -0
- package/dist/api/billing.js +42 -0
- package/dist/api/billing.js.map +1 -0
- package/dist/api/flags.d.ts +73 -0
- package/dist/api/flags.d.ts.map +1 -0
- package/dist/api/flags.js +108 -0
- package/dist/api/flags.js.map +1 -0
- package/dist/api/keys.d.ts +48 -0
- package/dist/api/keys.d.ts.map +1 -0
- package/dist/api/keys.js +87 -0
- package/dist/api/keys.js.map +1 -0
- package/dist/auth/browser-open.d.ts +21 -4
- package/dist/auth/browser-open.d.ts.map +1 -1
- package/dist/auth/browser-open.js +45 -65
- package/dist/auth/browser-open.js.map +1 -1
- package/dist/auth/lock.d.ts +8 -0
- package/dist/auth/lock.d.ts.map +1 -0
- package/dist/auth/lock.js +43 -0
- package/dist/auth/lock.js.map +1 -0
- package/dist/auth/loopback.d.ts +8 -12
- package/dist/auth/loopback.d.ts.map +1 -1
- package/dist/auth/loopback.js +40 -45
- package/dist/auth/loopback.js.map +1 -1
- package/dist/auth/session.d.ts +61 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +142 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/auth/sign-in.d.ts +67 -0
- package/dist/auth/sign-in.d.ts.map +1 -0
- package/dist/auth/sign-in.js +113 -0
- package/dist/auth/sign-in.js.map +1 -0
- package/dist/auth/store.d.ts +89 -0
- package/dist/auth/store.d.ts.map +1 -0
- package/dist/auth/store.js +214 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/bin.js +0 -2
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +1 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -17
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +31 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +67 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/accounts.command.d.ts +4 -0
- package/dist/commands/accounts.command.d.ts.map +1 -0
- package/dist/commands/accounts.command.js +116 -0
- package/dist/commands/accounts.command.js.map +1 -0
- package/dist/commands/app.command.d.ts +3 -2
- package/dist/commands/app.command.d.ts.map +1 -1
- package/dist/commands/app.command.js +132 -233
- package/dist/commands/app.command.js.map +1 -1
- package/dist/commands/auth.command.d.ts +2 -12
- package/dist/commands/auth.command.d.ts.map +1 -1
- package/dist/commands/auth.command.js +147 -20
- package/dist/commands/auth.command.js.map +1 -1
- package/dist/commands/billing.command.d.ts +4 -0
- package/dist/commands/billing.command.d.ts.map +1 -0
- package/dist/commands/billing.command.js +185 -0
- package/dist/commands/billing.command.js.map +1 -0
- package/dist/commands/check.command.d.ts +2 -1
- package/dist/commands/check.command.d.ts.map +1 -1
- package/dist/commands/check.command.js +11 -14
- package/dist/commands/check.command.js.map +1 -1
- package/dist/commands/context.d.ts +58 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +78 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/flag.command.d.ts +3 -62
- package/dist/commands/flag.command.d.ts.map +1 -1
- package/dist/commands/flag.command.js +181 -864
- package/dist/commands/flag.command.js.map +1 -1
- package/dist/commands/key.command.d.ts +4 -0
- package/dist/commands/key.command.d.ts.map +1 -0
- package/dist/commands/key.command.js +44 -0
- package/dist/commands/key.command.js.map +1 -0
- package/dist/commands/plan.command.d.ts +3 -203
- package/dist/commands/plan.command.d.ts.map +1 -1
- package/dist/commands/plan.command.js +200 -759
- package/dist/commands/plan.command.js.map +1 -1
- package/dist/config.d.ts +19 -101
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +51 -364
- package/dist/config.js.map +1 -1
- package/dist/core/discovery.d.ts +27 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +97 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/errors.d.ts +26 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +33 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/http.d.ts +23 -0
- package/dist/core/http.d.ts.map +1 -0
- package/dist/core/http.js +153 -0
- package/dist/core/http.js.map +1 -0
- package/dist/core/private-files.d.ts +6 -0
- package/dist/core/private-files.d.ts.map +1 -0
- package/dist/core/private-files.js +96 -0
- package/dist/core/private-files.js.map +1 -0
- package/dist/core/routes.d.ts +94 -0
- package/dist/core/routes.d.ts.map +1 -0
- package/dist/core/routes.js +91 -0
- package/dist/core/routes.js.map +1 -0
- package/dist/core/urls.d.ts +15 -0
- package/dist/core/urls.d.ts.map +1 -0
- package/dist/core/urls.js +55 -0
- package/dist/core/urls.js.map +1 -0
- package/dist/gate-rules.d.ts +1 -2
- package/dist/gate-rules.d.ts.map +1 -1
- package/dist/gate-rules.js +4 -5
- package/dist/gate-rules.js.map +1 -1
- package/dist/index.d.ts +23 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/io.d.ts +21 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +59 -0
- package/dist/io.js.map +1 -0
- package/dist/money.d.ts +42 -0
- package/dist/money.d.ts.map +1 -0
- package/dist/money.js +112 -0
- package/dist/money.js.map +1 -0
- package/dist/program.d.ts +5 -24
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +25 -113
- package/dist/program.js.map +1 -1
- package/package.json +7 -8
- package/dist/auth/api-client.d.ts +0 -50
- package/dist/auth/api-client.d.ts.map +0 -1
- package/dist/auth/api-client.js +0 -109
- package/dist/auth/api-client.js.map +0 -1
- package/dist/auth/relative-time.d.ts +0 -2
- package/dist/auth/relative-time.d.ts.map +0 -1
- package/dist/auth/relative-time.js +0 -27
- package/dist/auth/relative-time.js.map +0 -1
- package/dist/auth/scopes.d.ts +0 -30
- package/dist/auth/scopes.d.ts.map +0 -1
- package/dist/auth/scopes.js +0 -39
- package/dist/auth/scopes.js.map +0 -1
- package/dist/auth/workspace-client.d.ts +0 -70
- package/dist/auth/workspace-client.d.ts.map +0 -1
- package/dist/auth/workspace-client.js +0 -105
- package/dist/auth/workspace-client.js.map +0 -1
- package/dist/commands/auth/config.command.d.ts +0 -8
- package/dist/commands/auth/config.command.d.ts.map +0 -1
- package/dist/commands/auth/config.command.js +0 -60
- package/dist/commands/auth/config.command.js.map +0 -1
- package/dist/commands/auth/login.command.d.ts +0 -46
- package/dist/commands/auth/login.command.d.ts.map +0 -1
- package/dist/commands/auth/login.command.js +0 -166
- package/dist/commands/auth/login.command.js.map +0 -1
- package/dist/commands/auth/logout.command.d.ts +0 -21
- package/dist/commands/auth/logout.command.d.ts.map +0 -1
- package/dist/commands/auth/logout.command.js +0 -97
- package/dist/commands/auth/logout.command.js.map +0 -1
- package/dist/commands/auth/methods.command.d.ts +0 -68
- package/dist/commands/auth/methods.command.d.ts.map +0 -1
- package/dist/commands/auth/methods.command.js +0 -91
- package/dist/commands/auth/methods.command.js.map +0 -1
- package/dist/commands/auth/status.command.d.ts +0 -18
- package/dist/commands/auth/status.command.d.ts.map +0 -1
- package/dist/commands/auth/status.command.js +0 -104
- package/dist/commands/auth/status.command.js.map +0 -1
- package/dist/commands/auth/use.command.d.ts +0 -17
- package/dist/commands/auth/use.command.d.ts.map +0 -1
- package/dist/commands/auth/use.command.js +0 -47
- package/dist/commands/auth/use.command.js.map +0 -1
- package/dist/commands/branding.command.d.ts +0 -3
- package/dist/commands/branding.command.d.ts.map +0 -1
- package/dist/commands/branding.command.js +0 -42
- package/dist/commands/branding.command.js.map +0 -1
- package/dist/commands/event.command.d.ts +0 -3
- package/dist/commands/event.command.d.ts.map +0 -1
- package/dist/commands/event.command.js +0 -27
- package/dist/commands/event.command.js.map +0 -1
- package/dist/commands/flag-init.command.d.ts +0 -13
- package/dist/commands/flag-init.command.d.ts.map +0 -1
- package/dist/commands/flag-init.command.js +0 -463
- package/dist/commands/flag-init.command.js.map +0 -1
- package/dist/commands/guide.command.d.ts +0 -61
- package/dist/commands/guide.command.d.ts.map +0 -1
- package/dist/commands/guide.command.js +0 -655
- package/dist/commands/guide.command.js.map +0 -1
- package/dist/commands/info.command.d.ts +0 -3
- package/dist/commands/info.command.d.ts.map +0 -1
- package/dist/commands/info.command.js +0 -70
- package/dist/commands/info.command.js.map +0 -1
- package/dist/commands/integration.command.d.ts +0 -35
- package/dist/commands/integration.command.d.ts.map +0 -1
- package/dist/commands/integration.command.js +0 -290
- package/dist/commands/integration.command.js.map +0 -1
- package/dist/commands/journeys.d.ts +0 -43
- package/dist/commands/journeys.d.ts.map +0 -1
- package/dist/commands/journeys.js +0 -221
- package/dist/commands/journeys.js.map +0 -1
- package/dist/commands/ops.command.d.ts +0 -17
- package/dist/commands/ops.command.d.ts.map +0 -1
- package/dist/commands/ops.command.js +0 -129
- package/dist/commands/ops.command.js.map +0 -1
- package/dist/commands/privilege.command.d.ts +0 -16
- package/dist/commands/privilege.command.d.ts.map +0 -1
- package/dist/commands/privilege.command.js +0 -86
- package/dist/commands/privilege.command.js.map +0 -1
- package/dist/commands/role.command.d.ts +0 -3
- package/dist/commands/role.command.d.ts.map +0 -1
- package/dist/commands/role.command.js +0 -101
- package/dist/commands/role.command.js.map +0 -1
- package/dist/commands/runtime-dir.d.ts +0 -16
- package/dist/commands/runtime-dir.d.ts.map +0 -1
- package/dist/commands/runtime-dir.js +0 -18
- package/dist/commands/runtime-dir.js.map +0 -1
- package/dist/commands/setup.command.d.ts +0 -63
- package/dist/commands/setup.command.d.ts.map +0 -1
- package/dist/commands/setup.command.js +0 -148
- package/dist/commands/setup.command.js.map +0 -1
- package/dist/commands/stripe.command.d.ts +0 -29
- package/dist/commands/stripe.command.d.ts.map +0 -1
- package/dist/commands/stripe.command.js +0 -99
- package/dist/commands/stripe.command.js.map +0 -1
- package/dist/commands/tenant.command.d.ts +0 -3
- package/dist/commands/tenant.command.d.ts.map +0 -1
- package/dist/commands/tenant.command.js +0 -135
- package/dist/commands/tenant.command.js.map +0 -1
- package/dist/commands/token.command.d.ts +0 -3
- package/dist/commands/token.command.d.ts.map +0 -1
- package/dist/commands/token.command.js +0 -54
- package/dist/commands/token.command.js.map +0 -1
- package/dist/commands/user.command.d.ts +0 -3
- package/dist/commands/user.command.d.ts.map +0 -1
- package/dist/commands/user.command.js +0 -117
- package/dist/commands/user.command.js.map +0 -1
- package/dist/credentials.d.ts +0 -141
- package/dist/credentials.d.ts.map +0 -1
- package/dist/credentials.js +0 -348
- package/dist/credentials.js.map +0 -1
- package/dist/flag-coherence.d.ts +0 -42
- package/dist/flag-coherence.d.ts.map +0 -1
- package/dist/flag-coherence.js +0 -103
- package/dist/flag-coherence.js.map +0 -1
- package/dist/output.d.ts +0 -17
- package/dist/output.d.ts.map +0 -1
- package/dist/output.js +0 -107
- package/dist/output.js.map +0 -1
- package/dist/preview.d.ts +0 -9
- package/dist/preview.d.ts.map +0 -1
- package/dist/preview.js +0 -63
- package/dist/preview.js.map +0 -1
- package/dist/product-decisions.d.ts +0 -40
- package/dist/product-decisions.d.ts.map +0 -1
- package/dist/product-decisions.js +0 -52
- package/dist/product-decisions.js.map +0 -1
- package/dist/prompt-urls.d.ts +0 -31
- package/dist/prompt-urls.d.ts.map +0 -1
- package/dist/prompt-urls.js +0 -35
- package/dist/prompt-urls.js.map +0 -1
- package/dist/prompts/auth-master-integration-prompt.md +0 -255
- package/dist/prompts/billing/master.md +0 -332
- package/dist/prompts/decisions/feature-control.md +0 -131
- package/dist/prompts/decisions/going-live.md +0 -60
- package/dist/prompts/decisions/login.md +0 -71
- package/dist/prompts/decisions/look-and-feel.md +0 -68
- package/dist/prompts/decisions/payments.md +0 -97
- package/dist/prompts/decisions/roles.md +0 -78
- package/dist/prompts/decisions/teams.md +0 -61
- package/dist/prompts/fit-together.md +0 -97
- package/dist/prompts/flags/master.md +0 -220
- package/dist/prompts/guide-coverage.json +0 -17
- package/dist/prompts/integration-success.md +0 -106
- package/dist/prompts/mcp-tools.json +0 -90
- package/dist/prompts/mechanisms.md +0 -304
- package/dist/prompts/orientation.md +0 -42
- package/dist/prompts/product-decisions.json +0 -338
- package/dist/resolve.d.ts +0 -110
- package/dist/resolve.d.ts.map +0 -1
- package/dist/resolve.js +0 -260
- package/dist/resolve.js.map +0 -1
- package/dist/shape.d.ts +0 -25
- package/dist/shape.d.ts.map +0 -1
- package/dist/shape.js +0 -74
- 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 +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 +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
|