@qidcloud/sdk 1.2.0 → 1.2.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.
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import axios from 'axios';
2
2
  import { io } from 'socket.io-client';
3
+ import { QRCodeSVG } from 'qrcode.react';
3
4
 
4
5
  class AuthModule {
5
6
  sdk;
@@ -156,6 +157,37 @@ class EdgeModule {
156
157
  const resp = await this.sdk.api.delete(`/api/edge/${name}`, { headers });
157
158
  return resp.data;
158
159
  }
160
+ /**
161
+ * Deploy a new function or update an existing one
162
+ * @param data Deployment data including name, code, and optional envVars
163
+ * @param userToken Optional session token
164
+ */
165
+ async deploy(data, userToken) {
166
+ const headers = {};
167
+ if (userToken)
168
+ headers['Authorization'] = `Bearer ${userToken}`;
169
+ const resp = await this.sdk.api.post('/api/edge/deploy', data, { headers });
170
+ return resp.data;
171
+ }
172
+ /**
173
+ * Get available serverless runtimes
174
+ */
175
+ async getRuntimes() {
176
+ const resp = await this.sdk.api.get('/api/edge/runtimes');
177
+ return resp.data;
178
+ }
179
+ /**
180
+ * Toggle centralized logging for the project's edge functions
181
+ * @param enabled Whether to enable or disable logging
182
+ * @param userToken Optional session token
183
+ */
184
+ async toggleLogging(enabled, userToken) {
185
+ const headers = {};
186
+ if (userToken)
187
+ headers['Authorization'] = `Bearer ${userToken}`;
188
+ const resp = await this.sdk.api.post('/api/edge/logs/settings', { enabled }, { headers });
189
+ return resp.data;
190
+ }
159
191
  }
160
192
 
161
193
  class VaultModule {
@@ -212,7 +244,7 @@ class VaultModule {
212
244
  return resp.data;
213
245
  }
214
246
  /**
215
- * Delete a file from storage
247
+ * Delete a file from storage (Soft Delete)
216
248
  * @param fileId Unique ID of the file
217
249
  * @param userToken Session token for user-scoped storage
218
250
  */
@@ -224,6 +256,44 @@ class VaultModule {
224
256
  const resp = await this.sdk.api.delete(`/api/storage/${fileId}`, { headers });
225
257
  return resp.data;
226
258
  }
259
+ /**
260
+ * List deleted files in the project enclave (Recycle Bin)
261
+ * @param userToken Session token for user-scoped storage
262
+ */
263
+ async listDeleted(userToken) {
264
+ const headers = {};
265
+ if (userToken) {
266
+ headers['Authorization'] = `Bearer ${userToken}`;
267
+ }
268
+ const resp = await this.sdk.api.get('/api/storage/deleted', { headers });
269
+ return resp.data;
270
+ }
271
+ /**
272
+ * Restore a deleted file from the recycle bin
273
+ * @param fileId Unique ID of the file
274
+ * @param userToken Session token for user-scoped storage
275
+ */
276
+ async restore(fileId, userToken) {
277
+ const headers = {};
278
+ if (userToken) {
279
+ headers['Authorization'] = `Bearer ${userToken}`;
280
+ }
281
+ const resp = await this.sdk.api.post(`/api/storage/restore/${fileId}`, {}, { headers });
282
+ return resp.data;
283
+ }
284
+ /**
285
+ * Permanently purge a deleted file
286
+ * @param fileId Unique ID of the file
287
+ * @param userToken Session token for user-scoped storage
288
+ */
289
+ async purge(fileId, userToken) {
290
+ const headers = {};
291
+ if (userToken) {
292
+ headers['Authorization'] = `Bearer ${userToken}`;
293
+ }
294
+ const resp = await this.sdk.api.delete(`/api/storage/purge/${fileId}`, { headers });
295
+ return resp.data;
296
+ }
227
297
  }
228
298
 
