@flashbacktech/flashbackclient 0.0.96 → 0.0.98
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 +4 -0
- package/dist/api/client.d.ts +9 -1
- package/dist/api/client.js +40 -1
- package/dist/api/index.d.ts +2 -1
- package/dist/api/index.js +3 -1
- package/dist/api/interfaces.d.ts +5 -3
- package/dist/api/types/auth.d.ts +1 -1
- package/dist/api/types/stats.d.ts +52 -0
- package/dist/api/types/storage.d.ts +1 -1
- package/dist/gcs/index.d.ts +2 -2
- package/dist/gcs/oauth2.js +5 -3
- package/dist/gcs/storage.js +9 -7
- package/dist/utils/blob.js +2 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -12,6 +12,10 @@ TypeScript/JavaScript client for:
|
|
|
12
12
|
npm install @flashbacktech/flashbackclient
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## Documentation
|
|
16
|
+
|
|
17
|
+
For comprehensive API documentation, examples, and usage instructions, see the [Documentation](./docs/index.md).
|
|
18
|
+
|
|
15
19
|
## Usage
|
|
16
20
|
|
|
17
21
|
### Client Library
|
package/dist/api/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CreateUnitRequest, CreateUnitResponse, CreateRepoRequest, CreateRepoResponse, StorageUnit, CreateRepoKeyRequest, CreateRepoKeyResponse, GetUnitsResponse, GetReposResponse, GetRepoKeysResponse, UpdateUnitRequest, UpdateUnitResponse, ActionResponse, UpdateRepoRequest, UpdateRepoResponse, UpdateRepoKeyRequest, UpdateRepoKeyResponse, ValidateUnitRequest, ValidateUnitResponse, ValidateRepoUnitsRequest, ValidateRepoUnitsResponse, StorageUnitStatusResponse, GetUnitNodeStatsResponse, GetUnitNodeStatsRequest } from './types/storage';
|
|
2
2
|
import { IApiClient, ProviderType } from './interfaces';
|
|
3
3
|
import { ActivateResponse, DeactivateResponse, LoginBody, LoginResponse, LogoutResponse, OAuth2ResponseDTO, RefreshTokenErrorResponse, RefreshTokenResponse, RegisterBody, RegisterResponse } from './types/auth';
|
|
4
|
-
import { StatsQueryParams, StatsResponse } from './types/stats';
|
|
4
|
+
import { StatsQueryParams, StatsResponse, NodeStatsMinuteResponse, NodeStatsDailyResponse, NodeStatsQueryParams, UnitStatsResponse, RepoStatsResponse } from './types/stats';
|
|
5
5
|
interface ErrorResponse {
|
|
6
6
|
message?: string;
|
|
7
7
|
[key: string]: any;
|
|
@@ -63,5 +63,13 @@ export declare class ApiClient implements IApiClient {
|
|
|
63
63
|
private validateDateRange;
|
|
64
64
|
getDailyStats: (params: StatsQueryParams) => Promise<StatsResponse>;
|
|
65
65
|
getMinuteStats: (params: StatsQueryParams) => Promise<StatsResponse>;
|
|
66
|
+
getNodeStatsMinute: (params?: NodeStatsQueryParams) => Promise<NodeStatsMinuteResponse>;
|
|
67
|
+
getNodeStatsDaily: (params?: NodeStatsQueryParams) => Promise<NodeStatsDailyResponse>;
|
|
68
|
+
getRepoStats: (params?: {
|
|
69
|
+
repoId?: string[];
|
|
70
|
+
}) => Promise<RepoStatsResponse>;
|
|
71
|
+
getUnitStats: (params?: {
|
|
72
|
+
unitId?: string[];
|
|
73
|
+
}) => Promise<UnitStatsResponse>;
|
|
66
74
|
}
|
|
67
75
|
export {};
|
package/dist/api/client.js
CHANGED
|
@@ -137,7 +137,9 @@ class ApiClient {
|
|
|
137
137
|
return this.makeRequest('auth/github', 'POST', { code });
|
|
138
138
|
};
|
|
139
139
|
this.refreshGoogleToken = async (refreshToken) => {
|
|
140
|
-
return this.makeRequest('auth/google/refresh', 'POST', {
|
|
140
|
+
return this.makeRequest('auth/google/refresh', 'POST', {
|
|
141
|
+
refresh_token: refreshToken,
|
|
142
|
+
});
|
|
141
143
|
};
|
|
142
144
|
this.exchangeGoogleCode = async (code) => {
|
|
143
145
|
return this.makeRequest('auth/google/exchange', 'POST', { code });
|
|
@@ -248,6 +250,43 @@ class ApiClient {
|
|
|
248
250
|
queryParams.append('unitId', params.unitId.join(','));
|
|
249
251
|
return this.makeRequest(`stats/minute?${queryParams.toString()}`, 'GET', null);
|
|
250
252
|
};
|
|
253
|
+
this.getNodeStatsMinute = async (params) => {
|
|
254
|
+
const queryParams = new URLSearchParams();
|
|
255
|
+
if (params && params.unitId && params.unitId.length > 0) {
|
|
256
|
+
queryParams.append('unitId', params.unitId.join(','));
|
|
257
|
+
}
|
|
258
|
+
const response = await this.makeRequest(`stats/nodes/minute?${queryParams.toString() ? `?${queryParams.toString()}` : ''}`, 'GET', null);
|
|
259
|
+
// Process the response to convert lastUpdated strings to Date objects
|
|
260
|
+
const processedData = response.data.map((item) => ({
|
|
261
|
+
...item,
|
|
262
|
+
lastUpdated: new Date(item.lastUpdated),
|
|
263
|
+
}));
|
|
264
|
+
return {
|
|
265
|
+
...response,
|
|
266
|
+
data: processedData,
|
|
267
|
+
};
|
|
268
|
+
};
|
|
269
|
+
this.getNodeStatsDaily = async (params) => {
|
|
270
|
+
const queryParams = new URLSearchParams();
|
|
271
|
+
if (params && params.unitId && params.unitId.length > 0) {
|
|
272
|
+
queryParams.append('unitId', params.unitId.join(','));
|
|
273
|
+
}
|
|
274
|
+
return this.makeRequest(`stats/nodes/daily${queryParams.toString() ? `?${queryParams.toString()}` : ''}`, 'GET', null);
|
|
275
|
+
};
|
|
276
|
+
this.getRepoStats = async (params) => {
|
|
277
|
+
const queryParams = new URLSearchParams();
|
|
278
|
+
if (params && params.repoId && params.repoId.length > 0) {
|
|
279
|
+
queryParams.append('repoId', params.repoId.join(','));
|
|
280
|
+
}
|
|
281
|
+
return this.makeRequest(`repo/stats${queryParams.toString() ? `?${queryParams.toString()}` : ''}`, 'GET', null);
|
|
282
|
+
};
|
|
283
|
+
this.getUnitStats = async (params) => {
|
|
284
|
+
const queryParams = new URLSearchParams();
|
|
285
|
+
if (params && params.unitId && params.unitId.length > 0) {
|
|
286
|
+
queryParams.append('unitId', params.unitId.join(','));
|
|
287
|
+
}
|
|
288
|
+
return this.makeRequest(`unit/stats${queryParams.toString() ? `?${queryParams.toString()}` : ''}`, 'GET', null);
|
|
289
|
+
};
|
|
251
290
|
this.baseURL = baseURL;
|
|
252
291
|
this.headers = {};
|
|
253
292
|
this.debug = false;
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ApiClient, HttpError } from './client';
|
|
2
2
|
import * as ApiTypes from './types/storage';
|
|
3
3
|
import * as AuthTypes from './types/auth';
|
|
4
|
+
import * as StatsTypes from './types/stats';
|
|
4
5
|
import * as ApiInterfaces from './interfaces';
|
|
5
6
|
import * as BridgeTypes from './types/bridge';
|
|
6
|
-
export { ApiClient, ApiTypes, AuthTypes, ApiInterfaces, HttpError, BridgeTypes };
|
|
7
|
+
export { ApiClient, ApiTypes, AuthTypes, StatsTypes, ApiInterfaces, HttpError, BridgeTypes };
|
package/dist/api/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.BridgeTypes = exports.HttpError = exports.ApiInterfaces = exports.AuthTypes = exports.ApiTypes = exports.ApiClient = void 0;
|
|
36
|
+
exports.BridgeTypes = exports.HttpError = exports.ApiInterfaces = exports.StatsTypes = exports.AuthTypes = exports.ApiTypes = exports.ApiClient = void 0;
|
|
37
37
|
const client_1 = require("./client");
|
|
38
38
|
Object.defineProperty(exports, "ApiClient", { enumerable: true, get: function () { return client_1.ApiClient; } });
|
|
39
39
|
Object.defineProperty(exports, "HttpError", { enumerable: true, get: function () { return client_1.HttpError; } });
|
|
@@ -41,6 +41,8 @@ const ApiTypes = __importStar(require("./types/storage"));
|
|
|
41
41
|
exports.ApiTypes = ApiTypes;
|
|
42
42
|
const AuthTypes = __importStar(require("./types/auth"));
|
|
43
43
|
exports.AuthTypes = AuthTypes;
|
|
44
|
+
const StatsTypes = __importStar(require("./types/stats"));
|
|
45
|
+
exports.StatsTypes = StatsTypes;
|
|
44
46
|
const ApiInterfaces = __importStar(require("./interfaces"));
|
|
45
47
|
exports.ApiInterfaces = ApiInterfaces;
|
|
46
48
|
const BridgeTypes = __importStar(require("./types/bridge"));
|
package/dist/api/interfaces.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { StorageUnit, CreateUnitRequest, CreateUnitResponse, CreateRepoRequest, CreateRepoResponse, CreateRepoKeyRequest, CreateRepoKeyResponse, GetUnitsResponse, GetReposResponse, GetRepoKeysResponse, UpdateUnitRequest, UpdateUnitResponse, ActionResponse, UpdateRepoResponse, UpdateRepoRequest, UpdateRepoKeyRequest, UpdateRepoKeyResponse, ValidateUnitRequest, ValidateUnitResponse, ValidateRepoUnitsRequest, ValidateRepoUnitsResponse, GetUnitNodeStatsRequest, GetUnitNodeStatsResponse } from
|
|
2
|
-
import { RegisterBody, LoginBody, RegisterResponse, LoginResponse, LogoutResponse, ActivateResponse, DeactivateResponse, RefreshTokenResponse, RefreshTokenErrorResponse } from
|
|
3
|
-
import { StatsQueryParams, StatsResponse } from
|
|
1
|
+
import { StorageUnit, CreateUnitRequest, CreateUnitResponse, CreateRepoRequest, CreateRepoResponse, CreateRepoKeyRequest, CreateRepoKeyResponse, GetUnitsResponse, GetReposResponse, GetRepoKeysResponse, UpdateUnitRequest, UpdateUnitResponse, ActionResponse, UpdateRepoResponse, UpdateRepoRequest, UpdateRepoKeyRequest, UpdateRepoKeyResponse, ValidateUnitRequest, ValidateUnitResponse, ValidateRepoUnitsRequest, ValidateRepoUnitsResponse, GetUnitNodeStatsRequest, GetUnitNodeStatsResponse } from './types/storage';
|
|
2
|
+
import { RegisterBody, LoginBody, RegisterResponse, LoginResponse, LogoutResponse, ActivateResponse, DeactivateResponse, RefreshTokenResponse, RefreshTokenErrorResponse } from './types/auth';
|
|
3
|
+
import { StatsQueryParams, StatsResponse, NodeStatsMinuteResponse, NodeStatsDailyResponse, NodeStatsQueryParams } from './types/stats';
|
|
4
4
|
export declare enum ProviderType {
|
|
5
5
|
GOOGLE = "GOOGLE",
|
|
6
6
|
GITHUB = "GITHUB",
|
|
@@ -34,4 +34,6 @@ export interface IApiClient {
|
|
|
34
34
|
userDeactivate(): Promise<DeactivateResponse>;
|
|
35
35
|
getDailyStats(params: StatsQueryParams): Promise<StatsResponse>;
|
|
36
36
|
getMinuteStats(params: StatsQueryParams): Promise<StatsResponse>;
|
|
37
|
+
getNodeStatsMinute(params?: NodeStatsQueryParams): Promise<NodeStatsMinuteResponse>;
|
|
38
|
+
getNodeStatsDaily(params?: NodeStatsQueryParams): Promise<NodeStatsDailyResponse>;
|
|
37
39
|
}
|
package/dist/api/types/auth.d.ts
CHANGED
|
@@ -18,3 +18,55 @@ export interface StatsData {
|
|
|
18
18
|
size_change: bigint;
|
|
19
19
|
latency_ms: number;
|
|
20
20
|
}
|
|
21
|
+
export interface NodeStatsMinuteResponse {
|
|
22
|
+
success: boolean;
|
|
23
|
+
data: NodeStatsMinuteData[];
|
|
24
|
+
message?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface NodeStatsMinuteData {
|
|
27
|
+
nodeId: string;
|
|
28
|
+
unitId: string;
|
|
29
|
+
nodeStatus: string;
|
|
30
|
+
lastUpdated: Date;
|
|
31
|
+
latency_ms: number;
|
|
32
|
+
}
|
|
33
|
+
export interface NodeStatsDailyResponse {
|
|
34
|
+
success: boolean;
|
|
35
|
+
data: NodeStatsDailyData[];
|
|
36
|
+
message?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface NodeStatsDailyData {
|
|
39
|
+
nodeId: string;
|
|
40
|
+
unitId: string;
|
|
41
|
+
day: number;
|
|
42
|
+
online: number;
|
|
43
|
+
latency_ms: number;
|
|
44
|
+
endpoint: string;
|
|
45
|
+
region: string;
|
|
46
|
+
storageType: string;
|
|
47
|
+
provider: string;
|
|
48
|
+
status: string;
|
|
49
|
+
version: string;
|
|
50
|
+
}
|
|
51
|
+
export interface NodeStatsQueryParams {
|
|
52
|
+
unitId?: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface RepoStatsResponse {
|
|
55
|
+
success: boolean;
|
|
56
|
+
stats: {
|
|
57
|
+
repoId: string;
|
|
58
|
+
totalUploadBytes: string;
|
|
59
|
+
totalDownloadBytes: string;
|
|
60
|
+
totalSizeChange: string;
|
|
61
|
+
}[];
|
|
62
|
+
}
|
|
63
|
+
export interface UnitStatsResponse {
|
|
64
|
+
success: boolean;
|
|
65
|
+
stats: {
|
|
66
|
+
unitId: string;
|
|
67
|
+
totalCount: string;
|
|
68
|
+
totalUploadBytes: string;
|
|
69
|
+
totalDownloadBytes: string;
|
|
70
|
+
totalSizeChange: string;
|
|
71
|
+
}[];
|
|
72
|
+
}
|
package/dist/gcs/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { FlashbackAuthClient } from
|
|
2
|
-
import { FlashbackGCSStorage, FlashbackStorageOptions } from
|
|
1
|
+
import { FlashbackAuthClient } from './oauth2';
|
|
2
|
+
import { FlashbackGCSStorage, FlashbackStorageOptions } from './storage';
|
|
3
3
|
export { FlashbackAuthClient, FlashbackGCSStorage, FlashbackStorageOptions };
|
package/dist/gcs/oauth2.js
CHANGED
|
@@ -33,7 +33,7 @@ class FlashbackAuthClient extends google_auth_library_1.OAuth2Client {
|
|
|
33
33
|
await this.ensureValidToken();
|
|
34
34
|
return {
|
|
35
35
|
token: this._credentials?.access_token || null,
|
|
36
|
-
res: null
|
|
36
|
+
res: null,
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
async getRequestHeaders() {
|
|
@@ -44,7 +44,9 @@ class FlashbackAuthClient extends google_auth_library_1.OAuth2Client {
|
|
|
44
44
|
}
|
|
45
45
|
async ensureValidToken() {
|
|
46
46
|
const now = Date.now();
|
|
47
|
-
if (!this._credentials?.access_token ||
|
|
47
|
+
if (!this._credentials?.access_token ||
|
|
48
|
+
!this._credentials?.expiry_date ||
|
|
49
|
+
now >= this._credentials.expiry_date) {
|
|
48
50
|
await this.fetchToken();
|
|
49
51
|
}
|
|
50
52
|
}
|
|
@@ -57,7 +59,7 @@ class FlashbackAuthClient extends google_auth_library_1.OAuth2Client {
|
|
|
57
59
|
const { access_token, expires_in } = response.data;
|
|
58
60
|
this._credentials = {
|
|
59
61
|
access_token,
|
|
60
|
-
expiry_date: Date.now() +
|
|
62
|
+
expiry_date: Date.now() + expires_in * 1000 - 10000,
|
|
61
63
|
};
|
|
62
64
|
}
|
|
63
65
|
async request(opts) {
|
package/dist/gcs/storage.js
CHANGED
|
@@ -96,9 +96,10 @@ class FlashbackGCSStorage extends storage_1.Storage {
|
|
|
96
96
|
expires,
|
|
97
97
|
expiresPeriodInSeconds,
|
|
98
98
|
accessibleAt: accessibleAt.toISOString(),
|
|
99
|
-
contentType
|
|
99
|
+
contentType,
|
|
100
100
|
});
|
|
101
|
-
if (expiresPeriodInSeconds > 604800) {
|
|
101
|
+
if (expiresPeriodInSeconds > 604800) {
|
|
102
|
+
// 7 days in seconds
|
|
102
103
|
throw new Error('Max allowed expiration is seven days (604800 seconds).');
|
|
103
104
|
}
|
|
104
105
|
const extensionHeaders = {};
|
|
@@ -108,12 +109,11 @@ class FlashbackGCSStorage extends storage_1.Storage {
|
|
|
108
109
|
}
|
|
109
110
|
// Sort headers once and use the same order for both signedHeaders and canonicalHeaders
|
|
110
111
|
const sortedHeaderKeys = Object.keys(extensionHeaders)
|
|
111
|
-
.map(header => header.toLowerCase())
|
|
112
|
+
.map((header) => header.toLowerCase())
|
|
112
113
|
.sort();
|
|
113
114
|
const signedHeaders = sortedHeaderKeys.join(';');
|
|
114
|
-
const canonicalHeaders = sortedHeaderKeys
|
|
115
|
-
|
|
116
|
-
.join('\n') + '\n';
|
|
115
|
+
const canonicalHeaders = sortedHeaderKeys.map((key) => `${key}:${extensionHeaders[key.toLowerCase()]}`).join('\n') +
|
|
116
|
+
'\n';
|
|
117
117
|
const datestamp = accessibleAt.toISOString().split('T')[0];
|
|
118
118
|
const credentialScope = `${datestamp}/auto/storage/goog4_request`;
|
|
119
119
|
const credential = `${this.credentials.client_email}/${credentialScope}`;
|
|
@@ -162,7 +162,9 @@ class FlashbackGCSStorage extends storage_1.Storage {
|
|
|
162
162
|
sign.update(stringToSign);
|
|
163
163
|
const signature = sign.sign(this.credentials.private_key, 'hex');
|
|
164
164
|
this.doLog('Generated Signature:', signature);
|
|
165
|
-
return [
|
|
165
|
+
return [
|
|
166
|
+
`${this.apiEndpoint}/${cfg.file.bucket.name}/${cfg.file.name}?${canonicalQueryString}&X-Goog-Signature=${signature}`,
|
|
167
|
+
];
|
|
166
168
|
}
|
|
167
169
|
}
|
|
168
170
|
exports.FlashbackGCSStorage = FlashbackGCSStorage;
|
package/dist/utils/blob.js
CHANGED
|
@@ -18,6 +18,6 @@ function generateBlockID(blockIDPrefix, blockIndex) {
|
|
|
18
18
|
blockIDPrefix = blockIDPrefix.slice(0, maxAllowedBlockIDPrefixLength);
|
|
19
19
|
}
|
|
20
20
|
const res = blockIDPrefix +
|
|
21
|
-
blockIndex.toString().padStart(maxSourceStringLength - blockIDPrefix.length,
|
|
22
|
-
return Buffer.from(res).toString(
|
|
21
|
+
blockIndex.toString().padStart(maxSourceStringLength - blockIDPrefix.length, '0');
|
|
22
|
+
return Buffer.from(res).toString('base64');
|
|
23
23
|
}
|