@almadar/integrations 2.6.3 → 2.8.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.
@@ -135,4 +135,4 @@ declare abstract class BaseIntegration {
135
135
  protected executeWithRetry<T>(fn: () => Promise<T>): Promise<T>;
136
136
  }
137
137
 
138
- export { BaseIntegration as B, type IntegrationParams as I, type ValidationError as V, type IntegrationLogger as a, type IntegrationErrorCode as b, type IntegrationConfig as c, type IntegrationResult as d, IntegrationError as e, type ValidationResult as f, validateParams as v };
138
+ export { BaseIntegration as B, type IntegrationConfig as I, type ValidationError as V, IntegrationError as a, type IntegrationErrorCode as b, type IntegrationLogger as c, type IntegrationParams as d, type IntegrationResult as e, type ValidationResult as f, validateParams as v };
@@ -1,4 +1,4 @@
1
- import { c as IntegrationConfig, B as BaseIntegration, I as IntegrationParams, d as IntegrationResult } from './BaseIntegration-DjXCkytU.js';
1
+ import { I as IntegrationConfig, B as BaseIntegration, d as IntegrationParams, e as IntegrationResult } from './BaseIntegration-d17YX8KE.js';
2
2
 
3
3
  /**
4
4
  * Factory for creating and managing integration instances
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { I as IntegrationParams, a as IntegrationLogger, b as IntegrationErrorCode, c as IntegrationConfig, B as BaseIntegration, d as IntegrationResult } from './BaseIntegration-DjXCkytU.js';
2
- export { e as IntegrationError, V as ValidationError, f as ValidationResult, v as validateParams } from './BaseIntegration-DjXCkytU.js';
3
- import { LogMeta } from '@almadar/core';
4
- export { I as IntegrationFactory, g as getIntegrationFactory, r as resetIntegrationFactory } from './factory-BoDqQ89e.js';
1
+ import { d as IntegrationParams, c as IntegrationLogger, b as IntegrationErrorCode, I as IntegrationConfig, B as BaseIntegration, e as IntegrationResult } from './BaseIntegration-d17YX8KE.js';
2
+ export { a as IntegrationError, V as ValidationError, f as ValidationResult, v as validateParams } from './BaseIntegration-d17YX8KE.js';
3
+ import { ServiceParams, LogMeta } from '@almadar/core';
4
+ export { I as IntegrationFactory, g as getIntegrationFactory, r as resetIntegrationFactory } from './factory-BcFFy4JA.js';
5
5
  export { GitHubIntegration } from './integrations/github/index.js';
6
6
 
7
7
  /**
@@ -385,7 +385,7 @@ type StorageActions = {
385
385
  params: {
386
386
  bucket: string;
387
387
  key: string;
388
- content: unknown;
388
+ content: string;
389
389
  contentType?: string;
390
390
  metadata?: IntegrationParams;
391
391
  };
@@ -402,7 +402,7 @@ type StorageActions = {
402
402
  key: string;
403
403
  };
404
404
  result: {
405
- content: unknown;
405
+ content: string;
406
406
  contentType: string;
407
407
  size: number;
408
408
  metadata: IntegrationParams;
@@ -449,7 +449,7 @@ type QueueActions = {
449
449
  enqueue: {
450
450
  params: {
451
451
  queue: string;
452
- payload: unknown;
452
+ payload: ServiceParams;
453
453
  delay?: number;
454
454
  priority?: number;
455
455
  };
@@ -465,7 +465,7 @@ type QueueActions = {
465
465
  result: {
466
466
  job: {
467
467
  id: string;
468
- payload: unknown;
468
+ payload: ServiceParams;
469
469
  enqueuedAt: number;
470
470
  priority: number;
471
471
  } | null;
@@ -479,7 +479,7 @@ type QueueActions = {
479
479
  status: 'pending' | 'processing' | 'completed' | 'failed';
480
480
  job: {
481
481
  id: string;
482
- payload: unknown;
482
+ payload: ServiceParams;
483
483
  enqueuedAt: number;
484
484
  priority: number;
485
485
  } | null;
@@ -488,7 +488,7 @@ type QueueActions = {
488
488
  complete: {
489
489
  params: {
490
490
  jobId: string;
491
- result?: unknown;
491
+ result?: ServiceParams;
492
492
  };
493
493
  result: {
494
494
  completed: boolean;
@@ -528,13 +528,13 @@ type RedisActions = {
528
528
  key: string;
529
529
  };
530
530
  result: {
531
- value: unknown;
531
+ value: ServiceParams;
532
532
  };
533
533
  };
534
534
  set: {
535
535
  params: {
536
536
  key: string;
537
- value: unknown;
537
+ value: ServiceParams;
538
538
  ttl?: number;
539
539
  };
540
540
  result: {
@@ -589,7 +589,7 @@ type RedisActions = {
589
589
  publish: {
590
590
  params: {
591
591
  channel: string;
592
- message: unknown;
592
+ message: ServiceParams;
593
593
  };
594
594
  result: {
595
595
  receivers: number;
@@ -833,16 +833,24 @@ type IntegrationName = keyof IntegrationContracts;
833
833
  type IntegrationActionName<K extends IntegrationName> = keyof IntegrationContracts[K] & string;
834
834
 
835
835
  /**
836
- * Console-based logger implementation
836
+ * Console-based logger implementation.
837
+ *
838
+ * Routes through `@almadar/logger`'s shared gate so namespace filtering
839
+ * (`ALMADAR_DEBUG`, `globalThis.__ALMADAR_DEBUG__`) and the production
840
+ * level default (WARN+) apply uniformly with the rest of `@almadar/*`.
841
+ *
842
+ * The constructor's `level` argument is retained for backwards
843
+ * compatibility but is now a no-op — the active level is owned by the
844
+ * shared logger (compile-time + env). To filter integration logs at
845
+ * runtime, set `globalThis.__ALMADAR_DEBUG__ = 'almadar:integrations:*'`.
837
846
  */
