@tstdl/base 0.92.132 → 0.92.135
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/api/response.js +6 -6
- package/api/server/api-request-token.provider.d.ts +3 -0
- package/api/server/api-request-token.provider.js +9 -0
- package/api/server/module.js +1 -1
- package/database/mongo/module.js +6 -6
- package/document-management/api/document-management.api.d.ts +20 -4
- package/document-management/api/document-management.api.js +9 -3
- package/document-management/server/api/document-management.api.d.ts +1 -0
- package/document-management/server/api/document-management.api.js +9 -2
- package/document-management/server/module.d.ts +1 -0
- package/document-management/server/module.js +1 -0
- package/document-management/server/services/document-file.service.d.ts +16 -0
- package/document-management/server/services/document-file.service.js +55 -25
- package/document-management/server/services/document-management-ai.service.js +1 -1
- package/document-management/server/services/document-management-ancillary.service.d.ts +2 -2
- package/document-management/server/services/document-management.service.js +23 -11
- package/document-management/server/services/document-workflow.service.d.ts +1 -0
- package/document-management/server/services/document-workflow.service.js +15 -4
- package/document-management/server/services/document.service.d.ts +5 -1
- package/document-management/server/services/document.service.js +13 -10
- package/document-management/service-models/document-management.view-model.d.ts +15 -4
- package/document-management/service-models/document-management.view-model.js +42 -12
- package/document-management/service-models/document.service-model.d.ts +1 -0
- package/document-management/service-models/document.service-model.js +1 -0
- package/document-management/service-models/enriched/enriched-document-assignment.view.d.ts +13 -4
- package/document-management/service-models/enriched/enriched-document-assignment.view.js +29 -7
- package/document-management/service-models/enriched/enriched-document-collection.view.js +1 -1
- package/document-management/service-models/enriched/enriched-document-request.view.d.ts +1 -1
- package/document-management/service-models/enriched/enriched-document.view.d.ts +2 -2
- package/document-management/service-models/enriched/enriched-document.view.js +2 -6
- package/examples/document-management/main.d.ts +1 -1
- package/examples/document-management/main.js +20 -8
- package/http/client/adapters/undici.adapter.js +3 -3
- package/http/client/http-client.js +29 -30
- package/http/http-body.js +4 -4
- package/http/http.error.d.ts +5 -1
- package/http/http.error.js +6 -6
- package/http/utils.js +4 -4
- package/injector/decorators.d.ts +1 -1
- package/injector/injector.d.ts +1 -1
- package/injector/interfaces.d.ts +1 -1
- package/injector/provider.d.ts +4 -4
- package/object-storage/object-storage.d.ts +38 -2
- package/object-storage/s3/s3.object-storage-provider.js +1 -1
- package/object-storage/s3/s3.object-storage.d.ts +6 -3
- package/object-storage/s3/s3.object-storage.js +88 -14
- package/object-storage/s3/s3.object.js +2 -3
- package/orm/server/repository.js +37 -37
- package/package.json +1 -1
- package/schema/schema.error.js +4 -7
- package/search-index/elastic/module.js +5 -5
- package/utils/cryptography.js +18 -18
- package/utils/object/object.d.ts +3 -2
- package/utils/object/object.js +5 -2
- package/utils/stream/size-limited-stream.js +1 -1
- package/utils/type-guards.d.ts +7 -1
- package/utils/type-guards.js +13 -1
|
@@ -35,11 +35,11 @@ let HttpClient = class HttpClient {
|
|
|
35
35
|
constructor() {
|
|
36
36
|
this.internalStartMiddleware = [
|
|
37
37
|
getBuildRequestUrlMiddleware(this.options.baseUrl),
|
|
38
|
-
...((this.options.enableErrorHandling ?? true) ? [errorMiddleware] : [])
|
|
38
|
+
...((this.options.enableErrorHandling ?? true) ? [errorMiddleware] : []),
|
|
39
39
|
];
|
|
40
40
|
this.internalEndMiddleware = [
|
|
41
41
|
getAddRequestHeadersMiddleware(this.headers),
|
|
42
|
-
getAdapterCallMiddleware(this.adapter)
|
|
42
|
+
getAdapterCallMiddleware(this.adapter),
|
|
43
43
|
];
|
|
44
44
|
this.updateMiddleware();
|
|
45
45
|
}
|
|
@@ -54,22 +54,22 @@ let HttpClient = class HttpClient {
|
|
|
54
54
|
this.headers.remove(name);
|
|
55
55
|
}
|
|
56
56
|
async head(url, options) {
|
|
57
|
-
return this.request('HEAD', url, { ...options });
|
|
57
|
+
return await this.request('HEAD', url, { ...options });
|
|
58
58
|
}
|
|
59
59
|
async get(url, options) {
|
|
60
|
-
return this.request('GET', url, options);
|
|
60
|
+
return await this.request('GET', url, options);
|
|
61
61
|
}
|
|
62
62
|
async getText(url, options) {
|
|
63
63
|
const response = await this.request('GET', url, { ...options });
|
|
64
|
-
return response.body.readAsText();
|
|
64
|
+
return await response.body.readAsText();
|
|
65
65
|
}
|
|
66
66
|
async getJson(url, options) {
|
|
67
67
|
const response = await this.request('GET', url, { ...options });
|
|
68
|
-
return response.body.readAsJson();
|
|
68
|
+
return await response.body.readAsJson();
|
|
69
69
|
}
|
|
70
70
|
async getBuffer(url, options) {
|
|
71
71
|
const response = await this.request('GET', url, { ...options });
|
|
72
|
-
return response.body.readAsBuffer();
|
|
72
|
+
return await response.body.readAsBuffer();
|
|
73
73
|
}
|
|
74
74
|
getStream(url, options) {
|
|
75
75
|
return readableStreamFromPromise(async () => {
|
|
@@ -90,19 +90,19 @@ let HttpClient = class HttpClient {
|
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
async post(url, options) {
|
|
93
|
-
return this.request('POST', url, options);
|
|
93
|
+
return await this.request('POST', url, options);
|
|
94
94
|
}
|
|
95
95
|
async postText(url, options) {
|
|
96
96
|
const response = await this.request('POST', url, { ...options });
|
|
97
|
-
return response.body.readAsText();
|
|
97
|
+
return await response.body.readAsText();
|
|
98
98
|
}
|
|
99
99
|
async postJson(url, options) {
|
|
100
100
|
const response = await this.request('POST', url, { ...options });
|
|
101
|
-
return response.body.readAsJson();
|
|
101
|
+
return await response.body.readAsJson();
|
|
102
102
|
}
|
|
103
103
|
async postBuffer(url, options) {
|
|
104
104
|
const response = await this.request('POST', url, { ...options });
|
|
105
|
-
return response.body.readAsBuffer();
|
|
105
|
+
return await response.body.readAsBuffer();
|
|
106
106
|
}
|
|
107
107
|
postStream(url, options) {
|
|
108
108
|
return readableStreamFromPromise(async () => {
|
|
@@ -111,19 +111,19 @@ let HttpClient = class HttpClient {
|
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
async put(url, options) {
|
|
114
|
-
return this.request('PUT', url, options);
|
|
114
|
+
return await this.request('PUT', url, options);
|
|
115
115
|
}
|
|
116
116
|
async putText(url, options) {
|
|
117
117
|
const response = await this.request('PUT', url, { ...options });
|
|
118
|
-
return response.body.readAsText();
|
|
118
|
+
return await response.body.readAsText();
|
|
119
119
|
}
|
|
120
120
|
async putJson(url, options) {
|
|
121
121
|
const response = await this.request('PUT', url, { ...options });
|
|
122
|
-
return response.body.readAsJson();
|
|
122
|
+
return await response.body.readAsJson();
|
|
123
123
|
}
|
|
124
124
|
async putBuffer(url, options) {
|
|
125
125
|
const response = await this.request('PUT', url, { ...options });
|
|
126
|
-
return response.body.readAsBuffer();
|
|
126
|
+
return await response.body.readAsBuffer();
|
|
127
127
|
}
|
|
128
128
|
putStream(url, options) {
|
|
129
129
|
return readableStreamFromPromise(async () => {
|
|
@@ -132,19 +132,19 @@ let HttpClient = class HttpClient {
|
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
134
|
async patch(url, options) {
|
|
135
|
-
return this.request('PATCH', url, options);
|
|
135
|
+
return await this.request('PATCH', url, options);
|
|
136
136
|
}
|
|
137
137
|
async patchText(url, options) {
|
|
138
138
|
const response = await this.request('PATCH', url, { ...options });
|
|
139
|
-
return response.body.readAsText();
|
|
139
|
+
return await response.body.readAsText();
|
|
140
140
|
}
|
|
141
141
|
async patchJson(url, options) {
|
|
142
142
|
const response = await this.request('PATCH', url, { ...options });
|
|
143
|
-
return response.body.readAsJson();
|
|
143
|
+
return await response.body.readAsJson();
|
|
144
144
|
}
|
|
145
145
|
async patchBuffer(url, options) {
|
|
146
146
|
const response = await this.request('PATCH', url, { ...options });
|
|
147
|
-
return response.body.readAsBuffer();
|
|
147
|
+
return await response.body.readAsBuffer();
|
|
148
148
|
}
|
|
149
149
|
patchStream(url, options) {
|
|
150
150
|
return readableStreamFromPromise(async () => {
|
|
@@ -153,19 +153,19 @@ let HttpClient = class HttpClient {
|
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
155
|
async delete(url, options) {
|
|
156
|
-
return this.request('DELETE', url, options);
|
|
156
|
+
return await this.request('DELETE', url, options);
|
|
157
157
|
}
|
|
158
158
|
async deleteText(url, options) {
|
|
159
159
|
const response = await this.request('DELETE', url, { ...options });
|
|
160
|
-
return response.body.readAsText();
|
|
160
|
+
return await response.body.readAsText();
|
|
161
161
|
}
|
|
162
162
|
async deleteJson(url, options) {
|
|
163
163
|
const response = await this.request('DELETE', url, { ...options });
|
|
164
|
-
return response.body.readAsJson();
|
|
164
|
+
return await response.body.readAsJson();
|
|
165
165
|
}
|
|
166
166
|
async deleteBuffer(url, options) {
|
|
167
167
|
const response = await this.request('DELETE', url, { ...options });
|
|
168
|
-
return response.body.readAsBuffer();
|
|
168
|
+
return await response.body.readAsBuffer();
|
|
169
169
|
}
|
|
170
170
|
deleteStream(url, options) {
|
|
171
171
|
return readableStreamFromPromise(async () => {
|
|
@@ -175,7 +175,7 @@ let HttpClient = class HttpClient {
|
|
|
175
175
|
}
|
|
176
176
|
async request(method, url, options = {}) {
|
|
177
177
|
const request = new HttpClientRequest(url, method, options);
|
|
178
|
-
return this.rawRequest(request);
|
|
178
|
+
return await this.rawRequest(request);
|
|
179
179
|
}
|
|
180
180
|
async rawRequest(request) {
|
|
181
181
|
const context = { request };
|
|
@@ -197,7 +197,7 @@ function getBuildRequestUrlMiddleware(baseUrl) {
|
|
|
197
197
|
if (request.mapParameters) {
|
|
198
198
|
mapParameters(request, baseUrl);
|
|
199
199
|
}
|
|
200
|
-
|
|
200
|
+
await next();
|
|
201
201
|
}
|
|
202
202
|
return buildUrlParametersMiddleware;
|
|
203
203
|
}
|
|
@@ -238,7 +238,7 @@ function getAddRequestHeadersMiddleware(defaultHeaders) {
|
|
|
238
238
|
request.headers.authorization = `Token ${authorization.token}`;
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
-
|
|
241
|
+
await next();
|
|
242
242
|
}
|
|
243
243
|
return addRequestHeadersMiddleware;
|
|
244
244
|
}
|
|
@@ -267,7 +267,6 @@ async function errorMiddleware(context, next) {
|
|
|
267
267
|
throw error;
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
-
// eslint-disable-next-line max-statements, max-lines-per-function, complexity
|
|
271
270
|
function mapParameters(request, baseUrl) {
|
|
272
271
|
const isGetOrHead = (request.method == 'GET') || (request.method == 'HEAD');
|
|
273
272
|
let url;
|
|
@@ -299,7 +298,7 @@ function mapParameters(request, baseUrl) {
|
|
|
299
298
|
}
|
|
300
299
|
}
|
|
301
300
|
if (parameterEntries.size > 0) {
|
|
302
|
-
throw new HttpError(HttpErrorReason.InvalidRequest, request,
|
|
301
|
+
throw new HttpError(HttpErrorReason.InvalidRequest, request, { cause: 'Not all parameters could be mapped to url, query and body because request is either GET/HEAD or body is already defined' });
|
|
303
302
|
}
|
|
304
303
|
if (isDefined(request.query)) {
|
|
305
304
|
for (const [key, valueOrValues] of request.query) {
|
|
@@ -315,8 +314,8 @@ function mapParameters(request, baseUrl) {
|
|
|
315
314
|
}
|
|
316
315
|
function getAdapterCallMiddleware(adapter) {
|
|
317
316
|
async function adapterCallMiddleware(context, next) {
|
|
318
|
-
context.response = await adapter.call(context.request);
|
|
319
|
-
|
|
317
|
+
context.response = await adapter.call(context.request);
|
|
318
|
+
await next();
|
|
320
319
|
}
|
|
321
320
|
return adapterCallMiddleware;
|
|
322
321
|
}
|
package/http/http-body.js
CHANGED
|
@@ -17,19 +17,19 @@ export class HttpBody {
|
|
|
17
17
|
}
|
|
18
18
|
async readAsBuffer(options) {
|
|
19
19
|
this.prepareBodyRead();
|
|
20
|
-
return readBodyAsBuffer(this.body, this.headers, options);
|
|
20
|
+
return await readBodyAsBuffer(this.body, this.headers, options);
|
|
21
21
|
}
|
|
22
22
|
async readAsText(options) {
|
|
23
23
|
this.prepareBodyRead();
|
|
24
|
-
return readBodyAsText(this.body, this.headers, options);
|
|
24
|
+
return await readBodyAsText(this.body, this.headers, options);
|
|
25
25
|
}
|
|
26
26
|
async readAsJson(options) {
|
|
27
27
|
this.prepareBodyRead();
|
|
28
|
-
return readBodyAsJson(this.body, this.headers, options);
|
|
28
|
+
return await readBodyAsJson(this.body, this.headers, options);
|
|
29
29
|
}
|
|
30
30
|
async read(options) {
|
|
31
31
|
this.prepareBodyRead();
|
|
32
|
-
return readBody(this.body, this.headers, options);
|
|
32
|
+
return await readBody(this.body, this.headers, options);
|
|
33
33
|
}
|
|
34
34
|
readAsBinaryStream(options) {
|
|
35
35
|
this.prepareBodyRead();
|
package/http/http.error.d.ts
CHANGED
|
@@ -22,7 +22,11 @@ export declare class HttpError extends CustomError implements ErrorExtraInfo {
|
|
|
22
22
|
readonly responseBody: UndefinableJson | Uint8Array;
|
|
23
23
|
readonly requestInstance: HttpClientRequest;
|
|
24
24
|
readonly responseInstance: HttpClientResponse | undefined;
|
|
25
|
-
constructor(reason: HttpErrorReason, request: HttpClientRequest, response
|
|
25
|
+
constructor(reason: HttpErrorReason, request: HttpClientRequest, { response, responseBody, cause }?: {
|
|
26
|
+
response?: HttpClientResponse;
|
|
27
|
+
responseBody?: UndefinableJson | Uint8Array;
|
|
28
|
+
cause?: Error | string;
|
|
29
|
+
});
|
|
26
30
|
static create(reason: HttpErrorReason, request: HttpClientRequest, response: HttpClientResponse | undefined, cause?: Error | string): Promise<HttpError>;
|
|
27
31
|
getExtraInfo(): UndefinableJson | undefined;
|
|
28
32
|
}
|
package/http/http.error.js
CHANGED
|
@@ -22,8 +22,8 @@ export class HttpError extends CustomError {
|
|
|
22
22
|
responseBody;
|
|
23
23
|
requestInstance;
|
|
24
24
|
responseInstance;
|
|
25
|
-
constructor(reason, request, response, responseBody, cause) {
|
|
26
|
-
super({ message: (isString(cause) ? cause : cause?.message) ?? 'An error occurred', cause: (isNotString(cause) ? cause :
|
|
25
|
+
constructor(reason, request, { response, responseBody, cause } = {}) {
|
|
26
|
+
super({ message: (isString(cause) ? cause : cause?.message) ?? 'An error occurred', cause: (isNotString(cause) ? cause : new Error(cause)) });
|
|
27
27
|
this.reason = reason;
|
|
28
28
|
this.request = request.asObject();
|
|
29
29
|
this.response = response?.asObject();
|
|
@@ -35,21 +35,21 @@ export class HttpError extends CustomError {
|
|
|
35
35
|
}
|
|
36
36
|
Object.defineProperty(this, propertyNameOf((instance) => instance.requestInstance), {
|
|
37
37
|
value: request,
|
|
38
|
-
enumerable: false
|
|
38
|
+
enumerable: false,
|
|
39
39
|
});
|
|
40
40
|
Object.defineProperty(this, propertyNameOf((instance) => instance.responseInstance), {
|
|
41
41
|
value: response,
|
|
42
|
-
enumerable: false
|
|
42
|
+
enumerable: false,
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
static async create(reason, request, response, cause) {
|
|
46
46
|
const body = (response?.body.available == true) ? await response.body.read() : undefined;
|
|
47
|
-
return new HttpError(reason, request, response, body, cause);
|
|
47
|
+
return new HttpError(reason, request, { response, responseBody: body, cause });
|
|
48
48
|
}
|
|
49
49
|
getExtraInfo() {
|
|
50
50
|
const extraInfo = {
|
|
51
51
|
url: this.request.url,
|
|
52
|
-
method: this.request.method
|
|
52
|
+
method: this.request.method,
|
|
53
53
|
};
|
|
54
54
|
if (isDefined(this.response)) {
|
|
55
55
|
const responseExtraInfo = {};
|
package/http/utils.js
CHANGED
|
@@ -20,7 +20,7 @@ export function readBodyAsBinaryStream(body, headers, options = {}) {
|
|
|
20
20
|
start: (controller) => {
|
|
21
21
|
controller.enqueue(body);
|
|
22
22
|
controller.close();
|
|
23
|
-
}
|
|
23
|
+
},
|
|
24
24
|
})
|
|
25
25
|
: isAnyIterable(body)
|
|
26
26
|
? getReadableStreamFromIterable(body)
|
|
@@ -83,12 +83,12 @@ export async function readBodyAsJson(body, headers, options) {
|
|
|
83
83
|
}
|
|
84
84
|
export async function readBody(body, headers, options) {
|
|
85
85
|
if (headers.contentType?.includes('json') == true) {
|
|
86
|
-
return readBodyAsJson(body, headers, { ...options, fallbackToText: true });
|
|
86
|
+
return await readBodyAsJson(body, headers, { ...options, fallbackToText: true });
|
|
87
87
|
}
|
|
88
88
|
if (headers.contentType?.includes('text') == true) {
|
|
89
|
-
return readBodyAsText(body, headers, options);
|
|
89
|
+
return await readBodyAsText(body, headers, options);
|
|
90
90
|
}
|
|
91
|
-
return readBodyAsBuffer(body, headers, options);
|
|
91
|
+
return await readBodyAsBuffer(body, headers, options);
|
|
92
92
|
}
|
|
93
93
|
export function readBodyAsStream(body, headers, options) {
|
|
94
94
|
if ((headers.contentType?.includes('json') == true) || (headers.contentType?.includes('text') == true)) {
|
package/injector/decorators.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export declare function Injectable<T = any, A = any, C extends Record = Record>(
|
|
|
28
28
|
* Registers the class in the global container with singleton lifecycle. Decorated class is not modified in any way
|
|
29
29
|
* @param options registration options
|
|
30
30
|
*/
|
|
31
|
-
export declare function Singleton<T = any, A =
|
|
31
|
+
export declare function Singleton<T = any, A = undefined>(options?: InjectableOptionsWithoutLifecycle<T, A>): ClassDecorator;
|
|
32
32
|
/**
|
|
33
33
|
* Registers the class in the global container with scoped lifecycle. Decorated class is not modified in any way
|
|
34
34
|
* @param options registration options
|
package/injector/injector.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export declare class Injector implements AsyncDisposable {
|
|
|
49
49
|
* @param provider provider used to resolve the token
|
|
50
50
|
* @param options registration options
|
|
51
51
|
*/
|
|
52
|
-
static registerSingleton<T, A =
|
|
52
|
+
static registerSingleton<T, A = undefined, C extends Record = Record>(token: InjectionToken<T, A>, providers: OneOrMany<Provider<T, A, C>>, options?: TypedOmit<RegistrationOptions<T, A, C>, 'lifecycle'>): void;
|
|
53
53
|
dispose(): Promise<void>;
|
|
54
54
|
[Symbol.asyncDispose](): Promise<void>;
|
|
55
55
|
fork(name: string): Injector;
|
package/injector/interfaces.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { AfterResolveContext } from './types.js';
|
|
|
4
4
|
export declare const resolveArgumentType: unique symbol;
|
|
5
5
|
export declare const afterResolve: unique symbol;
|
|
6
6
|
export type ResolveArgumentType = typeof resolveArgumentType;
|
|
7
|
-
export type ResolveArgument<T, Fallback = undefined> = undefined | (T extends Resolvable<infer U> ? (U | undefined) : T extends Type<Resolvable<infer U>> ? (U | undefined) : T extends (ArgumentedInjectionToken<any, any> | ReifyingInjectionToken) ? InjectionTokenArgument<T> : Fallback);
|
|
7
|
+
export type ResolveArgument<T, Fallback = undefined> = undefined | (T extends Resolvable<infer U> ? (U | undefined) : T extends Type<Pick<Required<Resolvable<infer U>>, typeof resolveArgumentType>> ? (U | undefined) : T extends (ArgumentedInjectionToken<any, any> | ReifyingInjectionToken) ? InjectionTokenArgument<T> : Fallback);
|
|
8
8
|
export interface Resolvable<A = unknown, D extends Record = Record> extends Partial<AfterResolve<A, D>> {
|
|
9
9
|
/**
|
|
10
10
|
* Type of resolve argument
|
package/injector/provider.d.ts
CHANGED
|
@@ -2,15 +2,15 @@ import type { Constructor, Record, TypedOmit } from '../types.js';
|
|
|
2
2
|
import type { ResolveArgument } from './interfaces.js';
|
|
3
3
|
import type { InjectionToken } from './token.js';
|
|
4
4
|
import type { AfterResolveContext, ResolveContext } from './types.js';
|
|
5
|
-
export type Factory<T, A =
|
|
5
|
+
export type Factory<T, A = undefined, D extends Record = Record> = (argument: ResolveArgument<T, A>, context: ResolveContext<D>) => T;
|
|
6
6
|
export type ProviderWithArgument<T, A> = {
|
|
7
7
|
defaultArgument?: ResolveArgument<T, A>;
|
|
8
8
|
defaultArgumentProvider?: () => ResolveArgument<T, A>;
|
|
9
9
|
};
|
|
10
10
|
export type ProviderWithInitializer<T, A, D extends Record> = {
|
|
11
|
-
afterResolve?: (value: T, argument:
|
|
11
|
+
afterResolve?: (value: T, argument: ResolveArgument<T, A>, context: AfterResolveContext<D>) => void | Promise<void>;
|
|
12
12
|
};
|
|
13
|
-
export type Provider<T = any, A =
|
|
13
|
+
export type Provider<T = any, A = undefined, D extends Record = Record> = ClassProvider<T, A, D> | ValueProvider<T> | TokenProvider<T, A, D> | FactoryProvider<T, A, D>;
|
|
14
14
|
export type ClassProvider<T = any, A = any, D extends Record = Record> = ProviderWithArgument<T, A> & ProviderWithInitializer<T, A, D> & {
|
|
15
15
|
useClass: Constructor<T>;
|
|
16
16
|
};
|
|
@@ -34,7 +34,7 @@ export type TokenProvider<T = any, A = any, D extends Record = Record> = Provide
|
|
|
34
34
|
useTokenProvider: () => InjectionToken<T extends (infer U)[] ? U : T, A>;
|
|
35
35
|
resolveAll: true;
|
|
36
36
|
});
|
|
37
|
-
export type FactoryProvider<T = any, A =
|
|
37
|
+
export type FactoryProvider<T = any, A = undefined, D extends Record = Record> = ProviderWithArgument<T, A> & ProviderWithInitializer<T, A, D> & {
|
|
38
38
|
useFactory: Factory<T, A, D>;
|
|
39
39
|
};
|
|
40
40
|
export declare function classProvider<T, A, D extends Record>(constructor: Constructor<T>, options?: TypedOmit<ClassProvider<T, A, D>, 'useClass'>): ClassProvider<T, A, D>;
|
|
@@ -2,9 +2,30 @@ import { resolveArgumentType, type Resolvable } from '../injector/interfaces.js'
|
|
|
2
2
|
import type { ObjectMetadata, ObjectStorageObject } from './object.js';
|
|
3
3
|
export type UploadObjectOptions = {
|
|
4
4
|
contentLength?: number;
|
|
5
|
+
contentType?: string;
|
|
5
6
|
metadata?: ObjectMetadata;
|
|
6
7
|
};
|
|
7
|
-
export type
|
|
8
|
+
export type UploadUrlOptions = {
|
|
9
|
+
metadata?: ObjectMetadata;
|
|
10
|
+
};
|
|
11
|
+
export type CopyObjectOptions = {
|
|
12
|
+
metadata?: ObjectMetadata;
|
|
13
|
+
};
|
|
14
|
+
export type MoveObjectOptions = {
|
|
15
|
+
metadata?: ObjectMetadata;
|
|
16
|
+
};
|
|
17
|
+
export type ObjectStorageConfiguration = {
|
|
18
|
+
lifecycle?: {
|
|
19
|
+
expiration?: {
|
|
20
|
+
/** Expire (delete) objects after a certain number of seconds. Implementations may round up to supported intervals. */
|
|
21
|
+
after?: number;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export type ObjectStorageArgument = string | {
|
|
26
|
+
module: string;
|
|
27
|
+
configuration?: ObjectStorageConfiguration;
|
|
28
|
+
};
|
|
8
29
|
export declare abstract class ObjectStorage implements Resolvable<ObjectStorageArgument> {
|
|
9
30
|
/** Object storage module */
|
|
10
31
|
readonly module: string;
|
|
@@ -19,14 +40,29 @@ export declare abstract class ObjectStorage implements Resolvable<ObjectStorageA
|
|
|
19
40
|
* Uploads an object
|
|
20
41
|
* @param key object key
|
|
21
42
|
* @param content content of object
|
|
43
|
+
* @param options options
|
|
22
44
|
*/
|
|
23
45
|
abstract uploadObject(key: string, content: Uint8Array | ReadableStream<Uint8Array>, options?: UploadObjectOptions): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Copies an object
|
|
48
|
+
* @param sourceKey source object key
|
|
49
|
+
* @param destinationKey destination object key or destination storage and key
|
|
50
|
+
* @param options options
|
|
51
|
+
*/
|
|
52
|
+
abstract copyObject(sourceKey: string, destinationKey: string | [ObjectStorage, string], options?: CopyObjectOptions): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Moves an object
|
|
55
|
+
* @param sourceKey source object key
|
|
56
|
+
* @param destinationKey destination object key or destination storage and key
|
|
57
|
+
* @param options options
|
|
58
|
+
*/
|
|
59
|
+
abstract moveObject(sourceKey: string, destinationKey: string | [ObjectStorage, string], options?: MoveObjectOptions): Promise<void>;
|
|
24
60
|
/**
|
|
25
61
|
* Get an url which can be used to upload the object without further authorization
|
|
26
62
|
* @param key object key
|
|
27
63
|
* @param expirationTimestamp timestamp when the url expires and can no longer be used
|
|
28
64
|
*/
|
|
29
|
-
abstract getUploadUrl(key: string, expirationTimestamp: number): Promise<string>;
|
|
65
|
+
abstract getUploadUrl(key: string, expirationTimestamp: number, options?: UploadUrlOptions): Promise<string>;
|
|
30
66
|
/**
|
|
31
67
|
* Get all objects
|
|
32
68
|
*/
|
|
@@ -54,7 +54,7 @@ let S3ObjectStorageProvider = class S3ObjectStorageProvider extends ObjectStorag
|
|
|
54
54
|
port: (port.length > 0) ? parseInt(port, 10) : undefined,
|
|
55
55
|
useSSL: protocol == 'https:',
|
|
56
56
|
accessKey: config.accessKey,
|
|
57
|
-
secretKey: config.secretKey
|
|
57
|
+
secretKey: config.secretKey,
|
|
58
58
|
});
|
|
59
59
|
this.bucket = assertDefinedPass((config.bucketPerModule == true) ? true : config.bucket, 'either bucket or bucketPerModule must be specified');
|
|
60
60
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { ObjectStorage, type UploadObjectOptions } from '../../object-storage/index.js';
|
|
1
|
+
import { type BucketItemStat, type Client } from 'minio';
|
|
2
|
+
import { ObjectStorage, type CopyObjectOptions, type MoveObjectOptions, type ObjectStorageConfiguration, type UploadObjectOptions, type UploadUrlOptions } from '../../object-storage/index.js';
|
|
3
3
|
import { S3Object } from './s3.object.js';
|
|
4
4
|
export declare class S3ObjectStorage extends ObjectStorage {
|
|
5
5
|
private readonly client;
|
|
@@ -9,9 +9,12 @@ export declare class S3ObjectStorage extends ObjectStorage {
|
|
|
9
9
|
ensureBucketExists(region?: string, options?: {
|
|
10
10
|
objectLocking?: boolean;
|
|
11
11
|
}): Promise<void>;
|
|
12
|
+
configureBucket(configuration: ObjectStorageConfiguration): Promise<void>;
|
|
12
13
|
exists(key: string): Promise<boolean>;
|
|
13
14
|
statObject(key: string): Promise<BucketItemStat>;
|
|
14
15
|
uploadObject(key: string, content: Uint8Array | ReadableStream<Uint8Array>, options?: UploadObjectOptions): Promise<void>;
|
|
16
|
+
copyObject(source: string, destination: string | [ObjectStorage, string], options?: CopyObjectOptions): Promise<void>;
|
|
17
|
+
moveObject(sourceKey: string, destinationKey: string | [ObjectStorage, string], options?: MoveObjectOptions): Promise<void>;
|
|
15
18
|
getContent(key: string): Promise<Uint8Array>;
|
|
16
19
|
getContentStream(key: string): ReadableStream<Uint8Array>;
|
|
17
20
|
getObjects(): Promise<S3Object[]>;
|
|
@@ -19,7 +22,7 @@ export declare class S3ObjectStorage extends ObjectStorage {
|
|
|
19
22
|
getObject(key: string): Promise<S3Object>;
|
|
20
23
|
getResourceUri(key: string): Promise<string>;
|
|
21
24
|
getDownloadUrl(key: string, expirationTimestamp: number, responseHeaders?: Record<string, string>): Promise<string>;
|
|
22
|
-
getUploadUrl(key: string, expirationTimestamp: number): Promise<string>;
|
|
25
|
+
getUploadUrl(key: string, expirationTimestamp: number, options?: UploadUrlOptions): Promise<string>;
|
|
23
26
|
deleteObject(key: string): Promise<void>;
|
|
24
27
|
deleteObjects(keys: string[]): Promise<void>;
|
|
25
28
|
private getResourceUriSync;
|
|
@@ -7,18 +7,24 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
+
var S3ObjectStorage_1;
|
|
10
11
|
import { Readable } from 'node:stream';
|
|
12
|
+
import { CopyDestinationOptions, CopySourceOptions } from 'minio';
|
|
11
13
|
import { Singleton } from '../../injector/decorators.js';
|
|
14
|
+
import { registerAfterResolve } from '../../injector/resolution.js';
|
|
12
15
|
import { ObjectStorage } from '../../object-storage/index.js';
|
|
16
|
+
import { toArray } from '../../utils/array/array.js';
|
|
13
17
|
import { mapAsync } from '../../utils/async-iterable-helpers/map.js';
|
|
14
18
|
import { toArrayAsync } from '../../utils/async-iterable-helpers/to-array.js';
|
|
15
19
|
import { now } from '../../utils/date-time.js';
|
|
20
|
+
import { mapObjectKeys } from '../../utils/object/object.js';
|
|
16
21
|
import { readableStreamFromPromise } from '../../utils/stream/index.js';
|
|
17
22
|
import { readBinaryStream } from '../../utils/stream/stream-reader.js';
|
|
18
|
-
import {
|
|
23
|
+
import { assertDefinedPass, assertInstanceOfPass, isDefined, isObject, isString, isUint8Array, isUndefined } from '../../utils/type-guards.js';
|
|
24
|
+
import { secondsPerDay } from '../../utils/units.js';
|
|
19
25
|
import { S3ObjectStorageProvider } from './s3.object-storage-provider.js';
|
|
20
26
|
import { S3Object } from './s3.object.js';
|
|
21
|
-
let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
|
|
27
|
+
let S3ObjectStorage = S3ObjectStorage_1 = class S3ObjectStorage extends ObjectStorage {
|
|
22
28
|
client;
|
|
23
29
|
bucket;
|
|
24
30
|
prefix;
|
|
@@ -27,6 +33,11 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
|
|
|
27
33
|
this.client = client;
|
|
28
34
|
this.bucket = bucket;
|
|
29
35
|
this.prefix = keyPrefix;
|
|
36
|
+
registerAfterResolve(this, async (argument) => {
|
|
37
|
+
const configuration = (isString(argument) ? undefined : argument.configuration) ?? {};
|
|
38
|
+
await this.ensureBucketExists();
|
|
39
|
+
await this.configureBucket(configuration);
|
|
40
|
+
});
|
|
30
41
|
}
|
|
31
42
|
async ensureBucketExists(region, options) {
|
|
32
43
|
const exists = await this.client.bucketExists(this.bucket);
|
|
@@ -35,6 +46,49 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
|
|
|
35
46
|
}
|
|
36
47
|
await this.client.makeBucket(this.bucket, region ?? '', { ObjectLocking: options?.objectLocking ?? false });
|
|
37
48
|
}
|
|
49
|
+
async configureBucket(configuration) {
|
|
50
|
+
let currentLifecycle = null;
|
|
51
|
+
try {
|
|
52
|
+
currentLifecycle = await this.client.getBucketLifecycle(this.bucket);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
// ignore error if lifecycle configuration is not set
|
|
56
|
+
if (!isObject(error) || (error.code != 'NoSuchLifecycleConfiguration')) {
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const currentLifecycleRules = isDefined(currentLifecycle?.Rule) ? toArray(currentLifecycle.Rule) : undefined; // https://github.com/minio/minio-js/issues/1407
|
|
61
|
+
const tstdlRule = currentLifecycleRules?.find((rule) => rule.ID == 'TstdlExpireObjects');
|
|
62
|
+
const tstdlRuleExpiration = tstdlRule?.Expiration?.Days;
|
|
63
|
+
const targetExpirationDays = configuration.lifecycle?.expiration?.after;
|
|
64
|
+
const targetExpiration = isDefined(targetExpirationDays) ? Math.ceil(targetExpirationDays / secondsPerDay) : undefined;
|
|
65
|
+
if (tstdlRuleExpiration == targetExpiration) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const nonTstdlRules = currentLifecycleRules?.filter((rule) => rule.ID != 'TstdlExpireObjects') ?? [];
|
|
69
|
+
if (isUndefined(targetExpiration)) {
|
|
70
|
+
if (nonTstdlRules.length == 0) {
|
|
71
|
+
await this.client.removeBucketLifecycle(this.bucket);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
await this.client.setBucketLifecycle(this.bucket, { Rule: nonTstdlRules });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
await this.client.setBucketLifecycle(this.bucket, {
|
|
79
|
+
Rule: [
|
|
80
|
+
...nonTstdlRules,
|
|
81
|
+
{
|
|
82
|
+
ID: 'TstdlExpireObjects',
|
|
83
|
+
Status: 'Enabled',
|
|
84
|
+
Expiration: {
|
|
85
|
+
Days: targetExpiration,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
38
92
|
async exists(key) {
|
|
39
93
|
const bucketKey = this.getBucketKey(key);
|
|
40
94
|
try {
|
|
@@ -50,7 +104,7 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
|
|
|
50
104
|
}
|
|
51
105
|
async statObject(key) {
|
|
52
106
|
const bucketKey = this.getBucketKey(key);
|
|
53
|
-
return this.client.statObject(this.bucket, bucketKey);
|
|
107
|
+
return await this.client.statObject(this.bucket, bucketKey);
|
|
54
108
|
}
|
|
55
109
|
async uploadObject(key, content, options) {
|
|
56
110
|
const bucketKey = this.getBucketKey(key);
|
|
@@ -66,10 +120,28 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
|
|
|
66
120
|
]);
|
|
67
121
|
}
|
|
68
122
|
}
|
|
123
|
+
async copyObject(source, destination, options) {
|
|
124
|
+
const sourceBucketKey = this.getBucketKey(source);
|
|
125
|
+
const [destinationObjectStorage, destinationKey] = isString(destination) ? [this, destination] : [assertInstanceOfPass(destination[0], S3ObjectStorage_1, 'Destination storage is not an S3ObjectStorage'), destination[1]];
|
|
126
|
+
const destinationBucket = destinationObjectStorage.bucket;
|
|
127
|
+
const destinationBucketKey = destinationObjectStorage.getBucketKey(destinationKey);
|
|
128
|
+
const sourceObject = await this.getObject(source);
|
|
129
|
+
const sourceMetadata = await sourceObject.getMetadata();
|
|
130
|
+
await this.client.copyObject(new CopySourceOptions({ Bucket: this.bucket, Object: sourceBucketKey }), new CopyDestinationOptions({
|
|
131
|
+
Bucket: destinationBucket,
|
|
132
|
+
Object: destinationBucketKey,
|
|
133
|
+
MetadataDirective: 'REPLACE',
|
|
134
|
+
UserMetadata: { ...sourceMetadata, ...options?.metadata },
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
async moveObject(sourceKey, destinationKey, options) {
|
|
138
|
+
await this.copyObject(sourceKey, destinationKey, options);
|
|
139
|
+
await this.deleteObject(sourceKey);
|
|
140
|
+
}
|
|
69
141
|
async getContent(key) {
|
|
70
142
|
const bucketKey = this.getBucketKey(key);
|
|
71
143
|
const result = await this.client.getObject(this.bucket, bucketKey);
|
|
72
|
-
return readBinaryStream(result);
|
|
144
|
+
return await readBinaryStream(result);
|
|
73
145
|
}
|
|
74
146
|
getContentStream(key) {
|
|
75
147
|
const bucketKey = this.getBucketKey(key);
|
|
@@ -79,7 +151,7 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
|
|
|
79
151
|
});
|
|
80
152
|
}
|
|
81
153
|
async getObjects() {
|
|
82
|
-
return toArrayAsync(this.getObjectsCursor());
|
|
154
|
+
return await toArrayAsync(this.getObjectsCursor());
|
|
83
155
|
}
|
|
84
156
|
getObjectsCursor() {
|
|
85
157
|
const stream = this.client.listObjectsV2(this.bucket, this.prefix, true);
|
|
@@ -96,12 +168,13 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
|
|
|
96
168
|
async getDownloadUrl(key, expirationTimestamp, responseHeaders) {
|
|
97
169
|
const bucketKey = this.getBucketKey(key);
|
|
98
170
|
const { date, expiration } = getDateAndExpiration(expirationTimestamp);
|
|
99
|
-
return this.client.presignedGetObject(this.bucket, bucketKey, expiration, responseHeaders ?? {}, date);
|
|
171
|
+
return await this.client.presignedGetObject(this.bucket, bucketKey, expiration, responseHeaders ?? {}, date);
|
|
100
172
|
}
|
|
101
|
-
async getUploadUrl(key, expirationTimestamp) {
|
|
173
|
+
async getUploadUrl(key, expirationTimestamp, options) {
|
|
102
174
|
const bucketKey = this.getBucketKey(key);
|
|
103
175
|
const { date, expiration } = getDateAndExpiration(expirationTimestamp);
|
|
104
|
-
|
|
176
|
+
const query = mapObjectKeys(options?.metadata ?? {}, (key) => `X-Amz-Meta-${key}`);
|
|
177
|
+
return await this.client.presignedUrl('PUT', this.bucket, bucketKey, expiration, query, date);
|
|
105
178
|
}
|
|
106
179
|
async deleteObject(key) {
|
|
107
180
|
const bucketKey = this.getBucketKey(key);
|
|
@@ -122,14 +195,15 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
|
|
|
122
195
|
return bucketKey.slice(this.prefix.length);
|
|
123
196
|
}
|
|
124
197
|
};
|
|
125
|
-
S3ObjectStorage = __decorate([
|
|
198
|
+
S3ObjectStorage = S3ObjectStorage_1 = __decorate([
|
|
126
199
|
Singleton({
|
|
127
200
|
provider: {
|
|
128
|
-
useFactory: (argument, context) =>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
}
|
|
201
|
+
useFactory: (argument, context) => {
|
|
202
|
+
const { module } = (isString(argument) ? { module: argument } : assertDefinedPass(argument, 'argument must be a string or an object'));
|
|
203
|
+
return context.resolve(S3ObjectStorageProvider).get(module);
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
argumentIdentityProvider: JSON.stringify,
|
|
133
207
|
}),
|
|
134
208
|
__metadata("design:paramtypes", [Function, String, String, String])
|
|
135
209
|
], S3ObjectStorage);
|
|
@@ -15,7 +15,6 @@ export class S3Object extends ObjectStorageObject {
|
|
|
15
15
|
async getResourceUri() {
|
|
16
16
|
return this.resourceUri;
|
|
17
17
|
}
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
19
18
|
async getContentLength() {
|
|
20
19
|
if (isUndefined(this.contentLength)) {
|
|
21
20
|
const stat = await this.stat();
|
|
@@ -28,7 +27,7 @@ export class S3Object extends ObjectStorageObject {
|
|
|
28
27
|
return stat.metaData;
|
|
29
28
|
}
|
|
30
29
|
async getContent() {
|
|
31
|
-
return this.storage.getContent(this.key);
|
|
30
|
+
return await this.storage.getContent(this.key);
|
|
32
31
|
}
|
|
33
32
|
getContentStream() {
|
|
34
33
|
return this.storage.getContentStream(this.key);
|
|
@@ -37,6 +36,6 @@ export class S3Object extends ObjectStorageObject {
|
|
|
37
36
|
if (isUndefined(this.statPromise)) {
|
|
38
37
|
this.statPromise = this.storage.statObject(this.key);
|
|
39
38
|
}
|
|
40
|
-
return this.statPromise;
|
|
39
|
+
return await this.statPromise;
|
|
41
40
|
}
|
|
42
41
|
}
|