Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 9x 1x 1x | import { camelCase, toUpper } from 'lodash';
import { AwsConfigs } from '../configs';
import * as pdf from 'html-pdf';
import { promisify } from 'util';
import * as fs from 'fs';
import { AnyObject } from '@loopback/repository';
import * as crypto from 'crypto';
const createPdf = promisify(pdf.create);
/**
* String utils.
*/
export class StringUtils {
/**
* Converts HTML to PDF and saves it to the specified output path.
*
* @param {string} html - The HTML content to convert.
* @param {string} outputPath - The path where the PDF file will be saved.
* @return {Promise<void>} - A promise that resolves when the conversion is complete.
*/
public static async convertToPDF(htmlContent: string, timezone: string): Promise<Buffer> {
const date = new Date();
const dateFormatter = new Intl.DateTimeFormat('en-GB', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23',
timeZoneName: 'short',
timeZone: timezone,
});
const formattedDate = dateFormatter.format(date);
const dateParts = formattedDate.split(', '); // Tách ngày tháng và múi giờ thành mảng
// Thêm dấu gạch ngang giữa ngày, tháng và năm
const [dateInfo, timeInfo] = dateParts;
const [day, month, year] = dateInfo.split(' ');
const finalFormattedDate = `${day}-${month}-${year} ${timeInfo}`;
// PDF options
const pdfOptions: pdf.CreateOptions = {
format: 'A4',
border: {
top: '1cm',
right: '1cm',
bottom: '1cm',
left: '1cm',
},
footer: {
height: '5mm',
contents: {
default: `<div style="margin-top: 20px;"><div style="float: left; width: 48%;">Exported on ${finalFormattedDate}</div>
<div style="float:right ;text-align: right; width: 48%;">Page <span>{{page}}</span>/<span>{{pages}}</span></div></div>`
},
},
};
// Generate PDF
const result: AnyObject = await createPdf(htmlContent, pdfOptions) as AnyObject;
// Read the generated PDF file
return await fs.promises.readFile(result.filename);
}
/**
* Format string
* @param str_template The template
* @param args args
* @example
*
* ```ts
* const res = format("Hello {0}", "World!")
* console.log(res) // Hello World!
* ```
*/
public static format = (
str_template: string,
...args: (string | number)[]
) => {
return str_template.replace(
/{(\d+)}/g,
(_, index) => String(args[index]) || '',
);
};
/**
* Capitalize first letter of word.
* @param str
* @returns
*/
public static capitalizeFirstLetter(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
}
/**
* Get full s3 url.
* @param key The S3 Key
*/
public static getS3Url(key: string): string {
const { s3Config } = AwsConfigs;
if (!key || key.startsWith('http')) {
return key;
}
return `https://${s3Config.bucketName}.s3.${AwsConfigs.region}.amazonaws.com/${key}`;
}
public static pascalCase = (str: string) => camelCase(str).replace(/^(.)/, toUpper)
/**
* Get random string
* @param {number} length=8
*/
public static randomstring(length = 8): string {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for ( let i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
/**
* Get random transaction id
* @param {number} length=8
*/
public static generateTransactionId(length = 8): string {
const numbers = '0123456789';
let transactionId = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * numbers.length);
transactionId += numbers.charAt(randomIndex);
}
return transactionId;
}
/**
* Extracts texts from a given string between the specified start and end texts.
*
* @param {string} text - The input string from which texts will be extracted.
* @param {string} fromText - The start text to begin extraction.
* @param {string} toText - The end text to stop extraction.
* @return {string[]} An array of extracted texts.
*/
public static extractTextsByLineBreak = (text: string, fromText: string, toText: string): string[] => {
const lines = text.split('\n');
const extractedTexts: string[] = [];
let extracting = false;
for (const line of lines) {
if (line.includes(fromText.trim())) {
extracting = true;
extractedTexts.push(line.trim());
} else if (extracting) {
extractedTexts.push(line.trim());
}
if (line.includes(toText.trim())) {
extracting = false;
}
}
return extractedTexts;
};
/**
* Calculates the ETag for a given buffer using the MD5 hash algorithm.
*
* @param {Buffer} buffer - The buffer for which the ETag will be calculated.
* @return {string} The calculated ETag.
*/
public static calculateSingleEtag(buffer: Buffer): string {
const hash = crypto.createHash('md5').update(buffer).digest('hex');
return `${hash}`;
};
/**
* Calculates the ETag for a given buffer by splitting it into multiple parts,
* computing the MD5 hash for each part, and then computing the MD5 hash of all
* the part hashes. The ETag is then returned in the form "<hash>-<number of parts>".
* @param buffer The buffer for which the ETag will be calculated.
* @param partSize The size of each part in bytes. Defaults to 5MB.
* @return The calculated ETag.
*/
public static calculateMultipartEtag(buffer: Buffer, partSize: number = 5 * 1024 * 1024): string {
const parts: Buffer[] = [];
// Chia file thành từng part nhỏ (5MB mỗi part mặc định)
for (let i = 0; i < buffer.length; i += partSize) {
parts.push(buffer.slice(i, i + partSize));
}
// Tạo MD5 hash cho từng part
const md5Parts = parts.map((part) => crypto.createHash('md5').update(part).digest());
// Nối tất cả các MD5 hash của từng part lại và hash lần cuối
const combinedHash = crypto.createHash('md5').update(Buffer.concat(md5Parts)).digest('hex');
// Trả về ETag dạng <hash>-<số parts>
return `${combinedHash}-${parts.length}`;
};
/**
* Calculates the ETag for a given buffer by splitting it into multiple parts
* and computing the MD5 hash of the hashes of each part. The ETag is then
* returned in the form "<hash>-<number of parts>".
* @param buffer The buffer for which the ETag will be calculated.
* @returns The calculated ETag.
*/
public static calculateS3Etag(buffer: Buffer): string {
const partSize = 5 * 1024 * 1024; // 5MB
return buffer.length <= partSize
? StringUtils.calculateSingleEtag(buffer)
: StringUtils.calculateMultipartEtag(buffer, partSize);
};
/**
* Fabric-like transaction id (hex 64 chars).
* @example "9f2a... (64 hex chars)"
*/
public static randomFabricTxId(): string {
return crypto.randomBytes(32).toString('hex'); // 32 bytes -> 64 hex chars
};
} |