@tstdl/base 0.92.131 → 0.92.134

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.
Files changed (44) hide show
  1. package/api/server/api-request-token.provider.d.ts +3 -0
  2. package/api/server/api-request-token.provider.js +9 -0
  3. package/api/server/module.js +1 -1
  4. package/database/mongo/module.js +6 -6
  5. package/document-management/api/document-management.api.d.ts +20 -4
  6. package/document-management/api/document-management.api.js +9 -3
  7. package/document-management/server/api/document-management.api.d.ts +1 -0
  8. package/document-management/server/api/document-management.api.js +9 -2
  9. package/document-management/server/module.d.ts +1 -0
  10. package/document-management/server/module.js +1 -0
  11. package/document-management/server/services/document-file.service.d.ts +16 -0
  12. package/document-management/server/services/document-file.service.js +54 -24
  13. package/document-management/server/services/document-management-ancillary.service.d.ts +2 -2
  14. package/document-management/server/services/document.service.d.ts +5 -1
  15. package/document-management/server/services/document.service.js +12 -9
  16. package/document-management/service-models/document.service-model.d.ts +1 -0
  17. package/document-management/service-models/document.service-model.js +1 -0
  18. package/document-management/service-models/enriched/enriched-document-management-data.view.d.ts +2 -1
  19. package/document-management/service-models/enriched/enriched-document-management-data.view.js +10 -2
  20. package/examples/document-management/main.d.ts +1 -1
  21. package/examples/document-management/main.js +17 -8
  22. package/http/client/adapters/undici.adapter.js +3 -3
  23. package/http/client/http-client.js +29 -30
  24. package/http/http-body.js +4 -4
  25. package/http/http.error.d.ts +5 -1
  26. package/http/http.error.js +6 -6
  27. package/http/utils.js +4 -4
  28. package/injector/decorators.d.ts +1 -1
  29. package/injector/injector.d.ts +1 -1
  30. package/injector/interfaces.d.ts +1 -1
  31. package/injector/provider.d.ts +4 -4
  32. package/object-storage/object-storage.d.ts +37 -2
  33. package/object-storage/s3/s3.object-storage-provider.js +1 -1
  34. package/object-storage/s3/s3.object-storage.d.ts +6 -3
  35. package/object-storage/s3/s3.object-storage.js +86 -14
  36. package/object-storage/s3/s3.object.js +2 -3
  37. package/package.json +1 -1
  38. package/search-index/elastic/module.js +5 -5
  39. package/utils/cryptography.js +18 -18
  40. package/utils/object/object.d.ts +3 -2
  41. package/utils/object/object.js +5 -2
  42. package/utils/stream/size-limited-stream.js +1 -1
  43. package/utils/type-guards.d.ts +7 -1
  44. package/utils/type-guards.js +13 -1
@@ -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 { assertStringPass, isObject, isUint8Array } from '../../utils/type-guards.js';
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,27 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
66
120
  ]);
67
121
  }
68
122
  }
123
+ async copyObject(sourceKey, destinationKey, options) {
124
+ const sourceBucketKey = this.getBucketKey(sourceKey);
125
+ const destinationBucket = isString(destinationKey) ? this.bucket : assertInstanceOfPass(destinationKey[0], S3ObjectStorage_1, 'Destination storage is not an S3ObjectStorage').bucket;
126
+ const destinationBucketKey = isString(destinationKey) ? destinationKey : destinationKey[0].getBucketKey(destinationKey[1]);
127
+ const sourceObject = await this.getObject(sourceKey);
128
+ const sourceMetadata = await sourceObject.getMetadata();
129
+ await this.client.copyObject(new CopySourceOptions({ Bucket: this.bucket, Object: sourceBucketKey }), new CopyDestinationOptions({
130
+ Bucket: destinationBucket,
131
+ Object: destinationBucketKey,
132
+ MetadataDirective: 'REPLACE',
133
+ UserMetadata: { ...sourceMetadata, ...options?.metadata },
134
+ }));
135
+ }
136
+ async moveObject(sourceKey, destinationKey, options) {
137
+ await this.copyObject(sourceKey, destinationKey, options);
138
+ await this.deleteObject(sourceKey);
139
+ }
69
140
  async getContent(key) {
70
141
  const bucketKey = this.getBucketKey(key);
71
142
  const result = await this.client.getObject(this.bucket, bucketKey);
72
- return readBinaryStream(result);
143
+ return await readBinaryStream(result);
73
144
  }
