@omnibase/core-js 0.7.5 → 0.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.
package/dist/index.cjs CHANGED
@@ -801,25 +801,56 @@ var PermissionsClient = class {
801
801
  * on an object. This API handles read operations and is optimized for fast
802
802
  * permission checks in your application logic.
803
803
  *
804
+ * All operations are proxied through Omnibase's API at `/api/v1/permissions/read`.
805
+ *
804
806
  * Key methods:
805
- * - `checkPermission()` - Checks if a subject has permission on an object
806
- * - `checkPermissionOrError()` - Same as above but throws error if denied
807
- * - `expandPermissions()` - Expands relationships to show all granted permissions
807
+ * - `checkPermission(params)` - Checks if a subject has permission on an object
808
+ * - `checkPermissionOrError(params)` - Same as above but throws error if denied
809
+ * - `expandPermissions(namespace, object, relation, maxDepth?)` - Expands relationships to show all granted permissions
810
+ * - `postCheckPermission(maxDepth?, body)` - POST variant of permission check
808
811
  *
809
812
  * @example
813
+ * Check a single permission:
810
814
  * ```typescript
811
- * // Check permission
812
- * const result = await client.permissions.checkPermission(
813
- * undefined,
814
- * {
815
+ * const result = await omnibase.permissions.permissions.checkPermission({
816
+ * namespace: 'Tenant',
817
+ * object: 'tenant_123',
818
+ * relation: 'view',
819
+ * subjectId: 'user_456'
820
+ * });
821
+ *
822
+ * if (result.data.allowed) {
823
+ * console.log('User has permission');
824
+ * }
825
+ * ```
826
+ *
827
+ * @example
828
+ * Expand permission tree:
829
+ * ```typescript
830
+ * const tree = await omnibase.permissions.permissions.expandPermissions(
831
+ * 'Tenant',
832
+ * 'tenant_123',
833
+ * 'view'
834
+ * );
835
+ *
836
+ * console.log('Permission tree:', tree.data);
837
+ * ```
838
+ *
839
+ * @example
840
+ * Check permission or throw error:
841
+ * ```typescript
842
+ * try {
843
+ * await omnibase.permissions.permissions.checkPermissionOrError({
815
844
  * namespace: 'Tenant',
816
845
  * object: 'tenant_123',
817
- * relation: 'view',
846
+ * relation: 'edit',
818
847
  * subjectId: 'user_456'
819
- * }
820
- * );
821
- *
822
- * console.log('Has permission:', result.data.allowed);
848
+ * });
849
+ * // Permission granted
850
+ * } catch (error) {
851
+ * // Permission denied
852
+ * console.error('Access denied');
853
+ * }
823
854
  * ```
824
855
  *
825
856
  * @since 1.0.0
@@ -833,20 +864,34 @@ var PermissionsClient = class {
833
864
  * and managing role assignments. Works alongside the Keto-based
834
865
  * permissions system to provide dynamic RBAC capabilities.
835
866
  *
867
+ * Roles are stored in the database and automatically synchronized with
868
+ * Ory Keto relationships, providing a higher-level abstraction over
869
+ * raw relationship tuples.
870
+ *
836
871
  * @example
872
+ * Create a custom role:
837
873
  * ```typescript
838
- * // Create a custom role
839
874
  * const role = await omnibase.permissions.roles.create({
840
875
  * role_name: 'billing_manager',
841
876
  * permissions: ['tenant#manage_billing', 'tenant#view_invoices']
842
877
  * });
878
+ * ```
843
879
  *
844
- * // Assign role to user
880
+ * @example
881
+ * Assign role to a user:
882
+ * ```typescript
845
883
  * await omnibase.permissions.roles.assign('user_123', {
846
884
  * role_id: role.id
847
885
  * });
848
886
  * ```
849
887
  *
888
+ * @example
889
+ * List all roles:
890
+ * ```typescript
891
+ * const roles = await omnibase.permissions.roles.list();
892
+ * console.log('Available roles:', roles);
893
+ * ```
894
+ *
850
895
  * @since 0.7.0
851
896
  * @group Roles
852
897
  */
@@ -855,19 +900,43 @@ var PermissionsClient = class {
855
900
  * Creates a new PermissionsClient instance
856
901
  *
857
902
  * Initializes the client with separate endpoints for read and write operations.
858
- * The client automatically appends the appropriate Keto API paths to the base URL
859
- * for optimal performance and security separation.
903
+ * The client automatically configures the Ory Keto client libraries to use
904
+ * Omnibase's permission proxy endpoints:
905
+ * - Write endpoint: `${apiBaseUrl}/api/v1/permissions/write`
906
+ * - Read endpoint: `${apiBaseUrl}/api/v1/permissions/read`
907
+ *
908
+ * This separation follows Ory Keto's recommended architecture for optimal
909
+ * performance and security.
860
910
  *
861
- * @param apiBaseUrl - The base URL for your Omnibase API instance
862
- * @param client - The main OmnibaseClient instance (for roles handler)
911
+ * @param apiBaseUrl - The base URL for your Omnibase API instance (e.g., 'https://api.example.com')
912
+ * @param client - The main OmnibaseClient instance (required for roles handler)
863
913
  *
864
914
  * @throws {Error} When the base URL is invalid or cannot be reached
865
915
  *
866
916
  * @example
917
+ * Direct instantiation (not recommended - use OmnibaseClient instead):
867
918
  * ```typescript
868
919
  * const client = new PermissionsClient('https://api.example.com', omnibaseClient);
869
920
  * ```
870
921
  *
922
+ * @example
923
+ * Recommended usage via OmnibaseClient:
924
+ * ```typescript
925
+ * import { OmnibaseClient } from '@omnibase/core-js';
926
+ *
927
+ * const omnibase = new OmnibaseClient({
928
+ * apiUrl: 'https://api.example.com'
929
+ * });
930
+ *
931
+ * // Use the permissions client
932
+ * await omnibase.permissions.permissions.checkPermission({
933
+ * namespace: 'Tenant',
934
+ * object: 'tenant_123',
935
+ * relation: 'view',
936
+ * subjectId: 'user_456'
937
+ * });
938
+ * ```
939
+ *
871
940
  * @since 1.0.0
872
941
  * @group Client
873
942
  */
@@ -1423,6 +1492,157 @@ var TenantManger = class {
1423
1492
  }
1424
1493
  };
1425
1494
 
1495
+ // src/tenants/subscriptions.ts
1496
+ var TenantSubscriptionManager = class {
1497
+ /**
1498
+ * Creates a new TenantSubscriptionManager instance
1499
+ *
1500
+ * @param omnibaseClient - Configured Omnibase client instance
1501
+ *
1502
+ * @group Tenant Subscriptions
1503
+ */
1504
+ constructor(omnibaseClient) {
1505
+ this.omnibaseClient = omnibaseClient;
1506
+ }
1507
+ /**
1508
+ * Get all active subscriptions for the current tenant
1509
+ *
1510
+ * Retrieves all active Stripe subscriptions associated with the user's
1511
+ * currently active tenant. Returns subscriptions with config-based price IDs
1512
+ * instead of raw Stripe IDs, making it easier to match against your billing
1513
+ * configuration.
1514
+ *
1515
+ * The endpoint automatically:
1516
+ * - Fetches subscriptions from Stripe API
1517
+ * - Maps Stripe price IDs to your config price IDs
1518
+ * - Checks both current and historical price mappings
1519
+ * - Flags legacy prices from old billing configurations
1520
+ * - Filters to only active/trialing/past_due subscriptions
1521
+ *
1522
+ * Returns an empty array if:
1523
+ * - Tenant has no Stripe customer ID configured
1524
+ * - Tenant has no active subscriptions
1525
+ * - User is not authenticated
1526
+ *
1527
+ * @returns Promise resolving to array of active subscriptions
1528
+ *
1529
+ * @throws {Error} When the user is not authenticated
1530
+ * @throws {Error} When the API request fails due to network issues
1531
+ * @throws {Error} When the server returns an error response (4xx, 5xx)
1532
+ *
1533
+ * @example
1534
+ * ```typescript
1535
+ * const response = await subscriptionManager.getActive();
1536
+ *
1537
+ * if (response.data.length === 0) {
1538
+ * console.log('No active subscriptions');
1539
+ * } else {
1540
+ * response.data.forEach(sub => {
1541
+ * console.log(`Plan: ${sub.config_price_id}`);
1542
+ * console.log(`Status: ${sub.status}`);
1543
+ * if (sub.is_legacy_price) {
1544
+ * console.log('⚠️ Using legacy pricing');
1545
+ * }
1546
+ * });
1547
+ * }
1548
+ * ```
1549
+ *
1550
+ * @since 0.6.0
1551
+ * @public
1552
+ * @group Tenant Subscriptions
1553
+ */
1554
+ async getActive() {
1555
+ try {
1556
+ const response = await this.omnibaseClient.fetch(
1557
+ `/api/v1/tenants/subscriptions`,
1558
+ {
1559
+ method: "GET",
1560
+ credentials: "include"
1561
+ }
1562
+ );
1563
+ if (!response.ok) {
1564
+ const errorData = await response.text();
1565
+ throw new Error(
1566
+ `Failed to fetch subscriptions: ${response.status} - ${errorData}`
1567
+ );
1568
+ }
1569
+ const data = await response.json();
1570
+ return data;
1571
+ } catch (error) {
1572
+ console.error("Error fetching tenant subscriptions:", error);
1573
+ throw error;
1574
+ }
1575
+ }
1576
+ /**
1577
+ * Check if the current tenant has billing information configured
1578
+ *
1579
+ * Verifies whether the tenant has valid payment methods attached to their
1580
+ * Stripe customer account. This is useful for:
1581
+ * - Showing billing setup prompts
1582
+ * - Gating premium features behind payment method requirement
1583
+ * - Displaying billing status indicators in UI
1584
+ * - Determining if customer portal access should be shown
1585
+ *
1586
+ * The check verifies:
1587
+ * - Default payment source (card, bank account, etc.)
1588
+ * - Default payment method in invoice settings
1589
+ * - Whether the payment method is valid and active
1590
+ *
1591
+ * Returns `false` if:
1592
+ * - Tenant has no Stripe customer ID
1593
+ * - No payment methods are configured
1594
+ * - User is not authenticated
1595
+ *
1596
+ * @returns Promise resolving to billing status information
1597
+ *
1598
+ * @throws {Error} When the user is not authenticated
1599
+ * @throws {Error} When the API request fails due to network issues
1600
+ * @throws {Error} When the server returns an error response (4xx, 5xx)
1601
+ *
1602
+ * @example
1603
+ * ```typescript
1604
+ * const response = await subscriptionManager.getBillingStatus();
1605
+ *
1606
+ * if (!response.data.has_billing_info) {
1607
+ * // Show billing setup prompt
1608
+ * showBillingSetupModal();
1609
+ * } else if (!response.data.is_active) {
1610
+ * // Payment method exists but may be expired/invalid
1611
+ * showPaymentMethodUpdatePrompt();
1612
+ * } else {
1613
+ * // All good - show customer portal link
1614
+ * showManageBillingButton();
1615
+ * }
1616
+ * ```
1617
+ *
1618
+ * @since 0.6.0
1619
+ * @public
1620
+ * @group Tenant Subscriptions
1621
+ */
1622
+ async getBillingStatus() {
1623
+ try {
1624
+ const response = await this.omnibaseClient.fetch(
1625
+ `/api/v1/tenants/billing-status`,
1626
+ {
1627
+ method: "GET",
1628
+ credentials: "include"
1629
+ }
1630
+ );
1631
+ if (!response.ok) {
1632
+ const errorData = await response.text();
1633
+ throw new Error(
1634
+ `Failed to fetch billing status: ${response.status} - ${errorData}`
1635
+ );
1636
+ }
1637
+ const data = await response.json();
1638
+ return data;
1639
+ } catch (error) {
1640
+ console.error("Error fetching billing status:", error);
1641
+ throw error;
1642
+ }
1643
+ }
1644
+ };
1645
+
1426
1646
  // src/tenants/user.ts
1427
1647
  var TenantUserManager = class {
1428
1648
  /**
@@ -1634,6 +1854,7 @@ var TenantHandler = class {
1634
1854
  constructor(omnibaseClient) {
1635
1855
  this.invites = new TenantInviteManager(omnibaseClient);
1636
1856
  this.manage = new TenantManger(omnibaseClient);
1857
+ this.subscriptions = new TenantSubscriptionManager(omnibaseClient);
1637
1858
  this.user = new TenantUserManager(omnibaseClient);
1638
1859
  }
1639
1860
  /**
@@ -1698,6 +1919,30 @@ var TenantHandler = class {
1698
1919
  * ```
1699
1920
  */
1700
1921
  invites;
1922
+ /**
1923
+ * Tenant subscription and billing management
1924
+ *
1925
+ * Provides access to subscription data and billing status for the
1926
+ * active tenant, including legacy price detection and payment method
1927
+ * verification. All operations are automatically scoped to the user's
1928
+ * currently active tenant.
1929
+ *
1930
+ * @example
1931
+ * ```typescript
1932
+ * // Get active subscriptions
1933
+ * const subs = await tenantHandler.subscriptions.getActive();
1934
+ *
1935
+ * // Check billing status
1936
+ * const status = await tenantHandler.subscriptions.getBillingStatus();
1937
+ * if (!status.data.has_billing_info) {
1938
+ * console.log('No payment method configured');
1939
+ * }
1940
+ * ```
1941
+ *
1942
+ * @since 0.6.0
1943
+ * @group Tenant Management
1944
+ */
1945
+ subscriptions;
1701
1946
  };
1702
1947
 
1703
1948
  // src/client.ts
package/dist/index.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- export { q as ApiResponse, A as AssignRoleRequest, C as CreateRoleRequest, D as DownloadResult, N as NamespaceDefinition, p as OmnibaseClient, O as OmnibaseClientConfig, P as PermissionsClient, a as Role, R as RolesHandler, S as StorageClient, U as UpdateRoleRequest, b as UploadOptions, c as UploadResult } from './payments/index.cjs';
1
+ export { t as ApiResponse, A as AssignRoleRequest, C as CreateRoleRequest, D as DownloadResult, N as NamespaceDefinition, s as OmnibaseClient, O as OmnibaseClientConfig, P as PermissionsClient, a as Role, R as RolesHandler, S as StorageClient, U as UpdateRoleRequest, b as UploadOptions, c as UploadResult } from './payments/index.cjs';
2
2
  import '@ory/client';
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { q as ApiResponse, A as AssignRoleRequest, C as CreateRoleRequest, D as DownloadResult, N as NamespaceDefinition, p as OmnibaseClient, O as OmnibaseClientConfig, P as PermissionsClient, a as Role, R as RolesHandler, S as StorageClient, U as UpdateRoleRequest, b as UploadOptions, c as UploadResult } from './payments/index.js';
1
+ export { t as ApiResponse, A as AssignRoleRequest, C as CreateRoleRequest, D as DownloadResult, N as NamespaceDefinition, s as OmnibaseClient, O as OmnibaseClientConfig, P as PermissionsClient, a as Role, R as RolesHandler, S as StorageClient, U as UpdateRoleRequest, b as UploadOptions, c as UploadResult } from './payments/index.js';
2
2
  import '@ory/client';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PermissionsClient,
3
3
  RolesHandler
4
- } from "./chunk-V4FWENQQ.js";
4
+ } from "./chunk-5B37CXXH.js";
5
5
  import {
6
6
  PaymentHandler
7
7
  } from "./chunk-QPW6G4PA.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-I6DMWC32.js";
11
11
  import {
12
12
  TenantHandler
13
- } from "./chunk-V6HVRJCU.js";
13
+ } from "./chunk-TFAV5P6I.js";
14
14
 
15
15
  // src/client.ts
16
16
  var OmnibaseClient = class {