229
299
  class LogsModule {
@@ -2122,87 +2192,199 @@ function requireReact () {
2122
2192
  var reactExports = requireReact();
2123
2193
  var React = /*@__PURE__*/getDefaultExportFromCjs(reactExports);
2124
2194
 
2125
- const QidSignInButton = ({ sdk, onSuccess, onError, className, buttonText = 'Login with QidCloud' }) => {
2126
- const [modalOpen, setModalOpen] = reactExports.useState(false);
2127
- const [qrData, setQrData] = reactExports.useState(null);
2195
+ /**
2196
+ * A React hook for managing QidCloud authentication lifecycle.
2197
+ * Handles handshake initialization, WebSocket listeners, and profile fetching.
2198
+ */
2199
+ function useQidAuth(sdk) {
2200
+ const [user, setUser] = reactExports.useState(null);
2201
+ const [token, setToken] = reactExports.useState(null);
2202
+ const [session, setSession] = reactExports.useState(null);
2128
2203
  const [loading, setLoading] = reactExports.useState(false);
2129
- const startLogin = async () => {
2130
- setLoading(true);
2204
+ const [initializing, setInitializing] = reactExports.useState(false);
2205
+ const [error, setError] = reactExports.useState(null);
2206
+ // Use ref to track if we should still be listening (to avoid state updates after unmount/cancel)
2207
+ const activeSessionId = reactExports.useRef(null);
2208
+ const logout = reactExports.useCallback(() => {
2209
+ setUser(null);
2210
+ setToken(null);
2211
+ setSession(null);
2212
+ sdk.auth.disconnect();
2213
+ }, [sdk]);
2214
+ const cancel = reactExports.useCallback(() => {
2215
+ activeSessionId.current = null;
2216
+ setSession(null);
2217
+ setInitializing(false);
2218
+ sdk.auth.disconnect();
2219
+ }, [sdk]);
2220
+ const login = reactExports.useCallback(async () => {
2221
+ setInitializing(true);
2222
+ setError(null);
2131
2223
  try {
2132
- const session = await sdk.auth.createSession();
2133
- setQrData(session.qrData);
2134
- setModalOpen(true);
2135
- sdk.auth.listen(session.sessionId, async (token) => {
2136
- const user = await sdk.auth.getProfile(token);
2137
- setModalOpen(false);
2138
- onSuccess(user, token);
2224
+ const newSession = await sdk.auth.createSession();
2225
+ setSession(newSession);
2226
+ activeSessionId.current = newSession.sessionId;
2227
+ sdk.auth.listen(newSession.sessionId, async (receivedToken) => {
2228
+ // Safety check: is this still the active session?
2229
+ if (activeSessionId.current !== newSession.sessionId)
2230
+ return;
2231
+ setLoading(true);
2232
+ setInitializing(false);
2233
+ try {
2234
+ const profile = await sdk.auth.getProfile(receivedToken);
2235
+ setToken(receivedToken);
2236
+ setUser(profile);
2237
+ }
2238
+ catch (err) {
2239
+ setError(err.message || 'Failed to fetch user profile');
2240
+ }
2241
+ finally {
2242
+ setLoading(false);
2243
+ setSession(null);
2244
+ }
2139
2245
  }, (err) => {
2140
- if (onError)
2141
- onError(err);
2142
- setModalOpen(false);
2246
+ if (activeSessionId.current !== newSession.sessionId)
2247
+ return;
2248
+ setError(err);
2249
+ setInitializing(false);
2250
+ setSession(null);
2143
2251
  });
2144
2252
  }
2145
2253
  catch (err) {
2146
- if (onError)
2147
- onError(err.message || 'Failed to initiate login');
2148
- }
2149
- finally {
2150
- setLoading(false);
2254
+ setError(err.message || 'Failed to initiate login handshake');
2255
+ setInitializing(false);
2151
2256
  }
2257
+ }, [sdk]);
2258
+ // Cleanup on unmount
2259
+ reactExports.useEffect(() => {
2260
+ return () => {
2261
+ sdk.auth.disconnect();
2262
+ };
2263
+ }, [sdk]);
2264
+ return {
2265
+ user,
2266
+ token,
2267
+ loading,
2268
+ error,
2269
+ session,
2270
+ initializing,
2271
+ login,
2272
+ logout,
2273
+ cancel
2152
2274
  };
2275
+ }
2276
+
2277
+ /**
2278
+ * A ready-to-use React component for QidCloud QR identity authentication.
2279
+ */
2280
+ const QidSignInButton = ({ sdk, onSuccess, onError, className, buttonText = 'Login with QidCloud' }) => {
2281
+ const { user, token, error, session, initializing, login, cancel } = useQidAuth(sdk);
2282
+ // Watch for success
2283
+ React.useEffect(() => {
2284
+ if (user && token) {
2285
+ onSuccess(user, token);
2286
+ }
2287
+ }, [user, token, onSuccess]);
2288
+ // Watch for errors
2289
+ React.useEffect(() => {
2290
+ if (error && onError) {
2291
+ onError(error);
2292
+ }
2293
+ }, [error, onError]);
2153
2294
  return (React.createElement(React.Fragment, null,
2154
- React.createElement("button", { onClick: startLogin, disabled: loading, className: className || 'qid-signin-btn', style: {
2295
+ React.createElement("button", { onClick: login, disabled: initializing || !!session, className: className || 'qid-signin-btn', style: {
2155
2296
  backgroundColor: '#00e5ff',
2156
2297
  color: '#000',
2157
- padding: '10px 20px',
2158
- borderRadius: '8px',
2298
+ padding: '12px 24px',
2299
+ borderRadius: '12px',
2159
2300
  border: 'none',
2160
- fontWeight: 'bold',
2161
- cursor: 'pointer',
2301
+ fontWeight: '900',
2302
+ cursor: (initializing || !!session) ? 'not-allowed' : 'pointer',
2162
2303
  display: 'flex',
2163
2304
  alignItems: 'center',
2164
- gap: '10px'
2165
- } }, loading ? 'Initializing...' : buttonText),
2166
- modalOpen && (React.createElement("div", { className: "qid-modal-overlay", style: {
2305
+ gap: '10px',
2306
+ textTransform: 'uppercase',
2307
+ fontSize: '0.85rem',
2308
+ letterSpacing: '0.5px',
2309
+ boxShadow: '0 4px 15px rgba(0, 229, 255, 0.3)',
2310
+ transition: 'all 0.2s'
2311
+ } },
2312
+ React.createElement("div", { style: {
2313
+ width: '8px',
2314
+ height: '8px',
2315
+ borderRadius: '50%',
2316
+ backgroundColor: (initializing || !!session) ? '#333' : '#000',
2317
+ boxShadow: (initializing || !!session) ? 'none' : '0 0 8px rgba(0,0,0,0.5)'
2318
+ } }),
2319
+ initializing ? 'Preparing Handshake...' : (session ? 'Awaiting Scan...' : buttonText)),
2320
+ session && (React.createElement("div", { className: "qid-modal-overlay", style: {
2167
2321
  position: 'fixed',
2168
2322
  top: 0, left: 0, right: 0, bottom: 0,
2169
- backgroundColor: 'rgba(0,0,0,0.8)',
2323
+ backgroundColor: 'rgba(0,0,0,0.92)',
2170
2324
  display: 'flex',
2171
2325
  justifyContent: 'center',
2172
2326
  alignItems: 'center',
2173
- zIndex: 9999
2327
+ zIndex: 9999,
2328
+ backdropFilter: 'blur(8px)'
2174
2329
  } },
2175
2330
  React.createElement("div", { className: "qid-modal-content", style: {
2176
- backgroundColor: '#1a1a1a',
2177
- padding: '30px',
2178
- borderRadius: '16px',
2331
+ backgroundColor: '#0a0a0a',
2332
+ padding: '40px',
2333
+ borderRadius: '28px',
2179
2334
  textAlign: 'center',
2180
2335
  color: '#fff',
2181
- maxWidth: '400px',
2182
- width: '90%'
2336
+ maxWidth: '420px',
2337
+ width: '90%',
2338
+ border: '1px solid rgba(0, 229, 255, 0.2)',
2339
+ boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5)'
2183
2340
  } },
2184
- React.createElement("h2", { style: { marginBottom: '10px' } }, "Identity Handshake"),
2185
- React.createElement("p", { style: { marginBottom: '20px', fontSize: '14px', color: '#ccc' } }, "Open your QidCloud Mobile App and scan this PQC-secured QR code."),
2341
+ React.createElement("div", { style: { marginBottom: '25px' } },
2342
+ React.createElement("div", { style: {
2343
+ display: 'inline-block',
2344
+ padding: '12px 20px',
2345
+ borderRadius: '30px',
2346
+ backgroundColor: 'rgba(0, 229, 255, 0.1)',
2347
+ border: '1px solid rgba(0, 229, 255, 0.3)',
2348
+ marginBottom: '15px'
2349
+ } },
2350
+ React.createElement("span", { style: { color: '#00e5ff', fontSize: '0.7rem', fontWeight: '900', letterSpacing: '2px' } }, "PQC ENCLAVE SECURED")),
2351
+ React.createElement("h2", { style: { fontSize: '1.75rem', fontWeight: '900', marginBottom: '10px', letterSpacing: '-0.5px' } }, "Identity Handshake"),
2352
+ React.createElement("p", { style: { fontSize: '0.95rem', color: '#94a3b8', lineHeight: '1.6' } }, "Scan this encrypted gateway with your QidCloud app to authorize access.")),
2186
2353
  React.createElement("div", { style: {
2187
2354
  backgroundColor: '#fff',
2188
- padding: '10px',
2355
+ padding: '24px',
2189
2356
  display: 'inline-block',
2190
- borderRadius: '8px',
2191
- marginBottom: '20px'
2357
+ borderRadius: '24px',
2358
+ marginBottom: '30px',
2359
+ boxShadow: '0 10px 40px rgba(0,0,0,0.3)'
2192
2360
  } },
2193
- React.createElement("div", { style: { color: '#000', fontSize: '12px', wordBreak: 'break-all', width: '200px' } },
2194
- "QR: ",
2195
- qrData)),
2196
- React.createElement("button", { onClick: () => setModalOpen(false), style: {
2197
- display: 'block',
2198
- width: '100%',
2199
- padding: '10px',
2200
- backgroundColor: '#333',
2201
- color: '#fff',
2202
- border: 'none',
2203
- borderRadius: '8px',
2204
- cursor: 'pointer'
2205
- } }, "Cancel"))))));
2361
+ React.createElement(QRCodeSVG, { value: session.qrData, size: 220, level: "H", includeMargin: false, imageSettings: {
2362
+ src: "https://api.qidcloud.com/favicon.ico",
2363
+ x: undefined,
2364
+ y: undefined,
2365
+ height: 40,
2366
+ width: 40,
2367
+ excavate: true,
2368
+ } })),
2369
+ React.createElement("div", { style: { display: 'flex', flexDirection: 'column', gap: '15px' } },
2370
+ React.createElement("div", { style: { height: '4px', width: '60px', backgroundColor: '#00e5ff', margin: '0 auto', borderRadius: '2px', opacity: 0.5 } }),
2371
+ React.createElement("button", { onClick: cancel, style: {
2372
+ display: 'block',
2373
+ width: '100%',
2374
+ padding: '16px',
2375
+ backgroundColor: 'transparent',
2376
+ color: '#64748b',
2377
+ border: '1px solid rgba(148, 163, 184, 0.2)',
2378
+ borderRadius: '16px',
2379
+ cursor: 'pointer',
2380
+ fontWeight: '700',
2381
+ transition: 'all 0.2s',
2382
+ fontSize: '0.9rem'
2383
+ } }, "Cancel Handshake")),
2384
+ React.createElement("div", { style: { marginTop: '25px', fontSize: '0.75rem', color: '#475569' } },
2385
+ "Session ID: ",
2386
+ session.sessionId.slice(0, 8),
2387
+ "..."))))));
2206
2388
  };
2207
2389
 
2208
2390
  class QidCloud {
@@ -2239,5 +2421,5 @@ class QidCloud {
2239
2421
  }
2240
2422
  }
2241
2423
 
2242
- export { QidCloud, QidSignInButton, QidCloud as default };
2424
+ export { QidCloud, QidSignInButton, QidCloud as default, useQidAuth };
2243
2425
  //# sourceMappingURL=index.mjs.map