@nebulr-group/bridge-cli 0.4.4 → 0.5.1-beta.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 (38) hide show
  1. package/README.md +67 -6
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +13 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/auth/logout.command.d.ts +10 -3
  6. package/dist/commands/auth/logout.command.d.ts.map +1 -1
  7. package/dist/commands/auth/logout.command.js +58 -18
  8. package/dist/commands/auth/logout.command.js.map +1 -1
  9. package/dist/commands/auth/status.command.d.ts +4 -0
  10. package/dist/commands/auth/status.command.d.ts.map +1 -1
  11. package/dist/commands/auth/status.command.js +50 -19
  12. package/dist/commands/auth/status.command.js.map +1 -1
  13. package/dist/commands/auth/use.command.d.ts +17 -0
  14. package/dist/commands/auth/use.command.d.ts.map +1 -0
  15. package/dist/commands/auth/use.command.js +47 -0
  16. package/dist/commands/auth/use.command.js.map +1 -0
  17. package/dist/commands/auth.command.d.ts +1 -0
  18. package/dist/commands/auth.command.d.ts.map +1 -1
  19. package/dist/commands/auth.command.js +3 -0
  20. package/dist/commands/auth.command.js.map +1 -1
  21. package/dist/commands/setup.command.d.ts +60 -0
  22. package/dist/commands/setup.command.d.ts.map +1 -1
  23. package/dist/commands/setup.command.js +129 -28
  24. package/dist/commands/setup.command.js.map +1 -1
  25. package/dist/commands/stripe.command.d.ts +36 -0
  26. package/dist/commands/stripe.command.d.ts.map +1 -1
  27. package/dist/commands/stripe.command.js +70 -14
  28. package/dist/commands/stripe.command.js.map +1 -1
  29. package/dist/config.d.ts +20 -13
  30. package/dist/config.d.ts.map +1 -1
  31. package/dist/config.js +120 -32
  32. package/dist/config.js.map +1 -1
  33. package/dist/credentials.d.ts +68 -5
  34. package/dist/credentials.d.ts.map +1 -1
  35. package/dist/credentials.js +202 -11
  36. package/dist/credentials.js.map +1 -1
  37. package/dist/prompts/billing/master.md +3 -0
  38. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"setup.command.d.ts","sourceRoot":"","sources":["../../src/commands/setup.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuD5D"}
