@b613/utils
Advanced tools
Comparing version 1.0.0-alpha to 1.0.0-alpha10
@@ -6,7 +6,8 @@ "use strict"; | ||
const axios_1 = tslib_1.__importDefault(require("axios")); | ||
const cli_color_1 = tslib_1.__importDefault(require("cli-color")); | ||
const color_1 = tslib_1.__importDefault(require("./color")); | ||
const axios_cache_adapter_1 = require("axios-cache-adapter"); | ||
function createClient(baseURL, { headers = {}, logger, cache, ...options } = {}) { | ||
function createClient(baseURL, _a = {}) { | ||
var { headers = {}, logger, cache } = _a, options = tslib_1.__rest(_a, ["headers", "logger", "cache"]); | ||
const adapter = cache ? (0, axios_cache_adapter_1.setupCache)(cache).adapter : undefined; | ||
const instance = axios_1.default.create({ ...options, baseURL, headers, adapter }); | ||
const instance = axios_1.default.create(Object.assign(Object.assign({}, options), { baseURL, headers, adapter })); | ||
instance.interceptors.response.use((response) => { | ||
@@ -16,7 +17,7 @@ const method = response.request.method || 'GET'; | ||
if (response.status >= 400) { | ||
logger?.info(`${prefix} ${cli_color_1.default.red(response.status)}`, 'HTTP'); | ||
logger?.error(`Error ${response.status}: ${JSON.stringify(response.data, null, 2)}`); | ||
logger === null || logger === void 0 ? void 0 : logger.info(`${prefix} ${color_1.default.red(response.status)}`, 'HTTP'); | ||
logger === null || logger === void 0 ? void 0 : logger.error(`Error ${response.status}: ${JSON.stringify(response.data, null, 2)}`); | ||
} | ||
else { | ||
logger?.info(`${prefix} ${cli_color_1.default.green(response.status)}`, 'HTTP'); | ||
logger === null || logger === void 0 ? void 0 : logger.info(`${prefix} ${color_1.default.green(response.status)}`, 'HTTP'); | ||
} | ||
@@ -23,0 +24,0 @@ return response; |
@@ -0,4 +1,20 @@ | ||
import { __awaiter } from "tslib"; | ||
const EventOptions = { | ||
once: true, | ||
}; | ||
const REGEX = /^data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+);base64,(.+)/; | ||
export function base64MimeType(encoded) { | ||
if (typeof encoded !== 'string') { | ||
return null; | ||
} | ||
const matches = encoded.match(REGEX); | ||
if (matches === null || matches === void 0 ? void 0 : matches.length) { | ||
return { | ||
mime: matches[1], | ||
data: encoded, | ||
raw: matches[2], | ||
}; | ||
} | ||
return null; | ||
} | ||
/** | ||
@@ -38,9 +54,11 @@ * Compress an input image's dataurl with resizing & image quality compression | ||
} | ||
export async function parseBase64(imageUrl, resizeWidth) { | ||
const result = await compressFromDataurl(imageUrl, { | ||
type: 'datauri', | ||
width: resizeWidth, | ||
export function parseBase64(imageUrl, resizeWidth) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const result = yield compressFromDataurl(imageUrl, { | ||
type: 'datauri', | ||
width: resizeWidth, | ||
}); | ||
return result.data; | ||
}); | ||
return result.data; | ||
} | ||
//# sourceMappingURL=image.browser.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseBase64 = void 0; | ||
exports.parseBase64 = exports.base64MimeType = void 0; | ||
const tslib_1 = require("tslib"); | ||
@@ -9,20 +9,38 @@ const os_1 = tslib_1.__importDefault(require("os")); | ||
const download = require('image-downloader'); | ||
async function parseBase64(imageUrl, resizeWidth) { | ||
try { | ||
let { filename } = await download.image({ url: imageUrl, dest: os_1.default.tmpdir() }); | ||
if (resizeWidth) { | ||
const image = await jimp_1.default.read(filename); | ||
const newFilename = `${filename}.resized`; | ||
filename = newFilename; | ||
await image.resize(resizeWidth, jimp_1.default.AUTO, jimp_1.default.RESIZE_BEZIER).writeAsync(newFilename); | ||
} | ||
const image = await promises_1.default.readFile(filename); | ||
return 'data:image/jpeg;base64,' + Buffer.from(image).toString('base64'); | ||
const REGEX = /^data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+);base64,(.+)/; | ||
function base64MimeType(encoded) { | ||
if (typeof encoded !== 'string') { | ||
return null; | ||
} | ||
catch { | ||
// | ||
const matches = encoded.match(REGEX); | ||
if (matches === null || matches === void 0 ? void 0 : matches.length) { | ||
return { | ||
mime: matches[1], | ||
data: encoded, | ||
raw: matches[2], | ||
}; | ||
} | ||
return ''; | ||
return null; | ||
} | ||
exports.base64MimeType = base64MimeType; | ||
function parseBase64(imageUrl, resizeWidth) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
try { | ||
let { filename } = yield download.image({ url: imageUrl, dest: os_1.default.tmpdir() }); | ||
if (resizeWidth) { | ||
const image = yield jimp_1.default.read(filename); | ||
const newFilename = `${filename}.resized`; | ||
filename = newFilename; | ||
yield image.resize(resizeWidth, jimp_1.default.AUTO, jimp_1.default.RESIZE_BEZIER).writeAsync(newFilename); | ||
} | ||
const image = yield promises_1.default.readFile(filename); | ||
return 'data:image/jpeg;base64,' + Buffer.from(image).toString('base64'); | ||
} | ||
catch (_a) { | ||
// | ||
} | ||
return ''; | ||
}); | ||
} | ||
exports.parseBase64 = parseBase64; | ||
//# sourceMappingURL=image.node.js.map |
@@ -25,12 +25,12 @@ "use strict"; | ||
const check = () => { | ||
logger?.info(`Checking availability of service ${url.host} (${count})`); | ||
const socket = (0, net_1.createConnection)({ host: url.host, port, timeout }); | ||
logger === null || logger === void 0 ? void 0 : logger.info(`Checking availability of service ${url.host} (${count})`); | ||
const socket = (0, net_1.createConnection)({ host: url.hostname, port, timeout }); | ||
socket.on('connect', () => { | ||
retrying = false; | ||
resolve(true); | ||
logger?.info(`Service ${url.host} is now available`); | ||
logger === null || logger === void 0 ? void 0 : logger.info(`Service ${url.host} is now available`); | ||
}); | ||
socket.on('timeout', () => { | ||
socket.end(); | ||
logger?.warn(`Service ${url.host} is not yet available (timeout)`); | ||
logger === null || logger === void 0 ? void 0 : logger.warn(`Service ${url.host} is not yet available (timeout)`); | ||
retry(); | ||
@@ -40,6 +40,7 @@ }); | ||
socket.end(); | ||
logger?.warn(`Service ${url.host} is not yet available (${err.message})`); | ||
logger === null || logger === void 0 ? void 0 : logger.warn(`Service ${url.host} is not yet available (${err.message})`); | ||
retry(err); | ||
}); | ||
socket.on('close', () => socket.destroy()); | ||
socket.end(); | ||
}; | ||
@@ -46,0 +47,0 @@ check(); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.all = exports.chain = void 0; | ||
const tslib_1 = require("tslib"); | ||
/** | ||
* Sequential promise execution | ||
*/ | ||
async function chain(items, fn) { | ||
const results = []; | ||
await items.reduce((task, item, index) => { | ||
return task | ||
.then(() => fn(item, index)) | ||
.then((result) => results.push(result)) | ||
.then(() => Promise.resolve()); | ||
}, Promise.resolve()); | ||
return results; | ||
function chain(items, fn) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const results = []; | ||
yield items.reduce((task, item, index) => { | ||
return task | ||
.then(() => fn(item, index)) | ||
.then((result) => results.push(result)) | ||
.then(() => Promise.resolve()); | ||
}, Promise.resolve()); | ||
return results; | ||
}); | ||
} | ||
@@ -21,6 +24,8 @@ exports.chain = chain; | ||
*/ | ||
async function all(items, fn) { | ||
return Promise.all(items.map((item, index) => fn(item, index))); | ||
function all(items, fn) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
return Promise.all(items.map((item, index) => fn(item, index))); | ||
}); | ||
} | ||
exports.all = all; | ||
//# sourceMappingURL=promise.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.stringify = void 0; | ||
function pushKeyPairs(items, keyPrefix, object) { | ||
@@ -30,14 +31,13 @@ for (const key in object) { | ||
} | ||
exports.default = { | ||
/** | ||
* Get a query object from a given object | ||
* @param object Object representing search params | ||
* @returns string representation of query | ||
*/ | ||
stringify(object) { | ||
const items = []; | ||
pushKeyPairs(items, '', object); | ||
return items.filter((e) => e !== '').join('&'); | ||
}, | ||
}; | ||
/** | ||
* Get a query object from a given object | ||
* @param object Object representing search params | ||
* @returns string representation of query | ||
*/ | ||
function stringify(object) { | ||
const items = []; | ||
pushKeyPairs(items, '', object); | ||
return items.filter((e) => e !== '').join('&'); | ||
} | ||
exports.stringify = stringify; | ||
//# sourceMappingURL=qs.js.map |
@@ -10,2 +10,3 @@ "use strict"; | ||
function generateEmptyValue(schema, useDefault = false) { | ||
var _a; | ||
if (useDefault) { | ||
@@ -42,3 +43,3 @@ if (typeof schema.default !== 'undefined') { | ||
const propSchema = schema.properties[prop]; | ||
if (schema.required?.includes(prop) || 'default' in propSchema || 'const' in propSchema) { | ||
if (((_a = schema.required) === null || _a === void 0 ? void 0 : _a.includes(prop)) || 'default' in propSchema || 'const' in propSchema) { | ||
object[prop] = generateEmptyValue(propSchema, useDefault); | ||
@@ -45,0 +46,0 @@ } |
@@ -5,4 +5,2 @@ "use strict"; | ||
const tslib_1 = require("tslib"); | ||
const ping_1 = require("./ping"); | ||
const trace_node_1 = require("./Trace/trace.node"); | ||
const http_1 = tslib_1.__importDefault(require("http")); | ||
@@ -12,20 +10,18 @@ const https_1 = tslib_1.__importDefault(require("https")); | ||
const morgan_1 = tslib_1.__importDefault(require("morgan")); | ||
const HttpError_1 = require("./HttpError"); | ||
const ping_1 = require("./ping"); | ||
const Trace_1 = require("./Trace"); | ||
const http_2 = require("./http"); | ||
const promise_1 = require("./promise"); | ||
exports.createApp = express_1.default; | ||
tslib_1.__exportStar(require("./HttpError"), exports); | ||
tslib_1.__exportStar(require("./http"), exports); | ||
const isProduction = process.env.NODE_ENV === 'production'; | ||
class Server { | ||
constructor(options) { | ||
options.name = options.name.split('/').reverse()[0]; | ||
this.options = options; | ||
this.trace = new trace_node_1.Trace(options.name); | ||
this.trace = new Trace_1.Trace(options.name); | ||
this.app = (0, exports.createApp)(); | ||
this.trace.info(`Setting ${this.options.name} server...`); | ||
this.app.disable('x-powered-by'); | ||
const loggerFormat = options.loggerFormat | ||
? options.loggerFormat | ||
: isProduction | ||
? `:date[iso] ${options.name} HTTP - :remote-addr - :remote-user ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"` | ||
: `:date[iso] ${options.name} HTTP - :method :url :status :response-time ms - :res[content-length]`; | ||
const loggerFormat = isProduction | ||
? `:date[iso] ${options.name} HTTP - :remote-addr - :remote-user ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"` | ||
: `:date[iso] ${options.name} HTTP - :method :url :status :response-time ms - :res[content-length]`; | ||
this.app.use((0, morgan_1.default)(loggerFormat)); | ||
@@ -40,11 +36,11 @@ } | ||
static handleError(err, res, logger) { | ||
if (err instanceof HttpError_1.HttpError) { | ||
if (err instanceof http_2.HttpError) { | ||
res.status(err.statusCode); | ||
if (err.body) { | ||
res.json({ error: err.message, body: err.body }); | ||
logger?.error(`${err.statusCode} - ${err.message} - Body: ${JSON.stringify(err.body)}`); | ||
logger === null || logger === void 0 ? void 0 : logger.error(`${err.statusCode} - ${err.message} - Body: ${JSON.stringify(err.body)}`); | ||
} | ||
else { | ||
res.json({ error: err.message }); | ||
logger?.error(`${err.statusCode} - ${err.message}`); | ||
logger === null || logger === void 0 ? void 0 : logger.error(`${err.statusCode} - ${err.message}`); | ||
} | ||
@@ -55,3 +51,3 @@ } | ||
res.json({ error: err.message }); | ||
logger?.error(`${err.statusCode} - ${err.message}`); | ||
logger === null || logger === void 0 ? void 0 : logger.error(`${err.statusCode} - ${err.message}`); | ||
} | ||
@@ -61,3 +57,3 @@ else if (err.status) { | ||
res.json({ error: err.message }); | ||
logger?.error(`${err.status} - ${err.message}`); | ||
logger === null || logger === void 0 ? void 0 : logger.error(`${err.status} - ${err.message}`); | ||
} | ||
@@ -67,75 +63,69 @@ else { | ||
res.json({ error: err.message }); | ||
logger?.error(`500 - ${err.message} - ${err.stack}`); | ||
logger === null || logger === void 0 ? void 0 : logger.error(`500 - ${err.message} - ${err.stack}`); | ||
} | ||
} | ||
async _start() { | ||
this.app.route('/status') | ||
.head((req, res) => res.sendStatus(200)) | ||
.get((req, res) => res.json({ | ||
name: this.options.name, | ||
version: this.options.version, | ||
status: 'up', | ||
uptime: process.uptime(), | ||
})); | ||
this.app.set('port', this.options.port); | ||
await this._prepare(); | ||
if (this.options.beforeStart) { | ||
try { | ||
await this.options.beforeStart(this); | ||
} | ||
catch (err) { | ||
this.trace.error('Failed to initialize server'); | ||
if (err.message) { | ||
_start() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
this.trace.info(`Setting ${this.options.name} server...`); | ||
this.app.disable('x-powered-by'); | ||
this.app.route('/status') | ||
.head((req, res) => res.sendStatus(200)) | ||
.get((req, res) => res.json({ | ||
name: this.options.name, | ||
version: this.options.version, | ||
status: 'up', | ||
uptime: process.uptime(), | ||
})); | ||
this.app.set('port', this.options.port); | ||
yield this._prepare(); | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
this.app.use((err, req, res, next) => Server.handleError(err, res, this.trace)); | ||
this.server = this.options.certificat | ||
? https_1.default.createServer(this.options.certificat, this.app) | ||
: http_1.default.createServer(this.app); | ||
this.server.on('error', (error) => { | ||
if (error.syscall !== 'listen') { | ||
throw error; | ||
} | ||
// handle specific listen errors with friendly messages | ||
switch (error.code) { | ||
case 'EACCES': | ||
this.trace.error(`${this.options.port} requires elevated privileges`); | ||
process.exit(-3); | ||
case 'EADDRINUSE': | ||
this.trace.error(`${this.options.port} is already in use`); | ||
process.exit(-4); | ||
default: | ||
throw error; | ||
} | ||
}); | ||
this.server.on('listening', () => this.trace.info(`Listening on ${this.options.port}`)); | ||
this.trace.info(`Starting ${this.options.name} server...`); | ||
this.server.listen(this.options.port, '0.0.0.0'); | ||
process.on('SIGINT', () => this.server.close(() => process.exit(0))); | ||
}); | ||
} | ||
_prepare() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { }); | ||
} | ||
start() { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
if (this.options.serviceDependencies instanceof Array) { | ||
try { | ||
yield (0, promise_1.all)(this.options.serviceDependencies, (dependency) => (0, ping_1.ping)(dependency, { | ||
timeout: 5000, | ||
interval: isProduction ? 5000 : 3000, | ||
retries: isProduction ? 10 : Number.MAX_SAFE_INTEGER, | ||
logger: this.trace, | ||
})); | ||
} | ||
catch (err) { | ||
this.trace.error(err.message); | ||
this.trace.error('Starting aborted'); | ||
process.exit(-5); | ||
} | ||
this.trace.error(`${err.stack}`); | ||
process.exit(-6); | ||
} | ||
} | ||
this.options.loader(this.app); | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
this.app.use((err, req, res, next) => Server.handleError(err, res, this.trace)); | ||
this.server = this.options.certificat | ||
? https_1.default.createServer(this.options.certificat, this.app) | ||
: http_1.default.createServer(this.app); | ||
this.server.on('error', (error) => { | ||
if (error.syscall !== 'listen') { | ||
throw error; | ||
} | ||
// handle specific listen errors with friendly messages | ||
switch (error.code) { | ||
case 'EACCES': | ||
this.trace.error(`${this.options.port} requires elevated privileges`); | ||
process.exit(-3); | ||
case 'EADDRINUSE': | ||
this.trace.error(`${this.options.port} is already in use`); | ||
process.exit(-4); | ||
default: | ||
throw error; | ||
} | ||
yield this._start(); | ||
}); | ||
this.server.on('listening', () => this.trace.info(`Listening on ${this.options.port}`)); | ||
this.trace.info(`Starting ${this.options.name} server...`); | ||
this.server.listen(this.options.port, '0.0.0.0'); | ||
} | ||
async _prepare() { } | ||
async start() { | ||
process.on('SIGINT', () => this.server.close(() => process.exit(0))); | ||
if (this.options.serviceDependencies instanceof Array) { | ||
try { | ||
await (0, promise_1.all)(this.options.serviceDependencies, (dependency) => (0, ping_1.ping)(dependency, { | ||
timeout: 5000, | ||
interval: isProduction ? 5000 : 3000, | ||
retries: isProduction ? 10 : Number.MAX_SAFE_INTEGER, | ||
logger: this.trace, | ||
})); | ||
} | ||
catch (err) { | ||
this.trace.error(err.message); | ||
this.trace.error('Starting aborted'); | ||
process.exit(-5); | ||
} | ||
} | ||
await this._start(); | ||
} | ||
} | ||
@@ -142,0 +132,0 @@ exports.Server = Server; |
@@ -5,3 +5,3 @@ "use strict"; | ||
const tslib_1 = require("tslib"); | ||
const cli_color_1 = tslib_1.__importDefault(require("cli-color")); | ||
const color_1 = tslib_1.__importDefault(require("../color")); | ||
class Trace { | ||
@@ -19,6 +19,6 @@ constructor(name) { | ||
warn(msg, prefix = 'WARN') { | ||
process.stderr.write(this.parse(cli_color_1.default.yellow(prefix), msg)); | ||
process.stderr.write(this.parse(color_1.default.yellow(prefix), msg)); | ||
} | ||
error(msg, prefix = 'ERROR') { | ||
process.stderr.write(this.parse(cli_color_1.default.red(prefix), msg)); | ||
process.stderr.write(this.parse(color_1.default.red(prefix), msg)); | ||
} | ||
@@ -25,0 +25,0 @@ } |
{ | ||
"name": "@b613/utils", | ||
"version": "1.0.0-alpha", | ||
"version": "1.0.0-alpha10", | ||
"description": "Set of utility methods for common operations", | ||
@@ -10,3 +10,3 @@ "license": "MIT", | ||
"watch": "jest --detectOpenHandles --no-coverage --watchAll", | ||
"build": "tsc && tsc -p tsconfig.browser.json" | ||
"build": "rm -rf lib* && tsc && tsc -p tsconfig.browser.json && cp src/*.d.ts lib/ && mkdir -p libtmp && cp --parents src/*/package.json libtmp/ && cp -r libtmp/src/* lib/" | ||
}, | ||
@@ -35,3 +35,3 @@ "repository": { | ||
"author": "Sébastien Demanou", | ||
"types": "typings/index.d.ts", | ||
"types": "typings.d.ts", | ||
"dependencies": { | ||
@@ -38,0 +38,0 @@ "axios": "0.26.1", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
115972
61
2013
4