@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/README.md +18 -103
- package/dist/components/QidSignInButton.d.ts +3 -0
- package/dist/hooks/useQidAuth.d.ts +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +237 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +237 -55
- package/dist/index.mjs.map +1 -1
- package/dist/modules/edge.d.ts +28 -0
- package/dist/modules/vault.d.ts +24 -1
- package/package.json +34 -51
- package/rollup.config.mjs +26 -0
- package/src/components/QidSignInButton.tsx +174 -0
- package/src/hooks/useQidAuth.ts +104 -0
- package/src/index.ts +57 -0
- package/src/modules/auth.ts +77 -0
- package/src/modules/db.ts +40 -0
- package/src/modules/edge.ts +98 -0
- package/src/modules/logs.ts +30 -0
- package/src/modules/vault.ts +124 -0
- package/src/types.ts +52 -0
- package/tsconfig.json +31 -0
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
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
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
|
|
2130
|
-
|
|
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
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
sdk.auth.listen(
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
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 (
|
|
2141
|
-
|
|
2142
|
-
|
|
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
|
-
|
|
2147
|
-
|
|
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:
|
|
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: '
|
|
2158
|
-
borderRadius: '
|
|
2298
|
+
padding: '12px 24px',
|
|
2299
|
+
borderRadius: '12px',
|
|
2159
2300
|
border: 'none',
|
|
2160
|
-
fontWeight: '
|
|
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
|
-
|
|
2166
|
-
|
|
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.
|
|
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: '#
|
|
2177
|
-
padding: '
|
|
2178
|
-
borderRadius: '
|
|
2331
|
+
backgroundColor: '#0a0a0a',
|
|
2332
|
+
padding: '40px',
|
|
2333
|
+
borderRadius: '28px',
|
|
2179
2334
|
textAlign: 'center',
|
|
2180
2335
|
color: '#fff',
|
|
2181
|
-
maxWidth: '
|
|
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("
|
|
2185
|
-
|
|
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: '
|
|
2355
|
+
padding: '24px',
|
|
2189
2356
|
display: 'inline-block',
|
|
2190
|
-
borderRadius: '
|
|
2191
|
-
marginBottom: '
|
|
2357
|
+
borderRadius: '24px',
|
|
2358
|
+
marginBottom: '30px',
|
|
2359
|
+
boxShadow: '0 10px 40px rgba(0,0,0,0.3)'
|
|
2192
2360
|
} },
|
|
2193
|
-
React.createElement(
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
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
|