1
+ {"version":3,"file":"setup.command.d.ts","sourceRoot":"","sources":["../../src/commands/setup.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAuB5C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWhB,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,aAAa,CAAC;AAS9D,sEAAsE;AACtE,qBAAa,UAAW,SAAQ,KAAK;IACN,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAtC,OAAO,EAAE,MAAM,EAAW,IAAI,EAAE,MAAM;CAInD;AASD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe;;;;;GA4CnD;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,yBAAyB;;;;;GA+BvE;AAKD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyC5D"}
@@ -1,25 +1,133 @@
1
+ import { Option } from 'commander';
1
2
  import { getManagementClient } from '../config.js';
2
3
  import { outputSuccess, outputError } from '../output.js';
4
+ /*
5
+ * TBP-663 — `setup sso` and `setup communication` talk to the app service
6
+ * (`app.updateCredentials` / `app.update` / `app.get`) directly instead of
7
+ * `workflows.setupSSO` / `workflows.setupCommunication`.
8
+ *
9
+ * Why not the workflows: in auth-core <= 0.7.0-beta.0 they send fields the
10
+ * API rejects under forbidNonWhitelisted — azure as `azureClientId`, saml/oidc
11
+ * as `samlMetadataUrl` / `oidcDiscoveryUrl`, email as `sendgridApiKey` — so
12
+ * both commands 400'd. auth-core main (#34) fixed them but changed their
13
+ * signatures and throws on the options this CLI used to pass. The app service
14
+ * has the same shape in both, so calling it with the server's own field names
15
+ * behaves identically whichever auth-core is installed.
16
+ *
17
+ * Field names are the server's: bridge-api
18
+ * microservices/account/nebulr-api/app/dto/update-credentials-request.dto.ts
19
+ * and update-app-request.dto.ts. Same table as auth-core's `setupSSO` and the
20
+ * MCP `setup_sso` tool. `setup-command.test.ts` pins them to those DTOs.
21
+ */
22
+ export const SSO_PROVIDERS = {
23
+ google: { clientId: 'googleClientId', clientSecret: 'googleClientSecret', enable: 'googleSsoEnabled' },
24
+ github: { clientId: 'githubClientId', clientSecret: 'githubClientSecret', enable: 'githubSsoEnabled' },
25
+ linkedin: { clientId: 'linkedinClientId', clientSecret: 'linkedinClientSecret', enable: 'linkedinSsoEnabled' },
26
+ facebook: { clientId: 'facebookClientId', clientSecret: 'facebookClientSecret', enable: 'facebookSsoEnabled' },
27
+ azure: {
28
+ clientId: 'microsoftAzureADClientId',
29
+ clientSecret: 'microsoftAzureADClientSecret',
30
+ tenantId: 'microsoftAzureADTenantId',
31
+ enable: 'azureAdSsoEnabled',
32
+ },
33
+ };
34
+ const SUPPORTED = Object.keys(SSO_PROVIDERS).join(', ');
35
+ const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
36
+ /** Carries a machine-readable `code`, which `outputError` reports. */
37
+ export class SetupError extends Error {
38
+ code;
39
+ constructor(message, code) {
40
+ super(message);
41
+ this.code = code;
42
+ this.name = 'SetupError';
43
+ }
44
+ }
45
+ const NOT_SAVED = ' Nothing was saved.';
46
+ const invalid = (message) => new SetupError(message + NOT_SAVED, 'INVALID_ARGUMENT');
47
+ function isSupported(provider) {
48
+ return Object.prototype.hasOwnProperty.call(SSO_PROVIDERS, provider);
49
+ }
50
+ export async function setupSso(opts) {
51
+ const provider = String(opts.provider).toLowerCase();
52
+ if (!isSupported(provider)) {
53
+ throw new SetupError(provider === 'saml' || provider === 'oidc'
54
+ ? `SSO provider "${provider}" is not supported by the Bridge API: it has no fields for SAML or OIDC ` +
55
+ `connections. Set them up in the Bridge admin UI. Supported here: ${SUPPORTED}.${NOT_SAVED}`
56
+ : `Unknown SSO provider "${provider}". Supported: ${SUPPORTED}.${NOT_SAVED}`, 'SSO_PROVIDER_NOT_SUPPORTED');
57
+ }
58
+ for (const [flag, value] of [['--metadata-url', opts.metadataUrl], ['--discovery-url', opts.discoveryUrl]]) {
59
+ if (value !== undefined) {
60
+ throw new SetupError(`${flag} was removed: the Bridge API has no field for it (SAML and OIDC are set up in the Bridge admin UI).${NOT_SAVED}`, 'SSO_PROVIDER_NOT_SUPPORTED');
61
+ }
62
+ }
63
+ if (!opts.clientId || !opts.clientSecret) {
64
+ throw invalid('--client-id and --client-secret are required (from the provider console).');
65
+ }
66
+ const fields = SSO_PROVIDERS[provider];
67
+ const credentials = {
68
+ [fields.clientId]: opts.clientId,
69
+ [fields.clientSecret]: opts.clientSecret,
70
+ };
71
+ if ('tenantId' in fields) {
72
+ if (!opts.tenantId) {
73
+ throw invalid('azure needs --tenant-id: the Directory (tenant) ID from the Entra ID app registration.');
74
+ }
75
+ credentials[fields.tenantId] = opts.tenantId;
76
+ }
77
+ else if (opts.tenantId !== undefined) {
78
+ throw invalid(`--tenant-id applies to azure only, not "${provider}".`);
79
+ }
80
+ const mgmt = getManagementClient();
81
+ await mgmt.app.updateCredentials(credentials);
82
+ const enable = { [fields.enable]: true };
83
+ await mgmt.app.update(enable);
84
+ const app = await mgmt.app.get();
85
+ return { provider, enabled: true, callbackUrl: app.defaultCallbackUri, app };
86
+ }
87
+ export async function setupCommunication(opts) {
88
+ if (opts.provider !== undefined || opts.apiKey !== undefined) {
89
+ throw new SetupError('--provider and --api-key were removed: Bridge sends all email through its own provider, so there is ' +
90
+ 'no provider or API key to configure (the Bridge API has never accepted one). ' +
91
+ `Pass only --from-address and/or --from-name.${NOT_SAVED}`, 'EMAIL_PROVIDER_NOT_SUPPORTED');
92
+ }
93
+ const { fromAddress, fromName } = opts;
94
+ if (fromAddress === undefined && fromName === undefined) {
95
+ throw invalid('Nothing to set: pass --from-address, --from-name, or both.');
96
+ }
97
+ if (fromAddress !== undefined && !EMAIL.test(fromAddress)) {
98
+ throw invalid('--from-address must be an email address, e.g. "no-reply@example.com".');
99
+ }
100
+ if (fromName !== undefined && fromName.trim() === '') {
101
+ throw invalid('--from-name must not be empty.');
102
+ }
103
+ const update = {};
104
+ if (fromAddress !== undefined)
105
+ update.emailSenderEmail = fromAddress;
106
+ if (fromName !== undefined)
107
+ update.emailSenderName = fromName;
108
+ const app = await getManagementClient().app.update(update);
109
+ return {
110
+ configured: true,
111
+ emailSenderEmail: app.emailSenderEmail ?? null,
112
+ emailSenderName: app.emailSenderName ?? null,
113
+ app,
114
+ };
115
+ }
116
+ /** Accepted only to refuse it with an explanation instead of commander's bare "unknown option". */
117
+ const removed = (flags, description) => new Option(flags, description).hideHelp();
3
118
  export function registerSetupCommands(program) {
4
119
  const setup = program.command('setup').description('Run setup workflows (multi-step operations)');
5
120
  setup.command('sso')
6
- .description('Enable an SSO provider and get callback URL')
7
- .requiredOption('--provider <provider>', 'SSO provider: google, azure, github, linkedin, facebook, saml, oidc')
8
- .option('--client-id <id>', 'OAuth client ID')
9
- .option('--client-secret <secret>', 'OAuth client secret')
10
- .option('--metadata-url <url>', 'SAML metadata URL')
11
- .option('--discovery-url <url>', 'OIDC discovery URL')
121
+ .description('Enable an SSO login provider and get the callback URL to register with it')
122
+ .requiredOption('--provider <provider>', `SSO provider: ${SUPPORTED} (SAML/OIDC are set up in the Bridge admin UI)`)
123
+ .requiredOption('--client-id <id>', 'OAuth client ID from the provider console')
124
+ .requiredOption('--client-secret <secret>', 'OAuth client secret from the provider console')
125
+ .option('--tenant-id <id>', 'azure only, required: Entra ID Directory (tenant) ID (not a Bridge tenant)')
126
+ .addOption(removed('--metadata-url <url>', 'removed: SAML is not supported by the Bridge API'))
127
+ .addOption(removed('--discovery-url <url>', 'removed: OIDC is not supported by the Bridge API'))
12
128
  .action(async (opts) => {
13
129
  try {
14
- outputSuccess(await getManagementClient().workflows.setupSSO({
15
- provider: opts.provider,
16
- config: {
17
- clientId: opts.clientId,
18
- clientSecret: opts.clientSecret,
19
- metadataUrl: opts.metadataUrl,
20
- discoveryUrl: opts.discoveryUrl,
21
- },
22
- }));
130
+ outputSuccess(await setupSso(opts));
23
131
  }
24
132
  catch (err) {
25
133
  outputError(err);
@@ -41,21 +149,14 @@ export function registerSetupCommands(program) {
41
149
  }
42
150
  });
43
151
  setup.command('communication')
44
- .description('Configure email/communication provider')
45
- .requiredOption('--provider <provider>', 'Provider name (e.g., sendgrid)')
46
- .requiredOption('--api-key <key>', 'Provider API key')
47
- .option('--from-address <email>', 'Sender email address')
48
- .option('--from-name <name>', 'Sender name')
152
+ .description("Set the sender name and address of your app's emails (sent through Bridge's own email provider)")
153
+ .option('--from-address <email>', 'Sender email address. A new address is verified by email before Bridge uses it')
154
+ .option('--from-name <name>', 'Sender display name')
155
+ .addOption(removed('--provider <provider>', 'removed: email goes through Bridge\'s own provider'))
156
+ .addOption(removed('--api-key <key>', 'removed: email goes through Bridge\'s own provider'))
49
157
  .action(async (opts) => {
50
158
  try {
51
- outputSuccess(await getManagementClient().workflows.setupCommunication({
52
- provider: opts.provider,
53
- config: {
54
- apiKey: opts.apiKey,
55
- fromAddress: opts.fromAddress,
56
- fromName: opts.fromName,
57
- },
58
- }));
159
+ outputSuccess(await setupCommunication(opts));
59
160
  }
60
161
  catch (err) {
61
162
  outputError(err);
@@ -1 +1 @@
1
- {"version":3,"file":"setup.command.js","sourceRoot":"","sources":["../../src/commands/setup.command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG1D,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,6CAA6C,CAAC,CAAC;IAElG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;SACjB,WAAW,CAAC,6CAA6C,CAAC;SAC1D,cAAc,CAAC,uBAAuB,EAAE,qEAAqE,CAAC;SAC9G,MAAM,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;SAC7C,MAAM,CAAC,0BAA0B,EAAE,qBAAqB,CAAC;SACzD,MAAM,CAAC,sBAAsB,EAAE,mBAAmB,CAAC;SACnD,MAAM,CAAC,uBAAuB,EAAE,oBAAoB,CAAC;SACrD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,aAAa,CAAC,MAAM,mBAAmB,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC;gBAC3D,QAAQ,EAAE,IAAI,CAAC,QAAuB;gBACtC,MAAM,EAAE;oBACN,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;iBAChC;aACF,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEL,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;SACtB,WAAW,CAAC,4CAA4C,CAAC;SACzD,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;SACzD,MAAM,CAAC,2BAA2B,EAAE,mBAAmB,CAAC;SACxD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,aAAa,CAAC,MAAM,mBAAmB,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC;gBAChE,eAAe,EAAE,IAAI,CAAC,SAAS;gBAC/B,eAAe,EAAE,IAAI,CAAC,eAAe;aACtC,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEL,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC;SAC3B,WAAW,CAAC,wCAAwC,CAAC;SACrD,cAAc,CAAC,uBAAuB,EAAE,gCAAgC,CAAC;SACzE,cAAc,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;SACrD,MAAM,CAAC,wBAAwB,EAAE,sBAAsB,CAAC;SACxD,MAAM,CAAC,oBAAoB,EAAE,aAAa,CAAC;SAC3C,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,aAAa,CAAC,MAAM,mBAAmB,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC;gBACrE,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,MAAM,EAAE;oBACN,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;iBACxB;aACF,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
+ {"version":3,"file":"setup.command.js","sourceRoot":"","sources":["../../src/commands/setup.command.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,39 @@
1
1
  import { Command } from 'commander';
2
+ export interface ServerCredentialsState {
3
+ stripeCredentialsAdded: boolean;
4
+ /** TBP-658. Optional: older account APIs do not send it. */
5
+ stripeWebhookConfigured?: boolean;
6
+ azureMarketplaceCredentialsAdded: boolean;
7
+ azureAdSsoCredentialsAdded: boolean;
8
+ linkedinSsoCredentialsAdded: boolean;
9
+ googleSsoCredentialsAdded: boolean;
10
+ appleSsoCredentialsAdded: boolean;
11
+ githubSsoCredentialsAdded: boolean;
12
+ facebookSsoCredentialsAdded: boolean;
13
+ }
14
+ /** Webhook health fields on the app response (TBP-658). All optional: older APIs omit them. */
15
+ export interface ServerAppStripeState {
16
+ stripeSetupStatus?: 'pending' | 'completed' | 'failed' | null;
17
+ stripeSetupError?: string | null;
18
+ stripeLastWebhookAt?: string | null;
19
+ stripeLastWebhookRejectedAt?: string | null;
20
+ stripeLastWebhookRejectionReason?: string | null;
21
+ }
22
+ /** `true` only when the server confirms stored Stripe keys; never undefined. */
23
+ export declare function stripeConnectedFrom(state: unknown): boolean;
24
+ /** `null` when the API does not report it (older account API), so absence is not read as broken. */
25
+ export declare function stripeWebhookConfiguredFrom(state: unknown): boolean | null;
26
+ export interface StripeStatus {
27
+ connected: boolean;
28
+ webhookConfigured: boolean | null;
29
+ webhookHealthy: boolean | null;
30
+ lastWebhookAt: string | null;
31
+ lastWebhookRejectedAt: string | null;
32
+ lastWebhookRejectionReason: string | null;
33
+ setupStatus: string | null;
34
+ setupError: string | null;
35
+ message: string;
36
+ }
37
+ export declare function stripeStatusFrom(state: unknown, app: unknown): StripeStatus;
2
38
  export declare function registerStripeCommands(program: Command): void;
3
39
  //# sourceMappingURL=stripe.command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stripe.command.d.ts","sourceRoot":"","sources":["../../src/commands/stripe.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmC7D"}
1
+ {"version":3,"file":"stripe.command.d.ts","sourceRoot":"","sources":["../../src/commands/stripe.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,MAAM,WAAW,sBAAsB;IACrC,sBAAsB,EAAE,OAAO,CAAC;IAChC,4DAA4D;IAC5D,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,gCAAgC,EAAE,OAAO,CAAC;IAC1C,0BAA0B,EAAE,OAAO,CAAC;IACpC,2BAA2B,EAAE,OAAO,CAAC;IACrC,yBAAyB,EAAE,OAAO,CAAC;IACnC,wBAAwB,EAAE,OAAO,CAAC;IAClC,yBAAyB,EAAE,OAAO,CAAC;IACnC,2BAA2B,EAAE,OAAO,CAAC;CACtC;AAED,+FAA+F;AAC/F,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC9D,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,2BAA2B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,gCAAgC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClD;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE3D;AAED,oGAAoG;AACpG,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAG1E;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAyBD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,YAAY,CAuB3E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqC7D"}
@@ -1,18 +1,71 @@
1
1
  import { getManagementClient } from '../config.js';
2
2
  import { outputSuccess, outputError } from '../output.js';
3
+ /** `true` only when the server confirms stored Stripe keys; never undefined. */
4
+ export function stripeConnectedFrom(state) {
5
+ return state?.stripeCredentialsAdded === true;
6
+ }
7
+ /** `null` when the API does not report it (older account API), so absence is not read as broken. */
8
+ export function stripeWebhookConfiguredFrom(state) {
9
+ const value = state?.stripeWebhookConfigured;
10
+ return typeof value === 'boolean' ? value : null;
11
+ }
12
+ const CONNECT_HINT = 'run: bridge stripe connect --secret-key sk_... --publishable-key pk_...';
13
+ const REPAIR_HINT = 'Checkout still works, but subscription changes, cancellations and payment failures are not ' +
14
+ 'reaching Bridge. Repair: re-run `bridge setup payments` with the same keys, or use "Repair ' +
15
+ 'webhook" in the Bridge admin payment settings.';
16
+ /*
17
+ * Mirrors bridge-api's `AppService._stripeWebhookUnhealthy` plus the two
18
+ * explicit failure signals. `null` = the API gave us nothing to judge by.
19
+ */
20
+ function webhookHealthy(configured, app) {
21
+ if (configured === false || app.stripeSetupStatus === 'failed')
22
+ return false;
23
+ const rejectedAt = app.stripeLastWebhookRejectedAt;
24
+ if (rejectedAt) {
25
+ const lastAt = app.stripeLastWebhookAt;
26
+ if (!lastAt || new Date(rejectedAt).getTime() > new Date(lastAt).getTime())
27
+ return false;
28
+ }
29
+ return configured;
30
+ }
31
+ export function stripeStatusFrom(state, app) {
32
+ const a = (app ?? {});
33
+ const connected = stripeConnectedFrom(state);
34
+ const webhookConfigured = stripeWebhookConfiguredFrom(state);
35
+ const healthy = connected ? webhookHealthy(webhookConfigured, a) : null;
36
+ let message;
37
+ if (!connected)
38
+ message = `Stripe is not connected — ${CONNECT_HINT}`;
39
+ else if (healthy === false)
40
+ message = `Stripe is connected, but its webhook is not working. ${REPAIR_HINT}`;
41
+ else if (healthy === null)
42
+ message = 'Stripe is connected (webhook health not reported by this API)';
43
+ else
44
+ message = 'Stripe is connected and its webhook is configured';
45
+ return {
46
+ connected,
47
+ webhookConfigured,
48
+ webhookHealthy: healthy,
49
+ lastWebhookAt: a.stripeLastWebhookAt ?? null,
50
+ lastWebhookRejectedAt: a.stripeLastWebhookRejectedAt ?? null,
51
+ lastWebhookRejectionReason: a.stripeLastWebhookRejectionReason ?? null,
52
+ setupStatus: a.stripeSetupStatus ?? null,
53
+ setupError: a.stripeSetupError ?? null,
54
+ message,
55
+ };
56
+ }
3
57
  export function registerStripeCommands(program) {
4
58
  const stripe = program.command('stripe').description('Manage Stripe integration');
5
59
  stripe.command('status')
6
- .description('Show whether Stripe credentials are configured')
60
+ .description('Show whether Stripe credentials are configured and whether its webhook works')
7
61
  .action(async () => {
8
62
  try {
9
- const state = await getManagementClient().app.getCredentialsState();
10
- outputSuccess({
11
- connected: state.hasStripeCredentials,
12
- message: state.hasStripeCredentials
13
- ? 'Stripe is connected'
14
- : 'Stripe is not connected — run: bridge stripe connect --secret-key sk_... --publishable-key pk_...',
15
- });
63
+ const client = getManagementClient();
64
+ const [state, app] = await Promise.all([
65
+ client.app.getCredentialsState(),
66
+ client.app.get(),
67
+ ]);
68
+ outputSuccess(stripeStatusFrom(state, app));
16
69
  }
17
70
  catch (err) {
18
71
  outputError(err);
@@ -28,12 +81,15 @@ export function registerStripeCommands(program) {
28
81
  stripeSecretKey: opts.secretKey,
29
82
  stripePublicKey: opts.publishableKey,
30
83
  });
31
- outputSuccess({
32
- connected: state.hasStripeCredentials,
33
- message: state.hasStripeCredentials
34
- ? 'Stripe connected successfully'
35
- : 'Credentials saved but Stripe did not confirm — check your keys and try again',
36
- });
84
+ const connected = stripeConnectedFrom(state);
85
+ const webhookConfigured = stripeWebhookConfiguredFrom(state);
86
+ let message = connected
87
+ ? 'Stripe connected successfully'
88
+ : 'Credentials saved but Stripe did not confirm — check your keys and try again';
89
+ if (connected && webhookConfigured === false) {
90
+ message += '. Warning: the Stripe webhook is not configured — run `bridge stripe status` for details';
91
+ }
92
+ outputSuccess({ connected, webhookConfigured, message });
37
93
  }
38
94
  catch (err) {
39
95
  outputError(err);
@@ -1 +1 @@
1
- {"version":3,"file":"stripe.command.js","sourceRoot":"","sources":["../../src/commands/stripe.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,sBAAsB,CAAC,OAAgB;IACrD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC;IAElF,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;SACrB,WAAW,CAAC,gDAAgD,CAAC;SAC7D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;YACpE,aAAa,CAAC;gBACZ,SAAS,EAAE,KAAK,CAAC,oBAAoB;gBACrC,OAAO,EAAE,KAAK,CAAC,oBAAoB;oBACjC,CAAC,CAAC,qBAAqB;oBACvB,CAAC,CAAC,mGAAmG;aACxG,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEL,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SACtB,WAAW,CAAC,4BAA4B,CAAC;SACzC,cAAc,CAAC,oBAAoB,EAAE,gDAAgD,CAAC;SACtF,cAAc,CAAC,yBAAyB,EAAE,qDAAqD,CAAC;SAChG,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC;gBAC9D,eAAe,EAAE,IAAI,CAAC,SAAS;gBAC/B,eAAe,EAAE,IAAI,CAAC,cAAc;aACrC,CAAC,CAAC;YACH,aAAa,CAAC;gBACZ,SAAS,EAAE,KAAK,CAAC,oBAAoB;gBACrC,OAAO,EAAE,KAAK,CAAC,oBAAoB;oBACjC,CAAC,CAAC,+BAA+B;oBACjC,CAAC,CAAC,8EAA8E;aACnF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"stripe.command.js","sourceRoot":"","sources":["../../src/commands/stripe.command.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,22 +1,29 @@
1
1
  import { BridgeManagement } from '@nebulr-group/bridge-auth-core';
2
2
  export declare const DEFAULT_BASE_URL = "https://api.thebridge.dev";
3
+ /** Called once from the CLI entrypoint, before any action runs. */
4
+ export declare function setProfileOverride(profile: string | null | undefined): void;
3
5
  /**
4
6
  * Resolution order:
5
- * 1. `~/.config/bridge/credentials.json` (or `$XDG_CONFIG_HOME/bridge/credentials.json`)
6
- * written by `bridge auth login`. The interactive primary path. Token
7
- * carries the appId baked in by /v1/auth/cli/token, so post-login the
8
- * JWT is the source of truth for which app the CLI operates on.
9
- * 2. `BRIDGE_API_KEY` env var (CI / service-account fallback). Used when no
10
- * credentials file exists typical CI runner shape.
11
- * 3. Throw `ConfigError("Not logged in. Run `bridge auth login`.")`.
7
+ * 1. `--profile <label|id|name>` / `BRIDGE_PROFILE` a stored credential,
8
+ * named for this one invocation. Never falls back: naming a profile and
9
+ * silently getting a different app is the exact failure TBP-628 exists to
10
+ * stop, so an unknown or expired profile is an error.
11
+ * 2. The ACTIVE credential in `~/.config/bridge/credentials.json` (or
12
+ * `$XDG_CONFIG_HOME/...`), written by `bridge auth login` and moved by
13
+ * `bridge auth use`.
14
+ * 3. `BRIDGE_API_KEY` env var (CI / service-account fallback). Used when no
15
+ * usable credentials file exists — the typical CI runner shape.
16
+ * 4. Throw `ConfigError("Not logged in. Run `bridge auth login`.")`.
12
17
  *
13
- * Note: credentials-file wins over env so `bridge auth login` does what users
14
- * expect the new login takes effect immediately. CI is unaffected because
15
- * runners typically have no credentials file and fall through to step 2.
18
+ * The credentials file still wins over `BRIDGE_API_KEY`, unchanged, so
19
+ * `bridge auth login` takes effect immediately and CI is unaffected. What HAS
20
+ * changed is that being ignored is now said out loud: `BRIDGE_API_KEY` and
21
+ * `BRIDGE_APP_ID` look like a way to retarget the CLI and are not, and reading
22
+ * that in the output beats discovering it from a write that went to the wrong
23
+ * app (TBP-628).
16
24
  *
17
- * If a credentials file exists but its `expiresAt` is in the past, we fall
18
- * through to env (if set) — same as if there were no file. Otherwise throw a
19
- * friendly error pointing the user back to `bridge auth login`.
25
+ * Every resolution also prints one line to stderr naming the app that is about
26
+ * to answer. See `writeContextBanner`.
20
27
  */
21
28
  export declare function getManagementClient(): BridgeManagement;
22
29
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAGlE,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAI5D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CA+CtD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQnE;AAED,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AASlE,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAa5D,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAE3E;AAQD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CA0EtD;AAoDD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQnE;AAED,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B"}
package/dist/config.js CHANGED
@@ -1,24 +1,47 @@
1
1
  import { BridgeManagement } from '@nebulr-group/bridge-auth-core';
2
- import { isExpired, readCredentials } from './credentials.js';
2
+ import { CredentialSelectorError, findCredential, isExpired, readCredentials, } from './credentials.js';
3
3
  export const DEFAULT_BASE_URL = 'https://api.thebridge.dev';
4
4
  let _client = null;
5
+ /**
6
+ * The `--profile` value for this invocation, set by the CLI's preAction hook.
7
+ *
8
+ * A per-invocation override rather than a persisted switch, because that is
9
+ * what scripts and long-running agent sessions need: target one app for one
10
+ * command without mutating state another process is reading (TBP-628).
11
+ */
12
+ let _profileOverride = null;
13
+ /** Called once from the CLI entrypoint, before any action runs. */
14
+ export function setProfileOverride(profile) {
15
+ _profileOverride = profile?.trim() || null;
16
+ }
17
+ /** The profile in force: `--profile` beats `BRIDGE_PROFILE`. */
18
+ function activeProfileSelector() {
19
+ if (_profileOverride)
20
+ return _profileOverride;
21
+ return process.env.BRIDGE_PROFILE?.trim() || null;
22
+ }
5
23
  /**
6
24
  * Resolution order:
7
- * 1. `~/.config/bridge/credentials.json` (or `$XDG_CONFIG_HOME/bridge/credentials.json`)
8
- * written by `bridge auth login`. The interactive primary path. Token
9
- * carries the appId baked in by /v1/auth/cli/token, so post-login the
10
- * JWT is the source of truth for which app the CLI operates on.
11
- * 2. `BRIDGE_API_KEY` env var (CI / service-account fallback). Used when no
12
- * credentials file exists typical CI runner shape.
13
- * 3. Throw `ConfigError("Not logged in. Run `bridge auth login`.")`.
25
+ * 1. `--profile <label|id|name>` / `BRIDGE_PROFILE` a stored credential,
26
+ * named for this one invocation. Never falls back: naming a profile and
27
+ * silently getting a different app is the exact failure TBP-628 exists to
28
+ * stop, so an unknown or expired profile is an error.
29
+ * 2. The ACTIVE credential in `~/.config/bridge/credentials.json` (or
30
+ * `$XDG_CONFIG_HOME/...`), written by `bridge auth login` and moved by
31
+ * `bridge auth use`.
32
+ * 3. `BRIDGE_API_KEY` env var (CI / service-account fallback). Used when no
33
+ * usable credentials file exists — the typical CI runner shape.
34
+ * 4. Throw `ConfigError("Not logged in. Run `bridge auth login`.")`.
14
35
  *
15
- * Note: credentials-file wins over env so `bridge auth login` does what users
16
- * expect the new login takes effect immediately. CI is unaffected because
17
- * runners typically have no credentials file and fall through to step 2.
36
+ * The credentials file still wins over `BRIDGE_API_KEY`, unchanged, so
37
+ * `bridge auth login` takes effect immediately and CI is unaffected. What HAS
38
+ * changed is that being ignored is now said out loud: `BRIDGE_API_KEY` and
39
+ * `BRIDGE_APP_ID` look like a way to retarget the CLI and are not, and reading
40
+ * that in the output beats discovering it from a write that went to the wrong
41
+ * app (TBP-628).
18
42
  *
19
- * If a credentials file exists but its `expiresAt` is in the past, we fall
20
- * through to env (if set) — same as if there were no file. Otherwise throw a
21
- * friendly error pointing the user back to `bridge auth login`.
43
+ * Every resolution also prints one line to stderr naming the app that is about
44
+ * to answer. See `writeContextBanner`.
22
45
  */
23
46
  export function getManagementClient() {
24
47
  if (_client)
@@ -29,29 +52,56 @@ export function getManagementClient() {
29
52
  let apiKey;
30
53
  let baseUrl;
31
54
  let source;
32
- // 1. Credentials file from `bridge auth login` (interactive primary).
33
- const creds = safeReadCredentials();
34
- if (creds && !isExpired(creds)) {
55
+ let creds = null;
56
+ const selector = activeProfileSelector();
57
+ if (selector) {
58
+ // 1. Explicit profile. Resolve it or fail — no fallback of any kind.
59
+ let entry;
60
+ try {
61
+ entry = findCredential(selector);
62
+ }
63
+ catch (err) {
64
+ if (err instanceof CredentialSelectorError)
65
+ throw new ConfigError(err.message);
66
+ throw err;
67
+ }
68
+ if (isExpired(entry.creds)) {
69
+ throw new ConfigError(`Credential for "${selector}" (${entry.creds.app.name}) expired ` +
70
+ `${entry.creds.expiresAt}. Run \`bridge auth login\` to re-authenticate it. ` +
71
+ 'Refusing to fall back to another app.');
72
+ }
73
+ creds = entry.creds;
35
74
  apiKey = creds.apiKey;
36
- // Env override still wins for baseUrl (useful for hitting a local bridge-api
37
- // with a token issued by prod, or vice versa during dev).
38
75
  baseUrl = envBaseUrl && envBaseUrl.length > 0 ? envBaseUrl : creds.baseUrl;
39
- source = 'credentials-file';
40
- }
41
- else if (envApiKey && envApiKey.length > 0) {
42
- // 2. BRIDGE_API_KEY env var (CI / service-account fallback).
43
- apiKey = envApiKey;
44
- baseUrl = envBaseUrl && envBaseUrl.length > 0 ? envBaseUrl : DEFAULT_BASE_URL;
45
- source = 'env';
46
- }
47
- else if (creds && isExpired(creds)) {
48
- // 3a. Found a credentials file but token expired; no env fallback either.
49
- throw new ConfigError('Token expired. Run `bridge auth login` to re-authenticate.');
76
+ source = 'profile';
50
77
  }
51
78
  else {
52
- // 3b. No credentials at all.
53
- throw new ConfigError('Not logged in. Run `bridge auth login`.');
79
+ // 2. Active credential from `bridge auth login` / `bridge auth use`.
80
+ const active = safeReadCredentials();
81
+ if (active && !isExpired(active)) {
82
+ creds = active;
83
+ apiKey = active.apiKey;
84
+ // Env override still wins for baseUrl (useful for hitting a local
85
+ // bridge-api with a token issued by prod, or vice versa during dev).
86
+ baseUrl = envBaseUrl && envBaseUrl.length > 0 ? envBaseUrl : active.baseUrl;
87
+ source = 'credentials-file';
88
+ }
89
+ else if (envApiKey && envApiKey.length > 0) {
90
+ // 3. BRIDGE_API_KEY env var (CI / service-account fallback).
91
+ apiKey = envApiKey;
92
+ baseUrl = envBaseUrl && envBaseUrl.length > 0 ? envBaseUrl : DEFAULT_BASE_URL;
93
+ source = 'env';
94
+ }
95
+ else if (active && isExpired(active)) {
96
+ // 4a. Found a credentials file but token expired; no env fallback either.
97
+ throw new ConfigError('Token expired. Run `bridge auth login` to re-authenticate.');
98
+ }
99
+ else {
100
+ // 4b. No credentials at all.
101
+ throw new ConfigError('Not logged in. Run `bridge auth login`.');
102
+ }
54
103
  }
104
+ writeContextBanner({ creds, source, baseUrl, selector });
55
105
  if (debug) {
56
106
  const baseSource = envBaseUrl && envBaseUrl.length > 0
57
107
  ? 'env'
@@ -63,6 +113,44 @@ export function getManagementClient() {
63
113
  _client = new BridgeManagement({ apiKey, baseUrl, debug });
64
114
  return _client;
65
115
  }
116
+ /**
117
+ * One line on stderr naming the app that is about to answer.
118
+ *
119
+ * On EVERY command, not only writes. The incident behind TBP-628 started with a
120
+ * read: `bridge role list` was believed to describe the local app and described
121
+ * production, and nothing in the output said otherwise. A banner that only
122
+ * appears on writes would not have prevented it, because the wrong belief was
123
+ * already formed by then.
124
+ *
125
+ * stderr, so stdout stays pure JSON for the agents and scripts that parse it.
126
+ * Suppress with `BRIDGE_NO_BANNER=true` — for the one caller who is already
127
+ * certain and is merging the two streams.
128
+ */
129
+ function writeContextBanner(ctx) {
130
+ if (process.env.BRIDGE_NO_BANNER === 'true')
131
+ return;
132
+ const { creds, source, baseUrl, selector } = ctx;
133
+ const who = creds
134
+ ? `${creds.label ?? creds.app.name} (${creds.app.id})`
135
+ : 'BRIDGE_API_KEY (app unknown — the key carries it)';
136
+ const via = source === 'profile'
137
+ ? `--profile ${selector}`
138
+ : source === 'env'
139
+ ? 'BRIDGE_API_KEY'
140
+ : 'saved default';
141
+ process.stderr.write(`bridge: ${who} · ${baseUrl} · via ${via}\n`);
142
+ // The two env vars that look like a way to retarget the CLI and are not.
143
+ // Saying so here, at the moment they are being ignored, is the whole point:
144
+ // the reported incident was a session that set them and believed them.
145
+ if (source !== 'env' && process.env.BRIDGE_API_KEY?.trim()) {
146
+ process.stderr.write('bridge: BRIDGE_API_KEY is set but IGNORED — the credentials file wins. ' +
147
+ 'Use `--profile <label>` to pick a stored app, or `bridge auth logout` to use the key.\n');
148
+ }
149
+ if (process.env.BRIDGE_APP_ID?.trim()) {
150
+ process.stderr.write('bridge: BRIDGE_APP_ID has no effect — the app is carried by the credential itself. ' +
151
+ 'Use `--profile <label|app id>` or `BRIDGE_PROFILE` to target another app.\n');
152
+ }
153
+ }
66
154
  /**
67
155
  * For tests and for `bridge auth logout` / `bridge auth status` — they need
68
156
  * to reset the cached client between operations.
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,SAAS,EACT,eAAe,GAEhB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,CAAC,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AAE5D,IAAI,OAAO,GAA4B,IAAI,CAAC;AAE5C;;;;;;GAMG;AACH,IAAI,gBAAgB,GAAkB,IAAI,CAAC;AAE3C,mEAAmE;AACnE,MAAM,UAAU,kBAAkB,CAAC,OAAkC;IACnE,gBAAgB,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED,gEAAgE;AAChE,SAAS,qBAAqB;IAC5B,IAAI,gBAAgB;QAAE,OAAO,gBAAgB,CAAC;IAC9C,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,MAAM,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IACrD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAEvD,IAAI,MAAc,CAAC;IACnB,IAAI,OAAe,CAAC;IACpB,IAAI,MAAc,CAAC;IACnB,IAAI,KAAK,GAA6B,IAAI,CAAC;IAE3C,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;IACzC,IAAI,QAAQ,EAAE,CAAC;QACb,qEAAqE;QACrE,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,uBAAuB;gBAAE,MAAM,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC/E,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,WAAW,CACnB,mBAAmB,QAAQ,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,YAAY;gBAC/D,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,qDAAqD;gBAC7E,uCAAuC,CAC1C,CAAC;QACJ,CAAC;QACD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACpB,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACtB,OAAO,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QAC3E,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,qEAAqE;QACrE,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;QACrC,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,KAAK,GAAG,MAAM,CAAC;YACf,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YACvB,kEAAkE;YAClE,qEAAqE;YACrE,OAAO,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YAC5E,MAAM,GAAG,kBAAkB,CAAC;QAC9B,CAAC;aAAM,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,6DAA6D;YAC7D,MAAM,GAAG,SAAS,CAAC;YACnB,OAAO,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC;YAC9E,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC;aAAM,IAAI,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,0EAA0E;YAC1E,MAAM,IAAI,WAAW,CACnB,4DAA4D,CAC7D,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,6BAA6B;YAC7B,MAAM,IAAI,WAAW,CAAC,yCAAyC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,kBAAkB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEzD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,UAAU,GACd,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YACjC,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,MAAM,KAAK,KAAK;gBAChB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,kBAAkB,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,sCAAsC,MAAM,aAAa,OAAO,KAAK,UAAU,GAAG,CAAC,CAAC;IACpG,CAAC;IAED,OAAO,GAAG,IAAI,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAE3D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,kBAAkB,CAAC,GAK3B;IACC,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM;QAAE,OAAO;IAEpD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;IACjD,MAAM,GAAG,GAAG,KAAK;QACf,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG;QACtD,CAAC,CAAC,mDAAmD,CAAC;IACxD,MAAM,GAAG,GACP,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,aAAa,QAAQ,EAAE;QACzB,CAAC,CAAC,MAAM,KAAK,KAAK;YAChB,CAAC,CAAC,gBAAgB;YAClB,CAAC,CAAC,eAAe,CAAC;IACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,OAAO,UAAU,GAAG,IAAI,CAAC,CAAC;IAEnE,yEAAyE;IACzE,4EAA4E;IAC5E,uEAAuE;IACvE,IAAI,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yEAAyE;YACvE,yFAAyF,CAC5F,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qFAAqF;YACnF,6EAA6E,CAChF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAA2B;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC/D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,WAAW,CACnB,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;;;;GAIG;AACH,SAAS,mBAAmB;IAC1B,IAAI,CAAC;QACH,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,WAAW,CACnB,oCAAoC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI;YACtF,kEAAkE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC"}