@chatarmin/os 1.7.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { TRPCClientError, createTRPCClient, httpBatchLink } from "@trpc/client";
2
2
  import superjson from "superjson";
3
- import { createCompaniesClient, } from "./companies";
4
- import { webhooks } from "./webhooks";
5
- export { webhooks, constructProductWebhookEvent, generateTestWebhookHeaders, OsWebhookSignatureVerificationError, WEBHOOK_ID_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, } from "./webhooks";
3
+ import { createCompaniesClient, } from "./companies/index.js";
4
+ import { createBillingClient } from "./billing/index.js";
5
+ import { createFeaturesClient } from "./features/index.js";
6
+ import { webhooks } from "./webhooks/index.js";
7
+ export { webhooks, constructProductWebhookEvent, generateTestWebhookHeaders, OsWebhookSignatureVerificationError, WEBHOOK_ID_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, } from "./webhooks/index.js";
6
8
  const INSPECT_SYMBOL = Symbol.for("nodejs.util.inspect.custom");
7
9
  export class ChatarminOSError extends Error {
8
10
  details;
@@ -325,372 +327,14 @@ export class ChatarminOS {
325
327
  * ```
326
328
  */
327
329
  get features() {
328
- const client = this.client;
329
- const call = this.call.bind(this);
330
- return {
331
- /**
332
- * Check if a company has access to a specific feature.
333
- *
334
- * Returns detailed access information including whether the feature
335
- * is enabled, current usage, limits, and whether they can use more.
336
- *
337
- * @param input - Check parameters
338
- * @param input.companyId - Company ID to check
339
- * @param input.featureCode - Feature code (e.g., "ai_credit")
340
- * @returns Detailed feature access information
341
- *
342
- * @example
343
- * ```typescript
344
- * const access = await os.features.check({
345
- * companyId: 'comp_xxx',
346
- * featureCode: 'ai_credit'
347
- * })
348
- *
349
- * console.log({
350
- * enabled: access.isEnabled,
351
- * canUse: access.canUse,
352
- * usage: access.currentUsage,
353
- * limit: access.quantityLimit,
354
- * remaining: access.remaining,
355
- * included: access.includedQuantity
356
- * })
357
- * ```
358
- */
359
- check: (input) => call("features.check", () => client.features.check.query(input)),
360
- /**
361
- * List all features and their access status for a company.
362
- *
363
- * Returns a complete list of features with their current status,
364
- * useful for displaying a company's full feature set or building
365
- * a feature comparison view.
366
- *
367
- * @param input - Query parameters
368
- * @returns Array of feature access records
369
- *
370
- * @example Basic usage
371
- * ```typescript
372
- * const features = await os.features.listAccess({ companyId: company.id })
373
- *
374
- * for (const f of features) {
375
- * console.log(`${f.featureName}: ${f.isEnabled ? '✓' : '✗'}`)
376
- * if (f.quantityLimit) {
377
- * console.log(` Usage: ${f.currentUsage} / ${f.quantityLimit}`)
378
- * }
379
- * }
380
- * ```
381
- *
382
- * @example With billing details
383
- * ```typescript
384
- * const features = await os.features.listAccess({
385
- * companyId: company.id,
386
- * includeBillingDetails: true
387
- * })
388
- *
389
- * for (const f of features) {
390
- * console.log(`${f.featureName}:`)
391
- * console.log(` Usage: ${f.currentUsage} / ${f.quantityLimit}`)
392
- *
393
- * if (f.billing) {
394
- * console.log(` Price: ${f.billing.unitAmount / 100} ${f.billing.currency}`)
395
- * console.log(` Period: ${f.billing.currentPeriodStart} to ${f.billing.currentPeriodEnd}`)
396
- * console.log(` Status: ${f.billing.subscriptionStatus}`)
397
- * }
398
- * }
399
- * ```
400
- */
401
- listAccess: (input) => call("features.listAccess", () => {
402
- // Support legacy companyId string param for backward compatibility
403
- const params = typeof input === "string" ? { companyId: input } : input;
404
- return client.features.getAccess.query(params);
405
- }),
406
- /**
407
- * Update feature access for a company with partial config merge.
408
- *
409
- * This allows you to update individual feature configs without
410
- * replacing all config values. Only the fields you specify in
411
- * `config` will be updated - other fields remain unchanged.
412
- *
413
- * @param input - Update parameters
414
- * @returns Updated feature access information
415
- *
416
- * @example Update by company ID
417
- * ```typescript
418
- * await os.features.setAccess({
419
- * companyId: 'comp_xxx',
420
- * featureCode: 'ai_credit',
421
- * isEnabled: true,
422
- * config: {
423
- * included_quantity: 500,
424
- * max_quantity: 1000
425
- * }
426
- * })
427
- * ```
428
- *
429
- * @example Update by your product's external org ID
430
- * ```typescript
431
- * await os.features.setAccess({
432
- * externalOrgId: 'org_abc123',
433
- * featureCode: 'ai_credit',
434
- * config: { tier_level: 'premium' }
435
- * })
436
- * ```
437
- *
438
- * @example Partial config update (only updates specified fields)
439
- * ```typescript
440
- * // Existing config: { tier_level: 'basic', max_seats: 5 }
441
- * await os.features.setAccess({
442
- * companyId: 'comp_xxx',
443
- * featureCode: 'team_seats',
444
- * config: { max_seats: 10 } // tier_level remains 'basic'
445
- * })
446
- * // New config: { tier_level: 'basic', max_seats: 10 }
447
- * ```
448
- */
449
- setAccess: (input) => call("features.setAccess", () => client.features.updateAccess.mutate(input)),
450
- /**
451
- * Get all feature access using your product's external org ID.
452
- *
453
- * Convenience method when you know the external org ID but not
454
- * the ChatarminOS company ID.
455
- *
456
- * @param externalOrgId - Your product's organization ID
457
- * @returns All features with their access status and config values
458
- *
459
- * @example
460
- * ```typescript
461
- * const result = await os.features.getAccessByExternalOrgId('org_abc123')
462
- *
463
- * console.log(`Company: ${result.companyId}`)
464
- * for (const f of result.features) {
465
- * console.log(`${f.featureCode}: ${f.isEnabled}`)
466
- * console.log(` Config:`, f.configValues)
467
- * }
468
- * ```
469
- */
470
- getAccessByExternalOrgId: (externalOrgId) => call("features.getAccessByExternalOrgId", () => client.features.getAccessByExternalOrgId.query({ externalOrgId })),
471
- /**
472
- * Check specific feature access using your product's external org ID.
473
- *
474
- * @param externalOrgId - Your product's organization ID
475
- * @param featureCode - Feature code to check
476
- * @returns Detailed feature access including config values
477
- *
478
- * @example
479
- * ```typescript
480
- * const access = await os.features.checkByExternalOrgId(
481
- * 'org_abc123',
482
- * 'ai_credit'
483
- * )
484
- *
485
- * if (access.canUse) {
486
- * console.log(`Remaining: ${access.remaining}`)
487
- * console.log(`Config:`, access.configValues)
488
- * }
489
- * ```
490
- */
491
- checkByExternalOrgId: (externalOrgId, featureCode) => call("features.checkByExternalOrgId", () => client.features.checkByExternalOrgId.query({
492
- externalOrgId,
493
- featureCode,
494
- })),
495
- };
330
+ return createFeaturesClient(this.client, this.call.bind(this));
496
331
  }
497
332
  // ==========================================================================
498
333
  // Billing
499
334
  // ==========================================================================
500
- /**
501
- * Billing, usage tracking, and subscription management.
502
- *
503
- * Set feature usage for billing, claim subscriptions from Stripe checkout,
504
- * or link existing Stripe subscriptions to companies.
505
- *
506
- * @example Set Usage
507
- * ```typescript
508
- * await os.billing.setUsage({
509
- * companyId: company.id,
510
- * featureCode: 'ai_credit',
511
- * absoluteValue: 42,
512
- * reason: 'Synced current usage'
513
- * })
514
- * ```
515
- *
516
- * @example Claim Checkout Subscription
517
- * ```typescript
518
- * // After Stripe checkout completes
519
- * const result = await os.billing.claimCheckout({
520
- * companyId: company.id,
521
- * checkoutSessionId: 'cs_xxx'
522
- * })
523
- * ```
524
- *
525
- * @example Link Existing Subscription
526
- * ```typescript
527
- * // When you create subscriptions on your Stripe account
528
- * const result = await os.billing.linkSubscription({
529
- * companyId: company.id,
530
- * stripeSubscriptionId: 'sub_xxx',
531
- * tierCode: 'pro' // Apply tier features
532
- * })
533
- * ```
534
- */
335
+ /** Billing, usage tracking, subscriptions, and customer billing surfaces. */
535
336
  get billing() {
536
- const client = this.client;
537
- const call = this.call.bind(this);
538
- return {
539
- /**
540
- * Set usage to an absolute value.
541
- *
542
- * Use this for corrections when you know what the total usage SHOULD be.
543
- * Creates a snapshot for audit trail. The delta (difference) is calculated
544
- * automatically and synced to Stripe.
545
- *
546
- * @param input - Set usage parameters
547
- * @returns Result with previous and new usage values
548
- *
549
- * @example Correct usage to 100 (was 150)
550
- * ```typescript
551
- * const result = await os.billing.setUsage({
552
- * companyId: 'comp_xxx',
553
- * featureCode: 'ai_credit',
554
- * absoluteValue: 100,
555
- * reason: 'Corrected after customer support review',
556
- * performedBy: 'admin@company.com'
557
- * })
558
- *
559
- * console.log({
560
- * previousUsage: result.previousUsage, // 150
561
- * currentUsage: result.currentUsage, // 100
562
- * delta: result.delta // -50
563
- * })
564
- * ```
565
- */
566
- setUsage: (input) => call("billing.setUsage", () => client.billing.setUsage.mutate({
567
- ...input,
568
- source: "api",
569
- })),
570
- /**
571
- * Get usage event history for a feature.
572
- *
573
- * Returns the history of usage events including increments, sets,
574
- * and adjustments. Useful for auditing and debugging.
575
- *
576
- * @param companyId - Company ID
577
- * @param featureCode - Feature code to get history for
578
- * @param options - Query options
579
- * @returns Array of usage events
580
- *
581
- * @example
582
- * ```typescript
583
- * const history = await os.billing.getUsageHistory(
584
- * 'comp_xxx',
585
- * 'ai_credit',
586
- * { limit: 20, eventType: 'adjustment' }
587
- * )
588
- *
589
- * for (const event of history) {
590
- * console.log(`${event.event_type}: ${event.quantity} at ${event.event_time}`)
591
- * if (event.adjustment_reason) {
592
- * console.log(` Reason: ${event.adjustment_reason}`)
593
- * }
594
- * }
595
- * ```
596
- */
597
- getUsageHistory: (companyId, featureCode, options) => call("billing.getUsageHistory", () => client.billing.getUsageHistory.query({
598
- companyId,
599
- featureCode,
600
- ...options,
601
- })),
602
- /**
603
- * Claim a subscription from a completed Stripe Checkout Session.
604
- *
605
- * Use this after a user completes Stripe checkout in your product.
606
- * This links the subscription and customer to the company in OS.
607
- *
608
- * @param input - Claim parameters
609
- * @returns Result with subscription ID and claim status
610
- *
611
- * @example
612
- * ```typescript
613
- * // In your Stripe checkout success handler:
614
- * const result = await os.billing.claimCheckout({
615
- * companyId: company.id,
616
- * checkoutSessionId: session.id // From Stripe callback
617
- * })
618
- *
619
- * if (result.alreadyClaimed) {
620
- * console.log('Subscription was already claimed')
621
- * } else {
622
- * console.log(`Claimed subscription: ${result.subscriptionId}`)
623
- * }
624
- * ```
625
- */
626
- claimCheckout: (input) => call("billing.claimCheckout", () => client.billing.claimCheckout.mutate(input)),
627
- /**
628
- * Link an existing Stripe subscription to a company.
629
- *
630
- * Use this when you create subscriptions on your product's Stripe
631
- * account and want OS to track them. Optionally applies tier features.
632
- *
633
- * @param input - Link parameters
634
- * @returns Result with subscription ID, link status, and features applied
635
- *
636
- * @example
637
- * ```typescript
638
- * // After creating subscription on your Stripe account:
639
- * const result = await os.billing.linkSubscription({
640
- * companyId: company.id,
641
- * stripeSubscriptionId: 'sub_xxx',
642
- * stripeCustomerId: 'cus_xxx', // Optional
643
- * tierCode: 'pro', // Apply tier features
644
- * displayName: 'Pro Plan'
645
- * })
646
- *
647
- * console.log({
648
- * subscriptionId: result.subscriptionId,
649
- * isNew: !result.alreadyLinked,
650
- * featuresApplied: result.featuresApplied
651
- * })
652
- * ```
653
- */
654
- linkSubscription: (input) => call("billing.linkSubscription", () => client.billing.linkSubscription.mutate(input)),
655
- /**
656
- * Get billing status for a company.
657
- *
658
- * Quick check for subscription status, active features, and
659
- * billing profile information.
660
- *
661
- * @param companyId - Company ID to check
662
- * @returns Billing status overview
663
- *
664
- * @example
665
- * ```typescript
666
- * const status = await os.billing.getStatus(company.id)
667
- *
668
- * console.log({
669
- * hasBilling: status.hasBillingProfile,
670
- * subscriptions: status.activeSubscriptions.length,
671
- * features: status.enabledFeaturesCount
672
- * })
673
- *
674
- * // Check active tier
675
- * if (status.activeSubscriptions[0]?.tier) {
676
- * console.log(`Current tier: ${status.activeSubscriptions[0].tier.name}`)
677
- * }
678
- * ```
679
- */
680
- getStatus: (companyId) => call("billing.getStatus", () => client.billing.getStatus.query({ companyId })),
681
- /**
682
- * Sync billing profile, subscriptions, and feature access from Stripe.
683
- */
684
- syncCompanyFromStripe: (input) => call("billing.syncCompanyFromStripe", () => client.billing.syncCompanyFromStripe.mutate(input)),
685
- /**
686
- * Relink billing profile to a new Stripe customer (destructive).
687
- */
688
- relinkBillingProfile: (input) => call("billing.relinkBillingProfile", () => client.billing.relinkBillingProfile.mutate(input)),
689
- /**
690
- * Ensure a feature is linked to an active Stripe subscription item.
691
- */
692
- ensureFeatureSubscription: (input) => call("billing.ensureFeatureSubscription", () => client.billing.ensureFeatureSubscription.mutate(input)),
693
- };
337
+ return createBillingClient(this.client, this.call.bind(this));
694
338
  }
695
339
  // ==========================================================================
696
340
  // Links
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/companies/client.ts","../src/billing/client.ts","../src/features/client.ts","../src/webhooks/constants.ts","../src/webhooks/errors.ts","../src/webhooks/read-header.ts","../src/webhooks/signing.ts","../src/webhooks/construct-event.ts","../src/webhooks/generate-test-headers.ts","../src/webhooks/index.ts"],"sourcesContent":["import type { AppRouter } from \"@chatarmin/api/trpc-types\"\nimport { TRPCClientError, createTRPCClient, httpBatchLink } from \"@trpc/client\"\nimport superjson from \"superjson\"\nimport {\n createCompaniesClient,\n type CompaniesClient,\n type CreateCompanyInput,\n} from \"./companies/index.js\"\nimport { createBillingClient, type BillingClient } from \"./billing/index.js\"\nimport { createFeaturesClient, type FeaturesClient } from \"./features/index.js\"\nimport { webhooks } from \"./webhooks/index.js\"\n\nexport {\n webhooks,\n constructProductWebhookEvent,\n generateTestWebhookHeaders,\n OsWebhookSignatureVerificationError,\n WEBHOOK_ID_HEADER,\n WEBHOOK_SIGNATURE_HEADER,\n WEBHOOK_TIMESTAMP_HEADER,\n} from \"./webhooks/index.js\"\nexport type {\n ConstructProductWebhookEventOptions,\n ProductWebhookEventPayload,\n ProductWebhookHeaders,\n VerifiedProductWebhookEvent,\n} from \"./webhooks/index.js\"\n\nexport type {\n CompaniesClient,\n CompanyAssignee,\n CompanyAssignees,\n CreateCompanyInput,\n CreateCompanyResult,\n GetCompanyInput,\n LinkedCompany,\n ListCompaniesInput,\n ListCompaniesResult,\n ListLinkedCompaniesInput,\n ListLinkedCompaniesResult,\n ProductCompany,\n UpdateCompanyResult,\n} from \"./companies/index.js\"\nexport type {\n BillingClient,\n BillingInvoiceSummary,\n BillingOverview,\n BillingProfileSummary,\n BillingSubscriptionSummary,\n ClaimCheckoutInput,\n ClaimCheckoutResult,\n CreateBillingPortalSessionInput,\n EnsureFeatureSubscriptionInput,\n EnsureFeatureSubscriptionResult,\n GetBillingOverviewInput,\n GetUsageInput,\n LinkSubscriptionInput,\n LinkSubscriptionResult,\n ListBillingInvoicesOptions,\n PeriodOffsetRange,\n RelinkBillingProfileInput,\n ResolveInvoicePaymentUrlInput,\n SetUsageInput,\n SyncCompanyFromStripeInput,\n SyncCompanyFromStripeResult,\n UsageAggregate,\n UsageCycleBucket,\n UsageCycleSummary,\n UsagePoint,\n UsageQueryResult,\n UsageRecord,\n UsageSubscriptionItem,\n UsageResult,\n} from \"./billing/index.js\"\nexport type {\n ExternalOrgFeatureAccessItem,\n FeatureAccessByExternalOrgIdResult,\n FeatureAccessItem,\n FeatureBillingDetails,\n FeatureCheckByExternalOrgIdResult,\n FeatureCheckInput,\n FeatureCheckResult,\n FeatureSetAccessInput,\n FeatureSetAccessResult,\n FeaturesClient,\n ListFeatureAccessInput,\n} from \"./features/index.js\"\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration options for the ChatarminOS SDK client.\n */\nexport interface ChatarminOSConfig {\n /**\n * API key generated in the OS admin for your product.\n * Found in Settings → Developers → API Keys.\n * @example \"os_sk_xxxxxxxxxxxxxxxxxxxx\"\n */\n apiKey: string\n\n /**\n * Base URL of the OS API.\n * @default \"https://os.chatarmin.com/api/v1\"\n */\n baseUrl?: string\n}\n\nexport interface ChatarminOSErrorDetails {\n operation: string\n code?: string\n httpStatus?: number\n path?: string\n zodError?: unknown\n requestId?: string\n}\n\nconst INSPECT_SYMBOL = Symbol.for(\"nodejs.util.inspect.custom\")\n\nexport class ChatarminOSError extends Error {\n details: ChatarminOSErrorDetails\n\n constructor(\n message: string,\n details: ChatarminOSErrorDetails,\n cause?: unknown\n ) {\n super(message)\n this.name = \"ChatarminOSError\"\n // Make message enumerable so JSON/loggers show it clearly.\n Object.defineProperty(this, \"message\", {\n value: message,\n enumerable: true,\n writable: true,\n configurable: true,\n })\n this.details = details\n if (cause !== undefined) {\n // Keep cause for debugging but avoid logging huge blobs by default.\n Object.defineProperty(this, \"cause\", {\n value: cause,\n enumerable: false,\n writable: true,\n configurable: true,\n })\n }\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n details: this.details,\n }\n }\n\n [INSPECT_SYMBOL]() {\n return {\n name: this.name,\n message: this.message,\n details: this.details,\n }\n }\n}\n\nfunction readResponseHeader(\n headers: unknown,\n name: string\n): string | undefined {\n if (!headers) return undefined\n if (typeof (headers as Headers).get === \"function\") {\n return (headers as Headers).get(name) ?? undefined\n }\n if (typeof headers === \"object\" && headers !== null) {\n const record = headers as Record<string, unknown>\n const direct = record[name] ?? record[name.toLowerCase()]\n if (Array.isArray(direct)) return direct[0]\n if (typeof direct === \"string\") return direct\n }\n return undefined\n}\n\nfunction toChatarminOSError(\n operation: string,\n error: TRPCClientError<AppRouter>\n) {\n const data = error.data ?? error.shape?.data\n const requestId =\n (data as { requestId?: string } | undefined)?.requestId ??\n readResponseHeader(\n (error.meta as { response?: { headers?: unknown } } | undefined)?.response\n ?.headers,\n \"x-request-id\"\n )\n return new ChatarminOSError(\n error.message,\n {\n operation,\n code: data?.code,\n httpStatus: data?.httpStatus,\n path: data?.path,\n zodError: (data as { zodError?: unknown } | undefined)?.zodError,\n requestId,\n },\n error\n )\n}\n\n/**\n * Input for applying a tier to a company.\n */\nexport interface ApplyTierInput {\n /** Company ID to apply the tier to */\n companyId: string\n /** Feature overrides (key: feature code, value: config overrides) */\n features?: Record<string, Record<string, unknown>>\n}\n\n/**\n * Contact data for creating or updating a contact.\n */\nexport interface ContactInput {\n /** Contact email address (required, unique per company) */\n email: string\n /** Contact name */\n name?: string\n /** Contact role (e.g., \"CEO\", \"Marketing Manager\") */\n role?: string\n /** Whether this is the primary contact */\n isPrimary?: boolean\n /** Avatar URL */\n avatarUrl?: string\n /** Additional metadata */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Result from creating a single contact.\n */\nexport interface ContactResult {\n id: string\n email: string\n name: string | null\n role: string | null\n is_primary: boolean\n avatar_url: string | null\n isNew: boolean\n}\n\n/**\n * Result from bulk contact upsert.\n */\nexport interface BulkContactResult {\n /** Number of contacts created */\n created: number\n /** Number of contacts updated */\n updated: number\n /** Individual contact results */\n contacts: Array<{\n email: string\n id: string\n isNew: boolean\n }>\n}\n\n/**\n * Input for the unified onboarding flow.\n */\nexport interface OnboardInput {\n /** Your product's unique organization ID for this customer */\n externalOrgId: string\n\n /** Display label for the product link (e.g., \"Chatarmin CX\", \"Shopify\") */\n label: string\n\n /**\n * Company details used when creating a new company via onboard().\n */\n hints?: {\n /** Company name for new companies */\n companyName?: string\n /** Domain for new companies */\n domain?: string\n }\n\n /**\n * Stripe checkout session ID to claim.\n * Use when user completed Stripe checkout in your product.\n * @example \"cs_test_xxxxxxxxxxxxx\"\n */\n checkoutSessionId?: string\n\n /**\n * Existing Stripe subscription ID to link.\n * Use when you create subscriptions on your product's Stripe account.\n * @example \"sub_xxxxxxxxxxxxx\"\n */\n stripeSubscriptionId?: string\n\n /**\n * Stripe customer ID.\n * Will be fetched from subscription if not provided.\n * @example \"cus_xxxxxxxxxxxxx\"\n */\n stripeCustomerId?: string\n\n /**\n * Tier code to apply features from.\n * Use for free tier signups or to tag linked subscriptions.\n * @example \"free\" | \"pro\" | \"enterprise\"\n */\n tierCode?: string\n\n /** Primary contact email for new companies */\n contactEmail?: string\n\n /** Primary contact name for new companies */\n contactName?: string\n\n /**\n * Historical created_at timestamp for the company.\n * Only used when creating new companies (not for existing matches).\n * @example \"2024-01-15T10:30:00.000Z\"\n */\n createdAt?: string\n}\n\n/**\n * Result from the onboarding flow.\n */\nexport interface OnboardResult {\n /** The company ID (either existing or newly created) */\n companyId: string\n\n /** The company name */\n companyName: string\n\n /**\n * How the company was linked:\n * - `already_linked`: Company was already linked to your product\n * - `created`: New company was created\n */\n linkStatus: \"already_linked\" | \"created\"\n\n /** Billing status (only present if billing was configured) */\n billingStatus?: {\n /** Subscription ID if created/claimed */\n subscriptionId?: string\n /** True if subscription was claimed from checkout */\n claimed?: boolean\n /** True if subscription was linked */\n linked?: boolean\n /** True if tier features were applied */\n tierApplied?: boolean\n /** Error message if billing failed (company still linked) */\n error?: string\n }\n}\n\n// ============================================================================\n// SDK Client\n// ============================================================================\n\n/**\n * ChatarminOS SDK Client\n *\n * Type-safe client for interacting with ChatarminOS from your B2B SaaS product.\n * Use this SDK to manage companies, track feature usage, and handle billing.\n *\n * @example Basic Setup\n * ```typescript\n * import { ChatarminOS } from '@chatarmin/os-sdk'\n *\n * const os = new ChatarminOS({\n * apiKey: process.env.OS_API_KEY!\n * })\n * ```\n *\n * @example Complete Onboarding Flow\n * ```typescript\n * // When a new user signs up in your product:\n * const result = await os.onboard({\n * externalOrgId: 'org_abc123',\n * label: 'My Product',\n * hints: {\n * companyName: 'Acme Inc',\n * domain: 'acme.com'\n * },\n * tierCode: 'free' // Apply free tier features\n * })\n *\n * console.log(result.companyId) // Use this for all future API calls\n * ```\n *\n * @example Set Usage\n * ```typescript\n * await os.billing.setUsage({\n * companyId: company.id,\n * featureCode: 'ai_credit',\n * absoluteValue: 1,\n * reason: 'Synced current usage'\n * })\n * ```\n *\n * @see https://os.chatarmin.com/docs for full documentation\n */\nexport class ChatarminOS {\n static webhooks = webhooks\n\n private client: ReturnType<typeof createTRPCClient<AppRouter>>\n private async call<T>(\n operation: string,\n action: () => Promise<T>\n ): Promise<T> {\n try {\n return await action()\n } catch (error) {\n if (error instanceof TRPCClientError) {\n throw toChatarminOSError(operation, error as TRPCClientError<AppRouter>)\n }\n throw error\n }\n }\n\n /**\n * Create a new ChatarminOS SDK client.\n *\n * @param config - Configuration options\n * @param config.apiKey - Your product's API key from OS admin\n * @param config.baseUrl - Custom API base URL (optional)\n *\n * @example\n * ```typescript\n * const os = new ChatarminOS({\n * apiKey: process.env.OS_API_KEY!,\n * // Optional: custom base URL for development\n * baseUrl: 'http://localhost:3001/api/v1'\n * })\n * ```\n */\n constructor(config: ChatarminOSConfig) {\n const baseUrl = config.baseUrl || \"https://os.chatarmin.com/api/v1\"\n\n this.client = createTRPCClient<AppRouter>({\n links: [\n httpBatchLink({\n url: baseUrl,\n headers: () => ({\n \"x-api-key\": config.apiKey,\n }),\n transformer: superjson,\n }),\n ],\n })\n }\n\n // ==========================================================================\n // Companies\n // ==========================================================================\n\n /**\n * Company management operations.\n *\n * Companies represent your customers in ChatarminOS. Each company can be\n * linked to your product via an external organization ID.\n *\n * @example\n * ```typescript\n * // Look up a company by your org ID\n * const company = await os.companies.get({\n * externalOrgId: 'org_abc123'\n * })\n *\n * // Route support mail to the assigned CSM\n * const csmEmail = company?.assignees.csm?.email\n *\n * // Create a new company\n * const newCompany = await os.companies.create({\n * name: 'Acme Inc',\n * domain: 'acme.com',\n * externalOrgId: 'org_abc123',\n * contactEmail: 'admin@acme.com'\n * })\n * ```\n */\n get companies(): CompaniesClient {\n return createCompaniesClient(this.client, this.call.bind(this))\n }\n\n // ==========================================================================\n // Contacts\n // ==========================================================================\n\n /**\n * Contact management operations.\n *\n * Contacts are people associated with companies. Each contact has an email\n * (unique per company), optional name and role, and one contact can be\n * marked as primary.\n *\n * @example\n * ```typescript\n * // Create a single contact\n * const contact = await os.contacts.create({\n * companyId: company.id,\n * email: 'john@acme.com',\n * name: 'John Doe',\n * role: 'CEO',\n * isPrimary: true\n * })\n *\n * // Bulk create/update contacts\n * const result = await os.contacts.bulkUpsert({\n * companyId: company.id,\n * contacts: [\n * { email: 'john@acme.com', name: 'John', role: 'CEO', isPrimary: true },\n * { email: 'jane@acme.com', name: 'Jane', role: 'CTO' }\n * ]\n * })\n * ```\n */\n get contacts() {\n const client = this.client\n const call = this.call.bind(this)\n return {\n /**\n * Create or update a single contact for a company.\n *\n * If a contact with the same email exists, it will be updated.\n * Otherwise, a new contact is created.\n *\n * @param input - Contact creation parameters\n * @returns The created/updated contact\n *\n * @example\n * ```typescript\n * const contact = await os.contacts.create({\n * companyId: 'comp_xxx',\n * email: 'john@acme.com',\n * name: 'John Doe',\n * role: 'CEO',\n * isPrimary: true\n * })\n *\n * if (contact.isNew) {\n * console.log('Created new contact')\n * } else {\n * console.log('Updated existing contact')\n * }\n * ```\n */\n create: (input: { companyId: string } & ContactInput) =>\n call(\"contacts.create\", () =>\n client.contacts.createForCompany.mutate(input)\n ),\n\n /**\n * Bulk create or update multiple contacts for a company.\n *\n * This is the recommended way to sync contacts during onboarding.\n * Existing contacts (matched by email) are updated, new ones are created.\n *\n * @param input - Bulk upsert parameters\n * @returns Summary with created/updated counts\n *\n * @example\n * ```typescript\n * const result = await os.contacts.bulkUpsert({\n * companyId: 'comp_xxx',\n * contacts: [\n * { email: 'ceo@acme.com', name: 'CEO', role: 'CEO', isPrimary: true },\n * { email: 'cto@acme.com', name: 'CTO', role: 'CTO' },\n * { email: 'dev@acme.com', name: 'Developer', role: 'Engineer' }\n * ]\n * })\n *\n * console.log(`Created: ${result.created}, Updated: ${result.updated}`)\n * ```\n */\n bulkUpsert: (input: {\n companyId: string\n contacts: ContactInput[]\n }): Promise<BulkContactResult> =>\n call(\n \"contacts.bulkUpsert\",\n () =>\n client.contacts.bulkUpsert.mutate(\n input\n ) as Promise<BulkContactResult>\n ),\n\n /**\n * List all contacts for a company.\n *\n * @param companyId - Company ID to list contacts for\n * @param primaryOnly - If true, only return the primary contact\n * @returns Array of contacts\n *\n * @example\n * ```typescript\n * // Get all contacts\n * const contacts = await os.contacts.list('comp_xxx')\n *\n * // Get only primary contact\n * const primary = await os.contacts.list('comp_xxx', true)\n * ```\n */\n list: (companyId: string, primaryOnly = false) =>\n call(\"contacts.list\", () =>\n client.contacts.listForCompany.query({ companyId, primaryOnly })\n ),\n }\n }\n\n // ==========================================================================\n // Features\n // ==========================================================================\n\n /**\n * Feature access and entitlement operations.\n *\n * Check what features a company has access to and their current usage.\n * Features are defined in ChatarminOS and assigned via subscription tiers.\n *\n * @example\n * ```typescript\n * // Check if company can use a feature\n * const access = await os.features.check({\n * companyId: company.id,\n * featureCode: 'ai_credit'\n * })\n *\n * if (access.canUse) {\n * // Feature is available\n * console.log(`Remaining: ${access.remaining}`)\n * } else {\n * // Feature is disabled or limit reached\n * console.log('Upgrade required')\n * }\n * ```\n */\n get features(): FeaturesClient {\n return createFeaturesClient(this.client, this.call.bind(this))\n }\n\n // ==========================================================================\n // Billing\n // ==========================================================================\n\n /** Billing, usage tracking, subscriptions, and customer billing surfaces. */\n get billing(): BillingClient {\n return createBillingClient(this.client, this.call.bind(this))\n }\n\n // ==========================================================================\n // Links\n // ==========================================================================\n\n /**\n * Manual link operations for associating external IDs with companies.\n *\n * Use these when you need direct control over the linking process,\n * bypassing the smart link algorithm.\n *\n * @example\n * ```typescript\n * // Manually link an external org ID to an existing company\n * await os.links.create({\n * companyId: 'comp_xxx',\n * externalOrgId: 'org_abc123',\n * externalUserId: 'user_xyz'\n * })\n * ```\n */\n get links() {\n const client = this.client\n const call = this.call.bind(this)\n return {\n /**\n * Create a manual link between your external org ID and an existing company.\n *\n * Use this when you know the exact company ID and want to create\n * a direct link without smart matching.\n *\n * @param input - Link parameters\n * @param input.companyId - Company UUID or short_id (e.g., \"acme-corp\")\n * @returns The created link record\n *\n * @example Using UUID\n * ```typescript\n * const link = await os.links.create({\n * companyId: 'a1b2c3d4-e5f6-...',\n * externalOrgId: 'org_abc123',\n * label: 'Store Vienna'\n * })\n * ```\n *\n * @example Using short_id\n * ```typescript\n * const link = await os.links.create({\n * companyId: 'acme-corp', // short_id works too!\n * externalOrgId: 'org_abc123',\n * label: 'Store Vienna'\n * })\n * ```\n */\n create: (input: {\n /** Company UUID or short_id */\n companyId: string\n externalOrgId: string\n label?: string\n externalUserId?: string\n }) =>\n call(\"links.create\", () =>\n client.companies.upsertProductLink.mutate({\n companyId: input.companyId,\n externalOrgId: input.externalOrgId,\n externalUserId: input.externalUserId,\n label: input.label,\n })\n ),\n\n /**\n * Delete all product links for this product.\n *\n * Use this before re-importing to clean up old links.\n * This only affects links for YOUR product (identified by API key).\n *\n * **Options:**\n * - `deleteContacts`: Also delete contacts from linked companies\n * - `resetMrr`: Also reset MRR to 0 for linked companies\n *\n * @returns Counts of deleted/reset items\n *\n * @example Basic reset (links only)\n * ```typescript\n * const result = await os.links.reset()\n * console.log(`Deleted ${result.linksDeleted} links`)\n * ```\n *\n * @example Full reset (links + contacts + MRR)\n * ```typescript\n * const result = await os.links.reset({\n * deleteContacts: true,\n * resetMrr: true\n * })\n * console.log(`Deleted ${result.linksDeleted} links, ${result.contactsDeleted} contacts`)\n * ```\n */\n reset: (options?: { deleteContacts?: boolean; resetMrr?: boolean }) =>\n call(\"links.reset\", () =>\n client.companies.resetProductLinks.mutate(options)\n ),\n }\n }\n\n // ==========================================================================\n // Subscriptions\n // ==========================================================================\n\n /**\n * Subscription and tier management.\n *\n * Create subscriptions from tier templates, list available tiers,\n * and manage company entitlements.\n *\n * @example\n * ```typescript\n * // List available tiers\n * const tiers = await os.subscriptions.tiers()\n *\n * // Apply a tier to a company\n * const result = await os.subscriptions.create('pro', {\n * companyId: company.id,\n * features: {\n * ai_credit: { included_quantity: 500 }\n * }\n * })\n * ```\n */\n get subscriptions() {\n const client = this.client\n const call = this.call.bind(this)\n return {\n /**\n * Apply a subscription tier to a company.\n *\n * This grants the company access to all features defined in the tier.\n * Use feature overrides to customize specific feature limits.\n *\n * **Note:** This only applies feature access, it doesn't create a\n * Stripe subscription. Use `billing.linkSubscription` for that.\n *\n * @param tierCode - Tier code (e.g., \"free\", \"pro\", \"enterprise\")\n * @param options - Company ID and optional feature overrides\n * @returns Result with tier info and features applied\n *\n * @example\n * ```typescript\n * // Apply tier with defaults\n * await os.subscriptions.create('free', {\n * companyId: company.id\n * })\n *\n * // Apply with custom limits\n * await os.subscriptions.create('pro', {\n * companyId: company.id,\n * features: {\n * ai_credit: { included_quantity: 1000 },\n * seats: { max_quantity: 50 }\n * }\n * })\n * ```\n */\n create: (tierCode: string, options: ApplyTierInput) =>\n call(\"subscriptions.create\", () =>\n client.tiers.applyByCode.mutate({\n tierCode,\n companyId: options.companyId,\n featureOverrides: options.features,\n })\n ),\n\n /**\n * Get all available tiers for your product.\n *\n * Returns the list of subscription tiers configured in ChatarminOS\n * for your product, including their features.\n *\n * @returns Array of available tiers with features\n *\n * @example\n * ```typescript\n * const tiers = await os.subscriptions.tiers()\n *\n * for (const tier of tiers) {\n * console.log(`${tier.name} (${tier.code})`)\n * for (const feature of tier.features) {\n * console.log(` - ${feature.name}`)\n * }\n * }\n * ```\n */\n tiers: () =>\n call(\"subscriptions.tiers\", () =>\n client.tiers.listForProduct.query({ includeInactive: false })\n ),\n\n /**\n * Get detailed information about a specific tier.\n *\n * Returns the tier with all its features, including Stripe price IDs\n * if configured. Use this to get the prices needed to create a\n * Stripe subscription.\n *\n * @param tierCode - Tier code to look up\n * @returns Tier details with features and Stripe prices\n *\n * @example\n * ```typescript\n * const tier = await os.subscriptions.getTier('pro')\n *\n * console.log(tier.stripePriceIds)\n * // ['price_xxx', 'price_yyy']\n *\n * // Use these to create a Stripe subscription\n * const sub = await stripe.subscriptions.create({\n * customer: customerId,\n * items: tier.stripePriceIds.map(price => ({ price }))\n * })\n * ```\n */\n getTier: (tierCode: string) =>\n call(\"subscriptions.getTier\", () =>\n client.tiers.getByCode.query({ code: tierCode })\n ),\n }\n }\n\n // ==========================================================================\n // Tiers\n // ==========================================================================\n\n /**\n * Tier operations (convenient access to subscription tiers).\n *\n * Tiers define what features and limits a company gets. Each tier\n * can have associated Stripe prices for billing.\n *\n * @example Get Tier with Stripe Prices\n * ```typescript\n * const tier = await os.tiers.get('pro')\n *\n * // Create Stripe subscription using tier prices\n * const stripeSub = await stripe.subscriptions.create({\n * customer: stripeCustomerId,\n * items: tier.stripePriceIds.map(price => ({ price }))\n * })\n *\n * // Link back to OS\n * await os.billing.linkSubscription({\n * companyId: company.id,\n * stripeSubscriptionId: stripeSub.id,\n * tierCode: 'pro'\n * })\n * ```\n */\n get tiers() {\n const client = this.client\n const call = this.call.bind(this)\n return {\n /**\n * List all available tiers for your product.\n *\n * @returns Array of tiers with their features\n *\n * @example\n * ```typescript\n * const tiers = await os.tiers.list()\n * console.log(tiers.map(t => t.name))\n * // ['Free', 'Pro', 'Enterprise']\n * ```\n */\n list: () =>\n call(\"tiers.list\", () =>\n client.tiers.listForProduct.query({ includeInactive: false })\n ),\n\n /**\n * Get detailed tier information by code.\n *\n * Returns full tier details including:\n * - Base fee price (if configured)\n * - Features with config values\n * - Stripe price IDs for subscription creation (base fee + feature prices)\n * - Stripe product info\n *\n * @param tierCode - Tier code (e.g., \"free\", \"pro\")\n * @returns Tier with features, base fee, and Stripe prices\n *\n * @example\n * ```typescript\n * const tier = await os.tiers.get('pro')\n *\n * // Check base fee (for features without individual prices)\n * if (tier.baseFee) {\n * console.log(`Base fee: ${tier.baseFee.stripe.priceId}`)\n * console.log(`Amount: ${tier.baseFee.stripe.unitAmount / 100}€`)\n * }\n *\n * // Access features\n * for (const feature of tier.features) {\n * console.log(feature.code, feature.configValues)\n * }\n *\n * // Get Stripe prices for subscription creation\n * // Includes base fee + all feature prices\n * console.log(tier.stripePriceIds)\n * // ['price_base', 'price_feature1', 'price_feature2']\n *\n * // Create Stripe subscription with all prices\n * const sub = await stripe.subscriptions.create({\n * customer: stripeCustomerId,\n * items: tier.stripePriceIds.map(price => ({ price }))\n * })\n * ```\n */\n get: (tierCode: string) =>\n call(\"tiers.get\", () =>\n client.tiers.getByCode.query({ code: tierCode })\n ),\n\n /**\n * Apply a tier's features to a company (without Stripe).\n *\n * Use this for:\n * - Free tiers that don't need Stripe\n * - Trial periods\n * - Manual entitlement grants\n *\n * For paid tiers with Stripe, use `billing.linkSubscription` instead.\n *\n * @param tierCode - Tier code to apply\n * @param options - Company ID and optional feature overrides\n * @returns Result with applied features count\n *\n * @example\n * ```typescript\n * // Apply free tier\n * const result = await os.tiers.apply('free', {\n * companyId: company.id\n * })\n * console.log(`Applied ${result.featuresApplied} features`)\n *\n * // Apply with overrides\n * await os.tiers.apply('trial', {\n * companyId: company.id,\n * features: {\n * ai_credit: { included_quantity: 100 }\n * }\n * })\n * ```\n */\n apply: (tierCode: string, options: ApplyTierInput) =>\n call(\"tiers.apply\", () =>\n client.tiers.applyByCode.mutate({\n tierCode,\n companyId: options.companyId,\n featureOverrides: options.features,\n })\n ),\n }\n }\n\n // ==========================================================================\n // Onboarding\n // ==========================================================================\n\n /**\n * Complete onboarding flow in a single call.\n *\n * This is the recommended way to onboard new customers. It handles:\n * 1. Smart company matching/creation\n * 2. Product linking\n * 3. Subscription claiming/linking\n * 4. Tier feature application\n *\n * **Scenarios:**\n *\n * 1. **Stripe Checkout completed** - Pass `checkoutSessionId`\n * 2. **Free signup** - Pass `tierCode` only\n * 3. **You create Stripe subscription** - Pass `stripeSubscriptionId` + `tierCode`\n *\n * @param input - Onboarding parameters\n * @returns Result with company info and billing status\n *\n * @example Scenario 1: User completed Stripe checkout\n * ```typescript\n * const result = await os.onboard({\n * externalOrgId: 'org_abc123',\n * label: 'My Product',\n * hints: {\n * companyName: 'Acme Inc',\n * domain: 'acme.com'\n * },\n * checkoutSessionId: 'cs_test_xxx' // From Stripe callback\n * })\n *\n * // result.billingStatus.claimed = true\n * ```\n *\n * @example Scenario 2: Free tier signup\n * ```typescript\n * const result = await os.onboard({\n * externalOrgId: 'org_abc123',\n * label: 'My Product',\n * hints: {\n * companyName: 'Acme Inc',\n * domain: 'acme.com'\n * },\n * tierCode: 'free',\n * contactEmail: 'admin@acme.com',\n * contactName: 'John Doe'\n * })\n *\n * // result.billingStatus.tierApplied = true\n * ```\n *\n * @example Scenario 3: You create Stripe subscription\n * ```typescript\n * // First, get tier prices\n * const tier = await os.tiers.get('pro')\n *\n * // Create subscription on YOUR Stripe account\n * const stripeSub = await stripe.subscriptions.create({\n * customer: stripeCustomerId,\n * items: tier.stripePriceIds.map(price => ({ price }))\n * })\n *\n * // Then onboard with the subscription\n * const result = await os.onboard({\n * externalOrgId: 'org_abc123',\n * label: 'My Product',\n * hints: { companyName: 'Acme Inc' },\n * stripeSubscriptionId: stripeSub.id,\n * stripeCustomerId: stripeCustomerId,\n * tierCode: 'pro'\n * })\n *\n * // result.billingStatus.linked = true\n * // result.billingStatus.tierApplied = true\n * ```\n *\n * @example Handle existing customers\n * ```typescript\n * const result = await os.onboard({\n * externalOrgId: 'org_abc123',\n * label: 'My Product',\n * hints: { companyName: 'Acme Inc' }\n * })\n *\n * if (result.linkStatus === 'already_linked') {\n * console.log('Welcome back!')\n * } else {\n * console.log('New company created!')\n * }\n * ```\n */\n async onboard(input: OnboardInput): Promise<OnboardResult> {\n let companyId: string\n let companyName: string\n let linkStatus: \"already_linked\" | \"created\"\n\n const existing = await this.companies.get({\n externalOrgId: input.externalOrgId,\n })\n\n if (existing) {\n companyId = existing.id\n companyName = existing.name\n linkStatus = \"already_linked\"\n } else {\n const newCompany = await this.companies.create({\n name: input.hints?.companyName ?? `Company ${input.externalOrgId}`,\n domain: input.hints?.domain,\n externalOrgId: input.externalOrgId,\n label: input.label,\n contactEmail: input.contactEmail,\n contactName: input.contactName,\n createdAt: input.createdAt,\n })\n companyId = newCompany.id\n companyName = newCompany.name\n linkStatus = \"created\"\n }\n\n // Step 2: Handle billing (non-fatal - don't block company linking)\n let billingStatus: OnboardResult[\"billingStatus\"]\n\n try {\n if (input.checkoutSessionId) {\n // Claim subscription from checkout\n const claimResult = await this.billing.claimCheckout({\n companyId,\n checkoutSessionId: input.checkoutSessionId,\n })\n billingStatus = {\n subscriptionId: claimResult.subscriptionId,\n claimed: !claimResult.alreadyClaimed,\n }\n } else if (input.stripeSubscriptionId) {\n // Link existing subscription\n const linkResult = await this.billing.linkSubscription({\n companyId,\n stripeSubscriptionId: input.stripeSubscriptionId,\n stripeCustomerId: input.stripeCustomerId,\n tierCode: input.tierCode,\n })\n billingStatus = {\n subscriptionId: linkResult.subscriptionId,\n linked: !linkResult.alreadyLinked,\n tierApplied: linkResult.tierApplied,\n }\n } else if (input.tierCode) {\n // Just apply tier features (no Stripe)\n const applyResult = await this.tiers.apply(input.tierCode, {\n companyId,\n })\n billingStatus = {\n tierApplied: applyResult.featuresApplied > 0,\n }\n }\n } catch (err) {\n // Billing failed but company is still linked - capture error\n billingStatus = {\n error: err instanceof Error ? err.message : String(err),\n }\n }\n\n return {\n companyId,\n companyName,\n linkStatus,\n billingStatus,\n }\n }\n}\n\n// Re-export types that might be useful\nexport type { AppRouter }\n\n// Default export\nexport default ChatarminOS\n","import type { AppRouter } from '@chatarmin/api/trpc-types'\nimport type { createTRPCClient } from '@trpc/client'\nimport type {\n CompaniesClient,\n CreateCompanyInput,\n CreateCompanyResult,\n GetCompanyInput,\n ListCompaniesInput,\n ListCompaniesResult,\n UpdateCompanyResult,\n} from './types.js'\n\ntype SdkClient = ReturnType<typeof createTRPCClient<AppRouter>>\ntype SdkCall = <T>(operation: string, action: () => Promise<T>) => Promise<T>\n\nexport function createCompaniesClient(\n client: SdkClient,\n call: SdkCall,\n): CompaniesClient {\n return {\n get: (input: GetCompanyInput) =>\n call('companies.get', () => client.companies.get.query(input)),\n list: (input?: ListCompaniesInput) =>\n call('companies.list', () =>\n client.companies.listForProduct.query(input ?? {}),\n ),\n create: (input: CreateCompanyInput) =>\n call('companies.create', () =>\n client.companies.createWithLink.mutate(input),\n ),\n update: (input: { companyId: string; createdAt?: string }) =>\n call('companies.update', () =>\n client.companies.updateCompany.mutate(input),\n ),\n }\n}\n","import type { AppRouter } from '@chatarmin/api/trpc-types'\nimport type { createTRPCClient } from '@trpc/client'\nimport type {\n BillingClient,\n BillingOverview,\n BillingStatus,\n ClaimCheckoutInput,\n ClaimCheckoutResult,\n CreateBillingPortalSessionInput,\n EnsureFeatureSubscriptionInput,\n EnsureFeatureSubscriptionResult,\n ExportUsageInput,\n ExportUsageResult,\n GetBillingOverviewInput,\n GetUsageInput,\n LinkSubscriptionInput,\n LinkSubscriptionResult,\n ListBillingInvoicesOptions,\n PastDuePaymentUrlItem,\n ProductBillingCompanyScopeInput,\n RelinkBillingProfileInput,\n ResolveInvoicePaymentUrlInput,\n SendPastDueInvoiceInput,\n SetUsageInput,\n SyncCompanyFromStripeInput,\n SyncCompanyFromStripeResult,\n UsageQueryResult,\n UsageResult,\n} from './types.js'\n\nfunction mergeBillingInput<T>(\n companyIdOrInput: string | T,\n maybeOptions?: Partial<T>,\n): T {\n if (typeof companyIdOrInput === 'string') {\n return { companyId: companyIdOrInput, ...(maybeOptions ?? {}) } as T\n }\n\n return { ...companyIdOrInput, ...(maybeOptions ?? {}) } as T\n}\n\nfunction resolveBillingCompanyScopeInput(\n companyIdOrInput: string | ProductBillingCompanyScopeInput,\n maybeOptions?: Record<string, unknown>,\n): ProductBillingCompanyScopeInput & Record<string, unknown> {\n return mergeBillingInput(companyIdOrInput, maybeOptions) as ProductBillingCompanyScopeInput &\n Record<string, unknown>\n}\n\nfunction resolveBillingUsageInput(\n companyIdOrInput: string | GetUsageInput,\n maybeOptions?: Omit<GetUsageInput, 'companyId' | 'externalOrgId'>,\n): GetUsageInput {\n return mergeBillingInput(companyIdOrInput, maybeOptions)\n}\n\nfunction resolveBillingExportInput(\n companyIdOrInput: string | ExportUsageInput,\n maybeOptions?: Omit<ExportUsageInput, 'companyId' | 'externalOrgId' | 'format'>,\n): ExportUsageInput {\n return {\n ...mergeBillingInput<GetUsageInput>(companyIdOrInput, maybeOptions),\n format: 'csv',\n }\n}\n\ntype SdkClient = ReturnType<typeof createTRPCClient<AppRouter>>\ntype SdkCall = <T>(operation: string, action: () => Promise<T>) => Promise<T>\n\nexport function createBillingClient(client: SdkClient, call: SdkCall): BillingClient {\n return {\n setUsage: (input: SetUsageInput): Promise<UsageResult> =>\n call('billing.setUsage', () =>\n client.billing.setUsage.mutate({\n ...input,\n source: 'api',\n }) as Promise<UsageResult>,\n ),\n\n getUsageHistory: (companyId, featureCode, options) =>\n call('billing.getUsageHistory', () =>\n client.billing.getUsageHistory.query({\n companyId,\n featureCode,\n ...options,\n }),\n ),\n\n claimCheckout: (input: ClaimCheckoutInput): Promise<ClaimCheckoutResult> =>\n call('billing.claimCheckout', () =>\n client.billing.claimCheckout.mutate(input) as Promise<ClaimCheckoutResult>,\n ),\n\n linkSubscription: (input: LinkSubscriptionInput): Promise<LinkSubscriptionResult> =>\n call('billing.linkSubscription', () =>\n client.billing.linkSubscription.mutate(input) as Promise<LinkSubscriptionResult>,\n ),\n\n getStatus: (companyIdOrInput) =>\n call('billing.getStatus', () =>\n client.billing.getStatus.query(\n resolveBillingCompanyScopeInput(companyIdOrInput),\n ) as Promise<BillingStatus>,\n ),\n\n getOverview: (input: GetBillingOverviewInput): Promise<BillingOverview> =>\n call('billing.getOverview', () =>\n client.billing.getOverview.query(input) as Promise<BillingOverview>,\n ),\n\n getUsage: (companyIdOrInput, maybeOptions) =>\n call('billing.getUsage', () =>\n client.billing.getUsage.query(\n resolveBillingUsageInput(companyIdOrInput, maybeOptions),\n ) as Promise<UsageQueryResult>,\n ),\n\n exportUsage: (companyIdOrInput, maybeOptions) =>\n call('billing.exportUsage', () =>\n client.billing.exportUsage.query(\n resolveBillingExportInput(companyIdOrInput, maybeOptions),\n ),\n ),\n\n listInvoices: (companyIdOrInput, options) =>\n call('billing.listInvoices', () =>\n client.billing.listInvoices.query(\n resolveBillingCompanyScopeInput(\n companyIdOrInput,\n options as Record<string, unknown> | undefined,\n ),\n ),\n ),\n\n getPaymentMethod: (companyIdOrInput) =>\n call('billing.getPaymentMethod', () =>\n client.billing.getPaymentMethod.query(\n resolveBillingCompanyScopeInput(companyIdOrInput),\n ),\n ),\n\n createPortalSession: (input: CreateBillingPortalSessionInput) =>\n call('billing.createPortalSession', () =>\n client.billing.createPortalSession.mutate(input),\n ),\n\n resolveInvoicePaymentUrl: (input: ResolveInvoicePaymentUrlInput) =>\n call('billing.resolveProductInvoicePaymentUrl', () =>\n client.billing.resolveProductInvoicePaymentUrl.mutate(input),\n ),\n\n listPastDuePaymentUrls: (companyIdOrInput) =>\n call('billing.listProductPastDuePaymentUrls', () =>\n client.billing.listProductPastDuePaymentUrls.query(\n resolveBillingCompanyScopeInput(companyIdOrInput),\n ),\n ),\n\n sendPastDueInvoice: (input: SendPastDueInvoiceInput) =>\n call('billing.sendProductPastDueInvoice', () =>\n client.billing.sendProductPastDueInvoice.mutate(input),\n ),\n\n syncCompanyFromStripe: (\n input: SyncCompanyFromStripeInput,\n ): Promise<SyncCompanyFromStripeResult> =>\n call('billing.syncCompanyFromStripe', () =>\n client.billing.syncCompanyFromStripe.mutate(input),\n ),\n\n relinkBillingProfile: (input: RelinkBillingProfileInput) =>\n call('billing.relinkBillingProfile', () =>\n client.billing.relinkBillingProfile.mutate(input),\n ),\n\n ensureFeatureSubscription: (\n input: EnsureFeatureSubscriptionInput,\n ): Promise<EnsureFeatureSubscriptionResult> =>\n call('billing.ensureFeatureSubscription', () =>\n client.billing.ensureFeatureSubscription.mutate(input),\n ),\n }\n}\n","import type { AppRouter } from '@chatarmin/api/trpc-types'\nimport type { createTRPCClient } from '@trpc/client'\nimport type {\n FeatureAccessByExternalOrgIdResult,\n FeatureAccessItem,\n FeatureCheckByExternalOrgIdResult,\n FeatureCheckInput,\n FeatureCheckResult,\n FeatureSetAccessInput,\n FeatureSetAccessResult,\n FeaturesClient,\n ListFeatureAccessInput,\n} from './types.js'\n\ntype SdkClient = ReturnType<typeof createTRPCClient<AppRouter>>\ntype SdkCall = <T>(operation: string, action: () => Promise<T>) => Promise<T>\n\nexport function createFeaturesClient(client: SdkClient, call: SdkCall): FeaturesClient {\n return {\n check: (input: FeatureCheckInput): Promise<FeatureCheckResult> =>\n call('features.check', () =>\n client.features.check.query(input) as Promise<FeatureCheckResult>,\n ),\n\n listAccess: (input: ListFeatureAccessInput | string): Promise<FeatureAccessItem[]> =>\n call('features.listAccess', () => {\n const params = typeof input === 'string' ? { companyId: input } : input\n return client.features.getAccess.query(params) as Promise<FeatureAccessItem[]>\n }),\n\n setAccess: (input: FeatureSetAccessInput): Promise<FeatureSetAccessResult> =>\n call('features.setAccess', () =>\n client.features.updateAccess.mutate(input) as Promise<FeatureSetAccessResult>,\n ),\n\n getAccessByExternalOrgId: (\n externalOrgId: string,\n ): Promise<FeatureAccessByExternalOrgIdResult> =>\n call('features.getAccessByExternalOrgId', () =>\n client.features.getAccessByExternalOrgId.query({\n externalOrgId,\n }) as Promise<FeatureAccessByExternalOrgIdResult>,\n ),\n\n checkByExternalOrgId: (\n externalOrgId: string,\n featureCode: string,\n options?: { verifySubscription?: boolean },\n ): Promise<FeatureCheckByExternalOrgIdResult> =>\n call('features.checkByExternalOrgId', () =>\n client.features.checkByExternalOrgId.query({\n externalOrgId,\n featureCode,\n verifySubscription: options?.verifySubscription,\n }) as Promise<FeatureCheckByExternalOrgIdResult>,\n ),\n }\n}\n","export const WEBHOOK_SIGNATURE_HEADER = 'X-OS-Webhook-Signature'\nexport const WEBHOOK_TIMESTAMP_HEADER = 'X-OS-Webhook-Timestamp'\nexport const WEBHOOK_ID_HEADER = 'X-OS-Webhook-Id'\n\nexport const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300\n","export class OsWebhookSignatureVerificationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'OsWebhookSignatureVerificationError'\n }\n}\n","import type { ProductWebhookHeaders } from './types.js'\n\nexport function readWebhookHeader(\n headers: ProductWebhookHeaders,\n name: string,\n): string | null {\n if (headers instanceof Headers) {\n return headers.get(name)\n }\n\n const lowerName = name.toLowerCase()\n\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() !== lowerName || value == null) {\n continue\n }\n\n if (Array.isArray(value)) {\n return value[0] ?? null\n }\n\n return value\n }\n\n return null\n}\n","import { createHmac, timingSafeEqual } from 'node:crypto'\n\nexport function buildWebhookSignatureMaterial(\n timestamp: string,\n rawBody: string,\n): string {\n return `${timestamp}.${rawBody}`\n}\n\nexport function buildWebhookSignature(\n secret: string,\n timestamp: string,\n rawBody: string,\n): string {\n return createHmac('sha256', secret)\n .update(buildWebhookSignatureMaterial(timestamp, rawBody))\n .digest('hex')\n}\n\nexport function verifyWebhookSignature(\n secret: string,\n timestamp: string,\n rawBody: string,\n signature: string,\n): boolean {\n const expected = buildWebhookSignature(secret, timestamp, rawBody)\n\n if (expected.length !== signature.length) {\n return false\n }\n\n return timingSafeEqual(\n Buffer.from(expected, 'utf8'),\n Buffer.from(signature, 'utf8'),\n )\n}\n","import {\n DEFAULT_WEBHOOK_TOLERANCE_SECONDS,\n WEBHOOK_ID_HEADER,\n WEBHOOK_SIGNATURE_HEADER,\n WEBHOOK_TIMESTAMP_HEADER,\n} from './constants.js'\nimport { OsWebhookSignatureVerificationError } from './errors.js'\nimport { readWebhookHeader } from './read-header.js'\nimport { verifyWebhookSignature } from './signing.js'\nimport type {\n ConstructProductWebhookEventOptions,\n ProductWebhookEventPayload,\n ProductWebhookHeaders,\n VerifiedProductWebhookEvent,\n} from './types.js'\n\nfunction assertNonEmpty(value: string | null, message: string): string {\n const trimmed = value?.trim()\n if (!trimmed) {\n throw new OsWebhookSignatureVerificationError(message)\n }\n\n return trimmed\n}\n\nfunction assertTimestampWithinTolerance(\n timestamp: string,\n tolerance: number,\n now: Date,\n): void {\n if (tolerance <= 0) {\n return\n }\n\n const timestampMs = Number(timestamp)\n if (!Number.isFinite(timestampMs)) {\n throw new OsWebhookSignatureVerificationError('Invalid webhook timestamp')\n }\n\n const ageSeconds = Math.abs(now.getTime() - timestampMs) / 1000\n if (ageSeconds > tolerance) {\n throw new OsWebhookSignatureVerificationError(\n 'Webhook timestamp outside the tolerance window',\n )\n }\n}\n\nfunction parseWebhookPayload(rawBody: string): ProductWebhookEventPayload {\n try {\n const parsed = JSON.parse(rawBody) as ProductWebhookEventPayload\n if (\n typeof parsed !== 'object' ||\n parsed === null ||\n typeof parsed.type !== 'string' ||\n typeof parsed.action !== 'string' ||\n typeof parsed.idempotency_key !== 'string' ||\n typeof parsed.data !== 'object' ||\n parsed.data === null\n ) {\n throw new OsWebhookSignatureVerificationError('Invalid webhook payload shape')\n }\n\n return parsed\n } catch (error) {\n if (error instanceof OsWebhookSignatureVerificationError) {\n throw error\n }\n\n throw new OsWebhookSignatureVerificationError('Invalid JSON payload')\n }\n}\n\nexport function constructProductWebhookEvent(\n rawBody: string,\n headers: ProductWebhookHeaders,\n secret: string,\n options?: ConstructProductWebhookEventOptions,\n): VerifiedProductWebhookEvent {\n const signingSecret = secret\n if (!signingSecret) {\n throw new OsWebhookSignatureVerificationError('Webhook signing secret is required')\n }\n\n const signature = assertNonEmpty(\n readWebhookHeader(headers, WEBHOOK_SIGNATURE_HEADER),\n `Missing ${WEBHOOK_SIGNATURE_HEADER} header`,\n )\n const timestamp = assertNonEmpty(\n readWebhookHeader(headers, WEBHOOK_TIMESTAMP_HEADER),\n `Missing ${WEBHOOK_TIMESTAMP_HEADER} header`,\n )\n const webhookId = assertNonEmpty(\n readWebhookHeader(headers, WEBHOOK_ID_HEADER),\n `Missing ${WEBHOOK_ID_HEADER} header`,\n )\n\n assertTimestampWithinTolerance(\n timestamp,\n options?.tolerance ?? DEFAULT_WEBHOOK_TOLERANCE_SECONDS,\n options?.now ?? new Date(),\n )\n\n if (!verifyWebhookSignature(signingSecret, timestamp, rawBody, signature)) {\n throw new OsWebhookSignatureVerificationError(\n 'Webhook signature verification failed',\n )\n }\n\n const event = parseWebhookPayload(rawBody)\n\n return {\n ...event,\n webhookId,\n timestamp,\n }\n}\n","import {\n WEBHOOK_ID_HEADER,\n WEBHOOK_SIGNATURE_HEADER,\n WEBHOOK_TIMESTAMP_HEADER,\n} from './constants.js'\nimport { buildWebhookSignature } from './signing.js'\nimport type { GenerateTestWebhookHeadersInput } from './types.js'\n\nexport function generateTestWebhookHeaders(\n input: GenerateTestWebhookHeadersInput,\n): Record<string, string> {\n const timestamp = (input.timestamp ?? Date.now()).toString()\n const webhookId = input.webhookId ?? 'test_webhook_id'\n\n return {\n [WEBHOOK_SIGNATURE_HEADER]: buildWebhookSignature(\n input.secret,\n timestamp,\n input.payload,\n ),\n [WEBHOOK_TIMESTAMP_HEADER]: timestamp,\n [WEBHOOK_ID_HEADER]: webhookId,\n }\n}\n","import { constructProductWebhookEvent } from './construct-event.js'\nimport { generateTestWebhookHeaders } from './generate-test-headers.js'\n\nexport {\n DEFAULT_WEBHOOK_TOLERANCE_SECONDS,\n WEBHOOK_ID_HEADER,\n WEBHOOK_SIGNATURE_HEADER,\n WEBHOOK_TIMESTAMP_HEADER,\n} from './constants.js'\nexport { constructProductWebhookEvent } from './construct-event.js'\nexport { OsWebhookSignatureVerificationError } from './errors.js'\nexport { generateTestWebhookHeaders } from './generate-test-headers.js'\nexport {\n buildWebhookSignature,\n buildWebhookSignatureMaterial,\n verifyWebhookSignature,\n} from './signing.js'\nexport type {\n ConstructProductWebhookEventOptions,\n GenerateTestWebhookHeadersInput,\n ProductWebhookEventPayload,\n ProductWebhookHeaders,\n VerifiedProductWebhookEvent,\n} from './types.js'\n\n/**\n * Verify inbound OS product webhooks.\n *\n * @example\n * ```typescript\n * import { webhooks } from '@chatarmin/os/webhooks'\n *\n * export async function POST(request: Request) {\n * const rawBody = await request.text()\n * const event = webhooks.constructEvent(\n * rawBody,\n * request.headers,\n * process.env.OS_WEBHOOK_SIGNING_SECRET!,\n * )\n *\n * console.log(event.type, event.action, event.webhookId)\n * return Response.json({ received: true })\n * }\n * ```\n */\nexport const webhooks = {\n constructEvent: constructProductWebhookEvent,\n generateTestHeaders: generateTestWebhookHeaders,\n}\n"],"mappings":"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","names":[]}
@@ -8,6 +8,23 @@ export { buildWebhookSignature, buildWebhookSignatureMaterial, verifyWebhookSign
8
8
  export type { ConstructProductWebhookEventOptions, GenerateTestWebhookHeadersInput, ProductWebhookEventPayload, ProductWebhookHeaders, VerifiedProductWebhookEvent, } from './types.js';
9
9
  /**
10
10
  * Verify inbound OS product webhooks.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { webhooks } from '@chatarmin/os/webhooks'
15
+ *
16
+ * export async function POST(request: Request) {
17
+ * const rawBody = await request.text()
18
+ * const event = webhooks.constructEvent(
19
+ * rawBody,
20
+ * request.headers,
21
+ * process.env.OS_WEBHOOK_SIGNING_SECRET!,
22
+ * )
23
+ *
24
+ * console.log(event.type, event.action, event.webhookId)
25
+ * return Response.json({ received: true })
26
+ * }
27
+ * ```
11
28
  */
12
29
  export declare const webhooks: {
13
30
  constructEvent: typeof constructProductWebhookEvent;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webhooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAA;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AAEvE,OAAO,EACL,iCAAiC,EACjC,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAA;AACnE,OAAO,EAAE,mCAAmC,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AACvE,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,mCAAmC,EACnC,+BAA+B,EAC/B,0BAA0B,EAC1B,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,YAAY,CAAA;AAEnB;;GAEG;AACH,eAAO,MAAM,QAAQ;;;CAGpB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webhooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAA;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AAEvE,OAAO,EACL,iCAAiC,EACjC,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAA;AACnE,OAAO,EAAE,mCAAmC,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AACvE,OAAO,EACL,qBAAqB,EACrB,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,mCAAmC,EACnC,+BAA+B,EAC/B,0BAA0B,EAC1B,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,QAAQ;;;CAGpB,CAAA"}