838
847
  declare class ConsoleLogger implements IntegrationLogger {
839
- private level;
840
- constructor(level?: 'debug' | 'info' | 'warn' | 'error');
848
+ private readonly log;
849
+ constructor(_level?: 'debug' | 'info' | 'warn' | 'error');
841
850
  debug(message: string, meta?: LogMeta): void;
842
851
  info(message: string, meta?: LogMeta): void;
843
852
  warn(message: string, meta?: LogMeta): void;
844
853
  error(message: string, meta?: LogMeta): void;
845
- private shouldLog;
846
854
  }
847
855
 
848
856
  /**
@@ -881,15 +889,245 @@ declare function isKnownIntegration(name: string): boolean;
881
889
  declare function getRegisteredIntegrations(): string[];
882
890
 
883
891
  /**
884
- * Stripe integration for payment processing
892
+ * Canonical Almadar shapes for the Stripe integration.
893
+ *
894
+ * Consumers (apps/builder server, future apps) MUST consume these
895
+ * canonical types — never raw `Stripe.*` shapes from the `stripe` SDK.
896
+ * The `apps/builder is an assembler` rule applies inbound webhooks as
897
+ * well as outbound actions: parse, narrow, and re-shape at this layer
898
+ * so the SDK version never appears in apps/builder code.
899
+ *
900
+ * Mirrors the pattern used by the GitHub integration (PR / Issue / Repo
901
+ * canonical shapes in `./github/types.ts`).
902
+ */
903
+ /** Almadar-level tier identifier; mirrors `apps/builder` `TierKey`. */
904
+ type AlmadarTier = 'free' | 'solo' | 'teams';
905
+ /** Subscription status mapped from Stripe's lifecycle. */
906
+ type AlmadarSubscriptionStatus = 'active' | 'past_due' | 'canceled' | 'incomplete' | 'incomplete_expired' | 'trialing' | 'unpaid';
907
+ interface AlmadarCustomer {
908
+ customerId: string;
909
+ email: string | null;
910
+ /** `users/{uid}` reference stored as Stripe metadata for webhook resolution. */
911
+ almadarUid: string | null;
912
+ }
913
+ interface AlmadarSubscription {
914
+ subscriptionId: string;
915
+ customerId: string;
916
+ status: AlmadarSubscriptionStatus;
917
+ /** Stripe Price ID currently attached. */
918
+ priceId: string;
919
+ /** Seats / quantity (Solo=1, Teams=N). */
920
+ quantity: number;
921
+ /** Period boundaries in ISO timestamps. */
922
+ currentPeriodStart: string;
923
+ currentPeriodEnd: string;
924
+ cancelAtPeriodEnd: boolean;
925
+ /** Resolved tier from the price ID. `null` if price doesn't match a known tier. */
926
+ tier: AlmadarTier | null;
927
+ }
928
+ interface AlmadarCheckoutSession {
929
+ /** Hosted Checkout URL. Client redirects here. */
930
+ url: string;
931
+ /** Session id, useful for tracking. */
932
+ sessionId: string;
933
+ customerId: string | null;
934
+ }
935
+ interface AlmadarPortalSession {
936
+ /** Hosted Billing Portal URL. Client redirects here. */
937
+ url: string;
938
+ customerId: string;
939
+ }
940
+ /**
941
+ * Canonical webhook event surface — discriminated union over the five
942
+ * Stripe events apps/builder reacts to. Anything outside this set comes
943
+ * back as `{ error: 'unknown-event-type' }`; signature failures are
944
+ * `{ error: 'bad-signature' }`.
945
+ *
946
+ * IMPORTANT: NEVER expose `Stripe.Event` / `Stripe.Subscription` /
947
+ * `Stripe.Invoice` to consumers — that re-creates the SDK-version
948
+ * coupling we're explicitly breaking.
949
+ */
950
+ interface AlmadarInvoicePayment {
951
+ customerId: string;
952
+ subscriptionId: string | null;
953
+ paidAt: string;
954
+ amountUsd: number;
955
+ }
956
+ interface AlmadarInvoiceFailure {
957
+ customerId: string;
958
+ subscriptionId: string | null;
959
+ failedAt: string;
960
+ reason: string;
961
+ }
962
+ type AlmadarStripeEventOk = {
963
+ type: 'subscription.created';
964
+ eventId: string;
965
+ data: AlmadarSubscription;
966
+ } | {
967
+ type: 'subscription.updated';
968
+ eventId: string;
969
+ data: AlmadarSubscription;
970
+ } | {
971
+ type: 'subscription.deleted';
972
+ eventId: string;
973
+ data: {
974
+ subscriptionId: string;
975
+ customerId: string;
976
+ };
977
+ } | {
978
+ type: 'invoice.payment_succeeded';
979
+ eventId: string;
980
+ data: AlmadarInvoicePayment;
981
+ } | {
982
+ type: 'invoice.payment_failed';
983
+ eventId: string;
984
+ data: AlmadarInvoiceFailure;
985
+ };
986
+ type AlmadarStripeEvent = AlmadarStripeEventOk | {
987
+ error: 'bad-signature';
988
+ } | {
989
+ error: 'unknown-event-type';
990
+ stripeType: string;
991
+ };
992
+ /**
993
+ * Configuration consumed by `createCheckoutSession`. `tier` controls the
994
+ * price selection; `successUrl` / `cancelUrl` are app-supplied so the
995
+ * integration stays app-agnostic.
996
+ */
997
+ interface CreateCheckoutInput {
998
+ customerId: string | null;
999
+ /** Tier the user wants to subscribe to. */
1000
+ tier: 'solo' | 'teams';
1001
+ /** Solo = 1; Teams = 1..3. */
1002
+ quantity: number;
1003
+ successUrl: string;
1004
+ cancelUrl: string;
1005
+ /** Optional metadata written onto the Stripe Subscription on creation. */
1006
+ metadata: Record<string, string>;
1007
+ }
1008
+ interface CreatePortalInput {
1009
+ customerId: string;
1010
+ returnUrl: string;
1011
+ }
1012
+ interface CreateCustomerInput {
1013
+ email: string;
1014
+ almadarUid: string;
1015
+ displayName: string | null;
1016
+ }
1017
+ interface UpdateSubscriptionInput {
1018
+ subscriptionId: string;
1019
+ quantity?: number;
1020
+ cancelAtPeriodEnd?: boolean;
1021
+ }
1022
+ interface CancelSubscriptionInput {
1023
+ subscriptionId: string;
1024
+ /** Default `true`: cancel at period end so the user keeps access. */
1025
+ atPeriodEnd: boolean;
1026
+ }
1027
+ /**
1028
+ * Price → tier mapping table. The integration imports this at construction
1029
+ * time from `IntegrationConfig.env`; consumers pass the IDs they have
1030
+ * provisioned in their Stripe account.
1031
+ *
1032
+ * Solo: monthly $20 fixed. Teams: monthly $20 per seat (quantity drives total).
1033
+ */
1034
+ interface StripePriceMap {
1035
+ solo: string;
1036
+ teams: string;
1037
+ }
1038
+
1039
+ /**
1040
+ * Verify + parse Stripe webhook signatures into canonical Almadar
1041
+ * events. Apps/builder calls this from its `/billing/stripe-webhook`
1042
+ * route and switches on the returned discriminated union — it never
1043
+ * imports the `stripe` SDK or any `Stripe.*` shape.
1044
+ *
1045
+ * The five handled event types mirror docs §5.2 / `Almadar_Studio_Subscriptions.md`:
1046
+ * - customer.subscription.created
1047
+ * - customer.subscription.updated
1048
+ * - customer.subscription.deleted
1049
+ * - invoice.payment_succeeded
1050
+ * - invoice.payment_failed
1051
+ *
1052
+ * Anything else returns `{ error: 'unknown-event-type', stripeType: … }`
1053
+ * so the route can acknowledge with 200 + a log line (Stripe stops
1054
+ * retrying acknowledged events).
1055
+ */
1056
+
1057
+ interface VerifyAndParseInput {
1058
+ rawBody: string | Buffer;
1059
+ signature: string;
1060
+ /** Stripe webhook secret (`whsec_…`). */
1061
+ secret: string;
1062
+ /** Map of provisioned Stripe Price IDs → Almadar tier. */
1063
+ prices: StripePriceMap;
1064
+ }
1065
+ /**
1066
+ * Verify Stripe's signature header against the raw body and shape the
1067
+ * payload into a canonical `AlmadarStripeEvent`. The `stripe` SDK is
1068
+ * only used inside this module.
1069
+ */
1070
+ declare function verifyAndParseStripeEvent(input: VerifyAndParseInput): AlmadarStripeEvent;
1071
+
1072
+ /**
1073
+ * Stripe integration for payment processing and subscription billing.
1074
+ *
1075
+ * Two surfaces:
1076
+ * - Legacy `execute(action, params)` switch for the original three
1077
+ * PaymentIntent actions (kept for back-compat).
1078
+ * - New typed methods (`createCustomer`, `createCheckoutSession`,
1079
+ * `createSubscription`, etc.) that return canonical `Almadar*`
1080
+ * types. Consumers MUST prefer these — `Stripe.*` types never leak.
885
1081
  */
