@quanticjs/files-client 4.0.0 → 4.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/dist/files-client.d.ts +17 -10
- package/dist/files-client.js +57 -18
- package/dist/files-client.module.js +10 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/keycloak-token-provider.d.ts +13 -0
- package/dist/keycloak-token-provider.js +35 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.js +12 -1
- package/package.json +1 -1
package/dist/files-client.d.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { HttpService } from '@nestjs/axios';
|
|
2
|
-
import type {
|
|
2
|
+
import type { KeycloakTokenProvider } from './keycloak-token-provider';
|
|
3
|
+
import type { RequestUploadParams, FileUploadResponse, FileConfirmResponse, FileDownloadResponse, ListFilesParams, FileListResponse, InitiateMultipartParams, MultipartInitResponse, SignPartParams, MultipartSignResponse, CompleteMultipartParams, GrantAccessParams, BatchGrantAccessParams } from './types';
|
|
3
4
|
export declare class FilesClient {
|
|
4
5
|
private readonly http;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
private readonly tokenProvider?;
|
|
7
|
+
constructor(http: HttpService, tokenProvider?: KeycloakTokenProvider | undefined);
|
|
8
|
+
private headers;
|
|
9
|
+
private resolveToken;
|
|
10
|
+
requestUploadUrl(organizationId: string, authToken: string, params: RequestUploadParams): Promise<FileUploadResponse>;
|
|
11
|
+
confirmUpload(organizationId: string, authToken: string, fileId: string): Promise<FileConfirmResponse>;
|
|
12
|
+
getDownloadUrl(organizationId: string, authToken: string, fileId: string): Promise<FileDownloadResponse>;
|
|
13
|
+
listFiles(organizationId: string, authToken: string, params?: ListFilesParams): Promise<FileListResponse>;
|
|
14
|
+
deleteFile(organizationId: string, authToken: string, fileId: string): Promise<void>;
|
|
15
|
+
grantAccess(organizationId: string, fileId: string, params: GrantAccessParams, authToken?: string): Promise<void>;
|
|
16
|
+
grantAccessBatch(organizationId: string, fileId: string, params: BatchGrantAccessParams, authToken?: string): Promise<void>;
|
|
17
|
+
revokeAccess(organizationId: string, fileId: string, granteeType: string, granteeId: string, authToken?: string): Promise<void>;
|
|
18
|
+
initiateMultipart(organizationId: string, authToken: string, params: InitiateMultipartParams): Promise<MultipartInitResponse>;
|
|
19
|
+
signPart(organizationId: string, authToken: string, fileId: string, params: SignPartParams): Promise<MultipartSignResponse>;
|
|
20
|
+
completeMultipart(organizationId: string, authToken: string, fileId: string, params: CompleteMultipartParams): Promise<FileConfirmResponse>;
|
|
14
21
|
}
|
package/dist/files-client.js
CHANGED
|
@@ -8,64 +8,103 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
exports.FilesClient = void 0;
|
|
13
16
|
const common_1 = require("@nestjs/common");
|
|
14
17
|
const axios_1 = require("@nestjs/axios");
|
|
15
18
|
const rxjs_1 = require("rxjs");
|
|
16
19
|
const ORG_HEADER = 'x-organization-id';
|
|
20
|
+
const TOKEN_PROVIDER = 'KEYCLOAK_TOKEN_PROVIDER';
|
|
17
21
|
let FilesClient = class FilesClient {
|
|
18
22
|
http;
|
|
19
|
-
|
|
23
|
+
tokenProvider;
|
|
24
|
+
constructor(http, tokenProvider) {
|
|
20
25
|
this.http = http;
|
|
26
|
+
this.tokenProvider = tokenProvider;
|
|
27
|
+
}
|
|
28
|
+
headers(organizationId, authToken) {
|
|
29
|
+
return {
|
|
30
|
+
[ORG_HEADER]: organizationId,
|
|
31
|
+
Authorization: authToken,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
async resolveToken(authToken) {
|
|
35
|
+
if (authToken)
|
|
36
|
+
return authToken;
|
|
37
|
+
if (this.tokenProvider)
|
|
38
|
+
return this.tokenProvider.getToken();
|
|
39
|
+
throw new Error('No authToken provided and no serviceAccount configured in FilesClientModule');
|
|
21
40
|
}
|
|
22
|
-
async requestUploadUrl(organizationId, params) {
|
|
41
|
+
async requestUploadUrl(organizationId, authToken, params) {
|
|
23
42
|
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.post('/files/upload-url', params, {
|
|
24
|
-
headers:
|
|
43
|
+
headers: this.headers(organizationId, authToken),
|
|
25
44
|
}));
|
|
26
45
|
return data;
|
|
27
46
|
}
|
|
28
|
-
async confirmUpload(organizationId, fileId) {
|
|
47
|
+
async confirmUpload(organizationId, authToken, fileId) {
|
|
29
48
|
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.post(`/files/${fileId}/confirm`, {}, {
|
|
30
|
-
headers:
|
|
49
|
+
headers: this.headers(organizationId, authToken),
|
|
31
50
|
}));
|
|
32
51
|
return data;
|
|
33
52
|
}
|
|
34
|
-
async getDownloadUrl(organizationId, fileId) {
|
|
53
|
+
async getDownloadUrl(organizationId, authToken, fileId) {
|
|
35
54
|
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.get(`/files/${fileId}/download-url`, {
|
|
36
|
-
headers:
|
|
55
|
+
headers: this.headers(organizationId, authToken),
|
|
37
56
|
}));
|
|
38
57
|
return data;
|
|
39
58
|
}
|
|
40
|
-
async listFiles(organizationId, params) {
|
|
59
|
+
async listFiles(organizationId, authToken, params) {
|
|
41
60
|
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.get('/files', {
|
|
42
|
-
headers:
|
|
61
|
+
headers: this.headers(organizationId, authToken),
|
|
43
62
|
params,
|
|
44
63
|
}));
|
|
45
64
|
return data;
|
|
46
65
|
}
|
|
47
|
-
async deleteFile(organizationId, fileId) {
|
|
66
|
+
async deleteFile(organizationId, authToken, fileId) {
|
|
48
67
|
await (0, rxjs_1.firstValueFrom)(this.http.delete(`/files/${fileId}`, {
|
|
49
|
-
headers:
|
|
68
|
+
headers: this.headers(organizationId, authToken),
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
async grantAccess(organizationId, fileId, params, authToken) {
|
|
72
|
+
const token = await this.resolveToken(authToken);
|
|
73
|
+
await (0, rxjs_1.firstValueFrom)(this.http.post(`/files/${fileId}/grants`, params, {
|
|
74
|
+
headers: this.headers(organizationId, token),
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
async grantAccessBatch(organizationId, fileId, params, authToken) {
|
|
78
|
+
const token = await this.resolveToken(authToken);
|
|
79
|
+
await (0, rxjs_1.firstValueFrom)(this.http.post(`/files/${fileId}/grants/batch`, params, {
|
|
80
|
+
headers: this.headers(organizationId, token),
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
async revokeAccess(organizationId, fileId, granteeType, granteeId, authToken) {
|
|
84
|
+
const token = await this.resolveToken(authToken);
|
|
85
|
+
await (0, rxjs_1.firstValueFrom)(this.http.delete(`/files/${fileId}/grants/${granteeType}/${granteeId}`, {
|
|
86
|
+
headers: this.headers(organizationId, token),
|
|
50
87
|
}));
|
|
51
88
|
}
|
|
52
|
-
async initiateMultipart(organizationId, params) {
|
|
89
|
+
async initiateMultipart(organizationId, authToken, params) {
|
|
53
90
|
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.post('/files/multipart/initiate', params, {
|
|
54
|
-
headers:
|
|
91
|
+
headers: this.headers(organizationId, authToken),
|
|
55
92
|
}));
|
|
56
93
|
return data;
|
|
57
94
|
}
|
|
58
|
-
async signPart(organizationId, fileId, params) {
|
|
59
|
-
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.post(`/files/multipart/${fileId}/sign-part`, params, { headers:
|
|
95
|
+
async signPart(organizationId, authToken, fileId, params) {
|
|
96
|
+
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.post(`/files/multipart/${fileId}/sign-part`, params, { headers: this.headers(organizationId, authToken) }));
|
|
60
97
|
return data;
|
|
61
98
|
}
|
|
62
|
-
async completeMultipart(organizationId, fileId, params) {
|
|
63
|
-
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.post(`/files/multipart/${fileId}/complete`, params, { headers:
|
|
99
|
+
async completeMultipart(organizationId, authToken, fileId, params) {
|
|
100
|
+
const { data } = await (0, rxjs_1.firstValueFrom)(this.http.post(`/files/multipart/${fileId}/complete`, params, { headers: this.headers(organizationId, authToken) }));
|
|
64
101
|
return data;
|
|
65
102
|
}
|
|
66
103
|
};
|
|
67
104
|
exports.FilesClient = FilesClient;
|
|
68
105
|
exports.FilesClient = FilesClient = __decorate([
|
|
69
106
|
(0, common_1.Injectable)(),
|
|
70
|
-
|
|
107
|
+
__param(1, (0, common_1.Optional)()),
|
|
108
|
+
__param(1, (0, common_1.Inject)(TOKEN_PROVIDER)),
|
|
109
|
+
__metadata("design:paramtypes", [axios_1.HttpService, Function])
|
|
71
110
|
], FilesClient);
|
|
@@ -11,8 +11,17 @@ exports.FilesClientModule = void 0;
|
|
|
11
11
|
const common_1 = require("@nestjs/common");
|
|
12
12
|
const axios_1 = require("@nestjs/axios");
|
|
13
13
|
const files_client_1 = require("./files-client");
|
|
14
|
+
const keycloak_token_provider_1 = require("./keycloak-token-provider");
|
|
15
|
+
const TOKEN_PROVIDER = 'KEYCLOAK_TOKEN_PROVIDER';
|
|
14
16
|
let FilesClientModule = FilesClientModule_1 = class FilesClientModule {
|
|
15
17
|
static forRoot(options) {
|
|
18
|
+
const providers = [files_client_1.FilesClient];
|
|
19
|
+
if (options.serviceAccount) {
|
|
20
|
+
providers.push({
|
|
21
|
+
provide: TOKEN_PROVIDER,
|
|
22
|
+
useValue: new keycloak_token_provider_1.KeycloakTokenProvider(options.serviceAccount),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
16
25
|
return {
|
|
17
26
|
module: FilesClientModule_1,
|
|
18
27
|
imports: [
|
|
@@ -21,7 +30,7 @@ let FilesClientModule = FilesClientModule_1 = class FilesClientModule {
|
|
|
21
30
|
timeout: options.timeout ?? 10_000,
|
|
22
31
|
}),
|
|
23
32
|
],
|
|
24
|
-
providers
|
|
33
|
+
providers,
|
|
25
34
|
exports: [files_client_1.FilesClient],
|
|
26
35
|
};
|
|
27
36
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { FilesClientModule } from './files-client.module';
|
|
2
2
|
export { FilesClient } from './files-client';
|
|
3
|
-
export {
|
|
3
|
+
export { KeycloakTokenProvider, type ServiceAccountConfig } from './keycloak-token-provider';
|
|
4
|
+
export { type FilesClientOptions, FileStatus, FilePermission, GranteeType, type FileDto, type RequestUploadParams, type FileUploadResponse, type FileConfirmResponse, type FileDownloadResponse, type ListFilesParams, type FileListResponse, type InitiateMultipartParams, type MultipartInitResponse, type SignPartParams, type MultipartSignResponse, type CompleteMultipartParams, type GrantAccessParams, type GrantEntry, type BatchGrantAccessParams, } from './types';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FileStatus = exports.FilesClient = exports.FilesClientModule = void 0;
|
|
3
|
+
exports.GranteeType = exports.FilePermission = exports.FileStatus = exports.KeycloakTokenProvider = exports.FilesClient = exports.FilesClientModule = void 0;
|
|
4
4
|
var files_client_module_1 = require("./files-client.module");
|
|
5
5
|
Object.defineProperty(exports, "FilesClientModule", { enumerable: true, get: function () { return files_client_module_1.FilesClientModule; } });
|
|
6
6
|
var files_client_1 = require("./files-client");
|
|
7
7
|
Object.defineProperty(exports, "FilesClient", { enumerable: true, get: function () { return files_client_1.FilesClient; } });
|
|
8
|
+
var keycloak_token_provider_1 = require("./keycloak-token-provider");
|
|
9
|
+
Object.defineProperty(exports, "KeycloakTokenProvider", { enumerable: true, get: function () { return keycloak_token_provider_1.KeycloakTokenProvider; } });
|
|
8
10
|
var types_1 = require("./types");
|
|
9
11
|
Object.defineProperty(exports, "FileStatus", { enumerable: true, get: function () { return types_1.FileStatus; } });
|
|
12
|
+
Object.defineProperty(exports, "FilePermission", { enumerable: true, get: function () { return types_1.FilePermission; } });
|
|
13
|
+
Object.defineProperty(exports, "GranteeType", { enumerable: true, get: function () { return types_1.GranteeType; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ServiceAccountConfig {
|
|
2
|
+
issuerUrl: string;
|
|
3
|
+
clientId: string;
|
|
4
|
+
clientSecret: string;
|
|
5
|
+
scopes?: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare class KeycloakTokenProvider {
|
|
8
|
+
private readonly config;
|
|
9
|
+
private cachedToken;
|
|
10
|
+
private expiresAt;
|
|
11
|
+
constructor(config: ServiceAccountConfig);
|
|
12
|
+
getToken(): Promise<string>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.KeycloakTokenProvider = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
class KeycloakTokenProvider {
|
|
9
|
+
config;
|
|
10
|
+
cachedToken = null;
|
|
11
|
+
expiresAt = 0;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
async getToken() {
|
|
16
|
+
if (this.cachedToken && Date.now() < this.expiresAt) {
|
|
17
|
+
return this.cachedToken;
|
|
18
|
+
}
|
|
19
|
+
const tokenUrl = `${this.config.issuerUrl}/protocol/openid-connect/token`;
|
|
20
|
+
const params = new URLSearchParams({
|
|
21
|
+
grant_type: 'client_credentials',
|
|
22
|
+
client_id: this.config.clientId,
|
|
23
|
+
client_secret: this.config.clientSecret,
|
|
24
|
+
});
|
|
25
|
+
if (this.config.scopes?.length) {
|
|
26
|
+
params.set('scope', this.config.scopes.join(' '));
|
|
27
|
+
}
|
|
28
|
+
const { data } = await axios_1.default.post(tokenUrl, params.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
|
|
29
|
+
this.cachedToken = `Bearer ${data.access_token}`;
|
|
30
|
+
// Refresh 30 seconds before actual expiry
|
|
31
|
+
this.expiresAt = Date.now() + (data.expires_in - 30) * 1000;
|
|
32
|
+
return this.cachedToken;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.KeycloakTokenProvider = KeycloakTokenProvider;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
export interface FilesClientOptions {
|
|
2
2
|
url: string;
|
|
3
3
|
timeout?: number;
|
|
4
|
+
serviceAccount?: {
|
|
5
|
+
issuerUrl: string;
|
|
6
|
+
clientId: string;
|
|
7
|
+
clientSecret: string;
|
|
8
|
+
scopes?: string[];
|
|
9
|
+
};
|
|
4
10
|
}
|
|
5
11
|
export declare enum FileStatus {
|
|
6
12
|
Uploading = "uploading",
|
|
7
13
|
Ready = "ready",
|
|
8
14
|
Quarantined = "quarantined"
|
|
9
15
|
}
|
|
16
|
+
export declare enum FilePermission {
|
|
17
|
+
Read = "read",
|
|
18
|
+
Write = "write",
|
|
19
|
+
Admin = "admin"
|
|
20
|
+
}
|
|
21
|
+
export declare enum GranteeType {
|
|
22
|
+
User = "user",
|
|
23
|
+
Role = "role"
|
|
24
|
+
}
|
|
10
25
|
export interface FileDto {
|
|
11
26
|
id: string;
|
|
12
27
|
name: string;
|
|
@@ -77,3 +92,18 @@ export interface CompleteMultipartParams {
|
|
|
77
92
|
etag: string;
|
|
78
93
|
}[];
|
|
79
94
|
}
|
|
95
|
+
export interface GrantAccessParams {
|
|
96
|
+
granteeType: GranteeType;
|
|
97
|
+
granteeId: string;
|
|
98
|
+
permission: FilePermission;
|
|
99
|
+
grantReason?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface GrantEntry {
|
|
102
|
+
granteeType: GranteeType;
|
|
103
|
+
granteeId: string;
|
|
104
|
+
permission: FilePermission;
|
|
105
|
+
}
|
|
106
|
+
export interface BatchGrantAccessParams {
|
|
107
|
+
grants: GrantEntry[];
|
|
108
|
+
grantReason?: string;
|
|
109
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FileStatus = void 0;
|
|
3
|
+
exports.GranteeType = exports.FilePermission = exports.FileStatus = void 0;
|
|
4
4
|
var FileStatus;
|
|
5
5
|
(function (FileStatus) {
|
|
6
6
|
FileStatus["Uploading"] = "uploading";
|
|
7
7
|
FileStatus["Ready"] = "ready";
|
|
8
8
|
FileStatus["Quarantined"] = "quarantined";
|
|
9
9
|
})(FileStatus || (exports.FileStatus = FileStatus = {}));
|
|
10
|
+
var FilePermission;
|
|
11
|
+
(function (FilePermission) {
|
|
12
|
+
FilePermission["Read"] = "read";
|
|
13
|
+
FilePermission["Write"] = "write";
|
|
14
|
+
FilePermission["Admin"] = "admin";
|
|
15
|
+
})(FilePermission || (exports.FilePermission = FilePermission = {}));
|
|
16
|
+
var GranteeType;
|
|
17
|
+
(function (GranteeType) {
|
|
18
|
+
GranteeType["User"] = "user";
|
|
19
|
+
GranteeType["Role"] = "role";
|
|
20
|
+
})(GranteeType || (exports.GranteeType = GranteeType = {}));
|