@tenxyte/core 0.1.5 → 0.9.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.
@@ -1,39 +1,39 @@
1
- import type { TenxyteStorage } from './index';
2
-
3
- /**
4
- * CookieStorage implementation
5
- * Note: To be secure, tokens should be HttpOnly where possible.
6
- * This class handles client-side cookies if necessary.
7
- */
8
- export class CookieStorage implements TenxyteStorage {
9
- private defaultOptions: string;
10
-
11
- constructor(options: { secure?: boolean; sameSite?: 'Strict' | 'Lax' | 'None' } = {}) {
12
- const secure = options.secure ?? true;
13
- const sameSite = options.sameSite ?? 'Lax';
14
- this.defaultOptions = `path=/; SameSite=${sameSite}${secure ? '; Secure' : ''}`;
15
- }
16
-
17
- getItem(key: string): string | null {
18
- if (typeof document === 'undefined') return null;
19
- const match = document.cookie.match(new RegExp(`(^| )${key}=([^;]+)`));
20
- return match ? decodeURIComponent(match[2]) : null;
21
- }
22
-
23
- setItem(key: string, value: string): void {
24
- if (typeof document === 'undefined') return;
25
- document.cookie = `${key}=${encodeURIComponent(value)}; ${this.defaultOptions}`;
26
- }
27
-
28
- removeItem(key: string): void {
29
- if (typeof document === 'undefined') return;
30
- document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
31
- }
32
-
33
- clear(): void {
34
- // Cannot easily clear all cookies securely because we don't know them all
35
- // Usually auth keys are known, e.g., tx_access, tx_refresh
36
- this.removeItem('tx_access');
37
- this.removeItem('tx_refresh');
38
- }
39
- }
1
+ import type { TenxyteStorage } from './index';
2
+
3
+ /**
4
+ * CookieStorage implementation
5
+ * Note: To be secure, tokens should be HttpOnly where possible.
6
+ * This class handles client-side cookies if necessary.
7
+ */
8
+ export class CookieStorage implements TenxyteStorage {
9
+ private defaultOptions: string;
10
+
11
+ constructor(options: { secure?: boolean; sameSite?: 'Strict' | 'Lax' | 'None' } = {}) {
12
+ const secure = options.secure ?? true;
13
+ const sameSite = options.sameSite ?? 'Lax';
14
+ this.defaultOptions = `path=/; SameSite=${sameSite}${secure ? '; Secure' : ''}`;
15
+ }
16
+
17
+ getItem(key: string): string | null {
18
+ if (typeof document === 'undefined') return null;
19
+ const match = document.cookie.match(new RegExp(`(^| )${key}=([^;]+)`));
20
+ return match ? decodeURIComponent(match[2]) : null;
21
+ }
22
+
23
+ setItem(key: string, value: string): void {
24
+ if (typeof document === 'undefined') return;
25
+ document.cookie = `${key}=${encodeURIComponent(value)}; ${this.defaultOptions}`;
26
+ }
27
+
28
+ removeItem(key: string): void {
29
+ if (typeof document === 'undefined') return;
30
+ document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
31
+ }
32
+
33
+ clear(): void {
34
+ // Cannot easily clear all cookies securely because we don't know them all
35
+ // Usually auth keys are known, e.g., tx_access, tx_refresh
36
+ this.removeItem('tx_access');
37
+ this.removeItem('tx_refresh');
38
+ }
39
+ }
@@ -1,29 +1,29 @@
1
- export interface TenxyteStorage {
2
- /**
3
- * Retrieves a value from storage.
4
- * @param key The key to retrieve
5
- */
6
- getItem(key: string): string | null | Promise<string | null>;
7
-
8
- /**
9
- * Saves a value to storage.
10
- * @param key The key to store
11
- * @param value The string value
12
- */
13
- setItem(key: string, value: string): void | Promise<void>;
14
-
15
- /**
16
- * Removes a specific key from storage.
17
- * @param key The key to remove
18
- */
19
- removeItem(key: string): void | Promise<void>;
20
-
21
- /**
22
- * Clears all storage keys managed by the SDK.
23
- */
24
- clear(): void | Promise<void>;
25
- }
26
-
27
- export * from './memory';
28
- export * from './localStorage';
29
- export * from './cookie';
1
+ export interface TenxyteStorage {
2
+ /**
3
+ * Retrieves a value from storage.
4
+ * @param key The key to retrieve
5
+ */
6
+ getItem(key: string): string | null | Promise<string | null>;
7
+
8
+ /**
9
+ * Saves a value to storage.
10
+ * @param key The key to store
11
+ * @param value The string value
12
+ */
13
+ setItem(key: string, value: string): void | Promise<void>;
14
+
15
+ /**
16
+ * Removes a specific key from storage.
17
+ * @param key The key to remove
18
+ */
19
+ removeItem(key: string): void | Promise<void>;
20
+
21
+ /**
22
+ * Clears all storage keys managed by the SDK.
23
+ */
24
+ clear(): void | Promise<void>;
25
+ }
26
+
27
+ export * from './memory';
28
+ export * from './localStorage';
29
+ export * from './cookie';
@@ -1,75 +1,75 @@
1
- import type { TenxyteStorage } from './index';
2
- import { MemoryStorage } from './memory';
3
-
4
- /**
5
- * LocalStorage wrapper for the browser.
6
- * Degrades gracefully to MemoryStorage if localStorage is unavailable
7
- * (e.g., SSR, Private Browsing mode strictness).
8
- */
9
- export class LocalStorage implements TenxyteStorage {
10
- private fallbackMemoryStore: MemoryStorage | null = null;
11
- private isAvailable: boolean;
12
-
13
- constructor() {
14
- this.isAvailable = this.checkAvailability();
15
- if (!this.isAvailable) {
16
- this.fallbackMemoryStore = new MemoryStorage();
17
- }
18
- }
19
-
20
- private checkAvailability(): boolean {
21
- try {
22
- if (typeof window === 'undefined' || !window.localStorage) {
23
- return false;
24
- }
25
- const testKey = '__tenxyte_test__';
26
- window.localStorage.setItem(testKey, '1');
27
- window.localStorage.removeItem(testKey);
28
- return true;
29
- } catch (e) {
30
- return false;
31
- }
32
- }
33
-
34
- getItem(key: string): string | null {
35
- if (!this.isAvailable && this.fallbackMemoryStore) {
36
- return this.fallbackMemoryStore.getItem(key);
37
- }
38
- return window.localStorage.getItem(key);
39
- }
40
-
41
- setItem(key: string, value: string): void {
42
- if (!this.isAvailable && this.fallbackMemoryStore) {
43
- this.fallbackMemoryStore.setItem(key, value);
44
- return;
45
- }
46
- try {
47
- window.localStorage.setItem(key, value);
48
- } catch (e) {
49
- // Storage quota exceeded or similar error
50
- console.warn(`[Tenxyte SDK] Warning: failed to write to localStorage for key ${key}`);
51
- }
52
- }
53
-
54
- removeItem(key: string): void {
55
- if (!this.isAvailable && this.fallbackMemoryStore) {
56
- this.fallbackMemoryStore.removeItem(key);
57
- return;
58
- }
59
- window.localStorage.removeItem(key);
60
- }
61
-
62
- clear(): void {
63
- if (!this.isAvailable && this.fallbackMemoryStore) {
64
- this.fallbackMemoryStore.clear();
65
- return;
66
- }
67
- // We ideally only clear tenxyte specific keys if needed,
68
- // but standard clear() removes everything.
69
- // If the library only ever writes specific keys,
70
- // we could keep track of them and iterate, but for now clear() is standard.
71
- // For safer implementation we could just let the caller do removeItems() individually
72
- // but let's conform to the clear API.
73
- window.localStorage.clear();
74
- }
75
- }
1
+ import type { TenxyteStorage } from './index';
2
+ import { MemoryStorage } from './memory';
3
+
4
+ /**
5
+ * LocalStorage wrapper for the browser.
6
+ * Degrades gracefully to MemoryStorage if localStorage is unavailable
7
+ * (e.g., SSR, Private Browsing mode strictness).
8
+ */
9
+ export class LocalStorage implements TenxyteStorage {
10
+ private fallbackMemoryStore: MemoryStorage | null = null;
11
+ private isAvailable: boolean;
12
+
13
+ constructor() {
14
+ this.isAvailable = this.checkAvailability();
15
+ if (!this.isAvailable) {
16
+ this.fallbackMemoryStore = new MemoryStorage();
17
+ }
18
+ }
19
+
20
+ private checkAvailability(): boolean {
21
+ try {
22
+ if (typeof window === 'undefined' || !window.localStorage) {
23
+ return false;
24
+ }
25
+ const testKey = '__tenxyte_test__';
26
+ window.localStorage.setItem(testKey, '1');
27
+ window.localStorage.removeItem(testKey);
28
+ return true;
29
+ } catch (e) {
30
+ return false;
31
+ }
32
+ }
33
+
34
+ getItem(key: string): string | null {
35
+ if (!this.isAvailable && this.fallbackMemoryStore) {
36
+ return this.fallbackMemoryStore.getItem(key);
37
+ }
38
+ return window.localStorage.getItem(key);
39
+ }
40
+
41
+ setItem(key: string, value: string): void {
42
+ if (!this.isAvailable && this.fallbackMemoryStore) {
43
+ this.fallbackMemoryStore.setItem(key, value);
44
+ return;
45
+ }
46
+ try {
47
+ window.localStorage.setItem(key, value);
48
+ } catch (e) {
49
+ // Storage quota exceeded or similar error
50
+ console.warn(`[Tenxyte SDK] Warning: failed to write to localStorage for key ${key}`);
51
+ }
52
+ }
53
+
54
+ removeItem(key: string): void {
55
+ if (!this.isAvailable && this.fallbackMemoryStore) {
56
+ this.fallbackMemoryStore.removeItem(key);
57
+ return;
58
+ }
59
+ window.localStorage.removeItem(key);
60
+ }
61
+
62
+ clear(): void {
63
+ if (!this.isAvailable && this.fallbackMemoryStore) {
64
+ this.fallbackMemoryStore.clear();
65
+ return;
66
+ }
67
+ // We ideally only clear tenxyte specific keys if needed,
68
+ // but standard clear() removes everything.
69
+ // If the library only ever writes specific keys,
70
+ // we could keep track of them and iterate, but for now clear() is standard.
71
+ // For safer implementation we could just let the caller do removeItems() individually
72
+ // but let's conform to the clear API.
73
+ window.localStorage.clear();
74
+ }
75
+ }
@@ -1,30 +1,30 @@
1
- import type { TenxyteStorage } from './index';
2
-
3
- /**
4
- * MemoryStorage implementation primarily used in Node.js (SSR)
5
- * environments or as a fallback when browser storage is unavailable.
6
- */
7
- export class MemoryStorage implements TenxyteStorage {
8
- private store: Map<string, string>;
9
-
10
- constructor() {
11
- this.store = new Map<string, string>();
12
- }
13
-
14
- getItem(key: string): string | null {
15
- const value = this.store.get(key);
16
- return value !== undefined ? value : null;
17
- }
18
-
19
- setItem(key: string, value: string): void {
20
- this.store.set(key, value);
21
- }
22
-
23
- removeItem(key: string): void {
24
- this.store.delete(key);
25
- }
26
-
27
- clear(): void {
28
- this.store.clear();
29
- }
30
- }
1
+ import type { TenxyteStorage } from './index';
2
+
3
+ /**
4
+ * MemoryStorage implementation primarily used in Node.js (SSR)
5
+ * environments or as a fallback when browser storage is unavailable.
6
+ */
7
+ export class MemoryStorage implements TenxyteStorage {
8
+ private store: Map<string, string>;
9
+
10
+ constructor() {
11
+ this.store = new Map<string, string>();
12
+ }
13
+
14
+ getItem(key: string): string | null {
15
+ const value = this.store.get(key);
16
+ return value !== undefined ? value : null;
17
+ }
18
+
19
+ setItem(key: string, value: string): void {
20
+ this.store.set(key, value);
21
+ }
22
+
23
+ removeItem(key: string): void {
24
+ this.store.delete(key);
25
+ }
26
+
27
+ clear(): void {
28
+ this.store.clear();
29
+ }
30
+ }
@@ -1,150 +1,152 @@
1
- import type { components, paths } from './api-schema';
2
-
3
- export type GeneratedSchema = components['schemas'];
4
-
5
- /**
6
- * Core User Interface exposed by the SDK.
7
- */
8
- export interface TenxyteUser {
9
- id: string; // UUID
10
- email: string | null;
11
- phone_country_code: string | null;
12
- phone_number: string | null;
13
- first_name: string;
14
- last_name: string;
15
- is_email_verified: boolean;
16
- is_phone_verified: boolean;
17
- is_2fa_enabled: boolean;
18
- roles: string[]; // Role codes e.g., ['admin', 'viewer']
19
- permissions: string[]; // Permission codes (direct + inherited)
20
- created_at: string; // ISO 8601
21
- last_login: string | null;
22
- }
23
-
24
- /**
25
- * Standard SDK Token Pair (internal structure normalized by interceptors)
26
- */
27
- export interface TokenPair {
28
- access_token: string; // JWT Bearer
29
- refresh_token: string;
30
- token_type: 'Bearer';
31
- expires_in: number; // Current access_token lifetime in seconds
32
- device_summary: string | null; // e.g., "desktop — windows 11 — chrome 122" (null if device_info absent)
33
- }
34
-
35
- /**
36
- * Standardized API Error Response wrapper
37
- */
38
- export interface TenxyteError {
39
- error: string; // Human message
40
- code: TenxyteErrorCode; // Machine identifier
41
- details?: Record<string, string[]> | string; // Per-field errors or free message
42
- retry_after?: number; // Present on 429 and 423
43
- }
44
-
45
- export type TenxyteErrorCode =
46
- // Auth
47
- | 'LOGIN_FAILED'
48
- | 'INVALID_CREDENTIALS'
49
- | 'ACCOUNT_LOCKED'
50
- | 'ACCOUNT_BANNED'
51
- | '2FA_REQUIRED'
52
- | 'ADMIN_2FA_SETUP_REQUIRED'
53
- | 'TOKEN_EXPIRED'
54
- | 'TOKEN_BLACKLISTED'
55
- | 'REFRESH_FAILED'
56
- | 'PERMISSION_DENIED'
57
- | 'SESSION_LIMIT_EXCEEDED'
58
- | 'DEVICE_LIMIT_EXCEEDED'
59
- | 'RATE_LIMITED'
60
- | 'INVALID_OTP'
61
- | 'OTP_EXPIRED'
62
- | 'INVALID_PROVIDER'
63
- | 'SOCIAL_AUTH_FAILED'
64
- | 'VALIDATION_URL_REQUIRED'
65
- | 'INVALID_TOKEN'
66
- // User / Account
67
- | 'CONFIRMATION_REQUIRED'
68
- | 'PASSWORD_REQUIRED'
69
- | 'INVALID_PASSWORD'
70
- | 'INVALID_DEVICE_INFO'
71
- // B2B / Organizations
72
- | 'ORG_NOT_FOUND'
73
- | 'NOT_ORG_MEMBER'
74
- | 'NOT_OWNER'
75
- | 'ALREADY_MEMBER'
76
- | 'MEMBER_LIMIT_EXCEEDED'
77
- | 'HAS_CHILDREN'
78
- | 'CIRCULAR_HIERARCHY'
79
- | 'LAST_OWNER_REQUIRED'
80
- | 'INVITATION_EXISTS'
81
- | 'INVALID_ROLE'
82
- // AIRS — Agent errors
83
- | 'AGENT_NOT_FOUND'
84
- | 'AGENT_SUSPENDED'
85
- | 'AGENT_REVOKED'
86
- | 'AGENT_EXPIRED'
87
- | 'BUDGET_EXCEEDED'
88
- | 'RATE_LIMIT_EXCEEDED'
89
- | 'HEARTBEAT_MISSING'
90
- | 'AIRS_DISABLED';
91
-
92
- /**
93
- * Organization Structure
94
- */
95
- export interface Organization {
96
- id: number;
97
- name: string;
98
- slug: string;
99
- description: string | null;
100
- metadata: Record<string, unknown> | null;
101
- is_active: boolean;
102
- max_members: number; // 0 = unlimited
103
- member_count: number;
104
- created_at: string;
105
- updated_at: string;
106
- parent: { id: number; name: string; slug: string } | null;
107
- children: Array<{ id: number; name: string; slug: string }>;
108
- user_role: string | null; // Current user's role in this org
109
- user_permissions: string[]; // Effective permissions in this org
110
- }
111
-
112
- /**
113
- * Base Pagination Response wrapper
114
- */
115
- export interface PaginatedResponse<T> {
116
- count: number;
117
- page: number;
118
- page_size: number;
119
- total_pages: number;
120
- next: string | null;
121
- previous: string | null;
122
- results: T[];
123
- }
124
-
125
- /**
126
- * AIRS Agent Token metadata
127
- */
128
- export interface AgentTokenSummary {
129
- id: number;
130
- agent_id: string;
131
- status: 'ACTIVE' | 'SUSPENDED' | 'REVOKED' | 'EXPIRED';
132
- expires_at: string;
133
- created_at: string;
134
- organization: string | null; // Org slug, or null
135
- current_request_count: number;
136
- }
137
-
138
- /**
139
- * Request awaiting Human-In-The-Loop approval
140
- */
141
- export interface AgentPendingAction {
142
- id: number;
143
- agent_id: string;
144
- permission: string; // e.g., "users.delete"
145
- endpoint: string;
146
- payload: unknown;
147
- confirmation_token: string;
148
- expires_at: string;
149
- created_at: string;
150
- }
1
+ import type { components, paths } from './api-schema';
2
+
3
+ export type GeneratedSchema = components['schemas'];
4
+
5
+ /**
6
+ * Core User Interface exposed by the SDK.
7
+ * Represents the authenticated entity bound to the active session.
8
+ */
9
+ export interface TenxyteUser {
10
+ id: string; // UUID
11
+ email: string | null;
12
+ phone_country_code: string | null;
13
+ phone_number: string | null;
14
+ first_name: string;
15
+ last_name: string;
16
+ is_email_verified: boolean;
17
+ is_phone_verified: boolean;
18
+ is_2fa_enabled: boolean;
19
+ roles: string[]; // Role codes e.g., ['admin', 'viewer']
20
+ permissions: string[]; // Permission codes (direct + inherited)
21
+ created_at: string; // ISO 8601
22
+ last_login: string | null;
23
+ }
24
+
25
+ /**
26
+ * Standard SDK Token Pair (internal structure normalized by interceptors).
27
+ * These are managed automatically if auto-refresh is enabled.
28
+ */
29
+ export interface TokenPair {
30
+ access_token: string; // JWT Bearer
31
+ refresh_token: string;
32
+ token_type: 'Bearer';
33
+ expires_in: number; // Current access_token lifetime in seconds
34
+ device_summary: string | null; // e.g., "desktop — windows 11 — chrome 122" (null if device_info absent)
35
+ }
36
+
37
+ /**
38
+ * Standardized API Error Response wrapper thrown by network interceptors.
39
+ */
40
+ export interface TenxyteError {
41
+ error: string; // Human message
42
+ code: TenxyteErrorCode; // Machine identifier
43
+ details?: Record<string, string[]> | string; // Per-field errors or free message
44
+ retry_after?: number; // Present on HTTP 429 and 423
45
+ }
46
+
47
+ export type TenxyteErrorCode =
48
+ // Auth
49
+ | 'LOGIN_FAILED'
50
+ | 'INVALID_CREDENTIALS'
51
+ | 'ACCOUNT_LOCKED'
52
+ | 'ACCOUNT_BANNED'
53
+ | '2FA_REQUIRED'
54
+ | 'ADMIN_2FA_SETUP_REQUIRED'
55
+ | 'TOKEN_EXPIRED'
56
+ | 'TOKEN_BLACKLISTED'
57
+ | 'REFRESH_FAILED'
58
+ | 'PERMISSION_DENIED'
59
+ | 'SESSION_LIMIT_EXCEEDED'
60
+ | 'DEVICE_LIMIT_EXCEEDED'
61
+ | 'RATE_LIMITED'
62
+ | 'INVALID_OTP'
63
+ | 'OTP_EXPIRED'
64
+ | 'INVALID_PROVIDER'
65
+ | 'SOCIAL_AUTH_FAILED'
66
+ | 'VALIDATION_URL_REQUIRED'
67
+ | 'INVALID_TOKEN'
68
+ // User / Account
69
+ | 'CONFIRMATION_REQUIRED'
70
+ | 'PASSWORD_REQUIRED'
71
+ | 'INVALID_PASSWORD'
72
+ | 'INVALID_DEVICE_INFO'
73
+ // B2B / Organizations
74
+ | 'ORG_NOT_FOUND'
75
+ | 'NOT_ORG_MEMBER'
76
+ | 'NOT_OWNER'
77
+ | 'ALREADY_MEMBER'
78
+ | 'MEMBER_LIMIT_EXCEEDED'
79
+ | 'HAS_CHILDREN'
80
+ | 'CIRCULAR_HIERARCHY'
81
+ | 'LAST_OWNER_REQUIRED'
82
+ | 'INVITATION_EXISTS'
83
+ | 'INVALID_ROLE'
84
+ // AIRS — Agent errors
85
+ | 'AGENT_NOT_FOUND'
86
+ | 'AGENT_SUSPENDED'
87
+ | 'AGENT_REVOKED'
88
+ | 'AGENT_EXPIRED'
89
+ | 'BUDGET_EXCEEDED'
90
+ | 'RATE_LIMIT_EXCEEDED'
91
+ | 'HEARTBEAT_MISSING'
92
+ | 'AIRS_DISABLED';
93
+
94
+ /**
95
+ * Organization Structure defining a B2B tenant or hierarchical unit.
96
+ */
97
+ export interface Organization {
98
+ id: number;
99
+ name: string;
100
+ slug: string;
101
+ description: string | null;
102
+ metadata: Record<string, unknown> | null;
103
+ is_active: boolean;
104
+ max_members: number; // 0 = unlimited
105
+ member_count: number;
106
+ created_at: string;
107
+ updated_at: string;
108
+ parent: { id: number; name: string; slug: string } | null;
109
+ children: Array<{ id: number; name: string; slug: string }>;
110
+ user_role: string | null; // Current user's contextual role inside this exact org
111
+ user_permissions: string[]; // Effective permissions resolving downward in this org
112
+ }
113
+
114
+ /**
115
+ * Base Pagination Response wrapper
116
+ */
117
+ export interface PaginatedResponse<T> {
118
+ count: number;
119
+ page: number;
120
+ page_size: number;
121
+ total_pages: number;
122
+ next: string | null;
123
+ previous: string | null;
124
+ results: T[];
125
+ }
126
+
127
+ /**
128
+ * AIRS Agent Token metadata
129
+ */
130
+ export interface AgentTokenSummary {
131
+ id: number;
132
+ agent_id: string;
133
+ status: 'ACTIVE' | 'SUSPENDED' | 'REVOKED' | 'EXPIRED';
134
+ expires_at: string;
135
+ created_at: string;
136
+ organization: string | null; // Org slug, or null
137
+ current_request_count: number;
138
+ }
139
+
140
+ /**
141
+ * Request awaiting Human-In-The-Loop approval
142
+ */
143
+ export interface AgentPendingAction {
144
+ id: number;
145
+ agent_id: string;
146
+ permission: string; // e.g., "users.delete"
147
+ endpoint: string;
148
+ payload: unknown;
149
+ confirmation_token: string;
150
+ expires_at: string;
151
+ created_at: string;
152
+ }