886
1082
  declare class StripeIntegration extends BaseIntegration {
887
1083
  private client;
1084
+ private prices;
888
1085
  constructor(config: IntegrationConfig);
1086
+ /** Provisioned Price IDs the integration was constructed with. */
1087
+ getPrices(): StripePriceMap;
889
1088
  execute(action: string, params: IntegrationParams): Promise<IntegrationResult>;
890
1089
  private createPaymentIntent;
891
1090
  private confirmPayment;
892
1091
  private refund;
1092
+ /** Look up an existing customer by Stripe ID. */
1093
+ getCustomer(customerId: string): Promise<AlmadarCustomer | null>;
1094
+ /**
1095
+ * Create a Stripe Customer for the given Almadar user. `almadarUid` is
1096
+ * stored as Stripe metadata so webhook handlers can resolve back to
1097
+ * the right `users/{uid}` document.
1098
+ */
1099
+ createCustomer(input: CreateCustomerInput): Promise<AlmadarCustomer>;
1100
+ /**
1101
+ * Create a Stripe-hosted Checkout Session for the given tier. Client
1102
+ * redirects the user to the returned `url`; on success Stripe fires
1103
+ * `customer.subscription.created`, which the apps/builder webhook
1104
+ * handler turns into a `users/{uid}.tier` write.
1105
+ */
1106
+ createCheckoutSession(input: CreateCheckoutInput): Promise<AlmadarCheckoutSession>;
1107
+ /** Create a Billing Portal session for self-service plan management. */
1108
+ createBillingPortalSession(input: CreatePortalInput): Promise<AlmadarPortalSession>;
1109
+ /** Fetch a subscription and shape it into the canonical form. */
1110
+ getSubscription(subscriptionId: string): Promise<AlmadarSubscription>;
1111
+ /**
1112
+ * Create a subscription directly (server-side, no Checkout). Used by
1113
+ * P13.3 Solo → Teams upgrade flow.
1114
+ */
1115
+ createSubscription(input: {
1116
+ customerId: string;
1117
+ tier: 'solo' | 'teams';
1118
+ quantity: number;
1119
+ metadata: Record<string, string>;
1120
+ }): Promise<AlmadarSubscription>;
1121
+ /**
1122
+ * Update quantity or cancel-at-period-end. Used for Teams seat resize
1123
+ * and Solo → Teams transition.
1124
+ */
1125
+ updateSubscription(input: UpdateSubscriptionInput): Promise<AlmadarSubscription>;
1126
+ /**
1127
+ * Cancel a subscription. Defaults to `atPeriodEnd: true` so the user
1128
+ * keeps access until the current period ends.
1129
+ */
1130
+ cancelSubscription(input: CancelSubscriptionInput): Promise<AlmadarSubscription>;
893
1131
  }
894
1132
 
895
1133
  /**
@@ -1140,4 +1378,4 @@ declare class DockerIntegration extends BaseIntegration {
1140
1378
  private list;
1141
1379
  }
1142
1380
 
1143
- export { BaseIntegration, type CLIActions, CLIIntegration, ConsoleLogger, type DeepAgentActions, DeepAgentIntegration, type DockerActions, DockerIntegration, type EmailActions, EmailIntegration, type GitHubActions, type IntegrationActionName, IntegrationConfig, type IntegrationConstructor, type IntegrationContracts, IntegrationErrorCode, IntegrationLogger, type IntegrationName, IntegrationResult, LLMIntegration, type LLMIntegrationActions, type OAuthActions, OAuthIntegration, type OtelActions, OtelIntegration, type QueueActions, QueueIntegration, type RedisActions, RedisIntegration, type RetryConfig, type StorageActions, StorageIntegration, type StripeActions, StripeIntegration, type TwilioActions, TwilioIntegration, type YouTubeActions, YouTubeIntegration, getIntegration, getRegisteredIntegrations, isKnownIntegration, registerIntegration, withRetry };
1381
+ export { type AlmadarCheckoutSession, type AlmadarCustomer, type AlmadarInvoiceFailure, type AlmadarInvoicePayment, type AlmadarPortalSession, type AlmadarStripeEvent, type AlmadarStripeEventOk, type AlmadarSubscription, type AlmadarSubscriptionStatus, type AlmadarTier, BaseIntegration, type CLIActions, CLIIntegration, type CancelSubscriptionInput, ConsoleLogger, type CreateCheckoutInput, type CreateCustomerInput, type CreatePortalInput, type DeepAgentActions, DeepAgentIntegration, type DockerActions, DockerIntegration, type EmailActions, EmailIntegration, type GitHubActions, type IntegrationActionName, IntegrationConfig, type IntegrationConstructor, type IntegrationContracts, IntegrationErrorCode, IntegrationLogger, type IntegrationName, IntegrationResult, LLMIntegration, type LLMIntegrationActions, type OAuthActions, OAuthIntegration, type OtelActions, OtelIntegration, type QueueActions, QueueIntegration, type RedisActions, RedisIntegration, type RetryConfig, type StorageActions, StorageIntegration, type StripeActions, StripeIntegration, type StripePriceMap, type TwilioActions, TwilioIntegration, type UpdateSubscriptionInput, type VerifyAndParseInput, type YouTubeActions, YouTubeIntegration, getIntegration, getRegisteredIntegrations, isKnownIntegration, registerIntegration, verifyAndParseStripeEvent, withRetry };