74
145
  getContentStream(key) {
75
146
  const bucketKey = this.getBucketKey(key);
@@ -79,7 +150,7 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
79
150
  });
80
151
  }
81
152
  async getObjects() {
82
- return toArrayAsync(this.getObjectsCursor());
153
+ return await toArrayAsync(this.getObjectsCursor());
83
154
  }
84
155
  getObjectsCursor() {
85
156
  const stream = this.client.listObjectsV2(this.bucket, this.prefix, true);
@@ -96,12 +167,13 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
96
167
  async getDownloadUrl(key, expirationTimestamp, responseHeaders) {
97
168
  const bucketKey = this.getBucketKey(key);
98
169
  const { date, expiration } = getDateAndExpiration(expirationTimestamp);
99
- return this.client.presignedGetObject(this.bucket, bucketKey, expiration, responseHeaders ?? {}, date);
170
+ return await this.client.presignedGetObject(this.bucket, bucketKey, expiration, responseHeaders ?? {}, date);
100
171
  }
101
- async getUploadUrl(key, expirationTimestamp) {
172
+ async getUploadUrl(key, expirationTimestamp, options) {
102
173
  const bucketKey = this.getBucketKey(key);
103
174
  const { date, expiration } = getDateAndExpiration(expirationTimestamp);
104
- return this.client.presignedUrl('PUT', this.bucket, bucketKey, expiration, {}, date);
175
+ const query = mapObjectKeys(options?.metadata ?? {}, (key) => `X-Amz-Meta-${key}`);
176
+ return await this.client.presignedUrl('PUT', this.bucket, bucketKey, expiration, query, date);
105
177
  }
106
178
  async deleteObject(key) {
107
179
  const bucketKey = this.getBucketKey(key);
@@ -122,14 +194,14 @@ let S3ObjectStorage = class S3ObjectStorage extends ObjectStorage {
122
194
  return bucketKey.slice(this.prefix.length);
123
195
  }
124
196
  };
125
- S3ObjectStorage = __decorate([
197
+ S3ObjectStorage = S3ObjectStorage_1 = __decorate([
126
198
  Singleton({
127
199
  provider: {
128
- useFactory: (argument, context) => context.resolve(S3ObjectStorageProvider).get(assertStringPass(argument, 'resolve argument must be a string (object storage module)')),
129
- async afterResolve(value) {
130
- await value.ensureBucketExists();
131
- }
132
- }
200
+ useFactory: (argument, context) => {
201
+ const { module } = (isString(argument) ? { module: argument } : assertDefinedPass(argument, 'argument must be a string or an object'));
202
+ return context.resolve(S3ObjectStorageProvider).get(module);
203
+ },
204
+ },
133
205
  }),
134
206
  __metadata("design:paramtypes", [Function, String, String, String])
135
207
  ], 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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.92.131",
3
+ "version": "0.92.134",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -8,7 +8,7 @@ import { Client } from '@elastic/elasticsearch';
8
8
  import { ElasticSearchIndexConfig } from './config.js';
9
9
  export const elasticsearchModuleConfig = {
10
10
  defaultOptions: { node: 'http://localhost:9200' },
11
- logPrefix: 'ELASTIC'
11
+ logPrefix: 'ELASTIC',
12
12
  };
13
13
  export const ELASTIC_SEARCH_INDEX_CONFIG = injectionToken('ElasticSearchIndexConfig');
14
14
  export function configureElasticsearch(config = {}) {
@@ -20,19 +20,19 @@ Injector.registerSingleton(Client, {
20
20
  assertDefined(argument, 'missing elasticsearch client options');
21
21
  context.data.logger = inject(Logger, elasticsearchModuleConfig.logPrefix);
22
22
  const client = new Client(argument);
23
- context.addDisposeHandler(async () => client.close().then(() => context.data.logger.info('closed connection')));
23
+ context.addDisposeHandler(async () => await client.close().then(() => context.data.logger.info('closed connection')));
24
24
  return client;
25
25
  },
26
26
  async afterResolve(client, options, { cancellationSignal, data: { logger } }) {
27
27
  const url = getUrl(options.node ?? options.nodes);
28
- await connect(`elasticsearch (${url})`, async () => client.ping().then((alive) => assert(alive, 'failed to connect')), logger, cancellationSignal);
28
+ await connect(`elasticsearch (${url})`, async () => await client.ping().then((alive) => assert(alive, 'failed to connect')), logger, cancellationSignal);
29
29
  },
30
30
  defaultArgumentProvider() {
31
31
  return elasticsearchModuleConfig.defaultOptions;
32
- }
32
+ },
33
33
  });
34
34
  Injector.registerSingleton(ELASTIC_SEARCH_INDEX_CONFIG, {
35
- useFactory: (argument, context) => context.resolve(ElasticSearchIndexConfig, argument)
35
+ useFactory: (argument, context) => context.resolve(ElasticSearchIndexConfig, argument),
36
36
  });
37
37
  function getUrl(node) {
38
38
  if (isString(node)) {
@@ -14,11 +14,11 @@ export function encrypt(algorithm, key, data) {
14
14
  const bytes = isString(data) ? encodeUtf8(data) : data;
15
15
  const encryptedBuffer = globalThis.crypto.subtle.encrypt(algorithm, key, bytes);
16
16
  return {
17
- toBuffer: async () => encryptedBuffer,
17
+ toBuffer: async () => await encryptedBuffer,
18
18
  toHex: async () => encodeHex(await encryptedBuffer),
19
19
  toBase64: async () => encodeBase64(await encryptedBuffer),
20
20
  toBase64Url: async () => encodeBase64Url(await encryptedBuffer),
21
- toZBase32: async () => zBase32Encode(await encryptedBuffer)
21
+ toZBase32: async () => zBase32Encode(await encryptedBuffer),
22
22
  };
23
23
  }
24
24
  /**
@@ -30,12 +30,12 @@ export function encrypt(algorithm, key, data) {
30
30
  export function decrypt(algorithm, key, bytes) {
31
31
  const decryptedBuffer = globalThis.crypto.subtle.decrypt(algorithm, key, bytes);
32
32
  return {
33
- toBuffer: async () => decryptedBuffer,
33
+ toBuffer: async () => await decryptedBuffer,
34
34
  toHex: async () => encodeHex(await decryptedBuffer),
35
35
  toBase64: async () => encodeBase64(await decryptedBuffer),
36
36
  toBase64Url: async () => encodeBase64Url(await decryptedBuffer),
37
37
  toZBase32: async () => zBase32Encode(await decryptedBuffer),
38
- toUtf8: async () => decodeText(await decryptedBuffer)
38
+ toUtf8: async () => decodeText(await decryptedBuffer),
39
39
  };
40
40
  }
41
41
  /**
@@ -47,11 +47,11 @@ export function digest(algorithm, data) {
47
47
  const bytes = isString(data) ? encodeUtf8(data) : data;
48
48
  const arrayBufferPromise = globalThis.crypto.subtle.digest(algorithm, bytes);
49
49
  const result = {
50
- toBuffer: async () => arrayBufferPromise,
50
+ toBuffer: async () => await arrayBufferPromise,
51
51
  toHex: async () => encodeHex(await arrayBufferPromise),
52
52
  toBase64: async () => encodeBase64(await arrayBufferPromise),
53
53
  toBase64Url: async () => encodeBase64Url(await arrayBufferPromise),
54
- toZBase32: async () => zBase32Encode(await arrayBufferPromise)
54
+ toZBase32: async () => zBase32Encode(await arrayBufferPromise),
55
55
  };
56
56
  return result;
57
57
  }
@@ -65,11 +65,11 @@ export function sign(algorithm, key, data) {
65
65
  const bytes = isString(data) ? encodeUtf8(data) : data;
66
66
  const arrayBufferPromise = globalThis.crypto.subtle.sign(algorithm, key, bytes);
67
67
  const result = {
68
- toBuffer: async () => arrayBufferPromise,
68
+ toBuffer: async () => await arrayBufferPromise,
69
69
  toHex: async () => encodeHex(await arrayBufferPromise),
70
70
  toBase64: async () => encodeBase64(await arrayBufferPromise),
71
71
  toBase64Url: async () => encodeBase64Url(await arrayBufferPromise),
72
- toZBase32: async () => zBase32Encode(await arrayBufferPromise)
72
+ toZBase32: async () => zBase32Encode(await arrayBufferPromise),
73
73
  };
74
74
  return result;
75
75
  }
@@ -83,7 +83,7 @@ export function sign(algorithm, key, data) {
83
83
  export async function verify(algorithm, key, signature, data) {
84
84
  const signatureBytes = isString(signature) ? encodeUtf8(signature) : signature;
85
85
  const dataBytes = isString(data) ? encodeUtf8(data) : data;
86
- return globalThis.crypto.subtle.verify(algorithm, key, signatureBytes, dataBytes);
86
+ return await globalThis.crypto.subtle.verify(algorithm, key, signatureBytes, dataBytes);
87
87
  }
88
88
  /**
89
89
  * Imports a HMAC CryptoKey
@@ -94,9 +94,9 @@ export async function verify(algorithm, key, signature, data) {
94
94
  export async function importHmacKey(algorithm, key, extractable = false) {
95
95
  const binaryKey = isString(key) ? encodeUtf8(key) : key;
96
96
  if (isBinaryKey(binaryKey)) {
97
- return globalThis.crypto.subtle.importKey('raw', binaryKey, { name: 'HMAC', hash: algorithm }, extractable, ['sign', 'verify']);
97
+ return await globalThis.crypto.subtle.importKey('raw', binaryKey, { name: 'HMAC', hash: algorithm }, extractable, ['sign', 'verify']);
98
98
  }
99
- return globalThis.crypto.subtle.importKey('jwk', binaryKey, { name: 'HMAC', hash: algorithm }, extractable, ['sign', 'verify']);
99
+ return await globalThis.crypto.subtle.importKey('jwk', binaryKey, { name: 'HMAC', hash: algorithm }, extractable, ['sign', 'verify']);
100
100
  }
101
101
  /**
102
102
  * Imports a CryptoKey for symmetric encryption
@@ -108,9 +108,9 @@ export async function importHmacKey(algorithm, key, extractable = false) {
108
108
  export async function importSymmetricKey(algorithm, length, key, extractable = false) {
109
109
  const binaryKey = isString(key) ? encodeUtf8(key) : key;
110
110
  if (isBinaryKey(binaryKey)) {
111
- return globalThis.crypto.subtle.importKey('raw', binaryKey, { name: algorithm, length }, extractable, ['encrypt', 'decrypt']);
111
+ return await globalThis.crypto.subtle.importKey('raw', binaryKey, { name: algorithm, length }, extractable, ['encrypt', 'decrypt']);
112
112
  }
113
- return globalThis.crypto.subtle.importKey('jwk', binaryKey, { name: algorithm, length }, extractable, ['encrypt', 'decrypt']);
113
+ return await globalThis.crypto.subtle.importKey('jwk', binaryKey, { name: algorithm, length }, extractable, ['encrypt', 'decrypt']);
114
114
  }
115
115
  /**
116
116
  * Imports an ECDSA CryptoKey
@@ -121,9 +121,9 @@ export async function importSymmetricKey(algorithm, length, key, extractable = f
121
121
  export async function importEcdsaKey(curve, key, extractable = false) {
122
122
  const binaryKey = isString(key) ? encodeUtf8(key) : key;
123
123
  if (isBinaryKey(binaryKey)) {
124
- return globalThis.crypto.subtle.importKey('spki', binaryKey, { name: 'ECDSA', namedCurve: curve }, extractable, ['verify']);
124
+ return await globalThis.crypto.subtle.importKey('spki', binaryKey, { name: 'ECDSA', namedCurve: curve }, extractable, ['verify']);
125
125
  }
126
- return globalThis.crypto.subtle.importKey('jwk', binaryKey, { name: 'ECDSA', namedCurve: curve }, extractable, ['verify']);
126
+ return await globalThis.crypto.subtle.importKey('jwk', binaryKey, { name: 'ECDSA', namedCurve: curve }, extractable, ['verify']);
127
127
  }
128
128
  /**
129
129
  * Import a pbkdf2 CryptoKey
@@ -132,7 +132,7 @@ export async function importEcdsaKey(curve, key, extractable = false) {
132
132
  */
133
133
  export async function importPbkdf2Key(key, extractable = false) {
134
134
  const binaryKey = isString(key) ? encodeUtf8(key) : key;
135
- return globalThis.crypto.subtle.importKey('raw', binaryKey, { name: 'PBKDF2' }, extractable, ['deriveKey', 'deriveBits']);
135
+ return await globalThis.crypto.subtle.importKey('raw', binaryKey, { name: 'PBKDF2' }, extractable, ['deriveKey', 'deriveBits']);
136
136
  }
137
137
  /**
138
138
  * Generates a new ECDSA CryptoKeyPair
@@ -141,7 +141,7 @@ export async function importPbkdf2Key(key, extractable = false) {
141
141
  * @param usages whether to generate a key for signing, verifiying or both. Defaults to both
142
142
  */
143
143
  export async function generateEcdsaKey(curve, extractable = false, usages = ['sign', 'verify']) {
144
- return globalThis.crypto.subtle.generateKey({ name: 'ECDSA', namedCurve: curve }, extractable, usages);
144
+ return await globalThis.crypto.subtle.generateKey({ name: 'ECDSA', namedCurve: curve }, extractable, usages);
145
145
  }
146
146
  /**
147
147
  * Generates a pbkdf2 CryptoKey
@@ -149,7 +149,7 @@ export async function generateEcdsaKey(curve, extractable = false, usages = ['si
149
149
  */
150
150
  export async function generatePbkdf2Key(extractable = false) {
151
151
  const key = getRandomBytes(16);
152
- return importPbkdf2Key(key, extractable);
152
+ return await importPbkdf2Key(key, extractable);
153
153
  }
154
154
  /**
155
155
  * Derive byte array from key
@@ -13,9 +13,10 @@ export declare function objectKeys<T extends ObjectLiteral>(object: T): (keyof T
13
13
  export declare function objectValues<T extends ObjectLiteral>(object: T): (T[keyof T])[];
14
14
  export declare function fromEntries<A>(entries: A): FromEntries<A>;
15
15
  export declare function fromEntries<K extends PropertyKey, T>(entries: Iterable<readonly [K, T]>): Record<K, T>;
16
- export declare function mapObject<T extends ObjectLiteral, K extends string | number | symbol, V>(object: T, mapper: (value: T[keyof T], key: keyof T) => [key: K, value: V]): Record<K, V>;
17
- export declare function mapObjectAsync<T extends ObjectLiteral, K extends string | number | symbol, V>(object: T, mapper: (value: T[keyof T], key: keyof T) => Promise<[key: K, value: V]>): Promise<Record<K, V>>;
16
+ export declare function mapObject<T extends ObjectLiteral, K extends PropertyKey, V>(object: T, mapper: (value: T[keyof T], key: keyof T) => [key: K, value: V]): Record<K, V>;
17
+ export declare function mapObjectAsync<T extends ObjectLiteral, K extends PropertyKey, V>(object: T, mapper: (value: T[keyof T], key: keyof T) => Promise<[key: K, value: V]>): Promise<Record<K, V>>;
18
18
  export declare function mapObjectValues<T extends ObjectLiteral, V>(object: T, mapper: (value: T[keyof T], key: keyof T) => V): Record<keyof T, V>;
19
+ export declare function mapObjectKeys<T extends ObjectLiteral, K extends PropertyKey>(object: T, mapper: (key: keyof T, value: T[keyof T]) => K): Record<K, T[keyof T]>;
19
20
  export declare function mapObjectValuesAsync<T extends ObjectLiteral, V>(object: T, mapper: (value: T[keyof T], key: keyof T) => Promise<V>): Promise<Record<keyof T, V>>;
20
21
  export declare function filterObject<T extends ObjectLiteral, U extends T[keyof T]>(object: T, predicate: (value: T[keyof T], key: keyof T) => value is U): PickBy<T, U>;
21
22
  export declare function filterObject<T extends ObjectLiteral>(object: T, predicate: (value: T[keyof T], key: keyof T) => boolean): Partial<T>;
@@ -31,14 +31,17 @@ export function mapObject(object, mapper) {
31
31
  }
32
32
  export async function mapObjectAsync(object, mapper) {
33
33
  const entries = objectKeys(object);
34
- const mappedEntries = await toArrayAsync(mapAsync(entries, async (key) => mapper(object[key], key)));
34
+ const mappedEntries = await toArrayAsync(mapAsync(entries, async (key) => await mapper(object[key], key)));
35
35
  return Object.fromEntries(mappedEntries);
36
36
  }
37
37
  export function mapObjectValues(object, mapper) {
38
38
  return mapObject(object, (value, key) => [key, mapper(value, key)]);
39
39
  }
40
+ export function mapObjectKeys(object, mapper) {
41
+ return mapObject(object, (value, key) => [mapper(key, value), value]);
42
+ }
40
43
  export async function mapObjectValuesAsync(object, mapper) {
41
- return mapObjectAsync(object, async (value, key) => [key, await mapper(value, key)]);
44
+ return await mapObjectAsync(object, async (value, key) => [key, await mapper(value, key)]);
42
45
  }
43
46
  export function filterObject(object, predicate) {
44
47
  const mappedEntries = objectEntries(object).filter(([key, value]) => predicate(value, key));
@@ -8,6 +8,6 @@ export function sizeLimitTransform(maxBytes, writableStrategy, readableStrategy)
8
8
  throw MaxBytesExceededError.fromBytes(maxBytes);
9
9
  }
10
10
  controller.enqueue(chunk);
11
- }
11
+ },
12
12
  }, writableStrategy, readableStrategy);
13
13
  }
@@ -1,4 +1,4 @@
1
- import type { AbstractConstructor, BinaryData, JsonPrimitive, PascalCase, Primitive, TypedArray } from '../types.js';
1
+ import type { AbstractConstructor, BinaryData, JsonPrimitive, PascalCase, Primitive, Type, TypedArray } from '../types.js';
2
2
  export type AssertionMessage = string | (() => string);
3
3
  export type IsFunction<T> = <U extends T = T>(value: any) => value is U;
4
4
  export type IsNotFunction<T> = <V>(value: V) => value is Exclude<V, T>;
@@ -257,3 +257,9 @@ export declare const assertReadableStream: <T = any>(value: any, message?: Asser
257
257
  export declare const assertNotReadableStream: AssertNotFunction<ReadableStream>;
258
258
  export declare const assertReadableStreamPass: <T = any>(value: any, message?: AssertionMessage) => ReadableStream<T>;
259
259
  export declare const assertNotReadableStreamPass: AssertNotPassFunction<ReadableStream>;
260
+ export declare const isInstanceOf: <T>(value: any, type: Type<T>) => value is T;
261
+ export declare const isNotInstanceOf: <V, T>(value: V, type: Type<T>) => value is Exclude<V, T>;
262
+ export declare const assertInstanceOf: <T>(value: any, type: Type<T>, message?: AssertionMessage) => asserts value is T;
263
+ export declare const assertNotInstanceOf: <V, T>(value: V, type: Type<T>, message?: AssertionMessage) => asserts value is Exclude<V, T>;
264
+ export declare const assertInstanceOfPass: <T>(value: any, type: Type<T>, message?: AssertionMessage) => T;
265
+ export declare const assertNotInstanceOfPass: <V, T>(value: V, type: Type<T>, message?: AssertionMessage) => Exclude<V, T>;
@@ -36,7 +36,7 @@ export function createGuards(name, testFn) {
36
36
  [`assertNot${normalizedName}Pass`](value, message = defaultNotMessage) {
37
37
  assertNot(testFn(value), message);
38
38
  return value;
39
- }
39
+ },
40
40
  };
41
41
  }
42
42
  export function createInstanceGuards(name, type) {
@@ -335,3 +335,15 @@ export const assertReadableStream = readableStreamGuards.assertReadableStream;
335
335
  export const assertNotReadableStream = readableStreamGuards.assertNotReadableStream;
336
336
  export const assertReadableStreamPass = readableStreamGuards.assertReadableStreamPass;
337
337
  export const assertNotReadableStreamPass = readableStreamGuards.assertNotReadableStreamPass;
338
+ export const isInstanceOf = (value, type) => value instanceof type;
339
+ export const isNotInstanceOf = (value, type) => !isInstanceOf(value, type);
340
+ export const assertInstanceOf = (value, type, message) => assert(isInstanceOf(value, type), message);
341
+ export const assertNotInstanceOf = (value, type, message) => assertNot(isInstanceOf(value, type), message);
342
+ export const assertInstanceOfPass = (value, type, message) => {
343
+ assert(isInstanceOf(value, type), message);
344
+ return value;
345
+ };
346
+ export const assertNotInstanceOfPass = (value, type, message) => {
347
+ assertNot(isInstanceOf(value, type), message);
348
+ return value;
349
+ };