Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

contentful-batch-libs

Package Overview
Dependencies
Maintainers
3
Versions
111
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

contentful-batch-libs - npm Package Compare versions

Comparing version 9.5.1 to 9.6.0

58

dist/logging.js

@@ -13,10 +13,12 @@ "use strict";

exports.writeErrorLogFile = writeErrorLogFile;
var _events = _interopRequireDefault(require("events"));
var _bfj = _interopRequireDefault(require("bfj"));
var _figures = _interopRequireDefault(require("figures"));
var _format = _interopRequireDefault(require("date-fns/format"));
var _parseISO = _interopRequireDefault(require("date-fns/parseISO"));
var _figures = _interopRequireDefault(require("figures"));
var _nodeEvents = _interopRequireDefault(require("node:events"));
var _nodeFs = require("node:fs");
var _nodeStream = require("node:stream");
var _promises = require("node:stream/promises");
var _getEntityName = _interopRequireDefault(require("./get-entity-name"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const logEmitter = exports.logEmitter = new _events.default();
const logEmitter = exports.logEmitter = new _nodeEvents.default();
function extractErrorInformation(error) {

@@ -111,3 +113,7 @@ const source = error.originalError || error;

const count = errorLog.reduce((count, curr) => {
if (Object.prototype.hasOwnProperty.call(curr, 'warning')) count.warnings++;else if (Object.prototype.hasOwnProperty.call(curr, 'error')) count.errors++;
if (Object.prototype.hasOwnProperty.call(curr, 'warning')) {
count.warnings++;
} else if (Object.prototype.hasOwnProperty.call(curr, 'error')) {
count.errors++;
}
return count;

@@ -125,18 +131,32 @@ }, {

// Write all log messages instead of infos to the error log file
function writeErrorLogFile(destination, errorLog) {
const logFileData = errorLog.map(formatLogMessageLogfile);
return _bfj.default.write(destination, logFileData, {
circular: 'ignore',
space: 2
}).then(() => {
/**
* Write all log messages instead of infos to the error log file
* @param {import('node:fs').PathLike} destination
* @param {Record<string, unknown>[]} errorLog
* @returns {Promise<void>}
*/
async function writeErrorLogFile(destination, errorLog) {
const formatLogTransformer = new _nodeStream.Transform({
objectMode: true,
transform: (chunk, encoding, callback) => {
const formattedChunk = formatLogMessageLogfile(chunk);
callback(null, Buffer.from(JSON.stringify(formattedChunk)));
}
});
const logFileWriteStream = (0, _nodeFs.createWriteStream)(destination);
try {
await (0, _promises.pipeline)([_nodeStream.Readable.from(errorLog), formatLogTransformer, logFileWriteStream]);
console.log('\nStored the detailed error log file at:');
console.log(destination);
}).catch(e => {
} catch (err) {
// avoid crashing when writing the log file fails
console.error(e);
});
console.error(err);
}
}
// Init listeners for log messages, transform them into proper format and logs/displays them
/**
* Init listeners for log messages, transform them into proper format and logs/displays them
* @param {Record<string,unknown>[]} log
* @returns {Promise<void>}
*/
function setupLogging(log) {

@@ -159,3 +179,7 @@ function errorLogger(level, error) {

// Format log message to display them as task status
/**
* Format log message to display them as task status
* @template {Ctx}
* @param {import('listr').ListrTaskWrapper<Ctx>} task
*/
function logToTaskOutput(task) {

@@ -162,0 +186,0 @@ function logToTask(logMessage) {

{
"name": "contentful-batch-libs",
"version": "9.5.1",
"version": "9.6.0",
"description": "Library modules used by contentful batch utility CLI tools.",

@@ -26,3 +26,2 @@ "main": "dist/index.js",

"dependencies": {
"bfj": "7.1.0",
"date-fns": "^2.28.0",

@@ -39,10 +38,10 @@ "figures": "3.2.0",

"@types/lodash.clonedeep": "^4.5.7",
"@types/node": "^17.0.38",
"@types/node": "^20.8.4",
"@typescript-eslint/eslint-plugin": "^6.7.5",
"babel-eslint": "^10.1.0",
"babel-jest": "^27.3.1",
"babel-jest": "^29.7.0",
"babel-plugin-add-module-exports": "^1.0.4",
"babel-preset-env": "^1.7.0",
"contentful": "^9.1.31",
"contentful-management": "^10.6.0",
"contentful": "^10.6.1",
"contentful-management": "^11.1.1",
"cz-conventional-changelog": "^3.3.0",

@@ -55,3 +54,3 @@ "eslint": "^8.51.0",

"eslint-plugin-promise": "^6.1.1",
"husky": "7.0.4",
"husky": "8.0.3",
"jest": "^29.7.0",

@@ -58,0 +57,0 @@ "listr2": "^7.0.1",

@@ -0,1 +1,3 @@

import fs from 'node:fs'
import { Writable } from 'node:stream'
import {

@@ -10,7 +12,4 @@ formatLogMessageOneLine,

} from '../lib/logging'
import figures from 'figures'
import bfj from 'bfj'
function isValidDate (date) {

@@ -20,6 +19,2 @@ return !isNaN(Date.parse(date))

jest.mock('bfj', () => ({
write: jest.fn(() => Promise.resolve())
}))
const consoleLogSpy = jest.spyOn(global.console, 'log')

@@ -70,7 +65,12 @@ const logEmitterAddListenerSpy = jest.spyOn(logEmitter, 'addListener')

const output = formatLogMessageOneLine({ error, level: 'error' })
expect(output).toBe('Error: Status: status - status text - Message: Some API error - Entity: 42 - Details: error detail - Request ID: 3')
expect(output).toBe(
'Error: Status: status - status text - Message: Some API error - Entity: 42 - Details: error detail - Request ID: 3'
)
})
test('format one line message with level error', () => {
const output = formatLogMessageOneLine({ error: Error('normal error message'), level: 'error' })
const output = formatLogMessageOneLine({
error: Error('normal error message'),
level: 'error'
})
expect(output).toBe('Error: normal error message')

@@ -80,3 +80,6 @@ })

test('format one line message with level warning', () => {
const output = formatLogMessageOneLine({ warning: 'warning text', level: 'warning' })
const output = formatLogMessageOneLine({
warning: 'warning text',
level: 'warning'
})
expect(output).toBe('warning text')

@@ -117,3 +120,5 @@ })

expect(output.error.data.message).toBe(apiError.message)
expect(output.error.data.details.errors[0].name).toBe(apiError.details.errors[0].name)
expect(output.error.data.details.errors[0].name).toBe(
apiError.details.errors[0].name
)
})

@@ -140,7 +145,10 @@

test('displays error log well formatted', () => {
const extendedExampleErrorLog = [...exampleErrorLog, {
ts: new Date('2022-01-01T01:05:43+01:00').toJSON(),
level: 'warning',
warning: 'another warning'
}]
const extendedExampleErrorLog = [
...exampleErrorLog,
{
ts: new Date('2022-01-01T01:05:43+01:00').toJSON(),
level: 'warning',
warning: 'another warning'
}
]

@@ -150,6 +158,14 @@ displayErrorLog(extendedExampleErrorLog)

expect(consoleLogSpy.mock.calls).toHaveLength(4)
expect(consoleLogSpy.mock.calls[0][0]).toContain('The following 1 errors and 2 warnings occurred:')
expect(consoleLogSpy.mock.calls[1][0]).toMatch(/\d{2}:\d{2}:\d{2} - warning text/)
expect(consoleLogSpy.mock.calls[2][0]).toMatch(/\d{2}:\d{2}:\d{2} - Error: error message/)
expect(consoleLogSpy.mock.calls[3][0]).toMatch(/\d{2}:\d{2}:\d{2} - another warning/)
expect(consoleLogSpy.mock.calls[0][0]).toContain(
'The following 1 errors and 2 warnings occurred:'
)
expect(consoleLogSpy.mock.calls[1][0]).toMatch(
/\d{2}:\d{2}:\d{2} - warning text/
)
expect(consoleLogSpy.mock.calls[2][0]).toMatch(
/\d{2}:\d{2}:\d{2} - Error: error message/
)
expect(consoleLogSpy.mock.calls[3][0]).toMatch(
/\d{2}:\d{2}:\d{2} - another warning/
)
})

@@ -161,21 +177,49 @@

expect(consoleLogSpy.mock.calls).toHaveLength(1)
expect(consoleLogSpy.mock.calls[0][0]).toContain('No errors or warnings occurred')
expect(consoleLogSpy.mock.calls[0][0]).toContain(
'No errors or warnings occurred'
)
})
test('writes error log file to disk', async () => {
expect.assertions(8)
expect.assertions(9)
const destination = '/just/some/path/to/a/file.log'
await expect(writeErrorLogFile(destination, exampleErrorLog)).resolves.not.toThrow()
const chunks = []
const writeStreamSpy = jest
.spyOn(fs, 'createWriteStream')
.mockImplementation(() => {
return new Writable({
write: (chunk, b, cb) => {
try {
chunks.push(JSON.parse(chunk.toString('utf-8')))
cb()
} catch (err) {
cb(err)
}
}
})
})
await expect(
writeErrorLogFile(destination, exampleErrorLog)
).resolves.not.toThrow()
expect(consoleLogSpy.mock.calls).toHaveLength(2)
expect(consoleLogSpy.mock.calls[0][0]).toBe('\nStored the detailed error log file at:')
expect(consoleLogSpy.mock.calls[0][0]).toBe(
'\nStored the detailed error log file at:'
)
expect(consoleLogSpy.mock.calls[1][0]).toBe(destination)
expect(bfj.write.mock.calls).toHaveLength(1)
expect(bfj.write.mock.calls[0][0]).toBe(destination)
expect(bfj.write.mock.calls[0][1]).toMatchObject(exampleErrorLog)
expect(bfj.write.mock.calls[0][2]).toMatchObject({
circular: 'ignore',
space: 2
expect(writeStreamSpy.mock.calls).toHaveLength(1)
expect(writeStreamSpy.mock.calls[0][0]).toBe(destination)
chunks.forEach((chunk) => {
if ('error' in chunk) {
const { error, ...rest } = chunk
expect(typeof error).toBe('object')
expect(exampleErrorLog).toContainEqual(expect.objectContaining(rest))
} else {
expect(exampleErrorLog).toContainEqual(chunk)
}
})

@@ -268,3 +312,5 @@ })

expect(taskMock.output).not.toBe(`${figures.tick} this should no more change the task output`)
expect(taskMock.output).not.toBe(
`${figures.tick} this should no more change the task output`
)
})

@@ -5,2 +5,3 @@ import type { EventEmitter } from 'events'

import type HttpsProxyAgent from 'https-proxy-agent'
import type { PathLike } from 'node:fs'
import type { ListrDefaultRendererValue, ListrGetRendererClassFromValue, ListrRendererValue, ListrTask } from 'listr2'

@@ -47,3 +48,3 @@

export function writeErrorLogFile(destination: string, errorLog: unknown[]): Promise<void>;
export function writeErrorLogFile(destination: PathLike, errorLog: unknown[]): Promise<void>;

@@ -50,0 +51,0 @@ export function proxyStringToObject(proxyString: string): ProxyObject;

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc