mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-23 16:19:49 +00:00
feat: getting presigned url of the uploaded attachment
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.576.0",
|
"@aws-sdk/client-s3": "^3.576.0",
|
||||||
|
"@aws-sdk/s3-request-presigner": "^3.583.0",
|
||||||
"@casl/ability": "^5.4.3",
|
"@casl/ability": "^5.4.3",
|
||||||
"@hapi/boom": "^7.4.3",
|
"@hapi/boom": "^7.4.3",
|
||||||
"@lemonsqueezy/lemonsqueezy.js": "^2.2.0",
|
"@lemonsqueezy/lemonsqueezy.js": "^2.2.0",
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ export class AttachmentsController extends BaseController {
|
|||||||
this.validationResult,
|
this.validationResult,
|
||||||
this.unlinkDocument.bind(this)
|
this.unlinkDocument.bind(this)
|
||||||
);
|
);
|
||||||
|
router.get(
|
||||||
|
'/:id/presigned-url',
|
||||||
|
[param('id').exists()],
|
||||||
|
this.validationResult,
|
||||||
|
this.getAttachmentPresignedUrl.bind(this)
|
||||||
|
);
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
@@ -185,4 +191,27 @@ export class AttachmentsController extends BaseController {
|
|||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retreives the presigned url of the given attachment key.
|
||||||
|
* @param {Request} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @param next
|
||||||
|
*/
|
||||||
|
private async getAttachmentPresignedUrl(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: any
|
||||||
|
) {
|
||||||
|
const { id: documentKey } = req.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const presignedUrl = await this.attachmentsApplication.getPresignedUrl(
|
||||||
|
documentKey
|
||||||
|
);
|
||||||
|
return res.status(200).send({ presignedUrl });
|
||||||
|
} catch (error) {
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ exports.up = function (knex) {
|
|||||||
return knex.schema.createTable('documents', (table) => {
|
return knex.schema.createTable('documents', (table) => {
|
||||||
table.increments('id').primary();
|
table.increments('id').primary();
|
||||||
table.string('key').notNullable();
|
table.string('key').notNullable();
|
||||||
table.string('extension').notNullable();
|
table.string('mime_type').notNullable();
|
||||||
|
table.integer('size').unsigned().notNullable();
|
||||||
|
table.string('origin_name');
|
||||||
table.timestamps();
|
table.timestamps();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { GetAttachment } from './GetAttachment';
|
|||||||
import { AttachmentUploadPipeline } from './S3UploadPipeline';
|
import { AttachmentUploadPipeline } from './S3UploadPipeline';
|
||||||
import { LinkAttachment } from './LinkAttachment';
|
import { LinkAttachment } from './LinkAttachment';
|
||||||
import { UnlinkAttachment } from './UnlinkAttachment';
|
import { UnlinkAttachment } from './UnlinkAttachment';
|
||||||
|
import { getAttachmentPresignedUrl } from './GetAttachmentPresignedUrl';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class AttachmentsApplication {
|
export class AttachmentsApplication {
|
||||||
@@ -26,6 +27,9 @@ export class AttachmentsApplication {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private unlinkDocumentService: UnlinkAttachment;
|
private unlinkDocumentService: UnlinkAttachment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getPresignedUrlService: getAttachmentPresignedUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
@@ -101,4 +105,13 @@ export class AttachmentsApplication {
|
|||||||
modelId
|
modelId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the presigned url of the given attachment key.
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
public getPresignedUrl(key: string): Promise<string> {
|
||||||
|
return this.getPresignedUrlService.getPresignedUrl(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { GetObjectCommand } from '@aws-sdk/client-s3';
|
||||||
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
||||||
|
import { s3 } from '@/lib/S3/S3';
|
||||||
|
import { Service } from 'typedi';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class getAttachmentPresignedUrl {
|
||||||
|
/**
|
||||||
|
* Retrieves the presigned url of the given attachment key.
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {Promise<string?>}
|
||||||
|
*/
|
||||||
|
async getPresignedUrl(key: string) {
|
||||||
|
const params = {
|
||||||
|
Bucket: process.env.AWS_BUCKET,
|
||||||
|
Key: key,
|
||||||
|
Expires: 60 * 5, // 5 minutes
|
||||||
|
};
|
||||||
|
const command = new GetObjectCommand({
|
||||||
|
Bucket: process.env.AWS_BUCKET,
|
||||||
|
Key: key,
|
||||||
|
});
|
||||||
|
const signedUrl = await getSignedUrl(s3, command, { expiresIn: 300 });
|
||||||
|
|
||||||
|
return signedUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,12 +6,20 @@ export class UploadDocument {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts the document metadata.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {} file
|
||||||
|
* @returns {}
|
||||||
|
*/
|
||||||
async upload(tenantId: number, file: any) {
|
async upload(tenantId: number, file: any) {
|
||||||
const { Document } = this.tenancy.models(tenantId);
|
const { Document } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
const insertedDocument = await Document.query().insert({
|
const insertedDocument = await Document.query().insert({
|
||||||
key: file.key,
|
key: file.key,
|
||||||
extension: file.mimetype,
|
mimeType: file.mimetype,
|
||||||
|
size: file.size,
|
||||||
|
originName: file.originalname,
|
||||||
});
|
});
|
||||||
return insertedDocument;
|
return insertedDocument;
|
||||||
}
|
}
|
||||||
|
|||||||
57
pnpm-lock.yaml
generated
57
pnpm-lock.yaml
generated
@@ -38,6 +38,9 @@ importers:
|
|||||||
'@aws-sdk/client-s3':
|
'@aws-sdk/client-s3':
|
||||||
specifier: ^3.576.0
|
specifier: ^3.576.0
|
||||||
version: 3.583.0
|
version: 3.583.0
|
||||||
|
'@aws-sdk/s3-request-presigner':
|
||||||
|
specifier: ^3.583.0
|
||||||
|
version: 3.583.0
|
||||||
'@casl/ability':
|
'@casl/ability':
|
||||||
specifier: ^5.4.3
|
specifier: ^5.4.3
|
||||||
version: 5.4.4
|
version: 5.4.4
|
||||||
@@ -1473,6 +1476,20 @@ packages:
|
|||||||
tslib: 2.6.2
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@aws-sdk/s3-request-presigner@3.583.0:
|
||||||
|
resolution: {integrity: sha512-Xp48RdnUzERYraIczByhbV/92TtXeJNE7QXOyMGVdvQkVP+3rwuXRGg85FqNSkOq7TFaGhnuxPiYWvsTeEzZTg==}
|
||||||
|
engines: {node: '>=16.0.0'}
|
||||||
|
dependencies:
|
||||||
|
'@aws-sdk/signature-v4-multi-region': 3.582.0
|
||||||
|
'@aws-sdk/types': 3.577.0
|
||||||
|
'@aws-sdk/util-format-url': 3.577.0
|
||||||
|
'@smithy/middleware-endpoint': 3.0.0
|
||||||
|
'@smithy/protocol-http': 4.0.0
|
||||||
|
'@smithy/smithy-client': 3.0.1
|
||||||
|
'@smithy/types': 3.0.0
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@aws-sdk/signature-v4-multi-region@3.582.0:
|
/@aws-sdk/signature-v4-multi-region@3.582.0:
|
||||||
resolution: {integrity: sha512-aFCOjjNqEX2l+V8QjOWy5F7CtHIC/RlYdBuv3No6yxn+pMvVUUe6zdMk2yHWcudVpHWsyvcZzAUBliAPeFLPsQ==}
|
resolution: {integrity: sha512-aFCOjjNqEX2l+V8QjOWy5F7CtHIC/RlYdBuv3No6yxn+pMvVUUe6zdMk2yHWcudVpHWsyvcZzAUBliAPeFLPsQ==}
|
||||||
engines: {node: '>=16.0.0'}
|
engines: {node: '>=16.0.0'}
|
||||||
@@ -1524,6 +1541,16 @@ packages:
|
|||||||
tslib: 2.6.2
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@aws-sdk/util-format-url@3.577.0:
|
||||||
|
resolution: {integrity: sha512-SyEGC2J+y/krFRuPgiF02FmMYhqbiIkOjDE6k4nYLJQRyS6XEAGxZoG+OHeOVEM+bsDgbxokXZiM3XKGu6qFIg==}
|
||||||
|
engines: {node: '>=16.0.0'}
|
||||||
|
dependencies:
|
||||||
|
'@aws-sdk/types': 3.577.0
|
||||||
|
'@smithy/querystring-builder': 3.0.0
|
||||||
|
'@smithy/types': 3.0.0
|
||||||
|
tslib: 2.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@aws-sdk/util-locate-window@3.568.0:
|
/@aws-sdk/util-locate-window@3.568.0:
|
||||||
resolution: {integrity: sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==}
|
resolution: {integrity: sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==}
|
||||||
engines: {node: '>=16.0.0'}
|
engines: {node: '>=16.0.0'}
|
||||||
@@ -8995,7 +9022,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
|
resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
pascal-case: 3.1.2
|
pascal-case: 3.1.2
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/camelcase-css@2.0.1:
|
/camelcase-css@2.0.1:
|
||||||
@@ -9054,7 +9081,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
|
resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
no-case: 3.0.4
|
no-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
upper-case-first: 2.0.2
|
upper-case-first: 2.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@@ -9163,7 +9190,7 @@ packages:
|
|||||||
path-case: 3.0.4
|
path-case: 3.0.4
|
||||||
sentence-case: 3.0.4
|
sentence-case: 3.0.4
|
||||||
snake-case: 3.0.4
|
snake-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/char-regex@1.0.2:
|
/char-regex@1.0.2:
|
||||||
@@ -9678,7 +9705,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==}
|
resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
no-case: 3.0.4
|
no-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
upper-case: 2.0.2
|
upper-case: 2.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@@ -11035,7 +11062,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
|
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
no-case: 3.0.4
|
no-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/dot-prop@4.2.1:
|
/dot-prop@4.2.1:
|
||||||
@@ -13755,7 +13782,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==}
|
resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==}
|
||||||
dependencies:
|
dependencies:
|
||||||
capital-case: 1.0.4
|
capital-case: 1.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/helmet-crossdomain@0.4.0:
|
/helmet-crossdomain@0.4.0:
|
||||||
@@ -17083,7 +17110,7 @@ packages:
|
|||||||
/lower-case@2.0.2:
|
/lower-case@2.0.2:
|
||||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/lowercase-keys@1.0.1:
|
/lowercase-keys@1.0.1:
|
||||||
@@ -18120,7 +18147,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
lower-case: 2.0.2
|
lower-case: 2.0.2
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/nocache@2.1.0:
|
/nocache@2.1.0:
|
||||||
@@ -19209,7 +19236,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
|
resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
dot-case: 3.0.4
|
dot-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/parent-module@1.0.1:
|
/parent-module@1.0.1:
|
||||||
@@ -19309,7 +19336,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
|
resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
no-case: 3.0.4
|
no-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/pascalcase@0.1.1:
|
/pascalcase@0.1.1:
|
||||||
@@ -19329,7 +19356,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==}
|
resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
dot-case: 3.0.4
|
dot-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/path-dirname@1.0.2:
|
/path-dirname@1.0.2:
|
||||||
@@ -22966,7 +22993,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
|
resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
no-case: 3.0.4
|
no-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
upper-case-first: 2.0.2
|
upper-case-first: 2.0.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@@ -23212,7 +23239,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
|
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
dot-case: 3.0.4
|
dot-case: 3.0.4
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/snapdragon-node@2.1.1:
|
/snapdragon-node@2.1.1:
|
||||||
@@ -25212,13 +25239,13 @@ packages:
|
|||||||
/upper-case-first@2.0.2:
|
/upper-case-first@2.0.2:
|
||||||
resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==}
|
resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/upper-case@2.0.2:
|
/upper-case@2.0.2:
|
||||||
resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==}
|
resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.5.3
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/uri-js@4.4.1:
|
/uri-js@4.4.1:
|
||||||
|
|||||||
Reference in New Issue
Block a user