@syncvault/sdk 1.0.0 → 1.1.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/README.md +65 -14
- package/package.json +1 -1
- package/src/index.d.ts +15 -1
- package/src/index.js +34 -1
package/README.md
CHANGED
|
@@ -105,33 +105,59 @@ List all files for this app.
|
|
|
105
105
|
#### `vault.delete(path)`
|
|
106
106
|
Delete a file.
|
|
107
107
|
|
|
108
|
-
### Metadata Methods
|
|
108
|
+
### Metadata Methods (Preferences)
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
Metadata is unencrypted data for app preferences like theme, timezone, language. Use it for settings that don't need encryption and are needed for app logic.
|
|
111
111
|
|
|
112
112
|
#### `vault.getMetadata()`
|
|
113
|
-
Get
|
|
113
|
+
Get preferences for the current user.
|
|
114
114
|
|
|
115
115
|
#### `vault.setMetadata(metadata)`
|
|
116
|
-
Set
|
|
116
|
+
Set preferences (replaces all existing).
|
|
117
117
|
|
|
118
118
|
#### `vault.updateMetadata(metadata)`
|
|
119
|
-
Update
|
|
119
|
+
Update preferences (merges with existing).
|
|
120
120
|
|
|
121
121
|
```javascript
|
|
122
|
-
// Example: Store
|
|
122
|
+
// Example: Store user preferences
|
|
123
123
|
await vault.setMetadata({
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
theme: 'dark',
|
|
125
|
+
timezone: 'UTC',
|
|
126
|
+
language: 'en'
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
-
// Read
|
|
130
|
-
const
|
|
131
|
-
console.log(
|
|
129
|
+
// Read preferences
|
|
130
|
+
const prefs = await vault.getMetadata();
|
|
131
|
+
console.log(prefs.theme); // 'dark'
|
|
132
132
|
|
|
133
133
|
// Update specific fields
|
|
134
|
-
await vault.updateMetadata({
|
|
134
|
+
await vault.updateMetadata({ language: 'es' });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Entitlements Methods
|
|
138
|
+
|
|
139
|
+
Entitlements are read-only data set by the developer's backend. Use them for subscription status, feature flags, etc. Users can read but not modify entitlements.
|
|
140
|
+
|
|
141
|
+
#### `vault.getEntitlements()`
|
|
142
|
+
Get entitlements for the current user.
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
// Read entitlements (set by developer backend)
|
|
146
|
+
const entitlements = await vault.getEntitlements();
|
|
147
|
+
console.log(entitlements.plan); // 'premium'
|
|
148
|
+
console.log(entitlements.features); // ['advanced', 'export']
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Quota Methods
|
|
152
|
+
|
|
153
|
+
#### `vault.getQuota()`
|
|
154
|
+
Get user's storage quota information.
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
const quota = await vault.getQuota();
|
|
158
|
+
console.log(quota.quotaBytes); // 10485760 (10MB) or null if unlimited
|
|
159
|
+
console.log(quota.usedBytes); // 1048576 (1MB)
|
|
160
|
+
console.log(quota.unlimited); // false
|
|
135
161
|
```
|
|
136
162
|
|
|
137
163
|
### State Methods
|
|
@@ -158,4 +184,29 @@ Users see these permissions during OAuth authorization.
|
|
|
158
184
|
|
|
159
185
|
All data is encrypted client-side using AES-256-GCM with a key derived from the user's password using PBKDF2 (100,000 iterations). The server never sees unencrypted data.
|
|
160
186
|
|
|
161
|
-
Note: Metadata
|
|
187
|
+
Note: Metadata (preferences) and entitlements are NOT encrypted - use them only for non-sensitive settings and subscription status.
|
|
188
|
+
|
|
189
|
+
## Setting Entitlements (Developer Backend)
|
|
190
|
+
|
|
191
|
+
Entitlements can only be set from your backend using both the app token and secret token:
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
// On your backend (e.g., after payment webhook)
|
|
195
|
+
await fetch(`https://api.syncvault.dev/api/entitlements/${userId}`, {
|
|
196
|
+
method: 'PUT',
|
|
197
|
+
headers: {
|
|
198
|
+
'Content-Type': 'application/json',
|
|
199
|
+
'X-App-Token': process.env.SYNCVAULT_APP_TOKEN,
|
|
200
|
+
'X-Secret-Token': process.env.SYNCVAULT_SECRET_TOKEN
|
|
201
|
+
},
|
|
202
|
+
body: JSON.stringify({
|
|
203
|
+
entitlements: {
|
|
204
|
+
plan: 'premium',
|
|
205
|
+
features: ['advanced', 'export'],
|
|
206
|
+
expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString()
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Never expose the secret token in client-side code.
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -27,6 +27,14 @@ export interface DeleteResponse {
|
|
|
27
27
|
|
|
28
28
|
export type Metadata = Record<string, unknown>;
|
|
29
29
|
|
|
30
|
+
export type Entitlements = Record<string, unknown>;
|
|
31
|
+
|
|
32
|
+
export interface QuotaInfo {
|
|
33
|
+
quotaBytes: number | null;
|
|
34
|
+
usedBytes: number;
|
|
35
|
+
unlimited: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
export declare class SyncVault {
|
|
31
39
|
constructor(options: SyncVaultOptions);
|
|
32
40
|
|
|
@@ -45,11 +53,17 @@ export declare class SyncVault {
|
|
|
45
53
|
list(): Promise<FileInfo[]>;
|
|
46
54
|
delete(path: string): Promise<DeleteResponse>;
|
|
47
55
|
|
|
48
|
-
// Metadata operations (unencrypted
|
|
56
|
+
// Metadata operations (unencrypted, for app preferences like theme, timezone)
|
|
49
57
|
getMetadata<T extends Metadata = Metadata>(): Promise<T>;
|
|
50
58
|
setMetadata<T extends Metadata = Metadata>(metadata: T): Promise<T>;
|
|
51
59
|
updateMetadata<T extends Metadata = Metadata>(metadata: Partial<T>): Promise<T>;
|
|
52
60
|
|
|
61
|
+
// Entitlements (read-only, set by developer's backend for subscriptions, feature flags)
|
|
62
|
+
getEntitlements<T extends Entitlements = Entitlements>(): Promise<T>;
|
|
63
|
+
|
|
64
|
+
// Quota info
|
|
65
|
+
getQuota(): Promise<QuotaInfo>;
|
|
66
|
+
|
|
53
67
|
// State
|
|
54
68
|
isAuthenticated(): boolean;
|
|
55
69
|
logout(): void;
|
package/src/index.js
CHANGED
|
@@ -2,6 +2,15 @@ import { encrypt, decrypt, prepareAuthPassword } from './crypto.js';
|
|
|
2
2
|
|
|
3
3
|
const DEFAULT_SERVER = 'https://api.syncvault.dev';
|
|
4
4
|
|
|
5
|
+
export class SyncVaultError extends Error {
|
|
6
|
+
constructor(message, statusCode, data) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'SyncVaultError';
|
|
9
|
+
this.statusCode = statusCode;
|
|
10
|
+
this.data = data;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
5
14
|
export class SyncVault {
|
|
6
15
|
constructor(options = {}) {
|
|
7
16
|
if (!options.appToken) {
|
|
@@ -186,6 +195,26 @@ export class SyncVault {
|
|
|
186
195
|
return response.metadata;
|
|
187
196
|
}
|
|
188
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Get entitlements for current user (read-only, set by developer's backend)
|
|
200
|
+
* Entitlements are used for subscription status, feature flags, etc.
|
|
201
|
+
*/
|
|
202
|
+
async getEntitlements() {
|
|
203
|
+
this._checkAuth();
|
|
204
|
+
|
|
205
|
+
const response = await this._request('/api/sync/entitlements');
|
|
206
|
+
return response.entitlements;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get user storage quota info for the current app
|
|
211
|
+
*/
|
|
212
|
+
async getQuota() {
|
|
213
|
+
this._checkAuth();
|
|
214
|
+
|
|
215
|
+
return this._request('/api/sync/quota');
|
|
216
|
+
}
|
|
217
|
+
|
|
189
218
|
/**
|
|
190
219
|
* Check if user is authenticated
|
|
191
220
|
*/
|
|
@@ -239,7 +268,11 @@ export class SyncVault {
|
|
|
239
268
|
const data = await response.json();
|
|
240
269
|
|
|
241
270
|
if (!response.ok) {
|
|
242
|
-
throw new
|
|
271
|
+
throw new SyncVaultError(
|
|
272
|
+
data.error || 'Request failed',
|
|
273
|
+
response.status,
|
|
274
|
+
data
|
|
275
|
+
);
|
|
243
276
|
}
|
|
244
277
|
|
|
245
278
|
return data;
|