opencloud-platform-sdk 1.3.0 → 3.0.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/cli.mjs ADDED
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ var VERCEL_HEADERS = {
7
+ headers: [
8
+ {
9
+ source: "/(.*)",
10
+ headers: [
11
+ { key: "X-Frame-Options", value: "ALLOWALL" },
12
+ { key: "Content-Security-Policy", value: "frame-ancestors *" }
13
+ ]
14
+ }
15
+ ]
16
+ };
17
+ function findProjectRoot() {
18
+ let dir = process.cwd();
19
+ while (dir !== path.dirname(dir)) {
20
+ if (fs.existsSync(path.join(dir, "package.json"))) {
21
+ return dir;
22
+ }
23
+ dir = path.dirname(dir);
24
+ }
25
+ return process.cwd();
26
+ }
27
+ function setupVercelJson(projectRoot) {
28
+ const vercelJsonPath = path.join(projectRoot, "vercel.json");
29
+ try {
30
+ let config = {};
31
+ if (fs.existsSync(vercelJsonPath)) {
32
+ const content = fs.readFileSync(vercelJsonPath, "utf-8");
33
+ config = JSON.parse(content);
34
+ console.log(" Found existing vercel.json");
35
+ } else {
36
+ console.log(" Creating vercel.json");
37
+ }
38
+ if (config.headers) {
39
+ const hasFrameHeaders = config.headers.some(
40
+ (h) => h.headers?.some(
41
+ (header) => header.key === "X-Frame-Options" || header.key === "Content-Security-Policy"
42
+ )
43
+ );
44
+ if (hasFrameHeaders) {
45
+ console.log(" \u2713 Headers already configured in vercel.json");
46
+ return true;
47
+ }
48
+ config.headers.push(...VERCEL_HEADERS.headers);
49
+ } else {
50
+ config.headers = VERCEL_HEADERS.headers;
51
+ }
52
+ fs.writeFileSync(vercelJsonPath, JSON.stringify(config, null, 2));
53
+ console.log(" \u2713 Added iframe headers to vercel.json");
54
+ return true;
55
+ } catch (error) {
56
+ console.error(" \u2717 Failed to update vercel.json:", error);
57
+ return false;
58
+ }
59
+ }
60
+ function printManualInstructions() {
61
+ console.log(`
62
+ \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
63
+ \u2502 Manual Configuration Required \u2502
64
+ \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
65
+ \u2502 \u2502
66
+ \u2502 Add this to your vercel.json: \u2502
67
+ \u2502 \u2502
68
+ \u2502 { \u2502
69
+ \u2502 "headers": [ \u2502
70
+ \u2502 { \u2502
71
+ \u2502 "source": "/(.*)", \u2502
72
+ \u2502 "headers": [ \u2502
73
+ \u2502 { "key": "X-Frame-Options", "value": "ALLOWALL" },
74
+ \u2502 { "key": "Content-Security-Policy", \u2502
75
+ \u2502 "value": "frame-ancestors *" } \u2502
76
+ \u2502 ] \u2502
77
+ \u2502 } \u2502
78
+ \u2502 ] \u2502
79
+ \u2502 } \u2502
80
+ \u2502 \u2502
81
+ \u2502 Or add headers() to next.config.js: \u2502
82
+ \u2502 \u2502
83
+ \u2502 async headers() { \u2502
84
+ \u2502 return [{ \u2502
85
+ \u2502 source: '/(.*)', \u2502
86
+ \u2502 headers: [ \u2502
87
+ \u2502 { key: 'X-Frame-Options', value: 'ALLOWALL' }, \u2502
88
+ \u2502 { key: 'Content-Security-Policy', \u2502
89
+ \u2502 value: 'frame-ancestors *' } \u2502
90
+ \u2502 ] \u2502
91
+ \u2502 }]; \u2502
92
+ \u2502 } \u2502
93
+ \u2502 \u2502
94
+ \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
95
+ `);
96
+ }
97
+ function main() {
98
+ const args = process.argv.slice(2);
99
+ const command = args[0];
100
+ console.log("\n\u{1F680} OpenCloud SDK Setup\n");
101
+ if (command === "setup" || !command) {
102
+ const projectRoot = findProjectRoot();
103
+ console.log(`Project root: ${projectRoot}
104
+ `);
105
+ console.log("Configuring iframe headers for OpenCloud...\n");
106
+ const success = setupVercelJson(projectRoot);
107
+ if (success) {
108
+ console.log(`
109
+ \u2705 Setup complete!
110
+
111
+ Your app is now configured to work with OpenCloud.
112
+ After deploying, your app will be embeddable in the OpenCloud marketplace.
113
+
114
+ Next steps:
115
+ 1. Deploy your app: vercel deploy --prod
116
+ 2. Publish on OpenCloud: https://opencloud.app/publish
117
+ `);
118
+ } else {
119
+ printManualInstructions();
120
+ }
121
+ } else if (command === "help" || command === "--help" || command === "-h") {
122
+ console.log(`
123
+ Usage: opencloud-sdk [command]
124
+
125
+ Commands:
126
+ setup Configure your project for OpenCloud (default)
127
+ help Show this help message
128
+
129
+ Examples:
130
+ npx opencloud-platform-sdk setup
131
+ npx opencloud-platform-sdk
132
+ `);
133
+ } else {
134
+ console.log(`Unknown command: ${command}`);
135
+ console.log('Run "opencloud-sdk help" for usage information.');
136
+ }
137
+ }
138
+ main();
package/dist/index.d.mts CHANGED
@@ -1,103 +1,123 @@
1
1
  /**
2
- * opencloud-platform-sdk v1.3.0
2
+ * opencloud-platform-sdk v3.0.0
3
3
  * Official SDK for OpenCloud - AI App Marketplace
4
4
  *
5
- * Features:
6
- * - Automatic preview/production mode detection
7
- * - Works in bolt.diy/WebContainers preview
8
- * - Auto-detects API keys from bolt.diy builder
9
- * - Seamless transition to production with credits
10
- * - Safe for Vite/Rollup production builds (no side effects at import time)
5
+ * Standalone Mode:
6
+ * - Works directly on any domain (no iframe required)
7
+ * - Uses popup for authentication
8
+ * - Charges from user's OpenCloud wallet
11
9
  */
12
10
  interface OpenCloudConfig {
13
11
  appId: string;
14
12
  apiUrl?: string;
15
- previewApiKey?: string;
16
13
  }
17
- interface AICallParams {
18
- model: string;
19
- prompt: string;
20
- options?: Record<string, any>;
14
+ interface TrackUsageParams {
15
+ action?: string;
16
+ metadata?: Record<string, any>;
21
17
  }
22
- interface AIResponse {
18
+ interface TrackUsageResponse {
23
19
  success: boolean;
24
- text: string;
25
- usage: {
26
- promptTokens: number;
27
- completionTokens: number;
28
- totalTokens: number;
29
- };
30
- cost: number;
31
- model: string;
32
- mode: 'preview' | 'production';
20
+ charged: number;
21
+ userBalance: number;
22
+ transactionId: string;
23
+ }
24
+ interface ChargeResult {
25
+ success: boolean;
26
+ charged?: number;
27
+ balance?: number;
28
+ transactionId?: string;
29
+ error?: 'CANCELLED' | 'INSUFFICIENT_BALANCE' | 'NOT_AUTHENTICATED' | 'UNKNOWN';
33
30
  }
34
31
  interface UserSession {
35
32
  token: string;
33
+ user?: {
34
+ id: string;
35
+ email: string;
36
+ username?: string;
37
+ balance?: number;
38
+ };
39
+ }
40
+ interface UserInfo {
41
+ id: string;
42
+ email: string;
43
+ balance: number;
44
+ username?: string;
36
45
  }
37
46
  declare class OpenCloudSDK {
38
47
  private config;
39
- private heartbeatInterval?;
40
48
  private _isPreviewMode;
49
+ private _session;
50
+ private _authPopup;
41
51
  constructor();
42
- /**
43
- * Detect if running in preview/development mode
44
- */
45
52
  private detectPreviewMode;
53
+ private loadStoredSession;
54
+ private saveSession;
55
+ private clearStoredSession;
56
+ private setupMessageListener;
46
57
  /**
47
- * Check if currently in preview mode
58
+ * Check if running in preview/development mode
48
59
  */
49
60
  isPreview(): boolean;
50
61
  /**
51
- * Initialize the SDK
62
+ * Initialize the SDK with your app ID
52
63
  */
53
64
  init(options: OpenCloudConfig): void;
54
65
  /**
55
- * Set API key for preview mode
56
- * Safe to call during build - will be a no-op if not in browser
66
+ * Check if user is authenticated with OpenCloud
57
67
  */
58
- setPreviewApiKey(key: string, provider?: 'openrouter' | 'anthropic' | 'openai'): void;
68
+ isAuthenticated(): boolean;
59
69
  /**
60
- * Get API key for preview mode
61
- * Checks in order: config, localStorage, bolt.diy cookies
70
+ * Open login popup for user authentication
71
+ * Returns a promise that resolves when login is complete
62
72
  */
63
- private getPreviewApiKey;
73
+ login(): Promise<UserSession | null>;
64
74
  /**
65
- * Call an AI model - automatically uses preview or production mode
75
+ * Log out the current user
66
76
  */
67
- callAI(params: AICallParams): Promise<AIResponse>;
77
+ logout(): void;
68
78
  /**
69
- * Call AI in preview mode (direct to OpenRouter/provider)
79
+ * Get current user info
70
80
  */
71
- private callAIPreview;
81
+ getUser(): UserInfo | null;
72
82
  /**
73
- * Call AI in production mode (through OpenCloud API)
83
+ * Charge the user for using a feature
84
+ * Will automatically prompt for login if not authenticated
85
+ *
86
+ * @param action - Optional action name for analytics
87
+ * @returns ChargeResult with success status
74
88
  */
75
- private callAIProduction;
89
+ charge(action?: string, metadata?: Record<string, any>): Promise<ChargeResult>;
76
90
  /**
77
- * Get current user's balance (production only)
91
+ * Check if user can afford to use the app
78
92
  */
79
- getBalance(): Promise<number>;
93
+ canAfford(): Promise<boolean>;
80
94
  /**
81
- * Request user to purchase more tokens
95
+ * Get user's current balance
82
96
  */
83
- requestTopUp(): Promise<void>;
84
- /**
85
- * Start sending heartbeats
86
- */
87
- private startHeartbeat;
97
+ getBalance(): Promise<number>;
88
98
  /**
89
- * Send heartbeat to platform
99
+ * Open top-up popup for user to add credits
90
100
  */
91
- private sendHeartbeat;
101
+ openTopUp(): void;
92
102
  /**
93
- * Get user session token
103
+ * Get price per use for this app
94
104
  */
95
- private getUserSession;
105
+ getAppPrice(): Promise<number>;
96
106
  /**
97
- * Cleanup
107
+ * Execute a function and charge the user
108
+ * Handles authentication, balance check, and charging automatically
98
109
  */
110
+ withCharge<T>(fn: () => Promise<T>, options?: {
111
+ action?: string;
112
+ metadata?: Record<string, any>;
113
+ }): Promise<T>;
114
+ trackUsage(params?: TrackUsageParams): Promise<TrackUsageResponse>;
115
+ requestTopUp(): void;
116
+ requestLogin(): void;
117
+ getUserInfo(): Promise<UserInfo>;
118
+ clearSession(): void;
99
119
  destroy(): void;
100
120
  }
101
121
  declare const opencloud: OpenCloudSDK;
102
122
 
103
- export { type AICallParams, type AIResponse, type OpenCloudConfig, OpenCloudSDK, type UserSession, opencloud };
123
+ export { type ChargeResult, type OpenCloudConfig, OpenCloudSDK, type TrackUsageParams, type TrackUsageResponse, type UserInfo, type UserSession, opencloud };
package/dist/index.d.ts CHANGED
@@ -1,103 +1,123 @@
1
1
  /**
2
- * opencloud-platform-sdk v1.3.0
2
+ * opencloud-platform-sdk v3.0.0
3
3
  * Official SDK for OpenCloud - AI App Marketplace
4
4
  *
5
- * Features:
6
- * - Automatic preview/production mode detection
7
- * - Works in bolt.diy/WebContainers preview
8
- * - Auto-detects API keys from bolt.diy builder
9
- * - Seamless transition to production with credits
10
- * - Safe for Vite/Rollup production builds (no side effects at import time)
5
+ * Standalone Mode:
6
+ * - Works directly on any domain (no iframe required)
7
+ * - Uses popup for authentication
8
+ * - Charges from user's OpenCloud wallet
11
9
  */
12
10
  interface OpenCloudConfig {
13
11
  appId: string;
14
12
  apiUrl?: string;
15
- previewApiKey?: string;
16
13
  }
17
- interface AICallParams {
18
- model: string;
19
- prompt: string;
20
- options?: Record<string, any>;
14
+ interface TrackUsageParams {
15
+ action?: string;
16
+ metadata?: Record<string, any>;
21
17
  }
22
- interface AIResponse {
18
+ interface TrackUsageResponse {
23
19
  success: boolean;
24
- text: string;
25
- usage: {
26
- promptTokens: number;
27
- completionTokens: number;
28
- totalTokens: number;
29
- };
30
- cost: number;
31
- model: string;
32
- mode: 'preview' | 'production';
20
+ charged: number;
21
+ userBalance: number;
22
+ transactionId: string;
23
+ }
24
+ interface ChargeResult {
25
+ success: boolean;
26
+ charged?: number;
27
+ balance?: number;
28
+ transactionId?: string;
29
+ error?: 'CANCELLED' | 'INSUFFICIENT_BALANCE' | 'NOT_AUTHENTICATED' | 'UNKNOWN';
33
30
  }
34
31
  interface UserSession {
35
32
  token: string;
33
+ user?: {
34
+ id: string;
35
+ email: string;
36
+ username?: string;
37
+ balance?: number;
38
+ };
39
+ }
40
+ interface UserInfo {
41
+ id: string;
42
+ email: string;
43
+ balance: number;
44
+ username?: string;
36
45
  }
37
46
  declare class OpenCloudSDK {
38
47
  private config;
39
- private heartbeatInterval?;
40
48
  private _isPreviewMode;
49
+ private _session;
50
+ private _authPopup;
41
51
  constructor();
42
- /**
43
- * Detect if running in preview/development mode
44
- */
45
52
  private detectPreviewMode;
53
+ private loadStoredSession;
54
+ private saveSession;
55
+ private clearStoredSession;
56
+ private setupMessageListener;
46
57
  /**
47
- * Check if currently in preview mode
58
+ * Check if running in preview/development mode
48
59
  */
49
60
  isPreview(): boolean;
50
61
  /**
51
- * Initialize the SDK
62
+ * Initialize the SDK with your app ID
52
63
  */
53
64
  init(options: OpenCloudConfig): void;
54
65
  /**
55
- * Set API key for preview mode
56
- * Safe to call during build - will be a no-op if not in browser
66
+ * Check if user is authenticated with OpenCloud
57
67
  */
58
- setPreviewApiKey(key: string, provider?: 'openrouter' | 'anthropic' | 'openai'): void;
68
+ isAuthenticated(): boolean;
59
69
  /**
60
- * Get API key for preview mode
61
- * Checks in order: config, localStorage, bolt.diy cookies
70
+ * Open login popup for user authentication
71
+ * Returns a promise that resolves when login is complete
62
72
  */
63
- private getPreviewApiKey;
73
+ login(): Promise<UserSession | null>;
64
74
  /**
65
- * Call an AI model - automatically uses preview or production mode
75
+ * Log out the current user
66
76
  */
67
- callAI(params: AICallParams): Promise<AIResponse>;
77
+ logout(): void;
68
78
  /**
69
- * Call AI in preview mode (direct to OpenRouter/provider)
79
+ * Get current user info
70
80
  */
71
- private callAIPreview;
81
+ getUser(): UserInfo | null;
72
82
  /**
73
- * Call AI in production mode (through OpenCloud API)
83
+ * Charge the user for using a feature
84
+ * Will automatically prompt for login if not authenticated
85
+ *
86
+ * @param action - Optional action name for analytics
87
+ * @returns ChargeResult with success status
74
88
  */
75
- private callAIProduction;
89
+ charge(action?: string, metadata?: Record<string, any>): Promise<ChargeResult>;
76
90
  /**
77
- * Get current user's balance (production only)
91
+ * Check if user can afford to use the app
78
92
  */
79
- getBalance(): Promise<number>;
93
+ canAfford(): Promise<boolean>;
80
94
  /**
81
- * Request user to purchase more tokens
95
+ * Get user's current balance
82
96
  */
83
- requestTopUp(): Promise<void>;
84
- /**
85
- * Start sending heartbeats
86
- */
87
- private startHeartbeat;
97
+ getBalance(): Promise<number>;
88
98
  /**
89
- * Send heartbeat to platform
99
+ * Open top-up popup for user to add credits
90
100
  */
91
- private sendHeartbeat;
101
+ openTopUp(): void;
92
102
  /**
93
- * Get user session token
103
+ * Get price per use for this app
94
104
  */
95
- private getUserSession;
105
+ getAppPrice(): Promise<number>;
96
106
  /**
97
- * Cleanup
107
+ * Execute a function and charge the user
108
+ * Handles authentication, balance check, and charging automatically
98
109
  */
110
+ withCharge<T>(fn: () => Promise<T>, options?: {
111
+ action?: string;
112
+ metadata?: Record<string, any>;
113
+ }): Promise<T>;
114
+ trackUsage(params?: TrackUsageParams): Promise<TrackUsageResponse>;
115
+ requestTopUp(): void;
116
+ requestLogin(): void;
117
+ getUserInfo(): Promise<UserInfo>;
118
+ clearSession(): void;
99
119
  destroy(): void;
100
120
  }
101
121
  declare const opencloud: OpenCloudSDK;
102
122
 
103
- export { type AICallParams, type AIResponse, type OpenCloudConfig, OpenCloudSDK, type UserSession, opencloud };
123
+ export { type ChargeResult, type OpenCloudConfig, OpenCloudSDK, type TrackUsageParams, type TrackUsageResponse, type UserInfo, type UserSession, opencloud };